From 9d94da83d765b32fcd14f4b37813d833716dda27 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Wed, 20 Oct 2010 12:43:22 -0400 Subject: [PATCH] statusMenu: show a radio button-style dot next to the presence status Adding a "PopupMenuRadioButtonItem" wouldn't work well, because we'll need radio-button indicators on multiple different styles of menu item. Also, the current design draws the indicator in the menu item's padding, so it's sort of special anyway. So just add support at the BaseMenuItem level. Also, redo the menu/menuitem padding so that all the horizontal padding is in the menu item, or else the indicator dot will show up in the wrong spot. https://bugzilla.gnome.org/show_bug.cgi?id=631193 --- data/theme/gnome-shell.css | 4 ++-- js/ui/popupMenu.js | 48 +++++++++++++++++++++++++++++++++++++- js/ui/statusMenu.js | 7 ++++++ 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css index a08c69c12..30e74fe93 100644 --- a/data/theme/gnome-shell.css +++ b/data/theme/gnome-shell.css @@ -121,11 +121,11 @@ StTooltip { * override .popup-menu.font-size, everything else will scale with it. */ .popup-menu-content { - padding: 1em .5em; + padding: 1em 0em; } .popup-menu-item { - padding: .4em 1.25em; + padding: .4em 1.75em; spacing: 1em; } diff --git a/js/ui/popupMenu.js b/js/ui/popupMenu.js index 3d1718b98..7ef3bbb8a 100644 --- a/js/ui/popupMenu.js +++ b/js/ui/popupMenu.js @@ -66,6 +66,7 @@ PopupBaseMenuItem.prototype = { this.actor._delegate = this; this._children = []; + this._dot = null; this._columnWidths = null; this._spacing = 0; this.active = false; @@ -152,6 +153,38 @@ PopupBaseMenuItem.prototype = { } }, + setShowDot: function(show) { + if (show) { + if (this._dot) + return; + + this._dot = new St.DrawingArea({ style_class: 'popup-menu-item-dot' }); + this._dot.connect('repaint', Lang.bind(this, this._onRepaintDot)); + this.actor.add_actor(this._dot); + } else { + if (!this._dot) + return; + + this._dot.destroy(); + this._dot = null; + } + }, + + _onRepaintDot: function(area) { + let cr = area.get_context(); + let [width, height] = area.get_surface_size(); + let color = new Clutter.Color(); + area.get_theme_node().get_foreground_color(color); + + cr.setSourceRGBA ( + color.red / 255, + color.green / 255, + color.blue / 255, + color.alpha / 255); + cr.arc(width / 2, height / 2, width / 3, 0, 2 * Math.PI); + cr.fill(); + }, + getColumnWidths: function() { let widths = []; for (let i = 0, col = 0; i < this._children.length; i++) { @@ -202,7 +235,20 @@ PopupBaseMenuItem.prototype = { }, _allocate: function(actor, box, flags) { - let x = box.x1, height = box.y2 - box.y1; + let height = box.y2 - box.y1; + + if (this._dot) { + let dotBox = new Clutter.ActorBox(); + let dotWidth = Math.round(box.x1 / 2); + + dotBox.x1 = Math.round(box.x1 / 4); + dotBox.x2 = dotBox.x1 + dotWidth; + dotBox.y1 = Math.round(box.y1 + (height - dotWidth) / 2); + dotBox.y2 = dotBox.y1 + dotWidth; + this._dot.allocate(dotBox, flags); + } + + let x = box.x1; for (let i = 0, col = 0; i < this._children.length; i++) { let child = this._children[i]; let childBox = new Clutter.ActorBox(); diff --git a/js/ui/statusMenu.js b/js/ui/statusMenu.js index 89eb4eb08..5d12567e4 100644 --- a/js/ui/statusMenu.js +++ b/js/ui/statusMenu.js @@ -35,6 +35,7 @@ StatusMenuButton.prototype = { this._user = this._gdm.get_user(GLib.get_user_name()); this._presence = new GnomeSession.Presence(); + this._presenceItems = {}; this.actor.connect('destroy', Lang.bind(this, this._onDestroy)); @@ -89,6 +90,9 @@ StatusMenuButton.prototype = { this._iconBox.child = this._invisibleIcon; else this._iconBox.child = this._idleIcon; + + for (let itemStatus in this._presenceItems) + this._presenceItems[itemStatus].setShowDot(itemStatus == status); }, _createSubMenu: function() { @@ -97,14 +101,17 @@ StatusMenuButton.prototype = { item = new PopupMenu.PopupImageMenuItem(_("Available"), 'user-available', true); item.connect('activate', Lang.bind(this, this._setPresenceStatus, GnomeSession.PresenceStatus.AVAILABLE)); this.menu.addMenuItem(item); + this._presenceItems[GnomeSession.PresenceStatus.AVAILABLE] = item; item = new PopupMenu.PopupImageMenuItem(_("Busy"), 'user-busy', true); item.connect('activate', Lang.bind(this, this._setPresenceStatus, GnomeSession.PresenceStatus.BUSY)); this.menu.addMenuItem(item); + this._presenceItems[GnomeSession.PresenceStatus.BUSY] = item; item = new PopupMenu.PopupImageMenuItem(_("Invisible"), 'user-invisible', true); item.connect('activate', Lang.bind(this, this._setPresenceStatus, GnomeSession.PresenceStatus.INVISIBLE)); this.menu.addMenuItem(item); + this._presenceItems[GnomeSession.PresenceStatus.INVISIBLE] = item; item = new PopupMenu.PopupSeparatorMenuItem(); this.menu.addMenuItem(item);