MineOS/lib/windows.lua

357 lines
12 KiB
Lua
Executable File

----------------------------------------- Libraries -----------------------------------------
-- _G.GUI, package.loaded.GUI = nil, nil
local computer = require("computer")
local buffer = require("doubleBuffering")
local GUI = require("GUI")
local unicode = require("unicode")
local event = require("event")
----------------------------------------- Constants -----------------------------------------
local windows = {}
windows.alignment = GUI.alignment
windows.colors = {
background = 0xEEEEEE,
title = {
background = 0xDDDDDD,
text = 0x262626,
},
tabBar = {
background = 0xDDDDDD,
text = 0x262626,
selectedTab = {
background = 0xCCCCCC,
text = 0x262626,
}
},
}
----------------------------------------- Universal window event handlers -----------------------------------------
local function executeObjectMethod(method, ...)
if method then method(...) end
end
local function buttonHandler(window, object, objectIndex, eventData)
if object.switchMode then
object.pressed = not object.pressed
window:draw(); buffer.draw()
executeObjectMethod(object.onTouch, eventData)
else
object.pressed = true
window:draw(); buffer.draw()
os.sleep(0.2)
object.pressed = false
window:draw(); buffer.draw()
executeObjectMethod(object.onTouch, eventData)
end
end
local function tabBarTabHandler(window, object, objectIndex, eventData)
object.parent.parent.selectedTab = objectIndex
window:draw(); buffer.draw()
executeObjectMethod(object.parent.parent.onTabSwitched, object.parent.parent.selectedTab, eventData)
end
local function inputTextBoxHandler(window, object, objectIndex, eventData)
object:input()
window:draw(); buffer.draw()
executeObjectMethod(object.onInputFinished, object.text, eventData)
end
local function textBoxScrollHandler(window, object, objectIndex, eventData)
if eventData[5] == 1 then
object:scrollUp()
window:draw(); buffer.draw()
else
object:scrollDown()
window:draw(); buffer.draw()
end
end
local function horizontalSliderHandler(window, object, objectIndex, eventData)
local clickPosition = eventData[3] - object.x + 1
object.value = object.minimumValue + (clickPosition * (object.maximumValue - object.minimumValue) / object.width)
window:draw(); buffer.draw()
executeObjectMethod(object.onValueChanged, object.value, eventData)
end
local function switchHandler(window, object, objectIndex, eventData)
object.state = not object.state
window:draw(); buffer.draw()
executeObjectMethod(object.onStateChanged, object.state, eventData)
end
local function comboBoxHandler(window, object, objectIndex, eventData)
object:selectItem()
executeObjectMethod(object.onItemSelected, object.items[object.currentItem], eventData)
end
local function menuItemHandler(window, object, objectIndex, eventData)
object.pressed = true
window:draw(); buffer.draw()
executeObjectMethod(object.onTouch, eventData)
object.pressed = false
window:draw(); buffer.draw()
end
local function scrollBarHandler(window, object, objectIndex, eventData)
local newValue = object.value
if eventData[1] == "touch" or eventData[1] == "drag" then
local delta = object.maximumValue - object.minimumValue + 1
if object.height > object.width then
newValue = math.floor((eventData[4] - object.y + 1) / object.height * delta)
else
newValue = math.floor((eventData[3] - object.x + 1) / object.width * delta)
end
elseif eventData[1] == "scroll" then
if eventData[5] == 1 then
if object.value >= object.minimumValue + object.onScrollValueIncrement then
newValue = object.value - object.onScrollValueIncrement
else
newValue = object.minimumValue
end
else
if object.value <= object.maximumValue - object.onScrollValueIncrement then
newValue = object.value + object.onScrollValueIncrement
else
newValue = object.maximumValue
end
end
end
object.value = newValue
executeObjectMethod(object.onTouch, eventData)
window:draw(); buffer.draw()
end
local function treeViewHandler(window, object, objectIndex, eventData)
if eventData[1] == "touch" then
local fileIndex = eventData[4] - object.y + object.fromFile - 1
if object.fileList[fileIndex] then
if object.fileList[fileIndex].isDirectory then
if object.directoriesToShowContent[object.fileList[fileIndex].path] then
object.directoriesToShowContent[object.fileList[fileIndex].path] = nil
else
object.directoriesToShowContent[object.fileList[fileIndex].path] = true
end
object:updateFileList()
object:draw(); buffer.draw()
else
object.currentFile = object.fileList[fileIndex].path
object:draw(); buffer.draw()
executeObjectMethod(object.onFileSelected, object.currentFile, eventData)
end
end
elseif eventData[1] == "scroll" then
if eventData[5] == 1 then
if object.fromFile > 1 then
object.fromFile = object.fromFile - 1
object:draw(); buffer.draw()
end
else
if object.fromFile < #object.fileList then
object.fromFile = object.fromFile + 1
object:draw(); buffer.draw()
end
end
end
end
local function colorSelectorHandler(window, object, objectIndex, eventData)
object.pressed = true
object:draw(); buffer.draw()
object.color = require("palette").show("auto", "auto", object.color) or object.color
object.pressed = false
object:draw(); buffer.draw()
executeObjectMethod(object.onTouch, eventData)
end
function windows.handleEventData(window, eventData)
if eventData[1] == "touch" then
local object, objectIndex = window:getClickedObject(eventData[3], eventData[4])
if object then
if object.type == GUI.objectTypes.button then
buttonHandler(window, object, objectIndex, eventData)
elseif object.type == GUI.objectTypes.tabBarTab then
tabBarTabHandler(window, object, objectIndex, eventData)
elseif object.type == GUI.objectTypes.inputTextBox then
inputTextBoxHandler(window, object, objectIndex, eventData)
elseif object.type == GUI.objectTypes.horizontalSlider then
horizontalSliderHandler(window, object, objectIndex, eventData)
elseif object.type == GUI.objectTypes.switch then
switchHandler(window, object, objectIndex, eventData)
elseif object.type == GUI.objectTypes.comboBox then
comboBoxHandler(window, object, objectIndex, eventData)
elseif object.type == GUI.objectTypes.menuItem then
menuItemHandler(window, object, objectIndex, eventData)
elseif object.type == GUI.objectTypes.scrollBar then
scrollBarHandler(window, object, objectIndex, eventData)
elseif object.type == GUI.objectTypes.treeView then
treeViewHandler(window, object, objectIndex, eventData)
elseif object.type == GUI.objectTypes.colorSelector then
colorSelectorHandler(window, object, objectIndex, eventData)
elseif object.onTouch then
executeObjectMethod(object.onTouch, eventData)
end
else
executeObjectMethod(window.onTouch, eventData)
end
elseif eventData[1] == "scroll" then
local object, objectIndex = window:getClickedObject(eventData[3], eventData[4])
if object then
if object.type == GUI.objectTypes.textBox then
textBoxScrollHandler(window, object, objectIndex, eventData)
elseif object.type == GUI.objectTypes.scrollBar then
scrollBarHandler(window, object, objectIndex, eventData)
elseif object.type == GUI.objectTypes.treeView then
treeViewHandler(window, object, objectIndex, eventData)
elseif object.onScroll then
executeObjectMethod(object.onScroll, eventData)
end
else
executeObjectMethod(window.onScroll, eventData)
end
elseif eventData[1] == "drag" then
local object, objectIndex = window:getClickedObject(eventData[3], eventData[4])
if object then
if object.type == GUI.objectTypes.horizontalSlider then
horizontalSliderHandler(window, object, objectIndex, eventData)
elseif object.type == GUI.objectTypes.scrollBar then
scrollBarHandler(window, object, objectIndex, eventData)
elseif object.onDrag then
executeObjectMethod(object.onDrag, eventData)
end
else
executeObjectMethod(window.onDrag, eventData)
end
elseif eventData[1] == "drop" then
local object, objectIndex = window:getClickedObject(eventData[3], eventData[4])
if object then
if object.onDrag then
executeObjectMethod(object.onDrop, eventData)
end
else
executeObjectMethod(window.onDrop, eventData)
end
elseif eventData[1] == "key_down" then
executeObjectMethod(window.onKeyDown, eventData)
elseif eventData[1] == "key_up" then
executeObjectMethod(window.onKeyUp, eventData)
end
executeObjectMethod(window.onAnyEvent, eventData)
end
function windows.handleEvents(window, pullTime)
while true do
window:handleEventData({event.pull(pullTime)})
if window.dataToReturn then
local data = window.dataToReturn
window = nil
return table.unpack(data)
end
end
end
----------------------------------------- Window actions -----------------------------------------
function windows.returnData(window, ...)
window.dataToReturn = {...}
computer.pushSignal("windowAction")
end
function windows.close(window)
windows.returnData(window, nil)
end
----------------------------------------- Window creation -----------------------------------------
function windows.correctWindowCoordinates(x, y, width, height, minimumWidth, minimumHeight)
width = minimumWidth and math.max(width, minimumWidth) or width
height = minimumHeight and math.max(height, minimumHeight) or height
x = (x == "auto" and math.floor(buffer.screen.width / 2 - width / 2)) or x
y = (y == "auto" and math.floor(buffer.screen.height / 2 - height / 2)) or y
return x, y, width, height
end
local function drawWindow(window)
if window.onDrawStarted then window.onDrawStarted() end
window:drawMethodOutOfWindowsLibrary()
if window.drawShadow then GUI.windowShadow(window.x, window.y, window.width, window.height, 50) end
if window.onDrawFinished then window.onDrawFinished() end
end
local function newWindow(x, y, width, height, minimumWidth, minimumHeight)
x, y, width, height = windows.correctWindowCoordinates(x, y, width, height, minimumWidth, minimumHeight)
local window = GUI.container(x, y, width, height)
window.minimumWidth = minimumWidth
window.minimumHeight = minimumHeight
window.drawShadow = false
window.drawMethodOutOfWindowsLibrary = window.draw
window.draw = drawWindow
window.handleEventData = windows.handleEventData
window.handleEvents = windows.handleEvents
window.close = windows.close
window.returnData = windows.returnData
return window
end
----------------------------------------- Window patterns -----------------------------------------
function windows.empty(x, y, width, height, minimumWidth, minimumHeight)
return newWindow(x, y, width, height, minimumWidth, minimumHeight)
end
function windows.fullScreen()
return newWindow(1, 1, buffer.screen.width, buffer.screen.height)
end
function windows.tabbed(x, y, width, height, minimumWidth, minimumHeight, ...)
local tabs = {...}
local window = newWindow(x, y, width, height, minimumWidth, minimumHeight)
window:addPanel(1, 1, window.width, window.height, 0xEEEEEE).disabled = true
window:addTabBar(1, 1, window.width, 3, 1, 0xDDDDDD, 0x262626, 0xCCCCCC, 0x262626, ...)
window:addWindowActionButtons(2, 1, false)
return window
end
----------------------------------------- Playground -----------------------------------------
-- local myWindow = windows.empty(2, 2, 60, 30, 60, 30)
-- myWindow:addColorSelector(2, 2, 30, 3, 0xFF00FF, "Text")
-- myWindow:draw()
-- buffer.draw()
-- myWindow:handleEvents()
-- local myWindow = windows.empty(2, 2, 20, 40, 20, 40)
-- myWindow:addTreeView(1, 1, myWindow.width, myWindow.height, 0xDDDDDD, 0x2D2D2D, 0x2D2D2D, 0xEEEEEE, 0x555555, 0x444444, 0x00DBFF, "/")
-- myWindow:draw()
-- buffer.draw()
-- myWindow:handleEvents()
-- local myWindow = windows.empty(2, 2, 60, 20, 60, 20)
-- local scrollBar = myWindow:addScrollBar(1, 1, 20, 1, 0x444444, 0x00DBFF, 1, 100, 50, 20, 4, true)
-- scrollBar.onTouch = function()
-- buffer.text(4, 1, 0xFFFFFF, "Value: " .. scrollBar.value)
-- end
-- myWindow:draw()
-- buffer.draw()
-- myWindow:handleEvents()
----------------------------------------- End of shit -----------------------------------------
return windows