I recently saw a picture of what all the iOS 7 UI elements would look like, and i needed to update my toggle class to match the look and feel. Enjoy the new version:
--# Main
-- iOS 7 UI
-- Use this function to perform your initial setup
function setup()
saveProjectInfo("Author", "Jordan Arenstein")
saveProjectInfo("Description", "iOS 7 style UI")
t = Toggle(WIDTH / 2, HEIGHT / 2, "bool")
end
-- This function gets called once every frame
function draw()
background(0, 0, 0, 255)
t:draw()
end
function touched(touch)
t:touched(touch)
end
--# Toggle
local vS = [[
uniform mat4 modelViewProjection;
attribute vec4 position;
attribute vec2 texCoord;
varying highp vec2 tC;
void main()
{
tC = texCoord;
gl_Position = modelViewProjection * position;
}
]]
local fS = [[
precision highp float;
varying highp vec2 tC;
uniform highp vec4 bg; // Background color
uniform highp vec4 s; // Stroke Colour
uniform highp float sw;
uniform highp vec4 t; // Toggle Colour
uniform highp vec2 d; // Dimensions
uniform highp float v; // Value from false (0) to true (1)
uniform highp vec4 b;
uniform highp float bw;
highp float r = (d.y / 2.)/ d.x; // Horizontal Radius
highp vec2 ls = vec2(r, .5); // Left Side
highp vec2 rs = vec2(1. - r, .5); // Right Side
highp vec2 lsd = tC - ls;
highp vec2 rsd = tC - rs;
highp vec2 vd = tC - vec2(r + (1. - r * 2.) * v, .5);
void main()
{
if (
(vd.x * vd.x) / (r * r) + (vd.y * vd.y) / 0.25 <= 1.
) {
if (
(vd.x * vd.x) / (r * r) + (vd.y * vd.y) / 0.25 <= 1. - sw / (d.y / 2.)
) {
gl_FragColor = t;
} else {
gl_FragColor = mix(s, bg, (vd.x * vd.x) / (r * r) + (vd.y * vd.y) / 0.25);
}
} else if (
tC.x > r && tC.x < 1. - r
) {
if (abs(tC.y - 0.5) * 2. <= 1. - bw / (d.y * 2.) * 2.) {
gl_FragColor = bg;
} else {
gl_FragColor = mix(b, bg, abs(tC.y - 0.5) * 2.);
}
} else if (
(lsd.x * lsd.x) / (r * r) + (lsd.y * lsd.y) / 0.25 <= 1.
) {
if ((lsd.x * lsd.x) / (r * r) + (lsd.y * lsd.y) / 0.25 >= 1. - bw / (d.y / 2.)) {
gl_FragColor = mix(b, bg, (lsd.x * lsd.x) / (r * r) + (lsd.y * lsd.y) / 0.25);
} else {
gl_FragColor = bg;
}
} else if (
(rsd.x * rsd.x) / (r * r) + (rsd.y * rsd.y) / 0.25 <= 1.
) {
if ((rsd.x * rsd.x) / (r * r) + (rsd.y * rsd.y) / 0.25 >= 1. - bw / (d.y / 2.)) {
gl_FragColor = mix(b, bg, (rsd.x * rsd.x) / (r * r) + (rsd.y * rsd.y) / 0.25);
} else {
gl_FragColor = bg;
}
} else {
discard;
}
}
]]
Toggle = class()
function Toggle:init(x, y, name, callback, initial)
if callback then
self.callback = callback
self.bool = initial
self.name = name
_G[self.name] = self.bool
elseif initial ~= nil then
if type(initial) == "function" then
self.callback = initial
self.name = name
_G[self.name] = _G[self.name] or true
self.bool = _G[self.name]
else
self.bool = initial
self.callback = function () end
self.name = name
_G[self.name] = self.bool
end
else
self.name = name
self.callback = function () end
_G[name] = _G[name] or true
self.bool = _G[name]
end
self.selected = nil
self.tapped = false
self.x, self.y = x, y
self.w, self.h = 50, 30
self.p = (self.bool and 1 or 0)
local w, h = self.w / 2, self.h / 2
self.colors = {}
self.colors.on = color(83, 215, 105, 255)
self.colors.off = color(255, 255, 255, 255)
self.mesh = mesh()
self.mesh.shader = shader(vS, fS)
self.mesh.shader.d = vec2(w, h)
self.mesh.shader.bg = self.colors.on
self.mesh.shader.t = self.colors.off
self.mesh.shader.s = color(0, 0, 0, 255)
self.mesh.shader.sw = 2
self.mesh.shader.b = color(229, 229, 229, 255)
self.mesh.shader.bw = 3
self.mesh.shader.v = 0.5
self.mesh.vertices = {
vec2(-w, -h), vec2(-w, h), vec2(w, h),
vec2(-w, -h), vec2(w, -h), vec2(w, h),
}
self.mesh.texCoords = {
vec2(0, 0), vec2(0, 1), vec2(1, 1),
vec2(0, 0), vec2(1, 0), vec2(1, 1)
}
self.mesh:setColors(255, 255, 255, 255)
end
function Toggle:draw()
self.mesh.shader.v = self.p
self.mesh.shader.bg = self.colors.on:mix(self.colors.off, self.p)
self.mesh.shader.b = self.colors.on:mix(self.colors.off, self.p * .8)
pushMatrix()
translate(self.x, self.y)
self.mesh:draw()
popMatrix()
end
function Toggle:touched(touch)
if math.abs(touch.x - self.x) < self.w and math.abs(touch.y - self.y) < self.h and touch.state == BEGAN and self.selected == nil then
self.selected = touch.id
self.tapped = true
elseif self.selected and touch.id == self.selected then
if touch.state == MOVING then
self.p = math.max(math.min(1, self.p + touch.deltaX / self.w), 0)
self.tapped = false
end
if touch.state == ENDED then
self.selected = nil
if self.tapped then
self:switch()
return
end
if self.bool then
if self.p < 1 - 1 / 6 then
self:switch()
else
self:reset()
end
else
if self.p > 1 / 6 then
self:switch()
else
self:reset()
end
end
end
end
end
function Toggle:switch()
self.bool = not self.bool
_G[self.name] = self.bool
self.callback(self.bool)
tween(0.25, self, { p = (self.bool and 1 or 0) })
end
function Toggle:reset()
tween(0.25, self, { p = (self.bool and 1 or 0) } )
end