Annotation of zogiLib/js/dllib.js, revision 1.11
1.2 casties 1: /* Copyright (C) 2003,2004 IT-Group MPIWG, WTWG Uni Bern and others
1.1 casties 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:
1.2 casties 17: Authors:
18: Christian Luginbuehl, 01.05.2003 (first version)
19: DW 24.03.2004 (Changed for digiLib in Zope)
1.8 casties 20: Robert Casties, 14.7.2006
1.1 casties 21:
1.2 casties 22: ! Requires baselib.js !
1.1 casties 23:
24: */
25:
1.5 casties 26:
27: function identify() {
1.6 casties 28: // used for identifying a digilib instance
29: // Relato uses that function - lugi
30: return "Digilib 0.6";
1.5 casties 31: }
32:
1.1 casties 33:
34: /*
35: * more parameter handling
36: */
37:
38: function parseArea() {
39: // returns area Rectangle from current parameters
40: return new Rectangle(getParameter("wx"), getParameter("wy"), getParameter("ww"), getParameter("wh"));
41: }
42:
43: function setParamFromArea(rect) {
44: // sets digilib wx etc. from rect
45: setParameter("wx", cropFloat(rect.x));
46: setParameter("wy", cropFloat(rect.y));
47: setParameter("ww", cropFloat(rect.width));
48: setParameter("wh", cropFloat(rect.height));
49: return true;
50: }
51:
52: function parseTrafo(elem) {
53: // returns Transform from current dlArea and picsize
54: var picsize = getElementRect(elem);
55: var trafo = new Transform();
56: // subtract area offset and size
57: trafo.concat(getTranslation(new Position(-dlArea.x, -dlArea.y)));
58: trafo.concat(getScale(new Size(1/dlArea.width, 1/dlArea.height)));
59: // scale to screen size
60: trafo.concat(getScale(picsize));
61: trafo.concat(getTranslation(picsize));
62: // rotate
63: //trafo.concat(getRotation(- getParameter("rot"), new Position(0.5*picsize.width, 0.5*picsize.height)));
64: // mirror
65: //if (hasFlag("hmir")) {
66: //trafo.m00 = - trafo.m00;
67: //}
68: //if (hasFlag("vmir")) {
69: //trafo.m11 = - trafo.m11;
70: //}
71: return trafo;
72: }
73:
74:
75: function parseMarks() {
76: // returns marks array from current parameters
77: var marks = new Array();
78: var ma;
79: var mk = getParameter("mk");
80: if (mk.indexOf(";") >= 0) {
1.6 casties 81: // old format with ";"
82: ma = mk.split(";");
1.1 casties 83: } else {
1.6 casties 84: ma = mk.split(",");
1.1 casties 85: }
86: for (var i = 0; i < ma.length ; i++) {
1.6 casties 87: var pos = ma[i].split("/");
88: if (pos.length > 1) {
89: marks.push(new Position(pos[0], pos[1]));
90: }
1.1 casties 91: }
92: return marks;
93: }
94:
95: function getAllMarks() {
96: // returns a string with all marks in query format
97: var marks = new Array();
98: for (var i = 0; i < dlMarks.length; i++) {
1.6 casties 99: marks.push(cropFloat(dlMarks[i].x) + "/" + cropFloat(dlMarks[i].y));
1.1 casties 100: }
101: return marks.join(",");
102: }
103:
104: function addMark(pos) {
105: // add a mark
106: dlMarks.push(pos);
107: setParameter("mk", getAllMarks());
108: return true;
109: }
110:
111: function deleteMark() {
112: // delete the last mark
113: dlMarks.pop();
114: setParameter("mk", getAllMarks());
115: return true;
116: }
117:
118: function hasFlag(mode) {
119: // returns if mode flag is set
120: return (dlFlags[mode]);
121: }
122:
123: function addFlag(mode) {
124: // add a mode flag
125: dlFlags[mode] = mode;
126: setParameter("mo", getAllFlags());
127: return true;
128: }
129:
130: function removeFlag(mode) {
131: // remove a mode flag
132: if (dlFlags[mode]) {
1.6 casties 133: delete dlFlags[mode];
1.1 casties 134: }
135: setParameter("mo", getAllFlags());
136: return true;
137: }
138:
139: function toggleFlag(mode) {
140: // change a mode flag
141: if (dlFlags[mode]) {
1.6 casties 142: delete dlFlags[mode];
1.1 casties 143: } else {
1.6 casties 144: dlFlags[mode] = mode;
1.1 casties 145: }
146: setParameter("mo", getAllFlags());
147: return true;
148: }
149:
150: function getAllFlags() {
151: // returns a string with all flags in query format
152: var fa = new Array();
153: for (var f in dlFlags) {
1.6 casties 154: if ((f != "")&&(dlFlags[f] != null)) {
155: fa.push(f);
156: }
1.1 casties 157: }
158: return fa.join(",");
159: }
160:
161: function parseFlags() {
162: // sets dlFlags from the current parameters
163: var flags = new Object();
164: var fa = getParameter("mo").split(",");
165: for (var i = 0; i < fa.length ; i++) {
1.6 casties 166: var f = fa[i];
167: if (f != "") {
168: flags[f] = f;
169: }
1.1 casties 170: }
171: return flags;
172: }
173:
174:
175: function bestPicSize(elem, inset) {
176: // returns a Size with the best image size for the given element
177: if (! defined(inset)) {
1.6 casties 178: inset = 25;
1.1 casties 179: }
180: var ws = getWinSize();
1.10 casties 181: var wsold = ws.copy();
1.1 casties 182: var es = getElementPosition(elem);
183: if (es) {
1.10 casties 184: if ((es.x > ws.width)||(es.y > ws.height)) {
185: alert("es="+es+" is outside ws="+ws+" fixing...");
186: ws.width = ws.width - inset;
187: ws.height = ws.height - inset;
188: } else {
189: ws.width = ws.width - es.x - inset;
190: ws.height = ws.height - es.y - inset;
191: }
1.1 casties 192: }
1.11 ! casties 193: //alert("ws="+wsold+" es="+es+" -> ws="+ws);
1.10 casties 194: //alert("ws="+ws+"("+typeof(ws)+") es="+es);
1.1 casties 195: return ws;
196: }
197:
1.7 casties 198: function setDLParam(e, s, relative) {
1.6 casties 199: // sets parameter based on HTML event
200: var nam;
201: var val;
202: if (s.type && (s.type == "select-one")) {
203: nam = s.name;
204: val = s.options[s.selectedIndex].value;
205: } else if (s.name && s.value) {
206: nam = s.name;
207: val = s.value;
208: }
209: if (nam && val) {
1.7 casties 210: setParameter(nam, val, relative);
1.6 casties 211: display();
212: } else {
1.7 casties 213: alert("ERROR: unable to process event!");
1.6 casties 214: }
215: return true;
216: }
217:
1.1 casties 218:
219: /* **********************************************
220: * digilib specific routines
221: * ******************************************** */
222:
223:
224: function dl_param_init() {
225: // parameter initialisation before onload
1.5 casties 226: if (!baseScriptVersion) {
1.6 casties 227: base_init();
1.5 casties 228: }
1.9 casties 229: dlScriptVersion = "1.3a";
1.5 casties 230: dlArea = new Rectangle(0.0, 0.0, 1.0, 1.0);
231: dlMaxArea = new Rectangle(0.0, 0.0, 1.0, 1.0);
232: dlTrafo = new Transform();
233: dlMarks = new Array();
234: dlFlags = new Object();
235: elemScaler = null;
236: picElem = null;
237: ZOOMFACTOR = Math.sqrt(2);
1.1 casties 238:
239: // put the query parameters (sans "?") in the parameters array
1.9 casties 240: // non-digilib parameters get detail level 32
241: parseParameters(location.search.slice(1),32);
1.1 casties 242: // treat special parameters
243: dlMarks = parseMarks();
244: dlArea = parseArea();
245: dlFlags = parseFlags();
1.9 casties 246: // mask for parameters when creating new URL
247: dlUrlParamMask = 255;
1.1 casties 248: }
249:
250:
251: function dl_init() {
252: // initalisation on load
1.5 casties 253: if (!dlScriptVersion) {
1.6 casties 254: dl_param_init();
1.5 casties 255: }
1.1 casties 256: elemScaler = getElement("scaler", true);
257: picElem = getElement("pic", true);
258: if (picElem == null && elemScaler) {
1.6 casties 259: // in N4 pic is in the scaler layer
260: picElem = elemScaler.document.images[0];
1.1 casties 261: }
262: if ((!elemScaler)||(!picElem)) {
1.6 casties 263: alert("Sorry, digilib doesn't work here!");
264: return false;
1.1 casties 265: }
266: // give a name to the window containing digilib
267: if (defined(dlTarget)&&(dlTarget)) {
1.6 casties 268: window.name = dlTarget;
1.1 casties 269: } else {
1.6 casties 270: window.name = "digilib";
1.1 casties 271: }
272: // put the query parameters (sans "?") in the parameters array
1.9 casties 273: //parseParameters(location.search.slice(1),32);
1.1 casties 274: // treat special parameters
275: dlMarks = parseMarks();
276: dlArea = parseArea();
277: dlFlags = parseFlags();
278: // wait for image to load and display marks
279: renderMarks();
280: // done
281: focus();
282: return;
283: }
284:
285:
286: function display(detail) {
287: // redisplay the page
288: if (! detail) {
1.7 casties 289: detail = 255;
1.1 casties 290: }
1.9 casties 291: var queryString = getAllParameters(detail & dlUrlParamMask);
1.1 casties 292: location.href = location.protocol + "//" + location.host + location.pathname + "?" + queryString;
293: }
294:
295:
296: /* **********************************************
297: * interactive digilib functions
298: * ******************************************** */
299:
300:
301: function renderMarks() {
302: // put the visible marks on the image
303: var mark_count = dlMarks.length;
304: // make shure the image is loaded so we know its size
305: if (defined(picElem.complete) && picElem.complete == false && ! browserType.isN4 ) {
1.6 casties 306: setTimeout("renderMarks()", 100);
1.1 casties 307: } else {
1.6 casties 308: dlTrafo = parseTrafo(picElem);
309: for (var i = 0; i < 8; i++) {
310: var me = getElement("dot"+i);
311: if (i < mark_count) {
312: if (dlArea.containsPosition(dlMarks[i])) {
313: var mpos = dlTrafo.transform(dlMarks[i]);
314: // suboptimal to place -5 pixels and not half size of mark-image
315: mpos.x = mpos.x -5;
316: mpos.y = mpos.y -5;
317: moveElement(me, mpos);
318: showElement(me, true);
319: }
320: } else {
321: // hide the other marks
322: showElement(me, false);
323: }
324: }
1.1 casties 325: }
326: }
327:
328:
329: function setMark(reload) {
330: // add a mark where clicked
331: if ( dlMarks.length > 7 ) {
1.6 casties 332: alert("Only 8 marks are possible at the moment!");
333: return;
1.1 casties 334: }
1.2 casties 335: window.focus();
1.1 casties 336:
337: function markEvent(evt) {
1.6 casties 338: // event handler adding a new mark
339: unregisterEvent("mousedown", elemScaler, markEvent);
340: var p = dlTrafo.invtransform(evtPosition(evt));
341: addMark(p);
342: if (defined(reload)&&(!reload)) {
343: // don't redisplay
344: renderMarks();
345: return;
346: }
347: display();
1.1 casties 348: }
349:
350: // starting event capture
1.2 casties 351: registerEvent("mousedown", elemScaler, markEvent);
1.1 casties 352: }
353:
354:
355: function removeMark(reload) {
356: // remove the last mark
357: deleteMark();
358: if (defined(reload)&&(!reload)) {
1.6 casties 359: // don't redisplay
360: renderMarks();
361: return;
1.1 casties 362: }
363: display();
364: }
365:
366:
367: function zoomArea() {
368: var click = 1;
369: var pt1, pt2;
370: var eck1pos, eck2pos, eck3pos, eck4pos;
371: window.focus();
372: var eck1 = getElement("eck1");
373: var eck2 = getElement("eck2");
374: var eck3 = getElement("eck3");
375: var eck4 = getElement("eck4");
376:
377: function zoomClick(evt) {
1.6 casties 378: // mouse click handler
379: if (click == 1) {
380: // first click -- start moving
381: click = 2;
382: pt1 = evtPosition(evt);
383: pt2 = pt1;
384: eck1pos = pt1;
385: eck2pos = new Position(pt1.x - 12, pt1.y);
386: eck3pos = new Position(pt1.x, pt1.y - 12);
387: eck4pos = new Position(pt1.y - 12, pt1.y - 12);
388: moveElement(eck1, eck1pos);
389: moveElement(eck2, eck2pos);
390: moveElement(eck3, eck3pos);
391: moveElement(eck4, eck4pos);
392: showElement(eck1, true);
393: showElement(eck2, true);
394: showElement(eck3, true);
395: showElement(eck4, true);
396: // show moving
397: registerEvent("mousemove", elemScaler, zoomMove);
398: registerEvent("mousemove", eck4, zoomMove);
399: // enable drag-to-zoom
400: registerEvent("mouseup", elemScaler, zoomClick);
401: registerEvent("mouseup", eck4, zoomClick);
402: } else {
403: // second click -- end moving
404: pt2 = evtPosition(evt);
405: showElement(eck1, false);
406: showElement(eck2, false);
407: showElement(eck3, false);
408: showElement(eck4, false);
409: unregisterEvent("mousemove", elemScaler, zoomMove);
410: unregisterEvent("mousemove", eck4, zoomMove);
411: unregisterEvent("mousedown", elemScaler, zoomClick);
412: unregisterEvent("mousedown", eck4, zoomClick);
413: var p1 = dlTrafo.invtransform(pt1);
414: var p2 = dlTrafo.invtransform(pt2);
415: var ww = p2.x-p1.x;
416: var wh = p2.y-p1.y;
417: if ((ww > 0)&&(wh > 0)) {
418: setParameter("wx", cropFloat(p1.x));
419: setParameter("wy", cropFloat(p1.y));
420: setParameter("ww", cropFloat(ww));
421: setParameter("wh", cropFloat(wh));
422: parseArea();
423: // zoomed is always fit
424: setParameter("ws", 1);
425: display();
426: }
427: }
1.1 casties 428: }
429:
430: function zoomMove(evt) {
1.6 casties 431: // mouse move handler
432: pt2 = evtPosition(evt);
433: // restrict marks to move right and down
434: eck1pos = pt1;
435: eck2pos = new Position(Math.max(pt1.x, pt2.x)-12, pt1.y);
436: eck3pos = new Position(pt1.x, Math.max(pt1.y, pt2.y)-12);
437: eck4pos = new Position(Math.max(pt1.x, pt2.x)-12, Math.max(pt1.y, pt2.y)-12);
438: moveElement(eck1, eck1pos);
439: moveElement(eck2, eck2pos);
440: moveElement(eck3, eck3pos);
441: moveElement(eck4, eck4pos);
1.1 casties 442: }
443:
444: // starting event capture
1.2 casties 445: registerEvent("mousedown", elemScaler, zoomClick);
446: registerEvent("mousedown", eck4, zoomClick);
1.1 casties 447: }
448:
449: function zoomBy(factor) {
450: // zooms by the given factor
451: var newarea = dlArea.copy();
452: newarea.width /= factor;
453: newarea.height /= factor;
454: newarea.x -= 0.5 * (newarea.width - dlArea.width);
455: newarea.y -= 0.5 * (newarea.height - dlArea.height);
456: newarea = dlMaxArea.fit(newarea);
457: setParamFromArea(newarea);
458: display();
459: }
460:
461:
462: function zoomFullpage() {
463: // zooms out to show the whole image
464: setParameter("wx", 0.0);
465: setParameter("wy", 0.0);
466: setParameter("ww", 1.0);
467: setParameter("wh", 1.0);
468: display();
469: }
470:
471:
472: function moveCenter() {
473: // move visible area so that it's centered around the clicked point
474: if ( (dlArea.width == 1.0) && (dlArea.height == 1.0) ) {
1.7 casties 475: // nothing to do
1.6 casties 476: return;
1.1 casties 477: }
478: window.focus();
479:
480: function moveCenterEvent(evt) {
1.6 casties 481: // move to handler
482: unregisterEvent("mousedown", elemScaler, moveCenterEvent);
483: var pt = dlTrafo.invtransform(evtPosition(evt));
484: var newarea = new Rectangle(pt.x-0.5*dlArea.width, pt.y-0.5*dlArea.height, dlArea.width, dlArea.height);
485: newarea = dlMaxArea.fit(newarea);
486: // set parameters
487: setParamFromArea(newarea);
488: parseArea();
489: display();
1.1 casties 490: }
491:
492: // starting event capture
1.2 casties 493: registerEvent("mousedown", elemScaler, moveCenterEvent);
1.1 casties 494: }
495:
1.5 casties 496: function moveBy(movx, movy) {
1.6 casties 497: // move visible area by movx and movy (in units of ww, wh)
1.5 casties 498: if ((dlArea.width == 1.0)&&(dlArea.height == 1.0)) {
1.6 casties 499: // nothing to do
500: return;
1.5 casties 501: }
502: var newarea = dlArea.copy();
503: newarea.x += parseFloat(movx)*dlArea.width;
504: newarea.y += parseFloat(movy)*dlArea.height;
505: newarea = dlMaxArea.fit(newarea);
506: // set parameters
507: setParamFromArea(newarea);
508: parseArea();
509: display();
510: }
511:
1.1 casties 512: function getRef() {
513: // returns a reference to the current digilib set
514: if (! baseUrl) {
1.6 casties 515: var baseUrl = location.protocol + "//" + location.host + location.pathname;
1.1 casties 516: }
517: var hyperlinkRef = baseUrl;
1.9 casties 518: var par = getAllParameters((7+32+64) & dlUrlParamMask); // all without ddpi, pt
1.1 casties 519: if (par.length > 0) {
1.6 casties 520: hyperlinkRef += "?" + par;
1.1 casties 521: }
522: return hyperlinkRef;
523: }
1.3 casties 524:
525: function getRefWin(type, msg) {
526: // shows an alert with a reference to the current digilib set
527: if (! msg) {
1.6 casties 528: msg = "Link for HTML documents";
1.4 casties 529: }
1.3 casties 530: prompt(msg, getRef());
1.5 casties 531: }
1.6 casties 532:
533: function getQuality() {
534: // returns the current q setting
535: for (var i = 0; i < 3; i++) {
536: if (hasFlag("q"+i)) {
537: return i;
538: }
539: }
540: return 1
541: }
542:
543: function setQuality(qual) {
544: // set the image quality
545: for (var i = 0; i < 3; i++) {
546: removeFlag("q"+i);
547: if (i == qual) {
548: addFlag("q"+i);
549: }
550: }
551: setParameter("mo", getAllFlags());
552: display();
553: }
554:
555: function setQualityWin(msg) {
556: // dialog for setting quality
557: if (! msg) {
558: msg = "Quality (0..2)";
559: }
560: var q = getQuality();
561: var newq = window.prompt(msg, q);
562: if (newq) {
563: setQuality(newq);
564: }
565: }
566:
567: function mirror(dir) {
568: // mirror the image horizontally or vertically
569: if (dir == "h") {
570: toggleFlag("hmir");
571: } else {
572: toggleFlag("vmir");
573: }
574: setParameter("mo", getAllFlags());
575: display();
576: }
577:
1.7 casties 578: function gotoPage(gopage, keep) {
579: // goto given page nr (+/-: relative)
580: var oldpn = parseInt(getParameter("pn"));
581: setParameter("pn", gopage, true);
1.6 casties 582: var pn = parseInt(getParameter("pn"));
583: if (pn < 1) {
1.7 casties 584: alert("No such page! (Page number too low)");
585: setParameter("pn", oldpn);
586: return;
587: }
588: if (hasParameter("pt")) {
589: pt = parseInt(getParameter("pt"))
590: if (pn > pt) {
591: alert("No such page! (Page number too high)");
592: setParameter("pn", oldpn);
593: return;
594: }
595: }
596: if (keep) {
1.9 casties 597: display(63+128); // all, no mark
1.7 casties 598: } else {
1.9 casties 599: display(3+32+128); // fn, pn, ws, mo + pt
1.6 casties 600: }
601: }
602:
603: function gotoPageWin() {
604: // dialog to ask for new page nr
1.7 casties 605: var pn = getParameter("pn");
1.6 casties 606: var gopage = window.prompt("Go to page", pn);
607: if (gopage) {
608: gotoPage(gopage);
609: }
610: }
611:
1.7 casties 612: function setParamWin(param, text, relative) {
1.6 casties 613: // dialog to ask for new parameter value
614: var val = getParameter(param);
615: var newval = window.prompt(text, val);
616: if (newval) {
1.7 casties 617: setParameter(param, newval, relative);
1.6 casties 618: display();
619: }
620: }
621:
622: function showOptions(show) {
623: // show or hide option div
624: var elem = getElement("dloptions");
625: showElement(elem, show);
1.8 casties 626: }
627:
628: function toggleOptions() {
629: // toggle option div
630: var elem = getElement("dloptions");
631: showOptions(! isElementVisible(elem));
632: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>