Created
October 1, 2012 01:57
-
-
Save devilstower/3809036 to your computer and use it in GitHub Desktop.
Cider Library for Codea
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--# DropList | |
DropList = class() | |
function DropList:init(s, left, bottom, right, top) | |
local i, k | |
self.frame = Frame(left, bottom, right, top) | |
self.text = s | |
self.itemText = {} | |
self.value = 1 | |
self.background = color(255, 255, 255, 255) | |
self.foreground = color(31, 31, 31, 255) | |
i = 0 | |
for k in string.gmatch(s,"([^;]+)") do | |
i = i + 1 | |
self.itemText[i] = k | |
end | |
self.open = false | |
self.selected = 1 | |
end | |
function DropList:draw() | |
local i, t, h | |
textMode(CENTER) | |
stroke(self.foreground) | |
fill(self.background) | |
self.frame:draw() | |
fill(self.foreground) | |
if self.open then | |
for i, t in ipairs(self.itemText) do | |
text(t, self.frame:midX(), self.frame.top - i * 30 + 15) | |
end | |
strokeWidth(2) | |
stroke(243, 9, 9, 255) | |
line(self.frame.left + 4, | |
self.frame.top - self.selected * 30, | |
self.frame.right - 4, self.frame.top - self.selected * 30) | |
line(self.frame.left + 4, | |
self.frame.top - self.selected * 30 + 30, | |
self.frame.right - 4, self.frame.top - self.selected * 30 + 30) | |
else | |
text(self.itemText[self.selected], self.frame:midX(), | |
self.frame:midY()) | |
end | |
end | |
function DropList:touched(touch) | |
local h, tRect | |
h = #self.itemText * 30 | |
if self.frame:touched(touch) then | |
if not self.open then | |
if touch.state == BEGAN then | |
self.open = true | |
self.frame.bottom = self.frame.top - h | |
end | |
else | |
self.selected = | |
math.floor((self.frame.top - touch.y) / 30) | |
if self.selected < 1 then self.selected = 1 | |
elseif self.selected > #self.itemText then | |
self.selected = #self.itemText | |
end | |
end | |
end | |
if touch.state == ENDED then | |
self.open = false | |
self.frame.bottom = self.frame.top - 30 | |
end | |
end | |
--# Frame | |
Frame = class() | |
-- Frame | |
-- ver. 1.5 | |
-- a simple rectangle for holding controls. | |
-- ==================== | |
function Frame:init(left, bottom, right, top) | |
self.left = left | |
self.right = right | |
self.bottom = bottom | |
self.top = top | |
end | |
function Frame:inset(dx, dy) | |
self.left = self.left + dx | |
self.right = self.right - dx | |
self.bottom = self.bottom + dy | |
self.top = self.top - dy | |
end | |
function Frame:offset(dx, dy) | |
self.left = self.left + dx | |
self.right = self.right + dx | |
self.bottom = self.bottom + dy | |
self.top = self.top + dy | |
end | |
function Frame:draw() | |
pushStyle() | |
rectMode(CORNERS) | |
rect(self.left, self.bottom, self.right, self.top) | |
popStyle() | |
end | |
function Frame:roundRect(r) | |
pushStyle() | |
insetPos = vec2(self.left + r,self.bottom + r) | |
insetSize = vec2(self:width() - 2 * r,self:height() - 2 * r) | |
rectMode(CORNER) | |
rect(insetPos.x, insetPos.y, insetSize.x, insetSize.y) | |
if r > 0 then | |
smooth() | |
lineCapMode(ROUND) | |
strokeWidth(r * 2) | |
line(insetPos.x, insetPos.y, | |
insetPos.x + insetSize.x, insetPos.y) | |
line(insetPos.x, insetPos.y, | |
insetPos.x, insetPos.y + insetSize.y) | |
line(insetPos.x, insetPos.y + insetSize.y, | |
insetPos.x + insetSize.x, insetPos.y + insetSize.y) | |
line(insetPos.x + insetSize.x, insetPos.y, | |
insetPos.x + insetSize.x, insetPos.y + insetSize.y) | |
end | |
popStyle() | |
end | |
function Frame:gloss(baseclr) | |
local i, t, r, g, b, y | |
pushStyle() | |
if baseclr == nil then baseclr = color(194, 194, 194, 255) end | |
fill(baseclr) | |
rectMode(CORNERS) | |
rect(self.left, self.bottom, self.right, self.top) | |
r = baseclr.r | |
g = baseclr.g | |
b = baseclr.b | |
for i = 1 , self:height() / 2 do | |
r = r - 1 | |
g = g - 1 | |
b = b - 1 | |
stroke(r, g, b, 255) | |
y = (self.bottom + self.top) / 2 | |
line(self.left, y + i, self.right, y + i) | |
line(self.left, y - i, self.right, y - i) | |
end | |
popStyle() | |
end | |
function Frame:shade(base, step) | |
pushStyle() | |
strokeWidth(1) | |
for y = self.bottom, self.top do | |
i = self.top - y | |
stroke(base - i * step, base - i * step, base - i * step, 255) | |
line(self.left, y, self.right, y) | |
end | |
popStyle() | |
end | |
function Frame:touched(touch) | |
if touch.x >= self.left and touch.x <= self.right then | |
if touch.y >= self.bottom and touch.y <= self.top then | |
return true | |
end | |
end | |
return false | |
end | |
function Frame:ptIn(x, y) | |
if x >= self.left and x <= self.right then | |
if y >= self.bottom and y <= self.top then | |
return true | |
end | |
end | |
return false | |
end | |
function Frame:overlaps(f) | |
if self.left > f.right or self.right < f.left or | |
self.bottom > f.top or self.top < f.bottom then | |
return false | |
else | |
return true | |
end | |
end | |
function Frame:width() | |
return self.right - self.left | |
end | |
function Frame:height() | |
return self.top - self.bottom | |
end | |
function Frame:midX() | |
return (self.left + self.right) / 2 | |
end | |
function Frame:midY() | |
return (self.bottom + self.top) / 2 | |
end | |
--# IconButton | |
IconButton = class() | |
-- IconButton | |
-- ver. 1.0 | |
-- a simple control that centers an image in a frame | |
-- ==================== | |
function IconButton:init(x1, y1, x2, y2, img) | |
self.frame = Frame(x1, y1, x2, y2) | |
self.img = img | |
end | |
function IconButton:draw() | |
fill(52, 52, 52, 255) | |
self.frame:draw() | |
sprite(self.img, self.frame:midX(), self.frame:midY()) | |
end | |
function IconButton:touched(touch) | |
return self.frame:touched(touch) | |
end | |
--# Label | |
Label = class() | |
-- Label | |
-- ver. 1.5 | |
-- a control for basic text label | |
-- ==================== | |
function Label:init(s, left, bottom, right, top) | |
self.text = s | |
self.frame = Frame(left, bottom, right, top) | |
self.font = "ArialMT" | |
self.fontSize = 14 | |
self.background = color(222, 222, 222, 255) | |
self.foreground = color(20, 20, 20, 255) | |
end | |
function Label:draw() | |
local x, w, h | |
pushStyle() | |
pushMatrix() | |
font(self.font) | |
textMode(CENTER) | |
fontSize(self.fontSize) | |
fill(self.foreground) | |
text(self.text, self.frame:midX(), self.frame:midY()) | |
popMatrix() | |
popStyle() | |
end | |
function Label:touched(touch) | |
return self.frame:touched(touch) | |
end | |
--# Main | |
-- Cider Library | |
-- Use this fuile to test and demostrate controls in the library | |
function setup() | |
print("Hello World!") | |
btnTest = TextButton("Button", 100, HEIGHT - 100, 250, HEIGHT - 70) | |
txtTest = TextBox("Text Box", 100, HEIGHT - 160, 250, HEIGHT - 130) | |
sldTest = Slider("sTest", 100, 100, 300, 150, 14, 48, 14) | |
swtTest = Switch("On;Off", 100, 200, 200, 230, 14, 48, 14) | |
mlbTest = MultiButton("Left;Center;Right", 100, 400, 450, 440) | |
end | |
-- This function gets called once every frame | |
function draw() | |
-- This sets a dark background color | |
background(181, 181, 181, 255) | |
-- This sets the line thickness | |
strokeWidth(5) | |
-- Do your drawing here | |
btnTest:draw() | |
txtTest:draw() | |
sldTest:draw() | |
swtTest:draw() | |
mlbTest:draw() | |
--touched(CurrentTouch) | |
end | |
function touched(touch) | |
sldTest:touched(touch) | |
swtTest:touched(touch) | |
mlbTest:touched(touch) | |
end | |
--# MultiButton | |
MultiButton = class() | |
function MultiButton:init(s, left, bottom, right, top) | |
local i, k | |
self.text = s | |
self.frame = Frame(left, bottom, right, top) | |
self.font = "ArialMT" | |
self.fontSize = 14 | |
self.background = color(255, 255, 255, 255) | |
self.foreground = color(20, 20, 20, 255) | |
self.highlight = color(22, 127, 185, 32) | |
self.selected = 1 | |
self.itemText = {} | |
i = 0 | |
for k in string.gmatch(s,"([^;]+)") do | |
i = i + 1 | |
self.itemText[i] = k | |
end | |
end | |
function MultiButton:draw() | |
local w | |
w = (self.frame:width()) / #self.itemText | |
h = self.frame:height() | |
strokeWidth(2) | |
fill(self.background) | |
stroke(self.foreground) | |
self.frame:roundRect(6) | |
noStroke() | |
stroke(self.background) | |
self.frame:inset(2, 2) | |
self.frame:roundRect(6) | |
self.frame:inset(-2, -2) | |
stroke(self.foreground) | |
textMode(CENTER) | |
font(self.font) | |
fontSize(self.fontSize) | |
for i, b in ipairs(self.itemText) do | |
fill(self.foreground) | |
strokeWidth(2) | |
if i < #self.itemText then | |
line(self.frame.left + i * w, self.frame.top, | |
self.frame.left + i * w, self.frame.bottom) | |
end | |
text(b, (self.frame.left + i * w) - (w / 2), | |
self.frame:midY()) | |
noStroke() | |
fill(0, 0, 0, 22) | |
if i ~= self.selected then | |
rect(self.frame.left + i * w - w, self.frame:midY() - h/4, | |
w, self.frame:height() * 0.4 ) | |
rect(self.frame.left + i * w - w, self.frame.bottom, | |
w, self.frame:height() * 0.4 ) | |
else | |
fill(self.highlight) | |
rect(self.frame.left + i * w - w, self.frame:midY() - h/4, | |
w, self.frame:height() * 0.6) | |
rect(self.frame.left + i * w - w, self.frame:midY(), | |
w, self.frame:height() * 0.4 ) | |
rect(self.frame.left + i * w - w, self.frame:midY() + h/4, | |
w, self.frame:height() * 0.3 ) | |
end | |
end | |
end | |
function MultiButton:touched(touch) | |
if self.frame:touched(touch) then | |
if touch.state == BEGAN and oldState ~= BEGAN then | |
w = (self.frame:width()) / #self.itemText | |
i = math.floor((touch.x - self.frame.left) / w) + 1 | |
self.selected = i | |
end | |
return true | |
end | |
end | |
--# PopMenu | |
PopMenu = class() | |
-- PopMenu | |
-- ver. 1.0 | |
-- a control that provides a simple menu | |
-- ==================== | |
function PopMenu:init(x, y) | |
self.x = x | |
self.y = y | |
self.items={} | |
self.frames = {} | |
end | |
function PopMenu:draw() | |
local h, w, x, i | |
pushStyle() | |
h = 10 | |
w = 100 | |
for i, item in ipairs(self.items) do | |
h = h + 60 | |
if string.len(item) * 20 > w then | |
w = string.len(item) * 20 | |
end | |
end | |
w = w + 20 | |
fill(0, 0, 0, 255) | |
rect(self.x, self.y, w, h) | |
textAlign(CENTER) | |
for i, item in ipairs(self.items) do | |
self.frames[i] = Frame(self.x + 10, self.y + i * 60 - 50, | |
self.x + w - 10, self.y + i * 60 ) | |
self.frames[i]:gloss(color(255, 255, 255, 255)) | |
x = self.x + w / 2 | |
text(item, x, self.y + i * 60 - 24) | |
end | |
popStyle() | |
end | |
function PopMenu:touched(touch) | |
local i | |
for i, frame in ipairs(self.frames) do | |
if frame:touched(touch) then | |
fill(255, 14, 0, 255) | |
frame:draw() | |
return i | |
end | |
end | |
return nil | |
end | |
--# Slider | |
Slider = class() | |
-- Slider | |
-- ver. 1.0 | |
-- a control that replicates the iparameter slider | |
-- ==================== | |
function Slider:init(s, left, bottom, right, top, min, max, val) | |
self.frame = Frame(left, bottom, right, top) | |
self.min = min | |
self.max = max | |
self.text = s | |
self.val = val | |
self.background = color(238, 238, 238, 255) | |
self.foreground = color(31, 31, 31, 255) | |
self.highlight = color(53, 176, 215, 255) | |
self.font = "ArialMT" | |
self.fontSize = 12 | |
end | |
function Slider:draw() | |
local x, y, scale | |
pushStyle() | |
textMode(CORNER) | |
textAlign(LEFT) | |
font(self.font) | |
fontSize(self.fontSize) | |
stroke(self.foreground) | |
fill(self.background) | |
h, w = textSize(self.max) | |
scale = ((self.frame.right - self.frame.left) - h * 2) / | |
(self.max - self.min) | |
x = self.frame.left + h + ((self.val - self.min) * scale) | |
y = (self.frame:midY() + self.frame.top) / 2 + 4 | |
strokeWidth(3) | |
line(self.frame.left + h, y, self.frame.right - h, y) | |
stroke(self.background) | |
line(self.frame.left + h, y + 2, self.frame.right - h, y + 2) | |
stroke(self.background) | |
line(self.frame.left + h, y, self.frame.right - h, y) | |
strokeWidth(1) | |
stroke(self.foreground) | |
fill(self.highlight) | |
ellipse(x, y, 20) | |
fill(self.foreground) | |
h, w = textSize("Slider") | |
text(self.min, self.frame.left, self.frame:midY()) | |
textAlign(RIGHT) | |
text(self.max, self.frame.right, self.frame:midY()) | |
textMode(CENTER) | |
textAlign(CENTER) | |
text(self.text, self.frame:midX(), self.frame:midY() + h) | |
if self.val > self.min and self.val < self.max then | |
text(self.val, x, self.frame.top - h) | |
end | |
popStyle() | |
end | |
function Slider:touched(touch) | |
local x, scale | |
if touch.state == BEGAN or touch.state == MOVING then | |
if self.frame:touched(touch) then | |
x = touch.x - self.frame.left - 10 | |
scale = ((self.frame.right - self.frame.left) - 20) / | |
(self.max - self.min) | |
self.val = math.floor(x / scale) + self.min | |
if self.val < self.min then | |
self.val = self.min | |
elseif self.val > self.max then | |
self.val = self.max | |
end | |
return true | |
end | |
end | |
end | |
--# Switch | |
Switch = class() | |
function Switch:init(s, left, bottom, right, top) | |
local i, k | |
self.text = s | |
self.frame = Frame(left, bottom, right, top) | |
self.blink = ElapsedTime | |
self.blinkstate = true | |
self.font = "ArialMT" | |
self.fontSize = 14 | |
self.background = color(255, 255, 255, 255) | |
self.foreground = color(20, 20, 20, 255) | |
self.highlight = color(23, 127, 185, 255) | |
self.selected = true | |
self.itemText = {} | |
i = 0 | |
for k in string.gmatch(s,"([^;]+)") do | |
i = i + 1 | |
self.itemText[i] = k | |
end | |
end | |
function Switch:draw() | |
strokeWidth(1) | |
if self.selected then | |
stroke(self.highlight) | |
fill(self.highlight) | |
h = self.frame:height() | |
self.frame:roundRect(h/2) | |
fill(255, 255, 255, 53) | |
rect(self.frame.left + h/2, self.frame.top - 10, | |
self.frame:width() - h, 8) | |
strokeWidth(1) | |
stroke(76, 76, 76, 255) | |
fill(227, 227, 227, 255) | |
ellipse(self.frame.right - h/2, | |
self.frame:midY(), self.frame:height()) | |
fill(self.foreground) | |
if #self.itemText > 0 then | |
text(self.itemText[1], self.frame:midX(), self.frame:midY()) | |
end | |
else | |
fill(self.background) | |
stroke(self.background) | |
h = self.frame:height() | |
self.frame:roundRect(h/2) | |
fill(0, 0, 0, 18) | |
rect(self.frame.left + h, self.frame.bottom + 2, | |
self.frame:width() - h*1.5, 8) | |
strokeWidth(1) | |
stroke(self.foreground) | |
fill(self.background) | |
ellipse(self.frame.left + h/2, | |
self.frame:midY(), self.frame:height()) | |
fill(self.foreground) | |
if #self.itemText > 1 then | |
text(self.itemText[2], self.frame:midX(), self.frame:midY()) | |
end | |
end | |
end | |
function Switch:touched(touch) | |
if self.frame:touched(touch) then | |
if touch.state == BEGAN and oldState ~= BEGAN then | |
self.selected = not self.selected | |
end | |
return true | |
end | |
end | |
--# TextBox | |
TextBox = class() | |
-- TextBox | |
-- ver. 2.0 | |
-- a control for basic string editing | |
-- ==================== | |
function TextBox:init(s, left, bottom, right, top) | |
self.text = s | |
self.frame = Frame(left, bottom, right, top) | |
self.blink = ElapsedTime | |
self.blinkstate = true | |
self.font = "ArialMT" | |
self.fontSize = 14 | |
self.background = color(255, 255, 255, 255) | |
self.foreground = color(20, 20, 20, 255) | |
self.selected = true | |
end | |
function TextBox:draw() | |
local x, w, h | |
pushStyle() | |
pushMatrix() | |
font(self.font) | |
textMode(CORNER) | |
textAlign(LEFT) | |
fontSize(self.fontSize) | |
noStroke() | |
fill(self.background) | |
w, h = textSize(self.text) | |
self.frame:draw() | |
fill(self.foreground) | |
text(self.text, self.frame.left + 4, self.frame.bottom + 4) | |
if self.selected then | |
if self.blink < ElapsedTime - 0.3 then | |
self.blink = ElapsedTime | |
self.blinkstate = not self.blinkstate | |
end | |
if self.blinkstate then | |
strokeWidth(2) | |
stroke(45, 45, 45, 255) | |
x = self.frame.left + w + 6 | |
line(x, self.frame.bottom + 2, x, self.frame.top - 2) | |
end | |
end | |
popMatrix() | |
popStyle() | |
end | |
function TextBox:touched(touch) | |
return self.frame:touched(touch) | |
end | |
function TextBox:acceptKey(k) | |
if self.selected then | |
if k ~= nil then | |
if string.byte(k) == nil then | |
if string.len(self.text) > 0 then | |
self.text = string.sub(self.text, | |
1, string.len(self.text) - 1) | |
end | |
end | |
self.text = self.text..k | |
end | |
end | |
end | |
--# TextButton | |
TextButton = class() | |
-- TextButton | |
-- ver. 1.0 | |
-- a control for displaying a simple button | |
-- ==================== | |
function TextButton:init(s, left, bottom, right, top) | |
local w, h | |
self.frame = Frame(left, bottom, right, top) | |
self.font = "ArialMT" | |
self.fontSize = 14 | |
self.text = s | |
self.foreground = color(62, 62, 62, 255) | |
self.background = color(200, 200, 200, 255) | |
end | |
function TextButton:draw() | |
pushStyle() | |
stroke(self.foreground) | |
fill(self.foreground) | |
self.frame:roundRect(10) | |
self.frame:offset(-2, 2) | |
stroke(self.background) | |
fill(self.background) | |
self.frame:roundRect(10) | |
self.frame:offset(2, -2) | |
fill(255, 255, 255, 44) | |
rect(self.frame.left + 12, self.frame.top - 12, | |
self.frame:width()- 24, 8) | |
fill(0, 0, 0, 36) | |
rect(self.frame.left + 12, self.frame.bottom + 4, | |
self.frame:width()- 24, 4) | |
fill(self.foreground) | |
text(self.text, self.frame:midX(), self.frame:midY() + 2) | |
popStyle() | |
end | |
function TextButton:touched(touch) | |
return self.frame:touched(touch) | |
end | |
--# Ttouch | |
Ttouch = class() | |
-- Translatable Touch | |
-- ver. 1.0 | |
-- maps fields of a touch but is easily modified. | |
-- ====================. | |
function Ttouch:init(touch) | |
self.x = touch.x | |
self.y = touch.y | |
self.state = touch.state | |
self.prevX = touch.prevX | |
self.prevY = touch.prevY | |
self.deltaX = touch.deltaX | |
self.deltaY = touch.deltaY | |
self.id = touch.id | |
self.tapCount = touch.tapCount | |
self.timer = 0 | |
end | |
function Ttouch:translate(x, y) | |
self.x = self.x - x | |
self.y = self.y - y | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment