1 /*
  2  * Copyright (C) 2008, 2009 Mihai Şucan
  3  *
  4  * This file is part of PaintWeb.
  5  *
  6  * PaintWeb is free software: you can redistribute it and/or modify
  7  * it under the terms of the GNU General Public License as published by
  8  * the Free Software Foundation, either version 3 of the License, or
  9  * (at your option) any later version.
 10  *
 11  * PaintWeb is distributed in the hope that it will be useful,
 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 14  * GNU General Public License for more details.
 15  *
 16  * You should have received a copy of the GNU General Public License
 17  * along with PaintWeb.  If not, see <http://www.gnu.org/licenses/>.
 18  *
 19  * $URL: http://code.google.com/p/paintweb $
 20  * $Date: 2009-06-15 15:25:29 +0300 $
 21  */
 22 
 23 /**
 24  * @author <a lang="ro" href="http://www.robodesign.ro/mihai">Mihai Şucan</a>
 25  * @fileOverview Holds the pencil tool implementation.
 26  */
 27 
 28 /**
 29  * @class The drawing pencil.
 30  *
 31  * @param {PaintWeb} app Reference to the main paint application object.
 32  */
 33 pwlib.tools.pencil = function (app) {
 34   var _self         = this,
 35       clearInterval = app.win.clearInterval,
 36       context       = app.buffer.context,
 37       image         = app.image,
 38       mouse         = app.mouse,
 39       setInterval   = app.win.setInterval;
 40 
 41   /**
 42    * The interval ID used for running the pencil drawing operation every few 
 43    * milliseconds.
 44    *
 45    * @private
 46    * @see PaintWeb.config.toolDrawDelay
 47    */
 48   var timer = null;
 49 
 50   /**
 51    * Holds the points needed to be drawn. Each point is added by the 
 52    * <code>mousemove</code> event handler.
 53    *
 54    * @private
 55    * @type Array
 56    */
 57   var points = [];
 58 
 59   /**
 60    * Holds the last point on the <var>x</var> axis of the image, for the current 
 61    * drawing operation.
 62    *
 63    * @private
 64    * @type Number
 65    */
 66   var x0 = 0;
 67 
 68   /**
 69    * Holds the last point on the <var>y</var> axis of the image, for the current 
 70    * drawing operation.
 71    *
 72    * @private
 73    * @type Number
 74    */
 75   var y0 = 0;
 76 
 77   /**
 78    * Tool deactivation event handler.
 79    */
 80   this.deactivate = function () {
 81     if (timer) {
 82       clearInterval(timer);
 83       timer = null;
 84     }
 85 
 86     if (mouse.buttonDown) {
 87       context.clearRect(0, 0, image.width, image.height);
 88     }
 89 
 90     points = [];
 91   };
 92 
 93   /**
 94    * Initialize the drawing operation.
 95    */
 96   this.mousedown = function () {
 97     x0 = mouse.x;
 98     y0 = mouse.y;
 99 
100     points = [];
101     if (!timer) {
102       timer = setInterval(_self.draw, app.config.toolDrawDelay);
103     }
104 
105     return true;
106   };
107 
108   /**
109    * Save the mouse coordinates in the array.
110    */
111   this.mousemove = function () {
112     if (mouse.buttonDown) {
113       points.push(mouse.x, mouse.y);
114     }
115   };
116 
117   /**
118    * Draw the points in the stack. This function is called every few 
119    * milliseconds.
120    *
121    * @see PaintWeb.config.toolDrawDelay
122    */
123   this.draw = function () {
124     var i = 0, n = points.length;
125     if (!n) {
126       return;
127     }
128 
129     context.beginPath();
130     context.moveTo(x0, y0);
131 
132     while (i < n) {
133       x0 = points[i++];
134       y0 = points[i++];
135       context.lineTo(x0, y0);
136     }
137 
138     context.stroke();
139     context.closePath();
140 
141     points = [];
142   };
143 
144   /**
145    * End the drawing operation, once the user releases the mouse button.
146    */
147   this.mouseup = function () {
148     if (mouse.x == x0 && mouse.y == y0) {
149       points.push(x0+1, y0+1);
150     }
151 
152     if (timer) {
153       clearInterval(timer);
154       timer = null;
155     }
156 
157     _self.draw();
158     app.layerUpdate();
159 
160     return true;
161   };
162 
163   /**
164    * Allows the user to press <kbd>Escape</kbd> to cancel the drawing operation.
165    *
166    * @param {Event} ev The DOM Event object.
167    *
168    * @returns {Boolean} True if the drawing operation was cancelled, or false if 
169    * not.
170    */
171   this.keydown = function (ev) {
172     if (!mouse.buttonDown || ev.kid_ != 'Escape') {
173       return false;
174     }
175 
176     if (timer) {
177       clearInterval(timer);
178       timer = null;
179     }
180 
181     context.clearRect(0, 0, image.width, image.height);
182     mouse.buttonDown = false;
183     points = [];
184 
185     return true;
186   };
187 };
188 
189 // vim:set spell spl=en fo=wan1croqlt tw=80 ts=2 sw=2 sts=2 sta et ai cin fenc=utf-8 ff=unix:
190 
191