Difference between revisions of "UI Buttons"

From GiderosMobile
m
(changed button with text class)
Line 1: Line 1:
 
__TOC__
 
__TOC__
  
<languages />
+
Here you will find various resources to help you create buttons in Gideros Studio.
  
<translate><!--T:1--> Here you will find various resources to help you create buttons in Gideros Studio.</translate>
+
'''note''':You may have to provide your own assets (fonts, gfx, …).
 
 
 
 
<translate><!--T:1--> '''note''':You may have to provide your own assets (fonts, gfx, …).</translate>
 
<br/>
 
  
 
=== <translate>Simple Button</translate> ===
 
=== <translate>Simple Button</translate> ===
Line 128: Line 124:
 
--end)
 
--end)
 
</source>
 
</source>
<br/>
 
  
=== <translate>Button with Text</translate> ===
+
=== <translate>Button with Text and/or Images</translate> ===
  
 
<source lang="lua">
 
<source lang="lua">
 +
--[[
 +
A Button class with text and/or images
 +
This code is MIT licensed, see http://www.opensource.org/licenses/mit-license.php
 +
mokalux
 +
v.1: 2020-03-02
 +
]]
 
ButtonText = Core.class(Sprite)
 
ButtonText = Core.class(Sprite)
  
function ButtonText:init(text, tfont, tcolor, tscalex, tscaley, upState, downState)
+
function ButtonText:init(xparams)
if text ~= nil then
+
-- the params
self.text = TextField.new(tfont, text, text) -- string
+
self.params = xparams or {}
self.text:setAnchorPoint(0.5, 0.5)
+
self.params.upstate = xparams.upstate or nil -- img path
self.text:setScale(tscalex or 1, tscaley or 1)
+
self.params.downstate = xparams.downstate or nil -- img path
self.text:setTextColor(tcolor or 0xFFFFFF)
+
self.params.imgscalex = xparams.imagescalex or nil -- number
self.textwidth = self.text:getWidth()
+
self.params.imgscaley = xparams.imagescaley or nil -- number
self.textheight = self.text:getHeight()
+
self.params.text = xparams.text or nil -- text
self:addChild(self.text)
+
self.params.font = xparams.font or nil -- ttf font path
 +
self.params.fontsize = xparams.fontsize or 16 -- number
 +
self.params.textcolorup = xparams.textcolorup or 0x0 -- color
 +
self.params.textcolordown = xparams.textcolordown or self.params.textcolorup -- color
 +
self.params.textscalex = xparams.textscalex or 1 -- number
 +
self.params.textscaley = xparams.textscaley or self.params.textscalex -- number
 +
-- let's go
 +
self.sprite = Sprite.new()
 +
self.sprite:setAnchorPoint(0.5,0.5)
 +
self:addChild(self.sprite)
 +
-- button has image?
 +
if self.params.upstate ~= nil then
 +
self.upstate = Bitmap.new(Texture.new(self.params.upstate))
 +
self.downstate = Bitmap.new(Texture.new(self.params.downstate or self.params.upstate))
 +
self.upstate:setAnchorPoint(0.5, 0.5)
 +
self.downstate:setAnchorPoint(0.5, 0.5)
 +
self.bmpwidth = self.upstate:getWidth()
 +
self.bmpheight = self.upstate:getHeight()
 +
self.sprite:addChild(self.upstate)
 +
self.sprite:addChild(self.downstate)
 +
self.hasbmp = true
 +
else
 +
self.hasbmp = false
 +
end
 +
-- button has text?
 +
if self.params.text ~= nil then
 +
self:setText(self.params.text)
 
self.hastext = true
 
self.hastext = true
 
else
 
else
 
self.hastext = false
 
self.hastext = false
 
end
 
end
 
+
-- warnings
if upState ~= nil then
+
if not self.hasbmp and not self.hastext then
self.upState = Bitmap.new(Texture.new(upState))-- png path
+
print("*** WARNING: BUTTONTEXT NEEDS AT LEAST SOME TEXT OR SOME BITMAP! ***")
self.downState = Bitmap.new(Texture.new(downState or upState)) -- png path
 
self.upState:setAnchorPoint(0.5, 0.5)
 
self.downState:setAnchorPoint(0.5, 0.5)
 
self.bmpwidth = self.upState:getWidth()
 
self.bmpheight = self.upState:getHeight()
 
self.hasbmp = true
 
else
 
self.hasbmp = false
 
 
end
 
end
 
+
-- update visual state
if not self.hastext and not self.hasbmp then
+
self.focus = false
print("*** ERROR: BUTTONTEXT NEEDS AT LEAST SOME TEXT OR SOME BITMAP! ***")
 
end
 
 
 
 
if self.hasbmp then
 
if self.hasbmp then
 
self:updateVisualState(false)
 
self:updateVisualState(false)
 
end
 
end
 
+
-- event listeners
self.focus = false
 
 
 
 
self:addEventListener(Event.MOUSE_DOWN, self.onMouseDown, self)
 
self:addEventListener(Event.MOUSE_DOWN, self.onMouseDown, self)
 
self:addEventListener(Event.MOUSE_MOVE, self.onMouseMove, self)
 
self:addEventListener(Event.MOUSE_MOVE, self.onMouseMove, self)
 
self:addEventListener(Event.MOUSE_UP, self.onMouseUp, self)
 
self:addEventListener(Event.MOUSE_UP, self.onMouseUp, self)
 
+
self:addEventListener(Event.MOUSE_HOVER, self.onMouseHover, self)
 +
-- mobile
 
self:addEventListener(Event.TOUCHES_BEGIN, self.onTouchesBegin, self)
 
self:addEventListener(Event.TOUCHES_BEGIN, self.onTouchesBegin, self)
 
self:addEventListener(Event.TOUCHES_MOVE, self.onTouchesMove, self)
 
self:addEventListener(Event.TOUCHES_MOVE, self.onTouchesMove, self)
Line 181: Line 196:
 
end
 
end
  
-- BUTTONTEXT FUNCTIONS
+
-- FUNCTIONS
function ButtonText:setTextView(xcolor, xscalex, xscaley)
+
function ButtonText:setText(xtext)
self.text:setTextColor(xcolor)
+
if self.params.font ~= nil then
self.text:setScale(xscalex, xscaley)
+
self.font = TTFont.new(self.params.font, self.params.fontsize)
end
+
end
 
+
if self.text == nil then
function ButtonText:setText(xtext, xupper)
+
self.text = TextField.new(self.font, xtext, xtext)
if xupper then
 
self.text:setText(string.upper(xtext))
 
 
else
 
else
 
self.text:setText(xtext)
 
self.text:setText(xtext)
 +
end
 +
self.text:setAnchorPoint(0.5, 0.5)
 +
self.text:setScale(self.params.textscalex, self.params.textscaley)
 +
self.text:setTextColor(self.params.textcolorup)
 +
self.textwidth = self.text:getWidth()
 +
self.textheight = self.text:getHeight()
 +
self.sprite:addChild(self.text)
 +
-- scale image
 +
if self.hasbmp then
 +
local sx = self.params.imgscalex or (self.textwidth/self.bmpwidth * 1.25)
 +
local sy = self.params.imgscaley or (self.textheight/self.bmpheight * 2)
 +
self.upstate:setScale(sx, sy)
 +
self.downstate:setScale(sx, sy)
 
end
 
end
 
end
 
end
  
 
function ButtonText:setTextColor(xcolor)
 
function ButtonText:setTextColor(xcolor)
self.text:setTextColor(xcolor or 0xff0000)
+
self.text:setTextColor(xcolor or 0x0)
 
end
 
end
  
function ButtonText:show()
+
-- VISUAL STATE
self:addChild(self.text)
+
function ButtonText:updateVisualState(xisdown)
if self.downState ~= nil then self:addChild(self.downState) end
 
if self.upState ~= nil then self:addChild(self.upState) end
 
end
 
 
 
function ButtonText:hide()
 
self:removeChild(self.text)
 
if self.downState ~= nil then self:removeChild(self.downState) end
 
if self.upState ~= nil then self:removeChild(self.upState) end
 
end
 
 
 
function ButtonText:updateVisualState(state)
 
 
if self.hasbmp then
 
if self.hasbmp then
-- if state is true show downState bitmap else show upState bitmap
+
if xisdown then
if state then
+
self.upstate:setVisible(false)
if self:contains(self.upState) then
+
self.downstate:setVisible(true)
self:removeChild(self.upState)
+
self.text:setTextColor(self.params.textcolordown)
end
 
 
if not self:contains(self.downState) then
 
self:addChild(self.downState)
 
end
 
 
 
if self:contains(self.text) then
 
self:addChild(self.text)
 
end
 
 
else
 
else
if self:contains(self.downState) then
+
self.upstate:setVisible(true)
self:removeChild(self.downState)
+
self.downstate:setVisible(false)
end
+
self.text:setTextColor(self.params.textcolorup)
 
if not self:contains(self.upState) then
 
self:addChild(self.upState)
 
end
 
 
 
if self:contains(self.text) then
 
self:addChild(self.text)
 
end
 
 
end
 
end
 
end
 
end
 
end
 
end
  
-- BUTTONTEXT LISTENERS
+
-- BUTTON LISTENERS
 +
-- mouse
 
function ButtonText:onMouseDown(event)
 
function ButtonText:onMouseDown(event)
 
if self:hitTestPoint(event.x, event.y) then
 
if self:hitTestPoint(event.x, event.y) then
Line 250: Line 249:
 
end
 
end
 
end
 
end
 
 
function ButtonText:onMouseMove(event)
 
function ButtonText:onMouseMove(event)
if self.focus then
+
if self:hitTestPoint(event.x, event.y) then
if not self:hitTestPoint(event.x, event.y) then
+
self.focus = true
self.focus = false;
+
self:updateVisualState(true)
self:updateVisualState(false)
+
end
end
+
if not self:hitTestPoint(event.x, event.y) then
event:stopPropagation()
+
self.focus = false
 +
self:updateVisualState(false)
 
end
 
end
 +
event:stopPropagation()
 
end
 
end
 
 
function ButtonText:onMouseUp(event)
 
function ButtonText:onMouseUp(event)
 
if self.focus then
 
if self.focus then
self.focus = false;
+
self.focus = false
 
self:updateVisualState(false)
 
self:updateVisualState(false)
 
self:dispatchEvent(Event.new("click"))
 
self:dispatchEvent(Event.new("click"))
Line 269: Line 268:
 
end
 
end
 
end
 
end
 
+
function ButtonText:onMouseHover(event)
 +
if self:hitTestPoint(event.x, event.y) then
 +
self.focus = true
 +
self:updateVisualState(true)
 +
else
 +
self.focus = false
 +
self:updateVisualState(false)
 +
end
 +
event:stopPropagation()
 +
end
 +
-- mobile
 
function ButtonText:onTouchesBegin(event)
 
function ButtonText:onTouchesBegin(event)
-- if button is on focus, stop propagation of touch events
 
 
if self.focus then
 
if self.focus then
 
event:stopPropagation()
 
event:stopPropagation()
 
end
 
end
 
end
 
end
 
 
function ButtonText:onTouchesMove(event)
 
function ButtonText:onTouchesMove(event)
-- if button is on focus, stop propagation of touch events
 
 
if self.focus then
 
if self.focus then
 
event:stopPropagation()
 
event:stopPropagation()
 
end
 
end
 
end
 
end
 
 
function ButtonText:onTouchesEnd(event)
 
function ButtonText:onTouchesEnd(event)
-- if button is on focus, stop propagation of touch events
 
 
if self.focus then
 
if self.focus then
 
event:stopPropagation()
 
event:stopPropagation()
 
end
 
end
 
end
 
end
 
 
function ButtonText:onTouchesCancel(event)
 
function ButtonText:onTouchesCancel(event)
-- if touches are cancelled, reset the state of the button
 
 
if self.focus then
 
if self.focus then
self.focus = false;
+
self.focus = false
 
self:updateVisualState(false)
 
self:updateVisualState(false)
 
event:stopPropagation()
 
event:stopPropagation()
 
end
 
end
 
end
 
end
 
+
--[[
---- USAGE
+
-- usage
--local btntext = ButtonText.new("Level 1", nil, 0xFF0000, 3, 3, "gfx/ui/button.png", nil)
+
local btn1 = ButtonText.new(
--btntext:setPosition(128, 128)
+
{text="Hello -- World", textcolorup=0xff00ff, textscalex=4,
--stage:addChild(btntext)
+
upstate="gfx/btns/mid_up.png", downstate="gfx/btns/mid_down.png"}
--btntext:addEventListener("click", function()
+
)
-- -- your code here
+
btn1:setText("START")
--end)
+
btn1:setPosition(128,128)
 +
stage:addChild(btn1)
 +
local x=0
 +
btn1:addEventListener("click", function()
 +
x+=1
 +
print("clicked: "..x)
 +
end)
 +
]]
 
</source>
 
</source>
<br/>
 
  
 
=== <translate>Toggle Button</translate> ===
 
=== <translate>Toggle Button</translate> ===
Line 439: Line 447:
 
--end)
 
--end)
 
</source>
 
</source>
<br/>
 
  
 
{{Welcome!}}
 
{{Welcome!}}

Revision as of 20:40, 2 March 2020

Here you will find various resources to help you create buttons in Gideros Studio.

note:You may have to provide your own assets (fonts, gfx, …).

Simple Button

--[[
A generic button class

This code is MIT licensed, see http://www.opensource.org/licenses/mit-license.php
(C) 2010 - 2011 Gideros Mobile 
]]

Button = Core.class(Sprite)

function Button:init(upState, downState) -- upstate and downstate are bitmaps
	self.upState = upState
	self.downState = downState
		
	self.focus = false

	-- set the visual state as "up"
	self:updateVisualState(false)

	-- register to all mouse and touch events
	self:addEventListener(Event.MOUSE_DOWN, self.onMouseDown, self)
	self:addEventListener(Event.MOUSE_MOVE, self.onMouseMove, self)
	self:addEventListener(Event.MOUSE_UP, self.onMouseUp, self)

	self:addEventListener(Event.TOUCHES_BEGIN, self.onTouchesBegin, self)
	self:addEventListener(Event.TOUCHES_MOVE, self.onTouchesMove, self)
	self:addEventListener(Event.TOUCHES_END, self.onTouchesEnd, self)
	self:addEventListener(Event.TOUCHES_CANCEL, self.onTouchesCancel, self)
end

function Button:onMouseDown(event)
	if self:hitTestPoint(event.x, event.y) then
		self.focus = true
		self:updateVisualState(true)
		event:stopPropagation()
	end
end

function Button:onMouseMove(event)
	if self.focus then
		if not self:hitTestPoint(event.x, event.y) then	
			self.focus = false
			self:updateVisualState(false)
		end
		event:stopPropagation()
	end
end

function Button:onMouseUp(event)
	if self.focus then
		self.focus = false
		self:updateVisualState(false)
		self:dispatchEvent(Event.new("click"))	-- button is clicked, dispatch "click" event
		event:stopPropagation()
	end
end

-- if button is on focus, stop propagation of touch events
function Button:onTouchesBegin(event)
	if self.focus then
		event:stopPropagation()
	end
end

-- if button is on focus, stop propagation of touch events
function Button:onTouchesMove(event)
	if self.focus then
		event:stopPropagation()
	end
end

-- if button is on focus, stop propagation of touch events
function Button:onTouchesEnd(event)
	if self.focus then
		event:stopPropagation()
	end
end

-- if touches are cancelled, reset the state of the button
function Button:onTouchesCancel(event)
	if self.focus then
		self.focus = false;
		self:updateVisualState(false)
		event:stopPropagation()
	end
end

-- if state is true show downState else show upState
function Button:updateVisualState(state)
	if state then
		if self:contains(self.upState) then
			self:removeChild(self.upState)
		end
		
		if not self:contains(self.downState) then
			self:addChild(self.downState)
		end
	else
		if self:contains(self.downState) then
			self:removeChild(self.downState)
		end
		
		if not self:contains(self.upState) then
			self:addChild(self.upState)
		end
	end
end

---- USAGE
---- clickable button (arrow button)
--local arrow = Texture.new("gfx/arrow_right.png")
--local arrow_pressed = Texture.new("gfx/arrow_right_down.png")
--local button = Button.new(Bitmap.new(arrow), Bitmap.new(arrow_pressed))
--button:addEventListener("click", function()
--	-- your code here
--end)

Button with Text and/or Images

--[[
A Button class with text and/or images
This code is MIT licensed, see http://www.opensource.org/licenses/mit-license.php
mokalux
v.1: 2020-03-02
]]
ButtonText = Core.class(Sprite)

function ButtonText:init(xparams)
	-- the params
	self.params = xparams or {}
	self.params.upstate = xparams.upstate or nil -- img path
	self.params.downstate = xparams.downstate or nil -- img path
	self.params.imgscalex = xparams.imagescalex or nil -- number
	self.params.imgscaley = xparams.imagescaley or nil -- number
	self.params.text = xparams.text or nil -- text
	self.params.font = xparams.font or nil -- ttf font path
	self.params.fontsize = xparams.fontsize or 16 -- number
	self.params.textcolorup = xparams.textcolorup or 0x0 -- color
	self.params.textcolordown = xparams.textcolordown or self.params.textcolorup -- color
	self.params.textscalex = xparams.textscalex or 1 -- number
	self.params.textscaley = xparams.textscaley or self.params.textscalex -- number
	-- let's go
	self.sprite = Sprite.new()
	self.sprite:setAnchorPoint(0.5,0.5)
	self:addChild(self.sprite)
	-- button has image?
	if self.params.upstate ~= nil then
		self.upstate = Bitmap.new(Texture.new(self.params.upstate))
		self.downstate = Bitmap.new(Texture.new(self.params.downstate or self.params.upstate))
		self.upstate:setAnchorPoint(0.5, 0.5)
		self.downstate:setAnchorPoint(0.5, 0.5)
		self.bmpwidth = self.upstate:getWidth()
		self.bmpheight = self.upstate:getHeight()
		self.sprite:addChild(self.upstate)
		self.sprite:addChild(self.downstate)
		self.hasbmp = true
	else
		self.hasbmp = false
	end
	-- button has text?
	if self.params.text ~= nil then
		self:setText(self.params.text)
		self.hastext = true
	else
		self.hastext = false
	end
	-- warnings
	if not self.hasbmp and not self.hastext then
		print("*** WARNING: BUTTONTEXT NEEDS AT LEAST SOME TEXT OR SOME BITMAP! ***")
	end
	-- update visual state
	self.focus = false
	if self.hasbmp then
		self:updateVisualState(false)
	end
	-- event listeners
	self:addEventListener(Event.MOUSE_DOWN, self.onMouseDown, self)
	self:addEventListener(Event.MOUSE_MOVE, self.onMouseMove, self)
	self:addEventListener(Event.MOUSE_UP, self.onMouseUp, self)
	self:addEventListener(Event.MOUSE_HOVER, self.onMouseHover, self)
	-- mobile
	self:addEventListener(Event.TOUCHES_BEGIN, self.onTouchesBegin, self)
	self:addEventListener(Event.TOUCHES_MOVE, self.onTouchesMove, self)
	self:addEventListener(Event.TOUCHES_END, self.onTouchesEnd, self)
	self:addEventListener(Event.TOUCHES_CANCEL, self.onTouchesCancel, self)
end

-- FUNCTIONS
function ButtonText:setText(xtext)
	if self.params.font ~= nil then
		self.font = TTFont.new(self.params.font, self.params.fontsize)
	end
	if self.text == nil then
		self.text = TextField.new(self.font, xtext, xtext)
	else
		self.text:setText(xtext)
	end
	self.text:setAnchorPoint(0.5, 0.5)
	self.text:setScale(self.params.textscalex, self.params.textscaley)
	self.text:setTextColor(self.params.textcolorup)
	self.textwidth = self.text:getWidth()
	self.textheight = self.text:getHeight()
	self.sprite:addChild(self.text)
	-- scale image
	if self.hasbmp then
		local sx = self.params.imgscalex or (self.textwidth/self.bmpwidth * 1.25)
		local sy = self.params.imgscaley or (self.textheight/self.bmpheight * 2)
		self.upstate:setScale(sx, sy)
		self.downstate:setScale(sx, sy)
	end
end

function ButtonText:setTextColor(xcolor)
	self.text:setTextColor(xcolor or 0x0)
end

-- VISUAL STATE
function ButtonText:updateVisualState(xisdown)
	if self.hasbmp then
		if xisdown then
			self.upstate:setVisible(false)
			self.downstate:setVisible(true)
			self.text:setTextColor(self.params.textcolordown)
		else
			self.upstate:setVisible(true)
			self.downstate:setVisible(false)
			self.text:setTextColor(self.params.textcolorup)
		end
	end
end

-- BUTTON LISTENERS
-- mouse
function ButtonText:onMouseDown(event)
	if self:hitTestPoint(event.x, event.y) then
		self.focus = true
		self:updateVisualState(true)
		event:stopPropagation()
	end
end
function ButtonText:onMouseMove(event)
	if self:hitTestPoint(event.x, event.y) then
		self.focus = true
		self:updateVisualState(true)
	end
	if not self:hitTestPoint(event.x, event.y) then
		self.focus = false
		self:updateVisualState(false)
	end
	event:stopPropagation()
end
function ButtonText:onMouseUp(event)
	if self.focus then
		self.focus = false
		self:updateVisualState(false)
		self:dispatchEvent(Event.new("click"))
		event:stopPropagation()
	end
end
function ButtonText:onMouseHover(event)
	if self:hitTestPoint(event.x, event.y) then
		self.focus = true
		self:updateVisualState(true)
	else
		self.focus = false
		self:updateVisualState(false)
	end
	event:stopPropagation()
end
-- mobile
function ButtonText:onTouchesBegin(event)
	if self.focus then
		event:stopPropagation()
	end
end
function ButtonText:onTouchesMove(event)
	if self.focus then
		event:stopPropagation()
	end
end
function ButtonText:onTouchesEnd(event)
	if self.focus then
		event:stopPropagation()
	end
end
function ButtonText:onTouchesCancel(event)
	if self.focus then
		self.focus = false
		self:updateVisualState(false)
		event:stopPropagation()
	end
end
--[[
-- usage
local btn1 = ButtonText.new(
	{text="Hello -- World", textcolorup=0xff00ff, textscalex=4,
	upstate="gfx/btns/mid_up.png", downstate="gfx/btns/mid_down.png"}
)
btn1:setText("START")
btn1:setPosition(128,128)
stage:addChild(btn1)
local x=0
btn1:addEventListener("click", function()
	x+=1
	print("clicked: "..x)
end)
]]

Toggle Button

--[[
ToggleButton v1.0
 
v1.0 - 19.3.2013
Initial release
 
Free to modify and use!
Matjaž Bravc
]]

ToggleButton = Core.class(Sprite)

function ToggleButton:init(upState, downState)
	self.upState = upState
	self.downState = downState

	self.pressed = false
	self.focus = false

	self:updateVisualState(self.pressed)

	self:addEventListener(Event.MOUSE_DOWN, self.onMouseDown, self)
	self:addEventListener(Event.MOUSE_MOVE, self.onMouseMove, self)
	self:addEventListener(Event.MOUSE_UP, self.onMouseUp, self)

	self:addEventListener(Event.TOUCHES_BEGIN, self.onTouchesBegin, self)
	self:addEventListener(Event.TOUCHES_MOVE, self.onTouchesMove, self)
	self:addEventListener(Event.TOUCHES_END, self.onTouchesEnd, self)
	self:addEventListener(Event.TOUCHES_CANCEL, self.onTouchesCancel, self)
end

function ToggleButton:onMouseDown(event)
	if self:hitTestPoint(event.x, event.y) then
		self.focus = true
		event:stopPropagation()
	end
end

function ToggleButton:onMouseMove(event)
	if self.focus then
		if not self:hitTestPoint(event.x, event.y) then
			self.focus = false
		end
		event:stopPropagation()
	end
end

function ToggleButton:onMouseUp(event)
	if self.focus then
		self.focus = false
		self:updateVisualState(not self.pressed)
		self:dispatchEvent(Event.new("click"))
		event:stopPropagation()
	end
end

-- if button is on focus, stop propagation of touch events
function ToggleButton:onTouchesBegin(event)
	if self.focus then
		event:stopPropagation()
	end
end

-- if button is on focus, stop propagation of touch events
function ToggleButton:onTouchesMove(event)
	if self.focus then
		event:stopPropagation()
	end
end

-- if button is on focus, stop propagation of touch events
function ToggleButton:onTouchesEnd(event)
	if self.focus then
		event:stopPropagation()
	end
end

-- if touches are cancelled, reset the state of the button
function ToggleButton:onTouchesCancel(event)
	if self.focus then
		self.focus = false
		self:updateVisualState(false) -- XXX
		event:stopPropagation()
	end
end

-- if state is true show downState else show upState
function ToggleButton:updateVisualState(state)
	self.pressed = state

	-- Modification to allow single state buttons (checkboxes etc)
	if not self.downState then
		if not self:contains(self.upState) then
			self:addChild(self.upState)
		end
		return
	end

	if self.pressed then
		if self:contains(self.upState) then
			self:removeChild(self.upState)
		end
		if not self:contains(self.downState) then
			self:addChild(self.downState)
		end
	else
		if self:contains(self.downState) then
			self:removeChild(self.downState)
		end
		if not self:contains(self.upState) then
			self:addChild(self.upState)
		end
	end
end

function ToggleButton:isPressed()
	return self.pressed
end

---- USAGE
--local btntoggle = ToggleButton.new(Bitmap.new(Texture.new("gfx/off.png", true)), Bitmap.new(Texture.new("gfx/on.png", true)))
--stage:addChild(btntoggle)
--btntoggle:addEventListener("click", function()
--	print(btntoggle:isPressed())
--end)

Template:Welcome!