mirror of
https://github.com/airstruck/luigi.git
synced 2025-11-18 12:25:06 +00:00
decouple icon from text, see #19
This commit is contained in:
@@ -1,10 +1,13 @@
|
||||
return { style = 'dialog',
|
||||
{ style = 'dialogHead', text = 'About LUIGI' },
|
||||
{ style = 'dialogBody', padding = 24, icon = 'logo.png', text = [[
|
||||
{ style = 'dialogBody', padding = 24, icon = 'logo.png', align = 'middle right',
|
||||
textOffset = { -250, 0 },
|
||||
text = [[
|
||||
Lovely User Interfaces for Game Inventors
|
||||
|
||||
Copyright (c) 2015 airstruck
|
||||
]] },
|
||||
]]
|
||||
},
|
||||
{ style = 'dialogFoot',
|
||||
{}, -- spacer
|
||||
{ style = 'dialogButton', id = 'closeButton', text = 'Close' }
|
||||
|
||||
@@ -45,7 +45,7 @@ return { id = 'mainWindow',
|
||||
{ text = 'Use monospace font', id = 'mono' }
|
||||
},
|
||||
{ style = 'listThing', align = 'middle center',
|
||||
text = 'Try the scroll wheel on this area.', },
|
||||
text = 'Try the scroll wheel on this area.' },
|
||||
{ style = 'listThing', align = 'middle center',
|
||||
text = 'This text is centered, and in the middle vertically.' },
|
||||
{ style = 'listThing', align = 'middle left',
|
||||
@@ -73,10 +73,10 @@ return { id = 'mainWindow',
|
||||
{ text = 'Use sans-serif font', id = 'sans2' },
|
||||
{ text = 'Use monospace font', id = 'mono2' }
|
||||
},
|
||||
{ value = 1, text = 'Thing One' },
|
||||
{ value = 2, text = 'Thing Two' },
|
||||
{ value = 3, text = 'Thing Three' },
|
||||
{ value = 4, text = 'Thing Four' },
|
||||
{ value = 1, text = 'First stepper item' },
|
||||
{ value = 2, text = 'Item two' },
|
||||
{ value = 3, text = 'Third stepper item' },
|
||||
{ value = 4, text = 'Item four' },
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -14,6 +14,7 @@ to recalculate their size and position.
|
||||
local ROOT = (...):gsub('[^.]*$', '')
|
||||
|
||||
local Shortcut = require(ROOT .. 'shortcut')
|
||||
local Cleaner = require(ROOT .. 'cleaner')
|
||||
|
||||
local Attribute = {}
|
||||
|
||||
@@ -161,8 +162,10 @@ Attribute.style = {}
|
||||
|
||||
function Attribute.style.set (widget, value)
|
||||
widget.attributes.style = value
|
||||
widget.fontData = nil
|
||||
widget.textData = nil
|
||||
-- Cleaner.mark(widget, 'fontData')
|
||||
-- Cleaner.mark(widget, 'textData')
|
||||
Cleaner.mark(widget, 'fontData')
|
||||
Cleaner.mark(widget, 'textData')
|
||||
widget.reshape(widget.parent or widget)
|
||||
end
|
||||
|
||||
@@ -291,7 +294,7 @@ Attribute.flow = {}
|
||||
|
||||
function Attribute.flow.set (widget, value)
|
||||
widget.attributes.flow = value
|
||||
widget.textData = nil
|
||||
Cleaner.mark(widget, 'textData')
|
||||
widget.reshape(widget.parent or widget)
|
||||
end
|
||||
|
||||
@@ -310,12 +313,13 @@ with this widget.
|
||||
Attribute.width = {}
|
||||
|
||||
function Attribute.width.set (widget, value)
|
||||
if value ~= 'auto' then
|
||||
-- value ~= 'auto' then
|
||||
if type(value) == 'number' then
|
||||
value = value and math.max(value, widget.minwidth or 0)
|
||||
end
|
||||
widget.attributes.width = value
|
||||
if widget.wrap then
|
||||
widget.textData = nil
|
||||
Cleaner.mark(widget, 'textData')
|
||||
end
|
||||
widget.reshape(widget.parent or widget)
|
||||
end
|
||||
@@ -398,8 +402,10 @@ this widget's `text`.
|
||||
Attribute.font = {}
|
||||
|
||||
local function resetFont (widget)
|
||||
rawset(widget, 'fontData', nil)
|
||||
rawset(widget, 'textData', nil)
|
||||
-- rawset(widget, 'fontData', nil)
|
||||
-- rawset(widget, 'textData', nil)
|
||||
Cleaner.mark(widget, 'fontData')
|
||||
Cleaner.mark(widget, 'textData')
|
||||
for _, child in ipairs(widget) do
|
||||
resetFont(child)
|
||||
end
|
||||
@@ -432,8 +438,8 @@ Attribute.size = {}
|
||||
|
||||
function Attribute.size.set (widget, value)
|
||||
widget.attributes.size = value
|
||||
widget.fontData = nil
|
||||
widget.textData = nil
|
||||
Cleaner.mark(widget, 'fontData')
|
||||
Cleaner.mark(widget, 'textData')
|
||||
end
|
||||
|
||||
Attribute.size.get = cascade
|
||||
@@ -456,7 +462,7 @@ Attribute.text = {}
|
||||
|
||||
function Attribute.text.set (widget, value)
|
||||
widget.attributes.text = value
|
||||
widget.textData = nil
|
||||
Cleaner.mark(widget, 'textData')
|
||||
end
|
||||
|
||||
--[[--
|
||||
@@ -472,7 +478,7 @@ Attribute.color = {}
|
||||
|
||||
function Attribute.color.set (widget, value)
|
||||
widget.attributes.color = value
|
||||
widget.textData = nil
|
||||
Cleaner.mark(widget, 'textData')
|
||||
end
|
||||
|
||||
Attribute.color.get = cascade
|
||||
@@ -494,7 +500,7 @@ Attribute.align = {}
|
||||
|
||||
function Attribute.align.set (widget, value)
|
||||
widget.attributes.align = value
|
||||
widget.textData = nil
|
||||
Cleaner.mark(widget, 'textData')
|
||||
end
|
||||
|
||||
Attribute.align.get = cascade
|
||||
@@ -514,11 +520,34 @@ Attribute.wrap = {}
|
||||
|
||||
function Attribute.wrap.set (widget, value)
|
||||
widget.attributes.wrap = value
|
||||
widget.textData = nil
|
||||
Cleaner.mark(widget, 'textData')
|
||||
end
|
||||
|
||||
Attribute.wrap.get = cascade
|
||||
|
||||
--[[--
|
||||
Text offset.
|
||||
|
||||
@attrib textOffset
|
||||
--]]--
|
||||
Attribute.textOffset = {}
|
||||
|
||||
function Attribute.textOffset.set (widget, value)
|
||||
widget.attributes.textOffset = value
|
||||
end
|
||||
|
||||
--[[--
|
||||
Icon offset.
|
||||
|
||||
@attrib iconOffset
|
||||
--]]--
|
||||
Attribute.iconOffset = {}
|
||||
|
||||
function Attribute.iconOffset.set (widget, value)
|
||||
widget.attributes.iconOffset = value
|
||||
end
|
||||
|
||||
|
||||
--[[--
|
||||
Visual Attributes.
|
||||
|
||||
@@ -563,7 +592,7 @@ Attribute.margin = {}
|
||||
|
||||
function Attribute.margin.set (widget, value)
|
||||
widget.attributes.margin = value
|
||||
widget.textData = nil
|
||||
Cleaner.mark(widget, 'textData')
|
||||
widget:reshape()
|
||||
end
|
||||
|
||||
@@ -580,7 +609,7 @@ Attribute.padding = {}
|
||||
|
||||
function Attribute.padding.set (widget, value)
|
||||
widget.attributes.padding = value
|
||||
widget.textData = nil
|
||||
Cleaner.mark(widget, 'textData')
|
||||
widget:reshape()
|
||||
end
|
||||
|
||||
@@ -595,7 +624,8 @@ Attribute.icon = {}
|
||||
|
||||
function Attribute.icon.set (widget, value)
|
||||
widget.attributes.icon = value
|
||||
widget.textData = nil
|
||||
Cleaner.mark(widget, 'textData')
|
||||
widget.iconData = nil
|
||||
end
|
||||
|
||||
|
||||
|
||||
32
luigi/cleaner.lua
Normal file
32
luigi/cleaner.lua
Normal file
@@ -0,0 +1,32 @@
|
||||
local Cleaner = {}
|
||||
|
||||
local marked = {}
|
||||
local watched = setmetatable({}, { __mode = 'k' })
|
||||
|
||||
function Cleaner.mark (t, key)
|
||||
local length = #marked
|
||||
local keys = watched[t]
|
||||
if not keys then
|
||||
keys = {}
|
||||
watched[t] = keys
|
||||
elseif keys[key] then
|
||||
return
|
||||
end
|
||||
keys[key] = true
|
||||
local i = length + 1
|
||||
marked[i] = t
|
||||
marked[i + 1] = key
|
||||
end
|
||||
|
||||
function Cleaner.clean ()
|
||||
for i = #marked - 1, 1, -2 do
|
||||
local t = marked[i]
|
||||
local key = marked[i + 1]
|
||||
t[key] = nil
|
||||
marked[i] = nil
|
||||
marked[i + 1] = nil
|
||||
watched[t][key] = nil
|
||||
end
|
||||
end
|
||||
|
||||
return Cleaner
|
||||
@@ -7,6 +7,7 @@ return function (config)
|
||||
local lineColor = config.lineColor or { 220, 220, 220 }
|
||||
local textColor = config.textColor or { 0, 0, 0 }
|
||||
local highlight = config.highlight or { 0x19, 0xAE, 0xFF }
|
||||
local spacing = config.spacing or 2
|
||||
|
||||
local button_pressed = resources .. 'button_pressed.png'
|
||||
local button_focused = resources .. 'button_focused.png'
|
||||
@@ -54,6 +55,14 @@ return function (config)
|
||||
return self.value and check_checked or check_unchecked
|
||||
end
|
||||
|
||||
local function getCheckTextOffset (self)
|
||||
local align = self.align or ''
|
||||
local icon = self:getIcon()
|
||||
if not icon then return { 0, 0 } end
|
||||
local width = icon:getWidth() + spacing * 2
|
||||
return { align:find 'right' and -width or width, 0 }
|
||||
end
|
||||
|
||||
local function getControlHeight (self)
|
||||
return self.flow == 'x' and self._defaultDimension
|
||||
end
|
||||
@@ -120,15 +129,14 @@ return function (config)
|
||||
width = getControlWidth,
|
||||
color = textColor,
|
||||
align = 'center middle',
|
||||
margin = 2,
|
||||
margin = spacing,
|
||||
color = textColor,
|
||||
solid = true,
|
||||
_defaultDimension = 36,
|
||||
},
|
||||
|
||||
Line = {
|
||||
margin = 0,
|
||||
padding = 4,
|
||||
margin = spacing + 2,
|
||||
align = 'left middle',
|
||||
_defaultDimension = 24,
|
||||
},
|
||||
@@ -145,6 +153,7 @@ return function (config)
|
||||
type = { 'Line', 'Control' },
|
||||
focusable = true,
|
||||
icon = getCheckIcon,
|
||||
textOffset = getCheckTextOffset,
|
||||
},
|
||||
label = {
|
||||
type = { 'Line', 'Control' },
|
||||
@@ -159,13 +168,13 @@ return function (config)
|
||||
icon = resources .. 'triangle_right.png',
|
||||
},
|
||||
['menu.item'] = {
|
||||
padding = 4,
|
||||
padding = spacing * 2,
|
||||
height = 24,
|
||||
align = 'left middle',
|
||||
background = getMenuItemBackground,
|
||||
},
|
||||
panel = {
|
||||
padding = 2,
|
||||
padding = spacing,
|
||||
background = backColor,
|
||||
color = textColor,
|
||||
solid = true,
|
||||
@@ -183,6 +192,7 @@ return function (config)
|
||||
type = { 'Line', 'Control' },
|
||||
focusable = true,
|
||||
icon = getRadioIcon,
|
||||
textOffset = getCheckTextOffset,
|
||||
},
|
||||
sash = {
|
||||
background = getSashBackground,
|
||||
|
||||
@@ -4,6 +4,7 @@ local Backend = require(ROOT .. 'backend')
|
||||
local Base = require(ROOT .. 'base')
|
||||
local Event = require(ROOT .. 'event')
|
||||
local Shortcut = require(ROOT .. 'shortcut')
|
||||
local Cleaner = require(ROOT .. 'cleaner')
|
||||
|
||||
local Input = Base:extend()
|
||||
|
||||
@@ -18,6 +19,7 @@ function Input:handleDisplay (layout)
|
||||
local root = layout.root
|
||||
if root then root:paint() end
|
||||
Event.Display:emit(layout)
|
||||
Cleaner.clean()
|
||||
end
|
||||
|
||||
function Input:handleKeyPress (layout, key, x, y)
|
||||
@@ -147,7 +149,10 @@ function Input:handlePressStart (layout, button, x, y, widget, shortcut)
|
||||
-- if hit then
|
||||
self.pressedWidgets[button] = widget
|
||||
self.passedWidgets[button] = widget
|
||||
widget.pressed[button] = true
|
||||
-- widget.pressed[button] = true
|
||||
for ancestor in widget:eachAncestor(true) do
|
||||
ancestor.pressed[button] = true
|
||||
end
|
||||
if button == 'left' then
|
||||
widget:focus()
|
||||
end
|
||||
@@ -167,7 +172,10 @@ function Input:handlePressEnd (layout, button, x, y, widget, shortcut)
|
||||
local hit, widget = checkHit(widget or layout:getWidgetAt(x, y), layout)
|
||||
local wasPressed = originWidget.pressed[button]
|
||||
if hit then
|
||||
originWidget.pressed[button] = nil
|
||||
-- originWidget.pressed[button] = nil
|
||||
for ancestor in originWidget:eachAncestor(true) do
|
||||
ancestor.pressed[button] = nil
|
||||
end
|
||||
end
|
||||
widget:bubbleEvent('PressEnd', {
|
||||
hit = hit,
|
||||
|
||||
@@ -22,6 +22,7 @@ local Event = require(ROOT .. 'event')
|
||||
local Widget = require(ROOT .. 'widget')
|
||||
local Input = require(ROOT .. 'input')
|
||||
local Style = require(ROOT .. 'style')
|
||||
local Cleaner = require(ROOT .. 'cleaner')
|
||||
|
||||
local Layout = Base:extend()
|
||||
|
||||
@@ -79,7 +80,7 @@ function Layout:createWidget (data)
|
||||
end
|
||||
|
||||
local function clearWidget (widget)
|
||||
widget.textData = nil
|
||||
Cleaner.mark(widget, 'textData')
|
||||
widget.fontData = nil
|
||||
widget.position = {}
|
||||
widget.dimensions = {}
|
||||
|
||||
@@ -8,7 +8,7 @@ local Text = Backend.Text
|
||||
|
||||
local Painter = Base:extend()
|
||||
|
||||
local imageCache = {}
|
||||
local imageCache = setmetatable({}, { __mode = 'v' })
|
||||
-- local sliceCache = {}
|
||||
|
||||
function Painter:constructor (widget)
|
||||
@@ -199,8 +199,70 @@ function Painter:paintIconAndText ()
|
||||
Backend.pop()
|
||||
end
|
||||
|
||||
|
||||
function Painter:paintText ()
|
||||
local widget = self.widget
|
||||
if not widget.text then return end
|
||||
|
||||
local align = widget.align
|
||||
local text = widget:getText()
|
||||
local x, y, w, h = widget:getRectangle(true, true)
|
||||
local offset = widget.textOffset
|
||||
local ox, oy = 0, 0
|
||||
if offset then
|
||||
ox, oy = offset[1] or 0, offset[2] or 0
|
||||
end
|
||||
|
||||
-- horizontal alignment for non-wrapped text
|
||||
if align:find 'right' then
|
||||
x = x + (w - text:getWidth())
|
||||
elseif align:find 'center' then
|
||||
x = x + (w - text:getWidth()) * 0.5
|
||||
end
|
||||
|
||||
if align:find 'middle' then
|
||||
local textHeight = text:getHeight()
|
||||
y = y + (h - textHeight) * 0.5
|
||||
elseif align:find 'bottom' then
|
||||
local textHeight = text:getHeight()
|
||||
y = y + h - textHeight
|
||||
end
|
||||
|
||||
local sx, sy = widget.scrollX or 0, widget.scrollY or 0
|
||||
Backend.draw(text, x + ox - sx, y + oy - sy)
|
||||
|
||||
-- widget.innerHeight = text:getHeight()
|
||||
-- widget.innerWidth = text:getWidth()
|
||||
end
|
||||
|
||||
function Painter:paintIcon ()
|
||||
local widget = self.widget
|
||||
if not widget.icon then return end
|
||||
|
||||
local align = widget.align
|
||||
local icon = widget:getIcon()
|
||||
local x, y, w, h = widget:getRectangle(true, true)
|
||||
|
||||
if align:find 'right' then
|
||||
x = x + (w - icon:getWidth())
|
||||
elseif align:find 'center' then
|
||||
x = x + (w - icon:getWidth()) * 0.5
|
||||
end
|
||||
|
||||
if align:find 'middle' then
|
||||
local iconHeight = icon:getHeight()
|
||||
y = y + (h - iconHeight) * 0.5
|
||||
elseif align:find 'bottom' then
|
||||
local iconHeight = icon:getHeight()
|
||||
y = y + h - iconHeight
|
||||
end
|
||||
|
||||
Backend.draw(icon, x, y)
|
||||
end
|
||||
|
||||
function Painter:paintChildren ()
|
||||
for i, child in ipairs(self.widget) do
|
||||
local widget = self.widget
|
||||
for i, child in ipairs(widget) do
|
||||
child:paint()
|
||||
end
|
||||
end
|
||||
@@ -225,7 +287,9 @@ function Painter:paint ()
|
||||
self:paintBackground()
|
||||
self:paintOutline()
|
||||
self:paintSlices()
|
||||
self:paintIconAndText()
|
||||
-- self:paintIconAndText()
|
||||
self:paintIcon()
|
||||
self:paintText()
|
||||
self:paintChildren()
|
||||
|
||||
Backend.pop()
|
||||
|
||||
@@ -11,7 +11,9 @@ local Backend = require(ROOT .. 'backend')
|
||||
local Event = require(ROOT .. 'event')
|
||||
local Attribute = require(ROOT .. 'attribute')
|
||||
local Painter = require(ROOT .. 'painter')
|
||||
local Cleaner = require(ROOT .. 'cleaner')
|
||||
local Font = Backend.Font
|
||||
local Text = Backend.Text
|
||||
|
||||
local Widget = {}
|
||||
|
||||
@@ -230,7 +232,7 @@ local function metaCall (Widget, layout, self)
|
||||
|
||||
for k, v in ipairs(self) do
|
||||
self[k] = v.isWidget and v or metaCall(Widget, self.layout, v)
|
||||
self[k].parent = self
|
||||
v.parent = self
|
||||
end
|
||||
|
||||
return self
|
||||
@@ -285,6 +287,10 @@ function Widget:bubbleEvent (eventName, data)
|
||||
data = data or {}
|
||||
data.target = self
|
||||
for ancestor in self:eachAncestor(true) do
|
||||
if ancestor ~= self and ancestor.unified then
|
||||
data.innerTarget = self
|
||||
return ancestor:bubbleEvent(eventName, data)
|
||||
end
|
||||
local result = event:emit(ancestor, data)
|
||||
if result ~= nil then return result end
|
||||
end
|
||||
@@ -400,6 +406,16 @@ function Widget:getPreviousNeighbor ()
|
||||
return layout.root
|
||||
end
|
||||
|
||||
function Widget:registerChild (data)
|
||||
local layout = self.layout
|
||||
local child = data and data.isWidget and data or Widget(layout, data or {})
|
||||
|
||||
child.parent = self
|
||||
child.layout = self.layout
|
||||
|
||||
return child
|
||||
end
|
||||
|
||||
--[[--
|
||||
Add a child to this widget.
|
||||
|
||||
@@ -410,12 +426,8 @@ A widget or definition table representing a widget.
|
||||
The newly added child widget.
|
||||
--]]--
|
||||
function Widget:addChild (data)
|
||||
local layout = self.layout
|
||||
local child = data and data.isWidget and data or Widget(layout, data or {})
|
||||
|
||||
local child = self:registerChild(data)
|
||||
self[#self + 1] = child
|
||||
child.parent = self
|
||||
child.layout = self.layout
|
||||
|
||||
return child
|
||||
end
|
||||
@@ -491,7 +503,6 @@ function Widget:calculateDimension (name)
|
||||
end
|
||||
end
|
||||
local size = (parentDimension - claimed) / unsized
|
||||
|
||||
size = math.max(size, min)
|
||||
self.dimensions[name] = size
|
||||
return size
|
||||
@@ -568,6 +579,14 @@ function Widget:calculateDimensionMinimum (name)
|
||||
end
|
||||
end
|
||||
|
||||
if not self.wrap then
|
||||
if name == 'width' then
|
||||
value = math.max(value, self:getText():getWidth())
|
||||
else
|
||||
value = math.max(value, self:getText():getHeight())
|
||||
end
|
||||
end
|
||||
|
||||
if value > 0 then
|
||||
local space = (self.margin or 0) * 2 + (self.padding or 0) * 2
|
||||
value = value + space
|
||||
@@ -636,7 +655,8 @@ function Widget:getContentWidth ()
|
||||
width = math.max(width, child:getWidth())
|
||||
end
|
||||
end
|
||||
return width
|
||||
-- return width
|
||||
return math.max(width, self:getText():getWidth())
|
||||
end
|
||||
|
||||
--[[--
|
||||
@@ -659,16 +679,65 @@ function Widget:getContentHeight ()
|
||||
height = math.max(height, child:getHeight())
|
||||
end
|
||||
end
|
||||
return height
|
||||
-- return height
|
||||
return math.max(height, self:getText():getHeight())
|
||||
end
|
||||
|
||||
local imageCache = setmetatable({}, { __mode = 'v' })
|
||||
|
||||
local function loadImage (path)
|
||||
local cached = imageCache[path]
|
||||
if not cached then
|
||||
cached = Backend.Image(path)
|
||||
imageCache[path] = cached
|
||||
end
|
||||
|
||||
return cached
|
||||
end
|
||||
|
||||
function Widget:getIcon ()
|
||||
if self.lastIcon ~= self.icon or not self.iconData then
|
||||
self.lastIcon = self.icon
|
||||
self.iconData = loadImage(self.icon)
|
||||
end
|
||||
return self.iconData
|
||||
end
|
||||
|
||||
function Widget:getFont ()
|
||||
if not self.fontData then
|
||||
self.fontData = Font(self.font, self.size)
|
||||
end
|
||||
if self.fontData then return self.fontData end
|
||||
self.fontData = Font(self.font, self.size)
|
||||
return self.fontData
|
||||
end
|
||||
|
||||
function Widget:getText ()
|
||||
if self.textData then return self.textData end
|
||||
|
||||
local font = self:getFont()
|
||||
|
||||
if self.wrap then
|
||||
-- horizontal alignment
|
||||
local align = self.align
|
||||
if align:find 'right' then
|
||||
align = 'right'
|
||||
elseif align:find 'center' then
|
||||
align = 'center'
|
||||
elseif align:find 'justify' then
|
||||
align = 'justify'
|
||||
else
|
||||
align = 'left'
|
||||
end
|
||||
-- wrap limit
|
||||
local x, y, w, h = self:getRectangle(true, true)
|
||||
local offset = self.textOffset and self.textOffset[1] or 0
|
||||
local limit = w - math.abs(offset)
|
||||
self.textData = Text(font, self.text or '', self.color, align, limit)
|
||||
else
|
||||
self.textData = Text(font, self.text or '', self.color)
|
||||
end
|
||||
|
||||
return self.textData
|
||||
end
|
||||
|
||||
--[[--
|
||||
Get x/y/width/height values describing a rectangle within the widget.
|
||||
|
||||
@@ -772,7 +841,7 @@ function Widget:reshape ()
|
||||
self.position = {}
|
||||
self.dimensions = {}
|
||||
|
||||
self.textData = nil
|
||||
Cleaner.mark(self, 'textData')
|
||||
|
||||
Event.Reshape:emit(self, { target = self })
|
||||
for _, child in ipairs(self) do
|
||||
|
||||
@@ -13,6 +13,7 @@ standard themes, the widget's value should be indicated in some other way.
|
||||
--]]--
|
||||
|
||||
return function (self)
|
||||
|
||||
self:onPress(function (event)
|
||||
if event.button ~= 'left' then return end
|
||||
self.value = not self.value
|
||||
|
||||
@@ -37,22 +37,10 @@ local function addLayoutChildren (self)
|
||||
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 font = child:getFont()
|
||||
local pad = child.padding or 0
|
||||
local tw = font:getAdvance(child[2].text)
|
||||
+ pad * 2 + childHeight
|
||||
local kw = font:getAdvance(child[3].text)
|
||||
+ pad * 2 + childHeight
|
||||
textWidth = math.max(textWidth, tw)
|
||||
keyWidth = math.max(keyWidth, kw)
|
||||
end
|
||||
end
|
||||
|
||||
root.height = height
|
||||
root.width = textWidth + keyWidth + (root.padding or 0)
|
||||
root.height = 'auto'
|
||||
root.width = 'auto'
|
||||
|
||||
local isSubmenu = self.parentMenu and self.parentMenu.parentMenu
|
||||
local w = isSubmenu and self:getWidth() or 0
|
||||
@@ -141,22 +129,20 @@ local function registerLayoutEvents (self)
|
||||
menuLayout:onPress(function (event)
|
||||
-- if event.button ~= 'left' then return end
|
||||
if not checkMouseButton(self, event) then return end
|
||||
for widget in event.target:eachAncestor(true) do
|
||||
if widget.type == 'menu.item' and #widget.items == 0 then
|
||||
menuLayout:hide()
|
||||
deactivateSiblings(self.rootMenu[1])
|
||||
end
|
||||
local widget = event.target
|
||||
if widget.type == 'menu.item' and #widget.items == 0 then
|
||||
menuLayout:hide()
|
||||
deactivateSiblings(self.rootMenu[1])
|
||||
end
|
||||
end)
|
||||
|
||||
menuLayout:onPressEnd(function (event)
|
||||
-- if event.button ~= 'left' then return end
|
||||
if not checkMouseButton(self, event) then return end
|
||||
for widget in event.target:eachAncestor(true) do
|
||||
if widget.type == 'menu.item' and #widget.items == 0
|
||||
and event.target ~= event.origin then
|
||||
widget:bubbleEvent('Press', event)
|
||||
end
|
||||
local widget = event.target
|
||||
if widget.type == 'menu.item' and #widget.items == 0
|
||||
and event.target ~= event.origin then
|
||||
widget:bubbleEvent('Press', event)
|
||||
end
|
||||
end)
|
||||
|
||||
@@ -164,12 +150,12 @@ local function registerLayoutEvents (self)
|
||||
menuLayout:onPressEnter(activate)
|
||||
end
|
||||
|
||||
local function nothing () end
|
||||
|
||||
local function initialize (self)
|
||||
local font = self:getFont()
|
||||
local pad = self.padding or 0
|
||||
local isSubmenu = self.parentMenu and self.parentMenu.parentMenu
|
||||
local text, shortcut, icon = self.text or '', self.shortcut or '', self.icon
|
||||
local textWidth = font:getAdvance(text) + pad * 2
|
||||
-- local textWidth = font:getAdvance(text) + pad * 2
|
||||
|
||||
if isSubmenu then
|
||||
local edgeType
|
||||
@@ -177,27 +163,36 @@ local function initialize (self)
|
||||
shortcut = ' '
|
||||
edgeType = 'menu.expander'
|
||||
else
|
||||
shortcut = Shortcut.stringify(shortcut)
|
||||
shortcut = ' ' .. Shortcut.stringify(shortcut)
|
||||
end
|
||||
self.unified = true
|
||||
self.height = 'auto' -- font:getLineHeight() + pad * 2
|
||||
self.flow = 'x'
|
||||
self:addChild { icon = icon, width = self.height }
|
||||
self:addChild { text = text, width = textWidth }
|
||||
self:addChild {
|
||||
width = function () return self:getHeight() end,
|
||||
icon = function () return self.icon end,
|
||||
align = 'middle left',
|
||||
}
|
||||
self:addChild {
|
||||
width = 'auto',
|
||||
text = function () return self.text end
|
||||
}
|
||||
self:addChild {
|
||||
type = edgeType,
|
||||
text = shortcut,
|
||||
align = 'middle right',
|
||||
minwidth = self.height,
|
||||
minwidth = function () return self:getHeight() end,
|
||||
color = function ()
|
||||
local c = self.color or { 0, 0, 0 }
|
||||
return { c[1], c[2], c[3], (c[4] or 256) / 2 }
|
||||
end
|
||||
}
|
||||
|
||||
self.icon = nil
|
||||
self.text = nil
|
||||
self.painter.paintText = nothing
|
||||
self.painter.paintIcon = nothing
|
||||
else
|
||||
-- top level menu
|
||||
self.width = textWidth + pad * 2
|
||||
-- self.width = textWidth
|
||||
self.width = 'auto'
|
||||
self.align = 'middle center'
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user