fixed window element, better logging, improved click handling

This commit is contained in:
Paul Liverman III 2017-05-10 02:25:47 -07:00
parent 5089a87fe6
commit 8182d904db
10 changed files with 92 additions and 41 deletions

View File

@ -75,7 +75,9 @@ do
self.data = nil self.data = nil
end end
_class_0.__parent.__init(self, self.parent, self.data) _class_0.__parent.__init(self, self.parent, self.data)
self.data.type = "box" if self.data.type == "element" then
self.data.type = "box"
end
if not (self.data.background) then if not (self.data.background) then
self.data.background = background self.data.background = background
end end

View File

@ -19,7 +19,7 @@ class box extends element
super @parent, @data super @parent, @data
@data.type = "box" @data.type = "box" if @data.type == "element"
@data.background = background unless @data.background @data.background = background unless @data.background
draw: => draw: =>

View File

@ -59,7 +59,9 @@ do
fontFile = text fontFile = text
text = "" text = ""
end end
self.data.type = "text" if self.data.type == "element" then
self.data.type = "text"
end
if not (self.data.text) then if not (self.data.text) then
self.data.text = text self.data.text = text
end end

View File

@ -18,7 +18,7 @@ class text extends element
fontFile = text fontFile = text
text = "" text = ""
@data.type = "text" @data.type = "text" if @data.type == "element"
@data.text = text unless @data.text @data.text = text unless @data.text
@data.fontFile = fontFile unless @data.fontFile @data.fontFile = fontFile unless @data.fontFile
@data.fontSize = fontSize unless @data.fontSize @data.fontSize = fontSize unless @data.fontSize

View File

@ -92,9 +92,9 @@ do
end, end,
maximize = function(self) maximize = function(self)
if self.data.maximized then if self.data.maximized then
self.data.x = self.data.previous.x
self.data.y = self.data.previous.y
self:setSize(self.data.previous.w, self.data.previous.h) self:setSize(self.data.previous.w, self.data.previous.h)
self:align()
self:move(self.data.previous.x - self.data.x, self.data.previous.y - self.data.y)
else else
self.data.previous.x = self.data.x self.data.previous.x = self.data.x
self.data.previous.y = self.data.y self.data.previous.y = self.data.y
@ -104,9 +104,9 @@ do
self.data.y = self.parent.data.y self.data.y = self.parent.data.y
self:setSize(self.parent.data.w, self.parent.data.h) self:setSize(self.parent.data.w, self.parent.data.h)
table.insert(self.parent.child, table.remove(self.parent.child, self.parent:indexOf(self))) table.insert(self.parent.child, table.remove(self.parent.child, self.parent:indexOf(self)))
self:align()
end end
self.data.maximized = not self.data.maximized self.data.maximized = not self.data.maximized
self:align()
return self return self
end, end,
minimize = function(self) minimize = function(self)
@ -129,7 +129,9 @@ do
end end
self.parent, self.data = parent, data self.parent, self.data = parent, data
_class_0.__parent.__init(self, self.parent, self.data) _class_0.__parent.__init(self, self.parent, self.data)
self.data.type = "window" if self.data.type == "element" then
self.data.type = "window"
end
if not (self.data.w > 0) then if not (self.data.w > 0) then
self.data.w = 100 self.data.w = 100
end end
@ -152,14 +154,17 @@ do
if not (self.data.previous) then if not (self.data.previous) then
self.data.previous = { } self.data.previous = { }
end end
self.header = pop.box(self, self.data.titleBackground or { self.header = pop.box(self, {
type = "box (window header)"
}, self.data.titleBackground or {
25, 25,
180, 180,
230, 230,
255 255
}) })
self.title = pop.text(self.header, { self.title = pop.text(self.header, {
horizontal = "center" horizontal = "center",
type = "text (window title)"
}, title, self.data.titleColor or { }, title, self.data.titleColor or {
255, 255,
255, 255,
@ -167,7 +172,8 @@ do
255 255
}) })
self.window_area = pop.box(self, { self.window_area = pop.box(self, {
padding = 5 padding = 5,
type = "box (window area)"
}, self.data.windowBackground or { }, self.data.windowBackground or {
200, 200,
200, 200,
@ -180,7 +186,8 @@ do
self.closeButton = pop.box(self, { self.closeButton = pop.box(self, {
w = buttonSize, w = buttonSize,
h = buttonSize, h = buttonSize,
horizontalMargin = self.data.header_width_reduction horizontalMargin = self.data.header_width_reduction,
type = "box (window close button)"
}, closeImage):align("right") }, closeImage):align("right")
self.closeButton.clicked = function(self, x, y, button) self.closeButton.clicked = function(self, x, y, button)
if button == pop.constants.left_mouse then if button == pop.constants.left_mouse then
@ -193,7 +200,8 @@ do
self.maximizeButton = pop.box(self, { self.maximizeButton = pop.box(self, {
w = buttonSize, w = buttonSize,
h = buttonSize, h = buttonSize,
horizontalMargin = self.data.header_width_reduction horizontalMargin = self.data.header_width_reduction,
type = "box (window maximize button)"
}, maximizeImage):align("right") }, maximizeImage):align("right")
self.maximizeButton.clicked = function(self, x, y, button) self.maximizeButton.clicked = function(self, x, y, button)
if button == pop.constants.left_mouse then if button == pop.constants.left_mouse then
@ -206,7 +214,8 @@ do
self.minimizeButton = pop.box(self, { self.minimizeButton = pop.box(self, {
w = buttonSize, w = buttonSize,
h = buttonSize, h = buttonSize,
horizontalMargin = self.data.header_width_reduction horizontalMargin = self.data.header_width_reduction,
type = "box (window minimize button)"
}, minimizeImage):align("right") }, minimizeImage):align("right")
self.minimizeButton.clicked = function(self, x, y, button) self.minimizeButton.clicked = function(self, x, y, button)
if button == pop.constants.left_mouse then if button == pop.constants.left_mouse then

View File

@ -27,7 +27,7 @@ class window extends element
new: (@parent, @data={}, title="Window") => new: (@parent, @data={}, title="Window") =>
super @parent, @data super @parent, @data
@data.type = "window" @data.type = "window" if @data.type == "element"
@data.w = 100 unless @data.w > 0 @data.w = 100 unless @data.w > 0
@data.h = 80 unless @data.h > 0 @data.h = 80 unless @data.h > 0
@ -41,27 +41,28 @@ class window extends element
unless @data.previous unless @data.previous
@data.previous = {} @data.previous = {}
@header = pop.box @, @data.titleBackground or {25, 180, 230, 255} @header = pop.box @, {type: "box (window header)"}, @data.titleBackground or {25, 180, 230, 255}
@title = pop.text @header, {horizontal: "center"}, title, @data.titleColor or {255, 255, 255, 255} @title = pop.text @header, {horizontal: "center", type: "text (window title)"}, title, @data.titleColor or {255, 255, 255, 255}
@window_area = pop.box @, {padding: 5}, @data.windowBackground or {200, 200, 210, 255} @window_area = pop.box @, {padding: 5, type: "box (window area)"}, @data.windowBackground or {200, 200, 210, 255}
-- buttons! :D -- buttons! :D
@data.header_width_reduction = 0 @data.header_width_reduction = 0
buttonSize = @title\getHeight! + 1 buttonSize = @title\getHeight! + 1
if @data.closeable if @data.closeable
@closeButton = pop.box(@, {w: buttonSize, h: buttonSize, horizontalMargin: @data.header_width_reduction}, closeImage)\align "right" @closeButton = pop.box(@, {w: buttonSize, h: buttonSize, horizontalMargin: @data.header_width_reduction, type: "box (window close button)"}, closeImage)\align "right"
@closeButton.clicked = (x, y, button) => @closeButton.clicked = (x, y, button) =>
if button == pop.constants.left_mouse if button == pop.constants.left_mouse
@parent\close! @parent\close!
@data.header_width_reduction += buttonSize @data.header_width_reduction += buttonSize
if @data.maximizeable if @data.maximizeable
@maximizeButton = pop.box(@, {w: buttonSize, h: buttonSize, horizontalMargin: @data.header_width_reduction}, maximizeImage)\align "right" @maximizeButton = pop.box(@, {w: buttonSize, h: buttonSize, horizontalMargin: @data.header_width_reduction, type: "box (window maximize button)"}, maximizeImage)\align "right"
@maximizeButton.clicked = (x, y, button) => @maximizeButton.clicked = (x, y, button) =>
if button == pop.constants.left_mouse if button == pop.constants.left_mouse
@parent\maximize! @parent\maximize!
--return nil --probably not needed
@data.header_width_reduction += buttonSize @data.header_width_reduction += buttonSize
if @data.minimizeable if @data.minimizeable
@minimizeButton = pop.box(@, {w: buttonSize, h: buttonSize, horizontalMargin: @data.header_width_reduction}, minimizeImage)\align "right" @minimizeButton = pop.box(@, {w: buttonSize, h: buttonSize, horizontalMargin: @data.header_width_reduction, type: "box (window minimize button)"}, minimizeImage)\align "right"
@minimizeButton.clicked = (x, y, button) => @minimizeButton.clicked = (x, y, button) =>
if button == pop.constants.left_mouse if button == pop.constants.left_mouse
@parent\minimize! @parent\minimize!
@ -204,9 +205,9 @@ class window extends element
maximize: => maximize: =>
if @data.maximized if @data.maximized
@data.x = @data.previous.x
@data.y = @data.previous.y
@setSize @data.previous.w, @data.previous.h @setSize @data.previous.w, @data.previous.h
@align!
@move @data.previous.x - @data.x, @data.previous.y - @data.y
else else
@data.previous.x = @data.x @data.previous.x = @data.x
@data.previous.y = @data.y @data.previous.y = @data.y
@ -216,8 +217,8 @@ class window extends element
@data.y = @parent.data.y @data.y = @parent.data.y
@setSize @parent.data.w, @parent.data.h @setSize @parent.data.w, @parent.data.h
table.insert @parent.child, table.remove(@parent.child, @parent\indexOf @) table.insert @parent.child, table.remove(@parent.child, @parent\indexOf @)
@align!
@data.maximized = not @data.maximized @data.maximized = not @data.maximized
@align!
return @ return @
minimize: => minimize: =>

View File

@ -219,12 +219,19 @@ pop.mousemoved = function(x, y, dx, dy, element)
if element == nil then if element == nil then
element = pop.screen element = pop.screen
end end
local previously_hovered
if element == pop.screen then
previously_hovered = pop.hovered
end
if element.data.draw and element.data.hoverable and (x >= element.data.x) and (x <= element.data.x + element.data.w) and (y >= element.data.y) and (y <= element.data.y + element.data.h) then if element.data.draw and element.data.hoverable and (x >= element.data.x) and (x <= element.data.x + element.data.w) and (y >= element.data.y) and (y <= element.data.y + element.data.h) then
pop.hovered = element pop.hovered = element
for i = 1, #element.child do for i = 1, #element.child do
pop.mousemoved(x, y, dx, dy, element.child[i]) pop.mousemoved(x, y, dx, dy, element.child[i])
end end
end end
if element == pop.screen and pop.hovered ~= previously_hovered then
log(" pop.hovered: " .. tostring(pop.hovered) .. " (" .. tostring(pop.hovered.data.type) .. ")")
end
if pop.focused and pop.focused.mousemoved and element == pop.screen then if pop.focused and pop.focused.mousemoved and element == pop.screen then
return pop.focused:mousemoved(x - pop.focused.data.x, y - pop.focused.data.y, dx, dy) return pop.focused:mousemoved(x - pop.focused.data.x, y - pop.focused.data.y, dx, dy)
end end
@ -252,7 +259,11 @@ pop.mousepressed = function(x, y, button, element)
end end
if element.mousepressed then if element.mousepressed then
handled = element:mousepressed(x - element.data.x, y - element.data.y, button) handled = element:mousepressed(x - element.data.x, y - element.data.y, button)
if handled ~= false then
log(" " .. tostring(handled) .. " (handled)", tostring(element) .. " (" .. tostring(element.data.type) .. ")")
end
if handled then if handled then
log(" ^ focused")
pop.focused = element pop.focused = element
end end
end end
@ -277,26 +288,30 @@ pop.mousereleased = function(x, y, button, element)
mousereleasedHandled = element:mousereleased(x - element.data.x, y - element.data.y, button) mousereleasedHandled = element:mousereleased(x - element.data.x, y - element.data.y, button)
end end
if clickedHandled ~= false then if clickedHandled ~= false then
log(" " .. tostring(clickedHandled) .. " (click handled)", tostring(element) .. " (" .. tostring(element.data.type) .. ")")
end
if clickedHandled then
log(" ^ focused")
pop.focused = element pop.focused = element
end end
if mousereleasedHandled ~= false then
log(" " .. tostring(mousereleasedHandled) .. " (release handled)", tostring(element) .. " (" .. tostring(element.data.type) .. ")")
end
end end
else else
log("mousereleased", x, y, button) log("mousereleased", x, y, button)
do if element == pop.focused then
element = pop.focused if element.data.draw and (x >= element.data.x) and (x <= element.data.x + element.data.w) and (y >= element.data.y) and (y <= element.data.y + element.data.h) then
if element then if element.clicked then
if element.data.draw and (x >= element.data.x) and (x <= element.data.x + element.data.w) and (y >= element.data.y) and (y <= element.data.y + element.data.h) then clickedHandled = element:clicked(x - element.data.x, y - element.data.y, button)
if element.clicked then
clickedHandled = element:clicked(x - element.data.x, y - element.data.y, button)
end
end
if element.mousereleased then
mousereleasedHandled = element:mousereleased(x - element.data.x, y - element.data.y, button)
end
if clickedHandled ~= false or mousereleasedHandled ~= false then
return clickedHandled, mousereleasedHandled
end end
end end
if element.mousereleased then
mousereleasedHandled = element:mousereleased(x - element.data.x, y - element.data.y, button)
end
if clickedHandled ~= false or mousereleasedHandled ~= false then
return clickedHandled, mousereleasedHandled
end
end end
pop.mousereleased(x, y, button, pop.screen) pop.mousereleased(x, y, button, pop.screen)
end end

View File

@ -267,6 +267,10 @@ pop.draw = (element=pop.screen) ->
--- @treturn boolean Was the event handled? --- @treturn boolean Was the event handled?
pop.mousemoved = (x, y, dx, dy, element=pop.screen) -> pop.mousemoved = (x, y, dx, dy, element=pop.screen) ->
local previously_hovered
if element == pop.screen
previously_hovered = pop.hovered
-- first we find out if we're hovering over anything and set pop.hovered -- first we find out if we're hovering over anything and set pop.hovered
if element.data.draw and element.data.hoverable and (x >= element.data.x) and (x <= element.data.x + element.data.w) and (y >= element.data.y) and (y <= element.data.y + element.data.h) if element.data.draw and element.data.hoverable and (x >= element.data.x) and (x <= element.data.x + element.data.w) and (y >= element.data.y) and (y <= element.data.y + element.data.h)
-- okay, we're over this element for sure, but let's check its children -- okay, we're over this element for sure, but let's check its children
@ -275,6 +279,10 @@ pop.mousemoved = (x, y, dx, dy, element=pop.screen) ->
for i = 1, #element.child for i = 1, #element.child
pop.mousemoved x, y, dx, dy, element.child[i] pop.mousemoved x, y, dx, dy, element.child[i]
-- if we're hovering over something different, log it
if element == pop.screen and pop.hovered != previously_hovered
log " pop.hovered: #{pop.hovered} (#{pop.hovered.data.type})"
--- @todo Implement a way for an element to attach itself to `love.mousemoved()` events? --- @todo Implement a way for an element to attach itself to `love.mousemoved()` events?
-- checking element against pop.screen so that this only gets called once -- checking element against pop.screen so that this only gets called once
if pop.focused and pop.focused.mousemoved and element == pop.screen if pop.focused and pop.focused.mousemoved and element == pop.screen
@ -323,7 +331,10 @@ pop.mousepressed = (x, y, button, element) ->
-- if a child hasn't handled it yet, try to handle it, and set pop.focused -- if a child hasn't handled it yet, try to handle it, and set pop.focused
if element.mousepressed if element.mousepressed
handled = element\mousepressed x - element.data.x, y - element.data.y, button handled = element\mousepressed x - element.data.x, y - element.data.y, button
if handled != false
log " #{handled} (handled)", "#{element} (#{element.data.type})"
if handled -- you have to explicitly handle a mousepressed event to become focused if handled -- you have to explicitly handle a mousepressed event to become focused
log " ^ focused"
pop.focused = element pop.focused = element
-- return whether or not we have handled the event -- return whether or not we have handled the event
@ -365,6 +376,9 @@ pop.mousereleased = (x, y, button, element) ->
-- if we clicked, we're focused! -- if we clicked, we're focused!
if clickedHandled != false if clickedHandled != false
log " #{clickedHandled} (click handled)", "#{element} (#{element.data.type})"
if clickedHandled
log " ^ focused"
pop.focused = element pop.focused = element
--- @todo Figure out how to bring a focused element to the front of view (aka the first element in its parent's children). --- @todo Figure out how to bring a focused element to the front of view (aka the first element in its parent's children).
--- (If I do it right here, the for loop above may break! I need to test/figure this out.) --- (If I do it right here, the for loop above may break! I need to test/figure this out.)
@ -372,12 +386,14 @@ pop.mousereleased = (x, y, button, element) ->
-- basically, move focused element to front of its parent's child -- basically, move focused element to front of its parent's child
--element.parent\focusChild element --element.parent\focusChild element
--table.insert element.parent, element.parent\removeChild(element), --table.insert element.parent, element.parent\removeChild(element),
if mousereleasedHandled != false
log " #{mousereleasedHandled} (release handled)", "#{element} (#{element.data.type})"
-- else, check for focused element, and then default to pop.screen to begin! (and print that we received an event) -- else, check for focused element, and then default to pop.screen to begin! (and print that we received an event)
else else
log "mousereleased", x, y, button log "mousereleased", x, y, button
if element = pop.focused if element == pop.focused
if element.data.draw and (x >= element.data.x) and (x <= element.data.x + element.data.w) and (y >= element.data.y) and (y <= element.data.y + element.data.h) if element.data.draw and (x >= element.data.x) and (x <= element.data.x + element.data.w) and (y >= element.data.y) and (y <= element.data.y + element.data.h)
if element.clicked if element.clicked
clickedHandled = element\clicked x - element.data.x, y - element.data.y, button clickedHandled = element\clicked x - element.data.x, y - element.data.y, button
@ -385,7 +401,6 @@ pop.mousereleased = (x, y, button, element) ->
if element.mousereleased if element.mousereleased
mousereleasedHandled = element\mousereleased x - element.data.x, y - element.data.y, button mousereleasedHandled = element\mousereleased x - element.data.x, y - element.data.y, button
if clickedHandled != false or mousereleasedHandled != false if clickedHandled != false or mousereleasedHandled != false
--print "#{clickedHandled}, #{mousereleasedHandled}, #{element}, #{element.data.type}"
return clickedHandled, mousereleasedHandled return clickedHandled, mousereleasedHandled
pop.mousereleased x, y, button, pop.screen pop.mousereleased x, y, button, pop.screen

View File

@ -2,7 +2,7 @@ local pop = require("")
local debug = false local debug = false
love.load = function() love.load = function()
pop.text("Hello World!"):align("center", "center") pop.text("Hello World!"):align("center", "center")
pop.window({ local testWindow = pop.window({
windowBackground = { windowBackground = {
200, 200,
200, 200,
@ -12,6 +12,10 @@ love.load = function()
maximizeable = true, maximizeable = true,
minimizeable = true minimizeable = true
}, "Testing Window"):move(20, 20):setSize(200, 100):align("right", "top") }, "Testing Window"):move(20, 20):setSize(200, 100):align("right", "top")
print(testWindow.window_area)
pop.window({
maximizeable = true
}, "Test Window #2"):align("center", "bottom")
local centerBox = pop.box({ local centerBox = pop.box({
w = 200, w = 200,
h = 200 h = 200

View File

@ -7,7 +7,10 @@ debug = false
love.load = -> love.load = ->
pop.text("Hello World!")\align "center", "center" pop.text("Hello World!")\align "center", "center"
pop.window({windowBackground: {200, 200, 200}, closeable: true, maximizeable: true, minimizeable: true}, "Testing Window")\move(20, 20)\setSize(200, 100)\align "right", "top" testWindow = pop.window({windowBackground: {200, 200, 200}, closeable: true, maximizeable: true, minimizeable: true}, "Testing Window")\move(20, 20)\setSize(200, 100)\align "right", "top"
print testWindow.window_area
pop.window({maximizeable: true}, "Test Window #2")\align "center", "bottom"
-- alignment testing -- alignment testing
centerBox = pop.box({w: 200, h: 200}, {255, 255, 0, 120})\align "center", "center" centerBox = pop.box({w: 200, h: 200}, {255, 255, 0, 120})\align "center", "center"