@@ -13,6 +13,7 @@ local dkjson = require "dkjson"
1313local tradeHelpers = LoadModule (" Classes/CompareTradeHelpers" )
1414local buySimilar = LoadModule (" Classes/CompareBuySimilar" )
1515local calcsHelpers = LoadModule (" Classes/CompareCalcsHelpers" )
16+ local buildListHelpers = LoadModule (" Modules/BuildListHelpers" )
1617
1718-- Node IDs below this value are normal passive tree nodes; IDs at or above are cluster jewel nodes
1819local CLUSTER_NODE_OFFSET = 65536
@@ -183,11 +184,6 @@ function CompareTabClass:InitControls()
183184 end
184185 end
185186
186- -- Notes sub-tab controls
187- self .controls .notesDesc = new (" LabelControl" , nil , {0 , 0 , 0 , 16 }, " ^7These are the notes from the compared build. Any edits here are saved with this comparison and do not affect the main build's notes." )
188- self .controls .notesDesc .shown = function ()
189- return self .compareViewMode == " NOTES" and # self .compareEntries > 0
190- end
191187 self .controls .notesEdit = new (" EditControl" , nil , {0 , 0 , 0 , 0 }, " " , nil , " ^%C\t\n " , nil , nil , 16 , true )
192188 self .controls .notesEdit .shown = function ()
193189 return self .compareViewMode == " NOTES" and # self .compareEntries > 0
@@ -1396,7 +1392,7 @@ function CompareTabClass:OpenImportPopup()
13961392 controls .state .label = function ()
13971393 return stateText or " "
13981394 end
1399- controls .go = new (" ButtonControl" , nil , {- 45 , 130 , 80 , 20 }, " Import" , function ()
1395+ controls .go = new (" ButtonControl" , nil , {- 118 , 130 , 80 , 20 }, " Import" , function ()
14001396 local buf = controls .input .buf
14011397 if not buf or buf == " " then
14021398 return
@@ -1433,12 +1429,115 @@ function CompareTabClass:OpenImportPopup()
14331429 stateText = colorCodes .NEGATIVE .. " Invalid build code"
14341430 end
14351431 end )
1436- controls .cancel = new (" ButtonControl" , nil , {45 , 130 , 80 , 20 }, " Cancel" , function ()
1432+ controls .importFolder = new (" ButtonControl" , nil , {0 , 130 , 140 , 20 }, " Import from Folder" , function ()
1433+ main :ClosePopup ()
1434+ self :OpenImportFolderPopup ()
1435+ end )
1436+ controls .cancel = new (" ButtonControl" , nil , {118 , 130 , 80 , 20 }, " Cancel" , function ()
14371437 main :ClosePopup ()
14381438 end )
14391439 main :OpenPopup (500 , 160 , " Import Comparison Build" , controls , " go" , " input" , " cancel" )
14401440end
14411441
1442+ -- Open the "Import from Folder" popup: browse the user's local builds folder and
1443+ -- import the selected build file as a comparison.
1444+ function CompareTabClass :OpenImportFolderPopup ()
1445+ local controls = {}
1446+ local searchText = " "
1447+ local sortMode = main .buildSortMode
1448+
1449+ -- Minimal listMode-like host consumed by BuildListControl/PathControl.
1450+ local listHost = {
1451+ subPath = " " ,
1452+ list = { },
1453+ controls = { },
1454+ }
1455+ function listHost :BuildList ()
1456+ wipeTable (self .list )
1457+ local scanned = buildListHelpers .ScanFolder (self .subPath , searchText )
1458+ for _ , entry in ipairs (scanned ) do
1459+ t_insert (self .list , entry )
1460+ end
1461+ buildListHelpers .SortList (self .list , sortMode )
1462+ end
1463+ function listHost :SelectControl (control )
1464+ -- Focus is managed by the popup's ControlHost; this is a no-op for the popup list.
1465+ end
1466+
1467+ -- Import the given build entry (xml file on disk) as a comparison.
1468+ local function importBuildEntry (build )
1469+ local fileHnd = io.open (build .fullFileName , " r" )
1470+ if not fileHnd then
1471+ main :OpenMessagePopup (" Import Error" , " Couldn't open '" .. build .fullFileName .. " '." )
1472+ return
1473+ end
1474+ local xmlText = fileHnd :read (" *a" )
1475+ fileHnd :close ()
1476+ if not xmlText or xmlText == " " then
1477+ main :OpenMessagePopup (" Import Error" , " Build file is empty or unreadable." )
1478+ return
1479+ end
1480+ if self :ImportBuild (xmlText , build .buildName ) then
1481+ main :ClosePopup ()
1482+ else
1483+ main :OpenMessagePopup (" Import Error" , " Failed to import build for comparison." )
1484+ end
1485+ end
1486+
1487+ -- Search box and sort dropdown sit above the build list.
1488+ controls .searchText = new (" EditControl" , {" TOPLEFT" , nil , " TOPLEFT" }, {15 , 25 , 450 , 20 }, " " , " Search" , " %c%(%)" , 100 , function (buf )
1489+ searchText = buf
1490+ listHost :BuildList ()
1491+ end , nil , nil , true )
1492+ controls .sort = new (" DropDownControl" , {" TOPLEFT" , nil , " TOPLEFT" }, {475 , 25 , 210 , 20 }, buildListHelpers .buildSortDropList , function (index , value )
1493+ sortMode = value .sortMode
1494+ main .buildSortMode = value .sortMode
1495+ buildListHelpers .SortList (listHost .list , sortMode )
1496+ end )
1497+ controls .sort :SelByValue (sortMode , " sortMode" )
1498+
1499+ -- Build list itself. Reuses BuildListControl (which provides the PathControl breadcrumbs)
1500+ controls .buildList = new (" BuildListControl" , {" TOPLEFT" , nil , " TOPLEFT" }, {15 , 75 , 0 , 0 }, listHost )
1501+ controls .buildList .width = function () return 670 end
1502+ controls .buildList .height = function () return 355 end
1503+
1504+ -- Override instance methods on the BuildListControl to tailor it for the popup:
1505+ -- navigate folders, import builds, and suppress rename/delete/drag behaviors.
1506+ function controls .buildList :LoadBuild (build )
1507+ if build .folderName then
1508+ self .controls .path :SetSubPath (self .listMode .subPath .. build .folderName .. " /" )
1509+ else
1510+ importBuildEntry (build )
1511+ end
1512+ end
1513+ function controls .buildList :OnSelKeyDown (index , build , key )
1514+ if key == " RETURN" then
1515+ self :LoadBuild (build )
1516+ end
1517+ end
1518+ function controls .buildList :CanReceiveDrag () return false end
1519+ function controls .buildList :OnSelCopy () end
1520+ function controls .buildList :OnSelCut () end
1521+ function controls .buildList :OnSelDelete () end
1522+ function controls .buildList .controls .path :CanReceiveDrag () return false end
1523+
1524+ -- Populate the initial list now that the control (and its path control) exist.
1525+ listHost :BuildList ()
1526+
1527+ controls .open = new (" ButtonControl" , {" TOPLEFT" , nil , " TOPLEFT" }, {255 , 465 , 80 , 20 }, " Open" , function ()
1528+ local sel = controls .buildList .selValue
1529+ if sel then
1530+ controls .buildList :LoadBuild (sel )
1531+ end
1532+ end )
1533+ controls .open .enabled = function () return controls .buildList .selValue ~= nil end
1534+ controls .close = new (" ButtonControl" , {" TOPLEFT" , nil , " TOPLEFT" }, {365 , 465 , 80 , 20 }, " Close" , function ()
1535+ main :ClosePopup ()
1536+ end )
1537+
1538+ main :OpenPopup (700 , 500 , " Import from Folder" , controls , " open" , " searchText" , " close" )
1539+ end
1540+
14421541-- ============================================================
14431542-- DRAW - Main render method
14441543-- ============================================================
@@ -4364,13 +4463,8 @@ function CompareTabClass:DrawNotes(vp, compareEntry, inputEvents)
43644463 end
43654464 end
43664465
4367- -- Position label and edit control
4368- self .controls .notesDesc .x = vp .x + 8
4369- self .controls .notesDesc .y = vp .y + 8
4370-
4371- local editY = vp .y + 30
43724466 self .controls .notesEdit .x = vp .x + 8
4373- self .controls .notesEdit .y = editY
4467+ self .controls .notesEdit .y = vp . y + 8
43744468 self .controls .notesEdit .width = function ()
43754469 return vp .width - 16
43764470 end
0 commit comments