canvas overhaul
This commit is contained in:
@@ -1,32 +0,0 @@
|
||||
local class = require('opus.class')
|
||||
local UI = require('opus.ui')
|
||||
|
||||
UI.ActiveLayer = class(UI.Window)
|
||||
UI.ActiveLayer.defaults = {
|
||||
UIElement = 'ActiveLayer',
|
||||
}
|
||||
function UI.ActiveLayer:layout()
|
||||
UI.Window.layout(self)
|
||||
if not self.canvas then
|
||||
self.canvas = self:addLayer()
|
||||
else
|
||||
self.canvas:resize(self.width, self.height)
|
||||
end
|
||||
end
|
||||
|
||||
function UI.ActiveLayer:enable(...)
|
||||
self.canvas:raise()
|
||||
self.canvas:setVisible(true)
|
||||
UI.Window.enable(self, ...)
|
||||
if self.parent.transitionHint then
|
||||
self:addTransition(self.parent.transitionHint)
|
||||
end
|
||||
self:focusFirst()
|
||||
end
|
||||
|
||||
function UI.ActiveLayer:disable()
|
||||
if self.canvas then
|
||||
self.canvas:setVisible(false)
|
||||
end
|
||||
UI.Window.disable(self)
|
||||
end
|
||||
@@ -35,11 +35,11 @@ function UI.Button:draw()
|
||||
local bg = self.backgroundColor
|
||||
local ind = ' '
|
||||
if self.focused then
|
||||
bg = self.backgroundFocusColor
|
||||
fg = self.textFocusColor
|
||||
bg = self:getProperty('backgroundFocusColor')
|
||||
fg = self:getProperty('textFocusColor')
|
||||
ind = self.focusIndicator
|
||||
elseif self.inactive then
|
||||
fg = self.textInactiveColor
|
||||
fg = self:getProperty('textInactiveColor')
|
||||
end
|
||||
local text = ind .. self.text .. ' '
|
||||
if self.centered then
|
||||
|
||||
@@ -21,9 +21,6 @@ UI.Checkbox.defaults = {
|
||||
mouse_click = 'checkbox_toggle',
|
||||
}
|
||||
}
|
||||
UI.Checkbox.inherits = {
|
||||
labelBackgroundColor = 'backgroundColor',
|
||||
}
|
||||
function UI.Checkbox:postInit()
|
||||
self.width = self.label and #self.label + 4 or 3
|
||||
end
|
||||
|
||||
@@ -11,8 +11,8 @@ UI.Chooser.defaults = {
|
||||
nochoice = 'Select',
|
||||
backgroundFocusColor = colors.lightGray,
|
||||
textInactiveColor = colors.gray,
|
||||
leftIndicator = UI.extChars and '\17' or '<',
|
||||
rightIndicator = UI.extChars and '\16' or '>',
|
||||
leftIndicator = UI.extChars and '\171' or '<',
|
||||
rightIndicator = UI.extChars and '\187' or '>',
|
||||
height = 1,
|
||||
accelerators = {
|
||||
space = 'choice_next',
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
local Canvas = require('opus.ui.canvas')
|
||||
local class = require('opus.class')
|
||||
local UI = require('opus.ui')
|
||||
|
||||
@@ -19,14 +18,14 @@ function UI.Dialog:postInit()
|
||||
end
|
||||
|
||||
function UI.Dialog:show(...)
|
||||
local canvas = self.parent:getCanvas()
|
||||
local canvas = self.parent
|
||||
self.oldPalette = canvas.palette
|
||||
canvas:applyPalette(Canvas.darkPalette)
|
||||
canvas:applyPalette(self.darkPalette)
|
||||
UI.SlideOut.show(self, ...)
|
||||
end
|
||||
|
||||
function UI.Dialog:hide(...)
|
||||
self.parent:getCanvas().palette = self.oldPalette
|
||||
self.parent.palette = self.oldPalette
|
||||
UI.SlideOut.hide(self, ...)
|
||||
self.parent:draw()
|
||||
end
|
||||
@@ -37,3 +36,30 @@ function UI.Dialog:eventHandler(event)
|
||||
end
|
||||
return UI.SlideOut.eventHandler(self, event)
|
||||
end
|
||||
|
||||
function UI.Dialog.example()
|
||||
return UI.Dialog {
|
||||
title = 'Enter Starting Level',
|
||||
height = 7,
|
||||
form = UI.Form {
|
||||
y = 3, x = 2, height = 4,
|
||||
event = 'setStartLevel',
|
||||
cancelEvent = 'slide_hide',
|
||||
text = UI.Text {
|
||||
x = 5, y = 1, width = 20,
|
||||
textColor = colors.gray,
|
||||
},
|
||||
textEntry = UI.TextEntry {
|
||||
formKey = 'level',
|
||||
x = 15, y = 1, width = 7,
|
||||
},
|
||||
},
|
||||
statusBar = UI.StatusBar(),
|
||||
enable = function(self)
|
||||
require('opus.event').onTimeout(0, function()
|
||||
self:show()
|
||||
self:sync()
|
||||
end)
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
@@ -32,42 +32,38 @@ function UI.DropMenu:layout()
|
||||
self.height = #self.children + 1
|
||||
self.width = maxWidth + 2
|
||||
|
||||
if not self.canvas then
|
||||
self.canvas = self:addLayer()
|
||||
else
|
||||
self.canvas:resize(self.width, self.height)
|
||||
if self.x + self.width > self.parent.width then
|
||||
self.x = self.parent.width - self.width + 1
|
||||
end
|
||||
|
||||
self:reposition(self.x, self.y, self.width, self.height)
|
||||
end
|
||||
|
||||
function UI.DropMenu:enable()
|
||||
end
|
||||
|
||||
function UI.DropMenu:show(x, y)
|
||||
self.x, self.y = x, y
|
||||
self.canvas:move(x, y)
|
||||
self.canvas:setVisible(true)
|
||||
for _,c in pairs(self.children) do
|
||||
if not c.spacer then
|
||||
c.inactive = not self:getActive(c)
|
||||
end
|
||||
end
|
||||
|
||||
UI.Window.enable(self)
|
||||
|
||||
self:draw()
|
||||
self:capture(self)
|
||||
self:focusFirst()
|
||||
self:draw()
|
||||
end
|
||||
|
||||
function UI.DropMenu:hide()
|
||||
self:disable()
|
||||
self.canvas:setVisible(false)
|
||||
self:release(self)
|
||||
function UI.DropMenu:disable()
|
||||
UI.Window.disable(self)
|
||||
self:remove()
|
||||
end
|
||||
|
||||
function UI.DropMenu:eventHandler(event)
|
||||
if event.type == 'focus_lost' and self.enabled then
|
||||
if not Util.contains(self.children, event.focused) then
|
||||
self:hide()
|
||||
self:disable()
|
||||
end
|
||||
elseif event.type == 'mouse_out' and self.enabled then
|
||||
self:hide()
|
||||
self:refocus()
|
||||
self:disable()
|
||||
self:setFocus(self.parent:find(self.lastFocus))
|
||||
else
|
||||
return UI.MenuBar.eventHandler(self, event)
|
||||
end
|
||||
@@ -83,6 +79,15 @@ function UI.DropMenu.example()
|
||||
{ spacer = true },
|
||||
{ text = 'Quit ^q', event = 'quit' },
|
||||
} },
|
||||
{ text = 'Edit', dropdown = {
|
||||
{ text = 'Copy', event = 'run' },
|
||||
{ text = 'Paste s', event = 'shell' },
|
||||
} },
|
||||
{ text = '\187',
|
||||
x = -3,
|
||||
dropdown = {
|
||||
{ text = 'Associations', event = 'associate' },
|
||||
} },
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
@@ -14,7 +14,7 @@ UI.DropMenuItem.defaults = {
|
||||
}
|
||||
function UI.DropMenuItem:eventHandler(event)
|
||||
if event.type == 'button_activate' then
|
||||
self.parent:hide()
|
||||
self.parent:disable()
|
||||
end
|
||||
return UI.Button.eventHandler(self, event)
|
||||
end
|
||||
|
||||
@@ -18,45 +18,33 @@ UI.Embedded.defaults = {
|
||||
function UI.Embedded:setParent()
|
||||
UI.Window.setParent(self)
|
||||
|
||||
function self.render()
|
||||
self:sync()
|
||||
end
|
||||
self.win = Terminal.window(UI.term.device, self.x, self.y, self.width, self.height, false)
|
||||
self.win.canvas = self
|
||||
self.win.setMaxScroll(self.maxScroll)
|
||||
|
||||
local canvas = self:getCanvas()
|
||||
self.win.getCanvas().parent = canvas
|
||||
table.insert(canvas.layers, self.win.getCanvas())
|
||||
self.canvas = self.win.getCanvas()
|
||||
|
||||
self.win.setCursorPos(1, 1)
|
||||
self.win.setBackgroundColor(self.backgroundColor)
|
||||
self.win.setTextColor(self.textColor)
|
||||
self.win.clear()
|
||||
end
|
||||
|
||||
function UI.Embedded:layout()
|
||||
UI.Window.layout(self)
|
||||
if self.win then
|
||||
self.win.reposition(self.x, self.y, self.width, self.height)
|
||||
end
|
||||
function UI.Embedded:draw()
|
||||
self:dirty()
|
||||
end
|
||||
|
||||
function UI.Embedded:draw()
|
||||
self.canvas:dirty()
|
||||
function UI.Embedded:focus()
|
||||
-- allow scrolling
|
||||
end
|
||||
|
||||
function UI.Embedded:enable()
|
||||
self.canvas:setVisible(true)
|
||||
self.canvas:raise()
|
||||
if self.visible then
|
||||
-- the window will automatically update on changes
|
||||
-- the canvas does not need to be rendereed
|
||||
self.win.setVisible(true)
|
||||
end
|
||||
UI.Window.enable(self)
|
||||
self.canvas:dirty()
|
||||
self.win.setVisible(true)
|
||||
self:dirty()
|
||||
end
|
||||
|
||||
function UI.Embedded:disable()
|
||||
self.canvas:setVisible(false)
|
||||
self.win.setVisible(false)
|
||||
UI.Window.disable(self)
|
||||
end
|
||||
@@ -71,17 +59,12 @@ function UI.Embedded:eventHandler(event)
|
||||
end
|
||||
end
|
||||
|
||||
function UI.Embedded:focus()
|
||||
-- allow scrolling
|
||||
end
|
||||
|
||||
function UI.Embedded.example()
|
||||
local Event = require('opus.event')
|
||||
local Util = require('opus.util')
|
||||
local term = _G.term
|
||||
|
||||
return UI.Embedded {
|
||||
visible = true,
|
||||
enable = function (self)
|
||||
UI.Embedded.enable(self)
|
||||
Event.addRoutine(function()
|
||||
|
||||
@@ -60,7 +60,7 @@ UI.Grid.defaults = {
|
||||
textSelectedColor = colors.white,
|
||||
backgroundColor = colors.black,
|
||||
backgroundSelectedColor = colors.gray,
|
||||
headerBackgroundColor = colors.cyan,
|
||||
headerBackgroundColor = UI.colors.tertiary,
|
||||
headerTextColor = colors.white,
|
||||
headerSortColor = colors.yellow,
|
||||
unfocusedTextSelectedColor = colors.white,
|
||||
|
||||
@@ -1,19 +1,28 @@
|
||||
local class = require('opus.class')
|
||||
local UI = require('opus.ui')
|
||||
local Util = require('opus.util')
|
||||
|
||||
local lookup = '0123456789abcdef'
|
||||
|
||||
-- handle files produced by Paint
|
||||
UI.Image = class(UI.Window)
|
||||
UI.Image.defaults = {
|
||||
UIElement = 'Image',
|
||||
event = 'button_press',
|
||||
}
|
||||
function UI.Image:setParent()
|
||||
if self.image then
|
||||
function UI.Image:postInit()
|
||||
if self.filename then
|
||||
self.image = Util.readLines(self.filename)
|
||||
end
|
||||
|
||||
if self.image and not (self.height or self.ey) then
|
||||
self.height = #self.image
|
||||
end
|
||||
if self.image and not self.width then
|
||||
self.width = #self.image[1]
|
||||
if self.image and not (self.width or self.ex) then
|
||||
for i = 1, self.height do
|
||||
self.width = math.max(self.width or 0, #self.image[i])
|
||||
end
|
||||
end
|
||||
UI.Window.setParent(self)
|
||||
end
|
||||
|
||||
function UI.Image:draw()
|
||||
@@ -22,19 +31,22 @@ function UI.Image:draw()
|
||||
for y = 1, #self.image do
|
||||
local line = self.image[y]
|
||||
for x = 1, #line do
|
||||
local ch = line[x]
|
||||
if type(ch) == 'number' then
|
||||
if ch > 0 then
|
||||
self:write(x, y, ' ', ch)
|
||||
end
|
||||
else
|
||||
self:write(x, y, ch)
|
||||
local ch = lookup:find(line:sub(x, x))
|
||||
if ch then
|
||||
self:write(x, y, ' ', 2 ^ (ch -1))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
self:drawChildren()
|
||||
end
|
||||
|
||||
function UI.Image:setImage(image)
|
||||
self.image = image
|
||||
end
|
||||
|
||||
function UI.Image.example()
|
||||
return UI.Image {
|
||||
filename = 'test.paint',
|
||||
}
|
||||
end
|
||||
|
||||
@@ -3,16 +3,6 @@ local UI = require('opus.ui')
|
||||
|
||||
local colors = _G.colors
|
||||
|
||||
local function getPosition(element)
|
||||
local x, y = 1, 1
|
||||
repeat
|
||||
x = element.x + x - 1
|
||||
y = element.y + y - 1
|
||||
element = element.parent
|
||||
until not element
|
||||
return x, y
|
||||
end
|
||||
|
||||
UI.MenuBar = class(UI.Window)
|
||||
UI.MenuBar.defaults = {
|
||||
UIElement = 'MenuBar',
|
||||
@@ -22,7 +12,6 @@ UI.MenuBar.defaults = {
|
||||
textColor = colors.black,
|
||||
spacing = 2,
|
||||
lastx = 1,
|
||||
showBackButton = false,
|
||||
buttonClass = 'MenuItem',
|
||||
}
|
||||
function UI.MenuBar:postInit()
|
||||
@@ -62,10 +51,6 @@ function UI.MenuBar:addButtons(buttons)
|
||||
else
|
||||
table.insert(self.children, button)
|
||||
end
|
||||
|
||||
if button.dropdown then
|
||||
button.dropmenu = UI.DropMenu { buttons = button.dropdown }
|
||||
end
|
||||
end
|
||||
end
|
||||
if self.parent then
|
||||
@@ -78,23 +63,27 @@ function UI.MenuBar:getActive(menuItem)
|
||||
end
|
||||
|
||||
function UI.MenuBar:eventHandler(event)
|
||||
if event.type == 'button_press' and event.button.dropmenu then
|
||||
if event.button.dropmenu.enabled then
|
||||
event.button.dropmenu:hide()
|
||||
self:refocus()
|
||||
return true
|
||||
else
|
||||
local x, y = getPosition(event.button)
|
||||
if x + event.button.dropmenu.width > self.width then
|
||||
x = self.width - event.button.dropmenu.width + 1
|
||||
end
|
||||
for _,c in pairs(event.button.dropmenu.children) do
|
||||
if not c.spacer then
|
||||
c.inactive = not self:getActive(c)
|
||||
end
|
||||
end
|
||||
event.button.dropmenu:show(x, y + 1)
|
||||
if event.type == 'button_press' and event.button.dropdown then
|
||||
local function getPosition(element)
|
||||
local x, y = 1, 1
|
||||
repeat
|
||||
x = element.x + x - 1
|
||||
y = element.y + y - 1
|
||||
element = element.parent
|
||||
until not element
|
||||
return x, y
|
||||
end
|
||||
|
||||
local x, y = getPosition(event.button)
|
||||
|
||||
local menu = UI.DropMenu {
|
||||
buttons = event.button.dropdown,
|
||||
x = x,
|
||||
y = y + 1,
|
||||
lastFocus = event.button.uid,
|
||||
}
|
||||
self.parent:add({ dropmenu = menu })
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,8 +6,6 @@ local colors = _G.colors
|
||||
UI.MenuItem = class(UI.Button)
|
||||
UI.MenuItem.defaults = {
|
||||
UIElement = 'MenuItem',
|
||||
textColor = colors.black,
|
||||
backgroundColor = colors.lightGray,
|
||||
textFocusColor = colors.white,
|
||||
backgroundFocusColor = colors.lightGray,
|
||||
}
|
||||
|
||||
@@ -5,17 +5,18 @@ UI.NftImage = class(UI.Window)
|
||||
UI.NftImage.defaults = {
|
||||
UIElement = 'NftImage',
|
||||
}
|
||||
function UI.NftImage:setParent()
|
||||
if self.image then
|
||||
function UI.NftImage:postInit()
|
||||
if self.image and not (self.ey or self.height) then
|
||||
self.height = self.image.height
|
||||
end
|
||||
if self.image and not self.width then
|
||||
if self.image and not (self.ex or self.width) then
|
||||
self.width = self.image.width
|
||||
end
|
||||
UI.Window.setParent(self)
|
||||
end
|
||||
|
||||
function UI.NftImage:draw()
|
||||
self:clear()
|
||||
|
||||
if self.image then
|
||||
-- due to blittle, the background and foreground transparent
|
||||
-- color is the same as the background color
|
||||
@@ -25,8 +26,6 @@ function UI.NftImage:draw()
|
||||
self:write(x, y, self.image.text[y][x], self.image.bg[y][x], self.image.fg[y][x] or bg)
|
||||
end
|
||||
end
|
||||
else
|
||||
self:clear()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -43,32 +43,34 @@ function UI.Notification:cancel()
|
||||
self.timer = nil
|
||||
end
|
||||
|
||||
if self.canvas then
|
||||
self.enabled = false
|
||||
self.canvas:removeLayer()
|
||||
self.canvas = nil
|
||||
end
|
||||
self:disable()
|
||||
end
|
||||
|
||||
function UI.Notification:display(value, timeout)
|
||||
self:cancel()
|
||||
self.enabled = true
|
||||
local lines = Util.wordWrap(value, self.width - 3)
|
||||
|
||||
self.enabled = true
|
||||
self.height = #lines
|
||||
|
||||
if self.anchor == 'bottom' then
|
||||
self.y = self.parent.height - self.height + 1
|
||||
self.canvas = self:addLayer(self.backgroundColor, self.textColor)
|
||||
self:addTransition('expandUp', { ticks = self.height })
|
||||
else
|
||||
self.canvas = self:addLayer(self.backgroundColor, self.textColor)
|
||||
self.y = 1
|
||||
end
|
||||
self.canvas:setVisible(true)
|
||||
|
||||
self:reposition(self.x, self.y, self.width, self.height)
|
||||
self:raise()
|
||||
self:clear()
|
||||
for k,v in pairs(lines) do
|
||||
self:write(2, k, v)
|
||||
end
|
||||
self:write(self.width, 1, self.closeInd)
|
||||
|
||||
if self.timer then
|
||||
Event.off(self.timer)
|
||||
self.timer = nil
|
||||
end
|
||||
|
||||
timeout = timeout or self.timeout
|
||||
if timeout > 0 then
|
||||
@@ -77,7 +79,6 @@ function UI.Notification:display(value, timeout)
|
||||
self:sync()
|
||||
end)
|
||||
else
|
||||
self:write(self.width, 1, self.closeInd)
|
||||
self:sync()
|
||||
end
|
||||
end
|
||||
@@ -92,7 +93,7 @@ function UI.Notification:eventHandler(event)
|
||||
end
|
||||
|
||||
function UI.Notification.example()
|
||||
return UI.ActiveLayer {
|
||||
return UI.Window {
|
||||
notify1 = UI.Notification {
|
||||
anchor = 'top',
|
||||
},
|
||||
@@ -111,7 +112,9 @@ function UI.Notification.example()
|
||||
if event.type == 'test_success' then
|
||||
self.notify1:success('Example text')
|
||||
elseif event.type == 'test_error' then
|
||||
self.notify2:error('Example text', 0)
|
||||
self.notify2:error([[Example text test test
|
||||
test test test test test
|
||||
test test test]], 0)
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
@@ -1,21 +1,9 @@
|
||||
local Canvas = require('opus.ui.canvas')
|
||||
local class = require('opus.class')
|
||||
local UI = require('opus.ui')
|
||||
local Util = require('opus.util')
|
||||
|
||||
local colors = _G.colors
|
||||
|
||||
-- need to add offsets to this test
|
||||
local function getPosition(element)
|
||||
local x, y = 1, 1
|
||||
repeat
|
||||
x = element.x + x - 1
|
||||
y = element.y + y - 1
|
||||
element = element.parent
|
||||
until not element
|
||||
return x, y
|
||||
end
|
||||
|
||||
UI.Page = class(UI.Window)
|
||||
UI.Page.defaults = {
|
||||
UIElement = 'Page',
|
||||
@@ -26,21 +14,15 @@ UI.Page.defaults = {
|
||||
['shift-tab' ] = 'focus_prev',
|
||||
up = 'focus_prev',
|
||||
},
|
||||
backgroundColor = colors.cyan,
|
||||
backgroundColor = UI.colors.primary,
|
||||
textColor = colors.white,
|
||||
}
|
||||
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:enable()
|
||||
self.canvas.visible = true
|
||||
UI.Window.enable(self)
|
||||
|
||||
if not self.focused or not self.focused.enabled then
|
||||
@@ -49,12 +31,12 @@ function UI.Page:enable()
|
||||
end
|
||||
|
||||
function UI.Page:disable()
|
||||
self.canvas.visible = false
|
||||
UI.Window.disable(self)
|
||||
end
|
||||
|
||||
function UI.Page:sync()
|
||||
if self.enabled then
|
||||
self:checkFocus()
|
||||
self.parent:sync()
|
||||
end
|
||||
end
|
||||
@@ -73,22 +55,24 @@ function UI.Page:pointToChild(x, y)
|
||||
if self.__target == self then
|
||||
return UI.Window.pointToChild(self, x, y)
|
||||
end
|
||||
x = x + self.offx - self.x + 1
|
||||
y = y + self.offy - self.y + 1
|
||||
--[[
|
||||
-- this is supposed to fix when there are multiple sub canvases
|
||||
local absX, absY = getPosition(self.__target)
|
||||
if self.__target.canvas then
|
||||
x = x - (self.__target.canvas.x - self.__target.x)
|
||||
y = y - (self.__target.canvas.y - self.__target.y)
|
||||
_syslog({'raw', self.__target.canvas.y, self.__target.y})
|
||||
|
||||
-- need to add offsets to this test
|
||||
local function getPosition(element)
|
||||
local x, y = 1, 1
|
||||
repeat
|
||||
x = element.x + x - 1
|
||||
y = element.y + y - 1
|
||||
element = element.parent
|
||||
until not element
|
||||
return x, y
|
||||
end
|
||||
]]
|
||||
return self.__target:pointToChild(x, y)
|
||||
|
||||
local absX, absY = getPosition(self.__target)
|
||||
return self.__target:pointToChild(x - absX + self.__target.x, y - absY + self.__target.y)
|
||||
end
|
||||
|
||||
function UI.Page:getFocusables()
|
||||
if self.__target == self or self.__target.pageType ~= 'modal' then
|
||||
if self.__target == self or not self.__target.modal then
|
||||
return UI.Window.getFocusables(self)
|
||||
end
|
||||
return self.__target:getFocusables()
|
||||
@@ -149,12 +133,25 @@ function UI.Page:setFocus(child)
|
||||
if not child.focused then
|
||||
child.focused = true
|
||||
child:emit({ type = 'focus_change', focused = child })
|
||||
--self:emit({ type = 'focus_change', focused = child })
|
||||
end
|
||||
|
||||
child:focus()
|
||||
end
|
||||
|
||||
function UI.Page:checkFocus()
|
||||
if not self.focused or not self.focused.enabled then
|
||||
local el = self.__target
|
||||
while el do
|
||||
local focusables = el:getFocusables()
|
||||
if focusables[1] then
|
||||
self:setFocus(focusables[1])
|
||||
break
|
||||
end
|
||||
el = el.parent
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function UI.Page:eventHandler(event)
|
||||
if self.focused then
|
||||
if event.type == 'focus_next' then
|
||||
|
||||
@@ -28,12 +28,11 @@ function UI.ProgressBar:draw()
|
||||
end
|
||||
|
||||
function UI.ProgressBar.example()
|
||||
local Event = require('opus.event')
|
||||
return UI.ProgressBar {
|
||||
x = 2, ex = -2, y = 2,
|
||||
focus = function() end,
|
||||
enable = function(self)
|
||||
Event.onInterval(.25, function()
|
||||
require('opus.event').onInterval(.25, function()
|
||||
self.value = self.value == 100 and 0 or self.value + 5
|
||||
self:draw()
|
||||
self:sync()
|
||||
|
||||
@@ -17,7 +17,10 @@ UI.ScrollBar.defaults = {
|
||||
ey = -1,
|
||||
}
|
||||
function UI.ScrollBar:draw()
|
||||
local view = self.parent:getViewArea()
|
||||
local parent = self.target or self.parent --self:find(self.target)
|
||||
local view = parent:getViewArea()
|
||||
|
||||
self:clear()
|
||||
|
||||
if view.totalHeight > view.height then
|
||||
local maxScroll = view.totalHeight - view.height
|
||||
@@ -27,7 +30,7 @@ function UI.ScrollBar:draw()
|
||||
|
||||
local row = view.y
|
||||
if not view.static then -- does the container scroll ?
|
||||
self.height = view.totalHeight
|
||||
self:reposition(self.x, self.y, self.width, view.totalHeight)
|
||||
end
|
||||
|
||||
for i = 1, view.height - 2 do
|
||||
@@ -56,16 +59,17 @@ end
|
||||
function UI.ScrollBar:eventHandler(event)
|
||||
if event.type == 'mouse_click' or event.type == 'mouse_doubleclick' then
|
||||
if event.x == 1 then
|
||||
local view = self.parent:getViewArea()
|
||||
local parent = self.target or self.parent --self:find(self.target)
|
||||
local view = parent:getViewArea()
|
||||
if view.totalHeight > view.height then
|
||||
if event.y == view.y then
|
||||
self:emit({ type = 'scroll_up'})
|
||||
parent:emit({ type = 'scroll_up'})
|
||||
elseif event.y == view.y + view.height - 1 then
|
||||
self:emit({ type = 'scroll_down'})
|
||||
parent:emit({ type = 'scroll_down'})
|
||||
else
|
||||
local percent = (event.y - view.y) / (view.height - 2)
|
||||
local y = math.floor((view.totalHeight - view.height) * percent)
|
||||
self:emit({ type = 'scroll_to', offset = y })
|
||||
parent :emit({ type = 'scroll_to', offset = y })
|
||||
end
|
||||
end
|
||||
return true
|
||||
|
||||
@@ -57,3 +57,21 @@ function UI.ScrollingGrid:setIndex(index)
|
||||
end
|
||||
UI.Grid.setIndex(self, index)
|
||||
end
|
||||
|
||||
function UI.ScrollingGrid.example()
|
||||
local values = { }
|
||||
for i = 1, 20 do
|
||||
table.insert(values, { key = 'key' .. i, value = 'value' .. i })
|
||||
end
|
||||
return UI.ScrollingGrid {
|
||||
values = values,
|
||||
sortColumn = 'key',
|
||||
columns = {
|
||||
{ heading = 'key', key = 'key' },
|
||||
{ heading = 'value', key = 'value' },
|
||||
},
|
||||
accelerators = {
|
||||
grid_select = 'custom_select',
|
||||
}
|
||||
}
|
||||
end
|
||||
@@ -4,17 +4,9 @@ local UI = require('opus.ui')
|
||||
UI.SlideOut = class(UI.Window)
|
||||
UI.SlideOut.defaults = {
|
||||
UIElement = 'SlideOut',
|
||||
pageType = 'modal',
|
||||
transitionHint = 'expandUp',
|
||||
modal = true,
|
||||
}
|
||||
function UI.SlideOut:layout()
|
||||
UI.Window.layout(self)
|
||||
if not self.canvas then
|
||||
self.canvas = self:addLayer()
|
||||
else
|
||||
self.canvas:resize(self.width, self.height)
|
||||
end
|
||||
end
|
||||
|
||||
function UI.SlideOut:enable()
|
||||
end
|
||||
|
||||
@@ -27,24 +19,20 @@ function UI.SlideOut:toggle()
|
||||
end
|
||||
|
||||
function UI.SlideOut:show(...)
|
||||
self:addTransition('expandUp')
|
||||
self.canvas:raise()
|
||||
self.canvas:setVisible(true)
|
||||
UI.Window.enable(self, ...)
|
||||
self:draw()
|
||||
self:capture(self)
|
||||
self:focusFirst()
|
||||
end
|
||||
|
||||
function UI.SlideOut:disable()
|
||||
self.canvas:setVisible(false)
|
||||
UI.Window.disable(self)
|
||||
end
|
||||
|
||||
function UI.SlideOut:hide()
|
||||
self:disable()
|
||||
self:release(self)
|
||||
self:refocus()
|
||||
end
|
||||
|
||||
function UI.SlideOut:draw()
|
||||
if not self.noFill then
|
||||
self:fillArea(1, 1, self.width, self.height, string.rep('\127', self.width), colors.black, colors.gray)
|
||||
end
|
||||
self:drawChildren()
|
||||
end
|
||||
|
||||
function UI.SlideOut:eventHandler(event)
|
||||
@@ -59,24 +47,27 @@ function UI.SlideOut:eventHandler(event)
|
||||
end
|
||||
|
||||
function UI.SlideOut.example()
|
||||
-- for the transistion to work properly, the parent must have a canvas
|
||||
return UI.ActiveLayer {
|
||||
y = 2,
|
||||
return UI.Window {
|
||||
y = 3,
|
||||
backgroundColor = 2048,
|
||||
button = UI.Button {
|
||||
x = 2, y = 5,
|
||||
text = 'show',
|
||||
},
|
||||
slideOut = UI.SlideOut {
|
||||
backgroundColor = _G.colors.yellow,
|
||||
y = -4, height = 4, x = 3, ex = -3,
|
||||
backgroundColor = 16,
|
||||
y = -7, height = 4, x = 3, ex = -3,
|
||||
titleBar = UI.TitleBar {
|
||||
title = 'test',
|
||||
},
|
||||
button = UI.Button {
|
||||
x = 2, y = 2,
|
||||
text = 'hide',
|
||||
--visualize = true,
|
||||
},
|
||||
},
|
||||
eventHandler = function (self, event)
|
||||
if event.type == 'button_press' then
|
||||
self.slideOut.canvas.xxx = true
|
||||
self.slideOut:toggle()
|
||||
end
|
||||
end,
|
||||
|
||||
@@ -57,8 +57,16 @@ end
|
||||
|
||||
function UI.Slider:eventHandler(event)
|
||||
if event.type == "mouse_down" or event.type == "mouse_drag" then
|
||||
|
||||
local pos = event.x - 1
|
||||
if event.type == 'mouse_down' then
|
||||
self.anchor = event.x - 1
|
||||
else
|
||||
pos = self.anchor + event.dx
|
||||
end
|
||||
|
||||
local range = self.max - self.min
|
||||
local i = (event.x - 1) / (self.width - 1)
|
||||
local i = pos / (self.width - 1)
|
||||
self.value = self.min + (i * range)
|
||||
self:emit({ type = self.event, value = self.value, element = self })
|
||||
self:draw()
|
||||
|
||||
@@ -63,7 +63,7 @@ end
|
||||
|
||||
function UI.StatusBar:timedStatus(status, timeout)
|
||||
self:write(2, 1, Util.widthify(status, self.width-2), self.backgroundColor)
|
||||
Event.on(timeout or 3, function()
|
||||
Event.onTimeout(timeout or 3, function()
|
||||
if self.enabled then
|
||||
self:draw()
|
||||
self:sync()
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
local class = require('opus.class')
|
||||
local UI = require('opus.ui')
|
||||
|
||||
UI.Tab = class(UI.ActiveLayer)
|
||||
UI.Tab = class(UI.Window)
|
||||
UI.Tab.defaults = {
|
||||
UIElement = 'Tab',
|
||||
tabTitle = 'tab',
|
||||
y = 2,
|
||||
}
|
||||
|
||||
function UI.Tab:draw()
|
||||
if not self.noFill then
|
||||
self:fillArea(1, 1, self.width, self.height, string.rep('\127', self.width), colors.black, colors.gray)
|
||||
end
|
||||
self:drawChildren()
|
||||
end
|
||||
|
||||
@@ -2,13 +2,14 @@ local class = require('opus.class')
|
||||
local UI = require('opus.ui')
|
||||
local Util = require('opus.util')
|
||||
|
||||
local colors = _G.colors
|
||||
|
||||
UI.TabBar = class(UI.MenuBar)
|
||||
UI.TabBar.defaults = {
|
||||
UIElement = 'TabBar',
|
||||
buttonClass = 'TabBarMenuItem',
|
||||
}
|
||||
UI.TabBar.inherits = {
|
||||
selectedBackgroundColor = 'backgroundColor',
|
||||
selectedBackgroundColor = UI.colors.secondary,
|
||||
unselectedBackgroundColor = colors.lightGray,
|
||||
}
|
||||
function UI.TabBar:enable()
|
||||
UI.MenuBar.enable(self)
|
||||
|
||||
@@ -1,27 +1,18 @@
|
||||
local class = require('opus.class')
|
||||
local UI = require('opus.ui')
|
||||
|
||||
local colors = _G.colors
|
||||
|
||||
UI.TabBarMenuItem = class(UI.Button)
|
||||
UI.TabBarMenuItem.defaults = {
|
||||
UIElement = 'TabBarMenuItem',
|
||||
event = 'tab_select',
|
||||
textColor = colors.black,
|
||||
selectedBackgroundColor = colors.cyan,
|
||||
unselectedBackgroundColor = colors.lightGray,
|
||||
backgroundColor = colors.lightGray,
|
||||
}
|
||||
UI.TabBarMenuItem.inherits = {
|
||||
selectedBackgroundColor = 'selectedBackgroundColor',
|
||||
}
|
||||
function UI.TabBarMenuItem:draw()
|
||||
if self.selected then
|
||||
self.backgroundColor = self.selectedBackgroundColor
|
||||
self.backgroundFocusColor = self.selectedBackgroundColor
|
||||
self.backgroundColor = self:getProperty('selectedBackgroundColor')
|
||||
self.backgroundFocusColor = self.backgroundColor
|
||||
else
|
||||
self.backgroundColor = self.unselectedBackgroundColor
|
||||
self.backgroundFocusColor = self.unselectedBackgroundColor
|
||||
self.backgroundColor = self:getProperty('unselectedBackgroundColor')
|
||||
self.backgroundFocusColor = self.backgroundColor
|
||||
end
|
||||
UI.Button.draw(self)
|
||||
end
|
||||
|
||||
@@ -56,12 +56,12 @@ end
|
||||
|
||||
function UI.Tabs:enable()
|
||||
self.enabled = true
|
||||
self.transitionHint = nil
|
||||
self.tabBar:enable()
|
||||
|
||||
local menuItem = Util.find(self.tabBar.children, 'selected', true)
|
||||
|
||||
for _,child in pairs(self.children or { }) do
|
||||
for child in self:eachChild() do
|
||||
child.transitionHint = nil
|
||||
if child.uid == menuItem.tabUid then
|
||||
child:enable()
|
||||
self:emit({ type = 'tab_activate', activated = child })
|
||||
@@ -74,14 +74,11 @@ end
|
||||
function UI.Tabs:eventHandler(event)
|
||||
if event.type == 'tab_change' then
|
||||
local tab = self:find(event.tab.tabUid)
|
||||
if event.current > event.last then
|
||||
self.transitionHint = 'slideLeft'
|
||||
else
|
||||
self.transitionHint = 'slideRight'
|
||||
end
|
||||
local hint = event.current > event.last and 'slideLeft' or 'slideRight'
|
||||
|
||||
for _,child in pairs(self.children) do
|
||||
for child in self:eachChild() do
|
||||
if child.uid == event.tab.tabUid then
|
||||
child.transitionHint = hint
|
||||
child:enable()
|
||||
elseif child.tabTitle then
|
||||
child:disable()
|
||||
@@ -89,6 +86,7 @@ function UI.Tabs:eventHandler(event)
|
||||
end
|
||||
self:emit({ type = 'tab_activate', activated = tab })
|
||||
tab:draw()
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
@@ -102,7 +100,18 @@ function UI.Tabs.example()
|
||||
tab2 = UI.Tab {
|
||||
index = 2,
|
||||
tabTitle = 'tab2',
|
||||
button = UI.Button { y = 3 },
|
||||
subtabs = UI.Tabs {
|
||||
x = 3, y = 2, ex = -3, ey = -2,
|
||||
tab1 = UI.Tab {
|
||||
index = 1,
|
||||
tabTitle = 'tab4',
|
||||
entry = UI.TextEntry { y = 3, shadowText = 'text' },
|
||||
},
|
||||
tab3 = UI.Tab {
|
||||
index = 2,
|
||||
tabTitle = 'tab5',
|
||||
},
|
||||
},
|
||||
},
|
||||
tab3 = UI.Tab {
|
||||
index = 3,
|
||||
|
||||
@@ -6,11 +6,8 @@ UI.TextArea.defaults = {
|
||||
UIElement = 'TextArea',
|
||||
marginRight = 2,
|
||||
value = '',
|
||||
showScrollBar = true,
|
||||
}
|
||||
function UI.TextArea:postInit()
|
||||
self.scrollBar = UI.ScrollBar()
|
||||
end
|
||||
|
||||
function UI.TextArea:setText(text)
|
||||
self:reset()
|
||||
self.value = text
|
||||
@@ -23,19 +20,28 @@ end
|
||||
|
||||
function UI.TextArea:draw()
|
||||
self:clear()
|
||||
-- self:setCursorPos(1, 1)
|
||||
self.cursorX, self.cursorY = 1, 1
|
||||
self:print(self.value)
|
||||
|
||||
for _,child in pairs(self.children) do
|
||||
if child.enabled then
|
||||
child:draw()
|
||||
end
|
||||
end
|
||||
self:drawChildren()
|
||||
end
|
||||
|
||||
function UI.TextArea.example()
|
||||
return UI.TextArea {
|
||||
value = 'sample text\nabc'
|
||||
return UI.Window {
|
||||
backgroundColor = 2048,
|
||||
t1 = UI.TextArea {
|
||||
ey = 3,
|
||||
value = 'sample text\nabc'
|
||||
},
|
||||
t2 = UI.TextArea {
|
||||
y = 5,
|
||||
value = [[1
|
||||
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8]]
|
||||
}
|
||||
}
|
||||
end
|
||||
@@ -19,7 +19,6 @@ UI.TextEntry = class(UI.Window)
|
||||
UI.TextEntry.docs = { }
|
||||
UI.TextEntry.defaults = {
|
||||
UIElement = 'TextEntry',
|
||||
--value = '',
|
||||
shadowText = '',
|
||||
focused = false,
|
||||
textColor = colors.white,
|
||||
|
||||
@@ -20,24 +20,15 @@ UI.Throttle.defaults = {
|
||||
' //) (O ). @ \\-d ) (@ '
|
||||
}
|
||||
}
|
||||
function UI.Throttle:setParent()
|
||||
function UI.Throttle:layout()
|
||||
self.x = math.ceil((self.parent.width - self.width) / 2)
|
||||
self.y = math.ceil((self.parent.height - self.height) / 2)
|
||||
UI.Window.setParent(self)
|
||||
self:reposition(self.x, self.y, self.width, self.height)
|
||||
end
|
||||
|
||||
function UI.Throttle:enable()
|
||||
self.c = os.clock()
|
||||
self.enabled = false
|
||||
end
|
||||
|
||||
function UI.Throttle:disable()
|
||||
if self.canvas then
|
||||
self.enabled = false
|
||||
self.canvas:removeLayer()
|
||||
self.canvas = nil
|
||||
self.ctr = 0
|
||||
end
|
||||
self.ctr = 0
|
||||
end
|
||||
|
||||
function UI.Throttle:update()
|
||||
@@ -46,11 +37,7 @@ function UI.Throttle:update()
|
||||
os.sleep(0)
|
||||
self.c = os.clock()
|
||||
self.enabled = true
|
||||
if not self.canvas then
|
||||
self.canvas = self:addLayer(self.backgroundColor, self.borderColor)
|
||||
self.canvas:setVisible(true)
|
||||
self:clear(self.borderColor)
|
||||
end
|
||||
self:clear(self.borderColor)
|
||||
local image = self.image[self.ctr + 1]
|
||||
local width = self.width - 2
|
||||
for i = 0, #self.image do
|
||||
@@ -63,3 +50,25 @@ function UI.Throttle:update()
|
||||
self:sync()
|
||||
end
|
||||
end
|
||||
|
||||
function UI.Throttle.example()
|
||||
return UI.Window {
|
||||
button1 = UI.Button {
|
||||
x = 2, y = 2,
|
||||
text = 'Test',
|
||||
},
|
||||
throttle = UI.Throttle {
|
||||
textColor = colors.yellow,
|
||||
borderColor = colors.green,
|
||||
},
|
||||
eventHandler = function (self, event)
|
||||
if event.type == 'button_press' then
|
||||
for _ = 1, 40 do
|
||||
self.throttle:update()
|
||||
os.sleep(.05)
|
||||
end
|
||||
self.throttle:disable()
|
||||
end
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
@@ -38,8 +38,6 @@ UI.TitleBar = class(UI.Window)
|
||||
UI.TitleBar.defaults = {
|
||||
UIElement = 'TitleBar',
|
||||
height = 1,
|
||||
textColor = colors.white,
|
||||
backgroundColor = colors.cyan,
|
||||
title = '',
|
||||
frameChar = UI.extChars and '\140' or '-',
|
||||
closeInd = UI.extChars and '\215' or '*',
|
||||
@@ -69,5 +67,73 @@ function UI.TitleBar:eventHandler(event)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
elseif event.type == 'mouse_down' then
|
||||
self.anchor = { x = event.x, y = event.y, ox = self.parent.x, oy = self.parent.y, h = self.parent.height }
|
||||
|
||||
elseif event.type == 'mouse_drag' then
|
||||
if self.expand == 'height' then
|
||||
local d = event.dy
|
||||
if self.anchor.h - d > 0 and self.anchor.oy + d > 0 then
|
||||
self.parent:reposition(self.parent.x, self.anchor.oy + event.dy, self.width, self.anchor.h - d)
|
||||
end
|
||||
|
||||
else --if self.moveable then
|
||||
local d = event.dy
|
||||
if self.anchor.oy + d > 0 and self.anchor.oy + d <= self.parent.parent.height then
|
||||
self.parent:move(self.anchor.ox + event.dx, self.anchor.oy + event.dy)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function UI.TitleBar.example()
|
||||
return UI.Window {
|
||||
win1 = UI.Window {
|
||||
x = 9, y = 2, ex = -7, ey = -3,
|
||||
backgroundColor = colors.green,
|
||||
titleBar = UI.TitleBar {
|
||||
title = 'test', moveable = true,
|
||||
},
|
||||
button1 = UI.Button {
|
||||
x = 2, y = 3,
|
||||
text = 'Press',
|
||||
},
|
||||
focus = function (self)
|
||||
self:raise()
|
||||
end,
|
||||
},
|
||||
win2 = UI.Window {
|
||||
x = 7, y = 3, ex = -9, ey = -2,
|
||||
backgroundColor = colors.orange,
|
||||
titleBar = UI.TitleBar {
|
||||
title = 'test', moveable = true,
|
||||
},
|
||||
button1 = UI.Button {
|
||||
x = 2, y = 3,
|
||||
text = 'Press',
|
||||
},
|
||||
focus = function (self)
|
||||
self:raise()
|
||||
end,
|
||||
},
|
||||
draw = function(self, isBG)
|
||||
for i = 1, self.height do
|
||||
self:write(1, i, self.filler or '')
|
||||
end
|
||||
if not isBG then
|
||||
for _,v in pairs(self.children) do
|
||||
v:draw()
|
||||
end
|
||||
end
|
||||
end,
|
||||
enable = function (self)
|
||||
require('opus.event').onInterval(.5, function()
|
||||
self.filler = string.rep(string.char(math.random(33, 126)), self.width)
|
||||
self:draw(true)
|
||||
self:sync()
|
||||
end)
|
||||
UI.Window.enable(self)
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
@@ -18,12 +18,11 @@ function UI.VerticalMeter:draw()
|
||||
end
|
||||
|
||||
function UI.VerticalMeter.example()
|
||||
local Event = require('opus.event')
|
||||
return UI.VerticalMeter {
|
||||
x = 2, width = 3, y = 2, ey = -2,
|
||||
focus = function() end,
|
||||
enable = function(self)
|
||||
Event.onInterval(.25, function()
|
||||
require('opus.event').onInterval(.25, function()
|
||||
self.value = self.value == 100 and 0 or self.value + 5
|
||||
self:draw()
|
||||
self:sync()
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
local class = require('opus.class')
|
||||
local UI = require('opus.ui')
|
||||
|
||||
local colors = _G.colors
|
||||
|
||||
UI.Viewport = class(UI.Window)
|
||||
UI.Viewport.defaults = {
|
||||
UIElement = 'Viewport',
|
||||
backgroundColor = colors.cyan,
|
||||
accelerators = {
|
||||
down = 'scroll_down',
|
||||
up = 'scroll_up',
|
||||
home = 'scroll_top',
|
||||
left = 'scroll_left',
|
||||
right = 'scroll_right',
|
||||
[ 'end' ] = 'scroll_bottom',
|
||||
pageUp = 'scroll_pageUp',
|
||||
[ 'control-b' ] = 'scroll_pageUp',
|
||||
@@ -18,53 +17,53 @@ UI.Viewport.defaults = {
|
||||
[ 'control-f' ] = 'scroll_pageDown',
|
||||
},
|
||||
}
|
||||
function UI.Viewport:layout()
|
||||
UI.Window.layout(self)
|
||||
if not self.canvas then
|
||||
self.canvas = self:addLayer()
|
||||
else
|
||||
self.canvas:resize(self.width, self.height)
|
||||
function UI.Viewport:postInit()
|
||||
if self.showScrollBar then
|
||||
self.scrollBar = UI.ScrollBar()
|
||||
end
|
||||
end
|
||||
|
||||
function UI.Viewport:enable()
|
||||
UI.Window.enable(self)
|
||||
self.canvas:setVisible(true)
|
||||
end
|
||||
|
||||
function UI.Viewport:disable()
|
||||
UI.Window.disable(self)
|
||||
self.canvas:setVisible(false)
|
||||
end
|
||||
|
||||
function UI.Viewport:setScrollPosition(offset)
|
||||
local oldOffset = self.offy
|
||||
self.offy = math.max(offset, 0)
|
||||
self.offy = math.min(self.offy, math.max(#self.canvas.lines, self.height) - self.height)
|
||||
if self.offy ~= oldOffset then
|
||||
function UI.Viewport:setScrollPosition(offy, offx) -- argh - reverse
|
||||
local oldOffy = self.offy
|
||||
self.offy = math.max(offy, 0)
|
||||
self.offy = math.min(self.offy, math.max(#self.lines, self.height) - self.height)
|
||||
if self.offy ~= oldOffy then
|
||||
if self.scrollBar then
|
||||
self.scrollBar:draw()
|
||||
end
|
||||
self.canvas.offy = offset
|
||||
self.canvas:dirty()
|
||||
self.offy = offy
|
||||
self:dirty(true)
|
||||
end
|
||||
|
||||
local oldOffx = self.offx
|
||||
self.offx = math.max(offx or 0, 0)
|
||||
self.offx = math.min(self.offx, math.max(#self.lines[1], self.width) - self.width)
|
||||
if self.offx ~= oldOffx then
|
||||
if self.scrollBar then
|
||||
--self.scrollBar:draw()
|
||||
end
|
||||
self.offx = offx or 0
|
||||
self:dirty(true)
|
||||
end
|
||||
end
|
||||
|
||||
function UI.Viewport:write(x, y, text, bg, tc)
|
||||
if y > #self.canvas.lines then
|
||||
for i = #self.canvas.lines, y do
|
||||
self.canvas.lines[i + 1] = { }
|
||||
self.canvas:clearLine(i + 1, self.backgroundColor, self.textColor)
|
||||
end
|
||||
if y > #self.lines then
|
||||
self:resizeBuffer(self.width, y)
|
||||
end
|
||||
return UI.Window.write(self, x, y, text, bg, tc)
|
||||
end
|
||||
|
||||
function UI.Viewport:setViewHeight(h)
|
||||
if h > #self.lines then
|
||||
self:resizeBuffer(self.width, h)
|
||||
end
|
||||
end
|
||||
|
||||
function UI.Viewport:reset()
|
||||
self.offy = 0
|
||||
self.canvas.offy = 0
|
||||
for i = self.height + 1, #self.canvas.lines do
|
||||
self.canvas.lines[i] = nil
|
||||
for i = self.height + 1, #self.lines do
|
||||
self.lines[i] = nil
|
||||
end
|
||||
end
|
||||
|
||||
@@ -72,26 +71,30 @@ function UI.Viewport:getViewArea()
|
||||
return {
|
||||
y = (self.offy or 0) + 1,
|
||||
height = self.height,
|
||||
totalHeight = #self.canvas.lines,
|
||||
totalHeight = #self.lines,
|
||||
offsetY = self.offy or 0,
|
||||
}
|
||||
end
|
||||
|
||||
function UI.Viewport:eventHandler(event)
|
||||
if event.type == 'scroll_down' then
|
||||
self:setScrollPosition(self.offy + 1)
|
||||
self:setScrollPosition(self.offy + 1, self.offx)
|
||||
elseif event.type == 'scroll_up' then
|
||||
self:setScrollPosition(self.offy - 1)
|
||||
self:setScrollPosition(self.offy - 1, self.offx)
|
||||
elseif event.type == 'scroll_left' then
|
||||
self:setScrollPosition(self.offy, self.offx - 1)
|
||||
elseif event.type == 'scroll_right' then
|
||||
self:setScrollPosition(self.offy, self.offx + 1)
|
||||
elseif event.type == 'scroll_top' then
|
||||
self:setScrollPosition(0)
|
||||
self:setScrollPosition(0, 0)
|
||||
elseif event.type == 'scroll_bottom' then
|
||||
self:setScrollPosition(10000000)
|
||||
self:setScrollPosition(10000000, 0)
|
||||
elseif event.type == 'scroll_pageUp' then
|
||||
self:setScrollPosition(self.offy - self.height)
|
||||
self:setScrollPosition(self.offy - self.height, self.offx)
|
||||
elseif event.type == 'scroll_pageDown' then
|
||||
self:setScrollPosition(self.offy + self.height)
|
||||
self:setScrollPosition(self.offy + self.height, self.offx)
|
||||
elseif event.type == 'scroll_to' then
|
||||
self:setScrollPosition(event.offset)
|
||||
self:setScrollPosition(event.offset, 0)
|
||||
else
|
||||
return false
|
||||
end
|
||||
|
||||
@@ -25,9 +25,6 @@ function UI.Wizard:postInit()
|
||||
}
|
||||
|
||||
Util.merge(self, self.pages)
|
||||
--for _, child in pairs(self.pages) do
|
||||
-- child.ey = -2
|
||||
--end
|
||||
end
|
||||
|
||||
function UI.Wizard:add(pages)
|
||||
@@ -50,9 +47,8 @@ end
|
||||
function UI.Wizard:enable(...)
|
||||
self.enabled = true
|
||||
self.index = 1
|
||||
self.transitionHint = nil
|
||||
local initial = self:getPage(1)
|
||||
for _,child in pairs(self.children) do
|
||||
for child in self:eachChild() do
|
||||
if child == initial or not child.index then
|
||||
child:enable(...)
|
||||
else
|
||||
@@ -93,12 +89,13 @@ function UI.Wizard:eventHandler(event)
|
||||
elseif event.type == 'enable_view' then
|
||||
local current = event.next or event.prev
|
||||
if not current then error('property "index" is required on wizard pages') end
|
||||
local hint
|
||||
|
||||
if event.current then
|
||||
if event.next then
|
||||
self.transitionHint = 'slideLeft'
|
||||
hint = 'slideLeft'
|
||||
elseif event.prev then
|
||||
self.transitionHint = 'slideRight'
|
||||
hint = 'slideRight'
|
||||
end
|
||||
event.current:disable()
|
||||
end
|
||||
@@ -117,6 +114,7 @@ function UI.Wizard:eventHandler(event)
|
||||
self.nextButton.event = 'wizard_complete'
|
||||
end
|
||||
-- a new current view
|
||||
current.transitionHint = hint
|
||||
current:enable()
|
||||
current:emit({ type = 'view_enabled', view = current })
|
||||
self:draw()
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
local class = require('opus.class')
|
||||
local UI = require('opus.ui')
|
||||
|
||||
local colors = _G.colors
|
||||
|
||||
UI.WizardPage = class(UI.ActiveLayer)
|
||||
UI.WizardPage = class(UI.Window)
|
||||
UI.WizardPage.defaults = {
|
||||
UIElement = 'WizardPage',
|
||||
backgroundColor = colors.cyan,
|
||||
ey = -2,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user