[gnome-shell] statusMenu: show a radio button-style dot next to the presence status



commit 9d94da83d765b32fcd14f4b37813d833716dda27
Author: Dan Winship <danw gnome org>
Date:   Wed Oct 20 12:43:22 2010 -0400

    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 a08c69c..30e74fe 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 3d1718b..7ef3bbb 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 89eb4eb..5d12567 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);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]