annotate Libs/AceGUI-3.0/widgets/AceGUIContainer-TabGroup.lua @ 6:f10c8a083d2a

The ALPHA help request popup should pop when the addon is enabled for every 15th time. I really would like some data to. The timer to start opening mail when you open the mailbox will now use the initial mail opening delay.
author Zerotorescue
date Wed, 08 Sep 2010 00:48:37 +0200
parents 823e33465b6e
children
rev   line source
Zerotorescue@0 1 --[[-----------------------------------------------------------------------------
Zerotorescue@0 2 TabGroup Container
Zerotorescue@0 3 Container that uses tabs on top to switch between groups.
Zerotorescue@0 4 -------------------------------------------------------------------------------]]
Zerotorescue@0 5 local Type, Version = "TabGroup", 30
Zerotorescue@0 6 local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
Zerotorescue@0 7 if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
Zerotorescue@0 8
Zerotorescue@0 9 -- Lua APIs
Zerotorescue@0 10 local pairs, ipairs, assert, type, wipe = pairs, ipairs, assert, type, wipe
Zerotorescue@0 11
Zerotorescue@0 12 -- WoW APIs
Zerotorescue@0 13 local PlaySound = PlaySound
Zerotorescue@0 14 local CreateFrame, UIParent = CreateFrame, UIParent
Zerotorescue@0 15 local _G = _G
Zerotorescue@0 16
Zerotorescue@0 17 -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
Zerotorescue@0 18 -- List them here for Mikk's FindGlobals script
Zerotorescue@0 19 -- GLOBALS: PanelTemplates_TabResize, PanelTemplates_SetDisabledTabState, PanelTemplates_SelectTab, PanelTemplates_DeselectTab
Zerotorescue@0 20
Zerotorescue@0 21 -- local upvalue storage used by BuildTabs
Zerotorescue@0 22 local widths = {}
Zerotorescue@0 23 local rowwidths = {}
Zerotorescue@0 24 local rowends = {}
Zerotorescue@0 25
Zerotorescue@0 26 --[[-----------------------------------------------------------------------------
Zerotorescue@0 27 Support functions
Zerotorescue@0 28 -------------------------------------------------------------------------------]]
Zerotorescue@0 29 local function UpdateTabLook(frame)
Zerotorescue@0 30 if frame.disabled then
Zerotorescue@0 31 PanelTemplates_SetDisabledTabState(frame)
Zerotorescue@0 32 elseif frame.selected then
Zerotorescue@0 33 PanelTemplates_SelectTab(frame)
Zerotorescue@0 34 else
Zerotorescue@0 35 PanelTemplates_DeselectTab(frame)
Zerotorescue@0 36 end
Zerotorescue@0 37 end
Zerotorescue@0 38
Zerotorescue@0 39 local function Tab_SetText(frame, text)
Zerotorescue@0 40 frame:_SetText(text)
Zerotorescue@0 41 local width = frame.obj.frame.width or frame.obj.frame:GetWidth() or 0
Zerotorescue@0 42 PanelTemplates_TabResize(frame, 0, nil, width)
Zerotorescue@0 43 end
Zerotorescue@0 44
Zerotorescue@0 45 local function Tab_SetSelected(frame, selected)
Zerotorescue@0 46 frame.selected = selected
Zerotorescue@0 47 UpdateTabLook(frame)
Zerotorescue@0 48 end
Zerotorescue@0 49
Zerotorescue@0 50 local function Tab_SetDisabled(frame, disabled)
Zerotorescue@0 51 frame.disabled = disabled
Zerotorescue@0 52 UpdateTabLook(frame)
Zerotorescue@0 53 end
Zerotorescue@0 54
Zerotorescue@0 55 local function BuildTabsOnUpdate(frame)
Zerotorescue@0 56 local self = frame.obj
Zerotorescue@0 57 self:BuildTabs()
Zerotorescue@0 58 frame:SetScript("OnUpdate", nil)
Zerotorescue@0 59 end
Zerotorescue@0 60
Zerotorescue@0 61 --[[-----------------------------------------------------------------------------
Zerotorescue@0 62 Scripts
Zerotorescue@0 63 -------------------------------------------------------------------------------]]
Zerotorescue@0 64 local function Tab_OnClick(frame)
Zerotorescue@0 65 if not (frame.selected or frame.disabled) then
Zerotorescue@0 66 PlaySound("igCharacterInfoTab")
Zerotorescue@0 67 frame.obj:SelectTab(frame.value)
Zerotorescue@0 68 end
Zerotorescue@0 69 end
Zerotorescue@0 70
Zerotorescue@0 71 local function Tab_OnEnter(frame)
Zerotorescue@0 72 local self = frame.obj
Zerotorescue@0 73 self:Fire("OnTabEnter", self.tabs[frame.id].value, frame)
Zerotorescue@0 74 end
Zerotorescue@0 75
Zerotorescue@0 76 local function Tab_OnLeave(frame)
Zerotorescue@0 77 local self = frame.obj
Zerotorescue@0 78 self:Fire("OnTabLeave", self.tabs[frame.id].value, frame)
Zerotorescue@0 79 end
Zerotorescue@0 80
Zerotorescue@0 81 local function Tab_OnShow(frame)
Zerotorescue@0 82 _G[frame:GetName().."HighlightTexture"]:SetWidth(frame:GetTextWidth() + 30)
Zerotorescue@0 83 end
Zerotorescue@0 84
Zerotorescue@0 85 --[[-----------------------------------------------------------------------------
Zerotorescue@0 86 Methods
Zerotorescue@0 87 -------------------------------------------------------------------------------]]
Zerotorescue@0 88 local methods = {
Zerotorescue@0 89 ["OnAcquire"] = function(self)
Zerotorescue@0 90 self:SetTitle()
Zerotorescue@0 91 end,
Zerotorescue@0 92
Zerotorescue@0 93 ["OnRelease"] = function(self)
Zerotorescue@0 94 self.status = nil
Zerotorescue@0 95 for k in pairs(self.localstatus) do
Zerotorescue@0 96 self.localstatus[k] = nil
Zerotorescue@0 97 end
Zerotorescue@0 98 self.tablist = nil
Zerotorescue@0 99 for _, tab in pairs(self.tabs) do
Zerotorescue@0 100 tab:Hide()
Zerotorescue@0 101 end
Zerotorescue@0 102 end,
Zerotorescue@0 103
Zerotorescue@0 104 ["CreateTab"] = function(self, id)
Zerotorescue@0 105 local tabname = ("AceGUITabGroup%dTab%d"):format(self.num, id)
Zerotorescue@0 106 local tab = CreateFrame("Button", tabname, self.border, "OptionsFrameTabButtonTemplate")
Zerotorescue@0 107 tab.obj = self
Zerotorescue@0 108 tab.id = id
Zerotorescue@0 109
Zerotorescue@0 110 tab.text = _G[tabname .. "Text"]
Zerotorescue@0 111 tab.text:ClearAllPoints()
Zerotorescue@0 112 tab.text:SetPoint("LEFT", 14, -3)
Zerotorescue@0 113 tab.text:SetPoint("RIGHT", -12, -3)
Zerotorescue@0 114
Zerotorescue@0 115 tab:SetScript("OnClick", Tab_OnClick)
Zerotorescue@0 116 tab:SetScript("OnEnter", Tab_OnEnter)
Zerotorescue@0 117 tab:SetScript("OnLeave", Tab_OnLeave)
Zerotorescue@0 118 tab:SetScript("OnShow", Tab_OnShow)
Zerotorescue@0 119
Zerotorescue@0 120 tab._SetText = tab.SetText
Zerotorescue@0 121 tab.SetText = Tab_SetText
Zerotorescue@0 122 tab.SetSelected = Tab_SetSelected
Zerotorescue@0 123 tab.SetDisabled = Tab_SetDisabled
Zerotorescue@0 124
Zerotorescue@0 125 return tab
Zerotorescue@0 126 end,
Zerotorescue@0 127
Zerotorescue@0 128 ["SetTitle"] = function(self, text)
Zerotorescue@0 129 self.titletext:SetText(text or "")
Zerotorescue@0 130 if text and text ~= "" then
Zerotorescue@0 131 self.alignoffset = 25
Zerotorescue@0 132 else
Zerotorescue@0 133 self.alignoffset = 18
Zerotorescue@0 134 end
Zerotorescue@0 135 self:BuildTabs()
Zerotorescue@0 136 end,
Zerotorescue@0 137
Zerotorescue@0 138 ["SetStatusTable"] = function(self, status)
Zerotorescue@0 139 assert(type(status) == "table")
Zerotorescue@0 140 self.status = status
Zerotorescue@0 141 end,
Zerotorescue@0 142
Zerotorescue@0 143 ["SelectTab"] = function(self, value)
Zerotorescue@0 144 local status = self.status or self.localstatus
Zerotorescue@0 145 local found
Zerotorescue@0 146 for i, v in ipairs(self.tabs) do
Zerotorescue@0 147 if v.value == value then
Zerotorescue@0 148 v:SetSelected(true)
Zerotorescue@0 149 found = true
Zerotorescue@0 150 else
Zerotorescue@0 151 v:SetSelected(false)
Zerotorescue@0 152 end
Zerotorescue@0 153 end
Zerotorescue@0 154 status.selected = value
Zerotorescue@0 155 if found then
Zerotorescue@0 156 self:Fire("OnGroupSelected",value)
Zerotorescue@0 157 end
Zerotorescue@0 158 end,
Zerotorescue@0 159
Zerotorescue@0 160 ["SetTabs"] = function(self, tabs)
Zerotorescue@0 161 self.tablist = tabs
Zerotorescue@0 162 self:BuildTabs()
Zerotorescue@0 163 end,
Zerotorescue@0 164
Zerotorescue@0 165
Zerotorescue@0 166 ["BuildTabs"] = function(self)
Zerotorescue@0 167 local hastitle = (self.titletext:GetText() and self.titletext:GetText() ~= "")
Zerotorescue@0 168 local status = self.status or self.localstatus
Zerotorescue@0 169 local tablist = self.tablist
Zerotorescue@0 170 local tabs = self.tabs
Zerotorescue@0 171
Zerotorescue@0 172 if not tablist then return end
Zerotorescue@0 173
Zerotorescue@0 174 local width = self.frame.width or self.frame:GetWidth() or 0
Zerotorescue@0 175
Zerotorescue@0 176 wipe(widths)
Zerotorescue@0 177 wipe(rowwidths)
Zerotorescue@0 178 wipe(rowends)
Zerotorescue@0 179
Zerotorescue@0 180 --Place Text into tabs and get thier initial width
Zerotorescue@0 181 for i, v in ipairs(tablist) do
Zerotorescue@0 182 local tab = tabs[i]
Zerotorescue@0 183 if not tab then
Zerotorescue@0 184 tab = self:CreateTab(i)
Zerotorescue@0 185 tabs[i] = tab
Zerotorescue@0 186 end
Zerotorescue@0 187
Zerotorescue@0 188 tab:Show()
Zerotorescue@0 189 tab:SetText(v.text)
Zerotorescue@0 190 tab:SetDisabled(v.disabled)
Zerotorescue@0 191 tab.value = v.value
Zerotorescue@0 192
Zerotorescue@0 193 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
Zerotorescue@0 194 end
Zerotorescue@0 195
Zerotorescue@0 196 for i = (#tablist)+1, #tabs, 1 do
Zerotorescue@0 197 tabs[i]:Hide()
Zerotorescue@0 198 end
Zerotorescue@0 199
Zerotorescue@0 200 --First pass, find the minimum number of rows needed to hold all tabs and the initial tab layout
Zerotorescue@0 201 local numtabs = #tablist
Zerotorescue@0 202 local numrows = 1
Zerotorescue@0 203 local usedwidth = 0
Zerotorescue@0 204
Zerotorescue@0 205 for i = 1, #tablist do
Zerotorescue@0 206 --If this is not the first tab of a row and there isn't room for it
Zerotorescue@0 207 if usedwidth ~= 0 and (width - usedwidth - widths[i]) < 0 then
Zerotorescue@0 208 rowwidths[numrows] = usedwidth + 10 --first tab in each row takes up an extra 10px
Zerotorescue@0 209 rowends[numrows] = i - 1
Zerotorescue@0 210 numrows = numrows + 1
Zerotorescue@0 211 usedwidth = 0
Zerotorescue@0 212 end
Zerotorescue@0 213 usedwidth = usedwidth + widths[i]
Zerotorescue@0 214 end
Zerotorescue@0 215 rowwidths[numrows] = usedwidth + 10 --first tab in each row takes up an extra 10px
Zerotorescue@0 216 rowends[numrows] = #tablist
Zerotorescue@0 217
Zerotorescue@0 218 --Fix for single tabs being left on the last row, move a tab from the row above if applicable
Zerotorescue@0 219 if numrows > 1 then
Zerotorescue@0 220 --if the last row has only one tab
Zerotorescue@0 221 if rowends[numrows-1] == numtabs-1 then
Zerotorescue@0 222 --if there are more than 2 tabs in the 2nd last row
Zerotorescue@0 223 if (numrows == 2 and rowends[numrows-1] > 2) or (rowends[numrows] - rowends[numrows-1] > 2) then
Zerotorescue@0 224 --move 1 tab from the second last row to the last, if there is enough space
Zerotorescue@0 225 if (rowwidths[numrows] + widths[numtabs-1]) <= width then
Zerotorescue@0 226 rowends[numrows-1] = rowends[numrows-1] - 1
Zerotorescue@0 227 rowwidths[numrows] = rowwidths[numrows] + widths[numtabs-1]
Zerotorescue@0 228 rowwidths[numrows-1] = rowwidths[numrows-1] - widths[numtabs-1]
Zerotorescue@0 229 end
Zerotorescue@0 230 end
Zerotorescue@0 231 end
Zerotorescue@0 232 end
Zerotorescue@0 233
Zerotorescue@0 234 --anchor the rows as defined and resize tabs to fill thier row
Zerotorescue@0 235 local starttab = 1
Zerotorescue@0 236 for row, endtab in ipairs(rowends) do
Zerotorescue@0 237 local first = true
Zerotorescue@0 238 for tabno = starttab, endtab do
Zerotorescue@0 239 local tab = tabs[tabno]
Zerotorescue@0 240 tab:ClearAllPoints()
Zerotorescue@0 241 if first then
Zerotorescue@0 242 tab:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 0, -(hastitle and 14 or 7)-(row-1)*20 )
Zerotorescue@0 243 first = false
Zerotorescue@0 244 else
Zerotorescue@0 245 tab:SetPoint("LEFT", tabs[tabno-1], "RIGHT", -10, 0)
Zerotorescue@0 246 end
Zerotorescue@0 247 end
Zerotorescue@0 248
Zerotorescue@0 249 -- equal padding for each tab to fill the available width,
Zerotorescue@0 250 -- if the used space is above 75% already
Zerotorescue@0 251 local padding = 0
Zerotorescue@0 252 if not (numrows == 1 and rowwidths[1] < width*0.75) then
Zerotorescue@0 253 padding = (width - rowwidths[row]) / (endtab - starttab+1)
Zerotorescue@0 254 end
Zerotorescue@0 255
Zerotorescue@0 256 for i = starttab, endtab do
Zerotorescue@0 257 PanelTemplates_TabResize(tabs[i], padding + 4, nil, width)
Zerotorescue@0 258 end
Zerotorescue@0 259 starttab = endtab + 1
Zerotorescue@0 260 end
Zerotorescue@0 261
Zerotorescue@0 262 self.borderoffset = (hastitle and 17 or 10)+((numrows)*20)
Zerotorescue@0 263 self.border:SetPoint("TOPLEFT", 1, -self.borderoffset)
Zerotorescue@0 264 end,
Zerotorescue@0 265
Zerotorescue@0 266 ["OnWidthSet"] = function(self, width)
Zerotorescue@0 267 local content = self.content
Zerotorescue@0 268 local contentwidth = width - 60
Zerotorescue@0 269 if contentwidth < 0 then
Zerotorescue@0 270 contentwidth = 0
Zerotorescue@0 271 end
Zerotorescue@0 272 content:SetWidth(contentwidth)
Zerotorescue@0 273 content.width = contentwidth
Zerotorescue@0 274 self:BuildTabs(self)
Zerotorescue@0 275 self.frame:SetScript("OnUpdate", BuildTabsOnUpdate)
Zerotorescue@0 276 end,
Zerotorescue@0 277
Zerotorescue@0 278 ["OnHeightSet"] = function(self, height)
Zerotorescue@0 279 local content = self.content
Zerotorescue@0 280 local contentheight = height - (self.borderoffset + 23)
Zerotorescue@0 281 if contentheight < 0 then
Zerotorescue@0 282 contentheight = 0
Zerotorescue@0 283 end
Zerotorescue@0 284 content:SetHeight(contentheight)
Zerotorescue@0 285 content.height = contentheight
Zerotorescue@0 286 end,
Zerotorescue@0 287
Zerotorescue@0 288 ["LayoutFinished"] = function(self, width, height)
Zerotorescue@0 289 if self.noAutoHeight then return end
Zerotorescue@0 290 self:SetHeight((height or 0) + (self.borderoffset + 23))
Zerotorescue@0 291 end
Zerotorescue@0 292 }
Zerotorescue@0 293
Zerotorescue@0 294 --[[-----------------------------------------------------------------------------
Zerotorescue@0 295 Constructor
Zerotorescue@0 296 -------------------------------------------------------------------------------]]
Zerotorescue@0 297 local PaneBackdrop = {
Zerotorescue@0 298 bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
Zerotorescue@0 299 edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
Zerotorescue@0 300 tile = true, tileSize = 16, edgeSize = 16,
Zerotorescue@0 301 insets = { left = 3, right = 3, top = 5, bottom = 3 }
Zerotorescue@0 302 }
Zerotorescue@0 303
Zerotorescue@0 304 local function Constructor()
Zerotorescue@0 305 local num = AceGUI:GetNextWidgetNum(Type)
Zerotorescue@0 306 local frame = CreateFrame("Frame",nil,UIParent)
Zerotorescue@0 307 frame:SetHeight(100)
Zerotorescue@0 308 frame:SetWidth(100)
Zerotorescue@0 309 frame:SetFrameStrata("FULLSCREEN_DIALOG")
Zerotorescue@0 310
Zerotorescue@0 311 local titletext = frame:CreateFontString(nil,"OVERLAY","GameFontNormal")
Zerotorescue@0 312 titletext:SetPoint("TOPLEFT", 14, 0)
Zerotorescue@0 313 titletext:SetPoint("TOPRIGHT", -14, 0)
Zerotorescue@0 314 titletext:SetJustifyH("LEFT")
Zerotorescue@0 315 titletext:SetHeight(18)
Zerotorescue@0 316 titletext:SetText("")
Zerotorescue@0 317
Zerotorescue@0 318 local border = CreateFrame("Frame", nil, frame)
Zerotorescue@0 319 border:SetPoint("TOPLEFT", 1, -27)
Zerotorescue@0 320 border:SetPoint("BOTTOMRIGHT", -1, 3)
Zerotorescue@0 321 border:SetBackdrop(PaneBackdrop)
Zerotorescue@0 322 border:SetBackdropColor(0.1, 0.1, 0.1, 0.5)
Zerotorescue@0 323 border:SetBackdropBorderColor(0.4, 0.4, 0.4)
Zerotorescue@0 324
Zerotorescue@0 325 local content = CreateFrame("Frame", nil, border)
Zerotorescue@0 326 content:SetPoint("TOPLEFT", 10, -7)
Zerotorescue@0 327 content:SetPoint("BOTTOMRIGHT", -10, 7)
Zerotorescue@0 328
Zerotorescue@0 329 local widget = {
Zerotorescue@0 330 num = num,
Zerotorescue@0 331 frame = frame,
Zerotorescue@0 332 localstatus = {},
Zerotorescue@0 333 alignoffset = 18,
Zerotorescue@0 334 titletext = titletext,
Zerotorescue@0 335 border = border,
Zerotorescue@0 336 borderoffset = 27,
Zerotorescue@0 337 tabs = {},
Zerotorescue@0 338 content = content,
Zerotorescue@0 339 type = Type
Zerotorescue@0 340 }
Zerotorescue@0 341 for method, func in pairs(methods) do
Zerotorescue@0 342 widget[method] = func
Zerotorescue@0 343 end
Zerotorescue@0 344
Zerotorescue@0 345 return AceGUI:RegisterAsContainer(widget)
Zerotorescue@0 346 end
Zerotorescue@0 347
Zerotorescue@0 348 AceGUI:RegisterWidgetType(Type, Constructor, Version)