marks now done (at least it looks like everything is working fine)...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2013-12-05 03:58:13 +04:00
parent 84b5cb2e8a
commit c0168762ea
7 changed files with 178 additions and 36 deletions

View File

@ -32,6 +32,10 @@
color: red; color: red;
text-shadow: 0px 0px 2px rgba(0, 0, 0, 0.5); text-shadow: 0px 0px 2px rgba(0, 0, 0, 0.5);
} }
.panel .panel-content {
display: block;
min-height: 30px;
}
.panel button, .panel button,
.panel details, .panel details,
.panel .state { .panel .state {

View File

@ -33,6 +33,9 @@ var toggleEditor = createCSSClassToggler(
// XXX add handlers for saving data to images... // XXX add handlers for saving data to images...
// XXX // XXX
// make clicks on unfocusable elements remove focus... // make clicks on unfocusable elements remove focus...
.on('panelClosing', function(){
toggleEditor('off')
})
.click(function(){ .click(function(){
if(event.target != $('.panel :focus')[0]){ if(event.target != $('.panel :focus')[0]){
$('.panel :focus').blur() $('.panel :focus').blur()
@ -50,6 +53,7 @@ var toggleEditor = createCSSClassToggler(
} else { } else {
ed.show() ed.show()
} }
// update the state... // update the state...
reloadControls('.current.image') reloadControls('.current.image')

View File

@ -169,6 +169,7 @@ var KEYBOARD_CONFIG = {
// blur focused element, if nothing focused close... // blur focused element, if nothing focused close...
} else if(toggleEditor('?') == 'on'){ } else if(toggleEditor('?') == 'on'){
$(':focus').blur() $(':focus').blur()
return false
} }
}), }),
}, },
@ -659,6 +660,7 @@ var KEYBOARD_CONFIG = {
//} //}
centerRibbons() centerRibbons()
}), }),
ctrl: doc('Show mark dialog', function(){ markImagesDialog() }),
}, },
Ins: doc('Toggle mark on current image', function(){ toggleImageMark() }), Ins: doc('Toggle mark on current image', function(){ toggleImageMark() }),
'invert-marks': doc('Invert image marks', 'invert-marks': doc('Invert image marks',

13
ui/layout.css Normal file → Executable file
View File

@ -1214,11 +1214,16 @@ button:hover {
} }
/* XXX this is experimental... */ /* XXX this is experimental... */
.viewer.overlay .ribbon-set { .viewer.overlay .ribbon-set {
/* XXX blur makes things slow with transparency... */ /* XXX blur makes things slow with transparency... */
-webkit-filter: /*blur(2px)*/ grayscale(0.5); /*
filter: /*blur(2px)*/ grayscale(0.5); -webkit-filter: blur(2px);
/* filter: blur(2px);
*/
-webkit-filter: grayscale(0.5);
filter: grayscale(0.5);
/*
-webkit-animation-name: testAnim; -webkit-animation-name: testAnim;
-webkit-animation-duration: .2s; -webkit-animation-duration: .2s;
-webkit-animation-iteration-count: 1; -webkit-animation-iteration-count: 1;

View File

@ -100,6 +100,11 @@ function sortFilterSliders(order){
// Load state of sliders from target... // Load state of sliders from target...
// //
function loadSliderState(target){ function loadSliderState(target){
// break the feedback loop that if present will write the state
// back...
var filters = $('.filter-list input[type=range]')
.prop('disabled', true)
var res = $(target) var res = $(target)
.css('-webkit-filter') .css('-webkit-filter')
var state = res var state = res
@ -113,7 +118,6 @@ function loadSliderState(target){
}) })
// set the saved values... // set the saved values...
while(state.length > 0){ while(state.length > 0){
// XXX avoid using ids...
var e = $('[filter='+state.pop()+']') var e = $('[filter='+state.pop()+']')
if(e.prop('normalize')){ if(e.prop('normalize')){
e.val(v2r(parseFloat(state.pop()))).change() e.val(v2r(parseFloat(state.pop()))).change()
@ -121,6 +125,9 @@ function loadSliderState(target){
e.val(parseFloat(state.pop())).change() e.val(parseFloat(state.pop())).change()
} }
} }
filters
.prop('disabled', false)
return res return res
} }
@ -191,6 +198,7 @@ function makeAbsRange(text, filter, target, min, max, dfl, step, translate, norm
$('<span class="title"/>') $('<span class="title"/>')
.html(text) .html(text)
.appendTo(elem) .appendTo(elem)
// NOTE: the range element is the main "writer"...
var range = $('<input class="slider" type="range">') var range = $('<input class="slider" type="range">')
.attr({ .attr({
filter: filter, filter: filter,
@ -204,7 +212,9 @@ function makeAbsRange(text, filter, target, min, max, dfl, step, translate, norm
.change(function(){ .change(function(){
var val = this.valueAsNumber var val = this.valueAsNumber
value.val(val) value.val(val)
updateFilter(target, filter, translate(val)) if(!elem.prop('disabled') && !$(this).prop('disabled')){
updateFilter(target, filter, translate(val))
}
if(parseFloat(val) == dfl){ if(parseFloat(val) == dfl){
elem.addClass('at-default') elem.addClass('at-default')
} else { } else {
@ -236,21 +246,25 @@ function makeLogRange(text, filter, target){
} }
// XXX add panel update events to help save settings... function makePanel(title, open){
function makeEditorControls(target){ title = title == null ? '&nbsp;' : title
// tool panel... // tool panel...
var panel = $('<details open/>') var panel = $('<details/>')
.prop('open', open == null ? true : open)
.addClass('panel') .addClass('panel')
.css({ .css({
position: 'absolute', position: 'absolute',
top: '100px', top: '100px',
left: '100px', left: '100px',
}) })
.append($('<summary>Edit</summary>') .append($('<summary>'+title+'</summary>')
.append($('<span/>') .append($('<span/>')
.addClass('close-button') .addClass('close-button')
.click(function(){ .click(function(){
$(this).parents('.panel').hide() panel
.trigger('panelClosing')
.hide()
return false return false
}) })
.html('&times;'))) .html('&times;')))
@ -270,11 +284,33 @@ function makeEditorControls(target){
opacity: 0.7, opacity: 0.7,
}) })
.appendTo(panel) .appendTo(panel)
return panel
}
// filters...
$('<details open/>') function makeSubPanel(title, open, parent){
.append($('<summary>Filters</summary>')) title = title == null ? '&nbsp;' : title
.append($('<div class="sub-panel-content"/>')
var sub_panel = $('<details/>')
.prop('open', open == null ? true : open)
.append($('<summary>'+title+'</summary>'))
.append($('<div class="sub-panel-content"/>'))
if(parent != null){
if(parent.hasClass('panel-content')){
sub_panel.appendTo(parent)
} else {
sub_panel.appendTo(parent.find('.panel-content'))
}
}
return sub_panel
}
function makeFilterPanel(parent, target){
return makeSubPanel('Filters', true, parent)
.find('.sub-panel-content')
.append($('<div class="filter-list"/>') .append($('<div class="filter-list"/>')
//.append(makeLogRange('Gamma:', 'gamma', target)) //.append(makeLogRange('Gamma:', 'gamma', target))
.append(makeLogRange('Brightness:', 'brightness', target)) .append(makeLogRange('Brightness:', 'brightness', target))
@ -307,13 +343,12 @@ function makeEditorControls(target){
.click(function(){ .click(function(){
$('.reset').click() $('.reset').click()
sortFilterSliders(DEFAULT_FILTER_ORDER) sortFilterSliders(DEFAULT_FILTER_ORDER)
}))) }))
.appendTo(content) }
// snapshots... function makeSnapshotsPanel(parent, target){
$('<details open/>') return makeSubPanel('Snapshots', true, parent)
.append($('<summary>Snapshots</summary>')) .find('.sub-panel-content')
.append($('<div class="sub-panel-content"/>')
.append($('<div class="states"/>')) .append($('<div class="states"/>'))
.append($('<hr>')) .append($('<hr>'))
.append($('<button/>') .append($('<button/>')
@ -335,8 +370,20 @@ function makeEditorControls(target){
ui.helper.remove() ui.helper.remove()
} }
}))) }))
.appendTo(content) }
// XXX add panel update events to help save settings...
function makeEditorControls(target){
var panel = makePanel()
// filters...
makeFilterPanel(panel, target)
// snapshots...
makeSnapshotsPanel(panel, target)
return panel return panel
} }

View File

@ -105,15 +105,14 @@ var toggleMarkesView = createCSSClassToggler(
var toggleImageMark = createCSSClassToggler( var toggleImageMark = createCSSClassToggler(
'.current.image', '.current.image',
'marked', 'marked',
function(action){ function(action, elem){
toggleMarkesView('on') toggleMarkesView('on')
// XXX
if(action == 'on'){ if(action == 'on'){
_addMark('selected') _addMark('selected', getImageGID(elem), elem)
} else { } else {
_removeMark('selected') _removeMark('selected', getImageGID(elem), elem)
} }
$('.viewer').trigger('togglingMark', [getImage(), action]) $('.viewer').trigger('togglingMark', [elem, action])
}) })
@ -126,13 +125,17 @@ function removeImageMarks(mode){
var ribbon = getRibbon() var ribbon = getRibbon()
var res = ribbon var res = ribbon
.find('.marked') .find('.marked')
.removeClass('marked') .each(function(){
toggleImageMark(this, 'off')
})
$('.viewer').trigger('removeingRibbonMarks', [ribbon]) $('.viewer').trigger('removeingRibbonMarks', [ribbon])
// remove all marks... // remove all marks...
} else if(mode == 'all'){ } else if(mode == 'all'){
var res = $('.marked') var res = $('.marked')
.removeClass('marked') .each(function(){
toggleImageMark(this, 'off')
})
$('.viewer').trigger('removeingAllMarks') $('.viewer').trigger('removeingAllMarks')
} }
return res return res
@ -140,16 +143,22 @@ function removeImageMarks(mode){
function markAll(mode){ function markAll(mode){
// remove marks from current ribbon (default)... // current ribbon (default)...
if(mode == 'ribbon' || mode == null){ if(mode == 'ribbon' || mode == null){
var ribbon = getRibbon() var ribbon = getRibbon()
var res = ribbon var res = ribbon
.find('.image:not(.marked)') .find('.image:not(.marked)')
.addClass('marked') .each(function(){
toggleImageMark(this, 'on')
})
$('.viewer').trigger('markingRibbon', [ribbon]) $('.viewer').trigger('markingRibbon', [ribbon])
// mark everything...
} else if(mode == 'all'){ } else if(mode == 'all'){
var res = $('.image:not(.marked)').addClass('marked') var res = $('.image:not(.marked)')
.each(function(){
toggleImageMark(this, 'on')
})
$('.viewer').trigger('markingAll') $('.viewer').trigger('markingAll')
} }
return res return res
@ -161,7 +170,9 @@ function invertImageMarks(){
var ribbon = getRibbon() var ribbon = getRibbon()
var res = ribbon var res = ribbon
.find('.image') .find('.image')
.toggleClass('marked') .each(function(){
toggleImageMark(this, 'next')
})
$('.viewer').trigger('invertingMarks', [ribbon]) $('.viewer').trigger('invertingMarks', [ribbon])
return res return res
} }
@ -179,6 +190,7 @@ function toggleImageMarkBlock(image){
var state = toggleImageMark() var state = toggleImageMark()
var _convert = function(){ var _convert = function(){
if(toggleImageMark(this, '?') == state){ if(toggleImageMark(this, '?') == state){
// stop the iteration...
return false return false
} }
toggleImageMark(this, state) toggleImageMark(this, state)
@ -264,5 +276,75 @@ function shiftMarkedImagesRight(){
/**********************************************************************
* Dialogs...
*/
function markImagesDialog(){
updateStatus('Mark...').show()
var alg = 'Mark images: |'+
'Use Esc and Shift-Esc to exit crop modes.'+
'\n\n'+
'NOTE: all crop modes will produce a single ribbon unless\n'+
'otherwise stated.'
var cur = toggleImageMark('?') == 'on' ? 'Unmark' : 'Mark'
cfg = {}
cfg[alg] = [
cur + ' current image',
cur + ' current block | '+
'A block is a set of similarly marked images\n'+
'to the left and right of the current image,\n'+
'up until the closest images marked differently',
'Invert marks in current ribbon',
'Mark all in current ribbon',
'Unmark all in current ribbon',
'Unmark all images'
]
formDialog(null, '',
cfg,
'OK',
'markImagesDialog')
.done(function(res){
res = res[alg]
// NOTE: these must be in order of least-specific last...
if(/current image/.test(res)){
toggleImageMark()
var msg = (cur + ' image').toLowerCase()
} else if(/current block/.test(res)){
toggleImageMarkBlock()
var msg = 'toggled block marks'
} else if(/Invert/.test(res)){
invertImageMarks()
var msg = 'inverted ribbon marks'
} else if(/Mark all/.test(res)){
markAll()
var msg = 'marked ribbon'
} else if(/Unmark all in/.test(res)){
removeImageMarks('ribbon')
var msg = 'unmarked ribbon'
} else if(/Unmark all images/.test(res)){
removeImageMarks('all')
var msg = 'unmarked all'
}
showStatusQ('Mark: '+msg+'...')
})
.fail(function(){
showStatusQ('Marking: canceled.')
})
}
/********************************************************************** /**********************************************************************
* vim:set ts=4 sw=4 : */ * vim:set ts=4 sw=4 : */

View File

@ -94,7 +94,6 @@ function setupDataBindings(viewer){
// skip all but the curent ribbon in single image view... // skip all but the curent ribbon in single image view...
if(toggleSingleImageMode('?') == 'on' && r != getRibbonIndex()){ if(toggleSingleImageMode('?') == 'on' && r != getRibbonIndex()){
console.log('>>>> skipping ribbon:', r)
return return
} }
@ -114,7 +113,6 @@ function setupDataBindings(viewer){
var t = getRelativeVisualPosition(viewer, ribbon).top var t = getRelativeVisualPosition(viewer, ribbon).top
// XXX also check for visibility... // XXX also check for visibility...
if( t+h <= 0 || t >= H ){ if( t+h <= 0 || t >= H ){
//console.log('#### skipping align of ribbon:', r)
return return
} }