Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- CC Tweaked Forums: https://forums.computercraft.cc/index.php?topic=458.0
- local count = {}
- local increment = {index = 0, count = -1, max = -1}
- local scrollPos = 0
- local Vector2 = function(x, y)
- return {x = x, y = y}
- end
- local size = Vector2(term.getSize())
- if fs.exists("simplecounter.txt") then -- Checks if counter data exists and loads it.
- local f = fs.open("simplecounter.txt","r")
- count = textutils.unserialize(f.readAll())
- f.close()
- end
- local saveCount = function() -- Saves counter data to a file.
- local f = fs.open("simplecounter.txt","w")
- f.write(textutils.serialize(count))
- f.close()
- end
- local drawLine = function(index) -- Draws all counter properties.
- term.setCursorPos(1, index-scrollPos)
- local str = "x R " .. string.char(24) .. string.char(25) .. " L -+" .. count[index].count .. "/M" -- Text for delete, rename, reposition, lock, count up/down, max, and max up/down buttons, and the count itself, and "/" (for count/max).
- local textColor = "fff" -- Text color for lock button and surrounding spaces.
- local backColor = "8f8f88f8f88" .. string.rep("0", string.len(count[index].count)) .. "f8" -- Background color for all buttons up to count up/down.
- if index == #count then -- Text color for the down reposition button.
- textColor = "7" .. textColor -- Gray if at the bottom of the list; can't move this counter down anymore.
- else
- textColor = "f" .. textColor -- Black if not at the bottom of the list.
- end
- if index == 1 then -- Text color for the up reposition button and the space before.
- textColor = "f7" .. textColor -- Button is gray if at the top of the list; can't move this counter up anymore.
- else
- textColor = "ff" .. textColor -- Black if not at the top of the list.
- end
- if count[index].locked then -- Text color for the remainder of the buttons as well as the count itself.
- textColor = "7f7" .. textColor .. "77" .. string.rep("f", string.len(count[index].count)) .. "07" -- Gray if this counter is locked.
- else
- textColor = "fff" .. textColor .. "ff" .. string.rep("f", string.len(count[index].count)) .. "0f" -- Black if this counter is not locked
- end
- if count[index].max then -- Draws the max number and percentage if the max number is enabled.
- local percent = math.floor(count[index].count/count[index].max*100000)/1000 -- The percentage of count/max.
- str = str .. "-+" .. count[index].max .. " " .. percent .. "%"
- if count[index].locked then
- textColor = textColor .. "77"
- else
- textColor = textColor .. "ff"
- end
- textColor = textColor .. string.rep("f", string.len(count[index].max)) .. "f" .. string.rep("4", string.len(percent)) .. "4"
- backColor = backColor .. "88" .. string.rep("0", string.len(count[index].max)) .. "f" .. string.rep("f", string.len(percent)) .. "f"
- end
- str = str .. " " .. count[index].name -- Text, text color, and background color for the counter name.
- textColor = textColor .. "f" .. string.rep("0", count[index].name:len())
- backColor = backColor .. "f" .. string.rep("f", count[index].name:len())
- str = str .. string.rep(" ", size.x-str:len()) -- Text, text color, background color for the empty space after the counter name.
- textColor = textColor .. string.rep("f", size.x-textColor:len())
- backColor = backColor .. string.rep("f", size.x-backColor:len())
- term.blit(str, textColor, backColor) -- Draws the above data to the screen.
- end
- local drawAll = function() -- Draws the whole screen.
- for a = 1, size.y do
- if a+scrollPos <= #count then
- drawLine(a+scrollPos)
- elseif a+scrollPos > #count then
- term.setCursorPos(1, a)
- term.setBackgroundColor(colors.black)
- term.clearLine()
- if a+scrollPos == #count+1 then
- term.blit("Add Exit", "ffffffff", "888f8888")
- end
- end
- end
- end
- local editName = function(name) -- Enters a name for a new or existing counter.
- term.setBackgroundColor(colors.black)
- term.clear()
- term.setCursorPos(1, 1)
- term.setTextColor(colors.yellow)
- term.write(name)
- term.setCursorPos(1, 2)
- term.setTextColor(colors.white)
- term.write("New Name: ")
- return read()
- end
- local addSub = function(index, key, dir) -- Adds or subtracts the count or max values by the increment amount.
- local anti = ""
- if key == "count" then
- anti = "max"
- else
- anti = "count"
- end
- if increment[key] < 1 then
- increment[key] = 1
- end
- increment[anti] = -1
- count[index][key] = count[index][key] + increment[key] * dir
- if string.len(math.abs(count[index][key])) < string.len(increment[key]) then -- Moves the selected digit if the number is smaller than the increment amount.
- increment[key] = 10 ^ (string.len(math.abs(count[index][key])) - 1)
- end
- saveCount()
- drawLine(index)
- end
- local selectDigit = function(index, key, digit) -- Selects the clicked digit and the increment buttons will increment that digit.
- local anti = ""
- if key == "count" then
- anti = "max"
- else
- anti = "count"
- end
- if digit > 1 and count[index][key] < 0 then
- digit = digit + 1
- end
- if digit == string.len(math.abs(count[index][key]))+1 then
- increment[key] = 0 -- If the space after the number is clicked, it sets the cursor to where keyboard input can add numbers to the end.
- else
- increment[key] = 10 ^ (string.len(math.abs(count[index][key])) - digit)
- end
- increment[anti] = -1
- end
- local changeIndex = function(dir) -- Processes changing which counter the cursor is on when pressing the up or down keys.
- repeat -- Scans the counters in the given direction until it either reaches the top or bottom of the list or finds a counter that's not locked.
- increment.index = increment.index + dir
- until increment.index == 0 or increment.index > #count or not count[increment.index].locked
- if increment.index == 0 or increment.index > #count then -- If an unlocked counter is not found the cursor is turned off.
- increment = {index = 0, count = -1, max = -1}
- elseif increment.index > 0 and increment.count < 0 and increment.max < 0 then
- increment.count = 0
- end
- if increment.count > -1 and string.len(increment.count) > string.len(math.abs(count[increment.index].count)) then -- This ensures the cursor is within the digits of the selected counter.
- increment.count = 10 ^ (string.len(math.abs(count[increment.index].count)) - 1)
- elseif increment.max > -1 then
- if count[increment.index].max then -- This ensures the cursor is within the digits of the max of the selected counter.
- if string.len(increment.max) > string.len(math.abs(count[increment.index].max)) then
- increment.max = 10 ^ (string.len(math.abs(count[increment.index].count)) - 1)
- end
- else -- If the max is disabled, the cursor will move to the count.
- increment.max = -1
- increment.count = 0
- end
- end
- end
- local deleteNum = function(index, key, space) -- This processes when the backspace or delete keys are pressed and the cursor is enabled.
- local digit = string.len(count[index][key]) - string.len(increment[key]) -- Locates where on the number the cursor is located.
- if increment[key] == 0 then
- digit = string.len(count[index][key])
- end
- if (space == 0 and digit > 0) or (space == 1 and digit < string.len(count[index][key])) then -- Check if backspace is pressed and the cursor is not at the very start of the number, or if delete is pressed and the cursor is not at the very end of the number.
- if string.len(math.abs(count[index][key])) == 1 then -- If the number is single digit when deleted, it is set to 0.
- count[index][key] = 0
- elseif digit == 0 then -- If delete (but not backspace) is pressed, deleted the first digit in the number.
- count[index][key] = tonumber(string.sub(count[index][key], digit+1+space, string.len(count[index][key])))
- elseif digit == string.len(count[index][key]) then -- If backspace (but not delete) is pressed, delete the last digit in the number.
- count[index][key] = tonumber(string.sub(count[index][key], 0, digit-1+space))
- else -- If delete is pressed, delete the current digit. If backspace is pressed, delete the previous digit.
- count[index][key] = tonumber(string.sub(count[index][key], 0, digit-1+space) .. string.sub(count[index][key], digit+1+space, string.len(count[index][key])))
- end
- if string.len(increment[key]) > string.len(math.abs(count[index][key])) then -- Ensures that the increment value is still within the boundaries of the selected number.
- increment[key] = 10 ^ (string.len(math.abs(count[index][key])) - 1)
- end
- if space == 1 then -- Decreases the increment value when delete is pressed.
- if increment[key] == 1 then
- increment[key] = 0
- else
- increment[key] = increment[key] / 10
- end
- end
- saveCount()
- drawLine(index)
- end
- end
- drawAll()
- while true do
- if increment.index > 0 then -- Draws the cursor blink over whichever digit is being incremented or decremented if it is so.
- if increment.count > -1 then
- if increment.count > 0 then
- term.setCursorPos(12+string.len(count[increment.index].count)-string.len(increment.count), increment.index-scrollPos)
- term.setTextColor(colors.black)
- else
- term.setCursorPos(12+string.len(count[increment.index].count), increment.index-scrollPos)
- term.setTextColor(colors.white)
- end
- term.setCursorBlink(true)
- elseif count[increment.index].max and increment.max > -1 then
- if increment.max > 0 then
- term.setCursorPos(16+string.len(count[increment.index].count)+string.len(count[increment.index].max)-string.len(increment.max), increment.index-scrollPos)
- term.setTextColor(colors.black)
- else
- term.setCursorPos(16+string.len(count[increment.index].count)+string.len(count[increment.index].max), increment.index-scrollPos)
- term.setTextColor(colors.white)
- end
- term.setCursorBlink(true)
- end
- end
- local event = {os.pullEvent()}
- term.setCursorBlink(false)
- if event[1] == "mouse_click" then
- local clickPos = event[4] + scrollPos
- if clickPos == #count+1 then
- if event[3] >= 1 and event[3] <= 3 then -- Adds a counter to the list.
- table.insert(count, #count+1, {count=0, name=editName("New Counter"), locked=false})
- saveCount()
- drawAll()
- elseif event[3] >= 5 and event[3] <= 8 then -- Exits the program.
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- term.clear()
- term.setCursorPos(1, 1)
- error()
- end
- increment = {index = 0, count = -1, max = -1}
- elseif clickPos <= #count then -- Something on a counter is clicked.
- increment.index = clickPos
- if event[3] == 1 and not count[clickPos].locked then -- Deletes the counter if the counter is not locked.
- increment = {index = 0, count = -1, max = -1}
- table.remove(count, clickPos)
- term.setBackgroundColor(colors.black)
- term.clear()
- saveCount()
- drawAll()
- elseif event[3] == 3 and not count[clickPos].locked then -- Renames the counter if the counter is not locked.
- increment = {index = 0, count = -1, max = -1}
- count[clickPos].name = editName(count[clickPos].name)
- saveCount()
- drawAll()
- elseif event[3] == 5 and clickPos ~= 1 then -- Moves the counter up in the list if it is not at the top of the list. Locking does not affect this function.
- increment = {index = 0, count = -1, max = -1}
- table.insert(count, clickPos-1, count[clickPos])
- table.remove(count, clickPos+1)
- saveCount()
- drawLine(clickPos)
- drawLine(clickPos-1)
- elseif event[3] == 6 and clickPos ~= #count then -- Moves the counter down in the list if it is not at the bottom of the list. Locking does not affect this function.
- increment = {index = 0, count = -1, max = -1}
- table.insert(count, clickPos+2, count[clickPos])
- table.remove(count, clickPos)
- saveCount()
- drawLine(clickPos)
- drawLine(clickPos+1)
- elseif event[3] == 8 then -- Locks or unlocks the counter. Locking prevents accidentally deleting or changing the counter.
- increment = {index = 0, count = -1, max = -1}
- if count[clickPos].locked then
- count[clickPos].locked = false
- else
- count[clickPos].locked = true
- end
- saveCount()
- drawLine(clickPos)
- elseif event[3] == 10 and not count[clickPos].locked then -- Decrements the count if the counter is not locked.
- addSub(clickPos, "count", -1)
- elseif event[3] == 11 and not count[clickPos].locked then -- Increments the count if the counter is not locked.
- addSub(clickPos, "count", 1)
- elseif event[3] >= 12 and event[3] <= 12+string.len(count[clickPos].count) and not count[clickPos].locked then -- If the count number is clicked, it selects the clicked digit and the increment buttons will increment that digit. Will do nothing if the counter is locked.
- selectDigit(clickPos, "count", event[3] - 11)
- elseif event[3] == 13+string.len(count[clickPos].count) and not count[clickPos].locked then -- Toggles the max value if the counter is not locked.
- increment = {index = 0, count = -1, max = -1}
- if count[clickPos].max then
- count[clickPos].max = nil
- else
- count[clickPos].max = 0
- end
- saveCount()
- drawLine(clickPos)
- elseif event[3] == 14+string.len(count[clickPos].count) and count[clickPos].max and not count[clickPos].locked then -- Decrements the max value if it is enabled and the counter is not locked.
- addSub(clickPos, "max", -1)
- elseif event[3] == 15+string.len(count[clickPos].count) and count[clickPos].max and not count[clickPos].locked then -- Increments the max value if it is enabled and the counter is not locked.
- addSub(clickPos, "max", 1)
- elseif count[clickPos].max and event[3] >= 16+string.len(count[clickPos].count) and event[3] <= 16+string.len(count[clickPos].count)+string.len(count[clickPos].max) and not count[clickPos].locked then -- If the max number is clicked, it selects the clicked digit and the increment buttons will increment that digit. Will do nothing if the counter is locked.
- selectDigit(clickPos, "max", event[3] - string.len(count[clickPos].count) - 15)
- else
- increment = {index = 0, count = -1, max = -1}
- end
- else
- increment = {index = 0, count = -1, max = -1}
- end
- elseif event[1] == "mouse_scroll" then -- Scrolls the list with the mouse wheel.
- if (event[2] == -1 and scrollPos > 0) or (event[2] == 1 and scrollPos+size.y-1 <= #count) then
- scrollPos = scrollPos + event[2]
- drawAll()
- end
- elseif event[1] == "char" and increment.index > 0 then
- if event[2] == "-" then -- Toggles the selected number between positive and negative.
- if increment.count > -1 then
- count[increment.index].count = count[increment.index].count * -1
- saveCount()
- drawLine(increment.index)
- elseif increment.max > -1 then
- count[increment.index].max = count[increment.index].max * -1
- saveCount()
- drawLine(increment.index)
- end
- elseif tonumber(event[2]) then -- Inserts the input number into the selected number.
- if increment.count > -1 then
- local digit = string.len(count[increment.index].count) - string.len(increment.count)
- if increment.count == 0 then
- digit = string.len(count[increment.index].count)
- end
- count[increment.index].count = tonumber(string.sub(count[increment.index].count, 0, digit) .. event[2] .. string.sub(count[increment.index].count, digit+1, string.len(count[increment.index].count)+1))
- saveCount()
- drawLine(increment.index)
- elseif increment.max > -1 then
- local digit = string.len(count[increment.index].max) - string.len(increment.max)
- if increment.max == 0 then
- digit = string.len(count[increment.index].max)
- end
- count[increment.index].max = tonumber(string.sub(count[increment.index].max, 0, digit) .. event[2] .. string.sub(count[increment.index].max, digit+1, string.len(count[increment.index].max)+1))
- saveCount()
- drawLine(increment.index)
- end
- end
- elseif event[1] == "key" then
- if event[2] == keys.left and increment.index > 0 then -- Move the cursor left along the numbers in the current counter.
- if increment.max == 0 then
- increment.max = 1
- elseif increment.max > -1 and string.len(increment.max) < string.len(math.abs(count[increment.index].max)) then
- increment.max = increment.max * 10
- elseif increment.max > -1 and string.len(increment.max) == string.len(math.abs(count[increment.index].max)) then
- increment.max = -1
- increment.count = 0
- elseif increment.count == 0 then
- increment.count = 1
- elseif string.len(increment.count) < string.len(math.abs(count[increment.index].count)) then
- increment.count = increment.count * 10
- end
- elseif event[2] == keys.right and increment.index > 0 then -- Move the cursor right along the numbers in the current counter. Will not move to the max if max is disabled.
- if increment.count > 1 then
- increment.count = increment.count / 10
- elseif increment.count == 1 then
- increment.count = 0
- elseif increment.count == 0 and count[increment.index].max then
- increment.count = -1
- increment.max = 10 ^ (string.len(math.abs(count[increment.index].max)) - 1)
- elseif increment.max > 1 then
- increment.max = increment.max / 10
- elseif increment.max == 1 then
- increment.max = 0
- end
- elseif event[2] == keys.up and increment.index > 0 then -- Scans for the previous unlocked counter or deselects the counter.
- changeIndex(-1)
- elseif event[2] == keys.down and increment.index <= #count then -- Scans for the next unlocked counter or deselects the counter.
- changeIndex(1)
- elseif event[2] == keys.backspace and increment.index > 0 then -- Deletes the previous digit in the selected number.
- if increment.count > -1 then
- deleteNum(increment.index, "count", 0)
- elseif increment.max > -1 then
- deleteNum(increment.index, "max", 0)
- end
- elseif event[2] == keys.delete and increment.index > 0 then -- Deletes the current digit in the selected number.
- if increment.count > -1 then
- deleteNum(increment.index, "count", 1)
- elseif increment.max > -1 then
- deleteNum(increment.index, "max", 1)
- end
- elseif event[2] == keys.home and increment.index > 0 then -- Move the cursor to the start of the selected counter.
- if increment.max > -1 and (increment.max == 0 or string.len(increment.max) < string.len(math.abs(count[increment.index].max))) then -- If max is selected, moves the cursor to the start of the max.
- increment.max = 10 ^ (string.len(math.abs(count[increment.index].max)) - 1)
- else -- If the cursor is at the start of the max or is in counter, moves the cursor to the start of the counter.
- increment.max = -1
- increment.count = 10 ^ (string.len(math.abs(count[increment.index].count)) - 1)
- end
- elseif event[2] == keys["end"] and increment.index > 0 then -- Moves the cursor to the end of the selected counter.
- if increment.count > -1 and increment.count > 0 then -- If counter is selected, moves the cursor to the end of the counter.
- increment.count = 0
- else -- If at the end of the counter and max exists, or if max is selected, moves the cursor to the end of the max.
- if count[increment.index].max then
- increment.count = -1
- increment.max = 0
- end
- end
- end
- elseif event[1] == "term_resize" then
- size = Vector2(term.getSize())
- end
- end
- -- 2022/11/08
- -- Fixed a bug not displaying counters correctly when scrolling.
Add Comment
Please, Sign In to add comment