mirror of
https://github.com/airstruck/luigi.git
synced 2025-11-18 12:25:06 +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 = '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' },
|
||||
{ id = 'about', text = 'About Luigi', icon = 'icon/16px/Book.png', key = 'f1', },
|
||||
{ id = 'aboutDemo', text = 'About Luigi Demo', icon = 'icon/16px/Book Red.png', key = 'f2' },
|
||||
{ id = 'license', text = 'License', key = 'f3' },
|
||||
},
|
||||
},
|
||||
{ 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)
|
||||
|
||||
-- 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()
|
||||
|
||||
Backend.run()
|
||||
Backend.run() -- only needed when using ffisdl backend
|
||||
|
||||
@@ -38,6 +38,8 @@ ffi.gc(renderer, sdl.destroyRenderer)
|
||||
|
||||
local Backend = {}
|
||||
|
||||
Backend.sdl = sdl
|
||||
|
||||
local callback = {
|
||||
draw = function () end,
|
||||
resize = function () end,
|
||||
@@ -274,6 +276,9 @@ local stack = {}
|
||||
Backend.pop = function ()
|
||||
local history = stack[#stack]
|
||||
local color = history.color or { 0, 0, 0, 255 }
|
||||
Backend.setColor(history.color or { 0, 0, 0, 255 })
|
||||
Backend.sdl = sdl
|
||||
|
||||
sdl.setRenderDrawColor(renderer,
|
||||
color[1], color[2], color[3], color[4] or 255)
|
||||
sdl.renderSetClipRect(renderer, history.scissor) -- Backend.setScissor(history.scissor)
|
||||
|
||||
@@ -213,12 +213,14 @@ end
|
||||
function Input:handleReshape (layout, width, height)
|
||||
local root = layout.root
|
||||
|
||||
Event.Reshape:emit(layout, { target = layout })
|
||||
|
||||
if not root.float then
|
||||
if root.float then
|
||||
root:reshape()
|
||||
else
|
||||
root.width = width
|
||||
root.height = height
|
||||
end
|
||||
|
||||
Event.Reshape:emit(layout, { target = layout })
|
||||
end
|
||||
|
||||
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.
|
||||
--]]--
|
||||
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
|
||||
-- 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
|
||||
for i = #root, 1, -1 do
|
||||
local child = root[i]
|
||||
if child:isAt(x, y) then
|
||||
local inner = self:getWidgetAt(x, y, child)
|
||||
if inner then return inner end
|
||||
end
|
||||
end
|
||||
|
||||
if widget:isAt(x, y) then return widget end
|
||||
if root:isAt(x, y) then return root end
|
||||
end
|
||||
|
||||
-- Internal, called from Widget:new
|
||||
@@ -325,6 +326,7 @@ function Layout:addDefaultHandlers ()
|
||||
end -- if widget.scroll
|
||||
end -- ancestor loop
|
||||
end) -- wheel move
|
||||
|
||||
end
|
||||
|
||||
Event.injectBinders(Layout)
|
||||
|
||||
@@ -194,12 +194,8 @@ function Renderer:renderIconAndText (widget)
|
||||
return
|
||||
end
|
||||
|
||||
Backend.push()
|
||||
|
||||
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
|
||||
local iconX, iconY, x1, y1, x2, y2 = self:positionIcon(
|
||||
widget, x, y, x + w, y + h)
|
||||
@@ -242,6 +238,9 @@ function Renderer:renderIconAndText (widget)
|
||||
end
|
||||
end
|
||||
|
||||
Backend.push()
|
||||
Backend.setScissor(x, math.max(y, parentY), w, h)
|
||||
|
||||
-- draw the icon
|
||||
if icon then
|
||||
iconX, iconY = math.floor(iconX), math.floor(iconY)
|
||||
@@ -252,7 +251,7 @@ function Renderer:renderIconAndText (widget)
|
||||
end
|
||||
|
||||
-- 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)
|
||||
Backend.draw(widget.textData, textX, textY)
|
||||
end
|
||||
|
||||
Binary file not shown.
@@ -351,6 +351,28 @@ function Widget:calculateDimension (name)
|
||||
return size
|
||||
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)
|
||||
checkReshape(self)
|
||||
|
||||
@@ -360,10 +382,8 @@ function Widget:calculatePosition (axis)
|
||||
local parent = self.parent
|
||||
local scroll = 0
|
||||
if not parent then
|
||||
self.position[axis] = axis == 'x' and (self.left or 0)
|
||||
or axis == 'y' and (self.top or 0)
|
||||
return self.position[axis]
|
||||
elseif parent then
|
||||
return calculateRootPosition(self, axis)
|
||||
else
|
||||
scroll = axis == 'x' and (parent.scrollX or 0)
|
||||
or axis == 'y' and (parent.scrollY or 0)
|
||||
end
|
||||
|
||||
@@ -123,6 +123,25 @@ local function registerLayoutEvents (self)
|
||||
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:onPressEnter(activate)
|
||||
end
|
||||
|
||||
@@ -200,6 +200,20 @@ return function (self)
|
||||
end)
|
||||
|
||||
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 not deleteRange(self) then
|
||||
|
||||
Reference in New Issue
Block a user