canvas use in UI overhaul

This commit is contained in:
kepler155c@gmail.com 2019-01-30 15:11:41 -05:00
parent 02629e266b
commit 3574d26caa
12 changed files with 137 additions and 147 deletions

View File

@ -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 --]]--

View File

@ -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

View File

@ -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()

View File

@ -106,6 +106,7 @@ local page = UI.Page {
}
},
editor = UI.SlideOut {
y = -12, height = 12,
backgroundColor = colors.cyan,
titleBar = UI.TitleBar {
title = 'Edit Application',

View File

@ -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,

View File

@ -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 {

View File

@ -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 {

View File

@ -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)

View File

@ -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 {

View File

@ -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,

View File

@ -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',

View File

@ -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,