📄 photoframe.java
字号:
}
/**
* Translate the prop by the given horizontal and vertical distances.
*
* @param dx The horizontal distance to move the prop.
* @param dy The vertical distance to move the prop.
*/
public void translateProp(final SVGLocatableElement prop, final float dx, final float dy) {
if (prop != null) {
SVGMatrix translateTxf = prop.getMatrixTrait("transform");
SVGMatrix txf = prop.getScreenCTM();
translateTxf.mMultiply(txf.inverse());
translateTxf.mTranslate(dx, dy);
translateTxf.mMultiply(txf);
prop.setMatrixTrait("transform", translateTxf);
repaint();
}
}
/**
* Scales the prop by the given scale.
*
* @param scale The scaling factor to be applied to the prop.
*/
public void scaleProp(final SVGLocatableElement prop, final float scale) {
if (prop != null) {
SVGMatrix scaleTxf = prop.getMatrixTrait("transform");
SVGMatrix txf = prop.getScreenCTM();
scaleTxf.mMultiply(txf.inverse());
scaleTxf.mTranslate(cursorX, cursorY);
scaleTxf.mScale(scale);
scaleTxf.mTranslate(-cursorX, -cursorY);
scaleTxf.mMultiply(txf);
prop.setMatrixTrait("transform", scaleTxf);
repaint();
}
}
/**
* Rotates the prop by the given angle.
*
* @param angle The angle by which the prop will be rotated.
*/
public void rotateProp(final SVGLocatableElement prop, final float angle) {
if (prop != null) {
SVGMatrix rotateTxf = prop.getMatrixTrait("transform");
SVGMatrix txf = prop.getScreenCTM();
rotateTxf.mMultiply(txf.inverse());
rotateTxf.mTranslate(cursorX, cursorY);
rotateTxf.mRotate(angle);
rotateTxf.mTranslate(-cursorX, -cursorY);
rotateTxf.mMultiply(txf);
prop.setMatrixTrait("transform", rotateTxf);
repaint();
}
}
/**
* Mirrors the prop about the horizontal or vertical axis.
*
* @param angle The angle by which the image will be rotated.
* @param flipHorizontal <code>true</code> if mirroring will be about the
* vertical axis; <code>false</code> if mirroring will be about the
* horizontal axis.
*/
public void mirrorProp(final SVGLocatableElement prop, final boolean flipHorizontal) {
if (prop != null) {
SVGMatrix mirrorTxf = prop.getMatrixTrait("transform");
SVGMatrix mirroringTxf =
flipHorizontal ? svg.createSVGMatrixComponents(-1, 0, 0, 1, 0, 0)
: svg.createSVGMatrixComponents(1, 0, 0, -1, 0, 0);
SVGMatrix txf = prop.getScreenCTM();
mirrorTxf.mMultiply(txf.inverse());
mirrorTxf.mTranslate(cursorX, cursorY);
mirrorTxf.mMultiply(mirroringTxf);
mirrorTxf.mTranslate(-cursorX, -cursorY);
mirrorTxf.mMultiply(txf);
prop.setMatrixTrait("transform", mirrorTxf);
repaint();
}
}
/**
* Handle a keypress.
* @param keyCode The code for the key that was pressed.
*/
public void keyPressed(int keyCode) {
handleKey(keyCode);
}
/**
* Repeat a keypress.
* @param keyCode The code for the key that was pressed.
*/
public void keyRepeated(int keyCode) {
// keyPressed(keyCode);
}
/**
* Process a keypress.
* <p>
* Note: This routine has been made separate from keyPressed in case
* repeated events need to be handled.
*
* @param keyCode The code for the key that was pressed.
*/
private void handleKey(final int keyCode) {
if (svgImage == null) {
// Ignore input until the props are available.
return;
}
int gameAction = getGameAction(keyCode);
if (gameAction == FIRE) {
int w = getWidth();
int h = getHeight();
if (prop != null) {
// Detach the prop from the crosshair.
prop = null;
} else {
// Pick up a prop or nothing (Leave prop null).
prop = getPropContaining((float)cursorX, (float)cursorY);
}
// Center the cursor again if it went off the screen.
if ((cursorX < 0) || (cursorX >= w) || (cursorY < 0) || (cursorY >= h)) {
centerCursor();
}
// Make sure the cursor gets updated.
repaint();
} else if (gameAction == UP) {
cursorY -= CURSOR_STEP;
if (svgImage != null) {
translateProp(prop, 0, -CURSOR_STEP);
}
repaint();
} else if (gameAction == DOWN) {
cursorY += CURSOR_STEP;
translateProp(prop, 0, CURSOR_STEP);
repaint();
} else if (gameAction == LEFT) {
cursorX -= CURSOR_STEP;
translateProp(prop, -CURSOR_STEP, 0);
repaint();
} else if (gameAction == RIGHT) {
cursorX += CURSOR_STEP;
translateProp(prop, CURSOR_STEP, 0);
repaint();
} else if (keyCode == Canvas.KEY_NUM0) {
if (prop != null) {
removeProp();
}
} else if (keyCode == Canvas.KEY_NUM1) {
scaleProp(prop, 1.00F - 0.10F);
} else if (keyCode == Canvas.KEY_NUM2) {
try {
setPhoto(photoNumber + 1);
} catch (IllegalArgumentException iae) {
setPhoto(1);
}
} else if (keyCode == Canvas.KEY_NUM3) {
scaleProp(prop, 1.00F + 0.10F);
} else if (keyCode == Canvas.KEY_NUM4) {
picturedecorator.splashCanvas.showAndWait(picturedecorator.display, this);
} else if (keyCode == Canvas.KEY_NUM5) {
mirrorProp(prop, true); // Horizontal flip
} else if (keyCode == Canvas.KEY_NUM6) {
mirrorProp(prop, false);
} else if (keyCode == Canvas.KEY_NUM7) {
rotateProp(prop, -5);
} else if (keyCode == Canvas.KEY_NUM8) {
try {
setPhoto(photoNumber - 1);
} catch (IllegalArgumentException iae) {
setPhoto(picturedecorator.getMaxPhotoNumber());
}
} else if (keyCode == Canvas.KEY_NUM9) {
rotateProp(prop, +5);
} else if (keyCode == Canvas.KEY_POUND) {
// Show item picker
picturedecorator.display.setCurrent(itemPicker);
}
}
/**
* Returns the smallest prop containing the given coordinate.
* <p>
* Note: This isn't the most refined method for containing a point within
* a prop. If a prop is circular, for example, and the coordinate lies
* outside the visible part of the circle but within the bounding box,
* the prop will be returned.
*
* @param x The horizontal position to be tested.
* @param y The vertical position to be tested.
*
* @return The <code>SVGLocatableElement</code> that contains the
* coordinate; <code>null</code> if the coordinate isn't within the
* bounding box for any of the props on the screen.
*/
private SVGLocatableElement getPropContaining(final float x, final float y) {
// The last smallest rectangle.
float lastX1 = 0;
float lastY1 = 0;
float lastX2 = lastX1 + getWidth();
float lastY2 = lastY1 + getHeight();
// The prop that was located (Initially, no prop located.).
SVGLocatableElement foundProp = null;
int n = visibleProps.size();
for (int i = n - 1; i >= 0; i--) {
SVGLocatableElement elem = (SVGLocatableElement)visibleProps.elementAt(i);
if (elem == null) {
// This shouldn't happen, but just in case, don't crash.
continue;
}
SVGRect r = elem.getScreenBBox();
if (r == null) {
// This shouldn't happen, but just in case, don't crash.
continue;
}
float x1 = r.getX();
float y1 = r.getY();
float x2 = x1 + r.getWidth();
float y2 = y1 + r.getHeight();
if ((x >= x1) && (x < x2) && (y >= y1) && (y < y2)) {
/*
* The cursor is within this prop. If this is the first prop
* that was found, make sure it the user can get to it (This
* can happen in a case where the prop has been enlarged such
* that its bounding box has gone beyond the dimensions of the
* screen.).
*/
if (foundProp == null) {
foundProp = elem;
}
/*
* If this prop has the smallest bounding box, choose this prop
* over a prop that was previously selected.
*/
if ((x1 >= lastX1) || (x2 < lastX2) || (y1 >= lastY1) || (y2 < lastY2)) {
// Use the smaller bounding box now.
lastX1 = x1;
lastY1 = y1;
lastX2 = x2;
lastY2 = y2;
foundProp = elem;
}
}
} // for
return foundProp;
}
/**
* Paint the photo in the back, then layer all SVG images on top.
*
* @param g The graphics context for this canvas.
*/
public void paint(Graphics g) {
int width = getWidth();
int height = getHeight();
// Fill the background when a photo isn't present.
g.setColor(0x00ffffff);
g.fillRect(0, 0, width, height);
// Draw the photo only when the user has taken one.
if (currentImage != null) {
g.drawImage(currentImage, width / 2, height / 2, ANCHOR);
}
// Paint the current SVG image on top of everything.
if (svgImage != null) {
sg.bindTarget(g);
sg.render(0, 0, svgImage);
sg.releaseTarget();
/*
* Draw the cursor. When the cursor is just moving around and has no
* prop attached, use a green triangle. When a prop is attached to
* the cursor, represent the cursor with a crosshair.
*
* When the cursor is simply moving around, give the user a hint as
* to which prop can be picked up by highlighting the prop's
* bounding box.
*/
if (prop == null) {
// First, try to locate the prop that contains the cursor.
SVGLocatableElement elem = getPropContaining((float)cursorX, (float)cursorY);
// If the prop could be found, show its bounding box.
if (elem != null) {
SVGRect r = elem.getScreenBBox();
int rx = (int)r.getX();
int ry = (int)r.getY();
int rwidth = (int)r.getWidth();
int rheight = (int)r.getHeight();
// Draw the bounding box in red.
g.setColor(0x00FF0000);
g.drawRect(rx, ry, rwidth, rheight);
}
// No prop is being manipulated; Use a green triangle cursor.
g.setColor(0x0000CC00);
g.fillTriangle(cursorX, cursorY, cursorX + 4, cursorY + 12, cursorX - 4,
cursorY + 12);
} else {
// Prop is being manipulated. Use a red crosshair cursor.
g.setColor(0x00cc0000);
g.drawLine(cursorX - 5, cursorY, cursorX - 1, cursorY);
g.drawLine(cursorX + 1, cursorY, cursorX + 5, cursorY);
g.drawLine(cursorX, cursorY - 5, cursorX, cursorY - 1);
g.drawLine(cursorX, cursorY + 1, cursorX, cursorY + 5);
}
} // if there's an SVG props file available.
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -