1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
public class MyCanvas extends Canvas {
public enum Draw {
POINT,
LINE,
IMAGE;
}
private final PAffineTransform transform;
private List<IDrawable> drawables = new ArrayList<IDrawable>();
private IDrawable currentDrawable;
private Draw currentDraw = Draw.LINE;
public MyCanvas(Composite composite, int style) {
super(composite, style);
transform = new PAffineTransform(getDisplay()); //
addPaintListener(new PaintListener() {
// on va utiliser cette variable pour mémoriser le transform avant de le changr
// sinon on va foutre la zone dans tout l'affichage
// ici on a pas besoin de manipulation, donc on prend direct une Transform
private final Transform savetransform = new Transform(getDisplay());
{
addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
savetransform.dispose();
}
});
}
@Override
public void paintControl(PaintEvent e) {
e.gc.getTransform(savetransform); // on sauve
e.gc.setTransform(transform); // on affecte le zoom
for(IDrawable drawable : drawables) {
drawable.draw(e.gc, false);
}
if ( currentDrawable!=null ) {
currentDrawable.draw(e.gc, true);
}
e.gc.setTransform(savetransform); // on restaure
}
});
// permet de disposer la transformée lorsque le canvas est disposé : plus besoin d'y penser
addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
transform.dispose();
}
});
MouseAdapter mouseAdapter = new MouseAdapter();
addMouseListener(mouseAdapter);
addMouseMoveListener(mouseAdapter);
// changeZoom(2); // on peut forcer le zoom pour les tests
}
public void changeZoom(double factor) {
checkWidget(); // on s'assure de pas appeler la méthode en dehors du thread SWT par inadvertance
transform.setToScale(factor, factor);
redraw(); // on redessine pour prendre en compte le changement d'échelle
}
public void add(IDrawable drawable) {
checkWidget();
drawables.add(drawable);
redraw();
}
private class MouseAdapter implements MouseListener, MouseMoveListener {
@Override
public void mouseDoubleClick(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseDown(MouseEvent e) {
switch( currentDraw ) {
case LINE:
{
LineDrawable lineDrawable = new LineDrawable();
Point point = inverseTransform(e.x, e.y);
lineDrawable.setPoint1(point.x, point.y);
lineDrawable.setPoint2(point.x, point.y);
currentDrawable = lineDrawable;
}
break;
case POINT:
// à faire
break;
case IMAGE:
// à faire
break;
}
}
private Point inverseTransform(int x, int y) {
Point p1 = new Point(x,y);
try {
return transform.inverseTransform(p1, null);
} catch (NoninvertibleTransformException e) {
// normalement y'a pas de problème d'inversion
e.printStackTrace();
return p1;
}
}
@Override
public void mouseUp(MouseEvent e) {
if ( currentDrawable !=null ) {
drawables.add(currentDrawable);
}
currentDrawable=null;
redraw();
}
@Override
public void mouseMove(MouseEvent e) {
System.out.println("mousemo");
if ( currentDrawable instanceof LineDrawable ) {
LineDrawable lineDrawable = (LineDrawable) currentDrawable;
Point point = inverseTransform(e.x, e.y);
lineDrawable.setPoint2(point.x, point.y);
}
redraw();
}
}
} |
Partager