Files
gnome-shell-extensions/extensions/places-menu/extension.js
T
Florian Müllner 48399d46c0 cleanup: Port non-GObject classes to ES6 classes
ES6 finally adds standard class syntax to the language, so we can
replace our custom Lang.Class framework with the new syntax. Any
classes that inherit from GObject will need special treatment,
so limit the port to regular javascript classes for now.

Fixes https://gitlab.gnome.org/GNOME/gnome-shell-extensions/issues/30
2017-12-01 20:50:46 +01:00

146 lines
3.9 KiB
JavaScript

/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const Panel = imports.ui.panel;
const Gettext = imports.gettext.domain('gnome-shell-extensions');
const _ = Gettext.gettext;
const N_ = x => x;
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const Convenience = Me.imports.convenience;
const PlaceDisplay = Me.imports.placeDisplay;
const PLACE_ICON_SIZE = 16;
class PlaceMenuItem extends PopupMenu.PopupBaseMenuItem {
constructor(info) {
super();
this._info = info;
this._icon = new St.Icon({ gicon: info.icon,
icon_size: PLACE_ICON_SIZE });
this.actor.add_child(this._icon);
this._label = new St.Label({ text: info.name, x_expand: true });
this.actor.add_child(this._label);
if (info.isRemovable()) {
this._ejectIcon = new St.Icon({ icon_name: 'media-eject-symbolic',
style_class: 'popup-menu-icon ' });
this._ejectButton = new St.Button({ child: this._ejectIcon });
this._ejectButton.connect('clicked', Lang.bind(info, info.eject));
this.actor.add_child(this._ejectButton);
}
this._changedId = info.connect('changed',
Lang.bind(this, this._propertiesChanged));
}
destroy() {
if (this._changedId) {
this._info.disconnect(this._changedId);
this._changedId = 0;
}
super.destroy();
}
activate(event) {
this._info.launch(event.get_time());
super.activate(event);
}
_propertiesChanged(info) {
this._icon.gicon = info.icon;
this._label.text = info.name;
}
};
const SECTIONS = [
'special',
'devices',
'bookmarks',
'network'
]
class PlacesMenu extends PanelMenu.Button {
constructor() {
super(0.0, _("Places"));
let hbox = new St.BoxLayout({ style_class: 'panel-status-menu-box' });
let label = new St.Label({ text: _("Places"),
y_expand: true,
y_align: Clutter.ActorAlign.CENTER });
hbox.add_child(label);
hbox.add_child(PopupMenu.arrowIcon(St.Side.BOTTOM));
this.actor.add_actor(hbox);
this.placesManager = new PlaceDisplay.PlacesManager();
this._sections = { };
for (let i=0; i < SECTIONS.length; i++) {
let id = SECTIONS[i];
this._sections[id] = new PopupMenu.PopupMenuSection();
this.placesManager.connect(id + '-updated', () => {
this._redisplay(id);
});
this._create(id);
this.menu.addMenuItem(this._sections[id]);
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
}
}
destroy() {
this.placesManager.destroy();
super.destroy();
}
_redisplay(id) {
this._sections[id].removeAll();
this._create(id);
}
_create(id) {
let places = this.placesManager.get(id);
for (let i = 0; i < places.length; i++)
this._sections[id].addMenuItem(new PlaceMenuItem(places[i]));
this._sections[id].actor.visible = places.length > 0;
}
};
function init() {
Convenience.initTranslations();
}
let _indicator;
function enable() {
_indicator = new PlacesMenu;
let pos = 1;
if ('apps-menu' in Main.panel.statusArea)
pos = 2;
Main.panel.addToStatusArea('places-menu', _indicator, pos, 'left');
}
function disable() {
_indicator.destroy();
}