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)
return self.data.padding
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)
for i = #self.child, 1, -1 do
self.child[i]:delete()

View File

@ -206,6 +206,11 @@ class element
getPadding: =>
return @data.padding
indexOf: (element) =>
for i = 1, #@child
if @child[i] == element
return i
--- Deletes references to this element and then deletes it.
delete: =>
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
do
local _class_0
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
setmetatable(_base_0, _parent_0.__base)
_class_0 = setmetatable({
__init = function(self, parent, data)
__init = function(self, parent, data, title)
if data == nil then
data = { }
end
if title == nil then
title = "Window"
end
self.parent, self.data = parent, data
_class_0.__parent.__init(self, self.parent, self.data)
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,
__base = _base_0,
__name = "window",

View File

@ -3,17 +3,158 @@
--- @classmod window
--- @copyright Paul Liverman III (2016)
--- @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
load: (pop_lib) ->
pop = pop_lib
--- Constructor expects nothing, or a data table describing it.
new: (@parent, @data={}) =>
--- @todo document containMethod values
new: (@parent, @data={}, title="Window") =>
super @parent, @data
@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: =>
--do more stuff!
height = @title\getHeight!
@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
sub, len = _obj_0.sub, _obj_0.len
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")
element.__base.fill = function(self)
self.data.x = self.parent.data.x + self.data.padding

View File

@ -5,11 +5,12 @@
import graphics from love
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"
--box = require "#{path}/elements/box"
--text = require "#{path}/elements/text"
--- @todo make this built-in as maximize for window elements
element.__base.fill = =>
@data.x = @parent.data.x + @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)
log("Requiring \"" .. tostring(name) .. "\" from \"" .. 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)
end
log("Extension loaded: \"" .. tostring(name) .. "\"")
@ -226,10 +226,10 @@ pop.mousemoved = function(x, y, dx, dy, element)
end
pop.mousepressed = function(x, y, button, element)
if not (element) then
if button == "wd" then
if button == pop.constants.mouse_wheel_down then
pop.wheelmoved(0, -1)
return true
elseif button == "wu" then
elseif button == pop.constants.mouse_wheel_up then
pop.wheelmoved(0, 1)
return true
end
@ -276,6 +276,22 @@ pop.mousereleased = function(x, y, button, element)
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
end
end
end
pop.mousereleased(x, y, button, pop.screen)
end
return clickedHandled, mousereleasedHandled

View File

@ -158,7 +158,7 @@ pop.load = (load_path=path) ->
pop.extensions[name] = require "#{load_path}/extensions/#{name}"
-- 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
log "Extension loaded: \"#{name}\""
@ -299,10 +299,10 @@ pop.mousepressed = (x, y, button, element) ->
-- start at the screen, print that we received an event
unless element
-- 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
return true
elseif button == "wu"
elseif button == pop.constants.mouse_wheel_up
pop.wheelmoved 0, 1
return true
@ -373,9 +373,20 @@ pop.mousereleased = (x, y, button, element) ->
--element.parent\focusChild 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
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
return clickedHandled, mousereleasedHandled

View File

@ -2,6 +2,13 @@ local pop = require("")
local debug = false
love.load = function()
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({
w = 200,
h = 200
@ -129,12 +136,27 @@ love.load = function()
}
}):align("right", "bottom")
end
love.update = function(dt)
return pop.update(dt)
end
love.draw = function()
pop.draw()
if debug then
return pop.debugDraw()
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)
if key == "escape" then
return love.event.quit()
@ -142,3 +164,9 @@ love.keypressed = function(key)
debug = not debug
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 = ->
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
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.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 = ->
pop.draw!
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) ->
if key == "escape"
love.event.quit!
elseif key == "d"
debug = not debug
love.keyreleased = (key) ->
pop.keyreleased key
love.textinput = (text) ->
pop.textinput text
-- NOTE TEMPORARY