Mise au point.
[Portfolio.git] / skins / navigateur.js
1 /*
2 * © 2007 Benoît Pin – Centre de recherche en informatique – École des mines de Paris
3 * http://plinn.org
4 * Licence Creative Commons http://creativecommons.org/licenses/by-nc/2.0/
5 *
6 *
7 */
8
9 function Navigateur(mosaique) {
10 this.mosaique = mosaique;
11 var m = this.mosaique; // shortcut alias
12
13 this.drawPanel();
14
15 var thisNav = this;
16
17 this._ddHandlers = {'down' : function(evt){thisNav._mouseDownHandler(evt);},
18 'move' : function(evt){thisNav._mouseMoveHandler(evt);},
19 'up' : function(evt){thisNav._mouseUpHandler(evt);}};
20
21
22 if (m.zoomIndex == m.zoomTable.length - 1)
23 this.zoomInButton.src = this.zoomInButton.src.replace('zoom_in.gif', 'zoom_disabled.gif');
24 if (m.zoomIndex == 0)
25 this.zoomOutButton.src = this.zoomOutButton.src.replace('zoom_out.gif', 'zoom_disabled.gif');
26
27 this.currentZoomLevel.nodeValue = m.zoomLevel + ' %';
28
29 this._listeners = new Array();
30 this._listeners.push([this.zoomOutButton, 'click', function(evt){thisNav.zoomOut(evt);}]);
31 this._listeners.push([this.zoomInButton, 'click', function(evt){thisNav.zoomIn(evt);}]);
32 this._listeners.push([document, 'keypress', function(evt){thisNav.zoomByKeybord(evt);}]);
33
34 var _l;
35 for (var i = 0 ; i<this._listeners.length ; i++) {
36 _l = this._listeners[i];
37 addListener(_l[0], _l[1], _l[2]);
38 }
39 }
40
41 Navigateur.prototype.unload = function() {
42 var _l;
43 for (var i = 0 ; i<this._listeners.length ; i++) {
44 _l = this._listeners[i];
45 removeListener(_l[0], _l[1], _l[2]);
46 }
47 };
48
49 Navigateur.prototype.drawPanel = function() {
50 var m = this.mosaique;
51 // panel
52 var panel = document.createElement('div');
53 with(panel.style) {
54 position = 'absolute';
55 width = this.mosaique.thumbnailWidth + 2 + 'px';
56 height = this.mosaique.thumbnailHeight + 38 + 'px';
57 top = '27px';
58 right = '0px';
59 border = '1px solid #4c4c4c';
60 textAlign = 'center';
61 overflow = 'hidden';
62 }
63
64 // thumbnail
65 var thumbnail = document.createElement('img');
66 thumbnail.src = m.imgUrlBase + '/getThumbnail';
67 thumbnail.width = String(m.thumbnailWidth);
68 thumbnail.height = String(m.thumbnailHeight);
69 panel.appendChild(thumbnail);
70
71 // red frame
72 var frame = this.frame = document.createElement('div');
73 with(frame.style) {
74 position = 'absolute';
75 left = '0';
76 top = '0';
77 border = '1px solid red';
78 zIndex = '2';
79 cursor = 'move';
80 }
81 panel.appendChild(frame);
82 this.resizeFrame();
83
84 // for IE >:-(
85 var fill = document.createElement('img');
86 fill.src = portal_url() + '/transparent.gif';
87 with(fill.style) {
88 height = '100%';
89 width = '100%';
90 }
91 frame.appendChild(fill);
92
93 // table with -/+ buttons and current zoom level
94 var table = document.createElement('table');
95 with (table.style) {
96 width = '100%';
97 background = '#808080';
98 verticalAlign = 'middle';
99 }
100 panel.appendChild(table);
101
102 var tbody = document.createElement('tbody');
103 table.appendChild(tbody);
104
105 var tr = document.createElement('tr');
106 tbody.appendChild(tr);
107
108 var td = document.createElement('td');
109 tr.appendChild(td);
110
111 var img = this.zoomOutButton = document.createElement('img');
112 img.width = '32';
113 img.height = '32';
114 img.src = portal_url() + '/zoom_out.gif';
115 td.appendChild(img);
116
117 var td = document.createElement('td');
118 tr.appendChild(td);
119
120 var text = this.currentZoomLevel = document.createTextNode('10%');
121 td.appendChild(text);
122
123 var td = document.createElement('td');
124 tr.appendChild(td);
125
126 var img = this.zoomInButton = document.createElement('img');
127 img.width = '32';
128 img.height = '32';
129 img.src = portal_url() + '/zoom_in.gif';
130 td.appendChild(img);
131
132 this.display = panel;
133 this.mosaique.rootElement.appendChild(panel);
134 };
135
136 Navigateur.prototype.resizeFrame = function() {
137 var m = this.mosaique;
138 var width, height;
139
140 if (m.screenWidth >= m.imageWidth) {
141 width = m.thumbnailWidth + 'px';
142 }
143 else {
144 var wRatio = m.screenWidth / m.imageWidth;
145 width = Math.round(wRatio * m.thumbnailWidth) + 'px';
146 }
147
148 if (m.screenHeight >= m.imageHeight) {
149 height = m.thumbnailHeight + 'px';
150 }
151 else {
152 var hRatio = m.screenHeight / m.imageHeight;
153 height = Math.round(hRatio * m.thumbnailHeight) + 'px';
154 }
155
156 var frmStyle = this.frame.style;
157 frmStyle.width = width;
158 frmStyle.height = height;
159 this.alignFrame();
160 };
161
162 Navigateur.prototype.alignFrame = function() {
163 var m = this.mosaique;
164 var iPosition = m.getImagePosition();
165 iPosition.x = Math.max(0, iPosition.x);
166 iPosition.y = Math.max(0, iPosition.y);
167
168 var frmPosition = new Point(iPosition.x * (m.thumbnailWidth / m.imageWidth),
169 iPosition.y * (m.thumbnailHeight / m.imageHeight)
170 );
171 this.setFramePosition(frmPosition);
172 }
173
174 Navigateur.prototype.alignImage = function() {
175 var m = this.mosaique;
176 var frmPosition = this.getFramePosition();
177 var iPosition = new Point(frmPosition.x * (m.imageWidth / m.thumbnailWidth),
178 frmPosition.y * (m.imageHeight / m.thumbnailHeight)
179 );
180 this.mosaique.loadScreen(iPosition);
181 };
182
183 Navigateur.prototype.getFramePosition = function() {
184 var x = parseInt(this.frame.style.left);
185 var y = parseInt(this.frame.style.top);
186 var p = new Point(x, y);
187 return p;
188 };
189
190 Navigateur.prototype.setFramePosition = function(point) {
191 with(this.frame.style) {
192 left = point.x + 'px';
193 top = point.y + 'px';
194 }
195 };
196
197 /* event handlers */
198 Navigateur.prototype._mouseDownHandler = function(evt) {
199 this.initialClickPoint = new Point(evt.clientX, evt.clientY);
200 this.initialPosition = this.getFramePosition();
201 this.dragInProgress = true;
202 }
203
204 Navigateur.prototype._mouseMoveHandler = function(evt) {
205 disableDefault(evt);
206 if(!this.dragInProgress)
207 return;
208
209 evt = getEventObject(evt);
210 var currentPoint = new Point(evt.clientX, evt.clientY);
211 var displacement = currentPoint.diff(this.initialClickPoint);
212 this.setFramePosition(this.initialPosition.add(displacement));
213 };
214
215 Navigateur.prototype._mouseUpHandler = function(evt) {
216 this.dragInProgress = false;
217 this.alignImage();
218 };
219
220 Navigateur.prototype.zoomIn = function(evt) {
221 var m = this.mosaique;
222 var maxZoomIndex = m.zoomTable.length - 1
223 if (m.zoomIndex < maxZoomIndex) {
224 var targetZoomIndex = m.zoomIndex + 1;
225 m.loadZoomLevel(targetZoomIndex);
226 this.currentZoomLevel.nodeValue = m.zoomLevel + ' %';
227 this.resizeFrame();
228
229 if (targetZoomIndex == maxZoomIndex)
230 this.zoomInButton.src = this.zoomInButton.src.replace('zoom_in.gif', 'zoom_disabled.gif');
231 if (targetZoomIndex > 0)
232 this.zoomOutButton.src = this.zoomOutButton.src.replace('zoom_disabled.gif', 'zoom_out.gif');
233 }
234 };
235
236 Navigateur.prototype.zoomOut = function(evt) {
237 var m = this.mosaique;
238 if (m.zoomIndex > 0 ) {
239 var targetZoomIndex = m.zoomIndex - 1;
240 m.loadZoomLevel(targetZoomIndex);
241 this.currentZoomLevel.nodeValue = m.zoomLevel + ' %';
242 this.resizeFrame();
243
244 if (targetZoomIndex == 0)
245 this.zoomOutButton.src = this.zoomOutButton.src.replace('zoom_out.gif', 'zoom_disabled.gif');
246 if (targetZoomIndex < m.zoomTable.length - 1)
247 this.zoomInButton.src = this.zoomInButton.src.replace('zoom_disabled.gif', 'zoom_in.gif');
248 }
249 };
250
251 Navigateur.prototype.zoomByKeybord = function(evt){
252 evt = getEventObject(evt);
253 var charPress = String.fromCharCode((evt.keyCode) ? evt.keyCode : evt.which);
254 switch (charPress) {
255 case '+' :
256 this.zoomIn();
257 break;
258 case '-' :
259 this.zoomOut();
260 break;
261 }
262 };