Mercurial > hg > digilib
annotate client/digitallibrary/greyskin/dllib.js @ 436:95f910ecdca5
sizes menu;
button separators;
switched off debug window
| author | hertzhaft |
|---|---|
| date | Tue, 10 Jan 2006 16:48:28 +0100 |
| parents | a6af40003a38 |
| children | da024b494561 |
| rev | line source |
|---|---|
| 396 | 1 /* Copyright (C) 2003,2004 IT-Group MPIWG, WTWG Uni Bern and others |
| 2 | |
| 3 This program is free software; you can redistribute it and/or | |
| 4 modify it under the terms of the GNU General Public License | |
| 5 as published by the Free Software Foundation; either version 2 | |
| 6 of the License, or (at your option) any later version. | |
| 7 | |
| 8 This program is distributed in the hope that it will be useful, | |
| 9 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 11 GNU General Public License for more details. | |
| 12 | |
| 13 You should have received a copy of the GNU General Public License | |
| 14 along with this program; if not, write to the Free Software | |
| 15 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | |
| 16 | |
| 17 Authors: | |
| 18 Christian Luginbuehl, 01.05.2003 (first version) | |
| 19 DW 24.03.2004 (Changed for digiLib in Zope) | |
| 20 Robert Casties, 8.11.2005 | |
| 407 | 21 Martin Raspe <hertzhaft@biblhertz.it>, 12.12.2005 |
| 396 | 22 |
| 23 ! Requires baselib.js ! | |
| 24 | |
| 25 */ | |
| 407 | 26 digilibVersion = "Digilib NG"; |
| 436 | 27 dllibVersion = "2.029"; |
| 412 | 28 isDigilibInitialized = false; // gets set to true in dl_param_init |
|
425
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
29 reloadPage = true; // reload the page when parameters are changed, otherwise update only "src" attribute of scaler img |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
30 |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
31 // global variables |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
32 dlTrafo = new Transform(); |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
33 dlMaxArea = new Rectangle(0.0, 0.0, 1.0, 1.0); |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
34 dlArea = null; |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
35 dlMarks = null; |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
36 dlFlags = null; |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
37 |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
38 // global elements |
| 430 | 39 scalerDiv = null; |
| 40 scalerImg = null; | |
| 412 | 41 |
| 42 // flags for parameter sets | |
| 43 PARAM_FILE = 1; | |
| 44 PARAM_MODE = 2; | |
| 430 | 45 PARAM_DIM = 4; |
| 412 | 46 PARAM_IMAGE = 8; |
| 47 PARAM_DPI = 16; | |
| 48 PARAM_MARK = 32; | |
| 49 PARAM_PAGES = 64; | |
| 430 | 50 PARAM_SIZE = 128; |
| 51 PARAM_ALL = PARAM_FILE | PARAM_MODE | PARAM_DIM | PARAM_IMAGE | PARAM_DPI | PARAM_MARK | PARAM_PAGES | PARAM_SIZE; | |
| 412 | 52 |
| 53 // mouse drag area that counts as one click | |
| 54 MIN_AREA_SIZE = 3 * 3 + 1; | |
| 55 | |
| 56 // standard zoom factor | |
| 57 ZOOMFACTOR = Math.sqrt(2); | |
| 58 | |
| 59 // bird's eye view dimensions | |
| 60 BIRD_MAXX = 100; | |
| 61 BIRD_MAXY = 100; | |
| 62 | |
| 63 // with of arrow bars | |
| 64 ARROW_WIDTH = 32; | |
| 396 | 65 |
| 430 | 66 // with of calibration bar |
| 67 CALIBRATION_WIDTH = 64; | |
| 68 | |
| 396 | 69 function identify() { |
| 70 // used for identifying a digilib instance | |
| 71 // Relato uses that function - lugi | |
| 407 | 72 return digilibVersion; |
| 396 | 73 } |
| 74 /* | |
| 75 * more parameter handling | |
| 76 */ | |
| 77 | |
| 412 | 78 function initParameters() { |
| 79 // file | |
| 80 newParameter('fn', '', PARAM_FILE); | |
| 81 newParameter('pn', '1', PARAM_FILE); | |
| 82 // mode | |
| 83 newParameter('mo', '', PARAM_MODE); | |
| 84 // relative dimensions of zoomed image | |
| 430 | 85 newParameter('wx', '0.0', PARAM_DIM); |
| 86 newParameter('wy', '0.0', PARAM_DIM); | |
| 87 newParameter('ww', '1.0', PARAM_DIM); | |
| 88 newParameter('wh', '1.0', PARAM_DIM); | |
| 412 | 89 // image manipulation |
| 90 newParameter('brgt', '0.0', PARAM_IMAGE); | |
| 91 newParameter('cont', '0.0', PARAM_IMAGE); | |
| 92 newParameter('rot', '0.0', PARAM_IMAGE); | |
| 93 newParameter('rgba', '', PARAM_IMAGE); | |
| 94 newParameter('rgbm', '', PARAM_IMAGE); | |
| 95 // resolution | |
| 96 newParameter('ddpi', '', PARAM_DPI); | |
| 97 newParameter('ddpix', '', PARAM_DPI); | |
| 98 newParameter('ddpiy', '', PARAM_DPI); | |
| 99 // marks | |
| 100 newParameter('mk', '', PARAM_MARK); | |
| 101 // pages total | |
| 102 newParameter('pt', '0', PARAM_PAGES); | |
| 430 | 103 // size |
| 104 newParameter('ws', '1.0', PARAM_SIZE); | |
| 105 } | |
| 412 | 106 |
| 396 | 107 function parseArea() { |
| 108 // returns area Rectangle from current parameters | |
| 407 | 109 return new Rectangle( |
| 412 | 110 getParameter("wx"), |
| 111 getParameter("wy"), | |
| 112 getParameter("ww"), | |
| 113 getParameter("wh")); | |
| 114 } | |
| 396 | 115 |
| 116 function setParamFromArea(rect) { | |
| 412 | 117 // sets digilib wx etc. from rect |
| 118 setParameter("wx", cropFloat(rect.x)); | |
| 119 setParameter("wy", cropFloat(rect.y)); | |
| 120 setParameter("ww", cropFloat(rect.width)); | |
| 121 setParameter("wh", cropFloat(rect.height)); | |
| 122 return true; | |
| 123 } | |
| 124 | |
| 125 /* ********************************************** | |
| 126 * parse parameters routines | |
| 127 * ******************************************** */ | |
| 396 | 128 |
| 129 function parseTrafo(elem) { | |
| 130 // returns Transform from current dlArea and picsize | |
| 131 var picsize = getElementRect(elem); | |
| 132 var trafo = new Transform(); | |
| 133 // subtract area offset and size | |
| 134 trafo.concat(getTranslation(new Position(-dlArea.x, -dlArea.y))); | |
| 135 trafo.concat(getScale(new Size(1/dlArea.width, 1/dlArea.height))); | |
| 136 // scale to screen size | |
| 137 trafo.concat(getScale(picsize)); | |
| 138 trafo.concat(getTranslation(picsize)); | |
| 412 | 139 // FIX ME: Robert, kannst Du mal nachsehen, ob das folgende tut, was es soll? |
| 140 // oder gibt es dafür neuen Code? | |
| 396 | 141 // rotate |
| 412 | 142 var rot = getRotation(- getParameter("rot"), new Position(0.5*picsize.width, 0.5*picsize.height)); |
| 143 trafo.concat(rot); | |
| 396 | 144 // mirror |
| 412 | 145 if (hasFlag("hmir")) trafo.m00 = - trafo.m00; // ?? |
| 146 if (hasFlag("vmir")) trafo.m11 = - trafo.m11; // ?? | |
| 396 | 147 return trafo; |
| 148 } | |
| 149 | |
| 150 function parseMarks() { | |
| 151 // returns marks array from current parameters | |
| 152 var marks = new Array(); | |
| 407 | 153 var param = getParameter("mk"); |
| 154 var pairs = (param.indexOf(";") >= 0) | |
| 412 | 155 ? param.split(";") // old format with ";" |
| 156 : param.split(","); // new format | |
| 407 | 157 for (var i = 0; i < pairs.length ; i++) { |
| 158 var pos = pairs[i].split("/"); | |
| 159 if (pos.length > 1) marks.push(new Position(pos[0], pos[1])); | |
| 160 } | |
| 161 return marks; | |
| 396 | 162 } |
| 163 | |
| 412 | 164 /* ********************************************** |
| 165 * marks routines | |
| 166 * ******************************************** */ | |
| 167 | |
| 168 function getAllMarks() { | |
| 396 | 169 // returns a string with all marks in query format |
| 170 var marks = new Array(); | |
| 407 | 171 for (var i = 0; i < dlMarks.length; i++) |
| 396 | 172 marks.push(cropFloat(dlMarks[i].x) + "/" + cropFloat(dlMarks[i].y)); |
| 407 | 173 return marks.join(","); |
| 396 | 174 } |
| 407 | 175 |
| 176 getMarksQueryString = getAllMarks; | |
| 396 | 177 |
| 407 | 178 function addMark(evt) { |
| 412 | 179 // add a mark |
| 180 var pos = dlTrafo.invtransform(evtPosition(evt)); | |
| 181 dlMarks.push(pos) | |
| 182 setParameter("mk", getAllMarks()); | |
| 183 return true; | |
| 184 } | |
| 185 | |
| 186 function deleteMark() { | |
| 187 // delete the last mark | |
| 188 var mark = dlMarks.pop(); | |
| 189 setParameter("mk", getAllMarks()); | |
| 190 return true; | |
| 191 } | |
| 192 | |
| 193 function deleteAllMarks() { | |
| 194 // delete all marks and mk parameters | |
| 195 dlMarks.length = 0; | |
| 196 resetParameter("mk"); | |
| 197 return true; | |
| 198 } | |
| 407 | 199 |
| 200 function createMarkDiv(index) { | |
| 412 | 201 var div = document.createElement("div"); |
| 202 div.className = "mark"; | |
| 203 div.id = "mark" + index; | |
| 204 div.innerHTML = index + 1; | |
| 205 document.body.appendChild(div); | |
| 206 return div; | |
| 207 } | |
| 396 | 208 |
| 412 | 209 /* ********************************************** |
| 210 * flag routines | |
| 211 * ******************************************** */ | |
| 396 | 212 |
| 213 function hasFlag(mode) { | |
| 412 | 214 // returns if mode flag is set |
| 215 return (dlFlags[mode]); | |
| 216 } | |
| 396 | 217 |
| 218 function addFlag(mode) { | |
| 412 | 219 // add a mode flag |
| 220 dlFlags[mode] = mode; | |
| 221 setParameter("mo", getAllFlags()); | |
| 222 return true; | |
| 223 } | |
| 396 | 224 |
| 225 function removeFlag(mode) { | |
| 412 | 226 // remove a mode flag |
| 227 if (dlFlags[mode]) delete dlFlags[mode]; | |
| 228 setParameter("mo", getAllFlags()); | |
| 229 return true; | |
| 230 } | |
| 396 | 231 |
| 232 function toggleFlag(mode) { | |
| 412 | 233 // change a mode flag |
| 234 if (dlFlags[mode]) { | |
| 235 delete dlFlags[mode]; | |
| 236 } else { | |
| 237 dlFlags[mode] = mode; | |
| 238 } | |
| 239 setParameter("mo", getAllFlags()); | |
| 240 return true; | |
| 241 } | |
| 396 | 242 |
| 243 function getAllFlags() { | |
| 244 // returns a string with all flags in query format | |
| 245 var fa = new Array(); | |
| 246 for (var f in dlFlags) { | |
| 247 if ((f != "")&&(dlFlags[f] != null)) { | |
| 248 fa.push(f); | |
| 249 } | |
| 250 } | |
| 251 return fa.join(","); | |
| 252 } | |
| 253 | |
| 254 function parseFlags() { | |
| 255 // sets dlFlags from the current parameters | |
| 256 var flags = new Object(); | |
| 257 var fa = getParameter("mo").split(","); | |
| 258 for (var i = 0; i < fa.length ; i++) { | |
| 259 var f = fa[i]; | |
| 260 if (f != "") { | |
| 261 flags[f] = f; | |
| 262 } | |
| 263 } | |
| 264 return flags; | |
| 407 | 265 } |
| 396 | 266 |
| 267 | |
| 268 function bestPicSize(elem, inset) { | |
| 269 // returns a Size with the best image size for the given element | |
| 270 if (! defined(inset)) { | |
| 271 inset = 25; | |
| 272 } | |
| 273 var ws = getWinSize(); | |
| 274 var es = getElementPosition(elem); | |
| 275 if (es) { | |
| 276 ws.width = ws.width - es.x - inset; | |
| 277 ws.height = ws.height - es.y - inset; | |
| 278 } | |
| 279 return ws; | |
| 280 } | |
| 281 | |
| 282 function setDLParam(e, s, relative) { | |
| 412 | 283 // sets parameter based on HTML event |
| 284 var nam; | |
| 396 | 285 var val; |
| 286 if (s.type && (s.type == "select-one")) { | |
| 287 nam = s.name; | |
| 288 val = s.options[s.selectedIndex].value; | |
| 289 } else if (s.name && s.value) { | |
| 290 nam = s.name; | |
| 291 val = s.value; | |
| 292 } | |
| 293 if (nam && val) { | |
| 294 setParameter(nam, val, relative); | |
| 295 display(); | |
| 296 } else { | |
| 297 alert("ERROR: unable to process event!"); | |
| 298 } | |
| 299 return true; | |
| 300 } | |
| 301 | |
| 302 | |
| 303 /* ********************************************** | |
| 304 * digilib specific routines | |
| 305 * ******************************************** */ | |
| 306 | |
| 307 | |
| 407 | 308 function parseAllParameters() { |
| 412 | 309 // put the query parameters (sans "?") in the parameters array |
| 310 parseParameters(location.search.slice(1)); | |
| 311 // treat special parameters | |
| 312 dlMarks = parseMarks(); | |
| 313 dlArea = parseArea(); | |
| 314 dlFlags = parseFlags(); | |
| 315 } | |
| 407 | 316 |
| 396 | 317 function dl_param_init() { |
| 412 | 318 // initialisation before onload |
| 319 if (!baseLibVersion) alert("ERROR: baselib.js not loaded!"); | |
| 320 if (isDigilibInitialized) return false; // dl_param_init was already run | |
| 321 // dlArea = new Rectangle(0.0, 0.0, 1.0, 1.0); // overwritten by parseAllParameters() below | |
| 322 // dlMarks = new Array(); // dito | |
| 323 // dlFlags = new Object(); // dito | |
| 324 // parse parameters | |
| 325 parseAllParameters(); | |
| 326 isDigilibInitialized = true; | |
| 327 return true; | |
| 328 } | |
| 396 | 329 |
| 330 function dl_init() { | |
| 412 | 331 // initalisation on load |
| 332 if (!isDigilibInitialized) dl_param_init(); | |
| 430 | 333 scalerDiv = getElement("scaler"); |
| 334 scalerImg = getElement("pic", true); | |
| 412 | 335 // in N4 pic is in the scaler layer |
| 430 | 336 if (scalerImg == null && scalerDiv) { |
| 337 scalerImg = scalerDiv.document.images[0]; | |
| 412 | 338 } |
| 339 // give a name to the window containing digilib | |
| 340 window.name = defined(dlTarget) && dlTarget | |
| 341 ? dlTarget | |
| 342 : "digilib"; | |
| 343 // put the query parameters (sans "?") in the parameters array | |
| 344 // parseAllParameters(); // has already been called in dl_param_init() | |
| 345 // wait for image to load and display marks | |
| 346 renderMarks(); | |
| 347 // done | |
| 348 focus(); | |
| 349 } | |
| 350 | |
| 351 initScaler = dl_init; | |
| 396 | 352 |
| 407 | 353 function loadScalerImage(detail) { |
| 412 | 354 var pic = getElement('pic'); |
| 355 var scaler = getElement('scaler'); | |
| 356 var zoomdiv = getElement("zoom"); // test for presence only | |
| 357 var overlay = getElement("overlay"); // test for presence only | |
| 358 var about = getElement("bird"); // test for presence only | |
| 359 var bird = getElement("bird"); // test for presence only | |
| 360 var picsize = bestPicSize(scaler, 50); | |
| 361 var src = "../servlet/Scaler?" | |
| 362 + getQueryString() | |
| 363 + "&dw=" + picsize.width | |
| 364 + "&dh=" + picsize.height; | |
| 365 // debug(src); | |
| 366 pic.src = src; | |
| 367 initScaler(); // dl_init braucht die endgültigen Maße des pic Elements | |
| 368 } | |
| 396 | 369 |
| 370 function display(detail) { | |
| 412 | 371 // redisplay the page |
| 372 if (! detail) detail = PARAM_ALL; | |
| 373 var queryString = getAllParameters(detail); | |
| 374 if (reloadPage) { | |
| 375 location.href | |
| 376 = location.protocol + "//" | |
| 377 + location.host | |
| 378 + location.pathname | |
| 379 + "?" + queryString; | |
| 380 } else { | |
| 381 loadScalerImage(); | |
| 382 } | |
| 383 } | |
| 396 | 384 |
| 385 /* ********************************************** | |
| 386 * interactive digilib functions | |
| 387 * ******************************************** */ | |
| 388 function renderMarks() { | |
| 412 | 389 // make sure the image is loaded so we know its size |
| 430 | 390 if (defined(scalerImg.complete) && !scalerImg.complete && !browserType.isN4 ) { |
| 412 | 391 setTimeout("renderMarks()", 100); |
| 392 return; | |
| 396 | 393 } |
| 407 | 394 // put the visible marks on the image |
| 430 | 395 dlTrafo = parseTrafo(scalerImg); |
| 412 | 396 // debugProps(dlArea, "dlArea"); |
| 407 | 397 for (var i = 0; i < dlMarks.length; i++) { |
| 412 | 398 var div = document.getElementById("mark" + i) || createMarkDiv(i); |
| 407 | 399 var mark = dlMarks[i]; |
|
425
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
400 // debugProps(mark, "mark"); |
| 412 | 401 if (dlArea.containsPosition(mark)) { |
| 402 var mpos = dlTrafo.transform(mark); // FIX ME: transform does not change anything | |
|
425
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
403 // debugProps(mark, "mpos"); |
| 412 | 404 // suboptimal to place -5 pixels and not half size of mark-image |
| 405 // better not hide the marked spot (MR) | |
| 406 // mpos.x = mpos.x -5; | |
| 407 // mpos.y = mpos.y -5; | |
| 408 moveElement(div, mpos); | |
| 409 showElement(div, true); | |
| 410 } else { | |
| 411 // hide the other marks | |
| 412 showElement(div, false); | |
| 413 } | |
| 396 | 414 } |
| 415 } | |
| 416 | |
| 417 function setMark(reload) { | |
| 418 | |
| 412 | 419 function markEvent(evt) { |
| 420 // event handler adding a new mark | |
| 430 | 421 unregisterEvent("mousedown", scalerDiv, markEvent); |
| 412 | 422 addMark(evt); |
| 423 if ( defined(reload) && !reload ) { | |
| 424 // don't redisplay | |
| 425 renderMarks(); | |
| 426 return; | |
| 427 } | |
| 428 display(); | |
| 430 | 429 return stopEvent(evt); |
| 412 | 430 } |
| 431 | |
| 432 // add a mark where clicked | |
| 433 window.focus(); | |
| 430 | 434 moveCenter(false); |
| 412 | 435 // start event capturing |
| 430 | 436 registerEvent("mousedown", scalerDiv, markEvent); |
| 412 | 437 } |
| 396 | 438 |
| 439 function removeMark(reload) { | |
| 440 // remove the last mark | |
| 441 deleteMark(); | |
| 442 if (defined(reload)&&(!reload)) { | |
| 443 // don't redisplay | |
| 444 renderMarks(); | |
| 445 return; | |
| 446 } | |
| 447 display(); | |
| 448 } | |
| 449 | |
| 450 function zoomArea() { | |
| 412 | 451 var pt1, pt2; |
| 452 var zoomdiv = getElement("zoom"); | |
| 453 var overlay = getElement("overlay"); | |
| 454 // use overlay div to avoid <img> mousemove problems | |
| 430 | 455 var picRect = getElementRect(scalerImg); |
| 412 | 456 // FIX ME: is there a way to query the border width from CSS info? |
| 457 // rect.x -= 2; // account for overlay borders | |
| 458 // rect.y -= 2; | |
| 430 | 459 moveElement(overlay, picRect); |
| 412 | 460 showElement(overlay, true); |
| 461 // start event capturing | |
| 462 registerEvent("mousedown", overlay, zoomStart); | |
| 430 | 463 registerEvent("mousedown", scalerImg, zoomStart); |
| 412 | 464 window.focus(); |
| 396 | 465 |
| 407 | 466 // mousedown handler: start moving |
| 412 | 467 function zoomStart(evt) { |
| 468 pt1 = evtPosition(evt); | |
| 469 unregisterEvent("mousedown", overlay, zoomStart); | |
| 430 | 470 unregisterEvent("mousedown", scalerImg, zoomStart); |
| 412 | 471 // setup and show zoom div |
| 472 moveElement(zoomdiv, Rectangle(pt1.x, pt1.y, 0, 0)); | |
| 473 showElement(zoomdiv, true); | |
| 430 | 474 // register events |
| 475 registerEvent("mousemove", document, zoomMove); | |
| 476 registerEvent("mouseup", document, zoomEnd); | |
| 412 | 477 return stopEvent(evt); |
| 478 } | |
| 479 | |
| 407 | 480 // mouseup handler: end moving |
| 412 | 481 function zoomEnd(evt) { |
| 482 pt2 = evtPosition(evt); | |
| 483 // assume a click if the area is too small (up to 3 x 3 pixel) | |
| 430 | 484 var clickRect = getRect(pt1, pt2); |
| 485 if (clickRect.getArea() <= MIN_AREA_SIZE) return stopEvent(evt); | |
| 412 | 486 // hide zoom div |
| 487 showElement(zoomdiv, false); | |
| 488 showElement(overlay, false); | |
| 430 | 489 // unregister events |
| 490 unregisterEvent("mousemove", document, zoomMove); | |
| 491 unregisterEvent("mouseup", document, zoomMove); | |
| 412 | 492 // calc offsets |
| 430 | 493 clickRect.clipTo(picRect); |
| 412 | 494 var area = getRect( |
| 495 // FIX ME: liefert negative x/y Werte, wenn hmir/vmir=1 | |
| 430 | 496 dlTrafo.invtransform(clickRect.getPt1()), |
| 497 dlTrafo.invtransform(clickRect.getPt2()) | |
| 412 | 498 ); |
| 499 setParameter("wx", cropFloat(area.x)); | |
| 500 setParameter("wy", cropFloat(area.y)); | |
| 501 setParameter("ww", cropFloat(area.width)); | |
| 502 setParameter("wh", cropFloat(area.height)); | |
| 503 // parseArea(); // why? | |
| 504 // zoomed is always fit | |
| 505 setParameter("ws", 1); | |
| 506 display(); | |
| 507 return stopEvent(evt); | |
| 508 } | |
| 509 | |
| 407 | 510 // mouse move handler |
| 412 | 511 function zoomMove(evt) { |
| 512 pt2 = evtPosition(evt); | |
| 430 | 513 var rect = getRect(pt1, pt2); |
| 514 rect.clipTo(picRect); | |
| 412 | 515 // update zoom div |
| 430 | 516 moveElement(zoomdiv, rect); |
| 412 | 517 return stopEvent(evt); |
| 518 } | |
| 519 | |
| 520 // get a rectangle from two points | |
| 521 function getRect(p1, p2) { | |
| 522 return new Rectangle( | |
| 523 Math.min(p1.x, p2.x), | |
| 524 Math.min(p1.y, p2.y), | |
| 525 Math.abs(p1.x - p2.x), | |
| 526 Math.abs(p1.y - p2.y) | |
| 527 ); | |
| 528 } | |
| 396 | 529 } |
| 530 | |
| 531 function zoomBy(factor) { | |
| 532 // zooms by the given factor | |
| 533 var newarea = dlArea.copy(); | |
| 534 newarea.width /= factor; | |
| 535 newarea.height /= factor; | |
| 536 newarea.x -= 0.5 * (newarea.width - dlArea.width); | |
| 537 newarea.y -= 0.5 * (newarea.height - dlArea.height); | |
| 538 newarea = dlMaxArea.fit(newarea); | |
| 539 setParamFromArea(newarea); | |
| 540 display(); | |
| 541 } | |
| 542 | |
| 543 | |
| 544 function zoomFullpage() { | |
| 545 // zooms out to show the whole image | |
| 546 setParameter("wx", 0.0); | |
| 547 setParameter("wy", 0.0); | |
| 548 setParameter("ww", 1.0); | |
| 549 setParameter("wh", 1.0); | |
| 550 display(); | |
| 551 } | |
| 552 | |
| 553 | |
| 430 | 554 function moveCenter(on) { |
| 396 | 555 // move visible area so that it's centered around the clicked point |
| 430 | 556 if (isFullArea()) return; // nothing to do |
| 557 // starting event capture | |
| 558 if (on) registerEvent("mousedown", scalerImg, moveCenterEvent); | |
| 559 else unregisterEvent("mousedown", scalerImg, moveCenterEvent); | |
| 396 | 560 window.focus(); |
| 430 | 561 } |
| 396 | 562 |
| 430 | 563 function moveCenterEvent(evt) { |
| 564 // move to handler | |
| 565 var pt = dlTrafo.invtransform(evtPosition(evt)); | |
| 566 var newarea = new Rectangle( | |
| 567 pt.x - 0.5 * dlArea.width, | |
| 568 pt.y - 0.5 * dlArea.height, | |
| 569 dlArea.width, | |
| 570 dlArea.height | |
| 571 ); | |
| 572 newarea.stayInside(dlMaxArea); | |
| 573 // newarea = dlMaxArea.fit(newarea); | |
| 574 // debugProps(newarea, "newarea"); | |
| 575 // debugProps(dlArea, "dlArea"); | |
| 576 if (newarea.equals(dlArea)) return; // keep event handler | |
| 577 unregisterEvent("mousedown", scalerImg, moveCenterEvent); | |
| 578 // set parameters | |
| 579 setParamFromArea(newarea); | |
| 580 parseArea(); | |
| 581 display(); | |
| 396 | 582 } |
| 583 | |
| 412 | 584 function isFullArea(area) { |
| 585 if (!area) area = dlArea; | |
| 586 return ((area.width == 1.0) && (area.height == 1.0)); | |
| 430 | 587 } |
| 412 | 588 |
| 589 function canMove(movx, movy) { | |
|
425
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
590 if (isFullArea()) return false; |
| 430 | 591 var x2 = dlArea.x + dlArea.width; |
| 592 var y2 = dlArea.y + dlArea.height; | |
|
425
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
593 // debugProps(dlArea); |
| 412 | 594 return ((movx < 0) && (dlArea.x > 0)) |
| 430 | 595 || ((movx > 0) && (x2 < 1.0)) |
| 596 || ((movy < 0) && (dlArea.y > 0)) | |
| 597 || ((movy > 0) && (y2 < 1.0)) | |
| 598 } | |
| 412 | 599 |
| 396 | 600 function moveBy(movx, movy) { |
| 601 // move visible area by movx and movy (in units of ww, wh) | |
|
425
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
602 if (!canMove(movx, movy)) return; // nothing to do |
| 396 | 603 var newarea = dlArea.copy(); |
| 604 newarea.x += parseFloat(movx)*dlArea.width; | |
| 605 newarea.y += parseFloat(movy)*dlArea.height; | |
| 606 newarea = dlMaxArea.fit(newarea); | |
| 607 // set parameters | |
| 608 setParamFromArea(newarea); | |
| 609 parseArea(); | |
| 610 display(); | |
| 611 } | |
| 612 | |
| 407 | 613 function getRef(baseURL) { |
| 396 | 614 // returns a reference to the current digilib set |
|
425
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
615 if (!baseUrl) baseUrl |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
616 = location.protocol |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
617 + "//" |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
618 + location.host |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
619 + location.pathname; |
| 396 | 620 var hyperlinkRef = baseUrl; |
| 412 | 621 var params = getAllParameters(PARAM_ALL & ~(PARAM_DPI | PARAM_PAGES)); // all without ddpi, pt |
| 407 | 622 if (params.length > 0) hyperlinkRef += "?" + params; |
| 623 return hyperlinkRef; | |
| 396 | 624 } |
| 625 | |
| 626 function getRefWin(type, msg) { | |
| 627 // shows an alert with a reference to the current digilib set | |
| 407 | 628 if (! msg) msg = "URL reference to the current view"; |
| 629 prompt(msg, getRef()); | |
| 396 | 630 } |
| 631 | |
| 632 function getQuality() { | |
| 407 | 633 // returns the current q setting |
| 396 | 634 for (var i = 0; i < 3; i++) { |
| 407 | 635 if (hasFlag("q"+i)) return i; |
| 412 | 636 } |
| 407 | 637 return 1 |
| 396 | 638 } |
| 639 | |
| 640 function setQuality(qual) { | |
| 641 // set the image quality | |
| 407 | 642 for (var i = 0; i < 3; i++) removeFlag("q" + i); |
| 643 if (qual > 2) return alert("Quality number not supported"); | |
| 644 addFlag("q" + i); | |
| 396 | 645 setParameter("mo", getAllFlags()); |
| 646 display(); | |
| 407 | 647 } |
| 396 | 648 |
| 649 function setQualityWin(msg) { | |
| 412 | 650 // dialog for setting quality |
| 651 if (! msg) msg = "Quality (0..2)"; | |
| 652 var q = getQuality(); | |
| 653 var newq = window.prompt(msg, q); | |
| 654 if (newq) setQuality(newq); | |
| 655 } | |
| 396 | 656 |
| 657 function mirror(dir) { | |
| 658 // mirror the image horizontally or vertically | |
|
425
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
659 toggleFlag(dir == "h" |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
660 ? "hmir" |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
661 : "vmir" |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
662 ); |
| 396 | 663 setParameter("mo", getAllFlags()); |
| 664 display(); | |
| 665 } | |
| 666 | |
| 667 function gotoPage(gopage, keep) { | |
| 412 | 668 // goto given page nr (+/-: relative) |
| 669 var oldpn = parseInt(getParameter("pn")); | |
| 670 setParameter("pn", gopage, true); | |
| 671 var pn = parseInt(getParameter("pn")); | |
| 672 if (pn < 1) { | |
| 673 alert("No such page! (Page number too low)"); | |
| 674 setParameter("pn", oldpn); | |
| 675 return; | |
| 676 } | |
| 677 if (hasParameter("pt")) { | |
| 678 pt = parseInt(getParameter("pt")) | |
| 679 if (pn > pt) { | |
| 680 alert("No such page! (Page number too high)"); | |
| 681 setParameter("pn", oldpn); | |
| 682 return; | |
| 683 } | |
| 684 } | |
| 685 if (keep) { | |
| 686 display(PARAM_ALL & ~PARAM_MARK); // all, no mark | |
| 687 } else { | |
| 688 display(PARAM_FILE | PARAM_MODE | PARAM_PAGES); // fn, pn, ws, mo + pt | |
| 689 // FIX ME: currently the mirror status gets propagated to the other pages | |
| 690 // hmir and vmir should not be mode flags, but boolean params!!! | |
| 691 } | |
| 396 | 692 } |
| 693 | |
| 694 function gotoPageWin() { | |
| 412 | 695 // dialog to ask for new page nr |
| 696 var pn = getParameter("pn"); | |
| 697 var gopage = window.prompt("Go to page", pn); | |
| 698 if (gopage) gotoPage(gopage); | |
| 699 } | |
| 396 | 700 |
| 701 function setParamWin(param, text, relative) { | |
| 412 | 702 // dialog to ask for new parameter value |
| 703 var val = getParameter(param); | |
| 704 var newval = window.prompt(text, val); | |
| 705 if (newval) { | |
| 706 setParameter(param, newval, relative); | |
| 707 display(); | |
| 708 } | |
| 396 | 709 } |
| 710 | |
| 711 function showOptions(show) { | |
| 412 | 712 // show or hide option div |
| 713 var elem = getElement("dloptions"); | |
| 714 showElement(elem, show); | |
| 715 // FIX ME: get rid of the dotted line around the buttons when focused | |
| 716 } | |
| 407 | 717 |
| 718 function showAboutDiv(show) { | |
| 412 | 719 // show or hide "about" div |
| 720 var elem = getElement("about"); | |
| 721 if (elem == null) { | |
| 722 if (!show) return; | |
| 723 alert("About Digilib - dialog missing in HTML code!" | |
| 724 + "\nDigilib Version: " + digilibVersion | |
| 430 | 725 + "\JSP Version: " + jspVersion |
| 412 | 726 + "\ndlLib Version: " + dllibVersion |
| 727 + "\nbaseLib Version: " + baseLibVersion); | |
| 728 return; | |
| 729 } | |
| 730 document.getElementById("digilib-version").innerHTML = "Digilib Version: " + digilibVersion; | |
| 430 | 731 document.getElementById("jsp-version").innerHTML = "JSP Version: " + jspVersion; |
| 412 | 732 document.getElementById("baselib-version").innerHTML = "baseLib Version: " + baseLibVersion; |
| 733 document.getElementById("dllib-version").innerHTML = "dlLib Version: " + dllibVersion; | |
| 734 showElement(elem, show); | |
| 735 } | |
| 736 | |
| 737 function loadBirdImage() { | |
| 738 var img = getElement("bird-image"); | |
| 739 var src = "../servlet/Scaler?" | |
| 430 | 740 + getQueryString(PARAM_FILE) |
| 412 | 741 + "&dw=" + BIRD_MAXX |
| 742 + "&dh=" + BIRD_MAXY; | |
| 743 img.src = src; | |
| 744 } | |
| 745 | |
| 746 function showBirdDiv(show) { | |
| 747 // show or hide "bird's eye" div | |
| 748 var startPos; // anchor for dragging | |
| 749 var newRect; // position after drag | |
| 750 var birdImg = getElement("bird-image"); | |
| 430 | 751 var birdArea = getElement("bird-area"); |
| 752 var overlay = getElement("overlay"); | |
| 412 | 753 showElement(birdImg, show); |
| 430 | 754 // dont show selector if area has full size |
| 412 | 755 if (!show || isFullArea()) { |
| 756 // hide area | |
| 757 showElement(birdArea, false); | |
| 430 | 758 showElement(overlay, false); |
| 412 | 759 return; |
| 760 }; | |
| 761 var birdImgRect = getElementRect(birdImg); | |
| 762 var area = parseArea(); | |
| 763 // scale area down to img size | |
| 764 var birdAreaRect = new Rectangle( | |
| 765 // what about borders ?? | |
| 766 birdImgRect.x + birdImgRect.width * area.x, | |
| 767 birdImgRect.y + birdImgRect.height * area.y, | |
| 768 birdImgRect.width * area.width, | |
| 769 birdImgRect.height * area.height | |
| 770 ); | |
| 771 moveElement(birdArea, birdAreaRect); | |
| 430 | 772 showElement(birdArea, true); |
| 773 moveElement(overlay, birdImgRect); | |
| 774 showElement(overlay, true); | |
| 775 registerEvent("mousedown", overlay, birdAreaStartDrag); | |
| 776 registerEvent("mousedown", birdImg, birdAreaStartDrag); | |
| 412 | 777 |
| 778 function birdAreaStartDrag(evt) { | |
| 779 // mousedown handler: start drag | |
| 780 startPos = evtPosition(evt); | |
| 430 | 781 unregisterEvent("mousedown", overlay, birdAreaStartDrag); |
| 782 unregisterEvent("mousedown", birdImg, birdAreaStartDrag); | |
| 783 registerEvent("mousemove", document, birdAreaMove); | |
| 784 registerEvent("mouseup", document, birdAreaEndDrag); | |
| 412 | 785 // debugProps(getElementRect(bird)) |
| 786 return stopEvent(evt); | |
| 787 } | |
| 788 | |
| 789 function birdAreaMove(evt) { | |
| 790 // mousemove handler: drag | |
| 791 var pos = evtPosition(evt); | |
| 792 var dx = pos.x - startPos.x; | |
| 793 var dy = pos.y - startPos.y; | |
| 794 // move birdArea div, keeping size | |
| 795 newRect = new Rectangle( | |
| 796 birdAreaRect.x + dx, | |
| 797 birdAreaRect.y + dy, | |
| 798 birdAreaRect.width, | |
| 799 birdAreaRect.height); | |
| 800 // stay within image | |
| 801 newRect.stayInside(birdImgRect); | |
| 802 moveElement(birdArea, newRect); | |
| 803 showElement(birdArea, true); | |
| 804 return stopEvent(evt); | |
| 805 } | |
| 806 | |
| 807 function birdAreaEndDrag(evt) { | |
| 808 // mouseup handler: reload page | |
| 430 | 809 unregisterEvent("mousemove", document, birdAreaMove); |
| 810 unregisterEvent("mouseup", document, birdAreaEndDrag); | |
| 811 showElement(overlay, false); | |
| 812 if (newRect == null) { // no movement happened | |
| 813 startPos = birdAreaRect.getCenter(); | |
| 814 birdAreaMove(evt); // set center to click position | |
| 815 } | |
| 412 | 816 setParameter("wx", cropFloat((newRect.x - birdImgRect.x) / birdImgRect.width)); |
| 817 setParameter("wy", cropFloat((newRect.y - birdImgRect.y) / birdImgRect.height)); | |
| 818 // zoomed is always fit | |
| 819 setParameter("ws", 1); | |
| 820 display(); | |
| 821 return stopEvent(evt); | |
| 822 } | |
| 823 } | |
| 824 | |
|
425
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
825 function showArrow(name, rect, show) { |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
826 var arrow = getElement(name); |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
827 moveElement(arrow, rect); |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
828 showElement(arrow, show); |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
829 } |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
830 |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
831 function showArrows() { |
| 430 | 832 if (defined(scalerImg.complete) && !scalerImg.complete && !browserType.isN4 ) { |
|
425
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
833 setTimeout("showArrows()", 100); |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
834 return; |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
835 } |
| 430 | 836 var r = getElementRect(scalerImg); |
|
425
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
837 showArrow('up', |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
838 new Rectangle(r.x, r.y, r.width, ARROW_WIDTH), |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
839 canMove(0, -1) |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
840 ); |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
841 showArrow('down', |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
842 new Rectangle(r.x, r.y + r.height - ARROW_WIDTH, r.width, ARROW_WIDTH), |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
843 canMove(0, 1) |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
844 ); |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
845 showArrow('left', |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
846 new Rectangle(r.x, r.y, ARROW_WIDTH, r.height), |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
847 canMove(-1, 0) |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
848 ); |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
849 showArrow('right', |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
850 new Rectangle(r.x + r.width - ARROW_WIDTH, r.y, ARROW_WIDTH, r.height), |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
851 canMove(1, 0) |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
852 ); |
|
ab2557f079fc
added showArrows() function (navigation arrows overlay)
hertzhaft
parents:
412
diff
changeset
|
853 } |
| 412 | 854 |
| 430 | 855 function calibrate(direction) { |
| 856 // calibrate screen | |
| 857 var startPos; // anchor for dragging | |
| 858 var newRect; // position after drag | |
| 859 var calDiv = getElement("calibration"); | |
| 435 | 860 var pixel = calDiv.getElementsByTagName("p")[0]; |
| 430 | 861 var overlay = getElement("overlay"); |
| 862 moveElement(overlay, getWinRect()); | |
| 863 showElement(overlay, true); | |
| 864 var xDir = direction == "x"; | |
| 865 moveCenter(false); | |
| 866 registerEvent("mousedown", document, calibrationStartDrag); | |
| 867 | |
| 868 function calibrationStartDrag(evt) { | |
| 869 // mousedown handler: start drag | |
| 870 startPos = evtPosition(evt); | |
| 871 unregisterEvent("mousedown", document, calibrationStartDrag); | |
| 872 registerEvent("mousemove", document, calibrationMove); | |
| 873 registerEvent("mouseup", document, calibrationEndDrag); | |
| 874 registerEvent("mousemove", calDiv, calibrationMove); | |
| 875 registerEvent("mouseup", calDiv, calibrationEndDrag); | |
| 876 newRect = new Rectangle( | |
| 877 startPos.x, | |
| 878 startPos.y, | |
| 879 xDir ? 1 : CALIBRATION_WIDTH, | |
| 880 xDir ? CALIBRATION_WIDTH : 1 | |
| 881 ); | |
| 882 moveElement(calDiv, newRect); | |
| 883 showElement(calDiv, true); | |
| 884 // debugProps(getElementRect(bird)) | |
| 885 return stopEvent(evt); | |
| 886 } | |
| 887 | |
| 888 function calibrationMove(evt) { | |
| 889 // mousemove handler: drag | |
| 890 var pos = evtPosition(evt); | |
| 891 var dx = (xDir) ? pos.x - startPos.x : CALIBRATION_WIDTH; | |
| 892 var dy = (xDir) ? CALIBRATION_WIDTH : pos.y - startPos.y; | |
| 893 // move birdArea div, keeping size | |
| 894 newRect = new Rectangle(startPos.x, startPos.y, dx, dy); | |
| 435 | 895 pixel.innerHTML = (xDir ? dx : dy) + " px"; |
| 430 | 896 moveElement(calDiv, newRect); |
| 897 showElement(calDiv, true); | |
| 898 return stopEvent(evt); | |
| 899 } | |
| 900 | |
| 901 function calibrationEndDrag(evt) { | |
| 902 // mouseup handler: calibrate | |
| 903 unregisterEvent("mousemove", document, calibrationMove); | |
| 904 unregisterEvent("mouseup", document, calibrationEndDrag); | |
| 905 unregisterEvent("mousemove", calDiv, calibrationMove); | |
| 906 unregisterEvent("mouseup", calDiv, calibrationEndDrag); | |
| 435 | 907 if (xDir) { |
| 908 var val = newRect.width * 0.254; // ratio dm/inch | |
| 909 cookie.add("ddpi", val); | |
| 910 cookie.add("ddpix", val); | |
| 911 } else { | |
| 912 var val = newRect.height * 0.254; | |
| 913 cookie.add("ddpiy", val); | |
| 914 } | |
| 430 | 915 showElement(calDiv, false); |
| 916 showElement(overlay, false); | |
| 917 moveCenter(true); | |
| 918 return stopEvent(evt); | |
| 919 } | |
| 920 } | |
| 921 | |
| 435 | 922 function originalSize() { |
| 923 var dpi = cookie.get("ddpi"); | |
| 924 if (dpi == null) { | |
| 925 alert("Screen has not yet been calibrated - using default value of 72 dpi"); | |
| 926 dpi = 72; | |
| 927 } | |
| 928 setParameter("ddpi", dpi); | |
| 929 addFlag("osize"); | |
| 930 display(); | |
| 931 } | |
| 932 | |
| 933 function pixelByPixel() { | |
| 934 addFlag("clip"); | |
| 935 display(); | |
| 936 } | |
| 436 | 937 |
| 938 function resize(factor) { | |
| 939 setParameter("ws", factor); | |
| 940 display(); | |
| 941 var menu = getElement("sizes"); | |
| 942 showElement(menu, false); | |
| 943 } | |
| 944 | |
| 945 function sizeMenu() { | |
| 946 var menu = getElement("sizes"); | |
| 947 showElement(menu, true); | |
| 948 } | |
| 949 | |
| 430 | 950 // :tabSize=4:indentSize=4:noTabs=true: |
| 951 |
