Skip to content

Instantly share code, notes, and snippets.

@devilstower
Created August 11, 2013 14:18
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/6205085 to your computer and use it in GitHub Desktop.
Save devilstower/6205085 to your computer and use it in GitHub Desktop.
Cider7 7.0
--# Main
-- Cider 7
-- an interactive interface builder for Codea
-- version 7.0
-- 5 Aug 2013
-- Mark Sumner
-- devilstower@gmail.com
displayMode(FULLSCREEN)
supportedOrientations(PORTRAIT_ANY)
function setup()
elements = {}
dragElement = nil
selectedElement = 0
elementCount = 0
tray = Tray()
writer = CodeWriter()
dialog =nil
font("HelveticaNeue-Light")
end
function drawBackground()
pushStyle()
fontSize(222)
fill(146, 140, 140, 35)
text("Cider", WIDTH / 2, HEIGHT / 2 + 300)
text("7", WIDTH / 2, HEIGHT / 2 + 100)
fontSize(72)
text("Interface Designer", WIDTH / 2, HEIGHT / 2 - 150)
text("for Codea", WIDTH / 2, HEIGHT / 2 - 220)
fontSize(32)
text("Version 7.0", WIDTH / 2, 120)
text("by Mark Sumner", WIDTH / 2, 70)
popStyle()
end
function draw()
local i, x
background(255, 255, 255, 255)
if tray.swtTitle.selected then drawBackground() end
-- draw grid
stroke(146, 138, 138, 44)
strokeWidth(2)
if tray.swtGrid.selected then
for x=0, WIDTH, 20 do
line(x, 0, x, HEIGHT)
end
for x=0, HEIGHT, 20 do
line(0, x, WIDTH, x)
end
end
-- draw elements
for i, e in ipairs(elements) do
e:draw()
end
tray:draw()
if dialog ~= nil then
if dialog.visible then dialog:draw() end
end
if dragElement then
dragElement:draw()
end
end
function touched(touch)
local found
tray:touched(touch)
if dialog then dialog:touched(touch) end
if touch.state == BEGAN then
found = 0
for i, e in ipairs(elements) do
if e:touched(touch) then
found = i
end
end
if selectedElement > 0 then
elements[selectedElement].handles = false
end
selectedElement = found
if selectedElement > 0 then
elements[selectedElement].handles = true
elements[selectedElement]:setHandles()
end
end
if touch.state == MOVING then
if dragElement then
dragElement.element:setPosition(touch)
end
if selectedElement > 0 then
elements[selectedElement]:touched(touch)
end
end
if touch.state == ENDED then
if dragElement then
table.insert(elements, dragElement)
dragElement = nil
end
end
end
function keyboard(key)
if dialog.visible then
if CCActiveTextBox then
CCActiveTextBox:acceptKey(key)
end
end
end
--# PropertiesDialog
PropertiesDialog = class(Dialog)
function PropertiesDialog:init(tablePos, control)
Dialog.init(self, "Properties", 100, 280,
WIDTH - 200, HEIGHT - 290)
ds = ""
self.hasDrop = false
self.tablePos = tablePos
s = "&Name;"
s = s.."Font;"
s = s.."Background;"
s = s.."Foreground;"
s = s.."Text Color;"
s = s.."Highlight Color;"
s = s.."Highlighted Text Color;"
s = s.."&Text"
if control.type == TEXTFIELDTYPE then
s = s..";Style;&Title"
ds = "Standard;Titled;Search"
self.hasDrop = true
end
if control.type == BUTTONTYPE then
s = s..";Style"
ds = "Standard;Warning;Info;Details;Add;Round;Action"
self.hasDrop = true
end
self.list = SelectList(s, self.x + 10, self.y + 80,
self.w - 20, self.h - 150)
self.control = control
self.list.item[1].text = self.control.name
self.list.item[8].text = self.control.element.text
if self.hasDrop then
self.drop = DropList(ds, self.x + 335,
self.list.item[9].y + 4, 220, 30)
end
self.sldSize = Slider("Font Size", self.x + 30,
self.list.item[#self.list.item].y - 60, self.w - 60,
40, 1, 8, 48,
control.element.fontSize)
--self.list.item[1].type = 1
self.patches = {}
self.patches[1] = Frame(self:right() - 120, self.list.item[3].y + 4,
70, 30)
self.patches[2] = Frame(self:right() - 120, self.list.item[4].y + 4,
70, 30)
self.patches[3] = Frame(self:right() - 120, self.list.item[5].y + 4,
70, 30)
self.patches[4] = Frame(self:right() - 120, self.list.item[6].y + 4,
70, 30)
self.patches[5] = Frame(self:right() - 120, self.list.item[7].y + 4,
70, 30)
if control.type == TEXTFIELDTYPE then
self.list.item[10].text = control.element.title
self.drop.selectedItem = control.element.type + 1
end
if control.type == BUTTONTYPE then
self.drop.selectedItem = control.element.type + 1
end
self.colorSelector = ColorSelector(0, 0,
self.control.element.background)
self.sheet = ActionSheet("ArialMT;Copperplate-Light;"..
"Futura-Medium;GillSans-Light;HelveticaNeue;HelveticaNeue-Light;"..
"HelveticaNeue-UltraLight;Optima-Regular;SourceSansPro-Bold",
450, 450, 250, 480)
self.btnDelete = Button("Delete", self.x + 10, self.y + 10,
200, 50, ButtonTypeWarning)
self.btnOK = Button("OK", self:right() - 210, self.y + 10,
200, 50, 0)
self.btnOK.textColor = color(228, 226, 226, 255)
self.btnOK.background = color(78, 136, 78, 255)
self.visible = false
end
function PropertiesDialog:draw()
pushStyle()
Dialog.draw(self)
self.list:draw()
self.btnDelete:draw()
self.btnOK:draw()
fill(96, 96, 96, 255)
font(self.control.element.font)
text(self.control.element.font,
self:right() - 120, self.list.item[2]:midY())
-- color patches
stroke(178, 178, 178, 255)
strokeWidth(1)
fill(self.control.element.background)
self.patches[1]:draw()
fill(self.control.element.foreground)
self.patches[2]:draw()
fill(self.control.element.textColor)
self.patches[3]:draw()
fill(self.control.element.highlightColor)
self.patches[4]:draw()
fill(self.control.element.highlightedTextColor)
self.patches[5]:draw()
self.sldSize:draw()
font("HelveticaNeue-Light")
fontSize(self.sldSize.val)
fill(0, 0, 0, 255)
p = self.sldSize:getPointerPosition()
text(self.sldSize.val, p.x, p.y - 30)
if self.hasDrop then self.drop:draw() end
if self.colorSelector.visible then self.colorSelector:draw() end
if self.sheet.visible then self.sheet:draw() end
popStyle()
end
function PropertiesDialog:setColorSelector(x, y, c)
self.colorSelector = ColorSelector(x, y, c)
self.colorSelector.visible = true
end
function PropertiesDialog:getColorSelector()
self.colorSelector.closedOK = false
return self.colorSelector.color
end
function PropertiesDialog:touched(touch)
if not self.visible then
return false
else
if self.colorSelector.visible then
self.colorSelector:touched(touch)
elseif self.sheet.visible then
self.sheet:touched(touch)
if self.sheet.selectionMade then
self.control.element.font =
self.sheet.itemText[self.sheet.selectedItem]
self.sheet.visible = false
self.sheet.selectionMade = false
end
elseif self.hasDrop and self.drop:touched(touch) then
if self.control.type == BUTTONTYPE then
self.control.element:setType(self.drop.selectedItem - 1)
self.control.element.type = self.drop.selectedItem - 1
end
elseif self.sldSize:touched(touch) then
elseif self.list:touched(touch) and touch.state == BEGAN then
if self.list.selectedItem == 2 then
self.sheet.visible = true
end
if self.list.selectedItem == 3 then
self:setColorSelector(350, 600,
self.control.element.background)
end
if self.list.selectedItem == 4 then
self:setColorSelector(350, 570,
self.control.element.foreground)
end
if self.list.selectedItem == 5 then
self:setColorSelector(350, 540,
self.control.element.textColor)
end
if self.list.selectedItem == 6 then
self:setColorSelector(350, 510,
self.control.element.highlightColor)
end
if self.list.selectedItem == 7 then
self:setColorSelector(350, 540,
self.control.element.highlightedTextColor)
end
end
if self.colorSelector.visible == false and
self.colorSelector.closedOK then
if self.list.selectedItem == 3 then
self.control.element.background =
self:getColorSelector()
end
if self.list.selectedItem == 4 then
self.control.element.foreground =
self:getColorSelector()
end
if self.list.selectedItem == 5 then
self.control.element.textColor =
self:getColorSelector()
end
if self.list.selectedItem == 6 then
self.control.element.highlightColor =
self:getColorSelector()
end
if self.list.selectedItem == 7 then
self.control.element.highlightedTextColor =
self:getColorSelector()
end
end
end
if self.btnOK:touched(touch) then
self.visible = false
self.control.element.fontSize = self.sldSize.val
self.control.name = self.list.item[1].text
self.control.element.text = self.list.item[8].text
if isKeyboardShowing() then hideKeyboard() end
if self.control.type == TEXTFIELDTYPE then
self.control.element.title = self.list.item[10].text
self.control.element.type = self.drop.selectedItem - 1
end
if self.control.type == DROPLISTTYPE or
self.control.type == SEGMENTEDCONTROLTYPE then
self.control.element:splitText()
end
end
if self.btnDelete:touched(touch) then
print(self.tablePos)
table.remove(elements, self.tablePos)
selectedElement = 0
self.visible = false
end
end
--# Tray
Tray = class(Control)
function Tray:init()
Control.init(self, "", WIDTH, 0, 250, HEIGHT)
self.background = color(255, 255, 255, 255)
self.visible = true
self.handle = Frame(self.x-20, self:midY() - 40, 20, 80)
self.speed = 0
self.elements = {}
for i = 1, 10 do
self.elements[i] = UIElement(i, elementNames[i], 10,
HEIGHT - i * 70, 200, 40)
end
self.selectedElement = 0
self.swtGrid = Switch("Show Grid", 10, 90, 200, 35)
self.swtTitle = Switch("Show About", 10, 140, 200, 35)
self.swtTitle.selected = true
self.btnCode = Button("Save Code", 10, 30, 200, 35, 1)
self.btnCode.background = color(62, 170, 65, 255)
end
function Tray:move()
self.x = self.x + self.speed
end
function Tray:copyElement(e)
local u = {}
for k, v in pairs(e) do u[k] = v end
return setmetatable(u, getmetatable(t))
end
function Tray:draw()
-- update position
self:offset(self.speed, 0)
self.handle:offset(self.speed, 0)
if self.speed < 0 and self.x <= WIDTH - self.w then
self.speed = 0
elseif self.speed > 0 and self.x >= WIDTH then
self.speed = 0
end
-- draw handle
pushMatrix()
pushStyle()
fill(153, 165, 169, 255)
stroke(146, 158, 163, 255)
self.handle:roundRect(4)
fill(255, 255, 255, 255)
translate(self.handle:midX(), self.handle:midY())
rotate(90)
text("Controls", 0, 0)
popMatrix()
popStyle()
pushMatrix()
pushStyle()
-- draw outer box
stroke(self.foreground)
fill(self.background)
Frame.draw(self)
-- draw contents
translate(self.x, self.y)
for i, e in ipairs(self.elements) do
e:draw()
stroke(211, 211, 211, 255)
strokeWidth(1)
noSmooth()
line(e.element:left(), e.element:bottom() - 8,
e.element:right(), e.element:bottom() - 8)
smooth()
end
self.swtGrid:draw()
self.swtTitle:draw()
self.btnCode:draw()
translate(-self.x, -self.y)
popStyle()
popMatrix()
end
function Tray:touched(touch)
if self.handle:touched(touch) and touch.state == BEGAN then
if self.x >= WIDTH then
self.speed = - 50
elseif self.x <= WIDTH - self.w then
self.speed = 50
end
end
tt = Ttouch(touch)
tt.x = tt.x - self.x
self.swtGrid:touched(tt)
self.swtTitle:touched(tt)
for i, e in ipairs(self.elements) do
if e:touched(tt) and touch.state == BEGAN then
elementCount = elementCount + 1
dragElement =
UIElement(i,elementNames[i],
touch.x, touch.y, 200, 40)
self.speed = 50
end
end
if self.btnCode:touched(tt) then
writer:write()
end
end
--# UIElement
UIElement = class()
CONTROLTYPE = 1
LABELTYPE = 2
BUTTONTYPE = 3
TEXTFIELDTYPE = 4
SWITCHTYPE = 5
SLIDERTYPE = 6
DROPLISTTYPE = 7
SEGMENTEDCONTROLTYPE = 8
SPOTSWITCHTYPE = 9
ICONBUTTONTYPE = 10
SELECTLISTTYPE = 11
elementNames = {"Control", "Label", "Button", "TextField", "Switch",
"Slider", "DropList", "Segment;Control", "SpotSwitch", "IconButton",
"SelectSwitch"}
handleNames = {"X", "Y", "W", "H", "i"}
function UIElement:init(eType, text, x, y, w, h, tab)
self.type = eType
self.element = nil
self.tab = tab
self.source = 1
self.handles = false
self.hRect = {}
self.handleInfo = nil
self.handleTouched = 0
self.expandedFrame = nil
if self.type == CONTROLTYPE then
self.element = Control(text, x, y, w, h)
self.element.background = color(247, 247, 247, 255)
self.name = "ctl"
elseif self.type == LABELTYPE then
self.element = Label(text, x, y, w, h)
self.name = "lbl"
elseif self.type == BUTTONTYPE then
self.element = Button(text, x, y, w, h, 0)
self.element.foreground = color(255, 255, 255, 0)
self.name = "btn"
elseif self.type == TEXTFIELDTYPE then
self.element = TextField("Title", x, y, w, h, text, 0)
self.name = "txt"
elseif self.type == SWITCHTYPE then
self.element = Switch(text, x, y, w, h)
self.name = "swt"
elseif self.type == SLIDERTYPE then
self.element = Slider(text, x, y, w, h, 0, 0, 100, 50)
self.name = "sld"
elseif self.type == DROPLISTTYPE then
self.element = DropList(text, x, y, w, h)
self.name = "dpl"
elseif self.type == SEGMENTEDCONTROLTYPE then
self.element = SegmentedControl(text, x, y, w, h, 0)
self.name = "sct"
elseif self.type == SPOTSWITCHTYPE then
self.element = SpotSwitch(text, x, y, w, h)
self.name = "chb"
elseif self.type == ICONBUTTONTYPE then
self.element = IconButton(text, x + 50, y - 20, w - 100, h + 30,
"Cargo Bot:Crate Goal Red", "Top Text", "Bottom Text")
self.name = "ibn"
elseif self.type == SELECTLISTTYPE then
self.element = SelectList(text, x, y, w, h, true)
self.name = "sls"
end
self.name = self.name .. elementCount
end
function UIElement:setHandles()
self.hRect[1] = Frame(self.element.x - 15, self.element:midY() - 15,
30, 30)
self.hRect[2] = Frame(self.element:midX() - 15, self.element.y - 15,
30, 30)
self.hRect[3] = Frame(self.element:right() - 15,
self.element:midY() - 15, 30, 30)
self.hRect[4] = Frame(self.element:midX() - 15,
self.element:top() - 15, 30, 30)
self.hRect[5] = Frame(self.element:midX() - 20,
self.element:top() + 20, 40, 40)
self.expandedFrame = Frame(self.element.x - 20, self.element.y - 20,
self.element.w + 40, self.element.h + 50)
end
function UIElement:draw()
self.element:draw()
if self.handles then
strokeWidth(2)
noFill()
for i = 1, 4 do
if self.handleTouched == i then
stroke(37, 219, 46, 106)
else
stroke(20, 47, 233, 118)
end
self.hRect[i]:roundRect(2)
fill(57, 80, 208, 255)
text(handleNames[i], self.hRect[i]:midX(),
self.hRect[i]:midY())
noFill()
end
stroke(19, 46, 233, 175)
ellipse(self.hRect[5]:midX(), self.hRect[5]:midY(), 35)
fill(48, 65, 193, 255)
text("i", self.hRect[5]:midX(), self.hRect[5]:midY())
end
end
function UIElement:decodeColor(c)
return "color("..c.r..", "..c.g..", "..c.b..", "..c.a..")"
end
function UIElement:printInit()
local s
s = " "..self.name.." = "..self.element:initString("test").."\n"
if self.element.fontSize ~= 18 then
s = s.." "..self.name..".fontSize = "..self.element.fontSize
.."\n"
end
if self.element.font ~= "HelveticaNeue-Light" then
s = s.." "..self.name..".font = '"..self.element.font.."'\n"
end
if self.element.textColor ~= color(0, 0, 0, 255) then
s = s.." "..self.name..
".textColor = "..
self:decodeColor(self.element.textColor).."\n"
end
if self.element.background ~= color(0, 0, 0, 0) then
s = s.." "..self.name..
".background = "..
self:decodeColor(self.element.background).."\n"
end
if self.element.foreground ~= color(14, 14, 14, 255) then
s = s.." "..self.name..
".foreground = "..
self:decodeColor(self.element.foreground).."\n"
end
if self.element.highlightColor ~= color(0, 50, 255, 255) then
s = s.." "..self.name..
".highlightColor = "..
self:decodeColor(self.element.highlightColor).."\n"
end
if self.element.highlightedTextColor ~=
color(255, 255, 255, 255) then
s = s.." "..self.name..
".highlightedTextColor = "..
self:decodeColor(self.element.highlightedTextColor).."\n"
end
return s
end
function UIElement:printDraw()
return " "..self.name..":draw()\n"
end
function UIElement:printTouched()
return " "..self.name..":touched(touch)\n"
end
function UIElement:touched(touch)
if self.handles then
if touch.state == BEGAN then
self.handleTouched = 0
for i = 1, 5 do
if self.hRect[i]:touched(touch) then
self.handleTouched = i
end
end
if self.handleTouched == 5 then
dialog = PropertiesDialog(selectedElement, self)
dialog.visible = true
end
if self.handleTouched == 0 and
self.expandedFrame:touched(touch) then
self.handleTouched = 6
end
end
if touch.state == MOVING then
x = touch.x
if tray.swtGrid.selected then
x = math.floor(x/20) * 20
end
y = touch.y
if tray.swtGrid.selected then
y = math.floor(y/20) * 20
end
if self.handleTouched == 1 then
self.element.x = x
self:setHandles()
end
if self.handleTouched == 2 then
self.element.y = y
self:setHandles()
end
if self.handleTouched == 3 then
if x > self.element.x + 30 then
self.element.w = x - self.element.x
end
self:setHandles()
end
if self.handleTouched == 4 then
if y > self.element.y + 30 then
self.element.h = y - self.element.y
end
self:setHandles()
end
if self.handleTouched == 6 then
self.element.x = x - self.element:width() / 2
self.element.y = y
self:setHandles()
end
end
end
if self.handles then
if self.handleTouched > 0 then
return true
else
return false
end
else
return self.element:ptIn(touch)
end
end
--# CodeWriter
CodeWriter = class()
function CodeWriter:init()
end
function CodeWriter:write()
local s
s = ""
s = s.."-- Generated by Cider7\n"
s = s.."--\n"
s = s.."-- Add CiderControls7 as a dependency\n"
s = s.."--\n"
s = s.." \n"
s = s.." \n"
s = s.."function setup()\n"
s = s.." displayMode(FULLSCREEN)\n"
for i, e in ipairs(elements) do
s = s..e:printInit().."\n"
end
s = s.."end\n"
s = s.."\n"
s = s.."function draw()\n"
s = s.." background(255, 255, 255, 255)\n"
for i, e in ipairs(elements) do
s = s..e:printDraw()
end
s = s.."end\n"
s = s.."\n"
s = s.."function touched(touch)\n"
for i, e in ipairs(elements) do
s = s..e:printTouched()
end
s = s.."end\n"
s = s.."\n"
s = s.."function keyboard(key)\n"
s = s.." if CCActiveTextBox then\n"
s = s.." CCActiveTextBox:acceptKey(key)\n"
s = s.." end\n"
s = s.."end\n"
s = s.." \n"
saveProjectTab("Output", s)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment