diff --git a/ui/ImageGrid.js b/ui/ImageGrid.js index c244a215..d61f59f3 100755 --- a/ui/ImageGrid.js +++ b/ui/ImageGrid.js @@ -25,10 +25,12 @@ var DATA = { // the ribbon cache... // in the simplest form this is a list of lists of GIDs ribbons: [ + $(new Array(100)).map(function(i){return i}).toArray() ], // flat ordered list of images in current context... // in the simplest form this is a list of GIDs. - image_order: [ + order: [ + $(new Array(100)).map(function(i){return i}).toArray() ], // the images object, this is indexed by image GID and contains all // the needed data... @@ -67,6 +69,21 @@ function getRibbon(image){ return image.closest('.ribbon') } +// NOTE: elem is optional and if given can be an image or a ribbon... +function getRibbonIndex(elem){ + if(elem == null){ + var ribbon = getRibbon() + } else { + elem = $(elem) + if(elem.hasClass('image')){ + ribbon = getRibbon(elem) + } else { + ribbon = elem + } + } + return $('.ribbon').index(ribbon) +} + // ...tried to make this as brain-dead-stupidly-simple as possible... function getRelativeVisualPosition(outer, inner){ outer = $(outer).offset() @@ -107,7 +124,7 @@ function getImageBefore(image, ribbon, mode){ var prev = [] images.each(function(){ - if(order < $(this).attr('order')){ + if(order < JSON.parse($(this).attr('order'))){ return false } prev = this @@ -129,9 +146,11 @@ function shiftTo(image, ribbon){ image.insertAfter(target) } + $('.viewer').trigger('shiftedImage', [image, cur_ribbon, ribbon]) + // if removing last image out of a ribbon, remove the ribbon.... if(cur_ribbon.find('.image').length == 0){ - cur_ribbon.remove() + removeRibbon(cur_ribbon) } return image @@ -149,9 +168,11 @@ function shiftImage(direction, image, force_create_ribbon){ // need to create a new ribbon... if(ribbon.length == 0 || force_create_ribbon == true){ - ribbon = createRibbon()['insert' + (direction == 'prev' - ? 'Before' - : 'After')](old_ribbon) + var index = getRibbonIndex(old_ribbon) + index = direction == 'after' ? index + 1 : index + + ribbon = createRibbon(index) + shiftTo(image, ribbon) } else { shiftTo(image, ribbon) @@ -179,18 +200,20 @@ function createImage(n){ if(img.length > 0){ return img.first().clone() .attr({ - 'order': n, + 'order': JSON.stringify(n), + 'gid': JSON.stringify(n), // need to strip extra classes... 'class': 'image' }) } else { - return $('
') + return $('
') } } // This will create a set of new images, reusing a list of existing // elements if given. // XXX do we need this??? +// XXX add position... function createImages(need, have){ have = have == null ? [] : have @@ -210,37 +233,95 @@ function createImages(need, have){ } } -function createRibbon(){ - return $('
') +function createRibbon(index){ + // make the ribbon... + var ribbon = $('
') + + if(index == null){ + return ribbon + } + var ribbons = $('.ribbon') + if(index >= ribbons.length){ + ribbons.last().after(ribbon) + } else { + ribbons.eq(index).before(ribbon) + } + + $('.viewer').trigger('createdRibbon', [ribbon]) + + return ribbon } +// NOTE: this will pass the index where the ribbon was to the event, +// rather than an actual ribbon... +function removeRibbon(ribbon){ + // ribbon can be an index... + if(typeof(ribbon) == typeof(1)){ + ribbon = $('.ribbon').eq(ribbon) + } + + $('.viewer').trigger('removedRibbon', [getRibbonIndex(ribbon)]) + + return $(ribbon).remove() +} /********************************************************************** * Constructors */ -// XXX need to specify a ribbon... // NOTE: count can be either hegative or positive, this will idicate // load direction... // NOTE: this will not include the 'from' GID in the resulting list... -function getImageGIDs(from, count){ +// NOTE: this can calculate the ribbon number if an image can be only +// in one ribbon... +// NOTE: if an image can be in more than one ribbon, one MUST suply the +// correct ribbon number... +// XXX do we need more checking??? +function getImageGIDs(from, count, ribbon){ if(count == 0){ return [] } - // XXX get guid list (splice/slice)... - // - return [] + if(ribbon == null){ + $(DATA.ribbons).each(function(i, e){ + if(e.indexOf(from) >= 0){ + ribbon = i + return false + } + }) + } + // XXX checkif this is empty... + ribbon = DATA.ribbons[ribbon] + + if(count > 0){ + var start = ribbon.indexOf(from) + 1 + return ribbon.slice(start, start + count) + } else { + var end = ribbon.indexOf(from) + return ribbon.slice(+count >= end ? 0 : end + count, end) + } } function updateImage(image, gid, size){ image = $(image) if(gid == null){ - gid = image.attr('gid') - image.attr('gid', gid) + gid = JSON.parse(image.attr('gid')) + } else { + image.attr('gid', JSON.stringify(gid)) } size = size == null ? getVisibleImageSize() : size + image.attr({ + //order: JSON.stringify(DATA.order.indexOf(gid)), + order: JSON.stringify(gid) + // XXX update attrs + }) + + // XXX STUB + image.text(gid) + // XXX slect best previe by size... + // XXX + // XXX update classes... // XXX } @@ -252,8 +333,8 @@ function rollImages(n, ribbon){ return $([]) } ribbon = ribbon == null ? getRibbon() : $(ribbon) - var from = n > 0 ? ribbon.find('.image').last().attr('gid') - : ribbon.find('.image').first().attr('gid') + var from = n > 0 ? JSON.parse(ribbon.find('.image').last().attr('gid')) + : JSON.parse(ribbon.find('.image').first().attr('gid')) var gids = getImageGIDs(from, n) if(gids.length == 0){ return $([]) @@ -598,6 +679,22 @@ function rollRibbon(n, ribbon){ +/********************************************************************** +* Event handlers... +*/ + +// NOTE: this is on purpose done relative... +function clickHandler(evt){ + var img = $(evt.target).closest('.image') + + centerImage(focusImage(img)) + + centerRibbons() +} + + + + /********************************************************************** * User actions */ @@ -708,6 +805,25 @@ function nextRibbon(moving, mode){ } +function fitNImages(n){ + var image = $('.current.image') + var size = image.outerHeight(true) + + var viewer = $('.viewer') + var W = viewer.innerWidth() + var H = viewer.innerHeight() + + var scale = Math.min(W / (size * n), H / size) + + // XXX if animating, the next two likes must be animated together... + setElementScale($('.ribbon-set'), scale) + centerImage(image, 'css') +} + + + + +/************************************************** Editor Actions ***/ // XXX add a shift event here... // XXX get move direction... @@ -749,24 +865,9 @@ function shiftImageDownNewRibbon(image, moving){ // TODO manual image ordering (shiftLeft/shiftRight functions) // XXX -function fitNImages(n){ - var image = $('.current.image') - var size = image.outerHeight(true) - - var viewer = $('.viewer') - var W = viewer.innerWidth() - var H = viewer.innerHeight() - - var scale = Math.min(W / (size * n), H / size) - - // XXX if animating, the next two likes must be animated together... - setElementScale($('.ribbon-set'), scale) - centerImage(image, 'css') -} - -// Marks... +/*********************************************************** Marks ***/ // XXX if this unmarks an image in marked-only mode no visible image is // going to be current... @@ -831,21 +932,5 @@ function toggleImageMarkBlock(image){ -/********************************************************************** -* Event handlers... -*/ - -// NOTE: this is on purpose done relative... -function clickHandler(evt){ - var img = $(evt.target).closest('.image') - - centerImage(focusImage(img)) - - centerRibbons() -} - - - - /********************************************************************** * vim:set sw=4 ts=4 : */ diff --git a/ui/index.html b/ui/index.html index cddbb235..ac05b8e9 100755 --- a/ui/index.html +++ b/ui/index.html @@ -250,7 +250,6 @@ $(function(){ function(k){console.log(k)})) - // XXX dynamic loading test... // XXX this will be a stupid demo, until we get real image loading... // XXX update this depending on zoom and navigation speed... @@ -258,6 +257,7 @@ $(function(){ // XXX update this depending on zoom and navigation speed... var LOADER_CHUNK = LOADER_THRESHOLD * 2 $('.viewer') + // XXX it takes several steps for adjacent ribbons to catch up... .on('centeringRibbon', function(evt, ribbon, image){ var head = image.prevAll('.image') var tail = image.nextAll('.image') @@ -268,7 +268,6 @@ $(function(){ // XXX need to expand/contract the ribbon depending on zoom and speed... - // XXX check if we have images to load in the needed directions... // XXX use extendRibbon, to both roll and expand/contract... if(tail.length < LOADER_THRESHOLD){ var rolled = rollImages(LOADER_CHUNK, ribbon) @@ -277,6 +276,31 @@ $(function(){ var rolled = rollImages(-LOADER_CHUNK, ribbon) } }) + .on('shiftedImage', function(evt, image, from, to){ + from = getRibbonIndex(from) + var ribbon = to + to = getRibbonIndex(to) + + var gid = JSON.parse(image.attr('gid')) + + var index = DATA.ribbons[from].indexOf(gid) + var img = DATA.ribbons[from].splice(index, 1) + + // XXX a bit ugly, revise... + index = ribbon.find('.image') + .index(ribbon.find('[gid='+JSON.stringify(gid)+']')) + DATA.ribbons[to].splice(index, 0, gid) + }) + .on('createdRibbon', function(evt, index){ + index = getRibbonIndex(index) + + console.log('creating ribbon...') + DATA.ribbons.splice(index, 0, []) + }) + .on('removedRibbon', function(evt, index){ + console.log('removing ribbon...') + DATA.ribbons.splice(index, 1) + }) diff --git a/ui/keybindings3.js b/ui/keybindings3.js index 499fa62e..9316e738 100755 --- a/ui/keybindings3.js +++ b/ui/keybindings3.js @@ -78,10 +78,12 @@ var KEYBOARD_CONFIG = { Home: function(){ firstImage() centerRibbons() + return false }, End: function(){ lastImage() centerRibbons() + return false },