Skip to content

Commit

Permalink
Implement an API to pick different widget styles
Browse files Browse the repository at this point in the history
The public API is extended to take a widget style parameter anywhere a
widget type is being supplied. If its not specified, classic style is
assumed.

The style parameter is a string for future expandability,
currently defined are AceGUI.STYLE_CLASSIC ("classic"), and
AceGUI.STYLE_MODERN ("modern")

The Create function will also additionally accept 'true' (boolean) as a
parameter, which indicates automatic style selection, which switches
between classic and modern depending on which client this is run on.

API Changes:
AceGUI:Create(type, style)
AceGUI:RegisterWidgetType(Name, Constructor, Version, Style)
AceGUI:GetWidgetVersion(type, style)
  • Loading branch information
Nevcairiel committed Sep 26, 2022
1 parent c07eed7 commit 0c43b17
Showing 1 changed file with 70 additions and 27 deletions.
97 changes: 70 additions & 27 deletions AceGUI-3.0/AceGUI-3.0.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
-- @class file
-- @name AceGUI-3.0
-- @release $Id$
local ACEGUI_MAJOR, ACEGUI_MINOR = "AceGUI-3.0", 41
local ACEGUI_MAJOR, ACEGUI_MINOR = "AceGUI-3.0", 50
local AceGUI, oldminor = LibStub:NewLibrary(ACEGUI_MAJOR, ACEGUI_MINOR)

if not AceGUI then return end -- No upgrade needed
Expand All @@ -40,13 +40,25 @@ local math_max, math_min, math_ceil = math.max, math.min, math.ceil
-- WoW APIs
local UIParent = UIParent

AceGUI.STYLE_CLASSIC = "classic"
AceGUI.STYLE_MODERN = "modern"

AceGUI.WidgetRegistry = AceGUI.WidgetRegistry or {}
AceGUI.LayoutRegistry = AceGUI.LayoutRegistry or {}
AceGUI.WidgetBase = AceGUI.WidgetBase or {}
AceGUI.WidgetContainerBase = AceGUI.WidgetContainerBase or {}
AceGUI.WidgetVersions = AceGUI.WidgetVersions or {}
AceGUI.tooltip = AceGUI.tooltip or CreateFrame("GameTooltip", "AceGUITooltip", UIParent, "GameTooltipTemplate")

-- migrate widget registry to per-style layout
if oldminor and oldminor < 50 then
local Registry = AceGUI.WidgetRegistry
local Versions = AceGUI.WidgetVersions

AceGUI.WidgetRegistry = { [AceGUI.STYLE_CLASSIC] = Registry }
AceGUI.WidgetVersions = { [AceGUI.STYLE_CLASSIC] = Versions }
end

-- local upvalues
local WidgetRegistry = AceGUI.WidgetRegistry
local LayoutRegistry = AceGUI.LayoutRegistry
Expand Down Expand Up @@ -88,38 +100,42 @@ do
AceGUI.objPools = AceGUI.objPools or {}
local objPools = AceGUI.objPools
--Returns a new instance, if none are available either returns a new table or calls the given contructor
function newWidget(widgetType)
if not WidgetRegistry[widgetType] then
function newWidget(widgetType, style)
if not WidgetRegistry[style] or not WidgetRegistry[style][widgetType] then
error("Attempt to instantiate unknown widget type", 2)
end

if not objPools[widgetType] then
objPools[widgetType] = {}
local poolKey = widgetType..style
if not objPools[poolKey] then
objPools[poolKey] = {}
end

local newObj = next(objPools[widgetType])
local newObj = next(objPools[poolKey])
if not newObj then
newObj = WidgetRegistry[widgetType]()
newObj.AceGUIWidgetVersion = WidgetVersions[widgetType]
newObj = WidgetRegistry[style][widgetType]()
newObj.AceGUIWidgetVersion = WidgetVersions[style][widgetType]
-- save the style for future recycling
newObj.AceGUIWidgetStyle = style
else
objPools[widgetType][newObj] = nil
objPools[poolKey][newObj] = nil
-- if the widget is older then the latest, don't even try to reuse it
-- just forget about it, and grab a new one.
if not newObj.AceGUIWidgetVersion or newObj.AceGUIWidgetVersion < WidgetVersions[widgetType] then
return newWidget(widgetType)
if not newObj.AceGUIWidgetVersion or newObj.AceGUIWidgetVersion < WidgetVersions[style][widgetType] then
return newWidget(widgetType, style)
end
end
return newObj
end
-- Releases an instance to the Pool
function delWidget(obj,widgetType)
if not objPools[widgetType] then
objPools[widgetType] = {}
function delWidget(obj,widgetType,style)
local poolKey = widgetType..style
if not objPools[poolKey] then
objPools[poolKey] = {}
end
if objPools[widgetType][obj] then
if objPools[poolKey][obj] then
error("Attempt to Release Widget that is already released", 2)
end
objPools[widgetType][obj] = true
objPools[poolKey][obj] = true
end
end

Expand All @@ -134,10 +150,25 @@ end
-- This function will instantiate a new widget (or use one from the widget pool), and call the
-- OnAcquire function on it, before returning.
-- @param type The type of the widget.
-- @param style The widget style to use. (true for auto-selection, string for a specific style; "classic", "modern")
-- @return The newly created widget.
function AceGUI:Create(widgetType)
if WidgetRegistry[widgetType] then
local widget = newWidget(widgetType)
function AceGUI:Create(widgetType, style)
local widgetStyle

-- style auto-selection
if style == true then
-- TODO: support modern style once implemented
widgetStyle = AceGUI.STYLE_CLASSIC
elseif type(style) == "string" then
-- string-type styles specify a style directly
widgetStyle = style:lower()
else
-- fallback to classic style (default)
widgetStyle = AceGUI.STYLE_CLASSIC
end

if WidgetRegistry[widgetStyle] and WidgetRegistry[widgetStyle][widgetType] then
local widget = newWidget(widgetType, widgetStyle)

if rawget(widget, "Acquire") then
widget.OnAcquire = widget.Acquire
Expand Down Expand Up @@ -203,7 +234,7 @@ function AceGUI:Release(widget)
widget.content.height = nil
end
widget.isQueuedForRelease = nil
delWidget(widget, widget.type)
delWidget(widget, widget.type, widget.AceGUIWidgetStyle or AceGUI.STYLE_CLASSIC)
end

--- Check if a widget is currently in the process of being released
Expand Down Expand Up @@ -546,15 +577,25 @@ end
-- @param Name The name of the widget
-- @param Constructor The widget constructor function
-- @param Version The version of the widget
function AceGUI:RegisterWidgetType(Name, Constructor, Version)
function AceGUI:RegisterWidgetType(Name, Constructor, Version, Style)
assert(type(Constructor) == "function")
assert(type(Version) == "number")
assert(Style == nil or type(Style) == "string")

local oldVersion = WidgetVersions[Name]
local widgetStyle = Style and Style:lower() or AceGUI.STYLE_CLASSIC
if not WidgetRegistry[widgetStyle] then
WidgetRegistry[widgetStyle] = {}
end

if not WidgetVersions[widgetStyle] then
WidgetVersions[widgetStyle] = {}
end

local oldVersion = WidgetVersions[widgetStyle][Name]
if oldVersion and oldVersion >= Version then return end

WidgetVersions[Name] = Version
WidgetRegistry[Name] = Constructor
WidgetVersions[widgetStyle][Name] = Version
WidgetRegistry[widgetStyle][Name] = Constructor
end

--- Registers a Layout Function
Expand Down Expand Up @@ -599,9 +640,11 @@ function AceGUI:GetWidgetCount(widgetType)
end

--- Return the version of the currently registered widget type.
-- @param widgetType The widget type
function AceGUI:GetWidgetVersion(widgetType)
return WidgetVersions[widgetType]
-- @param type The widget type
-- @param style The widget style
function AceGUI:GetWidgetVersion(widgetType,style)
local widgetStyle = style or AceGUI.STYLE_CLASSIC
return WidgetVersions[widgetStyle] and WidgetVersions[widgetStyle][widgetType] or nil
end

-------------
Expand Down

0 comments on commit 0c43b17

Please sign in to comment.