Files

283 lines
7.8 KiB
Lua

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:setToTop()
object.dragPos = Vec2:newT( 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:newT( RL.LIGHTGRAY ),
} ) )
object.handle:add( Gui.texture:new( {
bounds = object.handle.bounds:clone(),
texture = BorderTexture,
HAling = Gui.ALING.CENTER,
VAling = Gui.ALING.CENTER,
color = Color:newT( RL.LIGHTGRAY ),
nPatchInfo = { source = { 0, 0, 24, 24 }, left = 8, top = 8, right = 8, bottom = 8, layout = RL.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( this ) this.items[1].color = Color:newT( RL.WHITE ) end,
notMouseOver = function( this ) this.items[1].color = Color:newT( RL.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:newT( RL.GRAY ),
} ) )
object.panel:add( Gui.texture:new( {
bounds = object.panel.bounds:clone(),
texture = BorderTexture,
HAling = Gui.ALING.CENTER,
VAling = Gui.ALING.CENTER,
color = Color:newT( RL.LIGHTGRAY ),
nPatchInfo = { source = { 0, 0, 24, 24 }, left = 8, top = 8, right = 8, bottom = 8, layout = RL.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:newT( RL.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:newT( RL.WHITE ) end,
notMouseOver = function( self ) self.color = Color:newT( RL.LIGHTGRAY ) 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:newT( 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:setToTop()
self.panel:setToTop()
for _, button in ipairs( self.buttons ) do
button:setToTop()
end
self.handle:setToTop()
self.closeButton:setToTop()
self.display:setToTop()
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
return Calculator