ButtonText class

From GiderosMobile
The class should be easy to adapt/modifiy

Button Text Class

--[[
-- ButtonText
-- A Button class with: Image, Text, Up state, Down state, Hover (ITUDH)
v 0.1.2: 2023-11-30 maintenance
v 0.1.1: 2020-03-07 added mouse hover
v 0.1.0: 2020-03-02 init (based on the initial generic Gideros Button class)
]]

ButtonText = Core.class(Sprite)

function ButtonText:init(xparams)
	-- the params
	self.params = xparams or {}
	self.params.imguptex = xparams.imguptex or nil -- img Up Texture
	self.params.imgdowntex = xparams.imgdowntex or self.params.imguptex -- img Down Texture
	self.params.imgscalex = xparams.imgscalex or 1 -- number or nil = autoscale
	self.params.imgscaley = xparams.imgscaley or self.params.imgscalex -- number or nil = autoscale
	self.params.text = xparams.text or nil -- string
	self.params.ttf = xparams.ttf or nil -- ttf font
	self.params.textscalex = xparams.textscalex or 1 -- number
	self.params.textscaley = xparams.textscaley or self.params.textscalex -- number
	self.params.textcolorup = xparams.textcolorup or 0x0 -- color
	self.params.textcolordown = xparams.textcolordown or self.params.textcolorup -- color
	-- let's go
	self:setButton()
	-- update visual state
	self.focus = false
	self:updateVisualState(false)
	-- register to all mouse 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.MOUSE_HOVER, self.onMouseHover, self)
	-- register to all touch events
	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 ButtonText:setButton()
	if self.params.imguptex then
		self.bmpup = Bitmap.new(self.params.imguptex)
		self.bmpup:setScale(self.params.imgscalex, self.params.imgscaley)
		self.bmpup:setAnchorPoint(0.5, 0.5)
		self:addChild(self.bmpup)
	end
	if self.params.imgdowntex then
		self.bmpdown = Bitmap.new(self.params.imgdowntex)
		self.bmpdown:setScale(self.params.imgscalex, self.params.imgscaley)
		self.bmpdown:setAnchorPoint(0.5, 0.5)
		self:addChild(self.bmpdown)
	end
	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:addChild(self.text)
	end
end

function ButtonText:onMouseDown(ev)
	if self:hitTestPoint(ev.x, ev.y) then
		self.focus = true
		self:updateVisualState(true)
		ev:stopPropagation()
	end
end
function ButtonText:onMouseMove(ev)
	if self.focus then
		if not self:hitTestPoint(ev.x, ev.y) then
			self.focus = false
			self:updateVisualState(false)
		end
		ev:stopPropagation() -- you may want to comment this line
	end
end
function ButtonText:onMouseUp(ev)
	if self.focus then
		self.focus = false
		self:updateVisualState(false)
		self:dispatchEvent(Event.new("clicked")) -- button is clicked, dispatch "clicked" event
		ev:stopPropagation()
	end
end
function ButtonText:onMouseHover(ev) -- mouse only
	if self:hitTestPoint(ev.x, ev.y) then -- onenter
		self.focus = true
		-- execute onenter code only once
		self.onenter = not self.onenter
		if not self.onenter then self.moving = true end
		if not self.moving then
			self:updateVisualState(true)
		else
			self.focus = false
			self.onexit = true
		end
		ev:stopPropagation()
	else -- onexit
		self.focus = false
		self.onenter = false
		self.moving = false
		if self.onexit then
			-- execute onexit code only once
			self.onexit = false
			self:updateVisualState(false)
		end
	end
end

-- if button is on focus, stop propagation of touch events
function ButtonText:onTouchesBegin(ev)
	if self.focus then
		ev:stopPropagation()
	end
end
-- if button is on focus, stop propagation of touch events
function ButtonText:onTouchesMove(ev)
	if self.focus then
		ev:stopPropagation()
	end
end
-- if button is on focus, stop propagation of touch events
function ButtonText:onTouchesEnd(ev)
	if self.focus then
		ev:stopPropagation()
	end
end
-- if touches are cancelled, reset the state of the button
function ButtonText:onTouchesCancel(ev) -- touch only
	if self.focus then
		self.focus = false
		self:updateVisualState(false)
		ev:stopPropagation()
	end
end

-- if state is true show downState else show upState
function ButtonText:updateVisualState(state)
--	print("updateVisualState")
	if state then -- downState
		if self.params.imguptex then self.bmpup:setVisible(false) end
		if self.params.imgdowntex then self.bmpdown:setVisible(true) end
		if self.params.text then self.text:setTextColor(self.params.textcolordown) end
	else -- upState
		if self.params.imguptex then self.bmpup:setVisible(true) end
		if self.params.imgdowntex then self.bmpdown:setVisible(false) end
		if self.params.text then self.text:setTextColor(self.params.textcolorup) end
	end
end

Button Text Demo

-- ButtonText DEMO
-- bg
application:setBackgroundColor(0x6c6c6c)
-- font
local myttf = TTFont.new("fonts/Cabin-Bold-TTF.ttf", 18)
-- textures
local texbtnup = Texture.new("gfx/ui/btn_01_up.png")
local texbtndown = Texture.new("gfx/ui/btn_01_down.png")
-- buttons
local btntext = ButtonText.new({
	imguptex=texbtnup, imgdowntex=texbtndown,
	text="ButtonText", ttf=myttf, textcolorup=0x0, textcolordown=0xffff00,
})
local btntext2 = ButtonText.new({
	imguptex=texbtnup, imgdowntex=texbtndown,
	text="ButtonText 2", ttf=myttf, textcolorup=0x0, textcolordown=0xffff00,
})
-- position
btntext:setPosition(16*4, 16*8.5)
btntext2:setPosition(16*13, 16*8.5)
-- order
stage:addChild(btntext)
stage:addChild(btntext2)
-- listeners
btntext:addEventListener("clicked", function() 
	print("button was clicked!")
end)
btntext2:addEventListener("clicked", function() 
	print("button 2 was clicked!")
end)


UI Buttons