changeset 989:f4757bf6ab65

new arrows plugin for scroll arrows next to the image. also new mechanism for specifying insets.
author robcast
date Fri, 03 Feb 2012 18:12:47 +0100
parents b6261d3d68c2
children 2feb71b40e10
files webapp/src/main/webapp/jquery/jquery.digilib.arrows.js webapp/src/main/webapp/jquery/jquery.digilib.buttons.js webapp/src/main/webapp/jquery/jquery.digilib.css webapp/src/main/webapp/jquery/jquery.digilib.js
diffstat 4 files changed, 204 insertions(+), 156 deletions(-) [+]
line wrap: on
line diff
--- a/webapp/src/main/webapp/jquery/jquery.digilib.arrows.js	Tue Jan 31 00:53:24 2012 +0100
+++ b/webapp/src/main/webapp/jquery/jquery.digilib.arrows.js	Fri Feb 03 18:12:47 2012 +0100
@@ -5,22 +5,14 @@
 (function($) {
 
     // affine geometry
-    var geom;
+    var geom = null;
     // plugin object with digilib data
-    var digilib;
-
-    var FULL_AREA;
+    var digilib = null;
 
-    var buttons = {
-        stub : {
-            onclick : [ "doStub", 1 ],
-            tooltip : "what does this button do?",
-            icon : "stub.png"
-        }
-    };
+    var FULL_AREA = null;
 
     var defaults = {
-        // arrow bar overlays for moving the zoomed area
+        // arrow bars for moving the zoomed area
         'showZoomArrows' : true,
         // zoom arrow bar minimal width (for small images)
         'zoomArrowMinWidth' : 6,
@@ -28,6 +20,43 @@
         'zoomArrowWidth' : 32,
         // by what percentage should the arrows move the zoomed area?
         'zoomArrowMoveFactor' : 0.5,
+        // defaults for digilib buttons
+        'buttonSettings' : {
+            'fullscreen' : {
+                // path to button images (must end with a slash)
+                'imagePath' : 'img/fullscreen/',
+                'buttonSetWidth' : 36,
+                'arrowSet' : [ "up", "down", "left", "right" ],
+            },
+            'embedded' : {
+                'imagePath' : 'img/embedded/16/',
+                'buttonSetWidth' : 18,
+                'arrowSet' : [ "up", "down", "left", "right" ],
+            }
+        }
+    };
+
+    var buttons = {
+        up : {
+            onclick : [ "moveZoomArea", 0, -1 ],
+            tooltip : "move zoom area up",
+            icon : "up.png"
+        },
+        down : {
+            onclick : [ "moveZoomArea", 0, 1 ],
+            tooltip : "move zoom area down",
+            icon : "down.png"
+        },
+        left : {
+            onclick : [ "moveZoomArea", -1, 0 ],
+            tooltip : "move zoom area left",
+            icon : "left.png"
+        },
+        right : {
+            onclick : [ "moveZoomArea", 1, 0 ],
+            tooltip : "move zoom area right",
+            icon : "right.png"
+        }
     };
 
     var actions = {
@@ -59,20 +88,22 @@
         // import geometry classes
         geom = digilib.fn.geometry;
         FULL_AREA = geom.rectangle(0, 0, 1, 1);
-        // add defaults, actions, buttons
-        $.extend(digilib.defaults, defaults);
+        // add defaults, actions
+        $.extend(true, digilib.defaults, defaults); // make deep copy
+        $.extend(digilib.buttons, buttons);
         $.extend(digilib.actions, actions);
-        $.extend(digilib.buttons, buttons);
     };
 
     // plugin initialization
     var init = function(data) {
         console.debug('initialising arrows plugin. data:', data);
         var $data = $(data);
+        // adjust insets
+        data.currentInsets['arrows'] = getInsets(data);
         // install event handler
         $data.bind('setup', handleSetup);
         $data.bind('update', handleUpdate);
-        //$data.bind('redisplay', handleRedisplay);
+        // $data.bind('redisplay', handleRedisplay);
     };
 
     var handleSetup = function(evt) {
@@ -87,14 +118,70 @@
         renderZoomArrows(data);
     };
 
-    var handleRedisplay = function(evt) {
-        console.debug("arrows: handleRedisplay");
-        var data = this;
+
+    /** 
+     * returns insets for arrows (based on canMove and buttonSetWidth
+     */
+    var getInsets = function(data) {
+        var settings = data.settings;
+        var insets = {
+            'x' : 0,
+            'y' : 0
+        };
+        if (settings.showZoomArrows) {
+            var mode = settings.interactionMode;
+            var bw = settings.buttonSettings[mode].buttonSetWidth;
+            if (digilib.fn.canMove(data, 0, -1))
+                insets.y += bw;
+            if (digilib.fn.canMove(data, 0, 1))
+                insets.y += bw;
+            if (digilib.fn.canMove(data, -1, 0))
+                insets.x += bw;
+            if (digilib.fn.canMove(data, 1, 0))
+                insets.x += bw;
+        }
+        return insets;
     };
 
     /**
-     * create arrow overlays for moving the zoomed area.
-     * 
+     * creates HTML structure for a single button
+     */
+    var createButton = function(data, $div, buttonName, show) {
+        var $elem = data.$elem;
+        var settings = data.settings;
+        var mode = settings.interactionMode;
+        var imagePath = settings.buttonSettings[mode].imagePath;
+        // make relative imagePath absolute
+        if (imagePath.charAt(0) !== '/' && imagePath.substring(0, 3) !== 'http') {
+            imagePath = settings.digilibBaseUrl + '/jquery/' + imagePath;
+        }
+        var buttonConfig = settings.buttons[buttonName];
+        // button properties
+        var action = buttonConfig.onclick;
+        var tooltip = buttonConfig.tooltip;
+        var icon = imagePath + buttonConfig.icon;
+        // construct the button html
+        var $button = $('<div class="keep"><a href=""><img class="button" src="' + icon + '"/></a></div>');
+        if (!show) {
+            $button.hide();
+        }
+        $div.append($button);
+        // add attributes and bindings
+        $button.attr('title', tooltip);
+        $button.addClass('arrow-' + buttonName);
+        // create handler for the buttons on the div (necessary for horizontal
+        // scroll arrows)
+        $div.on('click.digilib', function(evt) {
+            // the handler function calls digilib with action and parameters
+            console.debug('click action=', action, ' evt=', evt);
+            $elem.digilib.apply($elem, action);
+            return false;
+        });
+        return $button;
+    };
+
+    /**
+     * create arrows for moving the zoomed area.
      */
     var setupZoomArrows = function(data) {
         var $elem = data.$elem;
@@ -105,83 +192,66 @@
             return;
         var mode = settings.interactionMode;
         var arrowNames = settings.buttonSettings[mode].arrowSet;
-        if (arrowNames == null)
+        if (arrowNames == null) {
+            console.error("No buttons for scroll arrows!");
+            settings.showZoomArrows = false;
             return;
-        // arrow divs are marked with class "keep"
-        var $arrowsDiv = $('<div class="keep arrows"/>');
-        $elem.append($arrowsDiv);
-        // create all arrow buttons
-        // TODO: do this without buttons plugin?
-        $.each(arrowNames, function(i, arrowName) {
-            digilib.fn.createButton(data, $arrowsDiv, arrowName);
-        });
+        }
+        // wrap scaler img in table
+        data.$scaler.wrap('<table class="scalertable"><tbody><tr class="midrow"><td/></tr></tbody></table>');
+        // middle row with img has three elements
+        data.$scaler.parent().before('<td class="arrow left" valign="middle"/>').after('<td class="arrow right" valign="middle"/>');
+        // first and last row has only one
+        var $table = $elem.find('table.scalertable');
+        $table.find('tr.midrow').before('<tr class="firstrow"><td colspan="3" class="arrow up" align="center"/></tr>').after(
+                '<tr class="lasttrow"><td colspan="3" class="arrow down" align="center"/></tr>');
+        // add arrow buttons
+        var ar = {};
+        ar.$up = createButton(data, $table.find('td.up'), 'up', digilib.fn.canMove(data, 0, -1));
+        ar.$down = createButton(data, $table.find('td.down'), 'down', digilib.fn.canMove(data, 0, 1));
+        ar.$left = createButton(data, $table.find('td.left'), 'left', digilib.fn.canMove(data, -1, 0));
+        ar.$right = createButton(data, $table.find('td.right'), 'right', digilib.fn.canMove(data, 1, 0));
+        data.arrows = ar;
+
     };
 
     /**
-     * size and show arrow overlays, called after scaler img is loaded.
+     * show or hide arrows, called after scaler img is loaded.
      * 
      */
     var renderZoomArrows = function(data) {
         var settings = data.settings;
-        var $arrowsDiv = data.$elem.find('div.arrows');
+        var arrows = data.arrows;
         if (digilib.fn.isFullArea(data.zoomArea) || !settings.showZoomArrows) {
-            $arrowsDiv.hide();
+            arrows.$up.hide();
+            arrows.$down.hide();
+            arrows.$left.hide();
+            arrows.$right.hide();
+            data.currentInsets['arrows'] = {'x' : 0, 'y' : 0};
             return;
         }
-        $arrowsDiv.show();
-        var r = geom.rectangle(data.$scaler);
-        // calculate arrow bar width
-        var aw = settings.zoomArrowWidth;
-        var minWidth = settings.zoomArrowMinWidth;
-        // arrow bar width should not exceed 10% of scaler width/height
-        var maxWidth = Math.min(r.width, r.height) / 10;
-        if (aw > maxWidth) {
-            aw = maxWidth;
-            if (aw < minWidth) {
-                aw = minWidth;
-            }
+        if (digilib.fn.canMove(data, 0, -1)) {
+            arrows.$up.show();
+        } else {
+            arrows.$up.hide();
+        }
+        if (digilib.fn.canMove(data, 0, 1)) {
+            arrows.$down.show();
+        } else {
+            arrows.$down.hide();
         }
-        // vertical position of left/right image
-        var arrowData = [ {
-            name : 'up',
-            rect : geom.rectangle(r.x, r.y, r.width, aw),
-            show : digilib.fn.canMove(data, 0, -1)
-        }, {
-            name : 'down',
-            rect : geom.rectangle(r.x, r.y + r.height - aw, r.width, aw),
-            show : digilib.fn.canMove(data, 0, 1)
-        }, {
-            name : 'left',
-            rect : geom.rectangle(r.x, r.y, aw, r.height),
-            show : digilib.fn.canMove(data, -1, 0)
-        }, {
-            name : 'right',
-            rect : geom.rectangle(r.x + r.width - aw, r.y, aw, r.height),
-            show : digilib.fn.canMove(data, 1, 0)
-        } ];
-        // render a single zoom Arrow
-        var render = function(i, item) {
-            var $arrow = $arrowsDiv.find('div.button-' + item.name);
-            if (item.show) {
-                $arrow.show();
-            } else {
-                $arrow.hide();
-                return;
-            }
-            var r = item.rect;
-            r.adjustDiv($arrow);
-            var $a = $arrow.contents('a');
-            var $img = $a.contents('img');
-            $img.width(aw).height(aw);
-            // hack for missing vertical-align
-            if (item.name.match(/left|right/)) {
-                var top = (r.height - $a.height()) / 2;
-                $a.css({
-                    'top' : top
-                }); // position : 'relative'
-            }
-        };
-        $.each(arrowData, render);
+        if (digilib.fn.canMove(data, -1, 0)) {
+            arrows.$left.show();
+        } else {
+            arrows.$left.hide();
+        }
+        if (digilib.fn.canMove(data, 1, 0)) {
+            arrows.$right.show();
+        } else {
+            arrows.$right.hide();
+        }
+        // adjust insets
+        data.currentInsets['arrows'] = getInsets(data);
     };
 
     // plugin object with name and init
--- a/webapp/src/main/webapp/jquery/jquery.digilib.buttons.js	Tue Jan 31 00:53:24 2012 +0100
+++ b/webapp/src/main/webapp/jquery/jquery.digilib.buttons.js	Fri Feb 03 18:12:47 2012 +0100
@@ -145,26 +145,6 @@
                 tooltip : "less options",
                 icon : "options.png"
                 },
-            up : {
-                onclick : ["moveZoomArea", 0, -1],
-                tooltip : "move zoom area up",
-                icon : "up.png"
-                },
-            down : {
-                onclick : ["moveZoomArea", 0, 1],
-                tooltip : "move zoom area down",
-                icon : "down.png"
-                },
-            left : {
-                onclick : ["moveZoomArea", -1, 0],
-                tooltip : "move zoom area left",
-                icon : "left.png"
-                },
-            right : {
-                onclick : ["moveZoomArea", 1, 0],
-                tooltip : "move zoom area right",
-                icon : "right.png"
-                },
             SEP : {
                 icon : "sep.png"
                 }
@@ -195,7 +175,6 @@
                 'buttonSetWidth' : 36,
                 'standardSet' : ["reference","zoomin","zoomout","zoomarea","zoomfull","pagewidth","back","fwd","page","help","reset","toggleoptions"],
                 'specialSet' : ["mark","delmark","hmir","vmir","rot","brgt","cont","rgb","quality","size","calibrationx","scale","lessoptions"],
-                'arrowSet' : ["up", "down", "left", "right"],
                 'buttonSets' : ['standardSet', 'specialSet']
                 },
             'embedded' : {
@@ -203,7 +182,6 @@
                 'buttonSetWidth' : 18,
                 'standardSet' : ["reference","zoomin","zoomout","zoomarea","zoomfull","help","reset","toggleoptions"],
                 'specialSet' : ["mark","delmark","hmir","vmir","rot","brgt","cont","rgb","quality","scale","lessoptions"],
-                'arrowSet' : ["up", "down", "left", "right"],
                 'buttonSets' : ['standardSet', 'specialSet']
                 }
         },
@@ -237,6 +215,8 @@
                         settings.visibleButtonSets++;
                     }
                 }
+                // adjust insets
+                data.currentInsets['buttons'] = getInsets(data);
                 // persist setting
                 fn.storeOptions(data);
             },
@@ -300,9 +280,9 @@
         // import geometry classes
         geom = fn.geometry;
         // add defaults, actions, buttons
-        $.extend(digilib.defaults, defaults);
+        $.extend(digilib.buttons, buttons);
+        $.extend(true, digilib.defaults, defaults); // make deep copy
         $.extend(digilib.actions, actions);
-        $.extend(digilib.buttons, buttons);
         // update buttons reference in defaults
         digilib.defaults.buttons = digilib.buttons;
         // export functions
@@ -313,10 +293,8 @@
     // plugin initialization
     var init = function (data) {
         console.debug('initialising buttons plugin. data:', data);
-        /* create buttons before scaler 
-        for (var i = 0; i < data.settings.visibleButtonSets; ++i) {
-            showButtons(data, true, i);
-        } */
+        // adjust insets
+        data.currentInsets['buttons'] = getInsets(data);
         // install event handler
         var $data = $(data);
         $data.bind('setup', handleSetup);
@@ -326,8 +304,9 @@
     var handleSetup = function (evt) {
         console.debug("buttons: handleSetup");
         var data = this;
+        var settings = data.settings;
         // create buttons before scaler 
-        for (var i = 0; i < data.settings.visibleButtonSets; ++i) {
+        for (var i = 0; i < settings.visibleButtonSets; ++i) {
             showButtons(data, true, i);
         }
         // create ScaleMode selector;
@@ -336,6 +315,16 @@
         setupCalibrationDiv(data);
     };
 
+    /** 
+     * returns insets for buttons (based on visibleButtonSets and buttonSetWidth
+     */
+    var getInsets = function (data) {
+        var settings = data.settings;
+        var bw = settings.visibleButtonSets * settings.buttonSettings[settings.interactionMode].buttonSetWidth;
+        var insets = {'x' : bw, 'y' : 0};
+        return insets;
+    };
+    
     var centerOnScreen = function (data, $div) {
         var r = geom.rectangle($div);
         var s = fn.getFullscreenRect(data);
@@ -602,7 +591,7 @@
         var icon = imagePath + buttonConfig.icon;
         // construct the button html
         var $button = $('<div class="button"></div>');
-        var $a = $('<a/>');
+        var $a = $('<a href=""/>');
         var $img = $('<img class="button"/>');
         $div.append($button);
         $button.append($a);
--- a/webapp/src/main/webapp/jquery/jquery.digilib.css	Tue Jan 31 00:53:24 2012 +0100
+++ b/webapp/src/main/webapp/jquery/jquery.digilib.css	Fri Feb 03 18:12:47 2012 +0100
@@ -196,24 +196,22 @@
     margin-bottom: 20px;
 }
 
-div.digilib div.arrows {
-    display: none;
+/* scroll arrows */
+div.digilib table.scalertable {
+	border: 0;
+	padding: 0;
 }
-
-div.digilib div.arrows div.button {
-    position: absolute;
-    text-align: center;
+div.digilib table.scalertable td {
+    padding: 0;
+}
+div.digilib table.scalertable td.arrow {
+}
+div.digilib table.scalertable td.arrow:hover {
     background-color: black;
-    opacity: 0.08;
-    z-index: 200;
-    }
-
-div.digilib div.arrows div.button:hover {
-    opacity: 0.5;
+	opacity: 0.3;
 }
-
-div.digilib div.arrows div.button a {
-    position: relative;
+div.digilib table.scalertable img.button {
+    opacity: 1;
 }
 
 /* special definitions for fullscreen */
--- a/webapp/src/main/webapp/jquery/jquery.digilib.js	Tue Jan 31 00:53:24 2012 +0100
+++ b/webapp/src/main/webapp/jquery/jquery.digilib.js	Fri Feb 03 18:12:47 2012 +0100
@@ -38,7 +38,7 @@
 
     var defaults = {
         // version of this script
-        'version' : 'jquery.digilib.js 2.1.2b1',
+        'version' : 'jquery.digilib.js 2.1.2b2',
         // logo url
         'logoUrl' : 'img/digilib-logo-text1.png',
         // homepage url (behind logo)
@@ -88,8 +88,8 @@
         'maxBgSize' : 10000,
         // parameters used by background image
         'previewImgParamNames' : ['fn','pn','dw','dh','mo','rot'],
-        // reserved space in full page display (default value accounts for vertical scrollbar)
-        'scalerInset' : 10
+        // reserved space in full page display (default value accounts for body margins)
+        'scalerInsets' : { 'x' : 16, 'y': 20 }
         };
 
     // list of plugins
@@ -179,6 +179,8 @@
                 	elemSettings = data.settings;
                 }
                 unpackParams(data);
+                // list of current insets (dynamic for buttons etc.)
+                data.currentInsets = {'static' : elemSettings.scalerInsets};
                 // check if browser knows *background-size
                 for (var bs in {'':1, '-moz-':1, '-webkit-':1, '-o-':1}) {
                     if ($elem.css(bs+'background-size')) {
@@ -915,31 +917,20 @@
      * returns maximum size for scaler img in fullscreen mode.
      */
     var getFullscreenImgSize = function (data) {
-        var mode = data.settings.interactionMode;
+        //var mode = data.settings.interactionMode;
         var $win = $(window);
         var winH = $win.height();
         var winW = $win.width();
-        var $body = $('body');
-        // include standard body margins and check plausibility
-        var borderW = $body.outerWidth(true) - $body.width();
-        if (borderW === 0 || borderW > 100) {
-            console.debug("fixing border width for getFullscreenImgSize!");
-            borderW = data.settings.scalerInset;
-        }
-        var borderH = $body.outerHeight(true) - $body.height();
-        if (borderH === 0 || borderH > 100) {
-            console.debug("fixing border height for getFullscreenImgSize!");
-            borderH = 5;
-        }
-        var buttonsW = 0;
-        if (data.buttons != null) {
-            // get button width from settings
-            buttonsW = data.settings.buttonSettings[mode].buttonSetWidth * data.settings.visibleButtonSets;
-        }
-        // account for left/right border, body margins and additional requirements
-        var imgW = winW - borderW - buttonsW;
-        var imgH = winH - borderH;
-        console.debug('screen w/h:', winW, winH, 'window.width', $win.width(), 'border:', borderW, 'buttonsW:', buttonsW, 'img w/h:', imgW, imgH);
+        // add all current insets
+        var insets = { 'x' : 0, 'y' : 0};
+        for (var n in data.currentInsets) {
+            insets.x += data.currentInsets[n].x;
+            insets.y += data.currentInsets[n].y;
+        };
+        // accounting for left/right border, body margins and additional requirements
+        var imgW = winW - insets.x;
+        var imgH = winH - insets.y;
+        console.debug('screen w/h:', winW, winH, 'window.width', $win.width(), 'img w/h:', imgW, imgH);
         return geom.size(imgW, imgH);
     };