mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-30 10:50:08 +00:00
experementing with viewport-relative sizing (buggy in nw 0.8) and some work on images.js, still playing with the organization...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
6f14689747
commit
9056834c07
16
ui (gen4)/css/layout.css
Executable file → Normal file
16
ui (gen4)/css/layout.css
Executable file → Normal file
@ -239,6 +239,8 @@ button:hover {
|
|||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
/********************************************************** Ribbon ***/
|
/********************************************************** Ribbon ***/
|
||||||
|
/* XXX for some reason setting image size in vmin stops this from
|
||||||
|
stretching in width... */
|
||||||
.ribbon {
|
.ribbon {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: block;
|
display: block;
|
||||||
@ -246,14 +248,14 @@ button:hover {
|
|||||||
display: inline-block;*/
|
display: inline-block;*/
|
||||||
|
|
||||||
height: auto;
|
height: auto;
|
||||||
min-width: 0px;
|
/*min-width: 0px;*/
|
||||||
|
|
||||||
|
width: auto;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
font-size: 0;
|
font-size: 0;
|
||||||
float: left;
|
float: left;
|
||||||
clear: both;
|
clear: both;
|
||||||
/* XXX not still sure about this... */
|
|
||||||
|
|
||||||
background: black;
|
background: black;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
@ -283,9 +285,12 @@ button:hover {
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
color: white;
|
color: white;
|
||||||
text-shadow: black 0.1em 0.1em 0.4em, black 0.1em 0.1em;
|
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... */
|
||||||
|
|
||||||
background: no-repeat 50% transparent;
|
background: no-repeat 50% transparent;
|
||||||
background-size: contain;
|
background-size: contain;
|
||||||
border: solid 5px transparent;
|
border: solid 1.5px transparent;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
.current.image {
|
.current.image {
|
||||||
@ -1494,6 +1499,7 @@ progress:not(value)::-webkit-progress-bar {
|
|||||||
}
|
}
|
||||||
/********************************************************** Themes ***/
|
/********************************************************** Themes ***/
|
||||||
/* XXX this is by no means final... */
|
/* XXX this is by no means final... */
|
||||||
|
/*@import "theme-light";*/
|
||||||
.viewer,
|
.viewer,
|
||||||
.light.viewer,
|
.light.viewer,
|
||||||
.light.viewer .overlay-block .background {
|
.light.viewer .overlay-block .background {
|
||||||
@ -1528,6 +1534,7 @@ progress:not(value)::-webkit-progress-bar {
|
|||||||
.light.viewer .progress-bar {
|
.light.viewer .progress-bar {
|
||||||
color: silver;
|
color: silver;
|
||||||
}
|
}
|
||||||
|
/*@import "theme-gray";*/
|
||||||
.gray.viewer,
|
.gray.viewer,
|
||||||
.gray.viewer .overlay-block .background {
|
.gray.viewer .overlay-block .background {
|
||||||
background: #333;
|
background: #333;
|
||||||
@ -1539,6 +1546,7 @@ progress:not(value)::-webkit-progress-bar {
|
|||||||
color: silver;
|
color: silver;
|
||||||
opacity: 0.4;
|
opacity: 0.4;
|
||||||
}
|
}
|
||||||
|
/*@import "theme-dark";*/
|
||||||
.dark.viewer,
|
.dark.viewer,
|
||||||
.dark.viewer .overlay-block .background {
|
.dark.viewer .overlay-block .background {
|
||||||
background: #0a0a0a;
|
background: #0a0a0a;
|
||||||
|
|||||||
@ -5,11 +5,18 @@
|
|||||||
/******************************************************** Settings ***/
|
/******************************************************** Settings ***/
|
||||||
|
|
||||||
@image-tile-size: 300px;
|
@image-tile-size: 300px;
|
||||||
|
// XXX current used version of node-webkit (0.8) is buggy with this...
|
||||||
|
// -- ribbons are not sized horizpntally correctly...
|
||||||
|
//@image-tile-size: 100vmin;
|
||||||
|
|
||||||
@ribbon-mark-offset: 5px;
|
// these are relative to image tile size...
|
||||||
|
@image-border: @image-tile-size/200;
|
||||||
|
@ribbon-margin: @image-tile-size/30;
|
||||||
|
@ribbon-mark-offset: @image-tile-size/200;
|
||||||
|
|
||||||
|
|
||||||
|
// these are relative to dpi/scale...
|
||||||
@ribbon-mark-size: 10px;
|
@ribbon-mark-size: 10px;
|
||||||
|
|
||||||
@single-image-indicator-size: 10px;
|
@single-image-indicator-size: 10px;
|
||||||
|
|
||||||
|
|
||||||
@ -350,13 +357,16 @@ button:hover {
|
|||||||
|
|
||||||
|
|
||||||
/********************************************************** Ribbon ***/
|
/********************************************************** Ribbon ***/
|
||||||
|
/* XXX for some reason setting image size in vmin stops this from
|
||||||
|
stretching in width... */
|
||||||
.ribbon {
|
.ribbon {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: block;
|
display: block;
|
||||||
/* XXX BUG: setting this will mess up new ribbon creation....
|
/* XXX BUG: setting this will mess up new ribbon creation....
|
||||||
display: inline-block;*/
|
display: inline-block;*/
|
||||||
height: auto;
|
height: auto;
|
||||||
min-width: 0px;
|
/*min-width: 0px;*/
|
||||||
|
width: auto;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
font-size: 0;
|
font-size: 0;
|
||||||
@ -364,11 +374,10 @@ button:hover {
|
|||||||
float: left;
|
float: left;
|
||||||
clear: both;
|
clear: both;
|
||||||
|
|
||||||
/* XXX not still sure about this... */
|
|
||||||
background: black;
|
background: black;
|
||||||
|
|
||||||
margin-top: 10px;
|
margin-top: @ribbon-margin;
|
||||||
margin-bottom: 10px;
|
margin-bottom: @ribbon-margin;
|
||||||
}
|
}
|
||||||
.ribbon:empty {
|
.ribbon:empty {
|
||||||
display: none;
|
display: none;
|
||||||
@ -401,9 +410,11 @@ button:hover {
|
|||||||
|
|
||||||
text-shadow: black 0.1em 0.1em 0.4em, black 0.1em 0.1em;
|
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... */
|
||||||
background: no-repeat 50% transparent;
|
background: no-repeat 50% transparent;
|
||||||
background-size: contain;
|
background-size: contain;
|
||||||
border: solid 5px transparent;
|
border: solid @image-border transparent;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
.current.image {
|
.current.image {
|
||||||
@ -1300,6 +1311,8 @@ progress:not(value)::-webkit-progress-bar {
|
|||||||
/********************************************************** Themes ***/
|
/********************************************************** Themes ***/
|
||||||
|
|
||||||
/* XXX this is by no means final... */
|
/* XXX this is by no means final... */
|
||||||
|
/*@import "theme-light";*/
|
||||||
|
|
||||||
.viewer,
|
.viewer,
|
||||||
.light.viewer,
|
.light.viewer,
|
||||||
.light.viewer .overlay-block .background {
|
.light.viewer .overlay-block .background {
|
||||||
@ -1339,6 +1352,9 @@ progress:not(value)::-webkit-progress-bar {
|
|||||||
color: silver;
|
color: silver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*@import "theme-gray";*/
|
||||||
|
|
||||||
.gray.viewer,
|
.gray.viewer,
|
||||||
.gray.viewer .overlay-block .background {
|
.gray.viewer .overlay-block .background {
|
||||||
background: #333;
|
background: #333;
|
||||||
@ -1351,6 +1367,9 @@ progress:not(value)::-webkit-progress-bar {
|
|||||||
opacity: 0.4;
|
opacity: 0.4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*@import "theme-dark";*/
|
||||||
|
|
||||||
.dark.viewer,
|
.dark.viewer,
|
||||||
.dark.viewer .overlay-block .background {
|
.dark.viewer .overlay-block .background {
|
||||||
background: #0a0a0a;
|
background: #0a0a0a;
|
||||||
|
|||||||
@ -105,7 +105,8 @@ module.DataClassPrototype = {
|
|||||||
},
|
},
|
||||||
// XXX is this the right way to construct data???
|
// XXX is this the right way to construct data???
|
||||||
fromJSON: function(data){
|
fromJSON: function(data){
|
||||||
return new Data().loadJSON(data)
|
//return new Data().loadJSON(data)
|
||||||
|
return new this().loadJSON(data)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1402,9 +1403,7 @@ module.DataPrototype = {
|
|||||||
//
|
//
|
||||||
// NOTE: this loads in-place, use .fromJSON(..) to create new data...
|
// NOTE: this loads in-place, use .fromJSON(..) to create new data...
|
||||||
loadJSON: function(data){
|
loadJSON: function(data){
|
||||||
if(typeof(data) == typeof('str')){
|
data = typeof(data) == typeof('str') ? JSON.parse(data) : data
|
||||||
data = JSON.parse(data)
|
|
||||||
}
|
|
||||||
data = formats.updateData(data)
|
data = formats.updateData(data)
|
||||||
this.base = data.base
|
this.base = data.base
|
||||||
this.current = data.current
|
this.current = data.current
|
||||||
|
|||||||
@ -122,11 +122,11 @@ function(img){
|
|||||||
return JSON.parse('"'+$(img).attr('gid')+'"')
|
return JSON.parse('"'+$(img).attr('gid')+'"')
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX getImage(...)
|
// XXX getImage(...) -> ribbons
|
||||||
// XXX getVisibleImageSize(...)
|
// XXX getVisibleImageSize(...) -> ribbons
|
||||||
// XXX getBestPreview(...)
|
// XXX getBestPreview(...) -> ribbons/images
|
||||||
// XXX setImageFlipState(...)
|
// XXX setImageFlipState(...) -> ribbons
|
||||||
// XXX makeGIDDistanceCmp(...)
|
// XXX makeGIDDistanceCmp(...) -> data
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -11,20 +11,201 @@ console.log('>>> images')
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************************************/
|
||||||
|
|
||||||
|
// cmp functions...
|
||||||
|
// XXX is this the right way to seporate these???
|
||||||
|
|
||||||
|
module.makeImageDateCmp = function(data, get){
|
||||||
|
return function(a, b){
|
||||||
|
if(get != null){
|
||||||
|
a = get(a)
|
||||||
|
b = get(b)
|
||||||
|
}
|
||||||
|
b = data[b].ctime
|
||||||
|
a = data[a].ctime
|
||||||
|
|
||||||
|
if(a == b){
|
||||||
|
return 0
|
||||||
|
} else if(a < b){
|
||||||
|
return -1
|
||||||
|
} else {
|
||||||
|
return +1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: this expects gids...
|
||||||
|
module.makeImageNameCmp = function(data, get){
|
||||||
|
return function(a, b){
|
||||||
|
if(get != null){
|
||||||
|
a = get(a)
|
||||||
|
b = get(b)
|
||||||
|
}
|
||||||
|
a = data.getImageFileName(a)
|
||||||
|
b = data.getImageFileName(b)
|
||||||
|
if(a == b){
|
||||||
|
return 0
|
||||||
|
} else if(a < b){
|
||||||
|
return -1
|
||||||
|
} else {
|
||||||
|
return +1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.makeImageSeqOrNameCmp = function(data, get, seq){
|
||||||
|
seq = seq == null ? data.getImageNameSeq : seq
|
||||||
|
|
||||||
|
return function(a, b){
|
||||||
|
// XXX this is ugly and non-generic...
|
||||||
|
if(get != null){
|
||||||
|
a = get(a)
|
||||||
|
b = get(b)
|
||||||
|
}
|
||||||
|
// XXX this is ugly and non-generic...
|
||||||
|
var aa = seq.call(data, a)
|
||||||
|
var bb = seq.call(data, b)
|
||||||
|
|
||||||
|
// special case: seq, name
|
||||||
|
if(typeof(aa) == typeof(123) && typeof(bb) == typeof('str')){ return -1 }
|
||||||
|
// special case: name, seq
|
||||||
|
if(typeof(aa) == typeof('str') && typeof(bb) == typeof(123)){ return +1 }
|
||||||
|
|
||||||
|
// get the names if there are no sequence numbers...
|
||||||
|
// NOTE: at this point both a and b are either numbers or NaN's...
|
||||||
|
a = isNaN(aa) ? data.getImageFileName(a) : aa
|
||||||
|
b = isNaN(bb) ? data.getImageFileName(b) : bb
|
||||||
|
|
||||||
|
// do the actual comparison
|
||||||
|
if(a == b){
|
||||||
|
return 0
|
||||||
|
} else if(a < b){
|
||||||
|
return -1
|
||||||
|
} else {
|
||||||
|
return +1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
|
|
||||||
var ImagesClassPrototype =
|
var ImagesClassPrototype =
|
||||||
module.ImagesClassPrototype = {
|
module.ImagesClassPrototype = {
|
||||||
|
fromJSON: function(data){
|
||||||
|
return new this().loadJSON(data)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var ImagesPrototype =
|
var ImagesPrototype =
|
||||||
module.ImagesPrototype = {
|
module.ImagesPrototype = {
|
||||||
|
|
||||||
|
// Generic helpers...
|
||||||
|
// XXX are these slower than doing it manualy via Object.keys(..)
|
||||||
|
forEach: function(func){
|
||||||
|
var i = 0
|
||||||
|
for(var key in this){
|
||||||
|
func.call(this[key], key, this[key], i++, this)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
},
|
||||||
|
map: function(func){
|
||||||
|
var res = this.constructor()
|
||||||
|
var i = 0
|
||||||
|
for(var key in this){
|
||||||
|
res[k] = func.call(this[key], key, this[key], i++, this)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
},
|
||||||
|
filter: function(func){
|
||||||
|
var res = this.constructor()
|
||||||
|
var i = 0
|
||||||
|
for(var key in this){
|
||||||
|
if(func.call(this[key], key, this[key], i++, this)){
|
||||||
|
res[key] = this[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
// Image data helpers...
|
||||||
|
|
||||||
|
// Get image filename...
|
||||||
|
getImageFileName: function(gid, do_unescape){
|
||||||
|
do_unescape = do_unescape == null ? true : do_unescape
|
||||||
|
if(do_unescape){
|
||||||
|
return unescape(this[gid].path.split('/').pop())
|
||||||
|
} else {
|
||||||
|
return this[gid].path.split('/').pop()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// Get the first sequence of numbers in the file name...
|
||||||
|
getImageNameSeq: function(gid){
|
||||||
|
var n = this.getImageFileName(gid)
|
||||||
|
var r = /([0-9]+)/m.exec(n)
|
||||||
|
return r == null ? n : parseInt(r[1])
|
||||||
|
},
|
||||||
|
// Get the sequence of numbers in the file name but only if it is
|
||||||
|
// at the filename start...
|
||||||
|
getImageNameLeadingSeq: function(gid){
|
||||||
|
var n = this.getImageFileName(gid)
|
||||||
|
var r = /^([0-9]+)/g.exec(n)
|
||||||
|
return r == null ? n : parseInt(r[1])
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
// Gid sorters...
|
||||||
|
// XXX chainCmp(..) is loaded from lib/jli.js
|
||||||
|
sortImages: function(gids, cmp, reverse){
|
||||||
|
gids = gids == null ? Object.keys(this) : gids
|
||||||
|
|
||||||
|
cmp = cmp == null ? module.makeImageDateCmp(this) : cmp
|
||||||
|
cmp = cmp.constructor.name == 'Array' ? chainCmp(cmp) : cmp
|
||||||
|
|
||||||
|
gids = gids.sort(cmp)
|
||||||
|
gids = reverse ? gids.reverse() : gids
|
||||||
|
|
||||||
|
return gids
|
||||||
|
},
|
||||||
|
// Shorthands...
|
||||||
|
// XXX these seem a bit messy...
|
||||||
|
sortByDate: function(gids, reverse){ return this.sortImages(gids, null, reverse) },
|
||||||
|
sortByName: function(gids, reverse){
|
||||||
|
return this.sortImages(gids, module.makeImageNameCmp(this), reverse) },
|
||||||
|
sortBySeqOrName: function(gids, reverse){
|
||||||
|
return this.sortImages(gids, module.makeImageSeqOrNameCmp(this), reverse) },
|
||||||
|
sortByNameXPStyle: function(gids, reverse){
|
||||||
|
return this.sortImages(gids,
|
||||||
|
module.makeImageSeqOrNameCmp(this, null, this.getImageNameLeadingSeq),
|
||||||
|
reverse) },
|
||||||
|
sortByDateOrSeqOrName: function(gids, reverse){
|
||||||
|
return this.sortImages(gids, [
|
||||||
|
module.makeImageDateCmp(this),
|
||||||
|
module.makeImageSeqOrNameCmp(this)
|
||||||
|
], reverse)
|
||||||
|
},
|
||||||
|
// XXX
|
||||||
|
sortedImagesByFileNameSeqWithOverflow: function(gids, reverse){
|
||||||
|
// XXX see ui/sort.js
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
// serialization...
|
||||||
loadJSON: function(data){
|
loadJSON: function(data){
|
||||||
|
data = typeof(data) == typeof('str')
|
||||||
|
? JSON.parse(data)
|
||||||
|
: JSON.parse(JSON.stringify(data))
|
||||||
|
for(var k in data){
|
||||||
|
this[k] = data[k]
|
||||||
|
}
|
||||||
|
return this
|
||||||
},
|
},
|
||||||
dumpJSON: function(data){
|
dumpJSON: function(data){
|
||||||
|
return JSON.parse(JSON.stringify(this))
|
||||||
},
|
},
|
||||||
|
|
||||||
_reset: function(){
|
_reset: function(){
|
||||||
|
|||||||
@ -22,7 +22,7 @@ require('nw.gui').Window.get().showDevTools()
|
|||||||
|
|
||||||
<!-- for viewer structure doc see: ribbons.js... -->
|
<!-- for viewer structure doc see: ribbons.js... -->
|
||||||
|
|
||||||
<div class="viewer dark">
|
<div class="viewer gray">
|
||||||
|
|
||||||
<div class="ribbon-set"></div>
|
<div class="ribbon-set"></div>
|
||||||
|
|
||||||
|
|||||||
@ -100,6 +100,7 @@ module.RibbonsPrototype = {
|
|||||||
//
|
//
|
||||||
// .viewer (jQuery object)
|
// .viewer (jQuery object)
|
||||||
//
|
//
|
||||||
|
// XXX to update images we need to know about images...
|
||||||
|
|
||||||
// Constructors...
|
// Constructors...
|
||||||
createViewer: RibbonsClassPrototype.createViewer,
|
createViewer: RibbonsClassPrototype.createViewer,
|
||||||
@ -152,7 +153,7 @@ module.RibbonsPrototype = {
|
|||||||
return this.viewer.find('.ribbon').index(this.getRibbon(target))
|
return this.viewer.find('.ribbon').index(this.getRibbon(target))
|
||||||
},
|
},
|
||||||
|
|
||||||
// Get ribbon...
|
// Get image...
|
||||||
//
|
//
|
||||||
// Get current image:
|
// Get current image:
|
||||||
// .getImage()
|
// .getImage()
|
||||||
@ -603,6 +604,24 @@ module.RibbonsPrototype = {
|
|||||||
|
|
||||||
// UI manipulation...
|
// UI manipulation...
|
||||||
|
|
||||||
|
// XXX try and make image size the product of vmin and scale...
|
||||||
|
// XXX is this the right place for this???
|
||||||
|
// XXX uses jli.js getElementScale(..)
|
||||||
|
getVisibleImageSize: function(dim){
|
||||||
|
dim = dim == null ? 'width' : dim
|
||||||
|
var img = this.viewer.find('.image')
|
||||||
|
var scale = getElementScale(this.viewer.find('.ribbon-set'))
|
||||||
|
if(dim == 'height'){
|
||||||
|
return img.outerHeight(true) * scale
|
||||||
|
} else if(dim == 'width'){
|
||||||
|
return img.outerWidth(true) * scale
|
||||||
|
} else if(dim == 'max'){
|
||||||
|
return Math.max(img.outerHeight(true), img.outerWidth(true)) * scale
|
||||||
|
} else if(dim == 'min'){
|
||||||
|
return Math.min(img.outerHeight(true), img.outerWidth(true)) * scale
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// XXX if target is an image align the ribbon both vertically and horizontally...
|
// XXX if target is an image align the ribbon both vertically and horizontally...
|
||||||
alignRibbon: function(target, mode){
|
alignRibbon: function(target, mode){
|
||||||
// XXX
|
// XXX
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user