Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@devilstower
Created October 21, 2012 16:34
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save devilstower/3927512 to your computer and use it in GitHub Desktop.
Save devilstower/3927512 to your computer and use it in GitHub Desktop.
Cider 1.5
--# 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()
dragIndex = 0
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(0, "Control", 10, HEIGHT - 50,
130, HEIGHT - 10)
trayElement[2] = UIElement(1, "Label", 10, HEIGHT - 90,
130, HEIGHT - 60)
trayElement[3] = UIElement(2, "Button", 10, HEIGHT - 140,
140, HEIGHT - 100)
trayElement[4] = UIElement(3, "Text Box", 10, HEIGHT - 190,
140, HEIGHT - 160)
trayElement[5] = UIElement(4, "Switch;off", 10, HEIGHT - 240,
125, HEIGHT - 210)
trayElement[6] = UIElement(5, "", 10, HEIGHT - 300,
150, HEIGHT - 270)
trayElement[7] = UIElement(6, "Drop List", 10, HEIGHT - 350,
140, HEIGHT - 320)
trayElement[8] = UIElement(7, "Multi;Choice;Button", 10,
HEIGHT - 400, 150, HEIGHT - 370)
trayElement[9] = UIElement(8, "Check Box", 10,
HEIGHT - 450, 150, HEIGHT - 420)
trayElement[10] = UIElement(9, "Notch;Slider", 30,
HEIGHT - 520, 140, HEIGHT - 490)
trayElement[11] = UIElement(10, "IconButton", 30,
HEIGHT - 620, 140, HEIGHT - 550)
swtGrid = Switch("ON;OFF", 55, 90, 150, 120)
lblGrid = Label("Grid", 0, 90, 35, 100)
btnCode = TextButton("Save Code", 10, 30, 150, 70)
lblMain = Label("Main", 0, 130, 35, 140)
swtMain = Switch("ON;OFF", 55, 130, 150, 160)
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 - 76, r, t - 46)
drpFont.selected = 1
sldFontSize = Slider("", l, t - 130, r, t - 100,
8 , 48, 14)
mlbTextAlign = MultiButton("Left;Center;Right", l, t - 160,
r, t - 130)
ctlBackground = Control("", l, t - 200, r, t - 170)
ctlForeground = Control("", l, t - 240, r, t - 210)
ctlHighlight = Control("", l, t - 280, r, t - 250)
deleteBtn = TextButton("Delete", l - 80, b, l + 60, b + 40)
deleteBtn.background = color(224, 94, 94, 255)
clrChooser = nil
showBackgroundColor = false
showForegroundColor = false
showHighlightColor = false
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()
lblMain:draw()
swtMain:draw()
btnCode:draw()
popStyle()
popMatrix()
end
function drawProperties()
local i
pushStyle()
fontSize(14)
font("ArialMT")
dialog:draw()
strokeWidth(2)
stroke(30, 30, 30, 255)
for i = 1,10 do
line(dialog.left, dialog.top - i * 40,
dialog.right, dialog.top - i * 40)
end
deleteBtn:draw()
textMode(CORNER)
textAlign(LEFT)
fill(0, 0, 0, 255)
txtName:draw()
txtText:draw()
text("Name", dialog.left + 10, dialog.top - 70)
text("Text", dialog.left + 10, dialog.top - 110)
text("Font", dialog.left + 10, dialog.top - 150)
text("Font Size", dialog.left + 10, dialog.top - 190)
text("Text Align", dialog.left + 10, dialog.top - 230)
text("Background", dialog.left + 10, dialog.top - 270)
text("Foreground", dialog.left + 10, dialog.top - 310)
text("Highlight", dialog.left + 10, dialog.top - 350)
sldFontSize:draw()
mlbTextAlign:draw()
drpFont:draw()
ctlBackground:draw()
ctlForeground:draw()
ctlHighlight: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
if showBackgroundColor or showForegroundColor
or showHighlightColor then
clrChooser:draw()
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)
if swtMain.selected then
print("-- Generated by Cider")
print("-- ")
print("-- Add CiderControls as a dependency to enable controls")
print("-- ")
print(" ")
print("displayMode(FULLSCREEN)")
print("-- ")
print("function setup()")
else
print("-- ===================")
print("-- Copy into the setup function")
print("-- ===================")
end
for i, e in ipairs(elements) do
e:printInit()
end
if swtMain.selected then
print("end")
print("")
print("function draw()")
print(" background(194, 194, 194, 255)")
else
print(" ")
print("-- ===================")
print("-- Copy into the draw function")
print("-- ===================")
end
for i, e in ipairs(elements) do
e:printDraw()
end
if swtMain.selected then
print("end")
print("")
print("function touched(touch)")
else
print(" ")
print("-- ===================")
print("-- Copy into the touched function")
print("-- ===================")
end
for i, e in ipairs(elements) do
e:printTouched()
end
if swtMain.selected then
print("end")
print("")
else
print(" ")
print("-- ===================")
print("-- Copy into main, or modify your")
print("-- existing keyboard function")
print("-- ===================")
print(" ")
end
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 == NOTCHSLIDERTYPE or
dragElement.type == DROPLISTTYPE then
dragElement.element.itemText = {}
dragElement.element:splitText()
end
dragElement.element.font = drpFont.itemText[drpFont.selected]
dragElement.element.fontSize = sldFontSize.val
dragElement.element.background = ctlBackground.background
dragElement.element.foreground = ctlForeground.background
dragElement.element.highlight = ctlHighlight.background
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)
if ctlBackground:touched(touch) then
clrChooser = ColorSelector(ctlBackground:midX(),
ctlBackground.bottom)
clrChooser:setColor(ctlBackground.background)
showBackgroundColor = true
end
if ctlForeground:touched(touch) then
clrChooser = ColorSelector(ctlForeground:midX(),
ctlForeground.bottom)
clrChooser:setColor(ctlForeground.background)
showForegroundColor = true
end
if ctlHighlight:touched(touch) then
clrChooser = ColorSelector(ctlHighlight:midX(),
ctlHighlight.bottom)
clrChooser:setColor(ctlHighlight.background)
showHighlightColor = true
end
if deleteBtn:touched(touch) then
dragElement = nil
table.remove(elements, dragIndex)
showProperties = false
showHandles = false
end
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
ctlBackground.background = dragElement.element.background
ctlForeground.background = dragElement.element.foreground
ctlHighlight.background = dragElement.element.highlight
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 showBackgroundColor then
showBackgroundColor = clrChooser:touched(touch)
ctlBackground.background = clrChooser:getColor()
return false
elseif showForegroundColor then
showForegroundColor = clrChooser:touched(touch)
ctlForeground.background = clrChooser:getColor()
return false
elseif showHighlightColor then
showHighlightColor = clrChooser:touched(touch)
ctlHighlight.background = clrChooser:getColor()
return false
elseif 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)
swtGrid:touched(tt)
swtMain:touched(tt)
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)
dragIndex = i
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()
CONTROLTYPE = 0
LABELTYPE = 1
BUTTONTYPE = 2
TEXTBOXTYPE = 3
SWITCHTYPE = 4
SLIDERTYPE = 5
DROPLISTTYPE = 6
MULTIBUTTONTYPE = 7
CHECKBOXTYPE = 8
NOTCHSLIDERTYPE = 9
ICONBUTTONTYPE = 10
function UIElement:init(type, text, left, bottom, right, top)
self.type = type
self.element = nil
if type == CONTROLTYPE then
self.element = Control(text, left, bottom, right, top)
self.name = "control"
elseif 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"
elseif type == NOTCHSLIDERTYPE then
self.element = NotchSlider(text, left, bottom, right, top)
self.name = "notchSlider"
elseif type == ICONBUTTONTYPE then
self.element = IconButton(text, left, bottom, right, top,
"Cargo Bot:Crate Goal Red")
self.name = "iconButton"
end
end
function UIElement:draw()
self.element:draw()
end
function UIElement:printInit()
print(" "..self.name.." = "..self.element:initString())
if self.element.fontSize ~= 16 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