Created
August 24, 2012 10:53
-
-
Save devilstower/3449070 to your computer and use it in GitHub Desktop.
OnTop Beta all-in-one
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--# 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