window mostly functional

This commit is contained in:
Paul Liverman III 2017-04-30 16:40:29 -07:00
parent f18baa308f
commit 620ceb5204
10 changed files with 423 additions and 18 deletions

View File

@ -159,6 +159,13 @@ do
getPadding = function(self) getPadding = function(self)
return self.data.padding return self.data.padding
end, end,
indexOf = function(self, element)
for i = 1, #self.child do
if self.child[i] == element then
return i
end
end
end,
delete = function(self) delete = function(self)
for i = #self.child, 1, -1 do for i = #self.child, 1, -1 do
self.child[i]:delete() self.child[i]:delete()

View File

@ -206,6 +206,11 @@ class element
getPadding: => getPadding: =>
return @data.padding return @data.padding
indexOf: (element) =>
for i = 1, #@child
if @child[i] == element
return i
--- Deletes references to this element and then deletes it. --- Deletes references to this element and then deletes it.
delete: => delete: =>
for i=#@child, 1, -1 for i=#@child, 1, -1

View File

@ -1,19 +1,195 @@
local element = require(tostring((...):sub(1, -7)) .. "/element") local pop
local mouse
mouse = love.mouse
local path = (...):sub(1, -7)
local element = require(tostring(path) .. "/element")
local box = require(tostring(path) .. "/box")
local text = require(tostring(path) .. "/text")
local window local window
do do
local _class_0 local _class_0
local _parent_0 = element local _parent_0 = element
local _base_0 = { } local _base_0 = {
load = function(pop_lib)
pop = pop_lib
end,
align = function(self, ...)
if not (self.data.align) then
return self
end
_class_0.__parent.__base.align(self, ...)
self.header:align()
self.title:align()
self.window_area:align()
self.window_area:move(nil, self.header:getHeight())
return self
end,
setSize = function(self, w, h)
local x = 0
local y = 0
if w then
local _exp_0 = self.data.horizontal
if "center" == _exp_0 then
x = x - ((w - self.data.w) / 2)
elseif "right" == _exp_0 then
x = x - (w - self.data.w)
end
self.header:setWidth(w)
self.window_area:setWidth(w)
self.data.w = w
self.data.x = self.data.x + x
self.title:align()
end
if h then
local _exp_0 = self.data.vertical
if "center" == _exp_0 then
y = y - ((h - self.data.h) / 2)
elseif "right" == _exp_0 then
y = y - (h - self.data.h)
end
self.window_area:setHeight(h - self.header:getHeight())
self.window_area:move(nil, self.header:getHeight())
self.data.h = h
self.data.y = self.data.y + y
end
self.header:move(x, y)
self.window_area:move(x, y)
return self
end,
setWidth = function(self, w)
return self:setSize(w)
end,
setHeight = function(self, h)
return self:setSize(nil, h)
end
}
_base_0.__index = _base_0 _base_0.__index = _base_0
setmetatable(_base_0, _parent_0.__base) setmetatable(_base_0, _parent_0.__base)
_class_0 = setmetatable({ _class_0 = setmetatable({
__init = function(self, parent, data) __init = function(self, parent, data, title)
if data == nil then if data == nil then
data = { } data = { }
end end
if title == nil then
title = "Window"
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" self.data.type = "window"
if not (self.data.w > 0) then
self.data.w = 100
end
if not (self.data.h > 0) then
self.data.h = 80
end
if not (self.data.containMethod) then
self.data.containMethod = "mouse"
end
self.header = pop.box(self, self.data.titleBackground or {
25,
180,
230,
255
})
self.title = pop.text(self.header, {
horizontal = "center"
}, title, self.data.titleColor or {
255,
255,
255,
255
})
self.window_area = pop.box(self, self.data.windowBackground or {
200,
200,
210,
255
})
local height = self.title:getHeight()
self.header:setSize(self.data.w, height)
self.window_area:setSize(self.data.w, self.data.h - height)
self.window_area:move(nil, height)
self.window_area.mousepressed = function(x, y, button)
if button == pop.constants.left_mouse then
local grandparent = self.parent.parent
table.insert(grandparent.child, table.remove(grandparent.child, grandparent:indexOf(self.parent)))
end
return nil
end
self.window_area.clicked = function()
return nil
end
local selected = false
local mx = 0
local my = 0
self.header.mousemoved = function(self, x, y, dx, dy)
if selected then
self.parent:move(dx, dy)
local grandparent = self.parent.parent
local _exp_0 = self.parent.data.containMethod
if "title" == _exp_0 then
if self.data.x < grandparent.data.x then
self.parent:move(grandparent.data.x - self.data.x)
end
if self.data.y < grandparent.data.y then
self.parent:move(nil, grandparent.data.y - self.data.y)
end
if self.data.x + self.data.w > grandparent.data.x + grandparent.data.w then
self.parent:move(grandparent.data.x + grandparent.data.w - (self.data.x + self.data.w))
end
if self.data.y + self.data.h > grandparent.data.y + grandparent.data.h then
self.parent:move(nil, grandparent.data.y + grandparent.data.h - (self.data.y + self.data.h))
end
elseif "body" == _exp_0 then
if self.data.x < grandparent.data.x then
self.parent:move(grandparent.data.x - self.data.x)
end
if self.data.y < grandparent.data.y then
self.parent:move(nil, grandparent.data.y - self.data.y)
end
if self.parent.data.x + self.parent.data.w > grandparent.data.x + grandparent.data.w then
self.parent:move(grandparent.data.x + grandparent.data.w - (self.parent.data.x + self.parent.data.w))
end
if self.parent.data.y + self.parent.data.h > grandparent.data.y + grandparent.data.h then
self.parent:move(nil, grandparent.data.y + grandparent.data.h - (self.parent.data.y + self.parent.data.h))
end
elseif "mouse" == _exp_0 then
if mouse.getX() < grandparent.data.x then
self.parent:setPosition(grandparent.data.x + self.data.w - mx)
end
if mouse.getY() < grandparent.data.y then
self.parent:setPosition(nil, grandparent.data.y + self.parent.data.h - my)
end
if mouse.getX() > grandparent.data.x + grandparent.data.w then
self.parent:setPosition(grandparent.data.x + grandparent.data.w + self.data.w - mx)
end
if mouse.getY() > grandparent.data.y + grandparent.data.h then
self.parent:setPosition(nil, grandparent.data.y + grandparent.data.h + self.parent.data.h - my)
end
end
return true
end
return false
end
self.header.mousepressed = function(self, x, y, button)
if button == pop.constants.left_mouse then
local grandparent = self.parent.parent
table.insert(grandparent.child, table.remove(grandparent.child, grandparent:indexOf(self.parent)))
selected = true
mx = x
my = y
return true
end
return false
end
self.header.mousereleased = function(self, x, y, button)
if button == pop.constants.left_mouse then
selected = false
return true
end
return false
end
return self:align()
end, end,
__base = _base_0, __base = _base_0,
__name = "window", __name = "window",

View File

@ -3,17 +3,158 @@
--- @classmod window --- @classmod window
--- @copyright Paul Liverman III (2016) --- @copyright Paul Liverman III (2016)
--- @license The MIT License (MIT) --- @license The MIT License (MIT)
--- @todo Implement missing features.
element = require "#{(...)\sub 1, -7}/element" local pop
import mouse from love
path = (...)\sub 1, -7
element = require "#{path}/element"
box = require "#{path}/box"
text = require "#{path}/text"
-- images would go here
class window extends element class window extends element
load: (pop_lib) ->
pop = pop_lib
--- Constructor expects nothing, or a data table describing it. --- Constructor expects nothing, or a data table describing it.
new: (@parent, @data={}) => --- @todo document containMethod values
new: (@parent, @data={}, title="Window") =>
super @parent, @data super @parent, @data
@data.type = "window" @data.type = "window"
@data.w = 100 unless @data.w > 0
@data.h = 80 unless @data.h > 0
@data.containMethod = "mouse" unless @data.containMethod
--- @todo if data, do stuff about it @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 @, @data.windowBackground or {200, 200, 210, 255}
-- closeButton, minimizeButton, etc
--setSize: => height = @title\getHeight!
--do more stuff! @header\setSize @data.w, height
@window_area\setSize @data.w, @data.h - height
@window_area\move nil, height
-- window area steals mouse events to prevent propagation to elements under it
@window_area.mousepressed = (x, y, button) ->
-- attempted to also make them pull to foreground, but it doesn't work
if button == pop.constants.left_mouse
grandparent = @parent.parent
table.insert grandparent.child, table.remove(grandparent.child, grandparent\indexOf @parent)
return nil
@window_area.clicked = ->
return nil
selected = false
mx = 0
my = 0
@header.mousemoved = (x, y, dx, dy) =>
if selected
@parent\move dx, dy
-- do not leave area of grandparent (based on containMethod)
grandparent = @parent.parent
switch @parent.data.containMethod
when "title" -- the window title can't leave
@parent\move(grandparent.data.x - @data.x) if @data.x < grandparent.data.x
@parent\move(nil, grandparent.data.y - @data.y) if @data.y < grandparent.data.y
@parent\move(grandparent.data.x + grandparent.data.w - (@data.x + @data.w)) if @data.x + @data.w > grandparent.data.x + grandparent.data.w
@parent\move(nil, grandparent.data.y + grandparent.data.h - (@data.y + @data.h)) if @data.y + @data.h > grandparent.data.y + grandparent.data.h
when "body" -- the entire window can't leave
@parent\move(grandparent.data.x - @data.x) if @data.x < grandparent.data.x
@parent\move(nil, grandparent.data.y - @data.y) if @data.y < grandparent.data.y
@parent\move(grandparent.data.x + grandparent.data.w - (@parent.data.x + @parent.data.w)) if @parent.data.x + @parent.data.w > grandparent.data.x + grandparent.data.w
@parent\move(nil, grandparent.data.y + grandparent.data.h - (@parent.data.y + @parent.data.h)) if @parent.data.y + @parent.data.h > grandparent.data.y + grandparent.data.h
when "mouse" -- wherever the mouse has clicked can't leave
@parent\setPosition(grandparent.data.x + @data.w - mx) if mouse.getX! < grandparent.data.x
@parent\setPosition(nil, grandparent.data.y + @parent.data.h - my) if mouse.getY! < grandparent.data.y
@parent\setPosition(grandparent.data.x + grandparent.data.w + @data.w - mx) if mouse.getX! > grandparent.data.x + grandparent.data.w
@parent\setPosition(nil, grandparent.data.y + grandparent.data.h + @parent.data.h - my) if mouse.getY! > grandparent.data.y + grandparent.data.h
return true
return false
@header.mousepressed = (x, y, button) =>
if button == pop.constants.left_mouse
grandparent = @parent.parent
table.insert grandparent.child, table.remove(grandparent.child, grandparent\indexOf @parent)
selected = true
mx = x
my = y
return true
return false
@header.mousereleased = (x, y, button) =>
if button == pop.constants.left_mouse
selected = false
--pop.focused = false -- we have to manually clear our focus
return true
return false
-- unsure if needed or how needed
--@setSize @data.w, @data.h -- or 100, 80
@align!
align: (...) =>
unless @data.align return @
super ...
-- don't know if this is needed or why
--for i = 1, #@child
-- @child[i]\align!
@header\align!
@title\align!
@window_area\align!
@window_area\move nil, @header\getHeight!
return @
setSize: (w, h) =>
x = 0
y = 0
if w
switch @data.horizontal
when "center"
x -= (w - @data.w) / 2
when "right"
x -= w - @data.w
-- close button stuff
@header\setWidth w
@window_area\setWidth w
@data.w = w
@data.x += x
@title\align!
-- close button stuff 2 ?
if h
switch @data.vertical
when "center"
y -= (h - @data.h) / 2
when "right"
y -= h - @data.h
@window_area\setHeight h - @header\getHeight!
@window_area\move nil, @header\getHeight!
@data.h = h
@data.y += y
@header\move x, y
@window_area\move x, y
return @
setWidth: (w) =>
return @setSize w
setHeight: (h) =>
return @setSize nil, h

View File

@ -5,7 +5,7 @@ do
local _obj_0 = string local _obj_0 = string
sub, len = _obj_0.sub, _obj_0.len sub, len = _obj_0.sub, _obj_0.len
end end
local path = sub(..., 1, len(...) - len("/extensions/streamlined_get_set")) local path = sub(..., 1, len(...) - len("/extensions/utility"))
local element = require(tostring(path) .. "/elements/element") local element = require(tostring(path) .. "/elements/element")
element.__base.fill = function(self) element.__base.fill = function(self)
self.data.x = self.parent.data.x + self.data.padding self.data.x = self.parent.data.x + self.data.padding

View File

@ -5,11 +5,12 @@
import graphics from love import graphics from love
import sub, len from string import sub, len from string
path = sub ..., 1, len(...) - len "/extensions/streamlined_get_set" path = sub ..., 1, len(...) - len "/extensions/utility"
element = require "#{path}/elements/element" element = require "#{path}/elements/element"
--box = require "#{path}/elements/box" --box = require "#{path}/elements/box"
--text = require "#{path}/elements/text" --text = require "#{path}/elements/text"
--- @todo make this built-in as maximize for window elements
element.__base.fill = => element.__base.fill = =>
@data.x = @parent.data.x + @data.padding @data.x = @parent.data.x + @data.padding
@data.y = @parent.data.y + @data.padding @data.y = @parent.data.y + @data.padding

View File

@ -134,7 +134,7 @@ pop.load = function(load_path)
local name = extensions[i]:sub(1, -5) local name = extensions[i]:sub(1, -5)
log("Requiring \"" .. tostring(name) .. "\" from \"" .. tostring(load_path) .. "/extensions/" .. tostring(name) .. "\"") log("Requiring \"" .. tostring(name) .. "\" from \"" .. tostring(load_path) .. "/extensions/" .. tostring(name) .. "\"")
pop.extensions[name] = require(tostring(load_path) .. "/extensions/" .. tostring(name)) pop.extensions[name] = require(tostring(load_path) .. "/extensions/" .. tostring(name))
if pop.extensions[name].load then if type(pop.extensions[name]) == "table" and pop.extensions[name].load then
pop.extensions[name].load(pop) pop.extensions[name].load(pop)
end end
log("Extension loaded: \"" .. tostring(name) .. "\"") log("Extension loaded: \"" .. tostring(name) .. "\"")
@ -226,10 +226,10 @@ pop.mousemoved = function(x, y, dx, dy, element)
end end
pop.mousepressed = function(x, y, button, element) pop.mousepressed = function(x, y, button, element)
if not (element) then if not (element) then
if button == "wd" then if button == pop.constants.mouse_wheel_down then
pop.wheelmoved(0, -1) pop.wheelmoved(0, -1)
return true return true
elseif button == "wu" then elseif button == pop.constants.mouse_wheel_up then
pop.wheelmoved(0, 1) pop.wheelmoved(0, 1)
return true return true
end end
@ -276,6 +276,22 @@ pop.mousereleased = function(x, y, button, element)
end end
else else
log("mousereleased", x, y, button) 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
end
end
end
pop.mousereleased(x, y, button, pop.screen) pop.mousereleased(x, y, button, pop.screen)
end end
return clickedHandled, mousereleasedHandled return clickedHandled, mousereleasedHandled

View File

@ -158,7 +158,7 @@ pop.load = (load_path=path) ->
pop.extensions[name] = require "#{load_path}/extensions/#{name}" pop.extensions[name] = require "#{load_path}/extensions/#{name}"
-- call the extension's load function if it exists -- call the extension's load function if it exists
if pop.extensions[name].load if type(pop.extensions[name]) == "table" and pop.extensions[name].load
pop.extensions[name].load pop pop.extensions[name].load pop
log "Extension loaded: \"#{name}\"" log "Extension loaded: \"#{name}\""
@ -299,10 +299,10 @@ pop.mousepressed = (x, y, button, element) ->
-- start at the screen, print that we received an event -- start at the screen, print that we received an event
unless element unless element
-- take pre 0.10.0 wheel movement and pass it along -- take pre 0.10.0 wheel movement and pass it along
if button == "wd" if button == pop.constants.mouse_wheel_down
pop.wheelmoved 0, -1 pop.wheelmoved 0, -1
return true return true
elseif button == "wu" elseif button == pop.constants.mouse_wheel_up
pop.wheelmoved 0, 1 pop.wheelmoved 0, 1
return true return true
@ -373,9 +373,20 @@ pop.mousereleased = (x, y, button, element) ->
--element.parent\focusChild element --element.parent\focusChild element
--table.insert element.parent, element.parent\removeChild(element), --table.insert element.parent, element.parent\removeChild(element),
-- else, 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.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
-- a focused element needs to know when it has been released no matter what!
if element.mousereleased
mousereleasedHandled = element\mousereleased x - element.data.x, y - element.data.y, button
if clickedHandled != false or mousereleasedHandled != false
return clickedHandled, mousereleasedHandled
pop.mousereleased x, y, button, pop.screen pop.mousereleased x, y, button, pop.screen
return clickedHandled, mousereleasedHandled return clickedHandled, mousereleasedHandled

View File

@ -2,6 +2,13 @@ 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({
windowBackground = {
200,
200,
200
}
}, "Testing Window"):move(20, 20):setSize(200, 100):align("right", "top")
local centerBox = pop.box({ local centerBox = pop.box({
w = 200, w = 200,
h = 200 h = 200
@ -129,12 +136,27 @@ love.load = function()
} }
}):align("right", "bottom") }):align("right", "bottom")
end end
love.update = function(dt)
return pop.update(dt)
end
love.draw = function() love.draw = function()
pop.draw() pop.draw()
if debug then if debug then
return pop.debugDraw() return pop.debugDraw()
end end
end end
love.mousemoved = function(x, y, dx, dy)
return pop.mousemoved(x, y, dx, dy)
end
love.mousepressed = function(x, y, button)
return pop.mousepressed(x, y, button)
end
love.mousereleased = function(x, y, button)
return pop.mousereleased(x, y, button)
end
love.wheelmoved = function(x, y)
return pop.wheelmoved(x, y)
end
love.keypressed = function(key) love.keypressed = function(key)
if key == "escape" then if key == "escape" then
return love.event.quit() return love.event.quit()
@ -142,3 +164,9 @@ love.keypressed = function(key)
debug = not debug debug = not debug
end end
end end
love.keyreleased = function(key)
return pop.keyreleased(key)
end
love.textinput = function(text)
return pop.textinput(text)
end

View File

@ -7,6 +7,7 @@ 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}}, "Testing Window")\move(20, 20)\setSize(200, 100)\align "right", "top"
-- 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"
@ -28,18 +29,37 @@ love.load = ->
pop.text(centerBox, {padding: 5, color: {0, 0, 255, 100}}, "Align me!")\align "right", "top" pop.text(centerBox, {padding: 5, color: {0, 0, 255, 100}}, "Align me!")\align "right", "top"
pop.window(centerBox, {padding: 5, titleColor: {0, 0, 0, 150}, titleBackground: {0, 0, 255, 100}, windowBackground: {200, 200, 255, 100}})\align "right", "bottom" pop.window(centerBox, {padding: 5, titleColor: {0, 0, 0, 150}, titleBackground: {0, 0, 255, 100}, windowBackground: {200, 200, 255, 100}})\align "right", "bottom"
--- @todo finish writing callbacks! love.update = (dt) ->
pop.update dt
love.draw = -> love.draw = ->
pop.draw! pop.draw!
pop.debugDraw! if debug pop.debugDraw! if debug
love.mousemoved = (x, y, dx, dy) ->
pop.mousemoved x, y, dx, dy
love.mousepressed = (x, y, button) ->
pop.mousepressed x, y, button
love.mousereleased = (x, y, button) ->
pop.mousereleased x, y, button
love.wheelmoved = (x, y) ->
pop.wheelmoved x, y
love.keypressed = (key) -> love.keypressed = (key) ->
if key == "escape" if key == "escape"
love.event.quit! love.event.quit!
elseif key == "d" elseif key == "d"
debug = not debug debug = not debug
love.keyreleased = (key) ->
pop.keyreleased key
love.textinput = (text) ->
pop.textinput text
-- NOTE TEMPORARY -- NOTE TEMPORARY