[gnome-flashback/wip/segeiger/statusicon] input-sources: implement status icon with pango and cairo
- From: Sebastian Geiger <segeiger src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-flashback/wip/segeiger/statusicon] input-sources: implement status icon with pango and cairo
- Date: Thu, 1 Oct 2015 21:11:16 +0000 (UTC)
commit 7d01ba9026d270972b7b563cf1ef88b0f3a58d83
Author: Sebastian Geiger <sbastig gmx net>
Date: Wed Sep 30 14:54:55 2015 +0200
input-sources: implement status icon with pango and cairo
data/schemas/org.gnome.gnome-flashback.gschema.xml | 4 +-
.../libinput-sources/gf-input-sources.c | 268 ++++++++++++++++++++
2 files changed, 270 insertions(+), 2 deletions(-)
---
diff --git a/data/schemas/org.gnome.gnome-flashback.gschema.xml
b/data/schemas/org.gnome.gnome-flashback.gschema.xml
index 12c6e94..cdcbf4f 100644
--- a/data/schemas/org.gnome.gnome-flashback.gschema.xml
+++ b/data/schemas/org.gnome.gnome-flashback.gschema.xml
@@ -103,13 +103,13 @@
<schema id="org.gnome.gnome-flashback.input-sources" path="/org/gnome/gnome-flashback/input-sources/">
<key name="status-icon-bg-color" type="s">
- <default>'#000000'</default>
+ <default>'rgba(255, 255, 255, 1.0)'</default>
<summary>The background color for the status icon.</summary>
<description>This contains the background color for the status icon that is shown in the system
tray.</description>
</key>
<key name="status-icon-fg-color" type="s">
- <default>'#FFFFFF'</default>
+ <default>'rgba(0, 0, 0, 1.0)'</default>
<summary>The foreground color for the status icon.</summary>
<description>This contains the foreground color for the status icon that is shown in the system
tray.</description>
</key>
diff --git a/gnome-flashback/libinput-sources/gf-input-sources.c
b/gnome-flashback/libinput-sources/gf-input-sources.c
index ce708ad..6645df8 100644
--- a/gnome-flashback/libinput-sources/gf-input-sources.c
+++ b/gnome-flashback/libinput-sources/gf-input-sources.c
@@ -17,9 +17,34 @@
#include "config.h"
+#define _XOPEN_SOURCE
+
+#include <gtk/gtk.h>
+
#include "gf-ibus-manager.h"
#include "gf-input-sources.h"
#include "gf-input-source-manager.h"
+#include "gf-input-source.h"
+
+#include <pango/pangocairo.h>
+#include <math.h>
+
+#define INPUT_SOURCES_SCHEMA "org.gnome.gnome-flashback.input-sources"
+#define GNOME_DESKTOP_SCHEMA "org.gnome.desktop.interface"
+#define SIZE 256
+
+struct IconInfo_
+{
+ gchar *font_name,
+ *short_name;
+
+ gdouble font_size;
+
+ GdkRGBA bg_color,
+ fg_color;
+};
+
+typedef struct IconInfo_ IconInfo;
struct _GfInputSources
{
@@ -27,10 +52,101 @@ struct _GfInputSources
GfIBusManager *ibus_manager;
GfInputSourceManager *input_source_manager;
+
+ GtkStatusIcon *status_icon;
+
+ IconInfo *icon_info;
};
G_DEFINE_TYPE (GfInputSources, gf_input_sources, G_TYPE_OBJECT)
+static void draw_short_name (cairo_t *cr, IconInfo *info)
+{
+ gdouble text_width, text_y;
+ gdouble pango_font_size;
+ gdouble baseline;
+ gdouble x, y;
+
+ gint center;
+
+ gchar *short_name, *font_name;
+
+ PangoLayout *layout;
+ PangoFontDescription *font_description;
+ PangoRectangle ink_rect, logical_rect;
+
+ short_name = info->short_name;
+ font_name = info->font_name;
+
+ font_description = pango_font_description_from_string (font_name);
+ pango_font_description_set_weight (font_description, PANGO_WEIGHT_BOLD);
+ pango_font_size = SIZE * info->font_size * PANGO_SCALE;
+ pango_font_description_set_absolute_size (font_description,
+ pango_font_size);
+
+ layout = pango_cairo_create_layout (cr);
+ pango_layout_set_font_description (layout, font_description);
+ pango_layout_set_text (layout, short_name, -1);
+
+ pango_layout_get_extents (layout, &ink_rect, &logical_rect);
+
+ text_width = ink_rect.width / (gdouble) PANGO_SCALE;
+ text_y = ink_rect.y / (gdouble) PANGO_SCALE;
+
+ baseline = pango_layout_get_baseline (layout) / PANGO_SCALE;
+
+ center = SIZE / 2;
+ y = center + baseline / 2.0 - text_y / 2.0;
+ x = (SIZE - text_width) / 2.0 - (ink_rect.x / PANGO_SCALE);
+
+ gdk_cairo_set_source_rgba (cr, &info->fg_color);
+ cairo_move_to (cr, x, y);
+ pango_cairo_show_layout_line (cr, pango_layout_get_line (layout, 0));
+
+ g_object_unref (layout);
+ pango_font_description_free (font_description);
+}
+
+static void draw_rounded_rectangle (cairo_t *cr, IconInfo *info)
+{
+ double
+ x = 10,
+ y = 10,
+ width = SIZE - 2*x,
+ height = SIZE - 2*y,
+ aspect = 1.0, /* aspect ratio */
+ corner_radius = height / 10.0; /* and corner curvature radius */
+
+ double radius = corner_radius / aspect;
+ double degrees = M_PI / 180.0;
+
+ cairo_new_sub_path (cr);
+ cairo_arc (cr, x + width - radius, y + radius, radius, -90 * degrees, 0 * degrees);
+ cairo_arc (cr, x + width - radius, y + height - radius, radius, 0 * degrees, 90 * degrees);
+ cairo_arc (cr, x + radius, y + height - radius, radius, 90 * degrees, 180 * degrees);
+ cairo_arc (cr, x + radius, y + radius, radius, 180 * degrees, 270 * degrees);
+ cairo_close_path (cr);
+
+ gdk_cairo_set_source_rgba (cr, &info->bg_color);
+ cairo_fill_preserve (cr);
+}
+
+static GdkPixbuf *get_pixbuf_for_icon_info(IconInfo *info)
+{
+ cairo_surface_t *surface;
+ cairo_t * cr;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, SIZE, SIZE);
+ cr = cairo_create (surface);
+
+ draw_rounded_rectangle (cr, info);
+ draw_short_name (cr, info);
+
+ return gdk_pixbuf_get_from_surface (surface, 0, 0, SIZE, SIZE);
+
+}
+
+
static void
sources_changed_cb (GfInputSourceManager *manager,
gpointer user_data)
@@ -38,6 +154,95 @@ sources_changed_cb (GfInputSourceManager *manager,
}
static void
+update_status_icon_pixbuf (GfInputSources *sources)
+{
+ GdkPixbuf *pixbuf;
+
+ pixbuf = get_pixbuf_for_icon_info (sources->icon_info);
+
+ gtk_status_icon_set_from_pixbuf (sources->status_icon, pixbuf);
+}
+
+static void
+current_source_changed_cb (GfInputSourceManager *manager,
+ GfInputSource *old_source,
+ GfInputSources *sources)
+{
+ GfInputSource *current_source;
+ gchar *display_name, *short_name;
+
+ current_source = gf_input_source_manager_get_current_source (manager);
+ display_name = g_strdup (gf_input_source_get_display_name (current_source));
+ short_name = g_strdup (gf_input_source_get_short_name (current_source));
+
+ if (sources->status_icon == NULL)
+ {
+ sources->status_icon = gtk_status_icon_new ();
+ }
+
+ gtk_status_icon_set_tooltip_text (sources->status_icon, display_name);
+
+ sources->icon_info->short_name = short_name;
+
+ update_status_icon_pixbuf (sources);
+}
+
+static void
+status_icon_bg_color_changed_cb (GSettings *settings,
+ gchar *key,
+ gpointer user_data)
+{
+ GfInputSources *sources;
+ const gchar* bg_color;
+ GVariant *variant;
+
+ sources = GF_INPUT_SOURCES (user_data);
+ variant = g_settings_get_value (settings, key);
+ bg_color = g_variant_get_string (variant, NULL);
+
+ gdk_rgba_parse (&sources->icon_info->bg_color, bg_color);
+
+ update_status_icon_pixbuf (sources);
+}
+
+static void
+status_icon_fg_color_changed_cb (GSettings *settings,
+ gchar *key,
+ gpointer user_data)
+{
+ GfInputSources *sources;
+ const gchar* fg_color;
+ GVariant *variant;
+
+ sources = GF_INPUT_SOURCES (user_data);
+ variant = g_settings_get_value (settings, key);
+ fg_color = g_variant_get_string (variant, NULL);
+
+ gdk_rgba_parse (&sources->icon_info->fg_color, fg_color);
+
+ update_status_icon_pixbuf (sources);
+}
+
+static void
+font_name_changed_cb (GSettings *settings,
+ gchar *key,
+ gpointer user_data)
+{
+ GfInputSources *sources;
+ const gchar* font_name;
+ GVariant *variant;
+
+ sources = GF_INPUT_SOURCES (user_data);
+ variant = g_settings_get_value (settings, key);
+ font_name = g_variant_get_string (variant, NULL);
+
+ g_free (sources->icon_info->font_name);
+ sources->icon_info->font_name = g_strdup (font_name);
+
+ update_status_icon_pixbuf (sources);
+}
+
+static void
gf_input_sources_dispose (GObject *object)
{
GfInputSources *sources;
@@ -51,6 +256,18 @@ gf_input_sources_dispose (GObject *object)
}
static void
+gf_input_sources_finalize (GObject *object)
+{
+ GfInputSources *sources;
+
+ sources = GF_INPUT_SOURCES (object);
+
+ g_free (sources->icon_info->font_name);
+ g_free (sources->icon_info->short_name);
+ g_free (sources->icon_info);
+}
+
+static void
gf_input_sources_class_init (GfInputSourcesClass *sources_class)
{
GObjectClass *object_class;
@@ -58,17 +275,68 @@ gf_input_sources_class_init (GfInputSourcesClass *sources_class)
object_class = G_OBJECT_CLASS (sources_class);
object_class->dispose = gf_input_sources_dispose;
+ object_class->finalize= gf_input_sources_finalize;
}
static void
gf_input_sources_init (GfInputSources *sources)
{
+ GdkRGBA bg, fg;
+
+ const gchar* bg_color;
+ const gchar* fg_color;
+ const gchar* font_name;
+
+ GSettings *input_sources_settings;
+ GSettings *gnome_desktop_settings;
+
+ GVariant *variant;
+
sources->ibus_manager = gf_ibus_manager_new ();
sources->input_source_manager = gf_input_source_manager_new (sources->ibus_manager);
+ sources->icon_info = g_new0 (IconInfo, 1);
+
+ input_sources_settings = g_settings_new (INPUT_SOURCES_SCHEMA);
+ gnome_desktop_settings = g_settings_new (GNOME_DESKTOP_SCHEMA);
+
+ variant = g_settings_get_value (gnome_desktop_settings,
+ "font-name");
+
+ font_name = g_variant_get_string (variant, NULL);
+
+ variant = g_settings_get_value (input_sources_settings,
+ "status-icon-bg-color");
+
+ bg_color = g_variant_get_string (variant, NULL);
+
+ variant = g_settings_get_value (input_sources_settings,
+ "status-icon-fg-color");
+
+ fg_color = g_variant_get_string (variant, NULL);
+
+ gdk_rgba_parse (&bg, bg_color);
+ gdk_rgba_parse (&fg, fg_color);
+
+ sources->icon_info->font_name = g_strdup (font_name);
+ sources->icon_info->bg_color = bg;
+ sources->icon_info->fg_color = fg;
+ sources->icon_info->font_size = 0.6;
g_signal_connect (sources->input_source_manager, "sources-changed",
G_CALLBACK (sources_changed_cb), sources);
+ g_signal_connect (sources->input_source_manager, "current-source-changed",
+ G_CALLBACK (current_source_changed_cb), sources);
+
+ g_signal_connect (input_sources_settings, "changed::status-icon-bg-color",
+ G_CALLBACK (status_icon_bg_color_changed_cb), sources);
+
+ g_signal_connect (input_sources_settings, "changed::status-icon-fg-color",
+ G_CALLBACK (status_icon_fg_color_changed_cb), sources);
+
+ g_signal_connect (gnome_desktop_settings, "changed::font-name",
+ G_CALLBACK (font_name_changed_cb), sources);
+
gf_input_source_manager_reload (sources->input_source_manager);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]