Difference between revisions of "UI Slider"
From GiderosMobile
(→Slider with Text (Increments): added id) |
(→Slider with Text (Increments): added if text != nil) |
||
Line 256: | Line 256: | ||
self.width = self.slit:getWidth() | self.width = self.slit:getWidth() | ||
self.text = params.text | self.text = params.text | ||
+ | self.isFocus = false | ||
self.id = params.id | self.id = params.id | ||
− | |||
-- let's go! | -- let's go! | ||
− | self.textfield:setText(self.text..self.value) | + | if self.text then self.textfield:setText(self.text..self.value) end |
self:setValue(self.value) | self:setValue(self.value) | ||
-- event listeners | -- event listeners | ||
Line 281: | Line 281: | ||
self:dispatchEvent(e) | self:dispatchEvent(e) | ||
− | self.textfield:setText(self.text..self.value) | + | if self.text then self.textfield:setText(self.text..self.value) end |
event:stopPropagation() | event:stopPropagation() | ||
Line 298: | Line 298: | ||
self:dispatchEvent(e) | self:dispatchEvent(e) | ||
− | self.textfield:setText(self.text..self.value) | + | if self.text then self.textfield:setText(self.text..self.value) end |
event:stopPropagation() | event:stopPropagation() | ||
Line 313: | Line 313: | ||
-- functions | -- functions | ||
function SliderText:setValue(xvalue) | function SliderText:setValue(xvalue) | ||
− | + | -- local value = math.floor(xvalue) | |
+ | local value = xvalue // 1 | ||
-- check within a range of [0, max] | -- check within a range of [0, max] | ||
if value < 0 then value = 0 end | if value < 0 then value = 0 end | ||
Line 345: | Line 346: | ||
initialvalue=2, maximum=10, -- steps=2, | initialvalue=2, maximum=10, -- steps=2, | ||
slitcolor=0x330033, slitalpha=1, slitw=256*1.5, slith=48, | slitcolor=0x330033, slitalpha=1, slitw=256*1.5, slith=48, | ||
− | knobcolor= | + | knobcolor=0xffff00, knobalpha=0.7, knobw=40, knobh=30, |
− | text="SLIDER A: ", textscale=3, textoffsetx=64*0.2, textoffsety=48, textrotation= | + | text="SLIDER A: ", textscale=3, textoffsetx=64*0.2, textoffsety=48, textrotation=30, |
id=1, | id=1, | ||
}) | }) | ||
Line 355: | Line 356: | ||
text="SLIDER B: ", textscale=3, textoffsetx=64*0.2, textoffsety=48, | text="SLIDER B: ", textscale=3, textoffsetx=64*0.2, textoffsety=48, | ||
id=2, | 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 | -- positions | ||
Line 360: | Line 368: | ||
sliderA:setRotation(-90) | sliderA:setRotation(-90) | ||
sliderB:setPosition(64*2.5, 256*0.3) | sliderB:setPosition(64*2.5, 256*0.3) | ||
+ | sliderC:setPosition(64*6, 256*1.5) | ||
+ | sliderC:setRotation(-90) | ||
-- order | -- order | ||
stage:addChild(sliderA) | stage:addChild(sliderA) | ||
stage:addChild(sliderB) | 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 | -- listeners | ||
function onValueChanged(ev) | function onValueChanged(ev) | ||
− | print(ev.id, ev.value) | + | if ev.id == 3 then sliderCFunction(ev.value) |
+ | else print(ev.id, ev.value) | ||
+ | end | ||
end | end | ||
sliderA:addEventListener("value_changed", onValueChanged) | sliderA:addEventListener("value_changed", onValueChanged) | ||
sliderB:addEventListener("value_changed", onValueChanged) | sliderB:addEventListener("value_changed", onValueChanged) | ||
+ | sliderC:addEventListener("value_changed", onValueChanged) | ||
]] | ]] | ||
</source> | </source> |
Revision as of 22:21, 1 September 2021
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)
]]