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 20:27:08 +0300 $ 21 */ 22 23 /** 24 * @author <a lang="ro" href="http://www.robodesign.ro/mihai">Mihai Şucan</a> 25 * @fileOverview Holds the hand tool implementation. 26 */ 27 28 /** 29 * @class The hand tool. This tool allows the user to drag the image canvas 30 * inside the viewport. 31 * 32 * @param {PaintWeb} app Reference to the main paint application object. 33 */ 34 pwlib.tools.hand = function (app) { 35 var _self = this, 36 bufferCanvas = app.buffer.canvas, 37 bufferStyle = bufferCanvas.style, 38 config = app.config; 39 clearInterval = app.win.clearInterval, 40 image = app.image, 41 MathRound = Math.round, 42 mouse = app.mouse, 43 viewport = app.gui.elems.viewport, 44 vheight = 0, 45 vwidth = 0, 46 setInterval = app.win.setInterval; 47 48 /** 49 * The interval ID used for invoking the viewport drag operation every few 50 * milliseconds. 51 * 52 * @private 53 * @see PaintWeb.config.toolDrawDelay 54 */ 55 var timer = null; 56 57 /** 58 * Tells if the viewport needs to be scrolled. 59 * 60 * @private 61 * @type Boolean 62 * @default false 63 */ 64 var needsScroll = false; 65 66 /** 67 * Holds the previous tool ID. 68 * 69 * @private 70 * @type String 71 */ 72 this.prevTool = null; 73 74 var x0 = 0, y0 = 0, 75 x1 = 0, y1 = 0, 76 l0 = 0, t0 = 0; 77 78 /** 79 * Tool preactivation event handler. 80 * 81 * @returns {Boolean} True if the tool can become active, or false if not. 82 */ 83 this.preActivate = function () { 84 if (!viewport) { 85 return false; 86 } 87 88 _self.prevTool = app.tool._id; 89 90 // Check if the image canvas can be scrolled within the viewport. 91 92 var cs = app.win.getComputedStyle(viewport, null), 93 bwidth = parseInt(bufferStyle.width), 94 bheight = parseInt(bufferStyle.height); 95 96 vwidth = parseInt(cs.width), 97 vheight = parseInt(cs.height); 98 99 if (vheight < bheight || vwidth < bwidth) { 100 return true; 101 } else { 102 return false; 103 } 104 }; 105 106 /** 107 * Tool activation event handler. 108 */ 109 this.activate = function () { 110 bufferStyle.cursor = 'move'; 111 app.shadowDisallow(); 112 }; 113 114 /** 115 * Tool deactivation event handler. 116 */ 117 this.deactivate = function (ev) { 118 if (timer) { 119 clearInterval(timer); 120 timer = null; 121 app.doc.removeEventListener('mousemove', ev_mousemove, false); 122 app.doc.removeEventListener('mouseup', ev_mouseup, false); 123 } 124 125 bufferStyle.cursor = ''; 126 app.shadowAllow(); 127 }; 128 129 /** 130 * Initialize the canvas drag. 131 * 132 * @param {Event} ev The DOM event object. 133 */ 134 this.mousedown = function (ev) { 135 x0 = ev.clientX; 136 y0 = ev.clientY; 137 l0 = viewport.scrollLeft; 138 t0 = viewport.scrollTop; 139 140 needsScroll = false; 141 142 app.doc.addEventListener('mousemove', ev_mousemove, false); 143 app.doc.addEventListener('mouseup', ev_mouseup, false); 144 145 if (!timer) { 146 timer = setInterval(viewportScroll, config.toolDrawDelay); 147 } 148 149 return true; 150 }; 151 152 /** 153 * The <code>mousemove</code> event handler. This simply stores the current 154 * mouse location. 155 * 156 * @param {Event} ev The DOM Event object. 157 */ 158 function ev_mousemove (ev) { 159 x1 = ev.clientX; 160 y1 = ev.clientY; 161 needsScroll = true; 162 }; 163 164 /** 165 * Perform the canvas drag operation. This function is called every few 166 * milliseconds. 167 * 168 * <p>Press <kbd>Escape</kbd> to stop dragging and to get back to the previous 169 * tool. 170 */ 171 function viewportScroll () { 172 if (needsScroll) { 173 viewport.scrollTop = t0 - y1 + y0; 174 viewport.scrollLeft = l0 - x1 + x0; 175 needsScroll = false; 176 } 177 }; 178 179 /** 180 * The <code>mouseup</code> event handler. 181 */ 182 function ev_mouseup (ev) { 183 if (timer) { 184 clearInterval(timer); 185 timer = null; 186 } 187 188 ev_mousemove(ev); 189 viewportScroll(); 190 191 app.doc.removeEventListener('mousemove', ev_mousemove, false); 192 app.doc.removeEventListener('mouseup', ev_mouseup, false); 193 194 mouse.buttonDown = false; 195 }; 196 197 /** 198 * Allows the user to press <kbd>Escape</kbd> to stop dragging the canvas, and 199 * to return to the previous tool. 200 * 201 * @param {Event} ev The DOM Event object. 202 * 203 * @returns {Boolean} True if the key was recognized, or false if not. 204 */ 205 this.keydown = function (ev) { 206 if (!_self.prevTool || ev.kid_ != 'Escape') { 207 return false; 208 } 209 210 app.toolActivate(_self.prevTool, ev); 211 return true; 212 }; 213 }; 214 215 // vim:set spell spl=en fo=wan1croqlt tw=80 ts=2 sw=2 sts=2 sta et ai cin fenc=utf-8 ff=unix: 216 217