Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
#!/usr/bin/seed
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio
const LEFT = 113;
const RIGHT = 114;
var gallery = {
stage: null,
icons: null,
files: null,
preview_num: 5,
preview_group: null,
width: 1024,
height: 600,
thumbnail_width: 120,
thumbnail_height: 60,
margin: 20,
preview_width: 0,
main_image: null,
black: null,
preview_list: null,
init: function() {
Clutter.init (0, null);
var stage = new Clutter.Stage ();
this.stage = stage;
this.icons = [];
this.preview_list = [];
this.preview_group = new Clutter.Group ();
stage.set_width (this.width);
stage.set_height (this.height);
this.preview_width = this.width / 3 * 2;
var color = new Clutter.Color ();
color.from_string ("Black");
stage.color = color;
this.black = color;
stage.show ();
stage.signal.destroy.connect (this.onClose);
this.loadDir (Seed.argv[2]);
this.initLoadImages ();
this.setupGroupPosition ();
this.stage.signal["key-press-event"].connect (this.onKeyPress);
this.stage.add_actor (this.preview_group);
this.preview_group.show ();
},
slide: function (direct) {
var offset = this.preview_width / this.preview_num;
var center = parseInt (gallery.preview_num / 2);
var item = null;
var interval = 250;
var target_index = this.icons.indexOf (this.preview_list[center]) + (direct == RIGHT ? 1 : -1);
this.showMainImg (target_index);
for (i in this.preview_list) {
item = this.preview_list[i];
var x = item.get_x ();
opacity = 0;
if (direct == RIGHT)
opacity = this.getOpacity (i-1);
else
opacity = this.getOpacity (Number(i)+1);
opacity = opacity >= 255 ? 255 : opacity;
opacity = opacity < 0 ? 0 : opacity;
item.anim = item.animate
(Clutter.AnimationMode.LINEAR, interval,
{
x: direct==RIGHT?x-offset:x+offset,
opacity: opacity
});
item.anim.timeline.start ();
if (i == 0) {
item.anim.timeline
.signal.completed.connect (this.onCompleted,
{direct: direct});
}
}
},
onCompleted: function (timeline, user_data) {
var direct = user_data["direct"];
print ("direct: " + direct);
var item = null;
if (direct == RIGHT)
item = gallery.preview_list[gallery.preview_list.length-1];
else
item = gallery.preview_list[0];
// add new item
var index = gallery.icons.indexOf (item);
var new_item = gallery.icons[index+(direct==RIGHT?1:-1)];
try {
if (direct == RIGHT)
gallery.setupThumbnail (new_item, gallery.preview_num-1);
else
gallery.setupThumbnail (new_item, 0);
}
catch (e) {}
gallery.preview_group.add_actor (new_item);
new_item.show ();
if (direct == RIGHT)
gallery.preview_list.push (new_item);
else
gallery.preview_list.splice (0, 0, new_item);
// remove old item
var old_item = null;
if (direct == RIGHT)
old_item = gallery.preview_list.shift ();
else
old_item = gallery.preview_list.pop ();
gallery.preview_group.remove_actor (old_item);
},
onKeyPress: function (actor, e, user_data) {
var center = parseInt (gallery.preview_num / 2);
var index = gallery.icons.indexOf
(gallery.preview_list[center])
var next_index = 0;
if (e.get_key_code () == LEFT)
next_index = index -1;
else if (e.get_key_code () == RIGHT)
next_index = index +1;
else
return true;
print ("index: " + next_index);
print ("length: " + gallery.icons.length);
if (e.get_key_code() == LEFT && next_index >= center) {
gallery.slide (LEFT);
}
else if (e.get_key_code() == RIGHT &&
next_index + center < gallery.icons.length) {
gallery.slide (RIGHT);
}
return true;
},
setupGroupPosition: function () {
this.preview_group
.set_position (this.preview_width / 4,
this.height - this.thumbnail_height - this.margin);
},
getOpacity: function (i) {
var center = parseInt (this.preview_num / 2);
var val = Math.abs (center - i);
return 255 - 255 /(center+1)*val;
},
showMainImg: function (i) {
if (this.main_image != null) {
this.stage.remove_actor (this.main_image);
this.main_image.destroy ();
}
var width = {};
var height = {};
var main_image = new Clutter.Texture ({filename: this.files[i],
reactive: true,
opacity: 0});
var target_height = this.height - this.margin * 2 -
this.thumbnail_height;
main_image.get_base_size (width, height);
var scale = target_height / height.value;
main_image.set_scale (scale, scale);
main_image
.set_anchor_point_from_gravity (Clutter.Gravity.NORTH);
main_image.set_position (this.width/2, this.margin);
this.stage.add_actor (main_image);
main_image.show ();
main_image.anim = main_image.animate
(Clutter.AnimationMode.LINEAR, 250,
{ opacity: 255 });
main_image.anim.timeline.start ();
this.main_image = main_image;
},
setupThumbnail: function (icon, i) {
var offset = this.preview_width / this.preview_num;
var width = {};
var height = {};
icon.get_base_size (width, height);
var scale_x = this.thumbnail_width / width.value;
var opacity = this.getOpacity (i);
var scale_y = this.thumbnail_height / height.value;
icon.set_x (i * offset);
icon.set_scale (scale_x, scale_y);
icon.set_opacity (opacity);
},
initLoadImages: function () {
var center = parseInt (this.preview_num / 2);
for (var i = 0; i < this.preview_num; i++) {
if (i >= center) {
this.setupThumbnail (this.icons[i], i);
}
this.preview_group.add_actor (this.icons[i]);
this.icons[i].show ();
if (parseInt (this.preview_num / 2) == i) {
this.showMainImg (i);
}
this.preview_list.push (this.icons[i]);
}
},
loadDir: function (dir_path) {
var dir = Gio.file_new_for_path (dir_path);
var files = dir.enumerate_children ("*", 0, null);
var center = parseInt (this.preview_num / 2);
this.icons = [];
this.files = [];
for (var i = 0; i < center; i++) {
this.icons.push (this.getBlankIcon ());
this.files.push ("");
}
while (true) {
var info = files.next_file (null, null);
if (info == null) break;
if (info.get_name().indexOf (".png") == -1 &&
info.get_name().indexOf (".jpg") == -1) {
continue;
}
var path = dir.get_child (info.get_name()).get_path();
var icon = new Clutter.Texture ({filename: path,
reactive: true});
this.icons.push (icon);
this.files.push (path);
}
for (var i = 0; i < center; i++) {
this.icons.push (this.getBlankIcon ());
this.files.push ("");
}
print (this.files.length);
print (center);
if (this.files.length <= center * 2) {
print ("quit");
Clutter.main_quit ();
}
},
getBlankIcon: function () {
var icon = new Clutter.Rectangle ();
icon.set_color (this.black);
icon.set_size (this.thumbnail_width, this.thumbnail_height);
return icon;
},
onClose: function(o, event) {
Clutter.main_quit ();
}
}
if (Seed.argv.length < 3) {
print ("use js-gallery.js PATH");
}
else {
gallery.init ();
Clutter.main ();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment