merge window into layout

This commit is contained in:
airstruck
2015-10-24 15:10:22 -04:00
parent e5124b670b
commit cc0ca8387b
8 changed files with 81 additions and 114 deletions

View File

@@ -104,12 +104,10 @@ layout:onMotion(function(event)
layout.statusbar.text = (w.id or '(unnamed)') .. ' ' .. layout.statusbar.text = (w.id or '(unnamed)') .. ' ' ..
w:getX() .. ', ' .. w:getY() .. ' | ' .. w:getX() .. ', ' .. w:getY() .. ' | ' ..
w:getWidth() .. 'x' .. w:getHeight() w:getWidth() .. 'x' .. w:getHeight()
layout.statusbar:update()
end) end)
layout.newButton:onMotion(function(event) layout.newButton:onMotion(function(event)
layout.statusbar.text = 'Create a new thing' layout.statusbar.text = 'Create a new thing'
layout.statusbar:update()
return false return false
end) end)

View File

@@ -45,8 +45,6 @@ function Input:handleMotion (x, y)
previousWidget.hovered = nil previousWidget.hovered = nil
end end
widget.hovered = true widget.hovered = true
-- self.layout:update()
widget:update()
end end
self:bubbleEvent('Motion', widget, { self:bubbleEvent('Motion', widget, {
target = widget, target = widget,
@@ -91,8 +89,6 @@ function Input:handlePressedMotion (x, y)
}) })
else else
originWidget.pressed = (widget == originWidget) or nil originWidget.pressed = (widget == originWidget) or nil
originWidget:update()
-- self.layout:update()
if passedWidget then if passedWidget then
self:bubbleEvent('PressLeave', passedWidget, { self:bubbleEvent('PressLeave', passedWidget, {
target = passedWidget, target = passedWidget,
@@ -118,8 +114,6 @@ end
function Input:handlePressStart (button, x, y) function Input:handlePressStart (button, x, y)
local widget = self.layout:getWidgetAt(x, y) local widget = self.layout:getWidgetAt(x, y)
widget.pressed = true widget.pressed = true
-- self.layout:update()
widget:update()
self.pressedWidgets[button] = widget self.pressedWidgets[button] = widget
self.passedWidgets[button] = widget self.passedWidgets[button] = widget
self:bubbleEvent('PressStart', widget, { self:bubbleEvent('PressStart', widget, {
@@ -132,8 +126,6 @@ function Input:handlePressEnd (button, x, y)
local widget = self.layout:getWidgetAt(x, y) local widget = self.layout:getWidgetAt(x, y)
local originWidget = self.pressedWidgets[button] local originWidget = self.pressedWidgets[button]
originWidget.pressed = nil originWidget.pressed = nil
-- self.layout:update()
originWidget:update()
self:bubbleEvent('PressEnd', widget, { self:bubbleEvent('PressEnd', widget, {
target = widget, target = widget,
origin = originWidget, origin = originWidget,

View File

@@ -2,10 +2,10 @@ local ROOT = (...):gsub('[^.]*$', '')
local Base = require(ROOT .. 'base') local Base = require(ROOT .. 'base')
local Event = require(ROOT .. 'event') local Event = require(ROOT .. 'event')
local Window = require(ROOT .. 'window')
local Widget = require(ROOT .. 'widget') local Widget = require(ROOT .. 'widget')
local Input = require(ROOT .. 'input') local Input = require(ROOT .. 'input')
local Style = require(ROOT .. 'style') local Style = require(ROOT .. 'style')
local Hooker = require(ROOT .. 'hooker')
local Layout = Base:extend() local Layout = Base:extend()
@@ -16,6 +16,10 @@ function Layout:constructor (data)
self.root = Widget.create(self, data or {}) self.root = Widget.create(self, data or {})
self:setStyle() self:setStyle()
self:setTheme() self:setTheme()
self.isMousePressed = false
self.isManagingInput = false
self.hooks = {}
end end
function Layout:setStyle (rules) function Layout:setStyle (rules)
@@ -40,20 +44,29 @@ function Layout:show ()
if not self.input then if not self.input then
self.input = Input(self) self.input = Input(self)
end end
if not self.window then
self.window = Window(self.input) local currentWidth, currentHeight, flags = love.window.getMode()
love.window.setMode(width or currentWidth, height or currentHeight, flags)
if title then
love.window.setTitle(title)
end end
self.window:show(width, height, title) self:manageInput(self.input)
end end
function Layout:hide () function Layout:hide ()
self.window:hide() if not self.isManagingInput then
return
end
self.isManagingInput = false
self:unhook()
end end
-- Update the display. Call this after you change widget properties -- Reflow the layout. Call this after you change widget positions/dimensions.
-- that affect display. function Layout:reflow (reshape)
function Layout:update (reshape) for i, widget in ipairs(self.widgets) do
self.window:update(reshape) widget.position = {}
widget.dimensions = {}
end
end end
-- Get the innermost widget at a position, within a root widget. -- Get the innermost widget at a position, within a root widget.
@@ -82,6 +95,51 @@ function Layout:addWidget (widget)
table.insert(self.widgets, widget) table.insert(self.widgets, widget)
end end
-- event stuff
function Layout:hook (key, method)
self.hooks[#self.hooks + 1] = Hooker.hook(key, method)
end
function Layout:unhook ()
for _, item in ipairs(self.hooks) do
Hooker.unhook(item)
end
self.hooks = {}
end
function Layout:manageInput (input)
if self.isManagingInput then
return
end
self.isManagingInput = true
self:hook('draw', function ()
input:handleDisplay()
end)
self:hook('resize', function (width, height)
return input:handleReshape(width, height)
end)
self:hook('mousepressed', function (x, y, button)
self.isMousePressed = true
return input:handlePressStart(button, x, y)
end)
self:hook('mousereleased', function (x, y, button)
self.isMousePressed = false
return input:handlePressEnd(button, x, y)
end)
self:hook('mousemoved', function (x, y, dx, dy)
if self.isMousePressed then
return input:handlePressedMotion(x, y)
else
return input:handleMotion(x, y)
end
end)
self:hook('keypressed', function (key, isRepeat)
return input:handleKeyboard(key, love.mouse.getX(), love.mouse.getY())
end)
end
-- event binders -- event binders
Event.injectBinders(Layout) Event.injectBinders(Layout)

View File

@@ -141,17 +141,18 @@ function Renderer:renderIconAndText (widget, window)
-- reposition icon and text for proper vertical alignment -- reposition icon and text for proper vertical alignment
if icon and text and align:find('center') then if icon and text and align:find('center') then
local iconHeight = icon:getHeight() local iconHeight = icon:getHeight()
local textHeight = font:getWrappedHeight(text)
local contentHeight = textHeight + padding + iconHeight
local offset = ((y2 - y1) - contentHeight) / 2
if align:find('middle') then if align:find('middle') then
local textHeight = font:getWrappedHeight(text)
local contentHeight = textHeight + padding + iconHeight
local offset = ((y2 - y1) - contentHeight) / 2
iconY = y1 + offset iconY = y1 + offset
textY = y1 + offset + padding + iconHeight textY = y1 + offset + padding + iconHeight
elseif align:find('top') then elseif align:find('top') then
iconY = y1 iconY = y1
textY = y1 + padding + iconHeight textY = y1 + padding + iconHeight
else -- if align:find('bottom') else -- if align:find('bottom')
local textHeight = font:getWrappedHeight(text)
textY = y2 - textHeight textY = y2 - textHeight
iconY = textY - padding - iconHeight iconY = textY - padding - iconHeight
end end

View File

@@ -232,8 +232,13 @@ function Widget:getAncestors (includeSelf)
end end
end end
function Widget:update () function Widget:reflow ()
self.layout:update() self.position = {}
self.dimensions = {}
for i, widget in ipairs(self.children) do
widget.position = {}
widget.dimensions = {}
end
end end
Event.injectBinders(Widget) Event.injectBinders(Widget)

View File

@@ -27,7 +27,9 @@ function Sash:constructor(layout, data)
nextSibling[dimension] - event[axis]) nextSibling[dimension] - event[axis])
end end
layout:update(true) prevSibling:reflow()
nextSibling:reflow()
self:reflow()
end) end)
end end

View File

@@ -16,7 +16,6 @@ function Slider:constructor(layout, data)
position = (event.x - x1) / (x2 - x1) position = (event.x - x1) / (x2 - x1)
if position < 0 then position = 0 end if position < 0 then position = 0 end
if position > 1 then position = 1 end if position > 1 then position = 1 end
self:update()
end) end)
self:onDisplay(function(event) self:onDisplay(function(event)

View File

@@ -1,88 +0,0 @@
local ROOT = (...):gsub('[^.]*$', '')
local Base = require(ROOT .. 'base')
local Hooker = require(ROOT .. 'hooker')
local Window = Base:extend()
local unpack = table.unpack or _G.unpack
function Window:constructor (input)
self.input = input
self.isMousePressed = false
self.isManagingInput = false
self.hooked = {}
self.hooks = {}
end
function Window:hook (key, method)
self.hooks[#self.hooks + 1] = Hooker.hook(key, method)
end
function Window:unhook ()
for _, item in ipairs(self.hooks) do
Hooker.unhook(item)
end
self.hooks = {}
end
function Window:manageInput (input)
if self.isManagingInput then
return
end
self.isManagingInput = true
self:hook('draw', function ()
input:handleDisplay()
end)
self:hook('resize', function (width, height)
return input:handleReshape(width, height)
end)
self:hook('mousepressed', function (x, y, button)
self.isMousePressed = true
return input:handlePressStart(button, x, y)
end)
self:hook('mousereleased', function (x, y, button)
self.isMousePressed = false
return input:handlePressEnd(button, x, y)
end)
self:hook('mousemoved', function (x, y, dx, dy)
if self.isMousePressed then
return input:handlePressedMotion(x, y)
else
return input:handleMotion(x, y)
end
end)
self:hook('keypressed', function (key, isRepeat)
return input:handleKeyboard(key, love.mouse.getX(), love.mouse.getY())
end)
end
function Window:show (width, height, title)
local currentWidth, currentHeight, flags = love.window.getMode()
love.window.setMode(width or currentWidth, height or currentHeight, flags)
if title then
love.window.setTitle(title)
end
self:manageInput(self.input)
end
function Window:hide ()
if not self.isManagingInput then
return
end
self.isManagingInput = false
self:unhook()
end
function Window:update (reshape)
if reshape then
for i, widget in ipairs(self.input.layout.widgets) do
widget.position = {}
widget.dimensions = {}
widget.fontData = nil
end
end
end
return Window