RandomWallpaperGnome3/randomwallpaper@iflow.space/elements.js

357 lines
9 KiB
JavaScript
Raw Permalink Normal View History

const Lang = imports.lang;
const PopupMenu = imports.ui.popupMenu;
const St = imports.gi.St;
2014-10-22 13:17:46 +00:00
const Tweener = imports.ui.tweener;
const Util = imports.misc.util;
2017-07-23 01:14:23 +00:00
const GdkPixbuf = imports.gi.GdkPixbuf;
const Clutter = imports.gi.Clutter;
const Cogl = imports.gi.Cogl;
const Gtk = imports.gi.Gtk;
2017-07-23 01:14:23 +00:00
2017-02-24 22:31:35 +00:00
const Self = imports.misc.extensionUtils.getCurrentExtension();
2017-07-23 01:14:23 +00:00
const LoggerModule = Self.imports.logger;
2017-02-24 22:31:35 +00:00
const Timer = Self.imports.timer;
var HistoryElement = class extends PopupMenu.PopupSubMenuMenuItem {
constructor(historyEntry, index) {
super("", false);
2017-07-23 01:14:23 +00:00
this.logger = new LoggerModule.Logger('RWG3', 'HistoryElement');
this.historyEntry = null;
this.setAsWallpaperItem = null;
this.previewItem = null;
this._previewActor = null;
let timestamp = historyEntry.timestamp;
let date = new Date(timestamp);
let timeString = date.toLocaleTimeString();
let dateString = date.toLocaleDateString();
2017-07-20 19:49:54 +00:00
let prefixText;
if (index === 0) {
2017-07-26 01:42:06 +00:00
prefixText = "Current Background";
2017-07-20 19:49:54 +00:00
} else {
2017-07-26 01:42:06 +00:00
prefixText = String(index) + '.';
2017-07-20 19:49:54 +00:00
}
this.prefixLabel = new St.Label({
2017-07-26 01:42:06 +00:00
text: prefixText,
2014-10-22 13:17:46 +00:00
style_class: 'rwg-history-index'
});
2016-04-08 10:33:12 +00:00
2017-07-20 19:49:54 +00:00
this.actor.insert_child_above(this.prefixLabel, this.label);
this.label.destroy();
2014-10-22 13:17:46 +00:00
this._container = new St.BoxLayout({
vertical: true
});
this.dateLabel = new St.Label({
2014-10-22 13:17:46 +00:00
text: dateString,
style_class: 'rwg-history-date'
});
this._container.add_child(this.dateLabel);
this.timeLabel = new St.Label({
2014-10-22 13:17:46 +00:00
text: timeString,
style_class: 'rwg-history-time'
});
this._container.add_child(this.timeLabel);
this.historyEntry = historyEntry;
this.actor.historyId = historyEntry.id; // extend the actor with the historyId
2017-07-20 19:49:54 +00:00
if (index !== 0) {
this.actor.insert_child_above(this._container, this.prefixLabel);
}
2018-07-27 15:36:47 +00:00
this.menu.addMenuItem(new PopupMenu.PopupBaseMenuItem({can_focus: false, reactive: false})); // theme independent spacing
this.menu.actor.add_style_class_name("rwg-history-element-content");
2017-07-23 01:14:23 +00:00
if (this.historyEntry.source && this.historyEntry.source !== null) {
if (this.historyEntry.source.author !== null
&& this.historyEntry.source.authorUrl !== null) {
this.authorItem = new PopupMenu.PopupMenuItem('Image By: ' + this.historyEntry.source.author);
this.authorItem.connect('activate', () => {
Util.spawn(['xdg-open', this.historyEntry.source.authorUrl]);
});
this.menu.addMenuItem(this.authorItem);
}
if (this.historyEntry.source.source !== null
&& this.historyEntry.source.sourceUrl !== null) {
this.sourceItem = new PopupMenu.PopupMenuItem('Image From: ' + this.historyEntry.source.source);
this.sourceItem.connect('activate', () => {
Util.spawn(['xdg-open', this.historyEntry.source.sourceUrl]);
});
this.menu.addMenuItem(this.sourceItem);
}
this.imageUrlItem = new PopupMenu.PopupMenuItem('Open Image In Browser');
this.imageUrlItem.connect('activate', () => {
2018-04-12 16:06:19 +00:00
Util.spawn(['xdg-open', this.historyEntry.source.imageLinkUrl]);
});
this.menu.addMenuItem(this.imageUrlItem);
} else {
this.menu.addMenuItem(new PopupMenu.PopupMenuItem('Unknown source.'));
}
2017-07-23 01:14:23 +00:00
this.setAsWallpaperItem = new PopupMenu.PopupMenuItem('Set As Wallpaper');
this.setAsWallpaperItem.connect('activate', () => {
this.emit('activate');
});
this.previewItem = new PopupMenu.PopupBaseMenuItem({can_focus: false, reactive: false});
this.menu.addMenuItem(new PopupMenu.PopupBaseMenuItem({can_focus: false, reactive: false})); // theme independent spacing
this.menu.addMenuItem(this.setAsWallpaperItem);
this.menu.addMenuItem(this.previewItem);
this.menu.addMenuItem(new PopupMenu.PopupBaseMenuItem({can_focus: false, reactive: false})); // theme independent spacing
/*
Load the image on first opening of the sub menu instead of during creation of the history list.
*/
this.menu.connect('open-state-changed', (self, open) => {
if (open) {
if (this._previewActor !== null) {
return;
}
try {
let width = 250; // TODO: get width or add option in settings.
let pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(this.historyEntry.path, width, -1, true);
let height = pixbuf.get_height();
let image = new Clutter.Image();
let pixelFormat = pixbuf.get_has_alpha() ? Cogl.PixelFormat.RGBA_8888 : Cogl.PixelFormat.RGB_888;
image.set_data(
pixbuf.get_pixels(),
pixelFormat,
width,
height,
pixbuf.get_rowstride()
);
this._previewActor = new Clutter.Actor({height: height, width: width});
this._previewActor.set_content(image);
this.previewItem.actor.add_actor(this._previewActor);
} catch (exeption) {
this.logger.error(exeption);
}
}
})
}
setIndex(index) {
this.prefixLabel.set_text(String(index));
}
};
var CurrentImageElement = class extends HistoryElement {
2017-07-20 19:49:54 +00:00
constructor(historyElement) {
super(historyElement, 0);
if (this.setAsWallpaperItem !== null) {
this.setAsWallpaperItem.destroy();
}
2017-07-20 19:49:54 +00:00
}
};
2017-07-20 19:49:54 +00:00
2017-02-24 22:31:35 +00:00
/**
* Element for the New Wallpaper button and the remaining time for the auto fetch
* feature.
* The remaining time will only be displayed if the af-feature is activated.
*
* @type {Lang.Class}
*/
var NewWallpaperElement = class extends PopupMenu.PopupBaseMenuItem {
2017-02-24 22:31:35 +00:00
constructor(params) {
super(params);
2017-02-24 22:31:35 +00:00
this._timer = new Timer.AFTimer();
this._container = new St.BoxLayout({
vertical: true
});
this._newWPLabel = new St.Label({
text: 'New Wallpaper',
style_class: 'rwg-new-lable'
});
this._container.add_child(this._newWPLabel);
this._remainingLabel = new St.Label({
text: '1 minute remaining'
});
this._container.add_child(this._remainingLabel);
this.actor.add_child(this._container);
}
2017-02-24 22:31:35 +00:00
show() {
2017-02-24 22:31:35 +00:00
if (this._timer.isActive()) {
let remainingMinutes = this._timer.remainingMinutes();
let minutes = remainingMinutes % 60;
let hours = Math.floor(remainingMinutes / 60);
let hoursText = hours.toString();
hoursText += (hours == 1) ? ' hour' : ' hours';
let minText = minutes.toString();
minText += (minutes == 1) ? ' minute' : ' minutes';
if (hours >= 1) {
this._remainingLabel.text = '... ' + hoursText + ' and ' + minText + ' remaining.'
} else {
this._remainingLabel.text = '... ' + minText + ' remaining.'
}
this._remainingLabel.show();
} else {
this._remainingLabel.hide();
}
}
};
var StatusElement = class {
constructor() {
this.icon = new St.Icon({
2014-10-22 13:17:46 +00:00
icon_name: 'preferences-desktop-wallpaper-symbolic',
2016-04-08 10:33:12 +00:00
style_class: 'system-status-icon'
2014-10-22 13:17:46 +00:00
});
let _this = this;
this.loadingTweenIn = {
opacity: 20,
time: 2,
transition: 'easeInOutSine',
onComplete: function () {
2018-08-03 15:28:31 +00:00
try {
Tweener.addTween(_this.icon, _this.loadingTweenOut);
2018-08-03 15:28:31 +00:00
} catch (e) {
// swollow (not really important)
}
2014-10-22 13:17:46 +00:00
}
};
2014-10-22 13:17:46 +00:00
this.loadingTweenOut = {
opacity: 255,
time: 1,
transition: 'easeInOutSine',
onComplete: function () {
2014-10-22 13:17:46 +00:00
if (_this.isLoading) {
2018-08-03 15:28:31 +00:00
try {
Tweener.addTween(_this.icon, _this.loadingTweenIn);
2018-08-03 15:28:31 +00:00
} catch (e) {
// swollow (not really important)
}
2014-10-22 13:17:46 +00:00
} else {
return false;
2014-10-22 13:17:46 +00:00
}
return true;
}
}
}
2014-10-22 13:17:46 +00:00
startLoading() {
2014-10-22 13:17:46 +00:00
this.isLoading = true;
Tweener.addTween(this.icon, this.loadingTweenOut);
}
2014-10-22 13:17:46 +00:00
stopLoading() {
2014-10-22 13:17:46 +00:00
this.isLoading = false;
Tweener.removeTweens(this.icon);
this.icon.opacity = 255;
2014-10-22 13:17:46 +00:00
}
};
var HistorySection = class extends PopupMenu.PopupMenuSection {
constructor() {
super();
2018-08-03 15:28:31 +00:00
/**
* Cache HistoryElements for performance of long histories.
*/
this._historySectionCache = {};
2018-08-03 15:28:31 +00:00
this._historyCache = [];
this.actor = new St.ScrollView({
hscrollbar_policy: Gtk.PolicyType.NEVER,
vscrollbar_policy: Gtk.PolicyType.AUTOMATIC
});
this.actor.add_actor(this.box);
}
updateList(history, onEnter, onLeave, onSelect) {
2018-08-03 15:28:31 +00:00
if (this._historyCache.length <= 1) {
this.removeAll(); // remove empty history element
}
let existingHistoryElements = [];
for (let i = 1; i < history.length; i++) {
let historyID = history[i].id;
let tmp;
if (!(historyID in this._historySectionCache)) {
tmp = new HistoryElement(history[i], i);
tmp.actor.connect('key-focus-in', onEnter);
tmp.actor.connect('key-focus-out', onLeave);
tmp.actor.connect('enter-event', onEnter);
tmp.connect('activate', onSelect);
this._historySectionCache[historyID] = tmp;
this.addMenuItem(tmp, i - 1);
2018-08-03 15:28:31 +00:00
} else {
tmp = this._historySectionCache[historyID];
tmp.setIndex(i);
}
existingHistoryElements.push(historyID);
}
this._cleanupHistoryCache(existingHistoryElements);
this._historyCache = history;
}
2018-08-03 15:28:31 +00:00
_cleanupHistoryCache(existingIDs) {
2018-08-03 15:28:31 +00:00
let destroyIDs = Object.keys(this._historySectionCache).filter((i) => existingIDs.indexOf(i) === -1);
destroyIDs.map(id => {
this._historySectionCache[id].destroy();
delete this._historySectionCache[id];
});
}
2018-08-03 15:28:31 +00:00
clear() {
2018-08-03 15:28:31 +00:00
this._cleanupHistoryCache([]);
this.removeAll();
this.addMenuItem(
new PopupMenu.PopupMenuItem('No recent wallpaper ...', {
activate: false,
hover: false,
style_class: 'rwg-recent-lable',
can_focus: false
})
);
this._historyCache = [];
}
};