diff --git a/ui (gen4)/images.js b/ui (gen4)/images.js index b74c62b3..738a2dfe 100755 --- a/ui (gen4)/images.js +++ b/ui (gen4)/images.js @@ -13,6 +13,50 @@ console.log('>>> images') /*********************************************************************/ +var ImagesClassPrototype = +module.ImagesClassPrototype = { + +} + + +var ImagesPrototype = +module.ImagesPrototype = { + + loadJSON: function(data){ + }, + dumpJSON: function(data){ + }, + + _reset: function(){ + }, +} + + + +/*********************************************************************/ + +// Main Images object... +// +var Images = +module.Images = +function Images(json){ + // in case this is called as a function (without new)... + if(this.constructor.name != 'Images'){ + return new Images(json) + } + + // load initial state... + if(json != null){ + this.loadJSON(json) + } else { + this._reset() + } + + return this +} +Images.__proto__ = ImagesClassPrototype +Images.prototype = ImagesPrototype +Images.prototype.constructor = Images diff --git a/ui (gen4)/ribbons.js b/ui (gen4)/ribbons.js index 98c067de..6adc6692 100755 --- a/ui (gen4)/ribbons.js +++ b/ui (gen4)/ribbons.js @@ -5,6 +5,9 @@ * **********************************************************************/ +// XXX this is a stub, here untill image.js is done... +_UPDATE_IMAGE = false + define(function(require){ var module = {} console.log('>>> ribbons') @@ -53,10 +56,12 @@ var image = require('image') var RibbonsClassPrototype = module.RibbonsClassPrototype = { + // Generic getters... getElemGID: function(elem){ return JSON.parse('"' + elem.attr('gid') + '"') }, + // Constructors... // NOTE: these will return unattached objects... createViewer: function(){ return $('
') @@ -85,8 +90,7 @@ module.RibbonsClassPrototype = { } -// XXX this is a low level interface, not a set of actions... -// XXX test +// NOTE: this is a low level interface, not a set of actions... var RibbonsPrototype = module.RibbonsPrototype = { // @@ -101,22 +105,70 @@ module.RibbonsPrototype = { // Generic getters... getElemGID: RibbonsClassPrototype.getElemGID, + // Contextual getters... - // NOTE: these accept gids or jQuery objects... + + // Get ribbon... + // + // Get current ribbon: + // .getRibbon() + // -> ribbon + // + // Get ribbon by index/gid: + // .getRibbon(index) + // .getRibbon(gid) + // -> ribbon + // + // Get ribbons from list: + // .getRibbon($(..)) + // .getRibbon([..]) + // -> ribbon(s) + // NOTE: this will filter the list but not search the tree... + // getRibbon: function(target){ + // current... if(target == null) { return this.viewer.find('.current.image').parents('.ribbon').first() + // index... + } else if(typeof(target) == typeof(123)){ + return this.viewer.find('.ribbon').eq(target) + + // gid... } else if(typeof(target) == typeof('str')){ //return this.viewer.find('.ribbon[gid="'+JSON.stringify(target)+'"]') return this.viewer.find('.ribbon[gid='+JSON.stringify(target)+']') } return $(target).filter('.ribbon') }, + // Like .getRibbon(..) but returns ribbon index instead of the actual + // ribbon object... + getRibbonIndex: function(target){ + return this.viewer.find('.ribbon').index(this.getRibbon(target)) + }, + + // Get ribbon... + // + // Get current image: + // .getImage() + // -> image + // + // Get image by gid: + // .getImage(gid) + // -> image + // + // Get images from list: + // .getImage($(..)) + // .getImage([..]) + // -> image(s) + // NOTE: this will filter the list but not search the tree... + // getImage: function(target){ + // current... if(target == null) { return this.viewer.find('.current.image') + // gid... } else if(typeof(target) == typeof('str')){ //return this.viewer.find('.image[gid="'+JSON.stringify(target)+'"]') return this.viewer.find('.image[gid='+JSON.stringify(target)+']') @@ -125,37 +177,62 @@ module.RibbonsPrototype = { }, + // Basic manipulation... + // Place a ribbon... // - // position can be: - // - index - // - ribbon gid - // - ribbon - // - null - append the ribbon to the end + // Append target ribbon: + // .placeRibbon(target) + // -> ribbon + // + // Place target ribbon at position: + // .placeRibbon(target, index) + // .placeRibbon(target, ribbon-gid) + // .placeRibbon(target, ribbon) + // -> ribbon + // + // The ribbon will be placed at the new position shifting the next + // ribbon(s), if present, by one. + // + // Indexes if used, can be negative. Negative indexes are relative + // to the end, e.g. -1 is the same as length-1. + // Placing an element at a negative index will place it AFTER the + // target element, this is in contrast to positive indexes where an + // element is placed before the target. In both of the above cases + // (positive and negative indexes) the resulting target position + // will AT the passed position. + // + // NOTE: negative and positive indexes overflow to 0 and length + // respectively. + // NOTE: both target and position must be .getRibbon(..) compatible. + // NOTE: if target ribbon does not exist a new ribbon will be created. + // NOTE: if position ribbon (gid,ribbon) does not exist or is not + // attached then the target will be appended to the end. + // NOTE: this uses the DOM data for placement, this may differ from + // the actual data. // - // NOTE: if ribbon does not exist a new ribbon will be created... - // XXX these will place at current loaded position rather than the - // actual DATA position... - // ...is this correct? // XXX interaction animation... - placeRibbon: function(gid, position){ + placeRibbon: function(target, position){ // get create the ribbon... - var ribbon = this.getRibbon(gid) - ribbon = ribbon.length == 0 ? this.createRibbon(gid) : ribbon + var ribbon = this.getRibbon(target) + var i = this.getRibbonIndex(ribbon) + ribbon = ribbon.length == 0 ? this.createRibbon(target) : ribbon var ribbons = this.viewer.find('.ribbon') // normalize the position... - var p = this.getRibbon(position) - position = p.hasClass('ribbon') ? ribbons.index(p) : position - position = position == null ? -1 : position - position = position < 0 ? ribbons.length + position + 1 : position - position = position < 0 ? 0 : position + if(typeof(position) == typeof(123)){ + position = position < 0 ? ribbons.length + position + 1 : position + position = position < 0 ? 0 : position + } else { + var p = this.getRibbonIndex(position) + // XXX what do we do if the target does not exist, i.e. p == -1 ???? + } // place the ribbon... if(ribbons.length == 0 || ribbons.length <= position){ this.viewer.find('.ribbon-set').append(ribbon) - } else { + } else if(i != position) { ribbons.eq(position).before(ribbon) } @@ -184,10 +261,10 @@ module.RibbonsPrototype = { // be ignored and the actual ribbon will be derived from the // image given. // XXX interaction animation... - placeImage: function(gid, ribbon, position){ + placeImage: function(target, ribbon, position){ // get/create the image... - var img = this.getImage(gid) - img = img.length == 0 ? this.createImage(gid) : img + var img = this.getImage(target) + img = img.length == 0 ? this.createImage(target) : img // normalize the position, ribbon and images... if(position == null){ @@ -211,8 +288,7 @@ module.RibbonsPrototype = { images.eq(position).before(img) } - //return image.updateImage(img) - return img + return _UPDATE_IMAGE ? image.updateImage(img) : img }, // XXX do we need shorthands like shiftImageUp/shiftImageDown/... here? @@ -220,10 +296,14 @@ module.RibbonsPrototype = { // Bulk manipulation... + // update a set of images in a ribbon... + // + // This will reuse the images that already exist, thus if updating or + // adding images to an already loaded set this should be very fast. + // // NOTE: gids and ribbon must be .getImage(..) and .getRibbon(..) // compatible... - // XXX do we need an image pool here??? - showImagesInRibbon: function(gids, ribbon){ + updateRibbon: function(gids, ribbon){ // get/create the ribbon... var r = this.getRibbon(ribbon) if(r.length == 0){ @@ -239,7 +319,7 @@ module.RibbonsPrototype = { var img = that.getImage(gid) img = img.length == 0 ? that.createImage(gid) : img - // clear images that are not in gids... + // clear a chunk of images that are not in gids until one that is... var g = loaded.length > i ? that.getElemGID(loaded.eq(i)) : null while(g != null && gids.indexOf(g) < 0){ that.clear(g) @@ -267,7 +347,7 @@ module.RibbonsPrototype = { } } - //image.updateImage(img) + _UPDATE_IMAGE && image.updateImage(img) }) // remove the rest of the stuff in ribbon... @@ -278,12 +358,49 @@ module.RibbonsPrototype = { return this }, - // XXX do we need anything else here? ..seems too simple :) - loadData: function(data){ + + // Update a data object in ribbons... + // + // This uses .updateRibbon(..) to load individual ribbons, for + // more info see docs for that. + // + // This uses data.ribbon_order to place the ribbons and data.ribbons + // place the images, either is optional, but at least one of the two + // must exist for this to work. + // + // NOTE: this will not clear the ribbons object explicitly. + // NOTE: this will clear the ribbons that are not present in + // data.ribbon_order (if given) unless keep_untouched_ribbons + // is set. + updateData: function(data, keep_untouched_ribbons){ + // load the data... var that = this - data.ribbon_order.forEach(function(gid){ - that.showImagesInRibbon(data.ribbons[gid], gid) - }) + + // place images... + if(data.ribbons != null){ + Object.keys(data.ribbons).forEach(function(gid){ + that.updateRibbon(data.ribbons[gid], gid) + }) + } + + // place ribbons... + if(data.ribbon_order != null){ + data.ribbon_order.forEach(function(gid, i){ + that.placeRibbon(gid, i) + }) + } + + // clear the ribbons that did not get updated... + if(!keep_untouched_ribbons && data.ribbon_order != null){ + var ribbons = data.ribbon_order + that.viewer.find('.ribbon').each(function(){ + var r = $(this) + if(ribbons.indexOf(that.getElemGID(r)) < 0){ + r.remove() + } + }) + } + return this }, @@ -323,20 +440,6 @@ module.RibbonsPrototype = { }, - // UI manipulation... - - // XXX if target is an image align the ribbon both vertically and horizontally... - alignRibbon: function(target, mode){ - // XXX - }, - - // XXX - fitNImages: function(n){ - // XXX - }, - - - // XXX this does not align anything, it's just a low level focus... // XXX interaction animation... focusImage: function(gid){ this.viewer @@ -434,10 +537,23 @@ module.RibbonsPrototype = { // shorthands... // XXX should these be here??? - //rotateCW: function(target){ return this.rotateImage(target, this.CW) }, - //rotateCCW: function(target){ return this.rotateImage(target, this.CCW) }, - //flipVertical: function(target){ return this.flipImage(target, this.VERTICAL) }, - //flipHorizontal: function(target){ return this.flipImage(target, this.HORIZONTAL) }, + rotateCW: function(target){ return this.rotateImage(target, this.CW) }, + rotateCCW: function(target){ return this.rotateImage(target, this.CCW) }, + flipVertical: function(target){ return this.flipImage(target, this.VERTICAL) }, + flipHorizontal: function(target){ return this.flipImage(target, this.HORIZONTAL) }, + + + // UI manipulation... + + // XXX if target is an image align the ribbon both vertically and horizontally... + alignRibbon: function(target, mode){ + // XXX + }, + + // XXX + fitNImages: function(n){ + // XXX + }, _setup: function(viewer){ @@ -456,7 +572,7 @@ function Ribbons(viewer){ return new Ribbons(viewer) } - this.viewer = $(viewer) + this._setup(viewer) return this }