Drag and move a PImage from ArrayList with mouse

ArrayList photos = new ArrayList();
PImage[] loadPhotos;
int pos_x, pos_y;
int dragged_item;

void setup() {
  size(800, 800);
  smooth();
  loadPhotos = new PImage[4];
  loadPhotos();
  imageMode(CENTER);
  pos_x = 700; 
  pos_y = 100;
}

void draw() {
  background(51);

  //strokeWeight(1);
  for (int i = 0; i <= 800; i = i+100) {
    stroke(126);
    line(0, i, 600, i);
  }
  for (int j = 0; j <= 600; j = j+100) {
    //stroke(126);
    line(j, 0, j, 800);
  }

  int x=pos_x, y=pos_y;
  for (int i = 0; i < 4; i++) {
    image(loadPhotos[i], x, y);
    y = y + 120;
  }  

  for (int i = 0; i < photos.size (); i++) {
    Photo s = (Photo) photos.get(i);
    s.display();
    s.move();
  }
}

void loadPhotos() {
  for (int i=0; i<4; i++) {
    loadPhotos[i] = loadImage("icon" + i + ".png");
  }
}

void keyPressed() {
  if (key == 'x') {
    if (photos.size() > 0) {
      photos.remove(photos.size()-1);
    }
  }
  if (key == 'c') {
    photos.clear();
  }
}

int find_item() {
  dragged_item = -1;
  for (int i = 0; i < 4; i++) {
    if (mouseX>pos_x-50 && mouseX<pos_x+50 && mouseY>pos_y+120*i-50 && mouseY<pos_y+120*i+50) {
      dragged_item = i;
    }
  }
  return dragged_item;
}

void mousePressed()
{
  if (find_item() == 0) photos.add(new Photo(700, 100, 0, 0));
  if (find_item() == 1) photos.add(new Photo(700, 220, 0, 1));
  if (find_item() == 2) photos.add(new Photo(700, 340, 0, 2));
  if (find_item() == 3) photos.add(new Photo(700, 460, 0, 3));
}

void mouseDragged() {
  if (find_item() != -1) {
    ???
  }
}

void mouseReleased() {
  dragged_item = -1;
}

class Photo {
  PImage photo;
  float rotation;
  float Xpos;
  float Ypos;
  int item;

  Photo(float XposTemp, float YposTemp, float rotationTemp, int Nitem) {

    item = Nitem;
    photo = loadPhotos[item];
    Xpos = XposTemp;
    Ypos = YposTemp;
    rotation = rotationTemp;
  }

  void display() {
    rectMode(CENTER);
    imageMode(CENTER);
    noStroke();

    pushMatrix();

    translate(width/2, height/2);
    rotate(radians(rotation));
    translate(-width/2, -height/2);

    translate(Xpos, Ypos);

    fill(0, 0, 0, 70);
    rect(0, 0, 100, 100);

    image(photo, 0, 0, 100, 100);

    popMatrix();
  }

  void move() {
    ???
  }
}

https://dl.dropboxusercontent.com/u/70391886/icon0.png https://dl.dropboxusercontent.com/u/70391886/icon1.png https://dl.dropboxusercontent.com/u/70391886/icon2.png https://dl.dropboxusercontent.com/u/70391886/icon3.png https://dl.dropboxusercontent.com/u/70391886/photo.png

Please, help with mouseDragged function...

Solution with only one PImage with rotation (center mouse buttom) and snap an image to the grid possibility..

    PImage img1;
    boolean overImage, locked, kontrola, sit;
    float mX, mY, offX, offY, angle;
    int l = 0;

    float[] udaljenosti = new float[48];
    PVector[] sredista = new PVector[48];

    void setup() {
      size(800, 800);
      mX=700;
      mY=height/2;
      angle=0;

      imageMode(CENTER);
      ellipseMode(CENTER);

      for (int i1 = 50; i1 < 600; i1=i1+100) {
        for (int j1 = 50; j1 < 800; j1=j1+100) {
          sredista[l] = new PVector(i1, j1);
          udaljenosti[l] = 100.0;
          l++;
        }
      }

      img1 = loadImage(url, "png");

    }

    void draw() {
      background(0);  

      strokeWeight(1);
      for (int i = 0; i <= 800; i = i+100) {
        stroke(126);
        line(0, i, 600, i);
      }
      for (int j = 0; j <= 600; j = j+100) {
        line(j, 0, j, 800);
      }

      if (mouseX>mX-img1.width/2 && mouseX< mX+img1.width/2 && mouseY>mY-img1.height/2 && mouseY< mY+img1.height/2) {
        overImage=true;
      } else
        overImage=false;

      pushMatrix();
      translate(mX, mY);
      rotate(angle);
      image(img1, 0, 0);
      popMatrix();

      noStroke();
      fill(255, 0, 0);
      ellipse(mX, mY, 10, 10);

      if (kontrola) paint_blue();

      if (sit) {
        fill(20, 220, 20, 70);
        rect(mX-img1.width/2, mY-img1.height/2, img1.width, img1.height);
      }
    }

    void mousePressed()
    {
      if (overImage) {
        locked=true;
        if (mouseButton == CENTER) kontrola = true;
        if (mouseButton != CENTER) kontrola = false;
      } else {
        locked=false;
      }
      offX=mouseX-mX;
      offY=mouseY-mY;
    }

    void mouseDragged() {
      if (locked && mouseButton != CENTER) {
        mX=mouseX-offX;
        mY=mouseY-offY;

        for (int k = 0; k < 48; k++) {
          float[] f = sredista[k].array();
          udaljenosti[k] = dist(mX, mY, f[0], f[1]);
          if (udaljenosti[k] > 20) sit = false;
          if (udaljenosti[k] <= 20) {
            mX = f[0];
            mY = f[1];
            sit = true;
            break;
          }
        }

        noFill();
        strokeWeight(4);
        stroke(255, 2, 2);
        rect(mX-img1.width/2, mY-img1.height/2, img1.width, img1.height);
      }
    }

    void mouseReleased() {
      locked=false;
    }

    void keyPressed() {
      if (key == 'l' && kontrola || key == 'L' && kontrola) {
        angle = angle + HALF_PI;
      }
      if (key == 'r' && kontrola || key == 'R' && kontrola) {
        angle = angle - HALF_PI;
      }
    }

    void paint_blue() {
      noFill();
      strokeWeight(4);
      stroke(2, 2, 255);
      rect(mX-img1.width/2, mY-img1.height/2, img1.width, img1.height);
    }

Answers

  • Not sure what is the question. An old example of drag and drop with rects. no rotation though..

    DragMe[] drags = new DragMe[40];
    
    void setup() {
      size(400, 400);
      for (int i = 0; i < drags.length; i++) {
        drags[i]  = new DragMe();
      }
    }
    
    void draw() {
      background(255);
      for (int i = 0; i < drags.length; i++) {
        drags[i].display();
        drags[i].update();
      }
    }
    
    
    
    void mousePressed() {
      for (int i = 0; i < drags.length; i++) {
        if (!drags[i].isOver()) {
          drags[i].dontMove = true;
        }
        drags[i].offset_x = mouseX - drags[i].pos_x;
        drags[i].offset_y = mouseY - drags[i].pos_y;
      }
    }
    
    
    void mouseReleased() {
      for (int i = 0; i < drags.length; i++) {
        drags[i].locked = false;
        drags[i].dontMove = false;
      }
    }
    
    
    
    
    
    
    class DragMe {
      float pos_x, pos_y, SIZE = 20;
      float prev_x, prev_y;
      boolean locked;
      boolean dontMove;
      color c = color (0, 170, 170);
      float offset_x, offset_y;
    
      DragMe() {
        pos_x = random(width-SIZE);
        pos_y = random(height-SIZE);
      }
    
    
      void update() {
        if (isOver() && !locked && !dontMove || locked && !dontMove )
          c = color (170);
        else
          c = color (0, 170, 170);
    
        if (isClicked()) {
          locked = true;
        }
        if (locked && !dontMove) {
    
          pos_x =  mouseX - offset_x;
          pos_y =  mouseY - offset_y;
        }
      }
    
    
    
      void display() {
        fill(c);
        rect(pos_x, pos_y, SIZE, SIZE);
      }
    
      boolean isOver() {
        float right_x = pos_x + SIZE;
        float bottom_y = pos_y + SIZE;
        return mouseX >= pos_x && mouseX <= right_x &&
          mouseY >= pos_y && mouseY <= bottom_y;
      }
    
      boolean isClicked() {
        return isOver() && mousePressed && !dontMove;
      }
    }
    
  • edited October 2015

    I have four different object (PImage) on the left side (menu) that I have to put into the grid. Some images are repeated and I choose an image from menu with mouse click-drag-drop.. The solution with one PImage above is OK. I have a problem with arraylist..

  • _vk_vk
    edited October 2015 Answer ✓

    I see, sorry I haven't run the code.

    So the thing is... you gotta go OOP, I mean make a class of your draggable images. Or the code might become a mess..

    Each time the user clicks in a predetermined place it creates and add a new instance to the array.

    I adapted my code above to exemplify, as tweaking your code is harder and it is not OOP. C if this can help:

    //Click in the white square to make a new icon (upper left corner)
    ArrayList <DragMe> drags = new ArrayList <DragMe>();
    PImage imOne;
    boolean justPressed = false;
    
    void setup() {
      size(800, 800);
      imOne = loadImage("https:"+"//dl.dropboxusercontent.com/u/70391886/icon0.png");
    }
    
    
    void draw() {
      background(0);
      if (drags.size() > 0) {
        for (DragMe d : drags) {
          d.display();
          d.update();
        }
      }
      rect(0, 0, 30, 30);
    }
    
    
    void mousePressed() {
      if (!justPressed && mouseX > 0 && mouseX < 30 && mouseY > 0 && mouseY < 30) {
        drags.add(new DragMe(imOne, mouseX, mouseY));
        println(drags.size());
        justPressed = true;
      }
    
      if (drags.size() > 0) {
        for (DragMe d : drags) { 
          if (!d.isOver()) {
            d.dontMove = true;
          }
          d.offset_x = mouseX - d.pos_x;
          d.offset_y = mouseY - d.pos_y;
        }
      }
    }
    
    
    void mouseReleased() {
      if (drags.size() > 0) {
        for (DragMe d : drags) { 
          d.locked = false;
          d.dontMove = false;
        }
      }
      justPressed = false;
    }
    
    
    
    class DragMe {
      float pos_x, pos_y, size;
      boolean locked;
      boolean dontMove;
      color c = color (0, 170, 170);
      float offset_x, offset_y;
      PImage img;
    
      DragMe(PImage _img, int p_x, int p_y) {
        img = _img;
        size = img.width;
        pos_x = p_x;
        pos_y = p_y;
      }
    
    
      void update() {
        if (isClicked()) {
          locked = true;
        }
        if (locked && !dontMove) {
    
          pos_x =  mouseX - offset_x;
          pos_y =  mouseY - offset_y;
        }
      }
    
    
    
      void display() {
        if (isOver() && !locked && !dontMove || locked && !dontMove ) {
          tint(220, 225, 255);
       } else{
          noTint();
       }
    
        image(img, pos_x, pos_y, size, size);
      }
    
      boolean isOver() {
        float right_x = pos_x + size;
        float bottom_y = pos_y + size;
        return mouseX >= pos_x && mouseX <= right_x &&
          mouseY >= pos_y && mouseY <= bottom_y;
      }
    
      boolean isClicked() {
        return isOver() && mousePressed && !dontMove;
      }
    }
    

    Get the idea, and translate your cool working mouse interaction logic (grid constraint and all that) to a class. Test with one instance. Once satisfied implement the ArrayList.

  • edited October 2015

    Thanks _vk!

    The code will be useful but what I first noticed is when images are located one above the other, the mouse drag them all.. Further more, what I want: When you click on a image it becomes the last in the list and the only one draggable element in the list.

  • edited October 2015

    something like this:

    for (int i=0;i<drags.size();i++) {
    //for (int i=drags.size()-1;i>0;i--) {
        last = drags.get(drags.size()-1);
        curr = drags.get(i);
        if(curr.isClicked()) {
          index = i;
          temp = last;
          last = curr;
          curr = temp;
        }
    }
    
  • edited October 2015

    How to prevent Dragging multiple selected elements - NOT SOLVED !!!

    Solution for pushing current object to the end of the list:

    for (int i=0;i<drags.size();i++) {
      curr = drags.get(i);
      if(curr.isClicked()) {
        index = i;
        moveToTail(drags, index);
      }
    }
    
    static final List moveToTail(List l, int idx) {
      l.add(l.remove(idx));
      return l;
    }
    
  • edited October 2015

    OK...here it is...

    void mousePressed() {
    
      if (!justPressed && mouseX > 0 && mouseX < 30 && mouseY > 0 && mouseY < 30) {
        drags.add(new DragMe(imOne, mouseX, mouseY));
        justPressed = true;
      }
    
      for (int i=0;i<drags.size();i++) {
        curr = drags.get(i);
        if(curr.isClicked()) {
          index = i;
          moveToTail(drags, index);
        }
      }
    
      for (int i=0;i<drags.size();i++) {
        temp = drags.get(i);
        if (!temp.isOver() || (temp.isOver() && i != drags.size()-1)) {
          temp.dontMove = true;
        }
        temp.offset_x = mouseX - temp.pos_x;
        temp.offset_y = mouseY - temp.pos_y;
      }  
    
    }
    
  • _vk_vk
    edited October 2015 Answer ✓

    Are you all done?

    Why do you need them at the end of the list? Actually they are added at the end, aren't they?

    when images are located one above the other, the mouse drag them al

    If the mouse is hovering over an overlapping part, yes. You would need some more input to tell which one it should drag. But if images are overlapping and there are parts not overlapping, clicking in one not overlapping part will drag only the one below mouse pointer.

    There are always a ton of ways to do things.

    You could just re work the way dontMove is being set to avoid images to continue draggable... Or just set a image in the spot after the user releases the draggable one getting rid os Draggable arrayList... Tons of ways.

    cheers

  • edited October 2015

    SOLVED !!! (Thanks to _vk)

    "L" and "R" for tile rotation

    "X" - delete tile

    ArrayList <DragMe> drags = new ArrayList <DragMe>();
    PImage imOne, imTwo, imThree, imFour;
    boolean justPressed = false;
    DragMe last, curr, temp, rot;
    int index;
    int l = 0;
    PVector[] sredista = new PVector[48];
    float angle;
    
    
    void setup() {
    
      imageMode(CENTER);
      rectMode(CENTER);
    
      size(800, 800);
      imOne = loadImage("https:"+"//dl.dropboxusercontent.com/u/70391886/icon0.png");
      imTwo = loadImage("https:"+"//dl.dropboxusercontent.com/u/70391886/icon1.png");
      imThree = loadImage("https:"+"//dl.dropboxusercontent.com/u/70391886/icon2.png");
      imFour = loadImage("https:"+"//dl.dropboxusercontent.com/u/70391886/icon3.png");
      find_center();
    }
    
    
    void draw() {
    
      background(51);
    
      noTint();
      image(imOne, 700, 100);
      image(imTwo, 700, 230);
      image(imThree, 700, 360);
      image(imFour, 700, 490);
    
      strokeWeight(1);
      for (int i = 0; i <= 800; i = i+100) {
        stroke(126);
        line(0, i, 600, i);
      }
      for (int j = 0; j <= 600; j = j+100) {
        //stroke(126);
        line(j, 0, j, 800);
      }
      if (drags.size() > 0) {
        for (DragMe d : drags) {
          d.display();
          d.update();
        }
      }
    
    }
    
    
    void mousePressed() {
    
      if (!justPressed && mouseX > 650 && mouseX < 650 + 100 && mouseY > 100 && mouseY < 100 + 100) {
        drags.add(new DragMe(imOne, mouseX, mouseY));
        justPressed = true;
      }
    
      if (!justPressed && mouseX > 650 && mouseX <  650 + 100 && mouseY > 0 && mouseY < 230 + 100) {
        drags.add(new DragMe(imTwo, mouseX, mouseY));
        justPressed = true;
      }
    
      if (!justPressed && mouseX > 650 && mouseX <  650 + 100 && mouseY > 0 && mouseY < 360 + 100) {
        drags.add(new DragMe(imThree, mouseX, mouseY));
        justPressed = true;
      }
    
      if (!justPressed && mouseX > 650 && mouseX <  650 + 100 && mouseY > 0 && mouseY < 490 + 100) {
        drags.add(new DragMe(imFour, mouseX, mouseY));
        justPressed = true;
      }
    
      for (int i=0; i<drags.size (); i++) {
        curr = drags.get(i);
        if (curr.isClicked()) {
          index = i;
          moveToTail(drags, index);
        }
      }
    
      for (int i=0; i<drags.size (); i++) {
        temp = drags.get(i);
        if (!temp.isOver() || (temp.isOver() && i != drags.size()-1)) {
          temp.dontMove = true;
        }
        temp.offset_x = mouseX - temp.pos_x;
        temp.offset_y = mouseY - temp.pos_y;
      }
    
    }
    
    
    void mouseReleased() {
    
      if (drags.size() > 0) {
        for (DragMe d : drags) { 
          d.locked = false;
          d.dontMove = false;
        }
      }
      justPressed = false;
    }
    
    
    static final ArrayList moveToTail(ArrayList l, int idx) {
    
      l.add(l.remove(idx));
      return l;
    }
    
    
    void keyPressed() {
    
      if (key == 'x') {
        if (drags.size() > 0) {
          drags.remove(drags.size()-1);
        }
      }
      if (key == 'c') {
        drags.clear();
      }
    
      if (key == 'l' || key == 'L') {
        angle = angle + HALF_PI;
        rot = drags.get(drags.size()-1);
        rot.angle1 = angle;
      }
      if (key == 'r'|| key == 'R') {
        angle = angle - HALF_PI;
        rot = drags.get(drags.size()-1);
        rot.angle1 = angle;
      }
    
    }
    
    
    void find_center() {
      for (int i1 = 50; i1 < 600; i1=i1+100) {
        for (int j1 = 50; j1 < 800; j1=j1+100) {
          sredista[l] = new PVector(i1, j1);
          l++;
        }
      }
    }
    
    
    class DragMe {
    
      float pos_x, pos_y, size;
      boolean locked;
      boolean dontMove;
      boolean sit;
      color c = color (0, 170, 170);
      float offset_x, offset_y;
      PImage img;
      float[] udaljenosti = new float[48];
      float angle1;
    
      DragMe(PImage _img, int p_x, int p_y) {
        img = _img;
        size = img.width;
        pos_x = p_x;
        pos_y = p_y;
      }
    
      void update() {
        if (isClicked()) {
          locked = true;
        }
        if (locked && !dontMove) {
          pos_x =  mouseX - offset_x;
          pos_y =  mouseY - offset_y;
          snap();
        }    
      }
    
      void display() {
        if (locked) {
          if(sit) {
            tint(210, 210, 15);
          }
          else {
            tint(210, 15, 15);
          }
        } else {
          noTint();
        }
    
        pushMatrix();
        translate(pos_x,pos_y);
        rotate(angle1);
        image(img, 0, 0);
        popMatrix(); 
      }
    
      boolean isOver() {
        float left_x = pos_x - size/2;
        float top_y = pos_y - size/2;
        return mouseX >= left_x && mouseX <= left_x + 100 && mouseY >= top_y && mouseY <= top_y + 100;
      }
    
      boolean isClicked() {
        return isOver() && mousePressed && !dontMove;
      }
    
      void snap() {
        for (int k = 0; k < 48; k++) {
          float[] f = sredista[k].array();
          udaljenosti[k] = dist(pos_x, pos_y, f[0], f[1]);
          if (udaljenosti[k] > 25) sit = false;
          if (udaljenosti[k] <= 25) {
            pos_x = f[0];
            pos_y = f[1];
            sit = true;
            break;
          }
        }
      }
    
    }
    
  • _vk_vk
    edited October 2015

    Cool!

    what about this? :)

     if (key == 'x') {
        if (drags.size() > 0) {
    
          // going backwards to avoid concurrent modification by removing things
          for (int i = drags.size()-1; i >=0; i--) {
            if ( drags.get(i).isOver()) {
              drags.remove(i);
            }
          }
        }
      }
    

    You should consider renaming DragMe and drags to something more meaningful.

    Also if the image is not 'snapped' and you release them (even if outside the grid) it will stay there. Shouldn't they be 'dropped' only if they are aslo 'snapped' ?

  • _vk_vk
    Answer ✓

    Another thought

    this:

      if (!justPressed && mouseX > 650 && mouseX < 650 + 100 && mouseY > 100 && mouseY < 100 + 100) {
        drags.add(new DragMe(imOne, mouseX, mouseY));
        justPressed = true;
      }
    
      if (!justPressed && mouseX > 650 && mouseX <  650 + 100 && mouseY > 0 && mouseY < 230 + 100) {
        drags.add(new DragMe(imTwo, mouseX, mouseY));
        justPressed = true;
      }
    
      if (!justPressed && mouseX > 650 && mouseX <  650 + 100 && mouseY > 0 && mouseY < 360 + 100) {
        drags.add(new DragMe(imThree, mouseX, mouseY));
        justPressed = true;
      }
    
      if (!justPressed && mouseX > 650 && mouseX <  650 + 100 && mouseY > 0 && mouseY < 490 + 100) {
        drags.add(new DragMe(imFour, mouseX, mouseY));
        justPressed = true;
      }
    

    When you repeat yourself a lot :) is aways a place to go OOP. A button class could make the code nicer...

    What's your favourite way to code a button?

  • _vk, this is just a trial version, of course, that there will be changes.. DragMe and drags terms are ok :)

    Thanks!

  • edited November 2015

    I have a problem now with exporting PGraphics with transparency and high-resolution (It's not in the center - scaleFactor1 and does not scale entire PGraphics object - scaleFactor2)

    scaleFactor = 1

    Big1

    scaleFactor = 2

    Big2

    ArrayList <DragMe> drags = new ArrayList <DragMe>();
    PImage imOne, imTwo, imThree, imFour;
    boolean justPressed = false;
    boolean move_control = false;
    DragMe last, curr, temp, rot;
    int index;
    int l = 0;
    PVector[] sredista = new PVector[48];
    float angle;
    final int scaleFactor = 2;
    
    
    void setup() {
    
      imageMode(CENTER);
      rectMode(CENTER);
    
      size(800, 800, JAVA2D);
      imOne = loadImage("https:"+"//dl.dropboxusercontent.com/u/70391886/icon0.png");
      imTwo = loadImage("https:"+"//dl.dropboxusercontent.com/u/70391886/icon1.png");
      imThree = loadImage("https:"+"//dl.dropboxusercontent.com/u/70391886/icon2.png");
      imFour = loadImage("https:"+"//dl.dropboxusercontent.com/u/70391886/icon3.png");
      find_center();
    }
    
    
    void draw() {
    
      background(51);
    
      noTint();
      image(imOne, 700, 100);
      image(imTwo, 700, 230);
      image(imThree, 700, 360);
      image(imFour, 700, 490);
    
      strokeWeight(1);
      for (int i = 0; i <= 800; i = i+100) {
        stroke(126);
        line(0, i, 600, i);
      }
      for (int j = 0; j <= 600; j = j+100) {
        //stroke(126);
        line(j, 0, j, 800);
      }
    
      if (drags.size() > 0) {
        for (DragMe d : drags) {
          //d.display();
          d.drawOn(g);
          d.update();
        }
      }
    
      //drawOn(g);
    }
    
    
    void mousePressed() {
    
      if (mouseButton == LEFT && !move_control) {
        if (!justPressed && mouseX > 650 && mouseX < 650 + 100 && mouseY > 100 && mouseY < 100 + 100) {
          drags.add(new DragMe(imOne, mouseX, mouseY));
          justPressed = true;
        }
    
        if (!justPressed && mouseX > 650 && mouseX <  650 + 100 && mouseY > 0 && mouseY < 230 + 100) {
          drags.add(new DragMe(imTwo, mouseX, mouseY));
          justPressed = true;
        }
    
        if (!justPressed && mouseX > 650 && mouseX <  650 + 100 && mouseY > 0 && mouseY < 360 + 100) {
          drags.add(new DragMe(imThree, mouseX, mouseY));
          justPressed = true;
        }
    
        if (!justPressed && mouseX > 650 && mouseX <  650 + 100 && mouseY > 0 && mouseY < 490 + 100) {
          drags.add(new DragMe(imFour, mouseX, mouseY));
          justPressed = true;
        }
    
        for (int i=0; i<drags.size (); i++) {
          curr = drags.get(i);
          if (curr.isClicked()) {
            index = i;
            moveToTail(drags, index);
          }
        }
    
        for (int i=0; i<drags.size (); i++) {
          temp = drags.get(i);
          if (!temp.isOver() || (temp.isOver() && i != drags.size()-1)) {
            temp.dontMove = true;
          }
          temp.offset_x = mouseX - temp.pos_x;
          temp.offset_y = mouseY - temp.pos_y;
        }
      }  // END if (mouseButton == LEFT && !move_control)
    
      if (mouseButton == LEFT && move_control) {
        for (int i=0; i<drags.size (); i++) {
          temp = drags.get(i);
          if (temp.locked) {
            temp.dontMove = false;
          }
          if (!temp.locked) {
            temp.dontMove = true;
          }
          temp.offset_x = mouseX - temp.pos_x;
          temp.offset_y = mouseY - temp.pos_y;
        }
      }  // END if (mouseButton == LEFT && move_control)
    
      if (mouseButton == RIGHT && !move_control ) {
        if (drags.size() > 0) {
          for (DragMe d : drags) {
            if (d.isOver() == true) {
              d.locked = false;
              d.dontMove = true;
            }
          }
        }
      }
    
      if (mouseButton == RIGHT && move_control ) {
        if (drags.size() > 0) {
          for (DragMe d : drags) {
            if (d.isOver() == true) {
              d.locked = !d.locked;
              d.dontMove = true;
            }
          }
        }
      }
    }
    
    
    void mouseReleased() {
      if (mouseButton == LEFT) {
        if (drags.size() > 0) {
          for (DragMe d : drags) {
            d.locked = false;
            d.dontMove = false;
          }
        }
        justPressed = false;
      }
    }
    
    
    static final ArrayList moveToTail(ArrayList l, int idx) {
    
      l.add(l.remove(idx));
      return l;
    }
    
    
    void keyPressed() {
    
      if (key == 'x') {
        if (drags.size() > 0) {
          drags.remove(drags.size()-1);
        }
      }
      if (key == 'c') {
        drags.clear();
      }
    
      if (key == 'l' || key == 'L') {
        angle = angle + HALF_PI;
        rot = drags.get(drags.size()-1);
        rot.angle1 = angle;
      }
      if (key == 'r'|| key == 'R') {
        angle = angle - HALF_PI;
        rot = drags.get(drags.size()-1);
        rot.angle1 = angle;
      }
    
      if (key == 's')
      {
        PGraphics drawingSurface = createGraphics(600 * scaleFactor, 800 * scaleFactor, JAVA2D);
        drawingSurface.beginDraw();
        drawingSurface.smooth();
        drawingSurface.scale(scaleFactor);
        for (DragMe d : drags) {
          d.drawOn(drawingSurface);
        }
        //drawOn(drawingSurface);
        drawingSurface.endDraw();
        drawingSurface.stroke(0);
        drawingSurface.strokeWeight(10);
        drawingSurface.noFill();
        drawingSurface.rect(0, 0, 600 * scaleFactor, 800 * scaleFactor);
        drawingSurface.save("Big.png");
      }
    
      if (key == 't') {
        move_control = !move_control;
      }
    }
    
    
    void find_center() {
      for (int i1 = 50; i1 < 600; i1=i1+100) {
        for (int j1 = 50; j1 < 800; j1=j1+100) {
          sredista[l] = new PVector(i1, j1);
          l++;
        }
      }
    }
    
    
    class DragMe {
    
      float pos_x, pos_y, size;
      boolean locked;
      boolean dontMove;
      boolean sit;
      color c = color (0, 170, 170);
      float offset_x, offset_y;
      PImage img;
      float[] udaljenosti = new float[48];
      float angle1;
    
      DragMe(PImage _img, int p_x, int p_y) {
        img = _img;
        size = img.width;
        pos_x = p_x;
        pos_y = p_y;
      }
    
      void update() {
        if (isClicked()) {
          locked = true;
        }
        if (locked && !dontMove) {
          pos_x =  mouseX - offset_x;
          pos_y =  mouseY - offset_y;
          snap();
        }
      }
    
      void drawOn(PGraphics surface) {
    
        if (locked) {
          if (sit) {
            tint(210, 210, 15);
          } else {
            tint(210, 15, 15);
          }
        } else {
          noTint();
        }
    
        surface.beginDraw();
        surface.pushMatrix();
        surface.translate(pos_x, pos_y);
        //surface.translate(300, 400);
        surface.rotate(angle1);
        //surface.translate(-300, -400);
        //surface.image(img, pos_x, pos_y);
        surface.image(img, 0, 0);
        surface.popMatrix();
        surface.endDraw();
      }
    
      boolean isOver() {
        float left_x = pos_x - size/2;
        float top_y = pos_y - size/2;
        return mouseX >= left_x && mouseX <= left_x + 100 && mouseY >= top_y && mouseY <= top_y + 100;
      }
    
      boolean isClicked() {
        return isOver() && mousePressed && !dontMove;
      }
    
      void snap() {
        for (int k = 0; k < 48; k++) {
          float[] f = sredista[k].array();
          udaljenosti[k] = dist(pos_x, pos_y, f[0], f[1]);
          if (udaljenosti[k] > 25) sit = false;
          if (udaljenosti[k] <= 25) {
            pos_x = f[0];
            pos_y = f[1];
            sit = true;
            break;
          }
        }
      }
    }
    
  • edited November 2015

    Here is the solution:

    ArrayList <DragMe> drags = new ArrayList <DragMe>();
    PImage imOne, imTwo, imThree, imFour;
    boolean justPressed = false;
    boolean move_control = false;
    DragMe last, curr, temp, rot;
    int index;
    int l = 0;
    PVector[] sredista = new PVector[48];
    float angle;
    final int scaleFactor = 3;
    
    
    void setup() {
    
      imageMode(CENTER);
      rectMode(CENTER);
    
      size(800, 800, JAVA2D);
      imOne = loadImage("https:"+"//dl.dropboxusercontent.com/u/70391886/icon0.png");
      imTwo = loadImage("https:"+"//dl.dropboxusercontent.com/u/70391886/icon1.png");
      imThree = loadImage("https:"+"//dl.dropboxusercontent.com/u/70391886/icon2.png");
      imFour = loadImage("https:"+"//dl.dropboxusercontent.com/u/70391886/icon3.png");
      find_center();
    }
    
    
    void draw() {
    
      background(51);
    
      noTint();
      image(imOne, 700, 100);
      image(imTwo, 700, 230);
      image(imThree, 700, 360);
      image(imFour, 700, 490);
    
      strokeWeight(1);
      for (int i = 0; i <= 800; i = i+100) {
        stroke(126);
        line(0, i, 600, i);
      }
      for (int j = 0; j <= 600; j = j+100) {
        line(j, 0, j, 800);
      }
    
      if (drags.size() > 0) {
        for (DragMe d : drags) {
          d.drawOn(g);
          d.update();
        }
      }
    
    }
    
    
    void mousePressed() {
    
      if (mouseButton == LEFT && !move_control) {
        if (!justPressed && mouseX > 650 && mouseX < 650 + 100 && mouseY > 100 && mouseY < 100 + 100) {
          drags.add(new DragMe(imOne, mouseX, mouseY));
          justPressed = true;
        }
    
        if (!justPressed && mouseX > 650 && mouseX <  650 + 100 && mouseY > 0 && mouseY < 230 + 100) {
          drags.add(new DragMe(imTwo, mouseX, mouseY));
          justPressed = true;
        }
    
        if (!justPressed && mouseX > 650 && mouseX <  650 + 100 && mouseY > 0 && mouseY < 360 + 100) {
          drags.add(new DragMe(imThree, mouseX, mouseY));
          justPressed = true;
        }
    
        if (!justPressed && mouseX > 650 && mouseX <  650 + 100 && mouseY > 0 && mouseY < 490 + 100) {
          drags.add(new DragMe(imFour, mouseX, mouseY));
          justPressed = true;
        }
    
        for (int i=0; i<drags.size (); i++) {
          curr = drags.get(i);
          if (curr.isClicked()) {
            index = i;
            moveToTail(drags, index);
          }
        }
    
        for (int i=0; i<drags.size (); i++) {
          temp = drags.get(i);
          if (!temp.isOver() || (temp.isOver() && i != drags.size()-1)) {
            temp.dontMove = true;
          }
          temp.offset_x = mouseX - temp.pos_x;
          temp.offset_y = mouseY - temp.pos_y;
        }
      }  // END if (mouseButton == LEFT && !move_control)
    
      if (mouseButton == LEFT && move_control) {
        for (int i=0; i<drags.size (); i++) {
          temp = drags.get(i);
          if (temp.locked) {
            temp.dontMove = false;
          }
          if (!temp.locked) {
            temp.dontMove = true;
          }
          temp.offset_x = mouseX - temp.pos_x;
          temp.offset_y = mouseY - temp.pos_y;
        }
      }  // END if (mouseButton == LEFT && move_control)
    
      if (mouseButton == RIGHT && !move_control ) {
        if (drags.size() > 0) {
          for (DragMe d : drags) {
            if (d.isOver() == true) {
              d.locked = false;
              d.dontMove = true;
            }
          }
        }
      }
    
      if (mouseButton == RIGHT && move_control ) {
        if (drags.size() > 0) {
          for (DragMe d : drags) {
            if (d.isOver() == true) {
              d.locked = !d.locked;
              d.dontMove = true;
            }
          }
        }
      }
    }
    
    
    void mouseReleased() {
      if (mouseButton == LEFT) {
        if (drags.size() > 0) {
          for (DragMe d : drags) {
            d.locked = false;
            d.dontMove = false;
          }
        }
        justPressed = false;
      }
    }
    
    
    static final ArrayList moveToTail(ArrayList l, int idx) {
    
      l.add(l.remove(idx));
      return l;
    }
    
    
    void keyPressed() {
    
      if (key == 'x') {
        if (drags.size() > 0) {
          drags.remove(drags.size()-1);
        }
      }
      if (key == 'c') {
        drags.clear();
      }
    
      if (key == 'l' || key == 'L') {
        angle = angle + HALF_PI;
        rot = drags.get(drags.size()-1);
        rot.angle1 = angle;
      }
      if (key == 'r'|| key == 'R') {
        angle = angle - HALF_PI;
        rot = drags.get(drags.size()-1);
        rot.angle1 = angle;
      }
    
      if (key == 's')
      {
        PGraphics drawingSurface = createGraphics(600 * scaleFactor, 800 * scaleFactor, JAVA2D);
        drawingSurface.beginDraw();
        drawingSurface.smooth();
        drawingSurface.scale(scaleFactor);
        drawingSurface.imageMode(CENTER);
        for (DragMe d : drags) {
          d.drawOn(drawingSurface);
        }
        drawingSurface.stroke(0);
        drawingSurface.strokeWeight(15);
        drawingSurface.noFill();
        drawingSurface.rect(0, 0, 600, 800);
        drawingSurface.endDraw();
        drawingSurface.save("Big.png");
      }
    
      if (key == 't') {
        move_control = !move_control;
      }
    }
    
    
    void find_center() {
      for (int i1 = 50; i1 < 600; i1=i1+100) {
        for (int j1 = 50; j1 < 800; j1=j1+100) {
          sredista[l] = new PVector(i1, j1);
          l++;
        }
      }
    }
    
    
    class DragMe {
    
      float pos_x, pos_y, size;
      boolean locked;
      boolean dontMove;
      boolean sit;
      color c = color (0, 170, 170);
      float offset_x, offset_y;
      PImage img;
      float[] udaljenosti = new float[48];
      float angle1;
    
      DragMe(PImage _img, int p_x, int p_y) {
        img = _img;
        size = img.width;
        pos_x = p_x;
        pos_y = p_y;
      }
    
      void update() {
        if (isClicked()) {
          locked = true;
        }
        if (locked && !dontMove) {
          pos_x =  mouseX - offset_x;
          pos_y =  mouseY - offset_y;
          snap();
        }
      }
    
      void drawOn(PGraphics surface) {
    
        if (locked) {
          if (sit) {
            tint(210, 210, 15);
          } else {
            tint(210, 15, 15);
          }
        } else {
          noTint();
        }
    
        surface.pushMatrix();
        surface.translate(pos_x, pos_y);
        surface.rotate(angle1);
        surface.image(img, 0, 0);
        surface.popMatrix();
      }
    
      boolean isOver() {
        float left_x = pos_x - size/2;
        float top_y = pos_y - size/2;
        return mouseX >= left_x && mouseX <= left_x + 100 && mouseY >= top_y && mouseY <= top_y + 100;
      }
    
      boolean isClicked() {
        return isOver() && mousePressed && !dontMove;
      }
    
      void snap() {
        for (int k = 0; k < 48; k++) {
          float[] f = sredista[k].array();
          udaljenosti[k] = dist(pos_x, pos_y, f[0], f[1]);
          if (udaljenosti[k] > 25) sit = false;
          if (udaljenosti[k] <= 25) {
            pos_x = f[0];
            pos_y = f[1];
            sit = true;
            break;
          }
        }
      }
    }
    
Sign In or Register to comment.