Text Basis [Failed]

If you change position where to change the text - how to make it?

@TokOut Can you explain in more detail what you want. I’m not sure what you’re asking. Same with the question in the your other post.

I can make text boxes which will be only editable on the last point
Text … Input

I need
Some text … Input … Rest of the text

// Edit in all points of the text //

I think I understand what you’re trying to do. You have a text box with a lot of text in it. Do you want to be able to position a cursor anywhere in that text and insert new text at that spot with the existing text moving to the right. If that’s what you want, it’s going to be kind of hard. You’ll need to figure out where in the string you’re going to insert the text based on the screen x,y position. And that’s going to be hard because the character width isn’t the same per character unless you use the Courier font. Are you after something like a text editor that lets you insert text anywhere within the text.

Yup, as @dave1707 says, it’s a lot easier to do this if you use a fixed-width font. It’s not just courier though, you have a few to choose from in Codea (menlo maybe? iPad is not to hand so can’t check just now).

@TokOut I think this is what you want. Slide your finger back and forth under the text box to position the cursor where you want it. Key the text you want to insert or use the backspace key to delete text you don’t want. The RETURN key isn’t supported because that would require a lot more code to handle multiple lines of text in a text box. This will handle different fonts, but you might have to change the value of adj to tweak the cursor position. If you hide the keyboard, a double tap will show it again. This wasn’t as hard as I thought it was going to be.

EDIT: I also created a class version for this.

function setup()
    showKeyboard()
    textMode(CORNER)
    ellipseMode(CORNER)
    str="one two three four five six seven eight nine ten"
    curPos=0    -- position of the curson
    charPos=0   -- character position at cursor
    adj=-3      -- tweek the cursor position
end

function draw()
    background(40, 40, 50)
    clip(5,585,400,50)
    fill(0, 157, 255, 255)
    stroke(255)
    strokeWidth(3)
    rect(5,585,400,50)
    fill(255)
    text(str,10,600)
    fill(255, 0, 166, 255)
    text("|",10+curPos+adj,600) -- cursor
end

function touched(t)
    if t.state==BEGAN or t.state==MOVING then
        curPos=math.max(0,t.x-10)
        if curPos>0 then
            for z=1,#str do
                w,h=textSize(string.sub(str,1,z))
                if w>=curPos or z==#str then
                    charPos=z
                    curPos=w
                    break
                end
            end
        end
    end
    if t.tapCount==2 and not showKeyboard() then    -- double tap to show keyboard
        showKeyboard()
    end
end

function keyboard(k)
    if k==RETURN then   -- dont support multiple lines of text
        return  
    end
    if k==BACKSPACE then    -- handle backspace key
        if charPos>0 then
            str1=string.sub(str,1,charPos-1)..string.sub(str,charPos+1,#str)
            charPos=charPos-1
            str=str1
            curPos=textSize(string.sub(str,1,charPos))
        end
    else    -- normal characters
        str1=string.sub(str,1,charPos)..k..string.sub(str,charPos+1,#str)
        charPos=charPos+1
        str=str1
        curPos=textSize(string.sub(str,1,charPos))
    end
end

Ok, thanks, but why can’t I copy the code above?

I don’t have any problems copying it. Go about 1 inch from the bottom and do a double tap but don’t lift your finger on the second tap, that usually selects the whole code.


I remember a copy button which disappeared months ago. Get it back plz.

I wanted to export the code which @dave1707 wrote into a class and TOUCH and CURSOR got a Bug. I would like to know my mistake to not do it again. Also what exactly does clip()?

function setup()
    TB = TextBox("one two three four five six seven eight nine ten", vec2(250,585), vec2(400,50))
end

function draw()
    background(40, 40, 50)
    TB:draw()
end

function touched(t)
    TB:touched(t)
end

function keyboard(k)
    TB:keyboard(k)
end

TextBox = class()

function TextBox:init(textArgument, pos, size)
    self.align = {x=pos.x, y=pos.y, w=size.x, h=size.y}
    self.str=textArgument
    self.curPos=0    -- position of the curson
    self.charPos=0   -- character position at cursor
    self.adj=0       -- tweek the cursor position
end

function TextBox:draw()
    ellipseMode(CORNER)
    clip(self.align.x, self.align.y, self.align.w, self.align.h)
    fill(255, 255, 255, 255)
    rect(self.align.x, self.align.y, self.align.w, self.align.h)
    fill(0, 0, 0, 255)
    text(self.str,self.align.x+self.align.w/2, self.align.y+self.align.h/2)
    fill(0, 0, 200, 255)
    text("|",self.align.x+self.curPos+self.adj,self.align.y+self.align.h/2) -- cursor
end

function TextBox:touched(t)
    if t.x>self.align.x and t.x<self.align.w+self.align.x and t.y>self.align.y and t.y<self.align.y+self.align.h then
        self.curPos=math.max(0,t.x-10)
        if self.curPos>0 then
            for z=1,#self.str do
                w,h=textSize(string.sub(self.str,1,z))
                if w>=self.curPos or z==#self.str then
                    self.charPos=z
                    self.curPos=w
                    break
                end
            end
        end
        if t.state == BEGAN then
            showKeyboard()
        end
    end
end

function TextBox:keyboard(k)
    if k==RETURN then   -- dont support multiple lines of text
        return  
    end
    if k==BACKSPACE then    -- handle backspace key
        if self.charPos>0 then
            str1=string.sub(self.str,1,self.charPos-1)..string.sub(self.str,self.charPos+1,#self.str)
            self.charPos=self.charPos-1
            self.str=str1
            self.curPos=textSize(string.sub(self.str,1,self.charPos))
        end
    else    -- normal characters
        str1=string.sub(self.str,1,self.charPos)..k..string.sub(self.str,self.charPos+1,#self.str)
        self.charPos=self.charPos+1
        self.str=str1
        self.curPos=textSize(string.sub(self.str,1,self.charPos))
    end
end

The RETURN key isn’t supported because that would require a lot more code to handle multiple lines of text in a text box.

Hey I have an Idea of that. With this code you can!

First part of Text + \

  • Second part of text

@TokOut Having multiple lines of text is easy, just remove the code where I do a return when the RETURN key is pressed. That will give you as many lines as you press RETURN. The hard part is doing the calculations on multiple lines to know where to place the cursor. I’ll leave that up to you to work out. If you want to know what clip does, look in the reference. It’s explained there.

EDIT: As for your TOUCH and CURSOR bug, I’ll leave that up to you also.

Oh, Okay. May you just explain me what exactly I destroyed while exporting? I really see no reason why it should go each different size each different difference. Which tag (=editor command) is wrong? No solution (as you said), just short explanation. Then clip I didn’t seen the description, I have just thought. Is it something like a limitation for the text?

@TokOut You’ll find clip in the graphics section in the reference. Heres what it says.

Setting Clipping Bounds
clip( x, y, width, height )

Syntax
clip( x, y, width, height )
clip() --Disables clipping
Constrains all drawing performed after this function call to the rectangle specified by x, y, width, height. Any drawing that occurs outside the bounds will not be visible.

This can be used to make split-screen multiplayer games, for example. When called with zero arguments clip() disables the clipping rectangle, allowing drawing to occur anywhere on the screen.

x
integer, x coordinate of the lower-left corner of the clipping rectangle

y
integer, y coordinate of the lower-left corner of the clipping rectangle

width
integer, width of the clipping rectangle

height
integer, height of the clipping rectangle

Thank you. Very much.

@TokOut Here is my class version for the above code. You can compare this to yours to find out why yours doesn’t work, or just use this.

displayMode(FULLSCREEN)

function setup()
    showKeyboard()
    textMode(CORNER)
    ellipseMode(CORNER)
    str1="This is some text for textbox one."
    str2="This is some text for textbox two."
    str3="This is some text for textbox three."
    tb1=textBox(100,650,400,50,str1)
    tb2=textBox(200,550,400,50,str2)
    tb3=textBox(300,450,200,50,str3)
end

function draw()
    background(40, 40, 50)
    tb1:draw()   
    tb2:draw()   
    tb3:draw()   
end

function touched(t)
    tb1:touched(t)
    tb2:touched(t)
    tb3:touched(t)
    if t.tapCount==2 then    -- double tap to show keyboard
        showKeyboard()
    end
end

function keyboard(k)
    tb1:keyboard(k)
    tb2:keyboard(k)
    tb3:keyboard(k)
end

textBox=class()

function textBox:init(x,y,w,h,s)
    self.x=x
    self.y=y
    self.w=w
    self.h=h
    self.cursorPos=0
    self.charPos=0
    self.adj=-3
    self.adjX=10
    self.adjY=15
    self.str=s
    self.sel=false
end

function textBox:draw()
    clip(self.x,self.y,self.w,self.h)
    fill(0, 157, 255, 255)
    stroke(255)
    strokeWidth(3)
    rect(self.x,self.y,self.w,self.h)
    fill(255)
    text(self.str,self.x+self.adjX,self.y+self.adjY)
    if self.sel then
        fill(255, 0, 166, 255)
        text("|",self.x+self.adjX+self.cursorPos+self.adj,self.y+self.adjY) -- cursor
    end
end

function textBox:touched(t)
    if t.state==BEGAN or t.state==MOVING then
        if t.x>self.x-10 and t.x<self.x+self.w and
                t.y>self.y-self.h and t.y<self.y+self.h then
            self.sel=true
            self.cursorPos=math.max(0,t.x-self.x)
            if self.cursorPos>0 then
                for z=1,#self.str do
                    w,h=textSize(string.sub(self.str,1,z))
                    if w>=self.cursorPos or z==#self.str then
                        self.charPos=z
                        self.cursorPos=w
                        break
                    end
                end
            end
        else
            self.sel=false
        end
    end
end

function textBox:keyboard(k)
    if self.sel then
        local str1
        if k==RETURN then   -- dont support multiple lines of text
            return  
        end
        if k==BACKSPACE then    -- handle backspace key
            if self.charPos>0 then
                str1=string.sub(self.str,1,self.charPos-1)..
                        string.sub(self.str,self.charPos+1,#self.str)
                self.charPos=self.charPos-1
                self.str=str1
                self.cursorPos=textSize(string.sub(self.str,1,self.charPos))
            end
        else    -- normal characters
            str1=string.sub(self.str,1,self.charPos)..k..
                    string.sub(self.str,self.charPos+1,#self.str)
            self.charPos=self.charPos+1
            self.str=str1
            self.cursorPos=textSize(string.sub(self.str,1,self.charPos))
        end
    end
end

Thank you.