Advertisement
Guest User

Nixtux

a guest
Feb 17th, 2015
221
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 21.69 KB | None | 0 0
  1. local versionNumber = "v1.5"
  2.  
  3. function widget:GetInfo()
  4.     return {
  5.         name = "Nested Buildmenu",
  6.         desc = versionNumber .. " Nests large buildmenus. Commands are nested_buildmenu_X:\n"
  7.                 .. "press [number] to press an icon (numbered left to right, up to down, starting at 1)\n"
  8.                 .. "size, cols, cancelonly, uselists to tweak",
  9.         author = "Evil4Zerggin",
  10.         date = "3 January 2009",
  11.         license = "GNU LGPL, v2.1 or later",
  12.         layer = 1,
  13.         enabled = false
  14.     }
  15. end
  16.  
  17.  
  18.  
  19. --Nixtux :updated to work with current engine
  20. ------------------------------------------------
  21. --config
  22. ------------------------------------------------
  23. local startCategory = "Econ"
  24.  
  25. --sizing
  26. local mainSize = 64
  27. --relative to mainSize
  28. local lineWidth = 0.03125
  29. local textSize = 0.25
  30.  
  31. local numCols = 3
  32.  
  33. --nesting
  34. local nestThreshold = 12
  35. local cancelOnly = false
  36.  
  37. local mainX, mainY = 0, 512
  38.  
  39. local useLists = false
  40.  
  41. local drawFrames --looks for cancelFrameFile
  42. local cancelFrameFile = "Images/nested_buildmenu/frame_Cancel.png"
  43. local frameDir = ":l:" .. LUAUI_DIRNAME .. "Images/nested_buildmenu/frame_"
  44. local frameExt = ".png"
  45.  
  46. function widget:GetConfigData(data)
  47.     return {
  48.         mainX = mainX,
  49.         mainY = mainY,
  50.         mainSize = mainSize,
  51.         numCols = numCols,
  52.         cancelOnly = cancelOnly,
  53.         useLists = useLists,
  54.     }
  55. end
  56.  
  57. function widget:SetConfigData(data)
  58.     mainX = data.mainX or 0
  59.     mainY = data.mainY or 512
  60.     mainSize = data.mainSize or 64
  61.     numCols = data.numCols or 3
  62.     cancelOnly = data.cancelOnly
  63.     useLists = data.useLists
  64. end
  65.  
  66. ------------------------------------------------
  67. --speedups
  68. ------------------------------------------------
  69. local GetSelectedUnitsCounts = Spring.GetSelectedUnitsCounts
  70. local GetMouseState = Spring.GetMouseState
  71. local GetModKeyState = Spring.GetModKeyState
  72. local GetCmdDescIndex = Spring.GetCmdDescIndex
  73. local SetActiveCommand = Spring.SetActiveCommand
  74. local IsGUIHidden = Spring.IsGUIHidden
  75.  
  76. local glColor = gl.Color
  77. local glLineWidth = gl.LineWidth
  78. local glPolygonMode = gl.PolygonMode
  79. local glRect = gl.Rect
  80. local glTexRect = gl.TexRect
  81. local glShape = gl.Shape
  82. local glTranslate = gl.Translate
  83. local glScale = gl.Scale
  84. local glLoadIdentity = gl.LoadIdentity
  85. local glPopMatrix = gl.PopMatrix
  86. local glPushMatrix = gl.PushMatrix
  87. local glText = gl.Text
  88. local glGetTextWidth = gl.GetTextWidth
  89. local glTexture = gl.Texture
  90.  
  91. local glCreateList = gl.CreateList
  92. local glCallList = gl.CallList
  93. local glDeleteList = gl.DeleteList
  94.  
  95. local ceil = math.ceil
  96. local floor = math.floor
  97. local max = math.max
  98. local sort = table.sort
  99. local strFind = string.find
  100.  
  101. local GL_LINES = GL.LINES
  102. local GL_LINE = GL.LINE
  103. local GL_FILL = GL.FILL
  104. local GL_FRONT_AND_BACK = GL.FRONT_AND_BACK
  105.  
  106. ------------------------------------------------
  107. --vars
  108. ------------------------------------------------
  109. local vsx, vsy
  110. local numIcons
  111. local category
  112. local once
  113. local activeClick
  114. local buildIDs = {}
  115. --format: unitDefID = {category, ordering}
  116. local unitDefInfo = {}
  117. local mouseOffsetX, mouseOffsetY
  118.  
  119. local tweakList, mainList
  120.  
  121. local TEXT_CORRECT_Y = 1.25
  122.  
  123. local BUILD_CATEGORIES = {
  124.     "Econ",
  125.     "Fac",
  126.     "Aux",
  127.     "Def",
  128.     "Strat",
  129.     "Fort",
  130.     "Sensor",
  131.     "Mobile",
  132.     "Misc",
  133. }
  134.  
  135. local categoryCounts = {}
  136. --one unit from each category
  137. local categoryUnits = {}
  138.  
  139. local tweak = false
  140.  
  141. ------------------------------------------------
  142. --H4X
  143. ------------------------------------------------
  144.  
  145. local function GetRealTextWidth(text)
  146.     return glGetTextWidth(text) * vsx / vsy * 1.33333333
  147. end
  148.  
  149. ------------------------------------------------
  150. --util
  151. ------------------------------------------------
  152. local function energyToExtraM(energy)   -- mex overdrive equation
  153.   return math.sqrt(energy*0.2*WG.mexSquaredSum + WG.mexMetal*WG.mexMetal) - WG.mexMetal
  154. end
  155.  
  156.  
  157. local function TransformMain(x, y)
  158.     return (x - mainX) / mainSize, (y - mainY) / mainSize
  159. end
  160.  
  161. --nil if no icon, 0 for cancel button, iconID otherwise
  162. local function GetIconID(tx, ty)
  163.     if (tx < 0 or tx >= numCols or ty >= 0) then
  164.         return nil
  165.     else
  166.         result = -numCols * (floor(ty) + 1) + floor(tx) + 1
  167.         if (tweak) then
  168.             if (result == 1) then
  169.                 return 1
  170.             else
  171.                 return nil
  172.             end
  173.         elseif (category == "main") then
  174.             if (result <= #BUILD_CATEGORIES) then
  175.                 return result
  176.             else
  177.                 return nil
  178.             end
  179.         elseif (category ~= "all") then
  180.             result = result - 1
  181.         end
  182.         if (result > #buildIDs) then
  183.             return nil
  184.         else
  185.             return result
  186.         end
  187.     end
  188. end
  189.  
  190. local function DrawTextWithBackground(text, x, y, size, opt)
  191.     local width = GetRealTextWidth(text) * size
  192.     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
  193.    
  194.     glColor(0.25, 0.25, 0.25, 0.75)
  195.     if (opt) then
  196.         if (strFind(opt, "r")) then
  197.             glRect(x, y, x - width, y + size * TEXT_CORRECT_Y)
  198.             return
  199.         elseif (strFind(opt, "c")) then
  200.             glRect(x + width * 0.5, y, x - width * 0.5, y + size * TEXT_CORRECT_Y)
  201.             return
  202.         end
  203.         glRect(x, y, x + width, y + size * TEXT_CORRECT_Y)
  204.     else
  205.         glRect(x, y, x + width, y + size * TEXT_CORRECT_Y)
  206.     end
  207.    
  208.     glText(text, x, y, size, opt)
  209.    
  210. end
  211.  
  212. ------------------------------------------------
  213. --build categories
  214. ------------------------------------------------
  215. local function SetupBuildCategories()
  216.     --determine ordering
  217.    
  218.     local orderingInfo = {}
  219.     for unitDefID, unitDef in ipairs(UnitDefs) do
  220.         orderingInfo[unitDefID] = {unitDefID, unitDef.power, unitDef.customParams.sortname or unitDef.humanName}
  221.     end
  222.    
  223.     local function BuildComparator(a, b)
  224.         return a[2] < b[2] or (a[2] == b[2] and a[3] < b[3])
  225.     end
  226.    
  227.     sort(orderingInfo, BuildComparator)
  228.    
  229.     local ordering = {}
  230.     for index, info in ipairs(orderingInfo) do
  231.         ordering[info[1]] = index
  232.     end
  233.    
  234.     --fill table
  235.     for unitDefID, unitDef in ipairs(UnitDefs) do
  236.         unitDefInfo[unitDefID] = {}
  237.         if (unitDef.customParams.buildcategory) then --explicit build category
  238.             unitDefInfo[unitDefID][1] = unitDef.customParams.buildcategory
  239.         elseif (unitDef.speed > 0) then --mobiles
  240.             unitDefInfo[unitDefID][1] = "Mobile"
  241.         elseif (unitDef.extractsMetal > 0) then --mexes
  242.             unitDefInfo[unitDefID][1] = "Econ"
  243.         elseif (unitDef.isFeature or unitDef.canKamikaze) then --fortifications: features and mines
  244.             unitDefInfo[unitDefID][1] = "Fort"
  245.         elseif (unitDef.isFactory and unitDef.buildOptions and unitDef.buildOptions[1]) then --factories with buildoptions
  246.             unitDefInfo[unitDefID][1] = "Fac"
  247.         elseif (unitDef.buildSpeed > 0) then
  248.             unitDefInfo[unitDefID][1] = "Aux"
  249.         elseif (unitDef.stockpileWeaponDef or unitDef.shieldWeaponDef or unitDef.maxWeaponRange > 2048) then
  250.             unitDefInfo[unitDefID][1] = "Strat"
  251.         elseif (unitDef.weapons[1]) then
  252.             unitDefInfo[unitDefID][1] = "Def"
  253.         elseif (unitDef.radarRadius > 0
  254.                 or unitDef.sonarRadius > 0
  255.                 or unitDef.seismicRadius > 0
  256.                 or unitDef.jammerRadius > 0
  257.                 or unitDef.sonarJamRadius > 0) then
  258.             unitDefInfo[unitDefID][1] = "Sensor"
  259.         elseif (unitDef.makesMetal > 0
  260.                 or unitDef.metalMake - unitDef.metalUpkeep > 0
  261.                 or unitDef.tidalGenerator > 0
  262.                 or unitDef.windGenerator > 0
  263.                 or unitDef.totalEnergyOut > 0
  264.                 or unitDef.metalStorage > 0
  265.                 or unitDef.energyStorage > 0
  266.                 or unitDef.name == "armwin"
  267.                 or unitDef.name == "corwin"
  268.                 ) then
  269.             unitDefInfo[unitDefID][1] = "Econ"
  270.         else
  271.             unitDefInfo[unitDefID][1] = "Misc"
  272.         end
  273.         unitDefInfo[unitDefID][2] = ordering[unitDefID]
  274.        
  275.         --debug
  276.         --Spring.Echo(unitDef.humanName .. ": " .. unitDefInfo[unitDefID][1] .. ", " .. unitDefInfo[unitDefID][2])
  277.     end
  278. end
  279. ------------------------------------------------
  280. --drawing
  281. ------------------------------------------------
  282. --(0, 0) to (3, -3)
  283. local function DrawMain()
  284.     glLineWidth(lineWidth)
  285.    
  286.     for i=1,#BUILD_CATEGORIES do
  287.         local squareX, squareY = (i - 1) % numCols, - floor((i - 1) / numCols)
  288.         local textX, textY = (i - 1) % numCols + 0.5, -0.5 - floor((i - 1) / numCols) - textSize * 0.6
  289.         local name = BUILD_CATEGORIES[i]
  290.         if (categoryCounts[name] == 1) then --single option tex
  291.             glColor(1, 1, 1, 1)
  292.             glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
  293.            
  294.             --frames
  295.             if (drawFrames) then
  296.                 glTexture(true)
  297.                 glTexture(frameDir .. name .. frameExt)
  298.                 glTexRect(squareX, squareY - 1, squareX + 1, squareY)
  299.                 glTexture(false)
  300.             end
  301.            
  302.             glTexture(true)
  303.             glTexture('#' .. categoryUnits[name])
  304.             glTexRect(squareX, squareY - 1, squareX + 1, squareY)
  305.             glTexture(false)
  306.         else --background
  307.             glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
  308.             if (drawFrames) then
  309.                 glColor(1, 1, 1, 1)
  310.                 glTexture(true)
  311.                 glTexture(frameDir .. name .. frameExt)
  312.                 glTexRect(squareX, squareY - 1, squareX + 1, squareY)
  313.                 glTexture(false)
  314.             else
  315.                 glColor(0.25, 0.25, 0.25, 0.75)
  316.                 glRect(squareX, squareY - 1, squareX + 1, squareY)
  317.             end
  318.         end
  319.        
  320.         --text
  321.         if (categoryCounts[name] > 0) then
  322.             glColor(1, 1, 1, 1)
  323.             glText(name, textX, textY, textSize, "cn")
  324.         else
  325.             glColor(0, 0, 0, 1)
  326.             glText(name, textX, textY, textSize, "cn")
  327.         end
  328.        
  329.         --grid
  330.         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
  331.         glColor(1, 1, 1, 1)
  332.         glTexRect(squareX, squareY - 1, squareX + 1, squareY)
  333.     end
  334.    
  335. end
  336.  
  337. --(0, 0) to (3, -Y)
  338. local function DrawBuild()
  339.     glLineWidth(lineWidth)
  340.    
  341.     if (category ~= "all") then
  342.         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
  343.         if (drawFrames) then
  344.             glColor(1, 1, 1, 1)
  345.             glTexture(true)
  346.             glTexture(":l:" .. LUAUI_DIRNAME .. cancelFrameFile)
  347.             glTexRect(0, 0, 1, -1)
  348.             glTexture(false)
  349.         else
  350.             glColor(0.25, 0.25, 0.25, 0.75)
  351.             glRect(0, 0, 1, -1)
  352.         end
  353.         glColor(1, 1, 1, 1)
  354.         glText("Cancel", 0.5, -0.5, textSize, "cn")
  355.         glText(category, 0.5, -0.5 - textSize * TEXT_CORRECT_Y, textSize, "cn")
  356.         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
  357.         glRect(0, 0, 1, -1)
  358.     end
  359.    
  360.     glColor(1, 1, 1, 1)
  361.    
  362.     for i=1,#buildIDs do
  363.        
  364.         local buildID = buildIDs[i]
  365.         --top left reserved for cancel unless category is "all"
  366.         local realI = i
  367.         if (category == "all") then
  368.             realI = realI - 1
  369.         end
  370.         local x, y = realI % numCols, - floor(realI / numCols)
  371.        
  372.         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
  373.        
  374.         --test
  375.         if (drawFrames) then
  376.             glTexture(true)
  377.             if (category == "all") then
  378.                 glTexture(frameDir .. unitDefInfo[buildID][1] .. frameExt)
  379.             else
  380.                 glTexture(frameDir .. category .. frameExt)
  381.             end
  382.             glTexRect(x, y - 1, x + 1, y)
  383.             glTexture(false)
  384.         end
  385.        
  386.         glTexture(true)
  387.         glTexture('#' .. buildID)
  388.         glTexRect(x, y - 1, x + 1, y)
  389.         glTexture(false)
  390.        
  391.         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
  392.         glRect(x, y - 1, x + 1, y)
  393.     end
  394. end
  395.  
  396. local function DrawTweak()
  397.     glLineWidth(lineWidth)
  398.    
  399.     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
  400.     glColor(0.25, 0.25, 0.25, 0.75)
  401.     glRect(0, 0, 1, -1)
  402.     glColor(1, 1, 1, 1)
  403.     glText("Move", 0.5, -0.5, textSize, "cn")
  404.     glText("Menu", 0.5, -0.5 - textSize * TEXT_CORRECT_Y, textSize, "cn")
  405.     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
  406.     glRect(0, 0, 1, -1)
  407. end
  408.  
  409. local function DrawUnitTooltip(unitDef, tx, ty)
  410.     if (not unitDef) then return end
  411.     DrawTextWithBackground(
  412.             "\255\255\255\255" .. unitDef.humanName ..
  413.             " - " .. unitDef.tooltip
  414.             , tx + textSize, ty + textSize * TEXT_CORRECT_Y, textSize)
  415.     local metalCost, energyCost, buildTime = ceil(unitDef.metalCost), ceil(unitDef.energyCost), ceil(unitDef.buildTime)
  416.     if (metalCost ~= energyCost or metalCost ~= buildTime) then
  417.         DrawTextWithBackground(
  418.                 "(\255\192\192\192" .. metalCost ..
  419.                 "\255\255\255\255" .. " / " ..
  420.                 "\255\255\255\1" .. energyCost ..
  421.                 "\255\255\255\255" .. " / " ..
  422.                 "\255\1\255\1" .. buildTime ..
  423.                 "\255\255\255\255" .. ")"
  424.                 , tx + textSize, ty, textSize
  425.                 )
  426.     else
  427.         DrawTextWithBackground(
  428.             "(\255\255\255\255" .. metalCost .. ")"
  429.             , tx + textSize, ty, textSize)
  430.     end
  431.     local avgWind = 0
  432.     if (unitDef.name=="armwin" or unitDef.name=="corwin") then
  433.         avgWind = (Game.windMin + Game.windMax) * 0.05
  434.     end
  435.  
  436.     local eMake = (unitDef.energyMake or 0) - (unitDef.energyUpkeep or 0) + (unitDef.tidalGenerator or 0) * Game.tidal + avgWind
  437.     if (eMake > 0.2) then -- produces energy
  438.         local mMake = 0
  439.         if (WG.mexMetal ~= nil) then
  440.             mMake = energyToExtraM((WG.energy or 0)+ eMake)  - energyToExtraM((WG.energy or 0))
  441.         end
  442.         local sPayback = ""
  443.         if mMake > 0 then
  444.             local payback = (unitDef.metalCost or 0)/ mMake + (unitDef.energyCost or 0)/eMake  
  445.             sPayback = "- payback time ".. floor(payback/60) .."min " ..floor(payback%60) .. "s"
  446.         end
  447.         DrawTextWithBackground("Produces " .. string.format("%g",ceil(eMake*10)/10) .. " energy "..sPayback, tx+ textSize, ty -textSize* TEXT_CORRECT_Y, textSize)
  448.     end
  449. end
  450.  
  451. local function DrawTooltip(x, y)
  452.     local tx, ty = TransformMain(x, y)
  453.     local iconID = GetIconID(tx, ty)
  454.     if (not iconID) then return end
  455.    
  456.     --highlight
  457.     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
  458.     glColor(1, 1, 1, 0.25)
  459.     if (category == "all" or category == "main" or tweak) then
  460.         local x, y = (iconID - 1) % numCols, - floor((iconID - 1) / numCols)
  461.         glRect(x, y - 1, x + 1, y)
  462.     else
  463.         local x, y = iconID % numCols, - floor(iconID / numCols)
  464.         glRect(x, y - 1, x + 1, y)
  465.     end
  466.    
  467.     if (tweak) then
  468.         if (iconID == 1) then
  469.             DrawTextWithBackground("\255\255\255\255Drag to move menu", tx + textSize, ty, textSize)
  470.         end
  471.     elseif (category == "main") then
  472.         local name = BUILD_CATEGORIES[iconID]
  473.         if (categoryCounts[name] == 1) then --single unit is not nested
  474.             local buildID = categoryUnits[name]
  475.             local unitDef = UnitDefs[buildID]
  476.             DrawUnitTooltip(unitDef, tx, ty)
  477.         else
  478.             DrawTextWithBackground("\255\255\255\255" .. name, tx + textSize, ty + textSize * TEXT_CORRECT_Y, textSize)
  479.             DrawTextWithBackground("\255\255\255\255(" .. categoryCounts[name] .. " options)", tx + textSize, ty, textSize)
  480.         end
  481.     else
  482.         if (iconID == 0) then
  483.             DrawTextWithBackground("\255\255\255\255Cancel", tx + textSize, ty, textSize)
  484.         else
  485.             local unitDefID = buildIDs[iconID]
  486.             local unitDef = UnitDefs[unitDefID]
  487.             DrawUnitTooltip(unitDef, tx, ty)
  488.         end
  489.     end
  490.    
  491. end
  492.  
  493. function widget:ViewResize(viewSizeX, viewSizeY)
  494.     vsx = viewSizeX
  495.     vsy = viewSizeY
  496.     --keep panel in-screen
  497.     if (mainX < 0) then
  498.         mainX = 0
  499.     elseif (mainX > vsx - mainSize * numCols) then
  500.         mainX = vsx - mainSize * numCols
  501.     end
  502.     local numRows = ceil(max(nestThreshold, #BUILD_CATEGORIES) / numCols)
  503.     if (mainY < mainSize * numRows) then
  504.         mainY = mainSize * numRows
  505.     elseif (mainY > vsy) then
  506.         mainY = vsy
  507.     end
  508. end
  509.  
  510. function widget:DrawScreen()
  511.     if (once) then
  512.         local viewSizeX, viewSizeY = widgetHandler:GetViewSizes()
  513.         widget:ViewResize(viewSizeX, viewSizeY)
  514.         once = false
  515.     end
  516.    
  517.     if IsGUIHidden() then return end
  518.    
  519.     glPushMatrix()
  520.         glTranslate(mainX, mainY, 0)
  521.         glScale(mainSize, mainSize, 1)
  522.         if (useLists) then
  523.             if (tweak) then
  524.                 glCallList(tweakList)
  525.             else
  526.                 glCallList(mainList)
  527.             end
  528.         else
  529.             if (tweak) then
  530.                 DrawTweak()
  531.             elseif (category == "main") then
  532.                 DrawMain()
  533.             else
  534.                 DrawBuild()
  535.             end
  536.         end
  537.         local mx, my = GetMouseState()
  538.         DrawTooltip(mx, my)
  539.     glPopMatrix()
  540.    
  541.     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
  542.     glColor(1, 1, 1, 1)
  543.     glLineWidth(1)
  544. end
  545.  
  546. ------------------------------------------------
  547. --updates
  548. ------------------------------------------------
  549.  
  550. local function BuildInfoComparator(a, b)
  551.     return unitDefInfo[a][2] < unitDefInfo[b][2]
  552. end
  553.  
  554. local function UpdateLists()
  555.     if (mainList) then
  556.         glDeleteList(mainList)
  557.     end
  558.    
  559.     if (not useLists) then return end
  560.    
  561.     if (category == "main") then
  562.         mainList = glCreateList(DrawMain)
  563.     elseif (not tweak) then
  564.         mainList = glCreateList(DrawBuild)
  565.     end
  566. end
  567.  
  568. local function UpdateBuildIDs()
  569.     for i = 1, #BUILD_CATEGORIES do
  570.         local name = BUILD_CATEGORIES[i]
  571.         categoryCounts[name] = 0
  572.         categoryUnits[name] = nil
  573.     end
  574.    
  575.     local alreadySeen = {}
  576.     local totalNumber = 0
  577.     local allBuildIDs = {}
  578.     buildIDs = {}
  579.     local i = 1
  580.    
  581.     local selectedCounts = GetSelectedUnitsCounts()
  582.     for unitDefID, count in pairs(selectedCounts) do
  583.         local unitDef = UnitDefs[unitDefID]
  584.         if (unitDef and unitDef.isBuilder and unitDef.buildOptions[1]) then
  585.             for _, buildID in ipairs(unitDef.buildOptions) do
  586.                 if (not alreadySeen[buildID]) then
  587.                     alreadySeen[buildID] = true
  588.                     allBuildIDs[totalNumber + 1] = buildID
  589.                     totalNumber = totalNumber + 1
  590.                     local buildCategory = unitDefInfo[buildID][1]
  591.                     if (categoryCounts[buildCategory]) then
  592.                         categoryCounts[buildCategory] = categoryCounts[buildCategory] + 1
  593.                         categoryUnits[buildCategory] = buildID
  594.                     end
  595.                     if (buildCategory == category or category == "all") then
  596.                         buildIDs[i] = buildID
  597.                         i = i + 1
  598.                     end
  599.                 end
  600.                
  601.             end
  602.         end
  603.     end
  604.    
  605.     tweak = false
  606.     if (totalNumber == 0) then
  607.         tweak = true
  608.     elseif (totalNumber <= nestThreshold) then
  609.         category = "all"
  610.         buildIDs = allBuildIDs
  611.     elseif (#buildIDs == 0
  612.             or (totalNumber > nestThreshold and category == "all")) then
  613.         category = "main"
  614.     end
  615.    
  616.     sort(buildIDs, BuildInfoComparator)
  617.    
  618.     UpdateLists()
  619. end
  620.  
  621. --doesn't work in all mods
  622. --[[
  623. function widget:SelectionChanged(selection)
  624.     UpdateBuildIDs()
  625. end
  626. ]]
  627.  
  628. function widget:CommandsChanged()
  629.     UpdateBuildIDs()
  630. end
  631.  
  632.  
  633. ------------------------------------------------
  634. --mouse
  635. ------------------------------------------------
  636.  
  637. local function ProcessIcon(iconID, instantOnly)
  638.     if (tweak) then
  639.         if (iconID == 1 and not instantOnly) then
  640.             activeClick = "move"
  641.             return true
  642.         else
  643.             return false
  644.         end
  645.     elseif (category == "main") then
  646.         local name = BUILD_CATEGORIES[iconID]
  647.         if (not name) then return false end
  648.         if (categoryCounts[name] == 1) then --single unit is not nested
  649.             local alt, ctrl, meta, shift = GetModKeyState()
  650.             local _, _, left, _, right = GetMouseState()
  651.             local buildID = categoryUnits[name]
  652.             local index = GetCmdDescIndex(-buildID)
  653.             SetActiveCommand(index, button, left, right, alt, ctrl, meta, shift)
  654.         else
  655.             category = name
  656.             UpdateBuildIDs()
  657.         end
  658.         return true
  659.     else
  660.         if (iconID > 0 and iconID <= #buildIDs) then
  661.             local alt, ctrl, meta, shift = GetModKeyState()
  662.             local _, _, left, _, right = GetMouseState()
  663.             local index = GetCmdDescIndex(-buildIDs[iconID])
  664.             SetActiveCommand(index, button, left, right, alt, ctrl, meta, shift)
  665.         elseif (iconID ~= 0) then
  666.             return false
  667.         end
  668.         --return to main menu?
  669.         if (iconID == 0 or not cancelOnly) then
  670.             category = "main"
  671.             UpdateLists()
  672.         end
  673.         return true
  674.     end
  675. end
  676.  
  677. local function ReleaseActiveClick(x, y)
  678.     local viewSizeX, viewSizeY = widgetHandler:GetViewSizes()
  679.     widget:ViewResize(viewSizeX, viewSizeY)
  680.     activeClick = nil
  681. end
  682.  
  683. function widget:MousePress(x, y, button)
  684.     if (IsGUIHidden()) then return end
  685.     local tx, ty = TransformMain(x, y)
  686.     local iconID = GetIconID(tx, ty)
  687.     if (not iconID) then return end
  688.    
  689.     return ProcessIcon(iconID, false)
  690. end
  691.  
  692. function widget:MouseRelease(x, y, button)
  693.     if (activeClick) then
  694.         ReleaseActiveClick(x, y)
  695.         return true
  696.     end
  697.     return false
  698. end
  699.  
  700. function widget:MouseMove(x, y, dx, dy, button)
  701.     if (activeClick == "move") then
  702.         mainX = mainX + dx
  703.         mainY = mainY + dy
  704.     end
  705. end
  706.  
  707. ------------------------------------------------
  708. --bindings
  709. ------------------------------------------------
  710.  
  711. local function PressIcon(_,_,words)
  712.     if (IsGUIHidden()) then return end
  713.     local iconID = tonumber(words[1])
  714.     if (not iconID) then return end
  715.    
  716.     --account for cancel button
  717.     if (category ~= "all" and category ~= "main" and not tweak) then
  718.         iconID = iconID - 1
  719.     end
  720.    
  721.     ProcessIcon(iconID, true)
  722. end
  723.  
  724. local function ChangeSize(_,_,words)
  725.     local newSize = tonumber(words[1])
  726.     if (newSize and newSize >= 1) then
  727.         mainSize = newSize
  728.         local viewSizeX, viewSizeY = widgetHandler:GetViewSizes()
  729.         widget:ViewResize(viewSizeX, viewSizeY)
  730.     else
  731.         Spring.Echo("<Nested Buildmenu>: Invalid size.")
  732.     end
  733. end
  734.  
  735. local function ChangeCols(_,_,words)
  736.     local newCols = tonumber(words[1])
  737.     if (newCols and newCols >= 1) then
  738.         numCols = newCols
  739.         local viewSizeX, viewSizeY = widgetHandler:GetViewSizes()
  740.         widget:ViewResize(viewSizeX, viewSizeY)
  741.     else
  742.         Spring.Echo("<Nested Buildmenu>: Invalid number of columns.")
  743.     end
  744. end
  745.  
  746. local function ToggleCancelOnly()
  747.     cancelOnly = not cancelOnly
  748.     if (cancelOnly) then
  749.         Spring.Echo("<Nested Buildmenu>: Now only returns to main menu on cancel.")
  750.     else
  751.         Spring.Echo("<Nested Buildmenu>: Now only automatically returns to main menu.")
  752.     end
  753. end
  754.  
  755. local function ToggleUseLists()
  756.     useLists = not useLists
  757.     if (useLists) then
  758.         Spring.Echo("<Nested Buildmenu>: Now using display lists.")
  759.         tweakList = glCreateList(DrawTweak)
  760.         UpdateLists()
  761.     else
  762.         Spring.Echo("<Nested Buildmenu>: Now not using display lists.")
  763.         if (tweakList) then
  764.             glDeleteList(tweakList)
  765.         end
  766.         if (mainList) then
  767.             glDeleteList(mainList)
  768.         end
  769.     end
  770. end
  771.  
  772. ------------------------------------------------
  773. --other callins
  774. ------------------------------------------------
  775. function widget:Initialize()
  776.     once = true
  777.     SetupBuildCategories()
  778.     category = startCategory
  779.     tweak = true
  780.     UpdateBuildIDs()
  781.     widgetHandler:AddAction("nested_buildmenu_press", PressIcon, nil, "t")
  782.     widgetHandler:AddAction("nested_buildmenu_size", ChangeSize, nil, "t")
  783.     widgetHandler:AddAction("nested_buildmenu_cols", ChangeCols, nil, "t")
  784.     widgetHandler:AddAction("nested_buildmenu_cancelonly", ToggleCancelOnly, nil, "t")
  785.     widgetHandler:AddAction("nested_buildmenu_uselists", ToggleUseLists, nil, "t")
  786.    
  787.     drawFrames = VFS.FileExists(LUAUI_DIRNAME .. cancelFrameFile)
  788.    
  789.     tweakList = glCreateList(DrawTweak)
  790. end
  791.  
  792. function widget:Shutdown()
  793.     widgetHandler:RemoveAction("nested_buildmenu_press")
  794.     widgetHandler:RemoveAction("nested_buildmenu_size")
  795.     widgetHandler:RemoveAction("nested_buildmenu_cols")
  796.     widgetHandler:RemoveAction("nested_buildmenu_cancelonly")
  797.     widgetHandler:RemoveAction("nested_buildmenu_uselists")
  798.    
  799.     if (tweakList) then
  800.         glDeleteList(tweakList)
  801.     end
  802.     if (mainList) then
  803.         glDeleteList(mainList)
  804.     end
  805. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement