mirror of
https://github.com/airstruck/luigi.git
synced 2026-01-10 08:18:22 +00:00
add master layouts
This commit is contained in:
@@ -38,30 +38,62 @@ A tree of widget data.
|
|||||||
@treturn Layout
|
@treturn Layout
|
||||||
A Layout instance.
|
A Layout instance.
|
||||||
--]]--
|
--]]--
|
||||||
function Layout:constructor (data)
|
function Layout:constructor (data, master)
|
||||||
data = data or {}
|
data = data or {}
|
||||||
self.accelerators = {}
|
|
||||||
|
if master then
|
||||||
|
self:setMaster(master)
|
||||||
|
else
|
||||||
|
self:setTheme(require(ROOT .. 'theme.light'))
|
||||||
|
self:setStyle()
|
||||||
|
end
|
||||||
|
|
||||||
self:addDefaultHandlers()
|
self:addDefaultHandlers()
|
||||||
self:setStyle()
|
|
||||||
self:setTheme(require(ROOT .. 'theme.light'))
|
|
||||||
|
|
||||||
self.isShown = false
|
self.isShown = false
|
||||||
self.hooks = {}
|
self.hooks = {}
|
||||||
self.root = data
|
self.root = data
|
||||||
|
|
||||||
Widget(self, data)
|
Widget(self, data)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--[[--
|
||||||
|
Set the master layout for this layout.
|
||||||
|
|
||||||
|
This layout's theme and style will be set the same as the master layout, and
|
||||||
|
widgets added to this layout will be indexed and keyboard-accelerated by the
|
||||||
|
master layout instead of this layout.
|
||||||
|
|
||||||
|
@tparam Layout layout
|
||||||
|
Master layout
|
||||||
|
|
||||||
|
@treturn Layout Self
|
||||||
|
--]]--
|
||||||
|
function Layout:setMaster (layout)
|
||||||
|
self.master = layout
|
||||||
|
|
||||||
|
function self:addWidget (...)
|
||||||
|
return layout:addWidget(...)
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--[[--
|
--[[--
|
||||||
Set the style from a definition table or function.
|
Set the style from a definition table or function.
|
||||||
|
|
||||||
@tparam table|function rules
|
@tparam table|function rules
|
||||||
Style definition.
|
Style definition.
|
||||||
|
|
||||||
|
@treturn Layout Self
|
||||||
--]]--
|
--]]--
|
||||||
function Layout:setStyle (rules)
|
function Layout:setStyle (rules)
|
||||||
if type(rules) == 'function' then
|
if type(rules) == 'function' then
|
||||||
rules = rules()
|
rules = rules()
|
||||||
end
|
end
|
||||||
self.style = Style(rules or {}, { 'id', 'style' })
|
self.style = Style(rules or {}, { 'id', 'style' })
|
||||||
|
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[--
|
--[[--
|
||||||
@@ -77,6 +109,26 @@ function Layout:setTheme (rules)
|
|||||||
self.theme = Style(rules or {}, { 'type' })
|
self.theme = Style(rules or {}, { 'type' })
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--[[--
|
||||||
|
Get the style from master layout or this layout.
|
||||||
|
|
||||||
|
@treturn table
|
||||||
|
Style table.
|
||||||
|
--]]--
|
||||||
|
function Layout:getStyle ()
|
||||||
|
return self.master and self.master:getStyle() or self.style
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[--
|
||||||
|
Get the theme from master layout or this layout.
|
||||||
|
|
||||||
|
@treturn table
|
||||||
|
Theme table.
|
||||||
|
--]]--
|
||||||
|
function Layout:getTheme ()
|
||||||
|
return self.master and self.master:getTheme() or self.theme
|
||||||
|
end
|
||||||
|
|
||||||
--[[--
|
--[[--
|
||||||
Show the layout.
|
Show the layout.
|
||||||
|
|
||||||
@@ -187,6 +239,8 @@ end
|
|||||||
|
|
||||||
-- Add handlers for keyboard accelerators and tab focus
|
-- Add handlers for keyboard accelerators and tab focus
|
||||||
function Layout:addDefaultHandlers ()
|
function Layout:addDefaultHandlers ()
|
||||||
|
self.accelerators = {}
|
||||||
|
|
||||||
self:onKeyPress(function (event)
|
self:onKeyPress(function (event)
|
||||||
|
|
||||||
-- tab / shift-tab cycles focused widget
|
-- tab / shift-tab cycles focused widget
|
||||||
@@ -210,7 +264,6 @@ function Layout:addDefaultHandlers ()
|
|||||||
|
|
||||||
-- accelerators
|
-- accelerators
|
||||||
local acceleratedWidget = self.accelerators[event.key]
|
local acceleratedWidget = self.accelerators[event.key]
|
||||||
|
|
||||||
if acceleratedWidget then
|
if acceleratedWidget then
|
||||||
acceleratedWidget.hovered = true
|
acceleratedWidget.hovered = true
|
||||||
self.input:handlePressStart(self, event.key, event.x, event.y,
|
self.input:handlePressStart(self, event.key, event.x, event.y,
|
||||||
|
|||||||
@@ -38,11 +38,12 @@ local function metaIndex (self, property)
|
|||||||
local value = Widget[property]
|
local value = Widget[property]
|
||||||
if value ~= nil then return value end
|
if value ~= nil then return value end
|
||||||
|
|
||||||
local style = self.layout.style
|
local layout = self.layout
|
||||||
|
local style = layout:getStyle()
|
||||||
value = style and style:getProperty(self, property)
|
value = style and style:getProperty(self, property)
|
||||||
if value ~= nil and value ~= 'defer' then return value end
|
if value ~= nil and value ~= 'defer' then return value end
|
||||||
|
|
||||||
local theme = self.layout.theme
|
local theme = layout:getTheme()
|
||||||
return theme and theme:getProperty(self, property)
|
return theme and theme:getProperty(self, property)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,49 @@ local ROOT = (...):gsub('[^.]*.[^.]*.[^.]*$', '')
|
|||||||
|
|
||||||
local Layout, Event
|
local Layout, Event
|
||||||
|
|
||||||
local show
|
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
|
||||||
|
|
||||||
|
local function show (self)
|
||||||
|
if not self.items or #self.items < 1 then return end
|
||||||
|
|
||||||
|
addLayoutChildren(self)
|
||||||
|
self.menuLayout:show()
|
||||||
|
end
|
||||||
|
|
||||||
local function deactivateSiblings (target)
|
local function deactivateSiblings (target)
|
||||||
local sibling = target.parent and target.parent[1]
|
local sibling = target.parent and target.parent[1]
|
||||||
@@ -76,56 +118,6 @@ local function registerLayoutEvents (self)
|
|||||||
menuLayout:onPressEnter(activate)
|
menuLayout:onPressEnter(activate)
|
||||||
end
|
end
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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 function initialize (self)
|
||||||
local pad = self.padding or 0
|
local pad = self.padding or 0
|
||||||
local isSubmenu = self.parentMenu and self.parentMenu.parentMenu
|
local isSubmenu = self.parentMenu and self.parentMenu.parentMenu
|
||||||
@@ -180,13 +172,17 @@ local function registerEvents (self)
|
|||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function createLayout (self)
|
||||||
|
Layout = Layout or require(ROOT .. 'layout')
|
||||||
|
|
||||||
|
self.menuLayout = Layout({ type = 'submenu' }, self.rootMenu.layout)
|
||||||
|
end
|
||||||
|
|
||||||
return function (self)
|
return function (self)
|
||||||
extractChildren(self)
|
extractChildren(self)
|
||||||
initialize(self)
|
initialize(self)
|
||||||
registerEvents(self)
|
registerEvents(self)
|
||||||
|
|
||||||
self.rootMenu.layout:addWidget(self)
|
|
||||||
|
|
||||||
if not self.items or #self.items < 1 then return end
|
if not self.items or #self.items < 1 then return end
|
||||||
createLayout(self)
|
createLayout(self)
|
||||||
registerLayoutEvents(self)
|
registerLayoutEvents(self)
|
||||||
|
|||||||
Reference in New Issue
Block a user