Zerotorescue@62: local addon = select(2, ...); Zerotorescue@62: local Widgets = addon:NewModule("Widgets"); Zerotorescue@62: Zerotorescue@62: local AceGUI = LibStub("AceGUI-3.0"); Zerotorescue@62: Zerotorescue@62: function Widgets:ItemLinkButton() Zerotorescue@62: --[[ Zerotorescue@62: [ ItemLinkButton ] Zerotorescue@62: This custom widget has to show an icon with the item link next to it. Zerotorescue@62: Upon hover it must show the item tooltip. Zerotorescue@62: Upon click it must execute the function provided through user data. Zerotorescue@62: Zerotorescue@62: UserData: itemId, onClickEvent Zerotorescue@62: Zerotorescue@62: OnEnter: tooltip show Zerotorescue@62: OnLeave: tooltip hide Zerotorescue@62: OnClick: UserData.onClickEvent Zerotorescue@62: ]] Zerotorescue@62: Zerotorescue@62: local widgetType = "ItemLinkButton"; Zerotorescue@62: local widgetVersion = 1; Zerotorescue@62: Zerotorescue@62: local function Constructor() Zerotorescue@62: local widget = AceGUI:Create("InteractiveLabel"); Zerotorescue@62: widget.type = widgetType; Zerotorescue@62: Zerotorescue@62: -- We overwrite the OnAcquire as we want to set our callbacks even Zerotorescue@62: -- when the widget is re-used from the widget pool Zerotorescue@62: widget.originalOnAcquire = widget.OnAcquire; Zerotorescue@62: widget.OnAcquire = function(self, ...) Zerotorescue@62: Zerotorescue@62: Zerotorescue@62: -- We overwrite the setcallback because we don't want anything else Zerotorescue@62: -- to overwrite our OnEnter, OnLeave and OnClick events Zerotorescue@62: -- which would be done by the AceConfigDialog after a widget gets re-used Zerotorescue@62: if not self.originalSetCallBack then Zerotorescue@62: self.originalSetCallBack = self.SetCallback; Zerotorescue@62: self.SetCallback = function(this, event, func, ...) Zerotorescue@62: if event == "OnEnter" or event == "OnLeave" or event == "OnClick" then Zerotorescue@62: -- Don't allow overwriting of these events Zerotorescue@62: return; Zerotorescue@62: elseif event == "CustomOnEnter" then Zerotorescue@62: return this.originalSetCallBack(this, "OnEnter", func, ...); Zerotorescue@62: elseif event == "CustomOnLeave" then Zerotorescue@62: return this.originalSetCallBack(this, "OnLeave", func, ...); Zerotorescue@62: elseif event == "CustomOnClick" then Zerotorescue@62: return this.originalSetCallBack(this, "OnClick", func, ...); Zerotorescue@62: else Zerotorescue@62: return this.originalSetCallBack(this, event, func, ...); Zerotorescue@62: end Zerotorescue@62: end; Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: Zerotorescue@62: Zerotorescue@62: -- Set our own events, since we disabled the normal event-names, we'll call them our custom versions Zerotorescue@62: self:SetCallback("CustomOnEnter", function(this) Zerotorescue@62: local itemId = this:GetUserData("itemId"); Zerotorescue@62: Zerotorescue@62: if itemId then Zerotorescue@62: GameTooltip:SetOwner(this.frame, "ANCHOR_TOPRIGHT"); Zerotorescue@62: GameTooltip:SetHyperlink(("item:%d"):format(itemId)); Zerotorescue@62: GameTooltip:Show(); Zerotorescue@62: end Zerotorescue@62: end); Zerotorescue@62: self:SetCallback("CustomOnLeave", function(this) Zerotorescue@62: GameTooltip:Hide(); Zerotorescue@62: end); Zerotorescue@62: self:SetCallback("CustomOnClick", function(this, ...) Zerotorescue@62: -- Below is used in child widgets to prepare for onclick Zerotorescue@62: if this.OnClick then Zerotorescue@62: this.OnClick(this, ...); Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: local func = this:GetUserData("exec"); Zerotorescue@62: local itemId = this:GetUserData("itemId"); Zerotorescue@62: Zerotorescue@62: if func then Zerotorescue@62: -- If this is a config option we will need the group id Zerotorescue@62: local path = this:GetUserData("path"); Zerotorescue@62: local groupId = (path and path[2]) or nil; Zerotorescue@62: Zerotorescue@62: func(groupId, itemId, ...); Zerotorescue@62: end Zerotorescue@62: end); Zerotorescue@62: Zerotorescue@62: Zerotorescue@62: Zerotorescue@62: -- Then also do whatever it wanted to do Zerotorescue@62: self.originalOnAcquire(self, ...); Zerotorescue@62: end; Zerotorescue@62: Zerotorescue@62: -- Remember the original SetText as this might get overwritten by the config-widget Zerotorescue@62: widget.originalSetText = widget.SetText; Zerotorescue@62: Zerotorescue@62: widget.SetItemId = function(self, itemId) Zerotorescue@62: self:SetUserData("itemId", itemId); Zerotorescue@62: Zerotorescue@62: -- Put the icon in front of it Zerotorescue@62: self:SetImage(GetItemIcon(itemId)); Zerotorescue@62: -- Standardize the size Zerotorescue@62: self:SetImageSize(16, 16); Zerotorescue@62: Zerotorescue@62: -- Make readable font Zerotorescue@62: self:SetFontObject(GameFontHighlight); Zerotorescue@62: Zerotorescue@62: -- We don't want to set the itemId as text, but rather the item link, so get that. Zerotorescue@62: local itemLink = select(2, GetItemInfo(itemId)) or ("Unknown (#%d)"):format(itemId); Zerotorescue@62: Zerotorescue@62: self:originalSetText(itemLink); Zerotorescue@62: end; Zerotorescue@62: Zerotorescue@62: return widget; Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion); Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: function Widgets:ConfigItemLinkButton() Zerotorescue@62: -- Define out custom item link button widget Zerotorescue@62: -- This will be called as if it's an input element, we overwrite some of the related functions which are called for default input fields Zerotorescue@62: Zerotorescue@62: local widgetType = "ConfigItemLinkButton"; Zerotorescue@62: local widgetVersion = 1; Zerotorescue@62: Zerotorescue@62: -- Empty function for disabling functions Zerotorescue@62: local function Dummy() end Zerotorescue@62: Zerotorescue@62: -- Makes an instance of our ItemLinkButton widget Zerotorescue@62: local function GetItemLinkButton() Zerotorescue@62: local widget = AceGUI:Create("ItemLinkButton"); Zerotorescue@62: widget.type = widgetType; Zerotorescue@62: Zerotorescue@62: -- We can only provide custom widgets for input, select and multiselect fields Zerotorescue@62: -- Input being the simplest, we use that - however, it provides two parameters: label and text. We only need one, disable the other. Zerotorescue@62: widget.SetLabel = Dummy; Zerotorescue@62: Zerotorescue@62: -- SetText is called when this button is being created and contains the itemId Zerotorescue@62: -- Forward that itemId to the ItemLinkButton Zerotorescue@62: widget.SetText = function(self, value, ...) Zerotorescue@62: if value and tonumber(value) then Zerotorescue@62: self:SetItemId(tonumber(value)); Zerotorescue@62: end Zerotorescue@62: end; Zerotorescue@62: Zerotorescue@62: widget.OnClick = function(self, ...) Zerotorescue@62: local option = self:GetUserData("option"); Zerotorescue@62: Zerotorescue@62: if option and option.set then Zerotorescue@62: self:SetUserData("exec", option.set); Zerotorescue@62: end Zerotorescue@62: end; Zerotorescue@62: Zerotorescue@62: return widget; Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: AceGUI:RegisterWidgetType(widgetType, GetItemLinkButton, widgetVersion); Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: function Widgets:InlineGroupWithButton() Zerotorescue@62: -- Register InlineGroupWithButton-widget Zerotorescue@62: -- This widget adds a button next to the header of an inline group Zerotorescue@62: -- SetPoint doesn't seem usable within AceGUI. Zerotorescue@62: Zerotorescue@62: local widgetType = "InlineGroupWithButton"; Zerotorescue@62: local widgetVersion = 1; Zerotorescue@62: Zerotorescue@62: local function Constructor() Zerotorescue@62: local widget = AceGUI:Create("InlineGroup"); Zerotorescue@62: widget.type = widgetType; Zerotorescue@62: Zerotorescue@62: widget.MakeButton = function(self, buttonSettings) Zerotorescue@62: if type(buttonSettings) == "table" then Zerotorescue@62: if not self.btnQueue then Zerotorescue@62: -- Because widgets are re-used, we don't want to recreate this button Zerotorescue@62: self.btnQueue = CreateFrame("Button", nil, self.frame, "UIPanelButtonTemplate"); Zerotorescue@62: self.btnQueue:SetHeight(22); Zerotorescue@62: self.btnQueue:SetWidth(120); Zerotorescue@62: end Zerotorescue@62: self.btnQueue:SetText(buttonSettings.name); Zerotorescue@62: self.btnQueue:SetPoint("TOPRIGHT", self.frame, "TOPRIGHT", -10, 5); Zerotorescue@62: Zerotorescue@62: -- Triggers Zerotorescue@62: self.btnQueue:SetScript("OnClick", buttonSettings.exec); Zerotorescue@62: Zerotorescue@62: -- Tooltip Zerotorescue@62: self.btnQueue.tooltipTitle = buttonSettings.name; Zerotorescue@62: self.btnQueue.tooltip = buttonSettings.desc or ""; Zerotorescue@62: self.btnQueue:SetScript("OnEnter", ShowTooltip); Zerotorescue@62: self.btnQueue:SetScript("OnLeave", HideTooltip); Zerotorescue@62: else Zerotorescue@62: error("settings must be a table - usage: MakeButton(table);"); Zerotorescue@62: end Zerotorescue@62: end; Zerotorescue@62: Zerotorescue@62: return widget; Zerotorescue@62: end Zerotorescue@62: Zerotorescue@62: AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion); Zerotorescue@62: end