Skip to content

Instantly share code, notes, and snippets.

@devilstower
Created Aug 26, 2012
Embed
What would you like to do?
OnTopic Beta 3
--# Main
-- OnTopic Beta 3
-- 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
selectedMeeting = nil
--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(mm.frame.right - 65,
mm.frame.bottom,mm.frame.right,
mm.frame.top)
startFrame = mm.frame
selectedItem = nil
selectedItemPos = 0
selectedMeetingPos = m
if not isKeyboardShowing() then
showKeyboard()
end
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
if not isKeyboardShowing() then
showKeyboard()
end
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
showKeyboard()
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)
selectedMeeting = nil
selectedMeetingPos = 0
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)
self.pauseFlash = 0
self.playFlash = 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 + self.playFlash, 64 + self.playFlash, 116, 255)
if self.playFlash > 0 then
self.playFlash = self.playFlash - 1
end
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)
stroke(31 + self.pauseFlash, 64 + self.pauseFlash, 116, 255)
self.pauseBtn = Frame(WIDTH/2-30,50,WIDTH/2+30,100)
if self.pauseFlash > 0 then
self.pauseFlash = self.pauseFlash - 1
end
rect(WIDTH/2-30,50,WIDTH/2-5,100)
rect(WIDTH/2+5,50,WIDTH/2+30,100)
stroke(31, 64, 116, 255)
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
self.playFlash = 100
elseif self.pauseBtn:touched(touch) and not self.paused then
self.paused = true
self.pauseFlash = 100
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
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