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-11 20:23:04 +0300 $ 21 */ 22 23 /** 24 * @author <a lang="ro" href="http://www.robodesign.ro/mihai">Mihai Şucan</a> 25 * @fileOverview Holds the line tool implementation. 26 */ 27 28 /** 29 * @class The line tool. 30 * 31 * @param {PaintWeb} app Reference to the main paint application object. 32 */ 33 pwlib.tools.line = function (app) { 34 var _self = this, 35 clearInterval = app.win.clearInterval, 36 config = app.config, 37 context = app.buffer.context, 38 gui = app.gui, 39 image = app.image, 40 mouse = app.mouse, 41 setInterval = app.win.setInterval, 42 snapXY = app.toolSnapXY; 43 44 /** 45 * The interval ID used for invoking the drawing operation every few 46 * milliseconds. 47 * 48 * @private 49 * @see PaintWeb.config.toolDrawDelay 50 */ 51 var timer = null; 52 53 /** 54 * Tells if the <kbd>Shift</kbd> key is down or not. This is used by the 55 * drawing function. 56 * 57 * @private 58 * @type Boolean 59 * @default false 60 */ 61 var shiftKey = false; 62 63 /** 64 * Tells if the drawing canvas needs to be updated or not. 65 * 66 * @private 67 * @type Boolean 68 * @default false 69 */ 70 var needsRedraw = false; 71 72 /** 73 * Holds the starting point on the <var>x</var> axis of the image, for the 74 * current drawing operation. 75 * 76 * @private 77 * @type Number 78 */ 79 var x0 = 0; 80 81 /** 82 * Holds the starting point on the <var>y</var> axis of the image, for the 83 * current drawing operation. 84 * 85 * @private 86 * @type Number 87 */ 88 var y0 = 0; 89 90 /** 91 * Tool deactivation event handler. 92 */ 93 this.deactivate = function () { 94 if (timer) { 95 clearInterval(timer); 96 timer = null; 97 } 98 99 if (mouse.buttonDown) { 100 context.clearRect(0, 0, image.width, image.height); 101 } 102 103 needsRedraw = false; 104 105 return true; 106 }; 107 108 /** 109 * Initialize the drawing operation, by storing the location of the pointer, 110 * the start position. 111 * 112 * @param {Event} ev The DOM Event object. 113 */ 114 this.mousedown = function (ev) { 115 x0 = mouse.x; 116 y0 = mouse.y; 117 118 if (!timer) { 119 timer = setInterval(_self.draw, config.toolDrawDelay); 120 } 121 shiftKey = ev.shiftKey; 122 needsRedraw = false; 123 124 gui.statusShow('lineMousedown'); 125 126 return true; 127 }; 128 129 /** 130 * Store the <kbd>Shift</kbd> key state which is used by the drawing function. 131 * 132 * @param {Event} ev The DOM Event object. 133 */ 134 this.mousemove = function (ev) { 135 shiftKey = ev.shiftKey; 136 needsRedraw = true; 137 }; 138 139 /** 140 * Perform the drawing operation. This function is called every few 141 * milliseconds. 142 * 143 * <p>Hold down the <kbd>Shift</kbd> key to draw a straight 144 * horizontal/vertical line. 145 * <p>Press <kbd>Escape</kbd> to cancel the drawing operation. 146 * 147 * @see PaintWeb.config.toolDrawDelay 148 */ 149 this.draw = function () { 150 if (!needsRedraw) { 151 return; 152 } 153 154 context.clearRect(0, 0, image.width, image.height); 155 156 // Snapping on the X/Y axis. 157 if (shiftKey) { 158 snapXY(x0, y0); 159 } 160 161 context.beginPath(); 162 context.moveTo(x0, y0); 163 context.lineTo(mouse.x, mouse.y); 164 context.stroke(); 165 context.closePath(); 166 167 needsRedraw = false; 168 }; 169 170 /** 171 * End the drawing operation, once the user releases the mouse button. 172 * 173 * @param {Event} ev The DOM Event object. 174 */ 175 this.mouseup = function (ev) { 176 // Allow users to click then drag, not only mousedown+drag+mouseup. 177 if (mouse.x == x0 && mouse.y == y0) { 178 mouse.buttonDown = true; 179 return true; 180 } 181 182 if (timer) { 183 clearInterval(timer); 184 timer = null; 185 } 186 187 shiftKey = ev.shiftKey; 188 _self.draw(); 189 gui.statusShow('lineActive'); 190 app.layerUpdate(); 191 192 return true; 193 }; 194 195 /** 196 * Allows the user to press <kbd>Escape</kbd> to cancel the drawing operation. 197 * 198 * @param {Event} ev The DOM Event object. 199 * 200 * @returns {Boolean} True if the drawing operation was cancelled, or false if 201 * not. 202 */ 203 this.keydown = function (ev) { 204 if (!mouse.buttonDown || ev.kid_ != 'Escape') { 205 return false; 206 } 207 208 if (timer) { 209 clearInterval(timer); 210 timer = null; 211 } 212 213 context.clearRect(0, 0, image.width, image.height); 214 mouse.buttonDown = false; 215 needsRedraw = false; 216 217 gui.statusShow('lineActive'); 218 219 return true; 220 }; 221 }; 222 223 // vim:set spell spl=en fo=wan1croqlt tw=80 ts=2 sw=2 sts=2 sta et ai cin fenc=utf-8 ff=unix: 224 225