diff --git a/ui (gen4)/features/collections.js b/ui (gen4)/features/collections.js index 7fd145e5..10d8ea53 100755 --- a/ui (gen4)/features/collections.js +++ b/ui (gen4)/features/collections.js @@ -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, diff --git a/ui (gen4)/features/keyboard.js b/ui (gen4)/features/keyboard.js index a7cbe4db..459a37db 100755 --- a/ui (gen4)/features/keyboard.js +++ b/ui (gen4)/features/keyboard.js @@ -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... diff --git a/ui (gen4)/features/marks.js b/ui (gen4)/features/marks.js index e05961b6..e60ed156 100755 --- a/ui (gen4)/features/marks.js +++ b/ui (gen4)/features/marks.js @@ -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) diff --git a/ui (gen4)/features/ui-slideshow.js b/ui (gen4)/features/ui-slideshow.js index 2e6724c4..4acde582 100755 --- a/ui (gen4)/features/ui-slideshow.js +++ b/ui (gen4)/features/ui-slideshow.js @@ -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'] }], }) diff --git a/ui (gen4)/features/ui-widgets.js b/ui (gen4)/features/ui-widgets.js index 4d38c6ff..ceffa6c3 100755 --- a/ui (gen4)/features/ui-widgets.js +++ b/ui (gen4)/features/ui-widgets.js @@ -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.*', // ...