/trunk/Who Framed Watcher Wabbit/libs/AceGUI-3.0
DropdownGroup Container |
Container controlled by a dropdown on the top. |
-------------------------------------------------------------------------------]] |
local Type, Version = "DropdownGroup", 21 |
local Type, Version = "DropdownGroup", 22 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
dropdown.frame:Show() |
dropdown:SetLabel("") |
local border = CreateFrame("Frame", nil, frame) |
local border = CreateFrame("Frame", nil, frame, BackdropTemplateMixin and "BackdropTemplate" or nil) |
border:SetPoint("TOPLEFT", 0, -26) |
border:SetPoint("BOTTOMRIGHT", 0, 3) |
border:SetBackdrop(PaneBackdrop) |
widget[method] = func |
end |
dropdown.parentgroup = widget |
return AceGUI:RegisterAsContainer(widget) |
end |
ScrollFrame Container |
Plain container that scrolls its content and doesn't grow in height. |
-------------------------------------------------------------------------------]] |
local Type, Version = "ScrollFrame", 24 |
local Type, Version = "ScrollFrame", 26 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
-- Lua APIs |
local pairs, assert, type = pairs, assert, type |
local min, max, floor, abs = math.min, math.max, math.floor, math.abs |
local min, max, floor = math.min, math.max, math.floor |
-- WoW APIs |
local CreateFrame, UIParent = CreateFrame, UIParent |
Methods |
-------------------------------------------------------------------------------]] |
local methods = { |
["OnAcquire"] = function(self) |
["OnAcquire"] = function(self) |
self:SetScroll(0) |
self.scrollframe:SetScript("OnUpdate", FixScrollOnUpdate) |
end, |
self.scrollframe:SetPoint("BOTTOMRIGHT") |
self.scrollbar:Hide() |
self.scrollBarShown = nil |
self.content.height, self.content.width = nil, nil |
self.content.height, self.content.width, self.content.original_width = nil, nil, nil |
end, |
["SetScroll"] = function(self, value) |
["MoveScroll"] = function(self, value) |
local status = self.status or self.localstatus |
local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight() |
if self.scrollBarShown then |
local diff = height - viewheight |
local delta = 1 |
local status = self.status or self.localstatus |
local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight() |
local offset = status.offset or 0 |
local curvalue = self.scrollbar:GetValue() |
-- Give us a margin of error of 2 pixels to stop some conditions that i would blame on floating point inaccuracys |
-- No-one is going to miss 2 pixels at the bottom of the frame, anyhow! |
if viewheight < height + 2 then |
self.scrollbar:Hide() |
self.scrollbar:SetValue(0) |
self.scrollframe:SetPoint("BOTTOMRIGHT") |
if self.content.original_width then |
self.content.width = self.content.original_width |
end |
self:DoLayout() |
end |
else |
self.scrollBarShown = true |
self.scrollbar:Show() |
self.scrollframe:SetPoint("BOTTOMRIGHT", -20, 0) |
if self.content.original_width then |
self.content.width = self.content.original_width - 20 |
end |
self:DoLayout() |
end |
local value = (offset / (viewheight - height) * 1000) |
["LayoutFinished"] = function(self, width, height) |
self.content:SetHeight(height or 0 + 20) |
-- update the scrollframe |
self:FixScroll() |
-- schedule another update when everything has "settled" |
self.scrollframe:SetScript("OnUpdate", FixScrollOnUpdate) |
end, |
["OnWidthSet"] = function(self, width) |
local content = self.content |
content.width = width |
content.width = width - (self.scrollBarShown and 20 or 0) |
content.original_width = width |
end, |
["OnHeightSet"] = function(self, height) |
TreeGroup Container |
Container that uses a tree control to switch between groups. |
-------------------------------------------------------------------------------]] |
local Type, Version = "TreeGroup", 41 |
local Type, Version = "TreeGroup", 45 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
local WoW80 = select(4, GetBuildInfo()) >= 80000 |
-- Lua APIs |
local next, pairs, ipairs, assert, type = next, pairs, ipairs, assert, type |
local math_min, math_max, floor = math.min, math.max, floor |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: GameTooltip, FONT_COLOR_CODE_CLOSE |
-- GLOBALS: FONT_COLOR_CODE_CLOSE |
-- Recycling functions |
local new, del |
function del(t) |
for k in pairs(t) do |
t[k] = nil |
end |
end |
pool[t] = true |
end |
end |
local function UpdateButton(button, treeline, selected, canExpand, isExpanded) |
local self = button.obj |
local toggle = button.toggle |
local frame = self.frame |
local text = treeline.text or "" |
local icon = treeline.icon |
local iconCoords = treeline.iconCoords |
local value = treeline.value |
local uniquevalue = treeline.uniquevalue |
local disabled = treeline.disabled |
button.treeline = treeline |
button.value = value |
button.uniquevalue = uniquevalue |
button:UnlockHighlight() |
button.selected = false |
end |
local normalTexture = button:GetNormalTexture() |
local line = button.line |
button.level = level |
if ( level == 1 ) then |
button:SetNormalFontObject("GameFontNormal") |
button:SetHighlightFontObject("GameFontHighlightSmall") |
button.text:SetPoint("LEFT", (icon and 16 or 0) + 8 * level, 2) |
end |
if disabled then |
button:EnableMouse(false) |
button.text:SetText("|cff808080"..text..FONT_COLOR_CODE_CLOSE) |
button.text:SetText(text) |
button:EnableMouse(true) |
end |
if icon then |
button.icon:SetTexture(icon) |
button.icon:SetPoint("LEFT", 8 * level, (level == 1) and 0 or 1) |
else |
button.icon:SetTexture(nil) |
end |
if iconCoords then |
button.icon:SetTexCoord(unpack(iconCoords)) |
else |
button.icon:SetTexCoord(0, 1, 0, 1) |
end |
if canExpand then |
if not isExpanded then |
toggle:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-UP") |
toggle:SetPushedTexture("Interface\\Buttons\\UI-PlusButton-DOWN") |
toggle:SetNormalTexture(130838) -- Interface\\Buttons\\UI-PlusButton-UP |
toggle:SetPushedTexture(130836) -- Interface\\Buttons\\UI-PlusButton-DOWN |
else |
toggle:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-UP") |
toggle:SetPushedTexture("Interface\\Buttons\\UI-MinusButton-DOWN") |
toggle:SetNormalTexture(130821) -- Interface\\Buttons\\UI-MinusButton-UP |
toggle:SetPushedTexture(130820) -- Interface\\Buttons\\UI-MinusButton-DOWN |
end |
toggle:Show() |
else |
local function Button_OnDoubleClick(button) |
local self = button.obj |
local status = self.status or self.localstatus |
local status = (self.status or self.localstatus).groups |
status[button.uniquevalue] = not status[button.uniquevalue] |
self:RefreshTree() |
self:Fire("OnButtonEnter", frame.uniquevalue, frame) |
if self.enabletooltips then |
GameTooltip:SetOwner(frame, "ANCHOR_NONE") |
GameTooltip:SetPoint("LEFT",frame,"RIGHT") |
GameTooltip:SetText(frame.text:GetText() or "", 1, .82, 0, true) |
local tooltip = AceGUI.tooltip |
tooltip:SetOwner(frame, "ANCHOR_NONE") |
tooltip:ClearAllPoints() |
tooltip:SetPoint("LEFT",frame,"RIGHT") |
tooltip:SetText(frame.text:GetText() or "", 1, .82, 0, true) |
GameTooltip:Show() |
tooltip:Show() |
end |
end |
self:Fire("OnButtonLeave", frame.uniquevalue, frame) |
if self.enabletooltips then |
GameTooltip:Hide() |
AceGUI.tooltip:Hide() |
end |
end |
local function Dragger_OnMouseUp(frame) |
local treeframe = frame:GetParent() |
local self = treeframe.obj |
local frame = treeframe:GetParent() |
local treeframeParent = treeframe:GetParent() |
treeframe:StopMovingOrSizing() |
--treeframe:SetScript("OnUpdate", nil) |
treeframe:SetUserPlaced(false) |
--Without this :GetHeight will get stuck on the current height, causing the tree contents to not resize |
treeframe:SetHeight(0) |
treeframe:SetPoint("TOPLEFT", frame, "TOPLEFT",0,0) |
treeframe:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT",0,0) |
treeframe:ClearAllPoints() |
treeframe:SetPoint("TOPLEFT", treeframeParent, "TOPLEFT",0,0) |
treeframe:SetPoint("BOTTOMLEFT", treeframeParent, "BOTTOMLEFT",0,0) |
local status = self.status or self.localstatus |
status.treewidth = treeframe:GetWidth() |
treeframe.obj:Fire("OnTreeResize",treeframe:GetWidth()) |
-- recalculate the content width |
treeframe.obj:OnWidthSet(status.fullwidth) |
--sets the tree to be displayed |
["SetTree"] = function(self, tree, filter) |
self.filter = filter |
if tree then |
assert(type(tree) == "table") |
if tree then |
assert(type(tree) == "table") |
end |
self.tree = tree |
self:RefreshTree() |
["BuildLevel"] = function(self, tree, level, parent) |
local groups = (self.status or self.localstatus).groups |
local hasChildren = self.hasChildren |
for i, v in ipairs(tree) do |
if v.children then |
if not self.filter or ShouldDisplayLevel(v.children) then |
local tree = self.tree |
local treeframe = self.treeframe |
status.scrollToSelection = status.scrollToSelection or scrollToSelection -- needs to be cached in case the control hasn't been drawn yet (code bails out below) |
self:BuildLevel(tree, 1) |
local maxlines = (floor(((self.treeframe:GetHeight()or 0) - 20 ) / 18)) |
if maxlines <= 0 then return end |
-- workaround for lag spikes on WoW 8.0 |
if WoW80 and self.frame:GetParent() == UIParent and not fromOnUpdate then |
if self.frame:GetParent() == UIParent and not fromOnUpdate then |
self.frame:SetScript("OnUpdate", FirstFrameUpdate) |
return |
end |
local first, last |
scrollToSelection = status.scrollToSelection |
status.scrollToSelection = nil |
button:Show() |
buttonnum = buttonnum + 1 |
end |
end, |
["SetSelected"] = function(self, value) |
local status = self.status or self.localstatus |
if status.selected ~= value then |
local treeframe = self.treeframe |
local status = self.status or self.localstatus |
status.fullwidth = width |
local contentwidth = width - status.treewidth - 20 |
if contentwidth < 0 then |
contentwidth = 0 |
end |
content:SetWidth(contentwidth) |
content.width = contentwidth |
local maxtreewidth = math_min(400, width - 50) |
if maxtreewidth > 100 and status.treewidth > maxtreewidth then |
self:SetTreeWidth(maxtreewidth, status.treesizable) |
end |
treewidth = DEFAULT_TREE_WIDTH |
else |
resizable = false |
treewidth = DEFAULT_TREE_WIDTH |
treewidth = DEFAULT_TREE_WIDTH |
end |
end |
self.treeframe:SetWidth(treewidth) |
self.dragger:EnableMouse(resizable) |
local status = self.status or self.localstatus |
status.treewidth = treewidth |
status.treesizable = resizable |
-- recalculate the content width |
if status.fullwidth then |
self:OnWidthSet(status.fullwidth) |
local DraggerBackdrop = { |
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", |
edgeFile = nil, |
tile = true, tileSize = 16, edgeSize = 0, |
tile = true, tileSize = 16, edgeSize = 1, |
insets = { left = 3, right = 3, top = 7, bottom = 7 } |
} |
local num = AceGUI:GetNextWidgetNum(Type) |
local frame = CreateFrame("Frame", nil, UIParent) |
local treeframe = CreateFrame("Frame", nil, frame) |
local treeframe = CreateFrame("Frame", nil, frame, BackdropTemplateMixin and "BackdropTemplate" or nil) |
treeframe:SetPoint("TOPLEFT") |
treeframe:SetPoint("BOTTOMLEFT") |
treeframe:SetWidth(DEFAULT_TREE_WIDTH) |
treeframe:SetScript("OnSizeChanged", Tree_OnSizeChanged) |
treeframe:SetScript("OnMouseWheel", Tree_OnMouseWheel) |
local dragger = CreateFrame("Frame", nil, treeframe) |
local dragger = CreateFrame("Frame", nil, treeframe, BackdropTemplateMixin and "BackdropTemplate" or nil) |
dragger:SetWidth(8) |
dragger:SetPoint("TOP", treeframe, "TOPRIGHT") |
dragger:SetPoint("BOTTOM", treeframe, "BOTTOMRIGHT") |
scrollbg:SetAllPoints(scrollbar) |
scrollbg:SetColorTexture(0,0,0,0.4) |
local border = CreateFrame("Frame",nil,frame) |
local border = CreateFrame("Frame", nil, frame, BackdropTemplateMixin and "BackdropTemplate" or nil) |
border:SetPoint("TOPLEFT", treeframe, "TOPRIGHT") |
border:SetPoint("BOTTOMRIGHT") |
border:SetBackdrop(PaneBackdrop) |
self:SetWidth(self.text:GetStringWidth() + 30) |
end |
end, |
["SetAutoWidth"] = function(self, autoWidth) |
self.autoWidth = autoWidth |
if self.autoWidth then |
--[[ $Id: AceGUIWidget-DropDown-Items.lua 1167 2017-08-29 22:08:48Z funkydude $ ]]-- |
--[[ $Id: AceGUIWidget-DropDown-Items.lua 1202 2019-05-15 23:11:22Z nevcairiel $ ]]-- |
local AceGUI = LibStub("AceGUI-3.0") |
-- ItemBase is the base "class" for all dropdown items. |
-- Each item has to use ItemBase.Create(widgetType) to |
-- create an initial 'self' value. |
-- create an initial 'self' value. |
-- ItemBase will add common functions and ui event handlers. |
-- Be sure to keep basic usage when you override functions. |
self.highlight:Show() |
end |
self:Fire("OnEnter") |
if self.specialOnEnter then |
self.specialOnEnter(self) |
end |
function ItemBase.Frame_OnLeave(this) |
local self = this.obj |
self.highlight:Hide() |
self:Fire("OnLeave") |
if self.specialOnLeave then |
self.specialOnLeave(self) |
end |
-- Do not call this method directly |
function ItemBase.SetPullout(self, pullout) |
self.pullout = pullout |
self.frame:SetParent(nil) |
self.frame:SetParent(pullout.itemFrame) |
self.parent = pullout.itemFrame |
self.frame = frame |
frame.obj = self |
self.type = type |
self.useHighlight = true |
frame:SetHeight(17) |
frame:SetFrameStrata("FULLSCREEN_DIALOG") |
local text = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall") |
text:SetTextColor(1,1,1) |
text:SetJustifyH("LEFT") |
self.text = text |
local highlight = frame:CreateTexture(nil, "OVERLAY") |
highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight") |
highlight:SetTexture(136810) -- Interface\\QuestFrame\\UI-QuestTitleHighlight |
highlight:SetBlendMode("ADD") |
highlight:SetHeight(14) |
highlight:ClearAllPoints() |
highlight:Hide() |
self.highlight = highlight |
local check = frame:CreateTexture("OVERLAY") |
local check = frame:CreateTexture("OVERLAY") |
check:SetWidth(16) |
check:SetHeight(16) |
check:SetPoint("LEFT",frame,"LEFT",3,-1) |
check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check") |
check:SetTexture(130751) -- Interface\\Buttons\\UI-CheckBox-Check |
check:Hide() |
self.check = check |
sub:SetWidth(16) |
sub:SetHeight(16) |
sub:SetPoint("RIGHT",frame,"RIGHT",-3,-1) |
sub:SetTexture("Interface\\ChatFrame\\ChatFrameExpandArrow") |
sub:SetTexture(130940) -- Interface\\ChatFrame\\ChatFrameExpandArrow |
sub:Hide() |
self.sub = sub |
self.sub = sub |
frame:SetScript("OnEnter", ItemBase.Frame_OnEnter) |
frame:SetScript("OnLeave", ItemBase.Frame_OnLeave) |
self.OnAcquire = ItemBase.OnAcquire |
self.OnRelease = ItemBase.OnRelease |
self.SetPullout = ItemBase.SetPullout |
self.GetText = ItemBase.GetText |
self.SetText = ItemBase.SetText |
self.SetDisabled = ItemBase.SetDisabled |
self.SetPoint = ItemBase.SetPoint |
self.Show = ItemBase.Show |
self.Hide = ItemBase.Hide |
self.SetOnLeave = ItemBase.SetOnLeave |
self.SetOnEnter = ItemBase.SetOnEnter |
return self |
end |
--[[ |
Template for items: |
-- Item: |
-- |
do |
local widgetType = "Dropdown-Item-" |
local widgetVersion = 1 |
local function Constructor() |
local self = ItemBase.Create(widgetType) |
AceGUI:RegisterAsWidget(self) |
return self |
end |
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version) |
end |
--]] |
do |
local widgetType = "Dropdown-Item-Header" |
local widgetVersion = 1 |
local function OnEnter(this) |
local self = this.obj |
self:Fire("OnEnter") |
if self.specialOnEnter then |
self.specialOnEnter(self) |
end |
end |
local function OnLeave(this) |
local self = this.obj |
self:Fire("OnLeave") |
if self.specialOnLeave then |
self.specialOnLeave(self) |
end |
end |
-- exported, override |
local function SetDisabled(self, disabled) |
ItemBase.SetDisabled(self, disabled) |
self.text:SetTextColor(1, 1, 0) |
end |
end |
local function Constructor() |
local self = ItemBase.Create(widgetType) |
self.SetDisabled = SetDisabled |
self.frame:SetScript("OnEnter", OnEnter) |
self.frame:SetScript("OnLeave", OnLeave) |
self.text:SetTextColor(1, 1, 0) |
AceGUI:RegisterAsWidget(self) |
return self |
end |
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version) |
end |
do |
local widgetType = "Dropdown-Item-Execute" |
local widgetVersion = 1 |
local function Frame_OnClick(this, button) |
local self = this.obj |
if self.disabled then return end |
self.pullout:Close() |
end |
end |
local function Constructor() |
local self = ItemBase.Create(widgetType) |
self.frame:SetScript("OnClick", Frame_OnClick) |
AceGUI:RegisterAsWidget(self) |
return self |
end |
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version) |
end |
do |
local widgetType = "Dropdown-Item-Toggle" |
local widgetVersion = 4 |
local function UpdateToggle(self) |
if self.value then |
self.check:Show() |
self.check:Hide() |
end |
end |
local function OnRelease(self) |
ItemBase.OnRelease(self) |
self:SetValue(nil) |
end |
local function Frame_OnClick(this, button) |
local self = this.obj |
if self.disabled then return end |
UpdateToggle(self) |
self:Fire("OnValueChanged", self.value) |
end |
-- exported |
local function SetValue(self, value) |
self.value = value |
UpdateToggle(self) |
end |
-- exported |
local function GetValue(self) |
return self.value |
end |
local function Constructor() |
local self = ItemBase.Create(widgetType) |
self.frame:SetScript("OnClick", Frame_OnClick) |
self.SetValue = SetValue |
self.GetValue = GetValue |
self.OnRelease = OnRelease |
AceGUI:RegisterAsWidget(self) |
return self |
end |
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version) |
end |
do |
local widgetType = "Dropdown-Item-Menu" |
local widgetVersion = 2 |
local function OnEnter(this) |
local self = this.obj |
self:Fire("OnEnter") |
if self.specialOnEnter then |
self.specialOnEnter(self) |
end |
self.highlight:Show() |
if not self.disabled and self.submenu then |
self.submenu:Open("TOPLEFT", self.frame, "TOPRIGHT", self.pullout:GetRightBorderWidth(), 0, self.frame:GetFrameLevel() + 100) |
end |
end |
local function OnHide(this) |
local self = this.obj |
if self.submenu then |
self.submenu:Close() |
end |
end |
-- exported |
local function SetMenu(self, menu) |
assert(menu.type == "Dropdown-Pullout") |
self.submenu = menu |
end |
-- exported |
local function CloseMenu(self) |
self.submenu:Close() |
end |
local function Constructor() |
local self = ItemBase.Create(widgetType) |
self.sub:Show() |
self.frame:SetScript("OnEnter", OnEnter) |
self.frame:SetScript("OnHide", OnHide) |
self.SetMenu = SetMenu |
self.CloseMenu = CloseMenu |
AceGUI:RegisterAsWidget(self) |
return self |
end |
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version) |
end |
do |
local widgetType = "Dropdown-Item-Separator" |
local widgetVersion = 2 |
-- exported, override |
local function SetDisabled(self, disabled) |
ItemBase.SetDisabled(self, disabled) |
self.useHighlight = false |
end |
local function Constructor() |
local self = ItemBase.Create(widgetType) |
self.SetDisabled = SetDisabled |
local line = self.frame:CreateTexture(nil, "OVERLAY") |
line:SetHeight(1) |
line:SetColorTexture(.5, .5, .5) |
line:SetPoint("LEFT", self.frame, "LEFT", 10, 0) |
line:SetPoint("RIGHT", self.frame, "RIGHT", -10, 0) |
self.text:Hide() |
self.useHighlight = false |
AceGUI:RegisterAsWidget(self) |
return self |
end |
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion + ItemBase.version) |
end |
--[[----------------------------------------------------------------------------- |
ColorPicker Widget |
-------------------------------------------------------------------------------]] |
local Type, Version = "ColorPicker", 23 |
local Type, Version = "ColorPicker", 25 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: ShowUIPanel, HideUIPanel, ColorPickerFrame, OpacitySliderFrame |
-- GLOBALS: ColorPickerFrame, OpacitySliderFrame |
--[[----------------------------------------------------------------------------- |
Support functions |
end |
local function ColorSwatch_OnClick(frame) |
HideUIPanel(ColorPickerFrame) |
ColorPickerFrame:Hide() |
local self = frame.obj |
if not self.disabled then |
ColorPickerFrame:SetFrameStrata("FULLSCREEN_DIALOG") |
ColorCallback(self, r, g, b, a, true) |
end |
ShowUIPanel(ColorPickerFrame) |
ColorPickerFrame:Show() |
end |
AceGUI:ClearFocus() |
end |
local colorSwatch = frame:CreateTexture(nil, "OVERLAY") |
colorSwatch:SetWidth(19) |
colorSwatch:SetHeight(19) |
colorSwatch:SetTexture("Interface\\ChatFrame\\ChatFrameColorSwatch") |
colorSwatch:SetTexture(130939) -- Interface\\ChatFrame\\ChatFrameColorSwatch |
colorSwatch:SetPoint("LEFT") |
local texture = frame:CreateTexture(nil, "BACKGROUND") |
colorSwatch.background = texture |
texture:SetWidth(16) |
texture:SetHeight(16) |
texture:SetColorTexture(1, 1, 1) |
texture:Show() |
local checkers = frame:CreateTexture(nil, "BACKGROUND") |
colorSwatch.checkers = checkers |
checkers:SetWidth(14) |
checkers:SetHeight(14) |
checkers:SetTexture("Tileset\\Generic\\Checkers") |
checkers:SetTexture(188523) -- Tileset\\Generic\\Checkers |
checkers:SetTexCoord(.25, 0, 0.5, .25) |
checkers:SetDesaturated(true) |
checkers:SetVertexColor(1, 1, 1, 0.75) |
text:SetPoint("RIGHT") |
--local highlight = frame:CreateTexture(nil, "HIGHLIGHT") |
--highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight") |
--highlight:SetTexture(136810) -- Interface\\QuestFrame\\UI-QuestTitleHighlight |
--highlight:SetBlendMode("ADD") |
--highlight:SetAllPoints(frame) |
-- Lua APIs |
local select, pairs = select, pairs |
-- WoW APIs |
local CreateFrame, UIParent = CreateFrame, UIParent |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: GameFontHighlightSmall |
--[[----------------------------------------------------------------------------- |
Scripts |
-------------------------------------------------------------------------------]] |
Label Widget |
Displays text and optionally an icon. |
-------------------------------------------------------------------------------]] |
local Type, Version = "Label", 24 |
local Type, Version = "Label", 27 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
label:SetPoint("TOP", image, "BOTTOM") |
label:SetPoint("LEFT") |
label:SetWidth(width) |
height = image:GetHeight() + label:GetHeight() |
height = image:GetHeight() + label:GetStringHeight() |
else |
-- image on the left |
image:SetPoint("TOPLEFT") |
if image:GetHeight() > label:GetHeight() then |
if image:GetHeight() > label:GetStringHeight() then |
label:SetPoint("LEFT", image, "RIGHT", 4, 0) |
else |
label:SetPoint("TOPLEFT", image, "TOPRIGHT", 4, 0) |
end |
label:SetWidth(width - imagewidth - 4) |
height = max(image:GetHeight(), label:GetHeight()) |
height = max(image:GetHeight(), label:GetStringHeight()) |
end |
else |
-- no image shown |
label:SetPoint("TOPLEFT") |
label:SetWidth(width) |
height = label:GetHeight() |
height = label:GetStringHeight() |
end |
-- avoid zero-height labels, since they can used as spacers |
if not height or height == 0 then |
height = 1 |
end |
self.resizing = true |
frame:SetHeight(height) |
frame.height = height |
["SetImage"] = function(self, path, ...) |
local image = self.image |
image:SetTexture(path) |
if image:GetTexture() then |
self.imageshown = true |
local n = select("#", ...) |
["SetFont"] = function(self, font, height, flags) |
self.label:SetFont(font, height, flags) |
UpdateImageAnchor(self) |
end, |
["SetFontObject"] = function(self, font) |
local Type, Version = "MultiLineEditBox", 28 |
local Type, Version = "MultiLineEditBox", 29 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
end |
Layout(self) |
end, |
["ClearFocus"] = function(self) |
self.editBox:ClearFocus() |
self.frame:SetScript("OnShow", nil) |
["GetCursorPosition"] = function(self) |
return self.editBox:GetCursorPosition() |
end, |
["SetCursorPosition"] = function(self, ...) |
return self.editBox:SetCursorPosition(...) |
end, |
} |
--[[----------------------------------------------------------------------------- |
local function Constructor() |
local frame = CreateFrame("Frame", nil, UIParent) |
frame:Hide() |
local widgetNum = AceGUI:GetNextWidgetNum(Type) |
local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall") |
button:SetText(ACCEPT) |
button:SetScript("OnClick", OnClick) |
button:Disable() |
local text = button:GetFontString() |
text:ClearAllPoints() |
text:SetPoint("TOPLEFT", button, "TOPLEFT", 5, -5) |
text:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -5, 1) |
text:SetJustifyV("MIDDLE") |
local scrollBG = CreateFrame("Frame", nil, frame) |
local scrollBG = CreateFrame("Frame", nil, frame, BackdropTemplateMixin and "BackdropTemplate" or nil) |
scrollBG:SetBackdrop(backdrop) |
scrollBG:SetBackdropColor(0, 0, 0) |
scrollBG:SetBackdropBorderColor(0.4, 0.4, 0.4) |
editBox:SetScript("OnTextChanged", OnTextChanged) |
editBox:SetScript("OnTextSet", OnTextSet) |
editBox:SetScript("OnEditFocusGained", OnEditFocusGained) |
scrollFrame:SetScrollChild(editBox) |
local widget = { |
Slider Widget |
Graphical Slider, like, for Range values. |
-------------------------------------------------------------------------------]] |
local Type, Version = "Slider", 22 |
local Type, Version = "Slider", 23 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
AceGUI:ClearFocus() |
end |
local function Slider_OnValueChanged(frame) |
local function Slider_OnValueChanged(frame, newvalue) |
local self = frame.obj |
if not frame.setup then |
local newvalue = frame:GetValue() |
if self.step and self.step > 0 then |
local min_value = self.min or 0 |
newvalue = floor((newvalue - min_value) / self.step + 0.5) * self.step + min_value |
else |
value = tonumber(value) |
end |
if value then |
PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON |
self.slider:SetValue(value) |
label:SetJustifyH("CENTER") |
label:SetHeight(15) |
local slider = CreateFrame("Slider", nil, frame) |
local slider = CreateFrame("Slider", nil, frame, BackdropTemplateMixin and "BackdropTemplate" or nil) |
slider:SetOrientation("HORIZONTAL") |
slider:SetHeight(15) |
slider:SetHitRectInsets(0, 0, -10, 0) |
local hightext = slider:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall") |
hightext:SetPoint("TOPRIGHT", slider, "BOTTOMRIGHT", -2, 3) |
local editbox = CreateFrame("EditBox", nil, frame) |
local editbox = CreateFrame("EditBox", nil, frame, BackdropTemplateMixin and "BackdropTemplate" or nil) |
editbox:SetAutoFocus(false) |
editbox:SetFontObject(GameFontHighlightSmall) |
editbox:SetPoint("TOP", slider, "BOTTOM") |
TabGroup Container |
Container that uses tabs on top to switch between groups. |
-------------------------------------------------------------------------------]] |
local Type, Version = "TabGroup", 36 |
local Type, Version = "TabGroup", 37 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
self.tablist = tabs |
self:BuildTabs() |
end, |
["BuildTabs"] = function(self) |
local hastitle = (self.titletext:GetText() and self.titletext:GetText() ~= "") |
local status = self.status or self.localstatus |
local tablist = self.tablist |
local tabs = self.tabs |
if not tablist then return end |
local width = self.frame.width or self.frame:GetWidth() or 0 |
wipe(widths) |
wipe(rowwidths) |
wipe(rowends) |
--Place Text into tabs and get thier initial width |
for i, v in ipairs(tablist) do |
local tab = tabs[i] |
tab = self:CreateTab(i) |
tabs[i] = tab |
end |
tab:Show() |
tab:SetText(v.text) |
tab:SetDisabled(v.disabled) |
tab.value = v.value |
widths[i] = tab:GetWidth() - 6 --tabs are anchored 10 pixels from the right side of the previous one to reduce spacing, but add a fixed 4px padding for the text |
end |
for i = (#tablist)+1, #tabs, 1 do |
tabs[i]:Hide() |
end |
--First pass, find the minimum number of rows needed to hold all tabs and the initial tab layout |
local numtabs = #tablist |
local numrows = 1 |
end |
rowwidths[numrows] = usedwidth + 10 --first tab in each row takes up an extra 10px |
rowends[numrows] = #tablist |
--Fix for single tabs being left on the last row, move a tab from the row above if applicable |
if numrows > 1 then |
--if the last row has only one tab |
tab:SetPoint("LEFT", tabs[tabno-1], "RIGHT", -10, 0) |
end |
end |
-- equal padding for each tab to fill the available width, |
-- if the used space is above 75% already |
-- the 18 pixel is the typical width of a scrollbar, so we can have a tab group inside a scrolling frame, |
-- the 18 pixel is the typical width of a scrollbar, so we can have a tab group inside a scrolling frame, |
-- and not have the tabs jump around funny when switching between tabs that need scrolling and those that don't |
local padding = 0 |
if not (numrows == 1 and rowwidths[1] < width*0.75 - 18) then |
padding = (width - rowwidths[row]) / (endtab - starttab+1) |
end |
for i = starttab, endtab do |
PanelTemplates_TabResize(tabs[i], padding + 4, nil, nil, width, tabs[i]:GetFontString():GetStringWidth()) |
end |
starttab = endtab + 1 |
end |
self.borderoffset = (hastitle and 17 or 10)+((numrows)*20) |
self.border:SetPoint("TOPLEFT", 1, -self.borderoffset) |
end, |
content:SetHeight(contentheight) |
content.height = contentheight |
end, |
["LayoutFinished"] = function(self, width, height) |
if self.noAutoHeight then return end |
self:SetHeight((height or 0) + (self.borderoffset + 23)) |
titletext:SetHeight(18) |
titletext:SetText("") |
local border = CreateFrame("Frame", nil, frame) |
local border = CreateFrame("Frame", nil, frame, BackdropTemplateMixin and "BackdropTemplate" or nil) |
border:SetPoint("TOPLEFT", 1, -27) |
border:SetPoint("BOTTOMRIGHT", -1, 3) |
border:SetBackdrop(PaneBackdrop) |
for method, func in pairs(methods) do |
widget[method] = func |
end |
return AceGUI:RegisterAsContainer(widget) |
end |
Keybinding Widget |
Set Keybindings in the Config UI. |
-------------------------------------------------------------------------------]] |
local Type, Version = "Keybinding", 25 |
local Type, Version = "Keybinding", 26 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
label:SetJustifyH("CENTER") |
label:SetHeight(18) |
local msgframe = CreateFrame("Frame", nil, UIParent) |
local msgframe = CreateFrame("Frame", nil, UIParent, BackdropTemplateMixin and "BackdropTemplate" or nil) |
msgframe:SetHeight(30) |
msgframe:SetBackdrop(ControlBackdrop) |
msgframe:SetBackdropColor(0,0,0) |
--[[----------------------------------------------------------------------------- |
Checkbox Widget |
-------------------------------------------------------------------------------]] |
local Type, Version = "CheckBox", 24 |
local Type, Version = "CheckBox", 26 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
self.text:SetPoint("LEFT", self.checkbg, "RIGHT") |
self.text:SetPoint("RIGHT") |
else |
self.text:SetPoint("LEFT", self.checkbg, "RIGHT", self.image:GetWidth() + 2, 0) |
self.text:SetPoint("LEFT", self.image, "RIGHT", 1, 0) |
self.text:SetPoint("RIGHT") |
end |
end |
if self.desc then |
self.desc:SetWidth(width - 30) |
if self.desc:GetText() and self.desc:GetText() ~= "" then |
self:SetHeight(28 + self.desc:GetHeight()) |
self:SetHeight(28 + self.desc:GetStringHeight()) |
end |
end |
end, |
end |
end, |
["SetValue"] = function(self,value) |
["SetValue"] = function(self, value) |
local check = self.check |
self.checked = value |
if value then |
SetDesaturation(self.check, false) |
self.check:Show() |
SetDesaturation(check, false) |
check:Show() |
else |
--Nil is the unknown tristate value |
if self.tristate and value == nil then |
SetDesaturation(self.check, true) |
self.check:Show() |
SetDesaturation(check, true) |
check:Show() |
else |
SetDesaturation(self.check, false) |
self.check:Hide() |
SetDesaturation(check, false) |
check:Hide() |
end |
end |
self:SetDisabled(self.disabled) |
local size |
if type == "radio" then |
size = 16 |
checkbg:SetTexture("Interface\\Buttons\\UI-RadioButton") |
checkbg:SetTexture(130843) -- Interface\\Buttons\\UI-RadioButton |
checkbg:SetTexCoord(0, 0.25, 0, 1) |
check:SetTexture("Interface\\Buttons\\UI-RadioButton") |
check:SetTexture(130843) -- Interface\\Buttons\\UI-RadioButton |
check:SetTexCoord(0.25, 0.5, 0, 1) |
check:SetBlendMode("ADD") |
highlight:SetTexture("Interface\\Buttons\\UI-RadioButton") |
highlight:SetTexture(130843) -- Interface\\Buttons\\UI-RadioButton |
highlight:SetTexCoord(0.5, 0.75, 0, 1) |
else |
size = 24 |
checkbg:SetTexture("Interface\\Buttons\\UI-CheckBox-Up") |
checkbg:SetTexture(130755) -- Interface\\Buttons\\UI-CheckBox-Up |
checkbg:SetTexCoord(0, 1, 0, 1) |
check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check") |
check:SetTexture(130751) -- Interface\\Buttons\\UI-CheckBox-Check |
check:SetTexCoord(0, 1, 0, 1) |
check:SetBlendMode("BLEND") |
highlight:SetTexture("Interface\\Buttons\\UI-CheckBox-Highlight") |
highlight:SetTexture(130753) -- Interface\\Buttons\\UI-CheckBox-Highlight |
highlight:SetTexCoord(0, 1, 0, 1) |
end |
checkbg:SetHeight(size) |
self.desc:Show() |
--self.text:SetFontObject(GameFontNormal) |
self.desc:SetText(desc) |
self:SetHeight(28 + self.desc:GetHeight()) |
self:SetHeight(28 + self.desc:GetStringHeight()) |
else |
if self.desc then |
self.desc:SetText("") |
self:SetHeight(24) |
end |
end, |
["SetImage"] = function(self, path, ...) |
local image = self.image |
image:SetTexture(path) |
if image:GetTexture() then |
local n = select("#", ...) |
if n == 4 or n == 8 then |
checkbg:SetWidth(24) |
checkbg:SetHeight(24) |
checkbg:SetPoint("TOPLEFT") |
checkbg:SetTexture("Interface\\Buttons\\UI-CheckBox-Up") |
checkbg:SetTexture(130755) -- Interface\\Buttons\\UI-CheckBox-Up |
local check = frame:CreateTexture(nil, "OVERLAY") |
check:SetAllPoints(checkbg) |
check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check") |
check:SetTexture(130751) -- Interface\\Buttons\\UI-CheckBox-Check |
local text = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight") |
text:SetJustifyH("LEFT") |
text:SetPoint("RIGHT") |
local highlight = frame:CreateTexture(nil, "HIGHLIGHT") |
highlight:SetTexture("Interface\\Buttons\\UI-CheckBox-Highlight") |
highlight:SetTexture(130753) -- Interface\\Buttons\\UI-CheckBox-Highlight |
highlight:SetBlendMode("ADD") |
highlight:SetAllPoints(checkbg) |
["SetImage"] = function(self, path, ...) |
local image = self.image |
image:SetTexture(path) |
if image:GetTexture() then |
local n = select("#", ...) |
if n == 4 or n == 8 then |
local highlight = frame:CreateTexture(nil, "HIGHLIGHT") |
highlight:SetAllPoints(image) |
highlight:SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-Tab-Highlight") |
highlight:SetTexture(136580) -- Interface\\PaperDollInfoFrame\\UI-Character-Tab-Highlight |
highlight:SetTexCoord(0, 1, 0.23, 0.77) |
highlight:SetBlendMode("ADD") |
--[[----------------------------------------------------------------------------- |
Frame Container |
-------------------------------------------------------------------------------]] |
local Type, Version = "Frame", 26 |
local Type, Version = "Frame", 27 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
} |
local function Constructor() |
local frame = CreateFrame("Frame", nil, UIParent) |
local frame = CreateFrame("Frame", nil, UIParent, BackdropTemplateMixin and "BackdropTemplate" or nil) |
frame:Hide() |
frame:EnableMouse(true) |
closebutton:SetWidth(100) |
closebutton:SetText(CLOSE) |
local statusbg = CreateFrame("Button", nil, frame) |
local statusbg = CreateFrame("Button", nil, frame, BackdropTemplateMixin and "BackdropTemplate" or nil) |
statusbg:SetPoint("BOTTOMLEFT", 15, 15) |
statusbg:SetPoint("BOTTOMRIGHT", -132, 15) |
statusbg:SetHeight(24) |
statustext:SetText("") |
local titlebg = frame:CreateTexture(nil, "OVERLAY") |
titlebg:SetTexture("Interface\\DialogFrame\\UI-DialogBox-Header") |
titlebg:SetTexture(131080) -- Interface\\DialogFrame\\UI-DialogBox-Header |
titlebg:SetTexCoord(0.31, 0.67, 0, 0.63) |
titlebg:SetPoint("TOP", 0, 12) |
titlebg:SetWidth(100) |
titletext:SetPoint("TOP", titlebg, "TOP", 0, -14) |
local titlebg_l = frame:CreateTexture(nil, "OVERLAY") |
titlebg_l:SetTexture("Interface\\DialogFrame\\UI-DialogBox-Header") |
titlebg_l:SetTexture(131080) -- Interface\\DialogFrame\\UI-DialogBox-Header |
titlebg_l:SetTexCoord(0.21, 0.31, 0, 0.63) |
titlebg_l:SetPoint("RIGHT", titlebg, "LEFT") |
titlebg_l:SetWidth(30) |
titlebg_l:SetHeight(40) |
local titlebg_r = frame:CreateTexture(nil, "OVERLAY") |
titlebg_r:SetTexture("Interface\\DialogFrame\\UI-DialogBox-Header") |
titlebg_r:SetTexture(131080) -- Interface\\DialogFrame\\UI-DialogBox-Header |
titlebg_r:SetTexCoord(0.67, 0.77, 0, 0.63) |
titlebg_r:SetPoint("LEFT", titlebg, "RIGHT") |
titlebg_r:SetWidth(30) |
line1:SetWidth(14) |
line1:SetHeight(14) |
line1:SetPoint("BOTTOMRIGHT", -8, 8) |
line1:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border") |
line1:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border |
local x = 0.1 * 14/17 |
line1:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5) |
line2:SetWidth(8) |
line2:SetHeight(8) |
line2:SetPoint("BOTTOMRIGHT", -8, 8) |
line2:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border") |
line2:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border |
local x = 0.1 * 8/17 |
line2:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5) |
InlineGroup Container |
Simple container widget that creates a visible "box" with an optional title. |
-------------------------------------------------------------------------------]] |
local Type, Version = "InlineGroup", 21 |
local Type, Version = "InlineGroup", 22 |
local AceGUI = LibStub and LibStub("AceGUI-3.0", true) |
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end |
titletext:SetJustifyH("LEFT") |
titletext:SetHeight(18) |
local border = CreateFrame("Frame", nil, frame) |
local border = CreateFrame("Frame", nil, frame, BackdropTemplateMixin and "BackdropTemplate" or nil) |
border:SetPoint("TOPLEFT", 0, -17) |
border:SetPoint("BOTTOMRIGHT", -1, 3) |
border:SetBackdrop(PaneBackdrop) |
--[[ $Id: AceGUIWidget-DropDown.lua 1167 2017-08-29 22:08:48Z funkydude $ ]]-- |
--[[ $Id: AceGUIWidget-DropDown.lua 1239 2020-09-20 10:22:02Z nevcairiel $ ]]-- |
local AceGUI = LibStub("AceGUI-3.0") |
-- Lua APIs |
local min, max, floor = math.min, math.max, math.floor |
local select, pairs, ipairs, type = select, pairs, ipairs, type |
local select, pairs, ipairs, type, tostring = select, pairs, ipairs, type, tostring |
local tsort = table.sort |
-- WoW APIs |
do |
local widgetType = "Dropdown-Pullout" |
local widgetVersion = 3 |
local widgetVersion = 5 |
--[[ Static data ]]-- |
local backdrop = { |
bgFile = "Interface\\ChatFrame\\ChatFrameBackground", |
edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", |
local defaultWidth = 200 |
local defaultMaxHeight = 600 |
--[[ UI Event Handlers ]]-- |
-- HACK: This should be no part of the pullout, but there |
-- is no other 'clean' way to response to any item-OnEnter |
-- Used to close Submenus when an other item is entered |
end |
end |
end |
-- See the note in Constructor() for each scroll related function |
local function OnMouseWheel(this, value) |
this.obj:MoveScroll(value) |
end |
local function OnScrollValueChanged(this, value) |
this.obj:SetScroll(value) |
end |
local function OnSizeChanged(this) |
this.obj:FixScroll() |
end |
--[[ Exported methods ]]-- |
-- exported |
local function SetScroll(self, value) |
local status = self.scrollStatus |
child:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, offset) |
child:SetPoint("TOPRIGHT", frame, "TOPRIGHT", self.slider:IsShown() and -12 or 0, offset) |
status.offset = offset |
status.scrollvalue = value |
status.scrollvalue = value |
end |
-- exported |
local function MoveScroll(self, value) |
local status = self.scrollStatus |
self.slider:SetValue(min(max(status.scrollvalue + delta*(1000/(diff/45)),0), 1000)) |
end |
end |
-- exported |
local function FixScroll(self) |
local status = self.scrollStatus |
child:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, offset) |
self.slider:SetValue(0) |
else |
self.slider:Show() |
self.slider:Show() |
local value = (offset / (viewheight - height) * 1000) |
if value > 1000 then value = 1000 end |
self.slider:SetValue(value) |
end |
end |
end |
-- exported, AceGUI callback |
local function OnAcquire(self) |
self.frame:SetParent(UIParent) |
--self.itemFrame:SetToplevel(true) |
end |
-- exported, AceGUI callback |
local function OnRelease(self) |
self:Clear() |
self.frame:ClearAllPoints() |
self.frame:Hide() |
end |
-- exported |
local function AddItem(self, item) |
self.items[#self.items + 1] = item |
local h = #self.items * 16 |
self.itemFrame:SetHeight(h) |
self.frame:SetHeight(min(h + 34, self.maxHeight)) -- +34: 20 for scrollFrame placement (10 offset) and +14 for item placement |
item.frame:SetPoint("LEFT", self.itemFrame, "LEFT") |
item.frame:SetPoint("RIGHT", self.itemFrame, "RIGHT") |
item:SetPullout(self) |
item:SetOnEnter(OnEnter) |
end |
-- exported |
local function Open(self, point, relFrame, relPoint, x, y) |
local function Open(self, point, relFrame, relPoint, x, y) |
local items = self.items |
local frame = self.frame |
local itemFrame = self.itemFrame |
frame:SetPoint(point, relFrame, relPoint, x, y) |
local height = 8 |
for i, item in pairs(items) do |
if i == 1 then |
item:SetPoint("TOP", itemFrame, "TOP", 0, -2) |
else |
item:SetPoint("TOP", items[i-1].frame, "BOTTOM", 0, 1) |
end |
item:SetPoint("TOP", itemFrame, "TOP", 0, -2 + (i - 1) * -16) |
item:Show() |
height = height + 16 |
end |
itemFrame:SetHeight(height) |
fixstrata("TOOLTIP", frame, frame:GetChildren()) |
frame:Show() |
self:Fire("OnOpen") |
end |
end |
-- exported |
local function Close(self) |
self.frame:Hide() |
self:Fire("OnClose") |
end |
end |
-- exported |
local function Clear(self) |
local items = self.items |
AceGUI:Release(item) |
items[i] = nil |
end |
end |
end |
-- exported |
local function IterateItems(self) |
return ipairs(self.items) |
end |
-- exported |
local function SetHideOnLeave(self, val) |
self.hideOnLeave = val |
end |
-- exported |
local function SetMaxHeight(self, height) |
self.maxHeight = height or defaultMaxHeight |
self.frame:SetHeight(self.itemFrame:GetHeight() + 34) -- see :AddItem |
end |
end |
-- exported |
local function GetRightBorderWidth(self) |
return 6 + (self.slider:IsShown() and 12 or 0) |
end |
-- exported |
local function GetLeftBorderWidth(self) |
return 6 |
end |
--[[ Constructor ]]-- |
local function Constructor() |
local count = AceGUI:GetNextWidgetNum(widgetType) |
local frame = CreateFrame("Frame", "AceGUI30Pullout"..count, UIParent) |
local frame = CreateFrame("Frame", "AceGUI30Pullout"..count, UIParent, BackdropTemplateMixin and "BackdropTemplate" or nil) |
local self = {} |
self.count = count |
self.type = widgetType |
self.frame = frame |
frame.obj = self |
self.OnAcquire = OnAcquire |
self.OnRelease = OnRelease |
self.SetScroll = SetScroll |
self.MoveScroll = MoveScroll |
self.FixScroll = FixScroll |
self.SetMaxHeight = SetMaxHeight |
self.GetRightBorderWidth = GetRightBorderWidth |
self.GetLeftBorderWidth = GetLeftBorderWidth |
self.items = {} |
self.scrollStatus = { |
scrollvalue = 0, |
} |
self.maxHeight = defaultMaxHeight |
frame:SetBackdrop(backdrop) |
frame:SetBackdropColor(0, 0, 0) |
frame:SetFrameStrata("FULLSCREEN_DIALOG") |
frame:SetClampedToScreen(true) |
frame:SetWidth(defaultWidth) |
frame:SetHeight(self.maxHeight) |
frame:SetHeight(self.maxHeight) |
--frame:SetToplevel(true) |
-- NOTE: The whole scroll frame code is copied from the AceGUI-3.0 widget ScrollFrame |
local scrollFrame = CreateFrame("ScrollFrame", nil, frame) |
local itemFrame = CreateFrame("Frame", nil, scrollFrame) |
self.scrollFrame = scrollFrame |
self.itemFrame = itemFrame |
scrollFrame.obj = self |
itemFrame.obj = self |
local slider = CreateFrame("Slider", "AceGUI30PulloutScrollbar"..count, scrollFrame) |
local slider = CreateFrame("Slider", "AceGUI30PulloutScrollbar"..count, scrollFrame, BackdropTemplateMixin and "BackdropTemplate" or nil) |
slider:SetOrientation("VERTICAL") |
slider:SetHitRectInsets(0, 0, -10, 0) |
slider:SetBackdrop(sliderBackdrop) |
slider:SetFrameStrata("FULLSCREEN_DIALOG") |
self.slider = slider |
slider.obj = self |
scrollFrame:SetScrollChild(itemFrame) |
scrollFrame:SetPoint("TOPLEFT", frame, "TOPLEFT", 6, -12) |
scrollFrame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -6, 12) |
scrollFrame:SetScript("OnSizeChanged", OnSizeChanged) |
scrollFrame:SetToplevel(true) |
scrollFrame:SetFrameStrata("FULLSCREEN_DIALOG") |
itemFrame:SetPoint("TOPLEFT", scrollFrame, "TOPLEFT", 0, 0) |
itemFrame:SetPoint("TOPRIGHT", scrollFrame, "TOPRIGHT", -12, 0) |
itemFrame:SetHeight(400) |
itemFrame:SetToplevel(true) |
itemFrame:SetFrameStrata("FULLSCREEN_DIALOG") |
slider:SetPoint("TOPLEFT", scrollFrame, "TOPRIGHT", -16, 0) |
slider:SetPoint("BOTTOMLEFT", scrollFrame, "BOTTOMRIGHT", -16, 0) |
slider:SetScript("OnValueChanged", OnScrollValueChanged) |
slider:SetMinMaxValues(0, 1000) |
slider:SetValueStep(1) |
slider:SetValue(0) |
scrollFrame:Show() |
itemFrame:Show() |
slider:Hide() |
self:FixScroll() |
AceGUI:RegisterAsWidget(self) |
return self |
end |
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion) |
end |
do |
local widgetType = "Dropdown" |
local widgetVersion = 31 |
local widgetVersion = 35 |
--[[ Static data ]]-- |
--[[ UI event handler ]]-- |
local function Control_OnEnter(this) |
this.obj.button:LockHighlight() |
this.obj:Fire("OnEnter") |
end |
local function Control_OnLeave(this) |
this.obj.button:UnlockHighlight() |
this.obj:Fire("OnLeave") |
self.pullout:Close() |
end |
end |
local function Dropdown_TogglePullout(this) |
local self = this.obj |
PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON |
AceGUI:SetFocus(self) |
end |
end |
local function OnPulloutOpen(this) |
local self = this.userdata.obj |
local value = self.value |
if not self.multiselect then |
for i, item in this:IterateItems() do |
item:SetValue(item.userdata.value == value) |
end |
end |
self.open = true |
self:Fire("OnOpened") |
end |
self.open = nil |
self:Fire("OnClosed") |
end |
local function ShowMultiText(self) |
local text |
for i, widget in self.pullout:IterateItems() do |
end |
self:SetText(text) |
end |
local function OnItemValueChanged(this, event, checked) |
local self = this.userdata.obj |
if self.multiselect then |
self:Fire("OnValueChanged", this.userdata.value, checked) |
ShowMultiText(self) |
else |
this:SetValue(true) |
end |
if self.open then |
if self.open then |
self.pullout:Close() |
end |
end |
end |
--[[ Exported methods ]]-- |
-- exported, AceGUI callback |
local function OnAcquire(self) |
local pullout = AceGUI:Create("Dropdown-Pullout") |
pullout:SetCallback("OnOpen", OnPulloutOpen) |
self.pullout.frame:SetFrameLevel(self.frame:GetFrameLevel() + 1) |
fixlevels(self.pullout.frame, self.pullout.frame:GetChildren()) |
self:SetHeight(44) |
self:SetWidth(200) |
self:SetLabel() |
self:SetPulloutWidth(nil) |
self.list = {} |
end |
-- exported, AceGUI callback |
local function OnRelease(self) |
if self.open then |
end |
AceGUI:Release(self.pullout) |
self.pullout = nil |
self:SetText("") |
self:SetDisabled(false) |
self:SetMultiselect(false) |
self.value = nil |
self.list = nil |
self.open = nil |
self.hasClose = nil |
self.frame:ClearAllPoints() |
self.frame:Hide() |
end |
-- exported |
local function SetDisabled(self, disabled) |
self.disabled = disabled |
self.text:SetTextColor(1,1,1) |
end |
end |
-- exported |
local function ClearFocus(self) |
if self.open then |
self.pullout:Close() |
end |
end |
-- exported |
local function SetText(self, text) |
self.text:SetText(text or "") |
end |
-- exported |
local function SetLabel(self, text) |
if text and text ~= "" then |
self.alignoffset = 12 |
end |
end |
-- exported |
local function SetValue(self, value) |
if self.list then |
self:SetText(self.list[value] or "") |
end |
self:SetText(self.list[value] or "") |
self.value = value |
end |
-- exported |
local function GetValue(self) |
return self.value |
end |
-- exported |
local function SetItemValue(self, item, value) |
if not self.multiselect then return end |
end |
ShowMultiText(self) |
end |
-- exported |
local function SetItemDisabled(self, item, disabled) |
for i, widget in self.pullout:IterateItems() do |
end |
end |
end |
local function AddListItem(self, value, text, itemType) |
if not itemType then itemType = "Dropdown-Item-Toggle" end |
local exists = AceGUI:GetWidgetVersion(itemType) |
item:SetCallback("OnValueChanged", OnItemValueChanged) |
self.pullout:AddItem(item) |
end |
local function AddCloseButton(self) |
if not self.hasClose then |
local close = AceGUI:Create("Dropdown-Item-Execute") |
self.hasClose = true |
end |
end |
-- exported |
local sortlist = {} |
local function sortTbl(x,y) |
local num1, num2 = tonumber(x), tonumber(y) |
if num1 and num2 then -- numeric comparison, either two numbers or numeric strings |
return num1 < num2 |
else -- compare everything else tostring'ed |
return tostring(x) < tostring(y) |
end |
end |
local function SetList(self, list, order, itemType) |
self.list = list |
self.list = list or {} |
self.pullout:Clear() |
self.hasClose = nil |
if not list then return end |
if type(order) ~= "table" then |
for v in pairs(list) do |
sortlist[#sortlist + 1] = v |
end |
tsort(sortlist) |
tsort(sortlist, sortTbl) |
for i, key in ipairs(sortlist) do |
AddListItem(self, key, list[key], itemType) |
sortlist[i] = nil |
AddCloseButton(self) |
end |
end |
-- exported |
local function AddItem(self, value, text, itemType) |
if self.list then |
self.list[value] = text |
AddListItem(self, value, text, itemType) |
end |
self.list[value] = text |
AddListItem(self, value, text, itemType) |
end |
-- exported |
local function SetMultiselect(self, multi) |
self.multiselect = multi |
AddCloseButton(self) |
end |
end |
-- exported |
local function GetMultiselect(self) |
return self.multiselect |
end |
local function SetPulloutWidth(self, width) |
self.pulloutWidth = width |
end |
--[[ Constructor ]]-- |
local function Constructor() |
local count = AceGUI:GetNextWidgetNum(widgetType) |
local frame = CreateFrame("Frame", nil, UIParent) |
local dropdown = CreateFrame("Frame", "AceGUI30DropDown"..count, frame, "UIDropDownMenuTemplate") |
local self = {} |
self.type = widgetType |
self.frame = frame |
self.count = count |
frame.obj = self |
dropdown.obj = self |
self.OnRelease = OnRelease |
self.OnAcquire = OnAcquire |
self.ClearFocus = ClearFocus |
self.SetText = SetText |
self.SetItemValue = SetItemValue |
self.SetItemDisabled = SetItemDisabled |
self.SetPulloutWidth = SetPulloutWidth |
self.alignoffset = 26 |
frame:SetScript("OnHide",Dropdown_OnHide) |
dropdown:ClearAllPoints() |
local left = _G[dropdown:GetName() .. "Left"] |
local middle = _G[dropdown:GetName() .. "Middle"] |
local right = _G[dropdown:GetName() .. "Right"] |
middle:ClearAllPoints() |
right:ClearAllPoints() |
middle:SetPoint("LEFT", left, "RIGHT", 0, 0) |
middle:SetPoint("RIGHT", right, "LEFT", 0, 0) |
right:SetPoint("TOPRIGHT", dropdown, "TOPRIGHT", 0, 17) |
button:SetScript("OnEnter",Control_OnEnter) |
button:SetScript("OnLeave",Control_OnLeave) |
button:SetScript("OnClick",Dropdown_TogglePullout) |
local button_cover = CreateFrame("BUTTON",nil,self.frame) |
self.button_cover = button_cover |
button_cover.obj = self |
button_cover:SetScript("OnEnter",Control_OnEnter) |
button_cover:SetScript("OnLeave",Control_OnLeave) |
button_cover:SetScript("OnClick",Dropdown_TogglePullout) |
local text = _G[dropdown:GetName() .. "Text"] |
self.text = text |
text.obj = self |
text:ClearAllPoints() |
text:SetPoint("RIGHT", right, "RIGHT" ,-43, 2) |
text:SetPoint("LEFT", left, "LEFT", 25, 2) |
local label = frame:CreateFontString(nil,"OVERLAY","GameFontNormalSmall") |
label:SetPoint("TOPLEFT",frame,"TOPLEFT",0,0) |
label:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0) |
AceGUI:RegisterAsWidget(self) |
return self |
end |
AceGUI:RegisterWidgetType(widgetType, Constructor, widgetVersion) |
end |
end |
left:SetHeight(8) |
left:SetPoint("LEFT", 3, 0) |
left:SetPoint("RIGHT", label, "LEFT", -5, 0) |
left:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border") |
left:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border |
left:SetTexCoord(0.81, 0.94, 0.5, 1) |
local right = frame:CreateTexture(nil, "BACKGROUND") |
right:SetHeight(8) |
right:SetPoint("RIGHT", -3, 0) |
right:SetPoint("LEFT", label, "RIGHT", 5, 0) |
right:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border") |
right:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border |
right:SetTexCoord(0.81, 0.94, 0.5, 1) |
local widget = { |
local function frameOnClose(this) |
this.obj:Fire("OnClose") |
end |
local function closeOnClick(this) |
PlaySound(799) -- SOUNDKIT.GS_TITLE_OPTION_EXIT |
this.obj:Hide() |
end |
local function frameOnMouseDown(this) |
AceGUI:ClearFocus() |
end |
local function titleOnMouseDown(this) |
this:GetParent():StartMoving() |
AceGUI:ClearFocus() |
end |
local function frameOnMouseUp(this) |
local frame = this:GetParent() |
frame:StopMovingOrSizing() |
status.top = frame:GetTop() |
status.left = frame:GetLeft() |
end |
local function sizerseOnMouseDown(this) |
this:GetParent():StartSizing("BOTTOMRIGHT") |
AceGUI:ClearFocus() |
end |
local function sizersOnMouseDown(this) |
this:GetParent():StartSizing("BOTTOM") |
AceGUI:ClearFocus() |
end |
local function sizereOnMouseDown(this) |
this:GetParent():StartSizing("RIGHT") |
AceGUI:ClearFocus() |
end |
local function sizerOnMouseUp(this) |
this:GetParent():StopMovingOrSizing() |
end |
local function SetTitle(self,title) |
self.titletext:SetText(title) |
end |
local function SetStatusText(self,text) |
-- self.statustext:SetText(text) |
end |
local function Hide(self) |
self.frame:Hide() |
end |
local function Show(self) |
self.frame:Show() |
end |
local function OnAcquire(self) |
self.frame:SetParent(UIParent) |
self.frame:SetFrameStrata("FULLSCREEN_DIALOG") |
self:EnableResize(true) |
self:Show() |
end |
local function OnRelease(self) |
self.status = nil |
for k in pairs(self.localstatus) do |
self.localstatus[k] = nil |
end |
end |
-- called to set an external table to store status in |
local function SetStatusTable(self, status) |
assert(type(status) == "table") |
self.status = status |
self:ApplyStatus() |
end |
local function ApplyStatus(self) |
local status = self.status or self.localstatus |
local frame = self.frame |
frame:SetPoint("CENTER",UIParent,"CENTER") |
end |
end |
local function OnWidthSet(self, width) |
local content = self.content |
local contentwidth = width - 34 |
content:SetWidth(contentwidth) |
content.width = contentwidth |
end |
local function OnHeightSet(self, height) |
local content = self.content |
local contentheight = height - 57 |
content:SetHeight(contentheight) |
content.height = contentheight |
end |
local function EnableResize(self, state) |
local func = state and "Show" or "Hide" |
self.sizer_se[func](self.sizer_se) |
self.sizer_s[func](self.sizer_s) |
self.sizer_e[func](self.sizer_e) |
end |
local function Constructor() |
local frame = CreateFrame("Frame",nil,UIParent) |
local self = {} |
self.type = "Window" |
self.Hide = Hide |
self.Show = Show |
self.SetTitle = SetTitle |
self.OnWidthSet = OnWidthSet |
self.OnHeightSet = OnHeightSet |
self.EnableResize = EnableResize |
self.localstatus = {} |
self.frame = frame |
frame.obj = self |
frame:SetWidth(700) |
frame:SetResizable(true) |
frame:SetFrameStrata("FULLSCREEN_DIALOG") |
frame:SetScript("OnMouseDown", frameOnMouseDown) |
frame:SetScript("OnShow",frameOnShow) |
frame:SetScript("OnHide",frameOnClose) |
frame:SetMinResize(240,240) |
frame:SetToplevel(true) |
local titlebg = frame:CreateTexture(nil, "BACKGROUND") |
titlebg:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Title-Background]]) |
titlebg:SetTexture(251966) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Title-Background |
titlebg:SetPoint("TOPLEFT", 9, -6) |
titlebg:SetPoint("BOTTOMRIGHT", frame, "TOPRIGHT", -28, -24) |
local dialogbg = frame:CreateTexture(nil, "BACKGROUND") |
dialogbg:SetTexture([[Interface\Tooltips\UI-Tooltip-Background]]) |
dialogbg:SetTexture(137056) -- Interface\\Tooltips\\UI-Tooltip-Background |
dialogbg:SetPoint("TOPLEFT", 8, -24) |
dialogbg:SetPoint("BOTTOMRIGHT", -6, 8) |
dialogbg:SetVertexColor(0, 0, 0, .75) |
local topleft = frame:CreateTexture(nil, "BORDER") |
topleft:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]]) |
topleft:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border |
topleft:SetWidth(64) |
topleft:SetHeight(64) |
topleft:SetPoint("TOPLEFT") |
topleft:SetTexCoord(0.501953125, 0.625, 0, 1) |
local topright = frame:CreateTexture(nil, "BORDER") |
topright:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]]) |
topright:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border |
topright:SetWidth(64) |
topright:SetHeight(64) |
topright:SetPoint("TOPRIGHT") |
topright:SetTexCoord(0.625, 0.75, 0, 1) |
local top = frame:CreateTexture(nil, "BORDER") |
top:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]]) |
top:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border |
top:SetHeight(64) |
top:SetPoint("TOPLEFT", topleft, "TOPRIGHT") |
top:SetPoint("TOPRIGHT", topright, "TOPLEFT") |
top:SetTexCoord(0.25, 0.369140625, 0, 1) |
local bottomleft = frame:CreateTexture(nil, "BORDER") |
bottomleft:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]]) |
bottomleft:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border |
bottomleft:SetWidth(64) |
bottomleft:SetHeight(64) |
bottomleft:SetPoint("BOTTOMLEFT") |
bottomleft:SetTexCoord(0.751953125, 0.875, 0, 1) |
local bottomright = frame:CreateTexture(nil, "BORDER") |
bottomright:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]]) |
bottomright:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border |
bottomright:SetWidth(64) |
bottomright:SetHeight(64) |
bottomright:SetPoint("BOTTOMRIGHT") |
bottomright:SetTexCoord(0.875, 1, 0, 1) |
local bottom = frame:CreateTexture(nil, "BORDER") |
bottom:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]]) |
bottom:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border |
bottom:SetHeight(64) |
bottom:SetPoint("BOTTOMLEFT", bottomleft, "BOTTOMRIGHT") |
bottom:SetPoint("BOTTOMRIGHT", bottomright, "BOTTOMLEFT") |
bottom:SetTexCoord(0.376953125, 0.498046875, 0, 1) |
local left = frame:CreateTexture(nil, "BORDER") |
left:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]]) |
left:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border |
left:SetWidth(64) |
left:SetPoint("TOPLEFT", topleft, "BOTTOMLEFT") |
left:SetPoint("BOTTOMLEFT", bottomleft, "TOPLEFT") |
left:SetTexCoord(0.001953125, 0.125, 0, 1) |
local right = frame:CreateTexture(nil, "BORDER") |
right:SetTexture([[Interface\PaperDollInfoFrame\UI-GearManager-Border]]) |
right:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border |
right:SetWidth(64) |
right:SetPoint("TOPRIGHT", topright, "BOTTOMRIGHT") |
right:SetPoint("BOTTOMRIGHT", bottomright, "TOPRIGHT") |
right:SetTexCoord(0.1171875, 0.2421875, 0, 1) |
local close = CreateFrame("Button", nil, frame, "UIPanelCloseButton") |
close:SetPoint("TOPRIGHT", 2, 1) |
close:SetScript("OnClick", closeOnClick) |
self.closebutton = close |
close.obj = self |
local titletext = frame:CreateFontString(nil, "ARTWORK") |
titletext:SetFontObject(GameFontNormal) |
titletext:SetPoint("TOPLEFT", 12, -8) |
titletext:SetPoint("TOPRIGHT", -32, -8) |
self.titletext = titletext |
local title = CreateFrame("Button", nil, frame) |
title:SetPoint("TOPLEFT", titlebg) |
title:SetPoint("BOTTOMRIGHT", titlebg) |
title:SetScript("OnMouseDown",titleOnMouseDown) |
title:SetScript("OnMouseUp", frameOnMouseUp) |
self.title = title |
local sizer_se = CreateFrame("Frame",nil,frame) |
sizer_se:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0) |
sizer_se:SetWidth(25) |
line1:SetWidth(14) |
line1:SetHeight(14) |
line1:SetPoint("BOTTOMRIGHT", -8, 8) |
line1:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border") |
line1:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border |
local x = 0.1 * 14/17 |
line1:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5) |
line2:SetWidth(8) |
line2:SetHeight(8) |
line2:SetPoint("BOTTOMRIGHT", -8, 8) |
line2:SetTexture("Interface\\Tooltips\\UI-Tooltip-Border") |
line2:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border |
local x = 0.1 * 8/17 |
line2:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5) |
sizer_s:SetScript("OnMouseDown",sizersOnMouseDown) |
sizer_s:SetScript("OnMouseUp", sizerOnMouseUp) |
self.sizer_s = sizer_s |
local sizer_e = CreateFrame("Frame",nil,frame) |
sizer_e:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,25) |
sizer_e:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0) |
sizer_e:SetScript("OnMouseDown",sizereOnMouseDown) |
sizer_e:SetScript("OnMouseUp", sizerOnMouseUp) |
self.sizer_e = sizer_e |
--Container Support |
local content = CreateFrame("Frame",nil,frame) |
self.content = content |
content.obj = self |
content:SetPoint("TOPLEFT",frame,"TOPLEFT",12,-32) |
content:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-12,13) |
AceGUI:RegisterAsContainer(self) |
return self |
return self |
end |
AceGUI:RegisterWidgetType(Type,Constructor,Version) |
end |
--- **AceGUI-3.0** provides access to numerous widgets which can be used to create GUIs. |
-- AceGUI is used by AceConfigDialog to create the option GUIs, but you can use it by itself |
-- to create any custom GUI. There are more extensive examples in the test suite in the Ace3 |
-- to create any custom GUI. There are more extensive examples in the test suite in the Ace3 |
-- stand-alone distribution. |
-- |
-- **Note**: When using AceGUI-3.0 directly, please do not modify the frames of the widgets directly, |
-- f:AddChild(btn) |
-- @class file |
-- @name AceGUI-3.0 |
-- @release $Id: AceGUI-3.0.lua 1177 2018-06-25 12:12:48Z nevcairiel $ |
local ACEGUI_MAJOR, ACEGUI_MINOR = "AceGUI-3.0", 36 |
-- @release $Id: AceGUI-3.0.lua 1231 2020-04-14 22:20:36Z nevcairiel $ |
local ACEGUI_MAJOR, ACEGUI_MINOR = "AceGUI-3.0", 41 |
local AceGUI, oldminor = LibStub:NewLibrary(ACEGUI_MAJOR, ACEGUI_MINOR) |
if not AceGUI then return end -- No upgrade needed |
-- Lua APIs |
local tconcat, tremove, tinsert = table.concat, table.remove, table.insert |
local tinsert = table.insert |
local select, pairs, next, type = select, pairs, next, type |
local error, assert, loadstring = error, assert, loadstring |
local setmetatable, rawget, rawset = setmetatable, rawget, rawset |
local error, assert = error, assert |
local setmetatable, rawget = setmetatable, rawget |
local math_max = math.max |
-- WoW APIs |
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") |
-- local upvalues |
local WidgetRegistry = AceGUI.WidgetRegistry |
local LayoutRegistry = AceGUI.LayoutRegistry |
return geterrorhandler()(err) |
end |
local function CreateDispatcher(argCount) |
local code = [[ |
local xpcall, eh = ... |
local method, ARGS |
local function call() return method(ARGS) end |
local function dispatch(func, ...) |
method = func |
if not method then return end |
ARGS = ... |
return xpcall(call, eh) |
end |
return dispatch |
]] |
local ARGS = {} |
for i = 1, argCount do ARGS[i] = "arg"..i end |
code = code:gsub("ARGS", tconcat(ARGS, ", ")) |
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler) |
end |
local Dispatchers = setmetatable({}, {__index=function(self, argCount) |
local dispatcher = CreateDispatcher(argCount) |
rawset(self, argCount, dispatcher) |
return dispatcher |
end}) |
Dispatchers[0] = function(func) |
return xpcall(func, errorhandler) |
end |
local function safecall(func, ...) |
return Dispatchers[select("#", ...)](func, ...) |
if func then |
return xpcall(func, errorhandler, ...) |
end |
end |
-- Recycling functions |
-- Internal Storage of the objects changed, from an array table |
-- to a hash table, and additionally we introduced versioning on |
-- the widgets which would discard all widgets from a pre-29 version |
-- anyway, so we just clear the storage now, and don't try to |
-- anyway, so we just clear the storage now, and don't try to |
-- convert the storage tables to the new format. |
-- This should generally not cause *many* widgets to end up in trash, |
-- since once dialogs are opened, all addons should be loaded already |
if oldminor and oldminor < 29 and AceGUI.objPools then |
AceGUI.objPools = nil |
end |
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 |
if not WidgetRegistry[type] then |
error("Attempt to instantiate unknown widget type", 2) |
end |
if not objPools[type] then |
objPools[type] = {} |
end |
local newObj = next(objPools[type]) |
if not newObj then |
newObj = WidgetRegistry[type]() |
widget.OnAcquire = widget.Aquire |
widget.Aquire = nil |
end |
if rawget(widget, "Release") then |
widget.OnRelease = rawget(widget, "Release") |
widget.OnRelease = rawget(widget, "Release") |
widget.Release = nil |
end |
if widget.OnAcquire then |
widget:OnAcquire() |
else |
-- If this widget is a Container-Widget, all of its Child-Widgets will be releases as well. |
-- @param widget The widget to release |
function AceGUI:Release(widget) |
if widget.isQueuedForRelease then return end |
widget.isQueuedForRelease = true |
safecall(widget.PauseLayout, widget) |
widget.frame:Hide() |
widget:Fire("OnRelease") |
safecall(widget.ReleaseChildren, widget) |
widget.content.width = nil |
widget.content.height = nil |
end |
widget.isQueuedForRelease = nil |
delWidget(widget, widget.type) |
end |
--- Check if a widget is currently in the process of being released |
-- This function check if this widget, or any of its parents (in which case it'll be released shortly as well) |
-- are currently being released. This allows addon to handle any callbacks accordingly. |
-- @param widget The widget to check |
function AceGUI:IsReleasing(widget) |
if widget.isQueuedForRelease then |
return true |
end |
if widget.parent and widget.parent.AceGUIWidgetVersion then |
return AceGUI:IsReleasing(widget.parent) |
end |
return false |
end |
----------- |
-- Focus -- |
----------- |
--[[ |
Widgets must provide the following functions |
OnAcquire() - Called when the object is acquired, should set everything to a default hidden state |
And the following members |
frame - the frame or derivitive object that will be treated as the widget for size and anchoring purposes |
type - the type of the object, same as the name given to :RegisterWidget() |
Widgets contain a table called userdata, this is a safe place to store data associated with the wigdet |
It will be cleared automatically when a widget is released |
Placing values directly into a widget object should be avoided |
If the Widget can act as a container for other Widgets the following |
content - frame or derivitive that children will be anchored to |
The Widget can supply the following Optional Members |
:OnRelease() - Called when the object is Released, should remove any additional anchors and clear any data |
:OnWidthSet(width) - Called when the width of the widget is changed |
-- Widget Base Template -- |
-------------------------- |
do |
local WidgetBase = AceGUI.WidgetBase |
local WidgetBase = AceGUI.WidgetBase |
WidgetBase.SetParent = function(self, parent) |
local frame = self.frame |
frame:SetParent(nil) |
frame:SetParent(parent.content) |
self.parent = parent |
end |
WidgetBase.SetCallback = function(self, name, func) |
if type(func) == "function" then |
self.events[name] = func |
end |
end |
WidgetBase.Fire = function(self, name, ...) |
if self.events[name] then |
local success, ret = safecall(self.events[name], self, name, ...) |
end |
end |
end |
WidgetBase.SetWidth = function(self, width) |
self.frame:SetWidth(width) |
self.frame.width = width |
self:OnWidthSet(width) |
end |
end |
WidgetBase.SetRelativeWidth = function(self, width) |
if width <= 0 or width > 1 then |
error(":SetRelativeWidth(width): Invalid relative width.", 2) |
self.relWidth = width |
self.width = "relative" |
end |
WidgetBase.SetHeight = function(self, height) |
self.frame:SetHeight(height) |
self.frame.height = height |
self:OnHeightSet(height) |
end |
end |
--[[ WidgetBase.SetRelativeHeight = function(self, height) |
if height <= 0 or height > 1 then |
error(":SetRelativeHeight(height): Invalid relative height.", 2) |
WidgetBase.IsVisible = function(self) |
return self.frame:IsVisible() |
end |
WidgetBase.IsShown= function(self) |
return self.frame:IsShown() |
end |
WidgetBase.Release = function(self) |
AceGUI:Release(self) |
end |
WidgetBase.IsReleasing = function(self) |
return AceGUI:IsReleasing(self) |
end |
WidgetBase.SetPoint = function(self, ...) |
return self.frame:SetPoint(...) |
end |
WidgetBase.ClearAllPoints = function(self) |
return self.frame:ClearAllPoints() |
end |
WidgetBase.GetNumPoints = function(self) |
return self.frame:GetNumPoints() |
end |
WidgetBase.GetPoint = function(self, ...) |
return self.frame:GetPoint(...) |
end |
end |
WidgetBase.GetUserDataTable = function(self) |
return self.userdata |
end |
WidgetBase.SetUserData = function(self, key, value) |
self.userdata[key] = value |
end |
WidgetBase.GetUserData = function(self, key) |
return self.userdata[key] |
end |
WidgetBase.IsFullHeight = function(self) |
return self.height == "fill" |
end |
WidgetBase.SetFullHeight = function(self, isFull) |
if isFull then |
self.height = "fill" |
self.height = nil |
end |
end |
WidgetBase.IsFullWidth = function(self) |
return self.width == "fill" |
end |
WidgetBase.SetFullWidth = function(self, isFull) |
if isFull then |
self.width = "fill" |
self.width = nil |
end |
end |
-- local function LayoutOnUpdate(this) |
-- this:SetScript("OnUpdate",nil) |
-- this.obj:PerformLayout() |
-- end |
local WidgetContainerBase = AceGUI.WidgetContainerBase |
WidgetContainerBase.PauseLayout = function(self) |
self.LayoutPaused = true |
end |
WidgetContainerBase.ResumeLayout = function(self) |
self.LayoutPaused = nil |
end |
WidgetContainerBase.PerformLayout = function(self) |
if self.LayoutPaused then |
return |
end |
safecall(self.LayoutFunc, self.content, self.children) |
end |
--call this function to layout, makes sure layed out objects get a frame to get sizes etc |
WidgetContainerBase.DoLayout = function(self) |
self:PerformLayout() |
-- self.frame:SetScript("OnUpdate", LayoutOnUpdate) |
-- end |
end |
WidgetContainerBase.AddChild = function(self, child, beforeWidget) |
if beforeWidget then |
local siblingIndex = 1 |
if widget == beforeWidget then |
break |
end |
siblingIndex = siblingIndex + 1 |
siblingIndex = siblingIndex + 1 |
end |
tinsert(self.children, siblingIndex, child) |
else |
child.frame:Show() |
self:DoLayout() |
end |
WidgetContainerBase.AddChildren = function(self, ...) |
for i = 1, select("#", ...) do |
local child = select(i, ...) |
end |
self:DoLayout() |
end |
WidgetContainerBase.ReleaseChildren = function(self) |
local children = self.children |
for i = 1,#children do |
children[i] = nil |
end |
end |
WidgetContainerBase.SetLayout = function(self, Layout) |
self.LayoutFunc = AceGUI:GetLayout(Layout) |
end |
end |
end |
end |
local function ContentResize(this) |
if this:GetWidth() and this:GetHeight() then |
this.width = this:GetWidth() |
setmetatable(WidgetContainerBase, {__index=WidgetBase}) |
--One of these function should be called on each Widget Instance as part of its creation process |
--- Register a widget-class as a container for newly created widgets. |
-- @param widget The widget class |
function AceGUI:RegisterAsContainer(widget) |
widget:SetLayout("List") |
return widget |
end |
--- Register a widget-class as a widget. |
-- @param widget The widget class |
function AceGUI:RegisterAsWidget(widget) |
-- @param Version The version of the widget |
function AceGUI:RegisterWidgetType(Name, Constructor, Version) |
assert(type(Constructor) == "function") |
assert(type(Version) == "number") |
assert(type(Version) == "number") |
local oldVersion = WidgetVersions[Name] |
if oldVersion and oldVersion >= Version then return end |
WidgetVersions[Name] = Version |
WidgetRegistry[Name] = Constructor |
end |
local width = content.width or content:GetWidth() or 0 |
for i = 1, #children do |
local child = children[i] |
local frame = child.frame |
frame:ClearAllPoints() |
frame:Show() |
else |
frame:SetPoint("TOPLEFT", children[i-1].frame, "BOTTOMLEFT") |
end |
if child.width == "fill" then |
child:SetWidth(width) |
frame:SetPoint("RIGHT", content) |
if child.DoLayout then |
child:DoLayout() |
end |
elseif child.width == "relative" then |
child:SetWidth(width * child.relWidth) |
if child.DoLayout then |
child:DoLayout() |
end |
end |
height = height + (frame.height or frame:GetHeight() or 0) |
end |
safecall(content.obj.LayoutFinished, content.obj, nil, height) |
if children[1] then |
children[1]:SetWidth(content:GetWidth() or 0) |
children[1]:SetHeight(content:GetHeight() or 0) |
children[1].frame:ClearAllPoints() |
children[1].frame:SetAllPoints(content) |
children[1].frame:Show() |
safecall(content.obj.LayoutFinished, content.obj, nil, children[1].frame:GetHeight()) |
--height of the current row |
local rowheight = 0 |
local rowoffset = 0 |
local lastrowoffset |
local width = content.width or content:GetWidth() or 0 |
--control at the start of the row |
local rowstart |
local rowstartoffset |
local lastrowstart |
local isfullheight |
local frameoffset |
local lastframeoffset |
local oversize |
local oversize |
for i = 1, #children do |
local child = children[i] |
oversize = nil |
local frameheight = frame.height or frame:GetHeight() or 0 |
local framewidth = frame.width or frame:GetWidth() or 0 |
lastframeoffset = frameoffset |
-- HACK: Why did we set a frameoffset of (frameheight / 2) ? |
-- HACK: Why did we set a frameoffset of (frameheight / 2) ? |
-- That was moving all widgets half the widgets size down, is that intended? |
-- Actually, it seems to be neccessary for many cases, we'll leave it in for now. |
-- If widgets seem to anchor weirdly with this, provide a valid alignoffset for them. |
-- TODO: Investigate moar! |
frameoffset = child.alignoffset or (frameheight / 2) |
if child.width == "relative" then |
framewidth = width * child.relWidth |
end |
frame:Show() |
frame:ClearAllPoints() |
if i == 1 then |
else |
--handles cases where the new height is higher than either control because of the offsets |
--math.max(rowheight-rowoffset+frameoffset, frameheight-frameoffset+rowoffset) |
--offset is always the larger of the two offsets |
rowoffset = math_max(rowoffset, frameoffset) |
rowheight = math_max(rowheight, rowoffset + (frameheight / 2)) |
frame:SetPoint("TOPLEFT", children[i-1].frame, "TOPRIGHT", 0, frameoffset - lastframeoffset) |
usedwidth = framewidth + usedwidth |
end |
if child.width == "fill" then |
safelayoutcall(child, "SetWidth", width) |
frame:SetPoint("RIGHT", content) |
usedwidth = 0 |
rowstart = frame |
rowstartoffset = frameoffset |
if child.DoLayout then |
child:DoLayout() |
end |
rowstartoffset = rowoffset |
elseif child.width == "relative" then |
safelayoutcall(child, "SetWidth", width * child.relWidth) |
if child.DoLayout then |
child:DoLayout() |
end |
frame:SetPoint("RIGHT", content) |
end |
end |
if child.height == "fill" then |
frame:SetPoint("BOTTOM", content) |
isfullheight = true |
end |
end |
--anchor the last row, if its full height needs a special case since its height has just been changed by the anchor |
if isfullheight then |
rowstart:SetPoint("TOPLEFT", content, "TOPLEFT", 0, -height) |
elseif rowstart then |
rowstart:SetPoint("TOPLEFT", content, "TOPLEFT", 0, -(height + (rowoffset - rowstartoffset) + 3)) |
end |
height = height + rowheight + 3 |
safecall(content.obj.LayoutFinished, content.obj, nil, height) |
end) |
local spaceH = tableObj.spaceH or tableObj.space or 0 |
local spaceV = tableObj.spaceV or tableObj.space or 0 |
local totalH = (content:GetWidth() or content.width or 0) - spaceH * (#cols - 1) |
-- We need to reuse these because layout events can come in very frequently |
local layoutCache = obj:GetUserData("layoutCache") |
if not layoutCache then |
obj:SetUserData("layoutCache", layoutCache) |
end |
local t, laneH, laneV, rowspans, rowStart, colStart = unpack(layoutCache) |
-- Create the grid |
local n, slotFound = 0 |
for i,child in ipairs(children) do |
local f = child.frame |
f:ClearAllPoints() |
local childH = f:GetWidth() or 0 |
laneH[col] = max(laneH[col], childH - GetCellDimension("H", laneH, colStart[child], col - 1, spaceH)) |
end |
end |
local cellObj = child:GetUserData("cell") |
local offsetH = GetCellDimension("H", laneH, 1, colStart[child] - 1, spaceH) + (colStart[child] == 1 and 0 or spaceH) |
local cellH = GetCellDimension("H", laneH, colStart[child], col, spaceH) |
local f = child.frame |
f:ClearAllPoints() |
local childH = f:GetWidth() or 0 |
if child:IsFullWidth() or alignFn == "fill" or childH > cellH then |
f:SetPoint("RIGHT", content, "LEFT", offsetH + align + cellH, 0) |
end |
if child.DoLayout then |
child:DoLayout() |
end |
local cellObj = child:GetUserData("cell") |
local offsetV = GetCellDimension("V", laneV, 1, rowStart[child] - 1, spaceV) + (rowStart[child] == 1 and 0 or spaceV) |
local cellV = GetCellDimension("V", laneV, rowStart[child], row, spaceV) |
local f = child.frame |
local childV = f:GetHeight() or 0 |
-- Calculate total height |
local totalV = GetCellDimension("V", laneV, 1, #laneV, spaceV) |
-- Cleanup |
for _,v in pairs(layoutCache) do wipe(v) end |