mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-28 18:00: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'
|
||||
|
||||
@ -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 =
|
||||
module.CollectionTags = core.ImageGridFeatures.Feature({
|
||||
title: 'Collection tag handling',
|
||||
@ -899,19 +932,14 @@ module.CollectionTags = core.ImageGridFeatures.Feature({
|
||||
|
||||
depends: [
|
||||
'collections',
|
||||
'tags',
|
||||
|
||||
// XXX
|
||||
'image-marks',
|
||||
'image-bookmarks',
|
||||
],
|
||||
|
||||
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',
|
||||
],
|
||||
},
|
||||
actions: CollectionTagsActions,
|
||||
|
||||
handlers: [
|
||||
// move tags between collections...
|
||||
@ -1231,7 +1259,7 @@ module.AutoCollections = core.ImageGridFeatures.Feature({
|
||||
|
||||
// XXX show collections in image metadata...
|
||||
var UICollectionActions = actions.Actions({
|
||||
browseCollections: ['Collections|Crop/$Collec$tions...',
|
||||
browseCollections: ['Collections/$Collec$tions...',
|
||||
core.doc`Collection list...
|
||||
|
||||
NOTE: collections are added live and not on dialog close...
|
||||
@ -1393,7 +1421,7 @@ var UICollectionActions = actions.Actions({
|
||||
|
||||
// Collections actions with collection selection...
|
||||
// XXX should we warn the user when overwriting???
|
||||
saveAsCollection: ['Collections|Crop/$Save as collection...',
|
||||
saveAsCollection: ['Collections/$Save as collection...',
|
||||
widgets.uiDialog(function(){
|
||||
return this.browseCollections(function(title){
|
||||
this.saveCollection(title, 'current')
|
||||
@ -1401,17 +1429,23 @@ var UICollectionActions = actions.Actions({
|
||||
title == this.collection
|
||||
&& this.loadCollection('!')
|
||||
}) })],
|
||||
addToCollection: ['Collections|Crop|Image/Add $image to collection...',
|
||||
addToCollection: ['Collections|Image/Add $image to collection...',
|
||||
widgets.uiDialog(function(gids){
|
||||
return this.browseCollections(function(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') })],
|
||||
joinToCollection: ['Collections|Crop/$Merge view to collection...',
|
||||
joinToCollection: ['Collections/$Merge view to collection...',
|
||||
widgets.uiDialog(function(){
|
||||
return this.browseCollections(function(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...
|
||||
metadataSection: ['- Image/',
|
||||
function(gid, make){
|
||||
@ -1428,6 +1462,9 @@ module.UICollection = core.ImageGridFeatures.Feature({
|
||||
depends: [
|
||||
'ui',
|
||||
'collections',
|
||||
|
||||
// XXX needed only for .addMarkedToCollection(..)
|
||||
'collection-tags',
|
||||
],
|
||||
|
||||
actions: UICollectionActions,
|
||||
|
||||
@ -373,7 +373,8 @@ module.GLOBAL_KEYBOARD = {
|
||||
//alt_C: 'browseCollections',
|
||||
alt_C: 'browseActions: "/Collections/" -- Collections menu...',
|
||||
shift_O: 'browseCollections',
|
||||
F8: 'addToCollection',
|
||||
F8: 'addToCollection!',
|
||||
shift_F8: 'addMarkedToCollection!',
|
||||
|
||||
|
||||
// metadata...
|
||||
|
||||
@ -380,7 +380,7 @@ module.ImageEditMarks = core.ImageGridFeatures.Feature({
|
||||
|
||||
var ImageMarkGroupActions = actions.Actions({
|
||||
// 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,
|
||||
browseMode: 'cropMarked'},
|
||||
function(){
|
||||
@ -506,7 +506,7 @@ var ImageBookmarkEditActions = actions.Actions({
|
||||
// 'on' - toggle all on
|
||||
// 'off' - toggle all off
|
||||
// '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'},
|
||||
function(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',
|
||||
toggler.CSSClassToggler(
|
||||
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...
|
||||
resetSlideshowTimer: ['- Slideshow/Reset slideshow timer',
|
||||
function(){
|
||||
@ -235,6 +233,9 @@ var SlideshowActions = actions.Actions({
|
||||
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',
|
||||
// Non existing elements will not get drawn...
|
||||
//'File/-99:moo',
|
||||
'80:$Edit',
|
||||
'70:$Navigate',
|
||||
'60:$Image',
|
||||
'50:$Ribbon',
|
||||
'40:$Crop',
|
||||
'99:$Edit',
|
||||
'$Navigate',
|
||||
'$Image',
|
||||
'$Ribbon',
|
||||
'$Crop',
|
||||
'Crop/80:Crop $marked images',
|
||||
'Crop/80:Crop $bookmarked images',
|
||||
'Crop/70:$Crop',
|
||||
@ -1119,7 +1119,7 @@ var BrowseActionsActions = actions.Actions({
|
||||
// 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
|
||||
// that can be used multiple times.
|
||||
// ...any other elements with identical text will
|
||||
@ -1129,12 +1129,16 @@ var BrowseActionsActions = actions.Actions({
|
||||
'Crop/-60:.*collection.*',
|
||||
|
||||
'Crop/-70:---',
|
||||
//*/
|
||||
|
||||
'Crop/-80:Uncrop and keep crop image order',
|
||||
'Crop/-81:Uncrop all',
|
||||
'Crop/-82:$Uncrop',
|
||||
'Collec$tions',
|
||||
'$Mark',
|
||||
//'Mark/-99:.*remove.*',
|
||||
'$Bookmark',
|
||||
//'Bookmark/-99:.*remove.*',
|
||||
|
||||
// ...
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user