Skip to content

Instantly share code, notes, and snippets.

@fredbogg
Created April 2, 2012 13:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save fredbogg/2283493 to your computer and use it in GitHub Desktop.
Save fredbogg/2283493 to your computer and use it in GitHub Desktop.
ScrollBox v0.2 for Codea
--# Touch
Touch = class()
function Touch:init(x)
self.debug = true
gtTouches = {}
gtTouchList = {}
gnAverageX = 0
gnAverageY = 0
gnAverageXDelta = 0
gnAverageYDelta = 0
gnPrevAverageX = 0
gnPrevAverageY = 0
self.oldDistance = 0
gnPinchRatio = 1
end
function Touch:draw()
-- make a list of current touches so we can count them and know their order easily
gnPreviousNumberOfTouches = #gtTouchList
gtTouchList ={}
for k,v in pairs(gtTouches) do
if k ~= nil then table.insert(gtTouchList, v) end
end
-- generate an average point from all touches
gnPrevAverageX = gnAverageX
gnPrevAverageY = gnAverageY
gnAverageX = 0
gnAverageY = 0
for i = 1, #gtTouchList do
gnAverageX = gnAverageX + gtTouchList[i].x
gnAverageY = gnAverageY + gtTouchList[i].y
end
gnAverageX = gnAverageX/#gtTouchList
gnAverageY = gnAverageY/#gtTouchList
gnAverageXDelta = math.floor(gnPrevAverageX - gnAverageX)
gnAverageYDelta = math.floor(gnPrevAverageY - gnAverageY)
-- to stop our delta jumping when we add or subtract touches
if #gtTouchList ~= gnPreviousNumberOfTouches then
gnAverageXDelta = 0
gnAverageYDelta = 0
gnPinchRatio = 1
self.oldDistance = 1
gnPrevAverageY = gnAverageY
end
-- today I learned that NaN does not equal itself,
-- prolly get around this by not dividing by 0... :)
if gnAverageYDelta ~= gnAverageYDelta then gnAverageYDelta = 0 end
-- In debug mode, draw some things based on our touches
if self.debug == true then
-- draw a circle for each touch labelled with properties
fill(186, 175, 60, 255)
for i = 1, #gtTouchList do
ellipse(gtTouchList[i].x,gtTouchList[i].y,80,80)
text(i.." "..gtTouchList[i].id,gtTouchList[i].x,gtTouchList[i].y+50)
strokeWidth(2)
line(gnAverageX,gnAverageY,gtTouchList[i].x,gtTouchList[i].y)
end
ellipse(gnAverageX,gnAverageY,50,50)
text("delta "..gnAverageXDelta .. " ".. gnAverageYDelta, gnAverageX,gnAverageY + 30)
text("pinch "..gnPinchRatio, gnAverageX,gnAverageY - 30)
end
-- if pinch detected
if #gtTouchList == 2 then
-- take the distance between the touches to compute the pinch ratio
local v1 = vec2(gtTouchList[1].x, gtTouchList[1].y)
local v2 = vec2(gtTouchList[2].x, gtTouchList[2].y)
local distance = v1:dist(v2)
-- apply change in distance to make a pinch ratio, which the another class can use
if self.oldDistance == 1 then self.oldDistance = distance end
gnPinchRatio = distance / self.oldDistance
self.oldDistance = distance
end
end
function Touch:touched(touch)
-- add touches to a dictionary-type table which will be regenerated into a list each draw()
if touch.state == ENDED then
gtTouches[touch.id] = nil
end
if touch.state == BEGAN or touch.state == MOVING then
gtTouches[touch.id] = touch
end
end
--# ScrollBox
ScrollBox = class()
-- arguments: text, font, fontSize, margin, x, y, width, height
function ScrollBox:init(txt,fnt,fntSize,margin,x,y,w,h)
self.debug = false
self.sText = txt
self.nMargin = margin
self.BoxX = x
self.BoxY = y
self.BoxH = h
self.BoxW = w
self.strokeW = 2
self.fnt = fnt
self.fntSize = fntSize
self.nDirection = 0
end
-- this sets the limits of the scrolling text
function ScrollBox:setLimits()
textWrapWidth(self.BoxW - self.nMargin)
self.textWidth,self.textHeight = textSize(self.sText)
self.nUpperLimit = self.BoxY + ((self.textHeight - self.BoxH)/2+(self.BoxH/2))
self.nLowerLimit = self.BoxY - ((self.textHeight - self.BoxH)/2)
end
function ScrollBox:draw()
pushStyle()
font(self.fnt)
fontSize(math.floor(self.fntSize))
self:setLimits()
-- This sets the line thickness
strokeWidth(self.strokeW)
rectMode(CENTER)
if self.sText == nil then self.sText = "no text" end
-- scroll or initial position
if self.nY == nil then
self.nY = self.nLowerLimit
else
self.nY = self.nY + (self.nDirection)
end
-- if we have lifted the fingers, spring the text back
if #gtTouchList == 0 then
if self.nY <= self.nLowerLimit then
self.nY = math.floor(self.nLowerLimit - ((self.nLowerLimit - self.nY)/100))
end
if self.nY >= self.nUpperLimit then
self.nY = math.floor(self.nUpperLimit + ((self.nUpperLimit - self.nY)/100))
end
end
-- detect pinch gesture and adjust font size
if #gtTouchList == 2 and self.touchBeganInBox == true then
self.fntSize = self.fntSize * gnPinchRatio
end
-- if there are three touches and the last touch began in the box,
-- move it if the touch has moved more than one pixel
if #gtTouchList == 3 and self.touchBeganInBox == true
and (math.abs(gnAverageXDelta) > 1 or math.abs(gnAverageYDelta) > 1) then
self.BoxX = self.BoxX - gnAverageXDelta
self.BoxY = self.BoxY - gnAverageYDelta
end
-- change outline colour of box if selected
if self.touchBeganInBox == false then
stroke(127, 127, 127, 255)
else
stroke(200, 200, 200, 255)
end
-- draw a box for the text
fill(42, 38, 36, 255)
rect(self.BoxX,self.BoxY,self.BoxW,self.BoxH)
-- don't draw anything outside the box, such as text!
clip(self.BoxX-(self.BoxW/2),self.BoxY-(self.BoxH/2-self.strokeW),self.BoxW,self.BoxH-self.strokeW*2)
-- draw the text
fill(187, 155, 178, 255)
text(self.sText,self.BoxX,self.nY)
-- ok ou can draw outside the box now, such as other classes
clip()
-- in debug mode, display some info on the box
if self.debug then
fill(232, 31, 31, 255)
-- what y pixel is the text centered on?.
text(self.nY,self.BoxX,self.BoxY)
-- how many touchs are there?
text(#gtTouchList,self.BoxX,self.BoxY+200)
-- what is the font size?
text(math.floor(self.fntSize),self.BoxX,self.BoxY+100)
end
popStyle()
end
function ScrollBox:touched(touch)
self.nTouchState = touch.state
-- if the touch was within the bounds of the box
if touch.x > (self.BoxX-(self.BoxW/2))
and touch.x < (self.BoxX+(self.BoxW/2)) and touch.y > (self.BoxY-(self.BoxH/2))
and touch.y < (self.BoxY+(self.BoxH/2)) then
self.boxTouched = true
else
self.boxTouched = false
end
-- if one touch or three touches, scroll the text. Three touches needs to scroll
-- because it is also moving the box.
if (#gtTouchList == 1 or #gtTouchList == 3) and self.nTouchState == MOVING and self.touchBeganInBox == true then
-- only start moving if we are moving the finger vertically by more than a pixel
if math.abs(gnAverageYDelta) > 1 then
self.nDirection = -gnAverageYDelta
else
self.nDirection = 0
end
end
if self.nTouchState == BEGAN then
self.nDirection = 0
if self.boxTouched == true then
self.touchBeganInBox = true
else
self.touchBeganInBox = false
end
end
if self.nTouchState == ENDED then
self.touchBeganInBox = false
end
end
--# Text
GoldilocksText = 'Once upon a time there were three bears, a Papa Bear, a Mama Bear and a Baby Bear. One day, the three bears sat down to breakfast. “This porridge is too hot!” said Papa Bear. “This porridge is too hot!” said Mama Bear. “This porridge is too hot!” said Baby Bear. “Let’s go for a walk,” said Mama Bear. When we come back, our porridge will be just right.” Along came Goldilocks. She walked into the houses. She saw three bowls of porridge. “This is too hot,” said Goldilocks. “This is too cold, “said Goldilocks. “This is just right!” said Goldilocks. And she ate all up. She ate the Baby Bear’s porridge. Then Goldilocks went into the living room. She saw three chairs. “This is too hard,” said Goldilocks. “This is too soft,” said Goldilocks. “This is just right!” said Goldilocks. Then CRASH, the chair broke. Goldilocks felt tired. She went into the bedroom. She saw three beds. “This bed is too hard,” said Goldilocks. “This bed is too soft,” said Goldilocks. “This bed is just right!” said Goldilocks. And she fell fast asleep. The three bears came home. They went into the kitchen. “Someone’s been eating my porridge,” said Papa Bear. “Someone’s been eating my porridge,” said Mama Bear. “Someone’s been eating my porridge,” said Baby Bear. “And they ate it all up!” The three bears went into the living room. “Someone’s been sitting in my chair!” said Papa Bear. “Someone’s been sitting in my chair!” said Mama Bear. “Someone’s been sitting in my chair!” said Baby Bear. “And now it’s broken!” The three bears went into the bedroom. “Someone’s been sleeping in my bed!” said Papa Bear. “Someone’s been sleeping in my bed!” said Mama Bear. “Someone’s been sleeping in my bed!” said Baby Bear. “And here she is!” Goldilocks woke up. She saw three angry bears looking at her. Goldilocks jumped out of bed. She ran out of the house. And she never came back again.'
--# Main
-- ScrollBox by Fred Bogg
-- Use this function to perform your initial setup
function setup()
displayMode(FULLSCREEN)
myTouch = Touch()
-- arguments: text, font, fontSize, margin, x, y, width, height
myScrollBox0 = ScrollBox(GoldilocksText,"Arial",25,5,WIDTH/2,HEIGHT/2,600,700)
myScrollBox1 = ScrollBox(GoldilocksText,"Arial",10,15,WIDTH/4,HEIGHT/4,300,300)
end
function touched(touch)
myTouch:touched(touch)
myScrollBox0:touched(touch)
myScrollBox1:touched(touch)
end
-- This function gets called once every frame
function draw()
-- This sets a dark background color
background(0, 0, 0, 255)
myScrollBox1:draw()
myScrollBox0:draw()
myTouch:draw()
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment