summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjussi2022-12-01 23:15:54 +0200
committerjussi2022-12-01 23:15:54 +0200
commit2479049e1a1cd754df486df0142fabe67723de72 (patch)
tree603326cc83872e87b3443a3efa9c6323fb4e0760
parent08ef5b435273eaa3de860eac1c031219cd815587 (diff)
downloadreilua-enhanced-2479049e1a1cd754df486df0142fabe67723de72.tar.gz
reilua-enhanced-2479049e1a1cd754df486df0142fabe67723de72.tar.bz2
reilua-enhanced-2479049e1a1cd754df486df0142fabe67723de72.zip
ReiLuaGui basics.
-rw-r--r--README.md1
-rw-r--r--examples/ReiLuaGui/main.lua130
-rw-r--r--examples/platformer/main.lua4
-rw-r--r--examples/resources/lib/gui.lua384
-rw-r--r--examples/resources/lib/rectangle.lua87
-rw-r--r--examples/resources/lib/utillib.lua13
6 files changed, 617 insertions, 2 deletions
diff --git a/README.md b/README.md
index ed92cb6..14e0ef7 100644
--- a/README.md
+++ b/README.md
@@ -16,6 +16,7 @@ Included submodules.
* Raygui
* Raymath
+* Lights
* Easings
List of some MISSING features that are planned to be included. For specific function, check API.
diff --git a/examples/ReiLuaGui/main.lua b/examples/ReiLuaGui/main.lua
new file mode 100644
index 0000000..ae03e89
--- /dev/null
+++ b/examples/ReiLuaGui/main.lua
@@ -0,0 +1,130 @@
+package.path = package.path..";"..RL_GetBasePath().."../resources/lib/?.lua"
+
+util = require( "utillib" )
+Vec2 = require( "vector2" )
+Rect = require( "rectangle" )
+Gui = require( "gui" )
+
+local textColor = BLACK
+local textPos = { 192, 200 }
+local imageFont = -1
+
+local container = {}
+
+function initGui()
+ -- local label = Gui.label:new( { text = "Dog", bounds = { 32, 32, 96, 96 }, drawBounds = true, Haling = Gui.ALING.CENTER, Valing = Gui.ALING.TOP } )
+ local panel = Gui.panel:new( { bounds = Rect:new( 60, 32, 128, 128 ) } )
+ container = Gui.container:new( {
+ bounds = Rect:new( 256, 120, 128, 128 ),
+ drawBounds = true,
+ -- Haling = Gui.ALING.LEFT,
+ -- Haling = Gui.ALING.CENTER,
+ -- Valing = Gui.ALING.CENTER,
+ -- type = Gui.CONTAINER.HORIZONTAL,
+ -- scrollPos = Vec2:new( 0, 0 ),
+ scrollable = true,
+ } )
+
+ -- local container = Gui.container:new( { bounds = Rect:new( 256, 120, 128, 128 ), drawBounds = true, type = Gui.CONTAINER.HORIZONTAL } )
+
+ -- local itemBounds = { 0, 0, container.bounds.width - container.spacing * 2, 36 }
+ local itemBounds = Rect:new( 0, 0, 64, 36 )
+
+ container:add( Gui.label:new( {
+ text = "Dog",
+ bounds = itemBounds:clone(),
+ onClicked = function() panel:setPosition( Vec2:new( 500, 80 ) ) end,
+ onMouseOver = function( self ) self.color = RED end,
+ notMouseOver = function( self ) self.color = BLACK end,
+ drawBounds = true,
+ } ) )
+
+ container:add( Gui.label:new( {
+ text = "Cat",
+ -- bounds = itemBounds:clone(),
+ bounds = Rect:new( 0, 0, 78, 24 ),
+ onClicked = function() panel:setPosition( Vec2:new( 290, 120 ) ) end,
+ onMouseOver = function( self ) self.color = RED end,
+ notMouseOver = function( self ) self.color = BLACK end,
+ drawBounds = true,
+ } ) )
+
+ for i = 1, 5 do
+ container:add( Gui.label:new( {
+ text = "Giraffe",
+ bounds = Rect:new( 0, 0, 100, 30 ),
+ onClicked = function() panel:setPosition( Vec2:new( 340, 380 ) ) end,
+ onMouseOver = function( self ) self.color = RED end,
+ notMouseOver = function( self ) self.color = BLACK end,
+ drawBounds = true,
+ } ) )
+ end
+
+ local container2 = Gui.container:new( {
+ bounds = Rect:new( 400, 120, 154, 30 ),
+ drawBounds = true,
+ -- Haling = Gui.ALING.LEFT,
+ -- Haling = Gui.ALING.CENTER,
+ -- Valing = Gui.ALING.CENTER,
+ type = Gui.CONTAINER.HORIZONTAL,
+ } )
+
+ container2:add( Gui.label:new( {
+ text = "Dog",
+ bounds = itemBounds:clone(),
+ -- onClicked = function() panel:setPosition( Vec2:new( 500, 80 ) ) end,
+ onMouseOver = function( self ) self.color = RED end,
+ notMouseOver = function( self ) self.color = BLACK end,
+ drawBounds = true,
+ } ) )
+
+ container2:add( Gui.label:new( {
+ text = "Cat",
+ -- bounds = itemBounds:clone(),
+ bounds = Rect:new( 0, 0, 78, 24 ),
+ -- onClicked = function() panel:setPosition( Vec2:new( 290, 120 ) ) end,
+ onMouseOver = function( self ) self.color = RED end,
+ notMouseOver = function( self ) self.color = BLACK end,
+ drawBounds = true,
+ } ) )
+
+ container:add( container2 )
+
+ panel:set2Top()
+end
+
+function init()
+ local monitor = 0
+ local mPos = RL_GetMonitorPosition( monitor )
+ local mSize = RL_GetMonitorSize( monitor )
+ winSize = RL_GetWindowSize()
+ -- local winSize = { 1920, 1080 }
+
+ RL_SetWindowTitle( "ReiLua Gui" )
+ RL_SetWindowState( FLAG_WINDOW_RESIZABLE )
+ RL_SetWindowState( FLAG_VSYNC_HINT )
+ RL_SetWindowSize( winSize )
+ RL_SetWindowPosition( { mPos[1] + mSize[1] / 2 - winSize[1] / 2, mPos[2] + mSize[2] / 2 - winSize[2] / 2 } )
+
+ initGui()
+end
+
+function process( delta )
+ if RL_IsKeyDown( KEY_RIGHT ) then
+ container:scroll( Vec2:new( container._scrollRect.x + 50 * delta, 0 ) )
+ elseif RL_IsKeyDown( KEY_LEFT ) then
+ container:scroll( Vec2:new( container._scrollRect.x - 50 * delta, 0 ) )
+ elseif RL_IsKeyDown( KEY_UP ) then
+ container:scroll( Vec2:new( 0, container._scrollRect.y - 50 * delta ) )
+ elseif RL_IsKeyDown( KEY_DOWN ) then
+ container:scroll( Vec2:new( 0, container._scrollRect.y + 50 * delta ) )
+ end
+
+ Gui.process( RL_GetMousePosition() )
+end
+
+function draw()
+ RL_ClearBackground( RAYWHITE )
+
+ Gui.draw()
+end
diff --git a/examples/platformer/main.lua b/examples/platformer/main.lua
index e325fbd..8fc33d8 100644
--- a/examples/platformer/main.lua
+++ b/examples/platformer/main.lua
@@ -1,7 +1,7 @@
package.path = package.path..";"..RL_GetBasePath().."../resources/lib/?.lua"
-util = require "utillib"
-Vec2 = require "vector2"
+util = require( "utillib" )
+Vec2 = require( "vector2" )
local TILE_SIZE = 16
local PLAYER_MAXSPEED = 1.5
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
diff --git a/examples/resources/lib/rectangle.lua b/examples/resources/lib/rectangle.lua
new file mode 100644
index 0000000..236c432
--- /dev/null
+++ b/examples/resources/lib/rectangle.lua
@@ -0,0 +1,87 @@
+Rectangle = {}
+Rectangle.meta = {
+ __index = Rectangle,
+ __tostring = function( r )
+ return "{"..tostring( r.x )..", "..tostring( r.y )..", "..tostring( r.width )..", "..tostring( r.height ).."}"
+ end,
+ -- __add = function( v1, v2 )
+ -- return Vector2:new( v1.x + v2.x, v1.y + v2.y )
+ -- end,
+ -- __sub = function( v1, v2 )
+ -- return Vector2:new( v1.x - v2.x, v1.y - v2.y )
+ -- end,
+ -- __mul = function( v1, v2 )
+ -- return Vector2:new( v1.x * v2.x, v1.y * v2.y )
+ -- end,
+ -- __div = function( v1, v2 )
+ -- return Vector2:new( v1.x / v2.x, v1.y / v2.y )
+ -- end,
+ -- __mod = function( v, value )
+ -- return Vector2:new( math.fmod( v.x, value ), math.fmod( v.y, value ) )
+ -- end,
+ -- __pow = function( v, value )
+ -- return Vector2:new( v.x ^ value, v.y ^ value )
+ -- end,
+ -- __unm = function( v )
+ -- return Vector2:new( -v.x, -v.y )
+ -- end,
+ -- __idiv = function( v, value )
+ -- return Vector2:new( v.x // value, v.y // value )
+ -- end,
+ -- __len = function( v )
+ -- local len = 0
+
+ -- for _, _ in pairs( v ) do
+ -- len = len + 1
+ -- end
+
+ -- return len
+ -- end,
+ -- __eq = function( v1, v2 )
+ -- return v1.x == v2.x and v1.y == v2.y
+ -- end,
+}
+
+function Rectangle:new( x, y, width, height )
+ if type( x ) == "table" then
+ x, y, width, height = table.unpack( x )
+ elseif type( x ) == "nil" then
+ x, y, width, height = 0, 0, 0, 0
+ end
+
+ local o = {
+ x = x,
+ y = y,
+ width = width,
+ height = height,
+ }
+ setmetatable( o, Rectangle.meta )
+ return o
+end
+
+function Rectangle:set( x, y, width, height )
+ if type( x ) == "table" then
+ x, y, width, height = table.unpack( x )
+ elseif type( x ) == "nil" then
+ x, y, width, height = 0, 0, 0, 0
+ end
+
+ self.x = x
+ self.y = y
+ self.width = width
+ self.height = height
+end
+
+function Rectangle:arr()
+ return { self.x, self.y, self.width, self.height }
+end
+
+function Rectangle:unpack()
+ return self.x, self.y, self.width, self.height
+end
+
+function Rectangle:clone()
+ return Rectangle:new( self.x, self.y, self.width, self.height )
+end
+
+return Rectangle
diff --git a/examples/resources/lib/utillib.lua b/examples/resources/lib/utillib.lua
index b2b93e0..d6e5019 100644
--- a/examples/resources/lib/utillib.lua
+++ b/examples/resources/lib/utillib.lua
@@ -163,4 +163,17 @@ function utillib.printt( t )
print( "}" )
end
+-- Move secuence of elements inside table.
+function utillib.tableMove( t, src, len, dest )
+ local copy = table.move( t, src, src + len - 1, 1, {} )
+
+ if src >= dest then
+ table.move( t, dest, src - 1, dest + len )
+ else
+ table.move( t, src + len, dest + len - 1, src )
+ end
+
+ table.move( copy, 1, len, dest, t )
+end
+
return utillib