Difference between revisions of "UI Buttons"

From GiderosMobile
m (Text replacement - "<source" to "<syntaxhighlight")
Line 7: Line 7:
  
 
=== Simple Button ===
 
=== Simple Button ===
<source lang="lua">
+
<syntaxhighlight lang="lua">
 
--[[
 
--[[
 
A generic button class
 
A generic button class
Line 128: Line 128:
  
 
=== Simple Text Button ===
 
=== Simple Text Button ===
<source lang="lua">
+
<syntaxhighlight lang="lua">
 
--[[
 
--[[
 
ButtonTextBasic
 
ButtonTextBasic
Line 277: Line 277:
  
 
=== Button with an Up, Down and Disabled state (UDD) ===
 
=== Button with an Up, Down and Disabled state (UDD) ===
<source lang="lua">
+
<syntaxhighlight lang="lua">
 
--[[
 
--[[
 
A generic button class with an up, down and disabled state (UDD)
 
A generic button class with an up, down and disabled state (UDD)
Line 421: Line 421:
 
=== Button with Text and/or Images ===
 
=== Button with Text and/or Images ===
 
'''note''': You don't have to use an image, for example you can create a button with text only.
 
'''note''': You don't have to use an image, for example you can create a button with text only.
<source lang="lua">
+
<syntaxhighlight lang="lua">
 
--[[
 
--[[
 
A Button class with text and/or image
 
A Button class with text and/or image
Line 635: Line 635:
 
'''This button has it all (almost) :-)'''<br/>
 
'''This button has it all (almost) :-)'''<br/>
 
'''note''': You don't have to use all parameters (UDD), for example you can create a button with text only.
 
'''note''': You don't have to use all parameters (UDD), for example you can create a button with text only.
<source lang="lua">
+
<syntaxhighlight lang="lua">
 
--[[
 
--[[
 
A Button class with text and/or image with Up state, Down state, Disabled state (UDD)
 
A Button class with text and/or image with Up state, Down state, Disabled state (UDD)
Line 911: Line 911:
 
'''This button is the most complete :-)'''<br/>
 
'''This button is the most complete :-)'''<br/>
 
'''note''': You don't have to use all parameters, for example you can create a button with text only.
 
'''note''': You don't have to use all parameters, for example you can create a button with text only.
<source lang="lua">
+
<syntaxhighlight lang="lua">
 
--[[
 
--[[
 
ButtonTextP9UDDT
 
ButtonTextP9UDDT
Line 1,191: Line 1,191:
  
 
=== Toggle Button ===
 
=== Toggle Button ===
<source lang="lua">
+
<syntaxhighlight lang="lua">
 
--[[
 
--[[
 
ToggleButton v1.0
 
ToggleButton v1.0

Revision as of 15:32, 13 July 2023

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

note: UDD = Up Down Disabled images.
note2: you may have to provide your own assets (fonts, gfx, …).

Simple Button

<syntaxhighlight lang="lua"> --[[ A generic button class

This code is MIT licensed, see http://www.opensource.org/licenses/mit-license.php (C) 2010 - 2011 Gideros Mobile ]] --[[ -- 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 = 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 </source>


Simple Text Button

<syntaxhighlight lang="lua"> --[[ ButtonTextBasic A simple Button class with a Pixel and/or text. Ideal for in game action. This code is CC0 github: mokalux v 0.1.1: 2020-06-08 remove useless variables v 0.1.0: 2020-04-02 init (based on the initial gideros generic button class) ]] --[[ -- SAMPLES local mybtnquit = ButtonTextBasic.new({ pixelcolorup=mypixelcolorup, text="X", font=g_font1, fontsize=32, textcolorup=mytextcolorup, textcolordown=mytextcolordown, }) mybtnquit:setPosition(myappright - mybtnquit:getWidth() / 2, myapptop + mybtnquit:getHeight() / 2) self:addChild(mybtnquit) mybtnquit:addEventListener("clicked", function() self:goMenu() end) ]] ButtonTextBasic = Core.class(Sprite)

function ButtonTextBasic:init(xparams) -- the params self.params = xparams or {} -- pixel? self.params.pixelcolorup = xparams.pixelcolorup or nil -- color self.params.pixelcolordown = xparams.pixelcolordown or self.params.pixelcolorup -- color self.params.pixelalpha = xparams.pixelalpha or 1 -- number self.params.pixelscalex = xparams.pixelscalex or 1 -- number self.params.pixelscaley = xparams.pixelscaley or 1 -- number self.params.pixelpaddingx = xparams.pixelpaddingx or 12 -- number self.params.pixelpaddingy = xparams.pixelpaddingy or 12 -- number -- text? self.params.text = xparams.text or nil -- string 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 -- EXTRAS self.params.isautoscale = xparams.isautoscale or 1 -- number (default 1 = true) self.params.defaultpadding = xparams.defaultpadding or 12 -- number -- LET'S GO! if self.params.isautoscale == 0 then self.params.isautoscale = false else self.params.isautoscale = true end -- warnings if not self.params.pixelcolorup and not self.params.text then print("*** WARNING: YOUR BUTTON IS EMPTY! ***") else -- mouse catcher self.catcher = Pixel.new(0x0, 0, 1, 1) self:addChild(self.catcher) -- sprite holder self.sprite = Sprite.new() self:addChild(self.sprite) self:setButton() end -- update visual state self.focus = false self:updateVisualState(false) -- 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) end

-- FUNCTIONS function ButtonTextBasic:setButton() -- text local textwidth, textheight if self.params.text then local font if self.params.font ~= nil then -- font = TTFont.new(self.params.font, self.params.fontsize, "", true, 1) -- filtering, outline (number) font = TTFont.new(self.params.font, self.params.fontsize, "") end if self.text ~= nil then self.text:setButton(self.params.text) else self.text = TextField.new(font, self.params.text, self.params.text) end self.text:setAnchorPoint(0.5, 0.5) self.text:setScale(self.params.textscalex, self.params.textscaley) self.text:setTextColor(self.params.textcolorup) textwidth, textheight = self.text:getWidth(), self.text:getHeight() end -- first add pixel if self.params.pixelcolorup then if self.params.isautoscale and self.params.text then self.pixel = Pixel.new( self.params.pixelcolor, self.params.pixelalpha, textwidth + self.params.pixelpaddingx, textheight + self.params.pixelpaddingy) else self.pixel = Pixel.new( self.params.pixelcolor, self.params.pixelalpha, self.params.pixelpaddingx, self.params.pixelpaddingy) end self.pixel:setAnchorPoint(0.5, 0.5) self.pixel:setScale(self.params.pixelscalex, self.params.pixelscaley) self.sprite:addChild(self.pixel) end -- finally add text on top of all if self.params.text then self.sprite:addChild(self.text) end -- mouse catcher self.catcher:setDimensions(self.sprite:getWidth() + 8 * 2.5, self.sprite:getHeight() + 8 * 2.5) -- magik self.catcher:setAnchorPoint(0.5, 0.5) end

-- VISUAL STATE function ButtonTextBasic:updateVisualState(xstate) if xstate then -- button down state if self.params.pixelcolorup ~= nil then self.pixel:setColor(self.params.pixelcolordown) end if self.params.text ~= nil then self.text:setTextColor(self.params.textcolordown) end else -- button up state if self.params.pixelcolorup ~= nil then self.pixel:setColor(self.params.pixelcolorup) end if self.params.text ~= nil then self.text:setTextColor(self.params.textcolorup) end end end

-- MOUSE LISTENERS function ButtonTextBasic:onMouseDown(e) if self:hitTestPoint(e.x, e.y) then self.focus = true self:updateVisualState(true) e:stopPropagation() end end function ButtonTextBasic:onMouseMove(e) if self:hitTestPoint(e.x, e.y) then self.focus = true e:stopPropagation() else self.focus = false -- e:stopPropagation() -- you may want to delete this line end self:updateVisualState(self.focus) end function ButtonTextBasic:onMouseUp(e) if self.focus then self.focus = false self:dispatchEvent(Event.new("clicked")) -- button is clicked, dispatch "clicked" event e:stopPropagation() end end </source>

Button with an Up, Down and Disabled state (UDD)

<syntaxhighlight lang="lua"> --[[ A generic button class with an up, down and disabled state (UDD)

This code is MIT licensed, see http://www.opensource.org/licenses/mit-license.php (C) 2010 - 2011 Gideros Mobile ]] --[[ --usage local button = ButtonUDD.new( Bitmap.new(Texture.new("gfx/button-up.png")), -- up state Bitmap.new(Texture.new("gfx/button-down.png")), -- down state Bitmap.new(Texture.new("gfx/button-disabled.png")) -- disabled state ) button:setPosition(70, 130) stage:addChild(button) local function onRecord() -- play:setDisabled(true) -- record:removeFromParent() -- stage:addChild(recordStop) -- microphone:start() end button:addEventListener(Event.CLICK, onRecord) ]]

Event.CLICK = "click"

ButtonUDD = Core.class(Sprite)

function ButtonUDD:init(upState, downState, disabledState) self.upState = upState self.downState = downState self.disabledState = disabledState or upState

self.focus = false self.disabled = 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 ButtonUDD:onMouseDown(event) if self:hitTestPoint(event.x, event.y) then self.focus = true self:updateVisualState(true) event:stopPropagation() end end

function ButtonUDD: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 ButtonUDD:onMouseUp(event) if self.focus then self.focus = false self:updateVisualState(false) if not self.disabled then self:dispatchEvent(Event.new(Event.CLICK)) -- button is clicked, dispatch "click" event end event:stopPropagation() end end

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

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

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

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

-- if state is true show downState else show upState function ButtonUDD:updateVisualState(state) self.upState:removeFromParent() self.downState:removeFromParent() self.disabledState:removeFromParent()

if self.disabled then self:addChild(self.disabledState) else if state then self:addChild(self.downState) else self:addChild(self.upState) end end end

function ButtonUDD:setDisabled(disabled) if self.disabled == disabled then return end

self.disabled = disabled self.focus = false self:updateVisualState(false) end

function ButtonUDD:isDisabled() return self.disabled end </source>


Button with Text and/or Images

note: You don't have to use an image, for example you can create a button with text only. <syntaxhighlight lang="lua"> --[[ A Button class with text and/or image This code is MIT licensed, see http://www.opensource.org/licenses/mit-license.php github: mokalux v 0.1.1: 2020-03-07 added optional mouse hover effect params (mouse hover effect default is true) v 0.1.0: 2020-03-02 init (based on the initial gideros generic button class) ]] --[[ -- sample usage local button = ButtonText.new( { text="01", textscalex=4, textcolorup=0x0, textcolordown=0xffff00, imgdown="gfx/ui/Blue.png", nohover=true, } ) button:setPosition(128, 128) self:addChild(button) button:addEventListener("click", function() -- your code here end) ]] ButtonText = Core.class(Sprite)

function ButtonText:init(xparams) -- the params self.params = xparams or {} self.params.imgup = xparams.imgup or nil -- img up path self.params.imgdown = xparams.imgdown or self.params.imgup -- img down path self.params.imgscalex = xparams.imgscalex or nil -- number or nil = autoscale self.params.imgscaley = xparams.imgscaley or nil -- number or nil = autoscale self.params.text = xparams.text or nil -- string 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 self.params.nohover = xparams.nohover or nil -- boolean -- let's go self.sprite = Sprite.new() self.sprite:setAnchorPoint(0.5,0.5) self:addChild(self.sprite) -- button has up state image? if self.params.imgup ~= nil then self.bmpup = Bitmap.new(Texture.new(self.params.imgup)) self.bmpup:setAnchorPoint(0.5, 0.5) self.bmpupwidth = self.bmpup:getWidth() self.bmpupheight = self.bmpup:getHeight() self.sprite:addChild(self.bmpup) self.hasbmpup = true else self.hasbmpup = false end -- button has down state image? if self.params.imgdown ~= nil then self.bmpdown = Bitmap.new(Texture.new(self.params.imgdown)) self.bmpdown:setAnchorPoint(0.5, 0.5) self.bmpdownwidth = self.bmpdown:getWidth() self.bmpdownheight = self.bmpdown:getHeight() self.sprite:addChild(self.bmpdown) self.hasbmpdown = true else self.hasbmpdown = 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.hasbmpup and not self.hasbmpdown and not self.hastext then print("*** WARNING: BUTTONTEXT NEEDS AT LEAST SOME TEXT OR SOME BITMAPS! ***") end -- update visual state self.focus = false self:updateVisualState(false) -- 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) if self.params.nohover then -- print("*** no mouse hover effect ***") self:removeEventListener(Event.MOUSE_HOVER, self.onMouseHover, self) end -- 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:setText(xtext) else self.text = TextField.new(self.font, xtext, 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.hasbmpup then local sx, sy = 1, 1 if self.bmpupwidth < self.textwidth then sx = self.params.imgscalex or (self.textwidth/self.bmpupwidth * 1.25) sy = self.params.imgscaley or (self.textheight/self.bmpupheight * 2) end self.bmpup:setScale(sx, sy) end if self.hasbmpdown then local sx, sy = 1, 1 if self.bmpdownwidth < self.textwidth then sx = self.params.imgscalex or (self.textwidth/self.bmpdownwidth * 1.25) sy = self.params.imgscaley or (self.textheight/self.bmpdownheight * 2) end self.bmpdown:setScale(sx, sy) end end

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

-- VISUAL STATE function ButtonText:updateVisualState(xisdown) if xisdown then if self.params.imgup ~= nil then self.bmpup:setVisible(false) end if self.params.imgdown ~= nil then self.bmpdown:setVisible(true) end if self.params.text ~= nil then self.text:setTextColor(self.params.textcolordown) end else if self.params.imgup ~= nil then self.bmpup:setVisible(true) end if self.params.imgdown ~= nil then self.bmpdown:setVisible(false) end if self.params.text ~= nil then 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) event:stopPropagation() end if not self:hitTestPoint(event.x, event.y) then self.focus = false self:updateVisualState(false) -- event:stopPropagation() -- you may want to comment this line end 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 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 </source>


Button with Text and/or Images UDD

This button has it all (almost) :-)
note: You don't have to use all parameters (UDD), for example you can create a button with text only. <syntaxhighlight lang="lua"> --[[ A Button class with text and/or image with Up state, Down state, Disabled state (UDD) This code is MIT licensed, see http://www.opensource.org/licenses/mit-license.php github: mokalux v 0.1.0: 2020-03-09 init (based on the initial gideros generic button class) ]] --[[ -- sample usage local button = ButtonTextUDD.new( { text="01", textscalex=4, textcolorup=0x0, textcolordown=0xffff00, imgdown="gfx/ui/Blue.png", nohover=false, } ) button:setPosition(64, 2 * 16) stage:addChild(button)

local button2 = ButtonTextUDD.new( { text="02 CAN DO", textscalex=4, textcolorup=0x0, textcolordown=0xffff00, imgup="gfx/ui/blue (2).png", imgdown="gfx/ui/Blue.png", imgdisabled="gfx/ui/blocker2.png", nohover=true, } ) button2:setPosition(64, 4 * 16) stage:addChild(button2)

button:addEventListener("clicked", function() button2:setDisabled(not button2:isDisabled()) end) button2:addEventListener("click", function() -- your code here end) ]] ButtonTextUDD = Core.class(Sprite)

function ButtonTextUDD:init(xparams) -- the params self.params = xparams or {} self.params.imgup = xparams.imgup or nil -- img up path self.params.imgdown = xparams.imgdown or self.params.imgup -- img down path self.params.imgdisabled = xparams.imgdisabled or self.params.imgup -- img disabled path self.params.imgscalex = xparams.imgscalex or nil -- number or nil = autoscale self.params.imgscaley = xparams.imgscaley or nil -- number or nil = autoscale self.params.text = xparams.text or nil -- string 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.textcolordisabled = xparams.textcolordisabled or 0x555555 -- color self.params.textscalex = xparams.textscalex or 1 -- number self.params.textscaley = xparams.textscaley or self.params.textscalex -- number self.params.nohover = xparams.nohover or nil -- boolean -- let's go self.sprite = Sprite.new() self.sprite:setAnchorPoint(0.5,0.5) self:addChild(self.sprite) -- button has up state image? if self.params.imgup ~= nil then self.bmpup = Bitmap.new(Texture.new(self.params.imgup)) self.bmpup:setAnchorPoint(0.5, 0.5) self.bmpupwidth = self.bmpup:getWidth() self.bmpupheight = self.bmpup:getHeight() self.sprite:addChild(self.bmpup) self.hasbmpup = true else self.hasbmpup = false end -- button has down state image? if self.params.imgdown ~= nil then self.bmpdown = Bitmap.new(Texture.new(self.params.imgdown)) self.bmpdown:setAnchorPoint(0.5, 0.5) self.bmpdownwidth = self.bmpdown:getWidth() self.bmpdownheight = self.bmpdown:getHeight() self.sprite:addChild(self.bmpdown) self.hasbmpdown = true else self.hasbmpdown = false end -- button has disabled state image? if self.params.imgdisabled ~= nil then self.bmpdisabled = Bitmap.new(Texture.new(self.params.imgdisabled)) self.bmpdisabled:setAnchorPoint(0.5, 0.5) self.bmpdisabledwidth = self.bmpdown:getWidth() self.bmpdisabledheight = self.bmpdown:getHeight() self.sprite:addChild(self.bmpdisabled) self.hasbmpdisabled = true else self.hasbmpdisabled = 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.hasbmpup and not self.hasbmpdown and not self.hasbmpdisabled and not self.hastext then print("*** WARNING: BUTTONTEXT NEEDS AT LEAST SOME TEXT OR SOME BITMAPS! ***") end -- update visual state self.focus = false self.disabled = false self:updateVisualState(false) -- 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) if self.params.nohover then print("*** no mouse hover effect ***") self:removeEventListener(Event.MOUSE_HOVER, self.onMouseHover, self) end -- 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 ButtonTextUDD: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:setText(xtext) else self.text = TextField.new(self.font, xtext, 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.hasbmpup then local sx, sy = 1, 1 if self.bmpupwidth < self.textwidth then sx = self.params.imgscalex or (self.textwidth/self.bmpupwidth * 1.25) sy = self.params.imgscaley or (self.textheight/self.bmpupheight * 2) end self.bmpup:setScale(sx, sy) end if self.hasbmpdown then local sx, sy = 1, 1 if self.bmpdownwidth < self.textwidth then sx = self.params.imgscalex or (self.textwidth/self.bmpdownwidth * 1.25) sy = self.params.imgscaley or (self.textheight/self.bmpdownheight * 2) end self.bmpdown:setScale(sx, sy) end if self.hasbmpdisabled then local sx, sy = 1, 1 if self.bmpdisabledwidth < self.textwidth then sx = self.params.imgscalex or (self.textwidth/self.bmpdisabledwidth * 1.25) sy = self.params.imgscaley or (self.textheight/self.bmpdisabledheight * 2) end self.bmpdisabled:setScale(sx, sy) end end

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

-- VISUAL STATE function ButtonTextUDD:updateVisualState(xstate) if self.disabled then -- button disabled state if self.params.imgup ~= nil then self.bmpup:setVisible(false) end if self.params.imgdown ~= nil then self.bmpdown:setVisible(false) end if self.params.imgdisabled ~= nil then self.bmpdisabled:setVisible(true) end if self.params.text ~= nil then self.text:setTextColor(self.params.textcolordisabled) end else if xstate then -- button down state if self.params.imgup ~= nil then self.bmpup:setVisible(false) end if self.params.imgdown ~= nil then self.bmpdown:setVisible(true) end if self.params.imgdisabled ~= nil then self.bmpdisabled:setVisible(false) end if self.params.text ~= nil then self.text:setTextColor(self.params.textcolordown) end else -- button up state if self.params.imgup ~= nil then self.bmpup:setVisible(true) end if self.params.imgdown ~= nil then self.bmpdown:setVisible(false) end if self.params.imgdisabled ~= nil then self.bmpdisabled:setVisible(false) end if self.params.text ~= nil then self.text:setTextColor(self.params.textcolorup) end end end end

function ButtonTextUDD:setDisabled(xdisabled) if self.disabled == xdisabled then return end self.disabled = xdisabled self.focus = false self:updateVisualState(false) end

function ButtonTextUDD:isDisabled() return self.disabled end

-- BUTTON LISTENERS -- mouse function ButtonTextUDD:onMouseDown(e) if self:hitTestPoint(e.x, e.y) then self.focus = true self:updateVisualState(true) e:stopPropagation() end end function ButtonTextUDD:onMouseMove(e) if self:hitTestPoint(e.x, e.y) then self.focus = true self:updateVisualState(true) e:stopPropagation() end if self.focus then if not self:hitTestPoint(e.x, e.y) then self.focus = false self:updateVisualState(false) -- e:stopPropagation() -- you may want to comment this line end end end function ButtonTextUDD:onMouseUp(e) if self.focus then self.focus = false self:updateVisualState(false) if not self.disabled then self:dispatchEvent(Event.new("clicked")) -- button is clicked, dispatch "click" event end e:stopPropagation() end end function ButtonTextUDD:onMouseHover(e) if self:hitTestPoint(e.x, e.y) then self.focus = true self:updateVisualState(true) else self.focus = false self:updateVisualState(false) end end -- touch function ButtonTextUDD:onTouchesBegin(e) if self.focus then e:stopPropagation() end end function ButtonTextUDD:onTouchesMove(e) if self.focus then e:stopPropagation() end end function ButtonTextUDD:onTouchesEnd(e) if self.focus then e:stopPropagation() end end function ButtonTextUDD:onTouchesCancel(e) if self.focus then self.focus = false self:updateVisualState(false) e:stopPropagation() end end </source>


Button with Text, Pixel, Images 9 Patch, UDD, Tooltip

This button is the most complete :-)
note: You don't have to use all parameters, for example you can create a button with text only. <syntaxhighlight lang="lua"> --[[ ButtonTextP9UDDT A Button class with text, Pixel, images 9patch (Up, Down, Disabled) and Tooltip This code is CC0 github: mokalux v 0.1.6: 2021-05-29 fixed tooltip not disappearing + removed unnecessary sprite + added more params v 0.1.5: 2020-08-25 replaced font params with ttf params for better control v 0.1.41: 2020-08-19 added tooltip text scale and color v 0.1.4: 2020-06-08 removed useless variables + the class was somehow broken :/ v 0.1.3: 2020-03-30 added tooltiptext v 0.1.2: 2020-03-29 added nine patch v 0.1.1: 2020-03-28 added pixel v 0.1.0: 2020-03-28 init (based on the initial gideros generic button class) ]] --[[ -- SAMPLE local mybtn03 = ButtonTextP9UDDT.new({ pixelcolorup=0x123456, pixelpaddingx=196, pixelpaddingy=16, text=" XXX ", ttf=font01, textcolorup=0xA6740C, textcolordown=0xF2B941, hover=1, tooltiptext="disabled", tooltipoffsetx=96, isautoscale=0, }) mybtn03:setDisabled(true) mybtn03.text:setText(" GEEL ") mybtn03.params.tooltiptext = "GEEL" mybtn03:setPosition(myappwidth/2, 7*myappheight/10) self:addChild(mybtn03) self.mybtn03:addEventListener("clicked", function() -- code end) ]]

ButtonTextP9UDDT = Core.class(Sprite)

function ButtonTextP9UDDT:init(xparams) -- the params table self.params = xparams or {} -- pixel? self.params.pixelcolorup = xparams.pixelcolorup or nil -- color self.params.pixelcolordown = xparams.pixelcolordown or nil -- color self.params.pixelcolordisabled = xparams.pixelcolordisabled or 0x555555 -- color self.params.pixelalpha = xparams.pixelalpha or 1 -- number between 0 and 1 self.params.pixelscalex = xparams.pixelscalex or 1 -- number self.params.pixelscaley = xparams.pixelscaley or 1 -- number self.params.pixelpaddingx = xparams.pixelpaddingx or 12 -- number self.params.pixelpaddingy = xparams.pixelpaddingy or 12 -- number -- textures? self.params.imgup = xparams.imgup or nil -- img up path self.params.imgdown = xparams.imgdown or nil -- img down path self.params.imgdisabled = xparams.imgdisabled or nil -- img disabled path self.params.imagealpha = xparams.imagealpha or 1 -- number between 0 and 1 self.params.imgscalex = xparams.imgscalex or 1 -- number self.params.imgscaley = xparams.imgscaley or 1 -- number self.params.imagepaddingx = xparams.imagepaddingx or nil -- number (nil = auto, the image width) self.params.imagepaddingy = xparams.imagepaddingy or nil -- number (nil = auto, the image height) -- text? self.params.text = xparams.text or nil -- string self.params.ttf = xparams.ttf or nil -- ttf self.params.textcolorup = xparams.textcolorup or 0x0 -- color self.params.textcolordown = xparams.textcolordown or self.params.textcolorup -- color self.params.textcolordisabled = xparams.textcolordisabled or 0x777777 -- color self.params.textalpha = xparams.textalpha or 1 -- number between 0 and 1 self.params.textscalex = xparams.textscalex or 1 -- number self.params.textscaley = xparams.textscaley or self.params.textscalex -- number -- tool tip? self.params.tooltiptext = xparams.tooltiptext or nil -- string self.params.tooltipttf = xparams.tooltipttf or nil -- ttf self.params.tooltiptextcolor = xparams.tooltiptextcolor or 0xff00ff -- color self.params.tooltiptextscale = xparams.tooltiptextscale or 3 -- number self.params.tooltipoffsetx = xparams.tooltipoffsetx or 0 -- number self.params.tooltipoffsety = xparams.tooltipoffsety or 0 -- number -- EXTRAS self.params.hover = xparams.hover or 0 -- number 0 or 1 (default 0 = false) self.params.isautoscale = xparams.isautoscale or 1 -- number 0 or 1 (default 1 = true) -- LET'S GO! if self.params.hover == 0 then self.params.hover = false else self.params.hover = true end if self.params.isautoscale == 0 then self.params.isautoscale = false else self.params.isautoscale = true end -- warnings if not self.params.imgup and not self.params.imgdown and not self.params.imgdisabled and not self.params.pixelcolorup and not self.params.text and not self.params.tooltiptext then print("*** WARNING: YOUR BUTTON IS EMPTY! ***") else -- button sprite holder self.sprite = Sprite.new() self:addChild(self.sprite) self:setButton() end -- update visual state self.focus = false self.disabled = false self:updateVisualState(false) -- 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) if not self.params.hover and not self.params.tooltiptext then print("mouse hover event listener removed") self:removeEventListener(Event.MOUSE_HOVER, self.onMouseHover, self) end end

-- FUNCTIONS function ButtonTextP9UDDT:setButton() local textwidth, textheight local bmps = {} -- text if self.params.text then self.text = TextField.new(self.params.ttf, self.params.text, self.params.text) self.text:setAnchorPoint(0.5, 0.5) self.text:setScale(self.params.textscalex, self.params.textscaley) self.text:setTextColor(self.params.textcolorup) self.text:setAlpha(self.params.textalpha) textwidth, textheight = self.text:getWidth(), self.text:getHeight() end -- first add pixel if self.params.pixelcolorup then if self.params.isautoscale and self.params.text then self.pixel = Pixel.new( self.params.pixelcolorup, self.params.pixelalpha, textwidth + self.params.pixelpaddingx, textheight + self.params.pixelpaddingy) else self.pixel = Pixel.new( self.params.pixelcolorup, self.params.pixelalpha, self.params.pixelpaddingx, self.params.pixelpaddingy) end self.pixel:setAnchorPoint(0.5, 0.5) self.pixel:setScale(self.params.pixelscalex, self.params.pixelscaley) self.sprite:addChild(self.pixel) end -- then images if self.params.imgup then local texup = Texture.new(self.params.imgup) if self.params.isautoscale and self.params.text then self.bmpup = Pixel.new(texup, textwidth + (self.params.imagepaddingx), textheight + (self.params.imagepaddingy)) else self.bmpup = Pixel.new(texup, self.params.imagepaddingx, self.params.imagepaddingy) end bmps[self.bmpup] = 1 end if self.params.imgdown then local texdown = Texture.new(self.params.imgdown) if self.params.isautoscale and self.params.text then self.bmpdown = Pixel.new(texdown, textwidth + (self.params.imagepaddingx), textheight + (self.params.imagepaddingy)) else self.bmpdown = Pixel.new(texdown, self.params.imagepaddingx, self.params.imagepaddingy) end bmps[self.bmpdown] = 2 end if self.params.imgdisabled then local texdisabled = Texture.new(self.params.imgdisabled) if self.params.isautoscale and self.params.text then self.bmpdisabled = Pixel.new(texdisabled, textwidth + (self.params.imagepaddingx), textheight + (self.params.imagepaddingy)) else self.bmpdisabled = Pixel.new(texdisabled, self.params.imagepaddingx, self.params.imagepaddingy) end bmps[self.bmpdisabled] = 3 end -- image batch for k, _ in pairs(bmps) do k:setAnchorPoint(0.5, 0.5) k:setAlpha(self.params.imagealpha) local split = 9 -- magik number k:setNinePatch(math.floor(k:getWidth()/split), math.floor(k:getWidth()/split), math.floor(k:getHeight()/split), math.floor(k:getHeight()/split)) self.sprite:addChild(k) end -- finally add text on top of all if self.params.text then self.sprite:addChild(self.text) end -- and the tooltip text if self.params.tooltiptext then self.tooltiptext = TextField.new(self.params.tooltipttf, self.params.tooltiptext, self.params.tooltiptext) self.tooltiptext:setScale(self.params.tooltiptextscale) self.tooltiptext:setTextColor(self.params.tooltiptextcolor) self.tooltiptext:setVisible(false) -- self.sprite:addChild(self.tooltiptext) -- best to add here? self:addChild(self.tooltiptext) -- or here to self? end end

-- VISUAL STATE function ButtonTextP9UDDT:updateVisualState(xstate) if self.disabled then -- button is disabled if self.params.imgup ~= nil then self.bmpup:setVisible(false) end if self.params.imgdown ~= nil then self.bmpdown:setVisible(false) end if self.params.imgdisabled ~= nil then self.bmpdisabled:setVisible(true) end if self.params.pixelcolordisabled ~= nil then self.pixel:setColor(self.params.pixelcolordisabled) end if self.params.text ~= nil then self.text:setTextColor(self.params.textcolordisabled) end elseif not self.params.hover then -- no hover if self.params.imgup ~= nil then self.bmpup:setVisible(true) end if self.params.imgdown ~= nil then self.bmpdown:setVisible(false) end if self.params.imgdisabled ~= nil then self.bmpdisabled:setVisible(false) end if self.params.pixelcolorup ~= nil then self.pixel:setColor(self.params.pixelcolorup) end if self.params.text ~= nil then self.text:setTextColor(self.params.textcolorup) end else -- hover if xstate then -- button down state if self.params.imgup ~= nil then self.bmpup:setVisible(false) end if self.params.imgdown ~= nil then self.bmpdown:setVisible(true) end if self.params.imgdisabled ~= nil then self.bmpdisabled:setVisible(false) end if self.params.pixelcolordown ~= nil then self.pixel:setColor(self.params.pixelcolordown) end if self.params.text ~= nil then self.text:setTextColor(self.params.textcolordown) end else -- button up state if self.params.imgup ~= nil then self.bmpup:setVisible(true) end if self.params.imgdown ~= nil then self.bmpdown:setVisible(false) end if self.params.imgdisabled ~= nil then self.bmpdisabled:setVisible(false) end if self.params.pixelcolorup ~= nil then self.pixel:setColor(self.params.pixelcolorup) end if self.params.text ~= nil then self.text:setTextColor(self.params.textcolorup) end end end

-- if self.params.tooltiptext and not self.disabled then -- you can choose this option: hides the tooltip when button is disabled if self.params.tooltiptext then -- or this option: shows the tooltip even when button is disabled if xstate then -- button hover state if self.disabled then self.tooltiptext:setText("( "..self.params.tooltiptext.." )") else self.tooltiptext:setText(self.params.tooltiptext) end self.tooltiptext:setVisible(true) else -- button no hover state self.tooltiptext:setVisible(false) end end end

-- disabled function ButtonTextP9UDDT:setDisabled(xdisabled) if self.disabled == xdisabled then return end self.disabled = xdisabled self.focus = false self:updateVisualState(false) end function ButtonTextP9UDDT:isDisabled() return self.disabled end

-- MOUSE LISTENERS function ButtonTextP9UDDT:onMouseDown(e) if self:hitTestPoint(e.x, e.y) and self:getParent():isVisible() then self.focus = true self.isclicked = true self:updateVisualState(self.focus) e:stopPropagation() end end function ButtonTextP9UDDT:onMouseMove(e) if self:hitTestPoint(e.x, e.y) and self:getParent():isVisible() then self.focus = true else self.focus = false end self:updateVisualState(self.focus) end function ButtonTextP9UDDT:onMouseUp(e) if self.focus and self.isclicked then self.focus = false self.isclicked = false if not self.disabled then self:dispatchEvent(Event.new("clicked")) end e:stopPropagation() end end function ButtonTextP9UDDT:onMouseHover(e) if self.sprite:hitTestPoint(e.x, e.y) and self.sprite:isVisible() then if self.params.tooltiptext then self.tooltiptext:setPosition(self.sprite:globalToLocal(e.x + self.params.tooltipoffsetx, e.y + self.params.tooltipoffsety)) end self.focus = true else self.focus = false end self:updateVisualState(self.focus) end </source>

Toggle Button

<syntaxhighlight lang="lua"> --[[ ToggleButton v1.0

v1.0 - 19.3.2013 Initial release

Free to modify and use! Matjaž Bravc ]] --[[ -- 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) ]]

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:setPressed(xbool) self:updateVisualState(xbool) end

function ToggleButton:isPressed() return self.pressed end </source>

Template:Welcome!