Tercio@11: local Type, Version = "MultiLineEditBox", 28 tercio@0: local AceGUI = LibStub and LibStub("AceGUI-3.0", true) tercio@0: if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end tercio@0: tercio@0: -- Lua APIs tercio@0: local pairs = pairs tercio@0: tercio@0: -- WoW APIs tercio@0: local GetCursorInfo, GetSpellInfo, ClearCursor = GetCursorInfo, GetSpellInfo, ClearCursor tercio@0: local CreateFrame, UIParent = CreateFrame, UIParent tercio@0: local _G = _G tercio@0: tercio@0: -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded tercio@0: -- List them here for Mikk's FindGlobals script tercio@0: -- GLOBALS: ACCEPT, ChatFontNormal tercio@0: tercio@0: --[[----------------------------------------------------------------------------- tercio@0: Support functions tercio@0: -------------------------------------------------------------------------------]] tercio@0: tercio@0: if not AceGUIMultiLineEditBoxInsertLink then tercio@0: -- upgradeable hook tercio@0: hooksecurefunc("ChatEdit_InsertLink", function(...) return _G.AceGUIMultiLineEditBoxInsertLink(...) end) tercio@0: end tercio@0: tercio@0: function _G.AceGUIMultiLineEditBoxInsertLink(text) tercio@0: for i = 1, AceGUI:GetWidgetCount(Type) do tercio@0: local editbox = _G[("MultiLineEditBox%uEdit"):format(i)] tercio@0: if editbox and editbox:IsVisible() and editbox:HasFocus() then tercio@0: editbox:Insert(text) tercio@0: return true tercio@0: end tercio@0: end tercio@0: end tercio@0: tercio@0: tercio@0: local function Layout(self) tercio@0: self:SetHeight(self.numlines * 14 + (self.disablebutton and 19 or 41) + self.labelHeight) tercio@0: tercio@0: if self.labelHeight == 0 then tercio@0: self.scrollBar:SetPoint("TOP", self.frame, "TOP", 0, -23) tercio@0: else tercio@0: self.scrollBar:SetPoint("TOP", self.label, "BOTTOM", 0, -19) tercio@0: end tercio@0: tercio@0: if self.disablebutton then tercio@0: self.scrollBar:SetPoint("BOTTOM", self.frame, "BOTTOM", 0, 21) tercio@0: self.scrollBG:SetPoint("BOTTOMLEFT", 0, 4) tercio@0: else tercio@0: self.scrollBar:SetPoint("BOTTOM", self.button, "TOP", 0, 18) tercio@0: self.scrollBG:SetPoint("BOTTOMLEFT", self.button, "TOPLEFT") tercio@0: end tercio@0: end tercio@0: tercio@0: --[[----------------------------------------------------------------------------- tercio@0: Scripts tercio@0: -------------------------------------------------------------------------------]] tercio@0: local function OnClick(self) -- Button tercio@0: self = self.obj tercio@0: self.editBox:ClearFocus() tercio@0: if not self:Fire("OnEnterPressed", self.editBox:GetText()) then tercio@0: self.button:Disable() tercio@0: end tercio@0: end tercio@0: tercio@0: local function OnCursorChanged(self, _, y, _, cursorHeight) -- EditBox tercio@0: self, y = self.obj.scrollFrame, -y tercio@0: local offset = self:GetVerticalScroll() tercio@0: if y < offset then tercio@0: self:SetVerticalScroll(y) tercio@0: else tercio@0: y = y + cursorHeight - self:GetHeight() tercio@0: if y > offset then tercio@0: self:SetVerticalScroll(y) tercio@0: end tercio@0: end tercio@0: end tercio@0: tercio@0: local function OnEditFocusLost(self) -- EditBox tercio@0: self:HighlightText(0, 0) tercio@0: self.obj:Fire("OnEditFocusLost") tercio@0: end tercio@0: tercio@0: local function OnEnter(self) -- EditBox / ScrollFrame tercio@0: self = self.obj tercio@0: if not self.entered then tercio@0: self.entered = true tercio@0: self:Fire("OnEnter") tercio@0: end tercio@0: end tercio@0: tercio@0: local function OnLeave(self) -- EditBox / ScrollFrame tercio@0: self = self.obj tercio@0: if self.entered then tercio@0: self.entered = nil tercio@0: self:Fire("OnLeave") tercio@0: end tercio@0: end tercio@0: tercio@0: local function OnMouseUp(self) -- ScrollFrame tercio@0: self = self.obj.editBox tercio@0: self:SetFocus() tercio@0: self:SetCursorPosition(self:GetNumLetters()) tercio@0: end tercio@0: tercio@0: local function OnReceiveDrag(self) -- EditBox / ScrollFrame tercio@0: local type, id, info = GetCursorInfo() tercio@0: if type == "spell" then tercio@0: info = GetSpellInfo(id, info) tercio@0: elseif type ~= "item" then tercio@0: return tercio@0: end tercio@0: ClearCursor() tercio@0: self = self.obj tercio@0: local editBox = self.editBox tercio@0: if not editBox:HasFocus() then tercio@0: editBox:SetFocus() tercio@0: editBox:SetCursorPosition(editBox:GetNumLetters()) tercio@0: end tercio@0: editBox:Insert(info) tercio@0: self.button:Enable() tercio@0: end tercio@0: tercio@0: local function OnSizeChanged(self, width, height) -- ScrollFrame tercio@0: self.obj.editBox:SetWidth(width) tercio@0: end tercio@0: tercio@0: local function OnTextChanged(self, userInput) -- EditBox tercio@0: if userInput then tercio@0: self = self.obj tercio@0: self:Fire("OnTextChanged", self.editBox:GetText()) tercio@0: self.button:Enable() tercio@0: end tercio@0: end tercio@0: tercio@0: local function OnTextSet(self) -- EditBox tercio@0: self:HighlightText(0, 0) tercio@0: self:SetCursorPosition(self:GetNumLetters()) tercio@0: self:SetCursorPosition(0) tercio@0: self.obj.button:Disable() tercio@0: end tercio@0: tercio@0: local function OnVerticalScroll(self, offset) -- ScrollFrame tercio@0: local editBox = self.obj.editBox tercio@0: editBox:SetHitRectInsets(0, 0, offset, editBox:GetHeight() - offset - self:GetHeight()) tercio@0: end tercio@0: tercio@0: local function OnShowFocus(frame) tercio@0: frame.obj.editBox:SetFocus() tercio@0: frame:SetScript("OnShow", nil) tercio@0: end tercio@0: tercio@0: local function OnEditFocusGained(frame) tercio@0: AceGUI:SetFocus(frame.obj) tercio@0: frame.obj:Fire("OnEditFocusGained") tercio@0: end tercio@0: tercio@0: --[[----------------------------------------------------------------------------- tercio@0: Methods tercio@0: -------------------------------------------------------------------------------]] tercio@0: local methods = { tercio@0: ["OnAcquire"] = function(self) tercio@0: self.editBox:SetText("") tercio@0: self:SetDisabled(false) tercio@0: self:SetWidth(200) tercio@0: self:DisableButton(false) tercio@0: self:SetNumLines() tercio@0: self.entered = nil tercio@0: self:SetMaxLetters(0) tercio@0: end, tercio@0: tercio@0: ["OnRelease"] = function(self) tercio@0: self:ClearFocus() tercio@0: end, tercio@0: tercio@0: ["SetDisabled"] = function(self, disabled) tercio@0: local editBox = self.editBox tercio@0: if disabled then tercio@0: editBox:ClearFocus() tercio@0: editBox:EnableMouse(false) tercio@0: editBox:SetTextColor(0.5, 0.5, 0.5) tercio@0: self.label:SetTextColor(0.5, 0.5, 0.5) tercio@0: self.scrollFrame:EnableMouse(false) tercio@0: self.button:Disable() tercio@0: else tercio@0: editBox:EnableMouse(true) tercio@0: editBox:SetTextColor(1, 1, 1) tercio@0: self.label:SetTextColor(1, 0.82, 0) tercio@0: self.scrollFrame:EnableMouse(true) tercio@0: end tercio@0: end, tercio@0: tercio@0: ["SetLabel"] = function(self, text) tercio@0: if text and text ~= "" then tercio@0: self.label:SetText(text) tercio@0: if self.labelHeight ~= 10 then tercio@0: self.labelHeight = 10 tercio@0: self.label:Show() tercio@0: end tercio@0: elseif self.labelHeight ~= 0 then tercio@0: self.labelHeight = 0 tercio@0: self.label:Hide() tercio@0: end tercio@0: Layout(self) tercio@0: end, tercio@0: tercio@0: ["SetNumLines"] = function(self, value) tercio@0: if not value or value < 4 then tercio@0: value = 4 tercio@0: end tercio@0: self.numlines = value tercio@0: Layout(self) tercio@0: end, tercio@0: tercio@0: ["SetText"] = function(self, text) tercio@0: self.editBox:SetText(text) tercio@0: end, tercio@0: tercio@0: ["GetText"] = function(self) tercio@0: return self.editBox:GetText() tercio@0: end, tercio@0: tercio@0: ["SetMaxLetters"] = function (self, num) tercio@0: self.editBox:SetMaxLetters(num or 0) tercio@0: end, tercio@0: tercio@0: ["DisableButton"] = function(self, disabled) tercio@0: self.disablebutton = disabled tercio@0: if disabled then tercio@0: self.button:Hide() tercio@0: else tercio@0: self.button:Show() tercio@0: end tercio@0: Layout(self) tercio@0: end, tercio@0: tercio@0: ["ClearFocus"] = function(self) tercio@0: self.editBox:ClearFocus() tercio@0: self.frame:SetScript("OnShow", nil) tercio@0: end, tercio@0: tercio@0: ["SetFocus"] = function(self) tercio@0: self.editBox:SetFocus() tercio@0: if not self.frame:IsShown() then tercio@0: self.frame:SetScript("OnShow", OnShowFocus) tercio@0: end tercio@0: end, Tercio@11: Tercio@11: ["HighlightText"] = function(self, from, to) Tercio@11: self.editBox:HighlightText(from, to) Tercio@11: end, Tercio@11: tercio@0: ["GetCursorPosition"] = function(self) tercio@0: return self.editBox:GetCursorPosition() tercio@0: end, tercio@0: tercio@0: ["SetCursorPosition"] = function(self, ...) tercio@0: return self.editBox:SetCursorPosition(...) tercio@0: end, tercio@0: tercio@0: tercio@0: } tercio@0: tercio@0: --[[----------------------------------------------------------------------------- tercio@0: Constructor tercio@0: -------------------------------------------------------------------------------]] tercio@0: local backdrop = { tercio@0: bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tercio@0: edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]], edgeSize = 16, tercio@0: insets = { left = 4, right = 3, top = 4, bottom = 3 } tercio@0: } tercio@0: tercio@0: local function Constructor() tercio@0: local frame = CreateFrame("Frame", nil, UIParent) tercio@0: frame:Hide() tercio@0: tercio@0: local widgetNum = AceGUI:GetNextWidgetNum(Type) tercio@0: tercio@0: local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall") tercio@0: label:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, -4) tercio@0: label:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, -4) tercio@0: label:SetJustifyH("LEFT") tercio@0: label:SetText(ACCEPT) tercio@0: label:SetHeight(10) tercio@0: Tercio@11: local button = CreateFrame("Button", ("%s%dButton"):format(Type, widgetNum), frame, "UIPanelButtonTemplate") tercio@0: button:SetPoint("BOTTOMLEFT", 0, 4) tercio@0: button:SetHeight(22) tercio@0: button:SetWidth(label:GetStringWidth() + 24) tercio@0: button:SetText(ACCEPT) tercio@0: button:SetScript("OnClick", OnClick) tercio@0: button:Disable() tercio@0: tercio@0: local text = button:GetFontString() tercio@0: text:ClearAllPoints() tercio@0: text:SetPoint("TOPLEFT", button, "TOPLEFT", 5, -5) tercio@0: text:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -5, 1) tercio@0: text:SetJustifyV("MIDDLE") tercio@0: tercio@0: local scrollBG = CreateFrame("Frame", nil, frame) tercio@0: scrollBG:SetBackdrop(backdrop) tercio@0: scrollBG:SetBackdropColor(0, 0, 0) tercio@0: scrollBG:SetBackdropBorderColor(0.4, 0.4, 0.4) tercio@0: tercio@0: local scrollFrame = CreateFrame("ScrollFrame", ("%s%dScrollFrame"):format(Type, widgetNum), frame, "UIPanelScrollFrameTemplate") tercio@0: tercio@0: local scrollBar = _G[scrollFrame:GetName() .. "ScrollBar"] tercio@0: scrollBar:ClearAllPoints() tercio@0: scrollBar:SetPoint("TOP", label, "BOTTOM", 0, -19) tercio@0: scrollBar:SetPoint("BOTTOM", button, "TOP", 0, 18) tercio@0: scrollBar:SetPoint("RIGHT", frame, "RIGHT") tercio@0: tercio@0: scrollBG:SetPoint("TOPRIGHT", scrollBar, "TOPLEFT", 0, 19) tercio@0: scrollBG:SetPoint("BOTTOMLEFT", button, "TOPLEFT") tercio@0: tercio@0: scrollFrame:SetPoint("TOPLEFT", scrollBG, "TOPLEFT", 5, -6) tercio@0: scrollFrame:SetPoint("BOTTOMRIGHT", scrollBG, "BOTTOMRIGHT", -4, 4) tercio@0: scrollFrame:SetScript("OnEnter", OnEnter) tercio@0: scrollFrame:SetScript("OnLeave", OnLeave) tercio@0: scrollFrame:SetScript("OnMouseUp", OnMouseUp) tercio@0: scrollFrame:SetScript("OnReceiveDrag", OnReceiveDrag) tercio@0: scrollFrame:SetScript("OnSizeChanged", OnSizeChanged) tercio@0: scrollFrame:HookScript("OnVerticalScroll", OnVerticalScroll) tercio@0: tercio@0: local editBox = CreateFrame("EditBox", ("%s%dEdit"):format(Type, widgetNum), scrollFrame) tercio@0: editBox:SetAllPoints() tercio@0: editBox:SetFontObject(ChatFontNormal) tercio@0: editBox:SetMultiLine(true) tercio@0: editBox:EnableMouse(true) tercio@0: editBox:SetAutoFocus(false) tercio@0: editBox:SetCountInvisibleLetters(false) tercio@0: editBox:SetScript("OnCursorChanged", OnCursorChanged) tercio@0: editBox:SetScript("OnEditFocusLost", OnEditFocusLost) tercio@0: editBox:SetScript("OnEnter", OnEnter) tercio@0: editBox:SetScript("OnEscapePressed", editBox.ClearFocus) tercio@0: editBox:SetScript("OnLeave", OnLeave) tercio@0: editBox:SetScript("OnMouseDown", OnReceiveDrag) tercio@0: editBox:SetScript("OnReceiveDrag", OnReceiveDrag) tercio@0: editBox:SetScript("OnTextChanged", OnTextChanged) tercio@0: editBox:SetScript("OnTextSet", OnTextSet) tercio@0: editBox:SetScript("OnEditFocusGained", OnEditFocusGained) tercio@0: tercio@0: tercio@0: scrollFrame:SetScrollChild(editBox) tercio@0: tercio@0: local widget = { tercio@0: button = button, tercio@0: editBox = editBox, tercio@0: frame = frame, tercio@0: label = label, tercio@0: labelHeight = 10, tercio@0: numlines = 4, tercio@0: scrollBar = scrollBar, tercio@0: scrollBG = scrollBG, tercio@0: scrollFrame = scrollFrame, tercio@0: type = Type tercio@0: } tercio@0: for method, func in pairs(methods) do tercio@0: widget[method] = func tercio@0: end tercio@0: button.obj, editBox.obj, scrollFrame.obj = widget, widget, widget tercio@0: tercio@0: return AceGUI:RegisterAsWidget(widget) tercio@0: end tercio@0: tercio@0: AceGUI:RegisterWidgetType(Type, Constructor, Version)