mirror of
https://github.com/kepler155c/opus
synced 2025-01-01 03:10:28 +00:00
canvas use in UI overhaul
This commit is contained in:
parent
02629e266b
commit
3574d26caa
149
sys/apis/ui.lua
149
sys/apis/ui.lua
@ -317,6 +317,7 @@ end
|
||||
|
||||
function Manager:setActivePage(page)
|
||||
page.parent.currentPage = page
|
||||
page.parent.canvas = page.canvas
|
||||
end
|
||||
|
||||
function Manager:setPage(pageOrName, ...)
|
||||
@ -330,7 +331,6 @@ function Manager:setPage(pageOrName, ...)
|
||||
if page == currentPage then
|
||||
page:draw()
|
||||
else
|
||||
local needSync
|
||||
if currentPage then
|
||||
if currentPage.focused then
|
||||
currentPage.focused.focused = false
|
||||
@ -338,20 +338,16 @@ function Manager:setPage(pageOrName, ...)
|
||||
end
|
||||
currentPage:disable()
|
||||
page.previousPage = currentPage
|
||||
else
|
||||
needSync = true
|
||||
end
|
||||
self:setActivePage(page)
|
||||
page:clear(page.backgroundColor)
|
||||
--page:clear(page.backgroundColor)
|
||||
page:enable(...)
|
||||
page:draw()
|
||||
if page.focused then
|
||||
page.focused.focused = true
|
||||
page.focused:focus()
|
||||
end
|
||||
if needSync then
|
||||
page:sync() -- first time a page has been set
|
||||
end
|
||||
page:sync()
|
||||
end
|
||||
end
|
||||
|
||||
@ -607,12 +603,10 @@ function UI.Window:setTextScale(textScale)
|
||||
end
|
||||
|
||||
function UI.Window:clear(bg, fg)
|
||||
if self.enabled then
|
||||
if self.canvas then
|
||||
self.canvas:clear(bg or self.backgroundColor, fg or self.textColor)
|
||||
else
|
||||
self:clearArea(1 + self.offx, 1 + self.offy, self.width, self.height, bg)
|
||||
end
|
||||
if self.canvas then
|
||||
self.canvas:clear(bg or self.backgroundColor, fg or self.textColor)
|
||||
else
|
||||
self:clearArea(1 + self.offx, 1 + self.offy, self.width, self.height, bg)
|
||||
end
|
||||
end
|
||||
|
||||
@ -630,18 +624,17 @@ function UI.Window:clearArea(x, y, width, height, bg)
|
||||
end
|
||||
|
||||
function UI.Window:write(x, y, text, bg, tc)
|
||||
if self.enabled then
|
||||
bg = bg or self.backgroundColor
|
||||
tc = tc or self.textColor
|
||||
x = x - self.offx
|
||||
y = y - self.offy
|
||||
if y <= self.height and y > 0 then
|
||||
if self.canvas then
|
||||
self.canvas:write(x, y, text, bg, tc)
|
||||
else
|
||||
self.parent:write(
|
||||
self.x + x - 1, self.y + y - 1, tostring(text), bg, tc)
|
||||
end
|
||||
bg = bg or self.backgroundColor
|
||||
tc = tc or self.textColor
|
||||
-- TODO: get rid of offx/y - scroll canvas instead
|
||||
x = x - self.offx
|
||||
y = y - self.offy
|
||||
if y <= self.height and y > 0 then
|
||||
if self.canvas then
|
||||
self.canvas:write(x, y, text, bg, tc)
|
||||
else
|
||||
self.parent:write(
|
||||
self.x + x - 1, self.y + y - 1, tostring(text), bg, tc)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -933,12 +926,6 @@ function UI.Device:postInit()
|
||||
|
||||
self.isColor = self.device.isColor()
|
||||
|
||||
self.canvas = Canvas({
|
||||
x = 1, y = 1, width = self.width, height = self.height,
|
||||
isColor = self.isColor,
|
||||
})
|
||||
self.canvas:clear(self.backgroundColor, self.textColor)
|
||||
|
||||
UI.devices[self.device.side or 'terminal'] = self
|
||||
end
|
||||
|
||||
@ -946,6 +933,7 @@ function UI.Device:resize()
|
||||
self.device.setTextScale(self.textScale)
|
||||
self.width, self.height = self.device.getSize()
|
||||
self.lines = { }
|
||||
-- TODO: resize all pages added to this device
|
||||
self.canvas:resize(self.width, self.height)
|
||||
self.canvas:clear(self.backgroundColor, self.textColor)
|
||||
end
|
||||
@ -997,11 +985,13 @@ function UI.Device:addTransition(effect, args)
|
||||
end
|
||||
|
||||
function UI.Device:runTransitions(transitions, canvas)
|
||||
--[[
|
||||
for _,t in ipairs(transitions) do
|
||||
canvas:punch(t.args) -- punch out the effect areas
|
||||
end
|
||||
canvas:blitClipped(self.device) -- and blit the remainder
|
||||
canvas:reset()
|
||||
]]
|
||||
|
||||
while true do
|
||||
for _,k in ipairs(Util.keys(transitions)) do
|
||||
@ -1028,10 +1018,9 @@ function UI.Device:sync()
|
||||
self.device.setCursorBlink(false)
|
||||
end
|
||||
|
||||
self.canvas:render(self.device)
|
||||
if transitions then
|
||||
self:runTransitions(transitions, self.canvas)
|
||||
else
|
||||
self.canvas:render(self.device)
|
||||
end
|
||||
|
||||
if self:getCursorBlink() then
|
||||
@ -1126,16 +1115,23 @@ UI.Page.defaults = {
|
||||
function UI.Page:postInit()
|
||||
self.parent = self.parent or UI.defaultDevice
|
||||
self.__target = self
|
||||
self.canvas = Canvas({
|
||||
x = 1, y = 1, width = self.parent.width, height = self.parent.height,
|
||||
isColor = self.parent.isColor,
|
||||
})
|
||||
self.canvas:clear(self.backgroundColor, self.textColor)
|
||||
end
|
||||
|
||||
function UI.Page:setParent()
|
||||
UI.Window.setParent(self)
|
||||
--[[
|
||||
if self.z then
|
||||
self.canvas = self:addLayer(self.backgroundColor, self.textColor)
|
||||
self.canvas:clear(self.backgroundColor, self.textColor)
|
||||
else
|
||||
self.canvas = self.parent.canvas
|
||||
end
|
||||
]]
|
||||
end
|
||||
|
||||
function UI.Page:enable()
|
||||
@ -1154,6 +1150,12 @@ function UI.Page:disable()
|
||||
UI.Window.disable(self)
|
||||
end
|
||||
|
||||
function UI.Page:sync()
|
||||
if self.enabled then
|
||||
self.parent:sync()
|
||||
end
|
||||
end
|
||||
|
||||
function UI.Page:capture(child)
|
||||
self.__target = child
|
||||
end
|
||||
@ -2293,9 +2295,9 @@ function UI.Tabs:eventHandler(event)
|
||||
if event.type == 'tab_change' then
|
||||
local tab = self:find(event.tab.tabUid)
|
||||
if event.current > event.last then
|
||||
tab:addTransition('slideLeft')
|
||||
self.transitionHint = 'slideLeft'
|
||||
else
|
||||
tab:addTransition('slideRight')
|
||||
self.transitionHint = 'slideRight'
|
||||
end
|
||||
|
||||
for _,child in pairs(self.children) do
|
||||
@ -2310,6 +2312,30 @@ function UI.Tabs:eventHandler(event)
|
||||
end
|
||||
end
|
||||
|
||||
--[[-- Tab --]]--
|
||||
UI.Tab = class(UI.Window)
|
||||
UI.Tab.defaults = {
|
||||
UIElement = 'Tab',
|
||||
tabTitle = 'tab',
|
||||
backgroundColor = colors.cyan,
|
||||
}
|
||||
function UI.Tab:setParent()
|
||||
UI.Window.setParent(self)
|
||||
self.canvas = self:addLayer()
|
||||
end
|
||||
|
||||
function UI.Tab:enable(...)
|
||||
self.canvas:setVisible(true)
|
||||
UI.Window.enable(self, ...)
|
||||
self:addTransition(self.parent.transitionHint or 'slideLeft')
|
||||
self:focusFirst()
|
||||
end
|
||||
|
||||
function UI.Tab:disable()
|
||||
self.canvas:setVisible(false)
|
||||
UI.Window.disable(self)
|
||||
end
|
||||
|
||||
--[[-- Wizard --]]--
|
||||
UI.Wizard = class(UI.Window)
|
||||
UI.Wizard.defaults = {
|
||||
@ -3047,7 +3073,7 @@ function UI.Chooser:eventHandler(event)
|
||||
end
|
||||
end
|
||||
|
||||
--[[-- Chooser --]]--
|
||||
--[[-- Checkbox --]]--
|
||||
UI.Checkbox = class(UI.Window)
|
||||
UI.Checkbox.defaults = {
|
||||
UIElement = 'Checkbox',
|
||||
@ -3243,6 +3269,7 @@ UI.Form.defaults = {
|
||||
values = { },
|
||||
margin = 2,
|
||||
event = 'form_complete',
|
||||
cancelEvent = 'form_cancel',
|
||||
}
|
||||
function UI.Form:postInit()
|
||||
self:createForm()
|
||||
@ -3319,7 +3346,7 @@ function UI.Form:createForm()
|
||||
table.insert(self.children, UI.Button {
|
||||
y = -self.margin, x = -7 - self.margin,
|
||||
text = 'Cancel',
|
||||
event = 'form_cancel',
|
||||
event = self.cancelEvent,
|
||||
})
|
||||
end
|
||||
end
|
||||
@ -3346,6 +3373,7 @@ function UI.Form:save()
|
||||
local s, m = self:validateField(child)
|
||||
if not s then
|
||||
self:setFocus(child)
|
||||
Sound.play('entity.villager.no', .5)
|
||||
self:emit({ type = 'form_invalid', message = m, field = child })
|
||||
return false
|
||||
end
|
||||
@ -3372,7 +3400,7 @@ function UI.Form:eventHandler(event)
|
||||
if not self:save() then
|
||||
return false
|
||||
end
|
||||
self:emit({ type = self.event, UIElement = self })
|
||||
self:emit({ type = self.event, UIElement = self, values = self.values })
|
||||
else
|
||||
return UI.Window.eventHandler(self, event)
|
||||
end
|
||||
@ -3380,49 +3408,38 @@ function UI.Form:eventHandler(event)
|
||||
end
|
||||
|
||||
--[[-- Dialog --]]--
|
||||
UI.Dialog = class(UI.Page)
|
||||
UI.Dialog = class(UI.SlideOut)
|
||||
UI.Dialog.defaults = {
|
||||
UIElement = 'Dialog',
|
||||
x = 7,
|
||||
y = 4,
|
||||
z = 2,
|
||||
height = 7,
|
||||
textColor = colors.black,
|
||||
backgroundColor = colors.white,
|
||||
okEvent ='dialog_ok',
|
||||
cancelEvent = 'dialog_cancel',
|
||||
}
|
||||
function UI.Dialog:postInit()
|
||||
self.titleBar = UI.TitleBar({ previousPage = true, title = self.title })
|
||||
self.y = -self.height
|
||||
self.titleBar = UI.TitleBar({ event = self.cancelEvent, title = self.title })
|
||||
end
|
||||
|
||||
function UI.Dialog:setParent()
|
||||
if not self.width then
|
||||
self.width = self.parent.width - 11
|
||||
end
|
||||
if self.width > self.parent.width then
|
||||
self.width = self.parent.width
|
||||
end
|
||||
self.x = math.floor((self.parent.width - self.width) / 2) + 1
|
||||
self.y = math.floor((self.parent.height - self.height) / 2) + 1
|
||||
UI.Page.setParent(self)
|
||||
function UI.Dialog:show(...)
|
||||
local canvas = self.parent:getCanvas()
|
||||
self.oldPalette = canvas.palette
|
||||
canvas:applyPalette(Canvas.darkPalette)
|
||||
UI.SlideOut.show(self, ...)
|
||||
end
|
||||
|
||||
function UI.Dialog:disable()
|
||||
self.previousPage.canvas.palette = self.oldPalette
|
||||
UI.Page.disable(self)
|
||||
end
|
||||
|
||||
function UI.Dialog:enable(...)
|
||||
self.oldPalette = self.previousPage.canvas.palette
|
||||
self.previousPage.canvas:applyPalette(Canvas.darkPalette)
|
||||
self:addTransition('grow')
|
||||
UI.Page.enable(self, ...)
|
||||
function UI.Dialog:hide(...)
|
||||
self.parent:getCanvas().palette = self.oldPalette
|
||||
UI.SlideOut.hide(self, ...)
|
||||
self.parent:draw()
|
||||
end
|
||||
|
||||
function UI.Dialog:eventHandler(event)
|
||||
if event.type == 'cancel' then
|
||||
UI:setPreviousPage()
|
||||
if event.type == 'dialog_cancel' then
|
||||
self:hide()
|
||||
end
|
||||
return UI.Page.eventHandler(self, event)
|
||||
return UI.SlideOut.eventHandler(self, event)
|
||||
end
|
||||
|
||||
--[[-- Image --]]--
|
||||
|
@ -7,24 +7,14 @@ function Transition.slideLeft(args)
|
||||
local easing = args.easing or 'outQuint'
|
||||
local pos = { x = args.ex }
|
||||
local tween = Tween.new(ticks, pos, { x = args.x }, easing)
|
||||
local lastScreen = args.canvas:copy()
|
||||
|
||||
args.canvas:move(pos.x, args.canvas.y)
|
||||
|
||||
return function(device)
|
||||
local finished = tween:update(1)
|
||||
local x = math.floor(pos.x)
|
||||
lastScreen:dirty()
|
||||
lastScreen:blit(device, {
|
||||
x = args.ex - x + args.x,
|
||||
y = args.y,
|
||||
ex = args.ex,
|
||||
ey = args.ey },
|
||||
{ x = args.x, y = args.y })
|
||||
args.canvas:blit(device, {
|
||||
x = args.x,
|
||||
y = args.y,
|
||||
ex = args.ex - x + args.x,
|
||||
ey = args.ey },
|
||||
{ x = x, y = args.y })
|
||||
args.canvas:move(math.floor(pos.x), args.canvas.y)
|
||||
args.canvas:dirty()
|
||||
args.canvas:render(device)
|
||||
return not finished
|
||||
end
|
||||
end
|
||||
@ -32,26 +22,16 @@ end
|
||||
function Transition.slideRight(args)
|
||||
local ticks = args.ticks or 6
|
||||
local easing = args.easing or'outQuint'
|
||||
local pos = { x = args.x }
|
||||
local tween = Tween.new(ticks, pos, { x = args.ex }, easing)
|
||||
local lastScreen = args.canvas:copy()
|
||||
local pos = { x = -args.canvas.width }
|
||||
local tween = Tween.new(ticks, pos, { x = 1 }, easing)
|
||||
|
||||
args.canvas:move(pos.x, args.canvas.y)
|
||||
|
||||
return function(device)
|
||||
local finished = tween:update(1)
|
||||
local x = math.floor(pos.x)
|
||||
lastScreen:dirty()
|
||||
lastScreen:blit(device, {
|
||||
x = args.x,
|
||||
y = args.y,
|
||||
ex = args.ex - x + args.x,
|
||||
ey = args.ey },
|
||||
{ x = x, y = args.y })
|
||||
args.canvas:blit(device, {
|
||||
x = args.ex - x + args.x,
|
||||
y = args.y,
|
||||
ex = args.ex,
|
||||
ey = args.ey },
|
||||
{ x = args.x, y = args.y })
|
||||
args.canvas:move(math.floor(pos.x), args.canvas.y)
|
||||
args.canvas:dirty()
|
||||
args.canvas:render(device)
|
||||
return not finished
|
||||
end
|
||||
end
|
||||
@ -62,27 +42,13 @@ function Transition.expandUp(args)
|
||||
local pos = { y = args.ey + 1 }
|
||||
local tween = Tween.new(ticks, pos, { y = args.y }, easing)
|
||||
|
||||
return function(device)
|
||||
local finished = tween:update(1)
|
||||
args.canvas:blit(device, nil, { x = args.x, y = math.floor(pos.y) })
|
||||
return not finished
|
||||
end
|
||||
end
|
||||
|
||||
function Transition.grow(args)
|
||||
local ticks = args.ticks or 3
|
||||
local easing = args.easing or 'linear'
|
||||
local tween = Tween.new(ticks,
|
||||
{ x = args.width / 2 - 1, y = args.height / 2 - 1, w = 1, h = 1 },
|
||||
{ x = 1, y = 1, w = args.width, h = args.height }, easing)
|
||||
args.canvas:move(args.x, pos.y)
|
||||
|
||||
return function(device)
|
||||
local finished = tween:update(1)
|
||||
local subj = tween.subject
|
||||
local rect = { x = math.floor(subj.x), y = math.floor(subj.y) }
|
||||
rect.ex = math.floor(rect.x + subj.w - 1)
|
||||
rect.ey = math.floor(rect.y + subj.h - 1)
|
||||
args.canvas:blit(device, rect, { x = args.x + rect.x - 1, y = args.y + rect.y - 1})
|
||||
args.canvas:move(args.x, math.floor(pos.y))
|
||||
args.canvas:dirty()
|
||||
args.canvas:render(device)
|
||||
return not finished
|
||||
end
|
||||
end
|
||||
|
@ -72,6 +72,31 @@ local page = UI.Page {
|
||||
autospace = true,
|
||||
},
|
||||
},
|
||||
help = UI.SlideOut {
|
||||
backgroundColor = colors.cyan,
|
||||
x = 5, ex = -5, height = 8, y = -8,
|
||||
titleBar = UI.TitleBar {
|
||||
title = 'Network Help',
|
||||
event = 'slide_hide',
|
||||
},
|
||||
text = UI.TextArea {
|
||||
x = 2, y = 2,
|
||||
backgroundColor = colors.cyan,
|
||||
value = [[
|
||||
|
||||
In order to connect to another computer:
|
||||
|
||||
1. The target computer must have a password set (run 'password' from the shell prompt).
|
||||
|
||||
2. From this computer, click trust and enter the password for that computer.
|
||||
|
||||
This only needs to be done once.
|
||||
]],
|
||||
},
|
||||
accelerators = {
|
||||
q = 'slide_hide',
|
||||
}
|
||||
},
|
||||
notification = UI.Notification { },
|
||||
accelerators = {
|
||||
t = 'telnet',
|
||||
@ -180,27 +205,9 @@ function page:eventHandler(event)
|
||||
sendCommand(t.id, 'shutdown')
|
||||
end
|
||||
end
|
||||
|
||||
if event.type == 'help' then
|
||||
UI:setPage(UI.Dialog {
|
||||
title = 'Network Help',
|
||||
height = 10,
|
||||
backgroundColor = colors.white,
|
||||
text = UI.TextArea {
|
||||
x = 2, y = 2,
|
||||
backgroundColor = colors.white,
|
||||
value = [[
|
||||
In order to connect to another computer:
|
||||
|
||||
1. The target computer must have a password set (run 'password' from the shell prompt).
|
||||
2. From this computer, click trust and enter the password for that computer.
|
||||
|
||||
This only needs to be done once.
|
||||
]],
|
||||
},
|
||||
accelerators = {
|
||||
q = 'cancel',
|
||||
}
|
||||
})
|
||||
self.help:show()
|
||||
|
||||
elseif event.type == 'ports' then
|
||||
self.ports.grid:update()
|
||||
|
@ -106,6 +106,7 @@ local page = UI.Page {
|
||||
}
|
||||
},
|
||||
editor = UI.SlideOut {
|
||||
y = -12, height = 12,
|
||||
backgroundColor = colors.cyan,
|
||||
titleBar = UI.TitleBar {
|
||||
title = 'Edit Application',
|
||||
|
@ -8,7 +8,7 @@ UI:configure('System', ...)
|
||||
|
||||
local systemPage = UI.Page {
|
||||
tabs = UI.Tabs {
|
||||
settings = UI.Window {
|
||||
settings = UI.Tab {
|
||||
tabTitle = 'Category',
|
||||
grid = UI.Grid {
|
||||
y = 2,
|
||||
|
@ -1,7 +1,7 @@
|
||||
local Config = require('config')
|
||||
local UI = require('ui')
|
||||
|
||||
local aliasTab = UI.Window {
|
||||
local aliasTab = UI.Tab {
|
||||
tabTitle = 'Aliases',
|
||||
description = 'Shell aliases',
|
||||
alias = UI.TextEntry {
|
||||
|
@ -4,7 +4,7 @@ local Util = require('util')
|
||||
local fs = _G.fs
|
||||
local os = _G.os
|
||||
|
||||
local labelTab = UI.Window {
|
||||
local labelTab = UI.Tab {
|
||||
tabTitle = 'Label',
|
||||
description = 'Set the computer label',
|
||||
labelText = UI.Text {
|
||||
|
@ -3,7 +3,7 @@ local UI = require('ui')
|
||||
|
||||
local device = _G.device
|
||||
|
||||
local tab = UI.Window {
|
||||
local tab = UI.Tab {
|
||||
tabTitle = 'Network',
|
||||
description = 'Networking options',
|
||||
form = UI.Form {
|
||||
@ -40,7 +40,7 @@ function tab:enable()
|
||||
local config = Config.load('os')
|
||||
self.form.modem.value = config.wirelessModem or 'auto'
|
||||
|
||||
UI.Window.enable(self)
|
||||
UI.Tab.enable(self)
|
||||
end
|
||||
|
||||
function tab:eventHandler(event)
|
||||
|
@ -2,7 +2,7 @@ local Security = require('security')
|
||||
local SHA1 = require('sha1')
|
||||
local UI = require('ui')
|
||||
|
||||
local passwordTab = UI.Window {
|
||||
local passwordTab = UI.Tab {
|
||||
tabTitle = 'Password',
|
||||
description = 'Wireless network password',
|
||||
oldPass = UI.TextEntry {
|
||||
|
@ -2,7 +2,7 @@ local Config = require('config')
|
||||
local UI = require('ui')
|
||||
local Util = require('util')
|
||||
|
||||
local pathTab = UI.Window {
|
||||
local pathTab = UI.Tab {
|
||||
tabTitle = 'Path',
|
||||
description = 'Set the shell path',
|
||||
tabClose = true,
|
||||
|
@ -3,7 +3,6 @@ local UI = require('ui')
|
||||
local settings = _G.settings
|
||||
|
||||
if settings then
|
||||
|
||||
local values = { }
|
||||
for _,v in pairs(settings.getNames()) do
|
||||
local value = settings.get(v)
|
||||
@ -16,11 +15,11 @@ if settings then
|
||||
})
|
||||
end
|
||||
|
||||
local settingsTab = UI.Window {
|
||||
local settingsTab = UI.Tab {
|
||||
tabTitle = 'Settings',
|
||||
description = 'Computercraft configurable settings',
|
||||
grid = UI.Grid {
|
||||
y = 1,
|
||||
y = 2,
|
||||
values = values,
|
||||
autospace = true,
|
||||
sortColumn = 'name',
|
||||
|
@ -9,7 +9,7 @@ if turtle then
|
||||
local values = { }
|
||||
Config.load('gps', values.home and { values.home } or { })
|
||||
|
||||
local gpsTab = UI.Window {
|
||||
local gpsTab = UI.Tab {
|
||||
tabTitle = 'GPS',
|
||||
labelText = UI.Text {
|
||||
x = 3, y = 2,
|
||||
|
Loading…
Reference in New Issue
Block a user