mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-29 10:20: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;
|
||||
}
|
||||
/********************************************************** Ribbon ***/
|
||||
/* XXX for some reason setting image size in vmin stops this from
|
||||
stretching in width... */
|
||||
.ribbon {
|
||||
position: relative;
|
||||
display: block;
|
||||
@ -246,14 +248,14 @@ button:hover {
|
||||
display: inline-block;*/
|
||||
|
||||
height: auto;
|
||||
min-width: 0px;
|
||||
/*min-width: 0px;*/
|
||||
|
||||
width: auto;
|
||||
overflow: visible;
|
||||
white-space: nowrap;
|
||||
font-size: 0;
|
||||
float: left;
|
||||
clear: both;
|
||||
/* XXX not still sure about this... */
|
||||
|
||||
background: black;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
@ -283,9 +285,12 @@ button:hover {
|
||||
box-sizing: border-box;
|
||||
color: white;
|
||||
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-size: contain;
|
||||
border: solid 5px transparent;
|
||||
border: solid 1.5px transparent;
|
||||
}
|
||||
/*
|
||||
.current.image {
|
||||
@ -1494,6 +1499,7 @@ progress:not(value)::-webkit-progress-bar {
|
||||
}
|
||||
/********************************************************** Themes ***/
|
||||
/* XXX this is by no means final... */
|
||||
/*@import "theme-light";*/
|
||||
.viewer,
|
||||
.light.viewer,
|
||||
.light.viewer .overlay-block .background {
|
||||
@ -1528,6 +1534,7 @@ progress:not(value)::-webkit-progress-bar {
|
||||
.light.viewer .progress-bar {
|
||||
color: silver;
|
||||
}
|
||||
/*@import "theme-gray";*/
|
||||
.gray.viewer,
|
||||
.gray.viewer .overlay-block .background {
|
||||
background: #333;
|
||||
@ -1539,6 +1546,7 @@ progress:not(value)::-webkit-progress-bar {
|
||||
color: silver;
|
||||
opacity: 0.4;
|
||||
}
|
||||
/*@import "theme-dark";*/
|
||||
.dark.viewer,
|
||||
.dark.viewer .overlay-block .background {
|
||||
background: #0a0a0a;
|
||||
|
||||
@ -5,11 +5,18 @@
|
||||
/******************************************************** Settings ***/
|
||||
|
||||
@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;
|
||||
|
||||
@single-image-indicator-size: 10px;
|
||||
|
||||
|
||||
@ -350,13 +357,16 @@ button:hover {
|
||||
|
||||
|
||||
/********************************************************** Ribbon ***/
|
||||
/* XXX for some reason setting image size in vmin stops this from
|
||||
stretching in width... */
|
||||
.ribbon {
|
||||
position: relative;
|
||||
display: block;
|
||||
/* XXX BUG: setting this will mess up new ribbon creation....
|
||||
display: inline-block;*/
|
||||
height: auto;
|
||||
min-width: 0px;
|
||||
/*min-width: 0px;*/
|
||||
width: auto;
|
||||
overflow: visible;
|
||||
white-space: nowrap;
|
||||
font-size: 0;
|
||||
@ -364,11 +374,10 @@ button:hover {
|
||||
float: left;
|
||||
clear: both;
|
||||
|
||||
/* XXX not still sure about this... */
|
||||
background: black;
|
||||
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
margin-top: @ribbon-margin;
|
||||
margin-bottom: @ribbon-margin;
|
||||
}
|
||||
.ribbon:empty {
|
||||
display: none;
|
||||
@ -401,9 +410,11 @@ button:hover {
|
||||
|
||||
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-size: contain;
|
||||
border: solid 5px transparent;
|
||||
border: solid @image-border transparent;
|
||||
}
|
||||
/*
|
||||
.current.image {
|
||||
@ -1300,6 +1311,8 @@ progress:not(value)::-webkit-progress-bar {
|
||||
/********************************************************** Themes ***/
|
||||
|
||||
/* XXX this is by no means final... */
|
||||
/*@import "theme-light";*/
|
||||
|
||||
.viewer,
|
||||
.light.viewer,
|
||||
.light.viewer .overlay-block .background {
|
||||
@ -1339,6 +1352,9 @@ progress:not(value)::-webkit-progress-bar {
|
||||
color: silver;
|
||||
}
|
||||
|
||||
|
||||
/*@import "theme-gray";*/
|
||||
|
||||
.gray.viewer,
|
||||
.gray.viewer .overlay-block .background {
|
||||
background: #333;
|
||||
@ -1351,6 +1367,9 @@ progress:not(value)::-webkit-progress-bar {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
|
||||
/*@import "theme-dark";*/
|
||||
|
||||
.dark.viewer,
|
||||
.dark.viewer .overlay-block .background {
|
||||
background: #0a0a0a;
|
||||
|
||||
@ -105,7 +105,8 @@ module.DataClassPrototype = {
|
||||
},
|
||||
// XXX is this the right way to construct 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...
|
||||
loadJSON: function(data){
|
||||
if(typeof(data) == typeof('str')){
|
||||
data = JSON.parse(data)
|
||||
}
|
||||
data = typeof(data) == typeof('str') ? JSON.parse(data) : data
|
||||
data = formats.updateData(data)
|
||||
this.base = data.base
|
||||
this.current = data.current
|
||||
|
||||
@ -122,11 +122,11 @@ function(img){
|
||||
return JSON.parse('"'+$(img).attr('gid')+'"')
|
||||
}
|
||||
|
||||
// XXX getImage(...)
|
||||
// XXX getVisibleImageSize(...)
|
||||
// XXX getBestPreview(...)
|
||||
// XXX setImageFlipState(...)
|
||||
// XXX makeGIDDistanceCmp(...)
|
||||
// XXX getImage(...) -> ribbons
|
||||
// XXX getVisibleImageSize(...) -> ribbons
|
||||
// XXX getBestPreview(...) -> ribbons/images
|
||||
// XXX setImageFlipState(...) -> ribbons
|
||||
// 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 =
|
||||
module.ImagesClassPrototype = {
|
||||
|
||||
fromJSON: function(data){
|
||||
return new this().loadJSON(data)
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
var 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){
|
||||
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){
|
||||
return JSON.parse(JSON.stringify(this))
|
||||
},
|
||||
|
||||
_reset: function(){
|
||||
|
||||
@ -22,7 +22,7 @@ require('nw.gui').Window.get().showDevTools()
|
||||
|
||||
<!-- for viewer structure doc see: ribbons.js... -->
|
||||
|
||||
<div class="viewer dark">
|
||||
<div class="viewer gray">
|
||||
|
||||
<div class="ribbon-set"></div>
|
||||
|
||||
|
||||
@ -100,6 +100,7 @@ module.RibbonsPrototype = {
|
||||
//
|
||||
// .viewer (jQuery object)
|
||||
//
|
||||
// XXX to update images we need to know about images...
|
||||
|
||||
// Constructors...
|
||||
createViewer: RibbonsClassPrototype.createViewer,
|
||||
@ -152,7 +153,7 @@ module.RibbonsPrototype = {
|
||||
return this.viewer.find('.ribbon').index(this.getRibbon(target))
|
||||
},
|
||||
|
||||
// Get ribbon...
|
||||
// Get image...
|
||||
//
|
||||
// Get current image:
|
||||
// .getImage()
|
||||
@ -603,6 +604,24 @@ module.RibbonsPrototype = {
|
||||
|
||||
// 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...
|
||||
alignRibbon: function(target, mode){
|
||||
// XXX
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user