FYI, here's what I've got so far. Just mocked up; it will need to be streamlined a bit, especially since my end-goal is to have a whole array of these drag-able objects, but it's a start:
**NOTE: Updated since original posting:
Code:
PFont fontA;
PFont fontB;
grid grid1;
clickRect[] items = new clickRect[1];
void setup()
{
size(600,400); smooth();
fontA = loadFont("HelveticaNeue-Bold-48.vlw");
fontB = loadFont("HelveticaNeue-12.vlw");
textFont(fontB, 12);
grid1 = new grid(0,0,width-10,height-10);
items[0] = new clickRect(100, 150, 200, 100,32);
}
void draw()
{
background(255);
translate(width/2, height/2);
grid1.display();
for(int i=0; i<items.length; i++){
items[i].display();
}
}
void mousePressed()
{
for(int i=0; i<items.length; i++){
if(items[i].bounds(mouseX,mouseY)) {
items[i].lock();
}
}
}
void mouseDragged()
{
for(int i=0; i<items.length; i++){
if(items[i].hover) {
items[i].update(mouseX,mouseY);
}
}
}
void mouseReleased()
{
for(int i=0; i<items.length; i++){
items[i].unlock();
}
}
class grid {
float x;
float y;
float w;
float h;
grid(float xi,float yi,float wi,float hi) {
x = xi;
y = yi;
w = wi;
h = hi;
}
void display() {
rectMode(CENTER); stroke(150); noFill(); strokeWeight(1);
rect(x,y,w,h);
for(int i=0; i<=5; i++) {
stroke(245);
if(i==0) stroke(#ffb0b0);
line(x+(i*w/10), y-h/2, x+(i*w/10), y+h/2);
if(i!=0) line(x-(i*w/10), y-h/2, x-(i*w/10), y+h/2);
if(i==0) stroke(#b5ffbe);
line( x-w/2, y+(i*h/10), x+w/2, y+(i*h/10) );
if(i!=0) line(x-w/2, y-(i*h/10), x+w/2, y-(i*h/10));
}
}
}
class clickRect {
float mouseX1 = 0;
float mouseY1 = 0;
float x, y; // center X, center Y
float w, h; // width, height
float a; // angle (counter-clockwise from horiz)
float[] c = new float[8]; // will contain (x,y) for all four points
boolean locked = false;
boolean hover = false;
clickRect(float xi, float yi, float wi, float hi,float ai) {
x = xi; y = yi;
w = wi; h = hi;
a = radians(ai);
findCorners();
}
void display() {
if(bounds(mouseX,mouseY)) { fill(#ffe030,20); hover = true; } else { fill(0,20); hover = false; }
stroke(0); strokeWeight(2); rectMode(CENTER);
pushMatrix();
transform(); // move the object center into place
rect(0,0,w,h);
popMatrix();
}
void update(float xi, float yi) {
if(locked) {
xi = xi - mouseX1; yi = yi - mouseY1;
x = x + xi;
y = y - yi;
findCorners();
mouseX1 = mouseX; mouseY1 = mouseY;
}
}
void transform() {
translate(x,-y); rotate(a);
}
void findCorners() {
c[0] = -w/2; /* top-left X */ c[1] = -h/2; /* top-left Y */
c[2] = w/2; /* top-right X */ c[3] = -h/2; /* top-right Y */
c[4] = w/2; /* bottom-right X */ c[5] = h/2; /* bottom-right Y */
c[6] = w/2; /* bottom-left X */ c[7] = -h/2; /* bottom-left Y */
}
boolean bounds(float xi, float yi) {
pushMatrix();
transform(); // we'll be reversing the transforms manually for the mouse coordinates
// find out pixel coordinates of translated object center
float x2 = screenX(0,0);
float y2 = screenY(0,0);
popMatrix();
// input coordinates must be translated and rotated to match object coordinate system:
// see http://en.wikipedia.org/wiki/Rotation_(mathematics)
float xj = (xi-x2)*cos(-a) - (yi-y2)*sin(-a); // based on x' = x * cos(a) - y * sin(a)
float yj = (xi-x2)*sin(-a) + (yi-y2)*cos(-a); // based on y' = x * sing(a) + y * cos(a)
// since inputs are now oriented to object, it's easy to find out if input is inside the bounding box
if( xj < c[2] && xj > c[0] && yj > c[1] && yj < c[5]) return true;
else return false;
}
void lock() { locked = true; mouseX1 = mouseX; mouseY1 = mouseY; }
void unlock() { locked = false; }
}