refactored the config list editor out of slideshow -- still not too happy with it...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2016-04-14 18:31:10 +03:00
parent 5e1fccb9aa
commit a6382a2fb7
5 changed files with 200 additions and 157 deletions

View File

@ -44,7 +44,6 @@ function(attr, states, callback){
/*********************************************************************/
var ImageGridFeatures =

View File

@ -249,7 +249,7 @@ var ExternalEditorUIActions = actions.Actions({
})
o.client.select(0)
o.client.dom.addClass('editor-list')
o.client.dom.addClass('editor-list tail-action')
return o
}],

View File

@ -11,11 +11,12 @@ define(function(require){ var module = {}
var toggler = require('lib/toggler')
var actions = require('lib/actions')
var features = require('lib/features')
var keyboard = require('lib/keyboard')
var core = require('features/core')
var base = require('features/base')
var widgets = require('features/ui-widgets')
var browse = require('lib/widget/browse')
var overlay = require('lib/widget/overlay')
@ -57,7 +58,6 @@ var SlideshowActions = actions.Actions({
// click on the first option with a mouse...
// result:
// the top dialog is not focused...
// XXX move generic stuff to browse.js...
slideshowDialog: ['Slideshow/Slideshow settings and start',
function(){
var that = this
@ -76,7 +76,7 @@ var SlideshowActions = actions.Actions({
['Looping: ',
function(){ return that.config['slideshow-looping'] }],
'---',
//'---',
[function(){
return that.toggleSlideshow('?') == 'on' ? 'Stop' : 'Start' }],
])
@ -88,152 +88,29 @@ var SlideshowActions = actions.Actions({
return
}
var _makeEditable = function(elem){
$(elem).find('.text')
.prop('contenteditable', true)
.text('')
.selectText()
.keydown(function(){
event.stopPropagation()
var n = keyboard.toKeyName(event.keyCode)
// reset to original value...
if(n == 'Esc'){
oo.client.update()
// save value...
} else if(n == 'Enter'){
event.preventDefault()
var txt = $(this).text()
// invalid format...
if(!Date.str2ms(txt)){
oo.client.update()
return
}
// list length limit -> add ass is...
// XXX should this take into account crossed out items???
if(that.config['slideshow-interval-max-count']
&& (that.config['slideshow-intervals'].length
>= that.config['slideshow-interval-max-count'])){
that.config['slideshow-interval'] = txt
oo.close()
if(that.toggleSlideshow('?') == 'on'){
o.close()
} else {
o.client.update()
.done(function(){
o.client.select(txt)
})
}
return
}
// add new value and sort list...
that.config['slideshow-intervals']
.push(txt)
that.config['slideshow-intervals']
= that.config['slideshow-intervals']
.unique(Date.str2ms)
.sort(function(a, b){
return Date.str2ms(a) - Date.str2ms(b)
})
// update the list data...
oo.client.options.data
= that.config['slideshow-intervals']
.concat([
'---',
'New...'
])
// update list and select new value...
oo.client.update()
.done(function(){
oo.client.select('"'+txt+'"')
})
}
})
return $(elem)
}
// interval...
// XXX add custom interval editing...
if(/interval/i.test(path)){
var to_remove = []
var oo = overlay.Overlay(that.ribbons.viewer,
browse.makeList( null,
that.config['slideshow-intervals']
.concat([
'---',
'New...',
]),
{itemButtons: [
// mark for removal...
['&times;',
function(p){
var e = this.filter('"'+p+'"', false)
.toggleClass('strike-out')
var oo = widgets.makeConfigListEditor(that, 'slideshow-intervals', {
new_button: 'New...',
length_limit: that.config['slideshow-interval-max-count'],
check: Date.str2ms,
unique: Date.str2ms,
sort: function(a, b){
return Date.str2ms(a) - Date.str2ms(b) },
// NOTE: this is called when adding
// a new value and list maximum
// length is reached...
callback: function(value){
that.config['slideshow-interval'] = value
if(e.hasClass('strike-out')){
to_remove.indexOf(p) < 0
&& to_remove.push(p)
o.client.update()
oo.close()
} else {
var i = to_remove.indexOf(p)
if(i >= 0){
to_remove.splice(i, 1)
}
}
}],
]})
// select 'New...' item...
.on('select', function(evt, elem){
if(/new/i.test($(elem).text())){
_makeEditable(elem)
}
})
.open(function(evt, time){
if(!Date.str2ms(time)){
oo.client.select('New...')
// XXX place the cursor...
// XXX
} else {
that.config['slideshow-interval'] = time
// XXX this is ugly...
oo.close()
o.client.update()
o.client.select(path.split(':')[0])
}
}))
o.client.select(value)
},
})
.close(function(){
// remove striked items...
to_remove.forEach(function(e){
var lst = that.config['slideshow-intervals'].slice()
lst.splice(lst.indexOf(e), 1)
that.config['slideshow-intervals'] = lst
})
// XXX add new items...
// XXX
// sort the times...
that.config['slideshow-intervals'] =
that.config['slideshow-intervals']
.sort(function(a, b){
return Date.str2ms(a) - Date.str2ms(b)
})
// XXX this is ugly...
o.focus()
@ -242,7 +119,22 @@ var SlideshowActions = actions.Actions({
}
})
oo.client.dom.addClass('slideshow')
oo.client
.open(function(evt, time){
if(!Date.str2ms(time)){
oo.client.select('New...')
} else {
that.config['slideshow-interval'] = time
// XXX this is ugly...
oo.close()
o.client.update()
o.client.select(path.split(':')[0])
}
})
oo.client.dom.addClass('tail-action')
oo.client.select(that.config['slideshow-interval'])
return
@ -271,7 +163,7 @@ var SlideshowActions = actions.Actions({
that.resetSlideshowTimer()
})
o.client.dom.addClass('metadata-view slideshow')
o.client.dom.addClass('metadata-view tail-action')
o.client.select(-1)

View File

@ -8,6 +8,7 @@ define(function(require){ var module = {}
//var DEBUG = DEBUG != null ? DEBUG : true
var keyboard = require('lib/keyboard')
var actions = require('lib/actions')
var features = require('lib/features')
@ -28,6 +29,162 @@ var browseWalk = require('lib/widget/browse-walk')
/*********************************************************************/
//
// Options format:
// {
// new_button: <text>|<bool>,
//
// length_limit: <number>,
//
// // check input value...
// check: function(value){ ... },
//
// // if true only unique values will be stored...
// // if a function this will be used to normalize the values before
// // uniqueness check is performed...
// unique: <bool>|function(value){ ... },
//
// // if true sort values...
// // if function will be used as cmp for sorting...
// sort: <bool> || function(a, b){ ... },
//
// // this is called when a new value is added via new_button but
// // list length limit is reached...
// callback: function(selected){ ... },
// }
//
// XXX add sort buttons: up/down/top/bottom...
// XXX make this more generic...
var makeConfigListEditor =
module.makeConfigListEditor =
function(actions, list_key, options){
options = options || {}
var new_button = options.new_button
new_button = new_button === true ? 'New...' : new_button
var _makeEditable = function(elem){
$(elem).find('.text')
.prop('contenteditable', true)
.text('')
.selectText()
.keydown(function(){
event.stopPropagation()
var n = keyboard.toKeyName(event.keyCode)
// reset to original value...
if(n == 'Esc'){
list.update()
// save value...
} else if(n == 'Enter'){
event.preventDefault()
var txt = $(this).text()
// invalid format...
if(options.check && !options.check(txt)){
list.update()
return
}
// list length limit
if(options.length_limit
&& (actions.config[list_key].length >= options.length_limit)){
options.callback && options.callback.call(list, txt)
return
}
// add new value and sort list...
actions.config[list_key]
.push(txt)
// unique...
if(options.unique){
actions.config[list_key] = actions.config[list_key]
.unique(options.unique !== true ? options.unique : undefined)
}
// sort...
if(options.sort){
actions.config[list_key] = actions.config[list_key]
.sort(options.sort !== true ? options.sort : undefined)
}
// update the list data...
list.options.data
= actions.config[list_key]
.concat(new_button ? [ new_button ] : [])
// update list and select new value...
list.update()
.done(function(){
list.select('"'+txt+'"')
})
}
})
return $(elem)
}
var to_remove = []
var list = browse.makeList( null,
actions.config[list_key]
.concat(new_button ? [ new_button ] : []),
{itemButtons: [
// mark for removal...
['&times;',
function(p){
var e = this.filter('"'+p+'"', false)
.toggleClass('strike-out')
if(e.hasClass('strike-out')){
to_remove.indexOf(p) < 0
&& to_remove.push(p)
} else {
var i = to_remove.indexOf(p)
if(i >= 0){
to_remove.splice(i, 1)
}
}
}],
]})
// select the new_button item...
.on('select', function(evt, elem){
if(new_button && $(elem).find('.text').text() == new_button){
_makeEditable(elem)
}
})
var o = overlay.Overlay(actions.ribbons.viewer, list)
.close(function(){
// remove striked items...
to_remove.forEach(function(e){
var lst = actions.config[list_key].slice()
lst.splice(lst.indexOf(e), 1)
actions.config[list_key] = lst
})
// sort the times...
if(options.sort){
actions.config[list_key] = actions.config[list_key]
.sort(options.sort !== true ? options.sort : undefined)
}
})
new_button && list.dom.addClass('tail-action')
return o
}
/*********************************************************************/
// NOTE: if the action returns an instance of overlay.Overlay this will

View File

@ -169,24 +169,19 @@ body {
opacity: 0.1;
}
/* XXX STUB: use a button instead of a list element... */
.browse-widget.editor-list .list>div:last-child {
/* slideshow interval list... */
.browse-widget.tail-action .list>div:last-child {
margin-top: 0.2em;
border-top: solid 1px rgba(255,255,255, 0.2);
}
.browse-widget.editor-list .list>div:last-child .text {
.browse-widget.tail-action .list>div:last-child .text {
font-style: italic;
}
.browse-widget.editor-list .list>div:last-child .button {
.browse-widget.tail-action .list>div:last-child .button {
display: none;
}
/* slideshow interval list... */
.browse-widget.slideshow .list>div:last-child .text {
font-style: italic;
}
/* DEBUG stuff... */
.container-center {
position: absolute;