diff --git a/ui (gen4)/features/app.js b/ui (gen4)/features/app.js index 97bfb95d..477f9f9e 100755 --- a/ui (gen4)/features/app.js +++ b/ui (gen4)/features/app.js @@ -124,7 +124,7 @@ var NWHostActions = actions.Actions({ // XXX add ability to use devtools on background page (node context)... // XXX get the devtools stage... showDevTools: ['Interface|Development/Show Dev Tools', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, function(action){ if(action == '?'){ // XXX get the devtools stage... @@ -145,7 +145,7 @@ var NWHostActions = actions.Actions({ }], toggleSplashScreen: ['Interface/', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, function(){ }], }) @@ -246,7 +246,7 @@ var ElectronHostActions = actions.Actions({ // XXX should this be a toggler??? showDevTools: ['Interface|Development/Show Dev Tools', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, function(action){ var w = electron.remote.getCurrentWindow() @@ -277,7 +277,7 @@ var ElectronHostActions = actions.Actions({ // XXX make this a real toggler... toggleSplashScreen: ['Interface/', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, function(action){ var splash = this.splash = (!this.splash || this.splash.isDestroyed()) ? electron.remote.getGlobal('splash') @@ -560,7 +560,7 @@ var WindowedAppControlActions = actions.Actions({ }], toggleSplashScreenShowing: ['Interface/Splash screen on start', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, core.makeConfigToggler('show-splash-screen', ['on', 'off'], function(action){ diff --git a/ui (gen4)/features/base.js b/ui (gen4)/features/base.js index 6bee7bdd..18ab9efa 100755 --- a/ui (gen4)/features/base.js +++ b/ui (gen4)/features/base.js @@ -401,7 +401,7 @@ actions.Actions({ this.images && this.images.replaceGID(from, to) }], - + // basic navigation... // focusImage: ['- Navigate/Focus image', @@ -537,7 +537,7 @@ actions.Actions({ .focusImage(0) .focusImage(0, 'global') `, - {browseMode: function(target){ + {mode: function(target){ return this.data.getImageOrder('ribbon', target) == 0 && 'disabled' }}, function(all){ this.focusImage(0, all == null ? 'ribbon' : 'global') }], lastImage: ['Navigate/Last image in current ribbon', @@ -549,7 +549,7 @@ actions.Actions({ NOTE: this is symmetrical to .firstImage(..) see docs for that. `, - {browseMode: function(target){ + {mode: function(target){ return this.data.getImageOrder('ribbon', target) == this.data.getImageOrder('ribbon', -1) && 'disabled' }}, function(all){ this.focusImage(-1, all == null ? 'ribbon' : 'global') }], @@ -561,7 +561,7 @@ actions.Actions({ Shorthand for: .firstImage('global') `, - {browseMode: function(){ + {mode: function(){ return this.data.getImageOrder() == 0 && 'disabled' }}, function(){ this.firstImage(true) }], lastGlobalImage: ['Navigate/Last image globally', @@ -572,7 +572,7 @@ actions.Actions({ NOTE: this symmetrical to .firstGlobalImage(..) see docs for that. `, - {browseMode: function(){ + {mode: function(){ return this.data.getImageOrder() == this.data.getImageOrder(-1) && 'disabled' }}, function(){ this.lastImage(true) }], @@ -584,7 +584,7 @@ actions.Actions({ NOTE: this also modifies .direction NOTE: this is .symmetrical to .nextImage(..) see it for docs. `, - {browseMode: 'firstImage'}, + {mode: 'firstImage'}, function(a, mode){ // keep track of traverse direction... this.direction = 'left' @@ -627,7 +627,7 @@ actions.Actions({ NOTE: this also modifies .direction `, - {browseMode: 'lastImage'}, + {mode: 'lastImage'}, function(a, mode){ // keep track of traverse direction... this.direction = 'right' @@ -693,19 +693,19 @@ actions.Actions({ }], firstRibbon: ['Navigate/First ribbon', - {browseMode: function(target){ + {mode: function(target){ return this.data.getRibbonOrder(target) == 0 && 'disabled'}}, function(){ this.focusRibbon('first') }], lastRibbon: ['Navigate/Last ribbon', - {browseMode: function(target){ + {mode: function(target){ return this.data.getRibbonOrder(target) == this.data.getRibbonOrder(-1) && 'disabled'}}, function(){ this.focusRibbon('last') }], prevRibbon: ['Navigate/Previous ribbon', - {browseMode: 'firstRibbon'}, + {mode: 'firstRibbon'}, function(){ this.focusRibbon('before') }], nextRibbon: ['Navigate/Next ribbon', - {browseMode: 'lastRibbon'}, + {mode: 'lastRibbon'}, function(){ this.focusRibbon('after') }], }) @@ -720,6 +720,7 @@ core.ImageGridFeatures.Feature({ 'serialization', ], suggested: [ + 'sync', 'edit', //'tags', //'sort', @@ -734,8 +735,7 @@ core.ImageGridFeatures.Feature({ function(res){ // we save .current unconditionally (if it exists)... if(res.raw.data){ - res.index.current = res.raw.data.current - } + res.index.current = res.raw.data.current } var changes = res.changes @@ -743,10 +743,11 @@ core.ImageGridFeatures.Feature({ return } - // data... - if((changes === true || changes.data) && res.raw.data){ - res.index.data = res.raw.data - } + // basic sections... + // NOTE: config is local config... + ;['config', 'data'].forEach(function(section){ + if((changes === true || chages[section]) && res.raw[section]){ + res.index[section] = res.raw[section] } }) // images (full)... if(res.raw.images @@ -756,11 +757,11 @@ core.ImageGridFeatures.Feature({ // images-diff... } else if(changes && changes.images){ var diff = res.index['images-diff'] = {} - changes.images.forEach(function(gid){ - diff[gid] = res.raw.images[gid] - }) - } + changes.images + .forEach(function(gid){ + diff[gid] = res.raw.images[gid] }) } }], + // XXX restore local .config.... ['prepareIndexForLoad', function(res, json, base_path){ // build data and images... @@ -773,7 +774,9 @@ core.ImageGridFeatures.Feature({ var img = images.Images(json.images) - // this is needed for loading multiple indexes... + // handle base-path... + // XXX do we actually need this??? + // ...this is also done in 'location' if(base_path){ d.base_path = base_path // XXX STUB remove ASAP... @@ -829,7 +832,7 @@ actions.Actions({ // NOTE: resetting this option will clear the last direction... toggleShiftsAffectDirection: ['Interface/Shifts affect direction', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, core.makeConfigToggler('shifts-affect-direction', ['off', 'on'], function(action){ @@ -847,7 +850,7 @@ actions.Actions({ state.base = this.base }, undo: function(state){ this.setBaseRibbon(state.base) }, - browseMode: function(target){ + mode: function(target){ return this.current_ribbon == this.base && 'disabled' }}, function(target){ this.data.setBase(target) }], @@ -954,7 +957,7 @@ actions.Actions({ }], shiftImageLeft: ['Edit|Sort|Image/Shift image left', { undo: undoShift('shiftImageRight'), - browseMode: 'prevImage'}, + mode: 'prevImage'}, function(target){ if(target == null){ this.direction = 'left' @@ -964,7 +967,7 @@ actions.Actions({ }], shiftImageRight: ['Edit|Sort|Image/Shift image right', { undo: undoShift('shiftImageLeft'), - browseMode: 'nextImage'}, + mode: 'nextImage'}, function(target){ if(target == null){ this.direction = 'right' @@ -975,7 +978,7 @@ actions.Actions({ shiftRibbonUp: ['Ribbon|Edit|Sort/Shift ribbon up', { undo: undoShift('shiftRibbonDown'), - browseMode: 'prevRibbon'}, + mode: 'prevRibbon'}, function(target){ this.data.shiftRibbonUp(target) // XXX is this the right way to go/??? @@ -983,7 +986,7 @@ actions.Actions({ }], shiftRibbonDown: ['Ribbon|Edit|Sort/Shift ribbon down', { undo: undoShift('shiftRibbonUp'), - browseMode: 'nextRibbon'}, + mode: 'nextRibbon'}, function(target){ this.data.shiftRibbonDown(target) // XXX is this the right way to go/??? @@ -1046,16 +1049,16 @@ actions.Actions({ this.data.getImages( this.data.getRibbon(ribbon || 'current'))) }], mergeRibbonUp: ['Edit|Ribbon/Merge ribbon up', - {browseMode: function(){ + {mode: function(){ return this.data.ribbon_order[0] == this.current_ribbon && 'disabled' }}, 'mergeRibbon: "up" ...'], mergeRibbonDown: ['Edit|Ribbon/Merge ribbon down', - {browseMode: function(){ + {mode: function(){ return this.data.ribbon_order.slice(-1)[0] == this.current_ribbon && 'disabled' }}, 'mergeRibbon: "down" ...'], // XXX should this accept a list of ribbons to flatten??? flattenRibbons: ['Edit|Ribbon/Flatten', - {browseMode: function(){ + {mode: function(){ return this.data.ribbon_order.length <= 1 && 'disabled' }}, function(){ var ribbons = this.data.ribbons @@ -1245,16 +1248,16 @@ core.ImageGridFeatures.Feature({ var ImageGroupActions = module.ImageGroupActions = actions.Actions({ expandGroup: ['Group/Expand group', - {browseMode: 'ungroup'}, + {mode: 'ungroup'}, function(target){ this.data.expandGroup(target || this.current) }], collapseGroup: ['Group/Collapse group', { journal: true, - browseMode: 'ungroup'}, + mode: 'ungroup'}, function(target){ this.data.collapseGroup(target || this.current) }], cropGroup: ['Crop|Group/Crop group', { journal: true, - browseMode: 'ungroup'}, + mode: 'ungroup'}, function(target){ this.crop(this.data.cropGroup(target || this.current)) }], }) @@ -1285,7 +1288,7 @@ module.ImageEditGroupActions = actions.Actions({ function(gids, group){ this.data.group(gids, group) }], ungroup: ['Group|Edit/Ungroup images', {journal: true}, - {browseMode: function(){ + {mode: function(){ return this.data.getGroup() == null && 'disabled' }}, function(gids, group){ this.data.ungroup(gids, group) }], @@ -1500,7 +1503,7 @@ module.CropActions = actions.Actions({ } }], uncrop: ['Crop/Uncrop', - {browseMode: function(){ return this.cropped || 'disabled' }}, + {mode: function(){ return this.cropped || 'disabled' }}, function(level, restore_current, keep_crop_order){ level = level || 1 @@ -1538,13 +1541,13 @@ module.CropActions = actions.Actions({ } }], uncropAll: ['Crop/Uncrop all', - {browseMode: 'uncrop'}, + {mode: 'uncrop'}, function(restore_current){ this.uncrop('all', restore_current) }], // XXX see if we need to do this on this level?? // ...might be a good idea to do this in data... uncropAndKeepOrder: ['Crop|Edit/Uncrop keeping image order', { journal: true, - browseMode: 'uncrop'}, + mode: 'uncrop'}, function(level, restore_current){ this.uncrop(level, restore_current, true) }], // XXX same as uncrop but will also try and merge changes... // - the order is simple and already done above... @@ -1552,7 +1555,7 @@ module.CropActions = actions.Actions({ // only problem here is how to deal with new ribbons... mergeCrop: ['- Crop|Edit/Merge crop', { journal: true, - browseMode: 'uncrop'}, + mode: 'uncrop'}, function(){ // XXX }], @@ -1573,7 +1576,7 @@ module.CropActions = actions.Actions({ // XXX not sure if we actually need this... cropFlatten: ['Crop/$Flatten', - {browseMode: function(){ + {mode: function(){ return this.data.ribbon_order.length <= 1 && 'disabled' }}, function(list){ this.data.length > 0 && this.crop(list, true) }], cropRibbon: ['Crop|Ribbon/Crop $ribbon', @@ -1733,7 +1736,7 @@ module.CropActions = actions.Actions({ core.doc` `, { - browseMode: 'uncrop', + mode: 'uncrop', getUndoState: function(d){ d.placements = this.data.getImagePositions(d.args[0]) }, undo: function(d){ @@ -1796,7 +1799,7 @@ module.CropActions = actions.Actions({ NOTE: this is a shorthand for .removeFromCrop(..) but only supports ribbon removal.`, - {browseMode: 'uncrop',}, + {mode: 'uncrop',}, function(gids){ var that = this gids = gids || this.current_ribbon diff --git a/ui (gen4)/features/collections.js b/ui (gen4)/features/collections.js index e829889e..3b385551 100755 --- a/ui (gen4)/features/collections.js +++ b/ui (gen4)/features/collections.js @@ -745,7 +745,7 @@ var CollectionActions = actions.Actions({ .collectionToTop(gid) -> this `, - {browseMode: 'uncollect'}, + {mode: 'uncollect'}, function(collection){ collection = collection || this.collection collection = this.collectionGIDs[collection] || collection @@ -984,7 +984,7 @@ var CollectionActions = actions.Actions({ NOTE: this will remove any gid, be it image or ribbon. `, { - browseMode: function(){ return !this.collection && 'disabled' }, + mode: function(){ return !this.collection && 'disabled' }, // XXX two ways to go: // - .collect(..) + .data.placeImage(..) // - rewrite .collect(..) to use .data.placeImage(..) (like: .addToCrop(..)) @@ -1079,7 +1079,7 @@ var CollectionActions = actions.Actions({ i.e. each gid given will be resolved to a ribbon which will be removed. `, - {browseMode: 'uncollect'}, + {mode: 'uncollect'}, function(gids, collection){ var that = this gids = gids || 'current' @@ -1282,7 +1282,7 @@ var CollectionActions = actions.Actions({ // Config and interface stuff... // toggleCollectionCropRetention: ['Interface/Collection crop save mode', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, core.makeConfigToggler( 'collection-save-crop-state', [ @@ -2718,7 +2718,7 @@ var UICollectionActions = actions.Actions({ collectionGetterWrapper(function(title){ this.loadCollection(title) })], loadMainCollection: ['Collections/Exit collection view', { - browseMode: 'uncollect', + mode: 'uncollect', // prevent this from showing up in .uiDialogs list... __dialog__: false, }, @@ -2750,7 +2750,7 @@ var UICollectionActions = actions.Actions({ // XXX do we need this??? cropImagesInCollection: ['Collections|Crop/Crop images in collection...', - {browseMode: function(){ + {mode: function(){ return (!this.collections || Object.keys(this.collections).length == 0) && 'disabled' }}, @@ -2764,7 +2764,7 @@ var UICollectionActions = actions.Actions({ }) }, null, false)], cropOutImagesInCollection: ['Collections|Crop/Remove collection images from crop...', - {browseMode: 'cropImagesInCollection'}, + {mode: 'cropImagesInCollection'}, mixedModeCollectionAction(function(title){ var that = this this.ensureCollection(title) @@ -2900,7 +2900,7 @@ var CollectionMarksActions = actions.Actions({ function(collection){ return this.collect(this.marked, collection) }], uncollectMarked: ['Collections|Mark/Remove marked from collection', - {browseMode: function(){ + {mode: function(){ return (!this.collection || this.marked.length == 0) && 'disabled' }}, function(collection){ return this.uncollect(this.marked, collection) }], @@ -2910,7 +2910,7 @@ var CollectionMarksActions = actions.Actions({ function(collection){ return this.collectTagged('bookmark', collection) }], uncollectBookmarked: ['Collections|Bookmark/Remove bookmarked from collection', - {browseMode: function(){ + {mode: function(){ return (!this.collection || this.bookmarked.length == 0) && 'disabled' }}, function(collection){ return this.uncollectTagged('bookmark', collection) }], @@ -2939,7 +2939,7 @@ var UICollectionMarksActions = actions.Actions({ // UI... // XXX should these be a separate feature??? markImagesInCollection: ['Collections|Mark/$Mark images in collection...', - {browseMode: 'cropImagesInCollection'}, + {mode: 'cropImagesInCollection'}, mixedModeCollectionAction(function(title){ var that = this this.ensureCollection(title) @@ -2950,7 +2950,7 @@ var UICollectionMarksActions = actions.Actions({ }) })], addMarkedToCollection: ['Collections|Mark/Add marked to $collection...', - {browseMode: function(){ + {mode: function(){ return this.marked.length == 0 && 'disabled' }}, mixedModeCollectionAction(function(title){ this.collectMarked(title) })], }) diff --git a/ui (gen4)/features/comments.js b/ui (gen4)/features/comments.js index 24562452..9e3977ed 100755 --- a/ui (gen4)/features/comments.js +++ b/ui (gen4)/features/comments.js @@ -112,7 +112,7 @@ var FileSystemCommentsActions = actions.Actions({ // XXX this will not save comments for merged indexes... saveComments: ['- File/', function(path, date, logger){ - if(this.location.method != 'loadIndex' + if(this.location.load != 'loadIndex' || this.location.loaded.length > 1){ return } @@ -135,7 +135,7 @@ var FileSystemCommentsActions = actions.Actions({ //*/ loadComments: ['- File/', function(path, date, logger){ - if(this.location.method != 'loadIndex'){ + if(this.location.load != 'loadIndex'){ return } diff --git a/ui (gen4)/features/core.js b/ui (gen4)/features/core.js index 839952c6..d306bc10 100755 --- a/ui (gen4)/features/core.js +++ b/ui (gen4)/features/core.js @@ -485,6 +485,58 @@ var IntrospectionActions = actions.Actions({ isEvent: actions.doWithRootAction(function(action){ return !!action.__event__ }), + + // XXX revise... + getActionMode: ['- Interface/', + doc`Get action browse mode... + + Get and action's .mode(..) method and return its result. + + Expected values: + 'disabled' - actions is disabled + 'hidden' - actions is hidden + + NOTE: other values are ignored. + `, + function(action, mode_cache){ + var m = action + var visited = [m] + var last + + // check cache... + if(m in (mode_cache || {})){ + return mode_cache[m] } + + // handle aliases... + do { + last = m + m = this.getActionAttr(m, 'mode') + + // check cache... + if(m in (mode_cache || {})){ + return mode_cache[m] } + + // check for loops... + if(m && visited[m] != null){ + m = null + break + } + visited.push(m) + } while(typeof(m) == typeof('str')) + + //return m ? m.call(this) : undefined + return m ? + // no cache... + (mode_cache == null ? + m.call(this) + // cache hit... + : last in mode_cache ? + mode_cache[last] + // call check and populate cache... + : (mode_cache[action] = + mode_cache[last] = + m.call(this))) + : actions.UNDEFINED }], }) @@ -1799,7 +1851,7 @@ var JournalActions = actions.Actions({ .journal up until and including the undone action. NOTE: only the undone action is pushed to .rjournal `, - {browseMode: function(){ + {mode: function(){ return (this.journal && this.journal.length > 0) || 'disabled' }}, function(){ var journal = this.journal.slice() || [] @@ -1854,7 +1906,7 @@ var JournalActions = actions.Actions({ Essentially this will remove and re-run the last action in .rjournal `, - {browseMode: function(){ + {mode: function(){ return (this.rjournal && this.rjournal.length > 0) || 'disabled' }}, function(){ if(!this.rjournal || this.rjournal.length == 0){ diff --git a/ui (gen4)/features/examples.js b/ui (gen4)/features/examples.js index a5f7bc30..d8e1dc72 100755 --- a/ui (gen4)/features/examples.js +++ b/ui (gen4)/features/examples.js @@ -206,7 +206,7 @@ var ExampleActions = actions.Actions({ // target... // XXX more docs! null, - // state accessor... + // state getter... function(_, state){ // get the state... if(state == null){ @@ -324,7 +324,7 @@ var ExampleUIActions = actions.Actions({ }], exampleActionDisabled: ['Test/$Disabled example action', - {browseMode: function(){ return 'disabled' }}, + {mode: function(){ return 'disabled' }}, function(){ console.log('Disabled action called:', [...arguments]) }], diff --git a/ui (gen4)/features/filesystem.js b/ui (gen4)/features/filesystem.js index e5432fd4..d407dedd 100755 --- a/ui (gen4)/features/filesystem.js +++ b/ui (gen4)/features/filesystem.js @@ -382,13 +382,15 @@ var FileSystemLoaderActions = actions.Actions({ !index && console.error('Failed to load index from:', paths) - // prepare the location data... - index.location = { - path: path, - loaded: loaded, - method: 'loadIndex', - } + index.location = + Object.assign( + index.location || {}, + { + path: path, + loaded: loaded, + load: 'loadIndex', + }) if(from_date){ index.location.from = from_date } @@ -597,7 +599,8 @@ var FileSystemLoaderActions = actions.Actions({ location: { path: path, - method: 'loadImages', + load: 'loadImages', + sync: 'syncIndexWithDir', } }) .then(function(){ @@ -675,7 +678,7 @@ var FileSystemLoaderActions = actions.Actions({ // XXX revise logger... // XXX revise alignment... - loadNewImages: ['File/Load new images', + loadNewImages: ['File/Load new images to index', core.doc`Load new images... Load new images from current path... @@ -691,6 +694,10 @@ var FileSystemLoaderActions = actions.Actions({ NOTE: this will not load images that are already loaded. `, + { locationSync: true, + mode: function(){ + return ['loadIndex', 'loadImages'].includes(this.location.load) + || 'disabled' }, }, function(path, logger){ path = path || this.location.path @@ -843,6 +850,8 @@ var FileSystemLoaderActions = actions.Actions({ NOTE: no actual data is removed. NOTE: this will not remove generated previews from index. `, + { locationSync: true, + mode: 'loadNewImages', }, function(logger){ var that = this logger = logger || this.logger @@ -887,7 +896,7 @@ var FileSystemLoaderActions = actions.Actions({ // XXX EXPERIMENTAL... // shorthand... - syncIndexWithDir: ['- File/', + syncIndexWithDir: ['File/Synchronize index to path', core.doc`Load new and remove deleted images... .syncIndexWithDir() @@ -898,6 +907,8 @@ var FileSystemLoaderActions = actions.Actions({ .loadNewImages() .removeMissingImages() `, + { locationSync: true, + mode: 'loadNewImages', }, function(logger){ return Promise.all([ this.loadNewImages(), @@ -1137,7 +1148,7 @@ var FileSystemLoaderUIActions = actions.Actions({ var dialog = this var path = that.location.path - if(that.location.method != 'loadIndex'){ + if(that.location.load != 'loadIndex'){ make('No indexes loaded...', null, true) return } @@ -1405,7 +1416,7 @@ var FileSystemSaveHistoryUIActions = actions.Actions({ // Unsaved changes will be saved to .unsaved_index when switching // from current to a historic state. // - // NOTE: this will show no history if .location.method is not 'loadIndex'.. + // NOTE: this will show no history if .location.load is not 'loadIndex'.. // NOTE: this will set changes to all when loading a historic state // that the latest and to non otherwise.... // @@ -1441,7 +1452,7 @@ var FileSystemSaveHistoryUIActions = actions.Actions({ } // only search for history if we have an index loaded... - if(that.location.method != 'loadIndex'){ + if(that.location.load != 'loadIndex'){ make('No history...', {disabled: true}) // select the 'Unsaved' item... @@ -1758,7 +1769,7 @@ var FileSystemWriterActions = actions.Actions({ } // XXX - if(path == null && this.location.method != 'loadIndex'){ + if(path == null && this.location.load != 'loadIndex'){ path = this.location.path } @@ -1798,7 +1809,7 @@ var FileSystemWriterActions = actions.Actions({ .spawn('attrib', ['+h', full_path]) }) .then(function(){ - location.method = 'loadIndex' + location.load = 'loadIndex' location.from = index.date //return location diff --git a/ui (gen4)/features/history.js b/ui (gen4)/features/history.js index 74f37ff3..c180683f 100755 --- a/ui (gen4)/features/history.js +++ b/ui (gen4)/features/history.js @@ -144,7 +144,7 @@ var URLHistoryActions = actions.Actions({ this.url_history = this.url_history || {} var item = !clear ? (this.url_history[url] || {}) : {} - open = item.open = open || this.location.method + open = item.open = open || this.location.load check = item.check = check || this.location.check || 'checkPath' // remove the old value... @@ -429,7 +429,7 @@ var URLHistoryLocalStorageActions = actions.Actions({ }) } - this.openURLFromHistory(l.path, l.method) + this.openURLFromHistory(l.path, l.load) } else { this.openURLFromHistory(0) @@ -514,17 +514,17 @@ module.URLHistoryFSWriter = core.ImageGridFeatures.Feature({ res.then(function(l){ // push saved to top... if(that.config['url-history-push-to-top-on-save']){ - that.pushURLToHistory(l.path, l.method) + that.pushURLToHistory(l.path, l.load) // update... } else { var e = that.url_history[l.path] if(e != null){ - e.open = l.method + e.open = l.load that.storeURLHistory() } else { - that.pushURLToHistory(l.path, l.method) + that.pushURLToHistory(l.path, l.load) } } }) diff --git a/ui (gen4)/features/keyboard.js b/ui (gen4)/features/keyboard.js index 24254fe1..132868b6 100755 --- a/ui (gen4)/features/keyboard.js +++ b/ui (gen4)/features/keyboard.js @@ -263,9 +263,7 @@ module.GLOBAL_KEYBOARD = { ctrl_F: 'F11', meta_F: 'F11', - // XXX EXPERIMENTAL: which should it be??? - //ctrl_R: 'loadNewImages!', - ctrl_R: 'syncIndexWithDir!', + ctrl_R: 'sync!', ctrl_alt_R: 'reload!', ctrl_shift_R: 'F5', @@ -616,7 +614,7 @@ var KeyboardActions = actions.Actions({ // check if we have no doc... if(doc == null || doc == ''){ - console.warn('Action has no doc: "' + console.warn('Action has no short doc: "' + a.action +'" at: "'+ code +'"') // XXX ??? return diff --git a/ui (gen4)/features/location.js b/ui (gen4)/features/location.js index 70cc554a..d92561ca 100755 --- a/ui (gen4)/features/location.js +++ b/ui (gen4)/features/location.js @@ -12,6 +12,7 @@ var object = require('lib/object') var actions = require('lib/actions') var features = require('lib/features') +var toggler = require('lib/toggler') var core = require('features/core') @@ -22,26 +23,17 @@ var core = require('features/core') // XXX need the other .location stuff to be visible/accessible... // ...now this only shows path... -var LocationProto = { +var Location = +//module.Location = +object.Constructor('Location', { get path(){ - return this.__actions.__location.path - }, + return this.__actions.__location.path }, set path(value){ - this.__actions.location = value - }, + this.__actions.location = value }, - __init__: function(actions){ - this.__actions = actions - - // XXX this does not work... - // ...the oother way around seems best: - // actions.__location.__proto__ = this - //this.__proto__ = actions.__location - }, -} - -var Location = object.Constructor('Location', LocationProto) + this.__actions = actions }, +}) @@ -59,13 +51,18 @@ var Location = object.Constructor('Location', LocationProto) var LocationActions = actions.Actions({ config: { 'default-load-method': null, + + 'location-stored-attrs': [ + 'sync', + ], }, // Format: // { - // path: , - // method: , // current: , + // load: , + // sync: , + // path: , // ... // } // @@ -100,10 +97,6 @@ var LocationActions = actions.Actions({ this.loadLocation(value) }, - clearLoaction: ['File/Clear location', - function(){ delete this.__location }], - - // Load location... // // Reload current location... @@ -131,7 +124,7 @@ var LocationActions = actions.Actions({ if(typeof(location) == typeof('str')){ location = { path: path, - method: (this.__location && this.__location.method) + load: (this.__location && this.__location.load) || this.config['default-load-method'], current: this.current, } @@ -142,8 +135,8 @@ var LocationActions = actions.Actions({ location = JSON.parse(JSON.stringify(location)) } - var method = location.method - || this.location.method + var load = location.load + || this.location.load || this.config['default-load-method'] var cur = location.current var path = location.path @@ -158,7 +151,7 @@ var LocationActions = actions.Actions({ //this.__location = location // NOTE: the method should set the proper location if it uses .clear()... - var res = method && this[method](path) + var res = load && this[load](path) // load current... @@ -177,6 +170,10 @@ var LocationActions = actions.Actions({ return res }], + clearLoaction: ['File/Clear location', + function(){ delete this.__location }], + + // XXX // XXX should these have the same effect as .dispatch('location:*:load', location)??? // ...another way to put it is should we call this from dispatch? @@ -186,20 +183,19 @@ var LocationActions = actions.Actions({ _loadLocation: ['- File/Save location', {protocol: 'location:*:load'}, function(location){ - this.location.method = this.locationMethod(location) + this.location.load = this.locationMethod(location) this.dispatch('location:*:load', location) }], _saveLocation: ['- File/Save location', {protocol: 'location:*:save'}, function(location){ - this.location.method = this.locationMethod(location) + this.location.load = this.locationMethod(location) this.dispatch('location:*:save', location) }], _locationMethod: ['- File/', {protocol: 'location:?'}, function(location){ - return (location || this.location).method || null }], - - + return (location || this.location).load || null }], + // // format: // { // 'protocol:method': 'actionName', @@ -212,8 +208,7 @@ var LocationActions = actions.Actions({ get protocols(){ var cache = this.__location_protocol_cache = this.__location_protocol_cache || this.cacheProtocols() - return cache - }, + return cache }, cacheProtocols: ['- File/', function(){ var that = this @@ -221,11 +216,8 @@ var LocationActions = actions.Actions({ this.actions.forEach(function(n){ var proto = that.getActionAttr(n, 'protocol') if(proto){ - res[proto] = n - } - }) - return res - }], + res[proto] = n } }) + return res }], // XXX how do we call the dispatched actions and all the matching // pattern actions??? // One way to go would be: @@ -316,6 +308,91 @@ var LocationActions = actions.Actions({ } }], + + // sync API... + // + get location_sync_methods(){ + var that = this + return (this.__location_sync_methods_cache = + this.__location_sync_methods_cache + || this.actions + .filter(function(n){ + return that.getActionAttr(n, 'locationSync') }) + .reduce(function(res, n){ + res[n] = + (that.getActionAttr(n, 'doc') || '') + .split(/[\\\/]/) + .pop() + res[n] = res[n] == '' ? + n + : res[n] + return res + }, {})) }, + + sync: ['- System/Synchronize index', + core.doc`Synchronize index... + + .sync() + -> promise + + + NOTE: it is up to the client to detect and implement the actual + sync mechanics. + NOTE: this expects the return value of the sync handler to be + a promise... + `, + function(){ + var method = this.location.sync + return method in this ? + // NOTE: this should return a promise... + this[method](...arguments) + : Promise.resolve() }], + + toggleSyncMethod: ['File/Index synchronization method', + core.doc`Toggle index synchronization method + + NOTE: this will not show disabled methods.`, + toggler.Toggler(null, + function(_, state){ + var dict = this.location_sync_methods + + // get... + if(state == null){ + return dict[this.location.sync] + || this.location.sync + || 'none' } + + // clear... + if(state == 'none'){ + delete this.location.sync + + // set... + } else { + // reverse dict... + var rdict = new Map( + Object.entries(dict) + .map(function([k, v]){ + return [v, k] })) + // normalize state to action name... + state = state in dict ? + state + : (rdict.get(state) || state) + this.location.sync = state + } + + this.markChanged + && this.markChanged('config') + }, + function(){ + var that = this + return ['none', + ...Object.entries(this.location_sync_methods) + .filter(function([n, d]){ + // do not list disabled methods... + return that.getActionMode(n) != 'disabled' }) + .map(function([n, d]){ return d }) ] })], + + // 1) store .location // 2) cleanup .images[..].base_path // @@ -335,9 +412,7 @@ var LocationActions = actions.Actions({ if(l.path == img.base_path){ delete img.base_path } - }) - } - }}], + }) } }}], load: [function(){ return function(_, data){ var that = this @@ -356,14 +431,12 @@ var LocationActions = actions.Actions({ if(img.base_path == null){ img.base_path = l.path } - }) - }}], + }) }}], clone: [function(){ return function(res){ if(this.location){ res.__location = JSON.parse(JSON.stringify(this.__location)) - } - }}], + } }}], clear: [function(){ this.clearLoaction() }], }) @@ -380,6 +453,36 @@ module.Location = core.ImageGridFeatures.Feature({ actions: LocationActions, handlers: [ + // handle: + // - local configuration... + // .location <-> .config + // XXX should this handle image .base_path ??? + ['prepareIndexForWrite', + function(res){ + if(res.changes === true || res.changes.config){ + var data = {} + ;(this.config['location-stored-attrs'] || []) + .forEach(function(attr){ + attr in res.raw.location + && (data[attr] = res.raw.location[attr]) }) + Object.keys(data).length > 0 + && (res.index.config = + Object.assign( + res.index.config || {}, + data)) } }], + ['prepareIndexForLoad', + function(res, json, base_path){ + if(json.config){ + var data = {} + ;(this.config['location-stored-attrs'] || []) + .forEach(function(attr){ + attr in json.config + && (data[attr] = json.config[attr]) }) + Object.keys(data).length > 0 + && (res.location = + Object.assign( + res.location || {}, + data)) } }], ], }) diff --git a/ui (gen4)/features/marks.js b/ui (gen4)/features/marks.js index 131cab3b..424fb760 100755 --- a/ui (gen4)/features/marks.js +++ b/ui (gen4)/features/marks.js @@ -257,37 +257,37 @@ var ImageMarkActions = actions.Actions({ }], prevMarked: ['Mark|Navigate/Previous marked image', - {browseMode: function(target){ + {mode: function(target){ return this.data.getImage('current', 'before', this.marked) == null && 'disabled' }}, function(mode){ this.prevTagged('marked', mode) }], nextMarked: ['Mark|Navigate/Next marked image', - {browseMode: function(target){ + {mode: function(target){ return this.data.getImage('current', 'after', this.marked) == null && 'disabled' }}, function(mode){ this.nextTagged('marked', mode) }], cropMarked: ['Mark|Crop/Crop $marked images', - {browseMode: function(target){ + {mode: function(target){ return this.marked.length == 0 && 'disabled' }}, 'crop: "marked" ...'], //function(flatten){ this.cropTagged('marked', flatten) }], //function(flatten){ this.cropTagged('marked', 'any', flatten) }], removeMarkedFromCrop: ['Mark|Crop/Remove marked from crop', - {browseMode: function(target){ + {mode: function(target){ return (this.marked.length == 0 || !this.cropped) && 'disabled' }}, 'removeFromCrop: marked'], rotateMarkedCW: ['Mark/Rotate marked clockwise', - {browseMode: 'cropMarked'}, + {mode: 'cropMarked'}, 'rotateCW: marked'], rotateMarkedCCW: ['Mark/Rotate marked counterclockwise', - {browseMode: 'cropMarked'}, + {mode: 'cropMarked'}, 'rotateCCW: marked'], flipMarkedVertical: ['Mark/Flip marked vertically', - {browseMode: 'cropMarked'}, + {mode: 'cropMarked'}, 'flipVertical: marked'], flipMarkedHorizontal: ['Mark/Flip marked horizontally', - {browseMode: 'cropMarked'}, + {mode: 'cropMarked'}, 'flipHorizontal: marked'], }) @@ -396,29 +396,29 @@ var ImageMarkEditActions = actions.Actions({ shiftMarkedUp: ['Mark/Shift marked u$p', {undo: undoShift('shiftMarkedDown'), - browseMode: 'cropMarked'}, + mode: 'cropMarked'}, shiftMarked('up')], shiftMarkedDown: ['Mark/Shift marked $down', {undo: undoShift('shiftMarkedUp'), - browseMode: 'cropMarked'}, + mode: 'cropMarked'}, shiftMarked('down')], // XXX undo... shiftMarkedAfter: ['Mark|Image/Shift marked $after', - {browseMode: 'cropMarked'}, + {mode: 'cropMarked'}, function(target){ this.shiftImageTo(this.marked, target || 'current', 'after') }], // XXX undo... shiftMarkedBefore: ['Mark|Image/Shift marked $b$efore', - {browseMode: 'cropMarked'}, + {mode: 'cropMarked'}, function(target){ this.shiftImageTo(this.marked, target || 'current', 'before') }], unmarkRibbon: ['Mark/Unmark ribbon', - {browseMode: 'cropMarked'}, + {mode: 'cropMarked'}, 'toggleMark: "ribbon" "off"'], unmarkLoaded: ['Mark/$Unmark all', - {browseMode: 'cropMarked'}, + {mode: 'cropMarked'}, 'toggleMark: "loaded" "off"'], }) @@ -445,7 +445,7 @@ var ImageMarkGroupActions = actions.Actions({ // NOTE: this will only group loaded images... groupMarked: ['Group|Mark/-70:Group loaded marked images', {journal: true, - browseMode: 'cropMarked'}, + mode: 'cropMarked'}, function(){ this.group(this.data.getImages(this.marked)) }], }) @@ -524,16 +524,16 @@ var ImageBookmarkActions = actions.Actions({ : this.data.sortViaOrder(this.data.tagQuery('bookmark')) }, prevBookmarked: ['Bookmark|Navigate/Previous bookmarked image', - {browseMode: function(target){ + {mode: function(target){ return this.data.getImage('current', 'before', this.bookmarked) == null && 'disabled' }}, function(mode){ this.prevTagged('bookmark', mode) }], nextBookmarked: ['Bookmark|Navigate/Next bookmarked image', - {browseMode: function(target){ + {mode: function(target){ return this.data.getImage('current', 'after', this.bookmarked) == null && 'disabled' }}, function(mode){ this.nextTagged('bookmark', mode) }], cropBookmarked: ['Bookmark|Crop/Crop $bookmarked images', - {browseMode: function(target){ + {mode: function(target){ return this.bookmarked.length == 0 && 'disabled' }}, 'crop: "bookmarked" ...'], //function(flatten){ this.cropTagged('bookmark', 'any', flatten) }], @@ -572,7 +572,7 @@ var ImageBookmarkEditActions = actions.Actions({ // 'off' - toggle all off // 'next' - toggle each image to next state toggleBookmarkOnMarked: ['Bookmark|Mark/-70:Toggle bookmark on maked images', - {browseMode: 'cropMarked'}, + {mode: 'cropMarked'}, function(action){ return this.toggleBookmark(this.marked, action) }], }) diff --git a/ui (gen4)/features/metadata.js b/ui (gen4)/features/metadata.js index 3eb75247..0b015019 100755 --- a/ui (gen4)/features/metadata.js +++ b/ui (gen4)/features/metadata.js @@ -352,7 +352,7 @@ var MetadataUIActions = actions.Actions({ function(){ return this.config['metadata-auto-select-modes'] })], toggleMetadataGraph: ['Interface/Metadata graph display', - { browseMode: function(){ + { mode: function(){ return (!graph || this.config['browse-advanced-mode'] != 'on') && 'hidden' }}, core.makeConfigToggler('metadata-graph', ['on', 'off'])], diff --git a/ui (gen4)/features/tags.js b/ui (gen4)/features/tags.js index fe3811e9..25c91d38 100755 --- a/ui (gen4)/features/tags.js +++ b/ui (gen4)/features/tags.js @@ -172,7 +172,7 @@ module.TagsEditActions = actions.Actions({ // NOTE: setting source to 'both' and mode to 'reset' is the same as // 'images' and 'reset' as all .data tags will be lost on first // pass... - syncTags: ['Tag/-10:Synchoronize tags between data and images', + syncTags: ['Tag/-10:Synchronize tags between data and images', {journal: true}, function(source, mode){ // can't do anything if either .data or .images are not diff --git a/ui (gen4)/features/ui-partial-ribbons-precache.js b/ui (gen4)/features/ui-partial-ribbons-precache.js index eea5fcad..1951db61 100755 --- a/ui (gen4)/features/ui-partial-ribbons-precache.js +++ b/ui (gen4)/features/ui-partial-ribbons-precache.js @@ -28,7 +28,7 @@ var PreCacheActions = actions.Actions({ // NOTE: this will not work from chrome when loading from a local fs... // XXX experimental... startCacheWorker: ['Interface/', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, function(){ // a worker is started already... if(this.cacheWorker != null){ @@ -63,7 +63,7 @@ var PreCacheActions = actions.Actions({ this.cacheWorker.url = url }], stopCacheWorker: ['Interface/', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, function(){ if(this.cacheWorker){ this.cacheWorker.terminate() diff --git a/ui (gen4)/features/ui-ranges.js b/ui (gen4)/features/ui-ranges.js index 6299e00f..68482f29 100755 --- a/ui (gen4)/features/ui-ranges.js +++ b/ui (gen4)/features/ui-ranges.js @@ -101,7 +101,7 @@ var RangeActions = actions.Actions({ }], clearRange: ['Range/Clear range', // XXX not sure if this is the right way to go... - {browseMode: function(){ return !this.data.__range && 'disabled' }}, + {mode: function(){ return !this.data.__range && 'disabled' }}, function(image){ var r = this.dom.find('.ribbon') @@ -162,7 +162,7 @@ var RangeActions = actions.Actions({ cropRange: ['Range|Crop/Crop range', // XXX not sure if this is the right way to go... - {browseMode: function(){ return !this.data.__range && 'disabled' }}, + {mode: function(){ return !this.data.__range && 'disabled' }}, function(){ var range = this.data.__range var order = this.data.order @@ -175,7 +175,7 @@ var RangeActions = actions.Actions({ }], cropRangeOut: ['Range|Crop/Crop out range', // XXX not sure if this is the right way to go... - {browseMode: function(){ return !this.data.__range && 'disabled' }}, + {mode: function(){ return !this.data.__range && 'disabled' }}, function(){ var range = this.data.__range var order = this.data.order diff --git a/ui (gen4)/features/ui-slideshow.js b/ui (gen4)/features/ui-slideshow.js index 5263c170..154852ba 100755 --- a/ui (gen4)/features/ui-slideshow.js +++ b/ui (gen4)/features/ui-slideshow.js @@ -224,7 +224,7 @@ var SlideshowActions = actions.Actions({ NOTE: this will have no effect if the slideshow is not running... `, - {browseMode: function(){ return this.toggleSlideshow('?') == 'off' && 'disabled' }}, + {mode: function(){ return this.toggleSlideshow('?') == 'off' && 'disabled' }}, toggler.Toggler(null, function(_, state){ if(state == null){ diff --git a/ui (gen4)/features/ui-status.js b/ui (gen4)/features/ui-status.js index 1dd1e267..f5659541 100755 --- a/ui (gen4)/features/ui-status.js +++ b/ui (gen4)/features/ui-status.js @@ -852,12 +852,12 @@ var StatusLogActions = actions.Actions({ // XXX should this be here or in a separate feature??? statusLog: ['Interface/Show status log', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, function(){ // XXX use list }], clearStatusLog: ['Interface/Clear status log', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, function(){ delete this.__status_log }], diff --git a/ui (gen4)/features/ui-widgets.js b/ui (gen4)/features/ui-widgets.js index ccf91bf9..6a3c6fc1 100755 --- a/ui (gen4)/features/ui-widgets.js +++ b/ui (gen4)/features/ui-widgets.js @@ -904,7 +904,7 @@ var DialogsActions = actions.Actions({ listDialogs: ['Interface|System/Dialog/Dialog list...', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, makeUIDialog(function(){ var actions = this @@ -931,7 +931,7 @@ var DialogsActions = actions.Actions({ })], toggleOverlayBlur: ['Interface/Dialog overlay blur', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, toggler.CSSClassToggler( function(){ return this.dom }, 'overlay-blur-enabled', @@ -2587,7 +2587,7 @@ var BrowseActionsActions = actions.Actions({ // ...this would help with the (global) search -- switch to // flat if searching in root mode... browseActions: ['Interface/Dialog/Actions...', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, core.doc`Browse actions dialog... This uses action definition to build and present an action tree. @@ -2615,33 +2615,33 @@ var BrowseActionsActions = actions.Actions({ Action mode (disabled/hidden) and also be controlled dynamically: - - .browseMode() action method is called with actions as base. + - .mode() action method is called with actions as base. Example: someAction: ['Path/To/Some action', - {browseMode: function(){ ... }}, + {mode: function(){ ... }}, function(){ ... }], someOtherAction: ['Path/To/Some action', // alias - {browseMode: 'someAction'}, + {mode: 'someAction'}, function(){ ... }], - .browseMode can be: + .mode can be: - action method. - alias, name of action to get the method from. - .browseMode() can return: + .mode() can return: 'disabled' - item will be disabled. 'hidden' - item will be both hidden and disabled. - NOTE: disabling in path has priority over .browseMode(), thus + NOTE: disabling in path has priority over .mode(), thus it is possible to hide/disable an enabled item but not possible to enable a disabled by default path. - NOTE: .browseMode() can be defined in any action in chain, + NOTE: .mode() can be defined in any action in chain, though only the last one is called... @@ -2704,52 +2704,12 @@ var BrowseActionsActions = actions.Actions({ // Get action browse mode (disabled or hidden)... // - // NOTE: this will cache and reuse action's browseMode, this + // NOTE: this will cache and reuse action's mode, this // will make things faster when lots of actions use the // same mode test (alias)... var mode_cache = {} var getMode = function(action){ - var m = action - var visited = [m] - var last - - // check cache... - if(m in (mode_cache || {})){ - return mode_cache[m] - } - - // handle aliases... - do { - last = m - m = actions.getActionAttr(m, 'browseMode') - - // check cache... - if(m in (mode_cache || {})){ - return mode_cache[m] - } - - // check for loops... - if(m && visited[m] != null){ - m = null - break - } - visited.push(m) - } while(typeof(m) == typeof('str')) - - //return m ? m.call(actions) : undefined - return m ? - // no cache... - (mode_cache == null ? - m.call(actions) - // cache hit... - : last in mode_cache ? - mode_cache[last] - // call check and populate cache... - : (mode_cache[action] = - mode_cache[last] = - m.call(actions))) - : undefined - } + return actions.getActionMode(action, mode_cache) } // Wait for dialog... var waitFor = function(dialog, child){ @@ -2944,7 +2904,7 @@ var BrowseActionsActions = actions.Actions({ false // hide dirs containing only (statically) // hidden items... - // NOTE: we are not checking browseMode + // NOTE: we are not checking mode // of other items actively here at // this point to avoid side-effects... : Object.keys(cur[key]) @@ -2988,7 +2948,7 @@ var BrowseActionsActions = actions.Actions({ ['off', 'on'])], toggleBrowseActionKeys: ['Interface/Show keys in menu', - {browseMode: function(){ + {mode: function(){ return this.config['browse-advanced-mode'] != 'on' && 'hidden' }}, core.makeConfigToggler( 'browse-actions-keys', @@ -3034,7 +2994,7 @@ module.ContextActionMenu = core.ImageGridFeatures.Feature({ actions: actions.Actions({ showContextMenu: ['Interface/Show context menu...', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, uiDialog(function(){ return this.current ? this.browseActions('/Image/') @@ -3193,13 +3153,13 @@ var ButtonsActions = actions.Actions({ }, toggleMainButtons: ['Interface/Main buttons', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, makeButtonControlsToggler('main-buttons')], toggleSecondaryButtons: ['Interface/Secondary buttons', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, makeButtonControlsToggler('secondary-buttons')], toggleAppButtons: ['Interface/App buttons', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, makeButtonControlsToggler('app-buttons')], toggleSideButtons: ['Interface/70: Touch buttons', @@ -3216,7 +3176,7 @@ var ButtonsActions = actions.Actions({ })()], toggleButtonHighlightColor: ['Interface/Theme/Button highlight color', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, core.makeConfigToggler( 'button-highlight-color', function(){ return this.config['button-highlight-colors'] }, diff --git a/ui (gen4)/features/ui.js b/ui (gen4)/features/ui.js index 00578054..ffc5b843 100755 --- a/ui (gen4)/features/ui.js +++ b/ui (gen4)/features/ui.js @@ -361,7 +361,7 @@ module.ViewerActions = actions.Actions({ .centerImage(target) .centerRibbon(target) }], alignRibbons: ['Interface/Align ribbons', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, function(target, scale, now){ if(target == 'now'){ now = true @@ -392,7 +392,7 @@ module.ViewerActions = actions.Actions({ // XXX skip off-screen ribbons (???) // XXX should the timeout be configurable??? alignByOrder: ['Interface/Align ribbons by image order', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, function(target, scale, now){ if(target == 'now'){ now = true @@ -457,7 +457,7 @@ module.ViewerActions = actions.Actions({ } }], alignByFirst: ['Interface/Align ribbons except current to first image', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, function(target){ target = target == 'now' ? null : target @@ -591,7 +591,7 @@ module.ViewerActions = actions.Actions({ // Zooming is done by multiplying the current scale by .config['zoom-step'] // and rounding to nearest discrete number of images to fit on screen. zoomIn: ['Zoom/Zoom in', - {browseMode: function(){ + {mode: function(){ return Math.min(this.screenwidth, this.screenheight) <= 1 && 'disabled' }}, function(){ var d = (this.config['zoom-step'] || 1.2) @@ -606,7 +606,7 @@ module.ViewerActions = actions.Actions({ } }], zoomOut: ['Zoom/Zoom out', - {browseMode: function(){ + {mode: function(){ return this.screenwidth >= this.config['max-screen-images'] && 'disabled' }}, function(){ var max = this.config['max-screen-images'] @@ -647,7 +647,7 @@ module.ViewerActions = actions.Actions({ this.ribbonRotation('-='+ (a || this.config['ribbon-rotation-step'] || 10)) }], resetRibbonRotation: ['Interface|Ribbon/Reset ribbon rotation', - {browseMode: function(){ + {mode: function(){ return this.ribbonRotation() == 0 && 'disabled' }}, function(){ this.ribbonRotation(0) }], @@ -656,7 +656,7 @@ module.ViewerActions = actions.Actions({ // XXX make this play nice with crops... // ...should this be a crop??? toggleRibbonList: ['Interface|Ribbon/Ribbons as images view', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, function(){ if(this._full_data == null){ // XXX do a better name here... @@ -697,7 +697,7 @@ module.ViewerActions = actions.Actions({ function(angle){ }], toggleImageRendering: ['Interface/Image rendering', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, toggler.CSSClassToggler( function(){ return this.dom }, ['crisp-resize', 'default-resize'], @@ -936,7 +936,7 @@ module.Cursor = core.ImageGridFeatures.Feature({ actions: actions.Actions({ toggleHiddenCursor: ['Interface/Cursor hidden', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, toggler.CSSClassToggler( function(){ return this.dom }, 'cursor-hidden', @@ -1011,7 +1011,7 @@ module.Cursor = core.ImageGridFeatures.Feature({ // .config['cursor-show-threshold'] // toggleAutoHideCursor: ['Interface/Cursor auto-hide', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, toggler.CSSClassToggler( function(){ return this.dom }, 'cursor-autohide', @@ -1127,13 +1127,13 @@ module.Cursor = core.ImageGridFeatures.Feature({ })], toggleAutoHideCursorTimeout: ['Interface/Hide cursor on timeout', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, core.makeConfigToggler('cursor-autohide-on-timeout', ['on', 'off'], function(){ this.toggleAutoHideCursor('!') })], toggleAutoHideCursorKeyboard: ['Interface/Hide cursor on keyboard', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, core.makeConfigToggler('cursor-autohide-on-keyboard', ['on', 'off'], function(){ @@ -1224,7 +1224,7 @@ var ControlActions = actions.Actions({ from reaching the viewer. NOTE: this defines the focus/blur handlers on the window object.`, - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, core.makeConfigToggler('lock-unfocused', ['off', 'on'], function(state){ @@ -1378,7 +1378,7 @@ var ControlActions = actions.Actions({ // XXX depends on .ribbons... // XXX uses: .focusImage(..) toggleImageClickHandling: ['Interface/Image click handling', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, toggler.Toggler(null, function(_, new_state){ return new_state ? @@ -1631,7 +1631,7 @@ var ControlActions = actions.Actions({ // XXX depends on .ribbons... // XXX uses: .focusImage(..) toggleRibbonPanHandling: ['Interface/Ribbon pan handling', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, toggler.Toggler(null, function(_, new_state){ return new_state ? @@ -1871,7 +1871,7 @@ var ControlActions = actions.Actions({ // XXX depends on .ribbons... // XXX uses: .focusImage(..) toggleMouseWheelHandling: ['Interface/Mouse wheel handling', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, toggler.Toggler(null, function(_, new_state){ return new_state ? @@ -1976,7 +1976,7 @@ var ControlActions = actions.Actions({ })], togglePinchHandling: ['Interface/Pinch zoom handling', - {browseMode: 'toggleBrowseActionKeys'}, + {mode: 'toggleBrowseActionKeys'}, function(){ // XXX }], @@ -1986,7 +1986,7 @@ var ControlActions = actions.Actions({ // ...allow ui features to control this... // XXX depends on .ribbons... toggleSwipeHandling: ['Interface/Swipe handling', - //{browseMode: 'toggleBrowseActionKeys'}, + //{mode: 'toggleBrowseActionKeys'}, toggler.Toggler(null, function(_, state){ return state ? diff --git a/ui (gen4)/features/virtual-blocks.js b/ui (gen4)/features/virtual-blocks.js index ac1a4357..fd42afc4 100644 --- a/ui (gen4)/features/virtual-blocks.js +++ b/ui (gen4)/features/virtual-blocks.js @@ -98,7 +98,7 @@ var VirtualBlocksActions = actions.Actions({ ... } `, - { browseMode: function(){ return !this.collection && 'disabled' }, }, + { mode: function(){ return !this.collection && 'disabled' }, }, function(ref, offset, img){ ref = ref || 'current' offset = offset || 'after' @@ -153,11 +153,11 @@ var VirtualBlocksActions = actions.Actions({ core.doc`Add block before... This is the same as .makeVirtualBlock(.., 'before', ..)`, - { browseMode: 'makeVirtualBlock', }, + { mode: 'makeVirtualBlock', }, 'makeVirtualBlock: $0 "before" ...'], cloneVirtualBlock: ['Virtual block/$Clone block', - { browseMode: function(){ + { mode: function(){ return (this.image || {}).type != 'virtual' && 'disabled' }, }, function(ref, offset, img){ var img = Object.assign({}, @@ -169,15 +169,15 @@ var VirtualBlocksActions = actions.Actions({ // crop... // XXX would be nice to avoid these and just register a list and context... cropVirtualBlocks: ['Virtual block|Crop/$Crop $virtual $blocks', - { browseMode: 'makeVirtualBlock' }, + { mode: 'makeVirtualBlock' }, 'crop: "virtual" ...'], cropVirtualBlocksOut: ['Virtual block|Crop/Crop virtual blocks out', - { browseMode: 'cropVirtualBlocks' }, + { mode: 'cropVirtualBlocks' }, 'crop: "!virtual" ...'], // marks... toggleMarkVirtualBlocks: ['Virtual block|Mark/Toggle $mark on $virtual blocks', - { browseMode: 'makeVirtualBlock' }, + { mode: 'makeVirtualBlock' }, 'toggleMark: "virtual"'], // remove... @@ -358,7 +358,7 @@ var VirtualBlocksEditUIActions = actions.Actions({ // XXX should we also add a preview (preview constructor from features/metadata.js)??? // XXX should we do a sanity check for image type??? editVirtualBlock: ['Virtual block/$Edit...', - { browseMode: 'cloneVirtualBlock' }, + { mode: 'cloneVirtualBlock' }, widgets.makeUIDialog(function(gid){ var that = this