ReiLuaGui basics done.

This commit is contained in:
jussi
2022-12-02 22:53:51 +02:00
parent 2479049e1a
commit bdbd475ae3
11 changed files with 607 additions and 221 deletions

2
API.md
View File

@@ -2505,7 +2505,7 @@ Draw a line using cubic-bezier curves in-out
--- ---
> success = RL_DrawLineBezier( Vector2 startPos, Vector2 endPos, Vector2 controlPos, float thickness, Color color ) > success = RL_DrawLineBezierQuad( Vector2 startPos, Vector2 endPos, Vector2 controlPos, float thickness, Color color )
Draw line using quadratic bezier curves with a control point Draw line using quadratic bezier curves with a control point

View File

@@ -6,12 +6,16 @@ KEY CHANGES:
- ADDED: Lua interpreter mode. - ADDED: Lua interpreter mode.
- ADDED: Easings extra module. - ADDED: Easings extra module.
- ADDED: exit function. - ADDED: exit function.
- FIX: uluaGetNPatchInfo fix for RL_DrawTextureNPatch. Guess this was never tested and did not work at all >:E. - FIXED: uluaGetNPatchInfo fix for RL_DrawTextureNPatch. Guess this was never tested and did not work at all >:E.
- ADDED: ReiLuaGui.
Detailed changes: Detailed changes:
ADDED: Help argument. ADDED: Help argument.
CHANGED: Changed fuction name RL_rlSetLineWidth to RL_rlglSetLineWidth. CHANGED: Changed fuction name RL_rlSetLineWidth to RL_rlglSetLineWidth.
CHANGED: Changed fuction name RL_rlGetLineWidth to RL_rlglGetLineWidth. CHANGED: Changed fuction name RL_rlGetLineWidth to RL_rlglGetLineWidth.
FIX: DrawRectangleGradient V and H expecting wrong amount of arguments. FIXED: DrawRectangleGradient V and H expecting wrong arguments.
ADDED: RL_LoadDirectoryFilesEx. ADDED: RL_LoadDirectoryFilesEx.
ADDED: Flag option (-s) for doc_parser.lua for exporting module APIs to separate files. ADDED: Flag option (-s) for doc_parser.lua for exporting module APIs to separate files.
FIXED: RL_DrawLineBezierQuad was called RL_DrawLineBezier in API.
ADDED: Color lib.
FIXED: RL_DrawEllipse and RL_DrawEllipseLines expecting wrong arguments.

View File

@@ -1,4 +1,13 @@
Current { Current {
* ReiLuaGui
* Mouse wheel scrolling can be detected through other elements.
* Could try putting container over all of it's content elements and having it's onOver function not breaking loop.
* Text input.
* Movable window.
* Grid container.
* Calculator.
* Grid icon window.
* File explorer.
} }
Backlog { Backlog {

View File

@@ -3,26 +3,32 @@ package.path = package.path..";"..RL_GetBasePath().."../resources/lib/?.lua"
util = require( "utillib" ) util = require( "utillib" )
Vec2 = require( "vector2" ) Vec2 = require( "vector2" )
Rect = require( "rectangle" ) Rect = require( "rectangle" )
Color = require( "color" )
Gui = require( "gui" ) Gui = require( "gui" )
local textColor = BLACK
local textPos = { 192, 200 }
local imageFont = -1
local container = {} local container = {}
-- local circleTexture = RL_LoadTexture( RL_GetBasePath().."../resources/images/circle.png" )
local circleTexture = RL_LoadTexture( RL_GetBasePath().."../resources/images/plain-circle.png" )
local checkTexture = RL_LoadTexture( RL_GetBasePath().."../resources/images/check-mark.png" )
RL_GenTextureMipmaps( circleTexture )
RL_GenTextureMipmaps( checkTexture )
RL_SetTextureFilter( circleTexture, TEXTURE_FILTER_TRILINEAR )
RL_SetTextureFilter( checkTexture, TEXTURE_FILTER_TRILINEAR )
function initGui() 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 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 ) } ) local panel = Gui.element:new( { bounds = Rect:new( 60, 32, 128, 128 ), drawBounds = true } )
container = Gui.container:new( { container = Gui.container:new( {
bounds = Rect:new( 256, 120, 128, 128 ), bounds = Rect:new( 256, 120, 128, 128 ),
drawBounds = true, -- spacing = 4,
-- Haling = Gui.ALING.LEFT, -- Haling = Gui.ALING.LEFT,
-- Haling = Gui.ALING.CENTER, -- Haling = Gui.ALING.CENTER,
-- Valing = Gui.ALING.CENTER, -- Valing = Gui.ALING.CENTER,
-- type = Gui.CONTAINER.HORIZONTAL, -- type = Gui.CONTAINER.HORIZONTAL,
-- scrollPos = Vec2:new( 0, 0 ),
scrollable = true, scrollable = true,
showScrollbar = true,
} ) } )
-- local container = Gui.container:new( { bounds = Rect:new( 256, 120, 128, 128 ), drawBounds = true, type = Gui.CONTAINER.HORIZONTAL } ) -- local container = Gui.container:new( { bounds = Rect:new( 256, 120, 128, 128 ), drawBounds = true, type = Gui.CONTAINER.HORIZONTAL } )
@@ -30,63 +36,67 @@ function initGui()
-- local itemBounds = { 0, 0, container.bounds.width - container.spacing * 2, 36 } -- local itemBounds = { 0, 0, container.bounds.width - container.spacing * 2, 36 }
local itemBounds = Rect:new( 0, 0, 64, 36 ) local itemBounds = Rect:new( 0, 0, 64, 36 )
container:add( Gui.label:new( { local dog = Gui.element:new( {
text = "Dog", bounds = Rect:new( 0, 0, 128, 36 ),
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, onClicked = function() panel:setPosition( Vec2:new( 290, 120 ) ) end,
onMouseOver = function( self ) self.color = RED end, onMouseOver = function( self ) self.items[1].color = RED end,
notMouseOver = function( self ) self.color = BLACK end, notMouseOver = function( self ) self.items[1].color = BLACK end,
drawBounds = true, drawBounds = true,
} ) ) } )
dog:add( Gui.text:new( { text = "Dog", HAling = Gui.ALING.LEFT } ) )
dog:add( Gui.texture:new( { bounds = Rect:new( 0, 0, 24, 24 ), texture = circleTexture, HAling = Gui.ALING.RIGHT, color = Color:new( 150, 150, 255 ) } ) )
dog:add( Gui.texture:new( { bounds = Rect:new( 0, 0, 24, 24 ), texture = checkTexture, HAling = Gui.ALING.RIGHT, visible = true } ) )
-- dog:add( Gui.text:new( { text = "Cat", HAling = Gui.ALING.RIGHT } ) )
-- dog:add( Gui.shape:new( { bounds = Rect:new( 0, 0, 128, 36 ), shape = Gui.SHAPE.RECTANGLE_ROUNDED, color = Color:new( GREEN ) } ) )
container:add( dog )
-- container:add( Gui.element:new( {
-- text = "Cat",
-- 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 for i = 1, 5 do
container:add( Gui.label:new( { local element = Gui.element:new( {
text = "Giraffe", bounds = Rect:new( 0, 0, 120, 30 ),
bounds = Rect:new( 0, 0, 100, 30 ),
onClicked = function() panel:setPosition( Vec2:new( 340, 380 ) ) end, onClicked = function() panel:setPosition( Vec2:new( 340, 380 ) ) end,
onMouseOver = function( self ) self.color = RED end, onMouseOver = function( self ) self.color = Color:new( DARKBLUE ) end,
notMouseOver = function( self ) self.color = BLACK end, notMouseOver = function( self ) self.color = Color:new( LIGHTGRAY ) end,
drawBounds = true, drawBounds = true,
} ) ) } )
element:add( Gui.text:new( { text = "Giraffe" } ) )
container:add( element )
end end
local container2 = Gui.container:new( { local container2 = Gui.container:new( {
bounds = Rect:new( 400, 120, 154, 30 ), bounds = Rect:new( 0, 0, 154, 64 ),
drawBounds = true,
-- Haling = Gui.ALING.LEFT,
-- Haling = Gui.ALING.CENTER,
-- Valing = Gui.ALING.CENTER,
type = Gui.CONTAINER.HORIZONTAL, type = Gui.CONTAINER.HORIZONTAL,
} ) } )
container2:add( Gui.label:new( { local element = Gui.element:new( {
text = "Dog",
bounds = itemBounds:clone(), bounds = itemBounds:clone(),
-- onClicked = function() panel:setPosition( Vec2:new( 500, 80 ) ) end, onMouseOver = function( self ) self.color = Color:new( DARKBLUE ) end,
onMouseOver = function( self ) self.color = RED end, notMouseOver = function( self ) self.color = Color:new( LIGHTGRAY ) end,
notMouseOver = function( self ) self.color = BLACK end,
drawBounds = true, drawBounds = true,
} ) ) } )
element:add( Gui.text:new( { text = "Dog" } ) )
container2:add( element )
container2:add( Gui.label:new( { element = Gui.element:new( {
text = "Cat",
-- bounds = itemBounds:clone(),
bounds = Rect:new( 0, 0, 78, 24 ), bounds = Rect:new( 0, 0, 78, 24 ),
-- onClicked = function() panel:setPosition( Vec2:new( 290, 120 ) ) end, -- bounds = Rect:new( 0, 0, 78, 64 ),
onMouseOver = function( self ) self.color = RED end, onMouseOver = function( self ) self.color = Color:new( DARKBLUE ) end,
notMouseOver = function( self ) self.color = BLACK end, notMouseOver = function( self ) self.color = Color:new( LIGHTGRAY ) end,
drawBounds = true, drawBounds = true,
} ) ) } )
element:add( Gui.text:new( { text = "Cat" } ) )
container2:add( element )
container:add( container2 ) container:add( container2 )
@@ -110,17 +120,7 @@ function init()
end end
function process( delta ) function process( delta )
if RL_IsKeyDown( KEY_RIGHT ) then Gui.process( Vec2:new( RL_GetMousePosition() ) )
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 end
function draw() function draw()

View File

@@ -1,6 +1,9 @@
Resource Author Licence Source Resource Author Licence Source Edits
tiles.png Chris Hamons (maintainer) CC0 https://opengameart.org/content/dungeon-crawl-32x32-tiles tiles.png Chris Hamons (maintainer) CC0 https://opengameart.org/content/dungeon-crawl-32x32-tiles
arcade_platformerV2.png GrafxKid CC0 https://opengameart.org/content/arcade-platformer-assets arcade_platformerV2.png GrafxKid CC0 https://opengameart.org/content/arcade-platformer-assets
apple.png Jussi Viitala CC0 apple.png Jussi Viitala CC0
grass.png Jussi Viitala CC0 grass.png Jussi Viitala CC0
snake.png Jussi Viitala CC0 snake.png Jussi Viitala CC0
check-mark.png Delapouite Creative Commons 3.0 https://game-icons.net Resized
circle.png Delapouite Creative Commons 3.0 https://game-icons.net Resized
plain-circle.png Delapouite Creative Commons 3.0 https://game-icons.net Resized

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

@@ -0,0 +1,95 @@
Color = {}
Color.meta = {
__index = Color,
__tostring = function( r )
return "{"..tostring( r.r )..", "..tostring( r.g )..", "..tostring( r.b )..", "..tostring( r.a ).."}"
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 Color:new( r, g, b, a )
if type( r ) == "table" then
r, g, b, a = table.unpack( r )
elseif type( r ) == "nil" then
r, g, b, a = 0, 0, 0, 255
end
if a == nil then
a = 255
end
local o = {
r = r,
g = g,
b = b,
a = a,
}
setmetatable( o, Color.meta )
return o
end
function Color:set( r, g, b, a )
if type( r ) == "table" then
r, g, b, a = table.unpack( r )
elseif type( r ) == "nil" then
r, g, b, a = 0, 0, 0, 0
end
if a == nil then
a = 255
end
self.r = r
self.g = g
self.b = b
self.a = a
end
function Color:arr()
return { self.r, self.g, self.b, self.a }
end
function Color:unpack()
return self.r, self.g, self.b, self.a
end
function Color:clone()
return Color:new( self.r, self.g, self.b, self.a )
end
return Color

View File

@@ -1,11 +1,13 @@
util = require( "utillib" ) util = require( "utillib" )
Rect = require( "rectangle" ) Rect = require( "rectangle" )
Vec2 = require( "vector2" ) Vec2 = require( "vector2" )
Color = require( "color" )
-- NOTE!!! Work in progress! Do not use. -- NOTE!!! Work in progress! Do not use.
Gui = { Gui = {
ALING = { ALING = {
NONE = 0,
LEFT = 1, LEFT = 1,
RIGHT = 2, RIGHT = 2,
CENTER = 3, CENTER = 3,
@@ -16,30 +18,79 @@ Gui = {
HORIZONTAL = 1, HORIZONTAL = 1,
VERTICAL = 2, VERTICAL = 2,
}, },
SHAPE = {
LINE = 0,
CIRCLE = 1,
CIRCLE_LINES = 2,
ELLIPSE = 3,
ELLIPSE_LINES = 4,
RECTANGLE = 5,
RECTANGLE_LINES = 6,
RECTANGLE_ROUNDED = 7,
RECTANGLE_ROUNDED_LINES = 8,
},
font = 0, font = 0,
fontSize = 30, fontSize = 30,
textSpacing = 1,
padding = 2, padding = 2,
spacing = 4, spacing = 4,
scrollbarWidth = 8,
scrollAmount = 10,
_elements = {}, _elements = {},
_mousePos = Vec2:new( 0, 0 ), -- Last mouse position that was passed to Gui.process.
heldCallback = nil,
} }
local function setProperty( set, property, default )
if set ~= nil and set[ property ] ~= nil then
return set[ property ]
end
return default
end
function Gui.process( mousePosition ) function Gui.process( mousePosition )
local mouseWheel = RL_GetMouseWheelMove()
Gui._mousePos = mousePosition
for _, element in ipairs( Gui._elements ) do for _, element in ipairs( Gui._elements ) do
if element.notMouseOver ~= nil then if element.notMouseOver ~= nil then
element:notMouseOver() element:notMouseOver()
end end
-- Mousewheel scrolling. Note this would be detected through other elements.
if mouseWheel ~= 0 and element.scrollable and RL_CheckCollisionPointRec( mousePosition, element.bounds ) then
local pos = Vec2:new( element._scrollRect.x, element._scrollRect.y )
local scrollVec = Vec2:new( 0, element.scrollAmount * mouseWheel )
if RL_IsKeyDown( KEY_LEFT_SHIFT ) then
scrollVec = Vec2:new( element.scrollAmount * mouseWheel, 0 )
end end
element:scroll( pos - scrollVec )
end
end
if Gui.heldCallback ~= nil then
if RL_IsMouseButtonDown( MOUSE_BUTTON_LEFT ) then
Gui.heldCallback()
else
Gui.heldCallback = nil
end
return
end
-- Go backwards on process check so we trigger the top most ui first and stop there. -- Go backwards on process check so we trigger the top most ui first and stop there.
for i = #Gui._elements, 1, -1 do for i = #Gui._elements, 1, -1 do
local element = Gui._elements[i] local element = Gui._elements[i]
if element:isMouseOver( mousePosition ) and not element.disabled then if element.isMouseOver ~= nil and element:isMouseOver( mousePosition ) and not element.disabled then
if element.isClicked ~= nil then if RL_IsMouseButtonPressed( MOUSE_BUTTON_LEFT ) and element.onClicked ~= nil then
element:isClicked() element:onClicked()
end
if RL_IsMouseButtonDown( MOUSE_BUTTON_LEFT ) and element.onHeld ~= nil then
element:onHeld()
end end
break break
@@ -50,95 +101,268 @@ end
function Gui.draw() function Gui.draw()
for _, element in ipairs( Gui._elements ) do for _, element in ipairs( Gui._elements ) do
if element.draw ~= nil and element.visible then if element.draw ~= nil and element.visible then
-- //TODO Check here if needs scrissor mode.
-- if element
element:draw() element:draw()
end end
end end
end end
-- Label -- Items.
Label = {} -- Text.
Label.__index = Label
function Label:new( set ) Text = {}
Text.__index = Text
function Text:new( set )
local o = { local o = {
_ID = #Gui._elements + 1, bounds = Rect:new( 0, 0, 0, 0 ),
bounds = set ~= nil and set.bounds ~= nil and set.bounds or Rect:new( 0, 0, 0, 0 ), HAling = setProperty( set, "HAling", Gui.ALING.LEFT ),
font = set ~= nil and set.font ~= nil and set.font or Gui.font, VAling = setProperty( set, "VAling", Gui.ALING.BOTTOM ),
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, font = setProperty( set, "font", Gui.font ),
disabled = set ~= nil and set.disabled ~= nil and set.disabled or false, text = setProperty( set, "text", "" ),
drawBounds = set ~= nil and set.drawBounds ~= nil and set.drawBounds or false, fontSize = setProperty( set, "fontSize", Gui.fontSize ),
spacing = setProperty( set, "spacing", Gui.spacing ),
color = setProperty( set, "color", Color:new( BLACK ) ),
maxTextLen = setProperty( set, "maxTextLen", nil ),
_textRect = Rect:new( 0, 0, 0, 0 ), visible = setProperty( set, "visible", true ),
_visibilityBounds = nil, _parent = 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 ) setmetatable( o, self )
o:set( o.text ) -- To measure bounds.
o:setText( o.text ) -- To measure bounds.
table.insert( Gui._elements, o )
return o return o
end end
function Label:setText( text ) function Text:set( text )
if self.maxTextLen ~= nil then if self.maxTextLen ~= nil then
self.text = text:sub( 1, self.maxTextLen ) self.text = text:sub( 1, self.maxTextLen )
else else
self.text = text self.text = text
end end
local textSize = Vec2:new( RL_MeasureText( self.font, self.text, self.fontSize, self.textSpacing ) ) local textSize = Vec2:new( RL_MeasureText( self.font, self.text, self.fontSize, self.spacing ) )
-- Set bounds to text size if not given.
if self.bounds.width == nil then
self.bounds.width = textSize.x self.bounds.width = textSize.x
end
if self.bounds.height == nil then
self.bounds.height = textSize.y self.bounds.height = textSize.y
end
function Text:draw()
if not self.visible then
return
end end
RL_DrawText( self.font, self.text, { self.parent.bounds.x + self.bounds.x, self.parent.bounds.y + self.bounds.y }, self.fontSize, self.spacing, self.color )
end
-- Texture.
Texture = {}
Texture.__index = Texture
function Texture:new( set )
local o = {
bounds = setProperty( set, "bounds", Rect:new( 0, 0, 0, 0 ) ),
HAling = setProperty( set, "HAling", Gui.ALING.LEFT ),
VAling = setProperty( set, "VAling", Gui.ALING.CENTER ),
texture = setProperty( set, "texture", nil ),
source = setProperty( set, "source", Rect:new( 0, 0, 0, 0 ) ),
origin = setProperty( set, "origin", Vec2:new( 0, 0 ) ),
rotation = setProperty( set, "rotation", 0 ),
color = setProperty( set, "color", Color:new( WHITE ) ),
visible = setProperty( set, "visible", true ),
_parent = nil,
}
setmetatable( o, self )
o:set( o.texture ) -- To measure bounds.
return o
end
function Texture:set( texture )
if texture == nil then
return
end
local texSize = Vec2:new( RL_GetTextureSize( texture ) )
if self.bounds.width == 0 or self.bounds.height == 0 then
self.bounds.width = texSize.x
self.bounds.height = texSize.y
end
if self.source.width == 0 or self.source.height == 0 then
self.source.width = texSize.x
self.source.height = texSize.y
end
self.texture = texture
end
function Texture:draw()
if not self.visible or self.texture == nil then
return
end
local dst = {
self.bounds.x + self.parent.bounds.x,
self.bounds.y + self.parent.bounds.y,
self.bounds.width,
self.bounds.height
}
RL_DrawTexturePro( self.texture, self.source, dst, self.origin, self.rotation, self.color )
end
-- Shape.
Shape = {}
Shape.__index = Shape
function Shape:new( set )
local o = {
bounds = setProperty( set, "bounds", Rect:new( 0, 0, 0, 0 ) ),
HAling = setProperty( set, "HAling", Gui.ALING.LEFT ),
VAling = setProperty( set, "VAling", Gui.ALING.CENTER ),
shape = setProperty( set, "shape", Gui.SHAPE.RECTANGLE ),
-- Line.
startPos = setProperty( set, "startPos", Vec2:new( 0, 0 ) ),
endPos = setProperty( set, "endPos", Vec2:new( 0, 0 ) ),
thickness = setProperty( set, "thickness", 3.0 ),
-- Circle.
center = setProperty( set, "center", Vec2:new( 0, 0 ) ),
radius = setProperty( set, "radius", 0 ),
-- Ellipse.
radiusH = setProperty( set, "radiusH", 0 ),
radiusV = setProperty( set, "radiusV", 0 ),
-- Rectangle rounded.
roundness = setProperty( set, "roundness", 1 ),
segments = setProperty( set, "segments", 4 ),
color = setProperty( set, "color", Color:new( WHITE ) ),
visible = setProperty( set, "visible", true ),
_parent = nil,
}
setmetatable( o, self )
o:set( o.shape )
return o
end
-- Set to default shape values.
function Shape:set( shape )
if shape == Gui.SHAPE.LINE and self.startPos == Vec2:new( 0, 0 ) and self.endPos == Vec2:new( 0, 0 ) then
self.startPos = Vec2:new( 0, self.bounds.height / 2 )
self.endPos = Vec2:new( self.bounds.width, self.bounds.height / 2 )
elseif ( shape == Gui.SHAPE.CIRCLE or shape == Gui.SHAPE.CIRCLE_LINES ) and self.radius == 0 then
self.center = Vec2:new( self.bounds.width / 2, self.bounds.height / 2 )
self.radius = math.min( self.bounds.width, self.bounds.height ) / 2
elseif ( shape == Gui.SHAPE.ELLIPSE or shape == Gui.SHAPE.ELLIPSE_LINES ) and self.radiusH == 0 and self.radiusV == 0 then
self.center = Vec2:new( self.bounds.width / 2, self.bounds.height / 2 )
self.radiusH = self.bounds.width / 2
self.radiusV = self.bounds.height / 2
end
end
function Shape:draw()
if not self.visible then
return
end
local pos = Vec2:new( self.parent.bounds.x, self.parent.bounds.y )
if self.shape == Gui.SHAPE.LINE then
RL_DrawLine( self.startPos + pos, self.endPos + pos, self.thickness, self.color )
elseif self.shape == Gui.SHAPE.CIRCLE then
RL_DrawCircle( self.center + pos, self.radius, self.color )
elseif self.shape == Gui.SHAPE.CIRCLE_LINES then
RL_DrawCircleLines( self.center + pos, self.radius, self.color )
elseif self.shape == Gui.SHAPE.ELLIPSE then
RL_DrawEllipse( self.center + pos, self.radiusH, self.radiusV, self.color )
elseif self.shape == Gui.SHAPE.ELLIPSE_LINES then
RL_DrawEllipseLines( self.center + pos, self.radiusH, self.radiusV, self.color )
elseif self.shape == Gui.SHAPE.RECTANGLE then
RL_DrawRectangle( { self.bounds.x + pos.x, self.bounds.y + pos.y, self.bounds.width, self.bounds.height }, self.color )
elseif self.shape == Gui.SHAPE.RECTANGLE_LINES then
RL_DrawRectangleLines( { self.bounds.x + pos.x, self.bounds.y + pos.y, self.bounds.width, self.bounds.height }, self.color )
elseif self.shape == Gui.SHAPE.RECTANGLE_ROUNDED then
RL_DrawRectangleRounded( { self.bounds.x + pos.x, self.bounds.y + pos.y, self.bounds.width, self.bounds.height }, self.roundness, self.segments, self.color )
elseif self.shape == Gui.SHAPE.RECTANGLE_ROUNDED_LINES then
RL_DrawRectangleRoundedLines( { self.bounds.x + pos.x, self.bounds.y + pos.y, self.bounds.width, self.bounds.height }, self.roundness, self.segments, self.thickness, self.color )
end
end
-- End of items.
-- Element.
Element = {}
Element.__index = Element
function Element:new( set )
local o = {
_ID = #Gui._elements + 1,
bounds = setProperty( set, "bounds", Rect:new( 0, 0, 0, 0 ) ),
padding = setProperty( set, "padding", Gui.padding ),
visible = setProperty( set, "visible", true ),
disabled = setProperty( set, "disabled", false ),
drawBounds = setProperty( set, "drawBounds", false ),
color = setProperty( set, "color", Color:new( GRAY ) ),
items = {},
_visibilityBounds = nil,
-- Callbacks.
onMouseOver = setProperty( set, "onMouseOver", nil ),
notMouseOver = setProperty( set, "notMouseOver", nil ),
onClicked = setProperty( set, "onClicked", nil ),
onHeld = setProperty( set, "onHeld", nil ),
}
setmetatable( o, self )
table.insert( Gui._elements, o )
return o
end
function Element:update()
-- Horizontal aling. -- Horizontal aling.
if self.HAling == Gui.ALING.CENTER then for _, item in ipairs( self.items ) do
self._textRect.x = self.bounds.width / 2 - textSize.x / 2 if item.HAling == Gui.ALING.CENTER then
elseif self.HAling == Gui.ALING.LEFT then item.bounds.x = self.bounds.width / 2 - item.bounds.width / 2
self._textRect.x = self.padding elseif item.HAling == Gui.ALING.LEFT then
elseif self.HAling == Gui.ALING.RIGHT then item.bounds.x = self.padding
self._textRect.x = self.bounds.width - textSize.x - self.padding elseif item.HAling == Gui.ALING.RIGHT then
item.bounds.x = self.bounds.width - item.bounds.width - self.padding
end end
-- Vertical aling. -- Vertical aling.
if self.VAling == Gui.ALING.CENTER then if item.VAling == Gui.ALING.CENTER then
self._textRect.y = self.bounds.height / 2 - textSize.y / 2 item.bounds.y = self.bounds.height / 2 - item.bounds.height / 2
elseif self.VAling == Gui.ALING.TOP then elseif item.VAling == Gui.ALING.TOP then
self._textRect.y = self.padding item.bounds.y = self.padding
elseif self.VAling == Gui.ALING.BOTTOM then elseif item.VAling == Gui.ALING.BOTTOM then
self._textRect.y = self.bounds.height - textSize.y - self.padding item.bounds.y = self.bounds.height - item.bounds.height - self.padding
end
end end
self._textRect.width = textSize.x
self._textRect.height = textSize.y
end end
function Label:setPosition( pos ) function Element:setPosition( pos )
self.bounds.x = pos.x self.bounds.x = pos.x
self.bounds.y = pos.y self.bounds.y = pos.y
self:update()
end end
function Label:isMouseOver( mousePosition ) function Element:add( item )
table.insert( self.items, item )
item.parent = self
self:update()
end
function Element:isMouseOver( mousePosition )
local over = RL_CheckCollisionPointRec( mousePosition, self.bounds ) local over = RL_CheckCollisionPointRec( mousePosition, self.bounds )
if over and self._visibilityBounds ~= nil then if over and self._visibilityBounds ~= nil then
@@ -152,17 +376,7 @@ function Label:isMouseOver( mousePosition )
return over return over
end end
function Label:isClicked() function Element:draw()
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 local usedScissor = false
if self._visibilityBounds ~= nil then if self._visibilityBounds ~= nil then
@@ -178,10 +392,12 @@ function Label:draw()
end end
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 if self.drawBounds then
RL_DrawRectangleLines( self.bounds, self.color ) RL_DrawRectangle( self.bounds, self.color )
end
for _, item in ipairs( self.items ) do
item:draw()
end end
if usedScissor then if usedScissor then
@@ -190,60 +406,15 @@ function Label:draw()
end end
function Label:delete() function Element:delete()
table.remove( Gui._elements, self._ID ) table.remove( Gui._elements, self._ID )
end end
function Label:set2Top() function Element:set2Top()
util.tableMove( Gui._elements, self._ID, 1, #Gui._elements ) util.tableMove( Gui._elements, self._ID, 1, #Gui._elements )
end end
function Label:set2Back() function Element: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 ) util.tableMove( Gui._elements, self._ID, 1, 1 )
end end
@@ -255,35 +426,42 @@ Container.__index = Container
function Container:new( set ) function Container:new( set )
local o = { local o = {
_ID = #Gui._elements + 1, _ID = #Gui._elements + 1,
bounds = set ~= nil and set.bounds ~= nil and set.bounds or Rect:new( 0, 0, 0, 0 ), bounds = setProperty( set, "bounds", Rect:new( 0, 0, 0, 0 ) ),
color = set ~= nil and set.color ~= nil and set.color or LIGHTGRAY, spacing = setProperty( set, "spacing", Gui.spacing ),
spacing = set ~= nil and set.spacing ~= nil and set.spacing or Gui.spacing, type = setProperty( set, "type", Gui.CONTAINER.VERTICAL ),
type = set ~= nil and set.type ~= nil and set.type or Gui.CONTAINER.VERTICAL, HAling = setProperty( set, "HAling", Gui.ALING.LEFT ),
HAling = set ~= nil and set.HAling ~= nil and set.HAling or Gui.ALING.LEFT, VAling = setProperty( set, "VAling", Gui.ALING.TOP ),
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, visible = setProperty( set, "visible", true ),
disabled = set ~= nil and set.disabled ~= nil and set.disabled or false, disabled = setProperty( set, "disabled", false ),
drawBounds = set ~= nil and set.drawBounds ~= nil and set.drawBounds or false, -- drawBounds = setProperty( set, "drawBounds", false ),
scrollable = set ~= nil and set.scrollable ~= nil and set.scrollable or false, -- color = setProperty( set, "color", Color:new( DARKGRAY ) ),
scrollable = setProperty( set, "scrollable", false ),
showScrollbar = setProperty( set, "showScrollbar", false ),
scrollbarWidth = setProperty( set, "scrollbarWidth", Gui.scrollbarWidth ),
scrollAmount = setProperty( set, "scrollAmount", Gui.scrollAmount ), -- When using mouse scroll.
cells = {}, cells = {},
_visibilityBounds = nil, -- Will give this to it's children. _visibilityBounds = nil, -- Will give this to it's children.
_scrollRect = Rect:new( 0, 0, 0, 0 ), _scrollRect = Rect:new( 0, 0, 0, 0 ),
_VScrollbarRect = Rect:new( 0, 0, 0, 0 ),
_HScrollbarRect = Rect:new( 0, 0, 0, 0 ),
_VScrollbar = nil,
_HScrollbar = nil,
} }
setmetatable( o, self ) setmetatable( o, self )
table.insert( Gui._elements, o ) table.insert( Gui._elements, o )
return o return o
end end
function Container:setPosition( pos ) function Container:setPosition( pos )
self.bounds.x = pos.x self.bounds.x = pos.x
self.bounds.y = pos.y self.bounds.y = pos.y
end
function Container:isMouseOver( mousePosition ) self:update()
return RL_CheckCollisionPointRec( mousePosition, self.bounds )
end end
function Container:add( cell ) function Container:add( cell )
@@ -303,12 +481,66 @@ function Container:scroll( pos )
self._scrollRect.x = util.clamp( pos.x, 0, self._scrollRect.width - self.bounds.width ) 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.y = util.clamp( pos.y, 0, self._scrollRect.height - self.bounds.height )
-- self._scrollRect.x = pos.x
-- self._scrollRect.y = pos.y
self:update() self:update()
end end
function Container:mouseScroll( v )
local handleBounds = Vec2:new( self._HScrollbar.items[1].bounds.width, self._VScrollbar.items[1].bounds.height )
local mousePos = Gui._mousePos - Vec2:new( self.bounds.x, self.bounds.y ) - Vec2:new( handleBounds.x / 2, handleBounds.y / 2 )
local ratio = Vec2:new( self._scrollRect.width / self.bounds.width, self._scrollRect.height / self.bounds.height )
mousePos = mousePos * ratio * v
if v.x == 0 then
mousePos.x = self._scrollRect.x
elseif v.y == 0 then
mousePos.y = self._scrollRect.y
end
self:scroll( mousePos )
end
-- function Container:isMouseOver( mousePosition )
-- -- print( "Over container" )
-- local over = RL_CheckCollisionPointRec( mousePosition, self.bounds )
-- if over and self._visibilityBounds ~= nil then
-- over = RL_CheckCollisionPointRec( mousePosition, self._visibilityBounds )
-- print( "Over container" )
-- end
-- -- if over and self.onMouseOver ~= nil then
-- -- self:onMouseOver()
-- -- end
-- -- return over
-- end
function Container:updateScrollbar()
if self.bounds.height < self._scrollRect.height then
self._VScrollbar.bounds.width = self.scrollbarWidth
self._VScrollbar.bounds.height = self.bounds.height
self._VScrollbar.bounds.x = self.bounds.x + self.bounds.width
self._VScrollbar.bounds.y = self.bounds.y
-- Handle.
self._VScrollbar.items[1].bounds.width = self.scrollbarWidth
self._VScrollbar.items[1].bounds.height = self.bounds.height / self._scrollRect.height * self.bounds.height
self._VScrollbar.items[1].bounds.y = self._scrollRect.y / self._scrollRect.height * self.bounds.height
end
if self.bounds.width < self._scrollRect.width then
self._HScrollbar.bounds.width = self.bounds.width
self._HScrollbar.bounds.height = self.scrollbarWidth
self._HScrollbar.bounds.x = self.bounds.x
self._HScrollbar.bounds.y = self.bounds.y + self.bounds.height
-- Handle.
self._HScrollbar.items[1].bounds.width = self.bounds.width / self._scrollRect.width * self.bounds.width
self._HScrollbar.items[1].bounds.height = self.scrollbarWidth
self._HScrollbar.items[1].bounds.x = self._scrollRect.x / self._scrollRect.width * self.bounds.width
end
end
function Container:update() function Container:update()
local pos = Vec2:new( self.bounds.x + self.spacing, self.bounds.y + self.spacing ) local pos = Vec2:new( self.bounds.x + self.spacing, self.bounds.y + self.spacing )
@@ -316,6 +548,42 @@ function Container:update()
self._visibilityBounds = self.bounds self._visibilityBounds = self.bounds
self._scrollRect.width = 0 self._scrollRect.width = 0
self._scrollRect.height = 0 self._scrollRect.height = 0
-- Create scrollbars if can scroll.
if self._VScrollbar == nil then
self._VScrollbar = Element:new( {
padding = 0,
drawBounds = true,
color = Color:new( GRAY ),
onClicked = function() Gui.heldCallback = function() self:mouseScroll( Vec2:new( 0, 1 ) ) end end,
} )
self._VScrollbar:add( Gui.shape:new( {
HAling = Gui.ALING.CENTER,
VAling = Gui.ALING.NONE,
bounds = Rect:new( 0, 0, 0, 0 ),
shape = Gui.SHAPE.RECTANGLE_ROUNDED,
color = Color:new( LIGHTGRAY ),
} ) )
end
if self._HScrollbar == nil then
self._HScrollbar = Element:new( {
padding = 0,
drawBounds = true,
color = Color:new( GRAY ),
onClicked = function() Gui.heldCallback = function() self:mouseScroll( Vec2:new( 1, 0 ) ) end end,
} )
self._HScrollbar:add( Gui.shape:new( {
HAling = Gui.ALING.NONE,
VAling = Gui.ALING.CENTER,
bounds = Rect:new( 0, 0, 0, 0 ),
shape = Gui.SHAPE.RECTANGLE_ROUNDED,
color = Color:new( LIGHTGRAY ),
} ) )
end
end end
for i, cell in ipairs( self.cells ) do for i, cell in ipairs( self.cells ) do
@@ -357,18 +625,22 @@ function Container:update()
cell:update() cell:update()
end end
end end
if self.showScrollbar then
self:updateScrollbar()
end
end end
function Container:draw() function Container:draw()
if self.drawBounds then -- if self.drawBounds then
RL_DrawRectangleLines( self.bounds, self.color ) -- RL_DrawRectangle( self.bounds, self.color )
RL_DrawRectangleLines( { -- RL_DrawRectangleLines( {
self.bounds.x - self._scrollRect.x, -- self.bounds.x - self._scrollRect.x,
self.bounds.y - self._scrollRect.y, -- self.bounds.y - self._scrollRect.y,
self._scrollRect.width, -- self._scrollRect.width,
self._scrollRect.height, -- self._scrollRect.height,
}, RED ) -- }, RED )
end -- end
end end
function Container:delete() function Container:delete()
@@ -377,8 +649,11 @@ end
--Assingments. --Assingments.
Gui.label = Label Gui.text = Text
Gui.panel = Panel Gui.texture = Texture
Gui.shape = Shape
Gui.element = Element
Gui.container = Container Gui.container = Container
return Gui return Gui

View File

@@ -118,7 +118,7 @@ int lshapesDrawLineBezier( lua_State *L ) {
} }
/* /*
> success = RL_DrawLineBezier( Vector2 startPos, Vector2 endPos, Vector2 controlPos, float thickness, Color color ) > success = RL_DrawLineBezierQuad( Vector2 startPos, Vector2 endPos, Vector2 controlPos, float thickness, Color color )
Draw line using quadratic bezier curves with a control point Draw line using quadratic bezier curves with a control point
@@ -371,7 +371,7 @@ Draw ellipse
- Success return true - Success return true
*/ */
int lshapesDrawEllipse( lua_State *L ) { int lshapesDrawEllipse( lua_State *L ) {
if ( !lua_istable( L, -3 ) || !lua_isnumber( L, -2 ) || !lua_istable( L, -1 ) ) { if ( !lua_istable( L, -4 ) || !lua_isnumber( L, -3 ) || !lua_isnumber( L, -2 ) || !lua_istable( L, -1 ) ) {
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_DrawEllipse( Vector2 center, float radiusH, float radiusV, Color color )" ); TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_DrawEllipse( Vector2 center, float radiusH, float radiusV, Color color )" );
lua_pushboolean( L, false ); lua_pushboolean( L, false );
return 1; return 1;
@@ -399,7 +399,7 @@ Draw ellipse outline
- Success return true - Success return true
*/ */
int lshapesDrawEllipseLines( lua_State *L ) { int lshapesDrawEllipseLines( lua_State *L ) {
if ( !lua_istable( L, -3 ) || !lua_isnumber( L, -2 ) || !lua_istable( L, -1 ) ) { if ( !lua_istable( L, -4 ) || !lua_isnumber( L, -3 ) || !lua_isnumber( L, -2 ) || !lua_istable( L, -1 ) ) {
TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_DrawEllipseLines( Vector2 center, float radiusH, float radiusV, Color color )" ); TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_DrawEllipseLines( Vector2 center, float radiusH, float radiusV, Color color )" );
lua_pushboolean( L, false ); lua_pushboolean( L, false );
return 1; return 1;