Created
April 2, 2012 13:39
-
-
Save fredbogg/2283493 to your computer and use it in GitHub Desktop.
ScrollBox v0.2 for Codea
This file contains 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
--# 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