does anyone have a textbox function i could use?

edited August 2015 in General Discussion

yeah... nothing to add. :|

(how do you do a lenny?)

Answers

  • This code I copied from the old forum. IT'S NOT MINE. As you can see it is from @calsign

    /*
     * Multiline Text Box
     * 
     * 2012 William Smith
     * aka calsign
     * 
     * Implementation requires mousePressed(), mouseDragged(),
     * mouseReleased(), and keyPressed() to call their respective
     * functions in the class. This class has been extracted from one of my
     * ongoing projects and is in no way complete, although it features
     * numerous ideas that may be of use to beginners in this area.
     * 
     * Text box supports basic text input, multiple lines, lines returning when
     * becoming too long (TODO), selection, and copy + paste.
     */
    
    import java.awt.event.KeyEvent;
    
    
    MultilineTextBox textBox;
    
    void setup() {
      size(600, 600);
    
      textBox = new MultilineTextBox("Your Text", 50, 50, 500, 500);
    }
    
    void draw() {
      textBox.update();
      textBox.display();
    }
    
    void mousePressed() {
      textBox.updatePress();
    }
    
    void mouseDragged() {
      textBox.updateDrag();
    }
    
    void mouseReleased() {
      textBox.updateRelease();
    }
    
    void keyPressed() {
      textBox.updateKeys();
    }
    
    class MultilineTextBox {
      String prompt;
      String[] text;
      int xpos;
      int ypos;
    
      boolean alreadyPressed;
      boolean selecting;
      int xpos2;
      int ypos2;
    
      PVector loc;
    
      float WIDTH;
      float HEIGHT;
    
      boolean inverseBackground;
      boolean hasFocus;
      boolean hasInputFocus;
    
      int lastPress = -500;
    
      MultilineTextBox(String prompt, float x, float y, float w, float h) {
        WIDTH = w;
        HEIGHT = h;
    
        this.prompt = prompt;
        text = new String[1];
        text[0] = "";
        ypos = 0;
        xpos = 0;
    
        loc = new PVector(x, y);
      }
    
      MultilineTextBox(String prompt, float x, float y, float w, float h, boolean inverseBackground) {
        WIDTH = w;
        HEIGHT = h;
    
        this.prompt = prompt;
        text = new String[1];
        text[0] = "";
        ypos = 0;
        xpos = 0;
    
        loc = new PVector(x, y);
    
        this.inverseBackground = inverseBackground;
      }
    
      void update() {
      }
    
      void updatePress() {
        if (mousePressed) {
          if (mouseX > loc.x && mouseX < loc.x + WIDTH && mouseY > loc.y && mouseY < loc.y + HEIGHT) {
            hasFocus = true;
            hasInputFocus = true;
    
            testPos();
    
            alreadyPressed = true;
          } 
          else {
            hasFocus = (text.length <= 1 && text[0].length() <= 0 ? false : true);
            hasInputFocus = false;
            if (!alreadyPressed) selecting = false;
          }
        }
      }
    
      void updateDrag() {
        if (mouseX > loc.x && mouseX < loc.x + WIDTH && mouseY > loc.y && mouseY < loc.y + HEIGHT) testPos();
        else if (selecting) testPos();
      }
    
      void updateRelease() {
        alreadyPressed = false;
      }
    
      void updateKeys() {
        if (keyPressed) {
          if (key == CODED) {
            if (millis() - lastPress > 0) {
              if (keyCode == LEFT) {
                if (xpos <= 0 && ypos > 0) {
                  ypos --;
                  xpos = text[ypos].length();
                } 
                else xpos = constrain(xpos - 1, 0, text[ypos].length());
              }
              if (keyCode == RIGHT) {
                if (xpos >= text[ypos].length() && ypos < text.length - 1) {
                  ypos ++;
                  xpos = 0;
                } 
                else xpos = constrain(xpos + 1, 0, text[ypos].length());
              }
              if (keyCode == UP && ypos > 0) {
                ypos --;
                xpos = constrain(xpos, 0, text[ypos].length());
              }
              if (keyCode == DOWN && ypos < text.length - 1) {
                ypos ++;
                xpos = constrain(xpos, 0, text[ypos].length());
              }
              if (keyCode == KeyEvent.VK_HOME) xpos = 0;
              if (keyCode == KeyEvent.VK_END) xpos = text[ypos].length();
    
              if (!(keyCode == SHIFT)) {
                ypos2 = ypos;
                xpos2 = xpos;
              }
    
              lastPress = millis();
            }
          } 
          else {
            switch(key) {
            case ESC:
            case TAB:
              break;
            case ENTER:
            case RETURN:
              newline();
              break;
            case BACKSPACE:
            case DELETE:
              if (selecting && (ypos != ypos2 || xpos != xpos2)) {
                int minypos = min(ypos, ypos2);
                int maxypos = max(ypos, ypos2);
    
                int minxpos;
                int maxxpos;
    
                if (minypos == maxypos) {
                  minxpos = min(xpos, xpos2);
                  maxxpos = max(xpos, xpos2);
                } 
                else {
                  minxpos = (minypos == ypos ? xpos : xpos2);
                  maxxpos = (maxypos == ypos ? xpos : xpos2);
                }
    
                if (minypos == maxypos) text[ypos] = text[ypos].substring(0, minxpos) + text[ypos].substring(maxxpos, text[ypos].length());
                else {
                  String combine = text[minypos].substring(0, minxpos) + text[maxypos].substring(maxxpos, text[maxypos].length());
                  String[] pre = append(subset(text, 0, minypos), combine);
                  text = concat(pre, subset(text, maxypos + 1, text.length - (maxypos + 1)));
                }
    
                ypos = minypos;
                xpos = minxpos;
    
                ypos2 = ypos;
                xpos2 = xpos;
                selecting = false;
    
                lastPress = millis();
              } 
              else {
                if (millis() - lastPress > 0 && xpos > 0) {
                  text[ypos] = text[ypos].substring(0, xpos - 1) + text[ypos].substring(xpos, text[ypos].length());
    
                  xpos --;
                  xpos2 = xpos;
    
                  lastPress = millis();
                } 
                else if (ypos > 0 && xpos == 0) {
                  int over = text[ypos - 1].length();
                  String combine = text[ypos - 1] + text[ypos];
    
                  String[] pre = append(subset(text, 0, ypos - 1), combine);
                  text = concat(pre, subset(text, ypos + 1, text.length - (ypos + 1)));
    
                  ypos --;
                  xpos = over;
    
                  ypos2 = ypos;
                  xpos2 = xpos;
                }
              }
              break;
            default:
              if (selecting && (ypos != ypos2 || xpos != xpos2)) {
                int minypos = min(ypos, ypos2);
                int maxypos = max(ypos, ypos2);
    
                int minxpos;
                int maxxpos;
    
                if (minypos == maxypos) {
                  minxpos = min(xpos, xpos2);
                  maxxpos = max(xpos, xpos2);
                } 
                else {
                  minxpos = (minypos == ypos ? xpos : xpos2);
                  maxxpos = (maxypos == ypos ? xpos : xpos2);
                }
    
                if (millis() - lastPress > 0) {
    
                  if (minypos == maxypos) text[ypos] = text[ypos].substring(0, minxpos) + key + text[ypos].substring(maxxpos, text[ypos].length());
                  else {
                    String combine = text[minypos].substring(0, minxpos) + key + text[maxypos].substring(maxxpos, text[maxypos].length());
                    String[] pre = append(subset(text, 0, minypos), combine);
                    text = concat(pre, subset(text, maxypos + 1, text.length - (maxypos + 1)));
                  }
    
                  ypos = minypos;
                  xpos = minxpos + 1;
    
                  ypos2 = ypos;
                  xpos2 = xpos;
                  selecting = false;
    
                  lastPress = millis();
                }
              } 
              else {
                if (millis() - lastPress > 0 && textWidth(text[ypos].substring(0, xpos) + key + text[ypos].substring(xpos, text[ypos].length())) < WIDTH - 8) {
                  text[ypos] = text[ypos].substring(0, xpos) + key + text[ypos].substring(xpos, text[ypos].length());
    
                  xpos ++;
                  xpos2 = xpos;
    
                  lastPress = millis();
                }
              }
              break;
            }
          }
        }
      }
    
      void newline() {
        String after = text[ypos].substring(xpos, text[ypos].length());
        text[ypos] = text[ypos].substring(0, xpos);
        text = splice(text, after, ypos + 1);
    
        ypos ++;
        xpos = 0;
    
        ypos2 = ypos;
        xpos2 = xpos;
      }
    
      void testPos() {
        if (alreadyPressed) {
          selecting = true;
    
          ypos2 = int(constrain((mouseY - loc.y) / 12.0, 0, text.length - 1));
    
          for (int i = 0; i < text[ypos2].length(); i ++) {
            if (mouseX - loc.x - 4 <= textWidth(text[ypos2].substring(0, i)) + textWidth(text[ypos2].charAt(i)) / 2) {
              xpos2 = i;
              return;
            }
          }
    
          xpos2 = text[ypos].length();
        } 
        else {
          selecting = false;
    
          ypos = int(constrain((mouseY - loc.y) / 12.0, 0, text.length - 1));
    
          for (int i = 0; i < text[ypos].length(); i ++) {
            if (mouseX - loc.x - 4 <= textWidth(text[ypos].substring(0, i)) + textWidth(text[ypos].charAt(i)) / 2) {
              xpos = i;
              return;
            }
          }
    
          xpos = text[ypos].length();
        }
      }
    
      void display() {
        if (inverseBackground) fill(0);
        else fill(255);
        stroke(0);
        if (hasInputFocus) strokeWeight(2);
        else strokeWeight(1);
        rectMode(CORNER);
    
        rect(loc.x, loc.y, WIDTH, HEIGHT);
    
        textSize(12);
        textAlign(LEFT, TOP);
        if (hasFocus) fill(0);
        else fill(102);
    
        if (hasFocus) {
          for (int i = 0; i < text.length; i ++)
            text(text[i], loc.x + 4, loc.y + 2 + i * 12);
        } 
        else text(prompt, loc.x + 4, loc.y + 2);
    
        ypos = constrain(ypos, 0, text.length);
        ypos2 = constrain(ypos2, 0, text.length);
    
        xpos = constrain(xpos, 0, text[ypos].length());
        xpos2 = constrain(xpos2, 0, text[ypos2].length());
    
        if (selecting && (xpos != xpos2 || ypos != ypos2)) {
          fill(162, 234, 255, 102);
          noStroke();
    
          int minypos = min(ypos, ypos2);
          int maxypos = max(ypos, ypos2);
    
          int minxpos;
          int maxxpos;
    
          if (minypos == maxypos) {
            minxpos = min(xpos, xpos2);
            maxxpos = max(xpos, xpos2);
          } 
          else {
            minxpos = (minypos == ypos ? xpos : xpos2);
            maxxpos = (maxypos == ypos ? xpos : xpos2);
          }
    
          if (minypos == maxypos) rect(loc.x + 4 + textWidth(text[minypos].substring(0, minxpos)), loc.y + 4 + minypos * 12, textWidth(text[maxypos].substring(0, maxxpos)) - textWidth(text[maxypos].substring(0, minxpos)), 12);
          else {
            for (int y = minypos; y <= maxypos; y ++) {
              for (int x = 0; x < text[y].length(); x ++) {
                if ((y == minypos ? x >= minxpos : true) && (y == maxypos ? x < maxxpos : true)) rect(loc.x + 4 + textWidth(text[y].substring(0, x)), loc.y + 4 + y * 12, textWidth(text[y].charAt(x)), 12);
              }
              if (text[y].length() <= 0) rect(loc.x + 4, loc.y + 4 + y * 12, textWidth(" ") / 2, 12);
            }
          }
        } 
        else if (hasInputFocus && millis() / 300 % 2 == 1) line(loc.x + 4 + textWidth(text[ypos].substring(0, xpos)), loc.y + 4 + ypos * 12, (loc.x + 4 + textWidth(text[ypos].substring(0, xpos))), loc.y + 16 + ypos * 12);
      }
    
      String[] getText() {
        return text;
      }
    
      void setText(String toSet) {
        String[] output = new String[0];
        int last = -1;
        for (int i = 0; i < toSet.length(); i ++) {
          if (toSet.charAt(i) == '\n') {
            output = append(output, toSet.substring(last + 1, i));
            last = i;
          }
        }
    
        output = append(output, toSet.substring(last + 1, toSet.length()));
    
        text = output;
      }
    
      String consolidate() {
        String toReturn = "";
        for (int i = 0; i < text.length; i ++) {
          toReturn += text[i];
          if (i < text.length - 1) toReturn += "\n";
        }
    
        return toReturn;
      }
    }
    
  • As a side note, can you still use java.awt.event.KeyEvent in Processing 3? If not how would you do it?

  • thanks, but I'm looking for a function (if possible?) (I don't use classes, the can get to complicated)

    thanks, though!

  • edited August 2015

    @colouredmirrorball I don't know, but good question. (I use processing 3)

    edit: yes.

  • I don't know, but good question. (I use processing 3)

    Since you use PS3 then you could test it out by trying the code above.

    For something as complex as a 'multi-line text input control' implemented as a function is as likely as finding a snowball in the Hell. Classes may seem complicated at first glance but are well worth the effort to learn. In the above code you are not required to create the class it already exists so why not give it a try?

  • @quark ok, how do I?

  • How do I what?

  • edited August 2015 Answer ✓

    you can see how the class is used from the code above

    all above line 48 is the usage.....

    you can't have one function alone because you have to monitor mousePressed() and keyPressed()and also you have to do stuff in draw()....

  • use a class. @quark

  • Answer ✓

    I suggest you start with the tutorials, there is one on objects.

    Classes an objects (object orientation) is not something you can learn in 5 minutes but in many instances they can make it easier for you later, especially in large or complex sketches.

  • edited October 2015

    just to add take your time with that object tutorial as i did find it very convoluted at first. example is that in the writing the cookie cutter section i didn't realize that they were putting the class data(shown on right side of the picture) in an actual class. it might have just been my eyesight and the yellow throwing me off but i had to move to another language to learn about class based objects because i didn't take my time to read the above link he pointed to.

    EDIT: rather i did look through it but i didn't slow down enough.

  • edited October 2015

    also think of a class as a blueprint. it's like what it would be like to have a function that has function declarations in it rather than a function that has more function calls. example.

    void foo(){
        static int x;  //static values don't get discarded
        void bar(){
    
        }
    }
    

    if you could do the above in programming... well that's what a class is like. accept that you can access the inner functions of said class and you have to make an object out of it before you can use it. but this is the general way i had to picture it before i understood what it's purpose was. good luck cause like quark said it takes a while to grasp. EDIT: i recommend looking up the following to create arrays of objects. https://processing.org/discourse/beta/num_1243792004.html and search this in google. "processing multiple objects" and in case it's not clear an object of a class is like a product coming out of a factory. class being the factory.

  • and sorry to add another comment but i just remembered something. this is something you might not find out for a very long time cause it's not very much talked about. but "after" you understand the basics of how arrays of class based objects are made (and how child/parent relationships work) than i HIGHLY recommend looking up the following. "abstract classes" and "instanceof" for java. note instanceof is the same as c++'s dynamic_cast.

  • k, thanks.

  • Classes an objects (object orientation) is not something you can learn in 5 minutes but in many instances they can make it easier for you later, especially in large or complex sketches.

    after a long time, I am now comfortable using classes. Khan Academy (although they modified how some of the coding works) taught me the basics. Then by viewing other classes, I got it! Yay! :P

Sign In or Register to comment.