Difference between revisions of "UI Slider"
(→Slider with Text (Increments): added if text != nil) |
m (Text replacement - "<source" to "<syntaxhighlight") |
||
Line 5: | Line 5: | ||
=== Slider === | === Slider === | ||
− | < | + | <syntaxhighlight lang="lua"> |
-- UI Slider class | -- UI Slider class | ||
Slider = Core.class(Sprite) | Slider = Core.class(Sprite) | ||
Line 79: | Line 79: | ||
=== Slider with Increments === | === Slider with Increments === | ||
− | < | + | <syntaxhighlight lang="lua"> |
Slider2 = Core.class(Sprite) | Slider2 = Core.class(Sprite) | ||
Line 210: | Line 210: | ||
=== Slider with Text (Increments) === | === Slider with Text (Increments) === | ||
'''You can rotate it as well (0 and 90° work best)''' | '''You can rotate it as well (0 and 90° work best)''' | ||
− | < | + | <syntaxhighlight lang="lua"> |
SliderText = Core.class(Sprite) | SliderText = Core.class(Sprite) | ||
Revision as of 14:32, 13 July 2023
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
<syntaxhighlight lang="lua"> -- 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) </source>
Slider with Increments
<syntaxhighlight lang="lua"> 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) ]] </source>
Slider with Text (Increments)
You can rotate it as well (0 and 90° work best) <syntaxhighlight lang="lua"> 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) ]] </source>