mirror of
https://github.com/airstruck/luigi.git
synced 2026-01-11 08:48:23 +00:00
minor bug fixes
This commit is contained in:
30
example/dialog/license.lua
Normal file
30
example/dialog/license.lua
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
return { type = 'submenu', width = 600, height = 400, float = true,
|
||||||
|
{ type = 'panel', text = 'License', height = 40, size = 24, align = 'middle center', },
|
||||||
|
{ wrap = true, margin = 4, text = [[
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015 airstruck
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
]] },
|
||||||
|
{ type = 'panel', flow = 'x', height = 40,
|
||||||
|
{},
|
||||||
|
{ type = 'button', text = 'Close', id = 'closeButton', width = 100, margin = 4 }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -55,9 +55,9 @@ local mainForm = { id = 'mainWindow', type = 'panel',
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ text = 'Help',
|
{ text = 'Help',
|
||||||
{ text = 'About Luigi', icon = 'icon/16px/Book.png', key = 'f1', },
|
{ id = 'about', text = 'About Luigi', icon = 'icon/16px/Book.png', key = 'f1', },
|
||||||
{ text = 'About Luigi Demo', icon = 'icon/16px/Book Red.png', key = 'f2' },
|
{ id = 'aboutDemo', text = 'About Luigi Demo', icon = 'icon/16px/Book Red.png', key = 'f2' },
|
||||||
{ text = 'Licenses', key = 'f3' },
|
{ id = 'license', text = 'License', key = 'f3' },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ type = 'panel', id = 'toolbar', style = 'toolbar', flow = 'x',
|
{ type = 'panel', id = 'toolbar', style = 'toolbar', flow = 'x',
|
||||||
@@ -192,6 +192,21 @@ layout.menuQuit:onPress(function (event) Backend.quit() end)
|
|||||||
|
|
||||||
layout.themeLight:onPress(function (event) Backend.quit() end)
|
layout.themeLight:onPress(function (event) Backend.quit() end)
|
||||||
|
|
||||||
|
-- license dialog
|
||||||
|
|
||||||
|
local licenseDialog = Layout(require 'dialog.license')
|
||||||
|
|
||||||
|
licenseDialog.closeButton:onPress(function()
|
||||||
|
licenseDialog:hide()
|
||||||
|
end)
|
||||||
|
|
||||||
|
layout.license:onPress(function()
|
||||||
|
licenseDialog:show()
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
-- show the main layout
|
||||||
|
|
||||||
layout:show()
|
layout:show()
|
||||||
|
|
||||||
Backend.run()
|
Backend.run() -- only needed when using ffisdl backend
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ ffi.gc(renderer, sdl.destroyRenderer)
|
|||||||
|
|
||||||
local Backend = {}
|
local Backend = {}
|
||||||
|
|
||||||
|
Backend.sdl = sdl
|
||||||
|
|
||||||
local callback = {
|
local callback = {
|
||||||
draw = function () end,
|
draw = function () end,
|
||||||
resize = function () end,
|
resize = function () end,
|
||||||
@@ -274,6 +276,9 @@ local stack = {}
|
|||||||
Backend.pop = function ()
|
Backend.pop = function ()
|
||||||
local history = stack[#stack]
|
local history = stack[#stack]
|
||||||
local color = history.color or { 0, 0, 0, 255 }
|
local color = history.color or { 0, 0, 0, 255 }
|
||||||
|
Backend.setColor(history.color or { 0, 0, 0, 255 })
|
||||||
|
Backend.sdl = sdl
|
||||||
|
|
||||||
sdl.setRenderDrawColor(renderer,
|
sdl.setRenderDrawColor(renderer,
|
||||||
color[1], color[2], color[3], color[4] or 255)
|
color[1], color[2], color[3], color[4] or 255)
|
||||||
sdl.renderSetClipRect(renderer, history.scissor) -- Backend.setScissor(history.scissor)
|
sdl.renderSetClipRect(renderer, history.scissor) -- Backend.setScissor(history.scissor)
|
||||||
|
|||||||
@@ -213,12 +213,14 @@ end
|
|||||||
function Input:handleReshape (layout, width, height)
|
function Input:handleReshape (layout, width, height)
|
||||||
local root = layout.root
|
local root = layout.root
|
||||||
|
|
||||||
Event.Reshape:emit(layout, { target = layout })
|
if root.float then
|
||||||
|
root:reshape()
|
||||||
if not root.float then
|
else
|
||||||
root.width = width
|
root.width = width
|
||||||
root.height = height
|
root.height = height
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Event.Reshape:emit(layout, { target = layout })
|
||||||
end
|
end
|
||||||
|
|
||||||
function Input:handleWheelMove (layout, x, y)
|
function Input:handleWheelMove (layout, x, y)
|
||||||
|
|||||||
@@ -215,19 +215,20 @@ Number of pixels from window's top edge.
|
|||||||
Widget to search within, defaults to layout root.
|
Widget to search within, defaults to layout root.
|
||||||
--]]--
|
--]]--
|
||||||
function Layout:getWidgetAt (x, y, root)
|
function Layout:getWidgetAt (x, y, root)
|
||||||
local widget = root or self.root
|
if not root then
|
||||||
|
root = self.root
|
||||||
|
end
|
||||||
-- Loop through in reverse, because siblings defined later in the tree
|
-- Loop through in reverse, because siblings defined later in the tree
|
||||||
-- will overdraw earlier siblings.
|
-- will overdraw earlier siblings.
|
||||||
local childCount = #widget
|
for i = #root, 1, -1 do
|
||||||
|
local child = root[i]
|
||||||
for i = childCount, 1, -1 do
|
if child:isAt(x, y) then
|
||||||
local child = widget[i]
|
local inner = self:getWidgetAt(x, y, child)
|
||||||
local inner = self:getWidgetAt(x, y, child)
|
if inner then return inner end
|
||||||
if inner then return inner end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if widget:isAt(x, y) then return widget end
|
if root:isAt(x, y) then return root end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Internal, called from Widget:new
|
-- Internal, called from Widget:new
|
||||||
@@ -325,6 +326,7 @@ function Layout:addDefaultHandlers ()
|
|||||||
end -- if widget.scroll
|
end -- if widget.scroll
|
||||||
end -- ancestor loop
|
end -- ancestor loop
|
||||||
end) -- wheel move
|
end) -- wheel move
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
Event.injectBinders(Layout)
|
Event.injectBinders(Layout)
|
||||||
|
|||||||
@@ -194,12 +194,8 @@ function Renderer:renderIconAndText (widget)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
Backend.push()
|
|
||||||
|
|
||||||
local parentY = widget.parent and widget.parent:getY() or 0
|
local parentY = widget.parent and widget.parent:getY() or 0
|
||||||
|
|
||||||
Backend.setScissor(x, math.max(y, parentY), w, h)
|
|
||||||
|
|
||||||
-- calculate position for icon and text based on alignment and padding
|
-- calculate position for icon and text based on alignment and padding
|
||||||
local iconX, iconY, x1, y1, x2, y2 = self:positionIcon(
|
local iconX, iconY, x1, y1, x2, y2 = self:positionIcon(
|
||||||
widget, x, y, x + w, y + h)
|
widget, x, y, x + w, y + h)
|
||||||
@@ -242,6 +238,9 @@ function Renderer:renderIconAndText (widget)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Backend.push()
|
||||||
|
Backend.setScissor(x, math.max(y, parentY), w, h)
|
||||||
|
|
||||||
-- draw the icon
|
-- draw the icon
|
||||||
if icon then
|
if icon then
|
||||||
iconX, iconY = math.floor(iconX), math.floor(iconY)
|
iconX, iconY = math.floor(iconX), math.floor(iconY)
|
||||||
@@ -252,7 +251,7 @@ function Renderer:renderIconAndText (widget)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- draw the text
|
-- draw the text
|
||||||
if text and w > 1 then
|
if text and textX and textY and w > 1 then
|
||||||
textX, textY = math.floor(textX), math.floor(textY)
|
textX, textY = math.floor(textX), math.floor(textY)
|
||||||
Backend.draw(widget.textData, textX, textY)
|
Backend.draw(widget.textData, textX, textY)
|
||||||
end
|
end
|
||||||
|
|||||||
Binary file not shown.
@@ -351,6 +351,28 @@ function Widget:calculateDimension (name)
|
|||||||
return size
|
return size
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function calculateRootPosition (self, axis)
|
||||||
|
local value = (axis == 'x' and self.left) or (axis == 'y' and self.top)
|
||||||
|
|
||||||
|
if value then
|
||||||
|
self.position[axis] = value
|
||||||
|
return value
|
||||||
|
end
|
||||||
|
|
||||||
|
local ww, wh = Backend.getWindowSize()
|
||||||
|
|
||||||
|
if axis == 'x' and self.width then
|
||||||
|
value = (ww - self.width) / 2
|
||||||
|
elseif axis == 'y' and self.height then
|
||||||
|
value = (wh - self.height) / 2
|
||||||
|
else
|
||||||
|
value = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
self.position[axis] = value
|
||||||
|
return value
|
||||||
|
end
|
||||||
|
|
||||||
function Widget:calculatePosition (axis)
|
function Widget:calculatePosition (axis)
|
||||||
checkReshape(self)
|
checkReshape(self)
|
||||||
|
|
||||||
@@ -360,10 +382,8 @@ function Widget:calculatePosition (axis)
|
|||||||
local parent = self.parent
|
local parent = self.parent
|
||||||
local scroll = 0
|
local scroll = 0
|
||||||
if not parent then
|
if not parent then
|
||||||
self.position[axis] = axis == 'x' and (self.left or 0)
|
return calculateRootPosition(self, axis)
|
||||||
or axis == 'y' and (self.top or 0)
|
else
|
||||||
return self.position[axis]
|
|
||||||
elseif parent then
|
|
||||||
scroll = axis == 'x' and (parent.scrollX or 0)
|
scroll = axis == 'x' and (parent.scrollX or 0)
|
||||||
or axis == 'y' and (parent.scrollY or 0)
|
or axis == 'y' and (parent.scrollY or 0)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -123,6 +123,25 @@ local function registerLayoutEvents (self)
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
menuLayout:onPress(function (event)
|
||||||
|
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
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
menuLayout:onPressEnd(function (event)
|
||||||
|
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
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
menuLayout:onEnter(activate)
|
menuLayout:onEnter(activate)
|
||||||
menuLayout:onPressEnter(activate)
|
menuLayout:onPressEnter(activate)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -200,6 +200,20 @@ return function (self)
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
self:onKeyPress(function (event)
|
self:onKeyPress(function (event)
|
||||||
|
|
||||||
|
-- ignore tabs (keyboard navigation)
|
||||||
|
if event.key == 'tab' then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- focus next widget on enter (keyboard navigation)
|
||||||
|
if event.key == 'return' then
|
||||||
|
self.layout:focusNextWidget()
|
||||||
|
-- if the next widget is a button, allow the event to propagate
|
||||||
|
-- so that the button is pressed (TODO: is this a good idea?)
|
||||||
|
return self.layout.focusedWidget.type ~= 'button' or nil
|
||||||
|
end
|
||||||
|
|
||||||
if event.key == 'backspace' then
|
if event.key == 'backspace' then
|
||||||
|
|
||||||
if not deleteRange(self) then
|
if not deleteRange(self) then
|
||||||
|
|||||||
Reference in New Issue
Block a user