Mercurial > wow > askmrrobot
diff ui/AmrUiTabGroup.lua @ 57:01b63b8ed811 v21
total rewrite to version 21
author | yellowfive |
---|---|
date | Fri, 05 Jun 2015 11:05:15 -0700 |
parents | |
children | 0515882856f1 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/AmrUiTabGroup.lua Fri Jun 05 11:05:15 2015 -0700 @@ -0,0 +1,266 @@ +--[[----------------------------------------------------------------------------- +AMR TabGroup Container +Container that uses tabs on top to switch between groups. +This is adapted from AceGUIContainer-TabGroup, but has a custom look. +-------------------------------------------------------------------------------]] +local Type, Version = "AmrUiTabGroup", 1 +local AceGUI = LibStub and LibStub("AceGUI-3.0", true) +if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end + +local Amr = LibStub("AceAddon-3.0"):GetAddon("AskMrRobot") + +-- Lua APIs +local pairs, ipairs, assert, type, wipe = pairs, ipairs, assert, type, wipe + +-- WoW APIs +local PlaySound = PlaySound +local CreateFrame, UIParent = CreateFrame, UIParent +local _G = _G + + +--[[----------------------------------------------------------------------------- +Support functions +-------------------------------------------------------------------------------]] + +local function tabSetSelected(frame, selected) + frame.selected = selected +end + +local function tabSetDisabled(frame, disabled) + frame.disabled = disabled +end + +local function buildTabsOnUpdate(frame) + local self = frame.obj + self:BuildTabs() + frame:SetScript("OnUpdate", nil) +end + + +--[[----------------------------------------------------------------------------- +Scripts +-------------------------------------------------------------------------------]] +local function tabOnClick(frame) + if not (frame.selected or frame.disabled) then + PlaySound("igCharacterInfoTab") + frame.obj:SelectTab(frame.value) + end +end + + +--[[----------------------------------------------------------------------------- +Methods +-------------------------------------------------------------------------------]] +local methods = { + ["OnAcquire"] = function(self) + self.tabSelector:Hide() + self.frame:ClearAllPoints() + end, + + ["OnRelease"] = function(self) + self.status = nil + for k in pairs(self.localstatus) do + self.localstatus[k] = nil + end + self.tablist = nil + for _, tab in pairs(self.tabs) do + tab:Hide() + end + self.tabSelector:Hide() + end, + + ["CreateTab"] = function(self, id, style) + local tabname = ("AmrUiTabGroup%dTab%d"):format(self.num, id) + + local tab = CreateFrame("Button", tabname, self.border) + tab.obj = self + tab.id = id + + if style == "bold" then + tab:SetNormalFontObject(Amr.CreateFont("Regular", 24, Amr.Colors.TextHeaderDisabled)) + tab:SetHighlightFontObject(Amr.CreateFont("Regular", 24, Amr.Colors.TextHover)) + else + tab:SetNormalFontObject(Amr.CreateFont("Regular", 28, Amr.Colors.Text)) + tab:SetHighlightFontObject(Amr.CreateFont("Regular", 28, Amr.Colors.TextHover)) + end + + tab:SetScript("OnClick", tabOnClick) + + tab.SetSelected = tabSetSelected + tab.SetDisabled = tabSetDisabled + + return tab + end, + + ["SetStatusTable"] = function(self, status) + assert(type(status) == "table") + self.status = status + end, + + ["SelectTab"] = function(self, value) + local status = self.status or self.localstatus + + self.tabSelector:Hide() + + local found + for i, v in ipairs(self.tabs) do + if v.value == value then + v:SetSelected(true) + found = true + + -- show the tab selector under the proper tab + if v.style == "underline" then + self.tabSelector:SetWidth(v:GetWidth()) + self.tabSelector:ClearAllPoints() + self.tabSelector:SetPoint("TOPLEFT", v, "BOTTOMLEFT", 0, -2) + self.tabSelector:Show() + v:SetNormalFontObject(Amr.CreateFont("Regular", 28, Amr.Colors.Text)) + v:SetHighlightFontObject(Amr.CreateFont("Regular", 28, Amr.Colors.Text)) + elseif v.style == "bold" then + v:SetNormalFontObject(Amr.CreateFont("Bold", 28, Amr.Colors.TextHeaderActive)) + v:SetHighlightFontObject(Amr.CreateFont("Bold", 28, Amr.Colors.TextHeaderActive)) + end + else + v:SetSelected(false) + if v.style == "bold" then + v:SetNormalFontObject(Amr.CreateFont("Regular", 24, Amr.Colors.TextHeaderDisabled)) + v:SetHighlightFontObject(Amr.CreateFont("Regular", 24, Amr.Colors.TextHover)) + else + v:SetNormalFontObject(Amr.CreateFont("Regular", 28, Amr.Colors.Text)) + v:SetHighlightFontObject(Amr.CreateFont("Regular", 28, Amr.Colors.TextHover)) + end + end + end + status.selected = value + + -- call this to reposition after style change + self:BuildTabs() + + if found then + self:Fire("OnGroupSelected",value) + end + end, + + ["SetTabs"] = function(self, tabs) + self.tablist = tabs + self:BuildTabs() + end, + + ["BuildTabs"] = function(self) + local status = self.status or self.localstatus + local tablist = self.tablist + local tabs = self.tabs + + if not tablist then return end + + local first = true + for i, v in ipairs(tablist) do + local tab = tabs[i] + if not tab then + tab = self:CreateTab(i) + tabs[i] = tab + end + + local padding = 20 + if v.style == "bold" then padding = 0 end + + tab:Show() + tab:SetText(v.text) + tab:SetWidth(tab:GetTextWidth() + padding) + tab:SetHeight(tab:GetTextHeight()) + tab:SetDisabled(v.disabled) + tab.value = v.value + tab.style = v.style or "underline" + + tab:ClearAllPoints() + if first then + local firstOffset = 0 + if tab.style == "bold" then firstOffset = 4 end + tab:SetPoint("BOTTOMLEFT", self.border, "TOPLEFT", firstOffset, 8) + first = false + else + tab:SetPoint("LEFT", tabs[i - 1], "RIGHT", 30, 0) + end + end + end, + + ["OnWidthSet"] = function(self, width) + local content = self.content + local contentwidth = width - 60 + if contentwidth < 0 then + contentwidth = 0 + end + content:SetWidth(contentwidth) + content.width = contentwidth + self:BuildTabs(self) + self.frame:SetScript("OnUpdate", buildTabsOnUpdate) + end, + + ["OnHeightSet"] = function(self, height) + local content = self.content + local contentheight = height - (self.borderoffset + 23) + if contentheight < 0 then + contentheight = 0 + 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)) + end, + + ["SetVisible"] = function(self, visible) + if visible then + self.frame:Show() + else + self.frame:Hide() + end + end +} + +--[[----------------------------------------------------------------------------- +Constructor +-------------------------------------------------------------------------------]] +local function Constructor() + local num = AceGUI:GetNextWidgetNum(Type) + local frame = CreateFrame("Frame",nil,UIParent) + frame:SetHeight(100) + frame:SetWidth(100) + frame:SetFrameStrata("FULLSCREEN_DIALOG") + + local border = CreateFrame("Frame", nil, frame) + local borderoffset = 30 + border:SetPoint("TOPLEFT", 0, -borderoffset) + border:SetPoint("BOTTOMRIGHT", 0, 3) + + local line = border:CreateTexture(nil, "ARTWORK") + line:Hide() + line:SetTexture(1, 1, 1, 1) + line:SetHeight(4) + + local content = CreateFrame("Frame", nil, border) + content:SetPoint("TOPLEFT", 0, 0) + content:SetPoint("BOTTOMRIGHT", 0, 0) + + local widget = { + num = num, + frame = frame, + localstatus = {}, + alignoffset = 18, + border = border, + borderoffset = borderoffset, + tabs = {}, + tabSelector = line, + content = content, + type = Type + } + for method, func in pairs(methods) do + widget[method] = func + end + + return AceGUI:RegisterAsContainer(widget) +end + +AceGUI:RegisterWidgetType(Type, Constructor, Version)