experimenting...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2017-07-29 21:39:47 +03:00
parent 6f8ef29f2e
commit 831e82a28a
6 changed files with 434 additions and 112 deletions

View File

@ -19,6 +19,7 @@
border-bottom: solid 5px red;
}
.mark,
.image {
position: relative;
display: inline-block;
@ -28,14 +29,37 @@
outline: solid 1px blue;
background: silver;
vertical-align: middle;
}
.image:after {
content: attr(gid);
}
.current.image {
background: gray;
}
.mark {
position: absolute;
margin-left: -100px;
background: none;
pointer-events: none;
}
.mark:after {
position: absolute;
content: "";
top: 0;
right: 0;
width: 0;
height: 0;
border: solid 10px red;
border-bottom-color: transparent;
border-left-color: transparent;
pointer-events: auto;
}
</style>
@ -63,7 +87,7 @@ var stub_data = {
order: [].slice.call('abcdefghijklmopqrstuvwxyz'),
tags: {
a: [].slice.call('ahdtu'),
selected: [].slice.call('ahdtu'),
b: [].slice.call('adxz'),
},
@ -109,11 +133,23 @@ class IGRibbon extends preact.Component {
var data = props.data
var ribbon = props.gid
var images = data.ribbons[ribbon].map(function(gid){
return h(IGImage, {
gid: gid,
data: data
})})
var images = data.ribbons[ribbon]
.map(function(gid){
var marks = data.tags.selected.indexOf(gid) >= 0 ?
h(IGImageMark, {
gid: gid,
type: 'selected',
data: data,
})
: []
return [
h(IGImage, {
gid: gid,
data: data,
})].concat(marks)
})
.reduce(function(a, b){ return a.concat(b) })
.filter(function(a){ return !!a })
var base = data.base == ribbon ? ['base'] : []
@ -146,14 +182,22 @@ class IGImage extends preact.Component {
// XXX background-image...
},
// XXX experiemnt...
// XXX STUB
onClick: function(evt){
// toggle tag...
if(data.current == gid){
var selected = data.tags.selected = data.tags.selected || []
selected.indexOf(gid) < 0 ?
selected.push(gid)
: selected.splice(selected.indexOf(gid), 1)
}
// set current...
data.current = gid
render()
}
}, [
gid
])
},
})
}
}
@ -161,10 +205,22 @@ class IGImage extends preact.Component {
// - image mark
class IGImageMark extends preact.Component {
render(props, state){
var gid = props.gid
var type = props.type
var data = props.data
return h('div',
{
classList: ['mark'],
gid: props.gid,
classList: ['mark'].concat([type]).join(' '),
gid: gid,
// XXX STUB...
// ...and there is no way to add the mark back...
onClick: function(evt){
data.tags[type].splice(data.tags[type].indexOf(gid), 1)
render()
},
})
}
}

View File

@ -26,13 +26,26 @@ var ribbons = require('imagegrid/ribbons')
/*********************************************************************/
var RibbonsClassPrototype = {
// This is needed to calculate image size when no images are loaded...
createImage: function(){
// XXX
},
// XXX
}
RibbonsClassPrototype.__proto__ = ribbons.BaseRibbons.prototype.__proto__
var RibbonsPrototype = {
viewer: null,
createImage: RibbonsClassPrototype.createImage,
// XXX
__init__: function(viewer, images){
// XXX
},
}
RibbonsPrototype.__proto__ = ribbons.BaseRibbons.prototype
@ -77,14 +90,36 @@ var RenderActions = actions.Actions({
}],
reload: [
function(){
// full reload...
if(force == 'full'){
//this.stop()
/*
killAllWorkers()
.done(function(){
reload()
})
*/
return location.reload()
}
if(!this.ribbons){
return
}
// XXX
}],
refresh: [
function(){
if(!this.ribbons){
return
}
// XXX
}],
clear: [
function(){
if(!this.ribbons){
return
}
// XXX
}],
@ -106,6 +141,9 @@ var RenderActions = actions.Actions({
viewScale: ['- Zoom/',
function(scale){
if(!this.ribbons){
return
}
if(scale == null || scale == '?'){
return // XXX get scale...
}
@ -116,22 +154,43 @@ var RenderActions = actions.Actions({
}],
fitImage: ['Zoom/Fit image',
function(count, overflow){
if(!this.ribbons){
return
}
if(count == '?'){
return // XXX get size...
}
this.resizing.chainCall(this, function(){
if(count != null){
overflow = overflow == false ? 0 : overflow
var o = overflow != null ? overflow
: count % 2 != 1 ? 0
: (this.config['fit-overflow'] || 0)
count += o
}
// set the scale...
// XXX
// refresh image previews...
// XXX
}, 'screenwidth', count, overflow)
}],
fitRibbon: ['Zoom/Fit ribbon vertically',
function(count, whole){
if(!this.ribbons){
return
}
if(count == '?'){
return // XXX get size...
}
this.resizing.chainCall(this, function(){
// XXX set size...
// XXX refresh image previews...
}, 'screenheight', count, whole)
}],
@ -139,15 +198,24 @@ var RenderActions = actions.Actions({
centerImage: ['- Interface/Center an image in ribbon horizontally',
function(target, align, offset, scale){
if(!this.ribbons){
return
}
// XXX
}],
centerRibbon: ['- Interface/Center a ribbon vertically',
function(target){
if(!this.ribbons){
return
}
// XXX
}],
ribbonRotation: ['- Interface|Ribbon/',
function(angle){
if(!this.ribbons){
return
}
// XXX
}],
})

View File

@ -37,33 +37,28 @@ var ribbons = require('imagegrid/ribbons')
// - do we update preview in Preact render or outside?
//
// render:
// - ribbon-set
// - ribbon-locator
// - current-indicator (???)
//
// * this is static and only created once...
class IGRibbonSet extends preact.Component {
render(props, state){
// XXX need:
// - scale
// - ribbons
var ribbons = data.ribbon_order
.map(function(gid){ return h(IGRibbon, {
ribbon: gid,
// XXX
var data = props.data
var ribbons = data.ribbon_order.map(function(gid){
return h(IGRibbon, {
gid: gid,
current: data.current,
base: data.base,
data: data
}) })
var s = props.scale || 1
return h('div.ribbon-set',
return h('div',
{
className: 'ribbon-set',
style: {
transform: 'scale('+ s +', '+ s +')',
},
}, [
h('div.current-marker'),
h('div.ribbon-locator', null, ribbons),
h('div', {className: 'current-marker'}),
h('div', {className: 'ribbon-locator'}, ribbons),
])
}
}
@ -72,8 +67,42 @@ class IGRibbonSet extends preact.Component {
// - ribbon
// - images
// - image marks
//
// XXX needs horizontal align...
class IGRibbon extends preact.Component {
render(props, state){
var data = props.data
var ribbon = props.gid
var images = data.ribbons[ribbon]
.map(function(gid){
var marks = data.tags.selected.indexOf(gid) >= 0 ?
h(IGImageMark, {
gid: gid,
type: 'selected',
data: data,
})
: []
return [
h(IGImage, {
gid: gid,
data: data,
})].concat(marks)
})
.reduce(function(a, b){ return a.concat(b) })
.filter(function(a){ return !!a })
var base = data.base == ribbon ? ['base'] : []
return h('div',
{
classList: ['ribbon'].concat(base).join(' '),
gid: props.gid,
style: {
// XXX offset...
},
}, images)
}
}
@ -81,6 +110,21 @@ class IGRibbon extends preact.Component {
// - image
class IGImage extends preact.Component {
render(props, state){
var data = props.data || {}
var gid = props.gid
return h('div',
{
classList: ['image']
.concat(data.current == gid ? ['current'] : [])
.join(' '),
gid: gid || '',
style: {
// XXX background-image...
},
// XXX handle clicks???
})
}
}
@ -88,6 +132,15 @@ class IGImage extends preact.Component {
// - image mark
class IGImageMark extends preact.Component {
render(props, state){
var gid = props.gid
var type = props.type
var data = props.data
return h('div',
{
classList: ['mark'].concat([type]).join(' '),
gid: gid,
})
}
}
@ -96,13 +149,45 @@ class IGImageMark extends preact.Component {
//---------------------------------------------------------------------
var RibbonsClassPrototype = {
// XXX
// XXX this is almost exclusively needed for determining scale...
createImage: function(){
return preact.render(h(IGImage)) },
}
RibbonsClassPrototype.__proto__ = ribbons.BaseRibbons.prototype.__proto__
var RibbonsPrototype = {
// XXX
viewer: null,
dom: null,
createImage: RibbonsClassPrototype.createImage,
update: function(data, full){
if(!data){
return
}
full
&& this.clear()
this.dom = preact.render(
h(IGRibbonSet, {
data: data,
images: this.images || {},
scale: this.scale() || 1,
}),
this.viewer[0],
this.dom)
return this
},
clear: function(){
if(this.dom){
this.dom.remove()
delete this.dom
}
return this
},
}
RibbonsPrototype.__proto__ = ribbons.BaseRibbons.prototype
@ -116,6 +201,22 @@ object.makeConstructor('Ribbons',
/*********************************************************************/
// Checklist:
// - full ribbons:
// - build the initial DOM - DONE
// - centering - DONE
// - scaling - DONE (save/restore does not work)
// - ribbon up/down navigation - XXX
// XXX BUG: up does not hit limit on top ribbon,
// similar thing sometimes happened on down...
// XXX see if we need to put .focusRibbon(..) in ui???
// - shifting images - XXX
// - preview setting -
// - marks -
// - partial ribbons:
// - XXX
//
//
var RenderActions = actions.Actions({
get dom(){
@ -143,18 +244,47 @@ var RenderActions = actions.Actions({
this.reload()
}
}],
// XXX do a full reload...
reload: [
function(){
function(force){
// full reload...
if(force == 'full'){
//this.stop()
/*
killAllWorkers()
.done(function(){
reload()
})
*/
return location.reload()
}
// XXX is this correct here???
this.ribbons.preventTransitions()
if(!this.ribbons){
return
}
// XXX need to get the data...
// XXX
this.ribbons.update(this.data, force)
this.ribbons.restoreTransitions()
}],
// XXX refresh the previews...
refresh: [
function(){
if(!this.ribbons){
return
}
// XXX need to get the data...
// XXX
this.ribbons.update(this.data)
}],
clear: [
function(){
// XXX
}],
function(){ this.ribbons && this.ribbons.clear() }],
resizing: [
core.notUserCallable(function(unit, size, overflow){
@ -174,32 +304,56 @@ var RenderActions = actions.Actions({
viewScale: ['- Zoom/',
function(scale){
if(!this.ribbons){
return
}
if(scale == null || scale == '?'){
return // XXX get scale...
return this.ribbons.scale()
}
this.resizing.chainCall(this, function(){
// XXX set scale...
this.ribbons.scale(scale)
}, 'scale', scale)
}],
fitImage: ['Zoom/Fit image',
function(count, overflow){
if(!this.ribbons){
return
}
if(count == '?'){
return // XXX get size...
return this.ribbons.getScreenWidthImages()
}
this.resizing.chainCall(this, function(){
// XXX
if(count != null){
overflow = overflow == false ? 0 : overflow
var o = overflow != null ? overflow
: count % 2 != 1 ? 0
: (this.config['fit-overflow'] || 0)
count += o
}
// set the scale...
this.ribbons.fitImage(count)
// XXX refresh image previews...
}, 'screenwidth', count, overflow)
}],
fitRibbon: ['Zoom/Fit ribbon vertically',
function(count, whole){
if(!this.ribbons){
return
}
if(count == '?'){
return // XXX get size...
return this.ribbons.getScreenHeightRibbons()
}
this.resizing.chainCall(this, function(){
// XXX set size...
this.ribbons.fitRibbon(count, whole)
// XXX refresh image previews...
}, 'screenheight', count, whole)
}],
@ -207,17 +361,45 @@ var RenderActions = actions.Actions({
centerImage: ['- Interface/Center an image in ribbon horizontally',
function(target, align, offset, scale){
// XXX
}],
this.ribbons && this.ribbons.centerImage(target, align, offset, scale) }],
centerRibbon: ['- Interface/Center a ribbon vertically',
function(target){
// XXX
}],
this.ribbons && this.ribbons.centerRibbon(target) }],
ribbonRotation: ['- Interface|Ribbon/',
function(angle){
// XXX
}],
// XXX should these be here, in ui or in ribbons???
// XXX these are identical to features/ui-ribbons.js
focusRibbon: [
function(target, mode){
mode = mode || this.config['ribbon-focus-mode']
var c = this.data.getRibbonOrder()
var i = this.data.getRibbonOrder(target)
// NOTE: we are not changing the direction here based on
// this.direction as swap will confuse the user...
var direction = c < i ? 'before' : 'after'
if(mode == 'visual'){
var ribbons = this.ribbons
var r = this.data.getRibbon(target)
var t = ribbons.getImageByPosition('current', r)
if(t.length > 1){
t = t.eq(direction == 'before' ? 0 : 1)
}
t = ribbons.elemGID(t)
this.focusImage(t, r)
}
}],
})
var Render =
@ -234,7 +416,16 @@ module.Render = core.ImageGridFeatures.Feature({
actions: RenderActions,
handlers: [
// XXX
[[
'shiftImageTo',
'shiftImageUp',
'shiftImageDown',
'shiftImageLeft',
'shiftImageRight',
], function(){
// XXX stub...
this.reload()
}],
],
})

View File

@ -153,7 +153,7 @@ actions.Actions({
reload()
})
*/
location.reload()
return location.reload()
}
this.ribbons.preventTransitions()
@ -295,6 +295,8 @@ actions.Actions({
}],
// XXX should these be here, in ui or in ribbons???
// XXX these are identical to features/ui-preact-render.js
focusImage: [
function(target, list){
return function(){

View File

@ -1314,6 +1314,7 @@ var ControlActions = actions.Actions({
// XXX do not do anything on viewer focus... (???)
// XXX depends on .ribbons...
// XXX uses: .focusImage(..)
toggleImageClickHandling: ['Interface/Image click handling',
toggler.Toggler(null,
function(_, new_state){
@ -1518,6 +1519,7 @@ var ControlActions = actions.Actions({
// ...found the problem, need to disable transitions for this
// to work semi smoothly...
// XXX depends on .ribbons...
// XXX uses: .focusImage(..)
toggleRibbonPanHandling: ['Interface/Ribbon pan handling',
toggler.Toggler(null,
function(_, new_state){
@ -1756,6 +1758,7 @@ var ControlActions = actions.Actions({
// XXX BUG?: acceleration seems to be increasing with time...
// XXX add a "ribbonWheeling" ( ;) ) event a-la ribbonPanning...
// XXX depends on .ribbons...
// XXX uses: .focusImage(..)
toggleMouseWheelHandling: ['Interface/Mouse wheel handling',
toggler.Toggler(null,
function(_, new_state){

View File

@ -350,7 +350,6 @@ var BaseRibbonsPrototype = {
return this
},
// Get visible image tile size...
//
// .getVisibleImageSize()
@ -369,6 +368,7 @@ var BaseRibbonsPrototype = {
//
// XXX this might break when no images are loaded and proportions
// are not square...
// XXX this depends on .createImage(..)
getVisibleImageSize: function(dim, scale, img, force){
dim = dim == null ? 'width' : dim
img = img || this.viewer.find(IMAGE)
@ -385,7 +385,7 @@ var BaseRibbonsPrototype = {
// if no images are loaded create one temporarily....
if(img.length == 0){
img = tmp = this.createImage('__tmp_image__')
img = tmp = $(this.createImage('__tmp_image__'))
.css({
position: 'absolute',
visibility: 'hidden',
@ -449,6 +449,68 @@ var BaseRibbonsPrototype = {
return H/h
},
// Fit image to view...
//
// If n is given this will fit n images (default: 1)
//
// NOTE: this will never scale the view in a way that an image
// overflows either in height nor width.
//
// XXX might be useful to set origin before scaling...
fitImage: function(n, min){
n = n || 1
// NOTE: this is width oriented...
var scale = this.getScreenWidthImages(1, min) / n
// check bounds...
var H = this.viewer.height()
var h = this.getVisibleImageSize('height', 1)
// n images will be higher than the viewer, adjust for height...
if(h*scale >= H){
scale = H/h
}
this
.scale(scale)
//.centerRibbon(null, null, scale)
//.centerImage(null, null, null, scale)
return this
},
// NOTE: if fit_whole_images is true (default) this will fit a discrete
// number of images in width...
// XXX this does not account for ribbon spacing...
fitRibbon: function(n, fit_whole_images){
n = n || 1
fit_whole_images = fit_whole_images == null ? true : false
var scale = this.getScreenHeightRibbons(1) / n
var w = this.getVisibleImageSize('width', 1)
var W = this.viewer.width()
// n ribbons will be wider than the viewer...
if(w*scale >= W){
scale = W/w
}
// shift the scale to the point where screen width is a whole
// number of images...
if(fit_whole_images){
var d = this.getScreenWidthImages(scale)
d = d / Math.ceil(d)
scale *= d
}
this.scale(scale)
return this
},
// Contextual getters...
// Get ribbon-set...
@ -2489,66 +2551,6 @@ var RibbonsPrototype = {
return this.flipImage(target, 'horizontal', reference) },
// Fit image to view...
//
// If n is given this will fit n images (default: 1)
//
// NOTE: this will never scale the view in a way that an image
// overflows either in height nor width.
//
// XXX might be useful to set origin before scaling...
fitImage: function(n, min){
n = n || 1
// NOTE: this is width oriented...
var scale = this.getScreenWidthImages(1, min) / n
// check bounds...
var H = this.viewer.height()
var h = this.getVisibleImageSize('height', 1)
// n images will be higher than the viewer, adjust for height...
if(h*scale >= H){
scale = H/h
}
this
.scale(scale)
//.centerRibbon(null, null, scale)
//.centerImage(null, null, null, scale)
return this
},
// NOTE: if fit_whole_images is true (default) this will fit a discrete
// number of images in width...
// XXX this does not account for ribbon spacing...
fitRibbon: function(n, fit_whole_images){
n = n || 1
fit_whole_images = fit_whole_images == null ? true : false
var scale = this.getScreenHeightRibbons(1) / n
var w = this.getVisibleImageSize('width', 1)
var W = this.viewer.width()
// n ribbons will be wider than the viewer...
if(w*scale >= W){
scale = W/w
}
// shift the scale to the point where screen width is a whole
// number of images...
if(fit_whole_images){
var d = this.getScreenWidthImages(scale)
d = d / Math.ceil(d)
scale *= d
}
this.scale(scale)
return this
},
}
RibbonsPrototype.__proto__ = BaseRibbonsPrototype