-- ------------------------------------------------------------------------------ -- -- TradeSkillMaster -- -- https://tradeskillmaster.com -- -- All Rights Reserved - Detailed license information included with addon. -- -- ------------------------------------------------------------------------------ -- --- LargeApplicationFrame UI Element Class. -- This is the base frame of the large TSM windows which have tabs along the top (i.e. MainUI, AuctionUI, CraftingUI). -- It is a subclass of the @{ApplicationFrame} class. -- @classmod LargeApplicationFrame local _, TSM = ... local LargeApplicationFrame = TSM.Include("LibTSMClass").DefineClass("LargeApplicationFrame", TSM.UI.ApplicationFrame) local UIElements = TSM.Include("UI.UIElements") UIElements.Register(LargeApplicationFrame) TSM.UI.LargeApplicationFrame = LargeApplicationFrame local private = {} local NAV_BAR_SPACING = 16 local NAV_BAR_HEIGHT = 24 local NAV_BAR_RELATIVE_LEVEL = 21 local NAV_BAR_TOP_OFFSET = -8 -- ============================================================================ -- Meta Class Methods -- ============================================================================ function LargeApplicationFrame.__init(self) self.__super:__init() self._buttons = {} self._selectedButton = nil self._buttonIndex = {} end function LargeApplicationFrame.Acquire(self) self:SetContentFrame(UIElements.New("Frame", "content") :SetLayout("VERTICAL") :SetBackgroundColor("FRAME_BG") ) self.__super:Acquire() end function LargeApplicationFrame.Release(self) wipe(self._buttons) wipe(self._buttonIndex) self._selectedButton = nil self.__super:Release() end -- ============================================================================ -- Public Class Methods -- ============================================================================ --- Sets the context table. -- This table can be used to preserve position, size, and current page information across lifecycles of the frame and -- even WoW sessions if it's within the settings DB. -- @see ApplicationFrame.SetContextTable -- @tparam LargeApplicationFrame self The large application frame object -- @tparam table tbl The context table -- @tparam table defaultTbl Default values (see @{ApplicationFrame.SetContextTable} for fields) -- @treturn LargeApplicationFrame The large application frame object function LargeApplicationFrame.SetContextTable(self, tbl, defaultTbl) assert(defaultTbl.page) tbl.page = tbl.page or defaultTbl.page self.__super:SetContextTable(tbl, defaultTbl) return self end --- Adds a top-level navigation button. -- @tparam LargeApplicationFrame self The large application frame object -- @tparam string text The button text -- @tparam function drawCallback The function called when the button is clicked to get the corresponding content -- @treturn LargeApplicationFrame The large application frame object function LargeApplicationFrame.AddNavButton(self, text, drawCallback) local button = UIElements.New("AlphaAnimatedFrame", "NavBar_"..text) :SetRange(1, 0.3) :SetDuration(1) :SetLayout("HORIZONTAL") :SetRelativeLevel(NAV_BAR_RELATIVE_LEVEL) :SetContext(drawCallback) :AddChild(UIElements.New("Button", "button") :SetText(text) :SetScript("OnEnter", private.OnNavBarButtonEnter) :SetScript("OnLeave", private.OnNavBarButtonLeave) :SetScript("OnClick", private.OnNavBarButtonClicked) ) self:AddChildNoLayout(button) tinsert(self._buttons, button) self._buttonIndex[text] = #self._buttons if self._buttonIndex[text] == self._contextTable.page then self:SetSelectedNavButton(text) end return self end --- Set the selected nav button. -- @tparam LargeApplicationFrame self The large application frame object -- @tparam string buttonText The button text -- @tparam boolean redraw Whether or not to redraw the frame function LargeApplicationFrame.SetSelectedNavButton(self, buttonText, redraw) if buttonText == self._selectedButton then return end local index = self._buttonIndex[buttonText] self._contextTable.page = index self._selectedButton = buttonText self._contentFrame:ReleaseAllChildren() self._contentFrame:AddChild(self._buttons[index]:GetContext()(self)) if redraw then self:Draw() end return self end --- Get the selected nav button. -- @tparam LargeApplicationFrame self The large application frame object -- @treturn string The text of the selected button function LargeApplicationFrame.GetSelectedNavButton(self) return self._selectedButton end --- Sets which nav button is pulsing. -- @tparam LargeApplicationFrame self The large application frame object -- @tparam ?string buttonText The button text or nil if no nav button should be pulsing function LargeApplicationFrame.SetPulsingNavButton(self, buttonText) local index = buttonText and self._buttonIndex[buttonText] for i, button in ipairs(self._buttons) do if not index or i ~= index then button:SetPlaying(false) elseif not button:IsPlaying() then button:SetPlaying(true) end end end function LargeApplicationFrame.Draw(self) self.__super:Draw() for i, buttonFrame in ipairs(self._buttons) do local button = buttonFrame:GetElement("button") button:SetFont("BODY_BODY1_BOLD") button:SetTextColor(i == self._contextTable.page and "INDICATOR" or "TEXT_ALT") button:Draw() buttonFrame:SetSize(button:GetStringWidth(), NAV_BAR_HEIGHT) end local offsetX = 104 for _, buttonFrame in ipairs(self._buttons) do local buttonWidth = buttonFrame:GetElement("button"):GetStringWidth() buttonFrame:SetSize(buttonWidth, NAV_BAR_HEIGHT) buttonFrame:WipeAnchors() buttonFrame:AddAnchor("TOPLEFT", offsetX, NAV_BAR_TOP_OFFSET) offsetX = offsetX + buttonWidth + NAV_BAR_SPACING -- draw the buttons again now that we know their dimensions buttonFrame:Draw() end end -- ============================================================================ -- Private Class Methods -- ============================================================================ function LargeApplicationFrame._SetResizing(self, resizing) for _, button in ipairs(self._buttons) do if resizing then button:Hide() else button:Show() end end self.__super:_SetResizing(resizing) end -- ============================================================================ -- Local Script Handlers -- ============================================================================ function private.OnNavBarButtonEnter(button) if button:GetBaseElement():GetSelectedNavButton() == button:GetText() then return end button:SetTextColor("TEXT") :Draw() end function private.OnNavBarButtonLeave(button) if button:GetBaseElement():GetSelectedNavButton() == button:GetText() then return end button:SetTextColor("TEXT_ALT") :Draw() end function private.OnNavBarButtonClicked(button) local self = button:GetParentElement():GetParentElement() self:SetSelectedNavButton(button:GetText(), true) end