2017-01-10 20:57:02 +00:00
|
|
|
--- A generic window element. Built-in support for minimize, maximize, and close
|
|
|
|
--- buttons, as well as drag-to-resize and drag-to-move. Title bar customizable.
|
2016-08-23 04:22:13 +00:00
|
|
|
--- @classmod window
|
|
|
|
--- @copyright Paul Liverman III (2016)
|
|
|
|
--- @license The MIT License (MIT)
|
2017-04-30 23:40:29 +00:00
|
|
|
--- @todo Implement missing features.
|
2016-08-23 04:22:13 +00:00
|
|
|
|
2017-04-30 23:40:29 +00:00
|
|
|
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
|
2016-10-31 05:19:24 +00:00
|
|
|
|
|
|
|
class window extends element
|
2017-04-30 23:40:29 +00:00
|
|
|
load: (pop_lib) ->
|
|
|
|
pop = pop_lib
|
|
|
|
|
2016-08-23 04:22:13 +00:00
|
|
|
--- Constructor expects nothing, or a data table describing it.
|
2017-04-30 23:40:29 +00:00
|
|
|
--- @todo document containMethod values
|
|
|
|
new: (@parent, @data={}, title="Window") =>
|
2016-10-31 05:19:24 +00:00
|
|
|
super @parent, @data
|
|
|
|
|
2016-11-25 03:37:53 +00:00
|
|
|
@data.type = "window"
|
2017-04-30 23:40:29 +00:00
|
|
|
@data.w = 100 unless @data.w > 0
|
|
|
|
@data.h = 80 unless @data.h > 0
|
|
|
|
@data.containMethod = "mouse" unless @data.containMethod
|
|
|
|
|
|
|
|
@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
|
|
|
|
|
|
|
|
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 @
|
2016-10-31 06:40:40 +00:00
|
|
|
|
2017-04-30 23:40:29 +00:00
|
|
|
setWidth: (w) =>
|
|
|
|
return @setSize w
|
2016-08-23 04:22:13 +00:00
|
|
|
|
2017-04-30 23:40:29 +00:00
|
|
|
setHeight: (h) =>
|
|
|
|
return @setSize nil, h
|