Try this Drag Handle Example Code
in
Share your Work
•
1 year ago
I couldn't find any example code that supports 8 point drag handles. So I wrote some. I'm not sure what the process is to get code into
Examples. I think this would be a good addition, though it is a bit more complicated than most.
The Example contains 2 classes:
1. DragHandles - which contain 8 Drag handles: 4 corner handles, and 4 edge handles.
2. DragHandle
This is rudementary. Fixed size handles, Fixed color handles. Support Edge drag restricted mobility, and dynamic repositioning of sibling handles during drag.
Code style issues:
I am not a seasoned Java programmer and thus my naming conventions I expect are a bit sloppy. I also prefer newline {'s so they align visually. Old habits die hard, a remant of the '70's C coding. I don't want to start a religious war over it.
Comments welcome. Please feel fee to point out opportunities for improvement.
The example draws an ellipse and square and permits resize via drag. I pasted all 3 modules in as a single file. (I tired the insert code mode and the line numbering was strange). Here is the code:
int frameWidth = 600;
int frameHeight = 500;
int frameHeight = 500;
int xs[];
int ys[];
int widths[];
int heights[];
boolean captured;
DragHandles dragHandles[];
int ys[];
int widths[];
int heights[];
boolean captured;
DragHandles dragHandles[];
void setup()
{
int i;
captured = false;
size(frameWidth, frameHeight);
background(210);
widths = new int[4];
heights = new int[4];
xs = new int[4];
ys = new int[4];
dragHandles = new DragHandles[3];
i = 0;
xs[i] = 200;
ys[i] = 100;
widths[i] = 200;
heights[i] = 300;
dragHandles[i] = new DragHandles(xs[i],
ys[i],widths[i],
heights[i]);
dragHandles[i].setDraggable(true);
i++;
xs[i] = 50;
ys[i] = 150;
widths[i] = 80;
heights[i] = 180;
dragHandles[i] = new DragHandles(xs[i],
ys[i],widths[i],
heights[i]);
dragHandles[i].setDraggable(true);
{
int i;
captured = false;
size(frameWidth, frameHeight);
background(210);
widths = new int[4];
heights = new int[4];
xs = new int[4];
ys = new int[4];
dragHandles = new DragHandles[3];
i = 0;
xs[i] = 200;
ys[i] = 100;
widths[i] = 200;
heights[i] = 300;
dragHandles[i] = new DragHandles(xs[i],
ys[i],widths[i],
heights[i]);
dragHandles[i].setDraggable(true);
i++;
xs[i] = 50;
ys[i] = 150;
widths[i] = 80;
heights[i] = 180;
dragHandles[i] = new DragHandles(xs[i],
ys[i],widths[i],
heights[i]);
dragHandles[i].setDraggable(true);
}
void draw()
{
int i;
i = 0;
background(210);
fill(color(255,128,128));
rect(xs[i],ys[i],widths[i],heights[i]);
dragHandles[i].display();
xs[i] = dragHandles[i].getX();
ys[i] = dragHandles[i].getY();
widths[i] = dragHandles[i].getWidth();
heights[i] = dragHandles[i].getHeight();
i++;
{
int i;
i = 0;
background(210);
fill(color(255,128,128));
rect(xs[i],ys[i],widths[i],heights[i]);
dragHandles[i].display();
xs[i] = dragHandles[i].getX();
ys[i] = dragHandles[i].getY();
widths[i] = dragHandles[i].getWidth();
heights[i] = dragHandles[i].getHeight();
i++;
fill(128,255,128);
ellipseMode(CORNER);
ellipse(xs[i],ys[i],widths[i],heights[i]);
dragHandles[i].display();
xs[i] = dragHandles[i].getX();
ys[i] = dragHandles[i].getY();
widths[i] = dragHandles[i].getWidth();
heights[i] = dragHandles[i].getHeight();
i++;
}
ellipseMode(CORNER);
ellipse(xs[i],ys[i],widths[i],heights[i]);
dragHandles[i].display();
xs[i] = dragHandles[i].getX();
ys[i] = dragHandles[i].getY();
widths[i] = dragHandles[i].getWidth();
heights[i] = dragHandles[i].getHeight();
i++;
}
//======================================
class DragHandles
{
// final String handleNames[] = {"NW","NE","SE","SW"," W"," N"," E"," S"};
final static int HANDLE_OFFSET = 8;
final static float HANDLE_MULT = 1;
final static int NORTHWEST_CORNER = 0;
final static int NORTHEAST_CORNER = 1;
final static int SOUTHEAST_CORNER = 2;
final static int SOUTHWEST_CORNER = 3;
final static int WEST_EDGE = 4;
final static int NORTH_EDGE = 5;
final static int EAST_EDGE = 6;
final static int SOUTH_EDGE = 7;
int x;
int y;
int width;
int height;
DragHandle handles[];
int adj;
DragHandles(int x, int y, int width,int height)
{
int i;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
handles = new DragHandle[8];
//
// corners
//
i = NORTHWEST_CORNER;
handles[i] = new DragHandle(i,DragHandle.FULLY_MOBILE,x-HANDLE_OFFSET/2,
y-HANDLE_OFFSET/2,
HANDLE_OFFSET,HANDLE_OFFSET);
i = NORTHEAST_CORNER;
handles[i] = new DragHandle(i,DragHandle.FULLY_MOBILE,x+width-HANDLE_OFFSET/2,
y-HANDLE_OFFSET/2,
HANDLE_OFFSET,HANDLE_OFFSET);
i = SOUTHEAST_CORNER;
handles[i] = new DragHandle(i,DragHandle.FULLY_MOBILE,x+width-HANDLE_OFFSET/2,
y+height-HANDLE_OFFSET/2,
HANDLE_OFFSET,HANDLE_OFFSET);
i = SOUTHWEST_CORNER;
handles[i] = new DragHandle(i,DragHandle.FULLY_MOBILE,x-HANDLE_OFFSET/2,
y+height-HANDLE_OFFSET/2,
HANDLE_OFFSET,HANDLE_OFFSET);
//
// edges
//
i = WEST_EDGE;
handles[i] = new DragHandle(i,DragHandle.VERTICAL_MOBILE,x-HANDLE_OFFSET/2,
y+height/2-(int)(HANDLE_MULT*HANDLE_OFFSET)/2,
HANDLE_OFFSET,(int)(HANDLE_MULT*HANDLE_OFFSET));
i = EAST_EDGE;
handles[i] = new DragHandle(i,DragHandle.VERTICAL_MOBILE,x+width-HANDLE_OFFSET/2,
y+height/2-(int)(HANDLE_MULT*HANDLE_OFFSET)/2,
HANDLE_OFFSET,(int)(HANDLE_MULT*HANDLE_OFFSET));
i = NORTH_EDGE;
handles[i] = new DragHandle(i,DragHandle.HORIZONTAL_MOBILE,x+width/2-(int)(HANDLE_MULT*HANDLE_OFFSET)/2,
y-HANDLE_OFFSET/2,
(int)(HANDLE_MULT*HANDLE_OFFSET),HANDLE_OFFSET);
i = SOUTH_EDGE;
handles[i] = new DragHandle(i,DragHandle.HORIZONTAL_MOBILE,x+width/2-(int)(HANDLE_MULT*HANDLE_OFFSET)/2,
y+height-HANDLE_OFFSET/2,
(int)(HANDLE_MULT*HANDLE_OFFSET),HANDLE_OFFSET);
}
{
// final String handleNames[] = {"NW","NE","SE","SW"," W"," N"," E"," S"};
final static int HANDLE_OFFSET = 8;
final static float HANDLE_MULT = 1;
final static int NORTHWEST_CORNER = 0;
final static int NORTHEAST_CORNER = 1;
final static int SOUTHEAST_CORNER = 2;
final static int SOUTHWEST_CORNER = 3;
final static int WEST_EDGE = 4;
final static int NORTH_EDGE = 5;
final static int EAST_EDGE = 6;
final static int SOUTH_EDGE = 7;
int x;
int y;
int width;
int height;
DragHandle handles[];
int adj;
DragHandles(int x, int y, int width,int height)
{
int i;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
handles = new DragHandle[8];
//
// corners
//
i = NORTHWEST_CORNER;
handles[i] = new DragHandle(i,DragHandle.FULLY_MOBILE,x-HANDLE_OFFSET/2,
y-HANDLE_OFFSET/2,
HANDLE_OFFSET,HANDLE_OFFSET);
i = NORTHEAST_CORNER;
handles[i] = new DragHandle(i,DragHandle.FULLY_MOBILE,x+width-HANDLE_OFFSET/2,
y-HANDLE_OFFSET/2,
HANDLE_OFFSET,HANDLE_OFFSET);
i = SOUTHEAST_CORNER;
handles[i] = new DragHandle(i,DragHandle.FULLY_MOBILE,x+width-HANDLE_OFFSET/2,
y+height-HANDLE_OFFSET/2,
HANDLE_OFFSET,HANDLE_OFFSET);
i = SOUTHWEST_CORNER;
handles[i] = new DragHandle(i,DragHandle.FULLY_MOBILE,x-HANDLE_OFFSET/2,
y+height-HANDLE_OFFSET/2,
HANDLE_OFFSET,HANDLE_OFFSET);
//
// edges
//
i = WEST_EDGE;
handles[i] = new DragHandle(i,DragHandle.VERTICAL_MOBILE,x-HANDLE_OFFSET/2,
y+height/2-(int)(HANDLE_MULT*HANDLE_OFFSET)/2,
HANDLE_OFFSET,(int)(HANDLE_MULT*HANDLE_OFFSET));
i = EAST_EDGE;
handles[i] = new DragHandle(i,DragHandle.VERTICAL_MOBILE,x+width-HANDLE_OFFSET/2,
y+height/2-(int)(HANDLE_MULT*HANDLE_OFFSET)/2,
HANDLE_OFFSET,(int)(HANDLE_MULT*HANDLE_OFFSET));
i = NORTH_EDGE;
handles[i] = new DragHandle(i,DragHandle.HORIZONTAL_MOBILE,x+width/2-(int)(HANDLE_MULT*HANDLE_OFFSET)/2,
y-HANDLE_OFFSET/2,
(int)(HANDLE_MULT*HANDLE_OFFSET),HANDLE_OFFSET);
i = SOUTH_EDGE;
handles[i] = new DragHandle(i,DragHandle.HORIZONTAL_MOBILE,x+width/2-(int)(HANDLE_MULT*HANDLE_OFFSET)/2,
y+height-HANDLE_OFFSET/2,
(int)(HANDLE_MULT*HANDLE_OFFSET),HANDLE_OFFSET);
}
void display()
{
int deltay;
int deltax;
int i;
int adj;
for(i=0;i<8;i++)
{
deltax = -1*(handles[i].origx - handles[i].x);
deltay = -1*(handles[i].origy - handles[i].y);
switch(i)
{
case NORTHWEST_CORNER:
if(deltay != 0 || deltax != 0)
{
handles[NORTHWEST_CORNER].adjust(0,0);
handles[WEST_EDGE].adjust(deltax,0);
handles[NORTH_EDGE].adjust(0,deltay);
handles[NORTHEAST_CORNER].adjust(0,deltay);
handles[SOUTHWEST_CORNER].adjust(deltax,0);
fixEdges();
}
break;
case NORTHEAST_CORNER:
if(deltay != 0 || deltax != 0)
{
handles[NORTHEAST_CORNER].adjust(0,0);
handles[EAST_EDGE].adjust(deltax,0);
handles[NORTH_EDGE].adjust(0,deltay);
handles[SOUTHEAST_CORNER].adjust(deltax,0);
handles[NORTHWEST_CORNER].adjust(0,deltay);
fixEdges();
}
break;
case SOUTHEAST_CORNER:
if(deltay != 0 || deltax != 0)
{
handles[SOUTHEAST_CORNER].adjust(0,0);
handles[EAST_EDGE].adjust(deltax,0);
handles[SOUTH_EDGE].adjust(0,deltay);
handles[SOUTHWEST_CORNER].adjust(0,deltay);
handles[NORTHEAST_CORNER].adjust(deltax,0);
fixEdges();
}
break;
case SOUTHWEST_CORNER:
if(deltay != 0 || deltax != 0)
{
handles[SOUTHWEST_CORNER].adjust(0,0);
handles[SOUTHEAST_CORNER].adjust(0,deltay);
handles[NORTHWEST_CORNER].adjust(deltax,0);
handles[WEST_EDGE].adjust(deltax,0);
handles[SOUTH_EDGE].adjust(0,deltay);
fixEdges();
}
break;
case WEST_EDGE:
if(deltax != 0)
{
handles[WEST_EDGE].adjust(0,0);
handles[NORTHWEST_CORNER].adjust(deltax,deltay);
handles[SOUTHWEST_CORNER].adjust(deltax,deltay);
fixNSEdges();
}
break;
case NORTH_EDGE:
if(deltay != 0)
{
handles[NORTH_EDGE].adjust(0,0);
handles[NORTHEAST_CORNER].adjust(deltax,deltay);
handles[NORTHWEST_CORNER].adjust(deltax,deltay);
fixEWEdges();
}
break;
case EAST_EDGE:
if(deltax != 0)
{
handles[EAST_EDGE].adjust(0,0);
handles[NORTHEAST_CORNER].adjust(deltax,deltay);
handles[SOUTHEAST_CORNER].adjust(deltax,deltay);
fixNSEdges();
}
break;
case SOUTH_EDGE:
if(deltay != 0)
{
handles[SOUTH_EDGE].adjust(0,0);
handles[SOUTHWEST_CORNER].adjust(deltax,deltay);
handles[SOUTHEAST_CORNER].adjust(deltax,deltay);
fixEWEdges();
}
break;
}
handles[i].display();
}
}
void fixNSEdges()
{
adj =handles[WEST_EDGE].x +
(handles[EAST_EDGE].x - handles[WEST_EDGE].x)/2;
//println("setx()=" + adj);
handles[NORTH_EDGE].setx(adj);
handles[SOUTH_EDGE].setx(adj);
}
void fixEWEdges()
{
adj =handles[NORTH_EDGE].y +
(handles[SOUTH_EDGE].y - handles[NORTH_EDGE].y)/2;
handles[WEST_EDGE].sety(adj);
handles[EAST_EDGE].sety(adj);
}
void fixEdges()
{
fixEWEdges();
fixNSEdges();
}
public void setDraggable(boolean mode)
{
int i;
for(i=0;i<8;i++)
{
handles[i].setDraggable(mode);
}
}
int getWidth()
{
return (handles[NORTHEAST_CORNER].x - handles[NORTHWEST_CORNER].x);
}
int getX()
{
return handles[NORTHWEST_CORNER].x + HANDLE_OFFSET/2;
}
int getY()
{
return handles[NORTHWEST_CORNER].y + HANDLE_OFFSET/2;
}
int getHeight()
{
return -1*(handles[NORTHEAST_CORNER].y - handles[SOUTHEAST_CORNER].y);
}
}
//======================================================
{
int deltay;
int deltax;
int i;
int adj;
for(i=0;i<8;i++)
{
deltax = -1*(handles[i].origx - handles[i].x);
deltay = -1*(handles[i].origy - handles[i].y);
switch(i)
{
case NORTHWEST_CORNER:
if(deltay != 0 || deltax != 0)
{
handles[NORTHWEST_CORNER].adjust(0,0);
handles[WEST_EDGE].adjust(deltax,0);
handles[NORTH_EDGE].adjust(0,deltay);
handles[NORTHEAST_CORNER].adjust(0,deltay);
handles[SOUTHWEST_CORNER].adjust(deltax,0);
fixEdges();
}
break;
case NORTHEAST_CORNER:
if(deltay != 0 || deltax != 0)
{
handles[NORTHEAST_CORNER].adjust(0,0);
handles[EAST_EDGE].adjust(deltax,0);
handles[NORTH_EDGE].adjust(0,deltay);
handles[SOUTHEAST_CORNER].adjust(deltax,0);
handles[NORTHWEST_CORNER].adjust(0,deltay);
fixEdges();
}
break;
case SOUTHEAST_CORNER:
if(deltay != 0 || deltax != 0)
{
handles[SOUTHEAST_CORNER].adjust(0,0);
handles[EAST_EDGE].adjust(deltax,0);
handles[SOUTH_EDGE].adjust(0,deltay);
handles[SOUTHWEST_CORNER].adjust(0,deltay);
handles[NORTHEAST_CORNER].adjust(deltax,0);
fixEdges();
}
break;
case SOUTHWEST_CORNER:
if(deltay != 0 || deltax != 0)
{
handles[SOUTHWEST_CORNER].adjust(0,0);
handles[SOUTHEAST_CORNER].adjust(0,deltay);
handles[NORTHWEST_CORNER].adjust(deltax,0);
handles[WEST_EDGE].adjust(deltax,0);
handles[SOUTH_EDGE].adjust(0,deltay);
fixEdges();
}
break;
case WEST_EDGE:
if(deltax != 0)
{
handles[WEST_EDGE].adjust(0,0);
handles[NORTHWEST_CORNER].adjust(deltax,deltay);
handles[SOUTHWEST_CORNER].adjust(deltax,deltay);
fixNSEdges();
}
break;
case NORTH_EDGE:
if(deltay != 0)
{
handles[NORTH_EDGE].adjust(0,0);
handles[NORTHEAST_CORNER].adjust(deltax,deltay);
handles[NORTHWEST_CORNER].adjust(deltax,deltay);
fixEWEdges();
}
break;
case EAST_EDGE:
if(deltax != 0)
{
handles[EAST_EDGE].adjust(0,0);
handles[NORTHEAST_CORNER].adjust(deltax,deltay);
handles[SOUTHEAST_CORNER].adjust(deltax,deltay);
fixNSEdges();
}
break;
case SOUTH_EDGE:
if(deltay != 0)
{
handles[SOUTH_EDGE].adjust(0,0);
handles[SOUTHWEST_CORNER].adjust(deltax,deltay);
handles[SOUTHEAST_CORNER].adjust(deltax,deltay);
fixEWEdges();
}
break;
}
handles[i].display();
}
}
void fixNSEdges()
{
adj =handles[WEST_EDGE].x +
(handles[EAST_EDGE].x - handles[WEST_EDGE].x)/2;
//println("setx()=" + adj);
handles[NORTH_EDGE].setx(adj);
handles[SOUTH_EDGE].setx(adj);
}
void fixEWEdges()
{
adj =handles[NORTH_EDGE].y +
(handles[SOUTH_EDGE].y - handles[NORTH_EDGE].y)/2;
handles[WEST_EDGE].sety(adj);
handles[EAST_EDGE].sety(adj);
}
void fixEdges()
{
fixEWEdges();
fixNSEdges();
}
public void setDraggable(boolean mode)
{
int i;
for(i=0;i<8;i++)
{
handles[i].setDraggable(mode);
}
}
int getWidth()
{
return (handles[NORTHEAST_CORNER].x - handles[NORTHWEST_CORNER].x);
}
int getX()
{
return handles[NORTHWEST_CORNER].x + HANDLE_OFFSET/2;
}
int getY()
{
return handles[NORTHWEST_CORNER].y + HANDLE_OFFSET/2;
}
int getHeight()
{
return -1*(handles[NORTHEAST_CORNER].y - handles[SOUTHEAST_CORNER].y);
}
}
//======================================================
class DragHandle
{
final static int VERTICAL_MOBILE = 1;
final static int HORIZONTAL_MOBILE = 2;
final static int FULLY_MOBILE = 3;
public int x;
int y;
int origx;
int origy;
int mobility;
int height;
int width;
public int posXdiff;
public int posYdiff;
int xdragdelta;
int ydragdelta;
int Id;
boolean draggable = false;
boolean imCaptured = false;
boolean over = false;
boolean pressed = false;
boolean locked;
DragHandle(int Id,int mobility,int x,int y,int width,int height)
{
{
final static int VERTICAL_MOBILE = 1;
final static int HORIZONTAL_MOBILE = 2;
final static int FULLY_MOBILE = 3;
public int x;
int y;
int origx;
int origy;
int mobility;
int height;
int width;
public int posXdiff;
public int posYdiff;
int xdragdelta;
int ydragdelta;
int Id;
boolean draggable = false;
boolean imCaptured = false;
boolean over = false;
boolean pressed = false;
boolean locked;
DragHandle(int Id,int mobility,int x,int y,int width,int height)
{
this.x = x;
this.y = y;
origx = x;
origy = y;
this.mobility = mobility;
this.height = height;
this.width = width;
this.Id = Id;
posXdiff = 0;
posYdiff = 0;
}
void display()
{
if (draggable)
{
handleDrag();
}
fill(color(50,64,64,64));
rect(x,y,width,height);
}
void adjust(int xdelta, int ydelta)
{
x += xdelta;
y += ydelta;
origx = x;
origy = y;
}
boolean over()
{
if (mouseX >= x && mouseX <= x+width &&
mouseY >= y && mouseY <= y+height)
{
over = true;
return true;
}
else
{
over = false;
return false;
}
}
void handleDrag()
{
if (over() && mousePressed && !imCaptured && !captured)
{
posXdiff = x - mouseX;
posYdiff = y - mouseY;
captured = true;
imCaptured = true;
origx = x;
origy = y;
}
if((!mousePressed) && (imCaptured == true))
{
captured = false; //uncapture if mouse released
imCaptured = false;
}
if (imCaptured)
{
xdragdelta = x - (mouseX + posXdiff);
ydragdelta = y - (mouseY + posYdiff);
switch(mobility)
{
case VERTICAL_MOBILE:
x = mouseX + posXdiff;
//println(" Drag x =" + x);
break;
case HORIZONTAL_MOBILE:
y = mouseY + posYdiff;
break;
case FULLY_MOBILE:
x = mouseX + posXdiff;
y = mouseY + posYdiff;
break;
}
}
}
void setDraggable(boolean mode)
{
draggable = mode;
}
void setx(int newx)
{
x = newx;
}
void sety(int newy)
{
y = newy;
}
}
this.y = y;
origx = x;
origy = y;
this.mobility = mobility;
this.height = height;
this.width = width;
this.Id = Id;
posXdiff = 0;
posYdiff = 0;
}
void display()
{
if (draggable)
{
handleDrag();
}
fill(color(50,64,64,64));
rect(x,y,width,height);
}
void adjust(int xdelta, int ydelta)
{
x += xdelta;
y += ydelta;
origx = x;
origy = y;
}
boolean over()
{
if (mouseX >= x && mouseX <= x+width &&
mouseY >= y && mouseY <= y+height)
{
over = true;
return true;
}
else
{
over = false;
return false;
}
}
void handleDrag()
{
if (over() && mousePressed && !imCaptured && !captured)
{
posXdiff = x - mouseX;
posYdiff = y - mouseY;
captured = true;
imCaptured = true;
origx = x;
origy = y;
}
if((!mousePressed) && (imCaptured == true))
{
captured = false; //uncapture if mouse released
imCaptured = false;
}
if (imCaptured)
{
xdragdelta = x - (mouseX + posXdiff);
ydragdelta = y - (mouseY + posYdiff);
switch(mobility)
{
case VERTICAL_MOBILE:
x = mouseX + posXdiff;
//println(" Drag x =" + x);
break;
case HORIZONTAL_MOBILE:
y = mouseY + posYdiff;
break;
case FULLY_MOBILE:
x = mouseX + posXdiff;
y = mouseY + posYdiff;
break;
}
}
}
void setDraggable(boolean mode)
{
draggable = mode;
}
void setx(int newx)
{
x = newx;
}
void sety(int newy)
{
y = newy;
}
}