Skip to content

Instantly share code, notes, and snippets.

@devilstower
Created August 24, 2012 10:53
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/3449070 to your computer and use it in GitHub Desktop.
Save devilstower/3449070 to your computer and use it in GitHub Desktop.
OnTop Beta all-in-one
--# Main
-- AgendaTimer
-- Use this function to perform your initial setup
displayMode(FULLSCREEN)
rectMode(CORNERS)
font("HelveticaNeue")
function setup()
--clearProjectData()
VIEWING = 1
EDITING = 2
TITLES = 3
HELP = 4
-------------
meetings = {}
meeting = nil
item = nil
timePassed = 0
startTime = ElapsedTime
status = TITLES
split = false
blinkTimer = 0
showSlider = false
meetingScroll = 0
itemScroll = 0
startTime = ElapsedTime
-------------
playBtn = Frame(0,0,0,0)
stopBtn = Frame(0,0,0,0)
pauseBtn = Frame(0,0,0,0)
addBtn = Frame(0,0,0,0)
helpBtn = Frame(0,0,0,0)
slider = TimeSlider(1)
timeFrame = Frame(0,0,0,0)
startFrame = Frame(0,0,0,0)
-------------
selectedMeeting = nil
selectedMeetingPos = 0
selectedItem = nil
selectedItemPos = 0
loadMeetings()
if #meetings < 1 then
meeting = Meeting("Example Meeting")
item = AgendaItem("Greeting", 1, 0, 10)
meeting:addItem(item)
item = AgendaItem("Roundtable", 1, 0, 10)
meeting:addItem(item)
item = AgendaItem("Break Out", 1, 0, 10)
meeting:addItem(item)
item = AgendaItem("Closing", 1, 0, 10)
meeting:addItem(item)
meetings[1] = meeting
end
-------------
selectedMeeting = meetings[1]
end
function drawEditor()
pushMatrix()
if selectedMeeting and not isKeyboardShowing()
and not showSlider then
showKeyboard()
elseif showSlider and isKeyboardShowing() then
hideKeyboard()
end
stroke(255, 0, 0, 255)
fill(127, 127, 127, 255)
fontSize(64)
if selectedItem ~= nil then
--translate(-200,0)
end
text("Sessions", WIDTH/4, HEIGHT-35)
text("Topics", WIDTH/4*3, HEIGHT-35)
fontSize(24)
textMode(CORNER)
textAlign(LEFT)
for i, meeting in ipairs(meetings) do
meeting.frame = Frame(10, HEIGHT-140-i*50,
WIDTH/2 - 20, HEIGHT-140-i*50+50)
fill(48, 140, 28, 173)
stroke(40, 40, 50)
meeting.frame:draw()
fill(209, 209, 209, 255)
text(meeting.name, meeting.frame.left+10,
meeting.frame.bottom+10)
end
if selectedMeeting then
meeting = selectedMeeting
strokeWidth(5)
stroke(117, 127, 181, 255)
line(meeting.frame.right-35,meeting.frame.bottom+15,
meeting.frame.right-35,meeting.frame.top-15)
line(meeting.frame.right-35,meeting.frame.bottom+15,
meeting.frame.right-15,meeting.frame:midY())
line(meeting.frame.right-35,meeting.frame.top-15,
meeting.frame.right-15,meeting.frame:midY())
for i, item in ipairs(meeting.items) do
item.frame = Frame(WIDTH/2 + 20, HEIGHT-140-i*50,
WIDTH - 20, HEIGHT-140-i*50+50)
fill(48, 140, 28, 169)
stroke(40, 40, 50)
item.frame:draw()
fill(209, 209, 209, 255)
fontSize(24)
textAlign(LEFT)
text(item.name, item.frame.left+10,
item.frame.bottom+10)
textAlign(RIGHT)
fontSize(14)
if math.floor(item.duration) < 10 then
text(":0"..item.duration,
item.frame.right - 48, item.frame.bottom+17)
else
text(":"..item.duration,
item.frame.right - 48, item.frame.bottom+17)
end
if i == selectedItemPos then
noFill()
stroke(117, 127, 181, 255)
ellipse(item.frame.right - 40, item.frame:midY(), 42)
end
end
end
textMode(CENTER)
textAlign(CENTER)
stroke(127, 127, 127, 255)
line(WIDTH/2, 40, WIDTH/2, HEIGHT-150)
if selectedMeeting then
stroke(24, 88, 189, 255)
else
stroke(122, 127, 134, 87)
end
addBtn = Frame(25,HEIGHT-125,50,HEIGHT-100)
helpBtn = Frame(WIDTH-50,HEIGHT-125,WIDTH-25,HEIGHT-100)
stroke(117, 127, 181, 255)
strokeWidth(6)
fill(48, 122, 157, 255)
--line(addBtn:midX(), addBtn.bottom, addBtn:midX(), addBtn.top)
--line(addBtn.left, addBtn:midY(), addBtn.right, addBtn:midY())
fontSize(60)
text("+", addBtn:midX(), addBtn:midY())
fontSize(48)
text("?", helpBtn:midX(), helpBtn:midY())
if selectedMeeting then
noFill()
stroke(31, 64, 116, 255)
strokeWidth(5)
if selectedItem == nil then
selectedMeeting.frame:draw()
else
selectedItem.frame:draw()
end
end
textMode(CORNER)
textAlign(LEFT)
if showSlider and selectedItem then
item = selectedItem
slider:draw(item.value)
elseif selectedMeeting then
if ElapsedTime > blinkTimer + 0.25 then
strokeWidth(5)
stroke(217, 217, 217, 242)
if selectedItem == nil then
fontSize(24)
w,h = textSize(selectedMeeting.name)
w = w + 14
line(selectedMeeting.frame.left + w,
selectedMeeting.frame.bottom + 10,
selectedMeeting.frame.left + w,
selectedMeeting.frame.top - 10 )
else
fontSize(24)
item = selectedItem
w,h = textSize(item.name)
w = w + 14
line(item.frame.left + w,
item.frame.bottom + 10,
item.frame.left + w,
item.frame.top - 10 )
end
end
if ElapsedTime > blinkTimer + 0.5 then
blinkTimer = ElapsedTime
end
end
textMode(CENTER)
textAlign(CENTER)
popMatrix()
end
function draw()
background(26, 26, 50, 255)
strokeWidth(5)
if status == VIEWING then
-- meeting underway
meeting:draw()
elseif status == TITLES then
drawTitleScreen()
elseif status == HELP then
drawHelpScreen()
else
-- in editor
drawEditor()
end
touch()
end
function findMeeting(touch)
local m, mm
for m, mm in ipairs(meetings) do
if mm.frame:touched(CurrentTouch) then
selectedMeeting = mm
playBtn = Frame(meeting.frame.right - 65,
mm.frame.bottom,meeting.frame.right,
mm.frame.top)
startFrame = mm.frame
selectedItem = nil
selectedItemPos = 0
end -- end if touched
end -- for m, meeting
end
function findItem(touch)
local i, item
-- see if
if selectedMeeting then
for i, item in ipairs(selectedMeeting.items) do
if item.frame:touched(CurrentTouch) then
selectedItemPos = i
selectedItem = item
startFrame = item.frame
timeFrame = item.frame
timeFrame.left = item.frame.right - 65
end
end
end -- end select item
end
function newMeeting(touch)
local meeting
meeting = Meeting("")
meeting.items[1] = AgendaItem("Welcome", 1, 0, 0)
table.insert(meetings, meeting)
selectedMeeting = meeting
selectedMeetingPos = table.maxn(meetings)
selectedItem = nil
selectedItemPos = 0
end
function newItem(touch)
local item
item = AgendaItem("", 1, 0, 0)
table.insert(selectedMeeting.items, item)
selectedItem = item
selectedItemPos = table.maxn(selectedMeeting.items)
end
function saveMeetings()
local n, m, s, c, i
s = ""
for n, m in ipairs(meetings) do
s = s .. m.name
if n < #meetings then s=s.. "," end
end
saveProjectData("ONTOPIC", s)
s = "ONTOPIC"
for n, m in ipairs(meetings) do
s=""
for j, i in ipairs(m.items) do
s = s .. i.name .. ","
s = s .. math.floor(i.duration)
if j < #m.items then s = s .. "," end
end
saveProjectData(m.name, s)
end
end
function loadMeetings()
-- read existing meetings
local keys, k, s, i, count, m, item
keys = readProjectData("ONTOPIC")
if keys ~= nil then
-- keys are a comma-delimited list
for k in string.gmatch(keys,"([^,]+)") do
-- k = name of meeting
m = Meeting(k)
-- now read topics for this meeting
s = readProjectData(k)
count = 0
for i in string.gmatch(s,"([^,]+)") do
if count == 0 then
name = i
count = 1
else
item = AgendaItem(name, math.floor(i), 0, 0)
table.insert(m.items, item)
count = 0
end
end
table.insert(meetings, m)
end
end
end
function touch()
if CurrentTouch.state == BEGAN and
CurrentTouch.state ~= oldState then
-- track where touch began
startX = CurrentTouch.x
if status == VIEWING then
-- viewing meeting or paused
if selectedMeeting:touched(CurrentTouch) then
status = EDITING
end
elseif status == TITLES then
if playBtn:touched(CurrentTouch) then
status = EDITING
playBtn = Frame(0,0,0,0)
end
elseif status == HELP then
if playBtn:touched(CurrentTouch) then
status = EDITING
playBtn = Frame(0,0,0,0)
end
elseif status == EDITING then
-- editing meeting
if playBtn:touched(CurrentTouch) then
saveMeetings()
meeting.timePassed = 0
status = VIEWING
end -- playBtn
if helpBtn:touched(CurrentTouch) then
saveMeetings()
status = HELP
end -- playBtn
if addBtn:touched(CurrentTouch) then
if selectedItem then
newItem(touch)
else
newMeeting(touch)
end
end -- addBtn
findMeeting(CurrentTouch)
findItem(CurrentTouch)
if timeFrame:touched(CurrentTouch) and selectedItem then
slider.value =
selectedItem.duration
showSlider = true
end -- time frame
end -- status == EDITING
end -- touch == BEGAN
if CurrentTouch.state == MOVING then
if showSlider then
slider:touched(CurrentTouch)
selectedItem.duration = slider.value
end
end -- touch == MOVING
if CurrentTouch.state == ENDED and
CurrentTouch.state ~= oldState then
if showSlider then
showSlider = false
elseif startFrame:touched(CurrentTouch) and
startX < CurrentTouch.x - 75 then
-- look to see if in start frame
sound(SOUND_POWERUP, 28072)
if selectedMeeting.frame:touched(CurrentTouch) then
table.remove(meetings, selectedMeetingPos)
elseif selectedItem.frame:touched(CurrentTouch) then
table.remove(selectedMeeting.items, selectedItemPos)
selectedItem = nil
selectedItemPos = 0
end
end
end -- touch == ENDED
oldState = CurrentTouch.state
end
function keyboard(key)
if key ~= nil then
if string.byte(key) == 10 then
selectedMeeting = nil
saveMeetings()
hideKeyboard()
keyboardShown = false
elseif string.byte(key) == nil then
if string.len(selectedMeeting.name) > 0 then
if selectedItem then
selectedItem.name = string.sub(selectedItem.name,
1, string.len(selectedItem.name) - 1)
else
selectedMeeting.name =
string.sub(selectedMeeting.name,
1, string.len(selectedMeeting.name) - 1)
end
end
else
if selectedItem then
selectedItem.name = selectedItem.name..key
else
selectedMeeting.name = selectedMeeting.name..key
end
end
end
end
--# Meeting
Meeting = class()
function Meeting:init(txt)
-- you can accept and set parameters here
self.name = txt
self.duration = 0
self.startTime = ElapsedTime
self.timePassed = 0
self.paused = true
self.items = {}
self.style = 1
self.frame = Frame(0,0,0,0)
self.playBtn = Frame(0,0,0,0)
self.stopBtn = Frame(0,0,0,0)
self.pauseBtn = Frame(0,0,0,0)
end
function Meeting:addItem(item)
self.duration = self.duration + item.duration
table.insert(self.items, item)
end
function Meeting:draw()
local i, pixScale, left, right, bottom, top, totalTime
pushStyle()
if isKeyboardShowing() then
hideKeyboard()
end
if self.style == 1 then
fill(127, 127, 127, 255)
stroke(255, 255, 255, 255)
top = HEIGHT / 2 + HEIGHT / 4
bottom = HEIGHT / 2 - HEIGHT / 4
rect(10, bottom, WIDTH - 10, top)
pixScale = (WIDTH-20) / self.duration
left = 0
right = 10
width = 0
noStroke()
self.duration = 0
for i, item in ipairs(self.items) do
self.duration = self.duration + item.duration
end
totalTime = 0
for i, item in ipairs(self.items) do
if totalTime + item.duration * 60 < self.timePassed then
fill(178, 107, 21, 255)
elseif totalTime > self.timePassed then
fill(49, 140, 28, 255)
else
fill(149, 164, 24, 255)
end
stroke(220, 218, 232, 255)
left = right
width = (item.duration * pixScale)
right = left + width
rect(left, bottom+5, right, top-5)
fontSize(16)
fill(255, 255, 255, 255)
if right - left < 80 then
pushMatrix()
translate(left + (width/2), HEIGHT/2 + 20)
rotate(90)
text(item.name, 0, 0)
popMatrix()
else
text(item.name, left + (width/2), HEIGHT/2 + 20)
fill(182, 182, 182, 255)
text("("..timeString(item.duration*60)..")", left +
(width/2), HEIGHT/2 )
end
totalTime = totalTime + item.duration*60
if right - left > 50 then
fontSize(14)
text(timeString(totalTime, false),
right-20, top + 11)
end
fontSize(30)
if self.duration*60 - self.timePassed < 1 then
self.paused = true
end
text(timeString((self.duration*60 - self.timePassed), true),
WIDTH/2, HEIGHT-100)
end
end
if self.paused then
stroke(82, 31, 31, 255)
else
stroke(31, 42, 89, 255)
end
strokeWidth(5)
i = 10 + pixScale * self.timePassed / 60
line(i - 3, top, i - 3, top - 50)
line(i + 3, top, i + 3, top - 50)
line(i - 3, bottom, i - 3, bottom + 50)
line(i + 3, bottom, i + 3, bottom + 50)
if self.paused then
stroke(91, 45, 31, 132)
else
stroke(31, 41, 84, 125)
end
line(i, bottom, i, top)
fill(220, 220, 220, 255)
fontSize(14)
text(timeString(self.timePassed, true),i, bottom-18)
fontSize(36)
text(self.name, WIDTH/2, HEIGHT-50)
-- advance timer
if not self.paused then
self.timePassed = self.timePassed +
(ElapsedTime - self.startTime)
self.startTime = ElapsedTime
end
-- calculate button positions and draw
stroke(31, 64, 116, 255)
strokeWidth(5)
noFill()
self.playBtn = Frame(100,50,150,100)
line(100,50,100,100)
line(100,100,140,75)
line(140,75,100,50)
self.pauseBtn = Frame(WIDTH/2-30,50,WIDTH/2+30,100)
rect(WIDTH/2-30,50,WIDTH/2-5,100)
rect(WIDTH/2+5,50,WIDTH/2+30,100)
self.stopBtn = Frame(WIDTH-150,50,WIDTH-100,100)
rect(self.stopBtn.left,self.stopBtn.bottom,
self.stopBtn.right,self.stopBtn.top)
popStyle()
end
function Meeting:touched(touch)
if self.playBtn:touched(touch) and self.paused then
sound(SOUND_PICKUP, 1329)
self.paused = false
self.startTime = ElapsedTime
elseif self.pauseBtn:touched(touch) and not self.paused then
self.paused = true
elseif self.stopBtn:touched(touch) then
return true
end
return false
end
--# AgendaItem
AgendaItem = class()
-- an item for a meeting agenda
function AgendaItem:init(txt, len, s, e)
self.startTime = s
self.endTime = e
self.duration = len
self.name = txt
self.notes = ""
self.frame = Frame(0,0,0,0)
end
function AgendaItem:draw()
end
function AgendaItem:touched(touch)
end
--# Frame
Frame = class()
-- Frame (lite)
-- ver. 1.1
-- 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: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
--# TimeSlider
TimeSlider = class()
function TimeSlider:init(v)
-- you can accept and set parameters here
self.value = v
end
function TimeSlider:draw()
local s, t, x, y
popStyle()
strokeWidth(0)
fill(117, 127, 181, 255)
rect(WIDTH - 100, 50, WIDTH - 10, HEIGHT - 10)
strokeWidth(5)
stroke(70, 70, 70, 255)
ellipse(WIDTH - 55, HEIGHT - 55, 70)
fill(255, 255, 255, 255)
if self.value < 10 then
s = ":0" .. self.value
else
s = ":" .. self.value
end
fontSize(18)
textMode(CENTER)
textAlign(CENTER)
text(s, WIDTH - 55, HEIGHT - 55)
line(WIDTH - 90, HEIGHT - 100, WIDTH - 20, HEIGHT - 100)
stroke(192, 192, 192, 255)
fontSize(14)
strokeWidth(2)
stroke(255, 255, 255, 255)
for i = 1,60 do
y = HEIGHT-100-((HEIGHT - 160)/60 * i)
line(WIDTH - 70, y, WIDTH - 20, y)
end
strokeWidth(5)
for i = 1,6 do
t = i * 10
y = HEIGHT-100-((HEIGHT - 160) / 6 * i)
line(WIDTH - 70, y, WIDTH - 20, y)
if t < 10 then s = ":0" .. t else s = ":" .. t end
text(s, WIDTH - 85, y )
end
stroke(255, 22, 0, 255)
y = HEIGHT-100-((HEIGHT - 160)/60 * self.value)
line(WIDTH - 75, y, WIDTH - 15, y)
pushStyle()
end
function TimeSlider:touched(touch)
local y
y = (HEIGHT - 100 - touch.y) / (HEIGHT - 160) * 60
if y < 1 then y = 1 elseif y > 60 then y = 60 end
self.value = math.floor(y)
end
--# Utils
function timeString(time, showSeconds)
hours = math.floor(time / 3600)
if hours < 10 then hours = "0"..hours end
mins = math.floor(time / 60)
mins = math.fmod(mins, 3600)
if mins < 10 then mins = "0"..mins end
if showSeconds then
secs = math.floor(time)
secs = math.fmod(secs, 60)
if secs < 10 then secs = "0"..secs end
return hours..":"..mins.." " ..secs.."s"
else
return hours..":"..mins
end
end
function drawTitleScreen()
pushStyle()
font("Futura-CondensedExtraBold")
fontSize(96)
text("OnTopic", WIDTH/2, HEIGHT-100)
fontSize(30)
font("Futura-Medium")
text("Manage your meeting.", WIDTH/2, HEIGHT-200)
text("Conduct your session.", WIDTH/2, HEIGHT-250)
text("Keep on schedule.", WIDTH/2, HEIGHT-300)
text("Stay on topic.", WIDTH/2, HEIGHT-350)
playBtn = Frame(10, 10, WIDTH-10, HEIGHT-10)
sprite("Cargo Bot:Made With Codea", WIDTH/2, 70)
fontSize(24)
font("Papyrus")
text("Copyright 2012 by Mark Sumner", WIDTH/2, 300)
if ElapsedTime > startTime + 8 then
status = EDITING
playBtn = Frame(0,0,0,0)
end
popStyle()
end
function drawHelpScreen()
if isKeyboardShowing() then
hideKeyboard()
end
pushStyle()
font("Futura-CondensedExtraBold")
fill(82, 82, 82, 255)
fontSize(96)
text("OnTopic", WIDTH/2, HEIGHT-100)
font("Papyrus")
fontSize(24)
text("Copyright 2012 by Mark Sumner", WIDTH/2, HEIGHT-220)
fill(153, 176, 187, 255)
fontSize(30)
font("Futura-Medium")
textMode(CORNER)
textAlign(LEFT)
text("Create a new event or topic by selecting an", 100, HEIGHT-400)
text("existing item and tapping '+'", 100, HEIGHT-450)
text("Touch the topic timer to change the", 100, HEIGHT-550)
text("duration of a topic.", 100, HEIGHT-600)
text("Start the session with a tap on the ", 100, HEIGHT-700)
text("play button.", 100, HEIGHT-750)
playBtn = Frame(10, 10, WIDTH-10, HEIGHT-10)
popStyle()
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment