0

I am trying to design something in processing for a university experiment. I need people to be able to drag images and place them on a map. I was able to create the layout of my program and can load in the png files in a specific place within the window and I have place the map where I want in the window to. I found some approach to dragging images and it was ok but it broke and was not efficient. I came across the "dragging objects in processing" question on this website(found here: dragging objects in processing). Mike 'Pomax' Kamermans' code is really efficient and I was able to incorporate my current code with his so that I almost have what I want. The issue is that I am dragging stings. I have tried to adapt the code so that I can load in and drag images instead but it is beyond my level of knowledge. I do think that his approach to redrawing is the way to go. I also tried to find a method of replacing each string with an images but failed.

// adapted from Mike 'Pomax' Kamermans' code https://stackoverflow.com/questions/15305722/dragging-objects-in-processing
PImage wheel;
LineCollection lines;
float textSize;


void setup(){
  size(displayWidth, displayHeight);

  wheel = loadImage("wheel.png");

  // fix the text size, reference a real font
  textSize = 32; 
  textFont(createFont("Times New Roman", textSize));
  // parse strings, construct Lines container
  String[] textValues = new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", 
  "11", "12", "13", "14", "15", "16", "17", "18", "19"};
  lines = new LineCollection(textValues);
  // Do not loop! only update when events warrant,
  // based on redraw() calls  


  noLoop();
}
// fall through drawing
void draw() {
  background(255);
  image(wheel, ((displayWidth/2) - ((displayWidth * 0.4167)/2)), 0, (displayWidth * 0.4167), (displayWidth * 0.4167));

  stroke(0, 0, 0, 0); 
  fill(210, 210, 210);
  rect(0, (displayHeight*0.75), displayWidth, displayHeight);

  lines.draw(); 

}

// fall through event handling
void mouseMoved() { lines.mouseMoved(mouseX,mouseY); redraw(); }
void mousePressed() { lines.mousePressed(mouseX,mouseY); redraw(); }
void mouseDragged() { lines.mouseDragged(mouseX,mouseY); redraw(); }
void mouseReleased() { lines.mouseReleased(mouseX,mouseY); redraw(); }


/**
 * A collection of lines. This is *only* a collecton,
 * it is simply responsible for passing along events.
 */
class LineCollection {
  Line[] lines;
  int boundaryOverlap = 20;

  // construct
  LineCollection(String[] strings){
    lines = new Line[strings.length];
    int x, y;
    for(int i=0, last=strings.length; i<last; i++) {
      x = (int) (((displayWidth/20) * i) + 10);
      y = (int) ((displayHeight*0.85)-10);
      lines[i] = new Line(strings[i], x, y);   
    }
  }

  // fall through drawing   
  void draw() {

    // since we don't care about counting elements
    // in our "lines" container, we use the "foreach"
    // version of the for loop. This is identical to
    // "for(int i=0; i<lines.size(); i++) {
    //    Line l = lines[i];
    //    [... use l here ...]
    //  }"
    // except we don't have to unpack our list manually.

    for(Line l: lines) { l.draw(); }
  }

  // fall through event handling
  void mouseMoved(int mx, int my) { for(Line l: lines) { l.mouseMoved(mx,my); }} 
  void mousePressed(int mx, int my) { for(Line l: lines) { l.mousePressed(mx,my); }} 
  void mouseDragged(int mx, int my) { for(Line l: lines) { l.mouseDragged(mx,my); }}
  void mouseReleased(int mx, int my) { for(Line l: lines) { l.mouseReleased(mx,my); }}
}

/**
 * Individual lines
 */
class Line {
  String s;
  float x, y, w, h;
  boolean active;
  color fillColor = 0;
  int cx, cy, ox=0, oy=0;

  public Line(String _s, int _x, int _y) {
    s = _s;
    x = _x;
    y = _y;
    w = textWidth(s);
    h = textSize;
  }

  void draw() {
    fill(fillColor);
    text(s,ox+x,oy+y+h);
  }

  boolean over(int mx, int my) {
    return (x <= mx && mx <= x+w && y <= my && my <= y+h);
  }

  // Mouse moved: is the cursor over this line?
  // if so, change the fill color
  void mouseMoved(int mx, int my) {
    active = over(mx,my);
    fillColor = (active ? color(155,155,0) : 0);
  }

  // Mouse pressed: are we active? then
  // mark where we started clicking, so 
  // we can do offset computation on
  // mouse dragging.
  void mousePressed(int mx, int my) {
    if(active) {
      cx = mx;
      cy = my;
      ox = 0;
      oy = 0; 
    }
  }

  // Mouse click-dragged: if we're active,
  // change the draw offset, based on the
  // distance between where we initially
  // clicked, and where the mouse is now.
  void mouseDragged(int mx, int my) {
    if(active) {
      ox = mx-cx;
      oy = my-cy;
    }
  }

  // Mouse released: if we're active,
  // commit the offset to this line's
  // position. Also, regardless of
  // whether we're active, now we're not.  
  void mouseReleased(int mx, int my) {
    if(active) {
      x += mx-cx;
      y += my-cy;
      ox = 0;
      oy = 0;
    }
    active = false;
  }
}

Any help would be greatly appreciated.

Community
  • 1
  • 1
user69247
  • 15
  • 3

1 Answers1

0

The best advice I can give you is to stop trying to hamfist code you find on the internet into doing what you want. Even if the code is great, you need to understand what it's doing before you use it.

Take a step back and ask yourself how you would accomplish this yourself.

If all you want to do is drag a rectangular area (like an image), then you simply need to determine when the mouse is inside that area, then use the pmouseX and pmouseY variables to figure out how much to move that area. Something like this:

float squareX = 200;
float squareY = 200;
float squareWidth = 50;
float squareHeight = 50;

//keep track of when the mouse is inside the square
boolean mouseInSquare = false;

void setup() {
  size(500, 500);
}

//check if the mouse is in the square
void mousePressed() {
  if (mouseX > squareX && mouseX < squareX + squareWidth && mouseY > squareY && mouseY < squareY + squareHeight) {
    mouseInSquare = true;
  }
}

//if the mouse is in the square, then move it when the mouse is dragged
void mouseDragged() {
  if (mouseInSquare) {
    float deltaX = mouseX - pmouseX;
    float deltaY = mouseY - pmouseY;

    squareX += deltaX;
    squareY += deltaY;
  }
}

//when we let go of the mouse, stop dragging the square
void mouseReleased() {
  mouseInSquare = false;
}

//draw the square
void draw() {
  background(0);
  rect(squareX, squareY, squareWidth, squareHeight);
}
Kevin Workman
  • 41,537
  • 9
  • 68
  • 107
  • Thanks. I made so much progress with Processing before incorporating other code and was successful. You are correct that I should try to take a step back and think of the problem some more. I will have another go at it myself. – user69247 Jul 16 '15 at 17:20
  • @user69247 The example I posted does 90% of the work. You just have to draw an image instead of a square. – Kevin Workman Jul 16 '15 at 17:25
  • yeah I got it to work. Just trying to build on it now so I can have more than one image. Thanks again. – user69247 Jul 16 '15 at 18:10