mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-29 18:30:09 +00:00
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:
parent
84b5cb2e8a
commit
c0168762ea
@ -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 {
|
||||||
|
|||||||
@ -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')
|
||||||
|
|
||||||
|
|||||||
@ -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
13
ui/layout.css
Normal file → Executable 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;
|
||||||
|
|||||||
@ -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 ? ' ' : 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('×')))
|
.html('×')))
|
||||||
@ -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 ? ' ' : 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
|
||||||
}
|
}
|
||||||
|
|||||||
104
ui/marks.js
104
ui/marks.js
@ -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 : */
|
||||||
|
|||||||
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user