001 
002 /*
003  *  JScripter Standard 1.0 - To Script In Java
004  *  Copyright (C) 2008-2011  J.J.Liu<jianjunliu@126.com> <http://www.jscripter.org>
005  *  
006  *  This program is free software: you can redistribute it and/or modify
007  *  it under the terms of the GNU Affero General Public License as published by
008  *  the Free Software Foundation, either version 3 of the License, or
009  *  (at your option) any later version.
010  *  
011  *  This program is distributed in the hope that it will be useful,
012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014  *  GNU Affero General Public License for more details.
015  *  
016  *  You should have received a copy of the GNU Affero General Public License
017  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
018  */
019 
020 package jsx.ui.vect.canvas;
021 
022 import js.Js;
023 import jsx.Configurable;
024 import jsx.core.ObjectLikes;
025 import jsx.ui.dd.Mouse;
026 import jsx.ui.dd.event.DragMove;
027 import jsx.ui.dd.event.DragStart;
028 import jsx.ui.dd.event.DragStop;
029 import jsx.ui.event.Position;
030 import jsx.ui.vect.Canvas;
031 
032 /**
033  * <p>Defines a drawing wrapper that interactively paints on the wrapped canvas.</p>
034  * <p>A drawing tool of this class wraps a {@link Canvas} component and paints in 
035  * accordance with the {@link Mouse} handle to which it listens mouse events.</p>
036  * <p>A {@link CanvasSketch} widget is {@link Configurable} and is also an event source 
037  * which may fire high level events.</p>
038  * 
039  * @author <a href="mailto:jianjunliu@126.com">J.J.Liu (Jianjun Liu)</a> at <a href="http://www.jscripter.org" target="_blank">http://www.jscripter.org</a>
040  */
041 public class CanvasPaint extends CanvasDraw
042 {
043     /**
044      * <p>A typical constructor that constructs a wrapper widget of this type and forces 
045      * constructors of subclasses to pass a {@link Canvas} widget.</p>
046      * <p>This constructor invokes the typical constructor of the superclass passing 
047      * the component wrapped by the specified {@link Canvas} widget that is set to the 
048      * configurable property {@link CanvasDraw#CANVAS} of the widget to be constructed.</p>
049      * @param c A canvas widget.
050      * @since 1.0
051      */
052     public CanvasPaint(Canvas c) {
053         super(c);
054     }
055 
056     /**
057      * <p>Performs an action on the dispatched event.</p>
058      * <p>This method invokes the overridden method of the superclass to initialize the 
059      * drawing tool.</p>
060      * @param evt The event dispatched to this listener.
061      * @since 1.0
062      */
063     @Override
064     public void onEvent(DragStart evt) {
065         super.onEvent(evt);
066         Canvas c = canvas();
067         Canvas.fillStyle(c, Canvas.strokeStyle(c));
068     }
069 
070     /**
071      * <p>Performs an action on the dispatched event.</p>
072      * <p>If the current canvas drawing tool is in a drawing mode this method paints at 
073      * the position specified by the mouse move event.</p>
074      * @param evt The event dispatched to this listener.
075      * @since 1.0
076      */
077     public void onEvent(DragMove evt) {
078         if (Js.be(ini(this).var(START))) {
079             paint(this, evt);
080         }
081     }
082 
083     /**
084      * <p>Paints a specified canvas drawing wrapper at a specified mouse position.</p>
085      * <p>This method moves the current position of a specified {@link Canvas} widget 
086      * and paints there in accordance with the specified mouse {@link Position} data, 
087      * the position data cached by the specified canvas drawing tool and the specified 
088      * argument mouse position.</p>
089      * <p>A subclass may also call this method to meet its particular needs.</p>
090      * @param d A canvas drawing wrapper.
091      * @param evt A mouse position event.
092      * @since 1.0
093      */
094     protected static final void paint(CanvasDraw d, Position<?> evt) {
095         Canvas c = d.canvas();
096         double w = Canvas.lineWidth(c);
097         Canvas.fillRect(
098                 c,
099                 x(c, w, ini(evt).var(Position.X).doubleValue() - ini(d).var(X) - w / 2),
100                 y(c, w, ini(evt).var(Position.Y).doubleValue() - ini(d).var(Y) - w / 2),
101                 w,
102                 w
103         );
104         Canvas.closePath(c);
105         Canvas.beginPath(c);
106     }
107 
108     /**
109      * <p>Performs an action on the dispatched event.</p>
110      * <p>If the current canvas drawing tool is in a drawing mode this method paints at 
111      * the position specified by the mouse release event, closes the current drawing 
112      * path and exits the drawing mode.</p>
113      * @param evt The event dispatched to this listener.
114      * @since 1.0
115      */
116     public void onEvent(DragStop evt) {
117         if (Js.be(ini(this).var(START))) {
118             ObjectLikes.delete(ini(this), START);
119             paint(this, evt);
120             Canvas.closePath(canvas());
121         }
122     }
123 }