[gnome-shell/user-status-update: 3/12] status-menu: Implement new mockups
- From: Florian MÃllner <fmuellner src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/user-status-update: 3/12] status-menu: Implement new mockups
- Date: Thu, 4 Aug 2011 22:27:25 +0000 (UTC)
commit b79c5921ba7b9a26375dcc2c96d48963714e6a82
Author: Florian MÃllner <fmuellner gnome org>
Date: Thu Jul 28 16:59:03 2011 +0200
status-menu: Implement new mockups
data/theme/gnome-shell.css | 15 ++
js/ui/statusMenu.js | 344 +++++++++++++++++++++++++++++++++++++-------
2 files changed, 308 insertions(+), 51 deletions(-)
---
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index ef8cb0d..65c2b0d 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -354,6 +354,21 @@ StTooltip StLabel {
spacing: 4px;
}
+.status-chooser .popup-menu-item {
+ padding: .4em 0.75em;
+}
+
+.status-chooser-user-icon {
+ border: 2px solid #8b8b8b;
+ border-radius: 5px;
+ width: 64px;
+ height: 64px;
+}
+
+.status-chooser-user-name {
+ font-weight: bold;
+}
+
#legacyTray {
spacing: 14px;
padding-left: 14px;
diff --git a/js/ui/statusMenu.js b/js/ui/statusMenu.js
index c506be0..a250f33 100644
--- a/js/ui/statusMenu.js
+++ b/js/ui/statusMenu.js
@@ -22,11 +22,263 @@ const DISABLE_USER_SWITCH_KEY = 'disable-user-switching';
const DISABLE_LOCK_SCREEN_KEY = 'disable-lock-screen';
const DISABLE_LOG_OUT_KEY = 'disable-log-out';
+const IMStatus = {
+ AVAILABLE: 0,
+ BUSY: 1,
+ HIDDEN: 2,
+ AWAY: 3,
+ IDLE: 4,
+ OFFLINE: 5,
+ LAST: 6
+};
+
// Adapted from gdm/gui/user-switch-applet/applet.c
//
// Copyright (C) 2004-2005 James M. Cape <jcape ignore-your tv>.
// Copyright (C) 2008,2009 Red Hat, Inc.
+
+function IMStatusItem(label, iconName) {
+ this._init(label, iconName);
+}
+
+IMStatusItem.prototype = {
+ __proto__: PopupMenu.PopupBaseMenuItem.prototype,
+
+ _init: function(label, iconName) {
+ PopupMenu.PopupBaseMenuItem.prototype._init.call(this);
+
+ this._icon = new St.Icon({ style_class: 'popup-menu-icon' });
+ this.addActor(this._icon);
+
+ if (iconName)
+ this._icon.icon_name = iconName;
+
+ this.label = new St.Label({ text: label });
+ this.addActor(this.label);
+ }
+};
+
+function IMStatusChooserItem() {
+ this._init();
+}
+
+IMStatusChooserItem.prototype = {
+ __proto__: PopupMenu.PopupBaseMenuItem.prototype,
+
+ _init: function() {
+ PopupMenu.PopupBaseMenuItem.prototype._init.call (this,
+ { reactive: false,
+ style_class: 'status-chooser' });
+
+ this._iconBin = new St.Bin({ style_class: 'status-chooser-user-icon' });
+ this.addActor(this._iconBin);
+
+ this._section = new PopupMenu.PopupMenuSection();
+ this.addActor(this._section.actor);
+
+ this._name = new PopupMenu.PopupMenuItem('',
+ { reactive: false,
+ style_class: 'status-chooser-user-name' });
+ this._section.addMenuItem(this._name);
+
+ this._combo = new PopupMenu.PopupComboBoxMenuItem();
+ this._section.addMenuItem(this._combo);
+
+ let item;
+
+ item = new IMStatusItem(_("Available"), 'user-available');
+ this._combo.addMenuItem(item, IMStatus.AVAILABLE);
+
+ item = new IMStatusItem(_("Busy"), 'user-busy');
+ this._combo.addMenuItem(item, IMStatus.BUSY);
+
+ item = new IMStatusItem(_("Hidden"), 'user-invisible');
+ this._combo.addMenuItem(item, IMStatus.HIDDEN);
+
+ item = new IMStatusItem(_("Away"), 'user-away');
+ this._combo.addMenuItem(item, IMStatus.AWAY);
+
+ item = new IMStatusItem(_("Idle"), 'user-idle');
+ this._combo.addMenuItem(item, IMStatus.IDLE);
+
+ item = new IMStatusItem(_("Unavailable"), 'user-offline');
+ this._combo.addMenuItem(item, IMStatus.OFFLINE);
+
+ this._combo.connect('active-item-changed',
+ Lang.bind(this, this._changeIMStatus));
+
+ this._presence = new GnomeSession.Presence();
+ this._presence.getStatus(Lang.bind(this, this._sessionStatusChanged));
+ this._presence.connect('StatusChanged',
+ Lang.bind(this, this._sessionStatusChanged));
+
+ this._accountMgr = Tp.AccountManager.dup()
+ let [presence, s, msg] = this._accountMgr.get_most_available_presence();
+
+ this._previousPresence = presence;
+ this._accountMgr.connect('most-available-presence-changed',
+ Lang.bind(this, this._IMStatusChanged));
+
+ this._gdm = Gdm.UserManager.ref_default();
+ this._gdm.queue_load();
+
+ this._user = this._gdm.get_user(GLib.get_user_name());
+
+ this._userLoadedId = this._user.connect('notify::is-loaded',
+ Lang.bind(this,
+ this._updateUser));
+ this._userChangedId = this._user.connect('changed',
+ Lang.bind(this,
+ this._updateUser));
+ },
+
+ // Override getColumnWidths()/setColumnWidths() to make the item
+ // independent from the overall column layout of the menu
+ getColumnWidths: function() {
+ return [];
+ },
+
+ setColumnWidths: function(widths) {
+ this._columnWidths = PopupMenu.PopupBaseMenuItem.prototype.getColumnWidths.call(this);
+ let sectionWidths = this._section.getColumnWidths();
+ this._section.setColumnWidths(sectionWidths);
+ },
+
+ _updateUser: function() {
+ let iconFile = null;
+ if (this._user.is_loaded) {
+ this._name.label.set_text(this._user.get_real_name());
+ iconFile = this._user.get_icon_file();
+ if (!GLib.file_test(iconFile, GLib.FileTest.EXISTS))
+ iconFile = null;
+ } else {
+ this._name.label.set_text("");
+ }
+
+ if (iconFile)
+ this._setIconFromFile(iconFile);
+ else
+ this._setIconFromName('avatar-default');
+ },
+
+ _setIconFromFile: function(iconFile) {
+ this._iconBin.set_style('background-image: url("' + iconFile + '");');
+ },
+
+ _setIconFromName: function(iconName) {
+ this._iconBin.set_style(null);
+
+ if (iconName != null) {
+ let textureCache = St.TextureCache.get_default();
+ let icon = textureCache.load_icon_name(this._iconBin.get_theme_node(),
+ iconName,
+ St.IconType.SYMBOLIC,
+ _DIALOG_ICON_SIZE);
+
+ this._iconBin.child = icon;
+ this._iconBin.show();
+ } else {
+ this._iconBin.child = null;
+ this._iconBin.hide();
+ }
+ },
+
+ _statusForPresence: function(presence) {
+ switch(presence) {
+ case Tp.ConnectionPresenceType.AVAILABLE:
+ return _("Available");
+ case Tp.ConnectionPresenceType.BUSY:
+ return _("Busy");
+ case Tp.ConnectionPresenceType.OFFLINE:
+ return _("Unavailable");
+ case Tp.ConnectionPresenceType.HIDDEN:
+ return _("Hidden");
+ case Tp.ConnectionPresenceType.AWAY:
+ return _("Away");
+ case Tp.ConnectionPresenceType.EXTENDED_AWAY:
+ return _("Idle");
+ default:
+ return _("Unknown");
+ }
+ },
+
+ _IMStatusChanged: function(accountMgr, presence, status, message) {
+ if (presence == Tp.ConnectionPresenceType.AVAILABLE)
+ this._presence.setStatus(GnomeSession.PresenceStatus.AVAILABLE);
+
+ if (!this._expectedPresence || presence != this._expectedPresence)
+ this._previousPresence = presence;
+ else
+ this._expectedPresence = undefined;
+
+ let activatedItem;
+
+ if (presence == Tp.ConnectionPresenceType.AVAILABLE)
+ activatedItem = IMStatus.AVAILABLE;
+ else if (presence == Tp.ConnectionPresenceType.BUSY)
+ activatedItem = IMStatus.BUSY;
+ else if (presence == Tp.ConnectionPresenceType.HIDDEN)
+ activatedItem = IMStatus.HIDDEN;
+ else if (presence == Tp.ConnectionPresenceType.AWAY)
+ activatedItem = IMStatus.AWAY;
+ else if (presence == Tp.ConnectionPresenceType.EXTENDED_AWAY)
+ activatedItem = IMStatus.IDLE;
+ else if (presence == Tp.ConnectionPresenceType.OFFLINE)
+ activatedItem = IMStatus.OFFLINE;
+
+ this._combo.setActiveItem(activatedItem);
+ for (let i = 0; i < IMStatus.LAST; i++) {
+ if (i == IMStatus.AVAILABLE || i == IMStatus.OFFLINE)
+ continue; // always visible
+
+ this._combo.setItemVisible(i, i == activatedItem);
+ }
+ },
+
+ _changeIMStatus: function(menuItem, id) {
+ let [presence, s, msg] = this._accountMgr.get_most_available_presence();
+ let newPresence, status;
+
+ if (id == IMStatus.AVAILABLE) {
+ newPresence = Tp.ConnectionPresenceType.AVAILABLE;
+ } else if (id == IMStatus.OFFLINE) {
+ newPresence = Tp.ConnectionPresenceType.OFFLINE;
+ } else
+ return;
+
+ status = this._statusForPresence(newPresence);
+ msg = msg ? msg : "";
+ this._accountMgr.set_all_requested_presences(newPresence, status, msg);
+ },
+
+ _sessionStatusChanged: function(sessionPresence, sessionStatus) {
+ let [presence, s, msg] = this._accountMgr.get_most_available_presence();
+ let newPresence, status;
+
+ if (sessionStatus == GnomeSession.PresenceStatus.AVAILABLE) {
+ newPresence = this._previousPresence;
+ } else if (sessionStatus == GnomeSession.PresenceStatus.BUSY) {
+ // Only change presence if the current one is "more present" than
+ // busy
+ if (presence == Tp.ConnectionPresenceType.AVAILABLE) {
+ newPresence = Tp.ConnectionPresenceType.BUSY;
+ } else {
+ return;
+ }
+ } else {
+ return;
+ }
+
+ status = this._statusForPresence(newPresence);
+ msg = msg ? msg : "";
+
+ this._expectedPresence = newPresence;
+ this._accountMgr.set_all_requested_presences(newPresence, status, msg);
+ }
+};
+
+
function StatusMenuButton() {
this._init();
}
@@ -46,7 +298,6 @@ StatusMenuButton.prototype = {
this._user = this._gdm.get_user(GLib.get_user_name());
this._presence = new GnomeSession.Presence();
- this._presenceItems = {};
this._session = new GnomeSession.SessionManager();
this._haveShutdown = true;
@@ -60,13 +311,26 @@ StatusMenuButton.prototype = {
box.add(this._iconBox, { y_align: St.Align.MIDDLE, y_fill: false });
let textureCache = St.TextureCache.get_default();
- this._availableIcon = new St.Icon({ icon_name: 'user-available', style_class: 'popup-menu-icon' });
- this._busyIcon = new St.Icon({ icon_name: 'user-busy', style_class: 'popup-menu-icon' });
- this._invisibleIcon = new St.Icon({ icon_name: 'user-invisible', style_class: 'popup-menu-icon' });
- this._idleIcon = new St.Icon({ icon_name: 'user-idle', style_class: 'popup-menu-icon' });
-
- this._presence.connect('StatusChanged', Lang.bind(this, this._updatePresenceIcon));
- this._presence.getStatus(Lang.bind(this, this._updatePresenceIcon));
+ this._offlineIcon = new St.Icon({ icon_name: 'user-offline',
+ style_class: 'popup-menu-icon' });
+ this._availableIcon = new St.Icon({ icon_name: 'user-available',
+ style_class: 'popup-menu-icon' });
+ this._busyIcon = new St.Icon({ icon_name: 'user-busy',
+ style_class: 'popup-menu-icon' });
+ this._invisibleIcon = new St.Icon({ icon_name: 'user-invisible',
+ style_class: 'popup-menu-icon' });
+ this._awayIcon = new St.Icon({ icon_name: 'user-away',
+ style_class: 'popup-menu-icon' });
+ this._idleIcon = new St.Icon({ icon_name: 'user-idle',
+ style_class: 'popup-menu-icon' });
+
+ this._presence.connect('StatusChanged',
+ Lang.bind(this, this._updateSwitch));
+ this._presence.getStatus(Lang.bind(this, this._updateSwitch));
+
+ this._account_mgr.connect('most-available-presence-changed',
+ Lang.bind(this, this._updatePresenceIcon));
+ this._updatePresenceIcon();
this._name = new St.Label();
box.add(this._name, { y_align: St.Align.MIDDLE, y_fill: false });
@@ -197,32 +461,36 @@ StatusMenuButton.prototype = {
}
},
- _updatePresenceIcon: function(presence, status) {
- if (status == GnomeSession.PresenceStatus.AVAILABLE)
+ _updateSwitch: function(presence, status) {
+ let active = status == GnomeSession.PresenceStatus.BUSY;
+ this._dontDisturbSwitch.setToggleState(active);
+ },
+
+ _updatePresenceIcon: function(accountMgr, presence, status, message) {
+ if (presence == Tp.ConnectionPresenceType.OFFLINE)
+ this._iconBox.child = this._offlineIcon;
+ else if (presence == Tp.ConnectionPresenceType.AVAILABLE)
this._iconBox.child = this._availableIcon;
- else if (status == GnomeSession.PresenceStatus.BUSY)
+ else if (presence == Tp.ConnectionPresenceType.BUSY)
this._iconBox.child = this._busyIcon;
- else if (status == GnomeSession.PresenceStatus.INVISIBLE)
+ else if (presence == Tp.ConnectionPresenceType.HIDDEN)
this._iconBox.child = this._invisibleIcon;
- else
+ else if (presence == Tp.ConnectionPresenceType.AWAY)
+ this._iconBox.child = this._awayIcon;
+ else if (presence == Tp.ConnectionPresenceType.EXTENDED_AWAY)
this._iconBox.child = this._idleIcon;
-
- for (let itemStatus in this._presenceItems)
- this._presenceItems[itemStatus].setShowDot(itemStatus == status);
},
_createSubMenu: function() {
let item;
- item = new PopupMenu.PopupImageMenuItem(_("Available"), 'user-available');
- item.connect('activate', Lang.bind(this, this._setPresenceStatus, GnomeSession.PresenceStatus.AVAILABLE));
+ item = new IMStatusChooserItem();
this.menu.addMenuItem(item);
- this._presenceItems[GnomeSession.PresenceStatus.AVAILABLE] = item;
- item = new PopupMenu.PopupImageMenuItem(_("Busy"), 'user-busy');
- item.connect('activate', Lang.bind(this, this._setPresenceStatus, GnomeSession.PresenceStatus.BUSY));
+ item = new PopupMenu.PopupSwitchMenuItem(_("Do Not Disturb"));
+ item.connect('activate', Lang.bind(this, this._updatePresenceStatus));
this.menu.addMenuItem(item);
- this._presenceItems[GnomeSession.PresenceStatus.BUSY] = item;
+ this._dontDisturbSwitch = item;
item = new PopupMenu.PopupSeparatorMenuItem();
this.menu.addMenuItem(item);
@@ -266,10 +534,10 @@ StatusMenuButton.prototype = {
this._updateSuspendOrPowerOff();
},
- _setPresenceStatus: function(item, event, status) {
+ _updatePresenceStatus: function(item, event) {
+ let status = item.state ? GnomeSession.PresenceStatus.BUSY
+ : GnomeSession.PresenceStatus.AVAILABLE;
this._presence.setStatus(status);
-
- this._setIMStatus(status);
},
_onMyAccountActivate: function() {
@@ -315,31 +583,5 @@ StatusMenuButton.prototype = {
} else {
this._session.ShutdownRemote();
}
- },
-
- _setIMStatus: function(session_status) {
- let [presence_type, presence_status, msg] = this._account_mgr.get_most_available_presence();
- let type, status;
-
- // We change the IM presence only if there are connected accounts
- if (presence_type == Tp.ConnectionPresenceType.UNSET ||
- presence_type == Tp.ConnectionPresenceType.OFFLINE ||
- presence_type == Tp.ConnectionPresenceType.UNKNOWN ||
- presence_type == Tp.ConnectionPresenceType.ERROR)
- return;
-
- if (session_status == GnomeSession.PresenceStatus.AVAILABLE) {
- type = Tp.ConnectionPresenceType.AVAILABLE;
- status = "available";
- }
- else if (session_status == GnomeSession.PresenceStatus.BUSY) {
- type = Tp.ConnectionPresenceType.BUSY;
- status = "busy";
- }
- else {
- return;
- }
-
- this._account_mgr.set_all_requested_presences(type, status, msg);
}
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]