2011-09-28 13:16:26 +00:00
|
|
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
2010-06-22 21:02:26 +00:00
|
|
|
|
2010-10-07 18:15:51 +00:00
|
|
|
const Clutter = imports.gi.Clutter;
|
2012-08-26 13:49:18 +00:00
|
|
|
const Gio = imports.gi.Gio;
|
2011-02-08 19:53:43 +00:00
|
|
|
const Gtk = imports.gi.Gtk;
|
2011-06-09 15:50:24 +00:00
|
|
|
const Lang = imports.lang;
|
|
|
|
const Shell = imports.gi.Shell;
|
2011-08-22 21:19:13 +00:00
|
|
|
const Signals = imports.signals;
|
2010-06-22 21:02:26 +00:00
|
|
|
const St = imports.gi.St;
|
2012-02-27 16:31:10 +00:00
|
|
|
const Atk = imports.gi.Atk;
|
2011-02-08 19:53:43 +00:00
|
|
|
|
2010-06-22 21:02:26 +00:00
|
|
|
const Main = imports.ui.main;
|
2011-06-09 15:50:24 +00:00
|
|
|
const Params = imports.misc.params;
|
|
|
|
const PopupMenu = imports.ui.popupMenu;
|
|
|
|
|
2011-11-20 14:38:48 +00:00
|
|
|
const Button = new Lang.Class({
|
|
|
|
Name: 'PanelMenuButton',
|
2011-06-09 15:50:24 +00:00
|
|
|
|
2012-01-05 18:00:06 +00:00
|
|
|
_init: function(menuAlignment, nameText, dontCreateMenu) {
|
2014-10-28 09:56:46 +00:00
|
|
|
this.actor = new St.Bin({ style_class: 'panel-button',
|
|
|
|
reactive: true,
|
|
|
|
can_focus: true,
|
|
|
|
track_hover: true,
|
|
|
|
accessible_name: nameText ? nameText : "",
|
|
|
|
accessible_role: Atk.Role.MENU });
|
2011-06-09 15:50:24 +00:00
|
|
|
|
2014-07-22 10:28:00 +00:00
|
|
|
this.actor.connect('event', Lang.bind(this, this._onEvent));
|
2013-07-03 13:55:35 +00:00
|
|
|
this.actor.connect('notify::visible', Lang.bind(this, this._onVisibilityChanged));
|
2011-05-15 16:55:23 +00:00
|
|
|
|
|
|
|
if (dontCreateMenu)
|
2012-12-04 19:52:34 +00:00
|
|
|
this.menu = new PopupMenu.PopupDummyMenu(this.actor);
|
2011-05-15 16:55:23 +00:00
|
|
|
else
|
|
|
|
this.setMenu(new PopupMenu.PopupMenu(this.actor, menuAlignment, St.Side.TOP, 0));
|
2012-01-05 18:00:06 +00:00
|
|
|
},
|
|
|
|
|
2012-09-01 21:44:46 +00:00
|
|
|
setSensitive: function(sensitive) {
|
|
|
|
this.actor.reactive = sensitive;
|
|
|
|
this.actor.can_focus = sensitive;
|
|
|
|
this.actor.track_hover = sensitive;
|
|
|
|
},
|
|
|
|
|
2011-05-15 16:55:23 +00:00
|
|
|
setMenu: function(menu) {
|
|
|
|
if (this.menu)
|
|
|
|
this.menu.destroy();
|
|
|
|
|
|
|
|
this.menu = menu;
|
|
|
|
if (this.menu) {
|
|
|
|
this.menu.actor.add_style_class_name('panel-menu');
|
|
|
|
this.menu.connect('open-state-changed', Lang.bind(this, this._onOpenStateChanged));
|
|
|
|
this.menu.actor.connect('key-press-event', Lang.bind(this, this._onMenuKeyPress));
|
|
|
|
|
|
|
|
Main.uiGroup.add_actor(this.menu.actor);
|
|
|
|
this.menu.actor.hide();
|
|
|
|
}
|
2010-06-22 21:02:26 +00:00
|
|
|
},
|
|
|
|
|
2014-07-22 10:28:00 +00:00
|
|
|
_onEvent: function(actor, event) {
|
|
|
|
if (this.menu &&
|
|
|
|
(event.type() == Clutter.EventType.TOUCH_BEGIN ||
|
|
|
|
event.type() == Clutter.EventType.BUTTON_PRESS))
|
|
|
|
this.menu.toggle();
|
2011-05-15 16:55:23 +00:00
|
|
|
|
2013-11-29 18:17:34 +00:00
|
|
|
return Clutter.EVENT_PROPAGATE;
|
2010-06-22 21:02:26 +00:00
|
|
|
},
|
|
|
|
|
2013-07-03 13:55:35 +00:00
|
|
|
_onVisibilityChanged: function() {
|
|
|
|
if (!this.menu)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!this.actor.visible)
|
|
|
|
this.menu.close();
|
|
|
|
},
|
|
|
|
|
2011-02-08 19:53:43 +00:00
|
|
|
_onMenuKeyPress: function(actor, event) {
|
2013-05-04 01:33:05 +00:00
|
|
|
if (global.focus_manager.navigate_from_event(event))
|
2013-11-29 18:17:34 +00:00
|
|
|
return Clutter.EVENT_STOP;
|
2013-05-04 01:33:05 +00:00
|
|
|
|
2011-02-08 19:53:43 +00:00
|
|
|
let symbol = event.get_key_symbol();
|
|
|
|
if (symbol == Clutter.KEY_Left || symbol == Clutter.KEY_Right) {
|
2012-08-15 16:22:01 +00:00
|
|
|
let group = global.focus_manager.get_group(this.actor);
|
2011-02-08 19:53:43 +00:00
|
|
|
if (group) {
|
|
|
|
let direction = (symbol == Clutter.KEY_Left) ? Gtk.DirectionType.LEFT : Gtk.DirectionType.RIGHT;
|
|
|
|
group.navigate_focus(this.actor, direction, false);
|
2013-11-29 18:17:34 +00:00
|
|
|
return Clutter.EVENT_STOP;
|
2011-02-08 19:53:43 +00:00
|
|
|
}
|
|
|
|
}
|
2013-11-29 18:17:34 +00:00
|
|
|
return Clutter.EVENT_PROPAGATE;
|
2011-02-08 19:53:43 +00:00
|
|
|
},
|
|
|
|
|
2010-06-22 21:02:26 +00:00
|
|
|
_onOpenStateChanged: function(menu, open) {
|
2010-11-03 17:30:08 +00:00
|
|
|
if (open)
|
2011-02-08 18:46:05 +00:00
|
|
|
this.actor.add_style_pseudo_class('active');
|
2010-11-03 17:30:08 +00:00
|
|
|
else
|
2011-02-08 18:46:05 +00:00
|
|
|
this.actor.remove_style_pseudo_class('active');
|
2012-02-28 18:09:56 +00:00
|
|
|
|
|
|
|
// Setting the max-height won't do any good if the minimum height of the
|
|
|
|
// menu is higher then the screen; it's useful if part of the menu is
|
|
|
|
// scrollable so the minimum height is smaller than the natural height
|
2013-01-28 05:09:12 +00:00
|
|
|
let workArea = Main.layoutManager.getWorkAreaForMonitor(Main.layoutManager.primaryIndex);
|
|
|
|
this.menu.actor.style = ('max-height: ' + Math.round(workArea.height) + 'px;');
|
2011-08-22 21:19:13 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
destroy: function() {
|
2012-10-26 10:34:45 +00:00
|
|
|
if (this.menu)
|
|
|
|
this.menu.destroy();
|
2011-08-22 21:19:13 +00:00
|
|
|
this.actor.destroy();
|
|
|
|
|
|
|
|
this.emit('destroy');
|
2010-06-22 21:02:26 +00:00
|
|
|
}
|
2011-11-20 14:38:48 +00:00
|
|
|
});
|
2011-08-22 21:19:13 +00:00
|
|
|
Signals.addSignalMethods(Button.prototype);
|
2010-06-22 21:06:17 +00:00
|
|
|
|
2013-06-06 21:27:25 +00:00
|
|
|
/* SystemIndicator:
|
2010-06-22 21:06:17 +00:00
|
|
|
*
|
2013-06-06 21:27:25 +00:00
|
|
|
* This class manages one system indicator, which are the icons
|
|
|
|
* that you see at the top right. A system indicator is composed
|
|
|
|
* of an icon and a menu section, which will be composed into the
|
|
|
|
* aggregate menu.
|
2010-06-22 21:06:17 +00:00
|
|
|
*/
|
2013-06-06 21:27:25 +00:00
|
|
|
const SystemIndicator = new Lang.Class({
|
|
|
|
Name: 'SystemIndicator',
|
2010-06-22 21:06:17 +00:00
|
|
|
|
2013-06-06 21:27:25 +00:00
|
|
|
_init: function() {
|
2013-06-06 21:27:32 +00:00
|
|
|
this.indicators = new St.BoxLayout({ style_class: 'panel-status-indicators-box',
|
|
|
|
reactive: true });
|
2013-07-15 23:46:25 +00:00
|
|
|
this.indicators.hide();
|
2013-06-06 21:27:32 +00:00
|
|
|
this.menu = new PopupMenu.PopupMenuSection();
|
2012-12-21 01:25:54 +00:00
|
|
|
},
|
|
|
|
|
2013-07-15 23:46:25 +00:00
|
|
|
_syncIndicatorsVisible: function() {
|
|
|
|
this.indicators.visible = this.indicators.get_children().some(function(actor) {
|
|
|
|
return actor.visible;
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2013-07-19 10:05:47 +00:00
|
|
|
_addIndicator: function() {
|
|
|
|
let icon = new St.Icon({ style_class: 'system-status-icon' });
|
2013-06-06 21:27:25 +00:00
|
|
|
this.indicators.add_actor(icon);
|
2013-07-15 23:46:25 +00:00
|
|
|
icon.connect('notify::visible', Lang.bind(this, this._syncIndicatorsVisible));
|
|
|
|
this._syncIndicatorsVisible();
|
2012-08-26 13:49:18 +00:00
|
|
|
return icon;
|
2010-06-22 21:06:17 +00:00
|
|
|
}
|
2011-11-20 14:38:48 +00:00
|
|
|
});
|
2013-06-06 21:27:32 +00:00
|
|
|
Signals.addSignalMethods(SystemIndicator.prototype);
|