Difference between revisions of "UI Buttons"
From GiderosMobile
(added another button class) |
(→Button with Text, Pixel, Images UDD, 9 Patch, Tooltip: the code was broken, now it works again :-)) |
||
Line 923: | Line 923: | ||
=== Button with Text, Pixel, Images UDD, 9 Patch, Tooltip === | === Button with Text, Pixel, Images UDD, 9 Patch, Tooltip === | ||
'''This button is the most complete :-)'''<br/> | '''This button is the most complete :-)'''<br/> | ||
− | '''note''': You don't have to use all parameters | + | '''note''': You don't have to use all parameters, for example you can create a button with text only. |
<source lang="lua"> | <source lang="lua"> | ||
--[[ | --[[ | ||
− | + | ButtonTextP9UDDT | |
− | A Button class with text, Pixel, images (Up, Down, Disabled) and Tooltip | + | A Button class with text, Pixel, images 9patch (Up, Down, Disabled) and Tooltip |
This code is CC0 | This code is CC0 | ||
github: mokalux | github: mokalux | ||
− | v 0.1.3: 2020-03-30 added | + | v 0.1.4: 2020-06-08 removed useless variables |
+ | v 0.1.3: 2020-03-30 added tooltiptext | ||
v 0.1.2: 2020-03-29 added nine patch | v 0.1.2: 2020-03-29 added nine patch | ||
v 0.1.1: 2020-03-28 added pixel | v 0.1.1: 2020-03-28 added pixel | ||
Line 937: | Line 938: | ||
--[[ | --[[ | ||
-- SAMPLES | -- SAMPLES | ||
− | -- BUTTON QUIT | + | -- BUTTON QUIT |
− | local mybtnquit = | + | local mybtnquit = ButtonTextP9UDDT.new({ |
− | + | imgup="gfx/ui/btn_01_up.png", imgdown="gfx/ui/btn_01_down.png",imgdisabled="gfx/ui/btn_01_disabled.png", | |
− | + | text="QUIT", font=g_font1, fontsize=32, textcolorup=mytextcolorup, textcolordown=mytextcolordown, | |
− | + | tooltiptext="QUIT?", | |
− | }) | + | }) |
− | self:addChild(mybtnquit) | + | mybtnquit:setPosition(2 * myappwidth / 10, 8.75 * myappheight / 10 + myapptop) |
− | mybtnquit:addEventListener("clicked", function() self:goExit() end) | + | self:addChild(mybtnquit) |
− | mybtnquit:setDisabled(true) | + | mybtnquit:addEventListener("clicked", function() self:goExit() end) |
+ | mybtnquit:setDisabled(true) | ||
]] | ]] | ||
− | + | ButtonTextP9UDDT = Core.class(Sprite) | |
− | function | + | function ButtonTextP9UDDT:init(xparams) |
− | -- the params | + | -- the params table |
self.params = xparams or {} | 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.pixelcolordisabled = xparams.pixelcolordisabled or 0x555555 -- 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 | ||
-- textures? | -- textures? | ||
self.params.imgup = xparams.imgup or nil -- img up path | self.params.imgup = xparams.imgup or nil -- img up path | ||
Line 961: | Line 972: | ||
self.params.imagepaddingx = xparams.imagepaddingx or nil -- number (nil = auto, the image width) | 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) | self.params.imagepaddingy = xparams.imagepaddingy or nil -- number (nil = auto, the image height) | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
-- text? | -- text? | ||
self.params.text = xparams.text or nil -- string | self.params.text = xparams.text or nil -- string | ||
Line 981: | Line 983: | ||
-- EXTRAS | -- EXTRAS | ||
self.params.isautoscale = xparams.isautoscale or 1 -- number (default 1 = true) | self.params.isautoscale = xparams.isautoscale or 1 -- number (default 1 = true) | ||
− | self.params.hover = xparams.hover or | + | self.params.hover = xparams.hover or 0 -- number (default 0 = false) |
self.params.defaultpadding = xparams.defaultpadding or 12 -- number | self.params.defaultpadding = xparams.defaultpadding or 12 -- number | ||
− | self.params. | + | self.params.tooltiptext = xparams.tooltiptext or nil -- string |
-- LET'S GO! | -- LET'S GO! | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
if self.params.isautoscale == 0 then self.params.isautoscale = false else self.params.isautoscale = true end | if self.params.isautoscale == 0 then self.params.isautoscale = false else self.params.isautoscale = true end | ||
if self.params.hover == 0 then self.params.hover = false else self.params.hover = true end | if self.params.hover == 0 then self.params.hover = false else self.params.hover = true end | ||
− | |||
-- warnings | -- warnings | ||
− | if not self. | + | if not self.params.imgup and not self.params.imgdown and not self.params.imgdisabled |
− | and not self. | + | and not self.params.pixelcolorup and not self.params.text and not self.params.tooltiptext then |
print("*** WARNING: YOUR BUTTON IS EMPTY! ***") | print("*** WARNING: YOUR BUTTON IS EMPTY! ***") | ||
else | else | ||
− | -- mouse | + | -- draws a pixel around the button to catch the mouse leaving the button |
− | self.catcher = Pixel.new(0x0, 0, 1, 1) | + | self.catcher = Pixel.new(0x0, 0.25, 1, 1) |
self:addChild(self.catcher) | self:addChild(self.catcher) | ||
− | -- sprite holder | + | -- button sprite holder |
self.sprite = Sprite.new() | self.sprite = Sprite.new() | ||
self:addChild(self.sprite) | self:addChild(self.sprite) | ||
Line 1,017: | Line 1,011: | ||
self:addEventListener(Event.MOUSE_UP, self.onMouseUp, self) | self:addEventListener(Event.MOUSE_UP, self.onMouseUp, self) | ||
self:addEventListener(Event.MOUSE_HOVER, self.onMouseHover, self) | self:addEventListener(Event.MOUSE_HOVER, self.onMouseHover, self) | ||
− | if not self.params.hover and not self. | + | if not self.params.hover and not self.params.tooltiptext then |
print("*** no mouse hover effect ***") | print("*** no mouse hover effect ***") | ||
self:removeEventListener(Event.MOUSE_HOVER, self.onMouseHover, self) | self:removeEventListener(Event.MOUSE_HOVER, self.onMouseHover, self) | ||
Line 1,024: | Line 1,018: | ||
-- FUNCTIONS | -- FUNCTIONS | ||
− | function | + | function ButtonTextP9UDDT:setButton() |
local textwidth, textheight | local textwidth, textheight | ||
local bmps = {} | local bmps = {} | ||
-- text | -- text | ||
− | if self. | + | if self.params.text then |
local font | local font | ||
if self.params.font ~= nil then | if self.params.font ~= nil then | ||
Line 1,045: | Line 1,039: | ||
end | end | ||
-- first add pixel | -- first add pixel | ||
− | if self. | + | if self.params.pixelcolorup then |
− | if self.params.isautoscale and self. | + | if self.params.isautoscale and self.params.text then |
self.pixel = Pixel.new( | self.pixel = Pixel.new( | ||
self.params.pixelcolor, self.params.pixelalpha, | self.params.pixelcolor, self.params.pixelalpha, | ||
Line 1,062: | Line 1,056: | ||
end | end | ||
-- then images | -- then images | ||
− | if self. | + | if self.params.imgup then |
local texup = Texture.new(self.params.imgup) | local texup = Texture.new(self.params.imgup) | ||
− | if self.params.isautoscale and self. | + | if self.params.isautoscale and self.params.text then |
self.bmpup = Pixel.new(texup, | self.bmpup = Pixel.new(texup, | ||
textwidth + (self.params.imagepaddingx or self.params.defaultpadding), | textwidth + (self.params.imagepaddingx or self.params.defaultpadding), | ||
Line 1,073: | Line 1,067: | ||
bmps[self.bmpup] = 1 | bmps[self.bmpup] = 1 | ||
end | end | ||
− | if self. | + | if self.params.imgdown then |
local texdown = Texture.new(self.params.imgdown) | local texdown = Texture.new(self.params.imgdown) | ||
− | if self.params.isautoscale and self. | + | if self.params.isautoscale and self.params.text then |
self.bmpdown = Pixel.new(texdown, | self.bmpdown = Pixel.new(texdown, | ||
textwidth + (self.params.imagepaddingx or self.params.defaultpadding), | textwidth + (self.params.imagepaddingx or self.params.defaultpadding), | ||
Line 1,084: | Line 1,078: | ||
bmps[self.bmpdown] = 2 | bmps[self.bmpdown] = 2 | ||
end | end | ||
− | if self. | + | if self.params.imgdisabled then |
local texdisabled = Texture.new(self.params.imgdisabled) | local texdisabled = Texture.new(self.params.imgdisabled) | ||
− | if self.params.isautoscale and self. | + | if self.params.isautoscale and self.params.text then |
self.bmpdisabled = Pixel.new(texdisabled, | self.bmpdisabled = Pixel.new(texdisabled, | ||
textwidth + (self.params.imagepaddingx or self.params.defaultpadding), | textwidth + (self.params.imagepaddingx or self.params.defaultpadding), | ||
Line 1,105: | Line 1,099: | ||
end | end | ||
-- finally add text on top of all | -- finally add text on top of all | ||
− | if self. | + | if self.params.text then self.sprite:addChild(self.text) end |
− | -- and the tooltip | + | -- and the tooltip text |
− | if self. | + | if self.params.tooltiptext then |
− | self. | + | self.tooltiptext = TextField.new(nil, self.params.tooltiptext) |
− | self. | + | self.tooltiptext:setScale(2) -- magik |
− | self. | + | self.tooltiptext:setTextColor(0xffff00) -- magik |
− | self. | + | self.tooltiptext:setVisible(false) |
− | -- self.sprite:addChild(self. | + | -- self.sprite:addChild(self.tooltiptext) -- best to add here? |
− | self:addChild(self. | + | self:addChild(self.tooltiptext) -- or here to self? |
end | end | ||
− | -- mouse catcher | + | -- fits the mouse catcher a little bigger than the button |
− | self.catcher:setDimensions(self.sprite:getWidth() + 8 * 2, self.sprite:getHeight() + 8 * 2) -- magik | + | self.catcher:setDimensions(self.sprite:getWidth() + 8 * 2.5, self.sprite:getHeight() + 8 * 2.5) -- magik |
self.catcher:setAnchorPoint(0.5, 0.5) | self.catcher:setAnchorPoint(0.5, 0.5) | ||
end | end | ||
− | |||
− | |||
− | |||
− | |||
-- VISUAL STATE | -- VISUAL STATE | ||
− | function | + | function ButtonTextP9UDDT:updateVisualState(xstate) |
− | if self.disabled then -- button disabled | + | if self.disabled then -- button is disabled |
if self.params.imgup ~= nil then self.bmpup:setVisible(false) end | 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.imgdown ~= nil then self.bmpdown:setVisible(false) end | ||
Line 1,132: | Line 1,122: | ||
if self.params.pixelcolorup ~= nil then self.pixel:setColor(self.params.pixelcolordisabled) end | if self.params.pixelcolorup ~= nil then self.pixel:setColor(self.params.pixelcolordisabled) end | ||
if self.params.text ~= nil then self.text:setTextColor(self.params.textcolordisabled) end | if self.params.text ~= nil then self.text:setTextColor(self.params.textcolordisabled) end | ||
− | elseif not self.params.hover then -- button does | + | elseif not self.params.hover and self.params.tooltiptext then -- button does hover but has a tooltip text |
− | if self.params.imgup ~= nil then self.bmpup:setVisible(true) end | + | if xstate and self.isclicked then -- button down state |
− | if self.params.imgdown ~= nil then self.bmpdown:setVisible(false) end | + | 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.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.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 | ||
else | else | ||
if xstate then -- button down state | if xstate then -- button down state | ||
Line 1,153: | Line 1,151: | ||
end | end | ||
end | end | ||
− | -- if self. | + | |
− | if self. | + | -- if self.params.tooltiptext and not self.disabled then -- you can choose this option: hides to 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 xstate then -- button hover state | ||
if self.disabled then | if self.disabled then | ||
− | self. | + | self.tooltiptext:setText("( "..self.params.tooltiptext.." )") |
else | else | ||
− | self. | + | self.tooltiptext:setText(self.params.tooltiptext) |
end | end | ||
− | self. | + | self.tooltiptext:setVisible(true) |
else -- button no hover state | else -- button no hover state | ||
− | self. | + | self.tooltiptext:setText("") |
− | self. | + | self.tooltiptext:setVisible(false) |
end | end | ||
end | end | ||
end | end | ||
− | function | + | -- disabled |
+ | function ButtonTextP9UDDT:setDisabled(xdisabled) | ||
if self.disabled == xdisabled then return end | if self.disabled == xdisabled then return end | ||
self.disabled = xdisabled | self.disabled = xdisabled | ||
Line 1,176: | Line 1,176: | ||
end | end | ||
− | function | + | function ButtonTextP9UDDT:isDisabled() |
return self.disabled | return self.disabled | ||
end | end | ||
− | -- | + | -- MOUSE LISTENERS |
− | + | function ButtonTextP9UDDT:onMouseDown(e) | |
− | function | ||
if self:hitTestPoint(e.x, e.y) then | if self:hitTestPoint(e.x, e.y) then | ||
self.focus = true | self.focus = true | ||
+ | self.isclicked = true -- 200608 | ||
self:updateVisualState(true) | self:updateVisualState(true) | ||
e:stopPropagation() | e:stopPropagation() | ||
end | end | ||
end | end | ||
− | function | + | function ButtonTextP9UDDT:onMouseMove(e) |
if self:hitTestPoint(e.x, e.y) then | if self:hitTestPoint(e.x, e.y) then | ||
self.focus = true | self.focus = true | ||
+ | self.isclicked = false -- 200608 | ||
e:stopPropagation() | e:stopPropagation() | ||
else | else | ||
self.focus = false | self.focus = false | ||
− | -- e:stopPropagation() -- you may want to | + | -- e:stopPropagation() -- you may want to remove this line |
end | end | ||
self:updateVisualState(self.focus) | self:updateVisualState(self.focus) | ||
end | end | ||
− | function | + | function ButtonTextP9UDDT:onMouseUp(e) |
− | if self.focus then | + | if self.focus and self.isclicked then |
self.focus = false | self.focus = false | ||
− | self | + | self.isclicked = false -- 200608 |
if not self.disabled then | if not self.disabled then | ||
− | self:dispatchEvent(Event.new("clicked")) -- button is clicked | + | self:dispatchEvent(Event.new("clicked")) -- button is clicked |
end | end | ||
e:stopPropagation() | e:stopPropagation() | ||
end | end | ||
end | end | ||
− | function | + | function ButtonTextP9UDDT:onMouseHover(e) |
if self.catcher:hitTestPoint(e.x, e.y) then | if self.catcher:hitTestPoint(e.x, e.y) then | ||
self.focus = false | self.focus = false | ||
end | end | ||
if self.sprite:hitTestPoint(e.x, e.y) then | if self.sprite:hitTestPoint(e.x, e.y) then | ||
− | if self. | + | if self.params.tooltiptext then self.tooltiptext:setPosition(self.sprite:globalToLocal(e.x, e.y)) end |
self.focus = true | self.focus = true | ||
end | end | ||
Line 1,220: | Line 1,221: | ||
end | end | ||
</source> | </source> | ||
− | |||
=== Toggle Button === | === Toggle Button === |
Revision as of 08:50, 8 June 2020
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
--[[
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
Simple Text Button
--[[
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.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(128, 128)
stage:addChild(mybtnquit)
mybtnquit:addEventListener("clicked", function() print("you clicked me!") 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.textcolordisabled = xparams.textcolordisabled or 0x777777 -- 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!
-- button has images/pixel/text?
if self.params.pixelcolorup ~= nil then self.haspixel = true else self.haspixel = false end
if self.params.text ~= nil then self.hastext = true else self.hastext = false end
-- EXTRAS
if self.params.isautoscale == 0 then self.params.isautoscale = false else self.params.isautoscale = true end
-- warnings
if not self.haspixel and not self.hastext 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.hastext 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.haspixel then
if self.params.isautoscale and self.hastext 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.hastext then self.sprite:addChild(self.text) end
-- mouse catcher
self.catcher:setDimensions(self.sprite:getWidth() + 8 * 2, self.sprite:getHeight() + 8 * 2) -- magik number
self.catcher:setAnchorPoint(0.5, 0.5)
end
--function ButtonTextBasic:setTextColor(xcolor)
-- self.text:setTextColor(xcolor or 0x0)
--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
-- BUTTON LISTENERS
-- mouse
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 comment this line
end
self:updateVisualState(self.focus)
end
function ButtonTextBasic: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 "clicked" event
end
e:stopPropagation()
end
end
Button with an Up, Down and Disabled state (UDD)
--[[
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
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.
--[[
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
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.
--[[
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
Button with Text, Pixel, Images UDD, 9 Patch, 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.
--[[
ButtonTextP9UDDT
A Button class with text, Pixel, images 9patch (Up, Down, Disabled) and Tooltip
This code is CC0
github: mokalux
v 0.1.4: 2020-06-08 removed useless variables
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)
]]
--[[
-- SAMPLES
-- BUTTON QUIT
local mybtnquit = ButtonTextP9UDDT.new({
imgup="gfx/ui/btn_01_up.png", imgdown="gfx/ui/btn_01_down.png",imgdisabled="gfx/ui/btn_01_disabled.png",
text="QUIT", font=g_font1, fontsize=32, textcolorup=mytextcolorup, textcolordown=mytextcolordown,
tooltiptext="QUIT?",
})
mybtnquit:setPosition(2 * myappwidth / 10, 8.75 * myappheight / 10 + myapptop)
self:addChild(mybtnquit)
mybtnquit:addEventListener("clicked", function() self:goExit() end)
mybtnquit:setDisabled(true)
]]
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 self.params.pixelcolorup -- color
self.params.pixelcolordisabled = xparams.pixelcolordisabled or 0x555555 -- 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
-- textures?
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.imagealpha = xparams.imagealpha or 1 -- number
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.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 0x777777 -- 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.hover = xparams.hover or 0 -- number (default 0 = false)
self.params.defaultpadding = xparams.defaultpadding or 12 -- number
self.params.tooltiptext = xparams.tooltiptext or nil -- string
-- LET'S GO!
if self.params.isautoscale == 0 then self.params.isautoscale = false else self.params.isautoscale = true end
if self.params.hover == 0 then self.params.hover = false else self.params.hover = 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
-- draws a pixel around the button to catch the mouse leaving the button
self.catcher = Pixel.new(0x0, 0.25, 1, 1)
self:addChild(self.catcher)
-- 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("*** no mouse hover effect ***")
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
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
-- 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 or self.params.defaultpadding),
textheight + (self.params.imagepaddingy or self.params.defaultpadding))
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 or self.params.defaultpadding),
textheight + (self.params.imagepaddingy or self.params.defaultpadding))
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 or self.params.defaultpadding),
textheight + (self.params.imagepaddingy or self.params.defaultpadding))
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(nil, self.params.tooltiptext)
self.tooltiptext:setScale(2) -- magik
self.tooltiptext:setTextColor(0xffff00) -- magik
self.tooltiptext:setVisible(false)
-- self.sprite:addChild(self.tooltiptext) -- best to add here?
self:addChild(self.tooltiptext) -- or here to self?
end
-- fits the mouse catcher a little bigger than the button
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 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.pixelcolorup ~= 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 and self.params.tooltiptext then -- button does hover but has a tooltip text
if xstate and self.isclicked 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.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.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
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.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.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 to 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:setText("")
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) then
self.focus = true
self.isclicked = true -- 200608
self:updateVisualState(true)
e:stopPropagation()
end
end
function ButtonTextP9UDDT:onMouseMove(e)
if self:hitTestPoint(e.x, e.y) then
self.focus = true
self.isclicked = false -- 200608
e:stopPropagation()
else
self.focus = false
-- e:stopPropagation() -- you may want to remove this line
end
self:updateVisualState(self.focus)
end
function ButtonTextP9UDDT:onMouseUp(e)
if self.focus and self.isclicked then
self.focus = false
self.isclicked = false -- 200608
if not self.disabled then
self:dispatchEvent(Event.new("clicked")) -- button is clicked
end
e:stopPropagation()
end
end
function ButtonTextP9UDDT:onMouseHover(e)
if self.catcher:hitTestPoint(e.x, e.y) then
self.focus = false
end
if self.sprite:hitTestPoint(e.x, e.y) then
if self.params.tooltiptext then self.tooltiptext:setPosition(self.sprite:globalToLocal(e.x, e.y)) end
self.focus = true
end
self:updateVisualState(self.focus)
end
Toggle Button
--[[
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