From 79fbb36d2a4d73001c446f75b3b87dc84f1605b6 Mon Sep 17 00:00:00 2001 From: jussi Date: Wed, 7 Dec 2022 22:27:24 +0200 Subject: [PATCH] ReiLuaGui calculator example. --- API.md | 2 +- doc_parser.lua | 2 +- examples/ReiLuaGui/main.lua | 15 +- examples/ReiLuaGui_calculator/main.lua | 354 ++++++++++++++++++++++++ examples/n-patches/main.lua | 2 +- examples/resources/images/LICENCE | 3 + examples/resources/images/cancel.png | Bin 0 -> 8126 bytes examples/resources/images/n-patch.png | Bin 6021 -> 0 bytes examples/resources/images/ui_bgr.png | Bin 0 -> 2167 bytes examples/resources/images/ui_border.png | Bin 0 -> 1170 bytes examples/resources/lib/gui.lua | 34 ++- 11 files changed, 392 insertions(+), 20 deletions(-) create mode 100644 examples/ReiLuaGui_calculator/main.lua create mode 100644 examples/resources/images/cancel.png delete mode 100644 examples/resources/images/n-patch.png create mode 100644 examples/resources/images/ui_bgr.png create mode 100644 examples/resources/images/ui_border.png diff --git a/API.md b/API.md index b9741be..5b14782 100644 --- a/API.md +++ b/API.md @@ -1067,7 +1067,7 @@ int id. Basic Sound source and buffer --- -> NPatchInfo = { { 0, 0, 24, 24 }, 0, 0, 0, 0, NPATCH_NINE_PATCH } or { source = { 0, 0, 24, 24 }, left = 0, top = 0, right = 0, bottom = 0, layout = NPATCH_NINE_PATCH } +> NPatchInfo = { { 0, 0, 24, 24 }, 8, 8, 8, 8, NPATCH_NINE_PATCH } or { source = { 0, 0, 24, 24 }, left = 8, top = 8, right = 8, bottom = 8, layout = NPATCH_NINE_PATCH } { Rectangle source, int left, int top, int right, int bottom, int layout }. { Texture source rectangle, Left border offset, Top border offset, Right border offset, Bottom border offset, Layout of the n-patch: 3x3, 1x3 or 3x1 } diff --git a/doc_parser.lua b/doc_parser.lua index d7383e4..410eb05 100644 --- a/doc_parser.lua +++ b/doc_parser.lua @@ -145,7 +145,7 @@ apiFile:write( "\n> BoundingBox = { { 0.0, 0.0, 0.0 }, { 1.0, 1.0, 1.0 } }\n\ { min, max }. Bounding box type for 3d mesh\n\n---\n" ) apiFile:write( "\n> Sound = SoundId\n\ int id. Basic Sound source and buffer\n\n---\n" ) -apiFile:write( "\n> NPatchInfo = { { 0, 0, 24, 24 }, 0, 0, 0, 0, NPATCH_NINE_PATCH } or { source = { 0, 0, 24, 24 }, left = 0, top = 0, right = 0, bottom = 0, layout = NPATCH_NINE_PATCH }\n\ +apiFile:write( "\n> NPatchInfo = { { 0, 0, 24, 24 }, 8, 8, 8, 8, NPATCH_NINE_PATCH } or { source = { 0, 0, 24, 24 }, left = 8, top = 8, right = 8, bottom = 8, layout = NPATCH_NINE_PATCH }\n\ { Rectangle source, int left, int top, int right, int bottom, int layout }.\ { Texture source rectangle, Left border offset, Top border offset, Right border offset, Bottom border offset, Layout of the n-patch: 3x3, 1x3 or 3x1 }\n\n---\n" ) apiFile:write( "\n> ModelAnimations = ModelAnimationsId\n\ diff --git a/examples/ReiLuaGui/main.lua b/examples/ReiLuaGui/main.lua index 240e76e..9890646 100644 --- a/examples/ReiLuaGui/main.lua +++ b/examples/ReiLuaGui/main.lua @@ -10,6 +10,7 @@ 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" ) +local borderTexture = RL_LoadTexture( RL_GetBasePath().."../resources/images/ui_border.png" ) local textInput RL_GenTextureMipmaps( circleTexture ) @@ -29,8 +30,8 @@ function initGui() -- HAling = Gui.ALING.CENTER, -- type = Gui.CONTAINER.HORIZONTAL, -- VAling = Gui.ALING.CENTER, - type = Gui.CONTAINER.GRID, - columns = 2, + -- type = Gui.CONTAINER.GRID, + -- columns = 2, -- rows = 2, scrollable = true, showScrollbar = true, @@ -50,6 +51,16 @@ function initGui() } ) dog:add( Gui.text:new( { text = "Dog", HAling = Gui.ALING.LEFT } ) ) + + dog:add( Gui.texture:new( { + bounds = dog.bounds:clone(), + texture = borderTexture, + HAling = Gui.ALING.CENTER, + VAling = Gui.ALING.CENTER, + visible = true, + nPatchInfo = { source = { 0, 0, 24, 24 }, left = 8, top = 8, right = 8, bottom = 8, layout = NPATCH_NINE_PATCH }, + } ) ) + 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 } ) ) diff --git a/examples/ReiLuaGui_calculator/main.lua b/examples/ReiLuaGui_calculator/main.lua new file mode 100644 index 0000000..57ba9a1 --- /dev/null +++ b/examples/ReiLuaGui_calculator/main.lua @@ -0,0 +1,354 @@ +package.path = package.path..";"..RL_GetBasePath().."../resources/lib/?.lua" + +util = require( "utillib" ) +Vec2 = require( "vector2" ) +Rect = require( "rectangle" ) +Color = require( "color" ) +Gui = require( "gui" ) + +-- Textures. + +local cancelTexture = RL_LoadTexture( RL_GetBasePath().."../resources/images/cancel.png" ) +local borderTexture = RL_LoadTexture( RL_GetBasePath().."../resources/images/ui_border.png" ) +local bgrTexture = RL_LoadTexture( RL_GetBasePath().."../resources/images/ui_bgr.png" ) + +RL_GenTextureMipmaps( cancelTexture ) +RL_GenTextureMipmaps( bgrTexture ) + +RL_SetTextureFilter( cancelTexture, TEXTURE_FILTER_TRILINEAR ) +RL_SetTextureFilter( bgrTexture, TEXTURE_FILTER_TRILINEAR ) + +RL_SetTextureWrap( borderTexture, TEXTURE_WRAP_REPEAT ) +RL_SetTextureWrap( bgrTexture, TEXTURE_WRAP_REPEAT ) + +-- Calculator definition. + +Calculator = {} +Calculator.__index = Calculator + +function Calculator:new( pos ) + pos = pos or Vec2:new( 0, 0 ) + + local object = setmetatable( {}, self ) + + object.HANDLE_HIGHT = 32 + object.DISPLAY_HIGHT = 40 + object.OPERATIONS = { ADD = 0, SUB = 1, MUL = 2, DIV = 3 } + + object.windowRect = Rect:new( pos.x, pos.y, 196, 244 ) + object.dragPos = Vec2:new( 0, 0 ) + + -- Handle + + object.handle = Gui.element:new( { + bounds = Rect:new( 0, 0, object.windowRect.width, object.HANDLE_HIGHT ), + padding = 10, + onClicked = function() + object:set2Top() + object.dragPos = Vec2:new( RL_GetMousePosition() ) - Vec2:new( object.handle.bounds.x, object.handle.bounds.y ) + Gui.heldCallback = function() object:drag() end + end, + } ) + + object.handle:add( Gui.texture:new( { + bounds = object.handle.bounds:clone(), + texture = bgrTexture, + HAling = Gui.ALING.CENTER, + VAling = Gui.ALING.CENTER, + color = Color:new( LIGHTGRAY ), + } ) ) + + object.handle:add( Gui.texture:new( { + bounds = object.handle.bounds:clone(), + texture = borderTexture, + HAling = Gui.ALING.CENTER, + VAling = Gui.ALING.CENTER, + color = Color:new( LIGHTGRAY ), + nPatchInfo = { source = { 0, 0, 24, 24 }, left = 8, top = 8, right = 8, bottom = 8, layout = NPATCH_NINE_PATCH }, + } ) ) + + object.handle:add( Gui.text:new( { text = "Calculator", fontSize = 20, VAling = Gui.ALING.CENTER } ) ) + + -- Close button. + + object.closeButton = Gui.element:new( { + bounds = Rect:new( 0, 0, object.HANDLE_HIGHT, object.HANDLE_HIGHT ), + onClicked = function() + object:setVisible( false ) + end, + onMouseOver = function( self ) self.items[1].color = Color:new( WHITE ) end, + notMouseOver = function( self ) self.items[1].color = Color:new( BLACK ) end, + } ) + + object.closeButton:add( Gui.texture:new( { + bounds = object.closeButton.bounds:clone(), + texture = cancelTexture, + HAling = Gui.ALING.CENTER, + VAling = Gui.ALING.CENTER, + } ) ) + + -- Panel. + + object.panel = Gui.element:new( { + bounds = Rect:new( 0, 0, object.windowRect.width, object.windowRect.height - object.HANDLE_HIGHT ), + } ) + + object.panel:add( Gui.texture:new( { + bounds = object.panel.bounds:clone(), + texture = bgrTexture, + HAling = Gui.ALING.CENTER, + VAling = Gui.ALING.CENTER, + color = Color:new( GRAY ), + } ) ) + + object.panel:add( Gui.texture:new( { + bounds = object.panel.bounds:clone(), + texture = borderTexture, + HAling = Gui.ALING.CENTER, + VAling = Gui.ALING.CENTER, + color = Color:new( LIGHTGRAY ), + nPatchInfo = { source = { 0, 0, 24, 24 }, left = 8, top = 8, right = 8, bottom = 8, layout = NPATCH_NINE_PATCH }, + } ) ) + + -- Display. + + object.display = Gui.element:new( { + bounds = Rect:new( 0, 0, object.windowRect.width - 16, object.DISPLAY_HIGHT ), + padding = 10, + drawBounds = true, + color = Color:new( WHITE ) + } ) + + object.display:add( Gui.text:new( { text = "", fontSize = 30, VAling = Gui.ALING.CENTER, maxTextLen = 8 } ) ) + + -- Buttons. + + local buttonStrings = { "7", "8", "9", "/", "4", "5", "6", "*", "1", "2", "3", "-", "0", "C", "=", "+" } + object.buttons = {} + + for y = 0, 3 do + for x = 0, 3 do + local i = x + y * 4 + + table.insert( object.buttons, Gui.element:new( { + bounds = Rect:new( 0, 0, 40, 32 ), + drawBounds = true, + onMouseOver = function( self ) self.color = Color:new( LIGHTGRAY ) end, + notMouseOver = function( self ) self.color = Color:new( GRAY ) end, + } ) ) + + object.buttons[ #object.buttons ].pos = Vec2:new( 8 + x * 46, object.HANDLE_HIGHT + object.DISPLAY_HIGHT + 16 + y * 38 ) + object.buttons[ #object.buttons ]:add( Gui.text:new( { text = buttonStrings[i+1], fontSize = 30, HAling = Gui.ALING.CENTER, VAling = Gui.ALING.CENTER } ) ) + + if buttonStrings[i+1] == "/" then + object.buttons[ #object.buttons ].onClicked = function() object:setOperation( object.OPERATIONS.DIV ) end + elseif buttonStrings[i+1] == "*" then + object.buttons[ #object.buttons ].onClicked = function() object:setOperation( object.OPERATIONS.MUL ) end + elseif buttonStrings[i+1] == "-" then + object.buttons[ #object.buttons ].onClicked = function() object:setOperation( object.OPERATIONS.SUB ) end + elseif buttonStrings[i+1] == "+" then + object.buttons[ #object.buttons ].onClicked = function() object:setOperation( object.OPERATIONS.ADD ) end + elseif buttonStrings[i+1] == "C" then + object.buttons[ #object.buttons ].onClicked = function() object:clear() end + elseif buttonStrings[i+1] == "=" then + object.buttons[ #object.buttons ].onClicked = function() object:equals() end + else + object.buttons[ #object.buttons ].onClicked = function() object:addValue( tonumber( buttonStrings[i+1] ) ) end + end + end + end + + -- Calculator variables. + + object.value1 = "" + object.value2 = "" + object.operation = nil + + -- Set position. + + object:setPosition( Vec2:new( object.windowRect.x, object.windowRect.y ) ) + + return object +end + +function Calculator:setPosition( pos ) + self.windowRect.x = pos.x + self.windowRect.y = pos.y + + self.handle:setPosition( pos ) + self.closeButton:setPosition( Vec2:new( pos.x + self.windowRect.width - self.HANDLE_HIGHT, pos.y ) ) + self.panel:setPosition( Vec2:new( pos.x, pos.y + self.HANDLE_HIGHT ) ) + self.display:setPosition( Vec2:new( pos.x + 8, pos.y + self.HANDLE_HIGHT + 8 ) ) + + for _, button in ipairs( self.buttons ) do + button:setPosition( pos + button.pos ) + end +end + +function Calculator:drag() + local mousePos = Vec2:new( RL_GetMousePosition() ) + local winPos = Vec2:new( self.handle.bounds.x, self.handle.bounds.y ) + + self:setPosition( mousePos - self.dragPos ) +end + +function Calculator:setVisible( visible ) + self.handle.visible = visible + self.handle.disabled = not visible + + self.closeButton.visible = visible + self.closeButton.disabled = not visible + + self.panel.visible = visible + self.panel.disabled = not visible + + self.display.visible = visible + self.display.disabled = not visible + + for _, button in ipairs( self.buttons ) do + button.visible = visible + button.disabled = not visible + end +end + +function Calculator:set2Top() + self.panel:set2Top() + + for _, button in ipairs( self.buttons ) do + button:set2Top() + end + + self.handle:set2Top() + self.closeButton:set2Top() + self.display:set2Top() +end + +function Calculator:addValue( value ) + if self.operation == nil then + self.value1 = self.value1..value + else + self.value2 = self.value2..value + end + + self:updateDisplay() +end + +function Calculator:setOperation( operation ) + if self.value1 ~= "" then + self.operation = operation + end + + if self.value2 ~= "" then + self:equals() + end + + self:updateDisplay() +end + +function Calculator:clear() + self.value1 = "" + self.value2 = "" + self.operation = nil + + self:updateDisplay() +end + +function Calculator:updateDisplay( setText ) + local text = setText or "" + + if self.value1 ~= "" then + text = self.value1 + end + + if self.operation ~= nil then + if self.operation == self.OPERATIONS.ADD then + text = text.." + " + elseif self.operation == self.OPERATIONS.SUB then + text = text.." - " + elseif self.operation == self.OPERATIONS.MUL then + text = text.." * " + elseif self.operation == self.OPERATIONS.DIV then + text = text.." / " + end + end + + if self.value2 ~= "" then + text = text..self.value2 + end + + self.display.items[1]:set( text ) +end + +function Calculator:equals() + local result = 0 + + if self.operation == self.OPERATIONS.ADD then + result = tonumber( self.value1 ) + tonumber( self.value2 ) + elseif self.operation == self.OPERATIONS.SUB then + result = tonumber( self.value1 ) - tonumber( self.value2 ) + elseif self.operation == self.OPERATIONS.MUL then + result = tonumber( self.value1 ) * tonumber( self.value2 ) + elseif self.operation == self.OPERATIONS.DIV then + if tonumber( self.value2 ) == 0 then + self:clear() + self:updateDisplay( "Error" ) + + return + else + result = tonumber( self.value1 ) / tonumber( self.value2 ) + end + end + + self:clear() + self.value1 = tostring( result ) + self:updateDisplay() +end + +-- End of calculator definition. + +local calculator = nil +local calculator2 = nil +local showButton = nil + +function initGui() + showButton = Gui.element:new( { + bounds = Rect:new( 0, 0, 96, 32 ), + drawBounds = true, + onClicked = function() + calculator:setVisible( true ) + calculator2:setVisible( true ) + end, + onMouseOver = function( self ) self.color = Color:new( LIGHTGRAY ) end, + notMouseOver = function( self ) self.color = Color:new( GRAY ) end, + } ) + + showButton:add( Gui.text:new( { text = "Show", VAling = Gui.ALING.CENTER, HAling = Gui.ALING.CENTER } ) ) + + calculator = Calculator:new( Vec2:new( 128, 96 ) ) + calculator2 = Calculator:new( Vec2:new( 340, 96 ) ) +end + +function init() + local monitor = 0 + local mPos = RL_GetMonitorPosition( monitor ) + local mSize = RL_GetMonitorSize( monitor ) + winSize = RL_GetWindowSize() + + RL_SetWindowTitle( "Calculator" ) + 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 ) + Gui.process( Vec2:new( RL_GetMousePosition() ) ) +end + +function draw() + RL_ClearBackground( RAYWHITE ) + + Gui.draw() +end diff --git a/examples/n-patches/main.lua b/examples/n-patches/main.lua index 045bb84..91ea409 100644 --- a/examples/n-patches/main.lua +++ b/examples/n-patches/main.lua @@ -4,7 +4,7 @@ local origin = { 0.0, 0.0 } -- local ninePatchInfo = { { 0.0, 0.0, 24.0, 24.0 }, 8, 8, 8, 8, NPATCH_NINE_PATCH } local ninePatchInfo = { source = { 0, 0, 24.0, 24.0 }, left = 8, top = 8, right = 8, bottom = 8, layout = NPATCH_NINE_PATCH } -local nPatchTexture = RL_LoadTexture( RL_GetBasePath().."../resources/images/n-patch.png" ) +local nPatchTexture = RL_LoadTexture( RL_GetBasePath().."../resources/images/ui_border.png" ) function init() RL_SetWindowTitle( "N-Patches" ) diff --git a/examples/resources/images/LICENCE b/examples/resources/images/LICENCE index a1d1f46..bfe263f 100644 --- a/examples/resources/images/LICENCE +++ b/examples/resources/images/LICENCE @@ -4,6 +4,9 @@ arcade_platformerV2.png GrafxKid CC0 https://opengameart.org/content/ar apple.png Jussi Viitala CC0 grass.png Jussi Viitala CC0 snake.png Jussi Viitala CC0 +ui_border.png Jussi Viitala CC0 +ui_bgr.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 +cancel.png Sbed Creative Commons 3.0 https://game-icons.net Resized \ No newline at end of file diff --git a/examples/resources/images/cancel.png b/examples/resources/images/cancel.png new file mode 100644 index 0000000000000000000000000000000000000000..1468f67930495e8e77d4bfc3207d66c1f0d3d189 GIT binary patch literal 8126 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 literal 0 HcmV?d00001 diff --git a/examples/resources/images/n-patch.png b/examples/resources/images/n-patch.png deleted file mode 100644 index c6e738bfca9356b047df2bc57fd9d33d3b2f638b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6021 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 diff --git a/examples/resources/images/ui_bgr.png b/examples/resources/images/ui_bgr.png new file mode 100644 index 0000000000000000000000000000000000000000..d7cbec69b36a314342377f042e53b4acadcabcff GIT binary patch literal 2167 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 literal 0 HcmV?d00001 diff --git a/examples/resources/lib/gui.lua b/examples/resources/lib/gui.lua index 341489b..c7609c1 100644 --- a/examples/resources/lib/gui.lua +++ b/examples/resources/lib/gui.lua @@ -3,8 +3,6 @@ Rect = require( "rectangle" ) Vec2 = require( "vector2" ) Color = require( "color" ) --- NOTE!!! Work in progress! Do not use. - --[[ To add repeat inputs to the keys pressed buffer, you could add GLFW_REPEAT in railib rcore.c in function "KeyCallback" by changing: @@ -43,15 +41,16 @@ Gui = { mouseButton = MOUSE_BUTTON_LEFT, font = 0, - fontSize = 30, + fontSize = 20, padding = 2, spacing = 4, scrollbarWidth = 8, scrollAmount = 10, + heldCallback = nil, + _cells = {}, _mousePos = Vec2:new( 0, 0 ), -- Last mouse position that was passed to Gui.process. - _heldCallback = nil, _inputElement = nil, _inputItem = nil, -- Must be type Text. } @@ -119,11 +118,11 @@ function Gui.process( mousePosition ) Gui._mousePos = mousePosition - if Gui._heldCallback ~= nil then + if Gui.heldCallback ~= nil then if RL_IsMouseButtonDown( Gui.mouseButton ) then - Gui._heldCallback() + Gui.heldCallback() else - Gui._heldCallback = nil + Gui.heldCallback = nil end return @@ -265,7 +264,7 @@ function Text:draw() return end - RL_DrawText( self.font, self.text, { self._prante.bounds.x + self.bounds.x, self._prante.bounds.y + self.bounds.y }, self.fontSize, self.spacing, self.color ) + 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. @@ -285,6 +284,7 @@ function Texture:new( set ) object.origin = setProperty( set, "origin", Vec2:new( 0, 0 ) ) object.rotation = setProperty( set, "rotation", 0 ) object.color = setProperty( set, "color", Color:new( WHITE ) ) + object.nPatchInfo = setProperty( set, "nPatchInfo", nil ) object.visible = setProperty( set, "visible", true ) object._parent = nil @@ -319,13 +319,17 @@ function Texture:draw() end local dst = { - self.bounds.x + self._prante.bounds.x, - self.bounds.y + self._prante.bounds.y, + 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 ) + if self.nPatchInfo ~= nil then + RL_DrawTextureNPatch( self.texture, self.nPatchInfo, dst, self.origin, self.rotation, self.color ) + else + RL_DrawTexturePro( self.texture, self.source, dst, self.origin, self.rotation, self.color ) + end end -- Shape. @@ -385,7 +389,7 @@ function Shape:draw() return end - local pos = Vec2:new( self._prante.bounds.x, self._prante.bounds.y ) + 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 ) @@ -472,7 +476,7 @@ end function Element:add( item ) table.insert( self.items, item ) - item._prante = self + item._parent = self self:update() end @@ -686,7 +690,7 @@ function Container:update() padding = 0, drawBounds = true, color = Color:new( GRAY ), - onClicked = function() Gui._heldCallback = function() self:mouseScroll( Vec2:new( 0, 1 ) ) end end, + onClicked = function() Gui.heldCallback = function() self:mouseScroll( Vec2:new( 0, 1 ) ) end end, } ) self._VScrollbar:add( Gui.shape:new( { @@ -703,7 +707,7 @@ function Container:update() padding = 0, drawBounds = true, color = Color:new( GRAY ), - onClicked = function() Gui._heldCallback = function() self:mouseScroll( Vec2:new( 1, 0 ) ) end end, + onClicked = function() Gui.heldCallback = function() self:mouseScroll( Vec2:new( 1, 0 ) ) end end, } ) self._HScrollbar:add( Gui.shape:new( {