Text Box

@Monkeyman32123 that’s… just… amazing :slight_smile:
nice job, tho I found a very small ‘bug’…
when you insert text after the long text thing, the ‘g’ from that long line get cut of a little bit

@Invad3rZIM, just skip my buggy example :stuck_out_tongue: it’s no good at all

@stevon8ter thank you very much :slight_smile: and nice catch, I’ll get to fixing that!
EDIT: Fixed it! :slight_smile:

Great job on the examples. @Invad3rZIM Looks like you have all you need, so I’ll pass on this one.


--# Classic
Classic = class()

function Classic:init(x)
    -- you can accept and set parameters here
  --  self.player = Player()
   -- self.room = Room()
    self.textBox = TextBox()
end

function Classic:draw()
    -- Codea does not automatically call this method
    self.textBox:draw()
end

function Classic:touched(t)
    -- Codea does not automatically call this method
    self.textBox:touched(t)
end

--# Main
-- Cipher

-- Use this function to perform your initial setup
function setup()
    fontSize(14)
    font("AmericanTypewriter-Bold")

    mode = Classic()
    touches = {}
    displayMode(FULLSCREEN)
    parameter.color("player.color")
end

-- This function gets called once every frame
function draw()
    -- This sets a dark background color 
    background(255, 255, 255, 255)

    -- This sets the line thickness
    --strokeWidth(5)
    
    mode:draw()
    
    fill(88, 255, 0, 255)
    ellipse(CurrentTouch.x, CurrentTouch.y, 45)

    -- Do your drawing here
    
end

function touched(t)
    --adds a new touch to the touches table or modifies current empty index
    
    
    if t.state == BEGAN then
        local sentinel = 0
        
        for a,b in pairs(touches) do
            if b.id == 0 then
                b.id = t.id
                b.startingX = t.x
                b.startingY = t.y
                
                b.currentX = t.x
                b.currentY = t.y
                
                sentinel = 1
                break
            end
        end
        
        if sentinel == 0 then
            table.insert(touches, Touch(t.id,t.x,t.y))
        end
    end
    
    for a,b in pairs(touches) do
        b:touched(t)
    end
end

--# Message
Message = class()

function Message:init(text)
    -- you can accept and set parameters here
    self.text = ""..text
    
    self.num = 3
    local w,h = textSize(self.text)
    self.lineWrapCap = WIDTH * .47
    self.h = h
    self.lines = ( math.floor(w/self.lineWrapCap)) + 1
    self.size = (h+2) * (self.lines)-- hieght of box
    self.transVal = 0
    
    self.m = mesh()
    self.m:addRect(WIDTH * .25, (h+2)/2 * self.lines, WIDTH * .5, self.size)
    self.m:setColors(112, 76,31,200)
    self.m.texture = readImage("Documents:clearVig")
    
    self.nVal = 0
end

function Message:draw()
    -- Codea does not automatically call this method
    pushStyle()
    fill(147, 75, 35, 255)
    pushMatrix()

    translate(WIDTH*.63, (( HEIGHT -5) -  self.size) - self.nVal)

    self.m:draw() 
    self:drawText()
    
    popMatrix()
    popStyle()
end

function Message:drawText()
    --writes the text to each box
    fill(255, 255, 255, 164)
    textAlign(LEFT)
    textMode(CORNER)
    textWrapWidth(self.lineWrapCap)
    fontSize(14)
    text(self.text, WIDTH * .005, self.lines)
end
--# TextBox
TextBox = class()

function TextBox:init(x)
    -- you can accept and set parameters here
    
    self.messages = {} 
table.insert(self.messages, Message("'jwrtjwrtjga))))))))($))&,$$)8,7),&,)(&dgtehttjgwhtetffffgggfghghadrhadrherahwerjrwtjwrtjwrtjwrtjjjwrtjwrtjjtjwrtjj"))
    --, Message("@")}
    
  for a = 1, 35 do
 table.insert(self.messages, Message ("[11:44:"..a.."]: Madeline, you're fantastiikihihbouiubbiuibuiubbiuic!"))
 end
    
table.insert(self.messages, Message("[11:estinfdwbwrfberwdhhdfhsdfg testing"))
    
 table.insert(self.messages, Message("[10:23]: davsdbfe esting testing testing testinig testing testing testing testing testing testing testing testing"))
    self.maxMessages = 15
    
    self.dis = 0
    
    self.m = mesh()
    self.m = mesh()
    self.m:addRect(WIDTH * .25, HEIGHT /2, WIDTH * .52, HEIGHT)
   self.m:setColors(224, 152,62,175)
    self.m.texture = readImage("Documents:rectVig")
end

function TextBox:draw()
--sets a clip and draws the text boxed messages
    strokeWidth(8)
    stroke(102, 31, 31, 255)
    line(WIDTH*.62, HEIGHT, WIDTH * .62, 0)
    pushMatrix()
    translate(WIDTH*.63,0)
    self.m:draw()
    popMatrix()
    pushMatrix()
   clip(WIDTH*.60, HEIGHT*.015, WIDTH * .395, HEIGHT * .98)
    
    if self.dis < -10 then
        self.dis = -10
    end
    
    if self.dis > 300 then
        self.dis = 300
    end
    
    translate(0, self.dis)
    local n = 0
    
    for a = #self.messages, 1, -1 do
        
      local s = 0
        if a < #self.messages and self.messages[a].nVal == 0 then
         --   if self.messages[a].nVal == 0 then
             for b = #self.messages, a + 1, -1 do
        
                self.messages[a].nVal = self.messages[a].nVal + self.messages[b].size + 3
       --     s = s +  self.messages[b + 1].transVal
            end --end
         end
        
       self.messages[a]:draw() 
    end
    
    popMatrix()
end

function TextBox:touched(t)
    -- Codea does not automatically call this method
    if t.x > WIDTH * .62 and t.x < WIDTH * .99 then
        if dy == nil then
        local dy = self.dis
        end
        if t.state == BEGAN then
           dy = t.y
        end
        
        --if t.state == MOVING then
        
       self.dis = (t.y - dy)
      --  dy = t.y
       -- end
        
      --  print(self.dis)
        
        if t.state == ENDED then
           -- self.
        end
    end
end
--# Touch
Touch = class()

function Touch:init(id, x, y)
    -- you can accept and set parameters here
    self.id = id
    self.startingX = x
    self.currentX = x
    self.startingY = y
    self.currentY = y
    self.touchTimeStart = os.time()
    self.deltaTouchTime = os.time() - self.touchTimeStart
end

function Touch:draw()
    -- Codea does not automatically call this method
    if self.id ~= 0 then
        ellipse(self.startingX,self.startingY, 15)
    end
end

function Touch:touched(t)
    if t.id == self.id then
        if t.state == BEGAN then
            self.touchTimeStart = os.clock()
        end
        
        mode:touched(t, self.touchTimeStart)
        
        if t.state == ENDED or t.state == CANCELLED then
            self.id = 0
        end
    end
end

So I used 2 vignetted images…

Any would do…

But take a look at that and tell me what you guys think.

@everyone who posted above, the clip() was key…hadn’t known that function existed. Tell me what you guys think! Thanks everyone!

You’re welcome :slight_smile:
And Looks good, but there’s a bug with scrolling: any time you start to scroll it goes back to the top
Also if you restart it glitches the text wrapping

@invad3rZim nice. Bug: Wen touch begins, the scroll comes back to its zero position.

I want it to do that. The going back to the top. Mainly as a “tap to see the most current data”

How do I change the restart wrapping? Any ideas?

No clue how to fix the wrapping (still going over it), but I found another bug: if you have four lines of text in the message it adds an extra blank line on top

Here, if you want it I have modified mine to have the boxes around each message and to have the “tap to go to newest message” feature :slight_smile: (no clue how to fix yours, but I did know how to modify mine to be like yours :P)

Textbox = class()
function Textbox:init(corner,width,height,fontsize,tfont,limit)
    if corner.x and corner.y then
        self.c = corner
        else
        self.c = vec2(0,0)
    end
    self.w = width or 100
    self.h = height or 50
    self.tlim = limit or 26
    self.f = fontsize or 12
    self.tfont = tfont or "Helvetica"
    self.t = nil
    self.pos = 0
    self.maxY = self.h-5
    self.txts = {}
    self.txtlocs = {}
    self.bc = 255
    self.tc = 0
    self.dc = 0
    self.tbc = color(0,50)
    self.spos = (self.pos/self.maxY)*(self.h-5)
end
function Textbox:draw()
    pushStyle()
    noStroke()
    rectMode(CORNER)
    textMode(CORNER)
    textWrapWidth(self.w-10)
    fontSize(self.f or 20)
    font(self.tfont)
    fill(self.bc)
    rect(self.c.x,self.c.y,self.w,self.h)
    fill(self.dc)
    ellipse(self.c.x+self.w-4,self.c.y+self.spos+2.5,5)
    clip(self.c.x+1,self.c.y+1,self.w-2,self.h-2)
    for a,b in pairs(self.txts) do
        fill(self.tbc)
        rect(self.c.x+2.5,self.txtlocs[a].y+self.c.y+self.pos+.5,self.w-10, self.txtlocs[a].z+2)
        fill(self.tc)
        text(self.txts[a],self.c.x+5,self.txtlocs[a].y+self.c.y+self.pos+3)
    end
    clip()
    popStyle()
end
function Textbox:addTxt(str)
    pushStyle()
    textWrapWidth(self.w)
    fontSize(self.f or 20)
    font(self.tfont)
    table.insert(self.txts,1,str)
    local xa,ya = textSize(str)
    table.insert(self.txtlocs,1,vec3(0,1,ya))
    local yb = 0
    if #self.txts>self.tlim then
        xb,yb = textSize(self.txts[#self.txts])
        table.remove(self.txts,#self.txts)
    end
    for i=1,#self.txts do
        if i~=1 and self.txts[i] then
            self.txtlocs[i]=self.txtlocs[i]+vec3(0,ya+2,0)
            --self.txtlocs[i]=self.txtlocs[i]+vec3(0,2,0)
        end
    end
    popStyle()
    self.maxY = self.maxY - ya + yb
    if #self.txts < self.tlim and #self.txts > 1 then self.maxY = self.maxY - 2 end
    if self.pos ~= 0 then
        self.pos = self.pos - ya
        if self.pos < self.maxY then
            self.pos = self.maxY
        end
    end
    self.spos = (self.pos/self.maxY)*(self.h-5)
end
function Textbox:touched(t)
    if t.state == BEGAN and not self.t then
        if t.x > self.c.x and t.x < self.c.x+self.w then
            if t.y > self.c.y and t.y < self.c.y+self.h then
                self.t = t
                --
                self.tdy = 0
                --
            end
        end
    end
    if self.t then
        if t.state == MOVING and t.id == self.t.id then
            self.pos = self.pos + t.deltaY
            --
            self.tdy = self.tdy + math.abs(t.deltaY)
            --
            if self.pos < self.maxY then
                self.pos = self.maxY
            end
            if self.pos > 0 then self.pos = 0 end
            self.spos = (self.pos/self.maxY)*(self.h-5)
        end
        if t.state == ENDED and t.id == self.t.id then
            self.t = nil
            --
            if self.tdy < 1 then
                self.pos = 0
            end
            --
            self.spos = (self.pos/self.maxY)*(self.h-5)
        end
    end
end
function Textbox:setCols(boxc,textc,dotc,tbc)
    self.bc = boxc or self.bc
    self.tc = textc or self.tc
    self.dc = dotc or self.dc
    self.tbc = tbc or self.tbc
end
function Textbox:move(vec2orX,y)
    if y then
        self.c = vec2(vec2orX,y)
    else
        self.c = vec2orX
    end
end
function Textbox:clear()
    self.txts={}
    self.txtlocs={}
    self.pos=0
    self.spos = (self.pos/self.maxY)*(self.h-5)
    self.maxY = self.h-5
end
function Textbox:resize(wid,hei)
    self.w = wid or self.w
    self.h = hei or self.h
    self:rebuild()
end
function Textbox:newFont(fontstr,size)
    self.tfont = fontstr or self.tfont
    self.f = size or self.f
    self:rebuild()
end
function Textbox:rebuild()
    local tempstorage = self.txts
    self.txts={}
    self.txtlocs={}
    self.pos=0
    self.spos = (self.pos/self.maxY)*(self.h-5)
    self.maxY = self.h-5
    for i=#tempstorage,1,-1 do
        self:addTxt(tempstorage[i])
    end
end

--MAIN--

function setup()
    t=Textbox(vec2(WIDTH/2-100,HEIGHT/2-25),200,50)
    t:addTxt("invad3rZIM")
    t:addTxt("this is a textbox")
    t:addTxt("A morte fontes vitae")
    t:addTxt("I like to eat chicken tacos, they are super delicious and I love them long time")
    parameter.text("TextToAdd","")
    parameter.action("Add Text",function() t:addTxt(TextToAdd) end)
end
function draw()
    background(40, 40, 50)
    strokeWidth(5)
    t:draw()
end
function touched(p)
    if t then t:touched(p) end
end

EDIT: added some functionality

The user and all related content has been deleted.

@NatTheCoder There are some projects with thousands of lines of code, wait till you see those!

The user and all related content has been deleted.

@NatTheCoder most of time, If a project is over 1k lines of code, they’ll put it on the AppStore

The user and all related content has been deleted.

@NatTheCoder He said “most of the time,” and he didn’t say it was a requirement. I have a project with about 3K lines of code that I don’t think is ready for the App Store.

The user and all related content has been deleted.