mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-29 10:20: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...
|
||||
|
||||
@ -758,17 +767,21 @@ var FileSystemWriterActions = actions.Actions({
|
||||
exportView: ['File/Export current view',
|
||||
function(){
|
||||
}],
|
||||
// XXX not done yet...
|
||||
// needs:
|
||||
// ensureDir(..)
|
||||
// copy(..)
|
||||
// ...both denodeify(..)'ed
|
||||
// XXX export current state as a full loadable index
|
||||
|
||||
// Export current state as a full loadable index
|
||||
//
|
||||
// XXX might be interesting to unify this and .exportView(..)
|
||||
// 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 add a ui...
|
||||
// - select path
|
||||
// - select preview size
|
||||
exportCollection: ['File/Export as collection',
|
||||
function(path, logger){
|
||||
logger = logger || this.logger
|
||||
|
||||
var json = this.json()
|
||||
|
||||
// get all loaded gids...
|
||||
@ -785,6 +798,7 @@ var FileSystemWriterActions = actions.Actions({
|
||||
var img = json.images[gid]
|
||||
if(img){
|
||||
images[gid] = json.images[gid]
|
||||
|
||||
// remove un-needed previews...
|
||||
// XXX
|
||||
}
|
||||
@ -794,27 +808,28 @@ var FileSystemWriterActions = actions.Actions({
|
||||
json.data.order = gids
|
||||
json.images = images
|
||||
// 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...
|
||||
// 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){
|
||||
var img = json.images[gid]
|
||||
var img_base = img.base_path
|
||||
img.base_path = path
|
||||
var previews = img.preview
|
||||
|
||||
for(var res in previews){
|
||||
var from = (img_base || base_dir) +'/'+ preview_path
|
||||
// NOTE: we are copying everything to one place so no
|
||||
// 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
|
||||
|
||||
// XXX do we queue these or let the OS handle it???
|
||||
@ -823,7 +838,7 @@ var FileSystemWriterActions = actions.Actions({
|
||||
// XXX
|
||||
ensureDir(pathlib.dirname(to))
|
||||
.catch(function(err){
|
||||
// XXX
|
||||
logger && logger.emit('error', err)
|
||||
})
|
||||
.then(function(){
|
||||
return copy(from, to)
|
||||
@ -832,12 +847,99 @@ var FileSystemWriterActions = actions.Actions({
|
||||
// we just use the one above (after
|
||||
// .then(..))
|
||||
.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()
|
||||
|
||||
// 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,
|
||||
browse.makeList(
|
||||
null,
|
||||
[
|
||||
// XXX make this editable...
|
||||
['Interval: ',
|
||||
function(){ return that.config['slideshow-interval'] }],
|
||||
['Direction: ',
|
||||
function(){ return that.config['slideshow-direction'] }],
|
||||
['Looping: ',
|
||||
function(){ return that.config['slideshow-looping'] }],
|
||||
browse.makeLister(null, function(path, make){
|
||||
make(['Interval: ',
|
||||
function(){ return that.config['slideshow-interval'] }])
|
||||
.on('open', function(){
|
||||
var txt = $(this).find('.text').first().text()
|
||||
|
||||
//'---',
|
||||
[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', {
|
||||
new_button: 'New...',
|
||||
length_limit: that.config['slideshow-interval-max-count'],
|
||||
@ -107,9 +99,8 @@ var SlideshowActions = actions.Actions({
|
||||
// XXX this is ugly...
|
||||
o.focus()
|
||||
|
||||
if(that.toggleSlideshow('?') == 'on'){
|
||||
o.close()
|
||||
}
|
||||
that.toggleSlideshow('?') == 'on'
|
||||
&& o.close()
|
||||
})
|
||||
|
||||
oo.client
|
||||
@ -122,42 +113,36 @@ var SlideshowActions = actions.Actions({
|
||||
|
||||
// XXX this is ugly...
|
||||
oo.close()
|
||||
|
||||
o.client.update()
|
||||
o.client.select(path.split(':')[0])
|
||||
o.client.select(txt)
|
||||
}
|
||||
})
|
||||
|
||||
oo.client.dom.addClass('tail-action')
|
||||
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...
|
||||
if(/direction/i.test(path)){
|
||||
that.toggleSlideshowDirection()
|
||||
o.client.update()
|
||||
|
||||
// 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'){
|
||||
// Start/stop...
|
||||
make([function(){
|
||||
return that.toggleSlideshow('?') == 'on' ? 'Stop' : 'Start' }])
|
||||
.on('open', function(){
|
||||
that.toggleSlideshow()
|
||||
o.close()
|
||||
}
|
||||
}))
|
||||
})
|
||||
}))
|
||||
.close(function(){
|
||||
that.resetSlideshowTimer()
|
||||
})
|
||||
|
||||
o.client.dom.addClass('metadata-view tail-action')
|
||||
|
||||
o.client.select(-1)
|
||||
|
||||
return o
|
||||
|
||||
@ -94,8 +94,15 @@ function listJSON(path, pattern){
|
||||
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...
|
||||
var denodeify = function(func){
|
||||
var denodeify =
|
||||
module.denodeify =
|
||||
function(func){
|
||||
return function(){
|
||||
// XXX for some reason this does not see args2array...
|
||||
// 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...
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user