Mercurial > wow > itemauditor
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 |
