mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-29 18:30:09 +00:00
lots of minor chnages, fixes and cleanup + refactoring...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
76cb68a725
commit
267d5f705b
@ -258,6 +258,14 @@ body {
|
|||||||
cursor: text;
|
cursor: text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Collection list */
|
||||||
|
.browse-widget.collection-list .list .item .text[cropped]:after {
|
||||||
|
content: "(cropped)";
|
||||||
|
margin-left: 5px;
|
||||||
|
opacity: 0.5;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* External Editor List */
|
/* External Editor List */
|
||||||
.browse-widget.editor-list .list .item:first-child .text:after {
|
.browse-widget.editor-list .list .item:first-child .text:after {
|
||||||
|
|||||||
@ -1112,6 +1112,9 @@ module.TagsEditActions = actions.Actions({
|
|||||||
gids = gids.constructor !== Array ? [gids] : gids
|
gids = gids.constructor !== Array ? [gids] : gids
|
||||||
tags = tags.constructor !== Array ? [tags] : tags
|
tags = tags.constructor !== Array ? [tags] : tags
|
||||||
|
|
||||||
|
var that = this
|
||||||
|
gids = gids.map(function(gid){ return that.data.getImage(gid) })
|
||||||
|
|
||||||
// data...
|
// data...
|
||||||
this.data.tag(tags, gids)
|
this.data.tag(tags, gids)
|
||||||
|
|
||||||
@ -1190,7 +1193,9 @@ module.TagsEditActions = actions.Actions({
|
|||||||
|
|
||||||
source = source || 'both'
|
source = source || 'both'
|
||||||
mode = mode || 'merge'
|
mode = mode || 'merge'
|
||||||
images = this.images
|
|
||||||
|
var images = this.images
|
||||||
|
|
||||||
if(typeof(source) != typeof('str')){
|
if(typeof(source) != typeof('str')){
|
||||||
images = source
|
images = source
|
||||||
source = 'images'
|
source = 'images'
|
||||||
@ -1415,16 +1420,6 @@ module.CropActions = actions.Actions({
|
|||||||
|
|
||||||
crop_stack: null,
|
crop_stack: null,
|
||||||
|
|
||||||
// load the crop stack if present...
|
|
||||||
load: [function(data){
|
|
||||||
return function(){
|
|
||||||
if(data.crop_stack){
|
|
||||||
this.crop_stack = data.crop_stack.map(function(j){
|
|
||||||
return data.Data(j)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}],
|
|
||||||
clear: [function(){
|
clear: [function(){
|
||||||
delete this.crop_stack }],
|
delete this.crop_stack }],
|
||||||
|
|
||||||
@ -1458,17 +1453,29 @@ module.CropActions = actions.Actions({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
|
// load the crop stack if present...
|
||||||
load: [function(state){
|
load: [function(state){
|
||||||
return function(){
|
return function(){
|
||||||
var that = this
|
var that = this
|
||||||
|
|
||||||
|
if(!('crop_stack' in state)){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// load...
|
||||||
if(state.crop_stack){
|
if(state.crop_stack){
|
||||||
that.crop_stack = (state.crop_stack || [])
|
this.crop_stack = state.crop_stack
|
||||||
.map(function(d){
|
.map(function(d){
|
||||||
return d instanceof data.Data ? d : data.Data(d) })
|
return d instanceof data.Data ?
|
||||||
|
d
|
||||||
|
: data.Data(d) })
|
||||||
|
|
||||||
// merge the tags...
|
// merge the tags...
|
||||||
that.crop_stack.forEach(function(d){ d.tags = that.data.tags })
|
this.crop_stack.forEach(function(d){ d.tags = that.data.tags })
|
||||||
|
|
||||||
|
// remove...
|
||||||
|
} else {
|
||||||
|
delete this.crop_stack
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
|
|||||||
@ -26,7 +26,7 @@ var widgets = require('features/ui-widgets')
|
|||||||
// logical, would simplify control, etc.
|
// logical, would simplify control, etc.
|
||||||
//
|
//
|
||||||
|
|
||||||
var MAIN_COLLECTION_TITLE = 'All'
|
var MAIN_COLLECTION_TITLE = 'ALL'
|
||||||
|
|
||||||
// XXX things we need to do to collections:
|
// XXX things we need to do to collections:
|
||||||
// - auto-collections
|
// - auto-collections
|
||||||
@ -101,19 +101,30 @@ var CollectionActions = actions.Actions({
|
|||||||
.unique()
|
.unique()
|
||||||
.reverse()
|
.reverse()
|
||||||
|
|
||||||
|
// keep MAIN_COLLECTION_TITLE out of the collection order...
|
||||||
|
var m = res.indexOf(MAIN_COLLECTION_TITLE)
|
||||||
|
m >= 0
|
||||||
|
&& res.splice(m, 1)
|
||||||
|
|
||||||
// remove stuff not present...
|
// remove stuff not present...
|
||||||
if(res.length > keys.length){
|
if(res.length > keys.length){
|
||||||
res = res.filter(function(e){ return e in collections })
|
res = res.filter(function(e){ return e in collections })
|
||||||
}
|
}
|
||||||
|
|
||||||
this.__collection_order.splice.apply(this.__collection_order,
|
this.__collection_order.splice(0, this.__collection_order.length, ...res)
|
||||||
[0, this.__collection_order.length].concat(res))
|
|
||||||
|
|
||||||
return this.__collection_order
|
return this.__collection_order
|
||||||
},
|
},
|
||||||
set collection_order(value){
|
set collection_order(value){
|
||||||
this.__collection_order = value },
|
this.__collection_order = value },
|
||||||
|
|
||||||
|
get collections_length(){
|
||||||
|
var c = (this.collections || {})
|
||||||
|
return MAIN_COLLECTION_TITLE in c ?
|
||||||
|
Object.keys(c).length - 1
|
||||||
|
: Object.keys(c).length
|
||||||
|
},
|
||||||
|
|
||||||
// Format:
|
// Format:
|
||||||
// {
|
// {
|
||||||
// // NOTE: this is always the first handler...
|
// // NOTE: this is always the first handler...
|
||||||
@ -207,6 +218,7 @@ var CollectionActions = actions.Actions({
|
|||||||
var handlers = this.collection_handlers
|
var handlers = this.collection_handlers
|
||||||
|
|
||||||
// save current collection state...
|
// save current collection state...
|
||||||
|
//
|
||||||
// main view -> save it...
|
// main view -> save it...
|
||||||
if(this.collection == null){
|
if(this.collection == null){
|
||||||
var main = this.collections[MAIN_COLLECTION_TITLE] = {
|
var main = this.collections[MAIN_COLLECTION_TITLE] = {
|
||||||
@ -223,12 +235,11 @@ var CollectionActions = actions.Actions({
|
|||||||
//this.saveCollection(this.collection, 'crop')
|
//this.saveCollection(this.collection, 'crop')
|
||||||
main.data = this.data
|
main.data = this.data
|
||||||
main.crop_stack = this.crop_stack
|
main.crop_stack = this.crop_stack
|
||||||
|
&& this.crop_stack.slice()
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if(crop_mode == 'all'){
|
} else if(crop_mode == 'all'){
|
||||||
this.saveCollection(this.collection, 'crop')
|
this.saveCollection(this.collection, 'crop')
|
||||||
//this.collections[this.collection].data = this.data
|
|
||||||
//this.collections[this.collection].crop_stack = this.crop_stack
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// load collection...
|
// load collection...
|
||||||
@ -257,15 +268,21 @@ var CollectionActions = actions.Actions({
|
|||||||
// data needs to be updated as collections
|
// data needs to be updated as collections
|
||||||
// may contain different numbers/orders of
|
// may contain different numbers/orders of
|
||||||
// images...
|
// images...
|
||||||
data.updateImagePositions()
|
// XXX
|
||||||
|
//data.updateImagePositions()
|
||||||
|
data.sortTags()
|
||||||
|
|
||||||
that.load({
|
that.load({
|
||||||
data: data,
|
data: data,
|
||||||
|
|
||||||
crop_stack: collection_data.crop_stack,
|
crop_stack: collection_data.crop_stack
|
||||||
|
&& collection_data.crop_stack.slice(),
|
||||||
|
|
||||||
collections: that.collections,
|
// NOTE: we do not need to pass collections
|
||||||
collection_order: that.collection_order,
|
// and order here as they stay in from
|
||||||
|
// the last .load(..) in merge mode...
|
||||||
|
//collections: that.collections,
|
||||||
|
//collection_order: that.collection_order,
|
||||||
}, true)
|
}, true)
|
||||||
|
|
||||||
// maintain the .collection state...
|
// maintain the .collection state...
|
||||||
@ -375,15 +392,15 @@ var CollectionActions = actions.Actions({
|
|||||||
: mode == 'crop' ?
|
: mode == 'crop' ?
|
||||||
this.data.clone()
|
this.data.clone()
|
||||||
: this.data.clone()
|
: this.data.clone()
|
||||||
.removeUnloadedGIDs())
|
.run(function(){
|
||||||
.run(function(){
|
this.collection = collection
|
||||||
this.collection = collection
|
|
||||||
|
|
||||||
// NOTE: we are doing this manually after .removeUnloadedGIDs(..)
|
// optimization:
|
||||||
// as the later will mess-up the structures
|
// avoid processing .tags as we'll
|
||||||
// inherited from the main .data, namely tags...
|
// overwrite them anyway later...
|
||||||
//this.tags = that.data.tags
|
delete this.tags
|
||||||
}),
|
})
|
||||||
|
.removeUnloadedGIDs()),
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mode == 'crop' && this.crop_stack && depth != 0){
|
if(mode == 'crop' && this.crop_stack && depth != 0){
|
||||||
@ -410,10 +427,11 @@ var CollectionActions = actions.Actions({
|
|||||||
var that = this
|
var that = this
|
||||||
gid = this.data.getImage(gid)
|
gid = this.data.getImage(gid)
|
||||||
//return Object.keys(this.collections || {})
|
//return Object.keys(this.collections || {})
|
||||||
return this.collection_order
|
return (this.collection_order || [])
|
||||||
.filter(function(c){
|
.filter(function(c){
|
||||||
return !gid
|
return c != MAIN_COLLECTION_TITLE
|
||||||
|| that.collections[c].data.getImage(gid) })
|
&& (!gid
|
||||||
|
|| that.collections[c].data.getImage(gid)) })
|
||||||
}],
|
}],
|
||||||
|
|
||||||
collect: ['- Collections/',
|
collect: ['- Collections/',
|
||||||
@ -484,6 +502,7 @@ var CollectionActions = actions.Actions({
|
|||||||
this.saveCollection(collection)
|
this.saveCollection(collection)
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
|
// XXX BUG: .uncollect(..) from crop messes up global tags...
|
||||||
uncollect: ['Collections|Image/$Uncollect image',
|
uncollect: ['Collections|Image/$Uncollect image',
|
||||||
{browseMode: function(){ return !this.collection && 'disabled' }},
|
{browseMode: function(){ return !this.collection && 'disabled' }},
|
||||||
function(gids, collection){
|
function(gids, collection){
|
||||||
@ -505,31 +524,30 @@ var CollectionActions = actions.Actions({
|
|||||||
: [that.data.getImage(gid)] })
|
: [that.data.getImage(gid)] })
|
||||||
.reduce(function(a, b){ return a.concat(b) }, [])
|
.reduce(function(a, b){ return a.concat(b) }, [])
|
||||||
|
|
||||||
/*/ NOTE: we are not using .data.updateImagePositions(gids, 'hide')
|
|
||||||
// here because it will remove the gids from everything
|
|
||||||
// while we need them removed only from ribbons...
|
|
||||||
var hideGIDs = function(){
|
|
||||||
var d = this
|
|
||||||
gids.forEach(function(gid){
|
|
||||||
var i = d.order.indexOf(gid)
|
|
||||||
Object.keys(d.ribbons).forEach(function(r){
|
|
||||||
delete d.ribbons[r][i]
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
//*/
|
|
||||||
|
|
||||||
if(this.collection == collection){
|
if(this.collection == collection){
|
||||||
|
// need to keep this from updating .tags...
|
||||||
|
// XXX this seems a bit hacky...
|
||||||
|
var tags = this.data.tags
|
||||||
|
delete this.data.tags
|
||||||
|
|
||||||
this.data
|
this.data
|
||||||
//.run(hideGIDs)
|
.removeGIDs(gids)
|
||||||
|
.removeEmptyRibbons()
|
||||||
|
.run(function(){
|
||||||
|
this.tags = tags
|
||||||
|
this.sortTags()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: we do both this and the above iff data is cloned...
|
||||||
|
// NOTE: if tags are saved to the collection it means that
|
||||||
|
// those tags are local to the collection and we do not
|
||||||
|
// need to protect them...
|
||||||
|
if(this.data !== this.collections[collection].data){
|
||||||
|
this.collections[collection].data
|
||||||
.removeGIDs(gids)
|
.removeGIDs(gids)
|
||||||
.removeEmptyRibbons()
|
.removeEmptyRibbons()
|
||||||
}
|
}
|
||||||
|
|
||||||
this.collections[collection].data
|
|
||||||
//.run(hideGIDs)
|
|
||||||
.removeGIDs(gids)
|
|
||||||
.removeEmptyRibbons()
|
|
||||||
}],
|
}],
|
||||||
|
|
||||||
|
|
||||||
@ -541,6 +559,7 @@ var CollectionActions = actions.Actions({
|
|||||||
// their data on load as needed.
|
// their data on load as needed.
|
||||||
load: [function(json){
|
load: [function(json){
|
||||||
var that = this
|
var that = this
|
||||||
|
|
||||||
var collections = {}
|
var collections = {}
|
||||||
var c = json.collections || {}
|
var c = json.collections || {}
|
||||||
var order = json.collection_order || Object.keys(c)
|
var order = json.collection_order || Object.keys(c)
|
||||||
@ -550,6 +569,7 @@ var CollectionActions = actions.Actions({
|
|||||||
}
|
}
|
||||||
|
|
||||||
Object.keys(c).forEach(function(title){
|
Object.keys(c).forEach(function(title){
|
||||||
|
// load data...
|
||||||
var d = c[title].data instanceof data.Data ?
|
var d = c[title].data instanceof data.Data ?
|
||||||
c[title].data
|
c[title].data
|
||||||
: data.Data
|
: data.Data
|
||||||
@ -564,6 +584,18 @@ var CollectionActions = actions.Actions({
|
|||||||
data: d,
|
data: d,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: this can be done lazily when loading each collection
|
||||||
|
// but doing so will make the system more complex and
|
||||||
|
// confuse (or complicate) some code that expects
|
||||||
|
// .collections[*].crop_stack[*] to be instances of Data.
|
||||||
|
if(c[title].crop_stack){
|
||||||
|
state.crop_stack = c[title].crop_stack
|
||||||
|
.map(function(c){
|
||||||
|
return c instanceof data.Data ?
|
||||||
|
c
|
||||||
|
: data.Data(c) })
|
||||||
|
}
|
||||||
|
|
||||||
// copy the rest of collection data as-is...
|
// copy the rest of collection data as-is...
|
||||||
Object.keys(c[title])
|
Object.keys(c[title])
|
||||||
.forEach(function(key){
|
.forEach(function(key){
|
||||||
@ -761,6 +793,10 @@ module.Collection = core.ImageGridFeatures.Feature({
|
|||||||
// XXX show collections in image metadata...
|
// XXX show collections in image metadata...
|
||||||
var UICollectionActions = actions.Actions({
|
var UICollectionActions = actions.Actions({
|
||||||
browseCollections: ['Collections|Crop/$Collec$tions...',
|
browseCollections: ['Collections|Crop/$Collec$tions...',
|
||||||
|
core.doc`Collection list...
|
||||||
|
|
||||||
|
NOTE: collections are added live and not on dialog close...
|
||||||
|
`,
|
||||||
widgets.makeUIDialog(function(action){
|
widgets.makeUIDialog(function(action){
|
||||||
var that = this
|
var that = this
|
||||||
var to_remove = []
|
var to_remove = []
|
||||||
@ -774,34 +810,66 @@ var UICollectionActions = actions.Actions({
|
|||||||
.addClass('highlighted')
|
.addClass('highlighted')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
var openHandler = function(_, title){
|
||||||
|
var gid = that.current
|
||||||
|
action ?
|
||||||
|
action.call(that, title)
|
||||||
|
: that.loadCollection(title)
|
||||||
|
that.focusImage(gid)
|
||||||
|
dialog.close()
|
||||||
|
}
|
||||||
|
var setCroppedState = function(title){
|
||||||
|
// indicate collection crop...
|
||||||
|
var cs =
|
||||||
|
title == (that.collection || MAIN_COLLECTION_TITLE) ?
|
||||||
|
that.crop_stack
|
||||||
|
: (that.collections || {})[title] ?
|
||||||
|
that.collections[title].crop_stack
|
||||||
|
: null
|
||||||
|
cs
|
||||||
|
&& this.find('.text').last()
|
||||||
|
.attr('cropped', cs.length)
|
||||||
|
}
|
||||||
|
|
||||||
//var collections = Object.keys(that.collections || {})
|
//var collections = Object.keys(that.collections || {})
|
||||||
var collections = that.collection_order = that.collection_order || []
|
var collections = that.collection_order = that.collection_order || []
|
||||||
|
|
||||||
|
// main collection...
|
||||||
|
!action && collections.indexOf(MAIN_COLLECTION_TITLE) < 0
|
||||||
|
&& make([
|
||||||
|
MAIN_COLLECTION_TITLE,
|
||||||
|
],
|
||||||
|
{ events: {
|
||||||
|
update: function(_, title){
|
||||||
|
// make this look almost like a list element...
|
||||||
|
// XXX hack???
|
||||||
|
$(this).find('.text:first-child')
|
||||||
|
.before($('<span>')
|
||||||
|
.css('color', 'transparent')
|
||||||
|
.addClass('sort-handle')
|
||||||
|
.html('☰'))
|
||||||
|
setCroppedState
|
||||||
|
.call($(this), title)
|
||||||
|
},
|
||||||
|
open: openHandler,
|
||||||
|
}})
|
||||||
|
|
||||||
|
// collection list...
|
||||||
make.EditableList(collections,
|
make.EditableList(collections,
|
||||||
{
|
{
|
||||||
unique: true,
|
unique: true,
|
||||||
sortable: 'y',
|
sortable: 'y',
|
||||||
to_remove: to_remove,
|
to_remove: to_remove,
|
||||||
itemopen: function(title){
|
|
||||||
var gid = that.current
|
itemopen: openHandler,
|
||||||
action ?
|
|
||||||
action.call(that, title)
|
|
||||||
: that.loadCollection(title)
|
|
||||||
that.focusImage(gid)
|
|
||||||
dialog.close()
|
|
||||||
},
|
|
||||||
normalize: function(title){
|
normalize: function(title){
|
||||||
return title.trim() },
|
return title.trim() },
|
||||||
check: function(title){
|
check: function(title){
|
||||||
return title.length > 0 },
|
return title.length > 0 },
|
||||||
|
|
||||||
// remove the 'x' button from main collection...
|
each: setCroppedState,
|
||||||
// XXX is this the correct way to go???
|
|
||||||
each: function(title){
|
|
||||||
title == MAIN_COLLECTION_TITLE
|
|
||||||
&& this.find('.button-container').remove() },
|
|
||||||
|
|
||||||
// XXX should this be "on close"???
|
|
||||||
itemadded: function(title){
|
itemadded: function(title){
|
||||||
action ?
|
action ?
|
||||||
that.newCollection(title)
|
that.newCollection(title)
|
||||||
@ -810,6 +878,7 @@ var UICollectionActions = actions.Actions({
|
|||||||
disabled: action ? [MAIN_COLLECTION_TITLE] : false,
|
disabled: action ? [MAIN_COLLECTION_TITLE] : false,
|
||||||
})
|
})
|
||||||
}, {
|
}, {
|
||||||
|
cls: 'collection-list',
|
||||||
// focus current collection...
|
// focus current collection...
|
||||||
selected: that.collection || MAIN_COLLECTION_TITLE,
|
selected: that.collection || MAIN_COLLECTION_TITLE,
|
||||||
})
|
})
|
||||||
@ -869,7 +938,7 @@ var UICollectionActions = actions.Actions({
|
|||||||
dialog.update()
|
dialog.update()
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
: make.Empty()
|
: make.Empty('No collections...')
|
||||||
})
|
})
|
||||||
.close(function(){
|
.close(function(){
|
||||||
all.forEach(function(title){
|
all.forEach(function(title){
|
||||||
|
|||||||
@ -56,6 +56,10 @@ var demo_images =
|
|||||||
module.demo_images = {
|
module.demo_images = {
|
||||||
a: {
|
a: {
|
||||||
orientation: 90,
|
orientation: 90,
|
||||||
|
tags: ['test'],
|
||||||
|
},
|
||||||
|
d: {
|
||||||
|
tags: ['test', 'bookmark']
|
||||||
},
|
},
|
||||||
f: {
|
f: {
|
||||||
orientation: 270,
|
orientation: 270,
|
||||||
@ -68,6 +72,13 @@ module.demo_images = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sync tags with images...
|
||||||
|
//demo_data = data.Data(demo_data)
|
||||||
|
// .tagsToImages(demo_images, 'merge')
|
||||||
|
// .tagsFromImages(demo_images, 'merge')
|
||||||
|
// .dumpJSON()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
|
|
||||||
|
|||||||
@ -138,7 +138,7 @@ module.GLOBAL_KEYBOARD = {
|
|||||||
'Collection': {
|
'Collection': {
|
||||||
pattern: '.collection-mode',
|
pattern: '.collection-mode',
|
||||||
|
|
||||||
Esc: 'loadCollection: "All" -- Load all images',
|
Esc: 'loadCollection: "ALL" -- Load all images',
|
||||||
},
|
},
|
||||||
|
|
||||||
'Range': {
|
'Range': {
|
||||||
|
|||||||
@ -567,6 +567,7 @@ core.ImageGridFeatures.Feature({
|
|||||||
'reverseImages',
|
'reverseImages',
|
||||||
'reverseRibbons',
|
'reverseRibbons',
|
||||||
'cropGroup',
|
'cropGroup',
|
||||||
|
'syncTags',
|
||||||
],
|
],
|
||||||
function(target){ return this.reload() }],
|
function(target){ return this.reload() }],
|
||||||
],
|
],
|
||||||
|
|||||||
@ -1846,8 +1846,14 @@ module.Buttons = core.ImageGridFeatures.Feature({
|
|||||||
}],
|
}],
|
||||||
|
|
||||||
// update crop button status...
|
// update crop button status...
|
||||||
['load clear reload',
|
[[
|
||||||
|
'load',
|
||||||
|
'clear',
|
||||||
|
'reload',
|
||||||
|
],
|
||||||
function(){
|
function(){
|
||||||
|
var l = (this.crop_stack || []).length
|
||||||
|
|
||||||
$('.main-buttons.buttons .crop.button sub')
|
$('.main-buttons.buttons .crop.button sub')
|
||||||
// XXX should this be here or in CSS???
|
// XXX should this be here or in CSS???
|
||||||
.css({
|
.css({
|
||||||
@ -1855,11 +1861,38 @@ module.Buttons = core.ImageGridFeatures.Feature({
|
|||||||
'width': '0px',
|
'width': '0px',
|
||||||
'overflow': 'visible',
|
'overflow': 'visible',
|
||||||
})
|
})
|
||||||
.text(this.crop_stack ? this.crop_stack.length : '')
|
.text(l == 0 ? ''
|
||||||
|
: l > 99 ? '99+'
|
||||||
|
: l)
|
||||||
}],
|
}],
|
||||||
// update collection button status...
|
// update collection button status...
|
||||||
['load clear reload collectionLoaded collectionUnloaded',
|
[[
|
||||||
|
'load',
|
||||||
|
'clear',
|
||||||
|
'reload',
|
||||||
|
'saveCollection',
|
||||||
|
'collectionLoaded',
|
||||||
|
'collectionUnloaded',
|
||||||
|
],
|
||||||
function(){
|
function(){
|
||||||
|
$('.main-buttons.buttons .collections.button')
|
||||||
|
.css({
|
||||||
|
'color': this.collection ? 'yellow' : '',
|
||||||
|
//'text-decoration': this.collection ? 'underline': '',
|
||||||
|
})
|
||||||
|
|
||||||
|
var l = this.collections_length
|
||||||
|
$('.main-buttons.buttons .collections.button sub')
|
||||||
|
.css({
|
||||||
|
'display': 'inline-block',
|
||||||
|
'width': '0px',
|
||||||
|
'overflow': 'visible',
|
||||||
|
//'color': this.collection ? 'yellow' : '',
|
||||||
|
})
|
||||||
|
.text(l > 99 ? '99+'
|
||||||
|
: l == 0 ? ''
|
||||||
|
: l)
|
||||||
|
/*
|
||||||
$('.main-buttons.buttons .collections.button sub')
|
$('.main-buttons.buttons .collections.button sub')
|
||||||
// XXX should this be here or in CSS???
|
// XXX should this be here or in CSS???
|
||||||
.css({
|
.css({
|
||||||
@ -1869,6 +1902,7 @@ module.Buttons = core.ImageGridFeatures.Feature({
|
|||||||
'color': 'yellow',
|
'color': 'yellow',
|
||||||
})
|
})
|
||||||
.html(this.collection ? '●' : '')
|
.html(this.collection ? '●' : '')
|
||||||
|
//*/
|
||||||
}],
|
}],
|
||||||
// update zoom button status...
|
// update zoom button status...
|
||||||
['viewScale',
|
['viewScale',
|
||||||
|
|||||||
@ -222,9 +222,44 @@ var DataPrototype = {
|
|||||||
|
|
||||||
// Make a sparse list of image gids...
|
// Make a sparse list of image gids...
|
||||||
//
|
//
|
||||||
|
// Make sparse list out of gids...
|
||||||
|
// .makeSparseImages(gids)
|
||||||
|
// -> list
|
||||||
|
//
|
||||||
|
// Make sparse list out of gids and drop gids not in .order...
|
||||||
|
// .makeSparseImages(gids, true)
|
||||||
|
// .makeSparseImages(gids, null, null, true)
|
||||||
|
// -> list
|
||||||
|
// NOTE: this sets drop_non_order_gids...
|
||||||
|
//
|
||||||
|
// Plase gids into their .order positions into target...
|
||||||
|
// .makeSparseImages(gids, target)
|
||||||
|
// -> list
|
||||||
|
// NOTE: items in target on given gid .order positions will
|
||||||
|
// get overwritten...
|
||||||
|
//
|
||||||
|
// Plase gids into their .order positions into target and reposition
|
||||||
|
// overwritten target items...
|
||||||
|
// .makeSparseImages(gids, target, true)
|
||||||
|
// -> list
|
||||||
|
// NOTE: this sets keep_target_items...
|
||||||
|
//
|
||||||
|
// Plase gids into their .order positions into target and reposition
|
||||||
|
// overwritten target items and drop gids not in .order...
|
||||||
|
// .makeSparseImages(gids, target, true, true)
|
||||||
|
// -> list
|
||||||
|
// NOTE: this sets keep_target_items and drop_non_order_gids...
|
||||||
|
//
|
||||||
|
//
|
||||||
// This uses .order as the base for ordering the list.
|
// This uses .order as the base for ordering the list.
|
||||||
//
|
//
|
||||||
// If target is given then it will get updated with the input gids.
|
// By default items in gids that are not present in .order are
|
||||||
|
// appended to the output/target tail after .order.length, which ever
|
||||||
|
// is greater (this puts these items out of reach of further calls
|
||||||
|
// of .makeSparseImages(..)).
|
||||||
|
// Setting drop_non_order_gids to true will drop these items from
|
||||||
|
// output.
|
||||||
|
//
|
||||||
//
|
//
|
||||||
// NOTE: this can be used to re-sort sections of a target ribbon,
|
// NOTE: this can be used to re-sort sections of a target ribbon,
|
||||||
// but care must be taken not to overwrite existing data...
|
// but care must be taken not to overwrite existing data...
|
||||||
@ -234,44 +269,65 @@ var DataPrototype = {
|
|||||||
// (see next for more info).
|
// (see next for more info).
|
||||||
// Another way to deal with this is to .makeSparseImages(target)
|
// Another way to deal with this is to .makeSparseImages(target)
|
||||||
// before using it as a target.
|
// before using it as a target.
|
||||||
// NOTE: if keep_target_items is set items that are overwritten in
|
// NOTE: keep_target_items has no effect if target is not given...
|
||||||
// the target will get pushed to gids.
|
makeSparseImages: function(gids, target, keep_target_items, drop_non_order_gids){
|
||||||
// This flag has no effect if target is an empty list (default).
|
if(arguments.length == 2 && target === true){
|
||||||
makeSparseImages: function(gids, target, keep_target_items){
|
drop_non_order_gids = true
|
||||||
|
target = null
|
||||||
|
}
|
||||||
|
// avoid mutating gids...
|
||||||
|
gids = gids === target || keep_target_items ?
|
||||||
|
gids.slice()
|
||||||
|
: gids
|
||||||
target = target == null ? [] : target
|
target = target == null ? [] : target
|
||||||
keep_target_items = keep_target_items == null ? false : keep_target_items
|
|
||||||
order = this.order
|
order = this.order
|
||||||
|
|
||||||
// avoid directly updating self...
|
var rest = []
|
||||||
if(gids === target){
|
|
||||||
gids = gids.slice()
|
|
||||||
}
|
|
||||||
|
|
||||||
gids.forEach(function(e, i){
|
for(var i=0; i < gids.length; i++){
|
||||||
// if the element is in its place alredy do nothing...
|
var e = gids[i]
|
||||||
if(e == order[i] && e == target[i]){
|
|
||||||
return
|
// skip undefined...
|
||||||
|
if(e === undefined
|
||||||
|
// if the element is in its place alredy do nothing...
|
||||||
|
|| (e == order[i] && e == target[i])){
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: try and avoid the expensive .indexOf(..) as much as
|
// try and avoid the expensive .indexOf(..) as much as possible...
|
||||||
// possible...
|
var j = e != order[i] ? order.indexOf(e) : i
|
||||||
i = e != order[i] ? order.indexOf(e) : i
|
|
||||||
|
|
||||||
if(i >= 0){
|
if(j >= 0){
|
||||||
var o = target[i]
|
|
||||||
// save overwritten target items if keep_target_items
|
// save overwritten target items if keep_target_items
|
||||||
// is set...
|
// is set...
|
||||||
if(keep_target_items
|
var o = target[j]
|
||||||
&& o != null
|
keep_target_items
|
||||||
// if the items is already in gids, forget it...
|
&& o != null
|
||||||
// NOTE: this is to avoid juggling loops...
|
// if the item is already in gids, forget it...
|
||||||
&& gids.indexOf(o) < 0){
|
// NOTE: this is to avoid juggling loops...
|
||||||
gids.push(o)
|
&& gids.indexOf(o) < 0
|
||||||
}
|
// look at o again later...
|
||||||
|
// NOTE: we should not loop endlessly here as target
|
||||||
|
// will eventually get exhausted...
|
||||||
|
&& gids.push(o)
|
||||||
|
|
||||||
target[i] = e
|
target[j] = e
|
||||||
|
|
||||||
|
// handle elements in gids that are not in .order
|
||||||
|
} else if(!drop_non_order_gids){
|
||||||
|
rest.push(e)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
|
// avoid duplicating target items...
|
||||||
|
rest = rest
|
||||||
|
.filter(function(e){ return target.indexOf(e) < 0 })
|
||||||
|
|
||||||
|
if(rest.length > 0){
|
||||||
|
target.length = Math.max(order.length, target.length)
|
||||||
|
target.splice(target.length, 0, ...rest)
|
||||||
|
}
|
||||||
|
|
||||||
return target
|
return target
|
||||||
},
|
},
|
||||||
@ -1271,22 +1327,31 @@ var DataPrototype = {
|
|||||||
// .updateImagePositions()
|
// .updateImagePositions()
|
||||||
// -> data
|
// -> data
|
||||||
//
|
//
|
||||||
// Reposition item(s)
|
// Full sort and remove items not in .order
|
||||||
|
// .updateImagePositions('remove')
|
||||||
|
// -> data
|
||||||
|
//
|
||||||
|
// Reposition specific item(s)...
|
||||||
// .updateImagePositions(gid|index)
|
// .updateImagePositions(gid|index)
|
||||||
|
// .updateImagePositions([gid|index, .. ])
|
||||||
// -> data
|
// -> data
|
||||||
//
|
//
|
||||||
// Reposition item(s) and the item(s) they replace
|
// Reposition item(s) and the item(s) they replace...
|
||||||
// .updateImagePositions(gid|index, 'keep')
|
// .updateImagePositions(gid|index, 'keep')
|
||||||
|
// .updateImagePositions([gid|index, ..], 'keep')
|
||||||
// -> data
|
// -> data
|
||||||
//
|
//
|
||||||
// Hide item(s) from lists
|
// Hide item(s) from lists...
|
||||||
// .updateImagePositions(gid|index, 'hide')
|
// .updateImagePositions(gid|index, 'hide')
|
||||||
|
// .updateImagePositions([gid|index, ..], 'hide')
|
||||||
// -> data
|
// -> data
|
||||||
//
|
//
|
||||||
// Remove item(s) from lists
|
// Remove item(s) from lists...
|
||||||
// .updateImagePositions(gid|index, 'remove')
|
// .updateImagePositions(gid|index, 'remove')
|
||||||
|
// .updateImagePositions([gid|index, ..], 'remove')
|
||||||
// -> data
|
// -> data
|
||||||
//
|
//
|
||||||
|
//
|
||||||
// NOTE: hide will not change the order of other items while remove
|
// NOTE: hide will not change the order of other items while remove
|
||||||
// will do a full sort...
|
// will do a full sort...
|
||||||
// NOTE: in any case other that the first this will not try to
|
// NOTE: in any case other that the first this will not try to
|
||||||
@ -1295,6 +1360,10 @@ var DataPrototype = {
|
|||||||
// XXX needs more thought....
|
// XXX needs more thought....
|
||||||
// do we need to move images by this???
|
// do we need to move images by this???
|
||||||
updateImagePositions: function(from, mode, direction){
|
updateImagePositions: function(from, mode, direction){
|
||||||
|
if(['keep', 'hide', 'remove'].indexOf(from) >= 0){
|
||||||
|
mode = from
|
||||||
|
from = null
|
||||||
|
}
|
||||||
from = from != null && from.constructor !== Array ? [from] : from
|
from = from != null && from.constructor !== Array ? [from] : from
|
||||||
|
|
||||||
var r = this.getRibbon('current')
|
var r = this.getRibbon('current')
|
||||||
@ -1304,7 +1373,9 @@ var DataPrototype = {
|
|||||||
|
|
||||||
// resort...
|
// resort...
|
||||||
if(from == null){
|
if(from == null){
|
||||||
set[key] = this.makeSparseImages(cur)
|
set[key] = mode == 'remove' ?
|
||||||
|
this.makeSparseImages(cur, true)
|
||||||
|
: this.makeSparseImages(cur)
|
||||||
|
|
||||||
// remove/hide elements...
|
// remove/hide elements...
|
||||||
} else if(mode == 'remove' || mode == 'hide'){
|
} else if(mode == 'remove' || mode == 'hide'){
|
||||||
@ -1313,7 +1384,7 @@ var DataPrototype = {
|
|||||||
})
|
})
|
||||||
// if we are removing we'll also need to resort...
|
// if we are removing we'll also need to resort...
|
||||||
if(mode == 'remove'){
|
if(mode == 'remove'){
|
||||||
set[key] = this.makeSparseImages(cur)
|
set[key] = this.makeSparseImages(cur, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// place and keep existing...
|
// place and keep existing...
|
||||||
@ -1328,7 +1399,7 @@ var DataPrototype = {
|
|||||||
|
|
||||||
// maintain focus...
|
// maintain focus...
|
||||||
if(from && from.indexOf(this.current) >= 0){
|
if(from && from.indexOf(this.current) >= 0){
|
||||||
this.focusImage('r')
|
this.focusImage(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
return this
|
return this
|
||||||
@ -2613,7 +2684,7 @@ var DataPrototype = {
|
|||||||
// NOTE: this may result in empty ribbons...
|
// NOTE: this may result in empty ribbons...
|
||||||
removeUnloadedGIDs: function(){
|
removeUnloadedGIDs: function(){
|
||||||
this.order = this.getImages('loaded')
|
this.order = this.getImages('loaded')
|
||||||
this.updateImagePositions()
|
this.updateImagePositions('remove')
|
||||||
return this
|
return this
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -2647,7 +2718,8 @@ var DataPrototype = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.order = order
|
this.order = order
|
||||||
this.updateImagePositions()
|
|
||||||
|
this.updateImagePositions('remove')
|
||||||
|
|
||||||
return this
|
return this
|
||||||
},
|
},
|
||||||
|
|||||||
@ -559,11 +559,11 @@ function(data, options){
|
|||||||
//
|
//
|
||||||
// length_limit: <number>,
|
// length_limit: <number>,
|
||||||
//
|
//
|
||||||
// // Called when an item is opend...
|
// // Item open event handler...
|
||||||
// //
|
// //
|
||||||
// // NOTE: this is simpler that binding to the global open event
|
// // NOTE: this is simpler that binding to the global open event
|
||||||
// // and filtering through the results...
|
// // and filtering through the results...
|
||||||
// itemopen: function(value){ ... },
|
// itemopen: function(evt, value){ ... },
|
||||||
//
|
//
|
||||||
// // Check input value...
|
// // Check input value...
|
||||||
// check: function(value){ ... },
|
// check: function(value){ ... },
|
||||||
@ -910,7 +910,7 @@ function(list, options){
|
|||||||
})
|
})
|
||||||
|
|
||||||
options.itemopen
|
options.itemopen
|
||||||
&& res.on('open', function(){ options.itemopen(dialog.selected) })
|
&& res.on('open', function(evt){ options.itemopen(evt, dialog.selected) })
|
||||||
|
|
||||||
res = res.toArray()
|
res = res.toArray()
|
||||||
|
|
||||||
@ -2026,6 +2026,13 @@ var BrowserPrototype = {
|
|||||||
//
|
//
|
||||||
// // event handlers...
|
// // event handlers...
|
||||||
// events: {
|
// events: {
|
||||||
|
// // item-specific update events...
|
||||||
|
// //
|
||||||
|
// // item added to dom by .update(..)...
|
||||||
|
// // NOTE: this is not propagated up, thus it will not trigger
|
||||||
|
// // the list update.
|
||||||
|
// update: <handler>,
|
||||||
|
//
|
||||||
// <event>: <handler>,
|
// <event>: <handler>,
|
||||||
// ...
|
// ...
|
||||||
// },
|
// },
|
||||||
@ -2477,6 +2484,7 @@ var BrowserPrototype = {
|
|||||||
})
|
})
|
||||||
|
|
||||||
//--------------------------------- user event handlers ---
|
//--------------------------------- user event handlers ---
|
||||||
|
res.on('update', function(evt){ evt.stopPropagation() })
|
||||||
Object.keys(opts.events || {})
|
Object.keys(opts.events || {})
|
||||||
.forEach(function(evt){
|
.forEach(function(evt){
|
||||||
res.on(evt, opts.events[evt]) })
|
res.on(evt, opts.events[evt]) })
|
||||||
@ -2498,8 +2506,11 @@ var BrowserPrototype = {
|
|||||||
res.appendTo(l)
|
res.appendTo(l)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------
|
|
||||||
|
|
||||||
|
//------------------------------- item lifecycle events ---
|
||||||
|
res.trigger('update', txt)
|
||||||
|
|
||||||
|
//---------------------------------------------------------
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -238,12 +238,12 @@ $(function(){
|
|||||||
// load some testing data if nothing else loaded...
|
// load some testing data if nothing else loaded...
|
||||||
if(!this.url_history || Object.keys(this.url_history).length == 0){
|
if(!this.url_history || Object.keys(this.url_history).length == 0){
|
||||||
// NOTE: we can (and do) load this in parts...
|
// NOTE: we can (and do) load this in parts...
|
||||||
this.loadDemoIndex()
|
this
|
||||||
|
.loadDemoIndex()
|
||||||
// this is needed when loading legacy sources that do not have tags
|
// this is needed when loading legacy sources that do not have tags
|
||||||
// synced...
|
// synced...
|
||||||
// do not do for actual data...
|
// do not do for actual data...
|
||||||
//.syncTags()
|
.syncTags('both')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.start()
|
.start()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user