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