5 // Created by Lutz Mueller on 6/8/07.
8 // Copyright (C) 2007 Lutz Mueller
10 // This program is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
15 // This program is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
20 // You should have received a copy of the GNU General Public License
21 // along with this program. If not, see <http://www.gnu.org/licenses/>.
26 import java
.awt
.color
.*;
27 import java
.awt
.event
.*;
28 import java
.awt
.geom
.*;
29 import java
.awt
.print
.*;
30 import java
.awt
.image
.BufferStrategy
;
31 import java
.awt
.image
.BufferedImage
;
33 import javax
.imageio
.ImageIO
;
36 import java
.io
.IOException
;
38 @SuppressWarnings("unchecked")
39 public class CanvasWidget
extends gsObject
{
41 static CanvasWidget currentCanvas
;
43 Vector drawobjects
= new Vector();
47 double translationX
= 0;
48 double translationY
= 0;
52 Color background
= null;
55 //AffineTransform transform = AffineTransform.getScaleInstance(1.0, 1.0);
56 AffineTransform transform
= null;
57 AlphaComposite currentComposite
;
58 Font currentFont
= null;
59 boolean antiAliasing
= true;
60 boolean visible
= true;
62 String mouseClickedEvent
;
63 String mouseEnteredEvent
;
64 String mouseExitedEvent
;
65 String mousePressedEvent
;
66 String mouseReleasedEvent
;
67 String mouseDraggedEvent
;
68 String mouseMovedEvent
;
69 String mouseWheelMovedEvent
;
71 boolean mousePressedTags
= false;
72 boolean mouseReleasedTags
= false;
73 boolean mouseClickedTags
= false;
74 boolean mouseMovedTags
= false;
76 public CanvasWidget(StringTokenizer params
)
78 id
= params
.nextToken();
79 canvas
= new MyCanvas();
83 // if canvas is not Canvas but JPanel
87 CanvasWidget
.currentCanvas
= this;
89 currentStroke
= new BasicStroke();
90 currentPaint
= new Color(0,0,0);
95 gsObject
.widgets
.put(id
, this);
98 public void g2Canvas(StringTokenizer tokens
)
100 CanvasWidget
.currentCanvas
= this;
103 public void g2Translation(StringTokenizer tokens
)
105 translationX
= Float
.parseFloat(tokens
.nextToken());
106 translationY
= Float
.parseFloat(tokens
.nextToken());
109 public void g2Scale(StringTokenizer tokens
)
111 scaleX
= Float
.parseFloat(tokens
.nextToken());
112 scaleY
= Float
.parseFloat(tokens
.nextToken());
115 public void g2Rotation(StringTokenizer tokens
)
117 double rotation
= Float
.parseFloat(tokens
.nextToken());
118 theta
= 2.0 * Math
.PI
* rotation
/ 360.0;
121 public void g2Transform(StringTokenizer tokens
)
123 double m00
= Float
.parseFloat(tokens
.nextToken());
124 double m01
= Float
.parseFloat(tokens
.nextToken());
125 double m02
= Float
.parseFloat(tokens
.nextToken());
126 double m10
= Float
.parseFloat(tokens
.nextToken());
127 double m11
= Float
.parseFloat(tokens
.nextToken());
128 double m12
= Float
.parseFloat(tokens
.nextToken());
130 //transform.concatenate(new AffineTransform(m00, m01, m02, m10, m11, m12));
133 public void g2Stroke(StringTokenizer tokens
)
135 float strokeWidth
= Float
.parseFloat(tokens
.nextToken());
136 int strokeCap
= BasicStroke
.CAP_BUTT
;
137 int strokeJoin
= BasicStroke
.JOIN_MITER
;
138 float strokeMiterLimit
= (float)10.0;
140 if(tokens
.hasMoreTokens())
142 String cap
= tokens
.nextToken();
143 if(cap
.equals("round")) strokeCap
= BasicStroke
.CAP_ROUND
;
144 else if(cap
.equals("square")) strokeCap
= BasicStroke
.CAP_SQUARE
;
145 else strokeCap
= BasicStroke
.CAP_BUTT
;
148 if(tokens
.hasMoreTokens())
150 String join
= tokens
.nextToken();
151 if(join
.equals("round")) strokeJoin
= BasicStroke
.JOIN_BEVEL
;
152 else if(join
.equals("square")) strokeJoin
= BasicStroke
.JOIN_ROUND
;
153 else strokeJoin
= BasicStroke
.JOIN_MITER
;
156 if(tokens
.hasMoreTokens())
157 strokeMiterLimit
= Float
.parseFloat(tokens
.nextToken());
159 currentStroke
= new BasicStroke(strokeWidth
, strokeCap
, strokeJoin
, strokeMiterLimit
);
162 public void g2Paint(StringTokenizer tokens
)
167 R
= Float
.parseFloat(tokens
.nextToken());
168 G
= Float
.parseFloat(tokens
.nextToken());
169 B
= Float
.parseFloat(tokens
.nextToken());
171 if(tokens
.hasMoreTokens())
172 alpha
= Float
.parseFloat(tokens
.nextToken());
176 currentPaint
= new Color(R
, G
, B
, alpha
);
179 public void g2Update(StringTokenizer tokens
)
184 public void g2Export(StringTokenizer tokens
)
186 String path
= Base64Coder
.decodeString(tokens
.nextToken());
187 int width
= canvas
.getWidth();
188 int height
= canvas
.getHeight();
190 if(tokens
.hasMoreTokens())
192 width
= Integer
.parseInt(tokens
.nextToken());
193 height
= Integer
.parseInt(tokens
.nextToken());
196 canvas
.export(path
, "PNG", width
, height
);
199 public void g2Print(StringTokenizer tokens
)
203 public void setBackground(StringTokenizer tokens
)
208 R
= Float
.parseFloat(tokens
.nextToken());
209 G
= Float
.parseFloat(tokens
.nextToken());
210 B
= Float
.parseFloat(tokens
.nextToken());
212 if(tokens
.hasMoreTokens())
213 alpha
= Float
.parseFloat(tokens
.nextToken());
217 background
= new Color(R
, G
, B
, alpha
);
219 component
.setBackground(background
);
222 public void setFont(StringTokenizer tokens
)
224 String name
= Base64Coder
.decodeString(tokens
.nextToken());
228 if(tokens
.hasMoreTokens())
229 size
= Integer
.parseInt(tokens
.nextToken());
231 while(tokens
.hasMoreTokens())
233 String sstyle
= tokens
.nextToken();
234 if(sstyle
.equals("plain")) style
= style
| Font
.PLAIN
;
235 if(sstyle
.equals("bold")) style
= style
| Font
.BOLD
;
236 if(sstyle
.equals("italic")) style
= style
| Font
.ITALIC
;
239 currentFont
= new Font(name
, style
, size
);
240 component
.setFont(currentFont
);
244 public void setAntiAliasing(StringTokenizer tokens
)
246 antiAliasing
= tokens
.nextToken().equals("true");
251 public void drawLine(StringTokenizer tokens
)
253 new LineShape(tokens
);
256 public void drawRectangle(StringTokenizer tokens
)
258 new RectangleShape(tokens
);
261 public void fillRectangle(StringTokenizer tokens
)
263 new FilledRectangleShape(tokens
);
266 public void drawRoundRect(StringTokenizer tokens
)
268 new RoundRectangleShape(tokens
);
271 public void fillRoundRect(StringTokenizer tokens
)
273 new FilledRoundRectangleShape(tokens
);
276 public void drawEllipse(StringTokenizer tokens
)
278 new EllipseShape(tokens
);
281 public void fillEllipse(StringTokenizer tokens
)
283 new FilledEllipseShape(tokens
);
286 public void drawCircle(StringTokenizer tokens
)
288 new CircleShape(tokens
);
291 public void fillCircle(StringTokenizer tokens
)
293 new FilledCircleShape(tokens
);
296 public void drawArc(StringTokenizer tokens
)
298 new ArcShape(tokens
);
301 public void fillArc(StringTokenizer tokens
)
303 new FilledArcShape(tokens
);
306 public void drawPolygon(StringTokenizer tokens
)
308 new PolygonShape(tokens
);
311 public void fillPolygon(StringTokenizer tokens
)
313 new FilledPolygonShape(tokens
);
316 public void drawPath(StringTokenizer tokens
)
318 new PathShape(tokens
);
321 public void drawText(StringTokenizer tokens
)
323 new TextShape(tokens
);
326 public void drawImage(StringTokenizer tokens
)
328 new ImageShape(tokens
);
331 // register mouse events
333 public void registerMouseClicked(StringTokenizer tokens
)
335 mouseClickedEvent
= tokens
.nextToken();
336 if(tokens
.hasMoreTokens())
337 mouseClickedTags
= tokens
.nextToken().equals("true");
340 public void registerMousePressed(StringTokenizer tokens
)
342 mousePressedEvent
= tokens
.nextToken();
343 if(tokens
.hasMoreTokens())
344 mousePressedTags
= tokens
.nextToken().equals("true");
347 public void registerMouseRelease(StringTokenizer tokens
)
349 mouseReleasedEvent
= tokens
.nextToken();
350 if(tokens
.hasMoreTokens())
351 mouseReleasedTags
= tokens
.nextToken().equals("true");
354 public void registerMouseExited(StringTokenizer tokens
)
356 mouseExitedEvent
= tokens
.nextToken();
359 public void registerMouseEntered(StringTokenizer tokens
)
361 mouseEnteredEvent
= tokens
.nextToken();
364 public void registerMouseDragged(StringTokenizer tokens
)
366 mouseDraggedEvent
= tokens
.nextToken();
369 public void registerMouseMoved(StringTokenizer tokens
)
371 mouseMovedEvent
= tokens
.nextToken();
372 if(tokens
.hasMoreTokens())
373 mouseMovedTags
= tokens
.nextToken().equals("true");
376 public void registerMouseWheel(StringTokenizer tokens
)
378 mouseWheelMovedEvent
= tokens
.nextToken();
383 public void deleteTaggedShape(StringTokenizer tokens
)
385 String label
= tokens
.nextToken();
386 boolean updateFlag
= tokens
.nextToken().equals("true");
387 Vector filteredObjects
= new Vector();
390 for(int i
= 0; i
< drawobjects
.size(); i
++)
392 aShape
= (Shape
)drawobjects
.elementAt(i
);
393 if(!aShape
.tag
.equals(label
))
394 filteredObjects
.add(aShape
);
397 drawobjects
= filteredObjects
;
398 if(updateFlag
) canvas
.repaint();
401 public void moveTaggedShape(StringTokenizer tokens
)
403 String label
= tokens
.nextToken();
404 int dx
= Integer
.parseInt(tokens
.nextToken());
405 int dy
= Integer
.parseInt(tokens
.nextToken());
406 boolean updateFlag
= tokens
.nextToken().equals("true");
410 for(int i
= 0; i
< drawobjects
.size(); i
++)
412 aShape
= (Shape
)drawobjects
.elementAt(i
);
413 if(aShape
.tag
.equals(label
))
420 if(updateFlag
) canvas
.repaint();
423 public void translateTaggedShape(StringTokenizer tokens
)
425 String label
= tokens
.nextToken();
426 double X
= Float
.parseFloat(tokens
.nextToken());
427 double Y
= Float
.parseFloat(tokens
.nextToken());
428 boolean updateFlag
= tokens
.nextToken().equals("true");
431 for(int i
= 0; i
< drawobjects
.size(); i
++)
433 aShape
= (Shape
)drawobjects
.elementAt(i
);
434 if(aShape
.tag
.equals(label
))
435 aShape
.transform
.translate(X
, Y
);
438 if(updateFlag
) canvas
.repaint();
442 public void rotateTaggedShape(StringTokenizer tokens
)
444 String label
= tokens
.nextToken();
445 double theta
= Float
.parseFloat(tokens
.nextToken());
446 int X
= Integer
.parseInt(tokens
.nextToken());
447 int Y
= Integer
.parseInt(tokens
.nextToken());
448 boolean updateFlag
= tokens
.nextToken().equals("true");
451 theta
= 2.0 * Math
.PI
* theta
/ 360.0;
453 for(int i
= 0; i
< drawobjects
.size(); i
++)
455 aShape
= (Shape
)drawobjects
.elementAt(i
);
456 if(aShape
.tag
.equals(label
))
457 aShape
.transform
.rotate(theta
, X
, Y
);
460 if(updateFlag
) canvas
.repaint();
463 public void scaleTaggedShape(StringTokenizer tokens
)
465 String label
= tokens
.nextToken();
466 double sx
= Float
.parseFloat(tokens
.nextToken());
467 double sy
= Float
.parseFloat(tokens
.nextToken());
468 boolean updateFlag
= tokens
.nextToken().equals("true");
471 for(int i
= 0; i
< drawobjects
.size(); i
++)
473 aShape
= (Shape
)drawobjects
.elementAt(i
);
474 if(aShape
.tag
.equals(label
))
475 aShape
.transform
.scale(sx
, sy
);
478 if(updateFlag
) canvas
.repaint();
481 public void shearTaggedShape(StringTokenizer tokens
)
483 String label
= tokens
.nextToken();
484 double shx
= Float
.parseFloat(tokens
.nextToken());
485 double shy
= Float
.parseFloat(tokens
.nextToken());
486 boolean updateFlag
= tokens
.nextToken().equals("true");
489 for(int i
= 0; i
< drawobjects
.size(); i
++)
491 aShape
= (Shape
)drawobjects
.elementAt(i
);
492 if(aShape
.tag
.equals(label
))
493 aShape
.transform
.shear(shx
, shy
);
496 if(updateFlag
) canvas
.repaint();
499 public void hideTaggedShape(StringTokenizer tokens
)
501 String label
= tokens
.nextToken();
502 boolean updateFlag
= tokens
.nextToken().equals("true");
505 for(int i
= 0; i
< drawobjects
.size(); i
++)
507 aShape
= (Shape
)drawobjects
.elementAt(i
);
508 if(aShape
.tag
.equals(label
))
509 aShape
.visible
= false;
512 if(updateFlag
) canvas
.repaint();
516 public void showTaggedShape(StringTokenizer tokens
)
518 String label
= tokens
.nextToken();
519 boolean updateFlag
= tokens
.nextToken().equals("true");
522 for(int i
= 0; i
< drawobjects
.size(); i
++)
524 aShape
= (Shape
)drawobjects
.elementAt(i
);
525 if(aShape
.tag
.equals(label
))
526 aShape
.visible
= true;
529 if(updateFlag
) canvas
.repaint();
533 public void orderTaggedShapes(StringTokenizer tokens
)
538 Vector orderedTags
= new Vector();
540 while(tokens
.hasMoreTokens())
542 label
= tokens
.nextToken();
543 for(int i
= 0; i
< drawobjects
.size(); i
++)
545 aShape
= (Shape
)drawobjects
.elementAt(i
);
546 // System.out.println("comparing:" + label + "<->" + aShape.tag);
547 if(aShape
.tag
.equals(label
))
549 orderedTags
.add(aShape
);
550 // System.out.println("adding->" + aShape.tag);
555 drawobjects
= orderedTags
;
558 class MyCanvas
extends JPanel
implements MouseListener
, MouseMotionListener
, MouseWheelListener
, Printable
{
563 // if canvas extends JPanel
564 if(guiserver
.DOUBLE_BUFFERING
)
565 this.setDoubleBuffered(true);
567 addMouseListener(this);
568 addMouseMotionListener(this);
569 addMouseWheelListener(this);
572 public void update(Graphics g
)
574 if(guiserver
.MAC_OS_X
) super.update(g
);
578 public void paint(Graphics g
)
581 // BufferStrategy myStrategy = null;
583 /* only if canvas extends Canvas
584 if(guiserver.DOUBLE_BUFFERING)
587 this.createBufferStrategy(2);
589 catch (Exception evt)
591 System.out.println("event: =>" + evt);
595 myStrategy = this.getBufferStrategy();
596 Graphics myg = myStrategy.getDrawGraphics();
597 g2 = (Graphics2D)myg;
605 /* only used if canvas is Canvas
606 if(guiserver.DOUBLE_BUFFERING)
615 public void render(Graphics2D g2
)
617 if(background
!= null) g2
.setColor(background
);
620 if(background
!= null)
622 g2
.setPaint(background
);
623 g2
.fillRect(0, 0, canvas
.getWidth(), canvas
.getHeight());
626 g2
.translate(translationX
, translationY
);
627 g2
.scale(scaleX
, scaleY
);
630 AffineTransform normalTransform
= g2
.getTransform();
633 g2
.setRenderingHint(RenderingHints
.KEY_ANTIALIASING
,
634 RenderingHints
.VALUE_ANTIALIAS_ON
);
636 for(int i
= 0; i
< drawobjects
.size(); i
++)
638 Shape shape
= (Shape
)drawobjects
.elementAt(i
);
642 g2
.transform(shape
.transform
);
644 g2
.setTransform(normalTransform
);
651 public Iterator
getTagsFromPoint(int X
, int Y
)
653 HashMap tags
= new HashMap();
654 for(int i
= 0; i
< drawobjects
.size(); i
++)
656 Shape shape
= (Shape
)drawobjects
.elementAt(i
);
657 if(shape
.hasPoint(X
, Y
))
659 if(!tags
.containsKey(shape
.tag
))
660 tags
.put(shape
.tag
, 0);
664 return tags
.keySet().iterator();
667 public void mouseClicked(MouseEvent e
)
669 if(mouseClickedEvent
== null) return;
674 guiserver
.out
.print("(" + mouseClickedEvent
+ " " + X
+ " " + Y
+ " " +
675 e
.getButton() + " " + e
.getClickCount() + " " + e
.getModifiers());
679 guiserver
.out
.print(" '(");
680 Iterator tags
= getTagsFromPoint(X
, Y
);
681 while(tags
.hasNext())
682 guiserver
.out
.print("\"" + tags
.next() + "\" ");
683 guiserver
.out
.print(")");
686 guiserver
.out
.println(")");
687 guiserver
.out
.flush();
690 public void mouseEntered(MouseEvent e
)
692 if(mouseEnteredEvent
== null) return;
695 public void mouseExited(MouseEvent e
)
697 if(mouseExitedEvent
== null) return;
700 public void mousePressed(MouseEvent e
)
702 if(mousePressedEvent
== null) return;
707 guiserver
.out
.print("(" + mousePressedEvent
+ " " + X
+ " " + Y
+ " " +
708 e
.getButton() + " " + e
.getModifiers());
712 guiserver
.out
.print(" '(");
713 Iterator tags
= getTagsFromPoint(X
, Y
);
714 while(tags
.hasNext())
715 guiserver
.out
.print("\"" + tags
.next() + "\" ");
716 guiserver
.out
.print(")");
719 guiserver
.out
.println(")");
720 guiserver
.out
.flush();
723 public void mouseReleased(MouseEvent e
)
725 if(mouseReleasedEvent
== null) return;
730 guiserver
.out
.print("(" + mouseReleasedEvent
+ " " + X
+ " " + Y
+ " " +
731 e
.getButton() + " " + e
.getModifiers());
733 if(mouseReleasedTags
)
735 guiserver
.out
.print(" '(");
736 Iterator tags
= getTagsFromPoint(X
, Y
);
737 while(tags
.hasNext())
738 guiserver
.out
.print("\"" + tags
.next() + "\" ");
739 guiserver
.out
.print(")");
742 guiserver
.out
.println(")");
743 guiserver
.out
.flush();
746 public void mouseDragged(MouseEvent e
)
748 if(mouseDraggedEvent
== null) return;
753 guiserver
.out
.println("(" + mouseDraggedEvent
+ " " + X
+ " " + Y
+ " " +
754 e
.getButton() + " " + e
.getModifiers() + ")" );
755 guiserver
.out
.flush();
758 public void mouseMoved(MouseEvent e
)
760 if(mouseMovedEvent
== null) return;
765 guiserver
.out
.print("(" + mouseMovedEvent
+ " " + X
+ " " + Y
);
769 guiserver
.out
.print(" '(");
770 Iterator tags
= getTagsFromPoint(X
, Y
);
771 while(tags
.hasNext())
772 guiserver
.out
.print("\"" + tags
.next() + "\" ");
773 guiserver
.out
.print(")");
776 guiserver
.out
.println(")");
777 guiserver
.out
.flush();
780 public void mouseWheelMoved(MouseWheelEvent e
)
782 if(mouseWheelMovedEvent
== null) return;
784 int rotation
= e
.getWheelRotation();
788 guiserver
.out
.println("(" + mouseWheelMovedEvent
+ " " + X
+ " " + Y
+ " " + rotation
+ ")" );
789 guiserver
.out
.flush();
792 public void export(String path
, String format
, int width
, int height
)
794 //BufferedImage bufferimage = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
795 BufferedImage bufferimage
= new BufferedImage(width
, height
, BufferedImage
.TYPE_INT_ARGB
);
797 Graphics2D g2
= bufferimage
.createGraphics();
801 try { ImageIO
.write(bufferimage
, format
, new File(path
)); }
802 catch (IOException ie
) {
803 ErrorDialog
.show("Exporting", "Could not write file: " + path
);
807 public int print(Graphics graphics
, PageFormat pageFormat
, int pageIndex
)