Created
May 8, 2014 17:42
-
-
Save nataliefreed/4c0fe85c4d9946553012 to your computer and use it in GitHub Desktop.
Processing Code Generator / Drawing Tool
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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