comparison Libs/AceGUI-3.0/widgets/AceGUIWidget-TabGroup.lua @ 0:169f5211fc7f

First public revision. At this point ItemAuditor watches mail for auctions sold or purchased, watches for buy/sell (money and 1 item type change) and conversions/tradeskills. Milling isn't working yet because there is too much time between the first event and the last event.
author Asa Ayers <Asa.Ayers@Gmail.com>
date Thu, 20 May 2010 19:22:19 -0700
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:169f5211fc7f
1 local AceGUI = LibStub("AceGUI-3.0")
2
3 -- Lua APIs
4 local pairs, ipairs, assert, type = pairs, ipairs, assert, type
5
6 -- WoW APIs
7 local CreateFrame, UIParent = CreateFrame, UIParent
8 local _G = _G
9
10 -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
11 -- List them here for Mikk's FindGlobals script
12 -- GLOBALS: PanelTemplates_TabResize, PanelTemplates_SetDisabledTabState, PanelTemplates_SelectTab, PanelTemplates_DeselectTab
13
14 -------------
15 -- Widgets --
16 -------------
17 --[[
18 Widgets must provide the following functions
19 Acquire() - Called when the object is aquired, should set everything to a default hidden state
20 Release() - Called when the object is Released, should remove any anchors and hide the Widget
21
22 And the following members
23 frame - the frame or derivitive object that will be treated as the widget for size and anchoring purposes
24 type - the type of the object, same as the name given to :RegisterWidget()
25
26 Widgets contain a table called userdata, this is a safe place to store data associated with the wigdet
27 It will be cleared automatically when a widget is released
28 Placing values directly into a widget object should be avoided
29
30 If the Widget can act as a container for other Widgets the following
31 content - frame or derivitive that children will be anchored to
32
33 The Widget can supply the following Optional Members
34
35
36 ]]
37
38 --------------------------
39 -- Tab Group --
40 --------------------------
41
42 do
43 local Type = "TabGroup"
44 local Version = 24
45
46 local PaneBackdrop = {
47 bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
48 edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
49 tile = true, tileSize = 16, edgeSize = 16,
50 insets = { left = 3, right = 3, top = 5, bottom = 3 }
51 }
52
53 local function OnAcquire(self)
54
55 end
56
57 local function OnRelease(self)
58 self.frame:ClearAllPoints()
59 self.frame:Hide()
60 self.status = nil
61 for k in pairs(self.localstatus) do
62 self.localstatus[k] = nil
63 end
64 self.tablist = nil
65 for _, tab in pairs(self.tabs) do
66 tab:Hide()
67 end
68 self:SetTitle()
69 end
70
71 local function Tab_SetText(self, text)
72 self:_SetText(text)
73 local width = self.obj.frame.width or self.obj.frame:GetWidth() or 0
74 PanelTemplates_TabResize(self, 0, nil, width)
75 end
76
77 local function UpdateTabLook(self)
78 if self.disabled then
79 PanelTemplates_SetDisabledTabState(self)
80 elseif self.selected then
81 PanelTemplates_SelectTab(self)
82 else
83 PanelTemplates_DeselectTab(self)
84 end
85 end
86
87 local function Tab_SetSelected(self, selected)
88 self.selected = selected
89 UpdateTabLook(self)
90 end
91
92 local function Tab_OnClick(self)
93 if not (self.selected or self.disabled) then
94 self.obj:SelectTab(self.value)
95 end
96 end
97
98 local function Tab_SetDisabled(self, disabled)
99 self.disabled = disabled
100 UpdateTabLook(self)
101 end
102
103 local function Tab_OnEnter(this)
104 local self = this.obj
105 self:Fire("OnTabEnter", self.tabs[this.id].value, this)
106 end
107
108 local function Tab_OnLeave(this)
109 local self = this.obj
110 self:Fire("OnTabLeave", self.tabs[this.id].value, this)
111 end
112
113 local function Tab_OnShow(this)
114 _G[this:GetName().."HighlightTexture"]:SetWidth(this:GetTextWidth() + 30)
115 end
116
117 local function CreateTab(self, id)
118 local tabname = "AceGUITabGroup"..self.num.."Tab"..id
119 local tab = CreateFrame("Button",tabname,self.border,"OptionsFrameTabButtonTemplate")
120 tab.obj = self
121 tab.id = id
122
123 tab.text = _G[tabname .. "Text"]
124 tab.text:ClearAllPoints()
125 tab.text:SetPoint("LEFT", tab, "LEFT", 14, -3)
126 tab.text:SetPoint("RIGHT", tab, "RIGHT", -12, -3)
127
128 tab:SetScript("OnClick",Tab_OnClick)
129 tab:SetScript("OnEnter",Tab_OnEnter)
130 tab:SetScript("OnLeave",Tab_OnLeave)
131 tab:SetScript("OnShow", Tab_OnShow)
132
133 tab._SetText = tab.SetText
134 tab.SetText = Tab_SetText
135 tab.SetSelected = Tab_SetSelected
136 tab.SetDisabled = Tab_SetDisabled
137
138 return tab
139 end
140
141 local function SetTitle(self, text)
142 self.titletext:SetText(text or "")
143 if text and text ~= "" then
144 self.alignoffset = 25
145 else
146 self.alignoffset = 18
147 end
148 self:BuildTabs()
149 end
150
151 -- called to set an external table to store status in
152 local function SetStatusTable(self, status)
153 assert(type(status) == "table")
154 self.status = status
155 end
156
157 local function SelectTab(self, value)
158 local status = self.status or self.localstatus
159
160 local found
161 for i, v in ipairs(self.tabs) do
162 if v.value == value then
163 v:SetSelected(true)
164 found = true
165 else
166 v:SetSelected(false)
167 end
168 end
169 status.selected = value
170 if found then
171 self:Fire("OnGroupSelected",value)
172 end
173 end
174
175 local function SetTabs(self, tabs)
176 self.tablist = tabs
177 self:BuildTabs()
178 end
179
180
181 local widths = {}
182 local rowwidths = {}
183 local rowends = {}
184 local function BuildTabs(self)
185 local hastitle = (self.titletext:GetText() and self.titletext:GetText() ~= "")
186 local status = self.status or self.localstatus
187 local tablist = self.tablist
188 local tabs = self.tabs
189
190 if not tablist then return end
191
192 local width = self.frame.width or self.frame:GetWidth() or 0
193
194 for i = #widths, 1, -1 do
195 widths[i] = nil
196 end
197 for i = #rowwidths, 1, -1 do
198 rowwidths[i] = nil
199 end
200 for i = #rowends, 1, -1 do
201 rowends[i] = nil
202 end
203
204 --Place Text into tabs and get thier initial width
205 for i, v in ipairs(tablist) do
206 local tab = tabs[i]
207 if not tab then
208 tab = self:CreateTab(i)
209 tabs[i] = tab
210 end
211
212 tab:Show()
213 tab:SetText(v.text)
214 tab:SetDisabled(v.disabled)
215 tab.value = v.value
216
217 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
218 end
219
220 for i = (#tablist)+1, #tabs, 1 do
221 tabs[i]:Hide()
222 end
223
224 --First pass, find the minimum number of rows needed to hold all tabs and the initial tab layout
225 local numtabs = #tablist
226 local numrows = 1
227 local usedwidth = 0
228
229 for i = 1, #tablist do
230 --If this is not the first tab of a row and there isn't room for it
231 if usedwidth ~= 0 and (width - usedwidth - widths[i]) < 0 then
232 rowwidths[numrows] = usedwidth + 10 --first tab in each row takes up an extra 10px
233 rowends[numrows] = i - 1
234 numrows = numrows + 1
235 usedwidth = 0
236 end
237 usedwidth = usedwidth + widths[i]
238 end
239 rowwidths[numrows] = usedwidth + 10 --first tab in each row takes up an extra 10px
240 rowends[numrows] = #tablist
241
242 --Fix for single tabs being left on the last row, move a tab from the row above if applicable
243 if numrows > 1 then
244 --if the last row has only one tab
245 if rowends[numrows-1] == numtabs-1 then
246 --if there are more than 2 tabs in the 2nd last row
247 if (numrows == 2 and rowends[numrows-1] > 2) or (rowends[numrows] - rowends[numrows-1] > 2) then
248 --move 1 tab from the second last row to the last, if there is enough space
249 if (rowwidths[numrows] + widths[numtabs-1]) <= width then
250 rowends[numrows-1] = rowends[numrows-1] - 1
251 rowwidths[numrows] = rowwidths[numrows] + widths[numtabs-1]
252 rowwidths[numrows-1] = rowwidths[numrows-1] - widths[numtabs-1]
253 end
254 end
255 end
256 end
257
258 --anchor the rows as defined and resize tabs to fill thier row
259 local starttab = 1
260 for row, endtab in ipairs(rowends) do
261 local first = true
262 for tabno = starttab, endtab do
263 local tab = tabs[tabno]
264 tab:ClearAllPoints()
265 if first then
266 tab:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 0, -(hastitle and 14 or 7)-(row-1)*20 )
267 first = false
268 else
269 tab:SetPoint("LEFT", tabs[tabno-1], "RIGHT", -10, 0)
270 end
271 end
272
273 -- equal padding for each tab to fill the available width,
274 -- if the used space is above 75% already
275 local padding = 0
276 if not (numrows == 1 and rowwidths[1] < width*0.75) then
277 padding = (width - rowwidths[row]) / (endtab - starttab+1)
278 end
279
280 for i = starttab, endtab do
281 PanelTemplates_TabResize(tabs[i], padding + 4, nil, width)
282 end
283 starttab = endtab + 1
284 end
285
286 self.borderoffset = (hastitle and 17 or 10)+((numrows)*20)
287 self.border:SetPoint("TOPLEFT",self.frame,"TOPLEFT",1,-self.borderoffset)
288 end
289
290 local function BuildTabsOnUpdate(this)
291 BuildTabs(this.obj)
292 this:SetScript("OnUpdate", nil)
293 end
294
295 local function OnWidthSet(self, width)
296 local content = self.content
297 local contentwidth = width - 60
298 if contentwidth < 0 then
299 contentwidth = 0
300 end
301 content:SetWidth(contentwidth)
302 content.width = contentwidth
303 BuildTabs(self)
304 self.frame:SetScript("OnUpdate", BuildTabsOnUpdate)
305 end
306
307
308 local function OnHeightSet(self, height)
309 local content = self.content
310 local contentheight = height - (self.borderoffset + 23)
311 if contentheight < 0 then
312 contentheight = 0
313 end
314 content:SetHeight(contentheight)
315 content.height = contentheight
316 end
317
318 local function LayoutFinished(self, width, height)
319 if self.noAutoHeight then return end
320 self:SetHeight((height or 0) + (self.borderoffset + 23))
321 end
322
323 local function Constructor()
324 local frame = CreateFrame("Frame",nil,UIParent)
325 local self = {}
326 self.type = Type
327
328 self.num = AceGUI:GetNextWidgetNum(Type)
329
330 self.localstatus = {}
331
332 self.OnRelease = OnRelease
333 self.OnAcquire = OnAcquire
334 self.SetTitle = SetTitle
335 self.CreateTab = CreateTab
336 self.SelectTab = SelectTab
337 self.BuildTabs = BuildTabs
338 self.SetStatusTable = SetStatusTable
339 self.SetTabs = SetTabs
340 self.LayoutFinished = LayoutFinished
341 self.frame = frame
342
343 self.OnWidthSet = OnWidthSet
344 self.OnHeightSet = OnHeightSet
345
346 frame.obj = self
347
348 frame:SetHeight(100)
349 frame:SetWidth(100)
350 frame:SetFrameStrata("FULLSCREEN_DIALOG")
351
352 self.alignoffset = 18
353
354 local titletext = frame:CreateFontString(nil,"OVERLAY","GameFontNormal")
355 titletext:SetPoint("TOPLEFT",frame,"TOPLEFT",14,0)
356 titletext:SetPoint("TOPRIGHT",frame,"TOPRIGHT",-14,0)
357 titletext:SetJustifyH("LEFT")
358 titletext:SetHeight(18)
359 titletext:SetText("")
360
361 self.titletext = titletext
362
363 local border = CreateFrame("Frame",nil,frame)
364 self.border = border
365 self.borderoffset = 27
366 border:SetPoint("TOPLEFT",frame,"TOPLEFT",1,-27)
367 border:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-1,3)
368
369 border:SetBackdrop(PaneBackdrop)
370 border:SetBackdropColor(0.1,0.1,0.1,0.5)
371 border:SetBackdropBorderColor(0.4,0.4,0.4)
372
373 self.tabs = {}
374
375 --Container Support
376 local content = CreateFrame("Frame",nil,border)
377 self.content = content
378 content.obj = self
379 content:SetPoint("TOPLEFT",border,"TOPLEFT",10,-7)
380 content:SetPoint("BOTTOMRIGHT",border,"BOTTOMRIGHT",-10,7)
381
382 AceGUI:RegisterAsContainer(self)
383 return self
384 end
385
386 AceGUI:RegisterWidgetType(Type,Constructor,Version)
387 end