Skip to content

Instantly share code, notes, and snippets.

@nataliefreed
Created May 8, 2014 17:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nataliefreed/4c0fe85c4d9946553012 to your computer and use it in GitHub Desktop.
Save nataliefreed/4c0fe85c4d9946553012 to your computer and use it in GitHub Desktop.
Processing Code Generator / Drawing Tool
import controlP5.*;
ControlP5 cp5;
DraggableHandler circles;
ArrayList<Draggable> shapes;
int toolbarWidth = 75;
PVector toolbarLoc;
int codeMenuWidth = 300;
int codeLeftMargin = 10;
int codeTextHeight = 20;
int codeTopMargin = codeTextHeight*2;
PVector codeMenuLoc;
int codeColor = 0;
void setup()
{
size(1000, 600);
toolbarLoc = new PVector(0, 0);
codeMenuLoc = new PVector(width - codeMenuWidth, 0);
cp5 = new ControlP5(this);
setupToolbarButtons();
shapes = new ArrayList<Draggable>();
shapes.add(new DraggableCircle(3*width/4, height/2, 30, color(0, 100, 0, 150)));
shapes.add(new DraggableCircle(width/2, height/2, 20, color(0, 0, 100, 150)));
shapes.add(new DraggableCircle(width/4, height/2, 50, color(255, 0, 255, 150)));
circles = new DraggableHandler(this);
for (Draggable shape:shapes)
{
circles.addToEnd(shape);
}
}
void draw()
{
background(100);
drawToolbar();
drawCodeMenu();
circles.display(); //DraggableHandlers are automatically updated
drawCode();
}
void drawToolbar()
{
noStroke();
fill(150);
rect(toolbarLoc.x, toolbarLoc.y, toolbarWidth, height);
}
void drawCodeMenu()
{
noStroke();
fill(200);
rect(codeMenuLoc.x, codeMenuLoc.y, codeMenuWidth, height);
}
void drawCode()
{
for (int i=0;i<shapes.size();i++)
{
((DraggableCircle)shapes.get(i)).displayCode(int(codeMenuLoc.x)+codeLeftMargin, codeTextHeight*i+codeTopMargin, codeColor);
}
}
void setupToolbarButtons()
{
// String[] buttonNames = { "ellipseButton", "rectangleButton", "triangleButton", "lineButton", "createShapeButton", "arcButton", "backgroundButton" }
//
// for(int i=0;i<buttonNames.length;i++)
// {
//
// cp5.addButton(buttonNames[i])
// .setValue(0)
// .setPosition(toolbarLoc.x, toolbarLoc.y+i*toolbarWidth)
// .setSize(toolbarWidth, toolbarWidth)
// ;
// }
cp5.addButton("ellipseButton")
.setValue(0)
.setPosition(toolbarLoc.x, toolbarLoc.y)
.setSize(toolbarWidth, toolbarWidth)
;
cp5.addButton("rectangleButton")
.setValue(0)
.setPosition(toolbarLoc.x, toolbarLoc.y+toolbarWidth)
.setSize(toolbarWidth, toolbarWidth)
;
//
// cp5.addButton("triangleButton")
// .setValue(0)
// .setPosition(toolbarLoc.x, toolbarLoc.y)
// .setSize(toolbarWidth, toolbarWidth)
// ;
//
// cp5.addButton("lineButton")
// .setValue(0)
// .setPosition(toolbarLoc.x, toolbarLoc.y)
// .setSize(toolbarWidth, toolbarWidth)
// ;
//
// cp5.addButton("createShapeButton")
// .setValue(0)
// .setPosition(toolbarLoc.x, toolbarLoc.y)
// .setSize(toolbarWidth, toolbarWidth)
// ;
//
// cp5.addButton("arcButton")
// .setValue(0)
// .setPosition(toolbarLoc.x, toolbarLoc.y)
// .setSize(toolbarWidth, toolbarWidth)
// ;
//
// cp5.addButton("backgroundButton")
// .setValue(0)
// .setPosition(toolbarLoc.x, toolbarLoc.y)
// .setSize(toolbarWidth, toolbarWidth)
// ;
}
void ellipseButton()
{
println("creating ellipse!");
DraggableCircle e = new DraggableCircle(mouseX, mouseY, int(random(0, 100)), color(0, 100, 0, 150));
shapes.add(e);
circles.addToEnd(e);
}
//To make a draggable object that is not a circle, use the following class
//as a template. Write your own display and isOver functions that work
//for your shape. You can add your own functions if you want it to be draggable
//and do other things, like move on its own or be affected by gravity.
//You can add more actions to the update function, and it will be called automatically by the handler.
class DraggableCircle implements Draggable, Codeable
{
PVector center;
int radius;
boolean dragged;
int fillColor;
PVector clickOffset; //offset of cursor from center
String code;
boolean handlesDragged;
PVector handlesClickOffset;
DraggableCircle(int centerX, int centerY, int tempRadius, int tempColor)
{
center = new PVector(centerX, centerY);
radius = tempRadius;
fillColor = tempColor;
dragged = false;
handlesDragged = false;
PVector clickOffset = new PVector(0, 0);
PVector handlesClickOffset = new PVector(0, 0);
updateCode();
}
void display()
{
noStroke();
fill(fillColor);
ellipse(center.x, center.y, radius*2, radius*2);
}
void displayResizingHandles()
{
stroke(0, 50);
noFill();
rectMode(CENTER);
//big rectangle
rect(center.x, center.y, radius*2, radius*2);
//corner rectangles
rect(center.x-radius, center.y-radius, 10, 10);
rect(center.x+radius, center.y+radius, 10, 10);
rect(center.x+radius, center.y-radius, 10, 10);
rect(center.x-radius, center.y+radius, 10, 10);
rectMode(CORNER);
}
void displayCode(int x, int y, int c)
{
fill(c);
text(getCode(), x, y);
}
boolean isOver(int x, int y)
{
//return true if distance between point and center is smaller than radius
if (dist(center.x, center.y, x, y) <= radius)
{
return true;
}
else
{
return false;
}
}
boolean isOverHandles(int x, int y)
{
boolean leftTop = (x > (center.x-radius-5) && x < (center.x-radius+5) && y > (center.y-radius-5) && y < (center.y-radius+5));
boolean leftBottom = (x > (center.x-radius-5) && x < (center.x-radius+5) && y > (center.y+radius-5) && y < (center.y+radius+5));
boolean rightTop = (x > (center.x+radius-5) && x < (center.x+radius+5) && y > (center.y-radius-5) && y < (center.y-radius+5));
boolean rightBottom = (x > (center.x+radius-5) && x < (center.x+radius+5) && y > (center.y+radius-5) && y < (center.y+radius+5));
return (leftTop || leftBottom || rightTop || rightBottom);
}
String getCode()
{
return code;
}
void update() //move with mouse
{
if (dragged)
{
if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) //don't let it get away!
{
center.set(PVector.add(new PVector(mouseX, mouseY), clickOffset));
}
}
if (handlesDragged)
{
radius = (int)dist(mouseX, mouseY, center.x, center.y); //vector version?
//TODO: use handlesClickOffset to fix "pop" in radius size when you drag from corners
}
updateCode();
}
void updateCode()
{
// code = "fill(" + fillColor + ");\n";
code = "ellipse("+(int)center.x+", "+(int)center.y+", "+radius*2+", "+radius*2+");";
}
void setDragged(int fromX, int fromY)
{
dragged = true;
clickOffset = PVector.sub(center, new PVector(fromX, fromY));
}
void releaseDragged()
{
dragged = false;
}
void setHandlesDragged(int fromX, int fromY)
{
handlesDragged = true;
handlesClickOffset = PVector.sub(center, new PVector(fromX, fromY));
}
void releaseHandlesDragged()
{
handlesDragged = false;
}
}
//In Codeable Things tab:
interface Codeable
{
String getCode();
// ArrayList<String> getParams();
}
//In Draggable Things tab:
/*
Draggable objects and handler example for Processing 2.0
Natalie Freed, March 2014
*/
interface Draggable
{
void update();
void display();
void displayResizingHandles();
void setDragged(int fromX, int fromY);
void releaseDragged();
void setHandlesDragged(int fromX, int fromY);
void releaseHandlesDragged();
boolean isOver(int x, int y);
boolean isOverHandles(int x, int y);
}
public class DraggableHandler
{
ArrayList<Draggable> draggables;
Draggable currentDragged; //being dragged
Draggable currentSelected; //is currently selected
DraggableHandler(PApplet app)
{
draggables = new ArrayList<Draggable>();
currentDragged = null;
app.registerMethod("draw", this);
app.registerMethod("mouseEvent", this);
}
void addToEnd(Draggable d)
{
draggables.add(d);
}
void addToFront(Draggable d)
{
draggables.add(0, d); //add to index 0, shift all others
}
void remove(Draggable d)
{
draggables.remove(d);
}
void display()
{
for (int i=draggables.size()-1;i>=0;i--) //draw backwards so first will be on top
{
draggables.get(i).display();
}
if(currentSelected != null)
{
currentSelected.displayResizingHandles();
}
}
public void draw() //this draw is automatically called at the end of each draw()
{
for (int i=0;i<draggables.size();i++)
{
draggables.get(i).update();
}
}
//TODO: add keyboard event for delete, copy, cut, paste, shift
public void mouseEvent(MouseEvent event)
{
int x = event.getX();
int y = event.getY();
switch (event.getAction()) {
case MouseEvent.PRESS:
// choose top draggable to drag if clicked on
if (currentDragged == null)
{
for (int i=0;i<draggables.size();i++)
{
if (draggables.get(i).isOver(x, y))
{
currentDragged = draggables.get(i);
currentSelected = currentDragged;
currentDragged.setDragged(x, y);
break;
}
}
}
if(currentSelected != null)
{
if(currentSelected.isOverHandles(x, y))
{
currentSelected.setHandlesDragged(x, y);
}
}
break;
case MouseEvent.RELEASE:
// release any dragged objects
if (currentDragged != null)
{
currentDragged.releaseDragged();
currentDragged = null;
}
if(currentSelected != null)
{
currentSelected.releaseHandlesDragged();
}
break;
case MouseEvent.CLICK:
//
break;
case MouseEvent.DRAG:
//
break;
case MouseEvent.MOVE:
//
break;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment