From cd6ef0da5090fdd6ae8be9ab2850f29fac56e540 Mon Sep 17 00:00:00 2001 From: "kepler155c@gmail.com" Date: Thu, 9 Apr 2020 16:08:54 -0600 Subject: [PATCH] use layout() where appropriate and cleanup --- sys/apps/Overview.lua | 85 ++++++-------------- sys/apps/inspect.lua | 19 +++++ sys/modules/opus/fuzzy.lua | 19 +++++ sys/modules/opus/ui.lua | 44 +++------- sys/modules/opus/ui/components/Button.lua | 4 +- sys/modules/opus/ui/components/Checkbox.lua | 3 +- sys/modules/opus/ui/components/Chooser.lua | 4 +- sys/modules/opus/ui/components/DropMenu.lua | 18 ++++- sys/modules/opus/ui/components/Embedded.lua | 24 +++--- sys/modules/opus/ui/components/Grid.lua | 4 +- sys/modules/opus/ui/components/Menu.lua | 4 +- sys/modules/opus/ui/components/StatusBar.lua | 13 +-- sys/modules/opus/ui/components/Text.lua | 4 +- sys/modules/opus/ui/transition.lua | 46 +++++------ 14 files changed, 140 insertions(+), 151 deletions(-) create mode 100644 sys/modules/opus/fuzzy.lua diff --git a/sys/apps/Overview.lua b/sys/apps/Overview.lua index 2515fc4..222ae84 100644 --- a/sys/apps/Overview.lua +++ b/sys/apps/Overview.lua @@ -1,4 +1,5 @@ local Alt = require('opus.alternate') +local Array = require('opus.array') local class = require('opus.class') local Config = require('opus.config') local Event = require('opus.event') @@ -86,30 +87,18 @@ local function parseIcon(iconText) return s, m end -UI.VerticalTabBar = class(UI.TabBar) -function UI.VerticalTabBar:setParent() - self.x = 1 - self.width = 8 - self.height = nil - self.ey = -2 - UI.TabBar.setParent(self) - for k,c in pairs(self.children) do - c.x = 1 - c.y = k + 1 - c.ox, c.oy = c.x, c.y - c.ow = 8 - c.width = 8 - c:reposition(c.x, c.y, c.width, c.height) - end -end - -local cx = 9 -local cy = 1 - local page = UI.Page { container = UI.Viewport { - x = cx, - y = cy, + x = 9, y = 1, + }, + tabBar = UI.TabBar { + ey = -2, + width = 8, + selectedBackgroundColor = UI.colors.primary, + layout = function(self) + self.height = nil + UI.TabBar.layout(self) + end, }, tray = UI.Window { y = -1, width = 8, @@ -128,11 +117,6 @@ local page = UI.Page { text = '?', event = 'help', backgroundFocusColor = colors.lightGray, }, - --[[ - volume = UI.Button { - x = 3, - text = '\15', event = 'volume', - },]] }, editor = UI.SlideOut { y = -12, height = 12, @@ -253,7 +237,7 @@ local function loadApplications() return requirements[a.requires] end - return true -- Util.startsWith(a.run, 'http') or shell.resolveProgram(a.run) + return true end) local categories = { } @@ -263,6 +247,7 @@ local function loadApplications() categories[f.category] = true table.insert(buttons, { text = f.category, + width = 8, selected = config.currentCategory == f.category }) end @@ -270,14 +255,13 @@ local function loadApplications() table.sort(buttons, function(a, b) return a.text < b.text end) table.insert(buttons, 1, { text = 'Recent' }) - Util.removeByValue(page.children, page.tabBar) + for k,v in pairs(buttons) do + v.x = 1 + v.y = k + 1 + end - page:add { - tabBar = UI.VerticalTabBar { - buttons = buttons, - selectedBackgroundColor = UI.colors.primary, - }, - } + page.tabBar.children = { } + page.tabBar:addButtons(buttons) --page.tabBar:selectTab(config.currentCategory or 'Apps') page.container:setCategory(config.currentCategory or 'Apps') @@ -292,7 +276,6 @@ UI.Icon.defaults = { function UI.Icon:eventHandler(event) if event.type == 'mouse_click' then self:setFocus(self.button) - --self:emit({ type = self.button.event, button = self.button }) return true elseif event.type == 'mouse_doubleclick' then self:emit({ type = self.button.event, button = self.button }) @@ -308,37 +291,23 @@ function page.container:setCategory(categoryName, animate) self.children = { } self:reset() - local function filter(it, f) - local ot = { } - for _,v in pairs(it) do - if f(v) then - table.insert(ot, v) - end - end - return ot - end - - local filtered + local filtered = { } if categoryName == 'Recent' then - filtered = { } - for _,v in ipairs(config.Recent) do local app = Util.find(applications, 'key', v) - if app then -- and fs.exists(app.run) then + if app then table.insert(filtered, app) end end - else - filtered = filter(applications, function(a) - return a.category == categoryName -- and fs.exists(a.run) + filtered = Array.filter(applications, function(a) + return a.category == categoryName end) table.sort(filtered, function(a, b) return a.title < b.title end) end for _,program in ipairs(filtered) do - local icon if extSupport and program.iconExt then icon = parseIcon(program.iconExt) @@ -456,7 +425,6 @@ function page.container:setCategory(categoryName, animate) child.tween:update(1) child:move(math.floor(child.x), math.floor(child.y)) end - --os.sleep(.5) i = i + 1 return i <= frames end @@ -584,11 +552,6 @@ function page.editor:show(app) self:focusFirst() end -function page.editor.form.image:draw() - self:clear() - UI.NftImage.draw(self) -end - function page.editor:updateApplications(app) if not app.key then app.key = SHA.compute(app.title) @@ -652,8 +615,6 @@ function page.editor:eventHandler(event) local values = self.form.values self:hide() self:updateApplications(values) - --page:refresh() - --page:draw() config.currentCategory = values.category Config.update('Overview', config) os.queueEvent('overview_refresh') diff --git a/sys/apps/inspect.lua b/sys/apps/inspect.lua index 1d4f95b..d2117db 100644 --- a/sys/apps/inspect.lua +++ b/sys/apps/inspect.lua @@ -133,6 +133,12 @@ page = UI.Page { }, }, }, + accelerators = { + ['shift-right'] = 'size', + ['shift-left' ] = 'size', + ['shift-up' ] = 'size', + ['shift-down' ] = 'size', + }, eventHandler = function (self, event) if event.type == 'focus_change' and isRelevant(event.focused) then focused = event.focused @@ -168,6 +174,19 @@ page = UI.Page { elseif event.type == 'editor_apply' then self.editor:hide() + + elseif event.type == 'size' then + local sizing = { + ['shift-right'] = { 1, 0 }, + ['shift-left' ] = { -1, 0 }, + ['shift-up' ] = { 0, -1 }, + ['shift-down' ] = { 0, 1 }, + } + self.ox = math.max(self.ox + sizing[event.ie.code][1], 1) + self.oy = math.max(self.oy + sizing[event.ie.code][2], 1) + UI.term.device.clear() + self:resize() + self:draw() end return UI.Page.eventHandler(self, event) diff --git a/sys/modules/opus/fuzzy.lua b/sys/modules/opus/fuzzy.lua new file mode 100644 index 0000000..7a6082d --- /dev/null +++ b/sys/modules/opus/fuzzy.lua @@ -0,0 +1,19 @@ +-- Based on Squid's fuzzy search +-- https://github.com/SquidDev-CC/artist/blob/vnext/artist/lib/match.lua +-- +-- not very fuzzy anymore + +local SCORE_WEIGHT = 1000 +local LEADING_LETTER_PENALTY = -3 +local LEADING_LETTER_PENALTY_MAX = -9 + +local _find = string.find +local _max = math.max + +return function(str, pattern) + local start = _find(str, pattern, 1, true) + if start then + -- All letters before the current one are considered leading, so add them to our penalty + return SCORE_WEIGHT + _max(LEADING_LETTER_PENALTY * (start - 1), LEADING_LETTER_PENALTY_MAX) + end +end diff --git a/sys/modules/opus/ui.lua b/sys/modules/opus/ui.lua index 1386adf..58c14db 100644 --- a/sys/modules/opus/ui.lua +++ b/sys/modules/opus/ui.lua @@ -54,10 +54,7 @@ function Manager:init() local function resize(_, side) local dev = self.devices[side or 'terminal'] if dev and dev.currentPage then - -- the parent doesn't have any children set... - -- that's why we have to resize both the parent and the current page - -- kinda makes sense - dev.currentPage.parent:resize() + dev:resize() dev.currentPage:resize() dev.currentPage:draw() @@ -441,7 +438,7 @@ function UI.Window:init(args) local defaults = args local m = getmetatable(self) -- get the class for this instance repeat - if m.disable then + if m ~= Canvas then defaults = UI:getDefaults(m, defaults) end m = m._base @@ -562,6 +559,9 @@ function UI.Window:layout() self.height = self.parent.height - self.y + 1 end + self.width = math.max(self.width, 1) + self.height = math.max(self.height, 1) + self:reposition(self.x, self.y, self.width, self.height) end @@ -905,7 +905,7 @@ function UI.Window:pointToChild(x, y) } end -UI.Window.docs.getFocusables = [[getFocusables(VOID) +UI.Window.docs.getFocusables = [[getxables(VOID) Returns a list of children that can accept focus.]] function UI.Window:getFocusables() local focusable = { } @@ -929,7 +929,7 @@ function UI.Window:getFocusables() end if self.children then - getFocusable(self, self.x, self.y) + getFocusable(self) end return focusable @@ -974,18 +974,8 @@ function UI.Window:scrollIntoView() end end -function UI.Window:addTransition(effect, args) - if self.parent then - args = args or { } - if not args.x then -- not good - args.x, args.y = self.x, self.y - args.width = self.width - args.height = self.height - args.canvas = self - end - - self.parent:addTransition(effect, args) - end +function UI.Window:addTransition(effect, args, canvas) + self.parent:addTransition(effect, args, canvas or self) end function UI.Window:emit(event) @@ -1092,29 +1082,21 @@ function UI.Device:reset() self.device.setCursorPos(1, 1) end -function UI.Device:addTransition(effect, args) +function UI.Device:addTransition(effect, args, canvas) if not self.transitions then self.transitions = { } end - args = args or { } - args.ex = args.x + args.width - 1 - args.ey = args.y + args.height - 1 - args.canvas = args.canvas or self - if type(effect) == 'string' then - effect = Transition[effect] - if not effect then - error('Invalid transition') - end + effect = Transition[effect] or error('Invalid transition') end - table.insert(self.transitions, { effect = effect, args = args }) + table.insert(self.transitions, { effect = effect, args = args or { }, canvas = canvas }) end function UI.Device:runTransitions(transitions) for _,k in pairs(transitions) do - k.update = k.effect(k.args) + k.update = k.effect(k.canvas, k.args) end while true do for _,k in ipairs(Util.keys(transitions)) do diff --git a/sys/modules/opus/ui/components/Button.lua b/sys/modules/opus/ui/components/Button.lua index f928707..a2c5bd8 100644 --- a/sys/modules/opus/ui/components/Button.lua +++ b/sys/modules/opus/ui/components/Button.lua @@ -23,11 +23,11 @@ UI.Button.defaults = { mouse_click = 'button_activate', } } -function UI.Button:setParent() +function UI.Button:layout() if not self.width and not self.ex then self.width = self.noPadding and #self.text or #self.text + 2 end - UI.Window.setParent(self) + UI.Window.layout(self) end function UI.Button:draw() diff --git a/sys/modules/opus/ui/components/Checkbox.lua b/sys/modules/opus/ui/components/Checkbox.lua index e757797..0eb48e0 100644 --- a/sys/modules/opus/ui/components/Checkbox.lua +++ b/sys/modules/opus/ui/components/Checkbox.lua @@ -21,8 +21,9 @@ UI.Checkbox.defaults = { mouse_click = 'checkbox_toggle', } } -function UI.Checkbox:postInit() +function UI.Checkbox:layout() self.width = self.label and #self.label + 4 or 3 + UI.Window.layout(self) end function UI.Checkbox:draw() diff --git a/sys/modules/opus/ui/components/Chooser.lua b/sys/modules/opus/ui/components/Chooser.lua index fd1e327..6aa2e4a 100644 --- a/sys/modules/opus/ui/components/Chooser.lua +++ b/sys/modules/opus/ui/components/Chooser.lua @@ -20,7 +20,7 @@ UI.Chooser.defaults = { left = 'choice_prev', } } -function UI.Chooser:setParent() +function UI.Chooser:layout() if not self.width and not self.ex then self.width = 1 for _,v in pairs(self.choices) do @@ -30,7 +30,7 @@ function UI.Chooser:setParent() end self.width = self.width + 4 end - UI.Window.setParent(self) + UI.Window.layout(self) end function UI.Chooser:draw() diff --git a/sys/modules/opus/ui/components/DropMenu.lua b/sys/modules/opus/ui/components/DropMenu.lua index 2b61dff..d7fc52a 100644 --- a/sys/modules/opus/ui/components/DropMenu.lua +++ b/sys/modules/opus/ui/components/DropMenu.lua @@ -41,14 +41,28 @@ end function UI.DropMenu:enable() local menuBar = self.parent:find(self.menuUid) + local hasActive + for _,c in pairs(self.children) do if not c.spacer and menuBar then c.inactive = not menuBar:getActive(c) end + if not c.inactive then + hasActive = true + end end + -- jump through a lot of hoops if all selections are inactive + -- there's gotta be a better way + -- lots of exception code just to handle drop menus + self.focus = not hasActive and function() end + UI.Window.enable(self) - self:focusFirst() + if self.focus then + self:setFocus(self) + else + self:focusFirst() + end self:draw() end @@ -59,7 +73,7 @@ end function UI.DropMenu:eventHandler(event) if event.type == 'focus_lost' and self.enabled then - if not Util.contains(self.children, event.focused) then + if not (Util.contains(self.children, event.focused) or event.focused == self) then self:disable() end elseif event.type == 'mouse_out' and self.enabled then diff --git a/sys/modules/opus/ui/components/Embedded.lua b/sys/modules/opus/ui/components/Embedded.lua index 1747a10..03a4c88 100644 --- a/sys/modules/opus/ui/components/Embedded.lua +++ b/sys/modules/opus/ui/components/Embedded.lua @@ -15,19 +15,21 @@ UI.Embedded.defaults = { down = 'scroll_down', } } -function UI.Embedded:setParent() - UI.Window.setParent(self) +function UI.Embedded:layout() + UI.Window.layout(self) - function self.render() - self:sync() + if not self.win then + 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) + self.win.setCursorPos(1, 1) + self.win.setBackgroundColor(self.backgroundColor) + self.win.setTextColor(self.textColor) + self.win.clear() 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) - self.win.setCursorPos(1, 1) - self.win.setBackgroundColor(self.backgroundColor) - self.win.setTextColor(self.textColor) - self.win.clear() end function UI.Embedded:draw() diff --git a/sys/modules/opus/ui/components/Grid.lua b/sys/modules/opus/ui/components/Grid.lua index b728229..49780eb 100644 --- a/sys/modules/opus/ui/components/Grid.lua +++ b/sys/modules/opus/ui/components/Grid.lua @@ -83,8 +83,8 @@ UI.Grid.defaults = { [ 'control-f' ] = 'scroll_pageDown', }, } -function UI.Grid:setParent() - UI.Window.setParent(self) +function UI.Grid:layout() + UI.Window.layout(self) for _,c in pairs(self.columns) do c.cw = c.width diff --git a/sys/modules/opus/ui/components/Menu.lua b/sys/modules/opus/ui/components/Menu.lua index 0e18682..b5462cf 100644 --- a/sys/modules/opus/ui/components/Menu.lua +++ b/sys/modules/opus/ui/components/Menu.lua @@ -13,8 +13,7 @@ function UI.Menu:postInit() self.pageSize = #self.menuItems end -function UI.Menu:setParent() - UI.Grid.setParent(self) +function UI.Menu:layout() self.itemWidth = 1 for _,v in pairs(self.values) do if #v.prompt > self.itemWidth then @@ -28,6 +27,7 @@ function UI.Menu:setParent() else self.width = self.itemWidth + 2 end + UI.Grid.layout(self) end function UI.Menu:center() diff --git a/sys/modules/opus/ui/components/StatusBar.lua b/sys/modules/opus/ui/components/StatusBar.lua index 39c72a0..ecd5f4b 100644 --- a/sys/modules/opus/ui/components/StatusBar.lua +++ b/sys/modules/opus/ui/components/StatusBar.lua @@ -13,7 +13,8 @@ UI.StatusBar.defaults = { height = 1, ey = -1, } -function UI.StatusBar:adjustWidth() +function UI.StatusBar:layout() + UI.Window.layout(self) -- Can only have 1 adjustable width if self.columns then local w = self.width - #self.columns - 1 @@ -31,16 +32,6 @@ function UI.StatusBar:adjustWidth() end end -function UI.StatusBar:resize() - UI.Window.resize(self) - self:adjustWidth() -end - -function UI.StatusBar:setParent() - UI.Window.setParent(self) - self:adjustWidth() -end - function UI.StatusBar:setStatus(status) if self.values ~= status then self.values = status diff --git a/sys/modules/opus/ui/components/Text.lua b/sys/modules/opus/ui/components/Text.lua index 0250a48..5bf3799 100644 --- a/sys/modules/opus/ui/components/Text.lua +++ b/sys/modules/opus/ui/components/Text.lua @@ -8,11 +8,11 @@ UI.Text.defaults = { value = '', height = 1, } -function UI.Text:setParent() +function UI.Text:layout() if not self.width and not self.ex then self.width = #tostring(self.value) end - UI.Window.setParent(self) + UI.Window.layout(self) end function UI.Text:draw() diff --git a/sys/modules/opus/ui/transition.lua b/sys/modules/opus/ui/transition.lua index 0cd6245..24d07ee 100644 --- a/sys/modules/opus/ui/transition.lua +++ b/sys/modules/opus/ui/transition.lua @@ -2,61 +2,61 @@ local Tween = require('opus.ui.tween') local Transition = { } -function Transition.slideLeft(args) +function Transition.slideLeft(canvas, args) local ticks = args.ticks or 6 local easing = args.easing or 'inCirc' - local pos = { x = args.ex } - local tween = Tween.new(ticks, pos, { x = args.x }, easing) + local pos = { x = canvas.ex } + local tween = Tween.new(ticks, pos, { x = canvas.x }, easing) - args.canvas:move(pos.x, args.canvas.y) + canvas:move(pos.x, canvas.y) return function() local finished = tween:update(1) - args.canvas:move(math.floor(pos.x), args.canvas.y) - args.canvas:dirty(true) + canvas:move(math.floor(pos.x), canvas.y) + canvas:dirty(true) return not finished end end -function Transition.slideRight(args) +function Transition.slideRight(canvas, args) local ticks = args.ticks or 6 local easing = args.easing or 'inCirc' - local pos = { x = -args.canvas.width } + local pos = { x = -canvas.width } local tween = Tween.new(ticks, pos, { x = 1 }, easing) - args.canvas:move(pos.x, args.canvas.y) + canvas:move(pos.x, canvas.y) return function() local finished = tween:update(1) - args.canvas:move(math.floor(pos.x), args.canvas.y) - args.canvas:dirty(true) + canvas:move(math.floor(pos.x), canvas.y) + canvas:dirty(true) return not finished end end -function Transition.expandUp(args) +function Transition.expandUp(canvas, args) local ticks = args.ticks or 3 local easing = args.easing or 'linear' - local pos = { y = args.ey + 1 } - local tween = Tween.new(ticks, pos, { y = args.y }, easing) + local pos = { y = canvas.ey + 1 } + local tween = Tween.new(ticks, pos, { y = canvas.y }, easing) - args.canvas:move(args.x, pos.y) + canvas:move(canvas.x, pos.y) return function() local finished = tween:update(1) - args.canvas:move(args.x, math.floor(pos.y)) - args.canvas.parent:dirty(true) + canvas:move(canvas.x, math.floor(pos.y)) + canvas.parent:dirty(true) return not finished end end -function Transition.shake(args) +function Transition.shake(canvas, args) local ticks = args.ticks or 8 local i = ticks return function() i = -i - args.canvas:move(args.canvas.x + i, args.canvas.y) + canvas:move(canvas.x + i, canvas.y) if i > 0 then i = i - 2 end @@ -64,15 +64,15 @@ function Transition.shake(args) end end -function Transition.shuffle(args) +function Transition.shuffle(canvas, args) local ticks = args.ticks or 4 local easing = args.easing or 'linear' local t = { } - for _,child in pairs(args.canvas.children) do + for _,child in pairs(canvas.children) do t[child] = Tween.new(ticks, child, { x = child.x, y = child.y }, easing) - child.x = math.random(1, args.canvas.parent.width) - child.y = math.random(1, args.canvas.parent.height) + child.x = math.random(1, canvas.parent.width) + child.y = math.random(1, canvas.parent.height) end return function()