From 8182d904dbc94436f8159290dd748b9cb602b4a7 Mon Sep 17 00:00:00 2001 From: Paul Liverman III Date: Wed, 10 May 2017 02:25:47 -0700 Subject: [PATCH] fixed window element, better logging, improved click handling --- elements/box.lua | 4 +++- elements/box.moon | 2 +- elements/text.lua | 4 +++- elements/text.moon | 2 +- elements/window.lua | 29 +++++++++++++++++++---------- elements/window.moon | 21 +++++++++++---------- init.lua | 41 ++++++++++++++++++++++++++++------------- init.moon | 19 +++++++++++++++++-- main.lua | 6 +++++- main.moon | 5 ++++- 10 files changed, 92 insertions(+), 41 deletions(-) diff --git a/elements/box.lua b/elements/box.lua index 21eb50d..bdf92ff 100644 --- a/elements/box.lua +++ b/elements/box.lua @@ -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 diff --git a/elements/box.moon b/elements/box.moon index fde452c..2480716 100644 --- a/elements/box.moon +++ b/elements/box.moon @@ -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: => diff --git a/elements/text.lua b/elements/text.lua index 2ef1ec5..c0e268b 100644 --- a/elements/text.lua +++ b/elements/text.lua @@ -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 diff --git a/elements/text.moon b/elements/text.moon index 86ad45e..225a61e 100644 --- a/elements/text.moon +++ b/elements/text.moon @@ -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 diff --git a/elements/window.lua b/elements/window.lua index 7b61ad0..24aacae 100644 --- a/elements/window.lua +++ b/elements/window.lua @@ -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 diff --git a/elements/window.moon b/elements/window.moon index e803f8f..d87badb 100644 --- a/elements/window.moon +++ b/elements/window.moon @@ -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: => diff --git a/init.lua b/init.lua index c453fca..0b4804c 100644 --- a/init.lua +++ b/init.lua @@ -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 diff --git a/init.moon b/init.moon index 6d59c10..e279a87 100644 --- a/init.moon +++ b/init.moon @@ -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 diff --git a/main.lua b/main.lua index b833481..141d15f 100644 --- a/main.lua +++ b/main.lua @@ -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 diff --git a/main.moon b/main.moon index 8025959..71def8a 100644 --- a/main.moon +++ b/main.moon @@ -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"