Initial commit

This commit is contained in:
Nikita Kruglickiy
2020-12-25 22:18:23 +06:00
commit 1a0785862d
21 changed files with 1181 additions and 0 deletions

View File

@@ -0,0 +1,51 @@
--@include label.txt
--@include radius_mixin.txt
--@include ../utils.txt
require("label.txt")
require("../utils.txt")
EButton = class("EButton", ELabel)
EButton:include(require("radius_mixin.txt"))
accessorFunc(EButton, "_textColor", "TextColor", Color(230, 230, 230))
accessorFunc(EButton, "_hoveredColor", "HoveredColor", Color(66, 66, 66))
accessorFunc(EButton, "_hoveredTextColor", "HoveredTextColor", Color(230, 230, 230))
accessorFunc(EButton, "_disabledColor", "DisabledColor", Color(32, 32, 32))
accessorFunc(EButton, "_disabledTextColor", "DisabledTextColor", Color(80, 80, 80))
function EButton:initialize()
ELabel.initialize(self)
self:setText("Button")
self:setColor(Color(46, 46, 46))
self:setSize(100, 32)
self:setRoundedCorners(true)
self:setRadius(5)
end
function EButton:paint()
local x, y = self:getAbsolutePos()
local w, h = self:getSize()
local textW, textH = self:getTextSize()
local rTL, rTR, rBR, rBL = self:getRoundedCorners()
local bgColor, textColor
if self:isEnabled() then
bgColor = self:isHovered() and self:getHoveredColor() or self:getColor()
textColor = self:isHovered() and self:getHoveredTextColor() or self:getTextColor()
else
bgColor = self:getDisabledColor()
textColor = self:getDisabledTextColor()
end
render.setColor(bgColor)
if self:getRadius() > 0 and (rTL or rTR or rBR or rBL) then
render.drawRoundedBoxEx(self:getRadius(), x, y, w, h, rTL, rTR, rBL, rBR)
else
render.drawRectFast(x, y, w, h)
end
render.setFont(self:getFont())
render.setColor(textColor)
render.drawSimpleText(x + w / 2 - textW / 2, y + h / 2 - textH / 2, self:getText())
end

View File

@@ -0,0 +1,62 @@
--@include element.txt
--@include label.txt
--@include ../utils.txt
require("element.txt")
require("label.txt")
require("../utils.txt")
ECheckbox = class("ECheckbox", ELabel)
accessorFunc(ECheckbox, "_textColor", "TextColor", Color(255, 255, 255))
accessorFunc(ECheckbox, "_hoveredColor", "HoveredColor", Color(66, 66, 66))
accessorFunc(ECheckbox, "_hoveredTextColor", "HoveredTextColor", Color(255, 255, 255))
accessorFunc(ECheckbox, "_disabledColor", "DisabledColor", Color(32, 32, 32))
accessorFunc(ECheckbox, "_disabledTextColor", "DisabledTextColor", Color(80, 80, 80))
accessorFunc(ECheckbox, "_indent", "Indent", 8)
function ECheckbox:initialize()
ELabel.initialize(self)
self._checked = false
self:setText("Checkbox")
self:setSize(200, 16)
end
function ECheckbox:setChecked(state)
self._checked = state
self:onChange()
end
function ECheckbox:isChecked()
return self._checked
end
function ECheckbox:paint()
local x, y = self:getAbsolutePos()
local w, h = self:getSize()
local textW, textH = self:getTextSize()
--[[
local bgColor, textColor
if self:isEnabled() then
bgColor = self:isHovered() and self:getHoveredColor() or self:getColor()
textColor = self:isHovered() and self:getHoveredTextColor() or self:getTextColor()
else
bgColor = self:getDisabledColor()
textColor = self:getDisabledTextColor()
end
]]
render.setColor(Color(209, 209, 209))
render.drawCircle(x, y, h / 2)
--render.drawRectOutline(x, y, h, h, -8)
--render.setColor(Color(209, 209, 209, 0))
--render.drawRectFast(x, y, h - 2, h - 2)
render.setFont(self:getFont())
render.setColor(Color(255, 255, 255))
render.drawSimpleText(x + h + self:getIndent(), y + h / 2 - textH / 2, self:getText())
end

View File

@@ -0,0 +1,359 @@
--@include ../utils.txt
--@include ../skins/default.txt
require("../utils.txt")
local defaultSkin = require("../skins/default.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._parent = nil
self._firstChild = nil
self._prevSibling = nil
self._nextSibling = nil
self._skin = defaultSkin
end
function Element:setWidth(width)
self._width = width
self:performLayout(self:getSize())
end
function Element:getWidth()
return self._width
end
function Element:setHeight(height)
self._height = height
self:performLayout(self:getSize())
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._x, self._y
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: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)
child:_setSkin(self._skin)
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:_setSkin(skin)
self._skin = skin
end
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() then
if type(self.think) == "function" then
self:think()
end
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
]]
self:paint()
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)
if self:cursorIntersect(x, y) and self:isEnabled() then
local element = self:_postEventToAll("MOUSE_MOVED", x, y)
if not element then
if not self:isHovered() then
self._hovered = true
self:onMouseEnter()
end
self:onMouseMoved(x, y)
end
return true
else
if self:isHovered() then
self._hovered = false
self:onMouseLeave()
end
return false
end
end
function Element:_onButtonPressed(key, keyName)
end
function Element:_onButtonReleased(key, keyName)
end
-- STUB
function Element:performLayout()
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

View File

@@ -0,0 +1,7 @@
--@include element.txt
--@include ../utils.txt
require("element.txt")
require("../utils.txt")
EEmpty = class("EEmpty", Element)

View File

@@ -0,0 +1,58 @@
--@include element.txt
--@include ../utils.txt
require("element.txt")
require("../utils.txt")
ELabel = class("ELabel", Element)
accessorFunc(ELabel, "_color", "Color", Color(255, 255, 255))
accessorFunc(ELabel, "_disabledColor", "DisabledColor", Color(200, 200, 200))
function ELabel:initialize()
Element.initialize(self)
self._text = ""
self._textWidth = 0
self._textHeight = 0
self:setFont("Trebuchet18")
self:setText("Label")
end
function ELabel:setText(text)
self._text = tostring(text)
if self:getFont() then
render.setFont(self:getFont())
self._textWidth, self._textHeight = render.getTextSize(self:getText())
end
end
function ELabel:getText()
return self._text
end
function ELabel:setFont(font)
self._font = font
render.setFont(self:getFont())
self._textWidth, self._textHeight = render.getTextSize(self:getText())
end
function ELabel:getFont()
return self._font
end
function ELabel:getTextSize()
return self._textWidth, self._textHeight
end
function ELabel:paint()
local x, y = self:getAbsolutePos()
render.setFont(self:getFont())
render.setColor(self:isEnabled() and self:getColor() or self:getDisabledColor())
render.drawSimpleText(x, y, self:getText())
end

View File

@@ -0,0 +1,112 @@
--@include element.txt
--@include label.txt
--@include button.txt
--@include ../utils.txt
require("element.txt")
require("label.txt")
require("button.txt")
require("../utils.txt")
EPanel = class("EPanel", Element)
accessorFunc(EPanel, "_backgroundColor", "BackgroundColor", Color(23, 23, 23))
accessorFunc(EPanel, "_parentLock", "ParentLock", false)
function EPanel:initialize()
Element.initialize(self)
self._minimized = false
self.title = ELabel:new()
self.title:setPos(12, 8)
self:addChild(self.title)
self.minimizeButton = EButton:new()
self.minimizeButton:setText("_")
self.minimizeButton:setSize(32, 32)
self.minimizeButton:setRadius(0)
self.minimizeButton:setColor(Color(0, 0, 0))
self.minimizeButton:setHoveredColor(Color(25, 25, 25))
self:addChild(self.minimizeButton)
self.closeButton = EButton:new()
self.closeButton:setText("X")
self.closeButton:setSize(32, 32)
self.closeButton:setRadius(0)
self.closeButton:setColor(Color(0, 0, 0))
self.closeButton:setHoveredColor(Color(25, 25, 25))
self:addChild(self.closeButton)
self:setTitle("Panel")
end
function EPanel:setTitle(title)
self.title:setText(title)
end
function EPanel:getTitle()
return self.title:getText()
end
function EPanel:setMinimized(state)
self._minimized = state
end
function EPanel:isMinimized()
return self._minimized
end
function EPanel:onMousePressed(x, y, key, keyName)
if keyName == "MOUSE1" then
local aX, aY = self:getAbsolutePos()
if self:isDraggable() and y < aY + 33 then
self._dragStartPos = {x - self:getX(), y - self:getY()}
end
end
end
function EPanel:onMouseReleased(x, y, key, keyName)
if keyName == "MOUSE1" then
if self:isDraggable() then
self._dragStartPos = nil
end
end
end
function EPanel:onMouseMoved(x, y)
if self._dragStartPos then
local targetX, targetY = x - self._dragStartPos[1], y - self._dragStartPos[2]
if self:hasParent() and self:getParentLock() then
targetX = math.clamp(targetX, 0, 1920 - self:getWidth())
targetY = math.clamp(targetY, 0, 1080 - self:getHeight())
end
self:setPos(targetX, targetY)
end
end
function EPanel:onMouseLeave()
self._dragStartPos = nil
end
function EPanel:performLayout(w, h)
self.closeButton:setPos(w - 33, 1)
self.minimizeButton:setPos(w - 65, 1)
end
function EPanel:paint()
local x, y = self:getAbsolutePos()
local w, h = self:getSize()
render.setColor(Color(255, 255, 255, 10))
render.drawRectFast(x, y, w, h)
render.setColor(Color(0, 0, 0))
render.drawRectFast(x + 1, y + 1, w - 2, 32)
render.setColor(self:getBackgroundColor())
render.drawRectFast(x + 1, y + 33, w - 2, h - 34)
end

View File

@@ -0,0 +1,49 @@
--@include ../utils.txt
require("../utils.txt")
local MIXIN = {}
accessorFunc(MIXIN, "_radius", "Radius", 0)
function MIXIN:included(target)
self._roundTopLeftCorner = false
self._roundTopRightCorner = false
self._roundBottomLeftCorner = false
self._roundBottomRightCorner = false
end
function MIXIN:setRoundedCorners(c1, c2, c3, c4)
if c1 ~= nil and c2 ~= nil and c3 ~= nil and c4 ~= nil then
self._roundTopLeftCorner = c1
self._roundTopRightCorner = c2
self._roundBottomRightCorner = c3
self._roundBottomLeftCorner = c4
elseif c1 ~= nil and c2 ~= nil and c3 ~= nil then
self._roundTopLeftCorner = c1
self._roundTopRightCorner = c2
self._roundBottomRightCorner = c3
self._roundBottomLeftCorner = c2
elseif c1 ~= nil and c2 ~= nil then
self._roundTopLeftCorner = c1
self._roundTopRightCorner = c2
self._roundBottomRightCorner = c1
self._roundBottomLeftCorner = c2
elseif c1 ~= nil then
self._roundTopLeftCorner = c1
self._roundTopRightCorner = c1
self._roundBottomRightCorner = c1
self._roundBottomLeftCorner = c1
else
self._roundTopLeftCorner = false
self._roundTopRightCorner = false
self._roundBottomRightCorner = false
self._roundBottomLeftCorner = false
end
end
function MIXIN:getRoundedCorners()
return self._roundTopLeftCorner, self._roundTopRightCorner, self._roundBottomRightCorner, self._roundBottomLeftCorner
end
return MIXIN

View File

@@ -0,0 +1,5 @@
--@include element.txt
require("element.txt")
ERoot = class("ERoot", Element)

View File

@@ -0,0 +1,17 @@
--@include element.txt
--@include ../utils.txt
require("element.txt")
require("../utils.txt")
EShape = class("EShape", Element)
accessorFunc(EShape, "_color", "Color", Color(255, 255, 255))
function EShape:paint()
local x, y = self:getAbsolutePos()
local w, h = self:getSize()
render.setColor(self:getColor())
render.drawRectFast(x, y, w, h)
end