changeset 1047:4f17420392a9

factor out calibration/scalemode to new dialogs plugin
author hertzhaft
date Sun, 25 Mar 2012 22:05:23 +0200
parents b67f388df888
children 4aa90cccb3e4
files webapp/src/main/webapp/jquery/digilib.html webapp/src/main/webapp/jquery/jquery.digilib.buttons.js webapp/src/main/webapp/jquery/jquery.digilib.css webapp/src/main/webapp/jquery/jquery.digilib.dialogs.js webapp/src/main/webapp/jquery/jquery.digilib.js webapp/src/main/webapp/jquery/jquery.digilib.sliders.js webapp/src/main/webapp/jquery/jquery.range.js
diffstat 7 files changed, 257 insertions(+), 169 deletions(-) [+]
line wrap: on
line diff
--- a/webapp/src/main/webapp/jquery/digilib.html	Sat Mar 24 23:01:46 2012 +0100
+++ b/webapp/src/main/webapp/jquery/digilib.html	Sun Mar 25 22:05:23 2012 +0200
@@ -19,6 +19,7 @@
         <script type="text/javascript" src="jquery.range.js"></script>
         <link rel="stylesheet" type="text/css" href="jquery.range.css" />
         <script type="text/javascript" src="jquery.digilib.buttons.js"></script>
+        <script type="text/javascript" src="jquery.digilib.dialogs.js"></script>
         <script type="text/javascript" src="jquery.digilib.sliders.js"></script>
         <script type="text/javascript" src="jquery.digilib.birdseye.js"></script>
         <script type="text/javascript" src="jquery.digilib.marks.js"></script>
--- a/webapp/src/main/webapp/jquery/jquery.digilib.buttons.js	Sat Mar 24 23:01:46 2012 +0100
+++ b/webapp/src/main/webapp/jquery/jquery.digilib.buttons.js	Sun Mar 25 22:05:23 2012 +0200
@@ -108,12 +108,14 @@
             icon : "size.png"
             },
         calibrationx : {
-            onclick : "showCalibrationDiv",
+            // onclick : "showCalibrationDiv",
+            onclick : "calibrate",
             tooltip : "calibrate screen resolution",
             icon : "calibration-x.png"
             },
         scale : {
-            onclick : "showScaleModeSelector",
+            // onclick : "showScaleModeSelector",
+            onclick : "setScaleMode",
             tooltip : "change image scale",
             icon : "original-size.png"
             },
@@ -207,43 +209,6 @@
                 data.currentInsets['buttons'] = getInsets(data);
                 // persist setting
                 fn.storeOptions(data);
-            },
-
-            // shows Calibration Div
-            showCalibrationDiv : function (data) {
-                var $elem = data.$elem;
-                var cssPrefix = data.settings.cssPrefix;
-                var $calDiv = $elem.find('.'+cssPrefix+'calibration');
-                var $input = $elem.find('.'+cssPrefix+'calibration-input');
-                $calDiv.fadeIn();
-                $input.focus();
-            },
-
-            // shows ScaleModeSelector
-            showScaleModeSelector : function (data) {
-                var $elem = data.$elem;
-                var cssPrefix = data.settings.cssPrefix;
-                var $div = $elem.find('div#'+cssPrefix+'scalemode');
-                if ($div.is(':visible')) {
-                    $div.fadeOut();
-                    return;
-                    }
-                // select current mode
-                var mode = data.scaleMode;
-                $div.find('option').each(function () {
-                	$(this).prop('selected', $(this).attr('name') == mode);
-                });
-                var $button = $elem.find('div.'+cssPrefix+'button-scale');
-                var buttonRect = geom.rectangle($button);
-                $('body').on("click.scalemode", function(event) {
-                        $div.fadeOut();
-                        });
-                $div.fadeIn();
-                var divRect = geom.rectangle($div);
-                $div.offset({
-                    left : Math.abs(buttonRect.x - divRect.width - 4),
-                    top : buttonRect.y + 4
-                    });
             }
     };
 
@@ -284,10 +249,6 @@
         for (var i = 0; i < settings.visibleButtonSets; ++i) {
             showButtons(data, true, i);
         }
-        // create ScaleMode selector;
-        setupScaleModeDiv(data);
-        // create Calibration div;
-        setupCalibrationDiv(data);
     };
 
     /** 
@@ -300,107 +261,6 @@
         return insets;
     };
 
-    /** creates HTML structure for the calibration div
-     */
-    var setupCalibrationDiv = function (data) {
-        var $elem = data.$elem;
-        var settings = data.settings;
-        var cssPrefix = settings.cssPrefix;
-        var html = '\
-            <div id="'+cssPrefix+'calibration" class="'+cssPrefix+'calibration">\
-                <div class="'+cssPrefix+'ruler">\
-                    <div class="'+cssPrefix+'cm">Please enter the length of this scale on your screen</div>\
-                    <div>\
-                        <input id="'+cssPrefix+'calibration-input" size="5"/> cm\
-                        <button class="'+cssPrefix+'button" id="'+cssPrefix+'calibrationOk">OK</button>\
-                        <button class="'+cssPrefix+'button" id="'+cssPrefix+'calibrationCancel">Cancel</button>\
-                    </div>\
-                    <div class="'+cssPrefix+'calibration-error">Please enter a numeric value like this: 12.3</div>\
-                </div>\
-            </div>';
-        var $calDiv = $(html);
-        $elem.append($calDiv);
-        var $input = $calDiv.find('input');
-        var $ok = $calDiv.find('#'+cssPrefix+'calibrationOk');
-        var $cancel = $calDiv.find("#calibrationCancel");
-        data.calibrationDiv = $calDiv;
-        data.calibrationErrorDiv = $calDiv.find('div.'+cssPrefix+'calibration-error');
-        data.calibrationInput = $input;
-        fn.centerOnScreen(data, $calDiv);
-        var handler = function(event) {
-            var _data = data;
-            if (event.keyCode == 27 || event.target.id == cssPrefix+'calibrationCancel') {
-                $calDiv.fadeOut();
-                return false;
-                }
-            if (event.keyCode == 13 || event.target.id == cssPrefix+'calibrationOk') {
-                changeCalibration(_data);
-                return false;
-                }
-            _data.calibrationInput.removeClass(cssPrefix+'error');
-            };
-        $ok.on("click", handler);
-        $cancel.on("click", handler);
-        $input.on("keypress", handler);
-    };
-
-    /** creates HTML structure for the scale mode menu
-     */
-    var setupScaleModeDiv = function (data) {
-        var $elem = data.$elem;
-        var settings = data.settings;
-        var cssPrefix = settings.cssPrefix;
-        var currentMode = digilib.fn.getScaleMode(data);
-        var $scaleModeDiv = $('<div id="'+cssPrefix+'scalemode" style="display:none; z-index:9999; position:absolute"/>');
-        data.scaleModeDiv = $scaleModeDiv;
-        var $scaleModeSelect = $('<select class="'+cssPrefix+'scalemode" />');
-        $elem.append($scaleModeDiv);
-        $scaleModeDiv.append($scaleModeSelect);
-        for (var i = 0; i < modes.length; i++) {
-            var mode = modes[i];
-            var selected = (mode.name == currentMode) ? ' selected="selected"' : '';
-            $scaleModeSelect.append($('<option name="'
-                    + mode.name + '"' + selected + '>' 
-                    + mode.label + '</option>'));
-        }
-        $scaleModeDiv.on("click.scalemode", function(event) {
-            return false;
-            });
-        $scaleModeSelect.on('change.scalemode', function(event) {
-            var d = data;
-            changeMode(event, d);
-            });
-    };
-
-    /** event handler
-     */
-    var changeMode = function (event, data) {
-        var $select = $(event.target);
-        var newMode = $select.find("option:selected").attr("name");
-        console.debug('setting mode to:', newMode);
-        var $div = data.scaleModeDiv;
-        $('body').off("click.scalemode");
-        $div.fadeOut();
-        digilib.actions.setScaleMode(data, newMode);
-    };
-
-    /** event handler
-     */
-    var changeCalibration = function (data) {
-        var $calDiv = data.calibrationDiv;
-        var $input = data.calibrationInput;
-        var cm = $input.val();
-        var w = $calDiv.width();
-  		var dpi = fn.cropFloat(w / parseFloat(cm) * 2.54);
-  		console.debug('width', w, 'cm', cm, 'input dpi:', dpi);
-  		if(!fn.isNumber(dpi)) {
-  		    $input.addClass(data.settings.cssPrefix+'error');
-  		    return;
-  		    }
-  		digilib.actions.calibrate(data, dpi);
-        $calDiv.fadeOut();
-    };
-
     /**
      *  creates HTML structure for a single button
      */
@@ -432,6 +292,7 @@
         $a.append($img);
         // add attributes and bindings
         $button.attr('title', tooltip);
+        $button.attr('id', cssPrefix+'button-'+buttonName);
         $button.addClass(cssPrefix+'button-'+buttonName);
         $img.attr('src', icon);
         // create handler for the buttons
@@ -453,6 +314,7 @@
                 };
             }
         })());
+        return $button;
     };
 
     // creates HTML structure for buttons in elem
@@ -472,7 +334,8 @@
         var buttonNames = buttonSettings[buttonGroup];
         for (var i = 0; i < buttonNames.length; i++) {
             var buttonName = buttonNames[i];
-            createButton(data, $buttonsDiv, buttonName);
+            var $button = createButton(data, $buttonsDiv, buttonName);
+            settings.buttons[buttonName].button = $button;
         }
         // make buttons div scroll if too large for window
         if ($buttonsDiv.height() > $(window).height() - 10) {
--- a/webapp/src/main/webapp/jquery/jquery.digilib.css	Sat Mar 24 23:01:46 2012 +0100
+++ b/webapp/src/main/webapp/jquery/jquery.digilib.css	Sun Mar 25 22:05:23 2012 +0200
@@ -3,6 +3,14 @@
  *
  * Martin Raspe, Robert Casties, 11.1.2011
  */
+
+div.dl-digilib,
+div.dl-digilib button,
+div.dl-digilib input {
+   font-family: Verdana, Arial, Helvetica, sans-serif;
+   font-size: 12px;
+}
+
 div.dl-digilib div.dl-scaler {
 	background-color: grey;
 	z-index: 0;
@@ -116,7 +124,7 @@
 	font-weight: bold;
 }
 
-div.dl-digilib div.dl-calibration {
+div.dl-digilib #dl-calibration {
 	background: url('img/blue.png');
 	position: absolute;
 	border: 1px solid lightcyan;
@@ -125,7 +133,7 @@
 	z-index: 9999;
 	}
 
-div.dl-digilib div.dl-ruler {
+div.dl-digilib #dl-ruler {
 	width: 100%;
 	height: 100%;
 	padding-bottom: 10px;
@@ -137,23 +145,23 @@
 	background: url('img/ruler-top.gif') 0px -1px repeat-x;
 	}
 
-div.dl-digilib div.dl-cm {
+div.dl-digilib #dl-cm {
 	padding: 5px;
 	}
 
-div.dl-digilib div.dl-calibration-error {
+div.dl-digilib #dl-calibrationError {
 	color: red;
 	padding: 10px;
 	display: none;
 	}
 
-div.dl-digilib input.dl-calibration-input {
+div.dl-digilib #dl-calibrationInput {
 	margin: 0px 10px;
 	}
 
-div.dl-digilib input.dl-error {
+div.dl-digilib .dl-error {
 	color: red;
-	background-color: khaki;
+	background-color: darkred;
 	}
 
 div.dl-digilib button.dl-button {
@@ -165,6 +173,14 @@
 	background: transparent;
 	}
 
+div.dl-digilib div.dl-tinyslider {
+    display: none;
+	border: 1px solid lightcyan;
+	background-color: lightgrey;
+	width: 300px;
+	padding:10px;	
+    }
+
 div.dl-digilib div.dl-slider {
 	border: 1px solid lightcyan;
 	margin: 30px;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/webapp/src/main/webapp/jquery/jquery.digilib.dialogs.js	Sun Mar 25 22:05:23 2012 +0200
@@ -0,0 +1,199 @@
+/**
+digilib dialogs plugin
+ */
+
+(function($) {
+
+    // plugin object with digilib data
+    var digilib = null;
+    // the functions made available by digilib
+    var fn = null;
+    // affine geometry plugin
+    var geom = null;
+
+    var modes = [
+        {   name : "screen", 
+            label : "fit to screen",
+            tooltip : "scales the graphic file so that it fills the screen"
+        },
+        {   name : "pixel",
+            label : "pixel by pixel",
+            tooltip : "all pixels of the current part of the graphic file are shown"
+        },
+        {   name : "size",
+            label : "original size",
+            tooltip : "tries to display the current part of the graphic file in the size of the orginal resource (after screen calibration)" 
+        }
+    ];
+
+    var defaults = {
+    };
+
+    var actions = {
+        // shows Calibration Div
+        dialogCalibration : function (data) {
+            fn.showCalibrationDialog(data);
+        },
+
+        // shows ScaleModeSelector
+        dialogScaleMode : function (data) {
+            fn.showScaleModeDialog(data);
+        }
+    };
+
+    /** creates and displays HTML structure for screen calibration
+     */
+    var showCalibrationDialog = function (data) {
+        var $elem = data.$elem;
+        var settings = data.settings;
+        var cssPrefix = settings.cssPrefix;
+        var $calDiv = $elem.find('#'+cssPrefix+'calibration');
+        if ($calDiv.length > 0) return; // already onscreen
+        var html = '\
+            <div id="'+cssPrefix+'calibration" class="'+cssPrefix+'calibration">\
+                <div id="'+cssPrefix+'ruler">\
+                    <div id="'+cssPrefix+'cm">Please enter the length of this scale on your screen</div>\
+                    <div>\
+                        <input id="'+cssPrefix+'calibrationInput" size="5"/> cm\
+                        <button class="'+cssPrefix+'button" id="'+cssPrefix+'calibrationOk">OK</button>\
+                        <button class="'+cssPrefix+'button" id="'+cssPrefix+'calibrationCancel">Cancel</button>\
+                    </div>\
+                    <div id="'+cssPrefix+'calibrationError" class="'+cssPrefix+'calibration-error">Please enter a numeric value like this: 12.3</div>\
+                </div>\
+            </div>';
+        $calDiv = $(html);
+        $calDiv.appendTo($elem);
+        var $input = $calDiv.find('#'+cssPrefix+'calibrationInput');
+        var $ok = $calDiv.find('#'+cssPrefix+'calibrationOk');
+        var $cancel = $calDiv.find('#'+cssPrefix+'calibrationCancel');
+        var $error = $calDiv.find('#'+cssPrefix+'calibrationError');
+        var handler = function(event) {
+            // var _data = data;
+            console.log("HANDLER calibration");
+            if (event.keyCode == 27 || event.target.id == cssPrefix+'calibrationCancel') {
+                fn.withdraw($calDiv);
+                return false;
+                }
+            if (event.keyCode == 13 || event.target.id == cssPrefix+'calibrationOk') {
+                var w = $calDiv.width();
+                var cm = $input.val();
+                var dpi = fn.cropFloat(w / parseFloat(cm) * 2.54);
+                console.debug('width', w, 'cm', cm, 'input dpi:', dpi);
+                if (!fn.isNumber(dpi)) {
+                    $input.addClass(cssPrefix+'error');
+                    $error.fadeIn();
+                    return;
+                    }
+                digilib.actions.calibrate(data, dpi);
+                fn.withdraw($calDiv);
+                return false;
+                }
+            $error.fadeOut();
+            $input.removeClass(cssPrefix+'error');
+            };
+        $ok.on("click.dialog", handler);
+        $cancel.on("click.dialog", handler);
+        $input.on("keypress.dialog", handler);
+        $input.on("focus.dialog", handler);
+        $calDiv.fadeIn();
+        fn.centerOnScreen(data, $calDiv);
+        $input.focus();
+        return $calDiv;
+    };
+
+    /** creates and displays HTML structure for scale mode selection
+     */
+    var showScaleModeDialog = function (data) {
+        var $elem = data.$elem;
+        var settings = data.settings;
+        var cssPrefix = settings.cssPrefix;
+        var $scaleDiv = $elem.find('#'+cssPrefix+'scalemode');
+        if ($scaleDiv.length > 0) return; // already onscreen
+        var html = '\
+            <div id="'+cssPrefix+'scalemode" style="display:none; z-index:1000; position:absolute">\
+                <select class="'+cssPrefix+'scalemode" />\
+            </div>';
+        $scaleDiv = $(html);
+        $scaleDiv.appendTo($elem);
+        var mode = fn.getScaleMode(data);
+        var $select = $scaleDiv.find('select');
+        for (var i = 0; i < modes.length; i++) {
+            var m = modes[i];
+            var selected = (m.name == mode) ? ' selected="selected"' : '';
+            html = '<option name="'+m.name+'"'+selected+'>'+m.label+'</option>';
+            $select.append($(html));
+        }
+        $select.on('change.scalemode', function(event) {
+            var newMode = $select.find("option:selected").attr("name");
+            console.debug('setting mode to:', newMode);
+            digilib.actions.setScaleMode(data, newMode);
+            fn.withdraw($scaleDiv);
+            });
+        $select.on('blur.scalemode', function(event) {
+            fn.withdraw($scaleDiv);
+            });
+        // position the element next to the scale button
+        var $button = $elem.find('#'+cssPrefix+'button-scale');
+        // var $button = digilib.buttons['scale'].button;
+        var buttonRect = geom.rectangle($button);
+        $scaleDiv.fadeIn();
+        $select.focus();
+        var divRect = geom.rectangle($scaleDiv);
+        $scaleDiv.offset({
+            left : Math.abs(buttonRect.x - divRect.width - 4),
+            top : buttonRect.y + 4
+        });
+    };
+
+    // plugin installation called by digilib on plugin object.
+    var install = function (plugin) {
+        digilib = plugin;
+        console.debug('installing dialogs plugin. digilib:', digilib);
+        fn = digilib.fn;
+        // import geometry classes
+        geom = fn.geometry;
+        // add defaults, actions, buttons
+        $.extend(true, digilib.defaults, defaults); // make deep copy
+        $.extend(digilib.actions, actions);
+        fn.setButtonAction('calibrationx', 'dialogCalibration');
+        fn.setButtonAction('scale', 'dialogScaleMode');
+        // export functions
+        fn.showCalibrationDialog = showCalibrationDialog;
+        fn.showScaleModeDialog = showScaleModeDialog;
+    };
+
+    // plugin initialization
+    var init = function (data) {
+        console.debug('initialising dialogs plugin. data:', data);
+        var $data = $(data);
+        $data.bind('setup', handleSetup);
+        // create ScaleMode selector;
+        // setupScaleModeDiv(data);
+        // create Calibration div;
+        // setupCalibrationDiv(data);
+    };
+
+    var handleSetup = function (evt) {
+        console.debug("dialogs: handleSetup");
+        var data = this;
+        var settings = data.settings;
+    };
+
+    // plugin object with name and init
+    // shared objects filled by digilib on registration
+    var plugin = {
+            name : 'dialogs',
+            install : install,
+            init : init,
+            buttons : {},
+            actions : {},
+            fn : {},
+            plugins : {}
+    };
+
+    if ($.fn.digilib == null) {
+        $.error("jquery.digilib.dialogs must be loaded after jquery.digilib!");
+    } else {
+        $.fn.digilib('plugin', plugin);
+    }
+})(jQuery);
--- a/webapp/src/main/webapp/jquery/jquery.digilib.js	Sat Mar 24 23:01:46 2012 +0100
+++ b/webapp/src/main/webapp/jquery/jquery.digilib.js	Sun Mar 25 22:05:23 2012 +0200
@@ -1603,12 +1603,13 @@
     };
 
     /** return string from number with reduced precision.
-     * 
      */
     var cropFloatStr = function (x) {
         return cropFloat(x).toString();
     };
 
+    /** center an item on the visible screen rect
+    */
     var centerOnScreen = function (data, $div) {
         var r = geom.rectangle($div);
         var s = fn.getFullscreenRect(data);
@@ -1616,6 +1617,15 @@
         r.adjustDiv($div);
     };
 
+    /** fade out and remove an item
+    */
+    var withdraw = function ($item) {
+        $item.fadeOut(function () {
+            $item.remove();
+        });
+    };
+
+
     // fallback for console.log calls
     if (customConsole) {
         var logFunction = function(type) {
@@ -1667,7 +1677,8 @@
             getBorderWidth : getBorderWidth,
             cropFloat : cropFloat,
             cropFloatStr : cropFloatStr,
-            centerOnScreen : centerOnScreen
+            centerOnScreen : centerOnScreen,
+            withdraw : withdraw
     };
 
     // hook digilib plugin into jquery
--- a/webapp/src/main/webapp/jquery/jquery.digilib.sliders.js	Sat Mar 24 23:01:46 2012 +0100
+++ b/webapp/src/main/webapp/jquery/jquery.digilib.sliders.js	Sun Mar 25 22:05:23 2012 +0200
@@ -266,9 +266,7 @@
         var settings = $this.data('settings');
         var $handle = settings.$handle;
         $handle.off('mousedown.slider');
-        $this.fadeOut(function(){
-            $this.remove()
-            });
+        fn.withdraw($this);
     };
 
     // assign button actions to sliders (rotate, brightness, contrast) 
@@ -399,9 +397,7 @@
                     callback(data);
                     }
                 }
-            $panel.fadeOut(function() {
-                $panel.remove();
-                });
+            fn.withdraw($panel);
             return false;
             };
         $div.children().on('click', handler);
@@ -417,17 +413,18 @@
         var cssPrefix = data.settings.cssPrefix;
         var cssClass = cssPrefix + 'tinyslider';
         var sliderHtml = '\
-            <div class="'+cssClass+'" style="width:300px; background-color:white; padding:10px;" title="'+opts.tooltip+'">\
+        <div class="'+cssClass+'" title="'+opts.tooltip+'">\
                 <form class="'+cssClass+'">\
                     <span>'+opts.label+'</span>\
                     <input type="range" class="'+cssClass+'range" name="'+paramname+'" step="'+opts.step+'" min="'+opts.min+'" max="'+opts.max+'" value="'+param+'"/>\
-                    <input type="text" class="'+cssClass+'text" name="'+paramname+'" size="3" value="'+param+'"/>\
+                    <input type="text" class="'+cssClass+'text" name="'+paramname+'" size="4" value="'+param+'"/>\
                     <br/>\
                     <input class="'+cssClass+'cancel" type="button" value="Cancel"/><input type="submit" name="sub" value="Ok"/>\
                 </form>\
             </div>';
         var $slider = $(sliderHtml);
         $elem.append($slider);
+        $slider.fadeIn();
         var $range = $slider.find('input.'+cssClass+'range');
         var $text = $slider.find('input.'+cssClass+'text');
         // fix non-HTML5 slider
@@ -455,14 +452,13 @@
         $slider.find('form').on('submit', function () {
             // console.debug("brgt-form:", this, " sub=", this.sub);
             callback($text.val());
-            $slider.remove();
+            fn.withdraw($slider);
             return false;
         });
         // handle cancel
         $slider.find('.'+cssClass+'cancel').on('click', function () {
-            $slider.remove();
+            fn.withdraw($slider);
         });
-        $slider.fadeIn();
         fn.centerOnScreen(data, $slider);
     };
 
--- a/webapp/src/main/webapp/jquery/jquery.range.js	Sat Mar 24 23:01:46 2012 +0100
+++ b/webapp/src/main/webapp/jquery/jquery.range.js	Sun Mar 25 22:05:23 2012 +0200
@@ -127,15 +127,15 @@
       if(options.range){
       
         prev = options.values.slice(); // clone
-        options.values[0] = pxToValue($handle.position().left);
-        options.values[1] = pxToValue($handle2.position().left);
+        options.values[0] = bound(pxToValue($handle.position().left));
+        options.values[1] = bound(pxToValue($handle2.position().left));
         
         // set value on original element
         $original.val(options.values[0] +','+options.values[1]);
       } else {
       
         prev = options.values;
-        options.values = pxToValue($handle.position().left);
+        options.values = bound(pxToValue($handle.position().left));
         
         // set value on original element
         $original.val(options.values);
@@ -170,7 +170,9 @@
       var valspan = options.max - options.min;
       var v = px * valspan / w + options.min;
       if (options.snap) {
-        var tmp = Math.round(v / options.snap) * options.snap;
+        var tmp = v < 0
+            ? Math.floor(v / options.snap) * options.snap
+            : Math.round(v / options.snap) * options.snap;
         // hack to cut off floating point imprecision
         var result = parseFloat(tmp.toFixed(4));
         return result;