Difference between revisions of "UI Buttons"
From GiderosMobile
m |
(changed button with text class) |
||
Line 1: | Line 1: | ||
__TOC__ | __TOC__ | ||
− | + | 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, …). | |
− | |||
− | |||
− | |||
− | |||
=== <translate>Simple Button</translate> === | === <translate>Simple Button</translate> === | ||
Line 128: | Line 124: | ||
--end) | --end) | ||
</source> | </source> | ||
− | |||
− | === <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, | + | function ButtonText:init(xparams) |
− | if | + | -- the params |
− | self. | + | self.params = xparams or {} |
− | self. | + | self.params.upstate = xparams.upstate or nil -- img path |
− | self. | + | self.params.downstate = xparams.downstate or nil -- img path |
− | self. | + | self.params.imgscalex = xparams.imagescalex or nil -- number |
− | self. | + | self.params.imgscaley = xparams.imagescaley or nil -- number |
− | self. | + | self.params.text = xparams.text or nil -- text |
− | self: | + | 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 not self.hasbmp and not self.hastext then | |
− | + | print("*** WARNING: BUTTONTEXT NEEDS AT LEAST SOME TEXT OR SOME BITMAP! ***") | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
end | end | ||
− | + | -- update visual state | |
− | + | self.focus = false | |
− | |||
− | |||
− | |||
if self.hasbmp then | if self.hasbmp then | ||
self:updateVisualState(false) | self:updateVisualState(false) | ||
end | end | ||
− | + | -- event listeners | |
− | |||
− | |||
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 | ||
− | -- | + | -- FUNCTIONS |
− | function ButtonText: | + | function ButtonText:setText(xtext) |
− | self. | + | if self.params.font ~= nil then |
− | + | self.font = TTFont.new(self.params.font, self.params.fontsize) | |
− | end | + | end |
− | + | if self.text == nil then | |
− | + | self.text = TextField.new(self.font, xtext, xtext) | |
− | if | ||
− | self.text | ||
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 | + | self.text:setTextColor(xcolor or 0x0) |
end | end | ||
− | + | -- VISUAL STATE | |
− | + | function ButtonText:updateVisualState(xisdown) | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | function ButtonText:updateVisualState( | ||
if self.hasbmp then | if self.hasbmp then | ||
− | + | if xisdown then | |
− | + | self.upstate:setVisible(false) | |
− | + | self.downstate:setVisible(true) | |
− | + | self.text:setTextColor(self.params.textcolordown) | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
else | else | ||
− | + | self.upstate:setVisible(true) | |
− | + | self.downstate:setVisible(false) | |
− | + | self.text:setTextColor(self.params.textcolorup) | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
end | end | ||
end | end | ||
end | end | ||
− | -- | + | -- 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 | + | if self:hitTestPoint(event.x, event.y) then |
− | if not 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 | 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 self.focus then | if self.focus then | ||
event:stopPropagation() | event:stopPropagation() | ||
end | end | ||
end | end | ||
− | |||
function ButtonText:onTouchesMove(event) | function ButtonText:onTouchesMove(event) | ||
− | |||
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 self.focus then | if self.focus then | ||
event:stopPropagation() | event:stopPropagation() | ||
end | end | ||
end | end | ||
− | |||
function ButtonText:onTouchesCancel(event) | function ButtonText:onTouchesCancel(event) | ||
− | |||
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 |
− | + | 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) | ||
+ | ]] | ||
</source> | </source> | ||
− | |||
=== <translate>Toggle Button</translate> === | === <translate>Toggle Button</translate> === | ||
Line 439: | Line 447: | ||
--end) | --end) | ||
</source> | </source> | ||
− | |||
{{Welcome!}} | {{Welcome!}} |
Revision as of 19: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)