local _ , L = ...
local rematch = Rematch
local panel = RematchTeamTabs
local dialog , iconPicker , settings , saved
--[[ Team tabs are defined in settings.TeamGroups as an ordered table (tab#=table index)
Within each index of TeamGroups is a table of the following :
[ 1 ] = Name of the tab
[ 2 ] = Icon of the tab
[ 3 ] = An ordered table of keys if the tab is custom sorted , nil if not custom sorted
[ 4 ] = A table of leveling preferences if the tab has any , nil otherwise
[ 5 ] = True if the tab is to be sorted by win record
] ]
local MAX_DISPLAYED_TABS = 14 -- number of team tabs that can be dispayed at once
panel.MAX_TABS = 32 -- number of team tabs possible
panel.isScrolling = nil -- true while there are more tabs than can be displayed and the tabs are scrollable
-- this table describes the {yoffset,scale} to nudge the tabs to make room for more.
-- the index is the number of tabs to display (not including the + New Tabs button)
-- a nil yoffset means to center it to the side of the parent
local tabNudges = { [ 11 ] = { - 64 , 1 } , [ 12 ] = { - 28 , 1 } , [ 13 ] = { nil , 0.95 } , [ 14 ] = { nil , 0.9 } , [ 15 ] = { nil , 0.85 } , [ 16 ] = { nil , 0.85 } }
rematch : InitModule ( function ( )
rematch.TeamTabs = panel
settings = RematchSettings
saved = RematchSaved
dialog = RematchDialog
iconPicker = dialog.TeamTabIconPicker
panel.Tabs = { } -- where the tab buttons will go
local function isFirstTab ( self , index ) return index == 1 end
rematch : RegisterMenu ( " TabMenu " , { -- menu for Tab buttons
{ title = true , text = function ( self , index ) return settings.TeamGroups [ index ] [ 1 ] end , } ,
{ text = L [ " Edit Tab " ] , func = panel.ShowTabEditDialog , tooltipBody = L [ " Change the name or icon of this tab. " ] } ,
{ text = L [ " Custom Sort " ] , check = true ,
value = function ( entry , index )
return settings.TeamGroups [ index ] and settings.TeamGroups [ index ] [ 3 ] and true
end ,
func = function ( entry , index )
local tab = settings.TeamGroups [ index ]
if not tab then return end
if tab [ 3 ] then
local dialog = rematch : ShowDialog ( " DeleteCustomSort " , 300 , 172 , L [ " Remove Custom Sort " ] , nil , YES , function ( ) tab [ 3 ] = nil rematch : UpdateUI ( ) end , NO )
dialog : ShowText ( L [ " Are you sure you want to remove the custom sort order? \n \n The saved order of teams will be lost and turning this option back on will not restore the old order. " ] , 240 , 96 , " TOP " , 0 , - 32 )
else
tab [ 3 ] = { }
end
rematch : HideMenu ( )
rematch : UpdateUI ( )
end ,
tooltipBody = L [ " While checked, you can rearrange the order of teams within this tab from the teams' right-click menu. " ] } ,
{ text = L [ " Sort By Wins " ] , check = true ,
disabled = function ( entry , index ) return settings.TeamGroups [ index ] [ 3 ] and true end ,
disabledReason = L [ " This option is disabled while Custom Sort is active. " ] ,
value = function ( entry , index ) return settings.TeamGroups [ index ] [ 5 ] end ,
func = function ( entry , index )
local tab = settings.TeamGroups [ index ]
tab [ 5 ] = not tab [ 5 ]
rematch : UpdateUI ( )
end ,
tooltipBody = L [ " Sort teams in this tab by their wins. \n \n Favorited teams will still list at the top. " ]
} ,
{ text = L [ " Leveling Preferences " ] , func = function ( entry , index ) rematch : ShowPreferencesDialog ( " tab " , index ) end , tooltipBody = L [ " Set leveling preferences for all teams within this tab. \n \n If a team within this tab also has preferences, the tab's preferences will take priority over the team's preferences. " ] } ,
{ text = L [ " Export Tab " ] , func = function ( ) Rematch.Dialog . Share : ExportTeamTab ( ) end , tooltipBody = L [ " Export all teams in this tab to a string you can copy elsewhere, such as forums or emails. \n \n Other Rematch users can then paste these teams into their Rematch via Import Teams. \n \n You can export a single team by right-clicking one and choosing its Share menu. " ] } ,
{ text = L [ " Import Teams " ] , func = rematch.ShowImportDialog , tooltipBody = L [ " Import a single team or many teams that were exported from Rematch. " ] } ,
{ text = L [ " Delete Tab " ] , hidden = isFirstTab , func = panel.ShowTabDeleteDialog , tooltipBody = L [ " Delete this tab and either move all of its teams to the default tab or delete the teams too. " ] } ,
{ text = L [ " Delete Teams " ] , hidden = function ( self , index ) return index ~= 1 end , func = panel.ShowDeleteFirstTabDialog , tooltipBody = L [ " Permanently delete all teams in this tab. " ] } ,
{ text = L [ " Move Up " ] , hidden = isFirstTab , icon = " Interface \\ Buttons \\ UI-MicroStream-Yellow " , iconCoords = { 0.075 , 0.925 , 0.925 , 0.075 } , stay = true ,
disabled = function ( entry , index ) return index == 2 end ,
func = function ( entry , index ) panel : SwapTabs ( index , index - 1 ) end } ,
{ text = L [ " Move Down " ] , hidden = isFirstTab , icon = " Interface \\ Buttons \\ UI-MicroStream-Yellow " , stay = true ,
disabled = function ( entry , index ) return index ==# settings.TeamGroups end ,
func = function ( entry , index ) panel : SwapTabs ( index , index + 1 ) end } ,
{ text = OKAY } ,
} )
-- the offset (in increments of 44px) of the scrollframe
panel.scrollOffset = 0
end )
-- returns the selected team tab (and assigns it to first tab if anything weird happened)
function panel : GetSelectedTab ( )
local selected = settings.SelectedTab
if not selected or not settings.TeamGroups [ selected ] then
settings.SelectedTab = 1
return 1
else
return selected
end
end
function panel : Update ( )
panel : GetSelectedTab ( ) -- changes settings.SelectedTab to 1 if selected tab doesn't eixt
for index = 1 , panel.MAX_TABS do
panel : TabButtonUpdate ( index )
end
local maxHeight = MAX_DISPLAYED_TABS * 44
local height = min ( maxHeight , min ( panel.MAX_TABS , # settings.TeamGroups + 1 ) * 44 )
panel : SetHeight ( height )
-- anchor/rescale the parent TeamTabs frame depending on number of tabs to show
local numTabs = # settings.TeamGroups
local yoffset , scale = - 92 , 1 -- default to -92 from top of parent, 1.0 scale
local parent = panel : GetParent ( )
-- local tabNudges = {[11]={-64,1},[12]={-28,1},[13]={nil,0.95},[14]={nil,0.9},[15]={nil,0.85},[16]={nil,0.85}}
if numTabs < 11 then
yoffset , scale = - 92 , 1
elseif numTabs == 11 then
yoffset , scale = - 64 , 1
elseif numTabs == 12 then
yoffset , scale = - 28 , 1
elseif numTabs == 13 then
yoffset , scale = nil , 0.95
else -- for 14 or more tabs
yoffset , scale = nil , 0.85
end
panel : ClearAllPoints ( )
if yoffset then
if settings.TeamTabsToLeft and settings.AlwaysTeamTabs and parent == rematch.Frame then
panel : SetPoint ( " TOPRIGHT " , parent , " TOPLEFT " , - 1 , yoffset ) -- tabs anchored to topleft
else
panel : SetPoint ( " TOPLEFT " , parent , " TOPRIGHT " , - 1 , yoffset ) -- tabs anchored to topright
end
else
if settings.TeamTabsToLeft and settings.AlwaysTeamTabs and parent == rematch.Frame then
panel : SetPoint ( " RIGHT " , parent , " LEFT " , - 1 , 0 ) -- tabs anchored to left center
else
panel : SetPoint ( " LEFT " , parent , " RIGHT " , - 1 , 0 ) -- tabs anchored to right center
end
end
panel : SetScale ( scale )
panel : UpdateScroll ( ) -- updates state of scroll buttons and the scrollframe
end
function panel : SelectTeamTab ( index )
rematch.TeamPanel : SetTeamSearch ( nil )
settings.SelectedTab = index or 1
panel : Update ( )
if not rematch.TeamPanel : IsVisible ( ) and not rematch : IsDialogOpen ( " SaveAs " ) and not rematch : IsDialogOpen ( " ImportDialog " ) and not rematch : IsDialogOpen ( " ReceiveDialog " ) then
rematch : ShowTeam ( ) -- if teams not shown then switch to panel
else
rematch.TeamPanel : Update ( ) -- if not visible but shouldn't be, this Update will be ignored in the function
end
panel : ScrollToTab ( settings.SelectedTab )
if rematch.TeamPanel : IsVisible ( ) then
rematch.TeamPanel . List : ScrollToIndex ( 1 )
end
rematch.Dialog : UpdateTabPicker ( )
end
function panel : TabOnClick ( button )
rematch : HideMenu ( )
local index = self : GetID ( )
local groups = settings.TeamGroups
if button == " RightButton " then
if index <=# groups then
rematch : SetMenuSubject ( index )
panel : SelectTeamTab ( index )
rematch : ShowMenu ( " TabMenu " , " cursor " )
end
return
end
if index > 0 and index <=# groups then
panel : SelectTeamTab ( index )
else
if index ># groups then
panel : ShowTabEditDialog ( index )
end
end
end
function panel : TabButtonOnEnter ( )
local index = self : GetID ( )
if index == 0 then
rematch.ShowTooltip ( self , self == panel.UpButton and L [ " Previous Tabs " ] or L [ " Next Tabs " ] )
elseif index ># settings.TeamGroups then
rematch.ShowTooltip ( self , L [ " Create New Tab " ] )
else
local numTeams = 0
for k , v in pairs ( saved ) do
if ( v.tab or 1 ) == index then
numTeams = numTeams + 1
end
end
local info = rematch.info
wipe ( info )
tinsert ( info , settings.TeamGroups [ index ] [ 1 ] )
tinsert ( info , format ( L [ " Teams: %d " ] , numTeams ) )
if settings.TeamGroups [ index ] [ 4 ] then
tinsert ( info , " " )
rematch.ShowPreferencesTooltip ( self , " tab " , index , nil , info )
else
rematch : ShowTableTooltip ( self , info )
end
end
end
function panel : ShowTabEditDialog ( index )
local groups = settings.TeamGroups
local name , icon
if index ># groups then
name = L [ " New Tab " ]
icon = " Interface \\ Icons \\ PetJournalPortrait "
else
name = groups [ index ] [ 1 ]
icon = groups [ index ] [ 2 ]
end
rematch : ShowDialog ( " TabEdit " , 390 , 456 , name or L [ " New Tab " ] , L [ " Choose a name and icon " ] , SAVE , panel.IconPickerSave , CANCEL )
dialog : SetContext ( " tab " , index )
dialog : SetContext ( " name " , name )
dialog : SetContext ( " icon " , icon )
dialog.EditBox : SetPoint ( " TOP " , 22 , - 40 )
dialog.EditBox : SetWidth ( 180 )
dialog.EditBox : Show ( )
dialog.EditBox : SetText ( name )
dialog.Slot : SetPoint ( " RIGHT " , dialog.EditBox , " LEFT " , - 8 , 0 )
dialog.Slot : Show ( )
dialog.Slot . Icon : SetTexture ( icon )
iconPicker : SetPoint ( " TOP " , 0 , - 80 )
if not iconPicker.ScrollFrame . buttons then
-- scrollframe hasn't been set up yet
local scrollFrame = iconPicker.ScrollFrame
scrollFrame.update = panel.UpdateTabIconPickerList
scrollFrame.ScrollBar . doNotHide = true
scrollFrame.stepSize = 270
HybridScrollFrame_CreateButtons ( scrollFrame , " RematchTeamTabPickerListTemplate " )
end
-- set up icon choices (recreating table each time on purpose; don't want to keep these huge tables)
local iconChoices = dialog : SetContext ( " iconChoices " , { } )
tinsert ( iconChoices , " Interface \\ Icons \\ PetJournalPortrait " )
panel : AddMoreIcons ( iconChoices ) -- add icons from bags, inventory, etc
-- GetLooseMacroIcons(iconChoices)
GetMacroIcons ( iconChoices )
GetMacroItemIcons ( iconChoices )
panel : UpdateTabIconPickerList ( )
iconPicker : Show ( )
end
-- when save clicked on IconPicker
function panel : IconPickerSave ( )
local groups = settings.TeamGroups
local index = dialog : GetContext ( " tab " )
local scrollDown = not groups [ index ] -- whether to scroll down after adding the tab (if group doesn't exist, it's a new tab)
groups [ index ] = groups [ index ] or { }
groups [ index ] [ 1 ] = dialog.EditBox : GetText ( ) or " "
groups [ index ] [ 2 ] = dialog : GetContext ( " icon " )
panel : SelectTeamTab ( index )
if scrollDown then
panel : ScrollTabs ( - 1 )
end
end
-- update of icon list in iconpicker
function panel : UpdateTabIconPickerList ( )
-- data points to searchChoices if a search is used, or iconChoices (all icons) otherwise
local data = dialog : GetContext ( " iconChoices " )
if not data then return end
local numData = ceil ( # data / 10 )
local scrollFrame = iconPicker.ScrollFrame
local offset = HybridScrollFrame_GetOffset ( scrollFrame )
local buttons = scrollFrame.buttons
local selectedIcon = dialog : GetContext ( " icon " )
for i = 1 , # buttons do
local index = i + offset
local button = buttons [ i ]
if ( index <= numData ) then
for j = 1 , 10 do
local subbutton = button.Icons [ j ]
local iconID = data [ ( index - 1 ) * 10 + j ]
subbutton.iconID = iconID
if iconID then
subbutton.Texture : SetTexture ( iconID )
subbutton.Selected : SetShown ( iconID == selectedIcon )
subbutton : Show ( )
else
subbutton : Hide ( )
end
end
button : Show ( )
else
button : Hide ( )
end
end
HybridScrollFrame_Update ( scrollFrame , 30 * numData , 30 )
end
function panel : IconOnClick ( )
local iconID = self.iconID
if iconID then
dialog : SetContext ( " icon " , iconID )
dialog.Slot . Icon : SetTexture ( iconID )
panel : UpdateTabIconPickerList ( )
end
end
--[[ Delete ]]
-- (for now) the first team tab can't be deleted, so it has its own dialog to delete teams within the team
function panel : ShowDeleteFirstTabDialog ( )
rematch : ShowDialog ( " TabDeleteFirst " , 300 , 150 , L [ " Delete Teams? " ] , L [ " Delete ALL teams in the first tab? " ] , YES ,
function ( )
for key , team in pairs ( saved ) do
if not team.tab or team.tab == 1 then
saved [ key ] = nil
end
end
rematch : UpdateUI ( )
end , NO )
dialog : ShowText ( format ( L [ " %sWARNING! \124 r This will %sPERMANENTLY DELETE \124 r all teams in this tab! " ] , rematch.hexRed , rematch.hexWhite ) , 180 , 40 , " TOP " , 0 , - 40 )
end
-- non-default tabs get a "Delete Tab" option instead with an option to delete teams too
function panel : ShowTabDeleteDialog ( index )
local groups = settings.TeamGroups
rematch : ShowDialog ( " TabDelete " , 300 , 192 , groups [ index ] [ 1 ] , L [ " Delete this tab? " ] , YES , panel.ConfirmDeleteTab , NO )
dialog : SetContext ( " tab " , index )
dialog : ShowText ( format ( L [ " Deleting this tab will move its teams to the %s tab. " ] , groups [ 1 ] [ 1 ] ) , 180 , 40 , " TOP " , 22 , - 40 )
dialog.Slot : SetPoint ( " RIGHT " , dialog.Text , " LEFT " , - 8 , 0 )
dialog.Slot : Show ( )
dialog.Slot . Icon : SetTexture ( groups [ index ] [ 2 ] )
dialog.CheckButton : SetPoint ( " BOTTOMLEFT " , 32 , 70 )
dialog.CheckButton . text : SetText ( L [ " Delete teams within the tab too " ] )
dialog.CheckButton : SetChecked ( false )
dialog.CheckButton : Show ( )
dialog.CheckButton : SetScript ( " OnClick " , panel.DeleteTeamsOnClick )
end
function panel : DeleteTeamsOnClick ( )
local deleteTeams = self : GetChecked ( ) and true
local groups = settings.TeamGroups
dialog : SetContext ( " TabDeleteTeamsToo " , deleteTeams )
dialog.Text : SetText ( deleteTeams and format ( L [ " %sWARNING! \124 r This will %sPERMANENTLY DELETE \124 r all teams in this tab! " ] , rematch.hexRed , rematch.hexWhite ) or format ( L [ " Deleting this tab will move its teams to the %s tab. " ] , groups [ 1 ] [ 1 ] ) )
end
function panel : ConfirmDeleteTab ( )
local index = dialog : GetContext ( " tab " )
if index and index > 1 then
-- if checkbutton "Delete teams within this tab too" is checked, remove teams
if dialog : GetContext ( " TabDeleteTeamsToo " ) then
for key , team in pairs ( saved ) do
if team.tab == index then
saved [ key ] = nil
end
end
end
-- move any teams that belong to this tab to the general tab
-- (and move any beyond this tab to the prior tab)
for _ , team in pairs ( saved ) do
if team.tab == index then
team.tab = nil -- remove .tab from teams belonging to this tab (move them to general)
elseif team.tab and team.tab > index then
team.tab = team.tab - 1 -- move teams in tabs beyond deleted one to one previous
end
end
tremove ( settings.TeamGroups , index ) -- and delete the tab
panel : SelectTeamTab ( 1 ) -- go to first tab (this will update tabs and team panel)
end
end
-- swaps two tabs (index 2 to #groups) for moving tabs up/down
function panel : SwapTabs ( index1 , index2 )
local groups = settings.TeamGroups
if index1 == 1 or index2 == 1 or index1 ># groups or index2 ># groups then
return -- don't swap first tab! (or beyond last tab)
end
for teamName , teamData in pairs ( saved ) do
local teamTab = teamData.tab
if teamTab == index1 then
teamData.tab = index2
elseif teamTab == index2 then
teamData.tab = index1
end
end
-- swap the contents of groups[index1] and groups[index2]
for i = 1 , 5 do
local old = groups [ index1 ] [ i ]
groups [ index1 ] [ i ] = groups [ index2 ] [ i ]
groups [ index2 ] [ i ] = old
end
rematch : SetMenuSubject ( index2 ) -- change menu subject to destination tab
panel : SelectTeamTab ( index2 )
end
function panel : Configure ( parent )
panel : SetParent ( parent )
-- there used to be a lot more here (to reanchor tabs) that's now handled in the Update
panel : Show ( )
end
-- adds more icons to iconChoices (since default has only like 3.8k out of 15k icons)
function panel : AddMoreIcons ( iconChoices )
local function add ( icon )
if icon and not tContains ( iconChoices , icon ) then
tinsert ( iconChoices , icon )
end
end
-- add icons from items in bags
for i = 0 , 4 do
for j = 1 , GetContainerNumSlots ( i ) do
add ( GetContainerItemInfo ( i , j ) )
end
end
-- add icons from worn gear
for i = 1 , 19 do
add ( GetInventoryItemTexture ( " player " , i ) )
end
-- add all pet icons
for speciesID in rematch.Roster : AllSpecies ( ) do
add ( rematch : GetPetIcon ( speciesID ) )
end
end
-- returns the tab index that a team key belongs to
function rematch : GetTabFromTeam ( key )
if saved [ key ] then
return saved [ key ] . tab or 1
end
end
-- locks highlights on a specific tab (or unlocks highlight of all tabs if tab is nil)
function rematch : HighlightTeamTab ( tab )
local searching = rematch.TeamPanel : GetTeamSearchInfo ( )
for i = 1 , panel.MAX_TABS do
if panel.Tabs [ i ] then
if i == tab and searching then
panel.Tabs [ i ] : LockHighlight ( )
else
panel.Tabs [ i ] : UnlockHighlight ( )
end
end
end
end
function panel : TabButtonOnMouseDown ( )
if self : IsEnabled ( ) then
self.Icon : SetSize ( 28 , 28 )
self.Icon : SetVertexColor ( 0.75 , 0.75 , 0.75 )
end
end
function panel : TabButtonOnMouseUp ( )
self.Icon : SetSize ( 30 , 30 )
self.Icon : SetVertexColor ( 1 , 1 , 1 )
end
-- returns a tab button by its index (and creates if it hasn't been made yet)
function panel : GetTabButton ( index )
if not panel.Tabs [ index ] then
panel.Tabs [ index ] = CreateFrame ( " Button " , nil , panel.Layout , " RematchTeamTabTemplate " )
panel.Tabs [ index ] : RegisterForClicks ( " AnyUp " )
panel.Tabs [ index ] : SetID ( index )
panel.Tabs [ index ] : SetPoint ( " TOPLEFT " , 0 , ( index - 1 ) *- 44 )
end
return panel.Tabs [ index ]
end
function panel : TabButtonUpdate ( index )
local selected = panel : GetSelectedTab ( )
local numGroups = # settings.TeamGroups
local searchText , searchTabs = rematch.TeamPanel : GetTeamSearchInfo ( )
-- texcoords and icon anchoring is flipped when button goes to left
local left , right , centerSelected , centerUnselected = 0 , 0.6875 , 1 , - 5
if settings.TeamTabsToLeft and settings.AlwaysTeamTabs and panel : GetParent ( ) == rematch.Frame then
left , right , centerSelected , centerUnselected = 0.6875 , 0 , - 1 , 5
end
if index > 0 and index <= numGroups then
local button = panel : GetTabButton ( index )
if index == selected and not searchText then
button.Background : SetTexCoord ( left , right , 0 , 0.34375 )
button.Icon : SetPoint ( " CENTER " , centerSelected , 2 )
else
button.Background : SetTexCoord ( left , right , 0.5 , 0.84375 )
button.Icon : SetPoint ( " CENTER " , centerUnselected , 2 )
end
local desat = searchText and not searchTabs [ index ]
button.Icon : SetDesaturated ( desat )
button.Custom : SetDesaturated ( desat )
button.Preferences : SetDesaturated ( desat )
if searchText and not searchTabs [ index ] then
button.Icon : SetVertexColor ( 0.4 , 0.4 , 0.4 )
else
button.Icon : SetVertexColor ( 1 , 1 , 1 )
end
local group = settings.TeamGroups [ index ]
button.Icon : SetTexture ( group [ 2 ] )
button.Custom : SetShown ( group [ 3 ] and true )
button.Preferences : SetShown ( group [ 4 ] and true )
button : Show ( )
elseif index == ( numGroups + 1 ) and index <= panel.MAX_TABS then
local button = panel : GetTabButton ( index )
button.Background : SetTexCoord ( left , right , 0.5 , 0.84375 )
button.Icon : SetPoint ( " CENTER " , centerUnselected , 2 )
button.Icon : SetTexture ( " Interface \\ GuildBankFrame \\ UI-GuildBankFrame-NewTab " )
button.Custom : Hide ( )
button.Preferences : Hide ( )
button : Show ( )
elseif panel.Tabs [ index ] then
panel.Tabs [ index ] : Hide ( )
end
end
function panel : UpdateScroll ( )
if # settings.TeamGroups < MAX_DISPLAYED_TABS then
panel : SetVerticalScroll ( 0 )
panel.UpButton : Hide ( )
panel.DownButton : Hide ( )
panel.isScrolling = nil
return
end
local left , right , center = 0 , 0.6875 , - 5
if settings.TeamTabsToLeft and settings.AlwaysTeamTabs and panel : GetParent ( ) == rematch.Frame then
left , right , center = 0.6875 , 0 , 5
end
panel.UpButton . Background : SetTexCoord ( left , right , 0.5 , 0.84375 )
panel.UpButton . Icon : SetPoint ( " CENTER " , center , 2 )
panel.DownButton . Background : SetTexCoord ( left , right , 0.5 , 0.84375 )
panel.DownButton . Icon : SetPoint ( " CENTER " , center , 2 )
panel.UpButton . Icon : SetTexture ( " Interface \\ Icons \\ misc_arrowlup.blp " )
panel.DownButton . Icon : SetTexture ( " Interface \\ Icons \\ misc_arrowdown.blp " )
panel.UpButton : Show ( )
panel.DownButton : Show ( )
panel.isScrolling = true
panel : ScrollTabs ( )
end
-- this will scroll tabs up (direction>0), down (direction<0) or just update (direction==0)
-- and also call UpdateUpDownButtons afterwards
function panel : ScrollTabs ( direction )
local delta
if not direction then -- if no direction given, just update scroll
delta = 0
elseif direction < 0 then -- scrolling down
delta = 44 * ( MAX_DISPLAYED_TABS - 1 )
else -- scrolling up
delta = - 44 * ( MAX_DISPLAYED_TABS - 1 )
end
local offset = panel.scrollOffset + delta
offset = max ( 0 , offset )
local numTabs = # settings.TeamGroups
-- if we're not even supposed to be scrolling, offset is 0
local maxOffset
if numTabs < MAX_DISPLAYED_TABS then
offset = 0
else
-- if we've not reached the maximum possible team tabs, then add one more
-- tab for the "New Tab" tab
if numTabs < panel.MAX_TABS then
numTabs = numTabs + 1
end
maxOffset = ( numTabs ) * 44 - ( MAX_DISPLAYED_TABS ) * 44
-- constrain offset to scrolldown as far as the last tab
offset = min ( offset , maxOffset )
end
-- and finally scroll there
panel.scrollOffset = offset
panel : SetVerticalScroll ( offset )
-- enable/disable up/down buttons if at top/bottom of scroll
local atTop = offset == 0
panel.UpButton . Icon : SetDesaturated ( atTop )
panel.UpButton . Icon : SetAlpha ( atTop and 0.65 or 1 )
panel.UpButton : SetEnabled ( not atTop )
local atBottom = offset == maxOffset
panel.DownButton . Icon : SetDesaturated ( atBottom )
panel.DownButton . Icon : SetAlpha ( atBottom and 0.65 or 1 )
panel.DownButton : SetEnabled ( not atBottom )
end
-- this will move the tab index as close as possible to the middle of the scrollframe
function panel : ScrollToTab ( index )
if not panel.isScrolling then -- if not scrolling, always at the top
panel.scrollOffset = 0
else -- otherwise try to position index to middle of displayed tabs
-- if position is beyond range, it's okay; ScrollTabs will constrain it
-- (rounding to whole number since division involved)
panel.scrollOffset = floor ( ( index * 44 - ( MAX_DISPLAYED_TABS * 44 ) / 2 ) + 0.5 )
end
-- and do an update
panel : ScrollTabs ( )
end
-- this will scroll to the tab of the loaded team
function panel : ScrollToTeamTab ( key )
key = key or settings.loadedTeam -- if no key given, scroll to loaded team's tab
if key and saved [ key ] then
panel : ScrollToTab ( saved [ key ] . tab or 1 )
end
end