Initial commit of newLISP.
[newlisp.git] / guiserver / java / CanvasWidget.java
blobfd54a5e0b5809cfc3e4e2e8bb6aafc05888fea11
1 //
2 // CanvasWidget.java
3 // guiserver
4 //
5 // Created by Lutz Mueller on 6/8/07.
6 //
7 //
8 // Copyright (C) 2007 Lutz Mueller
9 //
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/>.
25 import java.awt.*;
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;
32 import javax.swing.*;
33 import javax.imageio.ImageIO;
34 import java.util.*;
35 import java.io.File;
36 import java.io.IOException;
38 @SuppressWarnings("unchecked")
39 public class CanvasWidget extends gsObject {
41 static CanvasWidget currentCanvas;
43 Vector drawobjects = new Vector();
45 MyCanvas canvas;
46 //Window ownerWindow;
47 double translationX = 0;
48 double translationY = 0;
49 double theta = 0;
50 double scaleX = 1;
51 double scaleY = 1;
52 Color background = null;
53 Stroke currentStroke;
54 Color currentPaint;
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();
81 component = canvas;
83 // if canvas is not Canvas but JPanel
84 container = canvas;
85 jcomponent = canvas;
87 CanvasWidget.currentCanvas = this;
89 currentStroke = new BasicStroke();
90 currentPaint = new Color(0,0,0);
92 scaleX = 1.0;
93 scaleY = 1.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)
164 float R, G, B;
165 float alpha;
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());
173 else
174 alpha = 1;
176 currentPaint = new Color(R, G, B, alpha);
179 public void g2Update(StringTokenizer tokens)
181 canvas.repaint();
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)
205 float R, G, B;
206 float alpha;
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());
214 else
215 alpha = 1;
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());
225 int style = 0;
226 int size = 12;
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");
249 // create shapes
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();
381 // manipulate shapes
383 public void deleteTaggedShape(StringTokenizer tokens)
385 String label = tokens.nextToken();
386 boolean updateFlag = tokens.nextToken().equals("true");
387 Vector filteredObjects = new Vector();
388 Shape aShape;
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");
408 Shape aShape;
410 for(int i = 0; i < drawobjects.size(); i++)
412 aShape = (Shape)drawobjects.elementAt(i);
413 if(aShape.tag.equals(label))
415 aShape.X += dx;
416 aShape.Y += dy;
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");
429 Shape aShape;
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");
449 Shape aShape;
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");
469 Shape aShape;
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");
487 Shape aShape;
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");
503 Shape aShape;
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");
520 Shape aShape;
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)
535 String label;
536 Shape aShape;
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 {
560 public MyCanvas() {
561 super();
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);
575 else paint(g);
578 public void paint(Graphics g)
580 Graphics2D g2;
581 // BufferStrategy myStrategy = null;
583 /* only if canvas extends Canvas
584 if(guiserver.DOUBLE_BUFFERING)
586 try {
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;
599 else
601 g2 = (Graphics2D)g;
603 render(g2);
605 /* only used if canvas is Canvas
606 if(guiserver.DOUBLE_BUFFERING)
608 myStrategy.show();
609 g2.dispose();
615 public void render(Graphics2D g2)
617 if(background != null) g2.setColor(background);
619 // fill 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);
628 g2.rotate(theta);
630 AffineTransform normalTransform = g2.getTransform();
632 if(antiAliasing)
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);
640 if(shape.visible)
642 g2.transform(shape.transform);
643 shape.drawShape(g2);
644 g2.setTransform(normalTransform);
648 paintComponents(g2);
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;
671 int X = e.getX();
672 int Y = e.getY();
674 guiserver.out.print("(" + mouseClickedEvent + " " + X + " " + Y + " " +
675 e.getButton() + " " + e.getClickCount() + " " + e.getModifiers());
677 if(mouseClickedTags)
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;
704 int X = e.getX();
705 int Y = e.getY();
707 guiserver.out.print("(" + mousePressedEvent + " " + X + " " + Y + " " +
708 e.getButton() + " " + e.getModifiers());
710 if(mousePressedTags)
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;
727 int X = e.getX();
728 int Y = e.getY();
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;
750 int X = e.getX();
751 int Y = e.getY();
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;
762 int X = e.getX();
763 int Y = e.getY();
765 guiserver.out.print("(" + mouseMovedEvent + " " + X + " " + Y);
767 if(mouseMovedTags)
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();
785 int X = e.getX();
786 int Y = e.getY();
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();
799 render(g2);
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)
809 return(0);
815 // eof //