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