partition manager + tab/wizard rework
This commit is contained in:
@@ -675,7 +675,7 @@ function UI.Window:drawChildren()
|
||||
end
|
||||
|
||||
UI.Window.docs.getDoc = [[getDoc(STRING method)
|
||||
Gets the documentation for a method.]]
|
||||
Get the documentation for a method.]]
|
||||
function UI.Window:getDoc(method)
|
||||
local m = getmetatable(self) -- get the class for this instance
|
||||
repeat
|
||||
@@ -743,6 +743,8 @@ function UI.Window:clear(bg, fg)
|
||||
Canvas.clear(self, bg or self:getProperty('backgroundColor'), fg or self:getProperty('textColor'))
|
||||
end
|
||||
|
||||
UI.Window.docs.clearLine = [[clearLine(NUMBER y, opt COLOR bg)
|
||||
Clears the specified line.]]
|
||||
function UI.Window:clearLine(y, bg)
|
||||
self:write(1, y, _rep(' ', self.width), bg)
|
||||
end
|
||||
@@ -760,6 +762,10 @@ function UI.Window:fillArea(x, y, width, height, fillChar, bg, fg)
|
||||
end
|
||||
end
|
||||
|
||||
UI.Window.docs.write = [[write(NUMBER x, NUMBER y, String text, opt COLOR bg, opt COLOR fg)
|
||||
Write text to the canvas.
|
||||
If colors are not specified, the colors from the base class will be used.
|
||||
If the base class does not have colors defined, colors will be inherited from the parent container.]]
|
||||
function UI.Window:write(x, y, text, bg, fg)
|
||||
Canvas.write(self, x, y, text, bg or self:getProperty('backgroundColor'), fg or self:getProperty('textColor'))
|
||||
end
|
||||
|
||||
@@ -1,86 +1,75 @@
|
||||
local class = require('opus.class')
|
||||
local UI = require('opus.ui')
|
||||
local Util = require('opus.util')
|
||||
local UI = require('opus.ui')
|
||||
local Util = require('opus.util')
|
||||
|
||||
local colors = _G.colors
|
||||
local fs = _G.fs
|
||||
local fs = _G.fs
|
||||
|
||||
UI.FileSelect = class(UI.Window)
|
||||
UI.FileSelect.defaults = {
|
||||
UIElement = 'FileSelect',
|
||||
}
|
||||
function UI.FileSelect:postInit()
|
||||
self.grid = UI.ScrollingGrid {
|
||||
x = 2, y = 2, ex = -2, ey = -4,
|
||||
dir = '/',
|
||||
sortColumn = 'name',
|
||||
columns = {
|
||||
{ heading = 'Name', key = 'name' },
|
||||
{ heading = 'Size', key = 'size', width = 5 }
|
||||
},
|
||||
getDisplayValues = function(_, row)
|
||||
if row.size then
|
||||
row = Util.shallowCopy(row)
|
||||
row.size = Util.toBytes(row.size)
|
||||
end
|
||||
return row
|
||||
end,
|
||||
getRowTextColor = function(_, file)
|
||||
if file.isDir then
|
||||
return colors.cyan
|
||||
end
|
||||
if file.isReadOnly then
|
||||
return colors.pink
|
||||
end
|
||||
return colors.white
|
||||
end,
|
||||
sortCompare = function(self, a, b)
|
||||
if self.sortColumn == 'size' then
|
||||
return a.size < b.size
|
||||
end
|
||||
if a.isDir == b.isDir then
|
||||
return a.name:lower() < b.name:lower()
|
||||
end
|
||||
return a.isDir
|
||||
end,
|
||||
draw = function(self)
|
||||
local files = fs.listEx(self.dir)
|
||||
if #self.dir > 0 then
|
||||
table.insert(files, {
|
||||
name = '..',
|
||||
isDir = true,
|
||||
})
|
||||
end
|
||||
self:setValues(files)
|
||||
self:setIndex(1)
|
||||
UI.Grid.draw(self)
|
||||
end,
|
||||
}
|
||||
self.path = UI.TextEntry {
|
||||
x = 2,
|
||||
y = -2,
|
||||
ex = -11,
|
||||
limit = 256,
|
||||
accelerators = {
|
||||
enter = 'path_enter',
|
||||
}
|
||||
}
|
||||
self.cancel = UI.Button {
|
||||
text = 'Cancel',
|
||||
x = -9,
|
||||
y = -2,
|
||||
event = 'select_cancel',
|
||||
}
|
||||
self.grid = UI.ScrollingGrid {
|
||||
x = 2, y = 2, ex = -2, ey = -4,
|
||||
dir = '/',
|
||||
sortColumn = 'name',
|
||||
columns = {
|
||||
{ heading = 'Name', key = 'name' },
|
||||
{ heading = 'Size', key = 'size', width = 5 }
|
||||
},
|
||||
getDisplayValues = function(_, row)
|
||||
return {
|
||||
name = row.name,
|
||||
size = row.size and Util.toBytes(row.size),
|
||||
}
|
||||
end,
|
||||
getRowTextColor = function(_, file)
|
||||
return file.isDir and 'cyan' or file.isReadOnly and 'pink' or 'white'
|
||||
end,
|
||||
sortCompare = function(self, a, b)
|
||||
if self.sortColumn == 'size' then
|
||||
return a.size < b.size
|
||||
end
|
||||
if a.isDir == b.isDir then
|
||||
return a.name:lower() < b.name:lower()
|
||||
end
|
||||
return a.isDir
|
||||
end,
|
||||
draw = function(self)
|
||||
local files = fs.listEx(self.dir)
|
||||
if #self.dir > 0 then
|
||||
table.insert(files, {
|
||||
name = '..',
|
||||
isDir = true,
|
||||
})
|
||||
end
|
||||
self:setValues(files)
|
||||
self:setIndex(1)
|
||||
UI.Grid.draw(self)
|
||||
end,
|
||||
}
|
||||
self.path = UI.TextEntry {
|
||||
x = 2, y = -2, ex = -11,
|
||||
limit = 256,
|
||||
accelerators = {
|
||||
enter = 'path_enter',
|
||||
}
|
||||
}
|
||||
self.cancel = UI.Button {
|
||||
x = -9, y = -2,
|
||||
text = 'Cancel',
|
||||
event = 'select_cancel',
|
||||
}
|
||||
end
|
||||
|
||||
function UI.FileSelect:draw()
|
||||
self:fillArea(1, 1, self.width, self.height, string.rep('\127', self.width), colors.black, colors.gray)
|
||||
self:drawChildren()
|
||||
self:fillArea(1, 1, self.width, self.height, string.rep('\127', self.width), 'black', 'gray')
|
||||
self:drawChildren()
|
||||
end
|
||||
|
||||
function UI.FileSelect:enable(path)
|
||||
self:setPath(path or '')
|
||||
UI.Window.enable(self)
|
||||
self:setPath(path or '')
|
||||
UI.Window.enable(self)
|
||||
end
|
||||
|
||||
function UI.FileSelect:setPath(path)
|
||||
@@ -98,21 +87,21 @@ function UI.FileSelect:eventHandler(event)
|
||||
if event.selected.isDir then
|
||||
self.grid:draw()
|
||||
self.path:draw()
|
||||
else
|
||||
self:emit({ type = 'select_file', file = '/' .. self.path.value, element = self })
|
||||
end
|
||||
return true
|
||||
else
|
||||
self:emit({ type = 'select_file', file = '/' .. self.path.value, element = self })
|
||||
end
|
||||
return true
|
||||
|
||||
elseif event.type == 'path_enter' then
|
||||
if self.path.value then
|
||||
if fs.isDir(self.path.value) then
|
||||
self:setPath(self.path.value)
|
||||
self.grid:draw()
|
||||
self.path:draw()
|
||||
else
|
||||
self:emit({ type = 'select_file', file = '/' .. self.path.value, element = self })
|
||||
end
|
||||
end
|
||||
return true
|
||||
elseif event.type == 'path_enter' then
|
||||
if self.path.value then
|
||||
if fs.isDir(self.path.value) then
|
||||
self:setPath(self.path.value)
|
||||
self.grid:draw()
|
||||
self.path:draw()
|
||||
else
|
||||
self:emit({ type = 'select_file', file = '/' .. self.path.value, element = self })
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
@@ -33,7 +33,7 @@ function UI.Image:draw()
|
||||
for x = 1, #line do
|
||||
local ch = lookup:find(line:sub(x, x))
|
||||
if ch then
|
||||
self:write(x, y, ' ', 2 ^ (ch -1))
|
||||
self:write(x, y, ' ', 2 ^ (ch - 1))
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -47,6 +47,7 @@ end
|
||||
|
||||
function UI.Image.example()
|
||||
return UI.Image {
|
||||
backgroundColor = 'primary',
|
||||
filename = 'test.paint',
|
||||
}
|
||||
end
|
||||
|
||||
@@ -7,7 +7,7 @@ local colors = _G.colors
|
||||
UI.ScrollBar = class(UI.Window)
|
||||
UI.ScrollBar.defaults = {
|
||||
UIElement = 'ScrollBar',
|
||||
lineChar = '|',
|
||||
lineChar = '\166',
|
||||
sliderChar = UI.extChars and '\127' or '#',
|
||||
upArrowChar = UI.extChars and '\30' or '^',
|
||||
downArrowChar = UI.extChars and '\31' or 'v',
|
||||
|
||||
@@ -4,7 +4,7 @@ local UI = require('opus.ui')
|
||||
UI.Tab = class(UI.Window)
|
||||
UI.Tab.defaults = {
|
||||
UIElement = 'Tab',
|
||||
tabTitle = 'tab',
|
||||
title = 'tab',
|
||||
y = 2,
|
||||
}
|
||||
|
||||
@@ -14,3 +14,8 @@ function UI.Tab:draw()
|
||||
end
|
||||
self:drawChildren()
|
||||
end
|
||||
|
||||
function UI.Tab:enable()
|
||||
UI.Window.enable(self)
|
||||
self:emit({ type = 'tab_activate', activated = self })
|
||||
end
|
||||
|
||||
@@ -37,9 +37,3 @@ function UI.TabBar:eventHandler(event)
|
||||
return UI.MenuBar.eventHandler(self, event)
|
||||
end
|
||||
|
||||
function UI.TabBar:selectTab(text)
|
||||
local menuItem = Util.find(self.children, 'text', text)
|
||||
if menuItem then
|
||||
menuItem.selected = true
|
||||
end
|
||||
end
|
||||
|
||||
@@ -14,11 +14,11 @@ end
|
||||
function UI.Tabs:add(children)
|
||||
local buttons = { }
|
||||
for _,child in pairs(children) do
|
||||
if type(child) == 'table' and child.UIElement and child.tabTitle then
|
||||
if type(child) == 'table' and child.UIElement and child.UIElement == 'Tab' then
|
||||
child.y = 2
|
||||
table.insert(buttons, {
|
||||
index = child.index,
|
||||
text = child.tabTitle,
|
||||
text = child.title,
|
||||
event = 'tab_select',
|
||||
tabUid = child.uid,
|
||||
})
|
||||
@@ -34,7 +34,12 @@ function UI.Tabs:add(children)
|
||||
end
|
||||
|
||||
if self.parent then
|
||||
local enabled = self.enabled
|
||||
|
||||
-- don't enable children upon add
|
||||
self.enabled = nil
|
||||
UI.Window.add(self, children)
|
||||
self.enabled = enabled
|
||||
end
|
||||
end
|
||||
|
||||
@@ -43,7 +48,15 @@ Make to the passed tab active.]]
|
||||
function UI.Tabs:selectTab(tab)
|
||||
local menuItem = Util.find(self.tabBar.children, 'tabUid', tab.uid)
|
||||
if menuItem then
|
||||
self.tabBar:emit({ type = 'tab_select', button = { uid = menuItem.uid } })
|
||||
if self.enabled then
|
||||
self.tabBar:emit({ type = 'tab_select', button = { uid = menuItem.uid } })
|
||||
else
|
||||
local previous = Util.find(self.tabBar.children, 'selected', true)
|
||||
if previous then
|
||||
previous.selected = false
|
||||
end
|
||||
menuItem.selected = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -59,14 +72,20 @@ function UI.Tabs:enable()
|
||||
self.tabBar:enable()
|
||||
|
||||
local menuItem = Util.find(self.tabBar.children, 'selected', true)
|
||||
self:enableTab(menuItem.tabUid)
|
||||
end
|
||||
|
||||
function UI.Tabs:enableTab(tabUid, hint)
|
||||
for child in self:eachChild() do
|
||||
child.transitionHint = nil
|
||||
if child.uid == menuItem.tabUid then
|
||||
child:enable()
|
||||
self:emit({ type = 'tab_activate', activated = child })
|
||||
elseif child.tabTitle then
|
||||
child:disable()
|
||||
child.transitionHint = hint
|
||||
if child.uid == tabUid then
|
||||
if not child.enabled then
|
||||
child:enable()
|
||||
end
|
||||
elseif child.UIElement == 'Tab' then
|
||||
if child.enabled then
|
||||
child:disable()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -76,15 +95,7 @@ function UI.Tabs:eventHandler(event)
|
||||
local tab = self:find(event.tab.tabUid)
|
||||
local hint = event.current > event.last and 'slideLeft' or 'slideRight'
|
||||
|
||||
for child in self:eachChild() do
|
||||
if child.uid == event.tab.tabUid then
|
||||
child.transitionHint = hint
|
||||
child:enable()
|
||||
elseif child.tabTitle then
|
||||
child:disable()
|
||||
end
|
||||
end
|
||||
self:emit({ type = 'tab_activate', activated = tab })
|
||||
self:enableTab(event.tab.tabUid, hint)
|
||||
tab:draw()
|
||||
return true
|
||||
end
|
||||
@@ -94,28 +105,28 @@ function UI.Tabs.example()
|
||||
return UI.Tabs {
|
||||
tab1 = UI.Tab {
|
||||
index = 1,
|
||||
tabTitle = 'tab1',
|
||||
title = 'tab1',
|
||||
entry = UI.TextEntry { y = 3, shadowText = 'text' },
|
||||
},
|
||||
tab2 = UI.Tab {
|
||||
index = 2,
|
||||
tabTitle = 'tab2',
|
||||
title = 'tab2',
|
||||
subtabs = UI.Tabs {
|
||||
x = 3, y = 2, ex = -3, ey = -2,
|
||||
tab1 = UI.Tab {
|
||||
index = 1,
|
||||
tabTitle = 'tab4',
|
||||
title = 'tab4',
|
||||
entry = UI.TextEntry { y = 3, shadowText = 'text' },
|
||||
},
|
||||
tab3 = UI.Tab {
|
||||
index = 2,
|
||||
tabTitle = 'tab5',
|
||||
title = 'tab5',
|
||||
},
|
||||
},
|
||||
},
|
||||
tab3 = UI.Tab {
|
||||
index = 3,
|
||||
tabTitle = 'tab3',
|
||||
title = 'tab3',
|
||||
},
|
||||
enable = function(self)
|
||||
UI.Tabs.enable(self)
|
||||
|
||||
@@ -8,11 +8,12 @@ UI.TextArea.defaults = {
|
||||
value = '',
|
||||
showScrollBar = true,
|
||||
}
|
||||
function UI.TextArea:setText(text)
|
||||
function UI.TextArea:setValue(text)
|
||||
self:reset()
|
||||
self.value = text
|
||||
self:draw()
|
||||
end
|
||||
UI.TextArea.setText = UI.TextArea.setValue -- deprecate
|
||||
|
||||
function UI.TextArea.focus()
|
||||
-- allow keyboard scrolling
|
||||
|
||||
@@ -15,52 +15,50 @@ function UI.Wizard:postInit()
|
||||
}
|
||||
self.previousButton = UI.Button {
|
||||
x = -18, y = -1,
|
||||
text = '< Back',
|
||||
text = '\17 Back',
|
||||
event = 'previousView',
|
||||
}
|
||||
self.nextButton = UI.Button {
|
||||
x = -9, y = -1,
|
||||
text = 'Next >',
|
||||
text = 'Next \16',
|
||||
event = 'nextView',
|
||||
}
|
||||
|
||||
Util.merge(self, self.pages)
|
||||
end
|
||||
|
||||
function UI.Wizard:add(pages)
|
||||
Util.merge(self.pages, pages)
|
||||
Util.merge(self, pages)
|
||||
|
||||
for _, child in pairs(self.pages) do
|
||||
child.ey = child.ey or -2
|
||||
end
|
||||
|
||||
if self.parent then
|
||||
self:initChildren()
|
||||
function UI.Wizard:getPages()
|
||||
local t = { }
|
||||
for child in self:eachChild() do
|
||||
if type(child) == 'table' and child.UIElement == 'WizardPage' then
|
||||
table.insert(t, child)
|
||||
end
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
function UI.Wizard:getPage(index)
|
||||
return Util.find(self.pages, 'index', index)
|
||||
local pages = self:getPages()
|
||||
return Util.find(pages, 'index', index)
|
||||
end
|
||||
|
||||
function UI.Wizard:enable(...)
|
||||
function UI.Wizard:enable()
|
||||
self.enabled = true
|
||||
self.index = 1
|
||||
local initial = self:getPage(1)
|
||||
for child in self:eachChild() do
|
||||
if child == initial or not child.index then
|
||||
child:enable(...)
|
||||
else
|
||||
if child.UIElement ~= 'WizardPage' then
|
||||
child:enable()
|
||||
elseif child.enabled then
|
||||
child:disable()
|
||||
end
|
||||
end
|
||||
local initial = self:getPage(1)
|
||||
self:emit({ type = 'enable_view', next = initial })
|
||||
end
|
||||
|
||||
function UI.Wizard:isViewValid()
|
||||
local currentView = self:getPage(self.index)
|
||||
return not currentView.validate and true or currentView:validate()
|
||||
return currentView:validate()
|
||||
end
|
||||
|
||||
function UI.Wizard:eventHandler(event)
|
||||
@@ -107,7 +105,7 @@ function UI.Wizard:eventHandler(event)
|
||||
end
|
||||
|
||||
if self:getPage(self.index + 1) then
|
||||
self.nextButton.text = 'Next >'
|
||||
self.nextButton.text = 'Next \16'
|
||||
self.nextButton.event = 'nextView'
|
||||
else
|
||||
self.nextButton.text = 'Accept'
|
||||
@@ -124,29 +122,27 @@ end
|
||||
function UI.Wizard.example()
|
||||
return UI.Wizard {
|
||||
ey = -2,
|
||||
pages = {
|
||||
splash = UI.WizardPage {
|
||||
index = 1,
|
||||
intro = UI.TextArea {
|
||||
inactive = true,
|
||||
x = 3, ex = -3, y = 2, ey = -2,
|
||||
value = 'sample text',
|
||||
},
|
||||
splash = UI.WizardPage {
|
||||
index = 1,
|
||||
intro = UI.TextArea {
|
||||
inactive = true,
|
||||
x = 3, ex = -3, y = 2, ey = -2,
|
||||
value = 'sample text',
|
||||
},
|
||||
label = UI.WizardPage {
|
||||
index = 2,
|
||||
intro = UI.TextArea {
|
||||
inactive = true,
|
||||
x = 3, ex = -3, y = 2, ey = -2,
|
||||
value = 'sample more text',
|
||||
},
|
||||
},
|
||||
label = UI.WizardPage {
|
||||
index = 2,
|
||||
intro = UI.TextArea {
|
||||
inactive = true,
|
||||
x = 3, ex = -3, y = 2, ey = -2,
|
||||
value = 'sample more text',
|
||||
},
|
||||
password = UI.WizardPage {
|
||||
index = 3,
|
||||
text = UI.TextEntry {
|
||||
x = 12, ex = -3, y = 2,
|
||||
shadowText = 'tet',
|
||||
},
|
||||
},
|
||||
password = UI.WizardPage {
|
||||
index = 3,
|
||||
text = UI.TextEntry {
|
||||
x = 12, ex = -3, y = 2,
|
||||
shadowText = 'tet',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -6,3 +6,6 @@ UI.WizardPage.defaults = {
|
||||
UIElement = 'WizardPage',
|
||||
ey = -2,
|
||||
}
|
||||
function UI.WizardPage.validate()
|
||||
return true
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user