Follow one function until key press

edited March 2017 in Questions about Code

My Program: User draws rectangles, one on top of another. Aim: User should be able to interact with top previously drawn e.g. send behind, bring to front, change colour etc..

My initial idea was if the user clicks on a previously drawn rectangle, they will be able to interact with that particular rectangle, however I don't think it is possible because if shapes are overlapping it will select all those rectangles.

Instead I decided that when the user presses "i" they enter "Interact Mode" where they can interact with the top rectangle until they go back to drawing mode.

My problem is that the "Interact Mode" isn't working. I think it's because the user presses "i" and it enters "Interact Mode" however, as soon as they press a key after that to send the top rectangle back or forward, it changes the "key" and it leaves "Interact Mode"

boolean startDraw;
int a, b, c, d;
Rect newRect;
Rect topRect;
ArrayList<Rect> rectList = new ArrayList();
boolean undo = false;

void setup() {
  size(800, 600);
  a=0;
  b=0;
  c=0;
  d=0;
}


void draw() {
  background(255);
  fill(255);
  strokeWeight(2);
   for(Rect newRect : rectList) {    
    newRect.createRect();
    topRect = rectList.get(rectList.size() - 1);
  }

  if (startDraw)
  {
    newRect = new Rect(a, b, c, d);
    newRect.createRect();
  }  



  if (undo == true) {
    rectList.remove(rectList.size() - 1);
    undo = false;
  }
}


void mousePressed() {
  startDraw = true;
  a=mouseX;
  b=mouseY;  
}


void mouseDragged() {
  if (startDraw)
  {
    c=mouseX-a;
    d=mouseY-b;
  }  

}

void mouseReleased() {
  rectList.add(newRect);
  startDraw = false;
  a=0; b=0; c=0; d=0;
}

void keyPressed() {
  if (key == 'z') {
    undo = true;
  }    
  if (key == 'i') {
    interactRect();
  }    
}

void interactRect() {    
  int currentIndex = rectList.size() - 1;
  if(key == CODED) {
    if(keyCode == UP) {
      rectList.remove(topRect);
      rectList.add(topRect);        
    } if(keyCode == DOWN) {
      currentIndex = 0;
      rectList.remove(topRect);
      rectList.add(currentIndex, topRect);
      println(currentIndex);
    } if(keyCode == LEFT) {
      currentIndex--;
      rectList.remove(topRect);
      rectList.add(currentIndex, topRect);
    } if(keyCode == RIGHT) {
      currentIndex++;
      rectList.remove(topRect);
      rectList.add(currentIndex, topRect);
  }
 }
}

class Rect {
  int a, b, c, d;

  Rect(int w, int x, int y, int z) {
    a = w;
    b = x;
    c = y;
    d = z;
  }

  void createRect() {
    rect(a, b, c, d);
  }


}

Answers

  • Answer ✓

    Hmmmm interaction mode is only call once. The layout of your program needs to be modified. Notice that if you use noFill(), you can see overlapping rectangles. You won't be able to tell which is is on top and which one is at the back if you do so. You could toggle between fill or noFill at first to see the interaction between overlapping figures. A next challenge is for the user to pick the right rectangle and then figure how to send it forward or backward. Te concept should work as this is precisely what you want to accomplish. Here is a modified version of your code. I have to say I didn't understand what you were trying to do in the function interactRect() and it is something to look in the future. Study the code and reflect on those changes. Also keep in mind that the changes I introduce might be useful but not optimal for your application. In other words, there could be a better way to use those features in your application. This better way depends heavily on you and the nature of your final product. It works for trying your concept nevertheless.

    boolean startDraw;
    int a, b, c, d;
    Rect newRect;
    Rect topRect;
    ArrayList<Rect> rectList = new ArrayList();
    boolean undo = false;
    boolean interactMode=false;
    
    void setup() {
      size(800, 600, P2D);
      a=0;
      b=0;
      c=0;
      d=0;
    }
    
    void draw() {
      background(255);
    
      for (Rect aRect : rectList) {    
        aRect.displayRect(!interactMode);
        //topRect = rectList.get(rectList.size() - 1);
      }
    
      if (startDraw)
      {    
        newRect.displayRect();
      }  
    
    
      if (undo == true && rectList.size()>0) {
        rectList.remove(rectList.size() - 1);
        undo = false;
      }
    
    
      showEngineStatus();
    }
    
    void showEngineStatus() {
      String engineTxt="";
      stroke(0, 255, 0);
      if (interactMode==true) {
        fill(0, 255, 0);
        engineTxt="Interaction mode ON ";
      } else {
        noFill();
        engineTxt="Interaction mode OFF";
      }
      ellipse(width-15, 15, 10, 10);
      fill(0, 255, 0);
      text(engineTxt, width-textWidth(engineTxt)*1.20, 20);
    }
    
    
    void mousePressed() {
      if (interactMode==false) {
        startDraw = true;
        a=mouseX;
        b=mouseY;
        newRect = new Rect(a, b, 0, 0);
      }
    }
    
    
    void mouseDragged() {
      if (startDraw)
      {
        newRect.c=c=mouseX-a;
        newRect.d=d=mouseY-b;
      }
    }
    
    void mouseReleased() {
      rectList.add(newRect);
      startDraw = false;
      a=0; 
      b=0; 
      c=0; 
      d=0;
    }
    
    void keyPressed() {
      if (key == 'z') {
        undo = true;
      }    
      if (key == 'i') {
        interactMode=!interactMode;
      }
    
      if (interactMode==true) {
        interactRect();
      }
    } 
    
    
    void interactRect() {    
    
    
      int currentIndex = rectList.size() - 1;
      if (key == CODED) {
        if (keyCode == UP) {
          rectList.remove(topRect);
          rectList.add(topRect);
        } 
        if (keyCode == DOWN) {
          currentIndex = 0;
          rectList.remove(topRect);
          rectList.add(currentIndex, topRect);
          println(currentIndex);
        } 
        if (keyCode == LEFT) {
          currentIndex--;
          rectList.remove(topRect);
          rectList.add(currentIndex, topRect);
        } 
        if (keyCode == RIGHT) {
          currentIndex++;
          rectList.remove(topRect);
          rectList.add(currentIndex, topRect);
        }
      }
    }
    
    class Rect {
      int a, b, c, d;
      color fColor;
    
      Rect(int w, int x, int y, int z) {
        a = w;
        b = x;
        c = y;
        d = z;
        fColor=color(random(256));
      }
    
      void displayRect() {
        displayRect(false);
      }
    
      void displayRect(boolean showFill) {
        if (showFill==true)
          fill(fColor);
        else
          noFill();
        stroke(0);
        strokeWeight(2);
        rect(a, b, c, d);
      }
    }
    

    Kf

    P.S. I didn't remove redundant code as I wanted to keep as much of the original code as I could.

  • Hey @kfrajer The purpose of interact mode is once they're in this mode, and press any of the arrow keys, it moves the top rectangle in the array. so by pressing down, it sends it to the beginning of the array and therefore sends it to the back in the canvas. Left, moves it one before in the array and sends it behind one layer etc..

Sign In or Register to comment.