diff --git a/ui/TODO.otl b/ui/TODO.otl index 8a035b44..a8f58124 100755 --- a/ui/TODO.otl +++ b/ui/TODO.otl @@ -110,32 +110,13 @@ Roadmap [_] 29% Gen 3 current todo [_] 58% High priority - [_] BUG: zooming vertical images in single image view results in size jumping... - | Reason: - | This is due to the proportion ratio changing in one step... + [_] BUG: in single image mode shifting first image up to new ribbon errs... + | error location/reason: + | getImageGid(..) got something odd in the image gid attribute... | - | Solution: - | Make the proportion transition smoothly, at least in two zoom-steps - [X] BUG: jumping more than one image in single image view messes up scale... + | Race condition?? | - | Procedure: - | - load: file:///L:/mnt/hdd13 (photo)/NTFS2/media/img/my/work/- 20131122Y.001/DCIM/preview (RAW)/ - | - go to single image mode - | - press 2 - | - go to end - | - press [ until a long jump between vertical and horizontal pics - | - | Effect: - | - the size of the images will change - | - | Solution: - | moved the proportions mode switch to preFittingImages handler - | - | Side-effect: - | vertical images, in horizontal viewer, and vice-versa jump - | in size a bit when zooming past the threshold... - | the amount of "jump" depends on viewer proportions vs. image - | proportions... + | Can't reproduce this... [X] BUG: appear to be leaking memory on very large sets of images (>8K) | don't remember it before, so it might be due to the new | loadImagesAround(..) @@ -545,6 +526,32 @@ Roadmap [_] side-by side view... [_] Simplify tool-tip structure in dialogs... | might also bee good to unify tool-tips across the app... + [X] BUG: zooming vertical images in single image view results in size jumping... + | Reason: + | This is due to the proportion ratio changing in one step... + | + | Solution: + | Make the proportion transition smoothly, at least in two zoom-steps + [X] BUG: jumping more than one image in single image view messes up scale... + | + | Procedure: + | - load: file:///L:/mnt/hdd13 (photo)/NTFS2/media/img/my/work/- 20131122Y.001/DCIM/preview (RAW)/ + | - go to single image mode + | - press 2 + | - go to end + | - press [ until a long jump between vertical and horizontal pics + | + | Effect: + | - the size of the images will change + | + | Solution: + | moved the proportions mode switch to preFittingImages handler + | + | Side-effect: + | vertical images, in horizontal viewer, and vice-versa jump + | in size a bit when zooming past the threshold... + | the amount of "jump" depends on viewer proportions vs. image + | proportions... [X] BUG: history dialog is focused on a disabled field... | Procedure: | - open a dir diff --git a/ui/data.js b/ui/data.js index 3ef4b9c8..993e1ada 100755 --- a/ui/data.js +++ b/ui/data.js @@ -33,8 +33,18 @@ var CONFIG = { // A threshold after which the image block ratio will be changed form // 1x1 to 'fit-viewer' in single image mode... // - // NOTE: if null this feature will be disabled. - proportions_ratio_threshold: 1.5, + // this can be: + // - null : feature disabled + // - number : discrete threshold + // - array of 2 numbers : two thresholds, in between the + // image proportions will transition + // gradually form square to screen + // + // NOTE: the array format, threshold order is not important. + proportions_ratio_threshold: [ + 1.2, + 2.5 + ], // ribbon scaling limits and defaults... max_screen_images: 12, @@ -72,7 +82,6 @@ var UI_STATE = { 'global-theme': null, 'ribbon-mode-screen-images': null, 'single-image-mode-screen-images': null, - 'single-image-mode-proportions': null, 'ribbon-mode-image-info': 'off', } @@ -1830,10 +1839,6 @@ function loadSettings(){ if(toggleSingleImageMode('?') == 'on'){ var w = UI_STATE['single-image-mode-screen-images'] - if(CONFIG.proportions_ratio_threshold == null){ - var p = UI_STATE['single-image-mode-proportions'] - toggleImageProportions(p) - } } else { var w = UI_STATE['ribbon-mode-screen-images'] toggleImageInfo(UI_STATE['ribbon-mode-image-info'] == 'on' ? 'on' : 'off') @@ -2100,15 +2105,26 @@ function setupData(viewer){ }) .on('preFittingImages', function(evt, n){ - // update proportions... - if(CONFIG.proportions_ratio_threshold != null - && toggleSingleImageMode('?') == 'on'){ - if(n <= CONFIG.proportions_ratio_threshold){ - toggleImageProportions('fit-viewer') + var ribbon_mode = (toggleSingleImageMode('?') == 'off') + var threshold = CONFIG.proportions_ratio_threshold + threshold = (threshold != null && threshold.length != null) + ? Math.max.apply(null, threshold) + : threshold + + // single image mode: update proportions... + if(!ribbon_mode && threshold != null){ + if(n <= threshold){ + toggleImageProportions('fit-viewer', null, n) + } else { toggleImageProportions('none') } } + + // ribbon mode: set square proportions... + if(ribbon_mode && toggleImageProportions('?') != 'none'){ + toggleImageProportions('none') + } }) .on('fittingImages', function(evt, n){ //console.log('!!!! fittingImages') diff --git a/ui/keybindings.js b/ui/keybindings.js index 33f83c14..8de2d865 100755 --- a/ui/keybindings.js +++ b/ui/keybindings.js @@ -374,6 +374,7 @@ var KEYBOARD_CONFIG = { '#7': doc('Fit seven images', function(){ fitNImages(7) }), '#8': doc('Fit eight images', function(){ fitNImages(8) }), '#9': doc('Fit nine images', function(){ fitNImages(9) }), + '#0': doc('Fit nine images', function(){ fitNImages(CONFIG.max_screen_images) }), // cropping... C: doc('Show ribbon crop dialog', cropImagesDialog), @@ -567,9 +568,8 @@ var KEYBOARD_CONFIG = { // zooming... '#1': doc('Fit image to screen', function(){ fitNImages(1) }), - // XXX this will do different stuff for different proportioned screens... - '#2': doc('Show big image', function(){ fitNImages(1.5, true) }), - '#3': doc('Show small image', function(){ fitNImages(3, true) }), + '#2': doc('Show big image', function(){ fitNImages(1.125) }), + '#3': doc('Show small image', function(){ fitNImages(3) }), '-': doc('Zoom in', function(){ zoomOut() }), '=': doc('Zoom out', function(){ zoomIn() }), diff --git a/ui/lib/jli.js b/ui/lib/jli.js index 3ad96a28..b015801a 100755 --- a/ui/lib/jli.js +++ b/ui/lib/jli.js @@ -123,6 +123,7 @@ function createCSSClassToggler(elem, class_list, callback_a, callback_b){ var e = a var action = b == 'next' ? null : b } + var args = args2array(arguments).slice(2) e = $(e) // option number... if(typeof(action) == typeof(1)){ @@ -181,7 +182,7 @@ function createCSSClassToggler(elem, class_list, callback_a, callback_b){ // function, this will enable them to act as metods correctly // pre callback... if(callback_pre != null){ - if(callback_pre.call(this, action, e) === false){ + if(callback_pre.apply(this, [action, e].concat(args)) === false){ // XXX should we return action here??? //return return func('?') @@ -194,7 +195,7 @@ function createCSSClassToggler(elem, class_list, callback_a, callback_b){ } // post callback... if(callback_post != null){ - callback_post.call(this, action, e) + callback_post.apply(this, [action, e].concat(args)) } return action @@ -742,6 +743,12 @@ Object.get = function(obj, name, dfl){ } +// convert JS arguments to Array... +function args2array(args){ + return Array.apply(null, args) +} + + var getAnimationFrame = (window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame diff --git a/ui/modes.js b/ui/modes.js index 0aee0a3f..d21cf5c8 100755 --- a/ui/modes.js +++ b/ui/modes.js @@ -139,11 +139,8 @@ var toggleSingleImageMode = createCSSClassToggler( // load things... w = UI_STATE['single-image-mode-screen-images'] w = w == null ? 1 : w - var p = UI_STATE['single-image-mode-proportions'] - p = p == null ? 'square' : p // set stuff... - toggleImageProportions(p) fitNImages(w) toggleImageInfo('off') @@ -153,13 +150,11 @@ var toggleSingleImageMode = createCSSClassToggler( // save things... UI_STATE['single-image-mode-screen-images'] = w - UI_STATE['single-image-mode-proportions'] = toggleImageProportions('?') // load things... w = UI_STATE['ribbon-mode-screen-images'] w = w == null ? CONFIG.default_screen_images : w - toggleImageProportions('none') fitNImages(w) var i = UI_STATE['ribbon-mode-image-info'] == 'on' ? 'on' : 'off' toggleImageInfo(i) @@ -362,43 +357,88 @@ function setImageProportions(image, mode){ } +// Toggle image container proportions mode +// +// Available modes: +// - none : square proportions +// - fit-viewer : calculate proportions +// +// If CONFIG.proportions_ratio_threshold is null or if ignore_thresholds, +// is set, this willsimply switch between square and viewer proportions. +// +// If CONFIG.proportions_ratio_threshold is set to a list of two values, +// this will use the screen width in images (S) to calculate the +// proportions: +// S < min : viewer proportions +// S > max : square proportions +// min > S < max : transitional, proportions between +// square and viewer... +// +// NOTE: if n is not passed, getScreenWidthInImages() will be used... +// NOTE: if ignore_thresholds is set or the threshold is not a list, this +// will ignore the threshold... +// +// XXX is this the right place to calculate proportions??? (revise) var toggleImageProportions = createCSSClassToggler( '.viewer', [ 'none', 'fit-viewer' ], - /* XXX do we need this??? - function(action){ - // prevent reentering... - if(action == toggleImageProportions('?')){ - return false - } - }, - */ - function(action){ + function(action, viewer, n, ignore_thresholds){ var image = $('.image') - var h = image.outerHeight(true) - var w = image.outerWidth(true) - // viewer proportions... - // XXX going into here twice for a rotated 90/270 image will - // set it back to square... - // XXX can't reproduce this error... if(action == 'fit-viewer'){ - var viewer = $('.viewer') + // NOTE: we care about n only in fit-viewer mode... + n = n == null ? getScreenWidthInImages() : n + var threshold = CONFIG.proportions_ratio_threshold + + // image proportions between square and viewer indicator... + // + // must be between 0 and 1: + // - 1 is square proportions + // - 0 is viewer proportions + var c = 0 + + // calculate c... + if(!ignore_thresholds + && (threshold != null + || threshold.length == 2)){ + var min = Math.min.apply(null, threshold) + var max = Math.max.apply(null, threshold) + var c = (n - min) / (max - min) + c = c < 0 ? 0 + : c > 1 ? 1 + : c + } + var W = viewer.innerWidth() var H = viewer.innerHeight() + // landscape viewer... if(W > H){ + var h = image.outerHeight(true) + var scale = h/H + var tw = W * scale + var d = tw - h + image.css({ - width: W * h/H, + //width: W * scale, + width: tw - (d * c), height: '', }) + + // portrait viewer... } else { + var w = image.outerWidth(true) + var scale = w/W + var th = H * scale + var d = th - w + image.css({ width: '', - height: H * w/W, + //height: H * scale, + height: th - d * c, }) } @@ -407,11 +447,11 @@ var toggleImageProportions = createCSSClassToggler( centerView(null, 'css') // square proportions... + // NOTE: this will reset the size to default (defined in CSS) } else { - var size = Math.min(w, h) image.css({ - width: size, - height: size + width: '', + height: '' }) // account for rotation...