Skip to content

Instantly share code, notes, and snippets.

@devilstower
Created October 18, 2012 03:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save devilstower/3909734 to your computer and use it in GitHub Desktop.
Save devilstower/3909734 to your computer and use it in GitHub Desktop.
Cider 1.3
--# Main
-- Cider
-- an interactive interface builder for Codea
-- version 1.3
-- 9 October 2012
-- Mark Sumner
-- devilstower@gmail.com
-- 1.3 adds CheckBox, bug fixes, code refactoring
-- 1.2 adds CCActiveTextBox to help simplify and manage text boxes
displayMode(FULLSCREEN)
minSize = 30
function setup()
activeTextBox = nil
controlCount = 1000
trayOpen = false
showCode = false
trayTab = Frame(WIDTH - 25, HEIGHT / 2 - 30,
WIDTH + 25, HEIGHT / 2 + 30)
trayWidth = 0
trayMaxWidth = 150
trayFrame = Frame(WIDTH - trayWidth, 0, trayMaxWidth, HEIGHT)
elements = {}
trayElement = {}
traySpeed = 20
trayElement[1] = UIElement(1, "Label", 10, HEIGHT - 60,
130, HEIGHT - 30)
trayElement[2] = UIElement(2, "Button", 10, HEIGHT - 110,
140, HEIGHT - 80)
trayElement[3] = UIElement(3, "Text Box", 10, HEIGHT - 160,
140, HEIGHT - 130)
trayElement[4] = UIElement(4, "Switch;off", 10, HEIGHT - 210,
110, HEIGHT - 180)
trayElement[5] = UIElement(5, "", 10, HEIGHT - 260,
150, HEIGHT - 230)
trayElement[6] = UIElement(6, "Drop List", 10, HEIGHT - 310,
140, HEIGHT - 280)
trayElement[7] = UIElement(7, "Multi;Choice;Button", 10,
HEIGHT - 370, 150, HEIGHT - 330)
trayElement[8] = UIElement(8, "Check Box", 10,
HEIGHT - 420, 40, HEIGHT - 390)
swtGrid = Switch("ON;OFF", 45, 90, 140, 120)
lblGrid = Label("Grid", 10, 90, 45, 120)
btnCode = TextButton("Save Code", 10, 40, 140, 70)
btnCode.background = color(147, 147, 147, 255)
eSelected = 0
eType = 0
dragElement = nil
leftTopSize = Frame(0, 0, 0, 0)
rightTopSize = Frame(0, 0, 0, 0)
leftBottomSize = Frame(0, 0, 0, 0)
rightBottomSize = Frame(0, 0, 0, 0)
infoRect = Frame(-90, 0, -90, 0)
startRect = Frame(0, 0, 0, 0)
stretch = 0
dialog = Dialog("Properties", 200, HEIGHT - 500,
WIDTH - 200, HEIGHT - 30)
showProperties = false
showHandles = false
l = dialog.left + 100
r = dialog.right - 30
b = dialog.bottom + 40
t = dialog.top - 75
txtName = TextBox("", l, t, r, t + 30)
txtText = TextBox("", l, t - 40, r, t - 10)
drpFont = DropList("ArialMT;Arial-BoldMT;Copperplate;"..
"Courier;TimesNewRomanPSMT", l, t - 80, r, t - 50)
drpFont.selected = 1
sldFontSize = Slider("", l, t - 120, r, t - 90,
8 , 48, 14)
mlbTextAlign = MultiButton("Left;Center;Right", l, t - 170,
r, t - 140)
dragElement = nil
offsetX = 0
offsetY = 0
stretch = 0
end
function drawTray()
pushMatrix()
pushStyle()
translate(WIDTH - trayWidth, 0)
for i, e in ipairs(trayElement) do
e:draw()
end
lblGrid:draw()
swtGrid:draw()
btnCode:draw()
popStyle()
popMatrix()
end
function drawProperties()
pushStyle()
fontSize(14)
font("ArialMT")
dialog:draw()
strokeWidth(2)
stroke(30, 30, 30, 255)
line(dialog.left, txtName.bottom - 4,
dialog.right, txtName.bottom - 4)
line(dialog.left, txtText.bottom - 4,
dialog.right, txtText.bottom - 4)
line(dialog.left, drpFont.top - 32,
dialog.right, drpFont.top - 32)
line(dialog.left, sldFontSize.top - 42,
dialog.right, sldFontSize.top - 42)
textMode(CORNER)
textAlign(LEFT)
fill(0, 0, 0, 255)
text("Name", dialog.left + 10, txtName.bottom + 4)
txtName:draw()
text("Text", dialog.left + 10, txtText.bottom + 4)
txtText:draw()
text("Font", dialog.left + 10, drpFont.top - 24)
text("Font Size", dialog.left + 10, sldFontSize.top - 24)
text("Text Align", dialog.left + 10, mlbTextAlign.bottom + 6)
sldFontSize:draw()
mlbTextAlign:draw()
drpFont:draw()
popStyle()
end
function draw()
-- This sets a dark background color
background(194, 194, 194, 255)
font("ArialMT")
fontSize(222)
fill(146, 140, 140, 29)
text("Cider", WIDTH / 2, HEIGHT / 2 + 200)
fontSize(72)
text("Interface Designer", WIDTH / 2, HEIGHT / 2 - 100)
fontSize(14)
-- Do your drawing here
for i, e in ipairs(elements) do
e:draw()
end
if trayOpen then
if trayWidth < trayMaxWidth then
trayWidth = trayWidth + traySpeed
trayTab:offset(-traySpeed , 0)
end
else
if trayWidth > 0 then
trayWidth = trayWidth - traySpeed
trayTab:offset(traySpeed , 0)
end
end
strokeWidth(2)
fill(216, 216, 216, 255)
ellipse(WIDTH - trayWidth, HEIGHT / 2, 40)
rect(WIDTH - trayWidth, 0, trayWidth, HEIGHT)
noStroke()
rect(WIDTH - trayWidth -5, HEIGHT / 2 - 18, 10, 36)
trayFrame.left = WIDTH - trayWidth
trayFrame.right = trayFrame.left + trayMaxWidth
strokeWidth(5)
stroke(127, 127, 127, 255)
line(WIDTH - trayWidth - 10, HEIGHT / 2,
WIDTH - trayWidth - 0, HEIGHT / 2 - 5)
line(WIDTH - trayWidth - 10, HEIGHT / 2,
WIDTH - trayWidth - 0, HEIGHT / 2 + 5)
if trayWidth > 0 then
drawTray()
end
if dragElement then
dragElement:draw()
end
if showHandles then
fontSize(14)
font("ArialMT")
strokeWidth(4)
stroke(78, 175, 203, 197)
noFill()
line(leftTopSize.left, leftTopSize.top,
leftTopSize.left + 15, leftTopSize.top)
line(leftTopSize.left, leftTopSize.top,
leftTopSize.left, leftTopSize.top - 15)
line(leftBottomSize.left, leftBottomSize.bottom,
leftBottomSize.left + 15, leftBottomSize.bottom)
line(leftBottomSize.left, leftBottomSize.bottom,
leftBottomSize.left, leftBottomSize.bottom + 15)
line(rightBottomSize.right - 15, rightBottomSize.bottom,
rightBottomSize.right, rightBottomSize.bottom)
line(rightBottomSize.right, rightBottomSize.bottom,
rightBottomSize.right, rightBottomSize.bottom + 15)
line(rightTopSize.right - 15, rightTopSize.top,
rightTopSize.right, rightTopSize.top)
line(rightTopSize.right, rightTopSize.top,
rightTopSize.right, rightTopSize.top - 15)
strokeWidth(1)
stroke(255, 255, 255, 255)
fill(93, 103, 230, 255)
ellipse(infoRect:midX(), infoRect:midY(), 25)
fill(255, 255, 255, 255)
text("i", infoRect:midX(), infoRect:midY())
end
if showProperties then
drawProperties()
end
end
function resetHandles(x, y)
l = dragElement.element.left - minSize
b = dragElement.element.bottom - minSize
r = dragElement.element.right
t = dragElement.element.top
x = dragElement.element:midX()
leftTopSize.left = l
leftTopSize.right = l + minSize
leftTopSize.bottom = t
leftTopSize.top = t + minSize
rightTopSize.left = r
rightTopSize.right = r + minSize
rightTopSize.bottom = t
rightTopSize.top = t + minSize
rightBottomSize.left = r
rightBottomSize.right = r + minSize
rightBottomSize.bottom = b
rightBottomSize.top = b + minSize
leftBottomSize.left = l
leftBottomSize.right = l + minSize
leftBottomSize.bottom = b
leftBottomSize.top = b + minSize
infoRect.left = x - minSize / 2
infoRect.right = x + minSize / 2
infoRect.bottom = t + minSize
infoRect.top = t + minSize * 2
end
function printElements()
showCode = true
displayMode(STANDARD)
print("-- ===================")
print("-- Copy into the init function")
print("-- ===================")
for i, e in ipairs(elements) do
e:printInit()
end
print(" ")
print("-- ===================")
print("-- Copy into the draw function")
print("-- ===================")
for i, e in ipairs(elements) do
e:printDraw()
end
print(" ")
print("-- ===================")
print("-- Copy into the touched function")
print("-- ===================")
for i, e in ipairs(elements) do
e:printTouched()
end
print(" ")
print("-- ===================")
print("-- Copy into main, or modify your")
print("-- existing keyboard function")
print("-- ===================")
print(" ")
print("function keyboard(key)")
print(" if CCActiveTextBox then")
print(" CCActiveTextBox:acceptKey(key)")
print(" end")
print("end")
print(" ")
end
function closeDialog()
showProperties = false
if string.len(txtName.text) > 0 then
dragElement.name = txtName.text
end
dragElement.element.text = txtText.text
if dragElement.type == SWITCHTYPE or
dragElement.type == MULTIBUTTONTYPE or
dragElement.type == DROPLISTTYPE then
dragElement.element.itemText = {}
dragElement.element:splitText()
end
dragElement.element.font = drpFont.itemText[drpFont.selected]
dragElement.element.fontSize = sldFontSize.val
if isKeyboardShowing() then hideKeyboard() end
if dragElement.type == TEXTBOXTYPE then
if mlbTextAlign.selected == 1 then
dragElement.element.textAlign = LEFT
elseif mlbTextAlign.selected == 2 then
dragElement.element.textAlign = CENTER
elseif mlbTextAlign.selected == 3 then
dragElement.element.textAlign = RIGHT
end
end
sound(SOUND_HIT, 28774)
end
function touchedProperties(touch)
if touch.state == BEGAN and oldState ~= BEGAN then
if dialog:touched(touch) then
txtName:touched(touch)
txtText:touched(touch)
drpFont:touched(touch)
sldFontSize:touched(touch)
mlbTextAlign:touched(touch)
else
closeDialog()
end
end
if touch.state == MOVING or touch.state == ENDED then
if dialog:touched(touch) then
drpFont:touched(touch)
sldFontSize:touched(touch)
end
end
oldState = touch.state
end
function touchedHandles(touch)
if touch.state == BEGAN and oldState ~= BEGAN then
stretch = 0
if leftTopSize:touched(touch) then stretch = 1
elseif rightTopSize:touched(touch) then stretch = 2
elseif leftBottomSize:touched(touch) then stretch = 3
elseif rightBottomSize:touched(touch) then stretch = 4
elseif infoRect:touched(touch) then
stretch = 5
showProperties = true
txtName.text = dragElement.name
txtText.text = dragElement.element.text
sldFontSize.val = dragElement.element.fontSize
if dragElement.type == LABELTYPE then
mlbTextAlign.selected = dragElement.element.textAlign
end
end
if stretch == 0 then
showHandles = false
end
elseif touch.state == MOVING then
if swtGrid.selected then
x = math.floor(touch.x / 20) * 20
y = math.floor(touch.y / 20) * 20
else
x = touch.x
y = touch.y
end
if stretch == 1 then
-- top left
if x > rightTopSize.left - minSize then
x = rightTopSize.left - minSize
end
if y < leftBottomSize.top + minSize then
y = leftBottomSize.top + minSize
end
dragElement.element.left = x
dragElement.element.top = y
elseif stretch == 2 then
-- top right
if x < leftTopSize.right + minSize then
x = leftTopSize.right + minSize
end
if y < leftBottomSize.top + minSize then
y = leftBottomSize.top + minSize
end
dragElement.element.right = x
dragElement.element.top = y
elseif stretch == 3 then
-- bottom left
if x > rightTopSize.left - minSize then
x = rightTopSize.left - minSize
end
if y > leftTopSize.bottom - minSize then
y = leftTopSize.bottom - minSize
end
dragElement.element.left = x
dragElement.element.bottom = y
elseif stretch == 4 then
-- bottom right
if x < leftTopSize.right + minSize then
x = leftTopSize.right + minSize
end
if y > leftTopSize.bottom - minSize then
y = leftTopSize.bottom - minSize
end
dragElement.element.right = x
dragElement.element.bottom = y
end
resetHandles()
elseif touch.state == ENDED and oldState == MOVING then
resetHandles()
end
end
function placeDragElement()
local e
if dragElement then
dragElement = nil
showHandles = false
end
end
function liftDragElement(e, l)
local ui
if l > 0 then
ui = UIElement(e.type, e.element.text, e.element.left + l,
e.element.bottom, e.element.right + l, e.element.top)
dragElement = ui
table.insert(elements, ui)
else
dragElement = e
end
showHandles = false
end
function touched(touch)
if showProperties then
touchedProperties(touch)
oldState = touch.state
return false
elseif showHandles and dragElement then
touchedHandles(touch)
if showProperties then return false end
end
if touch.state == BEGAN and oldState ~= BEGAN then
if showCode then
showCode = false
displayMode(FULLSCREEN)
return false
end
if dragElement and not showHandles then
if dragElement:touched(touch) then
showHandles = true
resetHandles(e)
end
end
if trayTab:touched(touch) then
placeDragElement()
trayOpen = not trayOpen
elseif trayOpen and trayFrame:touched(touch) then
if dragElement then placeDragElement() end
tt = Ttouch(touch)
tt:translate(trayFrame.left, 0)
if swtGrid:touched(tt) then
swtGrid.status = not swtGrid.status
end
if btnCode:touched(tt) then
printElements()
end
for i, e in ipairs(trayElement) do
if e:touched(tt) then
-- drag a new element into the table
liftDragElement(e, trayFrame.left)
dragElement.name = dragElement.name..controlCount
controlCount = controlCount + 1
offsetX = 0
trayOpen = false
end
end
else
-- pick up element
for i, e in ipairs(elements) do
if e:touched(touch) then
if dragElement then placeDragElement() end
liftDragElement(e, 0)
offsetX = e.element.left - touch.x
--table.remove(elements, i)
end
end
end
end
if touch.state == MOVING and dragElement
and showHandles == false then
w = dragElement.element:width()
h = dragElement.element:height()
if swtGrid.selected then
x = math.floor((touch.x + offsetX) / 20) * 20
y = math.floor(touch.y / 20) * 20
else
x = touch.x + offsetX
y = touch.y
end
dragElement.element.left = x
dragElement.element.right = x + w
dragElement.element.bottom = y
dragElement.element.top = y + h
elseif touch.state == ENDED and dragElement
and oldState == MOVING then
placeDragElement()
elseif touch.state == ENDED and dragElement
and oldState == BEGAN then
if dragElement:touched(touch) then
resetHandles(dragElement.element.left,
dragElement.element.right)
showHandles = true
else
showHandles = false
end
end
oldState = touch.state
end
function keyboard(key)
if showProperties then
if CCActiveTextBox then
CCActiveTextBox:acceptKey(key)
end
end
end
--# UIElement
UIElement = class()
LABELTYPE = 1
BUTTONTYPE = 2
TEXTBOXTYPE = 3
SWITCHTYPE = 4
SLIDERTYPE = 5
DROPLISTTYPE = 6
MULTIBUTTONTYPE = 7
CHECKBOXTYPE = 8
function UIElement:init(type, text, left, bottom, right, top)
self.type = type
self.element = nil
if type == LABELTYPE then
self.element = Label(text, left, bottom, right, top)
self.name = "label"
elseif type == BUTTONTYPE then
self.element = TextButton(text, left, bottom, right, top)
self.name = "button"
elseif type == TEXTBOXTYPE then
self.element = TextBox(text, left, bottom, right, top)
self.name = "textBox"
elseif type == SWITCHTYPE then
self.element = Switch(text, left, bottom, right, top)
self.name = "switch"
elseif type == SLIDERTYPE then
self.element = Slider(text, left, bottom, right, top,
0, 100, 50)
self.name = "slider"
elseif type == DROPLISTTYPE then
self.element = DropList(text, left, bottom, right, top)
self.name = "dropList"
elseif type == MULTIBUTTONTYPE then
self.element = MultiButton(text, left, bottom, right, top)
self.name = "multiButton"
elseif type == CHECKBOXTYPE then
self.element = CheckBox(text, left, bottom, right, top)
self.name = "checkBox"
end
end
function UIElement:draw()
self.element:draw()
end
function UIElement:printInit()
print(self.name.." = "..self.element:initString())
if self.element.fontSize ~= 14 then
print(self.name..".fontSize = "..self.element.fontSize)
end
if self.element.font ~= "ArialMT" then
print(self.name..".font = '"..self.element.font.."'")
end
end
function UIElement:printDraw()
print(self.name..":draw()")
end
function UIElement:printTouched()
print(self.name..":touched(touch)")
end
function UIElement:touched(touch)
return self.element:ptIn(touch.x, touch.y)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment