diff --git a/ui (gen4)/features/base.js b/ui (gen4)/features/base.js index c24985e3..33a80fba 100755 --- a/ui (gen4)/features/base.js +++ b/ui (gen4)/features/base.js @@ -95,6 +95,8 @@ actions.Actions({ // between ribbons... // // supported modes: + // + // XXX should this be here??? 'ribbon-focus-modes': [ 'visual', // select image closest visually 'order', // select image closest to current in order diff --git a/ui (gen4)/features/ui.js b/ui (gen4)/features/ui.js index 5a9fc57f..7f3dc6e4 100755 --- a/ui (gen4)/features/ui.js +++ b/ui (gen4)/features/ui.js @@ -2385,6 +2385,7 @@ module.AutoSingleImage = core.ImageGridFeatures.Feature({ // XXX add tap/click to focus... // XXX add pinch-zoom... // XXX add vertical scroll... +// XXX disable drag in single image mode unless image is larger than the screen... // XXX BUG: current image indicator gets shown in random places... var DirectControljQ = module.DirectControljQ = core.ImageGridFeatures.Feature({ @@ -2478,6 +2479,8 @@ module.DirectControljQ = core.ImageGridFeatures.Feature({ }) +// XXX disable drag in single image mode unless image is larger than the screen... +// XXX do not use this for production -- GSAp has bad license... var DirectControlGSAP = module.DirectControlGSAP = core.ImageGridFeatures.Feature({ title: '', @@ -2527,6 +2530,8 @@ module.DirectControlGSAP = core.ImageGridFeatures.Feature({ // XXX fast but uses messes up positioning... // ...setting type: 'left' will fix this but make things // really slow (as slow as jQuery.ui.draggable(..))... + // XXX shifting to using transforms for centering fixes the align + // issue but makes the initial move jump... ['updateRibbon', function(_, target){ var that = this @@ -2536,22 +2541,12 @@ module.DirectControlGSAP = core.ImageGridFeatures.Feature({ if(r.length > 0 && !r.hasClass('draggable')){ r.addClass('draggable') - var o + var o, scale Draggable.create(r, { type: 'x', - onDragStart: function(){ - o = r.position().left - }, + cursor: 'auto', onDragEnd: function(){ - var l = r.position().left - l += o - l - - that.ribbons.preventTransitions(r) - r[0].style.left = l - r[0].style.transform = 'translate3d(0, 0, 0)' - that.ribbons.restoreTransitions(r) - var c = that.ribbons.getImageByPosition('center', r) that .updateRibbon(c) diff --git a/ui (gen4)/index.html b/ui (gen4)/index.html index b7a3f3c1..dc0711d5 100755 --- a/ui (gen4)/index.html +++ b/ui (gen4)/index.html @@ -176,6 +176,7 @@ typeof(require) != 'undefined' && require('nw.gui').Window.get().showDevTools() + diff --git a/ui (gen4)/lib/jli.js b/ui (gen4)/lib/jli.js index 7bcf461e..d2812a69 100755 --- a/ui (gen4)/lib/jli.js +++ b/ui (gen4)/lib/jli.js @@ -217,6 +217,8 @@ function setElementTransform(elem, offset, scale, duration){ elem = $(elem) //var t3d = USE_3D_TRANSFORM ? 'translateZ(0)' : '' var t3d = USE_3D_TRANSFORM ? 'translate3d(0,0,0)' : '' + //var translate = USE_3D_TRANSFORM ? 'translate3d' : 'translate' + var translate = 'translate' if(offset == null){ offset = getElementOffset(elem) @@ -237,9 +239,12 @@ function setElementTransform(elem, offset, scale, duration){ var scale = getElementScale(elem) } if(USE_TRANSFORM){ - var transform = 'translate('+ + var transform = translate+'('+ Math.round(offset.left) +'px, '+ - Math.round(offset.top) +'px) scale('+ scale +') ' + t3d + //Math.round(offset.top) +'px'+ (USE_3D_TRANSFORM && ', 0px' || '') +') ' + Math.round(offset.top) +'px) ' + +'scale('+ scale +') ' + + t3d elem.css({ '-ms-transform' : transform, '-webkit-transform' : transform, @@ -253,7 +258,10 @@ function setElementTransform(elem, offset, scale, duration){ top: '' }, duration) } else { - var transform = 'translate(0px, 0px) scale('+ scale +') ' + t3d + //var transform = translate+'(0px, 0px'+ (USE_3D_TRANSFORM && ', 0px' || '') +') ' + var transform = translate+'(0px, 0px) ' + +'scale('+ scale +') ' + + t3d elem.css({ // NOTE: this will be wrong during a transition, that's why we // can pass the pre-calculated offset as an argument... @@ -465,8 +473,8 @@ function stopAnimation(elem){ // XXX account for other transitions... // XXX make a sync version... -function setElementOffset(elem, l, t){ - return setElementTransform(elem, [l, t]) +function setElementOffset(elem, l, t, scale){ + return setElementTransform(elem, [l, t], scale) } diff --git a/ui (gen4)/lib/util.js b/ui (gen4)/lib/util.js index 5155b8d2..77b1e877 100755 --- a/ui (gen4)/lib/util.js +++ b/ui (gen4)/lib/util.js @@ -11,6 +11,14 @@ define(function(require){ var module = {} /*********************************************************************/ +// convert JS arguments to Array... +var args2array = +module.args2array = +function(args){ + //return Array.apply(null, args) + return [].slice.call(args) +} + // Quote a string and convert to RegExp to match self literally. var quoteRegExp = module.quoteRegExp = @@ -67,6 +75,312 @@ function(path){ +/*********************************************************************/ + +var _transform_parse = { + // 2d transforms: + //martix: [], + + translate: ['left|0', 'top|0'], + translateX: ['left'], + translateY: ['top'], + + scale: [ + ['scale'], + ['scaleX|scale', 'scaleY|scale'], + ], + scaleX: ['scaleX'], + scaleY: ['scaleY'], + + rotate: ['rotate'], + + skew: ['skewX', 'skewY'], + skewX: ['skewX'], + skewY: ['skewY'], + + // 3d transforms: + //martix3d: [], + + translate3d: ['x|0', 'y|0', 'z|0'], + translateZ: ['z'], + + scale3d: ['scaleX', 'scaleY', 'scaleZ'], + scaleZ: ['scaleZ'], + + // XXX + //rotate3d: [x, y, z, angle], + // rotateX + // rotateY + // rotateZ + + perspective: ['perspective'], +} +var _transform_parse_rev = {} +Object.keys(_transform_parse).forEach(function(func){ + var args = _transform_parse[func] + + // we got multiple signatures == merge... + if(!(args[0] instanceof Array)){ + args = [args] + } + + args + // merge lists of args... + .reduce(function(a, b){ return [].concat.call(a, b) }) + .unique() + // split alternatives... + .map(function(a){ return a.split(/\|/g) }) + .forEach(function(a){ + var arg = a[0] + var alt = a.slice(1) + + var e = _transform_parse_rev[arg] = _transform_parse_rev[arg] || {} + + e.funcs = e.funcs || [] + e.funcs.indexOf(func) < 0 && e.funcs.push(func) + + e.alt = e.alt || [] + // XXX we explicitly support only one alternative now... + e.alt = e.alt.concat(alt).unique() + }) +}) + + +// XXX get vendor... + +// +// Set element transform... +// .transform({..}) +// -> element +// +// Get element transform... +// .transform() +// .transform([, ...]) +// .transform([, ...]) +// -> data +// +// Supported transformations: +// x/y +// scale +// scaleX/scaleY +// origin +// originX/originY +// +// NOTE: pixel values are converted to numbers and back by default... +// +// XXX this will get/set values only on the first element, is this correct??? +// XXX how do we combine translate(..) and translate3d(..)??? +jQuery.fn.transform = function(){ + var that = this + var args = args2array(arguments) + + // XXX get the browser prefix... + var prefix = '' + + // normalize... + args = args.length == 0 + || typeof(args[0]) == typeof('str') ? args + : args[0].constructor === Array + || args.length == 1 ? args[0] + : args + + var elem = $(this)[0] + var origin_str = elem.style[prefix + 'transformOrigin'] + var transform_str = elem.style[prefix + 'transform'] + + // build the current state... + // NOTE: we'll need this for both fetching (parsing) and writing + // (checking)... + var transform = {} + var functions = {} + + // origin... + var origin = origin_str + .split(/\s+/) + // XXX add this to transform... + + // transform... + transform_str + // split functions... + .split(/(\w+\([^\)]*)\)/) + // remove empty strings... + .filter(function(e){ return e.trim().length > 0}) + // split each function... + .map(function(e){ return e + // split args... + .split(/\s*[\(,\s]\s*/) + // cleanup... + .filter(function(e){ return e.trim().length > 0 }) }) + // build the structure... + .forEach(function(data){ + var func = data.shift() + var args = data + + // XXX do we care about function vendor tags here??? + var spec = _transform_parse[func] + + functions[func] = args + + // we do not know this function... + if(spec == null){ + transform[func] = args + + } else { + spec = spec[0] instanceof Array ? spec : [spec] + spec.forEach(function(s){ + // skip non-matching signatures... + // XXX is this correct??? + if(s.length != args.length){ + return + } + s.forEach(function(e, i){ + // this is for things that have optional arguments + // like scale(..) + // XXX should we treat this in some special way??? + if(args[i] == null){ + return + } + + var alternatives = e.split(/\|/g) + var k = alternatives.shift().trim() + + transform[k] = args[i].slice(-2) == 'px' + || /[0-9\.]+/.test(args[i]) ? + parseFloat(args[i]) + : args[i] + }) + }) + } + }) + + + // get data... + if(args.constructor === Array){ + var res = {} + + // return the full transform... + if(args.length == 0){ + return transform + } + + args.forEach(function(arg){ + // direct match in shorthand data... + if(arg in transform){ + res[arg] = transform[arg] + + // try and find an alias... + } else if(arg in _transform_parse_rev){ + var funcs = _transform_parse_rev[arg].funcs + var alt = _transform_parse_rev[arg].alt[0] + + // no alternatives... + if(!alt){ + res[arg] = '' + + // explicit number value... + } else if(/^[0-9\.]+$/.test(alt)){ + res[arg] = parseFloat(alt) + + // explicit string value... + } else if(/^(['"]).*\1$/.test(alt)){ + res[arg] = alt.slice(1, -1) + + } else { + var v = $(that).transform(alt) + res[arg] = v == '' ? alt : v + } + + + // collect from function... + } else if(arg in _transform_parse){ + var v = res[arg] = {} + _transform_parse[arg].forEach(function(e){ + var alternatives = e.split(/\|/g) + var k = alternatives.shift().trim() + + v[k] = transform[k] != null ? transform[k] : '' + }) + + // don't know about this attr... + } else { + res[arg] = '' + } + }) + + // special case: we asked for a single value... + if(args.length == 1){ + return res[args[0]] + } + return res + + // set data... + } else { + transform = Object.create(transform) + Object.keys(args).forEach(function(key){ + // the changing value already exists... + if(key in transform + // get one of the shorthand keys... + // NOTE: we might need to pack or re-pack the date but we + // can't decide here... + || key in _transform_parse_rev + // got one of the standard keys... + || key in _transform_parse){ + transform[key] = args[key] + + // key undefined... + } else { + console.warn('Ignoring key "%s".', key) + transform[key] = args[key] + } + }) + + + console.log('>>>>', transform) + + // XXX set new values and resolve new functions... + // XXX + + + // build the value string... + var transform_str = '' + for(var f in functions){ + transform_str += f +'(' + +(functions[f] + // XXX test if px value... + .map(function(e){ return typeof(e) == typeof(123) ? e + 'px' : e }) + .join(', '))+') ' + } + + console.log(transform_str) + + // XXX STUB + return functions + + // set the values... + elem.style.transform = transform_str + elem.style.transformOrigin = origin_str + } + + return $(this) +} + +// shorthands... +jQuery.fn.scale = function(value){ + if(value){ + return $(this).transform({scale: value}) + } else { + return $(this).transform('scale') + } +} +jQuery.fn.origin = function(value){ + if(value){ + return $(this).transform({origin: value}) + } else { + return $(this).transform('origin') + } +} + + /********************************************************************** * vim:set ts=4 sw=4 : */ return module }) diff --git a/ui (gen4)/ribbons.js b/ui (gen4)/ribbons.js index 7a4d5d77..9a56b250 100755 --- a/ui (gen4)/ribbons.js +++ b/ui (gen4)/ribbons.js @@ -1946,8 +1946,12 @@ var RibbonsPrototype = { ribbon .css({ left: (rl + ((W-w)/2 + image_offset) - il) / scale, + //transform: 'translate3d(' + // + ((rl + ((W-w)/2 + image_offset) - il) / scale) + 'px, 0px, 0px)' }) + //setElementOffset(ribbon, ((rl + ((W-w)/2 + image_offset) - il) / scale), 0, 1) + return this },