UI Slider
From GiderosMobile
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
Here you will find various resources to help you create sliders in Gideros Studio.
note:You may have to provide your own assets (fonts, gfx, …)
Slider
-- UI Slider class
Slider = Core.class(Sprite)
function Slider:init(slit, knob)
self.slit = slit
self.width = self.slit:getWidth()
self:addChild(self.slit)
self.knob = knob
self:addChild(self.knob)
self.value = 0
self.isFocus = false
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
function Slider:onMouseDown(event)
if self.knob:hitTestPoint(event.x, event.y) then
self.isFocus = true
self.x0 = event.x
event:stopPropagation()
end
end
function Slider:onMouseMove(event)
if self.isFocus then
local dx = event.x - self.x0
self.knob:setX(self.knob:getX() + dx)
self.x0 = event.x
-- keep the knob position within its range
if self.knob:getX() < 0 then self.knob:setX(0) end
if self.knob:getX() > self.width then self.knob:setX(self.width) end
self.value = math.floor(100 * self.knob:getX() / self.width)
event:stopPropagation()
end
end
function Slider:onMouseUp(event)
if self.isFocus then
self.isFocus = false
event:stopPropagation()
end
end
function Slider:setValue(value)
local value = math.floor(value)
-- check within a range of [0, 100]
if value < 0 then value = 0 end
if value > 100 then value = 100 end
local posX = self.width * value / 100
self.knob:setPosition(posX, 0)
self.value = value
end
function Slider:getValue()
return self.value
end
---- USAGE
--local slit = Bitmap.new(Texture.new("Images/slit.png"))
--slit:setAnchorPoint(0, 0.5)
--local knob = Bitmap.new(Texture.new("Images/knob.png"))
--knob:setAnchorPoint(0.5, 0.5)
--local myslider = Slider.new(slit, knob)
--stage:addChild(myslider)
--slider:setValue(75)
Slider with Increments
Slider2 = Core.class(Sprite)
function Slider2:init(xparams)
local params = xparams or {}
params.maximum = xparams.maximum or 100
params.steps = xparams.steps or params.maximum
params.slitcolor = xparams.slitcolor or 0x0
params.slitalpha = xparams.slitalpha or 1
params.slitw = xparams.slitw or 64
params.slith = xparams.slith or 64
params.knobcolor = xparams.knobcolor or 0xffffff
params.knobalpha = xparams.knobalpha or 1
params.knobw = xparams.knobw or 32
params.knobh = xparams.knobh or 32
-- parametrable slit and knob
local slit = Pixel.new(params.slitcolor, params.slitalpha, params.slitw, params.slith)
slit:setAnchorPoint(0, 0.5)
local knob = Pixel.new(params.knobcolor, params.knobalpha, params.knobw, params.knobh)
knob:setAnchorPoint(0.5, 0.5)
-- order
self.width = slit:getWidth()
self:addChild(slit)
self.knob = knob
self:addChild(self.knob)
-- class variables
self.maximum = params.maximum
self.steps = params.steps
self.value = 0
self.isFocus = 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
-- events
function Slider2:onMouseDown(event)
if self:hitTestPoint(event.x, event.y) then
local x, y = self:globalToLocal(event.x, event.y)
self.isFocus = true
self.knob:setX(self:setRange(x, self.steps))
self.value = self:round(self.maximum * self.knob:getX() / self.width)
local e = Event.new("value_changed")
e.value = self.value
self:dispatchEvent(e)
event:stopPropagation()
end
end
function Slider2:onMouseMove(event)
if self.isFocus then
local x, y = self:globalToLocal(event.x, event.y)
self.knob:setX(self:setRange(x, self.steps))
self.value = self:round(self.maximum * self.knob:getX() / self.width)
local e = Event.new("value_changed")
e.value = self.value
self:dispatchEvent(e)
event:stopPropagation()
end
end
function Slider2:onMouseUp(event)
if self.isFocus then
self.isFocus = false
event:stopPropagation()
end
end
-- functions
function Slider2:setValue(value)
local value = math.floor(value)
-- check within a range of [0, max]
if value < 0 then value = 0 end
if value > self.maximum then value = self.maximum end
local posX = self.width * value / self.maximum
self.knob:setPosition(posX, 0)
self.value = value
end
function Slider2:setRange(x, xstep)
for s = 0, self.width do
if x <= 0 then
return 0
elseif x >= s * self.width / xstep and x <= (s + 1) * self.width / xstep then
return s * self.width / xstep
elseif x >= self.width then
return self.width
end
end
end
function Slider2:round(num)
return num + (2^52 + 2^51) - (2^52 + 2^51)
end
--[[
---- usage
-- bg
application:setBackgroundColor(0x333333)
-- a volume slider
local volumeslider = Slider2.new({
maximum=20, steps=4,
slitcolor=0x330033, slitalpha=1, slitw=512 - 64 * 2, slith=48,
knobcolor=0xff00ff, knobalpha=0.7, knobw=40, knobh=30,
})
volumeslider:setValue(10)
tfsfxvolume = TextField.new(nil, "VOLUME: "..volumeslider.value)
tfsfxvolume:setScale(4)
tfsfxvolume:setTextColor(0xffffff)
-- positions
tfsfxvolume:setPosition(64, 128)
volumeslider:setPosition(64, 196)
-- order
stage:addChild(tfsfxvolume)
stage:addChild(volumeslider)
-- listeners
function onVolumeValueChanged(ev)
tfsfxvolume:setText("VOLUME: "..ev.value)
g_sfxvolume = ev.value
end
volumeslider:addEventListener("value_changed", onVolumeValueChanged)
]]
Slider with Text (Increments)
You can rotate it as well (0 and 90° work best)
SliderText = Core.class(Sprite)
function SliderText:init(xparams)
local params = xparams or {}
params.initialvalue = xparams.initialvalue or 0
params.maximum = xparams.maximum or 100
params.steps = xparams.steps or params.maximum
params.slitcolor = xparams.slitcolor or 0x0
params.slitalpha = xparams.slitalpha or 1
params.slitw = xparams.slitw or 64
params.slith = xparams.slith or 64
params.knobcolor = xparams.knobcolor or 0xffffff
params.knobalpha = xparams.knobalpha or 1
params.knobw = xparams.knobw or 32
params.knobh = xparams.knobh or 32
params.text = xparams.text or nil
params.font = xparams.font or nil
params.textscale = xparams.textscale or 1
params.textcolor = xparams.textcolor or 0xffffff
params.textoffsetx = xparams.textoffsetx or 0
params.textoffsety = xparams.textoffsety or 0
params.textrotation = xparams.textrotation or 0
params.id = xparams.id or nil
-- slit and knob
self.slit = Pixel.new(params.slitcolor, params.slitalpha, params.slitw, params.slith)
self.slit:setAnchorPoint(0, 0.5)
self.knob = Pixel.new(params.knobcolor, params.knobalpha, params.knobw, params.knobh)
self.knob:setAnchorPoint(0.5, 0.5)
-- text
self.textfield = TextField.new(params.font, params.text)
self.textfield:setRotation(params.textrotation)
self.textfield:setScale(params.textscale)
self.textfield:setTextColor(params.textcolor)
-- order
self:addChild(self.slit)
self:addChild(self.knob)
self:addChild(self.textfield)
-- positions
self.textfield:setPosition(self.slit:getX() + params.textoffsetx, self.slit:getY() + params.textoffsety)
-- class variables
self.value = params.initialvalue
self.maximum = params.maximum
self.steps = params.steps
self.width = self.slit:getWidth()
self.text = params.text
self.isFocus = false
self.id = params.id
-- let's go!
if self.text then self.textfield:setText(self.text..self.value) end
self:setValue(self.value)
-- 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
-- events
function SliderText:onMouseDown(event)
-- if self:hitTestPoint(event.x, event.y) then
if self.slit:hitTestPoint(event.x, event.y) or self.knob:hitTestPoint(event.x, event.y) then
local x, y = self:globalToLocal(event.x, event.y)
self.isFocus = true
self.knob:setX(self:setRange(x, self.steps))
self.value = self:round(self.maximum * self.knob:getX() / self.width)
local e = Event.new("value_changed")
e.value = self.value
e.id = self.id
self:dispatchEvent(e)
if self.text then self.textfield:setText(self.text..self.value) end
event:stopPropagation()
end
end
function SliderText:onMouseMove(event)
if self.isFocus then
local x, y = self:globalToLocal(event.x, event.y)
self.knob:setX(self:setRange(x, self.steps))
self.value = self:round(self.maximum * self.knob:getX() / self.width)
local e = Event.new("value_changed")
e.value = self.value
e.id = self.id
self:dispatchEvent(e)
if self.text then self.textfield:setText(self.text..self.value) end
event:stopPropagation()
end
end
function SliderText:onMouseUp(event)
if self.isFocus then
self.isFocus = false
event:stopPropagation()
end
end
-- functions
function SliderText:setValue(xvalue)
-- local value = math.floor(xvalue)
local value = xvalue // 1
-- check within a range of [0, max]
if value < 0 then value = 0 end
if value > self.maximum then value = self.maximum end
local posX = self.width * value / self.maximum
self.knob:setPosition(posX, 0)
self.value = value
end
function SliderText:setRange(x, xstep)
for s = 0, self.width do
if x <= 0 then
return 0
elseif x >= s * self.width / xstep and x <= (s + 1) * self.width / xstep then
return s * self.width / xstep
elseif x >= self.width then
return self.width
end
end
end
function SliderText:round(num)
return num + (2^52 + 2^51) - (2^52 + 2^51)
end
--[[
---- usage
application:setBackgroundColor(0x333333)
-- sliders
local sliderA = SliderText.new({
initialvalue=2, maximum=10, -- steps=2,
slitcolor=0x330033, slitalpha=1, slitw=256*1.5, slith=48,
knobcolor=0xffff00, knobalpha=0.7, knobw=40, knobh=30,
text="SLIDER A: ", textscale=3, textoffsetx=64*0.2, textoffsety=48, textrotation=30,
id=1,
})
local sliderB = SliderText.new({
initialvalue=15, maximum=100, steps=5,
slitcolor=0x330033, slitalpha=1, slitw=256*1.5, slith=48,
knobcolor=0xff00ff, knobalpha=0.7, knobw=40, knobh=30,
text="SLIDER B: ", textscale=3, textoffsetx=64*0.2, textoffsety=48,
id=2,
})
local sliderC = SliderText.new({
initialvalue=1, maximum=2, --steps=5,
slitcolor=0x330033, slitalpha=1, slitw=256*0.7, slith=48,
knobcolor=0x00ffff, knobalpha=0.7, knobw=40, knobh=30,
text=nil, textscale=3, textoffsetx=64*0.2, textoffsety=48, textrotation=90,
id=3,
})
-- positions
sliderA:setPosition(64, 256*1.7)
sliderA:setRotation(-90)
sliderB:setPosition(64*2.5, 256*0.3)
sliderC:setPosition(64*6, 256*1.5)
sliderC:setRotation(-90)
-- order
stage:addChild(sliderA)
stage:addChild(sliderB)
stage:addChild(sliderC)
-- functions
function sliderCFunction(xvalue)
if xvalue >= 2 then sliderC.textfield:setText("HARD")
elseif xvalue >= 1 then sliderC.textfield:setText("MEDIUM")
else sliderC.textfield:setText("EASY")
end
end
-- let's go!
sliderCFunction(sliderC.value)
-- listeners
function onValueChanged(ev)
if ev.id == 3 then sliderCFunction(ev.value)
else print(ev.id, ev.value)
end
end
sliderA:addEventListener("value_changed", onValueChanged)
sliderB:addEventListener("value_changed", onValueChanged)
sliderC:addEventListener("value_changed", onValueChanged)
]]