From 824220356f273a5cc5b7f82968203a15cde517e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Thu, 15 Sep 2011 16:51:19 +0200 Subject: [PATCH] popup-menu: Add 'sensitive' flag to item parameters A menu action may not make sense at any time, so add API to mark an item insensitive to indicate that its action is currently unavailable, but may become activatable at a later point. https://bugzilla.gnome.org/show_bug.cgi?id=659270 --- data/theme/gnome-shell.css | 4 ++++ js/ui/popupMenu.js | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css index f61fe6eb1..9052a13c7 100644 --- a/data/theme/gnome-shell.css +++ b/data/theme/gnome-shell.css @@ -164,6 +164,10 @@ StTooltip StLabel { background-color: #4c4c4c; } +.popup-menu-item:insensitive { + color: #9f9f9f; +} + .popup-image-menu-item { } diff --git a/js/ui/popupMenu.js b/js/ui/popupMenu.js index ef8a5494e..490228a1f 100644 --- a/js/ui/popupMenu.js +++ b/js/ui/popupMenu.js @@ -35,6 +35,7 @@ PopupBaseMenuItem.prototype = { params = Params.parse (params, { reactive: true, activate: true, hover: true, + sensitive: true, style_class: null }); this.actor = new Shell.GenericContainer({ style_class: 'popup-menu-item', @@ -52,11 +53,15 @@ PopupBaseMenuItem.prototype = { this._columnWidths = null; this._spacing = 0; this.active = false; + this._activatable = params.reactive && params.activate; + this.sensitive = this._activatable && params.sensitive; + + this.setSensitive(this.sensitive); if (params.style_class) this.actor.add_style_class_name(params.style_class); - if (params.reactive && params.activate) { + if (this._activatable) { this.actor.connect('button-release-event', Lang.bind(this, this._onButtonReleaseEvent)); this.actor.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent)); } @@ -117,6 +122,23 @@ PopupBaseMenuItem.prototype = { } }, + setSensitive: function(sensitive) { + if (!this._activatable) + return; + if (this.sensitive == sensitive) + return; + + this.sensitive = sensitive; + this.actor.reactive = sensitive; + this.actor.can_focus = sensitive; + + if (sensitive) + this.actor.remove_style_pseudo_class('insensitive'); + else + this.actor.add_style_pseudo_class('insensitive'); + this.emit('sensitive-changed', sensitive); + }, + destroy: function() { this.actor.destroy(); this.emit('destroy'); @@ -899,6 +921,17 @@ PopupMenuBase.prototype = { this.emit('active-changed', null); } })); + menuItem._sensitiveChangeId = menuItem.connect('sensitive-changed', Lang.bind(this, function(menuItem, sensitive) { + if (!sensitive && this._activeMenuItem == menuItem) { + if (!this.actor.navigate_focus(menuItem.actor, + Gtk.DirectionType.TAB_FORWARD, + true)) + this.actor.grab_key_focus(); + } else if (sensitive && this._activeMenuItem == null) { + if (global.stage.get_key_focus() == this.actor) + menuItem.actor.grab_key_focus(); + } + })); menuItem._activateId = menuItem.connect('activate', Lang.bind(this, function (menuItem, event) { this.emit('activate', menuItem); this.close(true); @@ -906,6 +939,7 @@ PopupMenuBase.prototype = { menuItem.connect('destroy', Lang.bind(this, function(emitter) { menuItem.disconnect(menuItem._activateId); menuItem.disconnect(menuItem._activeChangeId); + menuItem.disconnect(menuItem._sensitiveChangeId); if (menuItem.menu) { menuItem.menu.disconnect(menuItem._subMenuActivateId); menuItem.menu.disconnect(menuItem._subMenuActiveChangeId);