Avoid ellipsizing app names; Draw glow around running
Corresponding with the design, if an application is in a running state (has > 0 windows open), draw a glow behind the name. To make the display look a bit nicer, set the width of each item to be equal to the longest word among all the items.
This commit is contained in:
parent
9f4ccb83e3
commit
96cf9c739e
@ -19,6 +19,10 @@ const Workspaces = imports.ui.workspaces;
|
|||||||
const ENTERED_MENU_COLOR = new Clutter.Color();
|
const ENTERED_MENU_COLOR = new Clutter.Color();
|
||||||
ENTERED_MENU_COLOR.from_pixel(0x00ff0022);
|
ENTERED_MENU_COLOR.from_pixel(0x00ff0022);
|
||||||
|
|
||||||
|
const GLOW_COLOR = new Clutter.Color();
|
||||||
|
GLOW_COLOR.from_pixel(0x4f6ba4ff);
|
||||||
|
const GLOW_PADDING = 5;
|
||||||
|
|
||||||
const APP_ICON_SIZE = 48;
|
const APP_ICON_SIZE = 48;
|
||||||
const APP_PADDING = 18;
|
const APP_PADDING = 18;
|
||||||
|
|
||||||
@ -464,7 +468,6 @@ WellDisplayItem.prototype = {
|
|||||||
border: 0,
|
border: 0,
|
||||||
padding: 1,
|
padding: 1,
|
||||||
border_color: GenericDisplay.ITEM_DISPLAY_SELECTED_BACKGROUND_COLOR,
|
border_color: GenericDisplay.ITEM_DISPLAY_SELECTED_BACKGROUND_COLOR,
|
||||||
width: APP_ICON_SIZE + APP_PADDING,
|
|
||||||
reactive: true });
|
reactive: true });
|
||||||
this.actor.connect('enter-event', Lang.bind(this,
|
this.actor.connect('enter-event', Lang.bind(this,
|
||||||
function(o, event) {
|
function(o, event) {
|
||||||
@ -494,25 +497,46 @@ WellDisplayItem.prototype = {
|
|||||||
|
|
||||||
this._windows = Shell.AppMonitor.get_default().get_windows_for_app(appInfo.get_id());
|
this._windows = Shell.AppMonitor.get_default().get_windows_for_app(appInfo.get_id());
|
||||||
|
|
||||||
let nameBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
|
let nameBox = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||||
x_align: Big.BoxAlignment.CENTER });
|
x_align: Big.BoxAlignment.CENTER });
|
||||||
|
this._nameBox = nameBox;
|
||||||
|
|
||||||
|
this._wordWidth = Shell.Global.get().get_max_word_width(this.actor, appInfo.get_name(),
|
||||||
|
"Sans 12px");
|
||||||
this._name = new Clutter.Text({ color: GenericDisplay.ITEM_DISPLAY_NAME_COLOR,
|
this._name = new Clutter.Text({ color: GenericDisplay.ITEM_DISPLAY_NAME_COLOR,
|
||||||
font_name: "Sans 12px",
|
font_name: "Sans 12px",
|
||||||
ellipsize: Pango.EllipsizeMode.END,
|
|
||||||
line_alignment: Pango.Alignment.CENTER,
|
line_alignment: Pango.Alignment.CENTER,
|
||||||
line_wrap: true,
|
line_wrap: true,
|
||||||
line_wrap_mode: Pango.WrapMode.WORD_CHAR,
|
line_wrap_mode: Pango.WrapMode.WORD,
|
||||||
text: appInfo.get_name() });
|
text: appInfo.get_name() });
|
||||||
nameBox.append(this._name, Big.BoxPackFlags.EXPAND);
|
nameBox.append(this._name, Big.BoxPackFlags.NONE);
|
||||||
if (this._windows.length > 0) {
|
if (this._windows.length > 0) {
|
||||||
let runningBox = new Big.Box({ /* border_color: GenericDisplay.ITEM_DISPLAY_NAME_COLOR,
|
let glow = new Shell.DrawingArea({});
|
||||||
border: 1,
|
glow.connect('redraw', Lang.bind(this, function (e, tex) {
|
||||||
padding: 1 */ });
|
Shell.Global.clutter_cairo_texture_draw_glow(tex,
|
||||||
runningBox.append(nameBox, Big.BoxPackFlags.EXPAND);
|
GLOW_COLOR.red / 255,
|
||||||
this.actor.append(runningBox, Big.BoxPackFlags.NONE);
|
GLOW_COLOR.green / 255,
|
||||||
} else {
|
GLOW_COLOR.blue / 255,
|
||||||
this.actor.append(nameBox, Big.BoxPackFlags.NONE);
|
GLOW_COLOR.alpha / 255);
|
||||||
|
}));
|
||||||
|
this._name.connect('notify::allocation', Lang.bind(this, function (n, alloc) {
|
||||||
|
let x = this._name.x;
|
||||||
|
let y = this._name.y;
|
||||||
|
let width = this._name.width;
|
||||||
|
let height = this._name.height;
|
||||||
|
// If we're smaller than the allocated box width, pad out the glow a bit
|
||||||
|
// to make it more visible
|
||||||
|
if ((width + GLOW_PADDING * 2) < this._nameBox.width) {
|
||||||
|
width += GLOW_PADDING * 2;
|
||||||
|
x -= GLOW_PADDING;
|
||||||
}
|
}
|
||||||
|
glow.set_size(width, height);
|
||||||
|
glow.set_position(x, y);
|
||||||
|
}));
|
||||||
|
nameBox.add_actor(glow);
|
||||||
|
glow.lower(this._name);
|
||||||
|
}
|
||||||
|
this.actor.append(nameBox, Big.BoxPackFlags.NONE);
|
||||||
},
|
},
|
||||||
|
|
||||||
_handleActivate: function () {
|
_handleActivate: function () {
|
||||||
@ -560,6 +584,14 @@ WellDisplayItem.prototype = {
|
|||||||
// that represents the item as it is being dragged.
|
// that represents the item as it is being dragged.
|
||||||
getDragActorSource: function() {
|
getDragActorSource: function() {
|
||||||
return this._icon;
|
return this._icon;
|
||||||
|
},
|
||||||
|
|
||||||
|
getWordWidth: function() {
|
||||||
|
return this._wordWidth;
|
||||||
|
},
|
||||||
|
|
||||||
|
setWidth: function(width) {
|
||||||
|
this._nameBox.width = width + GLOW_PADDING * 2;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -587,14 +619,32 @@ WellArea.prototype = {
|
|||||||
v.destroy();
|
v.destroy();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
this._maxWordWidth = 0;
|
||||||
|
let displays = []
|
||||||
for (let i = 0; i < infos.length; i++) {
|
for (let i = 0; i < infos.length; i++) {
|
||||||
let app = infos[i];
|
let app = infos[i];
|
||||||
let display = new WellDisplayItem(app, this.isFavorite);
|
let display = new WellDisplayItem(app, this.isFavorite);
|
||||||
|
displays.push(display);
|
||||||
|
let width = display.getWordWidth();
|
||||||
|
if (width > this._maxWordWidth)
|
||||||
|
this._maxWordWidth = width;
|
||||||
display.connect('activated', Lang.bind(this, function (display) {
|
display.connect('activated', Lang.bind(this, function (display) {
|
||||||
this.emit('activated', display);
|
this.emit('activated', display);
|
||||||
}));
|
}));
|
||||||
this.actor.add_actor(display.actor);
|
this.actor.add_actor(display.actor);
|
||||||
}
|
}
|
||||||
|
this._displays = displays;
|
||||||
|
},
|
||||||
|
|
||||||
|
getWordWidth: function() {
|
||||||
|
return this._maxWordWidth;
|
||||||
|
},
|
||||||
|
|
||||||
|
setItemWidth: function(width) {
|
||||||
|
for (let i = 0; i < this._displays.length; i++) {
|
||||||
|
let display = this._displays[i];
|
||||||
|
display.setWidth(width);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Draggable target interface
|
// Draggable target interface
|
||||||
@ -710,6 +760,11 @@ AppWell.prototype = {
|
|||||||
let running = this._lookupApps(runningIds);
|
let running = this._lookupApps(runningIds);
|
||||||
this._favoritesArea.redisplay(favorites);
|
this._favoritesArea.redisplay(favorites);
|
||||||
this._runningArea.redisplay(running);
|
this._runningArea.redisplay(running);
|
||||||
|
let maxWidth = this._favoritesArea.getWordWidth();
|
||||||
|
if (this._runningArea.getWordWidth() > maxWidth)
|
||||||
|
maxWidth = this._runningArea.getWordWidth();
|
||||||
|
this._favoritesArea.setItemWidth(maxWidth);
|
||||||
|
this._runningArea.setItemWidth(maxWidth);
|
||||||
// If it's empty, we hide it so the top border doesn't show up
|
// If it's empty, we hide it so the top border doesn't show up
|
||||||
if (running.length == 0)
|
if (running.length == 0)
|
||||||
this._runningBox.hide();
|
this._runningBox.hide();
|
||||||
|
@ -1061,6 +1061,46 @@ shell_global_create_root_pixmap_actor (ShellGlobal *global)
|
|||||||
return clutter_clone_new (global->root_pixmap);
|
return clutter_clone_new (global->root_pixmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shell_global_get_max_word_width:
|
||||||
|
* @global:
|
||||||
|
* @ref: Actor to use for font information
|
||||||
|
* @text: Text to analyze
|
||||||
|
* @font: Given font size to use
|
||||||
|
*
|
||||||
|
* Compute the largest pixel size among the individual words in text, when
|
||||||
|
* rendered in the given font.
|
||||||
|
*/
|
||||||
|
guint
|
||||||
|
shell_global_get_max_word_width (ShellGlobal *global, ClutterActor *ref, const char *text, const char *font)
|
||||||
|
{
|
||||||
|
PangoLayout *layout;
|
||||||
|
PangoFontDescription *fontdesc;
|
||||||
|
char **components;
|
||||||
|
char **iter;
|
||||||
|
gint max;
|
||||||
|
|
||||||
|
layout = clutter_actor_create_pango_layout (ref, NULL);
|
||||||
|
fontdesc = pango_font_description_from_string (font);
|
||||||
|
pango_layout_set_font_description (layout, fontdesc);
|
||||||
|
pango_font_description_free (fontdesc);
|
||||||
|
|
||||||
|
max = 0;
|
||||||
|
components = g_strsplit (text, " ", 0);
|
||||||
|
for (iter = components; *iter; iter++)
|
||||||
|
{
|
||||||
|
char *component = *iter;
|
||||||
|
gint width, height;
|
||||||
|
pango_layout_set_text (layout, component, -1);
|
||||||
|
pango_layout_get_pixel_size (layout, &width, &height);
|
||||||
|
if (width > max)
|
||||||
|
max = width;
|
||||||
|
}
|
||||||
|
g_object_unref (layout);
|
||||||
|
g_strfreev (components);
|
||||||
|
return (guint)max;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
shell_global_clutter_cairo_texture_draw_clock (ClutterCairoTexture *texture,
|
shell_global_clutter_cairo_texture_draw_clock (ClutterCairoTexture *texture,
|
||||||
int hour,
|
int hour,
|
||||||
@ -1107,3 +1147,37 @@ shell_global_clutter_cairo_texture_draw_clock (ClutterCairoTexture *texture,
|
|||||||
|
|
||||||
cairo_destroy (cr);
|
cairo_destroy (cr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
shell_global_clutter_cairo_texture_draw_glow (ClutterCairoTexture *texture,
|
||||||
|
double red,
|
||||||
|
double green,
|
||||||
|
double blue,
|
||||||
|
double alpha)
|
||||||
|
{
|
||||||
|
cairo_t *cr;
|
||||||
|
guint width, height;
|
||||||
|
cairo_pattern_t *gradient;
|
||||||
|
|
||||||
|
clutter_cairo_texture_get_surface_size (texture, &width, &height);
|
||||||
|
|
||||||
|
clutter_cairo_texture_clear (texture);
|
||||||
|
cr = clutter_cairo_texture_create (texture);
|
||||||
|
|
||||||
|
cairo_save (cr);
|
||||||
|
cairo_translate (cr, width / 2.0, height / 2.0);
|
||||||
|
cairo_scale (cr, width / 2.0, height / 2.0);
|
||||||
|
|
||||||
|
gradient = cairo_pattern_create_radial (0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
|
||||||
|
cairo_pattern_add_color_stop_rgba (gradient, 0.0, red, green, blue, alpha);
|
||||||
|
cairo_pattern_add_color_stop_rgba (gradient, 0.7, red, green, blue, alpha * 0.7);
|
||||||
|
cairo_pattern_add_color_stop_rgba (gradient, 1.0, red, green, blue, alpha * 0.3);
|
||||||
|
cairo_set_source (cr, gradient);
|
||||||
|
|
||||||
|
cairo_arc (cr, 0.0, 0.0, 1.0, 0.0, 2.0 * M_PI);
|
||||||
|
cairo_fill (cr);
|
||||||
|
cairo_restore (cr);
|
||||||
|
cairo_pattern_destroy (gradient);
|
||||||
|
cairo_destroy (cr);
|
||||||
|
}
|
||||||
|
@ -81,10 +81,18 @@ void shell_global_format_time_relative_pretty (ShellGlobal *global, guint delta,
|
|||||||
|
|
||||||
ClutterActor *shell_global_create_root_pixmap_actor (ShellGlobal *global);
|
ClutterActor *shell_global_create_root_pixmap_actor (ShellGlobal *global);
|
||||||
|
|
||||||
|
guint shell_global_get_max_word_width (ShellGlobal *global, ClutterActor *ref, const char *text, const char *font);
|
||||||
|
|
||||||
void shell_global_clutter_cairo_texture_draw_clock (ClutterCairoTexture *texture,
|
void shell_global_clutter_cairo_texture_draw_clock (ClutterCairoTexture *texture,
|
||||||
int hour,
|
int hour,
|
||||||
int minute);
|
int minute);
|
||||||
|
|
||||||
|
void shell_global_clutter_cairo_texture_draw_glow (ClutterCairoTexture *texture,
|
||||||
|
double red,
|
||||||
|
double blue,
|
||||||
|
double green,
|
||||||
|
double alpha);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __SHELL_GLOBAL_H__ */
|
#endif /* __SHELL_GLOBAL_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user