@@ -187,6 +187,10 @@ function ConfigTabClass:ConfigTab(build)
187187 self .toggleConfigs = not self .toggleConfigs
188188 end )
189189
190+ local function isCollapsed (section )
191+ return self :IsSectionCollapsed (section )
192+ end
193+
190194 local function searchMatch (varData )
191195 local searchStr = self .controls .search .buf :lower ():gsub (" [%-%.%+%[%]%$%^%%%?%*]" , " %%%0" )
192196 if searchStr and searchStr :match (" %S" ) then
@@ -269,18 +273,32 @@ function ConfigTabClass:ConfigTab(build)
269273 lastSection = new (" SectionControl" ):SectionControl ({ " TOPLEFT" , self .controls .search , " BOTTOMLEFT" }, { 0 , 0 , 360 , 0 }, varData .section )
270274 lastSection .varControlList = { }
271275 lastSection .col = varData .col
272- lastSection .height = function (self )
276+ lastSection .collapsed = false
277+ lastSection .height = function (section )
278+ if isCollapsed (section ) then
279+ return 16
280+ end
273281 local height = 20
274- for _ , varControl in pairs (self .varControlList ) do
282+ for _ , varControl in pairs (section .varControlList ) do
275283 if varControl :IsShown () then
276284 local _ , ctrlHeight = varControl :GetSize ()
277285 height = height + m_max (ctrlHeight or varControl .height , 16 ) + 4
278286 end
279287 end
280288 return m_max (height , 32 )
281289 end
290+ -- Collapse toggle, matching the Calcs tab: right aligned, '-' when expanded, '+' when collapsed.
291+ -- Sits on the section's top border, as the header label does, to clear the option controls below.
292+ local section = lastSection
293+ local toggle = new (" ButtonControl" ):ButtonControl ({" TOPRIGHT" ,lastSection ," TOPRIGHT" }, {- 6 , - 7 , 16 , 16 }, function ()
294+ return section .collapsed and " +" or " -"
295+ end , function ()
296+ section .collapsed = not section .collapsed
297+ end )
298+ -- Deliberately not in varControlList: it must not count towards the section's height or visibility
282299 t_insert (self .sectionList , lastSection )
283300 t_insert (self .controls , lastSection )
301+ t_insert (self .controls , toggle )
284302 if varData .section == " Custom Modifiers" then
285303 self .customSection = lastSection
286304 end
@@ -810,6 +828,15 @@ function ConfigTabClass:ConfigTab(build)
810828 end
811829 end
812830
831+ local ownSection = lastSection
832+ local eligibleShown = control .shown
833+ control .shown = function ()
834+ if isCollapsed (ownSection ) then
835+ return false
836+ end
837+ return type (eligibleShown ) == " boolean" and eligibleShown or eligibleShown ()
838+ end
839+
813840 t_insert (self .controls , control )
814841 t_insert (lastSection .varControlList , control )
815842 end
@@ -824,12 +851,20 @@ function ConfigTabClass:ConfigTab(build)
824851 self :BuildModList ()
825852 self .build .buildFlag = true
826853 end )
827- self .customModsBlockControls = {}
854+ self .controls .customModsAddBlock .shown = function ()
855+ return not isCollapsed (self .customSection )
856+ end
857+ self .customModsBlockControls = { }
828858 self :UpdateCustomModsControls ()
829859 end
830860 return self
831861end
832862
863+ -- A collapsed section hides its contents, unless a search is active
864+ function ConfigTabClass :IsSectionCollapsed (section )
865+ return section .collapsed and not self .controls .search .buf :match (" %S" )
866+ end
867+
833868function ConfigTabClass :Load (xml , fileName )
834869 self .activeConfigSetId = 1
835870 self .configSets = { }
@@ -1052,6 +1087,10 @@ function ConfigTabClass:Draw(viewPort, inputEvents)
10521087 for _ , section in ipairs (self .sectionList ) do
10531088 local y = 14
10541089 section .shown = true
1090+ -- Probe with the section expanded, so a collapsed section that still has
1091+ -- eligible options keeps its (clickable) header on screen
1092+ local collapsed = section .collapsed
1093+ section .collapsed = false
10551094 local doShow = false
10561095 for _ , varControl in pairs (section .varControlList ) do
10571096 if varControl :IsShown () then
@@ -1062,6 +1101,7 @@ function ConfigTabClass:Draw(viewPort, inputEvents)
10621101 y = y + height + 4
10631102 end
10641103 end
1104+ section .collapsed = collapsed
10651105 section .shown = doShow
10661106 if doShow then
10671107 local width , height = section :GetSize ()
@@ -1343,7 +1383,10 @@ function ConfigTabClass:UpdateCustomModsControls()
13431383 self .customSection .varControlList = { self .controls .customModsAddBlock }
13441384
13451385 for index , block in ipairs (configSet .customModsList ) do
1346- local blockControl = new (" CustomModBlockControl" ):CustomModBlockControl ({ " TOPLEFT" , self .customSection , " TOPLEFT" }, { 8 , 0 , 344 , 120 }, self , index , block )
1386+ local blockControl = new (" CustomModBlockControl" ):CustomModBlockControl ({" TOPLEFT" , self .customSection , " TOPLEFT" }, {8 , 0 , 344 , 120 }, self , index , block )
1387+ blockControl .shown = function ()
1388+ return not self :IsSectionCollapsed (self .customSection )
1389+ end
13471390 t_insert (self .customModsBlockControls , blockControl )
13481391 self .controls [" customModsBlock" .. index ] = blockControl
13491392 t_insert (self .customSection .varControlList , blockControl )
0 commit comments