387 lines
7.9 KiB
Plaintext
387 lines
7.9 KiB
Plaintext
--@include /koptilnya/libs/utils.txt
|
|
|
|
require("/koptilnya/libs/utils.txt")
|
|
|
|
Element = class("Element")
|
|
|
|
accessorFunc(Element, "_x", "X", 0)
|
|
accessorFunc(Element, "_y", "Y", 0)
|
|
|
|
function Element:initialize()
|
|
self._width = 0
|
|
self._height = 0
|
|
self._enabled = true
|
|
self._visible = true
|
|
self._draggable = true
|
|
self._hovered = false
|
|
self._colorScheme = {}
|
|
self._parent = nil
|
|
self._firstChild = nil
|
|
self._prevSibling = nil
|
|
self._nextSibling = nil
|
|
end
|
|
|
|
function Element:setWidth(width)
|
|
self._width = width
|
|
|
|
self:invalidateLayout()
|
|
end
|
|
|
|
function Element:getWidth()
|
|
return self._width
|
|
end
|
|
|
|
function Element:setHeight(height)
|
|
self._height = height
|
|
|
|
self:invalidateLayout()
|
|
end
|
|
|
|
function Element:getHeight()
|
|
return self._height
|
|
end
|
|
|
|
function Element:setSize(width, height)
|
|
self:setWidth(width)
|
|
self:setHeight(height)
|
|
end
|
|
|
|
function Element:getSize()
|
|
return self:getWidth(), self:getHeight()
|
|
end
|
|
|
|
function Element:setPos(x, y)
|
|
self:setX(x)
|
|
self:setY(y)
|
|
end
|
|
|
|
function Element:getPos()
|
|
return self:getX(), self:getY()
|
|
end
|
|
|
|
function Element:getAbsolutePos(x, y)
|
|
x = x == nil and self:getX() or x + self:getX()
|
|
y = y == nil and self:getY() or y + self:getY()
|
|
|
|
if self:hasParent() then
|
|
x, y = self:getParent():getAbsolutePos(x, y)
|
|
end
|
|
|
|
return x, y
|
|
end
|
|
|
|
function Element:getBounds()
|
|
return self:getX(), self:getY(), self:getX() + self:getWidth(), self:getY() + self:getHeight()
|
|
end
|
|
|
|
function Element:getAbsoluteBounds()
|
|
local aX, aY = self:getAbsolutePos()
|
|
|
|
return aX, aY, aX + self:getWidth(), aY + self:getHeight()
|
|
end
|
|
|
|
function Element:setEnabled(enabled)
|
|
self._enabled = enabled
|
|
end
|
|
|
|
function Element:isEnabled()
|
|
return self._enabled
|
|
end
|
|
|
|
function Element:setVisible(visible)
|
|
self._visible = visible
|
|
end
|
|
|
|
function Element:isVisible()
|
|
return self._visible
|
|
end
|
|
|
|
function Element:setDraggable(draggable)
|
|
self._draggable = draggable
|
|
end
|
|
|
|
function Element:isDraggable()
|
|
return self._draggable
|
|
end
|
|
|
|
function Element:isHovered()
|
|
return self._hovered
|
|
end
|
|
|
|
function Element:setColorScheme(scheme, overwrite)
|
|
if overwrite then
|
|
self._colorScheme = scheme
|
|
else
|
|
self._colorScheme = table.merge(self._colorScheme, scheme)
|
|
end
|
|
end
|
|
|
|
function Element:getColorScheme()
|
|
return self._colorScheme
|
|
end
|
|
|
|
function Element:getColorFromScheme(key)
|
|
local scheme = self:getColorScheme()[key]
|
|
local color
|
|
|
|
if scheme then
|
|
if not self:isEnabled() then
|
|
color = scheme["disabled"] or scheme[1]
|
|
elseif self:isHovered() then
|
|
color = scheme["hover"] or scheme[1]
|
|
else
|
|
color = scheme[1]
|
|
end
|
|
end
|
|
|
|
return color or Color(255, 255, 255)
|
|
end
|
|
|
|
function Element:setParent(parent)
|
|
checkVarClass(parent, Element)
|
|
|
|
self._parent = parent
|
|
end
|
|
|
|
function Element:getParent()
|
|
return self._parent
|
|
end
|
|
|
|
function Element:hasParent()
|
|
return self:getParent() ~= nil
|
|
end
|
|
|
|
function Element:addChild(child)
|
|
checkVarClass(child, Element)
|
|
|
|
child:setParent(self)
|
|
|
|
if not self._firstChild then
|
|
self._firstChild = child
|
|
else
|
|
local temp = self._firstChild
|
|
|
|
while temp._nextSibling do
|
|
temp = temp._nextSibling
|
|
end
|
|
|
|
temp._nextSibling = child
|
|
child._prevSibling = temp
|
|
end
|
|
end
|
|
|
|
function Element:requestFocus()
|
|
--return
|
|
end
|
|
|
|
function Element:hasFocus()
|
|
--return self._focus
|
|
end
|
|
|
|
function Element:cursorIntersect(x, y)
|
|
--local self:getAbsoluteBounds()
|
|
local aX, aY = self:getAbsolutePos()
|
|
|
|
if x >= aX and x < aX + self:getWidth() and y >= aY and y < aY + self:getHeight() then
|
|
return true
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
function Element:moveToFront(child)
|
|
if child then
|
|
local next = child._nextSibling
|
|
local prev = child._prevSibling
|
|
|
|
if prev then
|
|
prev._nextSibling = next
|
|
|
|
if next then
|
|
next._prevSibling = prev
|
|
end
|
|
else
|
|
return
|
|
end
|
|
|
|
child._nextSibling = self._firstChild
|
|
self._firstChild._prevSibling = child
|
|
child._prevSibling = nil
|
|
self._firstChild = child
|
|
end
|
|
end
|
|
|
|
-- PROTECTED
|
|
|
|
function Element:_postEvent(eventKey, ...)
|
|
if eventKey == "THINK" then
|
|
return self:_onThink()
|
|
elseif eventKey == "PAINT" then
|
|
return self:_onPaint()
|
|
elseif eventKey == "MOUSE_PRESSED" then
|
|
return self:_onMousePressed(...)
|
|
elseif eventKey == "MOUSE_RELEASED" then
|
|
return self:_onMouseReleased(...)
|
|
elseif eventKey == "MOUSE_MOVED" then
|
|
return self:_onMouseMoved(...)
|
|
end
|
|
end
|
|
|
|
function Element:_postEventToAll(eventKey, ...)
|
|
local temp = self._firstChild
|
|
|
|
while temp do
|
|
local next = temp._nextSibling
|
|
|
|
if temp:_postEvent(eventKey, ...) then
|
|
return temp
|
|
end
|
|
|
|
temp = next
|
|
end
|
|
|
|
return nil
|
|
end
|
|
|
|
function Element:_postEventToAllReverse(eventKey, ...)
|
|
local next = self._nextSibling
|
|
|
|
if next then
|
|
next:_postEventToAllReverse(eventKey, ...)
|
|
end
|
|
|
|
self:_postEvent(eventKey, ...)
|
|
|
|
return nil
|
|
end
|
|
|
|
function Element:_onThink()
|
|
if self:isEnabled() and self:isVisible() then
|
|
self:think()
|
|
|
|
if self._firstChild then
|
|
self._firstChild:_postEventToAllReverse("THINK")
|
|
end
|
|
end
|
|
end
|
|
|
|
function Element:_onPaint()
|
|
if self:isVisible() then
|
|
--[[
|
|
if self:hasParent() then
|
|
render.enableScissorRect(self:getParent():getBounds())
|
|
end
|
|
]]
|
|
|
|
local x, y = self:getAbsolutePos()
|
|
local w, h = self:getSize()
|
|
|
|
self:paint(x, y, w, h)
|
|
|
|
if self._firstChild then
|
|
self._firstChild:_postEventToAllReverse("PAINT")
|
|
end
|
|
end
|
|
end
|
|
|
|
function Element:_onMousePressed(x, y, key, keyName)
|
|
if self:cursorIntersect(x, y) and self:isEnabled() then
|
|
local element = self:_postEventToAll("MOUSE_PRESSED", x, y, key, keyName)
|
|
|
|
if not element then
|
|
self:onMousePressed(x, y, key, keyName)
|
|
|
|
if self:hasParent() then
|
|
self:getParent():moveToFront(self)
|
|
end
|
|
|
|
-- focus
|
|
end
|
|
|
|
return true
|
|
else
|
|
-- unfocus
|
|
|
|
return false
|
|
end
|
|
end
|
|
|
|
function Element:_onMouseReleased(x, y, key, keyName)
|
|
if self:cursorIntersect(x, y) and self:isEnabled() then
|
|
local element = self:_postEventToAll("MOUSE_RELEASED", x, y, key, keyName)
|
|
|
|
if not element then
|
|
self:onMouseReleased(x, y, key, keyName)
|
|
end
|
|
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
function Element:_onMouseMoved(x, y)
|
|
local element = self:_postEventToAll("MOUSE_MOVED", x, y)
|
|
|
|
if self:cursorIntersect(x, y) then
|
|
if self:isEnabled() then
|
|
if not self:isHovered() then
|
|
self._hovered = true
|
|
|
|
self:onMouseEnter()
|
|
end
|
|
|
|
self:onMouseMoved(x, y)
|
|
end
|
|
else
|
|
if self:isHovered() then
|
|
self._hovered = false
|
|
|
|
self:onMouseLeave()
|
|
end
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
function Element:_onButtonPressed(key, keyName)
|
|
end
|
|
|
|
function Element:_onButtonReleased(key, keyName)
|
|
end
|
|
|
|
-- STUB
|
|
|
|
function Element:performLayout()
|
|
end
|
|
|
|
function Element:invalidateLayout()
|
|
self:performLayout(self:getSize())
|
|
end
|
|
|
|
function Element:think()
|
|
end
|
|
|
|
function Element:paint()
|
|
end
|
|
|
|
function Element:onMousePressed(x, y, key, keyName)
|
|
end
|
|
|
|
function Element:onMouseReleased(x, y, key, keyName)
|
|
end
|
|
|
|
function Element:onMouseMoved(x, y)
|
|
end
|
|
|
|
function Element:onMouseEnter()
|
|
end
|
|
|
|
function Element:onMouseLeave()
|
|
end
|
|
|
|
function Element:onButtonPressed(key, keyName)
|
|
end
|
|
|
|
function Element:onButtonReleased(key, keyName)
|
|
end |