Annotation of zogiLib/js/navigation.js, revision 1.4

1.1       dwinter     1: /*
                      2: Copyright (C) 2003 WTWG, Uni Bern
                      3:  
                      4: This program is free software; you can redistribute it and/or
                      5: modify it under the terms of the GNU General Public License
                      6: as published by the Free Software Foundation; either version 2
                      7: of the License, or (at your option) any later version.
                      8:  
                      9: This program is distributed in the hope that it will be useful,
                     10: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     12: GNU General Public License for more details.
                     13:  
                     14: You should have received a copy of the GNU General Public License
                     15: along with this program; if not, write to the Free Software
                     16: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
                     17:  
                     18: Author: Christian Luginbuehl, 01.05.2003 , Version Alcatraz 0.4
1.3       casties    19: Changed for digiLib in Zope by DW 24.03.2004, ROC 09.04.2004
1.1       dwinter    20: */
                     21: 
                     22: var ZOOMFACTOR = Math.sqrt(2);
                     23: 
1.3       casties    24: var dlParams = new Object();
                     25: var dlMarks = new Array();
                     26: var dlArea = new Rectangle(0.0, 0.0, 1.0, 1.0);
                     27: var dlMaxArea = new Rectangle(0.0, 0.0, 1.0, 1.0);
                     28: var dlFlags = new Object();
                     29: var dlTrafo = new Transform();
                     30: 
                     31: // fixes for silly browsers
                     32: if (! Array.prototype.push) {
                     33:     Array.prototype.push = function(val) {
                     34:    this[this.length] = val;
1.4     ! casties    35:    return this.length;
        !            36:     }
        !            37:     Array.prototype.pop = function() {
        !            38:    var val = this[this.length-1];
        !            39:    this.length -= 1;
        !            40:    return val;
1.3       casties    41:     }
                     42: }
1.1       dwinter    43: 
1.3       casties    44: // auxiliary function to crop senseless precision
                     45: function cropFloat(x) {
                     46:     return parseInt(10000*x)/10000;
                     47: }
1.1       dwinter    48: 
1.3       casties    49: function newParameter(name, defaultValue, detail) {
                     50:     // create a new parameter with a name and a default value
1.4     ! casties    51:     if (dlParams[name]) {
        !            52:    alert("Fatal: An object with name '" + name + "' already exists - cannot recreate!");
        !            53:    return false;
        !            54:     } else {
1.3       casties    55:    dlParams[name] = new Object();
                     56:    dlParams[name].defaultValue = defaultValue;
                     57:    dlParams[name].hasValue = false;
                     58:    dlParams[name].value = defaultValue;
                     59:    dlParams[name].detail = detail;
                     60:    return dlParams[name];
                     61:     }
                     62: }
1.1       dwinter    63: 
1.3       casties    64: function getParameter(name) {
                     65:     // returns the named parameter value or its default value
                     66:     if (dlParams[name]) {
                     67:    if (dlParams[name].hasValue) {
                     68:        return dlParams[name].value;
                     69:    } else {
                     70:        return dlParams[name].defaultValue;
                     71:    }
                     72:     } else {
1.4     ! casties    73:    return undefined;
1.3       casties    74:     }
                     75: }
1.1       dwinter    76: 
1.3       casties    77: function setParameter(name, value) {
                     78:     // sets parameter value
                     79:     if (dlParams[name]) {
                     80:    dlParams[name].value = value;
                     81:    dlParams[name].hasValue = true;
1.4     ! casties    82:    return true;
1.3       casties    83:     }
1.4     ! casties    84:     return false;
1.3       casties    85: }
1.1       dwinter    86: 
1.3       casties    87: function getAllParameters(detail) {
                     88:     // returns a string of all parameters in query format
                     89:     var params = new Array();
                     90:     for ( param in dlParams ) {
                     91:    if ((dlParams[param].detail <= detail)&&(dlParams[param].hasValue)) {
                     92:        var val = getParameter(param);
                     93:        if (val != "") {
                     94:        params.push(param + "=" + val);
                     95:        }
                     96:    }
                     97:     }
                     98:     return params.join("&");
                     99: }
1.1       dwinter   100: 
1.3       casties   101: function parseParameters(query) {
                    102:     // gets parameter values from query format string
                    103:     var params = query.split("&");
                    104:     for (var i = 0; i < params.length; i++) {
                    105:    var keyval = params[i].split("=");
                    106:    if (keyval.length == 2) {
                    107:        setParameter(keyval[0], keyval[1]);
                    108:    }
                    109:     }
                    110: }
1.1       dwinter   111: 
1.3       casties   112: function parseArea() {
                    113:     // returns area Rectangle from current parameters
                    114:     return new Rectangle(getParameter("wx"), getParameter("wy"), getParameter("ww"), getParameter("wh"));
                    115: }
                    116: 
                    117: function setParamFromRect(rect) {
                    118:     // sets digilib wx etc. from rect
                    119:     setParameter("wx", cropFloat(rect.x));
                    120:     setParameter("wy", cropFloat(rect.y));
                    121:     setParameter("ww", cropFloat(rect.width));
                    122:     setParameter("wh", cropFloat(rect.height));
1.4     ! casties   123:     return true;
1.3       casties   124: }
                    125: 
                    126: function parseTrafo() {
                    127:     // returns Transform from current dlArea and picsize
1.4     ! casties   128:     var picsize = getElementSize("pic");
1.3       casties   129:     var trafo = new Transform();
                    130:     // subtract area offset and size
                    131:     trafo.concat(getTranslation(new Position(-dlArea.x, -dlArea.y)));
                    132:     trafo.concat(getScale(new Size(1/dlArea.width, 1/dlArea.height)));
                    133:     // scale to screen size
                    134:     trafo.concat(getScale(picsize));
1.4     ! casties   135:     trafo.concat(getTranslation(picsize));
1.3       casties   136:     // rotate
                    137:     //trafo.concat(getRotation(- getParameter("rot"), new Position(0.5*picsize.width, 0.5*picsize.height)));
                    138:     // mirror
                    139:     //if (hasFlag("hmir")) {
                    140:     //trafo.m00 = - trafo.m00;
                    141:     //}
                    142:     //if (hasFlag("vmir")) {
                    143:     //trafo.m11 = - trafo.m11;
                    144:     //}
                    145:     return trafo;
                    146: }
                    147: 
                    148: function parseMarks() {
                    149:     // returns marks array from current parameters
                    150:     var marks = new Array();
                    151:     var ma = getParameter("mk").split(";");
                    152:     for (var i = 0; i < ma.length ; i++) {
                    153:    var pos = ma[i].split("/");
                    154:    if (pos.length > 1) {
                    155:        marks.push(new Position(pos[0], pos[1]));
                    156:    }
                    157:     }
                    158:     return marks;
                    159: }
1.1       dwinter   160: 
1.3       casties   161: function getAllMarks() {
                    162:     // returns a string with all marks in query format
                    163:     var marks = new Array();
                    164:     for (var i = 0; i < dlMarks.length; i++) {
                    165:    marks.push(cropFloat(dlMarks[i].x) + "/" + cropFloat(dlMarks[i].y));
                    166:     }
                    167:     return marks.join(";");
1.1       dwinter   168: }
                    169: 
1.4     ! casties   170: function addMark(pos) {
1.3       casties   171:     // add a mark
1.4     ! casties   172:     dlMarks.push(pos);
1.3       casties   173:     setParameter("mk", getAllMarks());
1.4     ! casties   174:     return true;
1.3       casties   175: }
1.1       dwinter   176: 
1.3       casties   177: function deleteMark() {
                    178:     // delete the last mark
                    179:     dlMarks.pop();
                    180:     setParameter("mk", getAllMarks());
1.4     ! casties   181:     return true;
1.1       dwinter   182: }
                    183: 
1.3       casties   184: function hasFlag(mode) {
                    185:     // returns if mode flag is set
1.4     ! casties   186:     return (dlFlags[mode]);
1.3       casties   187: }
1.1       dwinter   188: 
1.3       casties   189: function addFlag(mode) {
                    190:     // add a mode flag
                    191:     dlFlags[mode] = mode;
1.4     ! casties   192:     return true;
1.3       casties   193: }
1.1       dwinter   194: 
1.3       casties   195: function removeFlag(mode) {
                    196:     // remove a mode flag
                    197:     if (dlFlags[mode]) {
1.4     ! casties   198:    delete dlFlags[mode];
1.3       casties   199:     }
1.4     ! casties   200:     return true;
1.3       casties   201: }
1.1       dwinter   202: 
1.3       casties   203: function toggleFlag(mode) {
                    204:     // change a mode flag
                    205:     if (dlFlags[mode]) {
1.4     ! casties   206:    delete dlFlags[mode];
1.3       casties   207:     } else {
                    208:    dlFlags[mode] = mode;
                    209:     }
1.4     ! casties   210:     return true;
1.3       casties   211: }
1.1       dwinter   212: 
1.3       casties   213: function getAllFlags() {
                    214:     // returns a string with all flags in query format
                    215:     var fa = new Array();
                    216:     for (var f in dlFlags) {
                    217:    if ((f != "")&&(dlFlags[f] != null)) {
                    218:        fa.push(f);
                    219:    }
                    220:     }
                    221:     return fa.join(",");
                    222: }
1.1       dwinter   223: 
1.3       casties   224: function parseFlags() {
                    225:     // sets dlFlags from the current parameters
                    226:     var flags = new Object();
                    227:     var fa = getParameter("mo").split(",");
                    228:     for (var i = 0; i < fa.length ; i++) {
                    229:    var f = fa[i];
                    230:    if (f != "") {
                    231:        flags[f] = f;
                    232:    }
                    233:     }
                    234:     return flags;
                    235: }    
1.1       dwinter   236: 
1.3       casties   237: /*
                    238:  * Size class
                    239:  */
                    240: function Size(w, h) {
                    241:     this.width = parseFloat(w);
                    242:     this.height = parseFloat(h);
1.4     ! casties   243:     return this;
1.3       casties   244: }
                    245: 
                    246: /*
                    247:  * Position class
                    248:  */
                    249: function Position(x, y) {
                    250:     this.x = parseFloat(x);
                    251:     this.y = parseFloat(y);
1.4     ! casties   252:     return this;
        !           253: }
        !           254: function evtPosition(evt) {
        !           255:     // returns the on-screen Position of the Event 
        !           256:     var x;
        !           257:     var y;
        !           258:     if (document.all) {
        !           259:    x = parseInt(document.body.scrollLeft+event.clientX);
        !           260:    y = parseInt(document.body.scrollLeft+event.clientY);
        !           261:     } else {
        !           262:    x = parseInt(evt.pageX);
        !           263:    y = parseInt(evt.pageY);
        !           264:     }
        !           265:     return new Position(x, y);
1.3       casties   266: }
                    267: 
                    268: /*
                    269:  * Rectangle class
                    270:  */
                    271: function Rectangle(x, y, w, h) {
                    272:     this.x = parseFloat(x);
                    273:     this.y = parseFloat(y);
                    274:     this.width = parseFloat(w);
                    275:     this.height = parseFloat(h);
1.4     ! casties   276:     return this;
1.3       casties   277: }
                    278: Rectangle.prototype.copy = function() {
                    279:     // returns a copy of this Rectangle
                    280:     return new Rectangle(this.x, this.y, this.width, this.height);
                    281: }
                    282: Rectangle.prototype.containsPosition = function(pos) {
                    283:     // returns if the given Position lies in this Rectangle
                    284:     return ((pos.x >= this.x)&&(pos.y >= this.y)&&(pos.x <= this.x+this.width)&&(pos.y <= this.y+this.width));
                    285: }
                    286: Rectangle.prototype.intersect = function(rect) {
                    287:     // returns the intersection of the given Rectangle and this one
                    288:     var sec = rect.copy();
                    289:     if (sec.x < this.x) {
                    290:    sec.width = sec.width - (this.x - sec.x);
                    291:    sec.x = this.x;
                    292:     }
                    293:     if (sec.y < this.y) {
                    294:    sec.height = sec.height - (this.y - sec.y);
                    295:    sec.y = this.y;
                    296:     }
                    297:     if (sec.x + sec.width > this.x + this.width) {
                    298:    sec.width = (this.x + this.width) - sec.x;
                    299:     }
                    300:     if (sec.y + sec.height > this.y + this.height) {
                    301:    sec.height = (this.y + this.height) - sec.y;
                    302:     }
                    303:     return sec;
                    304: }
                    305: Rectangle.prototype.fit = function(rect) {
                    306:     // returns a Rectangle that fits into this one (by moving first)
                    307:     var sec = rect.copy();
                    308:     sec.x = Math.max(sec.x, this.x);
                    309:     sec.x = Math.max(sec.x, this.x);
                    310:     if (sec.x + sec.width > this.x + this.width) {
                    311:    sec.x = this.x + this.width - sec.width;
                    312:     }
                    313:     if (sec.y + sec.height > this.y + this.height) {
                    314:    sec.y = this.y + this.height - sec.height;
                    315:     }
                    316:     return sec.intersect(this);
1.1       dwinter   317: }
                    318: 
1.3       casties   319: /*
                    320:  * Transform class
                    321:  */
                    322: function Transform() {
                    323:     this.m00 = 1.0;
                    324:     this.m01 = 0.0;
                    325:     this.m02 = 0.0;
                    326:     this.m10 = 0.0;
                    327:     this.m11 = 1.0;
                    328:     this.m12 = 0.0;
                    329:     this.m20 = 0.0;
                    330:     this.m21 = 0.0;
                    331:     this.m22 = 1.0;
1.4     ! casties   332:     return this;
1.3       casties   333: }
                    334: Transform.prototype.concat = function(traf) {
                    335:     for (var i = 0; i < 3; i++) {
                    336:    for (var j = 0; j < 3; j++) {
                    337:        var c = 0.0;
                    338:        for (var k = 0; k < 3; k++) {
                    339:        c += traf["m"+i+k] * this["m"+k+j];
                    340:        }
                    341:        this["m"+i+j] = c;
                    342:    }
                    343:     }
1.4     ! casties   344:     return this;
1.3       casties   345: }
                    346: Transform.prototype.transform = function(pos) {
                    347:     var x = this.m00 * pos.x + this.m01 * pos.y + this.m02;
                    348:     var y = this.m10 * pos.x + this.m11 * pos.y + this.m12;
                    349:     return new Position(x, y);
                    350: }
                    351: Transform.prototype.invtransform = function(pos) {
                    352:     var det = this.m00 * this.m11 - this.m01 * this.m10;
                    353:     var x = (this.m11 * pos.x - this.m01 * pos.y - this.m11 * this.m02 + this.m01 * this.m12) / det;
                    354:     var y = (- this.m10 * pos.x + this.m00 * pos.y + this.m10 * this.m02 - this.m00 * this.m12) / det;
                    355:     return new Position(x, y);
                    356: }
                    357: function getRotation(angle, pos) {
                    358:     var traf = new Transform();
                    359:     if (angle != 0) {
                    360:    var t = 2.0 * Math.PI * parseFloat(angle) / 360.0;
                    361:    traf.m00 = Math.cos(t);
                    362:    traf.m01 = - Math.sin(t);
                    363:    traf.m10 = Math.sin(t);
                    364:    traf.m11 = Math.cos(t);
                    365:    traf.m02 = pos.x - pos.x * Math.cos(t) + pos.y * Math.sin(t);
                    366:    traf.m12 = pos.y - pos.x * Math.sin(t) - pos.y * Math.cos(t);
                    367:     }
                    368:     return traf;
                    369: }
                    370: function getTranslation(pos) {
                    371:     var traf = new Transform();
                    372:     traf.m02 = pos.x;
                    373:     traf.m12 = pos.y;
                    374:     return traf;
                    375: }
                    376: function getScale(size) {
                    377:     var traf = new Transform();
                    378:     traf.m00 = size.width;
                    379:     traf.m11 = size.height;
                    380:     return traf;
                    381: }
                    382: 
                    383: function getElement(tagid) {
                    384:     // returns the named element object
1.4     ! casties   385:     if (document.getElementById) {
        !           386:    return document.getElementById(tagid);
        !           387:     } else if (document.all) {
        !           388:    alert("document.all!");
1.3       casties   389:    return document.all[tagid];
                    390:     } else {
1.4     ! casties   391:    alert("no document.all!");
1.3       casties   392:    return document[tagid];
                    393:     }
                    394: }    
1.1       dwinter   395: 
1.3       casties   396: function getElementSize(tagid) {
                    397:     // returns a Rectangle with the size and position of the named element
                    398:     var x = 0;
                    399:     var y = 0;
                    400:     var width = 0;
                    401:     var height = 0;
                    402:     var elem = getElement(tagid);
1.4     ! casties   403:     if (elem.left) {
        !           404:    alert("elem.left!");
        !           405:    x = elem.left;
        !           406:    y = elem.top;
        !           407:    width = elem.width;
        !           408:    height = elem.height;
        !           409:     } else {
        !           410:    if (elem.clientLeft) {
        !           411:        // spass mit IE
        !           412:        x = elem.clientLeft;
        !           413:        y = elem.clientTop;
        !           414:    } else {
        !           415:        var e = elem;
        !           416:        while (e) {
        !           417:        x += e.offsetLeft;
        !           418:        y += e.offsetTop;
        !           419:        e = e.offsetParent;
        !           420:        }
        !           421:    }
        !           422:    width = elem.offsetWidth;
        !           423:    height = elem.offsetHeight;
1.3       casties   424:     }
                    425:     return new Rectangle(x, y, width, height);
                    426: }
1.1       dwinter   427: 
1.3       casties   428: function moveElement(tagid, pos) {
                    429:     // moves the named element to the indicated position
                    430:     var elem = getElement(tagid);
                    431:     if (elem.style) {
1.4     ! casties   432:    elem.style.left = pos.x + "px";
        !           433:    elem.style.top = pos.y + "px";
1.3       casties   434:     } else {
                    435:    alert("moveelement: no style property!");
1.4     ! casties   436:    elem.left = pos.x;
        !           437:    elem.top = pos.y;
1.3       casties   438:     }
1.4     ! casties   439:     return true;
1.3       casties   440: }
1.1       dwinter   441: 
1.3       casties   442: function showElement(tagid, show) {
                    443:     // shows or hides the named element
                    444:     var elem = getElement(tagid);
                    445:     if (elem.style) {
                    446:    if (show) {
                    447:        elem.style.visibility = "visible";
                    448:    } else {
                    449:        elem.style.visibility = "hidden";
                    450:    }
                    451:     } else {
                    452:    alert("showelement: no style property!");
                    453:     }
1.4     ! casties   454:     return true;
1.3       casties   455: }
1.1       dwinter   456: 
1.3       casties   457: function registerMouseDown(tagid, handler) {
                    458:     // register a mouse down event handler on the indicated element
                    459:     if ( document.all ) {
                    460:    document.all[tagid].onmousedown = handler;
                    461:     } else if (document.getElementById) {
                    462:    document.getElementById(tagid).addEventListener("mousedown", handler, true);
                    463:     } else {
                    464:    document[tagid].captureEvents(Event.MOUSEDOWN);
                    465:    document[tagid].onmousedown = handler;
                    466:     }
1.4     ! casties   467:     return true;
1.3       casties   468: }
1.1       dwinter   469: 
1.3       casties   470: function unregisterMouseDown(tagid, handler) {
                    471:     // unregister the mouse down event handler
                    472:     if ( document.all ) {
                    473:    document.all[tagid].onmousedown = null;
                    474:     } else if (document.getElementById) {
                    475:    document.getElementById(tagid).removeEventListener("mousedown", handler, true);
                    476:     } else {
                    477:    document[tagid].releaseEvents(Event.MOUSEDOWN);
                    478:     }
1.4     ! casties   479:     return true;
1.1       dwinter   480: }
                    481: 
1.3       casties   482: function registerMouseMove(tagid, handler) {
                    483:     // register a mouse move event handler on the indicated element
                    484:     if ( document.all ) {
                    485:    document.all[tagid].onmousemove = handler;
                    486:     } else if (document.getElementById) {
                    487:    document.getElementById(tagid).addEventListener("mousemove", handler, true);
                    488:     } else {
                    489:    document[tagid].captureEvents(Event.MOUSEMOVE);
                    490:    document[tagid].onmousemove = handler;
                    491:     }
1.4     ! casties   492:     return true;
1.3       casties   493: }
1.1       dwinter   494: 
1.3       casties   495: function unregisterMouseMove(tagid, handler) {
                    496:     // unregister the mouse move event handler
                    497:     if ( document.all ) {
                    498:    document.all[tagid].onmousemove = null;
                    499:     } else if (document.getElementById) {
                    500:    document.getElementById(tagid).removeEventListener("mousemove", handler, true);
                    501:     } else {
                    502:    document[tagid].releaseEvents(Event.MOUSEMOVE);
                    503:     }
1.4     ! casties   504:     return true;
1.3       casties   505: }
1.1       dwinter   506: 
1.3       casties   507: function registerKeyDown(handler) {
                    508:     // register a key down handler
                    509:     if ( document.all ) {
                    510:    this.document.onkeypress = handler
                    511:     } else if ( typeof(document.addEventListener) == "function" ) {
                    512:    this.document.addEventListener('keypress', handler, true);
                    513:     } else {
                    514:    window.captureEvents(Event.KEYDOWN);
                    515:    window.onkeydown = handler;
                    516:     }
1.4     ! casties   517:     return true;
1.3       casties   518: }
1.1       dwinter   519: 
1.3       casties   520: function getWinSize() {
                    521:     // returns a Size with the current window size (from www.quirksmode.org)
                    522:     var wsize = new Size(100, 100);
                    523:     if (self.innerHeight)  {
                    524:    // all except Explorer
                    525:    wsize.width = self.innerWidth;
                    526:    wsize.height = self.innerHeight;
                    527:     } else if (document.documentElement && document.documentElement.clientHeight) {
                    528:    // Explorer 6 Strict Mode
                    529:    wsize.width = document.documentElement.clientWidth;
                    530:    wsize.height = document.documentElement.clientHeight;
                    531:     } else if (document.body) {
                    532:    // other Explorers
                    533:    wsize.width = document.body.clientWidth;
                    534:    wsize.height = document.body.clientHeight;
                    535:     }
                    536:     return wsize;
                    537: }
1.1       dwinter   538: 
1.3       casties   539: function bestPicSize(tagid) {
                    540:     // returns a Size with the best image size for the given tagid
1.4     ! casties   541:     var inset = 0;
        !           542:     var ws = getWinSize();
        !           543:     var es = getElementSize(tagid);
        !           544:     ws.width = ws.width - es.x - inset;
        !           545:     ws.height = ws.height - es.y - inset;
        !           546:     return ws;
1.1       dwinter   547: }
                    548: 
                    549: 
                    550: 
1.3       casties   551: function init() {
                    552:     // give a name to the window containing digilib - this way one can test if there is already a
                    553:     // digilib-window open and replace the contents of it (ex. digicat)
                    554:     top.window.name = "digilib";
                    555:     // put the query parameters (sans "&") in the parameters array
                    556:     parseParameters(location.search.slice(1));
                    557:     // treat special parameters
                    558:     dlMarks = parseMarks();
                    559:     dlArea = parseArea();
                    560:     dlFlags = parseFlags();
1.1       dwinter   561: 
1.3       casties   562:     //registerKeyDown(parseKeypress);
                    563:     
                    564:     placeMarks();
1.1       dwinter   565: 
1.3       casties   566:     focus();
                    567:     return true;
                    568: }
1.1       dwinter   569: 
                    570: 
1.3       casties   571: function display(detail) {
                    572:     // redisplay the page
                    573:     var queryString = getAllParameters(detail);
                    574:     location.href = location.protocol + "//" + location.host + location.pathname + "?" + queryString;
                    575: }
1.1       dwinter   576: 
                    577: 
                    578: 
                    579: function page(page, details) {
                    580: 
                    581:   if ( details == null ) {
                    582:     details = 1;
                    583:   }
                    584:   
                    585:   if ( page.indexOf('-') == 0 ) {
                    586:     if ( dlParams.pn.value > 1 ) {
                    587:       page = Math.max(parseInt(dlParams.pn.value) - parseInt(page.slice(1)), 1);
                    588:       dlParams.pn.value = page;
                    589:       display(details);
                    590:     } else {
                    591:       alert("You are already on the first page!");
                    592:     }
                    593: 
                    594:   } else if ( page.indexOf('+') == 0 ) {
                    595:     page = parseInt(dlParams.pn.value) + parseInt(page.slice(1));
                    596:     dlParams.pn.value = page;
                    597:     display(details);
                    598:   } else if ( page == parseInt(page) ) {
                    599:     dlParams.pn.value = parseInt(page);
                    600:     display(details);
                    601:   }
                    602: 
                    603: }
                    604: 
                    605: 
                    606: 
                    607: function ref(select) {
1.3       casties   608:     // open a dialog with a reference to the current digilib set
                    609:     var hyperlinkRef = baseUrl + "?" + getAllParameters(9);
                    610:     if ( select == 0 ) {
                    611:    prompt("Link for LaTeX-documents", "\\href{" + hyperlinkRef + "}{TEXT}");
                    612:     } else if ( select == 1 ) {
                    613:    prompt("Link for HTML-documents", hyperlinkRef);
                    614:     }
1.1       dwinter   615: }
                    616: 
                    617: 
                    618: function mark() {
1.3       casties   619:     // add a mark where clicked
                    620:     if ( dlMarks.length > 7 ) {
                    621:    alert("Only 8 marks are possible at the moment!");
                    622:    return;
                    623:     }
1.1       dwinter   624: 
1.3       casties   625:     function markEvent(evt) {
                    626:    // event handler adding a new mark 
                    627:    unregisterMouseDown("scaler", markEvent);
1.4     ! casties   628:    var p = dlTrafo.invtransform(evtPosition(evt));
        !           629:    addMark(p);
1.3       casties   630:    placeMarks();
                    631:     }
1.1       dwinter   632: 
1.3       casties   633:     // starting event capture
                    634:     registerMouseDown("scaler", markEvent);
                    635: }
1.1       dwinter   636: 
1.3       casties   637: function unmark() {
                    638:     // remove the last mark
                    639:     deleteMark();
1.1       dwinter   640:     placeMarks();
                    641: }
                    642: 
                    643: function placeMarks() {
1.3       casties   644:     // put the visible marks on the image
                    645:     var mark_count = dlMarks.length;
                    646:     var picelem = getElement("pic");
                    647:     // make shure the image is loaded so we know its size
                    648:     if (picelem && picelem.complete == false) {
                    649:    setTimeout("placeMarks()", 100);
                    650:     } else {
1.4     ! casties   651:    var picsize = getElementSize("pic");
1.3       casties   652:    dlTrafo = parseTrafo();
                    653:    for (var i = 0; i < 8; i++) {
                    654:        if (i < mark_count) {
                    655:        if (dlArea.containsPosition(dlMarks[i])) {
                    656:            var mpos = dlTrafo.transform(dlMarks[i]);
                    657:            // suboptimal to place -5 pixels and not half size of mark-image
1.4     ! casties   658:            mpos.x = mpos.x -5;
        !           659:            mpos.y = mpos.y -5;
1.3       casties   660:            moveElement("dot"+i, mpos);
                    661:            showElement("dot"+i, true);
1.1       dwinter   662:        }
1.3       casties   663:        } else {
                    664:        // hide the other marks
                    665:        showElement("dot"+i, false);
                    666:        }
1.1       dwinter   667:    }
1.3       casties   668:     }
1.1       dwinter   669: }
                    670: 
                    671: 
1.3       casties   672: function zoomPoint(inout) {
                    673:     // zoom image in or out around the clicked point
                    674:     var zoom = ZOOMFACTOR;
                    675:     if (inout < 0) {
                    676:    zoom = 1/ZOOMFACTOR;
                    677:     }
1.4     ! casties   678:     window.focus();
1.1       dwinter   679: 
1.3       casties   680:     function zoomPointEvent(evt) {
                    681:    // take new center and set zoom parameters
1.4     ! casties   682:    var p = dlTrafo.invtransform(evtPosition(evt));
1.3       casties   683:    var neww = Math.min(dlArea.width * (1/zoom), 1.0);
                    684:    var newh = Math.min(dlArea.height * (1/zoom), 1.0);
1.4     ! casties   685:    var newx = p.x - 0.5 * neww;
        !           686:    var newy = p.y - 0.5 * newh;
1.3       casties   687:    var zoomarea = new Rectangle(newx, newy, neww, newh);
                    688:    // check bounds
                    689:    zoomarea = dlMaxArea.fit(zoomarea);
                    690:    // set parameters
                    691:    setParameter("wx", cropFloat(zoomarea.x));
                    692:    setParameter("wy", cropFloat(zoomarea.y));
                    693:    setParameter("ww", cropFloat(zoomarea.width));
                    694:    setParameter("wh", cropFloat(zoomarea.height));
                    695:    parseArea();
                    696:    display(3);
1.1       dwinter   697:     }
1.4     ! casties   698: 
1.3       casties   699:     // starting event capture
                    700:     registerMouseDown("scaler", zoomPointEvent);
1.1       dwinter   701: }
                    702: 
                    703: 
                    704: function zoomArea() {
1.3       casties   705:     var click = 1;
                    706:     var pt1, pt2;
                    707:     var eck1pos, eck2pos, eck3pos, eck4pos;
                    708:     window.focus();
                    709: 
                    710:     function zoomClick(evt) {
                    711:    // mouse click handler
                    712:    if (click == 1) {
                    713:        // first click -- start moving
                    714:        click = 2;
1.4     ! casties   715:        pt1 = evtPosition(evt);
1.3       casties   716:        pt2 = pt1;
1.4     ! casties   717:        eck1pos = pt1;
        !           718:        eck2pos = new Position(pt1.x - 12, pt1.y);
        !           719:        eck3pos = new Position(pt1.x, pt1.y - 12);
        !           720:        eck4pos = new Position(pt1.y - 12, pt1.y - 12);
1.3       casties   721:        moveElement("eck1", eck1pos);
                    722:        moveElement("eck2", eck2pos);
                    723:        moveElement("eck3", eck3pos);
                    724:        moveElement("eck4", eck4pos);
                    725:        showElement("eck1", true);
                    726:        showElement("eck2", true);
                    727:        showElement("eck3", true);
                    728:        showElement("eck4", true);
                    729:        registerMouseMove("scaler", zoomMove);
                    730:        registerMouseMove("eck4", zoomMove);
                    731:    } else {
                    732:        // second click -- end moving
1.4     ! casties   733:        pt2 = evtPosition(evt);
1.3       casties   734:        showElement("eck1", false);
                    735:        showElement("eck2", false);
                    736:        showElement("eck3", false);
                    737:        showElement("eck4", false);
                    738:        unregisterMouseMove("scaler", zoomMove);
                    739:        unregisterMouseMove("eck4", zoomMove);
                    740:        unregisterMouseDown("scaler", zoomClick);
                    741:        unregisterMouseDown("eck4", zoomClick);
1.4     ! casties   742:        var p1 = dlTrafo.invtransform(pt1);
        !           743:        var p2 = dlTrafo.invtransform(pt2);
        !           744:        var ww = p2.x-p1.x;
        !           745:        var wh = p2.y-p1.y;
1.3       casties   746:        if ((ww > 0)&&(wh > 0)) {
1.4     ! casties   747:        setParameter("wx", cropFloat(p1.x));
        !           748:        setParameter("wy", cropFloat(p1.y));
1.3       casties   749:        setParameter("ww", cropFloat(ww));
                    750:        setParameter("wh", cropFloat(wh));
                    751:        parseArea();
                    752:        display(3);
                    753:        }
                    754:    }
1.1       dwinter   755:     }
                    756: 
1.3       casties   757:     function zoomMove(evt) {
                    758:    // mouse move handler
1.4     ! casties   759:    pt2 = evtPosition(evt);
1.3       casties   760:    // restrict marks to move right and down
1.4     ! casties   761:    eck1pos = pt1;
        !           762:    eck2pos = new Position(Math.max(pt1.x, pt2.x)-12, pt1.y);
        !           763:    eck3pos = new Position(pt1.x, Math.max(pt1.y, pt2.y)-12);
        !           764:    eck4pos = new Position(Math.max(pt1.x, pt2.x)-12, Math.max(pt1.y, pt2.y)-12);
1.3       casties   765:    moveElement("eck1", eck1pos);
                    766:    moveElement("eck2", eck2pos);
                    767:    moveElement("eck3", eck3pos);
                    768:    moveElement("eck4", eck4pos);
1.1       dwinter   769:     }
1.4     ! casties   770: 
1.3       casties   771:     // starting event capture
                    772:     registerMouseDown("scaler", zoomClick);
                    773:     registerMouseDown("eck4", zoomClick);
1.1       dwinter   774: }
                    775: 
1.3       casties   776: function zoomFullpage() {
                    777:     // zooms out to show the whole image
                    778:     setParameter("wx", 0.0);
                    779:     setParameter("wy", 0.0);
                    780:     setParameter("ww", 1.0);
                    781:     setParameter("wh", 1.0);
                    782:     parseArea();
                    783:     display(3);
1.1       dwinter   784: }
                    785: 
                    786: 
1.3       casties   787: function moveTo() {
1.1       dwinter   788: 
1.4     ! casties   789:     if ( (dlArea.width == 1.0) && (dlArea.height == 1.0) ) {
1.3       casties   790:    alert("This function is only available when zoomed in!");
                    791:    return;
                    792:     }
1.1       dwinter   793: 
1.3       casties   794:     function moveToEvent(event) {
                    795:    // move to handler
1.4     ! casties   796:    var pt = evtPosition(evt);
        !           797:    var newarea = new Rectangle(pt.x-0.5*dlArea.width, pt.y-0.5*dlArea.height, dlArea.width, dlArea.height);
        !           798:    newarea = dlMaxArea.fit(newarea);
1.3       casties   799:    // stopping event capture
                    800:    unregisterMouseDown("scaler", moveToEvent);
                    801:    // set parameters
                    802:    setParameter("wx", cropFloat(newarea.x));
                    803:    setParameter("wy", cropFloat(newarea.y));
                    804:    setParameter("ww", cropFloat(newarea.width));
                    805:    setParameter("wh", cropFloat(newarea.height));
1.1       dwinter   806:    display(3);
1.3       casties   807:     }
1.4     ! casties   808: 
1.3       casties   809:     // starting event capture
                    810:     registerMouseDown("scaler", moveToEvent);
1.1       dwinter   811: }
                    812: 
1.3       casties   813: function setSize(factor) {
                    814:     // change the size of the image
                    815:     setParameter("ws", cropFloat(factor));
                    816:     display(3);
                    817: }
                    818: 
                    819: function setQuality(qual) {
                    820:     // set the image quality
                    821:     for (var i = 0; i < 3; i++) {
                    822:    removeFlag("q"+i);
                    823:    if (i == qual) {
                    824:        addFlag("q"+i);
1.1       dwinter   825:    }
1.3       casties   826:     }
                    827:     setParameter("mo", getAllFlags());
                    828:     display(3);
                    829: }    
                    830: 
                    831: function mirror(dir) {
                    832:     // mirror the image horizontally or vertically
                    833:     if (dir == "h") {
                    834:    toggleFlag("hmir");
1.1       dwinter   835:     } else {
1.3       casties   836:    toggleFlag("vmir");
1.1       dwinter   837:     }
1.3       casties   838:     setParameter("mo", getAllFlags());
                    839:     display(3);
1.1       dwinter   840: }
                    841: 
                    842: function parseKeypress(evt) {
1.3       casties   843:     // capturing keypresses for next and previous page
                    844:     if ( document.all ) {
1.1       dwinter   845:    if ( event.keyCode == 110 ) {
1.3       casties   846:        page('+1');
1.1       dwinter   847:    }
                    848:    if ( event.keyCode == 98 ) {
1.3       casties   849:        page('-1');
1.1       dwinter   850:    }
1.3       casties   851:    document.cancelBubble = true;
                    852:     } else {
1.1       dwinter   853:    if ( evt.charCode == 110 ) {
1.3       casties   854:        page('+1');
                    855:    } else if ( evt.charCode == 98 ) {
                    856:        page('-1');
                    857:    } else if ( evt.which == 110 ) {
                    858:        page('+1');
1.1       dwinter   859:    } else if ( evt.which == 98 ) {
1.3       casties   860:        // does not work currentlyfor Opera, because it catches the 'b'-key on it's own
                    861:        // have to change the key or find another way - luginbuehl
                    862:        page('-1');
1.1       dwinter   863:    }
1.3       casties   864:     }
1.1       dwinter   865: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>