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
end
_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
self.data.background = background
end

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -219,12 +219,19 @@ pop.mousemoved = function(x, y, dx, dy, element)
if element == nil then
element = pop.screen
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
pop.hovered = element
for i = 1, #element.child do
pop.mousemoved(x, y, dx, dy, element.child[i])
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
return pop.focused:mousemoved(x - pop.focused.data.x, y - pop.focused.data.y, dx, dy)
end
@ -252,7 +259,11 @@ pop.mousepressed = function(x, y, button, element)
end
if element.mousepressed then
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
log(" ^ focused")
pop.focused = element
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)
end
if clickedHandled ~= false then
log(" " .. tostring(clickedHandled) .. " (click handled)", tostring(element) .. " (" .. tostring(element.data.type) .. ")")
end
if clickedHandled then
log(" ^ focused")
pop.focused = element
end
if mousereleasedHandled ~= false then
log(" " .. tostring(mousereleasedHandled) .. " (release handled)", tostring(element) .. " (" .. tostring(element.data.type) .. ")")
end
end
else
log("mousereleased", x, y, button)
do
element = pop.focused
if element 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
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
if element == pop.focused 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
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
pop.mousereleased(x, y, button, pop.screen)
end

View File

@ -267,6 +267,10 @@ pop.draw = (element=pop.screen) ->
--- @treturn boolean Was the event handled?
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
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
@ -275,6 +279,10 @@ pop.mousemoved = (x, y, dx, dy, element=pop.screen) ->
for i = 1, #element.child
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?
-- checking element against pop.screen so that this only gets called once
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 element.mousepressed
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
log " ^ focused"
pop.focused = element
-- 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 clickedHandled != false
log " #{clickedHandled} (click handled)", "#{element} (#{element.data.type})"
if clickedHandled
log " ^ focused"
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).
--- (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
--element.parent\focusChild 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
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.clicked
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
mousereleasedHandled = element\mousereleased x - element.data.x, y - element.data.y, button
if clickedHandled != false or mousereleasedHandled != false
--print "#{clickedHandled}, #{mousereleasedHandled}, #{element}, #{element.data.type}"
return clickedHandled, mousereleasedHandled
pop.mousereleased x, y, button, pop.screen

View File

@ -2,7 +2,7 @@ local pop = require("")
local debug = false
love.load = function()
pop.text("Hello World!"):align("center", "center")
pop.window({
local testWindow = pop.window({
windowBackground = {
200,
200,
@ -12,6 +12,10 @@ love.load = function()
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")
local centerBox = pop.box({
w = 200,
h = 200

View File

@ -7,7 +7,10 @@ debug = false
love.load = ->
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
centerBox = pop.box({w: 200, h: 200}, {255, 255, 0, 120})\align "center", "center"