-- ------------------------------------------------------------------------------ -- -- TradeSkillMaster -- -- https://tradeskillmaster.com -- -- All Rights Reserved - Detailed license information included with addon. -- -- ------------------------------------------------------------------------------ -- local _, TSM = ... local VendoringUI = TSM.UI:NewPackage("VendoringUI") local L = TSM.Include("Locale").GetTable() local Delay = TSM.Include("Util.Delay") local FSM = TSM.Include("Util.FSM") local Event = TSM.Include("Util.Event") local ScriptWrapper = TSM.Include("Util.ScriptWrapper") local Settings = TSM.Include("Service.Settings") local UIElements = TSM.Include("UI.UIElements") local private = { settings = nil, topLevelPages = {}, fsm = nil, defaultUISwitchBtn = nil, isVisible = false, } local MIN_FRAME_SIZE = { width = 560, height = 500 } -- ============================================================================ -- Module Functions -- ============================================================================ function VendoringUI.OnInitialize() private.settings = Settings.NewView() :AddKey("global", "vendoringUIContext", "showDefault") :AddKey("global", "vendoringUIContext", "frame") private.FSMCreate() end function VendoringUI.OnDisable() -- hide the frame private.fsm:ProcessEvent("EV_FRAME_HIDE") end function VendoringUI.RegisterTopLevelPage(name, callback) tinsert(private.topLevelPages, { name = name, callback = callback }) end function VendoringUI.IsVisible() return private.isVisible end -- ============================================================================ -- Main Frame -- ============================================================================ function private.CreateMainFrame() TSM.UI.AnalyticsRecordPathChange("vendoring") local frame = UIElements.New("LargeApplicationFrame", "base") :SetParent(UIParent) :SetSettingsContext(private.settings, "frame") :SetMinResize(MIN_FRAME_SIZE.width, MIN_FRAME_SIZE.height) :SetStrata("HIGH") :AddSwitchButton(private.SwitchBtnOnClick) :SetScript("OnHide", private.BaseFrameOnHide) for _, info in ipairs(private.topLevelPages) do frame:AddNavButton(info.name, info.callback) end return frame end -- ============================================================================ -- Local Script Handlers -- ============================================================================ function private.BaseFrameOnHide() TSM.UI.AnalyticsRecordClose("vendoring") private.fsm:ProcessEvent("EV_FRAME_HIDE") end function private.SwitchBtnOnClick(button) private.settings.showDefault = button ~= private.defaultUISwitchBtn private.fsm:ProcessEvent("EV_SWITCH_BTN_CLICKED") end function private.SwitchButtonOnEnter(button) button:SetTextColor("TEXT") :Draw() end function private.SwitchButtonOnLeave(button) button:SetTextColor("TEXT_ALT") :Draw() end -- ============================================================================ -- FSM -- ============================================================================ function private.FSMCreate() local function MerchantShowDelayed() private.fsm:ProcessEvent("EV_MERCHANT_SHOW") end local function CurrencyUpdate() private.fsm:ProcessEvent("EV_CURRENCY_UPDATE") end Event.Register("MERCHANT_SHOW", function() Delay.AfterFrame("MERCHANT_SHOW_DELAYED", 0, MerchantShowDelayed) end) Event.Register("MERCHANT_CLOSED", function() private.fsm:ProcessEvent("EV_MERCHANT_CLOSED") end) MerchantFrame:UnregisterEvent("MERCHANT_SHOW") local fsmContext = { frame = nil, defaultPoint = nil, } local function DefaultFrameOnHide() private.fsm:ProcessEvent("EV_FRAME_HIDE") end private.fsm = FSM.New("MERCHANT_UI") :AddState(FSM.NewState("ST_CLOSED") :AddTransition("ST_DEFAULT_OPEN") :AddTransition("ST_FRAME_OPEN") :AddEvent("EV_FRAME_TOGGLE", function(context) assert(not private.settings.showDefault) return "ST_FRAME_OPEN" end) :AddEvent("EV_MERCHANT_SHOW", function(context) if private.settings.showDefault then return "ST_DEFAULT_OPEN" else return "ST_FRAME_OPEN" end end) ) :AddState(FSM.NewState("ST_DEFAULT_OPEN") :SetOnEnter(function(context, isIgnored) MerchantFrame_OnEvent(MerchantFrame, "MERCHANT_SHOW") if not private.defaultUISwitchBtn then private.defaultUISwitchBtn = UIElements.New("ActionButton", "switchBtn") :SetSize(60, TSM.IsWowClassic() and 16 or 15) :AddAnchor("TOPRIGHT", TSM.IsWowClassic() and -26 or -27, TSM.IsWowClassic() and -3 or -4) :SetFont("BODY_BODY3_MEDIUM") :DisableClickCooldown() :SetText(L["TSM4"]) :SetScript("OnClick", private.SwitchBtnOnClick) :SetScript("OnEnter", private.SwitchButtonOnEnter) :SetScript("OnLeave", private.SwitchButtonOnLeave) private.defaultUISwitchBtn:_GetBaseFrame():SetParent(MerchantFrame) end if isIgnored then private.defaultUISwitchBtn:Hide() else private.defaultUISwitchBtn:Show() private.defaultUISwitchBtn:Draw() end ScriptWrapper.Set(MerchantFrame, "OnHide", DefaultFrameOnHide) end) :SetOnExit(function(context) ScriptWrapper.Clear(MerchantFrame, "OnHide") HideUIPanel(MerchantFrame) end) :AddTransition("ST_CLOSED") :AddTransition("ST_FRAME_OPEN") :AddEvent("EV_FRAME_HIDE", function(context) CloseMerchant() return "ST_CLOSED" end) :AddEvent("EV_MERCHANT_SHOW", MerchantFrame_Update) :AddEventTransition("EV_MERCHANT_CLOSED", "ST_CLOSED") :AddEvent("EV_SWITCH_BTN_CLICKED", function() return "ST_FRAME_OPEN" end) ) :AddState(FSM.NewState("ST_FRAME_OPEN") :SetOnEnter(function(context) assert(not context.frame) MerchantFrame_OnEvent(MerchantFrame, "MERCHANT_SHOW") if not context.defaultPoint then context.defaultPoint = { MerchantFrame:GetPoint(1) } end MerchantFrame:SetClampedToScreen(false) MerchantFrame:ClearAllPoints() MerchantFrame:SetPoint("TOPLEFT", UIParent, "TOPLEFT", 100000, 100000) OpenAllBags() context.frame = private.CreateMainFrame() context.frame:Show() context.frame:GetElement("titleFrame.switchBtn"):Show() context.frame:Draw() if not TSM.IsWowClassic() then Event.Register("CURRENCY_DISPLAY_UPDATE", CurrencyUpdate) end private.isVisible = true end) :SetOnExit(function(context) CloseAllBags() MerchantFrame:ClearAllPoints() local point, region, relativePoint, x, y = unpack(context.defaultPoint) if point and region and relativePoint and x and y then MerchantFrame:SetPoint(point, region, relativePoint, x, y) else MerchantFrame:SetPoint("TOPLEFT", UIParent, "TOPLEFT", 16, -116) end if not TSM.IsWowClassic() then Event.Unregister("CURRENCY_DISPLAY_UPDATE", CurrencyUpdate) end private.isVisible = false context.frame:Hide() context.frame:Release() context.frame = nil end) :AddTransition("ST_CLOSED") :AddTransition("ST_DEFAULT_OPEN") :AddEvent("EV_CURRENCY_UPDATE", function(context) TSM.UI.VendoringUI.Buy.UpdateCurrency(context.frame) end) :AddEvent("EV_FRAME_HIDE", function(context) CloseMerchant() return "ST_CLOSED" end) :AddEvent("EV_MERCHANT_CLOSED", function(context) return "ST_CLOSED" end) :AddEvent("EV_SWITCH_BTN_CLICKED", function() return "ST_DEFAULT_OPEN" end) ) :Init("ST_CLOSED", fsmContext) end