Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- tui.lua — Расширенная библиотека псевдографического интерфейса для OpenComputers
- local component = require("component")
- local term = require("term")
- local event = require("event")
- local gpu = component.gpu
- local tui = {}
- -- Цвета по умолчанию
- tui.bgColor = 0x000000
- tui.fgColor = 0xFFFFFF
- function tui.setColors(fg, bg)
- gpu.setForeground(fg or tui.fgColor)
- gpu.setBackground(bg or tui.bgColor)
- end
- function tui.clear(bg)
- local w, h = gpu.getResolution()
- tui.setColors(nil, bg or tui.bgColor)
- gpu.fill(1, 1, w, h, " ")
- end
- function tui.box(x, y, w, h, title)
- gpu.set(x, y, "╔" .. string.rep("═", w - 2) .. "╗")
- for i = 1, h - 2 do
- gpu.set(x, y + i, "║" .. string.rep(" ", w - 2) .. "║")
- end
- gpu.set(x, y + h - 1, "╚" .. string.rep("═", w - 2) .. "╝")
- if title then gpu.set(x + 2, y, title) end
- end
- function tui.centerText(y, text)
- local w = gpu.getResolution()
- local x = math.floor((w - #text) / 2) + 1
- gpu.set(x, y, text)
- end
- function tui.button(x, y, label, active)
- local pad = 2
- local text = string.rep(" ", pad) .. label .. string.rep(" ", pad)
- tui.setColors(active and 0x000000 or 0xFFFFFF, active and 0xFFFFFF or 0x444444)
- gpu.set(x, y, text)
- tui.setColors()
- return {x = x, y = y, w = #text, h = 1, label = label}
- end
- function tui.clicked(btn, x, y)
- return x >= btn.x and x < btn.x + btn.w and y == btn.y
- end
- function tui.input(x, y, w, default)
- tui.setColors(0xFFFFFF, 0x000000)
- gpu.fill(x, y, w, 1, " ")
- gpu.set(x, y, default or "")
- term.setCursor(x, y)
- term.setCursorBlink(true)
- local input = io.read()
- term.setCursorBlink(false)
- return input
- end
- function tui.list(x, y, w, h, items, selected, keyControl)
- selected = math.max(1, math.min(selected or 1, #items))
- local offset = math.min(math.max(0, selected - math.floor(h / 2)), math.max(0, #items - h))
- local function drawList()
- for i = 1, h do
- local idx = offset + i
- local item = items[idx]
- if item then
- local isSelected = (idx == selected)
- tui.setColors(isSelected and 0x000000 or 0xFFFFFF, isSelected and 0xAAAAAA or 0x000000)
- gpu.fill(x, y + i - 1, w, 1, " ")
- gpu.set(x + 1, y + i - 1, item:sub(1, w - 2))
- else
- gpu.fill(x, y + i - 1, w, 1, " ")
- end
- end
- tui.setColors()
- end
- drawList()
- if keyControl then
- while true do
- local _, _, _, key = event.pull("key_down")
- if key == 200 then -- up
- if selected > 1 then selected = selected - 1 end
- elseif key == 208 then -- down
- if selected < #items then selected = selected + 1 end
- elseif key == 28 then -- enter
- break
- end
- offset = math.min(math.max(0, selected - math.floor(h / 2)), math.max(0, #items - h))
- drawList()
- end
- end
- return selected
- end
- function tui.toggle(x, y, label, state)
- local onText = "Вкл"
- local offText = "Выкл"
- local status = state and onText or offText
- local fullText = label .. ": [" .. status .. "]"
- local width = #label + 2 + math.max(#onText, #offText) + 2
- local bg = state and 0x00AA00 or 0xAA0000
- tui.setColors(0xFFFFFF, bg)
- gpu.fill(x, y, width, 1, " ")
- gpu.set(x + 1, y, fullText)
- tui.setColors()
- return {x = x, y = y, w = width, h = 1, state = state}
- end
- function tui.checkbox(x, y, label, checked)
- local box = checked and "[x]" or "[ ]"
- local text = box .. " " .. label
- tui.setColors(0xFFFFFF, 0x000000)
- gpu.set(x, y, text)
- return {x = x, y = y, w = #text, h = 1, checked = checked, label = label}
- end
- function tui.progressbar(x, y, w, percent)
- local fill = math.floor((w - 2) * percent)
- tui.setColors(0xFFFFFF, 0x222222)
- gpu.set(x, y, "[")
- gpu.set(x + w - 1, y, "]")
- gpu.fill(x + 1, y, w - 2, 1, " ")
- tui.setColors(0x00FF00, 0x00FF00)
- gpu.fill(x + 1, y, fill, 1, " ")
- tui.setColors()
- end
- function tui.tabBar(x, y, tabs, current)
- local tabPositions = {}
- for i, name in ipairs(tabs) do
- local active = (i == current)
- tui.setColors(active and 0x000000 or 0xFFFFFF, active and 0xFFFFFF or 0x333333)
- gpu.set(x, y, " " .. name .. " ")
- table.insert(tabPositions, {x = x, w = #name + 2})
- x = x + #name + 2
- end
- tui.setColors()
- return tabPositions
- end
- function tui.tabBarInteractive(x, y, tabs, current)
- local w = gpu.getResolution()
- local function draw()
- local cx = x
- for i, name in ipairs(tabs) do
- local active = (i == current)
- tui.setColors(active and 0x000000 or 0xFFFFFF, active and 0xFFFFFF or 0x333333)
- gpu.set(cx, y, " " .. name .. " ")
- cx = cx + #name + 2
- end
- tui.setColors()
- end
- while true do
- draw()
- local _, _, _, key = event.pull("key_down")
- if key == 203 then -- влево
- current = current > 1 and current - 1 or #tabs
- elseif key == 205 then -- вправо
- current = current < #tabs and current + 1 or 1
- elseif key == 28 then -- Enter
- break
- end
- end
- return current
- end
- function tui.popup(x, y, w, h, lines)
- tui.setColors(0xFFFFFF, 0x0000AA)
- tui.box(x, y, w, h, " ")
- for i, line in ipairs(lines) do
- if i + y < y + h - 1 then
- gpu.set(x + 1, y + i, line:sub(1, w - 2))
- end
- end
- tui.setColors()
- end
- function tui.toast(text, duration)
- local w, h = gpu.getResolution()
- local x = math.floor((w - #text) / 2)
- local y = h
- tui.setColors(0xFFFFFF, 0x880000)
- gpu.set(x, y, text)
- os.sleep(duration or 2)
- gpu.fill(x, y, #text, 1, " ")
- tui.setColors()
- end
- -- Обработка переключения вкладок и списка по клавишам, без блокировки
- -- state = { currentTab = 1, selectedItem = 1, tabs = {...}, items = {...} }
- function tui.updateTabsAndList(state, key)
- local tabsCount = #state.tabs
- local listCount = #state.items
- if key == 203 then -- влево
- state.currentTab = (state.currentTab - 2) % tabsCount + 1
- if state.currentTab ~= 2 then
- state.selectedItem = 1
- end
- elseif key == 205 then -- вправо
- state.currentTab = state.currentTab % tabsCount + 1
- if state.currentTab ~= 2 then
- state.selectedItem = 1
- end
- elseif state.currentTab == 2 then
- if key == 200 then -- вверх
- if state.selectedItem > 1 then
- state.selectedItem = state.selectedItem - 1
- end
- elseif key == 208 then -- вниз
- if state.selectedItem < listCount then
- state.selectedItem = state.selectedItem + 1
- end
- end
- end
- return state
- end
- -- Отрисовка вкладок и списка в зависимости от состояния
- function tui.drawTabsAndList(state, x, y, w, h)
- tui.tabBar(x, y, state.tabs, state.currentTab)
- if state.currentTab == 2 then
- tui.list(x, y + 2, w, h, state.items, state.selectedItem)
- else
- tui.clear()
- tui.centerText(y + 4, "Вкладка: " .. state.tabs[state.currentTab])
- end
- end
- function tui.confirmDialog(title, text)
- local w, h = 40, 7
- local sw, sh = gpu.getResolution()
- local x = math.floor((sw - w) / 2)
- local y = math.floor((sh - h) / 2)
- tui.box(x, y, w, h, title)
- tui.setColors(0xFFFFFF, 0x000000)
- gpu.set(x + 2, y + 2, text)
- local yesBtn = tui.button(x + 6, y + 4, "Да", true)
- local noBtn = tui.button(x + w - 10, y + 4, "Нет", false)
- while true do
- local _, _, cx, cy = event.pull("touch")
- if tui.clicked(yesBtn, cx, cy) then
- return true
- elseif tui.clicked(noBtn, cx, cy) then
- return false
- end
- end
- end
- return tui
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement