action .mode -> .browseMode, reworked .sync(..) (ctrl_R)...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2020-05-20 20:31:19 +03:00
parent d912ce2ebe
commit 78cb4bdff8
20 changed files with 372 additions and 245 deletions

View File

@ -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){

View File

@ -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

View File

@ -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) })],
})

View File

@ -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
}

View File

@ -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){

View File

@ -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]) }],

View File

@ -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

View File

@ -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)
}
}
})

View File

@ -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

View File

@ -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: <base-path>,
// method: <load-method>,
// current: <current-gid>,
// load: <load-method>,
// sync: <sync-method>,
// path: <base-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)) } }],
],
})

View File

@ -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) }],
})

View File

@ -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'])],

View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -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){

View File

@ -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
}],

View File

@ -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:
<function> - action method.
<action-name> - 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'] },

View File

@ -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 ?

View File

@ -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