mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-28 18:00:09 +00:00
refactoring + .loadImagesAsRibbon(..)...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
f8e149a8f5
commit
08492cbf35
@ -263,6 +263,19 @@ body {
|
||||
font-weight: bolder !important;
|
||||
}
|
||||
|
||||
.browse-widget .list>div .show-on-hover {
|
||||
opacity: 0;
|
||||
}
|
||||
.browse-widget .list>div:hover .show-on-hover {
|
||||
opacity: inherit;
|
||||
}
|
||||
.browse-widget .list>div .show-on-select {
|
||||
opacity: 0;
|
||||
}
|
||||
.browse-widget .list>.selected .show-on-select {
|
||||
opacity: inherit;
|
||||
}
|
||||
|
||||
|
||||
/* Dialog highlight experiment... */
|
||||
.browse-widget {
|
||||
|
||||
@ -204,13 +204,14 @@ actions.Actions({
|
||||
this.images = images.Images(d.images)
|
||||
this.data = data.Data(d.data)
|
||||
}],
|
||||
// XXX should this clear or load empty???
|
||||
clear: ['File/Clear',
|
||||
{journal: true},
|
||||
function(){
|
||||
//delete this.data
|
||||
//delete this.images
|
||||
this.data = null
|
||||
this.images = null
|
||||
//this.data = null
|
||||
//this.images = null
|
||||
this.data = new data.DataWithTags()
|
||||
this.images = new images.Images()
|
||||
}],
|
||||
|
||||
// NOTE: for complete isolation it is best to completely copy the
|
||||
|
||||
@ -668,6 +668,73 @@ var FileSystemLoaderActions = actions.Actions({
|
||||
})
|
||||
}],
|
||||
|
||||
//
|
||||
// .loadImagesAsRibbon(path[, logger])
|
||||
// -> promise
|
||||
//
|
||||
// .loadImagesAsRibbon(path, 'above'[, logger])
|
||||
// .loadImagesAsRibbon(path, 'below'[, logger])
|
||||
// -> promise
|
||||
//
|
||||
// NOTE: this does not touch .location
|
||||
//
|
||||
// XXX EXPERIMENTAL...
|
||||
// XXX should this be usable only in crops???
|
||||
// ....also would be a good idea to add things like .removeRibbon(..)...
|
||||
loadImagesAsRibbon: ['- File/Load images into ribbon',
|
||||
function(path, direction, logger){
|
||||
var that = this
|
||||
if(path == null){
|
||||
return
|
||||
}
|
||||
|
||||
if(logger === undefined
|
||||
&& direction
|
||||
&& typeof(direction) != typeof('str')){
|
||||
logger = direction
|
||||
direction = null
|
||||
}
|
||||
|
||||
direction = direction || 'below'
|
||||
|
||||
console.log('>>>>', direction)
|
||||
|
||||
logger = logger || this.logger
|
||||
logger = logger && logger.push('Load images to ribbon')
|
||||
|
||||
return this.getImagesInPath(
|
||||
path,
|
||||
that.config['image-file-read-stat'],
|
||||
that.config['image-file-skip-previews'],
|
||||
logger)
|
||||
// load the data...
|
||||
.then(function(imgs){
|
||||
that.clearLoaction()
|
||||
|
||||
var d = that.data
|
||||
var nd = data.Data.fromArray(imgs.keys())
|
||||
|
||||
var r = d.getRibbon()
|
||||
|
||||
// splice the order...
|
||||
d.order.splice.apply(d.order,
|
||||
[d.order.indexOf(d.current)+1, 0]
|
||||
.concat(nd.order))
|
||||
|
||||
// new ribbon and data...
|
||||
var n = d.newRibbon(r, direction)
|
||||
d.ribbons[n] = nd.ribbons[nd.ribbon_order[0]]
|
||||
|
||||
// sort elements within the new ribbon...
|
||||
d.updateImagePositions()
|
||||
|
||||
// join images...
|
||||
that.images.join(imgs)
|
||||
|
||||
that.reload(true)
|
||||
})
|
||||
}],
|
||||
|
||||
// Load new images...
|
||||
//
|
||||
// Load new images from current path...
|
||||
@ -846,6 +913,14 @@ var FileSystemLoaderUIActions = actions.Actions({
|
||||
config: {
|
||||
// list of loaders to complete .browsePath(..) action
|
||||
//
|
||||
// The loader can be action name or a keyboard.parseActionCall(..)
|
||||
// compatible syntax.
|
||||
//
|
||||
// If an argument string containing "$PATH" is passed then it
|
||||
// will be replaces by the selected path...
|
||||
// Example:
|
||||
// 'someAction: "$PATH" -- doc'
|
||||
//
|
||||
// NOTE: these will be displayed in the same order as they appear
|
||||
// in the list.
|
||||
// NOTE: the first one is auto-selected.
|
||||
@ -853,6 +928,9 @@ var FileSystemLoaderUIActions = actions.Actions({
|
||||
'loadIndex',
|
||||
'loadImages',
|
||||
//'loadPath',
|
||||
'---',
|
||||
'loadImagesAsRibbon: "$PATH" "above" -- Load images to new ribbon above',
|
||||
'loadImagesAsRibbon: "$PATH" "below" -- Load images to new ribbon below',
|
||||
],
|
||||
|
||||
'file-browser-settings': {
|
||||
@ -911,8 +989,29 @@ var FileSystemLoaderUIActions = actions.Actions({
|
||||
} else {
|
||||
var loaders = {}
|
||||
that.config['path-loaders'].forEach(function(m){
|
||||
loaders[that.getDoc(m)[m][0].split('/').pop()] = function(){
|
||||
return that[m](path)
|
||||
var a = keyboard.parseActionCall(m)
|
||||
|
||||
if(a.action in that){
|
||||
var args = a.arguments
|
||||
// empty args...
|
||||
args = args.length == 0 ?
|
||||
[path]
|
||||
: args
|
||||
// replace the path placeholder...
|
||||
var i = args.indexOf('$PATH')
|
||||
i >= 0
|
||||
&& args.splice(i, 1, path)
|
||||
|
||||
// the callback...
|
||||
loaders[a.doc != '' ?
|
||||
a.doc
|
||||
: that.getDocTitle(a.action)] =
|
||||
function(){
|
||||
return that[a.action].apply(that, a.arguments) }
|
||||
|
||||
// non-actions...
|
||||
} else {
|
||||
loaders[m] = null
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -2232,7 +2331,7 @@ var FileSystemWriterUIActions = actions.Actions({
|
||||
this.saveIndex()
|
||||
|
||||
} else {
|
||||
this.browseSaveIndex()
|
||||
this.browseExportIndex()
|
||||
}
|
||||
}],
|
||||
// XXX should this be a UI action???
|
||||
|
||||
@ -454,7 +454,6 @@ var URLHistoryUIActions = actions.Actions({
|
||||
})
|
||||
to_remove = []
|
||||
}
|
||||
|
||||
var makeHistoryList = function(fs_state){
|
||||
fs_state = fs_state || {}
|
||||
var history = Object.keys(that.url_history).reverse()
|
||||
@ -531,6 +530,19 @@ var URLHistoryUIActions = actions.Actions({
|
||||
|
||||
return list
|
||||
}
|
||||
// this will take care of any number of child dialogs...
|
||||
// XXX should this be generic???
|
||||
var onOpen = function(){
|
||||
// we are the top dialog --> close...
|
||||
if(that.modal.client === o){
|
||||
o.close()
|
||||
|
||||
// child dialog, ask to close us when opening...
|
||||
} else {
|
||||
that.modal.client.open(onOpen)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var o = browse.makeLister(null,
|
||||
function(path, make){
|
||||
@ -548,6 +560,8 @@ var URLHistoryUIActions = actions.Actions({
|
||||
},
|
||||
// add item buttons...
|
||||
{ itemButtons: [
|
||||
['<span class="show-on-hover">↗</span>',
|
||||
function(p){ o.browsePath(p) }],
|
||||
// move to top...
|
||||
['♦',
|
||||
function(p){
|
||||
@ -640,6 +654,13 @@ var URLHistoryUIActions = actions.Actions({
|
||||
return this
|
||||
}
|
||||
|
||||
// handle 'O' button to browse path...
|
||||
o.browsePath = function(p){
|
||||
that.browsePath(p || this.selected).open(onOpen) }
|
||||
// clone the bindings so as not to mess up the global browser...
|
||||
o.keybindings = JSON.parse(JSON.stringify(o.keybindings))
|
||||
o.keyboard.handler('General', 'O', 'browsePath')
|
||||
|
||||
return o
|
||||
})],
|
||||
})
|
||||
@ -654,58 +675,11 @@ module.URLHistoryUI = core.ImageGridFeatures.Feature({
|
||||
'ui',
|
||||
'url-history',
|
||||
],
|
||||
suggested: [
|
||||
'ui-url-history-browsable',
|
||||
],
|
||||
|
||||
actions: URLHistoryUIActions,
|
||||
})
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
var URLHistoryUIBrowsable =
|
||||
module.URLHistoryUIBrowsable = core.ImageGridFeatures.Feature({
|
||||
title: '',
|
||||
doc: '',
|
||||
|
||||
tag: 'ui-url-history-browsable',
|
||||
depends: [
|
||||
'ui',
|
||||
'url-history',
|
||||
'ui-fs-loader',
|
||||
],
|
||||
|
||||
handlers: [
|
||||
['listURLHistory',
|
||||
function(dialog){
|
||||
var that = this
|
||||
|
||||
// this will take care of any number of child dialogs...
|
||||
var onOpen = function(){
|
||||
// we are the top dialog --> close...
|
||||
if(that.modal.client === dialog){
|
||||
dialog.close()
|
||||
|
||||
// child dialog, ask to close us when opening...
|
||||
} else {
|
||||
that.modal.client.open(onOpen)
|
||||
}
|
||||
}
|
||||
|
||||
dialog.browsePath = function(){
|
||||
that.browsePath(this.selected).open(onOpen) }
|
||||
|
||||
// clone the bindings so as not to mess up the global browser...
|
||||
dialog.keybindings = JSON.parse(JSON.stringify(dialog.keybindings))
|
||||
|
||||
dialog.keyboard.handler('General', 'O', 'browsePath')
|
||||
}]],
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* vim:set ts=4 sw=4 : */ return module })
|
||||
|
||||
@ -101,6 +101,10 @@ var LocationActions = actions.Actions({
|
||||
},
|
||||
|
||||
|
||||
clearLoaction: ['File/Clear location',
|
||||
function(){ delete this.__location }],
|
||||
|
||||
|
||||
// Load location...
|
||||
//
|
||||
// Reload current location...
|
||||
@ -191,9 +195,7 @@ module.Location = core.ImageGridFeatures.Feature({
|
||||
}
|
||||
}],
|
||||
['clear',
|
||||
function(){
|
||||
delete this.__location
|
||||
}],
|
||||
function(){ this.clearLoaction() }],
|
||||
|
||||
// 1) store .location
|
||||
// 2) cleanup .images[..].base_path
|
||||
|
||||
@ -158,10 +158,21 @@ var DataPrototype = {
|
||||
//
|
||||
// .current (gid)
|
||||
// gid of the current image
|
||||
//
|
||||
// NOTE: if no current image is set explicitly this defaults
|
||||
// to first image in first ribbon, or first in .order.
|
||||
//
|
||||
//
|
||||
// .base (gid)
|
||||
// gid of the base ribbon
|
||||
//
|
||||
// NOTE: if no base ribbon is explicitly set, this defaults to
|
||||
// last ribbon.
|
||||
// This may not seem logical at first but this is by design
|
||||
// behavior, the goal is to keep all sets not explicitly
|
||||
// aligned (i.e. sorted) be misaligned by default.
|
||||
//
|
||||
//
|
||||
// .order
|
||||
// List of image gids setting the image order
|
||||
//
|
||||
@ -171,12 +182,14 @@ var DataPrototype = {
|
||||
// NOTE: this list may contain gids not loaded at the moment,
|
||||
// a common case for this is when data is cropped.
|
||||
//
|
||||
//
|
||||
// .ribbon_order
|
||||
// List of ribbon gids setting the ribbon order.
|
||||
//
|
||||
// format:
|
||||
// [ gid, .. ]
|
||||
//
|
||||
//
|
||||
// .ribbons
|
||||
// Dict of ribbons, indexed by ribbon gid, each ribbon is a
|
||||
// sparse list of image gids.
|
||||
@ -189,16 +202,17 @@ var DataPrototype = {
|
||||
//
|
||||
/*****************************************************************/
|
||||
|
||||
// XXX is this a good name for this??? (see: object.js)
|
||||
__init__: function(json){
|
||||
// load initial state...
|
||||
if(json != null){
|
||||
this.loadJSON(json)
|
||||
} else {
|
||||
this._reset()
|
||||
}
|
||||
return this
|
||||
},
|
||||
get current(){
|
||||
return this.__current = this.__current
|
||||
|| this.getImages(this.ribbon_order[0])[0]
|
||||
|| this.order[0] },
|
||||
set current(value){
|
||||
this.__current = value },
|
||||
|
||||
get base(){
|
||||
return this.__base || this.ribbon_order.slice(-1)[0] },
|
||||
set base(value){
|
||||
this.__base = value },
|
||||
|
||||
|
||||
|
||||
@ -432,7 +446,7 @@ var DataPrototype = {
|
||||
|
||||
// no more ribbons left...
|
||||
if(that.ribbon_order.length == 0){
|
||||
that.base = null
|
||||
delete that.__base
|
||||
|
||||
// shift base up or to first image...
|
||||
} else if(that.base == gid){
|
||||
@ -449,7 +463,7 @@ var DataPrototype = {
|
||||
})
|
||||
|
||||
if(that.current == gid){
|
||||
that.current = null
|
||||
delete that.__current
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -1082,8 +1096,7 @@ var DataPrototype = {
|
||||
},
|
||||
// same as .getRibbon(..) but returns ribbon order...
|
||||
getRibbonOrder: function(target, offset){
|
||||
return this.ribbon_order.indexOf(this.getRibbon(target, offset))
|
||||
},
|
||||
return this.ribbon_order.indexOf(this.getRibbon(target, offset)) },
|
||||
|
||||
|
||||
|
||||
@ -1313,8 +1326,7 @@ var DataPrototype = {
|
||||
},
|
||||
|
||||
reverseRibbons: function(){
|
||||
this.ribbon_order.reverse()
|
||||
},
|
||||
this.ribbon_order.reverse() },
|
||||
|
||||
|
||||
// Gather gids into a connected section...
|
||||
@ -2479,8 +2491,9 @@ var DataPrototype = {
|
||||
// Reset the state to empty...
|
||||
//
|
||||
_reset: function(){
|
||||
this.base = null
|
||||
this.current = null
|
||||
delete this.__base
|
||||
delete this.__current
|
||||
|
||||
this.order = []
|
||||
this.ribbon_order = []
|
||||
this.ribbons = {}
|
||||
@ -2554,6 +2567,20 @@ var DataPrototype = {
|
||||
}
|
||||
return res
|
||||
},
|
||||
|
||||
|
||||
|
||||
/*****************************************************************/
|
||||
// XXX is this a good name for this??? (see: object.js)
|
||||
__init__: function(json){
|
||||
// load initial state...
|
||||
if(json != null){
|
||||
this.loadJSON(json)
|
||||
} else {
|
||||
this._reset()
|
||||
}
|
||||
return this
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@ -2975,5 +3002,6 @@ module.Data = DataWithTags
|
||||
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* vim:set ts=4 sw=4 : */ return module })
|
||||
|
||||
@ -348,22 +348,8 @@ module.ImagesClassPrototype = {
|
||||
|
||||
var ImagesPrototype =
|
||||
module.ImagesPrototype = {
|
||||
|
||||
// XXX is this a good name for this??? (see: object.js)
|
||||
__init__: function(json){
|
||||
// load initial state...
|
||||
if(json != null){
|
||||
this.loadJSON(json)
|
||||
} else {
|
||||
this._reset()
|
||||
}
|
||||
return this
|
||||
},
|
||||
|
||||
|
||||
get length(){
|
||||
return Object.keys(this).length
|
||||
},
|
||||
return Object.keys(this).length },
|
||||
|
||||
// Generic iterators...
|
||||
//
|
||||
@ -435,8 +421,7 @@ module.ImagesPrototype = {
|
||||
},
|
||||
|
||||
keys: function(){
|
||||
return Object.keys(this)
|
||||
},
|
||||
return Object.keys(this) },
|
||||
|
||||
// Build an image index relative to an attribute...
|
||||
//
|
||||
@ -670,8 +655,7 @@ module.ImagesPrototype = {
|
||||
|
||||
|
||||
clone: function(){
|
||||
return (new Images()).loadJSON(this.dumpJSON())
|
||||
},
|
||||
return (new Images()).loadJSON(this.dumpJSON()) },
|
||||
// NOTE: this will join the other data into the current object in-place,
|
||||
// use .clone() to preserve current data...
|
||||
join: function(other){
|
||||
@ -702,6 +686,18 @@ module.ImagesPrototype = {
|
||||
|
||||
_reset: function(){
|
||||
},
|
||||
|
||||
|
||||
// XXX is this a good name for this??? (see: object.js)
|
||||
__init__: function(json){
|
||||
// load initial state...
|
||||
if(json != null){
|
||||
this.loadJSON(json)
|
||||
} else {
|
||||
this._reset()
|
||||
}
|
||||
return this
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1125,8 +1125,7 @@ var RibbonsPrototype = {
|
||||
// Like .getRibbon(..) but returns ribbon index instead of the actual
|
||||
// ribbon object...
|
||||
getRibbonOrder: function(target){
|
||||
return this.viewer.find(RIBBON).index(this.getRibbon(target))
|
||||
},
|
||||
return this.viewer.find(RIBBON).index(this.getRibbon(target)) },
|
||||
|
||||
|
||||
// Basic manipulation...
|
||||
@ -2090,8 +2089,7 @@ var RibbonsPrototype = {
|
||||
// Get image rotation...
|
||||
//
|
||||
getImageRotation: function(target){
|
||||
return (this.getImage(target).attr('orientation') || 0)*1
|
||||
},
|
||||
return (this.getImage(target).attr('orientation') || 0)*1 },
|
||||
// Rotate an image...
|
||||
//
|
||||
// Rotate image clockwise:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user