mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-29 18:30:09 +00:00
more work on collections...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
f0df4183c7
commit
17546ea8d8
@ -21,10 +21,6 @@ var widgets = require('features/ui-widgets')
|
|||||||
|
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
// XXX should collections be in the Crop menu????
|
|
||||||
// ...essentially a collection is a saved crop, so this would be
|
|
||||||
// logical, would simplify control, etc.
|
|
||||||
//
|
|
||||||
|
|
||||||
var MAIN_COLLECTION_TITLE = 'ALL'
|
var MAIN_COLLECTION_TITLE = 'ALL'
|
||||||
|
|
||||||
@ -862,6 +858,43 @@ module.Collection = core.ImageGridFeatures.Feature({
|
|||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
var CollectionTagsActions = actions.Actions({
|
||||||
|
config: {
|
||||||
|
// List of tags to be stored in a collection, unique to it...
|
||||||
|
//
|
||||||
|
// NOTE: the rest of the tags are shared between all collections
|
||||||
|
// NOTE: to disable local tags either delete this, set it to null
|
||||||
|
// or to an empty list.
|
||||||
|
'collection-local-tags': [
|
||||||
|
'bookmark',
|
||||||
|
'selected',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
collectTagged: ['- Collections|Tag/',
|
||||||
|
function(tags, collection){
|
||||||
|
return this.collect(this.data.getTaggedByAll(tags), collection) }],
|
||||||
|
uncollectTagged: ['- Collections|Tag/',
|
||||||
|
function(tags, collection){
|
||||||
|
return this.uncollect(this.data.getTaggedByAll(tags), collection) }],
|
||||||
|
|
||||||
|
// marked...
|
||||||
|
collectMarked: ['- Collections|Mark/',
|
||||||
|
function(collection){
|
||||||
|
return this.collectTagged('selected', collection) }],
|
||||||
|
uncollectMarked: ['Collections|Mark/Remove marked from collection',
|
||||||
|
function(collection){
|
||||||
|
return this.uncollectTagged('selected', collection) }],
|
||||||
|
|
||||||
|
// bookmarked...
|
||||||
|
collectBookmarked: ['- Collections|Bookmark/',
|
||||||
|
function(collection){
|
||||||
|
return this.collectTagged('bookmark', collection) }],
|
||||||
|
uncollectBookmarked: ['Collections|Bookmark/Remove bookmarked from collection',
|
||||||
|
function(collection){
|
||||||
|
return this.uncollectTagged('bookmark', collection) }],
|
||||||
|
})
|
||||||
|
|
||||||
var CollectionTags =
|
var CollectionTags =
|
||||||
module.CollectionTags = core.ImageGridFeatures.Feature({
|
module.CollectionTags = core.ImageGridFeatures.Feature({
|
||||||
title: 'Collection tag handling',
|
title: 'Collection tag handling',
|
||||||
@ -899,19 +932,14 @@ module.CollectionTags = core.ImageGridFeatures.Feature({
|
|||||||
|
|
||||||
depends: [
|
depends: [
|
||||||
'collections',
|
'collections',
|
||||||
|
'tags',
|
||||||
|
|
||||||
|
// XXX
|
||||||
|
'image-marks',
|
||||||
|
'image-bookmarks',
|
||||||
],
|
],
|
||||||
|
|
||||||
config: {
|
actions: CollectionTagsActions,
|
||||||
// List of tags to be stored in a collection, unique to it...
|
|
||||||
//
|
|
||||||
// NOTE: the rest of the tags are shared between all collections
|
|
||||||
// NOTE: to disable local tags either delete this, set it to null
|
|
||||||
// or to an empty list.
|
|
||||||
'collection-local-tags': [
|
|
||||||
'bookmark',
|
|
||||||
'selected',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
handlers: [
|
handlers: [
|
||||||
// move tags between collections...
|
// move tags between collections...
|
||||||
@ -1231,7 +1259,7 @@ module.AutoCollections = 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/$Collec$tions...',
|
||||||
core.doc`Collection list...
|
core.doc`Collection list...
|
||||||
|
|
||||||
NOTE: collections are added live and not on dialog close...
|
NOTE: collections are added live and not on dialog close...
|
||||||
@ -1393,7 +1421,7 @@ var UICollectionActions = actions.Actions({
|
|||||||
|
|
||||||
// Collections actions with collection selection...
|
// Collections actions with collection selection...
|
||||||
// XXX should we warn the user when overwriting???
|
// XXX should we warn the user when overwriting???
|
||||||
saveAsCollection: ['Collections|Crop/$Save as collection...',
|
saveAsCollection: ['Collections/$Save as collection...',
|
||||||
widgets.uiDialog(function(){
|
widgets.uiDialog(function(){
|
||||||
return this.browseCollections(function(title){
|
return this.browseCollections(function(title){
|
||||||
this.saveCollection(title, 'current')
|
this.saveCollection(title, 'current')
|
||||||
@ -1401,17 +1429,23 @@ var UICollectionActions = actions.Actions({
|
|||||||
title == this.collection
|
title == this.collection
|
||||||
&& this.loadCollection('!')
|
&& this.loadCollection('!')
|
||||||
}) })],
|
}) })],
|
||||||
addToCollection: ['Collections|Crop|Image/Add $image to collection...',
|
addToCollection: ['Collections|Image/Add $image to collection...',
|
||||||
widgets.uiDialog(function(gids){
|
widgets.uiDialog(function(gids){
|
||||||
return this.browseCollections(function(title){
|
return this.browseCollections(function(title){
|
||||||
this.collect(gids || this.current, title) }) })],
|
this.collect(gids || this.current, title) }) })],
|
||||||
addLoadedToCollection: ['Collections|Crop/$Add loaded images to collection...',
|
addLoadedToCollection: ['Collections/$Add loaded images to collection...',
|
||||||
widgets.uiDialog(function(){ return this.addToCollection('loaded') })],
|
widgets.uiDialog(function(){ return this.addToCollection('loaded') })],
|
||||||
joinToCollection: ['Collections|Crop/$Merge view to collection...',
|
joinToCollection: ['Collections/$Merge view to collection...',
|
||||||
widgets.uiDialog(function(){
|
widgets.uiDialog(function(){
|
||||||
return this.browseCollections(function(title){
|
return this.browseCollections(function(title){
|
||||||
this.joinCollect(title) }) })],
|
this.joinCollect(title) }) })],
|
||||||
|
|
||||||
|
// XXX should this be here???
|
||||||
|
addMarkedToCollection: ['Collections|Mark/Add marked to $collection...',
|
||||||
|
widgets.uiDialog(function(gids){
|
||||||
|
return this.browseCollections(function(title){
|
||||||
|
this.collectMarked(gids || this.current, title) }) })],
|
||||||
|
|
||||||
/*/ XXX this is not used by metadata yet...
|
/*/ XXX this is not used by metadata yet...
|
||||||
metadataSection: ['- Image/',
|
metadataSection: ['- Image/',
|
||||||
function(gid, make){
|
function(gid, make){
|
||||||
@ -1428,6 +1462,9 @@ module.UICollection = core.ImageGridFeatures.Feature({
|
|||||||
depends: [
|
depends: [
|
||||||
'ui',
|
'ui',
|
||||||
'collections',
|
'collections',
|
||||||
|
|
||||||
|
// XXX needed only for .addMarkedToCollection(..)
|
||||||
|
'collection-tags',
|
||||||
],
|
],
|
||||||
|
|
||||||
actions: UICollectionActions,
|
actions: UICollectionActions,
|
||||||
|
|||||||
@ -373,7 +373,8 @@ module.GLOBAL_KEYBOARD = {
|
|||||||
//alt_C: 'browseCollections',
|
//alt_C: 'browseCollections',
|
||||||
alt_C: 'browseActions: "/Collections/" -- Collections menu...',
|
alt_C: 'browseActions: "/Collections/" -- Collections menu...',
|
||||||
shift_O: 'browseCollections',
|
shift_O: 'browseCollections',
|
||||||
F8: 'addToCollection',
|
F8: 'addToCollection!',
|
||||||
|
shift_F8: 'addMarkedToCollection!',
|
||||||
|
|
||||||
|
|
||||||
// metadata...
|
// metadata...
|
||||||
|
|||||||
@ -380,7 +380,7 @@ module.ImageEditMarks = core.ImageGridFeatures.Feature({
|
|||||||
|
|
||||||
var ImageMarkGroupActions = actions.Actions({
|
var ImageMarkGroupActions = actions.Actions({
|
||||||
// NOTE: this will only group loaded images...
|
// NOTE: this will only group loaded images...
|
||||||
groupMarked: ['Group|Mark/-99:Group loaded marked images',
|
groupMarked: ['Group|Mark/-90:Group loaded marked images',
|
||||||
{journal: true,
|
{journal: true,
|
||||||
browseMode: 'cropMarked'},
|
browseMode: 'cropMarked'},
|
||||||
function(){
|
function(){
|
||||||
@ -506,7 +506,7 @@ var ImageBookmarkEditActions = actions.Actions({
|
|||||||
// 'on' - toggle all on
|
// 'on' - toggle all on
|
||||||
// 'off' - toggle all off
|
// 'off' - toggle all off
|
||||||
// 'next' - toggle each image to next state
|
// 'next' - toggle each image to next state
|
||||||
toggleBookmarkOnMarked: ['Bookmark|Mark/-99:Toggle bookmark on maked images',
|
toggleBookmarkOnMarked: ['Bookmark|Mark/-90:Toggle bookmark on maked images',
|
||||||
{browseMode: 'cropMarked'},
|
{browseMode: 'cropMarked'},
|
||||||
function(action){
|
function(action){
|
||||||
return this.toggleBookmark(this.data.getTaggedByAny('selected'), action)
|
return this.toggleBookmark(this.data.getTaggedByAny('selected'), action)
|
||||||
|
|||||||
@ -45,104 +45,6 @@ var SlideshowActions = actions.Actions({
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
resetSlideshowWorkspace: ['Slideshow/Reset workspace',
|
|
||||||
function(){ delete this.workspaces['slideshow'] }],
|
|
||||||
|
|
||||||
slideshowIntervalDialog: ['Slideshow/Slideshow interval...',
|
|
||||||
widgets.makeUIDialog(function(parent){
|
|
||||||
var that = this
|
|
||||||
var dialog = widgets.makeConfigListEditor(
|
|
||||||
that,
|
|
||||||
'slideshow-intervals',
|
|
||||||
'slideshow-interval',
|
|
||||||
{
|
|
||||||
length_limit: that.config['slideshow-interval-max-count'],
|
|
||||||
check: Date.str2ms,
|
|
||||||
unique: Date.str2ms,
|
|
||||||
sort: function(a, b){
|
|
||||||
return Date.str2ms(a) - Date.str2ms(b) },
|
|
||||||
})
|
|
||||||
.on('start', function(){
|
|
||||||
// suspend the timer if it's not suspended outside...
|
|
||||||
this.__slideshouw_timer == 'suspended'
|
|
||||||
|| this.suspendSlideshowTimer()
|
|
||||||
})
|
|
||||||
.on('close', function(){
|
|
||||||
// reset the timer if it was not suspended outside...
|
|
||||||
this.__slideshouw_timer == 'suspended'
|
|
||||||
|| that.resetSlideshowTimer()
|
|
||||||
|
|
||||||
if(parent){
|
|
||||||
var txt = parent.select('!').find('.text').first().text()
|
|
||||||
|
|
||||||
parent.update()
|
|
||||||
.then(function(){
|
|
||||||
txt != ''
|
|
||||||
&& parent.select(txt)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return dialog
|
|
||||||
})],
|
|
||||||
slideshowDialog: ['Slideshow/Slideshow...',
|
|
||||||
widgets.makeUIDialog(function(){
|
|
||||||
var that = this
|
|
||||||
|
|
||||||
// suspend the timer if it's not suspended outside...
|
|
||||||
var suspended_timer = this.__slideshouw_timer == 'suspended'
|
|
||||||
suspended_timer || this.suspendSlideshowTimer()
|
|
||||||
|
|
||||||
// XXX might be a good idea to make this generic...
|
|
||||||
var _makeToggleHandler = function(toggler){
|
|
||||||
return function(){
|
|
||||||
var txt = $(this).find('.text').first().text()
|
|
||||||
that[toggler]()
|
|
||||||
o.update()
|
|
||||||
.then(function(){ o.select(txt) })
|
|
||||||
that.toggleSlideshow('?') == 'on'
|
|
||||||
&& o.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var o = browse.makeLister(null, function(path, make){
|
|
||||||
make(['$Interval: ',
|
|
||||||
function(){ return that.config['slideshow-interval'] }])
|
|
||||||
.on('open', function(){
|
|
||||||
that.slideshowIntervalDialog(make.dialog) })
|
|
||||||
|
|
||||||
make(['$Direction: ',
|
|
||||||
function(){ return that.config['slideshow-direction'] }])
|
|
||||||
.on('open', _makeToggleHandler('toggleSlideshowDirection'))
|
|
||||||
make(['$Looping: ',
|
|
||||||
function(){ return that.config['slideshow-looping'] }])
|
|
||||||
.on('open', _makeToggleHandler('toggleSlideshowLooping'))
|
|
||||||
|
|
||||||
// Start/stop...
|
|
||||||
make([function(){
|
|
||||||
return that.toggleSlideshow('?') == 'on' ? '$Stop' : '$Start' }])
|
|
||||||
.on('open', function(){
|
|
||||||
that.toggleSlideshow()
|
|
||||||
o.close()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: that.toggleSlideshow('?') == 'on' ? 'Stop' : 'Start',
|
|
||||||
cls: 'table-view tail-action',
|
|
||||||
})
|
|
||||||
.on('close', function(){
|
|
||||||
// reset the timer if it was not suspended outside...
|
|
||||||
suspended_timer
|
|
||||||
|| that.resetSlideshowTimer()
|
|
||||||
})
|
|
||||||
|
|
||||||
return o
|
|
||||||
})],
|
|
||||||
|
|
||||||
toggleSlideshowDirection: ['- Slideshow/Slideshow direction',
|
|
||||||
core.makeConfigToggler('slideshow-direction', ['forward', 'reverse'])],
|
|
||||||
toggleSlideshowLooping: ['- Slideshow/Slideshow looping',
|
|
||||||
core.makeConfigToggler('slideshow-looping', ['on', 'off'])],
|
|
||||||
|
|
||||||
toggleSlideshow: ['Slideshow/Slideshow quick toggle',
|
toggleSlideshow: ['Slideshow/Slideshow quick toggle',
|
||||||
toggler.CSSClassToggler(
|
toggler.CSSClassToggler(
|
||||||
function(){ return this.dom },
|
function(){ return this.dom },
|
||||||
@ -223,6 +125,102 @@ var SlideshowActions = actions.Actions({
|
|||||||
}
|
}
|
||||||
})],
|
})],
|
||||||
|
|
||||||
|
slideshowDialog: ['Slideshow/Slideshow...',
|
||||||
|
widgets.makeUIDialog(function(){
|
||||||
|
var that = this
|
||||||
|
|
||||||
|
// suspend the timer if it's not suspended outside...
|
||||||
|
var suspended_timer = this.__slideshouw_timer == 'suspended'
|
||||||
|
suspended_timer || this.suspendSlideshowTimer()
|
||||||
|
|
||||||
|
// XXX might be a good idea to make this generic...
|
||||||
|
var _makeToggleHandler = function(toggler){
|
||||||
|
return function(){
|
||||||
|
var txt = $(this).find('.text').first().text()
|
||||||
|
that[toggler]()
|
||||||
|
o.update()
|
||||||
|
.then(function(){ o.select(txt) })
|
||||||
|
that.toggleSlideshow('?') == 'on'
|
||||||
|
&& o.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var o = browse.makeLister(null, function(path, make){
|
||||||
|
make(['$Interval: ',
|
||||||
|
function(){ return that.config['slideshow-interval'] }])
|
||||||
|
.on('open', function(){
|
||||||
|
that.slideshowIntervalDialog(make.dialog) })
|
||||||
|
|
||||||
|
make(['$Direction: ',
|
||||||
|
function(){ return that.config['slideshow-direction'] }])
|
||||||
|
.on('open', _makeToggleHandler('toggleSlideshowDirection'))
|
||||||
|
make(['$Looping: ',
|
||||||
|
function(){ return that.config['slideshow-looping'] }])
|
||||||
|
.on('open', _makeToggleHandler('toggleSlideshowLooping'))
|
||||||
|
|
||||||
|
// Start/stop...
|
||||||
|
make([function(){
|
||||||
|
return that.toggleSlideshow('?') == 'on' ? '$Stop' : '$Start' }])
|
||||||
|
.on('open', function(){
|
||||||
|
that.toggleSlideshow()
|
||||||
|
o.close()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: that.toggleSlideshow('?') == 'on' ? 'Stop' : 'Start',
|
||||||
|
cls: 'table-view tail-action',
|
||||||
|
})
|
||||||
|
.on('close', function(){
|
||||||
|
// reset the timer if it was not suspended outside...
|
||||||
|
suspended_timer
|
||||||
|
|| that.resetSlideshowTimer()
|
||||||
|
})
|
||||||
|
|
||||||
|
return o
|
||||||
|
})],
|
||||||
|
|
||||||
|
// settings...
|
||||||
|
slideshowIntervalDialog: ['Slideshow/Slideshow interval...',
|
||||||
|
widgets.makeUIDialog(function(parent){
|
||||||
|
var that = this
|
||||||
|
var dialog = widgets.makeConfigListEditor(
|
||||||
|
that,
|
||||||
|
'slideshow-intervals',
|
||||||
|
'slideshow-interval',
|
||||||
|
{
|
||||||
|
length_limit: that.config['slideshow-interval-max-count'],
|
||||||
|
check: Date.str2ms,
|
||||||
|
unique: Date.str2ms,
|
||||||
|
sort: function(a, b){
|
||||||
|
return Date.str2ms(a) - Date.str2ms(b) },
|
||||||
|
})
|
||||||
|
.on('start', function(){
|
||||||
|
// suspend the timer if it's not suspended outside...
|
||||||
|
this.__slideshouw_timer == 'suspended'
|
||||||
|
|| this.suspendSlideshowTimer()
|
||||||
|
})
|
||||||
|
.on('close', function(){
|
||||||
|
// reset the timer if it was not suspended outside...
|
||||||
|
this.__slideshouw_timer == 'suspended'
|
||||||
|
|| that.resetSlideshowTimer()
|
||||||
|
|
||||||
|
if(parent){
|
||||||
|
var txt = parent.select('!').find('.text').first().text()
|
||||||
|
|
||||||
|
parent.update()
|
||||||
|
.then(function(){
|
||||||
|
txt != ''
|
||||||
|
&& parent.select(txt)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return dialog
|
||||||
|
})],
|
||||||
|
toggleSlideshowDirection: ['- Slideshow/Slideshow direction',
|
||||||
|
core.makeConfigToggler('slideshow-direction', ['forward', 'reverse'])],
|
||||||
|
toggleSlideshowLooping: ['- Slideshow/Slideshow looping',
|
||||||
|
core.makeConfigToggler('slideshow-looping', ['on', 'off'])],
|
||||||
|
|
||||||
// NOTE: these can be used as pause and resume...
|
// NOTE: these can be used as pause and resume...
|
||||||
resetSlideshowTimer: ['- Slideshow/Reset slideshow timer',
|
resetSlideshowTimer: ['- Slideshow/Reset slideshow timer',
|
||||||
function(){
|
function(){
|
||||||
@ -235,6 +233,9 @@ var SlideshowActions = actions.Actions({
|
|||||||
this.__slideshouw_timer = 'suspended'
|
this.__slideshouw_timer = 'suspended'
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
|
|
||||||
|
resetSlideshowWorkspace: ['Slideshow/Reset workspace',
|
||||||
|
function(){ delete this.workspaces['slideshow'] }],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1091,11 +1091,11 @@ var BrowseActionsActions = actions.Actions({
|
|||||||
'File/-90:Close viewer',
|
'File/-90:Close viewer',
|
||||||
// Non existing elements will not get drawn...
|
// Non existing elements will not get drawn...
|
||||||
//'File/-99:moo',
|
//'File/-99:moo',
|
||||||
'80:$Edit',
|
'99:$Edit',
|
||||||
'70:$Navigate',
|
'$Navigate',
|
||||||
'60:$Image',
|
'$Image',
|
||||||
'50:$Ribbon',
|
'$Ribbon',
|
||||||
'40:$Crop',
|
'$Crop',
|
||||||
'Crop/80:Crop $marked images',
|
'Crop/80:Crop $marked images',
|
||||||
'Crop/80:Crop $bookmarked images',
|
'Crop/80:Crop $bookmarked images',
|
||||||
'Crop/70:$Crop',
|
'Crop/70:$Crop',
|
||||||
@ -1119,7 +1119,7 @@ var BrowseActionsActions = actions.Actions({
|
|||||||
// between the positive and negative prioritized items...
|
// between the positive and negative prioritized items...
|
||||||
// ...
|
// ...
|
||||||
|
|
||||||
// We can also add separators here...
|
/*/ We can also add separators here...
|
||||||
// NOTE: the separator is the only element in a level
|
// NOTE: the separator is the only element in a level
|
||||||
// that can be used multiple times.
|
// that can be used multiple times.
|
||||||
// ...any other elements with identical text will
|
// ...any other elements with identical text will
|
||||||
@ -1129,12 +1129,16 @@ var BrowseActionsActions = actions.Actions({
|
|||||||
'Crop/-60:.*collection.*',
|
'Crop/-60:.*collection.*',
|
||||||
|
|
||||||
'Crop/-70:---',
|
'Crop/-70:---',
|
||||||
|
//*/
|
||||||
|
|
||||||
'Crop/-80:Uncrop and keep crop image order',
|
'Crop/-80:Uncrop and keep crop image order',
|
||||||
'Crop/-81:Uncrop all',
|
'Crop/-81:Uncrop all',
|
||||||
'Crop/-82:$Uncrop',
|
'Crop/-82:$Uncrop',
|
||||||
|
'Collec$tions',
|
||||||
'$Mark',
|
'$Mark',
|
||||||
|
//'Mark/-99:.*remove.*',
|
||||||
'$Bookmark',
|
'$Bookmark',
|
||||||
|
//'Bookmark/-99:.*remove.*',
|
||||||
|
|
||||||
// ...
|
// ...
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user