You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
423 lines
16 KiB
423 lines
16 KiB
--========================================================--
|
|
-- Scorpio TabControl Widget --
|
|
-- --
|
|
-- Author : kurapica125@outlook.com --
|
|
-- Create Date : 2020/04/26 --
|
|
--========================================================--
|
|
|
|
--========================================================--
|
|
Scorpio "Scorpio.Widget.TabControl" "1.0.0"
|
|
--========================================================--
|
|
|
|
-----------------------------------------------------------
|
|
-- TabControl Widget --
|
|
-----------------------------------------------------------
|
|
__Sealed__() class "TabButton" (function(_ENV)
|
|
inherit "Button"
|
|
|
|
local Next = Scorpio.Next
|
|
|
|
local function OnClick(self)
|
|
if not self.Selected then
|
|
PlaySound(SOUNDKIT.IG_CHARACTER_INFO_TAB)
|
|
self.Selected = true
|
|
end
|
|
end
|
|
|
|
local function OnDisable(self)
|
|
self:GetFontString():SetTextColor(0.5, 0.5, 0.5)
|
|
|
|
if self.Selected then
|
|
for _, child in self:GetParent():GetChilds() do
|
|
if child ~= self and Class.IsObjectType(child, TabButton) and child:IsEnabled() then
|
|
child.Selected = true
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function OnEnable(self)
|
|
self:GetFontString():SetTextColor(1, 0.82, 0)
|
|
end
|
|
|
|
--- Whether the tab is selected
|
|
property "Selected" {
|
|
type = Boolean,
|
|
handler = function(self, flag)
|
|
self:GetChild("LeftDisabled"):SetShown(flag)
|
|
self:GetChild("MiddleDisabled"):SetShown(flag)
|
|
self:GetChild("RightDisabled"):SetShown(flag)
|
|
self:GetChild("Left"):SetShown(not flag)
|
|
self:GetChild("Middle"):SetShown(not flag)
|
|
self:GetChild("Right"):SetShown(not flag)
|
|
self.Container:SetShown(flag)
|
|
|
|
local text = self:GetFontString()
|
|
if flag then
|
|
text:SetTextColor(1, 1, 1)
|
|
text:ClearAllPoints()
|
|
text:SetPoint("CENTER", 0, 0)
|
|
self:GetHighlightTexture():Hide()
|
|
else
|
|
self:GetFontString():SetTextColor(1,0.82,0)
|
|
text:ClearAllPoints()
|
|
text:SetPoint("CENTER", 0, -3)
|
|
self:GetHighlightTexture():Show()
|
|
end
|
|
|
|
if flag then
|
|
for _, child in self:GetParent():GetChilds() do
|
|
if child ~= self and Class.IsObjectType(child, TabButton) then
|
|
child.Selected = false
|
|
end
|
|
end
|
|
end
|
|
end,
|
|
}
|
|
|
|
--- The Container of the tab page
|
|
property "Container" { type = Frame }
|
|
|
|
--- Override the SetText method
|
|
function SetText(self, text)
|
|
Button.SetText(self, text)
|
|
|
|
Next(function()
|
|
local text = self:GetFontString()
|
|
local width = text and text:GetStringWidth() or 0
|
|
|
|
self:SetWidth(width + 36)
|
|
end)
|
|
end
|
|
|
|
__Template__{
|
|
LeftDisabled = Texture,
|
|
MiddleDisabled = Texture,
|
|
RightDisabled = Texture,
|
|
Left = Texture,
|
|
Middle = Texture,
|
|
Right = Texture,
|
|
}
|
|
function __ctor(self)
|
|
self:SetWidth(115)
|
|
self:InstantApplyStyle()
|
|
|
|
self:SetFrameLevel(self:GetFrameLevel() + 4)
|
|
|
|
self.OnClick = self.OnClick + OnClick
|
|
self.OnEnable = self.OnEnable + OnEnable
|
|
self.OnDisable = self.OnDisable + OnDisable
|
|
end
|
|
end)
|
|
|
|
__Sealed__()
|
|
class "TabControl" (function(_ENV)
|
|
inherit "Frame"
|
|
|
|
local function refreshHeaderScroll(self)
|
|
local header = self:GetChild("Header")
|
|
local container = header:GetChild("Container")
|
|
|
|
if container:GetWidth() < self:GetWidth() then
|
|
if self:GetChild("LeftScroll"):IsShown() then
|
|
self:GetChild("LeftScroll"):Hide()
|
|
self:GetChild("RightScroll"):Hide()
|
|
|
|
header:ClearAllPoints()
|
|
header:SetPoint("TOPLEFT")
|
|
header:SetPoint("RIGHT")
|
|
|
|
container:ClearAllPoints()
|
|
container:SetPoint("TOPLEFT")
|
|
container:SetPoint("BOTTOM")
|
|
end
|
|
else
|
|
if not self:GetChild("LeftScroll"):IsShown() then
|
|
self:GetChild("LeftScroll"):Show()
|
|
self:GetChild("RightScroll"):Show()
|
|
|
|
header:ClearAllPoints()
|
|
header:SetPoint("TOPLEFT")
|
|
header:SetPoint("RIGHT", self:GetChild("LeftScroll"), "LEFT")
|
|
|
|
container:ClearAllPoints()
|
|
container:SetPoint("TOPLEFT")
|
|
container:SetPoint("BOTTOM")
|
|
end
|
|
|
|
local offset = container.HorizontalOffset or 0
|
|
|
|
if offset > (container:GetWidth() - header:GetWidth()) then
|
|
container.HorizontalOffset = container:GetWidth() - header:GetWidth()
|
|
container:ClearAllPoints()
|
|
container:SetPoint("TOPLEFT", -container.HorizontalOffset, 0)
|
|
container:SetPoint("BOTTOM")
|
|
end
|
|
end
|
|
end
|
|
|
|
local function HeaderContainer_Resize(self)
|
|
local width = 0
|
|
local index = 0
|
|
|
|
repeat
|
|
index = index + 1
|
|
local child = self:GetChild("TabButton" .. index)
|
|
if child then width = width + child:GetWidth() end
|
|
until not child
|
|
|
|
self:SetWidth(width)
|
|
|
|
return refreshHeaderScroll(self:GetParent():GetParent())
|
|
end
|
|
|
|
local function LeftScroll_OnClick(self)
|
|
self = self:GetParent()
|
|
local header = self:GetChild("Header")
|
|
local container = header:GetChild("Container")
|
|
local offset = container.HorizontalOffset or 0
|
|
|
|
offset = offset - header:GetWidth() / 2
|
|
if offset < 0 then offset = 0 end
|
|
|
|
container.HorizontalOffset = offset
|
|
container:ClearAllPoints()
|
|
container:SetPoint("TOPLEFT", -offset, 0)
|
|
container:SetPoint("BOTTOM")
|
|
end
|
|
|
|
local function RightScroll_OnClick(self)
|
|
self = self:GetParent()
|
|
local header = self:GetChild("Header")
|
|
local container = header:GetChild("Container")
|
|
local offset = container.HorizontalOffset or 0
|
|
local maxoff = container:GetWidth() - header:GetWidth()
|
|
|
|
offset = offset + header:GetWidth() / 2
|
|
if offset > maxoff then offset = maxoff end
|
|
|
|
container.HorizontalOffset = offset
|
|
container:ClearAllPoints()
|
|
container:SetPoint("TOPLEFT", -offset, 0)
|
|
container:SetPoint("BOTTOM")
|
|
end
|
|
|
|
local function TabButton_OnSizeChanged(self)
|
|
return HeaderContainer_Resize(self:GetParent())
|
|
end
|
|
|
|
local function OnSizeChanged(self)
|
|
return refreshHeaderScroll(self)
|
|
end
|
|
|
|
--- Add a tab page and return the tab button
|
|
__Arguments__{ NEString, UI/nil }
|
|
function AddTabPage(self, name, frame)
|
|
local header = self:GetChild("Header"):GetChild("Container")
|
|
local index = 0
|
|
|
|
repeat
|
|
index = index + 1
|
|
local child = header:GetChild("TabButton" .. index)
|
|
if child and child:GetText() == name then return child end
|
|
until not child
|
|
|
|
local tabButton = TabButton("TabButton" .. index, header)
|
|
tabButton.OnSizeChanged = tabButton.OnSizeChanged + TabButton_OnSizeChanged
|
|
|
|
tabButton:ClearAllPoints()
|
|
|
|
if index == 1 then
|
|
tabButton:SetPoint("BOTTOMLEFT")
|
|
else
|
|
local prev = header:GetChild("TabButton" .. (index - 1))
|
|
tabButton:SetPoint("BOTTOMLEFT", prev, "BOTTOMRIGHT")
|
|
end
|
|
|
|
tabButton:SetText(name)
|
|
local container = Frame("TabPageContainer" .. index, self:GetChild("Body"))
|
|
container:SetPoint("TOPLEFT")
|
|
container:SetPoint("BOTTOMRIGHT")
|
|
tabButton.Container = container
|
|
|
|
if index == 1 then
|
|
tabButton.Selected = true
|
|
else
|
|
tabButton.Selected = false
|
|
end
|
|
|
|
return tabButton
|
|
end
|
|
|
|
--- Get the tab button by name
|
|
function GetTabPage(self, name)
|
|
local header = self:GetChild("Header"):GetChild("Container")
|
|
local index = 0
|
|
|
|
repeat
|
|
index = index + 1
|
|
local child = header:GetChild("TabButton" .. index)
|
|
if child and child:GetText() == name then return child end
|
|
until not child
|
|
end
|
|
|
|
__Template__{
|
|
Header = ScrollFrame,
|
|
Body = Frame,
|
|
LeftScroll = Button,
|
|
RightScroll = Button,
|
|
|
|
-- Child Tree
|
|
{
|
|
Header = {
|
|
Container = Frame,
|
|
}
|
|
}
|
|
}
|
|
function __ctor(self)
|
|
local header = self:GetChild("Header")
|
|
header:ClearAllPoints()
|
|
header:SetPoint("TOPLEFT")
|
|
header:SetPoint("RIGHT")
|
|
header:SetHeight(32)
|
|
|
|
local container = header:GetChild("Container")
|
|
header:SetScrollChild(container)
|
|
container:ClearAllPoints()
|
|
container:SetPoint("TOPLEFT")
|
|
container:SetPoint("BOTTOM")
|
|
container:SetWidth(1)
|
|
|
|
local leftScroll = self:GetChild("LeftScroll")
|
|
local rightScroll = self:GetChild("RightScroll")
|
|
|
|
leftScroll:Hide()
|
|
rightScroll:Hide()
|
|
|
|
self.OnSizeChanged = self.OnSizeChanged + OnSizeChanged
|
|
leftScroll.OnClick = leftScroll.OnClick + LeftScroll_OnClick
|
|
rightScroll.OnClick = rightScroll.OnClick + RightScroll_OnClick
|
|
end
|
|
end)
|
|
|
|
-----------------------------------------------------------
|
|
-- TabControl Style --
|
|
-----------------------------------------------------------
|
|
Style.UpdateSkin("Default", {
|
|
[TabButton] = {
|
|
height = 24,
|
|
|
|
LeftDisabled = {
|
|
drawLayer = "BORDER",
|
|
file = [[Interface\OptionsFrame\UI-OptionsFrame-ActiveTab]],
|
|
size = Size(20, 24),
|
|
location = { Anchor("BOTTOMLEFT", 0, -3) },
|
|
texCoords = RectType(0, 0.15625, 0, 1.0),
|
|
},
|
|
MiddleDisabled = {
|
|
drawLayer = "BORDER",
|
|
file = [[Interface\OptionsFrame\UI-OptionsFrame-ActiveTab]],
|
|
location = { Anchor("TOPLEFT", 0, 0, "LeftDisabled", "TOPRIGHT"), Anchor("BOTTOMRIGHT", 0, 0, "RightDisabled", "BOTTOMLEFT") },
|
|
texCoords = RectType(0.15625, 0.84375, 0, 1.0),
|
|
},
|
|
RightDisabled = {
|
|
drawLayer = "BORDER",
|
|
file = [[Interface\OptionsFrame\UI-OptionsFrame-ActiveTab]],
|
|
size = Size(20, 24),
|
|
location = { Anchor("BOTTOMRIGHT", 0, -3) },
|
|
texCoords = RectType(0.84375, 1.0, 0, 1.0),
|
|
},
|
|
Left = {
|
|
drawLayer = "BORDER",
|
|
file = [[Interface\OptionsFrame\UI-OptionsFrame-InActiveTab]],
|
|
size = Size(20, 24),
|
|
location = { Anchor("TOPLEFT") },
|
|
texCoords = RectType(0, 0.15625, 0, 1.0),
|
|
},
|
|
Middle = {
|
|
drawLayer = "BORDER",
|
|
file = [[Interface\OptionsFrame\UI-OptionsFrame-InActiveTab]],
|
|
location = { Anchor("TOPLEFT", 0, 0, "Left", "TOPRIGHT"), Anchor("BOTTOMRIGHT", 0, 0, "Right", "BOTTOMLEFT") },
|
|
texCoords = RectType(0.15625, 0.84375, 0, 1.0),
|
|
},
|
|
Right = {
|
|
drawLayer = "BORDER",
|
|
file = [[Interface\OptionsFrame\UI-OptionsFrame-InActiveTab]],
|
|
size = Size(20, 24),
|
|
location = { Anchor("TOPRIGHT") },
|
|
texCoords = RectType(0.84375, 1.0, 0, 1.0),
|
|
},
|
|
ButtonText = {
|
|
fontObject = GlueFontNormalSmall,
|
|
},
|
|
|
|
HighlightTexture = {
|
|
file = [[Interface\PaperDollInfoFrame\UI-Character-Tab-Highlight]],
|
|
location = { Anchor("TOPLEFT", 10, -4), Anchor("BOTTOMRIGHT", -10, 4) },
|
|
alphamode = "ADD",
|
|
},
|
|
|
|
normalFont = GlueFontNormalSmall,
|
|
disabledFont = GameFontDisableSmall,
|
|
highlightFont = GlueFontHighlightSmall,
|
|
},
|
|
[TabControl] = {
|
|
RightScroll = {
|
|
location = { Anchor("TOPRIGHT") },
|
|
size = Size(32, 32),
|
|
|
|
NormalTexture = {
|
|
file = [[Interface\Buttons\UI-SpellbookIcon-NextPage-Up]],
|
|
setAllPoints = true,
|
|
},
|
|
PushedTexture = {
|
|
file = [[Interface\Buttons\UI-SpellbookIcon-NextPage-Down]],
|
|
setAllPoints = true,
|
|
},
|
|
DisabledTexture = {
|
|
file = [[Interface\Buttons\UI-SpellbookIcon-NextPage-Disabled]],
|
|
setAllPoints = true,
|
|
},
|
|
HighlightTexture = {
|
|
file = [[Interface\Buttons\UI-Common-MouseHilight]],
|
|
setAllPoints = true,
|
|
alphamode = "ADD",
|
|
},
|
|
},
|
|
LeftScroll = {
|
|
location = { Anchor("RIGHT", 0, 0, "RightScroll", "LEFT") },
|
|
size = Size(32, 32),
|
|
|
|
NormalTexture = {
|
|
file = [[Interface\Buttons\UI-SpellbookIcon-PrevPage-Up]],
|
|
setAllPoints = true,
|
|
},
|
|
PushedTexture = {
|
|
file = [[Interface\Buttons\UI-SpellbookIcon-PrevPage-Down]],
|
|
setAllPoints = true,
|
|
},
|
|
DisabledTexture = {
|
|
file = [[Interface\Buttons\UI-SpellbookIcon-PrevPage-Disabled]],
|
|
setAllPoints = true,
|
|
},
|
|
HighlightTexture = {
|
|
file = [[Interface\Buttons\UI-Common-MouseHilight]],
|
|
setAllPoints = true,
|
|
alphamode = "ADD",
|
|
},
|
|
},
|
|
Header = {
|
|
height = 24,
|
|
},
|
|
Body = {
|
|
location = { Anchor("TOPLEFT", 0, 0, "Header", "BOTTOMLEFT"), Anchor("BOTTOMRIGHT") },
|
|
backdrop = {
|
|
edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]],
|
|
tile = true, tileSize = 16, edgeSize = 16,
|
|
insets = { left = 5, right = 5, top = 5, bottom = 5 }
|
|
},
|
|
backdropBorderColor = Color(0.6, 0.6, 0.6),
|
|
}
|
|
},
|
|
})
|
|
|