From b9ce00ab56bef587b581fd8c15d697929e43e72c Mon Sep 17 00:00:00 2001 From: "Alex A. Naanou" Date: Tue, 5 Dec 2017 05:48:22 +0300 Subject: [PATCH] when adding stuff to collections the last used collection is now selected + tweaking + cleanup + docs... Signed-off-by: Alex A. Naanou --- ui (gen4)/features/base.js | 6 +- ui (gen4)/features/collections.js | 39 ++++++++--- ui (gen4)/features/ui-widgets.js | 27 ++++++-- ui (gen4)/lib/widget/browse.js | 110 ++++++++++++++++++++++++------ 4 files changed, 149 insertions(+), 33 deletions(-) diff --git a/ui (gen4)/features/base.js b/ui (gen4)/features/base.js index e50f6a23..ee0a4086 100755 --- a/ui (gen4)/features/base.js +++ b/ui (gen4)/features/base.js @@ -715,8 +715,10 @@ core.ImageGridFeatures.Feature({ // XXX handle 'full'??? ['prepareIndexForWrite', function(res){ - // we save .current unconditionally... - res.index.current = res.raw.data.current + // we save .current unconditionally (if it exists)... + if(res.raw.data){ + res.index.current = res.raw.data.current + } var changes = res.changes diff --git a/ui (gen4)/features/collections.js b/ui (gen4)/features/collections.js index bdf7f303..4bccbd8a 100755 --- a/ui (gen4)/features/collections.js +++ b/ui (gen4)/features/collections.js @@ -1923,7 +1923,6 @@ module.AutoCollections = core.ImageGridFeatures.Feature({ // XXX show collections in image metadata... (???) // XXX might be nice to indicate if a collection is loaded -- has .data... -// XXX rename collection ui... // XXX might be nice to add collection previews to the collection list... // ...show the base ribbon from collection as background var UICollectionActions = actions.Actions({ @@ -1932,6 +1931,8 @@ var UICollectionActions = actions.Actions({ // // NOTE: delete or set to null for none... //'default-collections': null, + + 'collection-last-used': null, }, editDefaultCollections: ['Interface/Edit default collections...', @@ -1950,8 +1951,6 @@ var UICollectionActions = actions.Actions({ && title != MAIN_COLLECTION_TITLE }, })], - // XXX edit collection title here??? (on menu) - // ...also might need a collection editor dialog... // XXX would be nice to make this nested (i.e. path list)... browseCollections: ['Collections/$Collec$tions...', core.doc`Collection list... @@ -2093,6 +2092,8 @@ var UICollectionActions = actions.Actions({ clear_on_edit: false, abort_keys: [ 'Esc', + + // XXX 'Up', 'Down', ], @@ -2220,23 +2221,46 @@ var UICollectionActions = actions.Actions({ }) })], addToCollection: ['Collections|Image/Add $image to collection...', widgets.uiDialog(function(gids){ + var that = this return this.browseCollections(function(title){ - this.collect(gids || 'current', title) }) })], + this.collect(gids || 'current', title) }) + .run(function(){ + var title = that.config['collection-last-used'] + title + && this.select(`"${title}"`) }) + .open(function(_, title){ + that.config['collection-last-used'] = title }) + })], addRibbonToCollection: ['Collections|Ribbon/Add $ribbon to collection...', widgets.uiDialog(function(){ return this.addToCollection('ribbon') })], addLoadedToCollection: ['Collections/$Add loaded images to collection...', widgets.uiDialog(function(){ return this.addToCollection('loaded') })], joinToCollection: ['Collections/$Merge view to collection...', widgets.uiDialog(function(){ - return this.browseCollections(function(title){ - this.joinCollect(title) }) })], + var that = this + return this.browseCollections(function(title){ this.joinCollect(title) }) + .run(function(){ + var title = that.config['collection-last-used'] + title + && this.select(`"${title}"`) }) + .open(function(_, title){ + that.config['collection-last-used'] = title }) + })], // XXX should this be here or in marks??? addMarkedToCollection: ['Collections|Mark/Add marked to $collection...', {browseMode: function(){ return this.marked.length == 0 && 'disabled' }}, widgets.uiDialog(function(){ - return this.browseCollections(function(title){ this.collectMarked(title) }) })], + var that = this + return this.browseCollections(function(title){ this.collectMarked(title) }) + .run(function(){ + var title = that.config['collection-last-used'] + title + && this.select(`"${title}"`) }) + .open(function(_, title){ + that.config['collection-last-used'] = title }) + })], /*/ XXX this is not used by metadata yet... // XXX might be a nice idea to define a default make(..) function @@ -2321,7 +2345,6 @@ var FileSystemCollectionActions = actions.Actions({ // } collections: null, - // XXX need to unload unchanged collections... collectionPathLoader: ['- Collections/', {collectionFormat: 'path'}, function(title, state, logger){ diff --git a/ui (gen4)/features/ui-widgets.js b/ui (gen4)/features/ui-widgets.js index be3d9d6d..1ef3a44c 100755 --- a/ui (gen4)/features/ui-widgets.js +++ b/ui (gen4)/features/ui-widgets.js @@ -2009,6 +2009,12 @@ var ButtonsActions = actions.Actions({ '⦊': ['right', 'nextImage -- Next image'], '↧': ['down', 'shiftImageDown -- Shift image down'], }, + + 'button-highlight-color': 'white', + 'button-highlight-colors': [ + 'white', + 'yellow', + ], }, toggleMainButtons: ['Interface/Main buttons', @@ -2029,6 +2035,13 @@ var ButtonsActions = actions.Actions({ right.apply(this, arguments) }) })()], + + toggleButtonHighlightColor: ['Interface/Button highlight color', + core.makeConfigToggler( + 'button-highlight-color', + function(){ return this.config['button-highlight-colors'] }, + // update the buttons... + function(){ this.reload() })], }) var Buttons = @@ -2067,6 +2080,12 @@ module.Buttons = core.ImageGridFeatures.Feature({ 'reload', ], function(){ + // XXX is this the right way to go??? + $('.main-buttons.buttons .crop.button') + .css({ 'color': this.cropped ? + (this.config['button-highlight-color'] || 'white') + : '', }) + var l = (this.crop_stack || []).length $('.main-buttons.buttons .crop.button sub') @@ -2091,11 +2110,11 @@ module.Buttons = core.ImageGridFeatures.Feature({ 'collectionUnloaded', ], function(){ + // XXX is this the right way to go??? $('.main-buttons.buttons .collections.button') - .css({ - 'color': this.collection ? 'yellow' : '', - //'text-decoration': this.collection ? 'underline': '', - }) + .css({ 'color': this.collection ? + (this.config['button-highlight-color'] || 'white') + : '', }) var l = this.collections_length diff --git a/ui (gen4)/lib/widget/browse.js b/ui (gen4)/lib/widget/browse.js index b436d97e..3066023e 100755 --- a/ui (gen4)/lib/widget/browse.js +++ b/ui (gen4)/lib/widget/browse.js @@ -615,10 +615,12 @@ function(data, options){ // // // // This can be: // // null - keep dialog state, ignore external state (default) -// // 'drop_changes' - load external state +// // 'drop_changes' - replace dialog state with input state +// // 'keep_changes' - keep dialog state (ignoring input) +// // 'merge' - merge dialog state and input state // // - merge the changes // // -// update_merge: null | 'drop_changes' | , +// update_merge: null | 'drop_changes' | 'keep_changes' | 'merge' | , // // // Special buttons... // // @@ -712,6 +714,90 @@ function(list, options){ || lst } + /* XXX make a universal add/replace handler... + var editItem = function(txt, replace){ + txt = options.normalize ? + options.normalize(txt) + : txt + // account for '$' as key binding marker... + var ntxt = txt.replace(/\$/g, '') + // unique-test text... + var utxt = options.unique instanceof Function ? + options.unique(txt)+'' + : null + + // invalid format... + if(options.check && !options.check(txt)){ + dialog.update() + return + } + + lst = dialog.__list[id] + var normalized = lst.map(function(e){ + return e.replace(/\$/g, '') }) + + // list length limit + if(options.length_limit + && (lst.length >= options.length_limit)){ + + options.overflow + && options.overflow.call(dialog, txt) + + return + } + + // prevent editing non-arrays... + if(!editable || !lst){ + return + } + + // check if item pre-existed... + var preexisted = utxt ? + //lst.indexOf(options.unique(txt)) >= 0 + (lst.indexOf(utxt) >= 0 + // account for '$' as key binding marker... (XXX ???) + || normalized.indexOf(utxt.replace(/\$/g, '')) >= 0) + : (lst.indexOf(txt) >= 0 + || normalized.indexOf(ntxt) >= 0) + + // add new value and sort list... + lst.push(txt) + + // unique... + if(options.unique == null || options.unique === true){ + // account for '$' as key binding marker... + lst = lst.unique(function(e){ return e.replace(/\$/g, '') }) + + // unique normalized... + } else if(options.unique instanceof Function){ + lst = lst.unique(options.unique) + } + + // itemadded handler... + options.itemadded + && !(options.unique && preexisted) + && options + .itemadded.call(dialog, txt) + + // sort... + if(options.sort){ + lst = lst + .sort(options.sort instanceof Function ? + options.sort + : undefined) + } + + lst = write(dialog.__list[id], lst) + + // update list and select new value... + dialog.update() + .done(function(){ + //dialog.select('"'+txt+'"') + dialog.select('"'+txt.replace(/\$/g, '')+'"') + }) + } + //*/ + dialog.__list = dialog.__list || {} dialog.__editable = dialog.__editable || {} dialog.__to_remove = dialog.__to_remove || {} @@ -734,30 +820,16 @@ function(list, options){ } options = opts - /* XXX - var merge_strategies = { - custom: function(stored, input){ - }, - } - //*/ - var lst = - // initial state... + // no local data -> load initial state... !dialog.__list[id] ? (list instanceof Function ? list() : list) - /*/ custom... - : (options.update_merge in merge_strategies && dialog.__list[id]) ? - merge_strategies[options.update_merge].call(this, - dialog.__list[id], - list instanceof Function ? list() : list) - //*/ - - // load dialog state... + // load dialog state (ignore input)... : (options.update_merge == null || options.update_merge == 'keep_changes') ? dialog.__list[id] - // load input/external state... + // load input/external state (ignore dialog state)... : (options.update_merge == 'drop_changes') ? (list instanceof Function ? list() : list)