[gnome-shell] [panel] Scale up, center and fade application icon in app menu
- From: Colin Walters <walters src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-shell] [panel] Scale up, center and fade application icon in app menu
- Date: Thu, 7 Jan 2010 23:31:40 +0000 (UTC)
commit c17e1249d5a00cd52ceaf903179571e8480e59f3
Author: Colin Walters <walters verbum org>
Date: Sat Dec 26 12:00:36 2009 -0500
[panel] Scale up, center and fade application icon in app menu
Per 20091114 design.
https://bugzilla.gnome.org/show_bug.cgi?id=605491
data/theme/gnome-shell.css | 4 +
js/ui/panel.js | 135 +++++++++++++++++++++++++++++++++++++++----
src/shell-drawing.c | 65 +++++++++++++++++++++
src/shell-drawing.h | 2 +
4 files changed, 193 insertions(+), 13 deletions(-)
---
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index ce2d109..b8c3881 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -26,6 +26,10 @@
color: #0000e0;
}
+.label-shadow {
+ color: rgba(0,0,0,0.5);
+}
+
StScrollBar
{
padding: 0px;
diff --git a/js/ui/panel.js b/js/ui/panel.js
index a07075d..510a328 100644
--- a/js/ui/panel.js
+++ b/js/ui/panel.js
@@ -13,6 +13,7 @@ const Signals = imports.signals;
const Gettext = imports.gettext.domain('gnome-shell');
const _ = Gettext.gettext;
+const AppDisplay = imports.ui.appDisplay;
const Calendar = imports.ui.calendar;
const Main = imports.ui.main;
const StatusMenu = imports.ui.statusMenu;
@@ -46,6 +47,99 @@ const STANDARD_TRAY_ICON_IMPLEMENTATIONS = {
'gnome-power-manager': 'battery'
};
+function TextShadower() {
+ this._init();
+}
+
+TextShadower.prototype = {
+ _init: function() {
+ this.actor = new Shell.GenericContainer();
+ this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
+ this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
+ this.actor.connect('allocate', Lang.bind(this, this._allocate));
+
+ this._label = new St.Label();
+ this.actor.add_actor(this._label);
+ for (let i = 0; i < 4; i++) {
+ let actor = new St.Label({ style_class: 'label-shadow' });
+ this.actor.add_actor(actor);
+ }
+ this._label.raise_top();
+ },
+
+ setText: function(text) {
+ let children = this.actor.get_children();
+ for (let i = 0; i < children.length; i++)
+ children[i].set_text(text);
+ },
+
+ _getPreferredWidth: function(actor, forHeight, alloc) {
+ let [minWidth, natWidth] = this._label.get_preferred_width(forHeight);
+ alloc.min_size = minWidth;
+ alloc.natural_size = natWidth;
+ },
+
+ _getPreferredHeight: function(actor, forWidth, alloc) {
+ let [minHeight, natHeight] = this._label.get_preferred_height(forWidth);
+ alloc.min_size = minHeight;
+ alloc.natural_size = natHeight;
+ },
+
+ _allocate: function(actor, box, flags) {
+ let children = this.actor.get_children();
+
+ let availWidth = box.x2 - box.x1;
+ let availHeight = box.y2 - box.y1;
+
+ let [minChildWidth, minChildHeight, natChildWidth, natChildHeight] =
+ this._label.get_preferred_size();
+
+ let childWidth = Math.min(natChildWidth, availWidth);
+ let childHeight = Math.min(natChildHeight, availHeight);
+
+ for (let i = 0; i < children.length; i++) {
+ let child = children[i];
+ let childBox = new Clutter.ActorBox();
+ // The order of the labels here is arbitrary, except
+ // we know the "real" label is at the end because Clutter.Group
+ // sorts by Z order
+ switch (i) {
+ case 0: // top
+ childBox.x1 = 1;
+ childBox.y1 = 0;
+ break;
+ case 1: // right
+ childBox.x1 = 2;
+ childBox.y1 = 1;
+ break;
+ case 2: // bottom
+ childBox.x1 = 1;
+ childBox.y1 = 2;
+ break;
+ case 3: // left
+ childBox.x1 = 0;
+ childBox.y1 = 1;
+ break;
+ case 4: // center
+ childBox.x1 = 1;
+ childBox.y1 = 1;
+ break;
+ }
+ childBox.x2 = childBox.x1 + childWidth;
+ childBox.y2 = childBox.y1 + childHeight;
+ child.allocate(childBox, flags);
+ }
+ }
+}
+
+/**
+ * AppPanelMenu:
+ *
+ * This class manages the "application menu" component. It tracks the
+ * currently focused application. However, when an app is launched,
+ * this menu also handles startup notification for it. So when we
+ * have an active startup notification, we switch modes to display that.
+ */
function AppPanelMenu() {
this._init();
}
@@ -59,10 +153,11 @@ AppPanelMenu.prototype = {
this._startupSequences = {};
this.actor = new St.BoxLayout({ name: 'appMenu' });
- this._iconBox = new St.Bin({ name: 'appMenuIcon' });
+ this._iconBox = new Shell.Slicer({ name: 'appMenuIcon' });
this.actor.add(this._iconBox);
- this._label = new St.Label();
- this.actor.add(this._label, { expand: true, y_fill: false });
+ this._label = new TextShadower();
+ this.actor.add(this._label.actor, { expand: true, y_fill: true });
+ this.actor.connect('notify::allocation', Lang.bind(this, this._repositionLabel));
this._startupBox = new St.BoxLayout();
this.actor.add(this._startupBox);
@@ -86,6 +181,16 @@ AppPanelMenu.prototype = {
this._sync();
},
+ _repositionLabel: function() {
+ this._label.actor.x = Math.floor(AppDisplay.APPICON_SIZE / 2);
+ let actorAlloc = this.actor.allocation;
+ let actorHeight = actorAlloc.y2 - actorAlloc.y1;
+ let labelAlloc = this._label.actor.allocation;
+ let labelHeight = labelAlloc.y2 - labelAlloc.y1;
+ this._label.actor.y = Math.floor((actorHeight - labelHeight) / 2);
+ this._label.actor.fixed_position_set = true;
+ },
+
_sync: function() {
let tracker = Shell.WindowTracker.get_default();
@@ -112,20 +217,24 @@ AppPanelMenu.prototype = {
if (this._iconBox.child != null)
this._iconBox.child.destroy();
this._iconBox.hide();
- this._label.set_text('');
+ this._label.setText('');
+ let icon;
if (this._focusedApp != null) {
- let icon = this._focusedApp.create_icon_texture(PANEL_ICON_SIZE);
- this._iconBox.set_child(icon);
- this._iconBox.show();
- let appName = this._focusedApp.get_name();
- // Use _set_text to work around http://bugzilla.openedhand.com/show_bug.cgi?id=1851
- this._label.set_text(appName);
+ icon = this._focusedApp.create_icon_texture(AppDisplay.APPICON_SIZE);
+ this._label.setText(this._focusedApp.get_name());
} else if (this._activeSequence != null) {
- let icon = this._activeSequence.create_icon(PANEL_ICON_SIZE);
- this._iconBox.set_child(icon);
+ icon = this._activeSequence.create_icon(AppDisplay.APPICON_SIZE);
+ this._label.setText(this._activeSequence.get_name());
+ } else {
+ icon = null;
+ }
+
+ if (icon != null) {
+ let faded = Shell.fade_app_icon(icon); /* TODO consider caching */
+ this._iconBox.set_child(faded);
this._iconBox.show();
- this._label.set_text(this._activeSequence.get_name());
}
+ this._repositionLabel();
this.emit('changed');
}
diff --git a/src/shell-drawing.c b/src/shell-drawing.c
index 21f7129..a4c8930 100644
--- a/src/shell-drawing.c
+++ b/src/shell-drawing.c
@@ -52,6 +52,71 @@ shell_draw_clock (ClutterCairoTexture *texture,
cairo_destroy (cr);
}
+/**
+ * shell_fade_app_icon:
+ * @source: Source #ClutterTexture
+ *
+ * Create a new texture by modifying the alpha channel of the
+ * source texture, adding a horizontal gradient fade.
+ *
+ * Returns: (transfer none): A new #ClutterTexture
+ */
+ClutterTexture *
+shell_fade_app_icon (ClutterTexture *source)
+{
+ CoglHandle texture;
+ guchar *pixels;
+ gint width, height, rowstride;
+ gint fade_start;
+ gint fade_range;
+ guint i, j;
+ ClutterTexture *result;
+
+ texture = clutter_texture_get_cogl_texture (source);
+ if (texture == COGL_INVALID_HANDLE)
+ return NULL;
+
+ width = cogl_texture_get_width (texture);
+ height = cogl_texture_get_height (texture);
+ rowstride = (width * 4 + 3) & ~3;
+
+ pixels = g_malloc0 (rowstride * height);
+
+ cogl_texture_get_data (texture, COGL_PIXEL_FORMAT_RGBA_8888_PRE,
+ rowstride, pixels);
+ cogl_texture_unref (texture);
+
+ fade_start = width / 2;
+ fade_range = width - fade_start;
+ for (i = fade_start; i < width; i++)
+ {
+ for (j = 0; j < height; j++)
+ {
+ guchar *pixel = &pixels[j * rowstride + i * 4];
+ float fade = 1.0 - ((float) i - fade_start) / fade_range;
+ pixel[0] = 0.5 + pixel[0] * fade;
+ pixel[1] = 0.5 + pixel[1] * fade;
+ pixel[2] = 0.5 + pixel[2] * fade;
+ pixel[3] = 0.5 + pixel[3] * fade;
+ }
+ }
+
+ texture = cogl_texture_new_from_data (width,
+ height,
+ COGL_TEXTURE_NONE,
+ COGL_PIXEL_FORMAT_RGBA_8888_PRE,
+ COGL_PIXEL_FORMAT_ANY,
+ rowstride,
+ pixels);
+ g_free (pixels);
+
+ result = (ClutterTexture*)clutter_texture_new ();
+ clutter_texture_set_cogl_texture (result, texture);
+ cogl_texture_unref (texture);
+
+ return result;
+}
+
void
shell_draw_box_pointer (ClutterCairoTexture *texture,
ShellPointerDirection direction,
diff --git a/src/shell-drawing.h b/src/shell-drawing.h
index 4b48d11..f60adf4 100644
--- a/src/shell-drawing.h
+++ b/src/shell-drawing.h
@@ -23,6 +23,8 @@ void shell_draw_clock (ClutterCairoTexture *texture,
int hour,
int minute);
+ClutterTexture * shell_fade_app_icon (ClutterTexture *source);
+
guint shell_add_hook_paint_red_border (ClutterActor *actor);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]