From bdc130aab99aa13a833a20530f75df9b243029b1 Mon Sep 17 00:00:00 2001 From: airstruck Date: Tue, 10 Nov 2015 17:01:17 -0500 Subject: [PATCH] rework menus --- example/main.lua | 18 ++--- luigi/layout.lua | 9 ++- luigi/renderer.lua | 4 +- luigi/widget.lua | 4 +- luigi/widget/menu/item.lua | 146 ++++++++++++++++++++----------------- 5 files changed, 95 insertions(+), 86 deletions(-) diff --git a/example/main.lua b/example/main.lua index 85c3495..bdb1eb4 100644 --- a/example/main.lua +++ b/example/main.lua @@ -34,8 +34,8 @@ local style = { local mainForm = { id = 'mainWindow', type = 'panel', { type = 'menu', id = 'menubar', flow = 'x', - { text = 'File', id = 'menuFile', - { text = 'Save', id = 'menuFileSave', key = 'ctrl-s' }, + { text = 'File', + { text = 'Save', id = 'menuSave', key = 'ctrl-s' }, { text = 'Quit', id = 'menuQuit', key = 'escape' }, }, { text = 'Edit', @@ -54,9 +54,9 @@ local mainForm = { id = 'mainWindow', type = 'panel', }, }, { text = 'Help', - { text = 'About Luigi', icon = 'icon/16px/Book.png', key = 'backspace', }, - { text = 'About Luigi Demo', icon = 'icon/16px/Book Red.png' }, - { text = 'Licenses' }, + { text = 'About Luigi', icon = 'icon/16px/Book.png', key = 'f1', }, + { text = 'About Luigi Demo', icon = 'icon/16px/Book Red.png', key = 'f2' }, + { text = 'Licenses', key = 'f3' }, }, }, { type = 'panel', id = 'toolbar', flow = 'x', @@ -161,12 +161,8 @@ erge rg eg erg er ergs erg er ge rh erh rth]] layout.mainCanvas.align = 'top' -print(layout.menuQuit) ---[[ -Layout.menuQuit:onPress(function (event) - love.event.quit() -end) -]] +layout.menuQuit:onPress(function (event) love.event.quit() end) + layout:show() diff --git a/luigi/layout.lua b/luigi/layout.lua index e334931..5b8bb7b 100644 --- a/luigi/layout.lua +++ b/luigi/layout.lua @@ -87,14 +87,13 @@ function Layout:show () self:unhook() -- return self.isShown = nil end - local root = self.root if not self.input then self.input = Input.default -- Input(self) end self:manageInput() - root:reshape() + self.root:reshape() end --[[-- @@ -162,16 +161,18 @@ Widget to search within, defaults to layout root. --]]-- function Layout:getWidgetAt (x, y, root) local widget = root or self.root - local childCount = #widget + -- Loop through in reverse, because siblings defined later in the tree -- will overdraw earlier siblings. + local childCount = #widget + for i = childCount, 1, -1 do local child = widget[i] local inner = self:getWidgetAt(x, y, child) if inner then return inner end end + if widget:isAt(x, y) then return widget end - -- if widget == self.root then return widget end end -- Internal, called from Widget:new diff --git a/luigi/renderer.lua b/luigi/renderer.lua index bfe53df..fbe07a7 100644 --- a/luigi/renderer.lua +++ b/luigi/renderer.lua @@ -248,7 +248,9 @@ function Renderer:renderIconAndText (widget) end function Renderer:renderChildren (widget) - for i, child in ipairs(widget) do self:render(child) end + for i, child in ipairs(widget) do + self:render(child) + end end function Renderer:render (widget) diff --git a/luigi/widget.lua b/luigi/widget.lua index eb00058..77eaf63 100644 --- a/luigi/widget.lua +++ b/luigi/widget.lua @@ -291,9 +291,9 @@ The newly added child widget. --]]-- function Widget:addChild (data) local layout = self.layout - local child = Widget(layout, data or {}) + local child = data and data.isWidget and data or Widget(layout, data or {}) - table.insert(self, child) + self[#self + 1] = child child.parent = self child.layout = self.layout diff --git a/luigi/widget/menu/item.lua b/luigi/widget/menu/item.lua index c9071d7..8708031 100644 --- a/luigi/widget/menu/item.lua +++ b/luigi/widget/menu/item.lua @@ -1,6 +1,6 @@ local ROOT = (...):gsub('[^.]*.[^.]*.[^.]*$', '') -local Layout +local Layout, Event local show @@ -53,54 +53,8 @@ local function activate (event, ignoreIfNoneOpen) end end -show = function (self) - if not self.items or #self.items < 1 then - return - end - if self.menuLayout then - self.menuLayout:show() - return - end - - local Layout = Layout or require(ROOT .. 'layout') - - local isSubmenu = self.parentMenu and self.parentMenu.parentMenu - - local x = isSubmenu and self:getWidth() or 0 - local y = isSubmenu and 0 or self:getHeight() - - local menuLayout = Layout { - type = 'submenu', - left = self:getX() + x, - top = self:getY() + y, - width = 0, - height = 0, - } - - local root = menuLayout.root - - local rootPad = root.padding or 0 - - local textWidth = 0 - local keyWidth = 0 - - for index, child in ipairs(self.items) do - child.type = child.type or 'menu.item' - root:addChild(child) - local h = child:getHeight() - root.height = root:getHeight() + h - if child.type == 'menu.item' then - local pad = child.padding or 0 - local tw = child.fontData:getAdvance(child[2].text) - + pad * 2 + h - local kw = child.fontData:getAdvance(child[3].text) - + pad * 4 - textWidth = math.max(textWidth, tw) - keyWidth = math.max(keyWidth, kw) - end - end - - root.width = textWidth + keyWidth + rootPad +local function registerLayoutEvents (self) + local menuLayout = self.menuLayout menuLayout:onReshape(function (event) menuLayout:hide() @@ -119,34 +73,65 @@ show = function (self) end) menuLayout:onEnter(activate) - menuLayout:onPressEnter(activate) - - menuLayout:show() - - self.menuLayout = menuLayout end -local function extractChild (self, index, child) - self[index] = nil - self.items[#self.items + 1] = child - child.parentMenu = self - child.rootMenu = self.rootMenu - child.type = child.type or 'menu.item' +local function addLayoutChildren (self) + local root = self.menuLayout.root + local textWidth = 0 + local keyWidth = 0 + local height = 0 + + while #root > 0 do rawset(root, #root, nil) end + + root.height = 0 + root.width = 0 + + for index, child in ipairs(self.items) do + child.type = child.type or 'menu.item' + root:addChild(child) + local childHeight = child:getHeight() + height = height + childHeight + if child.type == 'menu.item' then + local pad = child.padding or 0 + local tw = child.fontData:getAdvance(child[2].text) + + pad * 2 + childHeight + local kw = child.fontData:getAdvance(child[3].text) + + pad * 2 + childHeight + textWidth = math.max(textWidth, tw) + keyWidth = math.max(keyWidth, kw) + end + end + + local isSubmenu = self.parentMenu and self.parentMenu.parentMenu + local x = isSubmenu and self:getWidth() or 0 + local y = isSubmenu and 0 or self:getHeight() + + root.left = self:getX() + x + root.top = self:getY() + y + root.height = height + root.width = textWidth + keyWidth + (root.padding or 0) end -return function (self) +local function createLayout (self) + Layout = Layout or require(ROOT .. 'layout') + + self.menuLayout = Layout { type = 'submenu' } +end + +show = function (self) + if not self.items or #self.items < 1 then return end + + addLayoutChildren(self) + self.menuLayout:show() +end + +local function initialize (self) local pad = self.padding or 0 local isSubmenu = self.parentMenu and self.parentMenu.parentMenu local text, key, icon = self.text or '', self.key or '', self.icon local textWidth = self.fontData:getAdvance(text) + pad * 2 - self.items = self.items or {} - - for index, child in ipairs(self) do - extractChild(self, index, child) - end - if isSubmenu then local tc = self.textColor or { 0, 0, 0 } local keyColor = { tc[1], tc[2], tc[3], 0x90 } @@ -170,7 +155,20 @@ return function (self) else self.width = textWidth end +end +local function extractChildren (self) + self.items = {} + for index, child in ipairs(self) do + self[index] = nil + self.items[#self.items + 1] = child + child.parentMenu = self + child.rootMenu = self.rootMenu + child.type = child.type or 'menu.item' + end +end + +local function registerEvents (self) self:onPressStart(activate) self:onEnter(function (event) @@ -180,5 +178,17 @@ return function (self) self:onPressEnter(function (event) activate(event, true) end) - +end + +return function (self) + extractChildren(self) + initialize(self) + registerEvents(self) + + self.rootMenu.layout:addWidget(self) + + if not self.items or #self.items < 1 then return end + createLayout(self) + registerLayoutEvents(self) + addLayoutChildren(self) end