mirror of
https://github.com/euphy/polargraphcontroller
synced 2024-11-13 01:47:57 +01:00
Initial import
This is the controller application. It's a Processing app.
This commit is contained in:
commit
a2fa25cfaa
652
DisplayMachine.pde
Normal file
652
DisplayMachine.pde
Normal file
@ -0,0 +1,652 @@
|
||||
/**
|
||||
Polargraph controller
|
||||
Copyright Sandy Noble 2012.
|
||||
|
||||
This file is part of Polargraph Controller.
|
||||
|
||||
Polargraph Controller is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Polargraph Controller is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Polargraph Controller. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Requires the excellent ControlP5 GUI library available from http://www.sojamo.de/libraries/controlP5/.
|
||||
Requires the excellent Geomerative library available from http://www.ricardmarxer.com/geomerative/.
|
||||
|
||||
This is an application for controlling a polargraph machine, communicating using ASCII command language over a serial link.
|
||||
|
||||
sandy.noble@gmail.com
|
||||
http://www.polargraph.co.uk/
|
||||
http://code.google.com/p/polargraph/
|
||||
*/
|
||||
|
||||
class DisplayMachine extends Machine
|
||||
{
|
||||
private Rectangle outline = null;
|
||||
private float scaling = 1.0;
|
||||
private Scaler scaler = null;
|
||||
private PVector offset = null;
|
||||
private float imageTransparency = 1.0;
|
||||
|
||||
private Set<PVector> extractedPixels = new HashSet<PVector>(0);
|
||||
|
||||
PImage scaledImage = null;
|
||||
|
||||
private PVector currentPixel = null;
|
||||
|
||||
public DisplayMachine(Machine m, PVector offset, float scaling)
|
||||
{
|
||||
// construct
|
||||
super(m.getWidth(), m.getHeight(), m.getMMPerRev(), m.getStepsPerRev());
|
||||
|
||||
super.machineSize = m.machineSize;
|
||||
|
||||
super.page = m.page;
|
||||
super.imageFrame = m.imageFrame;
|
||||
super.pictureFrame = m.pictureFrame;
|
||||
|
||||
super.imageBitmap = m.imageBitmap;
|
||||
super.imageFilename = m.imageFilename;
|
||||
|
||||
super.stepsPerRev = m.stepsPerRev;
|
||||
super.mmPerRev = m.mmPerRev;
|
||||
|
||||
super.mmPerStep = m.mmPerStep;
|
||||
super.stepsPerMM = m.stepsPerMM;
|
||||
super.maxLength = m.maxLength;
|
||||
super.gridSize = m.gridSize;
|
||||
|
||||
this.offset = offset;
|
||||
this.scaling = scaling;
|
||||
this.scaler = new Scaler(scaling, 100.0);
|
||||
|
||||
this.outline = null;
|
||||
}
|
||||
|
||||
public Rectangle getOutline()
|
||||
{
|
||||
outline = new Rectangle(offset, new PVector(sc(super.getWidth()), sc(super.getHeight())));
|
||||
return this.outline;
|
||||
}
|
||||
|
||||
private Scaler getScaler()
|
||||
{
|
||||
if (scaler == null)
|
||||
this.scaler = new Scaler(getScaling(), getMMPerStep());
|
||||
return scaler;
|
||||
}
|
||||
|
||||
public void setScale(float scale)
|
||||
{
|
||||
this.scaling = scale;
|
||||
this.scaler = new Scaler(scale, getMMPerStep());
|
||||
}
|
||||
public float getScaling()
|
||||
{
|
||||
return this.scaling;
|
||||
}
|
||||
public float sc(float val)
|
||||
{
|
||||
return getScaler().scale(val);
|
||||
}
|
||||
public void setOffset(PVector offset)
|
||||
{
|
||||
this.offset = offset;
|
||||
}
|
||||
public PVector getOffset()
|
||||
{
|
||||
return this.offset;
|
||||
}
|
||||
public void setImageTransparency(float trans)
|
||||
{
|
||||
this.imageTransparency = trans;
|
||||
}
|
||||
public int getImageTransparency()
|
||||
{
|
||||
float f = 255.0 * this.imageTransparency;
|
||||
f += 0.5;
|
||||
int result = (int) f;
|
||||
return result;
|
||||
}
|
||||
|
||||
public PVector getCurrentPixel()
|
||||
{
|
||||
return this.currentPixel;
|
||||
}
|
||||
public void setCurrentPixel(PVector p)
|
||||
{
|
||||
this.currentPixel = p;
|
||||
}
|
||||
|
||||
public void loadNewImageFromFilename(String filename)
|
||||
{
|
||||
super.loadImageFromFilename(filename);
|
||||
super.sizeImageFrameToImageAspectRatio();
|
||||
this.setExtractedPixels(new HashSet<PVector>(0));
|
||||
}
|
||||
|
||||
public final int DROP_SHADOW_DISTANCE = 4;
|
||||
public String getZoomText()
|
||||
{
|
||||
NumberFormat nf = NumberFormat.getNumberInstance(Locale.UK);
|
||||
DecimalFormat df = (DecimalFormat)nf;
|
||||
df.applyPattern("###");
|
||||
String zoom = df.format(scaling * 100) + "% zoom";
|
||||
return zoom;
|
||||
}
|
||||
|
||||
public String getDimensionsAsText(Rectangle r)
|
||||
{
|
||||
return getDimensionsAsText(r.getSize());
|
||||
}
|
||||
public String getDimensionsAsText(PVector p)
|
||||
{
|
||||
String dim = inMM(p.x) + " x " + inMM(p.y) + "mm";
|
||||
return dim;
|
||||
}
|
||||
|
||||
public void drawForSetup()
|
||||
{
|
||||
// work out the scaling factor.
|
||||
noStroke();
|
||||
// draw machine outline
|
||||
|
||||
// drop shadow
|
||||
fill(80);
|
||||
rect(getOutline().getLeft()+DROP_SHADOW_DISTANCE, getOutline().getTop()+DROP_SHADOW_DISTANCE, getOutline().getWidth(), getOutline().getHeight());
|
||||
|
||||
fill(getMachineColour());
|
||||
rect(getOutline().getLeft(), getOutline().getTop(), getOutline().getWidth(), getOutline().getHeight());
|
||||
text("machine " + getDimensionsAsText(getSize()) + " " + getZoomText(), getOutline().getLeft(), getOutline().getTop());
|
||||
|
||||
if (displayingGuides)
|
||||
{
|
||||
// draw some guides
|
||||
stroke(getGuideColour());
|
||||
strokeWeight(1);
|
||||
// centre line
|
||||
line(getOutline().getLeft()+(getOutline().getWidth()/2), getOutline().getTop(),
|
||||
getOutline().getLeft()+(getOutline().getWidth()/2), getOutline().getBottom());
|
||||
|
||||
// page top line
|
||||
line(getOutline().getLeft(), getOutline().getTop()+sc(getHomePoint().y),
|
||||
getOutline().getRight(), getOutline().getTop()+sc(getHomePoint().y));
|
||||
}
|
||||
|
||||
// draw page
|
||||
fill(getPageColour());
|
||||
rect(getOutline().getLeft()+sc(getPage().getLeft()),
|
||||
getOutline().getTop()+sc(getPage().getTop()),
|
||||
sc(getPage().getWidth()),
|
||||
sc(getPage().getHeight()));
|
||||
text("page " + getDimensionsAsText(getPage()), getOutline().getLeft()+sc(getPage().getLeft()),
|
||||
getOutline().getTop()+sc(getPage().getTop()));
|
||||
fill(0);
|
||||
text("offset " + getDimensionsAsText(getPage().getPosition()),
|
||||
getOutline().getLeft()+sc(getPage().getLeft()),
|
||||
getOutline().getTop()+sc(getPage().getTop())+10);
|
||||
noFill();
|
||||
|
||||
// draw home point
|
||||
noFill();
|
||||
strokeWeight(5);
|
||||
stroke(0, 128);
|
||||
PVector onScreen = scaleToScreen(inMM(getHomePoint()));
|
||||
ellipse(onScreen.x, onScreen.y, 15, 15);
|
||||
strokeWeight(2);
|
||||
stroke(255);
|
||||
ellipse(onScreen.x, onScreen.y, 15, 15);
|
||||
|
||||
text("Home point", onScreen.x+ 15, onScreen.y-5);
|
||||
text(int(inMM(getHomePoint().x)+0.5) + ", " + int(inMM(getHomePoint().y)+0.5), onScreen.x+ 15, onScreen.y+15);
|
||||
|
||||
|
||||
if (displayingGuides
|
||||
&& getOutline().surrounds(getMouseVector())
|
||||
&& currentMode != MODE_MOVE_IMAGE
|
||||
&& mouseOverControls().isEmpty()
|
||||
)
|
||||
{
|
||||
drawHangingStrings();
|
||||
drawLineLengthTexts();
|
||||
cursor(CROSS);
|
||||
}
|
||||
else
|
||||
{
|
||||
cursor(ARROW);
|
||||
}
|
||||
}
|
||||
|
||||
public void drawLineLengthTexts()
|
||||
{
|
||||
PVector actual = inMM(asNativeCoords(inSteps(scaleToDisplayMachine(getMouseVector()))));
|
||||
PVector cart = scaleToDisplayMachine(getMouseVector());
|
||||
NumberFormat nf = NumberFormat.getNumberInstance(Locale.UK);
|
||||
DecimalFormat df = (DecimalFormat)nf;
|
||||
df.applyPattern("###.#");
|
||||
|
||||
text("Line 1: " + df.format(actual.x) + "mm", getDisplayMachine().getOutline().getLeft()+10, getDisplayMachine().getOutline().getTop()+18);
|
||||
text("Line 2: " + df.format(actual.y) + "mm", getDisplayMachine().getOutline().getLeft()+10, getDisplayMachine().getOutline().getTop()+28);
|
||||
|
||||
text("X Position: " + df.format(cart.x) + "mm", getDisplayMachine().getOutline().getLeft()+10, getDisplayMachine().getOutline().getTop()+42);
|
||||
text("Y Position: " + df.format(cart.y) + "mm", getDisplayMachine().getOutline().getLeft()+10, getDisplayMachine().getOutline().getTop()+52);
|
||||
}
|
||||
|
||||
public void draw()
|
||||
{
|
||||
// work out the scaling factor.
|
||||
noStroke();
|
||||
// draw machine outline
|
||||
|
||||
// fill(80);
|
||||
// rect(getOutline().getLeft()+DROP_SHADOW_DISTANCE, getOutline().getTop()+DROP_SHADOW_DISTANCE, getOutline().getWidth(), getOutline().getHeight());
|
||||
|
||||
fill(getMachineColour());
|
||||
rect(getOutline().getLeft(), getOutline().getTop(), getOutline().getWidth(), getOutline().getHeight());
|
||||
|
||||
|
||||
|
||||
if (displayingGuides)
|
||||
{
|
||||
// draw some guides
|
||||
stroke(getGuideColour());
|
||||
strokeWeight(1);
|
||||
// centre line
|
||||
line(getOutline().getLeft()+(getOutline().getWidth()/2), getOutline().getTop(),
|
||||
getOutline().getLeft()+(getOutline().getWidth()/2), getOutline().getBottom());
|
||||
|
||||
// page top line
|
||||
line(getOutline().getLeft(), getOutline().getTop()+sc(getHomePoint().y),
|
||||
getOutline().getRight(), getOutline().getTop()+sc(getHomePoint().y));
|
||||
}
|
||||
|
||||
// draw page
|
||||
fill(getPageColour());
|
||||
rect(getOutline().getLeft()+sc(getPage().getLeft()),
|
||||
getOutline().getTop()+sc(getPage().getTop()),
|
||||
sc(getPage().getWidth()),
|
||||
sc(getPage().getHeight()));
|
||||
text("page " + getDimensionsAsText(getPage()), getOutline().getLeft()+sc(getPage().getLeft()),
|
||||
getOutline().getTop()+sc(getPage().getTop())-3);
|
||||
noFill();
|
||||
|
||||
|
||||
|
||||
// draw actual image
|
||||
if (displayingImage && imageIsReady())
|
||||
{
|
||||
float ox = getOutline().getLeft()+sc(getImageFrame().getLeft());
|
||||
float oy = getOutline().getTop()+sc(getImageFrame().getTop());
|
||||
float w = sc(getImageFrame().getWidth());
|
||||
float h = sc(getImageFrame().getHeight());
|
||||
tint(255, getImageTransparency());
|
||||
image(getImage(), ox, oy, w, h);
|
||||
noTint();
|
||||
strokeWeight(1);
|
||||
stroke(150, 150, 150, 40);
|
||||
rect(ox, oy, w-1, h-1);
|
||||
fill(150, 150, 150, 40);
|
||||
text("image", ox, oy-3);
|
||||
noFill();
|
||||
}
|
||||
|
||||
stroke(getBackgroundColour(),150);
|
||||
strokeWeight(3);
|
||||
noFill();
|
||||
rect(getOutline().getLeft()-2, getOutline().getTop()-2, getOutline().getWidth()+3, getOutline().getHeight()+3);
|
||||
|
||||
stroke(getMachineColour(),150);
|
||||
strokeWeight(3);
|
||||
noFill();
|
||||
rect(getOutline().getLeft()+sc(getPage().getLeft())-2,
|
||||
getOutline().getTop()+sc(getPage().getTop())-2,
|
||||
sc(getPage().getWidth())+4,
|
||||
sc(getPage().getHeight())+4);
|
||||
|
||||
|
||||
|
||||
if (displayingSelectedCentres)
|
||||
{
|
||||
drawExtractedPixelCentres();
|
||||
}
|
||||
if (displayingDensityPreview)
|
||||
{
|
||||
drawExtractedPixelDensities();
|
||||
}
|
||||
if (displayingGuides)
|
||||
{
|
||||
drawPictureFrame();
|
||||
}
|
||||
|
||||
if (displayingVector && getVectorShape() != null)
|
||||
{
|
||||
displayVectorImage();
|
||||
}
|
||||
|
||||
if (displayingGuides
|
||||
&& getOutline().surrounds(getMouseVector())
|
||||
&& currentMode != MODE_MOVE_IMAGE
|
||||
&& mouseOverControls().isEmpty()
|
||||
)
|
||||
{
|
||||
drawHangingStrings();
|
||||
drawRows();
|
||||
cursor(CROSS);
|
||||
}
|
||||
else
|
||||
{
|
||||
cursor(ARROW);
|
||||
}
|
||||
}
|
||||
|
||||
public void displayVectorImage()
|
||||
{
|
||||
RPoint[][] pointPaths = getVectorShape().getPointsInPaths();
|
||||
RG.ignoreStyles();
|
||||
stroke(1);
|
||||
if (pointPaths != null)
|
||||
{
|
||||
for(int i = 0; i<pointPaths.length; i++)
|
||||
{
|
||||
if (pointPaths[i] != null)
|
||||
{
|
||||
beginShape();
|
||||
for (int j = 0; j<pointPaths[i].length; j++)
|
||||
{
|
||||
PVector p = new PVector(pointPaths[i][j].x, pointPaths[i][j].y);
|
||||
p = PVector.mult(p, (vectorScaling/100));
|
||||
p = PVector.add(p, getVectorPosition());
|
||||
if (getPage().surrounds(inSteps(p)))
|
||||
{
|
||||
p = scaleToScreen(p);
|
||||
stroke(0);
|
||||
vertex(p.x, p.y);
|
||||
ellipse(p.x, p.y, 3, 3);
|
||||
}
|
||||
}
|
||||
endShape();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// this scales a value from the screen to be a position on the machine
|
||||
/** Given a point on-screen, this works out where on the
|
||||
actual machine it refers to.
|
||||
*/
|
||||
public PVector scaleToDisplayMachine(PVector screen)
|
||||
{
|
||||
// offset
|
||||
float x = screen.x - getOffset().x;
|
||||
float y = screen.y - getOffset().y;
|
||||
|
||||
// transform
|
||||
float scalingFactor = 1.0/getScaling();
|
||||
x = scalingFactor * x;
|
||||
y = scalingFactor * y;
|
||||
|
||||
// and out
|
||||
PVector mach = new PVector(x, y);
|
||||
return mach;
|
||||
}
|
||||
|
||||
/** This works out the position, on-screen of a specific point on the machine.
|
||||
Both values are cartesian coordinates.
|
||||
*/
|
||||
public PVector scaleToScreen(PVector mach)
|
||||
{
|
||||
// transform
|
||||
float x = mach.x * scaling;
|
||||
float y = mach.y * scaling;
|
||||
|
||||
// offset
|
||||
x = x + getOffset().x;
|
||||
y = y + getOffset().y;
|
||||
|
||||
// and out!
|
||||
PVector screen = new PVector(x, y);
|
||||
return screen;
|
||||
}
|
||||
|
||||
// converts a cartesian coord into a native one
|
||||
public PVector convertToNative(PVector cart)
|
||||
{
|
||||
// width of machine in mm
|
||||
float width = inMM(super.getWidth());
|
||||
|
||||
// work out distances
|
||||
float a = dist(0, 0, cart.x, cart.y);
|
||||
float b = dist(width, 0, cart.x, cart.y);
|
||||
|
||||
// and out
|
||||
PVector nativeMM = new PVector(a, b);
|
||||
return nativeMM;
|
||||
}
|
||||
|
||||
void drawPictureFrame()
|
||||
{
|
||||
strokeWeight(1);
|
||||
|
||||
PVector topLeft = scaleToScreen(inMM(getPictureFrame().getTopLeft()));
|
||||
PVector botRight = scaleToScreen(inMM(getPictureFrame().getBotRight()));
|
||||
|
||||
stroke (getFrameColour());
|
||||
|
||||
// top left
|
||||
line(topLeft.x-4, topLeft.y, topLeft.x-10, topLeft.y);
|
||||
line(topLeft.x, topLeft.y-4, topLeft.x, topLeft.y-10);
|
||||
|
||||
// top right
|
||||
line(botRight.x+4, topLeft.y, botRight.x+10, topLeft.y);
|
||||
line(botRight.x, topLeft.y-4, botRight.x, topLeft.y-10);
|
||||
|
||||
// bot right
|
||||
line(botRight.x+4, botRight.y, botRight.x+10, botRight.y);
|
||||
line(botRight.x, botRight.y+4, botRight.x, botRight.y+10);
|
||||
|
||||
// bot left
|
||||
line(topLeft.x-4, botRight.y, topLeft.x-10, botRight.y);
|
||||
line(topLeft.x, botRight.y+4, topLeft.x, botRight.y+10);
|
||||
|
||||
stroke(255);
|
||||
|
||||
|
||||
// float width = inMM(getPictureFrame().getBotRight().x - getPictureFrame().getTopLeft().x);
|
||||
// println("width: "+ width);
|
||||
}
|
||||
|
||||
|
||||
public void drawHangingStrings()
|
||||
{
|
||||
// hanging strings
|
||||
strokeWeight(4);
|
||||
stroke(255, 255, 255, 64);
|
||||
line(getOutline().getLeft(), getOutline().getTop(), mouseX, mouseY);
|
||||
line(getOutline().getRight(), getOutline().getTop(), mouseX, mouseY);
|
||||
}
|
||||
|
||||
/** This draws on screen, showing an arc highlighting the row that the mouse
|
||||
is on.
|
||||
*/
|
||||
public void drawRows()
|
||||
{
|
||||
PVector mVect = getMouseVector();
|
||||
|
||||
// scale it to find out the coordinates on the machine that the mouse is pointing at.
|
||||
mVect = scaleToDisplayMachine(mVect);
|
||||
// convert it to the native coordinates system
|
||||
mVect = convertToNative(mVect);
|
||||
// snap it to the grid
|
||||
mVect = snapToGrid(mVect, getGridSize());
|
||||
// scale it back to find out how to represent this on-screen
|
||||
mVect = scaleToScreen(mVect);
|
||||
|
||||
// and finally, because scaleToScreen also allows for the machine position (offset), subtract it.
|
||||
mVect.sub(getOffset());
|
||||
|
||||
float rowThickness = inMM(getGridSize()) * getScaling();
|
||||
rowThickness = (rowThickness < 1.0) ? 1.0 : rowThickness;
|
||||
strokeWeight(rowThickness);
|
||||
stroke(150, 200, 255, 50);
|
||||
strokeCap(SQUARE);
|
||||
|
||||
float dia = mVect.x*2;
|
||||
arc(getOutline().getLeft(), getOutline().getTop(), dia, dia, 0, 1.57079633);
|
||||
|
||||
dia = mVect.y*2;
|
||||
arc(getOutline().getRight(), getOutline().getTop(), dia, dia, 1.57079633, 3.14159266);
|
||||
|
||||
}
|
||||
|
||||
void drawExtractedPixelCentres()
|
||||
{
|
||||
for (PVector cartesianPos : getExtractedPixels())
|
||||
{
|
||||
// scale em, danno.
|
||||
PVector scaledPos = scaleToScreen(cartesianPos);
|
||||
strokeWeight(1);
|
||||
stroke(255, 0, 0, 128);
|
||||
noFill();
|
||||
line(scaledPos.x-1, scaledPos.y-1, scaledPos.x+1, scaledPos.y+1);
|
||||
line(scaledPos.x-1, scaledPos.y+1, scaledPos.x+1, scaledPos.y-1);
|
||||
}
|
||||
}
|
||||
|
||||
void drawExtractedPixelDensities()
|
||||
{
|
||||
|
||||
float pixelSize = inMM(getGridSize()) * getScaling();
|
||||
pixelSize = (pixelSize < 1.0) ? 1.0 : pixelSize;
|
||||
|
||||
pixelSize = pixelSize * getPixelScalingOverGridSize();
|
||||
|
||||
if (getExtractedPixels() != null)
|
||||
{
|
||||
for (PVector cartesianPos : getExtractedPixels())
|
||||
{
|
||||
if ((cartesianPos.z <= pixelExtractBrightThreshold) && (cartesianPos.z >= pixelExtractDarkThreshold))
|
||||
{
|
||||
// scale em, danno.
|
||||
PVector scaledPos = scaleToScreen(cartesianPos);
|
||||
noStroke();
|
||||
fill(cartesianPos.z);
|
||||
switch (getDensityPreviewStyle())
|
||||
{
|
||||
case DENSITY_PREVIEW_ROUND:
|
||||
previewRoundPixel(scaledPos, pixelSize, pixelSize);
|
||||
break;
|
||||
case DENSITY_PREVIEW_DIAMOND:
|
||||
previewDiamondPixel(scaledPos, pixelSize, pixelSize, cartesianPos.z);
|
||||
break;
|
||||
default:
|
||||
previewRoundPixel(scaledPos, pixelSize, pixelSize);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
noFill();
|
||||
}
|
||||
|
||||
void previewDiamondPixel(PVector pos, float wide, float high, float brightness)
|
||||
{
|
||||
wide*=1.4;
|
||||
high*=1.4;
|
||||
// shall I try and draw a diamond here instead? OK! I'll do it! Ha!
|
||||
float halfWidth = wide / 2.0;
|
||||
float halfHeight = high / 2.0;
|
||||
fill(0,0,0, 255-brightness);
|
||||
quad(pos.x, pos.y-halfHeight, pos.x+halfWidth, pos.y, pos.x, pos.y+halfHeight, pos.x-halfWidth, pos.y);
|
||||
|
||||
}
|
||||
void previewNativePixel(PVector pos, float wide, float high)
|
||||
{
|
||||
// shall I try and draw a diamond here instead? OK! I'll do it! Ha!
|
||||
float halfWidth = wide / 2.0;
|
||||
float halfHeight = high / 2.0;
|
||||
quad(pos.x, pos.y-halfHeight, pos.x+halfWidth, pos.y, pos.x, pos.y+halfHeight, pos.x-halfWidth, pos.y);
|
||||
|
||||
}
|
||||
void previewRoundPixel(PVector pos, float wide, float high)
|
||||
{
|
||||
ellipse(pos.x, pos.y, wide*1.1, high*1.1);
|
||||
}
|
||||
|
||||
color getPixelAtScreenCoords(PVector pos)
|
||||
{
|
||||
pos = scaleToDisplayMachine(pos);
|
||||
pos = inSteps(pos);
|
||||
float scalingFactor = getImage().width / getImageFrame().getWidth();
|
||||
color col = super.getPixelAtMachineCoords(pos, scalingFactor);
|
||||
return col;
|
||||
}
|
||||
|
||||
Set<PVector> getExtractedPixels()
|
||||
{
|
||||
return this.extractedPixels;
|
||||
}
|
||||
void setExtractedPixels(Set<PVector> p)
|
||||
{
|
||||
this.extractedPixels = p;
|
||||
}
|
||||
|
||||
/* This will return a list of pixels that are included in the area in the
|
||||
parameter. All coordinates are for the screen.
|
||||
*/
|
||||
Set<PVector> getPixelsPositionsFromArea(PVector p, PVector s, float rowSize)
|
||||
{
|
||||
extractPixelsFromArea(p, s, rowSize, 0.0);
|
||||
return getExtractedPixels();
|
||||
}
|
||||
|
||||
public void extractPixelsFromArea(PVector p, PVector s, float rowSize, float sampleSize)
|
||||
{
|
||||
// get the native positions from the superclass
|
||||
Set<PVector> nativePositions = super.getPixelsPositionsFromArea(inSteps(p), inSteps(s), rowSize, sampleSize);
|
||||
|
||||
// work out the cartesian positions
|
||||
Set<PVector> cartesianPositions = new HashSet<PVector>(nativePositions.size());
|
||||
for (PVector nativePos : nativePositions)
|
||||
{
|
||||
// convert to cartesian
|
||||
PVector displayPos = super.asCartesianCoords(nativePos);
|
||||
displayPos = inMM(displayPos);
|
||||
displayPos.z = nativePos.z;
|
||||
cartesianPositions.add(displayPos);
|
||||
}
|
||||
setExtractedPixels(cartesianPositions);
|
||||
}
|
||||
|
||||
|
||||
public Set<PVector> extractNativePixelsFromArea(PVector p, PVector s, float rowSize, float sampleSize)
|
||||
{
|
||||
// get the native positions from the superclass
|
||||
Set<PVector> nativePositions = super.getPixelsPositionsFromArea(inSteps(p), inSteps(s), rowSize, sampleSize);
|
||||
return nativePositions;
|
||||
}
|
||||
|
||||
protected PVector snapToGrid(PVector loose, float rowSize)
|
||||
{
|
||||
PVector snapped = inSteps(loose);
|
||||
snapped = super.snapToGrid(snapped, rowSize);
|
||||
snapped = inMM(snapped);
|
||||
return snapped;
|
||||
}
|
||||
|
||||
public boolean pixelsCanBeExtracted()
|
||||
{
|
||||
if (super.getImage() == null)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
690
Machine.pde
Normal file
690
Machine.pde
Normal file
@ -0,0 +1,690 @@
|
||||
/**
|
||||
Polargraph controller
|
||||
Copyright Sandy Noble 2012.
|
||||
|
||||
This file is part of Polargraph Controller.
|
||||
|
||||
Polargraph Controller is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Polargraph Controller is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Polargraph Controller. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Requires the excellent ControlP5 GUI library available from http://www.sojamo.de/libraries/controlP5/.
|
||||
Requires the excellent Geomerative library available from http://www.ricardmarxer.com/geomerative/.
|
||||
|
||||
This is an application for controlling a polargraph machine, communicating using ASCII command language over a serial link.
|
||||
|
||||
sandy.noble@gmail.com
|
||||
http://www.polargraph.co.uk/
|
||||
http://code.google.com/p/polargraph/
|
||||
*/
|
||||
/**
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
class Machine
|
||||
{
|
||||
protected PVector machineSize = new PVector(4000,6000);
|
||||
|
||||
protected Rectangle page = new Rectangle(1000,1000,2000,3000);
|
||||
protected Rectangle imageFrame = new Rectangle(1500,1500,1000,1000);
|
||||
protected Rectangle pictureFrame = new Rectangle(1600,1600,800,800);
|
||||
|
||||
protected Float stepsPerRev = 800.0;
|
||||
protected Float mmPerRev = 95.0;
|
||||
|
||||
protected Float mmPerStep = null;
|
||||
protected Float stepsPerMM = null;
|
||||
protected Float maxLength = null;
|
||||
protected Float gridSize = 100.0;
|
||||
protected List<Float> gridLinePositions = null;
|
||||
|
||||
protected PImage imageBitmap = null;
|
||||
protected String imageFilename = null;
|
||||
|
||||
|
||||
public Machine(Integer width, Integer height, Float stepsPerRev, Float mmPerRev)
|
||||
{
|
||||
this.setSize(width, height);
|
||||
this.setStepsPerRev(stepsPerRev);
|
||||
this.setMMPerRev(mmPerRev);
|
||||
}
|
||||
|
||||
public void setSize(Integer width, Integer height)
|
||||
{
|
||||
PVector s = new PVector(width, height);
|
||||
this.machineSize = s;
|
||||
maxLength = null;
|
||||
}
|
||||
public PVector getSize()
|
||||
{
|
||||
return this.machineSize;
|
||||
}
|
||||
public Float getMaxLength()
|
||||
{
|
||||
if (maxLength == null)
|
||||
{
|
||||
maxLength = dist(0,0, getWidth(), getHeight());
|
||||
}
|
||||
return maxLength;
|
||||
}
|
||||
|
||||
public void setPage(Rectangle r)
|
||||
{
|
||||
this.page = r;
|
||||
}
|
||||
public Rectangle getPage()
|
||||
{
|
||||
return this.page;
|
||||
}
|
||||
public float getPageCentrePosition(float pageWidth)
|
||||
{
|
||||
return (getWidth()- pageWidth/2)/2;
|
||||
}
|
||||
|
||||
public void setImageFrame(Rectangle r)
|
||||
{
|
||||
this.imageFrame = r;
|
||||
}
|
||||
|
||||
public Rectangle getImageFrame()
|
||||
{
|
||||
return this.imageFrame;
|
||||
}
|
||||
|
||||
public void setPictureFrame(Rectangle r)
|
||||
{
|
||||
this.pictureFrame = r;
|
||||
}
|
||||
public Rectangle getPictureFrame()
|
||||
{
|
||||
return this.pictureFrame;
|
||||
}
|
||||
|
||||
public Integer getWidth()
|
||||
{
|
||||
return int(this.machineSize.x);
|
||||
}
|
||||
public Integer getHeight()
|
||||
{
|
||||
return int(this.machineSize.y);
|
||||
}
|
||||
|
||||
public void setStepsPerRev(Float s)
|
||||
{
|
||||
this.stepsPerRev = s;
|
||||
}
|
||||
public Float getStepsPerRev()
|
||||
{
|
||||
mmPerStep = null;
|
||||
stepsPerMM = null;
|
||||
return this.stepsPerRev;
|
||||
}
|
||||
public void setMMPerRev(Float d)
|
||||
{
|
||||
mmPerStep = null;
|
||||
stepsPerMM = null;
|
||||
this.mmPerRev = d;
|
||||
}
|
||||
public Float getMMPerRev()
|
||||
{
|
||||
return this.mmPerRev;
|
||||
}
|
||||
public Float getMMPerStep()
|
||||
{
|
||||
if (mmPerStep == null)
|
||||
{
|
||||
mmPerStep = mmPerRev / stepsPerRev;
|
||||
}
|
||||
return mmPerStep;
|
||||
}
|
||||
public Float getStepsPerMM()
|
||||
{
|
||||
if (stepsPerMM == null)
|
||||
{
|
||||
stepsPerMM = stepsPerRev / mmPerRev;
|
||||
}
|
||||
return stepsPerMM;
|
||||
}
|
||||
|
||||
public int inSteps(int inMM)
|
||||
{
|
||||
double steps = inMM * getStepsPerMM();
|
||||
steps += 0.5;
|
||||
int stepsInt = (int) steps;
|
||||
return stepsInt;
|
||||
}
|
||||
|
||||
public int inSteps(float inMM)
|
||||
{
|
||||
double steps = inMM * getStepsPerMM();
|
||||
steps += 0.5;
|
||||
int stepsInt = (int) steps;
|
||||
return stepsInt;
|
||||
}
|
||||
|
||||
public PVector inSteps(PVector mm)
|
||||
{
|
||||
PVector steps = new PVector(inSteps(mm.x), inSteps(mm.y));
|
||||
return steps;
|
||||
}
|
||||
|
||||
public int inMM(float steps)
|
||||
{
|
||||
double mm = steps / getStepsPerMM();
|
||||
mm += 0.5;
|
||||
int mmInt = (int) mm;
|
||||
return mmInt;
|
||||
}
|
||||
|
||||
public PVector inMM (PVector steps)
|
||||
{
|
||||
PVector mm = new PVector(inMM(steps.x), inMM(steps.y));
|
||||
return mm;
|
||||
}
|
||||
|
||||
float getPixelBrightness(PVector pos, float dim, float scalingFactor)
|
||||
{
|
||||
float averageBrightness = 255.0;
|
||||
|
||||
if (getImageFrame().surrounds(pos))
|
||||
{
|
||||
// offset it by image position to get position over image
|
||||
PVector offsetPos = PVector.sub(pos, getImageFrame().getPosition());
|
||||
int originX = (int) offsetPos.x;
|
||||
int originY = (int) offsetPos.y;
|
||||
|
||||
PImage extractedPixels = null;
|
||||
|
||||
extractedPixels = getImage().get(int(originX*scalingFactor), int(originY*scalingFactor), 1, 1);
|
||||
extractedPixels.loadPixels();
|
||||
|
||||
if (dim >= 2)
|
||||
{
|
||||
int halfDim = (int)dim / (int)2.0;
|
||||
|
||||
// restrict the sample area from going off the top/left edge of the image
|
||||
float startX = originX - halfDim;
|
||||
float startY = originY - halfDim;
|
||||
|
||||
if (startX < 0)
|
||||
startX = 0;
|
||||
|
||||
if (startY < 0)
|
||||
startY = 0;
|
||||
|
||||
// and do the same for the bottom / right edges
|
||||
float endX = originX+halfDim;
|
||||
float endY = originY+halfDim;
|
||||
|
||||
if (endX > getImageFrame().getWidth())
|
||||
endX = getImageFrame().getWidth();
|
||||
|
||||
if (endY > getImageFrame().getHeight())
|
||||
endY = getImageFrame().getHeight();
|
||||
|
||||
// now convert end coordinates to width/height
|
||||
float dimWidth = (endX - startX)*scalingFactor;
|
||||
float dimHeight = (endY - startY)*scalingFactor;
|
||||
|
||||
dimWidth = (dimWidth < 1.0) ? 1.0 : dimWidth;
|
||||
dimHeight = (dimHeight < 1.0) ? 1.0 : dimHeight;
|
||||
startX = int(startX*scalingFactor);
|
||||
startY = int(startY*scalingFactor);
|
||||
|
||||
// get the block of pixels
|
||||
extractedPixels = getImage().get(int(startX), int(startY), int(dimWidth+0.5), int(dimHeight+0.5));
|
||||
extractedPixels.loadPixels();
|
||||
}
|
||||
|
||||
// going to go through them and total the brightnesses
|
||||
int numberOfPixels = extractedPixels.pixels.length;
|
||||
float totalPixelBrightness = 0;
|
||||
for (int i = 0; i < numberOfPixels; i++)
|
||||
{
|
||||
color p = extractedPixels.pixels[i];
|
||||
float r = brightness(p);
|
||||
totalPixelBrightness += r;
|
||||
}
|
||||
|
||||
// and get an average brightness for all of these pixels.
|
||||
averageBrightness = totalPixelBrightness / numberOfPixels;
|
||||
}
|
||||
|
||||
return averageBrightness;
|
||||
}
|
||||
|
||||
color getPixelAtMachineCoords(PVector pos, float scalingFactor)
|
||||
{
|
||||
if (getImageFrame().surrounds(pos))
|
||||
{
|
||||
// offset it by image position to get position over image
|
||||
PVector offsetPos = PVector.sub(pos, getImageFrame().getPosition());
|
||||
int originX = (int) offsetPos.x;
|
||||
int originY = (int) offsetPos.y;
|
||||
|
||||
PImage centrePixel = null;
|
||||
|
||||
centrePixel = getImage().get(int(originX*scalingFactor), int(originY*scalingFactor), 1, 1);
|
||||
centrePixel.loadPixels();
|
||||
|
||||
color col = centrePixel.pixels[0];
|
||||
return col;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
boolean isChromaKey(PVector pos, float scalingFactor)
|
||||
{
|
||||
if (getImageFrame().surrounds(pos))
|
||||
{
|
||||
color col = getPixelAtMachineCoords(pos, scalingFactor);
|
||||
|
||||
// get pixels from the vector coords
|
||||
if (col == chromaKeyColour)
|
||||
{
|
||||
// println("is chroma key " + red(col) + ", "+green(col)+","+blue(col));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// println("isn't chroma key " + red(col) + ", "+green(col)+","+blue(col));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
public PVector asNativeCoords(PVector cartCoords)
|
||||
{
|
||||
return asNativeCoords(cartCoords.x, cartCoords.y);
|
||||
}
|
||||
public PVector asNativeCoords(float cartX, float cartY)
|
||||
{
|
||||
float distA = dist(0,0,cartX, cartY);
|
||||
float distB = dist(getWidth(),0,cartX, cartY);
|
||||
PVector pgCoords = new PVector(distA, distB);
|
||||
return pgCoords;
|
||||
}
|
||||
|
||||
|
||||
public PVector asCartesianCoords(PVector pgCoords)
|
||||
{
|
||||
float calcX = int((pow(getWidth(), 2) - pow(pgCoords.y, 2) + pow(pgCoords.x, 2)) / (getWidth()*2));
|
||||
float calcY = int(sqrt(pow(pgCoords.x,2)-pow(calcX,2)));
|
||||
PVector vect = new PVector(calcX, calcY);
|
||||
return vect;
|
||||
}
|
||||
|
||||
public Integer convertSizePreset(String preset)
|
||||
{
|
||||
Integer result = A3_SHORT;
|
||||
if (preset.equalsIgnoreCase(PRESET_A3_SHORT))
|
||||
result = A3_SHORT;
|
||||
else if (preset.equalsIgnoreCase(PRESET_A3_LONG))
|
||||
result = A3_LONG;
|
||||
else if (preset.equalsIgnoreCase(PRESET_A2_SHORT))
|
||||
result = A2_SHORT;
|
||||
else if (preset.equalsIgnoreCase(PRESET_A2_LONG))
|
||||
result = A2_LONG;
|
||||
else if (preset.equalsIgnoreCase(PRESET_A2_IMP_SHORT))
|
||||
result = A2_IMP_SHORT;
|
||||
else if (preset.equalsIgnoreCase(PRESET_A2_IMP_LONG))
|
||||
result = A2_IMP_LONG;
|
||||
else if (preset.equalsIgnoreCase(PRESET_A1_SHORT))
|
||||
result = A1_SHORT;
|
||||
else if (preset.equalsIgnoreCase(PRESET_A1_LONG))
|
||||
result = A1_LONG;
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
result = Integer.parseInt(preset);
|
||||
}
|
||||
catch (NumberFormatException nfe)
|
||||
{
|
||||
result = A3_SHORT;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void loadDefinitionFromProperties(Properties props)
|
||||
{
|
||||
// get these first because they are important to convert the rest of them
|
||||
setStepsPerRev(getFloatProperty("machine.motors.stepsPerRev", 800.0));
|
||||
setMMPerRev(getFloatProperty("machine.motors.mmPerRev", 95.0));
|
||||
|
||||
// now stepsPerMM and mmPerStep should have been calculated. It's safe to get the rest.
|
||||
|
||||
// machine size
|
||||
setSize(inSteps(getIntProperty("machine.width", 600)), inSteps(getIntProperty("machine.height", 800)));
|
||||
|
||||
// page size
|
||||
String pageWidth = getStringProperty("controller.page.width", PRESET_A3_SHORT);
|
||||
float pw = convertSizePreset(pageWidth);
|
||||
String pageHeight = getStringProperty("controller.page.height", PRESET_A3_LONG);
|
||||
float ph = convertSizePreset(pageHeight);
|
||||
PVector pageSize = new PVector(pw, ph);
|
||||
|
||||
// page position
|
||||
String pos = getStringProperty("controller.page.position.x", "CENTRE");
|
||||
float px = 0.0;
|
||||
println("machine size: " + getSize().x + ", " + inSteps(pageSize.x));
|
||||
if (pos.equalsIgnoreCase("CENTRE"))
|
||||
{
|
||||
px = inMM((getSize().x - pageSize.x) / 2.0);
|
||||
}
|
||||
else
|
||||
px = getFloatProperty("controller.page.position.x", (int) getDisplayMachine().getPageCentrePosition(pageSize.x));
|
||||
|
||||
float py = getFloatProperty("controller.page.position.y", 120);
|
||||
|
||||
PVector pagePos = new PVector(px, py);
|
||||
Rectangle page = new Rectangle(inSteps(pagePos), inSteps(pageSize));
|
||||
setPage(page);
|
||||
|
||||
// bitmap
|
||||
setImageFilename(getStringProperty("controller.image.filename", ""));
|
||||
loadImageFromFilename(imageFilename);
|
||||
|
||||
// image position
|
||||
Float offsetX = getFloatProperty("controller.image.position.x", 0.0);
|
||||
Float offsetY = getFloatProperty("controller.image.position.y", 0.0);
|
||||
PVector imagePos = new PVector(offsetX, offsetY);
|
||||
// println("image pos: " + imagePos);
|
||||
|
||||
// image size
|
||||
Float imageWidth = getFloatProperty("controller.image.width", 500);
|
||||
Float imageHeight = getFloatProperty("controller.image.height", 0);
|
||||
if (imageHeight == 0) // default was set
|
||||
{
|
||||
println("Image height not supplied - creating default.");
|
||||
if (getImage() != null)
|
||||
{
|
||||
float scaling = imageWidth / getImage().width;
|
||||
imageHeight = getImage().height * scaling;
|
||||
}
|
||||
else
|
||||
imageHeight = 500.0;
|
||||
}
|
||||
PVector imageSize = new PVector(imageWidth, imageHeight);
|
||||
|
||||
Rectangle imageFrame = new Rectangle(inSteps(imagePos), inSteps(imageSize));
|
||||
setImageFrame(imageFrame);
|
||||
|
||||
// picture frame size
|
||||
PVector frameSize = new PVector(getIntProperty("controller.pictureframe.width", 200), getIntProperty("controller.pictureframe.height", 200));
|
||||
PVector framePos = new PVector(getIntProperty("controller.pictureframe.position.x", 200), getIntProperty("controller.pictureframe.position.y", 200));
|
||||
Rectangle frame = new Rectangle(inSteps(framePos), inSteps(frameSize));
|
||||
setPictureFrame(frame);
|
||||
}
|
||||
|
||||
|
||||
public Properties loadDefinitionIntoProperties(Properties props)
|
||||
{
|
||||
// Put keys into properties file:
|
||||
props.setProperty("machine.motors.stepsPerRev", getStepsPerRev().toString());
|
||||
props.setProperty("machine.motors.mmPerRev", getMMPerRev().toString());
|
||||
|
||||
// machine width
|
||||
props.setProperty("machine.width", Integer.toString((int) inMM(getWidth())));
|
||||
// machine.height
|
||||
props.setProperty("machine.height", Integer.toString((int) inMM(getHeight())));
|
||||
|
||||
// image filename
|
||||
props.setProperty("controller.image.filename", (getImageFilename() == null) ? "" : getImageFilename());
|
||||
|
||||
// image position
|
||||
float imagePosX = 0.0;
|
||||
float imagePosY = 0.0;
|
||||
float imageWidth = 0.0;
|
||||
float imageHeight = 0.0;
|
||||
if (getImageFrame() != null)
|
||||
{
|
||||
imagePosX = getImageFrame().getLeft();
|
||||
imagePosY = getImageFrame().getTop();
|
||||
imageWidth = getImageFrame().getWidth();
|
||||
imageHeight = getImageFrame().getHeight();
|
||||
}
|
||||
props.setProperty("controller.image.position.x", Integer.toString((int) inMM(imagePosX)));
|
||||
props.setProperty("controller.image.position.y", Integer.toString((int) inMM(imagePosY)));
|
||||
|
||||
// image size
|
||||
props.setProperty("controller.image.width", Integer.toString((int) inMM(imageWidth)));
|
||||
props.setProperty("controller.image.height", Integer.toString((int) inMM(imageHeight)));
|
||||
|
||||
// page size
|
||||
// page position
|
||||
float pageSizeX = 0.0;
|
||||
float pageSizeY = 0.0;
|
||||
float pagePosX = 0.0;
|
||||
float pagePosY = 0.0;
|
||||
if (getPage() != null)
|
||||
{
|
||||
pageSizeX = getPage().getWidth();
|
||||
pageSizeY = getPage().getHeight();
|
||||
pagePosX = getPage().getLeft();
|
||||
pagePosY = getPage().getTop();
|
||||
}
|
||||
props.setProperty("controller.page.width", Integer.toString((int) inMM(pageSizeX)));
|
||||
props.setProperty("controller.page.height", Integer.toString((int) inMM(pageSizeY)));
|
||||
props.setProperty("controller.page.position.x", Integer.toString((int) inMM(pagePosX)));
|
||||
props.setProperty("controller.page.position.y", Integer.toString((int) inMM(pagePosY)));
|
||||
|
||||
// picture frame size
|
||||
float frameSizeX = 0.0;
|
||||
float frameSizeY = 0.0;
|
||||
float framePosX = 0.0;
|
||||
float framePosY = 0.0;
|
||||
if (getPictureFrame() != null)
|
||||
{
|
||||
frameSizeX = getPictureFrame().getWidth();
|
||||
frameSizeY = getPictureFrame().getHeight();
|
||||
framePosX = getPictureFrame().getLeft();
|
||||
framePosY = getPictureFrame().getTop();
|
||||
}
|
||||
props.setProperty("controller.pictureframe.width", Integer.toString((int) inMM(frameSizeX)));
|
||||
props.setProperty("controller.pictureframe.height", Integer.toString((int) inMM(frameSizeY)));
|
||||
|
||||
// picture frame position
|
||||
props.setProperty("controller.pictureframe.position.x", Integer.toString((int) inMM(framePosX)));
|
||||
props.setProperty("controller.pictureframe.position.y", Integer.toString((int) inMM(framePosY)));
|
||||
|
||||
// println("framesize: " + inMM(frameSizeX));
|
||||
|
||||
return props;
|
||||
}
|
||||
|
||||
protected void loadImageFromFilename(String filename)
|
||||
{
|
||||
if (filename != null && !"".equals(filename))
|
||||
{
|
||||
// check for format etc here
|
||||
println("loading from filename: " + filename);
|
||||
this.imageBitmap = loadImage(filename);
|
||||
this.imageFilename = filename;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.imageBitmap = null;
|
||||
this.imageFilename = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void sizeImageFrameToImageAspectRatio()
|
||||
{
|
||||
float scaling = getImageFrame().getWidth() / getImage().width;
|
||||
float frameHeight = getImage().height * scaling;
|
||||
getImageFrame().getSize().y = frameHeight;
|
||||
}
|
||||
|
||||
public void setImage(PImage b)
|
||||
{
|
||||
this.imageBitmap = b;
|
||||
}
|
||||
public void setImageFilename(String filename)
|
||||
{
|
||||
this.loadImageFromFilename(filename);
|
||||
}
|
||||
public String getImageFilename()
|
||||
{
|
||||
return this.imageFilename;
|
||||
}
|
||||
public PImage getImage()
|
||||
{
|
||||
return this.imageBitmap;
|
||||
}
|
||||
|
||||
public boolean imageIsReady()
|
||||
{
|
||||
if (imageBitmapIsLoaded())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean imageBitmapIsLoaded()
|
||||
{
|
||||
if (getImage() != null)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
protected void setGridSize(float gridSize)
|
||||
{
|
||||
this.gridSize = gridSize;
|
||||
this.gridLinePositions = generateGridLinePositions(gridSize);
|
||||
}
|
||||
|
||||
/**
|
||||
This takes in an area defined in cartesian steps,
|
||||
and returns a set of pixels that are included
|
||||
in that area. Coordinates are specified
|
||||
in cartesian steps. The pixels are worked out
|
||||
based on the gridsize parameter. d*/
|
||||
Set<PVector> getPixelsPositionsFromArea(PVector p, PVector s, float gridSize, float sampleSize)
|
||||
{
|
||||
|
||||
// work out the grid
|
||||
setGridSize(gridSize);
|
||||
float maxLength = getMaxLength();
|
||||
float numberOfGridlines = maxLength / gridSize;
|
||||
float gridIncrement = maxLength / numberOfGridlines;
|
||||
List<Float> gridLinePositions = getGridLinePositions(gridSize);
|
||||
|
||||
Rectangle selectedArea = new Rectangle (p.x,p.y, s.x,s.y);
|
||||
|
||||
// now work out the scaling factor that'll be needed to work out
|
||||
// the positions of the pixels on the bitmap.
|
||||
float scalingFactor = getImage().width / getImageFrame().getWidth();
|
||||
|
||||
// now go through all the combinations of the two values.
|
||||
Set<PVector> nativeCoords = new HashSet<PVector>();
|
||||
for (Float a : gridLinePositions)
|
||||
{
|
||||
for (Float b : gridLinePositions)
|
||||
{
|
||||
PVector nativeCoord = new PVector(a, b);
|
||||
PVector cartesianCoord = asCartesianCoords(nativeCoord);
|
||||
if (selectedArea.surrounds(cartesianCoord))
|
||||
{
|
||||
if (isChromaKey(cartesianCoord, scalingFactor))
|
||||
{
|
||||
nativeCoord.z = MASKED_PIXEL_BRIGHTNESS; // magic number
|
||||
nativeCoords.add(nativeCoord);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sampleSize >= 1.0)
|
||||
{
|
||||
float brightness = getPixelBrightness(cartesianCoord, sampleSize, scalingFactor);
|
||||
nativeCoord.z = brightness;
|
||||
}
|
||||
nativeCoords.add(nativeCoord);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nativeCoords;
|
||||
}
|
||||
|
||||
protected PVector snapToGrid(PVector loose, float gridSize)
|
||||
{
|
||||
List<Float> pos = getGridLinePositions(gridSize);
|
||||
boolean higherupperFound = false;
|
||||
boolean lowerFound = false;
|
||||
|
||||
float halfGrid = gridSize / 2.0;
|
||||
float x = loose.x;
|
||||
float y = loose.y;
|
||||
|
||||
Float snappedX = null;
|
||||
Float snappedY = null;
|
||||
|
||||
int i = 0;
|
||||
while ((snappedX == null || snappedY == null) && i < pos.size())
|
||||
{
|
||||
float upperBound = pos.get(i)+halfGrid;
|
||||
float lowerBound = pos.get(i)-halfGrid;
|
||||
// println("pos:" +pos.get(i) + "half: "+halfGrid+ ", upper: "+ upperBound + ", lower: " + lowerBound);
|
||||
if (snappedX == null
|
||||
&& x > lowerBound
|
||||
&& x <= upperBound)
|
||||
{
|
||||
snappedX = pos.get(i);
|
||||
// println("snappedX:" + snappedX);
|
||||
}
|
||||
|
||||
if (snappedY == null
|
||||
&& y > lowerBound
|
||||
&& y <= upperBound)
|
||||
{
|
||||
snappedY = pos.get(i);
|
||||
// println("snappedY:" + snappedY);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
PVector snapped = new PVector((snappedX == null) ? 0.0 : snappedX, (snappedY == null) ? 0.0 : snappedY);
|
||||
// println("loose:" + loose);
|
||||
// println("snapped:" + snapped);
|
||||
return snapped;
|
||||
}
|
||||
|
||||
protected List<Float> getGridLinePositions(float gridSize)
|
||||
{
|
||||
setGridSize(gridSize);
|
||||
return this.gridLinePositions;
|
||||
}
|
||||
|
||||
private List<Float> generateGridLinePositions(float gridSize)
|
||||
{
|
||||
List<Float> glp = new ArrayList<Float>();
|
||||
float maxLength = getMaxLength();
|
||||
for (float i = gridSize; i <= maxLength; i+=gridSize)
|
||||
{
|
||||
glp.add(i);
|
||||
}
|
||||
return glp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
253
Misc.pde
Normal file
253
Misc.pde
Normal file
@ -0,0 +1,253 @@
|
||||
/**
|
||||
Polargraph controller
|
||||
Copyright Sandy Noble 2012.
|
||||
|
||||
This file is part of Polargraph Controller.
|
||||
|
||||
Polargraph Controller is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Polargraph Controller is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Polargraph Controller. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Requires the excellent ControlP5 GUI library available from http://www.sojamo.de/libraries/controlP5/.
|
||||
Requires the excellent Geomerative library available from http://www.ricardmarxer.com/geomerative/.
|
||||
|
||||
This is an application for controlling a polargraph machine, communicating using ASCII command language over a serial link.
|
||||
|
||||
sandy.noble@gmail.com
|
||||
http://www.polargraph.co.uk/
|
||||
http://code.google.com/p/polargraph/
|
||||
*/
|
||||
|
||||
class Scaler
|
||||
{
|
||||
public float scale = 1.0;
|
||||
public float mmPerStep = 1.0;
|
||||
|
||||
public Scaler(float scale, float mmPerStep)
|
||||
{
|
||||
this.scale = scale;
|
||||
this.mmPerStep = mmPerStep;
|
||||
}
|
||||
public void setScale(float scale)
|
||||
{
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
public float scale(float in)
|
||||
{
|
||||
return in * mmPerStep * scale;
|
||||
}
|
||||
}
|
||||
|
||||
class PreviewVector extends PVector
|
||||
{
|
||||
public String command;
|
||||
}
|
||||
|
||||
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
|
||||
public class Console extends WindowAdapter implements WindowListener, ActionListener, Runnable
|
||||
{
|
||||
private JFrame frame;
|
||||
private JTextArea textArea;
|
||||
private Thread reader;
|
||||
private Thread reader2;
|
||||
private boolean quit;
|
||||
|
||||
private final PipedInputStream pin=new PipedInputStream();
|
||||
private final PipedInputStream pin2=new PipedInputStream();
|
||||
|
||||
private PrintStream cOut = System.out;
|
||||
private PrintStream cErr = System.err;
|
||||
|
||||
Thread errorThrower; // just for testing (Throws an Exception at this Console
|
||||
|
||||
public Console()
|
||||
{
|
||||
// create all components and add them
|
||||
frame=new JFrame("Java Console");
|
||||
Dimension screenSize=Toolkit.getDefaultToolkit().getScreenSize();
|
||||
Dimension frameSize=new Dimension((int)(screenSize.width/2),(int)(screenSize.height/2));
|
||||
int x=(int)(frameSize.width/2);
|
||||
int y=(int)(frameSize.height/2);
|
||||
frame.setBounds(x,y,frameSize.width,frameSize.height);
|
||||
|
||||
textArea=new JTextArea();
|
||||
textArea.setEditable(false);
|
||||
JButton button=new JButton("clear");
|
||||
|
||||
frame.getContentPane().setLayout(new BorderLayout());
|
||||
frame.getContentPane().add(new JScrollPane(textArea),BorderLayout.CENTER);
|
||||
frame.getContentPane().add(button,BorderLayout.SOUTH);
|
||||
frame.setVisible(true);
|
||||
|
||||
frame.addWindowListener(this);
|
||||
button.addActionListener(this);
|
||||
|
||||
try
|
||||
{
|
||||
this.cOut = System.out;
|
||||
PipedOutputStream pout=new PipedOutputStream(this.pin);
|
||||
System.setOut(new PrintStream(pout,true));
|
||||
}
|
||||
catch (java.io.IOException io)
|
||||
{
|
||||
textArea.append("Couldn't redirect STDOUT to this console\n"+io.getMessage());
|
||||
}
|
||||
catch (SecurityException se)
|
||||
{
|
||||
textArea.append("Couldn't redirect STDOUT to this console\n"+se.getMessage());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
this.cErr = System.err;
|
||||
PipedOutputStream pout2=new PipedOutputStream(this.pin2);
|
||||
System.setErr(new PrintStream(pout2,true));
|
||||
}
|
||||
catch (java.io.IOException io)
|
||||
{
|
||||
textArea.append("Couldn't redirect STDERR to this console\n"+io.getMessage());
|
||||
}
|
||||
catch (SecurityException se)
|
||||
{
|
||||
textArea.append("Couldn't redirect STDERR to this console\n"+se.getMessage());
|
||||
}
|
||||
|
||||
quit=false; // signals the Threads that they should exit
|
||||
|
||||
// Starting two seperate threads to read from the PipedInputStreams
|
||||
//
|
||||
reader=new Thread(this);
|
||||
reader.setDaemon(true);
|
||||
reader.start();
|
||||
//
|
||||
reader2=new Thread(this);
|
||||
reader2.setDaemon(true);
|
||||
reader2.start();
|
||||
|
||||
// // testing part
|
||||
// // you may omit this part for your application
|
||||
// //
|
||||
// System.out.println("Hello World 2");
|
||||
// System.out.println("All fonts available to Graphic2D:\n");
|
||||
// GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
// String[] fontNames=ge.getAvailableFontFamilyNames();
|
||||
// for(int n=0;n<fontNames.length;n++) System.out.println(fontNames[n]);
|
||||
// // Testing part: simple an error thrown anywhere in this JVM will be printed on the Console
|
||||
// // We do it with a seperate Thread becasue we don't wan't to break a Thread used by the Console.
|
||||
// System.out.println("\nLets throw an error on this console");
|
||||
// errorThrower=new Thread(this);
|
||||
// errorThrower.setDaemon(true);
|
||||
// errorThrower.start();
|
||||
}
|
||||
|
||||
public synchronized void windowClosed(WindowEvent evt)
|
||||
{
|
||||
quit=true;
|
||||
this.notifyAll(); // stop all threads
|
||||
try {
|
||||
reader.join(1000);
|
||||
pin.close();
|
||||
System.setOut(this.cOut);
|
||||
}
|
||||
catch (Exception e){
|
||||
}
|
||||
try {
|
||||
reader2.join(1000);
|
||||
pin2.close();
|
||||
System.setErr(this.cErr);
|
||||
}
|
||||
catch (Exception e){
|
||||
}
|
||||
// System.exit(0);
|
||||
}
|
||||
|
||||
public synchronized void windowClosing(WindowEvent evt)
|
||||
{
|
||||
frame.setVisible(false); // default behaviour of JFrame
|
||||
frame.dispose();
|
||||
}
|
||||
|
||||
public synchronized void actionPerformed(ActionEvent evt)
|
||||
{
|
||||
textArea.setText("");
|
||||
}
|
||||
|
||||
public synchronized void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
while (Thread.currentThread()==reader)
|
||||
{
|
||||
try {
|
||||
this.wait(100);
|
||||
}
|
||||
catch(InterruptedException ie) {
|
||||
}
|
||||
if (pin.available()!=0)
|
||||
{
|
||||
String input=this.readLine(pin);
|
||||
textArea.append(input);
|
||||
textArea.setCaretPosition(textArea.getDocument().getLength());
|
||||
|
||||
}
|
||||
if (quit) return;
|
||||
}
|
||||
|
||||
while (Thread.currentThread()==reader2)
|
||||
{
|
||||
try {
|
||||
this.wait(100);
|
||||
}
|
||||
catch(InterruptedException ie) {
|
||||
}
|
||||
if (pin2.available()!=0)
|
||||
{
|
||||
String input=this.readLine(pin2);
|
||||
textArea.append(input);
|
||||
textArea.setCaretPosition(textArea.getDocument().getLength());
|
||||
|
||||
}
|
||||
if (quit) return;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
textArea.append("\nConsole reports an Internal error.");
|
||||
textArea.append("The error is: "+e);
|
||||
}
|
||||
}
|
||||
|
||||
public void close()
|
||||
{
|
||||
this.windowClosing(null);
|
||||
}
|
||||
|
||||
public synchronized String readLine(PipedInputStream in) throws IOException
|
||||
{
|
||||
String input="";
|
||||
do
|
||||
{
|
||||
int available=in.available();
|
||||
if (available==0) break;
|
||||
byte b[]=new byte[available];
|
||||
in.read(b);
|
||||
input=input+new String(b,0,b.length);
|
||||
}
|
||||
while( !input.endsWith("\n") && !input.endsWith("\r\n") && !quit);
|
||||
return input;
|
||||
}
|
||||
}
|
235
Panel.pde
Normal file
235
Panel.pde
Normal file
@ -0,0 +1,235 @@
|
||||
/**
|
||||
Polargraph controller
|
||||
Copyright Sandy Noble 2012.
|
||||
|
||||
This file is part of Polargraph Controller.
|
||||
|
||||
Polargraph Controller is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Polargraph Controller is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Polargraph Controller. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Requires the excellent ControlP5 GUI library available from http://www.sojamo.de/libraries/controlP5/.
|
||||
Requires the excellent Geomerative library available from http://www.ricardmarxer.com/geomerative/.
|
||||
|
||||
This is an application for controlling a polargraph machine, communicating using ASCII command language over a serial link.
|
||||
|
||||
sandy.noble@gmail.com
|
||||
http://www.polargraph.co.uk/
|
||||
http://code.google.com/p/polargraph/
|
||||
*/
|
||||
class Panel
|
||||
{
|
||||
private Rectangle outline = null;
|
||||
private String name = null;
|
||||
private List<Controller> controls = null;
|
||||
private Map<String, PVector> controlPositions = null;
|
||||
private Map<String, PVector> controlSizes = null;
|
||||
private boolean resizable = true;
|
||||
private float minimumHeight = DEFAULT_CONTROL_SIZE.y+4;
|
||||
private color outlineColour = color(255);
|
||||
|
||||
public final color CONTROL_COL_BG_DEFAULT = color(0,54,82);
|
||||
public final color CONTROL_COL_BG_DISABLED = color(20,44,62);
|
||||
public final color CONTROL_COL_LABEL_DEFAULT = color(255);
|
||||
public final color CONTROL_COL_LABEL_DISABLED = color(200);
|
||||
|
||||
public Panel(String name, Rectangle outline)
|
||||
{
|
||||
this.name = name;
|
||||
this.outline = outline;
|
||||
}
|
||||
|
||||
public Rectangle getOutline()
|
||||
{
|
||||
return this.outline;
|
||||
}
|
||||
public void setOutline(Rectangle r)
|
||||
{
|
||||
this.outline = r;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public List<Controller> getControls()
|
||||
{
|
||||
if (this.controls == null)
|
||||
this.controls = new ArrayList<Controller>(0);
|
||||
return this.controls;
|
||||
}
|
||||
public void setControls(List<Controller> c)
|
||||
{
|
||||
this.controls = c;
|
||||
}
|
||||
|
||||
public Map<String, PVector> getControlPositions()
|
||||
{
|
||||
return this.controlPositions;
|
||||
}
|
||||
public void setControlPositions(Map<String, PVector> cp)
|
||||
{
|
||||
this.controlPositions = cp;
|
||||
}
|
||||
|
||||
public Map<String, PVector> getControlSizes()
|
||||
{
|
||||
return this.controlSizes;
|
||||
}
|
||||
public void setControlSizes(Map<String, PVector> cs)
|
||||
{
|
||||
this.controlSizes = cs;
|
||||
}
|
||||
|
||||
void setOutlineColour(color c)
|
||||
{
|
||||
this.outlineColour = c;
|
||||
}
|
||||
|
||||
void setResizable(boolean r)
|
||||
{
|
||||
this.resizable = r;
|
||||
}
|
||||
boolean isResizable()
|
||||
{
|
||||
return this.resizable;
|
||||
}
|
||||
|
||||
void setMinimumHeight(float h)
|
||||
{
|
||||
this.minimumHeight = h;
|
||||
}
|
||||
float getMinimumHeight()
|
||||
{
|
||||
return this.minimumHeight;
|
||||
}
|
||||
|
||||
public void draw()
|
||||
{
|
||||
// stroke(outlineColour);
|
||||
// strokeWeight(2);
|
||||
// rect(getOutline().getLeft(), getOutline().getTop(), getOutline().getWidth(), getOutline().getHeight());
|
||||
|
||||
drawControls();
|
||||
}
|
||||
|
||||
public void drawControls()
|
||||
{
|
||||
for (Controller c : this.getControls())
|
||||
{
|
||||
PVector pos = getControlPositions().get(c.name());
|
||||
float x = pos.x+getOutline().getLeft();
|
||||
float y = pos.y+getOutline().getTop();
|
||||
c.setPosition(x, y);
|
||||
|
||||
PVector cSize = getControlSizes().get(c.name());
|
||||
c.setSize((int)cSize.x, (int)cSize.y);
|
||||
|
||||
boolean locked = false;
|
||||
|
||||
// theres a few cases here where the controls are locked (disabled)
|
||||
|
||||
// any drawing / extracting controls are disabled if there is no selec
|
||||
// box specified.
|
||||
if (getControlsToLockIfBoxNotSpecified().contains(c.name()) && !isBoxSpecified())
|
||||
{
|
||||
locked = true;
|
||||
}
|
||||
|
||||
// if there is no vector shape loaded then lock the "draw vector"
|
||||
// control.
|
||||
if (c.name().equals(MODE_RENDER_VECTORS) && getVectorShape() == null)
|
||||
{
|
||||
locked = true;
|
||||
}
|
||||
|
||||
// if there's no image loaded, then hide resizing/moving
|
||||
if (getControlsToLockIfImageNotLoaded().contains(c.name()) && getDisplayMachine().getImage() == null)
|
||||
{
|
||||
locked = true;
|
||||
}
|
||||
|
||||
if (c.name().equals(MODE_LOAD_VECTOR_FILE))
|
||||
{
|
||||
if (getVectorShape() != null)
|
||||
c.setLabel("Clear vector");
|
||||
else
|
||||
c.setLabel("Load vector");
|
||||
}
|
||||
else if (c.name().equals(MODE_LOAD_IMAGE))
|
||||
{
|
||||
if (getDisplayMachine().getImage() != null)
|
||||
c.setLabel("Clear image");
|
||||
else
|
||||
c.setLabel("Load image file");
|
||||
}
|
||||
|
||||
|
||||
int col = c.getColor().getBackground();
|
||||
setLock(c, locked);
|
||||
}
|
||||
}
|
||||
|
||||
void setLock(Controller c, boolean locked)
|
||||
{
|
||||
c.setLock(locked);
|
||||
if (locked)
|
||||
{
|
||||
c.setColorBackground(CONTROL_COL_BG_DISABLED);
|
||||
c.setColorLabel(CONTROL_COL_LABEL_DISABLED);
|
||||
}
|
||||
else
|
||||
{
|
||||
c.setColorBackground(CONTROL_COL_BG_DEFAULT);
|
||||
c.setColorLabel(CONTROL_COL_LABEL_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
void setHeight(float h)
|
||||
{
|
||||
if (this.isResizable())
|
||||
{
|
||||
if (h <= getMinimumHeight())
|
||||
this.getOutline().setHeight(getMinimumHeight());
|
||||
else
|
||||
this.getOutline().setHeight(h);
|
||||
setControlPositions(buildControlPositionsForPanel(this));
|
||||
|
||||
float left = 0.0;
|
||||
String controlName = "";
|
||||
for (String key : getControlPositions().keySet())
|
||||
{
|
||||
PVector pos = getControlPositions().get(key);
|
||||
if (pos.x >= left)
|
||||
{
|
||||
left = pos.x;
|
||||
controlName = key;
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, PVector> map = getControlSizes();
|
||||
|
||||
// PVector size = getControlSizes().get(controlName);
|
||||
// println("size: " + size);
|
||||
float right = left + DEFAULT_CONTROL_SIZE.x;
|
||||
|
||||
this.getOutline().setWidth(right);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
121
Rectangle.pde
Normal file
121
Rectangle.pde
Normal file
@ -0,0 +1,121 @@
|
||||
/**
|
||||
Polargraph controller
|
||||
Copyright Sandy Noble 2012.
|
||||
|
||||
This file is part of Polargraph Controller.
|
||||
|
||||
Polargraph Controller is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Polargraph Controller is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Polargraph Controller. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Requires the excellent ControlP5 GUI library available from http://www.sojamo.de/libraries/controlP5/.
|
||||
Requires the excellent Geomerative library available from http://www.ricardmarxer.com/geomerative/.
|
||||
|
||||
This is an application for controlling a polargraph machine, communicating using ASCII command language over a serial link.
|
||||
|
||||
sandy.noble@gmail.com
|
||||
http://www.polargraph.co.uk/
|
||||
http://code.google.com/p/polargraph/
|
||||
*/
|
||||
class Rectangle
|
||||
{
|
||||
public PVector position = null;
|
||||
public PVector size = null;
|
||||
|
||||
public Rectangle(float px, float py, float width, float height)
|
||||
{
|
||||
this.position = new PVector(px, py);
|
||||
this.size = new PVector(width, height);
|
||||
}
|
||||
public Rectangle(PVector position, PVector size)
|
||||
{
|
||||
this.position = position;
|
||||
this.size = size;
|
||||
}
|
||||
public Rectangle(Rectangle r)
|
||||
{
|
||||
this.position = new PVector(r.getPosition().x, r.getPosition().y);
|
||||
this.size = new PVector(r.getSize().x, r.getSize().y);
|
||||
}
|
||||
|
||||
public float getWidth()
|
||||
{
|
||||
return this.size.x;
|
||||
}
|
||||
public void setWidth(float w)
|
||||
{
|
||||
this.size.x = w;
|
||||
}
|
||||
public float getHeight()
|
||||
{
|
||||
return this.size.y;
|
||||
}
|
||||
public void setHeight(float h)
|
||||
{
|
||||
this.size.y = h;
|
||||
}
|
||||
public PVector getPosition()
|
||||
{
|
||||
return this.position;
|
||||
}
|
||||
public PVector getSize()
|
||||
{
|
||||
return this.size;
|
||||
}
|
||||
public PVector getTopLeft()
|
||||
{
|
||||
return getPosition();
|
||||
}
|
||||
public PVector getBotRight()
|
||||
{
|
||||
return PVector.add(this.position, this.size);
|
||||
}
|
||||
public float getLeft()
|
||||
{
|
||||
return getPosition().x;
|
||||
}
|
||||
public float getRight()
|
||||
{
|
||||
return getPosition().x + getSize().x;
|
||||
}
|
||||
public float getTop()
|
||||
{
|
||||
return getPosition().y;
|
||||
}
|
||||
public float getBottom()
|
||||
{
|
||||
return getPosition().y + getSize().y;
|
||||
}
|
||||
|
||||
public void setPosition(float x, float y)
|
||||
{
|
||||
if (this.position == null)
|
||||
this.position = new PVector(x, y);
|
||||
else
|
||||
{
|
||||
this.position.x = x;
|
||||
this.position.y = y;
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean surrounds(PVector p)
|
||||
{
|
||||
if (p.x >= this.getLeft()
|
||||
&& p.x < this.getRight()
|
||||
&& p.y >= this.getTop()
|
||||
&& p.y < this.getBottom()-1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
1107
controlsActions.pde
Normal file
1107
controlsActions.pde
Normal file
File diff suppressed because it is too large
Load Diff
957
controlsSetup.pde
Normal file
957
controlsSetup.pde
Normal file
@ -0,0 +1,957 @@
|
||||
/**
|
||||
Polargraph controller
|
||||
Copyright Sandy Noble 2012.
|
||||
|
||||
This file is part of Polargraph Controller.
|
||||
|
||||
Polargraph Controller is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Polargraph Controller is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Polargraph Controller. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Requires the excellent ControlP5 GUI library available from http://www.sojamo.de/libraries/controlP5/.
|
||||
Requires the excellent Geomerative library available from http://www.ricardmarxer.com/geomerative/.
|
||||
|
||||
This is an application for controlling a polargraph machine, communicating using ASCII command language over a serial link.
|
||||
|
||||
sandy.noble@gmail.com
|
||||
http://www.polargraph.co.uk/
|
||||
http://code.google.com/p/polargraph/
|
||||
*/
|
||||
Set<String> getPanelNames()
|
||||
{
|
||||
if (this.panelNames == null)
|
||||
this.panelNames = buildPanelNames();
|
||||
return this.panelNames;
|
||||
}
|
||||
List<String> getTabNames()
|
||||
{
|
||||
if (this.tabNames == null)
|
||||
this.tabNames = buildTabNames();
|
||||
return this.tabNames;
|
||||
}
|
||||
Set<String> getControlNames()
|
||||
{
|
||||
if (this.controlNames == null)
|
||||
this.controlNames = buildControlNames();
|
||||
return this.controlNames;
|
||||
}
|
||||
Map<String, List<Controller>> getControlsForPanels()
|
||||
{
|
||||
if (this.controlsForPanels == null)
|
||||
this.controlsForPanels = buildControlsForPanels();
|
||||
return this.controlsForPanels;
|
||||
}
|
||||
Map<String, Controller> getAllControls()
|
||||
{
|
||||
if (this.allControls == null)
|
||||
this.allControls = buildAllControls();
|
||||
return this.allControls;
|
||||
}
|
||||
Map<String, String> getControlLabels()
|
||||
{
|
||||
if (this.controlLabels == null)
|
||||
this.controlLabels = buildControlLabels();
|
||||
return this.controlLabels;
|
||||
}
|
||||
Map<String, Set<Panel>> getPanelsForTabs()
|
||||
{
|
||||
if (this.panelsForTabs == null)
|
||||
this.panelsForTabs = buildPanelsForTabs();
|
||||
return this.panelsForTabs;
|
||||
}
|
||||
Map<String, Panel> getPanels()
|
||||
{
|
||||
if (this.panels == null)
|
||||
this.panels = buildPanels();
|
||||
return this.panels;
|
||||
}
|
||||
|
||||
Set<String> getControlsToLockIfBoxNotSpecified()
|
||||
{
|
||||
if (this.controlsToLockIfBoxNotSpecified == null)
|
||||
{
|
||||
this.controlsToLockIfBoxNotSpecified = buildControlsToLockIfBoxNotSpecified();
|
||||
}
|
||||
return this.controlsToLockIfBoxNotSpecified;
|
||||
}
|
||||
|
||||
Set<String> getControlsToLockIfImageNotLoaded()
|
||||
{
|
||||
if (this.controlsToLockIfImageNotLoaded == null)
|
||||
{
|
||||
this.controlsToLockIfImageNotLoaded = buildControlsToLockIfImageNotLoaded();
|
||||
}
|
||||
return this.controlsToLockIfImageNotLoaded;
|
||||
}
|
||||
|
||||
|
||||
void hideAllControls()
|
||||
{
|
||||
for (String key : allControls.keySet())
|
||||
{
|
||||
Controller c = allControls.get(key);
|
||||
c.hide();
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Panel> buildPanels()
|
||||
{
|
||||
Map<String, Panel> panels = new HashMap<String, Panel>();
|
||||
|
||||
float panelHeight = frame.getHeight() - getMainPanelPosition().y - (DEFAULT_CONTROL_SIZE.y*3);
|
||||
Rectangle panelOutline = new Rectangle(getMainPanelPosition(),
|
||||
new PVector((DEFAULT_CONTROL_SIZE.x+CONTROL_SPACING.x)*2, panelHeight));
|
||||
Panel inputPanel = new Panel(PANEL_NAME_INPUT, panelOutline);
|
||||
inputPanel.setResizable(true);
|
||||
inputPanel.setOutlineColour(color(200, 200, 200));
|
||||
// get controls
|
||||
inputPanel.setControls(getControlsForPanels().get(PANEL_NAME_INPUT));
|
||||
// get control positions
|
||||
inputPanel.setControlPositions(buildControlPositionsForPanel(inputPanel));
|
||||
inputPanel.setControlSizes(buildControlSizesForPanel(inputPanel));
|
||||
panels.put(PANEL_NAME_INPUT, inputPanel);
|
||||
|
||||
Panel rovingPanel = new Panel(PANEL_NAME_ROVING, panelOutline);
|
||||
rovingPanel.setOutlineColour(color(200,200,200));
|
||||
// get controls
|
||||
rovingPanel.setResizable(true);
|
||||
rovingPanel.setControls(getControlsForPanels().get(PANEL_NAME_ROVING));
|
||||
// get control positions
|
||||
rovingPanel.setControlPositions(buildControlPositionsForPanel(rovingPanel));
|
||||
rovingPanel.setControlSizes(buildControlSizesForPanel(rovingPanel));
|
||||
panels.put(PANEL_NAME_ROVING, rovingPanel);
|
||||
|
||||
Panel detailsPanel = new Panel(PANEL_NAME_DETAILS, panelOutline);
|
||||
detailsPanel.setOutlineColour(color(200, 200, 200));
|
||||
// get controls
|
||||
detailsPanel.setResizable(true);
|
||||
detailsPanel.setControls(getControlsForPanels().get(PANEL_NAME_DETAILS));
|
||||
// get control positions
|
||||
detailsPanel.setControlPositions(buildControlPositionsForPanel(detailsPanel));
|
||||
detailsPanel.setControlSizes(buildControlSizesForPanel(detailsPanel));
|
||||
panels.put(PANEL_NAME_DETAILS, detailsPanel);
|
||||
|
||||
Panel queuePanel = new Panel(PANEL_NAME_QUEUE, panelOutline);
|
||||
queuePanel.setOutlineColour(color(200, 200, 200));
|
||||
// get controls
|
||||
queuePanel.setResizable(true);
|
||||
queuePanel.setControls(getControlsForPanels().get(PANEL_NAME_QUEUE));
|
||||
// get control positions
|
||||
queuePanel.setControlPositions(buildControlPositionsForPanel(queuePanel));
|
||||
queuePanel.setControlSizes(buildControlSizesForPanel(queuePanel));
|
||||
panels.put(PANEL_NAME_QUEUE, queuePanel);
|
||||
|
||||
panelOutline = new Rectangle(
|
||||
new PVector(getMainPanelPosition().x, getMainPanelPosition().y-((DEFAULT_CONTROL_SIZE.y+CONTROL_SPACING.y)*2)),
|
||||
new PVector((DEFAULT_CONTROL_SIZE.x+CONTROL_SPACING.x)*2, (DEFAULT_CONTROL_SIZE.y+CONTROL_SPACING.y)*2));
|
||||
Panel generalPanel = new Panel(PANEL_NAME_GENERAL, panelOutline);
|
||||
generalPanel.setResizable(false);
|
||||
generalPanel.setOutlineColour(color(200, 200, 200));
|
||||
// get controls
|
||||
generalPanel.setControls(getControlsForPanels().get(PANEL_NAME_GENERAL));
|
||||
// get control positions
|
||||
generalPanel.setControlPositions(buildControlPositionsForPanel(generalPanel));
|
||||
generalPanel.setControlSizes(buildControlSizesForPanel(generalPanel));
|
||||
panels.put(PANEL_NAME_GENERAL, generalPanel);
|
||||
|
||||
return panels;
|
||||
}
|
||||
|
||||
PVector getMainPanelPosition()
|
||||
{
|
||||
return this.mainPanelPosition;
|
||||
}
|
||||
|
||||
void updateNumberboxValues()
|
||||
{
|
||||
initialiseNumberboxValues(getAllControls());
|
||||
}
|
||||
|
||||
Set<String> buildControlsToLockIfBoxNotSpecified()
|
||||
{
|
||||
Set<String> result = new HashSet<String>();
|
||||
result.add(MODE_DRAW_OUTLINE_BOX);
|
||||
result.add(MODE_DRAW_OUTLINE_BOX_ROWS);
|
||||
result.add(MODE_DRAW_SHADE_BOX_ROWS_PIXELS);
|
||||
result.add(MODE_RENDER_SQUARE_PIXELS);
|
||||
result.add(MODE_RENDER_SCALED_SQUARE_PIXELS);
|
||||
result.add(MODE_RENDER_SAW_PIXELS);
|
||||
result.add(MODE_RENDER_CIRCLE_PIXELS);
|
||||
result.add(MODE_RENDER_PIXEL_DIALOG);
|
||||
result.add(MODE_DRAW_GRID);
|
||||
result.add(MODE_DRAW_TESTPATTERN);
|
||||
result.add(MODE_RENDER_SOLID_SQUARE_PIXELS);
|
||||
result.add(MODE_RENDER_SCRIBBLE_PIXELS);
|
||||
result.add(MODE_CONVERT_BOX_TO_PICTUREFRAME);
|
||||
result.add(MODE_IMAGE_PIXEL_BRIGHT_THRESHOLD);
|
||||
result.add(MODE_IMAGE_PIXEL_DARK_THRESHOLD);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Set<String> buildControlsToLockIfImageNotLoaded()
|
||||
{
|
||||
Set<String> result = new HashSet<String>();
|
||||
result.add(MODE_MOVE_IMAGE);
|
||||
result.add(MODE_RESIZE_IMAGE);
|
||||
// result.add(MODE_INPUT_BOX_TOP_LEFT);
|
||||
result.add(MODE_CHANGE_GRID_SIZE);
|
||||
result.add(MODE_CHANGE_SAMPLE_AREA);
|
||||
result.add(MODE_SELECT_PICTUREFRAME);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Map<String, Controller> buildAllControls()
|
||||
{
|
||||
|
||||
Map<String, Controller> map = new HashMap<String, Controller>();
|
||||
|
||||
for (String controlName : getControlNames())
|
||||
{
|
||||
if (controlName.startsWith("button_"))
|
||||
{
|
||||
Button b = cp5.addButton(controlName, 0, 100, 100, 100, 100);
|
||||
b.setLabel(getControlLabels().get(controlName));
|
||||
b.hide();
|
||||
map.put(controlName, b);
|
||||
// println("Added button " + controlName);
|
||||
}
|
||||
else if (controlName.startsWith("toggle_"))
|
||||
{
|
||||
Toggle t = cp5.addToggle(controlName, false, 100, 100, 100, 100);
|
||||
t.setLabel(getControlLabels().get(controlName));
|
||||
t.hide();
|
||||
controlP5.Label l = t.captionLabel();
|
||||
l.style().marginTop = -17; //move upwards (relative to button size)
|
||||
l.style().marginLeft = 4; //move to the right
|
||||
map.put(controlName, t);
|
||||
// println("Added toggle " + controlName);
|
||||
}
|
||||
else if (controlName.startsWith("minitoggle_"))
|
||||
{
|
||||
Toggle t = cp5.addToggle(controlName, false, 100, 100, 100, 100);
|
||||
t.setLabel(getControlLabels().get(controlName));
|
||||
t.hide();
|
||||
controlP5.Label l = t.captionLabel();
|
||||
l.style().marginTop = -17; //move upwards (relative to button size)
|
||||
l.style().marginLeft = 4; //move to the right
|
||||
map.put(controlName, t);
|
||||
// println("Added minitoggle " + controlName);
|
||||
}
|
||||
else if (controlName.startsWith("numberbox_"))
|
||||
{
|
||||
Numberbox n = cp5.addNumberbox(controlName, 100, 100, 100, 100, 20);
|
||||
n.setLabel(getControlLabels().get(controlName));
|
||||
n.hide();
|
||||
n.setDecimalPrecision(0);
|
||||
controlP5.Label l = n.captionLabel();
|
||||
l.style().marginTop = -17; //move upwards (relative to button size)
|
||||
l.style().marginLeft = 40; //move to the right
|
||||
// change the control direction to left/right
|
||||
n.setDirection(Controller.VERTICAL);
|
||||
map.put(controlName, n);
|
||||
// println("Added numberbox " + controlName);
|
||||
}
|
||||
}
|
||||
|
||||
initialiseMiniToggleValues(map);
|
||||
initialiseNumberboxValues(map);
|
||||
return map;
|
||||
}
|
||||
|
||||
Map<String, Controller> initialiseNumberboxValues(Map<String, Controller> map)
|
||||
{
|
||||
for (String key : map.keySet())
|
||||
{
|
||||
if (key.startsWith("numberbox_"))
|
||||
{
|
||||
Numberbox n = (Numberbox) map.get(key);
|
||||
|
||||
if (MODE_CHANGE_SAMPLE_AREA.equals(key))
|
||||
{
|
||||
n.setValue(getSampleArea());
|
||||
n.setMin(1);
|
||||
n.setMultiplier(1);
|
||||
}
|
||||
else if (MODE_CHANGE_GRID_SIZE.equals(key))
|
||||
{
|
||||
n.setValue(getGridSize());
|
||||
n.setMin(20);
|
||||
n.setMultiplier(0.5);
|
||||
}
|
||||
else if (MODE_CHANGE_MACHINE_WIDTH.equals(key))
|
||||
{
|
||||
println("key:"+key+", width: " + getDisplayMachine().getWidth() + ", multiplied:"+getDisplayMachine().inMM(getDisplayMachine().getWidth()));
|
||||
n.setValue(getDisplayMachine().inMM(getDisplayMachine().getWidth()));
|
||||
n.setMin(20);
|
||||
n.setMultiplier(0.5);
|
||||
}
|
||||
else if (MODE_RESIZE_IMAGE.equals(key))
|
||||
{
|
||||
n.setValue(getDisplayMachine().inMM(getDisplayMachine().getImageFrame().getWidth()));
|
||||
n.setMin(20);
|
||||
n.setMultiplier(1);
|
||||
}
|
||||
else if (MODE_CHANGE_MACHINE_HEIGHT.equals(key))
|
||||
{
|
||||
n.setValue(getDisplayMachine().inMM(getDisplayMachine().getHeight()));
|
||||
n.setMin(20);
|
||||
n.setMultiplier(0.5);
|
||||
}
|
||||
else if (MODE_CHANGE_MM_PER_REV.equals(key))
|
||||
{
|
||||
n.setValue(getDisplayMachine().getMMPerRev());
|
||||
n.setMin(20);
|
||||
n.setMultiplier(0.5);
|
||||
}
|
||||
else if (MODE_CHANGE_STEPS_PER_REV.equals(key))
|
||||
{
|
||||
n.setValue(getDisplayMachine().getStepsPerRev());
|
||||
n.setMin(20);
|
||||
n.setMultiplier(0.5);
|
||||
}
|
||||
else if (MODE_CHANGE_STEP_MULTIPLIER.equals(key))
|
||||
{
|
||||
n.setValue(machineStepMultiplier);
|
||||
n.setMin(1);
|
||||
n.setMax(16);
|
||||
n.setMultiplier(0.01);
|
||||
}
|
||||
else if (MODE_CHANGE_PAGE_WIDTH.equals(key))
|
||||
{
|
||||
n.setValue(getDisplayMachine().inMM(getDisplayMachine().getPage().getWidth()));
|
||||
n.setMin(10);
|
||||
n.setMultiplier(0.5);
|
||||
}
|
||||
else if (MODE_CHANGE_PAGE_HEIGHT.equals(key))
|
||||
{
|
||||
n.setValue(getDisplayMachine().inMM(getDisplayMachine().getPage().getHeight()));
|
||||
n.setMin(10);
|
||||
n.setMultiplier(0.5);
|
||||
}
|
||||
else if (MODE_CHANGE_PAGE_OFFSET_X.equals(key))
|
||||
{
|
||||
n.setValue(getDisplayMachine().inMM(getDisplayMachine().getPage().getLeft()));
|
||||
n.setMin(0);
|
||||
n.setMultiplier(0.5);
|
||||
}
|
||||
else if (MODE_CHANGE_PAGE_OFFSET_Y.equals(key))
|
||||
{
|
||||
n.setValue(getDisplayMachine().inMM(getDisplayMachine().getPage().getTop()));
|
||||
n.setMin(0);
|
||||
n.setMultiplier(0.5);
|
||||
}
|
||||
else if (MODE_CHANGE_HOMEPOINT_X.equals(key))
|
||||
{
|
||||
n.setValue(getDisplayMachine().inMM(getHomePoint().x));
|
||||
n.setMin(0);
|
||||
n.setMultiplier(0.5);
|
||||
}
|
||||
else if (MODE_CHANGE_HOMEPOINT_Y.equals(key))
|
||||
{
|
||||
n.setValue(getDisplayMachine().inMM(getHomePoint().y));
|
||||
n.setMin(0);
|
||||
n.setMultiplier(0.5);
|
||||
}
|
||||
else if (MODE_CHANGE_PEN_WIDTH.equals(key))
|
||||
{
|
||||
n.setDecimalPrecision(2);
|
||||
n.setValue(currentPenWidth);
|
||||
n.setMin(0.01);
|
||||
n.setMultiplier(0.01);
|
||||
}
|
||||
else if (MODE_CHANGE_PEN_TEST_START_WIDTH.equals(key))
|
||||
{
|
||||
n.setDecimalPrecision(2);
|
||||
n.setValue(testPenWidthStartSize);
|
||||
n.setMin(0.01);
|
||||
n.setMultiplier(0.01);
|
||||
}
|
||||
else if (MODE_CHANGE_PEN_TEST_END_WIDTH.equals(key))
|
||||
{
|
||||
n.setDecimalPrecision(2);
|
||||
n.setValue(testPenWidthEndSize);
|
||||
n.setMin(0.01);
|
||||
n.setMultiplier(0.01);
|
||||
}
|
||||
else if (MODE_CHANGE_PEN_TEST_INCREMENT_SIZE.equals(key))
|
||||
{
|
||||
n.setDecimalPrecision(2);
|
||||
n.setValue(testPenWidthIncrementSize);
|
||||
n.setMin(0.01);
|
||||
n.setMultiplier(0.01);
|
||||
}
|
||||
else if (MODE_CHANGE_MACHINE_MAX_SPEED.equals(key))
|
||||
{
|
||||
n.setDecimalPrecision(0);
|
||||
n.setValue(currentMachineMaxSpeed);
|
||||
n.setMin(1);
|
||||
n.setMultiplier(1);
|
||||
}
|
||||
else if (MODE_CHANGE_MACHINE_ACCELERATION.equals(key))
|
||||
{
|
||||
n.setDecimalPrecision(0);
|
||||
n.setValue(currentMachineAccel);
|
||||
n.setMin(1);
|
||||
n.setMultiplier(1);
|
||||
}
|
||||
else if (MODE_IMAGE_PIXEL_BRIGHT_THRESHOLD.equals(key))
|
||||
{
|
||||
n.setDecimalPrecision(0);
|
||||
n.setValue(pixelExtractBrightThreshold);
|
||||
n.setMin(0);
|
||||
n.setMax(255);
|
||||
n.setMultiplier(0.5);
|
||||
}
|
||||
else if (MODE_IMAGE_PIXEL_DARK_THRESHOLD.equals(key))
|
||||
{
|
||||
n.setDecimalPrecision(0);
|
||||
n.setValue(pixelExtractDarkThreshold);
|
||||
n.setMin(0);
|
||||
n.setMax(255);
|
||||
n.setMultiplier(0.5);
|
||||
}
|
||||
else if (MODE_RESIZE_VECTOR.equals(key))
|
||||
{
|
||||
n.setDecimalPrecision(0);
|
||||
n.setValue(vectorScaling);
|
||||
n.setMin(1);
|
||||
n.setMax(1000);
|
||||
n.setMultiplier(0.5);
|
||||
}
|
||||
else if (MODE_CHANGE_PIXEL_SCALING.equals(key))
|
||||
{
|
||||
n.setDecimalPrecision(2);
|
||||
n.setValue(pixelScalingOverGridSize);
|
||||
n.setMin(0.1);
|
||||
n.setMax(4.0);
|
||||
n.setMultiplier(0.01);
|
||||
}
|
||||
else if (MODE_CHANGE_MIN_VECTOR_LINE_LENGTH.equals(key))
|
||||
{
|
||||
n.setValue(minimumVectorLineLength);
|
||||
n.setMin(0);
|
||||
n.setMultiplier(0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
Map<String, Controller> initialiseMiniToggleValues(Map<String, Controller> map)
|
||||
{
|
||||
for (String key : map.keySet())
|
||||
{
|
||||
if (MODE_SHOW_DENSITY_PREVIEW.equals(key))
|
||||
{
|
||||
Toggle t = (Toggle) map.get(key);
|
||||
t.setValue((displayingDensityPreview) ? 1 : 0);
|
||||
}
|
||||
if (MODE_SHOW_QUEUE_PREVIEW.equals(key))
|
||||
{
|
||||
Toggle t = (Toggle) map.get(key);
|
||||
t.setValue((displayingQueuePreview) ? 1 : 0);
|
||||
}
|
||||
if (MODE_SHOW_IMAGE.equals(key))
|
||||
{
|
||||
Toggle t = (Toggle) map.get(key);
|
||||
t.setValue((displayingImage) ? 1 : 0);
|
||||
}
|
||||
if (MODE_SHOW_VECTOR.equals(key))
|
||||
{
|
||||
Toggle t = (Toggle) map.get(key);
|
||||
t.setValue((displayingVector) ? 1 : 0);
|
||||
}
|
||||
if (MODE_SHOW_GUIDES.equals(key))
|
||||
{
|
||||
Toggle t = (Toggle) map.get(key);
|
||||
t.setValue((displayingGuides) ? 1 : 0);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
String getControlLabel(String butName)
|
||||
{
|
||||
if (controlLabels.containsKey(butName))
|
||||
return controlLabels.get(butName);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
Map<String, PVector> buildControlPositionsForPanel(Panel panel)
|
||||
{
|
||||
Map<String, PVector> map = new HashMap<String, PVector>();
|
||||
String panelName = panel.getName();
|
||||
int col = 0;
|
||||
int row = 0;
|
||||
for (Controller controller : panel.getControls())
|
||||
{
|
||||
if (controller.name().startsWith("minitoggle_"))
|
||||
{
|
||||
PVector p = new PVector(col*(DEFAULT_CONTROL_SIZE.x+CONTROL_SPACING.x), row*(DEFAULT_CONTROL_SIZE.y+CONTROL_SPACING.y));
|
||||
map.put(controller.name(), p);
|
||||
row++;
|
||||
if (p.y + (DEFAULT_CONTROL_SIZE.y*2) >= panel.getOutline().getHeight())
|
||||
{
|
||||
row = 0;
|
||||
col++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PVector p = new PVector(col*(DEFAULT_CONTROL_SIZE.x+CONTROL_SPACING.x), row*(DEFAULT_CONTROL_SIZE.y+CONTROL_SPACING.y));
|
||||
map.put(controller.name(), p);
|
||||
row++;
|
||||
if (p.y + (DEFAULT_CONTROL_SIZE.y*2) >= panel.getOutline().getHeight())
|
||||
{
|
||||
row = 0;
|
||||
col++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
Map<String, PVector> buildControlSizesForPanel(Panel panel)
|
||||
{
|
||||
Map<String, PVector> map = new HashMap<String, PVector>();
|
||||
String panelName = panel.getName();
|
||||
int col = 0;
|
||||
int row = 0;
|
||||
for (Controller controller : panel.getControls())
|
||||
{
|
||||
if (controller.name().startsWith("minitoggle_"))
|
||||
{
|
||||
PVector s = new PVector(DEFAULT_CONTROL_SIZE.y, DEFAULT_CONTROL_SIZE.y);
|
||||
map.put(controller.name(), s);
|
||||
}
|
||||
else
|
||||
{
|
||||
PVector s = new PVector(DEFAULT_CONTROL_SIZE.x, DEFAULT_CONTROL_SIZE.y);
|
||||
map.put(controller.name(), s);
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
Map<String, List<Controller>> buildControlsForPanels()
|
||||
{
|
||||
// println("build controls for panels.");
|
||||
Map<String, List<Controller>> map = new HashMap<String, List<Controller>>();
|
||||
map.put(PANEL_NAME_INPUT, getControllersForControllerNames(getControlNamesForInputPanel()));
|
||||
map.put(PANEL_NAME_ROVING, getControllersForControllerNames(getControlNamesForRovingPanel()));
|
||||
map.put(PANEL_NAME_DETAILS, getControllersForControllerNames(getControlNamesForDetailPanel()));
|
||||
map.put(PANEL_NAME_QUEUE, getControllersForControllerNames(getControlNamesForQueuePanel()));
|
||||
map.put(PANEL_NAME_GENERAL, getControllersForControllerNames(getControlNamesForGeneralPanel()));
|
||||
return map;
|
||||
}
|
||||
|
||||
List<Controller> getControllersForControllerNames(List<String> names)
|
||||
{
|
||||
List<Controller> list = new ArrayList<Controller>();
|
||||
for (String name : names)
|
||||
{
|
||||
Controller c = getAllControls().get(name);
|
||||
if (c != null)
|
||||
list.add(c);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/* This creates a list of control names for the input panel. */
|
||||
List<String> getControlNamesForInputPanel()
|
||||
{
|
||||
List<String> controlNames = new ArrayList<String>();
|
||||
controlNames.add(MODE_CLEAR_QUEUE);
|
||||
controlNames.add(MODE_SET_POSITION_HOME);
|
||||
controlNames.add(MODE_SET_POSITION);
|
||||
controlNames.add(MODE_DRAW_TO_POSITION);
|
||||
controlNames.add(MODE_DRAW_DIRECT);
|
||||
controlNames.add(MODE_RETURN_TO_HOME);
|
||||
controlNames.add(MODE_PEN_LIFT_UP);
|
||||
controlNames.add(MODE_PEN_LIFT_DOWN);
|
||||
controlNames.add(MODE_INPUT_BOX_TOP_LEFT);
|
||||
controlNames.add(MODE_CONVERT_BOX_TO_PICTUREFRAME);
|
||||
controlNames.add(MODE_SELECT_PICTUREFRAME);
|
||||
controlNames.add(MODE_LOAD_IMAGE);
|
||||
controlNames.add(MODE_MOVE_IMAGE);
|
||||
controlNames.add(MODE_RESIZE_IMAGE);
|
||||
controlNames.add(MODE_IMAGE_PIXEL_BRIGHT_THRESHOLD);
|
||||
controlNames.add(MODE_IMAGE_PIXEL_DARK_THRESHOLD);
|
||||
controlNames.add(MODE_CHANGE_GRID_SIZE);
|
||||
controlNames.add(MODE_CHANGE_SAMPLE_AREA);
|
||||
controlNames.add(MODE_CHOOSE_CHROMA_KEY_COLOUR);
|
||||
controlNames.add(MODE_CHANGE_PIXEL_SCALING);
|
||||
|
||||
controlNames.add(MODE_RENDER_PIXEL_DIALOG);
|
||||
controlNames.add(MODE_DRAW_GRID);
|
||||
controlNames.add(MODE_DRAW_OUTLINE_BOX);
|
||||
controlNames.add(MODE_DRAW_OUTLINE_BOX_ROWS);
|
||||
controlNames.add(MODE_DRAW_SHADE_BOX_ROWS_PIXELS);
|
||||
|
||||
controlNames.add(MODE_LOAD_VECTOR_FILE);
|
||||
controlNames.add(MODE_RESIZE_VECTOR);
|
||||
controlNames.add(MODE_MOVE_VECTOR);
|
||||
controlNames.add(MODE_CHANGE_MIN_VECTOR_LINE_LENGTH);
|
||||
controlNames.add(MODE_RENDER_VECTORS);
|
||||
|
||||
controlNames.add(MODE_SHOW_IMAGE);
|
||||
controlNames.add(MODE_SHOW_VECTOR);
|
||||
controlNames.add(MODE_SHOW_QUEUE_PREVIEW);
|
||||
controlNames.add(MODE_SHOW_DENSITY_PREVIEW);
|
||||
controlNames.add(MODE_SHOW_GUIDES);
|
||||
|
||||
|
||||
return controlNames;
|
||||
}
|
||||
|
||||
List<String> getControlNamesForRovingPanel()
|
||||
{
|
||||
List<String> controlNames = new ArrayList<String>();
|
||||
controlNames.add(MODE_CLEAR_QUEUE);
|
||||
controlNames.add(MODE_INPUT_BOX_TOP_LEFT);
|
||||
controlNames.add(MODE_CONVERT_BOX_TO_PICTUREFRAME);
|
||||
controlNames.add(MODE_SELECT_PICTUREFRAME);
|
||||
controlNames.add(MODE_SEND_ROVE_AREA);
|
||||
controlNames.add(MODE_SEND_START_TEXT);
|
||||
controlNames.add(MODE_CHANGE_GRID_SIZE);
|
||||
controlNames.add(MODE_SHOW_WRITING_DIALOG);
|
||||
// controlNames.add(MODE_START_SWIRLING);
|
||||
// controlNames.add(MODE_STOP_SWIRLING);
|
||||
// controlNames.add(MODE_START_SPRITE);
|
||||
// controlNames.add(MODE_START_RANDOM_SPRITES);
|
||||
// controlNames.add(MODE_STOP_RANDOM_SPRITES);
|
||||
controlNames.add(MODE_DRAW_NORWEGIAN_DIALOG);
|
||||
|
||||
return controlNames;
|
||||
}
|
||||
|
||||
List<String> getControlNamesForDetailPanel()
|
||||
{
|
||||
List<String> controlNames = new ArrayList<String>();
|
||||
controlNames.add(MODE_CHANGE_MACHINE_SPEC);
|
||||
controlNames.add(MODE_REQUEST_MACHINE_SIZE);
|
||||
controlNames.add(MODE_RESET_MACHINE);
|
||||
|
||||
controlNames.add(MODE_CHANGE_MM_PER_REV);
|
||||
controlNames.add(MODE_CHANGE_STEPS_PER_REV);
|
||||
controlNames.add(MODE_CHANGE_STEP_MULTIPLIER);
|
||||
controlNames.add(MODE_CHANGE_MACHINE_WIDTH);
|
||||
controlNames.add(MODE_CHANGE_MACHINE_HEIGHT);
|
||||
controlNames.add(MODE_CHANGE_PAGE_WIDTH);
|
||||
controlNames.add(MODE_CHANGE_PAGE_HEIGHT);
|
||||
controlNames.add(MODE_CHANGE_PAGE_OFFSET_X);
|
||||
controlNames.add(MODE_CHANGE_PAGE_OFFSET_Y);
|
||||
controlNames.add(MODE_CHANGE_PAGE_OFFSET_X_CENTRE);
|
||||
|
||||
controlNames.add(MODE_CHANGE_HOMEPOINT_X);
|
||||
controlNames.add(MODE_CHANGE_HOMEPOINT_Y);
|
||||
controlNames.add(MODE_CHANGE_HOMEPOINT_X_CENTRE);
|
||||
|
||||
controlNames.add(MODE_CHANGE_PEN_WIDTH);
|
||||
controlNames.add(MODE_SEND_PEN_WIDTH);
|
||||
|
||||
controlNames.add(MODE_CHANGE_PEN_TEST_START_WIDTH);
|
||||
controlNames.add(MODE_CHANGE_PEN_TEST_END_WIDTH);
|
||||
controlNames.add(MODE_CHANGE_PEN_TEST_INCREMENT_SIZE);
|
||||
controlNames.add(MODE_DRAW_TEST_PENWIDTH);
|
||||
|
||||
controlNames.add(MODE_CHANGE_MACHINE_MAX_SPEED);
|
||||
controlNames.add(MODE_CHANGE_MACHINE_ACCELERATION);
|
||||
controlNames.add(MODE_SEND_MACHINE_SPEED);
|
||||
|
||||
controlNames.add(MODE_CHANGE_SERIAL_PORT);
|
||||
|
||||
return controlNames;
|
||||
}
|
||||
|
||||
List<String> getControlNamesForQueuePanel()
|
||||
{
|
||||
List<String> controlNames = new ArrayList<String>();
|
||||
controlNames.add(MODE_CLEAR_QUEUE);
|
||||
controlNames.add(MODE_EXPORT_QUEUE);
|
||||
controlNames.add(MODE_IMPORT_QUEUE);
|
||||
|
||||
if (getHardwareVersion() >= HARDWARE_VER_MEGA)
|
||||
{
|
||||
controlNames.add(MODE_SEND_MACHINE_STORE_MODE);
|
||||
controlNames.add(MODE_SEND_MACHINE_LIVE_MODE);
|
||||
controlNames.add(MODE_SEND_MACHINE_EXEC_MODE);
|
||||
}
|
||||
|
||||
return controlNames;
|
||||
}
|
||||
|
||||
List<String> getControlNamesForGeneralPanel()
|
||||
{
|
||||
List<String> controlNames = new ArrayList<String>();
|
||||
controlNames.add(MODE_SAVE_PROPERTIES);
|
||||
controlNames.add(MODE_SAVE_AS_PROPERTIES);
|
||||
controlNames.add(MODE_LOAD_PROPERTIES);
|
||||
return controlNames;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Map<String, String> buildControlLabels()
|
||||
{
|
||||
Map<String, String> result = new HashMap<String, String>();
|
||||
|
||||
result.put(MODE_BEGIN, "Reset queue");
|
||||
result.put(MODE_INPUT_BOX_TOP_LEFT, "Select Area");
|
||||
result.put(MODE_INPUT_BOX_BOT_RIGHT, "Select BotRight");
|
||||
result.put(MODE_DRAW_OUTLINE_BOX, "Draw Outline box");
|
||||
result.put(MODE_DRAW_OUTLINE_BOX_ROWS, "Draw Outline rows");
|
||||
result.put(MODE_DRAW_SHADE_BOX_ROWS_PIXELS, "Draw Outline pixels");
|
||||
result.put(MODE_DRAW_TO_POSITION, "Move pen to point");
|
||||
result.put(MODE_DRAW_DIRECT, "Move direct");
|
||||
result.put(MODE_RENDER_SQUARE_PIXELS, "Shade Squarewave");
|
||||
result.put(MODE_RENDER_SCALED_SQUARE_PIXELS, "Shade Scaled Square");
|
||||
result.put(MODE_RENDER_SAW_PIXELS, "Shade sawtooth");
|
||||
result.put(MODE_RENDER_CIRCLE_PIXELS, "Shade circular");
|
||||
result.put(MODE_INPUT_ROW_START, "Select Row start");
|
||||
result.put(MODE_INPUT_ROW_END, "Select Row end");
|
||||
result.put(MODE_SET_POSITION, "Set pen position");
|
||||
result.put(MODE_DRAW_GRID, "Draw grid of box");
|
||||
result.put(MODE_DRAW_TESTPATTERN, "test pattern");
|
||||
result.put(MODE_PLACE_IMAGE, "place image");
|
||||
result.put(MODE_LOAD_IMAGE, "Load image file");
|
||||
result.put(MODE_INC_ROW_SIZE, "Rowsize up");
|
||||
result.put(MODE_DEC_ROW_SIZE, "Rowsize down");
|
||||
result.put(MODE_SET_POSITION_HOME, "Set home");
|
||||
result.put(MODE_RETURN_TO_HOME, "Return to home");
|
||||
result.put(MODE_INPUT_SINGLE_PIXEL, "Choose pixel");
|
||||
result.put(MODE_DRAW_TEST_PENWIDTH, "Test pen widths");
|
||||
result.put(MODE_RENDER_SOLID_SQUARE_PIXELS, "Shade solid");
|
||||
result.put(MODE_RENDER_SCRIBBLE_PIXELS, "Shade scribble");
|
||||
|
||||
result.put(MODE_CHANGE_MACHINE_SPEC, "Upload machine spec");
|
||||
result.put(MODE_REQUEST_MACHINE_SIZE, "Download size spec");
|
||||
result.put(MODE_RESET_MACHINE, "Reset machine to factory");
|
||||
result.put(MODE_SAVE_PROPERTIES, "Save");
|
||||
result.put(MODE_SAVE_AS_PROPERTIES, "Save as");
|
||||
result.put(MODE_LOAD_PROPERTIES, "Load config");
|
||||
|
||||
result.put(MODE_INC_SAMPLE_AREA, "Inc sample size");
|
||||
result.put(MODE_DEC_SAMPLE_AREA, "Dec sample size");
|
||||
|
||||
result.put(MODE_MOVE_IMAGE, "Move image");
|
||||
result.put(MODE_CONVERT_BOX_TO_PICTUREFRAME, "Set frame to area");
|
||||
result.put(MODE_SELECT_PICTUREFRAME, "Select frame");
|
||||
|
||||
result.put(MODE_CLEAR_QUEUE, "Clear queue");
|
||||
result.put(MODE_EXPORT_QUEUE, "Export queue");
|
||||
result.put(MODE_IMPORT_QUEUE, "Import queue");
|
||||
result.put(MODE_RESIZE_IMAGE, "Resize image");
|
||||
|
||||
result.put(MODE_RENDER_COMMAND_QUEUE, "Preview queue");
|
||||
|
||||
result.put(MODE_CHANGE_GRID_SIZE, "Grid size");
|
||||
result.put(MODE_CHANGE_SAMPLE_AREA, "Sample area");
|
||||
|
||||
result.put(MODE_SHOW_IMAGE, "Show image");
|
||||
result.put(MODE_SHOW_DENSITY_PREVIEW, "Show density preview");
|
||||
result.put(MODE_SHOW_QUEUE_PREVIEW, "Show Queue preview");
|
||||
result.put(MODE_SHOW_VECTOR, "Show Vector");
|
||||
result.put(MODE_SHOW_GUIDES, "Show Guides");
|
||||
|
||||
result.put(MODE_CHANGE_MACHINE_WIDTH, "Machine Width");
|
||||
result.put(MODE_CHANGE_MACHINE_HEIGHT, "Machine Height");
|
||||
result.put(MODE_CHANGE_MM_PER_REV, "MM Per Rev");
|
||||
result.put(MODE_CHANGE_STEPS_PER_REV, "Steps Per Rev");
|
||||
result.put(MODE_CHANGE_STEP_MULTIPLIER, "Step multiplier");
|
||||
result.put(MODE_CHANGE_PAGE_WIDTH, "Page Width");
|
||||
result.put(MODE_CHANGE_PAGE_HEIGHT, "Page Height");
|
||||
result.put(MODE_CHANGE_PAGE_OFFSET_X, "Page Pos X");
|
||||
result.put(MODE_CHANGE_PAGE_OFFSET_Y, "Page Pos Y");
|
||||
result.put(MODE_CHANGE_PAGE_OFFSET_X_CENTRE, "Centre page");
|
||||
|
||||
result.put(MODE_CHANGE_HOMEPOINT_X, "Home Pos X");
|
||||
result.put(MODE_CHANGE_HOMEPOINT_Y, "Home Pos Y");
|
||||
result.put(MODE_CHANGE_HOMEPOINT_X_CENTRE, "Centre Homepoint");
|
||||
|
||||
result.put(MODE_CHANGE_PEN_WIDTH, "Pen tip size");
|
||||
result.put(MODE_SEND_PEN_WIDTH, "Send Pen tip size");
|
||||
|
||||
result.put(MODE_CHANGE_PEN_TEST_START_WIDTH, "Pen test start tip");
|
||||
result.put(MODE_CHANGE_PEN_TEST_END_WIDTH, "Pen test end tip");
|
||||
result.put(MODE_CHANGE_PEN_TEST_INCREMENT_SIZE, "Pen test inc size");
|
||||
|
||||
result.put(MODE_CHANGE_MACHINE_MAX_SPEED, "Motor max speed");
|
||||
result.put(MODE_CHANGE_MACHINE_ACCELERATION, "Motor acceleration");
|
||||
result.put(MODE_SEND_MACHINE_SPEED, "Send speed");
|
||||
result.put(MODE_RENDER_VECTORS, "Draw vectors");
|
||||
result.put(MODE_LOAD_VECTOR_FILE, "Load vector");
|
||||
result.put(MODE_CHANGE_MIN_VECTOR_LINE_LENGTH, "Shortest vector");
|
||||
|
||||
result.put(MODE_IMAGE_PIXEL_BRIGHT_THRESHOLD, "Bright pixel");
|
||||
result.put(MODE_IMAGE_PIXEL_DARK_THRESHOLD, "Dark pixel");
|
||||
|
||||
result.put(MODE_CHANGE_SERIAL_PORT, "Serial port...");
|
||||
|
||||
result.put(MODE_SEND_MACHINE_STORE_MODE, "Signal store...");
|
||||
result.put(MODE_SEND_MACHINE_LIVE_MODE, "Signal play");
|
||||
result.put(MODE_SEND_MACHINE_EXEC_MODE, "Exec from store...");
|
||||
|
||||
result.put(MODE_RESIZE_VECTOR, "Resize vector");
|
||||
result.put(MODE_MOVE_VECTOR, "Move vector");
|
||||
result.put(MODE_RENDER_PIXEL_DIALOG, "Render pixels...");
|
||||
result.put(MODE_CHOOSE_CHROMA_KEY_COLOUR, "Choose mask colour");
|
||||
result.put(MODE_CHANGE_PIXEL_SCALING, "Pixel scaling");
|
||||
|
||||
result.put(MODE_PEN_LIFT_UP, "Pen lift");
|
||||
result.put(MODE_PEN_LIFT_DOWN, "Pen drop");
|
||||
|
||||
result.put(MODE_SEND_ROVE_AREA, "Send Roving Area");
|
||||
result.put(MODE_SEND_START_TEXT, "Start text at point");
|
||||
result.put(MODE_SHOW_WRITING_DIALOG, "Render writing...");
|
||||
|
||||
result.put(MODE_START_SWIRLING, "Swirl");
|
||||
result.put(MODE_STOP_SWIRLING, "Stop swirl");
|
||||
result.put(MODE_START_SPRITE, "Choose sprite...");
|
||||
result.put(MODE_START_RANDOM_SPRITES, "Random sprites");
|
||||
result.put(MODE_STOP_RANDOM_SPRITES, "Stop sprites");
|
||||
result.put(MODE_DRAW_NORWEGIAN_DIALOG, "Draw norwegian...");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Set<String> buildControlNames()
|
||||
{
|
||||
Set<String> result = new HashSet<String>();
|
||||
result.add(MODE_BEGIN);
|
||||
result.add(MODE_INPUT_BOX_TOP_LEFT);
|
||||
result.add(MODE_INPUT_BOX_BOT_RIGHT);
|
||||
result.add(MODE_DRAW_OUTLINE_BOX);
|
||||
result.add(MODE_DRAW_OUTLINE_BOX_ROWS);
|
||||
result.add(MODE_DRAW_SHADE_BOX_ROWS_PIXELS);
|
||||
result.add(MODE_DRAW_TO_POSITION);
|
||||
result.add(MODE_DRAW_DIRECT);
|
||||
result.add(MODE_RENDER_SQUARE_PIXELS);
|
||||
result.add(MODE_RENDER_SCALED_SQUARE_PIXELS);
|
||||
result.add(MODE_RENDER_SAW_PIXELS);
|
||||
result.add(MODE_RENDER_CIRCLE_PIXELS);
|
||||
|
||||
result.add(MODE_RENDER_PIXEL_DIALOG);
|
||||
|
||||
result.add(MODE_INPUT_ROW_START);
|
||||
result.add(MODE_INPUT_ROW_END);
|
||||
result.add(MODE_SET_POSITION);
|
||||
result.add(MODE_DRAW_GRID);
|
||||
result.add(MODE_DRAW_TESTPATTERN);
|
||||
result.add(MODE_PLACE_IMAGE);
|
||||
result.add(MODE_LOAD_IMAGE);
|
||||
result.add(MODE_INC_ROW_SIZE);
|
||||
result.add(MODE_DEC_ROW_SIZE);
|
||||
result.add(MODE_SET_POSITION_HOME);
|
||||
result.add(MODE_RETURN_TO_HOME);
|
||||
result.add(MODE_INPUT_SINGLE_PIXEL);
|
||||
result.add(MODE_DRAW_TEST_PENWIDTH);
|
||||
result.add(MODE_RENDER_SOLID_SQUARE_PIXELS);
|
||||
result.add(MODE_RENDER_SCRIBBLE_PIXELS);
|
||||
result.add(MODE_CHANGE_MACHINE_SPEC);
|
||||
result.add(MODE_REQUEST_MACHINE_SIZE);
|
||||
result.add(MODE_RESET_MACHINE);
|
||||
|
||||
result.add(MODE_SAVE_PROPERTIES);
|
||||
result.add(MODE_SAVE_AS_PROPERTIES);
|
||||
result.add(MODE_LOAD_PROPERTIES);
|
||||
|
||||
result.add(MODE_INC_SAMPLE_AREA);
|
||||
result.add(MODE_DEC_SAMPLE_AREA);
|
||||
result.add(MODE_MOVE_IMAGE);
|
||||
result.add(MODE_CONVERT_BOX_TO_PICTUREFRAME);
|
||||
result.add(MODE_SELECT_PICTUREFRAME);
|
||||
result.add(MODE_CLEAR_QUEUE);
|
||||
result.add(MODE_EXPORT_QUEUE);
|
||||
result.add(MODE_IMPORT_QUEUE);
|
||||
result.add(MODE_FIT_IMAGE_TO_BOX);
|
||||
result.add(MODE_RESIZE_IMAGE);
|
||||
result.add(MODE_RENDER_COMMAND_QUEUE);
|
||||
|
||||
result.add(MODE_CHANGE_GRID_SIZE);
|
||||
result.add(MODE_CHANGE_SAMPLE_AREA);
|
||||
|
||||
result.add(MODE_SHOW_IMAGE);
|
||||
result.add(MODE_SHOW_DENSITY_PREVIEW);
|
||||
result.add(MODE_SHOW_VECTOR);
|
||||
result.add(MODE_SHOW_QUEUE_PREVIEW);
|
||||
result.add(MODE_SHOW_GUIDES);
|
||||
|
||||
result.add(MODE_CHANGE_MACHINE_WIDTH);
|
||||
result.add(MODE_CHANGE_MACHINE_HEIGHT);
|
||||
result.add(MODE_CHANGE_MM_PER_REV);
|
||||
result.add(MODE_CHANGE_STEPS_PER_REV);
|
||||
result.add(MODE_CHANGE_STEP_MULTIPLIER);
|
||||
result.add(MODE_CHANGE_PAGE_WIDTH);
|
||||
result.add(MODE_CHANGE_PAGE_HEIGHT);
|
||||
result.add(MODE_CHANGE_PAGE_OFFSET_X);
|
||||
result.add(MODE_CHANGE_PAGE_OFFSET_Y);
|
||||
result.add(MODE_CHANGE_PAGE_OFFSET_X_CENTRE);
|
||||
|
||||
result.add(MODE_CHANGE_HOMEPOINT_X);
|
||||
result.add(MODE_CHANGE_HOMEPOINT_Y);
|
||||
result.add(MODE_CHANGE_HOMEPOINT_X_CENTRE);
|
||||
|
||||
result.add(MODE_CHANGE_PEN_WIDTH);
|
||||
|
||||
result.add(MODE_CHANGE_PEN_TEST_START_WIDTH);
|
||||
result.add(MODE_CHANGE_PEN_TEST_END_WIDTH);
|
||||
result.add(MODE_CHANGE_PEN_TEST_INCREMENT_SIZE);
|
||||
|
||||
result.add(MODE_SEND_PEN_WIDTH);
|
||||
|
||||
result.add(MODE_CHANGE_MACHINE_MAX_SPEED);
|
||||
result.add(MODE_CHANGE_MACHINE_ACCELERATION);
|
||||
result.add(MODE_SEND_MACHINE_SPEED);
|
||||
|
||||
result.add(MODE_RENDER_VECTORS);
|
||||
result.add(MODE_LOAD_VECTOR_FILE);
|
||||
result.add(MODE_IMAGE_PIXEL_BRIGHT_THRESHOLD);
|
||||
result.add(MODE_IMAGE_PIXEL_DARK_THRESHOLD);
|
||||
result.add(MODE_CHANGE_SERIAL_PORT);
|
||||
|
||||
result.add(MODE_SEND_MACHINE_STORE_MODE);
|
||||
result.add(MODE_SEND_MACHINE_LIVE_MODE);
|
||||
result.add(MODE_SEND_MACHINE_EXEC_MODE);
|
||||
|
||||
result.add(MODE_RESIZE_VECTOR);
|
||||
result.add(MODE_MOVE_VECTOR);
|
||||
result.add(MODE_CHANGE_MIN_VECTOR_LINE_LENGTH);
|
||||
|
||||
result.add(MODE_CHOOSE_CHROMA_KEY_COLOUR);
|
||||
result.add(MODE_CHANGE_PIXEL_SCALING);
|
||||
result.add(MODE_PEN_LIFT_UP);
|
||||
result.add(MODE_PEN_LIFT_DOWN);
|
||||
|
||||
result.add(MODE_SEND_ROVE_AREA);
|
||||
result.add(MODE_SEND_START_TEXT);
|
||||
result.add(MODE_SHOW_WRITING_DIALOG);
|
||||
result.add(MODE_START_SWIRLING);
|
||||
result.add(MODE_STOP_SWIRLING);
|
||||
result.add(MODE_START_SPRITE);
|
||||
result.add(MODE_START_RANDOM_SPRITES);
|
||||
result.add(MODE_STOP_RANDOM_SPRITES);
|
||||
result.add(MODE_DRAW_NORWEGIAN_DIALOG);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
770
drawing.pde
Normal file
770
drawing.pde
Normal file
@ -0,0 +1,770 @@
|
||||
/**
|
||||
Polargraph controller
|
||||
Copyright Sandy Noble 2012.
|
||||
|
||||
This file is part of Polargraph Controller.
|
||||
|
||||
Polargraph Controller is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Polargraph Controller is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Polargraph Controller. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Requires the excellent ControlP5 GUI library available from http://www.sojamo.de/libraries/controlP5/.
|
||||
Requires the excellent Geomerative library available from http://www.ricardmarxer.com/geomerative/.
|
||||
|
||||
This is an application for controlling a polargraph machine, communicating using ASCII command language over a serial link.
|
||||
|
||||
sandy.noble@gmail.com
|
||||
http://www.polargraph.co.uk/
|
||||
http://code.google.com/p/polargraph/
|
||||
*/
|
||||
static final String CMD_CHANGELENGTH = "C01,";
|
||||
static final String CMD_CHANGEPENWIDTH = "C02,";
|
||||
static final String CMD_CHANGEMOTORSPEED = "C03,";
|
||||
static final String CMD_CHANGEMOTORACCEL = "C04,";
|
||||
static final String CMD_DRAWPIXEL = "C05,";
|
||||
static final String CMD_DRAWSCRIBBLEPIXEL = "C06,";
|
||||
static final String CMD_DRAWRECT = "C07,";
|
||||
static final String CMD_CHANGEDRAWINGDIRECTION = "C08,";
|
||||
static final String CMD_SETPOSITION = "C09,";
|
||||
static final String CMD_TESTPATTERN = "C10,";
|
||||
static final String CMD_TESTPENWIDTHSQUARE = "C11,";
|
||||
static final String CMD_TESTPENWIDTHSCRIBBLE = "C12,";
|
||||
static final String CMD_PENDOWN = "C13,";
|
||||
static final String CMD_PENUP = "C14,";
|
||||
static final String CMD_DRAWSAWPIXEL = "C15,";
|
||||
static final String CMD_DRAWROUNDPIXEL = "C16,";
|
||||
static final String CMD_CHANGELENGTHDIRECT = "C17,";
|
||||
static final String CMD_TXIMAGEBLOCK = "C18,";
|
||||
static final String CMD_STARTROVE = "C19,";
|
||||
static final String CMD_STOPROVE = "C20,";
|
||||
static final String CMD_SET_ROVE_AREA = "C21,";
|
||||
static final String CMD_LOADMAGEFILE = "C23,";
|
||||
static final String CMD_CHANGEMACHINESIZE = "C24,";
|
||||
static final String CMD_CHANGEMACHINENAME = "C25,";
|
||||
static final String CMD_REQUESTMACHINESIZE = "C26,";
|
||||
static final String CMD_RESETMACHINE = "C27,";
|
||||
static final String CMD_DRAWDIRECTIONTEST = "C28,";
|
||||
static final String CMD_CHANGEMACHINEMMPERREV = "C29,";
|
||||
static final String CMD_CHANGEMACHINESTEPSPERREV = "C30,";
|
||||
static final String CMD_SETMOTORSPEED = "C31,";
|
||||
static final String CMD_SETMOTORACCEL = "C32,";
|
||||
static final String CMD_MACHINE_MODE_STORE_COMMANDS = "C33,";
|
||||
static final String CMD_MACHINE_MODE_EXEC_FROM_STORE = "C34,";
|
||||
static final String CMD_MACHINE_MODE_LIVE = "C35,";
|
||||
static final String CMD_RANDOM_DRAW = "C36,";
|
||||
static final String CMD_SETMACHINESTEPMULTIPLIER = "C37,";
|
||||
static final String CMD_START_TEXT = "C38,";
|
||||
static final String CMD_DRAW_SPRITE = "C39,";
|
||||
static final String CMD_CHANGELENGTH_RELATIVE = "C40,";
|
||||
static final String CMD_SWIRLING = "C41,";
|
||||
static final String CMD_DRAW_RANDOM_SPRITE = "C42,";
|
||||
static final String CMD_DRAW_NORWEGIAN = "C43,";
|
||||
static final String CMD_DRAW_NORWEGIAN_OUTLINE = "C44,";
|
||||
|
||||
private PVector mouseVector = new PVector(0,0);
|
||||
|
||||
Comparator xAscending = new Comparator()
|
||||
{
|
||||
public int compare(Object p1, Object p2)
|
||||
{
|
||||
PVector a = (PVector) p1;
|
||||
PVector b = (PVector) p2;
|
||||
|
||||
int xValue = new Float(a.x).compareTo(b.x);
|
||||
return xValue;
|
||||
}
|
||||
};
|
||||
|
||||
Comparator yAscending = new Comparator()
|
||||
{
|
||||
public int compare(Object p1, Object p2)
|
||||
{
|
||||
PVector a = (PVector) p1;
|
||||
PVector b = (PVector) p2;
|
||||
|
||||
int yValue = new Float(a.y).compareTo(b.y);
|
||||
return yValue;
|
||||
}
|
||||
};
|
||||
|
||||
void sendResetMachine()
|
||||
{
|
||||
String command = CMD_RESETMACHINE + "END";
|
||||
addToCommandQueue(command);
|
||||
}
|
||||
void sendRequestMachineSize()
|
||||
{
|
||||
String command = CMD_REQUESTMACHINESIZE + "END";
|
||||
addToCommandQueue(command);
|
||||
}
|
||||
void sendMachineSpec()
|
||||
{
|
||||
// ask for input to get the new machine size
|
||||
String command = CMD_CHANGEMACHINENAME+newMachineName+",END";
|
||||
addToCommandQueue(command);
|
||||
command = CMD_CHANGEMACHINESIZE+getDisplayMachine().inMM(getDisplayMachine().getWidth())+","+getDisplayMachine().inMM(getDisplayMachine().getHeight())+",END";
|
||||
addToCommandQueue(command);
|
||||
command = CMD_CHANGEMACHINEMMPERREV+int(getDisplayMachine().getMMPerRev())+",END";
|
||||
addToCommandQueue(command);
|
||||
command = CMD_CHANGEMACHINESTEPSPERREV+int(getDisplayMachine().getStepsPerRev())+",END";
|
||||
addToCommandQueue(command);
|
||||
command = CMD_SETMACHINESTEPMULTIPLIER+machineStepMultiplier+",END";
|
||||
addToCommandQueue(command);
|
||||
}
|
||||
|
||||
public PVector getMouseVector()
|
||||
{
|
||||
if (mouseVector == null)
|
||||
{
|
||||
mouseVector = new PVector(0,0);
|
||||
}
|
||||
|
||||
mouseVector.x = mouseX;
|
||||
mouseVector.y = mouseY;
|
||||
return mouseVector;
|
||||
}
|
||||
|
||||
// Uses the mouse position unless one is specified
|
||||
void sendMoveToPosition(boolean direct)
|
||||
{
|
||||
sendMoveToPosition(direct, getMouseVector());
|
||||
}
|
||||
|
||||
void sendMoveToPosition(boolean direct, PVector position)
|
||||
{
|
||||
String command = null;
|
||||
PVector p = getDisplayMachine().scaleToDisplayMachine(position);
|
||||
p = getDisplayMachine().inSteps(p);
|
||||
p = getDisplayMachine().asNativeCoords(p);
|
||||
sendMoveToNativePosition(direct, p);
|
||||
}
|
||||
|
||||
void sendMoveToNativePosition(boolean direct, PVector p)
|
||||
{
|
||||
String command = null;
|
||||
if (direct)
|
||||
command = CMD_CHANGELENGTHDIRECT+int(p.x+0.5)+","+int(p.y+0.5)+","+getMaxSegmentLength()+",END";
|
||||
else
|
||||
command = CMD_CHANGELENGTH+(int)p.x+","+(int)p.y+",END";
|
||||
|
||||
addToCommandQueue(command);
|
||||
}
|
||||
|
||||
|
||||
int getMaxSegmentLength()
|
||||
{
|
||||
return this.maxSegmentLength;
|
||||
}
|
||||
|
||||
void sendTestPattern()
|
||||
{
|
||||
String command = CMD_DRAWDIRECTIONTEST+int(gridSize)+",6,END";
|
||||
addToCommandQueue(command);
|
||||
}
|
||||
|
||||
void sendTestPenWidth()
|
||||
{
|
||||
NumberFormat nf = NumberFormat.getNumberInstance(Locale.UK);
|
||||
DecimalFormat df = (DecimalFormat)nf;
|
||||
df.applyPattern("##0.##");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(testPenWidthCommand)
|
||||
.append(int(gridSize))
|
||||
.append(",")
|
||||
.append(df.format(testPenWidthStartSize))
|
||||
.append(",")
|
||||
.append(df.format(testPenWidthEndSize))
|
||||
.append(",")
|
||||
.append(df.format(testPenWidthIncrementSize))
|
||||
.append(",END");
|
||||
addToCommandQueue(sb.toString());
|
||||
}
|
||||
|
||||
void sendSetPosition()
|
||||
{
|
||||
PVector p = getDisplayMachine().scaleToDisplayMachine(getMouseVector());
|
||||
p = getDisplayMachine().convertToNative(p);
|
||||
p = getDisplayMachine().inSteps(p);
|
||||
|
||||
String command = CMD_SETPOSITION+int(p.x+0.5)+","+int(p.y+0.5)+",END";
|
||||
addToCommandQueue(command);
|
||||
}
|
||||
|
||||
void sendStartTextAtPoint()
|
||||
{
|
||||
PVector p = getDisplayMachine().scaleToDisplayMachine(getMouseVector());
|
||||
p = getDisplayMachine().convertToNative(p);
|
||||
p = getDisplayMachine().inSteps(p);
|
||||
|
||||
String command = CMD_START_TEXT+(int)p.x+","+(int)p.y+","+gridSize+",2,END";
|
||||
addToCommandQueue(command);
|
||||
}
|
||||
|
||||
void sendSetHomePosition()
|
||||
{
|
||||
PVector pgCoords = getDisplayMachine().asNativeCoords(getHomePoint());
|
||||
|
||||
String command = CMD_SETPOSITION+int(pgCoords.x+0.5)+","+int(pgCoords.y+0.5)+",END";
|
||||
addToCommandQueue(command);
|
||||
}
|
||||
|
||||
int scaleDensity(int inDens, int inMax, int outMax)
|
||||
{
|
||||
float reducedDens = (float(inDens) / float(inMax)) * float(outMax);
|
||||
reducedDens = outMax-reducedDens;
|
||||
// println("inDens:"+inDens+", inMax:"+inMax+", outMax:"+outMax+", reduced:"+reducedDens);
|
||||
|
||||
// round up if bigger than .5
|
||||
int result = int(reducedDens);
|
||||
if (reducedDens - (result) > 0.5)
|
||||
result ++;
|
||||
|
||||
//result = outMax - result;
|
||||
return result;
|
||||
}
|
||||
|
||||
SortedMap<Float, List<PVector>> divideIntoRows(Set<PVector> pixels, int direction)
|
||||
{
|
||||
SortedMap<Float, List<PVector>> inRows = new TreeMap<Float, List<PVector>>();
|
||||
|
||||
for (PVector p : pixels)
|
||||
{
|
||||
Float row = p.x;
|
||||
if (direction == DRAW_DIR_SE || direction == DRAW_DIR_NW)
|
||||
row = p.y;
|
||||
|
||||
if (!inRows.containsKey(row))
|
||||
{
|
||||
inRows.put(row, new ArrayList<PVector>());
|
||||
}
|
||||
inRows.get(row).add(p);
|
||||
}
|
||||
return inRows;
|
||||
}
|
||||
|
||||
PVector sortPixelsInRowsAlternating(SortedMap<Float, List<PVector>> inRows, int initialDirection, float maxPixelSize)
|
||||
{
|
||||
PVector startPoint = null;
|
||||
Comparator comp = null;
|
||||
boolean rowIsAlongXAxis = true;
|
||||
|
||||
if (initialDirection == DRAW_DIR_SE || initialDirection == DRAW_DIR_NW)
|
||||
{
|
||||
rowIsAlongXAxis = true;
|
||||
comp = xAscending;
|
||||
}
|
||||
else
|
||||
{
|
||||
rowIsAlongXAxis = false;
|
||||
comp = yAscending;
|
||||
}
|
||||
|
||||
// now sort each row, reversing the direction after each row
|
||||
boolean reverse = false;
|
||||
for (Float rowCoord : inRows.keySet())
|
||||
{
|
||||
println("row: " + rowCoord);
|
||||
List<PVector> row = inRows.get(rowCoord);
|
||||
|
||||
if (reverse)
|
||||
{
|
||||
// reverse it (descending)
|
||||
Collections.sort(row, comp);
|
||||
Collections.reverse(row);
|
||||
// if (startPoint == null)
|
||||
// {
|
||||
// if (rowIsAlongXAxis)
|
||||
// startPoint = new PVector(row.get(0).x+(maxPixelSize/2.0), row.get(0).y);
|
||||
// else
|
||||
// startPoint = new PVector(row.get(0).x, row.get(0).y-(maxPixelSize/2.0));
|
||||
// }
|
||||
reverse = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// sort row ascending
|
||||
Collections.sort(row, comp);
|
||||
// if (startPoint == null)
|
||||
// {
|
||||
// if (rowIsAlongXAxis)
|
||||
// startPoint = new PVector(row.get(0).x-(maxPixelSize/2.0), row.get(0).y);
|
||||
// else
|
||||
// startPoint = new PVector(row.get(0).x, row.get(0).y+(maxPixelSize/2.0));
|
||||
// }
|
||||
reverse = true;
|
||||
}
|
||||
}
|
||||
return startPoint;
|
||||
}
|
||||
|
||||
void sortPixelsInRows(SortedMap<Float, List<PVector>> inRows, int initialDirection)
|
||||
{
|
||||
PVector startPoint = null;
|
||||
Comparator comp = null;
|
||||
boolean rowIsAlongXAxis = true;
|
||||
|
||||
if (initialDirection == DRAW_DIR_SE || initialDirection == DRAW_DIR_NW)
|
||||
{
|
||||
rowIsAlongXAxis = true;
|
||||
comp = xAscending;
|
||||
}
|
||||
else
|
||||
{
|
||||
rowIsAlongXAxis = false;
|
||||
comp = yAscending;
|
||||
}
|
||||
|
||||
// now sort each row, reversing the direction after each row
|
||||
for (Float rowCoord : inRows.keySet())
|
||||
{
|
||||
println("row: " + rowCoord);
|
||||
List<PVector> row = inRows.get(rowCoord);
|
||||
// sort row ascending
|
||||
Collections.sort(row, comp);
|
||||
|
||||
if (initialDirection == DRAW_DIR_NW || initialDirection == DRAW_DIR_NE)
|
||||
Collections.reverse(row);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void sendPixels(Set<PVector> pixels, String pixelCommand, int initialDirection, int startCorner, float maxPixelSize, boolean scaleSizeToDensity)
|
||||
{
|
||||
|
||||
// sort it into a map of rows, keyed by y coordinate value
|
||||
SortedMap<Float, List<PVector>> inRows = divideIntoRows(pixels, initialDirection);
|
||||
|
||||
sortPixelsInRowsAlternating(inRows, initialDirection, maxPixelSize);
|
||||
|
||||
// that was easy.
|
||||
// load the queue
|
||||
// add a preamble
|
||||
|
||||
// set the first direction
|
||||
int drawDirection = initialDirection;
|
||||
String changeDir = CMD_CHANGEDRAWINGDIRECTION+getPixelDirectionMode()+"," + drawDirection +",END";
|
||||
addToCommandQueue(changeDir);
|
||||
|
||||
// reverse the row sequence if the draw is starting from the bottom
|
||||
// and reverse the pixel sequence if it needs to be done (odd number of rows)
|
||||
boolean reversePixelSequence = false;
|
||||
List<Float> rowKeys = new ArrayList<Float>();
|
||||
rowKeys.addAll(inRows.keySet());
|
||||
Collections.sort(rowKeys);
|
||||
if (startCorner == DRAW_DIR_SE || startCorner == DRAW_DIR_SW)
|
||||
{
|
||||
Collections.reverse(rowKeys);
|
||||
if (rowKeys.size() % 2 == 0)
|
||||
reversePixelSequence = true;
|
||||
}
|
||||
|
||||
// and move the pen to just next to the first pixel
|
||||
List<PVector> firstRow = inRows.get(rowKeys.get(0));
|
||||
|
||||
PVector startPoint = firstRow.get(0);
|
||||
int startPointX = int(startPoint.x);
|
||||
int startPointY = int(startPoint.y);
|
||||
int halfSize = int(maxPixelSize/2.0);
|
||||
|
||||
print("Dir:");
|
||||
if (initialDirection == DRAW_DIR_SE)
|
||||
{
|
||||
startPointX-=halfSize;
|
||||
println("SE");
|
||||
}
|
||||
else if (initialDirection == DRAW_DIR_SW)
|
||||
{
|
||||
startPointY-=halfSize;
|
||||
println("SW");
|
||||
}
|
||||
else if (initialDirection == DRAW_DIR_NW)
|
||||
{
|
||||
startPointX-=halfSize;
|
||||
println("NW");
|
||||
}
|
||||
else if (initialDirection == DRAW_DIR_NE)
|
||||
{
|
||||
startPointY-=halfSize;
|
||||
println("NE");
|
||||
}
|
||||
|
||||
if (startPoint != null)
|
||||
{
|
||||
String touchdown = CMD_CHANGELENGTH+int(startPointX)+","+int(startPointY)+",END";
|
||||
addToCommandQueue(touchdown);
|
||||
addToCommandQueue(CMD_PENDOWN+"END");
|
||||
}
|
||||
|
||||
boolean penLifted = false;
|
||||
|
||||
// so for each row
|
||||
for (Float key : rowKeys)
|
||||
{
|
||||
List<PVector> row = inRows.get(key);
|
||||
if (reversePixelSequence)
|
||||
Collections.reverse(row);
|
||||
|
||||
for (PVector v : row)
|
||||
{
|
||||
if (isHiddenPixel(v)) // check for masked pixels,
|
||||
{
|
||||
//println("It's outside the bright/dark threshold.");
|
||||
if (liftPenOnMaskedPixels)
|
||||
{
|
||||
if (!penLifted) // if the pen isn't already up
|
||||
{
|
||||
String raisePen = CMD_PENUP + "END";
|
||||
addToCommandQueue(raisePen);
|
||||
penLifted = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// println("Pen is already lifted.");
|
||||
}
|
||||
// now convert to ints
|
||||
int inX = int(v.x);
|
||||
int inY = int(v.y);
|
||||
int pixelSize = int(maxPixelSize);
|
||||
// render a fully bright (255) pixel.
|
||||
String command = pixelCommand+inX+","+inY+","+int(pixelSize+0.5)+",255,END";
|
||||
addToCommandQueue(command);
|
||||
}
|
||||
else
|
||||
{
|
||||
//println("liftPenOnMaskedPixels is not selected.");
|
||||
}
|
||||
// so this pixel doesn't get added to the queue.
|
||||
}
|
||||
else // pixel wasn't masked - render it up
|
||||
{
|
||||
// now convert to ints
|
||||
int inX = int(v.x);
|
||||
int inY = int(v.y);
|
||||
Integer density = int(v.z);
|
||||
int pixelSize = int(maxPixelSize);
|
||||
if (scaleSizeToDensity)
|
||||
{
|
||||
pixelSize = scaleDensity(density, 255, int(maxPixelSize));
|
||||
density = 0;
|
||||
}
|
||||
int scaledPixelSize = int((pixelSize*getPixelScalingOverGridSize())+0.5);
|
||||
String command = pixelCommand+inX+","+inY+","+scaledPixelSize+","+density+",END";
|
||||
|
||||
// put the pen down if lifting over masked pixels is on
|
||||
if (liftPenOnMaskedPixels && penLifted)
|
||||
{
|
||||
// println("Pen down.");
|
||||
String lowerPen = CMD_PENDOWN + "END";
|
||||
addToCommandQueue(lowerPen);
|
||||
penLifted = false;
|
||||
}
|
||||
addToCommandQueue(command);
|
||||
}
|
||||
}
|
||||
|
||||
drawDirection = flipDrawDirection(drawDirection);
|
||||
String command = CMD_CHANGEDRAWINGDIRECTION+getPixelDirectionMode()+"," + drawDirection +",END";
|
||||
addToCommandQueue(command);
|
||||
}
|
||||
|
||||
addToCommandQueue(CMD_PENUP+"END");
|
||||
numberOfPixelsTotal = commandQueue.size();
|
||||
startPixelTimer();
|
||||
}
|
||||
|
||||
|
||||
int flipDrawDirection(int curr)
|
||||
{
|
||||
if (curr == DRAW_DIR_SE)
|
||||
return DRAW_DIR_NW;
|
||||
else if (curr == DRAW_DIR_NW)
|
||||
return DRAW_DIR_SE;
|
||||
else if (curr == DRAW_DIR_NE)
|
||||
return DRAW_DIR_SW;
|
||||
else if (curr == DRAW_DIR_SW)
|
||||
return DRAW_DIR_NE;
|
||||
else return DRAW_DIR_SE;
|
||||
}
|
||||
|
||||
|
||||
int getPixelDirectionMode()
|
||||
{
|
||||
return pixelDirectionMode;
|
||||
}
|
||||
|
||||
|
||||
void sendSawtoothPixels(Set<PVector> pixels)
|
||||
{
|
||||
sendPixels(pixels, CMD_DRAWSAWPIXEL, renderStartDirection, renderStartPosition, getGridSize(), false);
|
||||
}
|
||||
void sendCircularPixels(Set<PVector> pixels)
|
||||
{
|
||||
sendPixels(pixels, CMD_DRAWROUNDPIXEL, renderStartDirection, renderStartPosition, getGridSize(), false);
|
||||
}
|
||||
|
||||
void sendScaledSquarePixels(Set<PVector> pixels)
|
||||
{
|
||||
sendPixels(pixels, CMD_DRAWPIXEL, renderStartDirection, renderStartPosition, getGridSize(), true);
|
||||
}
|
||||
|
||||
void sendSolidSquarePixels(Set<PVector> pixels)
|
||||
{
|
||||
for (PVector p : pixels)
|
||||
{
|
||||
if (p.z != MASKED_PIXEL_BRIGHTNESS)
|
||||
p.z = 0.0;
|
||||
}
|
||||
sendPixels(pixels, CMD_DRAWPIXEL, renderStartDirection, renderStartPosition, getGridSize(), false);
|
||||
}
|
||||
|
||||
void sendSquarePixels(Set<PVector> pixels)
|
||||
{
|
||||
sendPixels(pixels, CMD_DRAWPIXEL, renderStartDirection, renderStartPosition, getGridSize(), false);
|
||||
}
|
||||
|
||||
void sendScribblePixels(Set<PVector> pixels)
|
||||
{
|
||||
sendPixels(pixels, CMD_DRAWSCRIBBLEPIXEL, renderStartDirection, renderStartPosition, getGridSize(), false);
|
||||
}
|
||||
|
||||
|
||||
void sendOutlineOfPixels(Set<PVector> pixels)
|
||||
{
|
||||
// sort it into a map of rows, keyed by y coordinate value
|
||||
SortedMap<Float, List<PVector>> inRows = divideIntoRows(pixels, DRAW_DIR_SE);
|
||||
|
||||
sortPixelsInRowsAlternating(inRows, DRAW_DIR_SE, getGridSize());
|
||||
|
||||
float halfGrid = getGridSize() / 2.0;
|
||||
for (Float key : inRows.keySet())
|
||||
{
|
||||
for (PVector p : inRows.get(key))
|
||||
{
|
||||
PVector startPoint = new PVector(p.x-halfGrid, p.y-halfGrid);
|
||||
PVector endPoint = new PVector(p.x+halfGrid, p.y+halfGrid);
|
||||
String command = CMD_DRAWRECT + int(startPoint.x)+","+int(startPoint.y)+","+int(endPoint.x)+","+int(endPoint.y)+",END";
|
||||
addToCommandQueue(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sendOutlineOfRows(Set<PVector> pixels, int drawDirection)
|
||||
{
|
||||
// sort it into a map of rows, keyed by y coordinate value
|
||||
SortedMap<Float, List<PVector>> inRows = divideIntoRows(pixels, drawDirection);
|
||||
|
||||
sortPixelsInRows(inRows, drawDirection);
|
||||
|
||||
PVector offset = new PVector(getGridSize() / 2.0, getGridSize() / 2.0);
|
||||
for (Float key : inRows.keySet())
|
||||
{
|
||||
PVector startPoint = inRows.get(key).get(0);
|
||||
PVector endPoint = inRows.get(key).get(inRows.get(key).size()-1);
|
||||
|
||||
if (drawDirection == DRAW_DIR_SE)
|
||||
{
|
||||
startPoint.sub(offset);
|
||||
endPoint.add(offset);
|
||||
}
|
||||
else if (drawDirection == DRAW_DIR_NW)
|
||||
{
|
||||
startPoint.add(offset);
|
||||
endPoint.sub(offset);
|
||||
}
|
||||
else if (drawDirection == DRAW_DIR_SW)
|
||||
{
|
||||
startPoint.add(offset);
|
||||
endPoint.sub(offset);
|
||||
}
|
||||
else if (drawDirection == DRAW_DIR_NW)
|
||||
{
|
||||
startPoint.add(offset);
|
||||
endPoint.sub(offset);
|
||||
}
|
||||
|
||||
String command = CMD_DRAWRECT + int(startPoint.x)+","+int(startPoint.y)+","+int(endPoint.x)+","+int(endPoint.y)+",END";
|
||||
addToCommandQueue(command);
|
||||
}
|
||||
}
|
||||
|
||||
void sendGridOfBox(Set<PVector> pixels)
|
||||
{
|
||||
sendOutlineOfRows(pixels, DRAW_DIR_SE);
|
||||
sendOutlineOfRows(pixels, DRAW_DIR_SW);
|
||||
}
|
||||
|
||||
|
||||
void sendOutlineOfBox()
|
||||
{
|
||||
// convert cartesian to native format
|
||||
PVector tl = getDisplayMachine().inSteps(getBoxVector1());
|
||||
PVector br = getDisplayMachine().inSteps(getBoxVector2());
|
||||
|
||||
PVector tr = new PVector(br.x, tl.y);
|
||||
PVector bl = new PVector(tl.x, br.y);
|
||||
|
||||
tl = getDisplayMachine().asNativeCoords(tl);
|
||||
tr = getDisplayMachine().asNativeCoords(tr);
|
||||
bl = getDisplayMachine().asNativeCoords(bl);
|
||||
br = getDisplayMachine().asNativeCoords(br);
|
||||
|
||||
String command = CMD_CHANGELENGTHDIRECT+(int)tl.x+","+(int)tl.y+","+getMaxSegmentLength()+",END";
|
||||
addToCommandQueue(command);
|
||||
|
||||
command = CMD_CHANGELENGTHDIRECT+(int)tr.x+","+(int)tr.y+","+getMaxSegmentLength()+",END";
|
||||
addToCommandQueue(command);
|
||||
|
||||
command = CMD_CHANGELENGTHDIRECT+(int)br.x+","+(int)br.y+","+getMaxSegmentLength()+",END";
|
||||
addToCommandQueue(command);
|
||||
|
||||
command = CMD_CHANGELENGTHDIRECT+(int)bl.x+","+(int)bl.y+","+getMaxSegmentLength()+",END";
|
||||
addToCommandQueue(command);
|
||||
|
||||
command = CMD_CHANGELENGTHDIRECT+(int)tl.x+","+(int)tl.y+","+getMaxSegmentLength()+",END";
|
||||
addToCommandQueue(command);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void sendVectorShapes()
|
||||
{
|
||||
RPoint[][] pointPaths = getVectorShape().getPointsInPaths();
|
||||
|
||||
String command = "";
|
||||
|
||||
// go through and get each path
|
||||
for (int i = 0; i<pointPaths.length; i++)
|
||||
{
|
||||
if (pointPaths[i] != null)
|
||||
{
|
||||
boolean firstPointFound = false;
|
||||
PVector lastPoint = null;
|
||||
|
||||
List<PVector> filteredPoints = filterPoints(pointPaths[i], VECTOR_FILTER_LOW_PASS, minimumVectorLineLength);
|
||||
//println(filteredPoints);
|
||||
if (!filteredPoints.isEmpty())
|
||||
{
|
||||
// draw the first one with a pen up and down to get to it
|
||||
PVector p = filteredPoints.get(0);
|
||||
// pen UP!
|
||||
addToCommandQueue(CMD_PENUP+"END");
|
||||
// move to this point and put the pen down
|
||||
command = CMD_CHANGELENGTHDIRECT+(int)p.x+","+(int)p.y+","+getMaxSegmentLength()+",END";
|
||||
addToCommandQueue(command);
|
||||
addToCommandQueue(CMD_PENDOWN+"END");
|
||||
|
||||
// then just iterate through the rest
|
||||
for (int j=1; j<filteredPoints.size(); j++)
|
||||
{
|
||||
p = filteredPoints.get(j);
|
||||
command = CMD_CHANGELENGTHDIRECT+(int)p.x+","+(int)p.y+","+getMaxSegmentLength()+",END";
|
||||
addToCommandQueue(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
println("finished.");
|
||||
}
|
||||
|
||||
List<PVector> filterPoints(RPoint[] points, int filterToUse, long filterParam)
|
||||
{
|
||||
return filterPointsLowPass(points, filterParam);
|
||||
}
|
||||
|
||||
List<PVector> filterPointsLowPass(RPoint[] points, long filterParam)
|
||||
{
|
||||
List<PVector> result = new ArrayList<PVector>();
|
||||
|
||||
// scale and convert all the points first
|
||||
List<PVector> scaled = new ArrayList<PVector>(points.length);
|
||||
for (int j = 0; j<points.length; j++)
|
||||
{
|
||||
RPoint firstPoint = points[j];
|
||||
PVector p = new PVector(firstPoint.x, firstPoint.y);
|
||||
p = PVector.mult(p, (vectorScaling/100));
|
||||
p = PVector.add(p, getVectorPosition());
|
||||
p = getDisplayMachine().inSteps(p);
|
||||
if (getDisplayMachine().getPage().surrounds(p))
|
||||
{
|
||||
p = getDisplayMachine().asNativeCoords(p);
|
||||
scaled.add(p);
|
||||
}
|
||||
}
|
||||
|
||||
if (scaled.size() > 1)
|
||||
{
|
||||
PVector p = scaled.get(0);
|
||||
result.add(p);
|
||||
|
||||
for (int j = 1; j<scaled.size(); j++)
|
||||
{
|
||||
p = scaled.get(j);
|
||||
// and even then, only bother drawing if it's a move of over "x" steps
|
||||
int diffx = int(p.x) - int(result.get(result.size()-1).x);
|
||||
int diffy = int(p.y) - int(result.get(result.size()-1).y);
|
||||
|
||||
if (abs(diffx) > filterParam || abs(diffy) > filterParam)
|
||||
{
|
||||
println("Adding point " + p + ", last: " + result.get(result.size()-1));
|
||||
result.add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result.size() < 2)
|
||||
result.clear();
|
||||
|
||||
println("finished filter.");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void sendMachineStoreMode()
|
||||
{
|
||||
String overwrite = ",R";
|
||||
if (!getOverwriteExistingStoreFile())
|
||||
overwrite = ",A";
|
||||
|
||||
addToCommandQueue(CMD_MACHINE_MODE_STORE_COMMANDS + getStoreFilename()+overwrite+",END");
|
||||
}
|
||||
void sendMachineLiveMode()
|
||||
{
|
||||
addToCommandQueue(CMD_MACHINE_MODE_LIVE+"END");
|
||||
}
|
||||
void sendMachineExecMode()
|
||||
{
|
||||
sendMachineLiveMode();
|
||||
if (storeFilename != null && !"".equals(storeFilename))
|
||||
addToCommandQueue(CMD_MACHINE_MODE_EXEC_FROM_STORE + getStoreFilename() + ",END");
|
||||
}
|
||||
void sendRandomDraw()
|
||||
{
|
||||
addToCommandQueue(CMD_RANDOM_DRAW+"END");
|
||||
}
|
||||
void sendStartSwirling()
|
||||
{
|
||||
addToCommandQueue(CMD_SWIRLING+"1,END");
|
||||
}
|
||||
void sendStopSwirling()
|
||||
{
|
||||
addToCommandQueue(CMD_SWIRLING+"0,END");
|
||||
}
|
||||
void sendDrawRandomSprite(String spriteFilename)
|
||||
{
|
||||
addToCommandQueue(CMD_DRAW_RANDOM_SPRITE+","+spriteFilename+",100,500,END");
|
||||
}
|
||||
|
||||
|
||||
|
674
gpl.txt
Normal file
674
gpl.txt
Normal file
@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
2865
polargraphcontroller.pde
Normal file
2865
polargraphcontroller.pde
Normal file
File diff suppressed because it is too large
Load Diff
107
tabSetup.pde
Normal file
107
tabSetup.pde
Normal file
@ -0,0 +1,107 @@
|
||||
/**
|
||||
Polargraph controller
|
||||
Copyright Sandy Noble 2012.
|
||||
|
||||
This file is part of Polargraph Controller.
|
||||
|
||||
Polargraph Controller is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Polargraph Controller is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Polargraph Controller. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Requires the excellent ControlP5 GUI library available from http://www.sojamo.de/libraries/controlP5/.
|
||||
Requires the excellent Geomerative library available from http://www.ricardmarxer.com/geomerative/.
|
||||
|
||||
This is an application for controlling a polargraph machine, communicating using ASCII command language over a serial link.
|
||||
|
||||
sandy.noble@gmail.com
|
||||
http://www.polargraph.co.uk/
|
||||
http://code.google.com/p/polargraph/
|
||||
*/
|
||||
|
||||
Set<Panel> getPanelsForTab(String tabName)
|
||||
{
|
||||
if (getPanelsForTabs().containsKey(tabName))
|
||||
{
|
||||
return getPanelsForTabs().get(tabName);
|
||||
}
|
||||
else
|
||||
return new HashSet<Panel>(0);
|
||||
}
|
||||
|
||||
Map<String, Set<Panel>> buildPanelsForTabs()
|
||||
{
|
||||
Map<String, Set<Panel>> map = new HashMap<String, Set<Panel>>();
|
||||
|
||||
Set<Panel> inputPanels = new HashSet<Panel>(2);
|
||||
inputPanels.add(getPanel(PANEL_NAME_INPUT));
|
||||
inputPanels.add(getPanel(PANEL_NAME_GENERAL));
|
||||
|
||||
Set<Panel> rovingPanels = new HashSet<Panel>(2);
|
||||
rovingPanels.add(getPanel(PANEL_NAME_ROVING));
|
||||
rovingPanels.add(getPanel(PANEL_NAME_GENERAL));
|
||||
|
||||
Set<Panel> detailsPanels = new HashSet<Panel>(2);
|
||||
detailsPanels.add(getPanel(PANEL_NAME_DETAILS));
|
||||
detailsPanels.add(getPanel(PANEL_NAME_GENERAL));
|
||||
|
||||
Set<Panel> queuePanels = new HashSet<Panel>(2);
|
||||
queuePanels.add(getPanel(PANEL_NAME_QUEUE));
|
||||
queuePanels.add(getPanel(PANEL_NAME_GENERAL));
|
||||
|
||||
map.put(TAB_NAME_INPUT, inputPanels);
|
||||
map.put(TAB_NAME_ROVING, rovingPanels);
|
||||
map.put(TAB_NAME_DETAILS, detailsPanels);
|
||||
map.put(TAB_NAME_QUEUE, queuePanels);
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
List<String> buildTabNames()
|
||||
{
|
||||
List<String> list = new ArrayList<String>(4);
|
||||
list.add(TAB_NAME_INPUT);
|
||||
list.add(TAB_NAME_ROVING);
|
||||
list.add(TAB_NAME_DETAILS);
|
||||
list.add(TAB_NAME_QUEUE);
|
||||
return list;
|
||||
}
|
||||
|
||||
void initTabs()
|
||||
{
|
||||
cp5.tab(TAB_NAME_INPUT).setLabel(TAB_LABEL_INPUT);
|
||||
cp5.tab(TAB_NAME_INPUT).activateEvent(true);
|
||||
cp5.tab(TAB_NAME_INPUT).setId(1);
|
||||
|
||||
cp5.tab(TAB_NAME_DETAILS).setLabel(TAB_LABEL_DETAILS);
|
||||
cp5.tab(TAB_NAME_DETAILS).activateEvent(true);
|
||||
cp5.tab(TAB_NAME_DETAILS).setId(2);
|
||||
|
||||
cp5.tab(TAB_NAME_ROVING).setLabel(TAB_LABEL_ROVING);
|
||||
cp5.tab(TAB_NAME_ROVING).activateEvent(true);
|
||||
cp5.tab(TAB_NAME_ROVING).setId(3);
|
||||
|
||||
cp5.tab(TAB_NAME_QUEUE).setLabel(TAB_LABEL_QUEUE);
|
||||
cp5.tab(TAB_NAME_QUEUE).activateEvent(true);
|
||||
cp5.tab(TAB_NAME_QUEUE).setId(4);
|
||||
}
|
||||
|
||||
public Set<String> buildPanelNames()
|
||||
{
|
||||
Set<String> set = new HashSet<String>(5);
|
||||
set.add(PANEL_NAME_INPUT);
|
||||
set.add(PANEL_NAME_ROVING);
|
||||
set.add(PANEL_NAME_DETAILS);
|
||||
set.add(PANEL_NAME_QUEUE);
|
||||
set.add(PANEL_NAME_GENERAL);
|
||||
return set;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user