📄 cpcanvas.java
字号:
public void setInterpolation(boolean enabled) {
interpolation = enabled;
repaint();
}
public boolean getInterpolation() {
return interpolation;
}
// Update the affine transformation
void updateTransform() {
transform.setToIdentity();
transform.translate(offsetX, offsetY);
transform.scale(zoom, zoom);
transform.rotate(canvasRotation);
updateScrollBars();
repaint();
}
// More advanced zoom methods
public void zoomOnCenter(float zoom) {
Dimension d = getSize();
zoomOnPoint(zoom, d.width / 2, d.height / 2);
}
public void zoomOnPoint(float zoom, int centerX, int centerY) {
zoom = Math.max(minZoom, Math.min(maxZoom, zoom));
if (getZoom() != zoom) {
Point offset = getOffset();
setOffset(offset.x + (int) ((centerX - offset.x) * (1 - zoom / getZoom())), offset.y
+ (int) ((centerY - offset.y) * (1 - zoom / getZoom())));
setZoom(zoom);
CPController.CPViewInfo viewInfo = new CPController.CPViewInfo();
viewInfo.zoom = zoom;
viewInfo.offsetX = offsetX;
viewInfo.offsetY = offsetY;
controller.callViewListeners(viewInfo);
repaint();
}
}
public void zoomIn() {
zoomOnCenter(getZoom() * 2);
}
public void zoomOut() {
zoomOnCenter(getZoom() * .5f);
}
public void zoom100() {
resetRotation();
zoomOnCenter(1);
centerCanvas();
}
public void centerCanvas() {
Dimension d = getSize();
setOffset((d.width - (int) (artwork.width * getZoom())) / 2,
(d.height - (int) (artwork.height * getZoom())) / 2);
repaint();
}
public void resetRotation() {
Dimension d = getSize();
Point2D.Float center = new Point2D.Float(d.width / 2.f, d.height / 2.f);
AffineTransform rotTrans = new AffineTransform();
rotTrans.rotate(-getRotation(), center.x, center.y);
rotTrans.concatenate(transform);
setOffset((int) rotTrans.getTranslateX(), (int) rotTrans.getTranslateY());
setRotation(0);
}
//
// Coordinates and refresh areas methods
//
public Point2D.Float coordToDocument(Point2D p) {
Point2D.Float result = new Point2D.Float();
try {
transform.inverseTransform(p, result);
} catch (NoninvertibleTransformException ex) {
}
return result;
}
public Point coordToDocumentInt(Point2D p) {
Point2D.Float result = new Point2D.Float();
try {
transform.inverseTransform(p, result);
} catch (NoninvertibleTransformException ex) {
}
return new Point((int) result.x, (int) result.y);
}
public Point2D.Float coordToDisplay(Point2D p) {
Point2D.Float result = new Point2D.Float();
transform.transform(p, result);
return result;
}
public Point coordToDisplayInt(Point2D p) {
Point2D.Float result = new Point2D.Float();
transform.transform(p, result);
return new Point((int) result.x, (int) result.y);
}
public Polygon coordToDisplay(CPRect r) {
Polygon poly = new Polygon();
Point p = coordToDisplayInt(new Point(r.left, r.top));
poly.addPoint(p.x, p.y);
p = coordToDisplayInt(new Point(r.right - 1, r.top));
poly.addPoint(p.x, p.y);
p = coordToDisplayInt(new Point(r.right - 1, r.bottom - 1));
poly.addPoint(p.x, p.y);
p = coordToDisplayInt(new Point(r.left, r.bottom - 1));
poly.addPoint(p.x, p.y);
return poly;
}
public Rectangle getRefreshArea(CPRect r) {
Point p1 = coordToDisplayInt(new Point(r.left - 1, r.top - 1));
Point p2 = coordToDisplayInt(new Point(r.left - 1, r.bottom));
Point p3 = coordToDisplayInt(new Point(r.right, r.top - 1));
Point p4 = coordToDisplayInt(new Point(r.right, r.bottom));
Rectangle r2 = new Rectangle();
r2.x = Math.min(Math.min(p1.x, p2.x), Math.min(p3.x, p4.x));
r2.y = Math.min(Math.min(p1.y, p2.y), Math.min(p3.y, p4.y));
r2.width = Math.max(Math.max(p1.x, p2.x), Math.max(p3.x, p4.x)) - r2.x + 1;
r2.height = Math.max(Math.max(p1.y, p2.y), Math.max(p3.y, p4.y)) - r2.y + 1;
r2.grow(2, 2); // to be sure to include everything
return r2;
}
private void repaintBrushPreview() {
if (oldPreviewRect != null) {
Rectangle r = oldPreviewRect;
oldPreviewRect = null;
repaint(r.x, r.y, r.width, r.height);
}
}
private Rectangle getBrushPreviewOval() {
int bSize = (int) (controller.getBrushSize() * zoom);
return new Rectangle(mouseX - bSize / 2, mouseY - bSize / 2, bSize, bSize);
}
//
// ChibiPaint interfaces methods
//
public void newTool(int tool, CPBrushInfo toolInfo) {
if (curSelectedMode == curDrawMode) {
curSelectedMode = drawingModes[toolInfo.strokeMode];
}
curDrawMode = drawingModes[toolInfo.strokeMode];
if (!spacePressed && mouseIn) {
brushPreview = true;
Rectangle r = getBrushPreviewOval();
r.grow(2, 2);
if (oldPreviewRect != null) {
r = r.union(oldPreviewRect);
oldPreviewRect = null;
}
repaint(r.x, r.y, r.width, r.height);
}
}
public void modeChange(int mode) {
switch (mode) {
case CPController.M_DRAW:
curSelectedMode = curDrawMode;
break;
case CPController.M_FLOODFILL:
curSelectedMode = floodFillMode;
break;
case CPController.M_RECT_SELECTION:
curSelectedMode = rectSelectionMode;
break;
case CPController.M_MOVE_TOOL:
curSelectedMode = moveToolMode;
break;
case CPController.M_ROTATE_CANVAS:
curSelectedMode = rotateCanvasMode;
break;
}
}
//
// misc overloaded and interface standard methods
//
public Dimension getPreferredSize() {
return new Dimension((int) (artwork.width * zoom), (int) (artwork.height * zoom));
}
public void componentResized(ComponentEvent e) {
centerCanvas();
repaint();
}
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
spacePressed = true;
repaintBrushPreview();
if (activeMode == defaultMode) {
setCursor(moveCursor);
}
}
// FIXME: these should probably go through the controller to be dispatched
if ((e.getModifiers() & InputEvent.CTRL_MASK) != 0) {
switch (e.getKeyCode()) {
// case KeyEvent.VK_ADD:
case KeyEvent.VK_EQUALS:
zoomIn();
break;
// case KeyEvent.VK_SUBTRACT:
case KeyEvent.VK_MINUS:
zoomOut();
break;
case KeyEvent.VK_0:
// case KeyEvent.VK_NUMPAD0:
zoom100();
break;
}
} else {
switch (e.getKeyCode()) {
case KeyEvent.VK_ADD:
case KeyEvent.VK_EQUALS:
zoomIn();
break;
case KeyEvent.VK_SUBTRACT:
case KeyEvent.VK_MINUS:
zoomOut();
break;
case KeyEvent.VK_1:
controller.setAlpha((int) (.1f * 255));
break;
case KeyEvent.VK_2:
controller.setAlpha((int) (.2f * 255));
break;
case KeyEvent.VK_3:
controller.setAlpha((int) (.3f * 255));
break;
case KeyEvent.VK_4:
controller.setAlpha((int) (.4f * 255));
break;
case KeyEvent.VK_5:
controller.setAlpha((int) (.5f * 255));
break;
case KeyEvent.VK_6:
controller.setAlpha((int) (.6f * 255));
break;
case KeyEvent.VK_7:
controller.setAlpha((int) (.7f * 255));
break;
case KeyEvent.VK_8:
controller.setAlpha((int) (.8f * 255));
break;
case KeyEvent.VK_9:
controller.setAlpha((int) (.9f * 255));
break;
case KeyEvent.VK_0:
controller.setAlpha(255);
break;
}
}
}
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
spacePressed = false;
if (activeMode == defaultMode) {
setCursor(defaultCursor);
}
}
}
public void keyTyped(KeyEvent e) {
switch (e.getKeyChar()) {
case '[':
controller.setBrushSize(controller.getBrushSize() - 1);
break;
case ']':
controller.setBrushSize(controller.getBrushSize() + 1);
break;
}
}
public boolean isFocusable() {
return true;
}
// Unused interface methods
public void mouseClicked(MouseEvent e) {
}
public void componentHidden(ComponentEvent e) {
}
public void componentMoved(ComponentEvent e) {
}
public void componentShown(ComponentEvent e) {
}
public void updateRegion(CPArtwork artwork, CPRect region) {
updateRegion.union(region);
Rectangle r = getRefreshArea(region);
repaint(r.x, r.y, r.width, r.height);
}
// unused method
public void layerChange(CPArtwork artwork) {
}
public void showGrid(boolean show) {
showGrid = show;
repaint();
}
//
// base class for the different modes
//
abstract class CPMode implements MouseListener, MouseMotionListener {
// Mouse Input
public void mousePressed(MouseEvent e) {
}
public void mouseDragged(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
// GUI drawing
public void paint(Graphics2D g2d) {
}
}
//
// Default UI Mode when not doing anything: used to start the other modes
//
//
// /!\ WARNING: always use getModifiersEx() to test for modifier
// keys as methods like isAltDown() have unexpected results
//
class CPDefaultMode extends CPMode {
public void mousePressed(MouseEvent e) {
// FIXME: replace the moveToolMode hack by a new and improved system
if (!spacePressed && e.getButton() == MouseEvent.BUTTON1
&& (((e.getModifiersEx() & InputEvent.ALT_DOWN_MASK) == 0) || curSelectedMode == moveToolMode)) {
if (!artwork.getActiveLayer().visible && curSelectedMode != rotateCanvasMode
&& curSelectedMode != rectSelectionMode) {
return; // don't draw on a hidden layer
}
repaintBrushPreview();
activeMode = curSelectedMode;
activeMode.mousePressed(e);
} else if (!spacePressed
&& (e.getButton() == MouseEvent.BUTTON3 || (e.getButton() == MouseEvent.BUTTON1 && ((e
.getModifiersEx() & InputEvent.ALT_DOWN_MASK) == InputEvent.ALT_DOWN_MASK)))) {
repaintBrushPreview();
activeMode = colorPickerMode;
activeMode.mousePressed(e);
} else if ((e.getButton() == MouseEvent.BUTTON2 || spacePressed)
&& ((e.getModifiersEx() & InputEvent.ALT_DOWN_MASK) == 0)) {
repaintBrushPreview();
activeMode = moveCanvasMode;
activeMode.mousePressed(e);
} else if ((e.getButton() == MouseEvent.BUTTON2 || spacePressed)
&& ((e.getModifiersEx() & InputEvent.ALT_DOWN_MASK) == InputEvent.ALT_DOWN_MASK)) {
repaintBrushPreview();
activeMode = rotateCanvasMode;
activeMode.mousePressed(e);
}
}
public void paint(Graphics2D g2d) {
if (brushPreview && curSelectedMode == curDrawMode) {
brushPreview = false;
Rectangle r = getBrushPreviewOval();
g2d.drawOval(r.x, r.y, r.width, r.height);
r.grow(2, 2);
oldPreviewRect = oldPreviewRect != null ? r.union(oldPreviewRect) : r;
}
}
public void mouseMoved(MouseEvent e) {
if (!spacePressed) {
brushPreview = true;
Rectangle r = getBrushPreviewOval();
r.grow(2, 2);
if (oldPreviewRect != null) {
r = r.union(oldPreviewRect);
oldPreviewRect = null;
}
Point p = e.getPoint();
Point2D.Float pf = coordToDocument(p);
if (artwork.isPointWithin(pf.x, pf.y)) {
setCursor(defaultCursor); // FIXME find a cursor that everyone likes
} else {
setCursor(defaultCursor);
}
repaint(r.x, r.y, r.width, r.height);
}
}
}
//
// Freehand mode
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -