minor improvements
@@ -264,7 +264,9 @@ with this widget.
|
||||
Attribute.width = {}
|
||||
|
||||
function Attribute.width.set (widget, value)
|
||||
value = value and math.max(value, widget.minwidth or 0)
|
||||
if value ~= 'auto' then
|
||||
value = value and math.max(value, widget.minwidth or 0)
|
||||
end
|
||||
widget.attributes.width = value
|
||||
if widget.wrap then
|
||||
widget.textData = nil
|
||||
@@ -453,6 +455,8 @@ Should contain `true` for multiline text, or `false` or `nil`
|
||||
for a single line. Even text containing line breaks will display
|
||||
as a single line when this attribute is not set to `true`.
|
||||
|
||||
- This attribute cascades.
|
||||
|
||||
@attrib wrap
|
||||
--]]--
|
||||
Attribute.wrap = {}
|
||||
@@ -462,6 +466,10 @@ function Attribute.wrap.set (widget, value)
|
||||
widget.textData = nil
|
||||
end
|
||||
|
||||
function Attribute.wrap.get (widget)
|
||||
return widget.attributes.wrap or widget.parent and widget.parent.wrap
|
||||
end
|
||||
|
||||
--[[--
|
||||
Visual Attributes.
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@ end
|
||||
|
||||
ffi.gc(renderer, sdl.destroyRenderer)
|
||||
|
||||
sdl.setRenderDrawBlendMode(renderer, sdl.BLENDMODE_BLEND)
|
||||
|
||||
local Backend = {}
|
||||
|
||||
Backend.sdl = sdl
|
||||
|
||||
@@ -3,12 +3,14 @@ local Multiline = {}
|
||||
function Multiline.wrap (font, text, limit)
|
||||
local lines = {{ width = 0 }}
|
||||
local advance = 0
|
||||
local lastSpaceAdvance = 0
|
||||
|
||||
local function append (word, space)
|
||||
local wordAdvance = font:getAdvance(word)
|
||||
local spaceAdvance = font:getAdvance(space)
|
||||
local words = lines[#lines]
|
||||
if advance + wordAdvance > limit then
|
||||
words.width = (words.width or 0) - lastSpaceAdvance
|
||||
advance = wordAdvance + spaceAdvance
|
||||
lines[#lines + 1] = { width = advance, word, space }
|
||||
else
|
||||
@@ -17,6 +19,7 @@ function Multiline.wrap (font, text, limit)
|
||||
words[#words + 1] = word
|
||||
words[#words + 1] = space
|
||||
end
|
||||
lastSpaceAdvance = spaceAdvance
|
||||
end
|
||||
|
||||
local function appendFrag (frag, isFirst)
|
||||
|
||||
|
Before Width: | Height: | Size: 891 B After Width: | Height: | Size: 768 B |
BIN
luigi/theme/dark/triangle_down.png
Normal file
|
After Width: | Height: | Size: 188 B |
BIN
luigi/theme/dark/triangle_up.png
Normal file
|
After Width: | Height: | Size: 185 B |
@@ -62,6 +62,16 @@ return function (config)
|
||||
return self.parent and self.parent.flow == 'x' and 4
|
||||
end
|
||||
|
||||
local function getStepperBeforeIcon (self)
|
||||
return self.parent.flow == 'x' and resources .. 'triangle_left.png'
|
||||
or resources .. 'triangle_up.png'
|
||||
end
|
||||
|
||||
local function getStepperAfterIcon (self)
|
||||
return self.parent.flow == 'x' and resources .. 'triangle_right.png'
|
||||
or resources .. 'triangle_down.png'
|
||||
end
|
||||
|
||||
local function getTextSlices (self)
|
||||
return self.focused and resources .. 'text_focused.png'
|
||||
or resources .. 'text.png'
|
||||
@@ -73,36 +83,40 @@ return function (config)
|
||||
height = getControlHeight,
|
||||
width = getControlWidth,
|
||||
color = textColor,
|
||||
minheight = 28,
|
||||
minwidth = 28,
|
||||
minheight = 36,
|
||||
minwidth = 36,
|
||||
align = 'center middle',
|
||||
margin = 2,
|
||||
color = textColor,
|
||||
},
|
||||
button = {
|
||||
type = 'control',
|
||||
padding = 6,
|
||||
slices = getButtonSlices,
|
||||
minwidth = 24,
|
||||
minheight = 24,
|
||||
focusable = true,
|
||||
color = textColor,
|
||||
},
|
||||
check = {
|
||||
type = 'control',
|
||||
focusable = true,
|
||||
color = textColor,
|
||||
icon = getCheckOrRadioIcon,
|
||||
margin = 0,
|
||||
padding = 4,
|
||||
align = 'left middle',
|
||||
minheight = 24,
|
||||
},
|
||||
label = {
|
||||
type = 'control',
|
||||
background = backColor,
|
||||
padding = 4,
|
||||
align = 'left bottom',
|
||||
height = 14,
|
||||
margin = 0,
|
||||
padding = 4,
|
||||
minheight = 24,
|
||||
height = 24,
|
||||
},
|
||||
menu = {
|
||||
flow = 'x',
|
||||
height = 24,
|
||||
background = backColor,
|
||||
color = textColor,
|
||||
},
|
||||
['menu.expander'] = {
|
||||
icon = resources .. 'triangle_right.png',
|
||||
@@ -110,31 +124,31 @@ return function (config)
|
||||
['menu.item'] = {
|
||||
padding = 4,
|
||||
align = 'left middle',
|
||||
color = textColor,
|
||||
background = getMenuItemBackground,
|
||||
},
|
||||
panel = {
|
||||
padding = 2,
|
||||
background = backColor,
|
||||
color = textColor,
|
||||
},
|
||||
progress = {
|
||||
type = 'control',
|
||||
slices = resources .. 'button_pressed.png',
|
||||
padding = 0,
|
||||
},
|
||||
['progress.bar'] = {
|
||||
type = 'control',
|
||||
slices = resources .. 'progress.png',
|
||||
padding = 0,
|
||||
minwidth = 12,
|
||||
minheight= 22,
|
||||
},
|
||||
radio = {
|
||||
type = 'control',
|
||||
focusable = true,
|
||||
color = textColor,
|
||||
icon = getCheckOrRadioIcon,
|
||||
margin = 0,
|
||||
padding = 4,
|
||||
align = 'left middle',
|
||||
minheight = 24,
|
||||
},
|
||||
sash = {
|
||||
background = getSashBackground,
|
||||
@@ -144,10 +158,17 @@ return function (config)
|
||||
slider = {
|
||||
type = 'control',
|
||||
slices = resources .. 'button_pressed.png',
|
||||
padding = 0,
|
||||
},
|
||||
['slider.thumb'] = {
|
||||
type = 'button',
|
||||
align = 'middle center',
|
||||
margin = 0,
|
||||
minwidth = 32,
|
||||
minheight = 32,
|
||||
},
|
||||
status = {
|
||||
type = 'panel',
|
||||
background = backColor,
|
||||
color = textColor,
|
||||
align = 'left middle',
|
||||
padding = 4,
|
||||
height = 22,
|
||||
@@ -156,17 +177,26 @@ return function (config)
|
||||
type = 'control',
|
||||
slices = resources .. 'button_pressed.png',
|
||||
},
|
||||
['stepper.after'] = {
|
||||
type = 'button',
|
||||
icon = getStepperAfterIcon,
|
||||
margin = 0,
|
||||
minwidth = 32,
|
||||
minheight = 32,
|
||||
},
|
||||
['stepper.before'] = {
|
||||
type = 'button',
|
||||
icon = getStepperBeforeIcon,
|
||||
margin = 0,
|
||||
minwidth = 32,
|
||||
minheight = 32,
|
||||
},
|
||||
['stepper.item'] = {
|
||||
align = 'center middle',
|
||||
color = textColor,
|
||||
},
|
||||
['stepper.left'] = {
|
||||
type = 'button',
|
||||
icon = resources .. 'triangle_left.png',
|
||||
},
|
||||
['stepper.right'] = {
|
||||
type = 'button',
|
||||
icon = resources .. 'triangle_right.png',
|
||||
['stepper.view'] = {
|
||||
margin = 4,
|
||||
},
|
||||
submenu = {
|
||||
padding = 10,
|
||||
|
||||
|
Before Width: | Height: | Size: 895 B After Width: | Height: | Size: 786 B |
BIN
luigi/theme/light/triangle_down.png
Normal file
|
After Width: | Height: | Size: 188 B |
BIN
luigi/theme/light/triangle_up.png
Normal file
|
After Width: | Height: | Size: 185 B |
@@ -302,24 +302,31 @@ end
|
||||
function Widget:calculateDimension (name)
|
||||
checkReshape(self)
|
||||
|
||||
-- If dimensions are already calculated, return them.
|
||||
if self.dimensions[name] then
|
||||
return self.dimensions[name]
|
||||
end
|
||||
|
||||
-- Get minimum width/height from attributes.
|
||||
local min = (name == 'width') and (self.minwidth or 0)
|
||||
or (self.minheight or 0)
|
||||
|
||||
-- If width/height attribute is found (in widget, style or theme)
|
||||
if self[name] then
|
||||
-- and if width/height is "auto" then shrink to fit content
|
||||
if self[name] == 'auto' then
|
||||
self.dimensions[name] = self:calculateDimensionMinimum(name)
|
||||
return self.dimensions[name]
|
||||
end
|
||||
-- else width/height should be a number; use that value,
|
||||
-- clamped to minimum.
|
||||
self.dimensions[name] = math.max(self[name], min)
|
||||
return self.dimensions[name]
|
||||
end
|
||||
|
||||
-- If the widget is a layout root (and has no width/height),
|
||||
-- it's the same size as the window.
|
||||
local parent = self.parent
|
||||
|
||||
if not parent then
|
||||
local windowWidth, windowHeight = Backend.getWindowSize()
|
||||
local size = name == 'width' and windowWidth or windowHeight
|
||||
@@ -327,15 +334,24 @@ function Widget:calculateDimension (name)
|
||||
return self.dimensions[name]
|
||||
end
|
||||
|
||||
-- Widgets expand to fit their parents when no width/height is specified.
|
||||
local parentDimension = parent:calculateDimension(name)
|
||||
parentDimension = parentDimension - (parent.margin or 0) * 2
|
||||
parentDimension = parentDimension - (parent.padding or 0) * 2
|
||||
|
||||
-- If the dimension is in the opposite direction of the parent flow
|
||||
-- (for example if parent.flow is 'x' and the dimension is 'height'),
|
||||
-- then return the parent dimension.
|
||||
local parentFlow = parent.flow or 'y'
|
||||
if (parentFlow ~= 'x' and name == 'width')
|
||||
or (parentFlow == 'x' and name == 'height') then
|
||||
self.dimensions[name] = math.max(parentDimension, min)
|
||||
return self.dimensions[name]
|
||||
end
|
||||
|
||||
-- If the dimension is in the same direction as the parent flow
|
||||
-- (for example if parent.flow is 'x' and the dimension is 'width'),
|
||||
-- then return an equal portion of the unclaimed space in the parent.
|
||||
local claimed = 0
|
||||
local unsized = 1
|
||||
for i, widget in ipairs(self.parent) do
|
||||
@@ -399,9 +415,7 @@ function Widget:calculatePosition (axis)
|
||||
or axis ~= 'x' and (parent.scrollY or 0)
|
||||
end
|
||||
local parentPos = parent:calculatePosition(axis)
|
||||
local p = parentPos - scroll
|
||||
p = p + (parent.margin or 0)
|
||||
p = p + (parent.padding or 0)
|
||||
local p = parentPos - scroll + (parent.margin or 0) + (parent.padding or 0)
|
||||
local parentFlow = parent.flow or 'y'
|
||||
for i, widget in ipairs(parent) do
|
||||
if widget == self then
|
||||
|
||||
@@ -32,8 +32,12 @@ local function setDimension (widget, name, size)
|
||||
local parentDimension = widget.parent:calculateDimension(name)
|
||||
local claimed = 0
|
||||
for i, sibling in ipairs(widget.parent) do
|
||||
if sibling ~= widget and sibling[name] then
|
||||
claimed = claimed + sibling[name]
|
||||
local value = sibling[name]
|
||||
if sibling ~= widget and value then
|
||||
if value == 'auto' then
|
||||
value = sibling:calculateDimensionMinimum(name)
|
||||
end
|
||||
claimed = claimed + value
|
||||
end
|
||||
end
|
||||
if claimed + size > parentDimension then
|
||||
@@ -71,11 +75,13 @@ return function (self)
|
||||
local prevSize = prevSibling and prevSibling[dimension]
|
||||
local nextSize = nextSibling and nextSibling[dimension]
|
||||
|
||||
if prevSize then
|
||||
if prevSize or not nextSize then
|
||||
setDimension(prevSibling, dimension,
|
||||
event[axis] - prevSibling:calculatePosition(axis))
|
||||
end
|
||||
if nextSize then
|
||||
elseif nextSize then
|
||||
if nextSize == 'auto' then
|
||||
nextSize = nextSibling:calculateDimensionMinimum(dimension)
|
||||
end
|
||||
setDimension(nextSibling, dimension,
|
||||
nextSibling:calculatePosition(axis) + nextSize - event[axis])
|
||||
end
|
||||
|
||||
@@ -12,15 +12,13 @@ return function (self)
|
||||
return value < 0 and 0 or value > 1 and 1 or value
|
||||
end
|
||||
|
||||
self.value = clamp(self.value or 0.5)
|
||||
self.value = clamp(self.value or 0)
|
||||
self.step = self.step or 0.01
|
||||
|
||||
local spacer = self:addChild()
|
||||
|
||||
local thumb = self:addChild {
|
||||
type = 'button',
|
||||
align = 'middle center',
|
||||
margin = 0,
|
||||
type = 'slider.thumb',
|
||||
}
|
||||
|
||||
local function unpress ()
|
||||
|
||||
@@ -21,9 +21,9 @@ return function (self)
|
||||
self[index] = nil
|
||||
end
|
||||
|
||||
local before = self:addChild { type = 'stepper.left' }
|
||||
local view = self:addChild()
|
||||
local after = self:addChild { type = 'stepper.right' }
|
||||
local before = self:addChild { type = 'stepper.before' }
|
||||
local view = self:addChild { type = 'stepper.view' }
|
||||
local after = self:addChild { type = 'stepper.after' }
|
||||
|
||||
self:onReshape(function (event)
|
||||
if self.flow == 'x' then
|
||||
|
||||
@@ -182,7 +182,7 @@ return function (self)
|
||||
self.fontData = Backend.Font(self.font, self.size)
|
||||
end
|
||||
|
||||
self.value = self.value or self.text or ''
|
||||
self.value = tostring(self.value or self.text or '')
|
||||
|
||||
self.text = ''
|
||||
|
||||
|
||||