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