KeyPressed BACKSPACE and delete just one shape

edited June 2016 in Library Questions

Hi there again, this time I need a little help: I've create a code for a "generative" logo (it's at the start so is not complete), and I want that while pressing one time the BACKSPACE I can go back just for one shape. Now like I have my code, when I press Backspace it delete all.

I leave the code here, thanks !

    import controlP5.*;

    ControlP5 cp5;

    String textValue = "";
    String val;

    void setup() {
       size(700,800);

      PFont font = createFont("arial",20);

      cp5 = new ControlP5(this);

      cp5.addTextfield("INPUT")
         .setPosition(width/2-100,600)
         .setSize(200,40)
         .setFont(font)
         .setFocus(true)
         .setColor(color(255,255,255))

         ;

      textFont(font);
      background(0);
      noStroke();
    }
    void draw() {


      if (keyPressed) {

        if (key == 'o' || key == 'O') {
          fill(205, 152, 59, 100);
          ellipse(width/2, height/2, 50, 50);
        } 

          if (key == 'b' || key == 'B') {
            fill(20, 84, 42, 100);
            rectMode(CENTER);
            rect(width/2, height/2, 50, 50);
          }
        } 
        if (key == BACKSPACE) {    //This reset all, I want to reset just the last one shape
      background (0);
    }

    val = cp5.get(Textfield.class,"INPUT").getText();
     println(val.length());

    }

Answers

  • you'd have to store all pixels in an array at the point you wanted to remember it, and then recall them when you press backspace. Is it worth it, when you could just clear the screen with background(0) & redo all the steps except the last?

  • Well my intent is to create a generative brand like this http://ebologna.it/ , so you think is wrong to put the background(0) ?

    Speaking of code, what I have to digit for do what you say?

  • Answer ✓

    I get it now - nice looking site. So basically you need an undo. Background(0) clears the screen so that's no good. Never tried this before but I assume if you read each pixel in a nested for loop: for (x=0; x >= width; x ++) {for (y = 0; y>= height; y++); // read value of each pixel into an array; you could save the current screen - but I bet there's a function to do this already & hopefully someone will point us to it.

  • The pixels() function looks good for this - save the current screen into an array, then loadPixels() to recover it.

  • edited June 2016

    So in my code what I have to write? My study is really basic and I never see he pixels function!

    Ps: I don't have a int variable, just like you can see in my code, there are only if with the key to be pressed!

    Hope someone can answer too! Thanks a lot fuzzySi

  • Can't test this for you until this evening, but looks like it should be:

    loadPixels(); // this should load current image into pixels array Use arrayCopy to copy current pixels[] into a new array eg undoBuffer[] updatePixels();

    Your undo function should reverse this ie swap the pixels in the undoBuffer into the pixels array. Only pseudocode so far but that should be a start.

    Some useful stuff here, but not the exact code you need https://processing.org/tutorials/pixels/

  • edited June 2016

    How about this - functions to backup current display and restore it. I was getting bounce with your keypressed code so I've changed it to keyRelease instead.

        color[] previousDisplay; // this will store current state of pixels as a backup
    
        void setup() {
          size(100, 100);
          previousDisplay = new color[width * height];
          background(0);
        } // end setup
    
        void draw() {
        } // end draw
    
        void keyReleased() {
          if (key == 'o' || key == 'O') {
            backupDisplay(); // backup the display before doing anything 
                                       // that you might want to undo later
            fill(205, 152, 59, 100);
            ellipse(width/2, height/2, 50, 50);
          } else if (key == 'b' || key == 'B') {
            backupDisplay();
            fill(20, 84, 42, 100);
            rectMode(CENTER);
            rect(width/2, height/2, 50, 50);
          } else if (key == BACKSPACE) {   
           restoreBackup();
           }
        }
    
        void backupDisplay() {
          // saves current state of pixels into an array
          loadPixels();
          for (int i=0; i <= (width * height) -1; i ++) {
            previousDisplay[i] = pixels[i];
          }
          println("backed up");
          updatePixels();
        }
    
        void restoreBackup() {
          // restores display to previously saved
          loadPixels();
          for (int i=0; i <= (width * height) -1; i ++) {
            pixels[i] = previousDisplay[i];
          }
          println("restored");
          updatePixels();
        }
    
  • edited June 2016

    Mh but with this code I can just go back only one? Because I want it that I can delete, just one shape, but all the time I push the key BACKSPACE. I think this really work, but do you think can it be like I was saying?

    Notice this, I have to create all the alphabet so is right to write if and else if for the key?

    (Sorry for bother you a lot!)

    I've try too to put, but it work the same as yours :

        void keyReleased() {
          if (key == 'o' || key == 'O') {
            backupDisplay(); // backup the display before doing anything 
                                       // that you might want to undo later
            fill(205, 152, 59, 100);
            ellipse(width/2, height/2, 50, 50);
          } else if (key == BACKSPACE) {
           restoreBackup();
        }
    
        if (key == 'b' || key == 'B') {
            backupDisplay();
            fill(20, 84, 42, 100);
            rectMode(CENTER);
            rect(width/2, height/2, 50, 50);
          } else if (key == BACKSPACE) {   
           restoreBackup();
           }
        }
    
  • Answer ✓

    So you want multiple undos? Ah. Yes, it's possible using the same technique, but to get each array in the right order you'd have to have a series of arrays, and dump the current pixels into the correct array, so a bit more tricky. If you want unlimited undos, you'd need to copy most recent array into previous one etc to keep them in order. You should be able to adapt the code above. Yes can have lots of if/ else statements so OK to put the whole alphabet into that function.

  • Oh gosh this will be really difficult for me!

  • well, instead of saving the whole screen I suggest bringing the stuff into an ArrayList and display the content of the ArrayList - and let backspace work on that...

    in this version, the data in the textfield is not totally connected to the ArrayList (you can type when the inputbox has no focus and it still works but never mind)

  • // mcve for interface with different classes
    
    // the nodes 
    ArrayList<Node> nodes = new ArrayList();
    
    
    
    
    import controlP5.*;
    
    ControlP5 cp5;
    
    String textValue = "";
    String val;
    
    
    
    
    // --------------------------------------------
    // Core functions 
    
    void setup() {
      size(900, 800);
    
      PFont font = createFont("arial", 20);
      cp5 = new ControlP5(this);
      cp5.addTextfield("INPUT")
        .setPosition(width/2-100, 600)
        .setSize(200, 40)
        .setFont(font)
        .setFocus(true)
        .setColor(color(255, 255, 255))    ;
    
      textFont(font);
      background(255);
      noStroke();
    } // func 
    
    void draw() {
      // clear screen 
      background(255);
    
      // for-loop
      for (int i = 0; i < nodes.size (); i++) { 
        Node someClass  = nodes.get(i);
        someClass.display();
      } // for 
    
    
      val = cp5.get(Textfield.class, "INPUT").getText();
      // println(val.length());
    
      //if (frameCount>60&&frameCount<64) {     
      //  Node someClass  = nodes.get(1);
      //  someClass.incrementXY(22, 0); // change position 
      //  someClass.incrementXY(33, 0);
      //} // else
    } // func 
    
    void keyPressed() {
    
      // add new EllipseClass/RectClass with random color 
    
      if (key == 'o' || key == 'O') {
        color col1 = color (205, 152, 59, 100);
        // ellipse(width/2, height/2, 50, 50);
    
        nodes.add ( new EllipseClass(44, 44, 
          col1));
    
        return;
      } 
    
      if (key == 'b' || key == 'B') {
        color col1 = color (20, 84, 42, 100);
        // rectMode(CENTER);
        // rect(width/2, height/2, 50, 50);
    
        nodes.add ( new RectClass(211, 211, 
          col1));
    
        return;
      }
    
      if (key == BACKSPACE) {    
        // reset just the last one shape
        int count  = nodes.size();
        if (count>0)
          nodes.remove(count-1); 
        return;
      }
    }
    
    // ==============================================
    // interface and classes
    
    class RectClass implements Node {  
    
      // pos
      float x=0;
      float y=0;
    
      // color 
      color RectClassColor=0; 
    
    
      // constr 
      RectClass(float tempX, float tempY, 
        color tempRectClassColor) {
        x = tempX;
        y = tempY;
    
        RectClassColor = tempRectClassColor;
        //
      } // constr
      //
      void display() {
        fill(RectClassColor);
        rect (x, y, 16, 16);
      }
    
      void setXY(float x_, float y_) {
        x=x_;
        y=y_;
      }
    
      void incrementXY(float x_, float y_) {
        x+=x_;
        y+=y_;
      }
      //
    } // class
    
    // -------------------------
    
    class EllipseClass implements Node {  
    
      // pos
      float x=0;
      float y=0;
    
      // color 
      color RectClassColor=0; 
    
    
      // constr 
      EllipseClass(float tempX, float tempY, 
        color tempRectClassColor) {
        x = tempX;
        y = tempY;
    
        RectClassColor = tempRectClassColor;
        //
      } // constr
      //
      void display() {
        fill(RectClassColor);
        ellipse (x, y, 15, 15);
      }
    
      void setXY(float x_, float y_) {
        x=x_;
        y=y_;
      }
    
      void incrementXY(float x_, float y_) {
        x+=x_;
        y+=y_;
      }
      //
    } // class
    
    
    interface Node {
    
      // Let's abstract
    
      // Let's abstract display()
      void display();
      void incrementXY(float x_, float y_);
    }
    //
    
Sign In or Register to comment.