mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-30 02:40:08 +00:00
simplified the custom dialog constructing -- still not too happy with it + some preliminary work on exporting...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
de0136c614
commit
4063cc4898
@ -33,6 +33,15 @@ var browseWalk = require('lib/widget/browse-walk')
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************************************/
|
||||||
|
|
||||||
|
if(typeof(process) != 'undefined'){
|
||||||
|
var copy = file.denodeify(fse.copy)
|
||||||
|
var ensureDir = file.denodeify(fse.ensureDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
// fs reader/loader...
|
// fs reader/loader...
|
||||||
|
|
||||||
@ -758,17 +767,21 @@ var FileSystemWriterActions = actions.Actions({
|
|||||||
exportView: ['File/Export current view',
|
exportView: ['File/Export current view',
|
||||||
function(){
|
function(){
|
||||||
}],
|
}],
|
||||||
// XXX not done yet...
|
|
||||||
// needs:
|
// Export current state as a full loadable index
|
||||||
// ensureDir(..)
|
//
|
||||||
// copy(..)
|
|
||||||
// ...both denodeify(..)'ed
|
|
||||||
// XXX export current state as a full loadable index
|
|
||||||
// XXX might be interesting to unify this and .exportView(..)
|
// XXX might be interesting to unify this and .exportView(..)
|
||||||
// XXX should this return a promise??? ...a clean promise???
|
// XXX should this return a promise??? ...a clean promise???
|
||||||
|
// XXX add preview selection...
|
||||||
|
// XXX handle .image.path and other stack files...
|
||||||
// XXX local collections???
|
// XXX local collections???
|
||||||
|
// XXX add a ui...
|
||||||
|
// - select path
|
||||||
|
// - select preview size
|
||||||
exportCollection: ['File/Export as collection',
|
exportCollection: ['File/Export as collection',
|
||||||
function(path, logger){
|
function(path, logger){
|
||||||
|
logger = logger || this.logger
|
||||||
|
|
||||||
var json = this.json()
|
var json = this.json()
|
||||||
|
|
||||||
// get all loaded gids...
|
// get all loaded gids...
|
||||||
@ -785,6 +798,7 @@ var FileSystemWriterActions = actions.Actions({
|
|||||||
var img = json.images[gid]
|
var img = json.images[gid]
|
||||||
if(img){
|
if(img){
|
||||||
images[gid] = json.images[gid]
|
images[gid] = json.images[gid]
|
||||||
|
|
||||||
// remove un-needed previews...
|
// remove un-needed previews...
|
||||||
// XXX
|
// XXX
|
||||||
}
|
}
|
||||||
@ -794,27 +808,28 @@ var FileSystemWriterActions = actions.Actions({
|
|||||||
json.data.order = gids
|
json.data.order = gids
|
||||||
json.images = images
|
json.images = images
|
||||||
// XXX should we check if index dir is present in path???
|
// XXX should we check if index dir is present in path???
|
||||||
path = path +'/'+ this.config['index-dir']
|
var index_path = path +'/'+ this.config['index-dir']
|
||||||
|
|
||||||
// NOTE: if we are to use .saveIndex(..) here, do not forget
|
|
||||||
// to reset .changes
|
|
||||||
file.writeIndex(
|
|
||||||
this.prepareIndexForWrite(json).prepared,
|
|
||||||
path,
|
|
||||||
this.config['index-filename-template'],
|
|
||||||
logger || this.logger)
|
|
||||||
|
|
||||||
// copy previews for the loaded images...
|
// copy previews for the loaded images...
|
||||||
// XXX should also optionally populate the base dir and nested favs...
|
// XXX should also optionally populate the base dir and nested favs...
|
||||||
var base_dir = this.base_dir
|
var base_dir = this.location.path
|
||||||
|
|
||||||
gids.forEach(function(gid){
|
gids.forEach(function(gid){
|
||||||
var img = json.images[gid]
|
var img = json.images[gid]
|
||||||
var img_base = img.base_path
|
var img_base = img.base_path
|
||||||
img.base_path = path
|
|
||||||
var previews = img.preview
|
var previews = img.preview
|
||||||
|
|
||||||
for(var res in previews){
|
// NOTE: we are copying everything to one place so no
|
||||||
var from = (img_base || base_dir) +'/'+ preview_path
|
// need for a base path...
|
||||||
|
delete img.base_path
|
||||||
|
|
||||||
|
// XXX copy img.path -- the main image, especially when no previews present....
|
||||||
|
// XXX
|
||||||
|
|
||||||
|
Object.keys(previews).forEach(function(res){
|
||||||
|
var preview_path = decodeURI(previews[res])
|
||||||
|
|
||||||
|
var from = (img_base || base_dir) +'/'+ preview_path
|
||||||
var to = path +'/'+ preview_path
|
var to = path +'/'+ preview_path
|
||||||
|
|
||||||
// XXX do we queue these or let the OS handle it???
|
// XXX do we queue these or let the OS handle it???
|
||||||
@ -823,7 +838,7 @@ var FileSystemWriterActions = actions.Actions({
|
|||||||
// XXX
|
// XXX
|
||||||
ensureDir(pathlib.dirname(to))
|
ensureDir(pathlib.dirname(to))
|
||||||
.catch(function(err){
|
.catch(function(err){
|
||||||
// XXX
|
logger && logger.emit('error', err)
|
||||||
})
|
})
|
||||||
.then(function(){
|
.then(function(){
|
||||||
return copy(from, to)
|
return copy(from, to)
|
||||||
@ -832,12 +847,99 @@ var FileSystemWriterActions = actions.Actions({
|
|||||||
// we just use the one above (after
|
// we just use the one above (after
|
||||||
// .then(..))
|
// .then(..))
|
||||||
.catch(function(err){
|
.catch(function(err){
|
||||||
// XXX
|
logger && logger.emit('error', err)
|
||||||
|
})
|
||||||
|
.then(function(){
|
||||||
|
logger && logger.emit('done', to)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// NOTE: if we are to use .saveIndex(..) here, do not forget
|
||||||
|
// to reset .changes
|
||||||
|
file.writeIndex(
|
||||||
|
this.prepareIndexForWrite(json, true).prepared,
|
||||||
|
index_path,
|
||||||
|
this.config['index-filename-template'],
|
||||||
|
logger || this.logger)
|
||||||
|
|
||||||
}],
|
}],
|
||||||
|
|
||||||
|
// XXX use options:
|
||||||
|
// - level dir name
|
||||||
|
// - size
|
||||||
|
// - filename pattern
|
||||||
|
// XXX might also be good to save/load the export state to .ImageGrid-export.json
|
||||||
|
// XXX make custom previews...
|
||||||
|
// ...should this be a function of .images.getBestPreview(..)???
|
||||||
|
exportDirs: ['File/Export as nested directories',
|
||||||
|
function(path, pattern, level_dir, size, logger){
|
||||||
|
logger = logger || this.logger
|
||||||
|
var that = this
|
||||||
|
var base_dir = this.location.path
|
||||||
|
var to_dir = path
|
||||||
|
|
||||||
|
// get/set the config data...
|
||||||
|
// XXX should this store the last set???
|
||||||
|
level_dir = level_dir || this.config['export-level-directory-name'] || 'fav'
|
||||||
|
size = size || this.config['export-preview-size'] || 1000
|
||||||
|
pattern = pattern || this.config['export-preview-name-pattern'] || '%f'
|
||||||
|
|
||||||
|
this.data.ribbon_order
|
||||||
|
.slice()
|
||||||
|
.reverse()
|
||||||
|
.forEach(function(ribbon){
|
||||||
|
// NOTE: this is here to keep the specific path local to
|
||||||
|
// this scope...
|
||||||
|
var img_dir = to_dir
|
||||||
|
|
||||||
|
ensureDir(pathlib.dirname(img_dir))
|
||||||
|
.catch(function(err){
|
||||||
|
logger && logger.emit('error', err)
|
||||||
|
})
|
||||||
|
.then(function(){
|
||||||
|
that.data.ribbons[ribbon].forEach(function(gid){
|
||||||
|
var img = that.images[gid]
|
||||||
|
|
||||||
|
|
||||||
|
// get best preview...
|
||||||
|
var from = (img.base_path || base_dir) +'/'+ that.images.getBestPreview(gid, size).url
|
||||||
|
|
||||||
|
// XXX see if we need to make a preview (sharp)
|
||||||
|
// XXX
|
||||||
|
|
||||||
|
// XXX get/form image name...
|
||||||
|
// XXX might be a good idea to connect this to the info framework...
|
||||||
|
var ext = pathlib.extname(img.name)
|
||||||
|
var name = pattern
|
||||||
|
.replace(/%f/, img.name)
|
||||||
|
.replace(/%n/, img.name.replace(ext, ''))
|
||||||
|
.replace(/%e/, ext)
|
||||||
|
.replace(/%gid/, gid)
|
||||||
|
// XXX get the correct length...
|
||||||
|
.replace(/%g/, gid.slice(-7, -1))
|
||||||
|
// XXX %()m marked...
|
||||||
|
// XXX
|
||||||
|
// XXX %()b bookmarked...
|
||||||
|
// XXX
|
||||||
|
// XXX EXIF...
|
||||||
|
|
||||||
|
var to = img_dir +'/'+ name
|
||||||
|
|
||||||
|
copy(from, to)
|
||||||
|
.catch(function(err){
|
||||||
|
logger && logger.emit('error', err)
|
||||||
|
})
|
||||||
|
.then(function(){
|
||||||
|
logger && logger.emit('done', to)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
to_dir += '/'+level_dir
|
||||||
|
})
|
||||||
|
}]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -57,33 +57,25 @@ var SlideshowActions = actions.Actions({
|
|||||||
|
|
||||||
this.suspendSlideshowTimer()
|
this.suspendSlideshowTimer()
|
||||||
|
|
||||||
|
// XXX might be a good idea to make this generic...
|
||||||
|
var _makeTogglHandler = function(toggler){
|
||||||
|
return function(){
|
||||||
|
var txt = $(this).find('.text').first().text()
|
||||||
|
that[toggler]()
|
||||||
|
o.client.update()
|
||||||
|
.then(function(){ o.client.select(txt) })
|
||||||
|
that.toggleSlideshow('?') == 'on'
|
||||||
|
&& o.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var o = overlay.Overlay(this.ribbons.viewer,
|
var o = overlay.Overlay(this.ribbons.viewer,
|
||||||
browse.makeList(
|
browse.makeLister(null, function(path, make){
|
||||||
null,
|
make(['Interval: ',
|
||||||
[
|
function(){ return that.config['slideshow-interval'] }])
|
||||||
// XXX make this editable...
|
.on('open', function(){
|
||||||
['Interval: ',
|
var txt = $(this).find('.text').first().text()
|
||||||
function(){ return that.config['slideshow-interval'] }],
|
|
||||||
['Direction: ',
|
|
||||||
function(){ return that.config['slideshow-direction'] }],
|
|
||||||
['Looping: ',
|
|
||||||
function(){ return that.config['slideshow-looping'] }],
|
|
||||||
|
|
||||||
//'---',
|
|
||||||
[function(){
|
|
||||||
return that.toggleSlideshow('?') == 'on' ? 'Stop' : 'Start' }],
|
|
||||||
])
|
|
||||||
.open(function(evt, path){
|
|
||||||
// start/stop...
|
|
||||||
if(path == 'Start' || path == 'Stop'){
|
|
||||||
that.toggleSlideshow()
|
|
||||||
o.close()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// interval...
|
|
||||||
if(/interval/i.test(path)){
|
|
||||||
var to_remove = []
|
|
||||||
var oo = widgets.makeConfigListEditor(that, 'slideshow-intervals', {
|
var oo = widgets.makeConfigListEditor(that, 'slideshow-intervals', {
|
||||||
new_button: 'New...',
|
new_button: 'New...',
|
||||||
length_limit: that.config['slideshow-interval-max-count'],
|
length_limit: that.config['slideshow-interval-max-count'],
|
||||||
@ -107,9 +99,8 @@ var SlideshowActions = actions.Actions({
|
|||||||
// XXX this is ugly...
|
// XXX this is ugly...
|
||||||
o.focus()
|
o.focus()
|
||||||
|
|
||||||
if(that.toggleSlideshow('?') == 'on'){
|
that.toggleSlideshow('?') == 'on'
|
||||||
o.close()
|
&& o.close()
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
oo.client
|
oo.client
|
||||||
@ -122,42 +113,36 @@ var SlideshowActions = actions.Actions({
|
|||||||
|
|
||||||
// XXX this is ugly...
|
// XXX this is ugly...
|
||||||
oo.close()
|
oo.close()
|
||||||
|
|
||||||
o.client.update()
|
o.client.update()
|
||||||
o.client.select(path.split(':')[0])
|
o.client.select(txt)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
oo.client.dom.addClass('tail-action')
|
oo.client.dom.addClass('tail-action')
|
||||||
oo.client.select(that.config['slideshow-interval'])
|
oo.client.select(that.config['slideshow-interval'])
|
||||||
|
})
|
||||||
|
|
||||||
return
|
make(['Direction: ',
|
||||||
}
|
function(){ return that.config['slideshow-direction'] }])
|
||||||
|
.on('open', _makeTogglHandler('toggleSlideshowDirection'))
|
||||||
|
make(['Looping: ',
|
||||||
|
function(){ return that.config['slideshow-looping'] }])
|
||||||
|
.on('open', _makeTogglHandler('toggleSlideshowLooping'))
|
||||||
|
|
||||||
// direction...
|
// Start/stop...
|
||||||
if(/direction/i.test(path)){
|
make([function(){
|
||||||
that.toggleSlideshowDirection()
|
return that.toggleSlideshow('?') == 'on' ? 'Stop' : 'Start' }])
|
||||||
o.client.update()
|
.on('open', function(){
|
||||||
|
that.toggleSlideshow()
|
||||||
// Looping...
|
|
||||||
} else if(/looping/i.test(path)){
|
|
||||||
that.toggleSlideshowLooping()
|
|
||||||
o.client.update()
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX this is ugly...
|
|
||||||
o.client.select(path.split(':')[0])
|
|
||||||
|
|
||||||
// do not keep the dialog open during the slideshow...
|
|
||||||
if(that.toggleSlideshow('?') == 'on'){
|
|
||||||
o.close()
|
o.close()
|
||||||
}
|
})
|
||||||
}))
|
}))
|
||||||
.close(function(){
|
.close(function(){
|
||||||
that.resetSlideshowTimer()
|
that.resetSlideshowTimer()
|
||||||
})
|
})
|
||||||
|
|
||||||
o.client.dom.addClass('metadata-view tail-action')
|
o.client.dom.addClass('metadata-view tail-action')
|
||||||
|
|
||||||
o.client.select(-1)
|
o.client.select(-1)
|
||||||
|
|
||||||
return o
|
return o
|
||||||
|
|||||||
@ -94,8 +94,15 @@ function listJSON(path, pattern){
|
|||||||
return gGlob(path +'/'+ pattern +'.json')
|
return gGlob(path +'/'+ pattern +'.json')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// wrap a node style callback function into a Promise...
|
||||||
|
//
|
||||||
|
// NOTE: this is inspired by the promise module for node this stopped
|
||||||
|
// working, and porting one method was simpler that trying to get
|
||||||
|
// to the bottom of the issue, especially with native promises...
|
||||||
// XXX move to someplace generic...
|
// XXX move to someplace generic...
|
||||||
var denodeify = function(func){
|
var denodeify =
|
||||||
|
module.denodeify =
|
||||||
|
function(func){
|
||||||
return function(){
|
return function(){
|
||||||
// XXX for some reason this does not see args2array...
|
// XXX for some reason this does not see args2array...
|
||||||
// XXX and for some reason the error is not reported...
|
// XXX and for some reason the error is not reported...
|
||||||
|
|||||||
@ -2189,6 +2189,48 @@ Browser.prototype.__proto__ = widget.Widget.prototype
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************************************/
|
||||||
|
|
||||||
|
var ListerPrototype = Object.create(BrowserPrototype)
|
||||||
|
ListerPrototype.options = {
|
||||||
|
pathPrefix: '',
|
||||||
|
fullPathEdit: false,
|
||||||
|
traversable: false,
|
||||||
|
flat: true,
|
||||||
|
|
||||||
|
// XXX not sure if we need these...
|
||||||
|
skipDisabledItems: false,
|
||||||
|
// NOTE: to disable this set it to false or null
|
||||||
|
disableItemPattern: '^- ',
|
||||||
|
|
||||||
|
elementSeparatorText: '---',
|
||||||
|
}
|
||||||
|
// XXX should we inherit or copy options???
|
||||||
|
// ...inheriting might pose problems with deleting values reverting
|
||||||
|
// them to default instead of nulling them and mutable options might
|
||||||
|
// get overwritten...
|
||||||
|
ListerPrototype.options.__proto__ = BrowserPrototype.options
|
||||||
|
|
||||||
|
var Lister =
|
||||||
|
module.Lister =
|
||||||
|
object.makeConstructor('Lister',
|
||||||
|
BrowserClassPrototype,
|
||||||
|
ListerPrototype)
|
||||||
|
|
||||||
|
|
||||||
|
// This is a shorthand for: new List(<elem>, { data: <list> })
|
||||||
|
var makeLister =
|
||||||
|
module.makeLister = function(elem, lister, options){
|
||||||
|
var opts = {}
|
||||||
|
for(var k in options){
|
||||||
|
opts[k] = rest[k]
|
||||||
|
}
|
||||||
|
opts.list = lister
|
||||||
|
return Lister(elem, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
|
|
||||||
// Flat list...
|
// Flat list...
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user