summaryrefslogtreecommitdiff
path: root/examples/resources/lib/gui.lua
diff options
context:
space:
mode:
authorjussi2022-12-01 23:15:54 +0200
committerjussi2022-12-01 23:15:54 +0200
commit2479049e1a1cd754df486df0142fabe67723de72 (patch)
tree603326cc83872e87b3443a3efa9c6323fb4e0760 /examples/resources/lib/gui.lua
parent08ef5b435273eaa3de860eac1c031219cd815587 (diff)
downloadreilua-enhanced-2479049e1a1cd754df486df0142fabe67723de72.tar.gz
reilua-enhanced-2479049e1a1cd754df486df0142fabe67723de72.tar.bz2
reilua-enhanced-2479049e1a1cd754df486df0142fabe67723de72.zip
ReiLuaGui basics.
Diffstat (limited to 'examples/resources/lib/gui.lua')
-rw-r--r--examples/resources/lib/gui.lua384
1 files changed, 384 insertions, 0 deletions
diff --git a/examples/resources/lib/gui.lua b/examples/resources/lib/gui.lua
new file mode 100644
index 0000000..1377335
--- /dev/null
+++ b/examples/resources/lib/gui.lua
@@ -0,0 +1,384 @@
+util = require( "utillib" )
+Rect = require( "rectangle" )
+Vec2 = require( "vector2" )
+
+-- NOTE!!! Work in progress! Do not use.
+
+Gui = {
+ ALING = {
+ LEFT = 1,
+ RIGHT = 2,
+ CENTER = 3,
+ TOP = 1,
+ BOTTOM = 2,
+ },
+ CONTAINER = {
+ HORIZONTAL = 1,
+ VERTICAL = 2,
+ },
+
+ font = 0,
+ fontSize = 30,
+ textSpacing = 1,
+ padding = 2,
+ spacing = 4,
+
+ _elements = {},
+}
+
+function Gui.process( mousePosition )
+ for _, element in ipairs( Gui._elements ) do
+ if element.notMouseOver ~= nil then
+ element:notMouseOver()
+ end
+ end
+
+ -- Go backwards on process check so we trigger the top most ui first and stop there.
+ for i = #Gui._elements, 1, -1 do
+ local element = Gui._elements[i]
+
+ if element:isMouseOver( mousePosition ) and not element.disabled then
+ if element.isClicked ~= nil then
+ element:isClicked()
+ end
+
+ break
+ end
+ end
+end
+
+function Gui.draw()
+ for _, element in ipairs( Gui._elements ) do
+ if element.draw ~= nil and element.visible then
+ -- //TODO Check here if needs scrissor mode.
+ -- if element
+
+ element:draw()
+ end
+ end
+end
+
+-- Label
+
+Label = {}
+Label.__index = Label
+
+function Label:new( set )
+ local o = {
+ _ID = #Gui._elements + 1,
+ bounds = set ~= nil and set.bounds ~= nil and set.bounds or Rect:new( 0, 0, 0, 0 ),
+ font = set ~= nil and set.font ~= nil and set.font or Gui.font,
+ text = set ~= nil and set.text ~= nil and set.text or "",
+ fontSize = set ~= nil and set.fontSize ~= nil and set.fontSize or Gui.fontSize,
+ textSpacing = set ~= nil and set.textSpacing ~= nil and set.textSpacing or Gui.textSpacing,
+ color = set ~= nil and set.color ~= nil and set.color or BLACK,
+ maxTextLen = set ~= nil and set.maxTextLen ~= nil and set.maxTextLen or nil,
+ padding = set ~= nil and set.padding ~= nil and set.padding or Gui.padding,
+ HAling = set ~= nil and set.HAling ~= nil and set.HAling or Gui.ALING.LEFT,
+ VAling = set ~= nil and set.VAling ~= nil and set.VAling or Gui.ALING.BOTTOM,
+
+ visible = set ~= nil and set.visible ~= nil and set.visible or true,
+ disabled = set ~= nil and set.disabled ~= nil and set.disabled or false,
+ drawBounds = set ~= nil and set.drawBounds ~= nil and set.drawBounds or false,
+
+ _textRect = Rect:new( 0, 0, 0, 0 ),
+ _visibilityBounds = nil,
+ -- Callbacks.
+ onMouseOver = set ~= nil and set.onMouseOver ~= nil and set.onMouseOver or nil,
+ notMouseOver = set ~= nil and set.notMouseOver ~= nil and set.notMouseOver or nil,
+ onClicked = set ~= nil and set.onClicked ~= nil and set.onClicked or nil,
+ }
+ setmetatable( o, self )
+
+ o:setText( o.text ) -- To measure bounds.
+ table.insert( Gui._elements, o )
+ return o
+end
+
+function Label:setText( text )
+ if self.maxTextLen ~= nil then
+ self.text = text:sub( 1, self.maxTextLen )
+ else
+ self.text = text
+ end
+
+ local textSize = Vec2:new( RL_MeasureText( self.font, self.text, self.fontSize, self.textSpacing ) )
+
+ -- Set bounds to text size if not given.
+ if self.bounds.width == nil then
+ self.bounds.width = textSize.x
+ end
+ if self.bounds.height == nil then
+ self.bounds.height = textSize.y
+ end
+
+ -- Horizontal aling.
+ if self.HAling == Gui.ALING.CENTER then
+ self._textRect.x = self.bounds.width / 2 - textSize.x / 2
+ elseif self.HAling == Gui.ALING.LEFT then
+ self._textRect.x = self.padding
+ elseif self.HAling == Gui.ALING.RIGHT then
+ self._textRect.x = self.bounds.width - textSize.x - self.padding
+ end
+ -- Vertical aling.
+ if self.VAling == Gui.ALING.CENTER then
+ self._textRect.y = self.bounds.height / 2 - textSize.y / 2
+ elseif self.VAling == Gui.ALING.TOP then
+ self._textRect.y = self.padding
+ elseif self.VAling == Gui.ALING.BOTTOM then
+ self._textRect.y = self.bounds.height - textSize.y - self.padding
+ end
+
+ self._textRect.width = textSize.x
+ self._textRect.height = textSize.y
+end
+
+function Label:setPosition( pos )
+ self.bounds.x = pos.x
+ self.bounds.y = pos.y
+end
+
+function Label:isMouseOver( mousePosition )
+ local over = RL_CheckCollisionPointRec( mousePosition, self.bounds )
+
+ if over and self._visibilityBounds ~= nil then
+ over = RL_CheckCollisionPointRec( mousePosition, self._visibilityBounds )
+ end
+
+ if over and self.onMouseOver ~= nil then
+ self:onMouseOver()
+ end
+
+ return over
+end
+
+function Label:isClicked()
+ local clicked = RL_IsMouseButtonPressed( MOUSE_BUTTON_LEFT )
+
+ if clicked and self.onClicked ~= nil then
+ self:onClicked()
+ end
+
+ return clicked
+end
+
+function Label:draw()
+ local usedScissor = false
+
+ if self._visibilityBounds ~= nil then
+ local rect = Rect:new( RL_GetCollisionRec( self.bounds, self._visibilityBounds ) )
+
+ -- Use scissor mode only on partyally visible.
+ if rect.width == 0 and rect.height == 0 then
+ return
+ elseif math.floor( rect.width ) ~= math.floor( self.bounds.width )
+ or math.floor( rect.height ) ~= math.floor( self.bounds.height ) then
+ usedScissor = true
+ RL_BeginScissorMode( self._visibilityBounds )
+ end
+ end
+
+ RL_DrawText( self.font, self.text, { self.bounds.x + self._textRect.x, self.bounds.y + self._textRect.y }, self.fontSize, self.textSpacing, self.color )
+
+ if self.drawBounds then
+ RL_DrawRectangleLines( self.bounds, self.color )
+ end
+
+ if usedScissor then
+ RL_EndScissorMode()
+ end
+
+end
+
+function Label:delete()
+ table.remove( Gui._elements, self._ID )
+end
+
+function Label:set2Top()
+ util.tableMove( Gui._elements, self._ID, 1, #Gui._elements )
+end
+
+function Label:set2Back()
+ util.tableMove( Gui._elements, self._ID, 1, 1 )
+end
+
+-- Panel.
+
+Panel = {}
+Panel.__index = Panel
+
+function Panel:new( set )
+ local o = {
+ _ID = #Gui._elements + 1,
+ bounds = set ~= nil and set.bounds ~= nil and set.bounds or Rect:new( 0, 0, 0, 0 ),
+ color = set ~= nil and set.color ~= nil and set.color or LIGHTGRAY,
+
+ visible = set ~= nil and set.visible ~= nil and set.visible or true,
+ disabled = set ~= nil and set.disabled ~= nil and set.disabled or false,
+ }
+ setmetatable( o, self )
+ table.insert( Gui._elements, o )
+
+ return o
+end
+
+function Panel:setPosition( pos )
+ self.bounds.x = pos.x
+ self.bounds.y = pos.y
+end
+
+function Panel:isMouseOver( mousePosition )
+ return RL_CheckCollisionPointRec( mousePosition, self.bounds )
+end
+
+function Panel:draw()
+ RL_DrawRectangle( self.bounds, self.color )
+end
+
+function Panel:delete()
+ table.remove( Gui._elements, self._ID )
+end
+
+function Panel:set2Top()
+ util.tableMove( Gui._elements, self._ID, 1, #Gui._elements )
+end
+
+function Panel:set2Back()
+ util.tableMove( Gui._elements, self._ID, 1, 1 )
+end
+
+-- Container.
+
+Container = {}
+Container.__index = Container
+
+function Container:new( set )
+ local o = {
+ _ID = #Gui._elements + 1,
+ bounds = set ~= nil and set.bounds ~= nil and set.bounds or Rect:new( 0, 0, 0, 0 ),
+ color = set ~= nil and set.color ~= nil and set.color or LIGHTGRAY,
+ spacing = set ~= nil and set.spacing ~= nil and set.spacing or Gui.spacing,
+ type = set ~= nil and set.type ~= nil and set.type or Gui.CONTAINER.VERTICAL,
+ HAling = set ~= nil and set.HAling ~= nil and set.HAling or Gui.ALING.LEFT,
+ VAling = set ~= nil and set.VAling ~= nil and set.VAling or Gui.ALING.TOP,
+
+ visible = set ~= nil and set.visible ~= nil and set.visible or true,
+ disabled = set ~= nil and set.disabled ~= nil and set.disabled or false,
+ drawBounds = set ~= nil and set.drawBounds ~= nil and set.drawBounds or false,
+ scrollable = set ~= nil and set.scrollable ~= nil and set.scrollable or false,
+
+ cells = {},
+
+ _visibilityBounds = nil, -- Will give this to it's children.
+ _scrollRect = Rect:new( 0, 0, 0, 0 ),
+ }
+ setmetatable( o, self )
+ table.insert( Gui._elements, o )
+ return o
+end
+
+function Container:setPosition( pos )
+ self.bounds.x = pos.x
+ self.bounds.y = pos.y
+end
+
+function Container:isMouseOver( mousePosition )
+ return RL_CheckCollisionPointRec( mousePosition, self.bounds )
+end
+
+function Container:add( cell )
+ table.insert( self.cells, cell )
+
+ self:update()
+
+ if cell.update ~= nil then
+ cell:update()
+ end
+end
+
+function Container:scroll( pos )
+ if not self.scrollable then
+ return
+ end
+
+ self._scrollRect.x = util.clamp( pos.x, 0, self._scrollRect.width - self.bounds.width )
+ self._scrollRect.y = util.clamp( pos.y, 0, self._scrollRect.height - self.bounds.height )
+ -- self._scrollRect.x = pos.x
+ -- self._scrollRect.y = pos.y
+
+ self:update()
+end
+
+function Container:update()
+ local pos = Vec2:new( self.bounds.x + self.spacing, self.bounds.y + self.spacing )
+
+ if self.scrollable then
+ self._visibilityBounds = self.bounds
+ self._scrollRect.width = 0
+ self._scrollRect.height = 0
+ end
+
+ for i, cell in ipairs( self.cells ) do
+ if self._visibilityBounds ~= nil then
+ cell._visibilityBounds = self._visibilityBounds
+ end
+
+ if self.type == Gui.CONTAINER.VERTICAL then
+ if self.HAling == Gui.ALING.CENTER then
+ pos.x = self.bounds.x + self.bounds.width / 2 - cell.bounds.width / 2
+ elseif self.HAling == Gui.ALING.RIGHT then
+ pos.x = self.bounds.x + self.bounds.width - cell.bounds.width - self.spacing
+ end
+
+ cell.bounds.x = pos.x - self._scrollRect.x
+ cell.bounds.y = pos.y - self._scrollRect.y
+
+ self._scrollRect.width = math.max( self._scrollRect.width, pos.x + cell.bounds.width + self.spacing - self.bounds.x )
+ self._scrollRect.height = math.max( self._scrollRect.height, pos.y + cell.bounds.height + self.spacing - self.bounds.y )
+
+ pos.y = pos.y + cell.bounds.height + self.spacing
+ elseif self.type == Gui.CONTAINER.HORIZONTAL then
+ if self.VAling == Gui.ALING.CENTER then
+ pos.y = self.bounds.y + self.bounds.height / 2 - cell.bounds.height / 2
+ elseif self.VAling == Gui.ALING.BOTTOM then
+ pos.y = self.bounds.y + self.bounds.height - cell.bounds.height - self.spacing
+ end
+
+ cell.bounds.x = pos.x - self._scrollRect.x
+ cell.bounds.y = pos.y - self._scrollRect.y
+
+ self._scrollRect.width = math.max( self._scrollRect.width, pos.x + cell.bounds.width + self.spacing - self.bounds.x )
+ self._scrollRect.height = math.max( self._scrollRect.height, pos.y + cell.bounds.height + self.spacing - self.bounds.y )
+
+ pos.x = pos.x + cell.bounds.width + self.spacing
+ end
+
+ if cell.update ~= nil then
+ cell:update()
+ end
+ end
+end
+
+function Container:draw()
+ if self.drawBounds then
+ RL_DrawRectangleLines( self.bounds, self.color )
+ RL_DrawRectangleLines( {
+ self.bounds.x - self._scrollRect.x,
+ self.bounds.y - self._scrollRect.y,
+ self._scrollRect.width,
+ self._scrollRect.height,
+ }, RED )
+ end
+end
+
+function Container:delete()
+ table.remove( Gui._elements, self._ID )
+end
+
+--Assingments.
+
+Gui.label = Label
+Gui.panel = Panel
+Gui.container = Container
+
+return Gui