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