diff --git a/inferium-gui.lua b/inferium-gui.lua index e505c41..b06d4b5 100644 --- a/inferium-gui.lua +++ b/inferium-gui.lua @@ -1 +1,15 @@ -print('TODO') \ No newline at end of file +local CountersSelector = require('libs/ui/CountersSelector') + +local config = { + counterMax = 8 +} + +local countersMap = { + iron = 1, + yolo = 2, + truc = 3 +} + +local result = CountersSelector(countersMap, config) +term.clear() +print(textutils.serialize(result)) diff --git a/install.lua b/install.lua index 18c2ee8..d21a8ee 100644 --- a/install.lua +++ b/install.lua @@ -28,7 +28,8 @@ local LIST_LIBS_FILES = { 'libs/net.lua', 'libs/utils.lua', 'libs/turtle-utils.lua', - 'libs/robot.lua' + 'libs/robot.lua', + 'libs/ui/CountersSelector.lua' } local LIST_GLOBAL_CONFIG_FILES = { @@ -73,6 +74,7 @@ end local prepareDirs = function() fs.makeDir('/old') fs.makeDir('/libs') + fs.makeDir('/libs/ui') fs.makeDir('/config') fs.makeDir('/data') end diff --git a/libs/ui/CountersSelector.lua b/libs/ui/CountersSelector.lua new file mode 100644 index 0000000..839ed56 --- /dev/null +++ b/libs/ui/CountersSelector.lua @@ -0,0 +1,157 @@ +local utils = require('libs/utils') + +local function noTitleFn() + return "" +end + +local savedTextColor = nil +local savedBackgroundColor = nil + +local function saveTermConfig() + savedTextColor = term.getTextColor() + savedBackgroundColor = term.getBackgroundColor() +end + +local function restoreTermConfig() + term.setTextColor(savedTextColor) + term.setBackgroundColor(savedBackgroundColor) +end + +local function getTotalCount(countersMap) + local total = 0 + for _, counter in pairs(countersMap) do + total = total + (counter or 0) + end + return total +end + +local function omitN(t, n) + local result = {} + + for k,v in pairs(t) do + if n == 0 then + result[k] = v + end + n = n - 1 + end + + return result +end + +local function pickN(t, n) + local result = {} + + for k,v in pairs(t) do + if n == 0 then + break + end + result[k] = v + n = n - 1 + end + + return result +end + +local TITLE_MARGIN = 1 + +local function renderCountersMap(countersMap, selectedCounter, titleFn) + term.setCursorPos(1, 1) + local _, height = term.getSize() + -- local nbCounters = utils.sizeof(countersMap) + local selectedCounterKey = countersMap[selectedCounter] + -- local totalCount = getTotalCount(countersMap) + + local topMargin = 0 + local bottomMargin = 0 + + if titleFn ~= noTitleFn then + term.clearLine() + term.write('custom title: ' .. titleFn(countersMap, selectedCounter)) + topMargin = TITLE_MARGIN + end + + local availableHeight = height - topMargin - bottomMargin + + local selectedPage = (selectedCounter % availableHeight) + 1 + -- local totalPages = (nbCounters % availableHeight) + 1 + + local nbElementsToOmit = (selectedPage - 1) * availableHeight + local displayedCounters = pickN(omitN(countersMap, nbElementsToOmit), availableHeight) + + local cursorYIndex = 1 + topMargin + for k,v in pairs(displayedCounters) do + term.clearLine() + term.setCursorPos(1, cursorYIndex) + + if k == selectedCounterKey then + term.setBackgroundColor(colors.white) + term.setTextColor(colors.black) + else + term.setBackgroundColor(colors.black) + term.setTextColor(colors.white) + end + + term.write(tostring(k) .. ' ' .. tostring(v)) + cursorYIndex = cursorYIndex + 1 + end +end + +local function CountersSelector(initialCountersMap, config) + local countersMap = utils.shallowClone(initialCountersMap) + local counterMax = config.counterMax + local titleFn = config.titleFn or noTitleFn + + if not counterMax then + error('no counterMax found in CountersSelector config') + end + + if utils.sizeof(countersMap) == 0 then + error('empty countersMap provided') + end + + saveTermConfig() + term.clear() + + local selectedCounter = 1 + local nbCounters = utils.sizeof(countersMap) + local globalCounter = getTotalCount(countersMap) + + if globalCounter > counterMax then + error('counter cannot be greater than the counterMax') + end + + local shouldContinue = true + while shouldContinue do + local _, keyPressed, isHeld = os.pullEvent('key') + + if keyPressed == keys.up then + selectedCounter = math.max(1, selectedCounter - 1) + elseif keyPressed == keys.down then + selectedCounter = math.min(nbCounters, selectedCounter + 1) + elseif keyPressed == keys.left and globalCounter > 0 then + local currentCount = countersMap[selectedCounter] + if currentCount and currentCount > 0 then + countersMap[selectedCounter] = currentCount - 1 + globalCounter = globalCounter - 1 + end + elseif keyPressed == keys.right and globalCounter < counterMax then + local currentCount = countersMap[selectedCounter] + if currentCount then + countersMap[selectedCounter] = currentCount + 1 + globalCounter = globalCounter + 1 + end + elseif keyPressed == keys.enter then + shouldContinue = false + end + + if shouldContinue then + renderCountersMap(countersMap, selectedCounter, titleFn) + end + end + + restoreTermConfig() + + return countersMap, selectedCounter +end + +return CountersSelector \ No newline at end of file