Skip to content

Instantly share code, notes, and snippets.

@AntonioCiolino
Forked from devilstower/Cider
Created November 21, 2012 22:10
Show Gist options
  • Save AntonioCiolino/4128192 to your computer and use it in GitHub Desktop.
Save AntonioCiolino/4128192 to your computer and use it in GitHub Desktop.
Cider 1.5.2 -- interface builder for Codea
--
-- Cache.lua - this is a SUBSET of HTTPLoader.
--
Cache = class()
function Cache:loadStringData(name)
return readLocalData(name)
end
function Cache:saveStringData(name,cache)
saveLocalData(name, cache)
end
--this cache process is flawed - it pads to the nearest 3 bytes. ths is probably ok for most
--things, and it seems to work OK for raw AUDIO files.
function Cache:saveBinaryData(name, cache)
local im = image(#cache/3+1, 1) -- +1 for the spare bytes of any!
pos=1
for b in string.gfind(cache, ".") do
if r == nil then r = string.byte(b)
else if g == nil then g = string.byte(b)
else if cb == nil then cb = string.byte(b) end end end
if not (r == nil or g == nil or cb ==nil) then
im:set(pos,1,r,g,cb)
pos=pos + 1
r = nil
g = nil
cb = nil
end
end
if r == nil then r=0 end
if g == nil then g=0 end
if cb == nil then cb=0 end
if not (r == nil or g == nil or cb ==nil) then
im:set(pos,1,r,g,cb) -- we will write extra bytes here!
end
saveImage("Documents:"..name, im)
end
--due to the buffers being "exact" sans the extra pixel of filler, we
--ca rip through and read very fast.
function Cache:loadBinaryData(name)
local im = readImage("Documents:" .. name)
if not im then return nil end
local w,h = spriteSize(im)
local cache=""
for i = 1,w do
local r,g,b = im:get(i,1) --
cache = cache .. string.char(r)
cache = cache .. string.char(g)
cache = cache .. string.char(b)
end
return cache
end
--images don't need any interpretation - jus load then from the cache directly!
function Cache:saveImageData(name, cache)
saveImage("Documents:Cache-" .. name, cache)
end
function Cache:loadImageData(name)
local im = readImage("Documents:Cache-" .. name)
return im
end
--
-- Cider.lua
--
--# 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
-- Version 1.5.1 11/22/2012
-- Changes made to execute callbacks on controls, added rendered grid
-- integrated a menu for code gneration, added load/save of code to Cache, added dropbox
-- write suport (with AC's DropBox library. )
-- Version 1.5.2 12/5/2012
-- added dial and doughnut gauges - still needs eork on the color passing.
-- found a bug with twpsters's textbox during desig time, so it't not in by default though
-- it can be downloaded and used.
displayMode(FULLSCREEN)
minSize = 30 --not sure what this is for yet.
GRIDSIZE =20
function setup()
code=""
saveCode("Cider")
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 = 300
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)
--second column - 150 px to the right
trayElement[12] = UIElement(11, "Dial", 10+150,
HEIGHT - 90, 130+150, HEIGHT - 50)
trayElement[13] = UIElement(12, "Doughnut", 10+150,
HEIGHT - 230, 130+150, HEIGHT - 150)
swtGrid = Switch("ON;OFF", 55, 60, 150, 90)
lblGrid = Label("Grid", 0, 50, 35, 80)
--get space back
--btnCode = TextButton("Generate Code", 10, 30, 150, 70, btnCode_Clicked)
lblMain = Label("Main", 0, 100, 35, 110)
swtMain = Switch("ON;OFF", 55, 100, 150, 130)
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
menu2 = Menu({side="top", pos=0.1, width=.25,
list={"Load",true,"Save",true,"Clear",true,
"Generate", true,
"DropBox", true
}, callback=menuSelected})
dlg = Dialog("Save As", 200, HEIGHT - 500,
WIDTH - 200, HEIGHT - 30)
showSaveAs = false
end
-- cache up the ouput
function printc(chunk)
code = code .. "\r\n" .. chunk
end
--calls the code generation area
function btnCode_Clicked()
code=""
printElements()
end
-- perform user based functions to save and load ui designs, generate code.
-- goal is to generate code from menu and get back the button space from the
-- tool/dock area.
function menuSelected(e)
if e=="Load" then
local cache=Cache:loadStringData("CiderCache")
if cache == nil then return end
local cached = JSON:decode(cache)
-- we need to convert these to uielements
for k,e in pairs(cached) do
--dump(e)
local ui = UIElement(e.type, e.element.text, e.element.left ,
e.element.bottom, e.element.right , e.element.top)
table.insert(elements, ui)
ui.name = e.name
ui.font = e.font
ui.fontSize = e.fontSize
ui.background = e.background
ui.foreground = e.foreground
ui.highlight = e.highlight
ui.textAlign =e.textAlign
--there may be other things
end
elseif e== "Save" then
local cache = JSON:encode(elements)
Cache:saveStringData("CiderCache",cache)
elseif e=="Clear" then
elements={}
elseif e=="Generate" then
btnCode_Clicked()
print(code)
elseif e== "DropBox" then
btnCode_Clicked()
SaveToDropBox()
end
end
function SaveToDropBox()
appKey = "YOURAPPKEY" --app key
appSecret = "YOUAPPSECRET" --app secret
db = DropBox(appKey, appSecret)
db:Write("Cider.lua", code)
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)
if swtGrid.selected then
strokeWidth(2)
stroke(202, 151, 151, 255)
--faster than rects
if swtGrid.selected then
for x=0, WIDTH, GRIDSIZE do
line(x, 0, x, HEIGHT)
end
for y=0, HEIGHT, GRIDSIZE do
line(0, y, WIDTH, y)
end
end
end
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)
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())
--mark's adds from thanksgiving
text(dragElement.element:width(), infoRect:midX(),
rightBottomSize.bottom)
text(dragElement.element:height(), leftBottomSize:midX(),
dragElement.element:midY())
end
if showProperties then
drawProperties()
end
if showBackgroundColor or showForegroundColor
or showHighlightColor then
clrChooser:draw()
end
menu2:draw()
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
--needs to store as a trig instadof a ries of print statements.
function printElements()
showCode = true
displayMode(STANDARD)
if swtMain.selected then
printc("-- Generated by Cider")
printc("-- ")
printc("-- Add CiderControls as a dependency to enable controls")
printc("assert(Frame ~= nil, \"CiderControls not found. Please add the dependency.\")")
printc("-- ")
printc(" ")
printc("displayMode(FULLSCREEN)")
printc("-- ")
printc("function setup()")
else
printc("-- ===================")
printc("-- Copy into the setup function")
printc("-- ===================")
end
for i, e in ipairs(elements) do
e:printInit()
end
if swtMain.selected then
printc("end")
printc("")
printc("function draw()")
printc(" background(194, 194, 194, 255)")
else
printc(" ")
printc("-- ===================")
printc("-- Copy into the draw function")
printc("-- ===================")
end
for i, e in ipairs(elements) do
e:printDraw()
end
if swtMain.selected then
printc("end")
printc("")
printc("function touched(touch)")
else
printc(" ")
printc("-- ===================")
printc("-- Copy into the touched function")
printc("-- ===================")
end
for i, e in ipairs(elements) do
e:printTouched()
end
if swtMain.selected then
printc("end")
printc("")
else
printc(" ")
printc("-- ===================")
printc("-- Events ")
printc("-- ===================")
end
for i, e in ipairs(elements) do
e:printEvent()
end
if swtMain.selected then
--printc("end")
printc("")
else
printc(" ")
printc("-- ===================")
printc("-- Copy into main, or modify your")
printc("-- existing keyboard function")
printc("-- ===================")
printc(" ")
end
printc("function keyboard(key)")
printc(" if CCActiveTextBox then")
printc(" CCActiveTextBox:acceptKey(key)")
printc(" end")
printc("end")
printc(" ")
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 / GRIDSIZE) * GRIDSIZE
y = math.floor(touch.y / GRIDSIZE) * GRIDSIZE
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)
menu2:touched(touch)
dlg: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
DIALTYPE=11
DOUGHNUTTYPE=12
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"
elseif type == DIALTYPE then
self.element = Dial(text, left, bottom, right, top)
self.name="dial"
elseif type == DOUGHNUTTYPE then
self.element = Doughnut(text, left, bottom, right, top)
self.name="doughnut"
end
end
function UIElement:draw()
self.element:draw()
end
function UIElement:printInit()
printc(" "..self.name.." = "..self.element:initString(self.name))
if self.element.fontSize ~= 16 then
printc(" "..self.name..".fontSize = "..self.element.fontSize)
end
if self.element.font ~= "ArialMT" then
printc(" "..self.name..".font = '"..self.element.font.."'")
end
--these "magic values" are defined in Frame or Control.
if self.element.background ~= color(63, 105, 149, 255) then
printc(" ".. self.name..".background=color".. tostring(self.element.background) .. "")
end
if self.element.foreground ~= color(14, 14, 14, 255) then
printc(" ".. self.name..".foreground=color".. tostring(self.element.foreground) .. "")
end
if self.element.highlight ~= color(112, 226, 78, 255) then
printc(" ".. self.name..".highlight=color".. tostring(self.element.highlight) .. "")
end
end
function UIElement:printDraw()
printc(" "..self.name..":draw()")
end
function UIElement:printTouched()
printc(" "..self.name..":touched(touch)")
end
function UIElement:printEvent()
printc("function "..self.name.."_Clicked()")
printc(" --TODO: add user code here")
printc("end")
end
function UIElement:touched(touch)
return self.element:ptIn(touch.x, touch.y)
end
--
-- Menu.lua
--
--# Menu
--taken from jvm38's code base to enable features off of the control panel
Menu = class()
function Menu:init(args)
-- actions
self.callback = args.callback or doNothing
-- layout
self.title = args.title or "menu"
local list = args.list or {"choice1",true,"choice2",true,"choice3",true}
self.list,self.disabled = {},{}
local imax = #list/2
for i=1,imax do
self.list[i] = list[2*i-1]
self.disabled[i] = not list[2*i]
end
self.selected = args.selected or 1
self.side = args.side or "bottom"
-- settings by pos and w
local x = args.pos
local w = args.width or 0.09
-- or by x0 and x1
if args.x0 and args.x1 then
x = (args.x0 + args.x1)/2
w = args.x1 - args.x0
end
local w1,w2,h1,h2
local pos
local dx0,dy0,dx,dy
local htxt = 30
local w0,h0 = math.floor( w * WIDTH ), math.floor( w * HEIGHT )
if self.side == "top" then
w1,w2,h1,h2 = w0,w0,htxt,htxt
pos = vec2(x*WIDTH, HEIGHT-h1/2)
dx0,dy0,dx,dy = 0, -h1-5, 0, -h2-2
elseif self.side == "bottom" then
w1,w2,h1,h2 = w0,w0,htxt,htxt
pos = vec2(x*WIDTH, h1/2)
dx0,dy0,dx,dy = 0,h1+5, 0, h2+2
elseif self.side == "left" then
w1,w2,h1,h2 = htxt,w0,h0,htxt
pos = vec2(w1/2, x*HEIGHT)
dx0,dy0,dx,dy = w1/2+5+w2/2, h1/2-h2/2, 0, -h2-2
elseif self.side == "right" then
w1,w2,h1,h2 = htxt,w0,h0,htxt
pos = vec2(WIDTH-w1/2, x*HEIGHT)
dx0,dy0,dx,dy = -w1/2-5-w2/2, h1/2-h2/2, 0, -h2-2
end
-- create text images
self.img = {}
for i,txt in ipairs(self.list) do
self.img[i] = self:calcImg(txt,w2,h2)
end
self.img["title"] = self:calcImg(self.title,w1,h1,self.side)
-- position of images
local x,y = pos.x,pos.y
self.pos = {}
self.radius = {}
self.pos["title"] = pos
self.radius["title"] = vec2(w1/2,h1/2)
for i,img in ipairs(self.img) do
if i==1 then x,y = x+dx0,y+dy0
else x,y = x+dx,y+dy end
self.pos[i] = vec2(x,y)
self.radius[i] = vec2(w2/2,h2/2)
end
-- manage various drawing states
self.deployed = false
self.highlighted = nil -- the choice highlighted
end
function Menu:resetDemo()
-- do nothing
end
function Menu:calcImg(txt,w,h,rot)
local w0,h0
pushStyle() pushMatrix()
if rot=="left" or rot=="right"
then w0,h0 = h,w
else w0,h0 = w,h
end
local img0 = image(w0,h0)
setContext(img0)
font("AmericanTypewriter-Bold")
rectMode(CENTER)
textMode(CENTER)
strokeWidth(1)
-- background(255, 255, 255, 184)
background(255, 255, 255, 255)
fill(0, 0, 0, 255)
stroke(0, 0, 0, 255)
fontSize(20)
text(txt,w0/2,h0/2)
setContext()
local img = image(w,h)
setContext(img)
-- background(255, 255, 255, 184)
background(255, 255, 255, 255)
spriteMode(CENTER)
translate(w/2,h/2)
if rot=="left" then rotate(-90) end
if rot=="right" then rotate(90) end
sprite(img0,0,0)
setContext()
popStyle() popMatrix()
return img
end
function Menu:draw()
pushStyle()
spriteMode(CENTER)
-- menu title
if self.deployed then
tint(196, 196, 196, 255)
else tint(211, 211, 211, 127)
end
local pos = self.pos
-- menu button
sprite(self.img["title"], pos["title"].x, pos["title"].y)
-- deployed
if self.deployed then
local isel = self.selected
for i,img in ipairs(self.img) do
pushStyle()
if self.disabled[i] then tint(72, 72, 72, 255)
elseif i==isel then tint(255,255,255,255)
else tint(127, 127, 127, 255) end
sprite(img, pos[i].x, pos[i].y)
popStyle()
end
end
popStyle()
end
function Menu:titleTouched(touch)
local pos,radius= self.pos["title"],self.radius["title"]
local goodZone = false
if math.abs((touch.x-pos.x))<radius.x
and math.abs((touch.y-pos.y))<radius.y
then
goodZone = true
end
self.choiceDone = false
return goodZone
end
function Menu:selectTouched(touch)
local pos,radius
for i,v in ipairs(self.pos) do
pos,radius = self.pos[i],self.radius[i]
if math.abs((touch.x-pos.x))<radius.x
and math.abs((touch.y-pos.y))<radius.y
and not self.disabled[i]
then self.selected = i self.choiceDone=true
end
end
end
function Menu:touched(t)
if self:titleTouched(t) and t.state == BEGAN then
self.deployed=true
self.initialSelect = self.selected
end
if self.deployed then
self:selectTouched(t)
end
if t.state == ENDED and self.deployed then
self.deployed=false
if self.choiceDone then
self.callback(self.list[self.selected])
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment