From 12c5ac8693797af297407cdbd53499f954ef1b08 Mon Sep 17 00:00:00 2001 From: "Alex A. Naanou" Date: Wed, 9 Oct 2019 03:04:46 +0300 Subject: [PATCH] sorking on virtual blocks... Signed-off-by: Alex A. Naanou --- ui (gen4)/css/experimenting.css | 2 - ui (gen4)/css/layout.less | 33 ++++- ui (gen4)/features/all.js | 3 + ui (gen4)/features/experimental.js | 65 ---------- ui (gen4)/features/meta.js | 1 + ui (gen4)/features/virtual-images.js | 187 +++++++++++++++++++++++++++ ui (gen4)/imagegrid/images.js | 6 + ui (gen4)/imagegrid/ribbons.js | 131 ++----------------- 8 files changed, 238 insertions(+), 190 deletions(-) create mode 100644 ui (gen4)/features/virtual-images.js diff --git a/ui (gen4)/css/experimenting.css b/ui (gen4)/css/experimenting.css index 3b916514..c9a142d9 100755 --- a/ui (gen4)/css/experimenting.css +++ b/ui (gen4)/css/experimenting.css @@ -524,8 +524,6 @@ body { - - /* DEBUG stuff... */ .container-center { position: absolute; diff --git a/ui (gen4)/css/layout.less b/ui (gen4)/css/layout.less index cf3fcff1..c17774ac 100755 --- a/ui (gen4)/css/layout.less +++ b/ui (gen4)/css/layout.less @@ -695,8 +695,10 @@ stretching in width... */ box-sizing: border-box; color: white; - - text-shadow: black 0.1em 0.1em 0.4em, black 0.1em 0.1em; + /* XXX do we need this??? + text-shadow: + black 0.1em 0.1em 0.4em, + black 0.1em 0.1em; */ /* NOTE: we can't set the bg color here because it will get affected by filters... */ @@ -705,6 +707,28 @@ stretching in width... */ border: solid @image-border transparent; } +.image { + padding: @single-image-indicator-size; +} +.image div { + display: block; + position: absolute; + + max-width: @image-tile-size; + width: auto; + max-height: @image-tile-size; + height: auto; + + left: 50%; + top: 50%; + transform: translate(-50%,-50%); + + white-space: normal; + text-align: center; + text-overflow: ellipsis; + /*font-size: 2vh;*/ +} + .crisp-resize .image { image-rendering: -webkit-optimize-contrast; image-rendering: crisp-edges; @@ -2042,7 +2066,10 @@ progress:not(value)::-webkit-progress-bar { /* XXX this is by no means final... */ /*@import "theme-light";*/ -.viewer, +.light.single-image-mode.viewer .image, +.light.transparent-ribbon.viewer .image { + color: black; +} .light.viewer, .light.viewer .overlay-block .background { background: white; diff --git a/ui (gen4)/features/all.js b/ui (gen4)/features/all.js index 012ce6fe..70e20af6 100755 --- a/ui (gen4)/features/all.js +++ b/ui (gen4)/features/all.js @@ -48,6 +48,9 @@ require('features/external-editor') require('features/metadata') require('features/meta') +// XXX EXPERIMENTAL... +require('features/virtual-images') + require('features/experimental') require('features/tests') require('features/demo') diff --git a/ui (gen4)/features/experimental.js b/ui (gen4)/features/experimental.js index 2b8aa166..2286bcbb 100755 --- a/ui (gen4)/features/experimental.js +++ b/ui (gen4)/features/experimental.js @@ -122,71 +122,6 @@ var ExperimentActions = actions.Actions({ function(){ }], - - - // construction of new "virtual images"... - // - // XXX should this be restricted to collections??? - // XXX should these be importable??? - // i.e. exported as json to .virt and imported back... - // ...might be a good idea to add custom import/export handlers... - // - // XXX do better arg processing -- handle metadata correctly... - // XXX add export support for this type of stuff... - // XXX add default named templates... - // XXX add svg templates... - // - blank (white/black/gray/...) - // - title - // - text - // XXX move to 'virtual-images' feature... - makeVirtualImage: ['Experimental/', - function(ref, offset, metadata){ - ref = ref || 'current' - offset = offset || 'after' - offset = offset == 'after' ? - 1 - : offset == 'before' ? - 0 - : typeof(offset) == typeof(123) ? - offset - : 0 - // XXX revise... - metadata = arguments[arguments.length-1] instanceof Object ? - arguments[arguments.length-1] - : null - - var data = this.data - - ref = data.getImage(ref) - var r = data.getRibbon(ref) - - var gid = data.newGID() - - // place image into data... - var order = data.order - order.splice(order.indexOf(ref)+offset,0, gid) - var ribbon = data.ribbons[r] - ribbon.splice(ribbon.indexOf(ref)+offset,0, gid) - - // update data... - data.updateImagePositions() - - // update metadata... - metadata - && (this.images[gid] = metadata) - - // focus new image... - // NOTE: this should update the view too... - this.focusImage(gid) - }], - // XXX - makeVirtualBlank: ['Experimental/', - function(){ - }], - // XXX - makeVirtualText: ['Experimental/', - function(){ - }], }) var ExperimentFeature = diff --git a/ui (gen4)/features/meta.js b/ui (gen4)/features/meta.js index a801f4b5..99715a45 100755 --- a/ui (gen4)/features/meta.js +++ b/ui (gen4)/features/meta.js @@ -163,6 +163,7 @@ core.ImageGridFeatures.Feature('imagegrid-testing', [ 'ui-preview-filters', 'url-history', 'external-editor', + 'virtual-images', // experimental features... //'ui-range', diff --git a/ui (gen4)/features/virtual-images.js b/ui (gen4)/features/virtual-images.js new file mode 100644 index 00000000..9c98191f --- /dev/null +++ b/ui (gen4)/features/virtual-images.js @@ -0,0 +1,187 @@ +/********************************************************************** +* +* +* +**********************************************************************/ +((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define) +(function(require){ var module={} // make module AMD/node compatible... +/*********************************************************************/ + +var actions = require('lib/actions') +var features = require('lib/features') + +var core = require('features/core') + + + +/*********************************************************************/ + +// XXX revise menu placement... +var VirtualImagesActions = actions.Actions({ + // construction of new "virtual images"... + // + // XXX should this be restricted to collections??? + // XXX should these be importable from fs??? + // i.e. exported as json to <title>.virt and imported back... + // ...might be a good idea to add custom import/export handlers... + // + // XXX do better arg processing -- handle metadata correctly... + // XXX add export support for this type of stuff... + // XXX add default named templates... + // XXX add svg templates??? + makeVirtualBlock: ['- Virtual/', + function(ref, offset, metadata){ + ref = ref || 'current' + offset = offset || 'after' + offset = offset == 'after' ? + 1 + : offset == 'before' ? + 0 + : typeof(offset) == typeof(123) ? + offset + : 0 + // XXX revise... + metadata = arguments[arguments.length-1] instanceof Object ? + arguments[arguments.length-1] + : null + + var data = this.data + + ref = data.getImage(ref) + var r = data.getRibbon(ref) + + var gid = data.newGID() + + // place image into data... + var order = data.order + order.splice(order.indexOf(ref)+offset,0, gid) + var ribbon = data.ribbons[r] + ribbon.splice(ribbon.indexOf(ref)+offset,0, gid) + + // update data... + data.updateImagePositions() + + // update metadata... + metadata + && (this.images[gid] = metadata) + + // focus new image... + // NOTE: this should update the view too... + this.focusImage(gid) + }], + + // XXX + makeVirtualBlank: ['Virtual/Add blank after', + core.doc``, + //{ browseMode: function(){ return !this.collection && 'disabled' }, }, + function(ref, offset){ + this.makeVirtualBlock(ref, offset, { + type: 'virtual', + path: null, + }) }], + makeVirtualText: ['Virtual/Add text block after', + core.doc` + + NOTE: this was not designed for complex HTML, only use simple + formatted text.`, + //{ browseMode: function(){ return !this.collection && 'disabled' }, }, + function(text, ref, offset){ + this.makeVirtualBlock(ref, offset, { + type: 'virtual', + path: null, + text: text || '', + }) }], + + // XXX virtual block editor UI... + // XXX + + + // XXX export... +}) + +var VirtualImages = +module.VirtualImages = core.ImageGridFeatures.Feature({ + title: '', + doc: '', + + tag: 'virtual-images', + depends: [ + 'edit', + // XXX + ], + suggested: [ + 'ui-virtual-images', + ], + + actions: VirtualImagesActions, + +}) + + + + +//--------------------------------------------------------------------- + +var VirtualImagesUIActions = actions.Actions({ + // XXX +}) + +var VirtualImagesUI = +module.VirtualImagesUI = core.ImageGridFeatures.Feature({ + title: '', + doc: '', + + tag: 'ui-virtual-images', + depends: [ + 'ui', + 'virtual-images' + ], + + actions: VirtualImagesUIActions, + + handlers: [ + ['updateImage', + function(res, gid, img){ + var image = this.images[gid] || {} + + // set image content... + if(image.type == 'virtual' && image.text){ + var text = document.createElement('div') + text.innerHTML = image.text + img[0].innerHTML = '' + img[0].appendChild(text) + + // threshold after which we try to fill the volume... + var C = 100 + + // scale the text if it is small... + var R = img[0].offsetHeight * 0.8 + var r = image.text.length > C ? + Math.max( + text.offsetWidth, + text.offsetHeight, + // keep large text blocks roughly square-ish... + Math.sqrt(text.scrollHeight * text.scrollWidth)) + : Math.max( + text.offsetWidth, + text.offsetHeight, + text.scrollHeight, + text.scrollWidth) + var s = R/r + text.style.fontSize = `${ 100*s }%` + // prioritize width... + text.style.width = '100%' + + // clear reused image content... + } else if(img[0].innerHTML != ''){ + img[0].innerHTML = '' + } + }], + ], +}) + + + + +/********************************************************************** +* vim:set ts=4 sw=4 : */ return module }) diff --git a/ui (gen4)/imagegrid/images.js b/ui (gen4)/imagegrid/images.js index 1ceebb29..898300ca 100755 --- a/ui (gen4)/imagegrid/images.js +++ b/ui (gen4)/imagegrid/images.js @@ -495,6 +495,12 @@ module.ImagesPrototype = { //gid = gid == null ? getImageGID(): gid //size = size == null ? getVisibleImageSize('max') : size img_data = img_data == null ? this[gid] : img_data + img_data = img_data || IMAGE_DATA + + // if path is explicitly null there are no previews... + if(img_data.path === null){ + return undefined + } // if no usable images are available use STUB data... if(!img_data diff --git a/ui (gen4)/imagegrid/ribbons.js b/ui (gen4)/imagegrid/ribbons.js index 89fa15e7..da8f6408 100755 --- a/ui (gen4)/imagegrid/ribbons.js +++ b/ui (gen4)/imagegrid/ribbons.js @@ -1514,126 +1514,12 @@ var RibbonsPrototype = { // .correctImageProportionsForRotation(..) // // .updateImageIndicators(..) - _updateImage: function(image, gid, size, sync){ - image = (image == '*' ? this.viewer.find(IMAGE) - : image == null - || typeof(image) == typeof('str') ? this.getImage(image) - : $(image)) - sync = sync == null ? this.load_img_sync : sync - size = size == null ? this.getVisibleImageSize('max') : size - - var that = this - return $(image.map(function(){ - var image = this instanceof String - || typeof(this) == typeof('str') - ? that.getImage(this+'') - : $(this) - if(image.length == 0){ - return - } - var old_gid = that.elemGID(image) - - // same image -- update... - if(old_gid == gid || gid == null){ - var gid = old_gid - - // reuse for different image -- reconstruct... - } else { - // remove old marks... - if(typeof(old_gid) == typeof('str')){ - that.getImageMarks(old_gid).remove() - } - // reset gid... - image - .attr('gid', JSON.stringify(gid) - // this removes the extra quots... - .replace(/^"(.*)"$/g, '$1')) - .css({ - // clear the old preview... - 'background-image': '', - }) - } - - // if no images data defined drop out... - if(that.images == null){ - return image[0] - } - - // get the image data... - var img_data = that.images[gid] - if(img_data == null){ - img_data = images.IMAGE_DATA - } - - // if we are a group, get the cover... - // NOTE: groups can be nested... - var seen = [] - while(img_data.type == 'group'){ - // error, recursive group... - if(seen.indexOf(img_data.id) >= 0){ - img_data = images.IMAGE_DATA - console.error('Recursive group:', gid) - break - } - seen.push(img_data.id) - - img_data = that.images[img_data.cover] - } - - // image state... - //that.rotateImage(image, img_data.orientation == null ? 0 : img_data.orientation) - //that.flipImage(image, img_data.flipped == null ? [] : img_data.flipped) - image.attr({ - orientation: img_data.orientation == null ? '' : img_data.orientation*1, - flipped: (img_data.flipped == null ? [] : img_data.flipped).join(', '), - }) - - // preview... - var p_url = that.images.getBestPreview(img_data.id, size, img_data, true).url - - // update the preview if it's a new image or... - // XXX this should be pushed as far back as possible... - if(old_gid != gid - // the new preview (p_url) is different to current... - // NOTE: this may not work correctly for relative urls... - || image.css('background-image').indexOf(util.path2url(p_url)) < 0){ - // sync load... - if(sync){ - that._loadImagePreviewURL(image, p_url) - - // async load... - } else { - // NOTE: storing the url in .data() makes the image load the - // last requested preview and in a case when we manage to - // call updateImage(...) on the same element multiple times - // before the previews get loaded... - // ...setting the data().loading is sync while loading an - // image is not, and if several loads are done in sequence - // there is no guarantee that they will happen in the same - // order as requested... - image.data().loading = p_url - setTimeout(function(){ - that._loadImagePreviewURL(image, image.data().loading) - }, 0) - } - } - - // NOTE: this only has effect on non-square image blocks... - // XXX this needs the loaded image, thus should be done right - // after preview loading... - // XXX preview loading is async, is this the right - // place for this?? - // ...this is also done in .rotateImage(..) above... - that.correctImageProportionsForRotation(image) - - // marks and other indicators... - that.updateImageIndicators(gid, image) - - return image[0] - })) - }, + // // XXX add options for images to preload and only then do the update... // XXX really slow for very large numbers of input images/gids... + // XXX add support for basic image templating here... + // ...templates for blank images, text blocks and other stuff, + // this would best be done by simply filling in SVG templates... updateImage: function(image, gid, size, sync, callback){ var that = this var imgs = this.viewer.find(IMAGE) @@ -1729,8 +1615,13 @@ var RibbonsPrototype = { //will_change.push('transform') // stage background image update... - var p_url = that.images.getBestPreview(img_data.id, size, img_data, true).url - if(old_gid != gid + // XXX add support for basic templating here... + var p_url = (that.images.getBestPreview(img_data.id, size, img_data, true) || {}).url + // no preview -> reset bg... + if(p_url == null){ + image[0].style.backgroundImage = '' + + } else if(old_gid != gid // the new preview (p_url) is different to current... // NOTE: this may not work correctly for relative urls... || image.css('background-image').indexOf(util.path2url(p_url)) < 0){