[Galago-commits] r2342 - in trunk/notify-daemon-ng: . src
galago-commits at freedesktop.org
galago-commits at freedesktop.org
Tue Nov 22 14:00:24 PST 2005
Author: johnp
Date: 2005-11-22 14:00:12 -0800 (Tue, 22 Nov 2005)
New Revision: 2342
Modified:
trunk/notify-daemon-ng/ChangeLog
trunk/notify-daemon-ng/configure.ac
trunk/notify-daemon-ng/src/eggnotificationbubblewidget.c
trunk/notify-daemon-ng/src/eggnotificationbubblewidget.h
Log:
* src/eggnotificationbubblewidget.c: Add a more stylized bubble
and render in both composite and shaped window mode
Modified: trunk/notify-daemon-ng/ChangeLog
===================================================================
--- trunk/notify-daemon-ng/ChangeLog 2005-11-21 09:36:06 UTC (rev 2341)
+++ trunk/notify-daemon-ng/ChangeLog 2005-11-22 22:00:12 UTC (rev 2342)
@@ -1,3 +1,8 @@
+2005-11-22 John (J5) Palmieri <johnp at redhat.com>
+
+ * src/eggnotificationbubblewidget.c: Add a more stylized bubble
+ and render in both composite and shaped window mode
+
2005-11-15 John (J5) Palmieri <johnp at redhat.com>
* Change refrences from notification to notify
Modified: trunk/notify-daemon-ng/configure.ac
===================================================================
--- trunk/notify-daemon-ng/configure.ac 2005-11-21 09:36:06 UTC (rev 2341)
+++ trunk/notify-daemon-ng/configure.ac 2005-11-22 22:00:12 UTC (rev 2342)
@@ -3,7 +3,7 @@
dnl ################################################################
dnl # Initialize autoconf
dnl ################################################################
-AC_INIT(notify-daemon, 0.3.0, johnp at redhat.com)
+AC_INIT(notify-daemon, 0.3.1, johnp at redhat.com)
AC_PREREQ(2.50)
AC_CONFIG_SRCDIR(config.h.in)
AC_COPYRIGHT([Copyright 2005 John (J5) Palmieri])
@@ -14,7 +14,7 @@
dnl ################################################################
NOTIFY_DAEMON_MAJOR_VERSION=0
NOTIFY_DAEMON_MINOR_VERSION=3
-NOTIFY_DAEMON_MICRO_VERSION=0
+NOTIFY_DAEMON_MICRO_VERSION=1
NOTIFY_DAEMON_DEVEL_VERSION=0
NOTIFY_DAEMON_VERSION=$NOTIFY_DAEMON_MAJOR_VERSION.$NOTIFY_DAEMON_MINOR_VERSION.$NOTIFY_DAEMON_MICRO_VERSION
Modified: trunk/notify-daemon-ng/src/eggnotificationbubblewidget.c
===================================================================
--- trunk/notify-daemon-ng/src/eggnotificationbubblewidget.c 2005-11-21 09:36:06 UTC (rev 2341)
+++ trunk/notify-daemon-ng/src/eggnotificationbubblewidget.c 2005-11-22 22:00:12 UTC (rev 2342)
@@ -20,11 +20,16 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
+#include <math.h>
#include <gtk/gtk.h>
#include "eggnotificationbubblewidget.h"
-#define BORDER_SIZE 15
+#define BORDER_SIZE 30
+#define CURVE_LENGTH 25
+#define TRIANGLE_START 45
+#define TRIANGLE_WIDTH 60
+#define TEXT_WIDTH_THRESHOLD 100
static void egg_notification_bubble_widget_class_init (EggNotificationBubbleWidgetClass *klass);
static void egg_notification_bubble_widget_init (EggNotificationBubbleWidget *bubble_widget);
@@ -32,9 +37,21 @@
static void egg_notification_bubble_widget_event_handler (GtkWidget *widget,
GdkEvent *event,
gpointer user_data);
-static gboolean egg_notification_bubble_widget_expose (GtkWidget *widget, GdkEventExpose *event);
+static gboolean egg_notification_bubble_widget_expose (GtkWidget *widget,
+ GdkEventExpose *event);
-static void populate_window (EggNotificationBubbleWidget *bubble_widget);
+static gboolean egg_notification_bubble_widget_body_label_expose_handler (GtkWidget *widget,
+ GdkEventExpose *event,
+ EggNotificationBubbleWidget *bw);
+
+static void egg_notification_bubble_widget_context_changed_handler (EggNotificationBubbleWidget *bubble_widget);
+
+static void egg_notification_bubble_widget_realize (GtkWidget *widget);
+
+static void egg_notification_bubble_widget_screen_changed (GtkWidget *widget,
+ GdkScreen *old_screen);
+
+static void _populate_window (EggNotificationBubbleWidget *bubble_widget);
static void draw_bubble_widget (EggNotificationBubbleWidget *bubble_widget);
static GtkWindowClass *parent_class;
@@ -103,6 +120,8 @@
object_class->finalize = egg_notification_bubble_widget_finalize;
widget_class->expose_event = egg_notification_bubble_widget_expose;
+ widget_class->realize = egg_notification_bubble_widget_realize;
+ widget_class->screen_changed = egg_notification_bubble_widget_screen_changed;
egg_notification_bubble_widget_signals[NOTIFICATION_CLICKED] =
g_signal_new ("clicked",
@@ -116,14 +135,63 @@
}
static void
+_size_request_handler (GtkWidget *widget, GtkRequisition *requisition, EggNotificationBubbleWidget *bw)
+{
+ #if 0
+ GtkRequisition req;
+ int new_height;
+
+ if (!GTK_WIDGET_VISIBLE (widget) ||
+ GTK_WIDGET (bw)->allocation.width <= 1)
+ return;
+
+ gtk_widget_set_size_request (GTK_WIDGET (bw), 0, -1);
+ gtk_widget_size_request (GTK_WIDGET (bw), &req);
+ g_print ("req width: %d, req height: %d\n", req.width, req.height);
+
+ new_height = GTK_WIDGET (bw)->allocation.height - widget->allocation.height
+ + req.height;
+
+ if (GTK_WIDGET (bw)->allocation.width > 0 && new_height > 0 && new_height !=
+ widget->allocation.height)
+ {
+
+ g_print ("window req width: %d, req height: %d\n",
+ GTK_WIDGET (bw)->allocation.width,
+ new_height);
+ gtk_window_resize (GTK_WINDOW (bw),
+ GTK_WIDGET (bw)->allocation.width,
+ new_height);
+ }
+ #endif
+
+#if 0
+ if (req.width > MAX_BUBBLE_WIDTH)
+ {
+ g_print ("-");
+ fflush (stdout);
+ gtk_widget_set_size_request (GTK_WIDGET (bubble_widget), MAX_BUBBLE_WIDTH, -1);
+ gtk_widget_size_request (GTK_WIDGET (bubble_widget), &req);
+ gtk_window_resize (GTK_WINDOW (bubble_widget), req.width, req.height);
+ }
+#endif
+}
+
+static void
egg_notification_bubble_widget_init (EggNotificationBubbleWidget *bubble_widget)
{
GtkWindow *win;
-
+
win = GTK_WINDOW (bubble_widget);
- populate_window (bubble_widget);
+ bubble_widget->can_composite = FALSE;
+ egg_notification_bubble_widget_screen_changed (GTK_WIDGET (bubble_widget),
+ NULL);
+
+
+ _populate_window (bubble_widget);
+
}
static void
@@ -138,52 +206,143 @@
}
static void
-populate_window (EggNotificationBubbleWidget *bubble_widget)
+_populate_window (EggNotificationBubbleWidget *bubble_widget)
{
g_return_if_fail (EGG_IS_NOTIFICATION_BUBBLE_WIDGET (bubble_widget));
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *widget;
-
+ GdkGeometry geom;
+
widget = GTK_WIDGET (bubble_widget);
gtk_widget_add_events (widget, GDK_BUTTON_PRESS_MASK);
gtk_widget_set_app_paintable (widget, TRUE);
- gtk_window_set_resizable (GTK_WINDOW (bubble_widget), FALSE);
- gtk_widget_set_name (widget, "gtk-tooltips");
+ gtk_window_set_resizable (GTK_WINDOW (bubble_widget), TRUE);
gtk_container_set_border_width (GTK_CONTAINER (bubble_widget), BORDER_SIZE + 5);
bubble_widget->bubble_widget_header_label = gtk_label_new (NULL);
- bubble_widget->bubble_widget_body_label = gtk_label_new (NULL);
+
+ //use placeholder so we can use pango/cairo to draw body
+ bubble_widget->bubble_widget_body_label = gtk_frame_new("");
+ gtk_frame_set_shadow_type (bubble_widget->bubble_widget_body_label, GTK_SHADOW_NONE);
bubble_widget->icon = gtk_image_new_from_stock (GTK_STOCK_INFO, GTK_ICON_SIZE_BUTTON);
+ gtk_widget_ref (bubble_widget->bubble_widget_header_label);
+ gtk_widget_ref (bubble_widget->bubble_widget_body_label);
+ gtk_widget_ref (bubble_widget->icon);
+
gtk_label_set_line_wrap (GTK_LABEL (bubble_widget->bubble_widget_header_label), TRUE);
- gtk_label_set_line_wrap (GTK_LABEL (bubble_widget->bubble_widget_body_label), TRUE);
gtk_misc_set_alignment (GTK_MISC (bubble_widget->bubble_widget_header_label), 0.0, 0.0);
- gtk_misc_set_alignment (GTK_MISC (bubble_widget->bubble_widget_body_label), 0.0, 0.0);
gtk_misc_set_alignment (GTK_MISC (bubble_widget->icon), 0.0, 0.0);
gtk_widget_show (bubble_widget->icon);
gtk_widget_show (bubble_widget->bubble_widget_header_label);
gtk_widget_show (bubble_widget->bubble_widget_body_label);
- bubble_widget->main_hbox = gtk_hbox_new (FALSE, 10);
-
- vbox = gtk_vbox_new (FALSE, 5);
- hbox = gtk_hbox_new (FALSE, 5);
- gtk_box_pack_start (GTK_BOX (hbox), bubble_widget->icon, FALSE, FALSE, 0);
- gtk_container_add (GTK_CONTAINER (vbox), bubble_widget->bubble_widget_header_label);
- gtk_container_add (GTK_CONTAINER (vbox), bubble_widget->bubble_widget_body_label);
- gtk_container_add (GTK_CONTAINER (hbox), vbox);
- gtk_container_add (GTK_CONTAINER (bubble_widget), hbox);
+ bubble_widget->table = gtk_table_new (2, 2, FALSE);
+ gtk_table_set_col_spacings (bubble_widget->table, 5);
+ gtk_table_set_row_spacings (bubble_widget->table, 5);
+
+ gtk_table_attach (GTK_TABLE (bubble_widget->table),
+ bubble_widget->icon,
+ 0, 1, 1, 2,
+ GTK_FILL, GTK_FILL,
+ 0, 0);
+ gtk_table_attach (GTK_TABLE (bubble_widget->table),
+ bubble_widget->bubble_widget_header_label,
+ 1, 2, 0, 1,
+ GTK_FILL, GTK_FILL,
+ 0, 0);
+
+ gtk_table_attach (GTK_TABLE (bubble_widget->table),
+ bubble_widget->bubble_widget_body_label,
+ 1, 2, 1, 2,
+ GTK_FILL, GTK_FILL,
+ 0, 0);
+
+ gtk_container_add (GTK_CONTAINER (bubble_widget), bubble_widget->table);
+
+ bubble_widget->body_layout = pango_layout_new (
+ gtk_widget_get_pango_context (
+ GTK_WIDGET (bubble_widget)));
+
+ g_signal_connect (bubble_widget, "style-set",
+ G_CALLBACK (egg_notification_bubble_widget_context_changed_handler),
+ NULL);
+
+ g_signal_connect (bubble_widget, "direction-changed",
+ G_CALLBACK (egg_notification_bubble_widget_context_changed_handler),
+ NULL);
+
g_signal_connect_after (bubble_widget, "event-after",
G_CALLBACK (egg_notification_bubble_widget_event_handler),
bubble_widget);
+ g_signal_connect (bubble_widget->bubble_widget_body_label, "expose-event",
+ G_CALLBACK (egg_notification_bubble_widget_body_label_expose_handler),
+ bubble_widget);
}
static void
+_layout_window (EggNotificationBubbleWidget *bubble_widget,
+ int alignment)
+{
+
+ gtk_container_remove (GTK_CONTAINER (bubble_widget->table),
+ bubble_widget->icon);
+
+ gtk_container_remove (GTK_CONTAINER (bubble_widget->table),
+ bubble_widget->bubble_widget_header_label);
+
+ gtk_container_remove (GTK_CONTAINER (bubble_widget->table),
+ bubble_widget->bubble_widget_body_label);
+
+ if (alignment == TRIANGLE_LEFT)
+ {
+ gtk_table_attach (GTK_TABLE (bubble_widget->table),
+ bubble_widget->icon,
+ 0, 1, 1, 2,
+ GTK_FILL, GTK_FILL,
+ 0, 0);
+
+ gtk_table_attach (GTK_TABLE (bubble_widget->table),
+ bubble_widget->bubble_widget_header_label,
+ 1, 2, 0, 1,
+ GTK_FILL, GTK_FILL,
+ 0, 0);
+
+ gtk_table_attach (GTK_TABLE (bubble_widget->table),
+ bubble_widget->bubble_widget_body_label,
+ 1, 2, 1, 2,
+ GTK_FILL, GTK_FILL,
+ 0, 0);
+ }
+ else
+ {
+ gtk_table_attach (GTK_TABLE (bubble_widget->table),
+ bubble_widget->icon,
+ 1, 2, 1, 2,
+ GTK_FILL, GTK_FILL,
+ 0, 0);
+
+ gtk_table_attach (GTK_TABLE (bubble_widget->table),
+ bubble_widget->bubble_widget_header_label,
+ 0, 1, 0, 1,
+ GTK_FILL, GTK_FILL,
+ 0, 0);
+
+ gtk_table_attach (GTK_TABLE (bubble_widget->table),
+ bubble_widget->bubble_widget_body_label,
+ 0, 1, 1, 2,
+ GTK_FILL, GTK_FILL,
+ 0, 0);
+
+ }
+}
+
+static void
_destroy_pixmap_data_func (guchar *pixels,
gpointer data)
{
@@ -215,6 +374,32 @@
gdk_pixbuf_unref (pixbuf);
}
+static void
+_calculate_pango_layout_from_aspect (PangoLayout *layout,
+ const char *text,
+ double factor)
+{
+ gint len;
+ gint w, h;
+ double x;
+
+ len = strlen (text);
+ pango_layout_set_width(layout, -1);
+ pango_layout_set_text (layout, text, len);
+
+ pango_layout_get_pixel_size (layout, &w, &h);
+
+ if (w > TEXT_WIDTH_THRESHOLD)
+ {
+ pango_layout_get_size (layout, &w, &h);
+
+ x = sqrt (factor * w / h);
+ w = round (w / x);
+
+ pango_layout_set_width(layout, w);
+ }
+}
+
void
egg_notification_bubble_widget_set (EggNotificationBubbleWidget *bubble_widget,
const gchar *bubble_widget_header_text,
@@ -223,7 +408,7 @@
{
gchar *markupquoted;
gchar *markuptext;
- gchar *paddedtext;
+ gint w, h;
g_return_if_fail (EGG_IS_NOTIFICATION_BUBBLE_WIDGET (bubble_widget));
@@ -246,321 +431,451 @@
}
markupquoted = g_markup_escape_text (bubble_widget->bubble_widget_header_text, -1);
- markuptext = g_strdup_printf ("<b>%s</b>", markupquoted);
+ markuptext = g_strdup_printf ("<span size=\"larger\" weight=\"ultrabold\">%s</span>", markupquoted);
gtk_label_set_markup (GTK_LABEL (bubble_widget->bubble_widget_header_label), markuptext);
g_free (markuptext);
g_free (markupquoted);
- paddedtext = g_strdup_printf (" %s", bubble_widget->bubble_widget_body_text);
- gtk_label_set_text (GTK_LABEL (bubble_widget->bubble_widget_body_label), paddedtext);
- g_free (paddedtext);
+ _calculate_pango_layout_from_aspect (bubble_widget->body_layout,
+ bubble_widget->bubble_widget_body_text,
+ 0.25);
+
+ pango_layout_get_pixel_size (bubble_widget->body_layout, &w, &h);
+ gtk_widget_set_size_request (bubble_widget->bubble_widget_body_label, w, h);
+
+
}
void
egg_notification_bubble_widget_set_pos (EggNotificationBubbleWidget *bubble_widget,
gint x, gint y)
{
+ GdkScreen *screen;
+ gint monitor_num;
+ GdkRectangle monitor;
+
bubble_widget->x = x;
bubble_widget->y = y;
+
+ screen = gtk_window_get_screen (GTK_WINDOW(bubble_widget));
+ monitor_num = gdk_screen_get_monitor_at_point (screen, x, y);
+ gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+
+ gtk_window_move (GTK_WINDOW (bubble_widget), x, y);
+
+ if (x < (monitor.x + monitor.width) / 2)
+ _layout_window (bubble_widget, TRIANGLE_LEFT);
+ else
+ _layout_window (bubble_widget, TRIANGLE_RIGHT);
}
-static gboolean
-egg_notification_bubble_widget_expose (GtkWidget *widget, GdkEventExpose *event)
+static void
+egg_notification_bubble_widget_realize (GtkWidget *widget)
{
- GtkRequisition req;
GtkWidgetClass *widget_parent_class;
- gtk_widget_size_request (widget, &req);
- gtk_paint_flat_box (widget->style, widget->window,
- GTK_STATE_NORMAL, GTK_SHADOW_OUT,
- NULL, widget, "notification",
- 0, 0, req.width, req.height);
+ widget_parent_class = (GtkWidgetClass *)parent_class;
+ if (widget_parent_class->realize)
+ widget_parent_class->realize (widget);
draw_bubble_widget (EGG_NOTIFICATION_BUBBLE_WIDGET(widget));
-
- widget_parent_class = (GtkWidgetClass *)parent_class;
- if (widget_parent_class->expose_event)
- widget_parent_class->expose_event (widget, event);
-
- return FALSE;
}
static void
-subtract_rectangle (GdkRegion *region, GdkRectangle *rectangle)
+egg_notification_bubble_widget_screen_changed (GtkWidget *widget,
+ GdkScreen *old_screen)
{
- GdkRegion *temp_region;
+ GtkWidgetClass *widget_parent_class;
+ EggNotificationBubbleWidget *bw;
+ GdkScreen *screen;
+ GdkColormap *colormap;
+ gboolean can_composite;
+
+ bw = EGG_NOTIFICATION_BUBBLE_WIDGET (widget);
- temp_region = gdk_region_rectangle (rectangle);
- gdk_region_subtract (region, temp_region);
- gdk_region_destroy (temp_region);
-}
+ widget_parent_class = (GtkWidgetClass *)parent_class;
+ if (widget_parent_class->screen_changed)
+ widget_parent_class->screen_changed (widget, old_screen);
-static GdkRegion *
-add_bevels_to_rectangle (GdkRectangle *rectangle, cairo_t *cairo_context, int orient, int orient_triangle)
-{
- GdkRectangle temp_rect;
- GdkRegion *region = gdk_region_rectangle (rectangle);
+ can_composite = TRUE;
- /* Top left */
- if (!(orient == ORIENT_TOP && orient_triangle == TRIANGLE_LEFT))
+ screen = gtk_widget_get_screen (widget);
+ colormap = gdk_screen_get_rgba_colormap (screen);
+
+ if (!colormap)
{
- temp_rect.width = 5;
- temp_rect.height = 1;
- temp_rect.x = rectangle->x;
- temp_rect.y = rectangle->y;
- subtract_rectangle (region, &temp_rect);
+ colormap = gdk_screen_get_rgb_colormap (screen);
+ can_composite = FALSE;
+ }
+
+ gtk_widget_set_colormap (widget, colormap);
+
+ bw->can_composite = can_composite;
+}
- temp_rect.y += 1;
- temp_rect.width -= 2;
- subtract_rectangle (region, &temp_rect);
- temp_rect.y += 1;
- temp_rect.width -= 1;
- subtract_rectangle (region, &temp_rect);
+static gboolean
+egg_notification_bubble_widget_body_label_expose_handler (GtkWidget *widget,
+ GdkEventExpose *event,
+ EggNotificationBubbleWidget *bw)
+{
+ cairo_t *cr;
+ cr = gdk_cairo_create (GTK_WIDGET(bw)->window);
- temp_rect.y += 1;
- temp_rect.width -= 1;
- temp_rect.height = 2;
- subtract_rectangle (region, &temp_rect);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
- temp_rect.x = rectangle->x;
- temp_rect.y = rectangle->y;
+ cairo_set_source_rgba (cr, bw->body_text_color.red,
+ bw->body_text_color.green,
+ bw->body_text_color.blue,
+ 0.60);
+ cairo_move_to (cr, event->area.x, event->area.y);
- cairo_move_to (cairo_context, temp_rect.x + 3, temp_rect.y + 1.5);
- cairo_line_to (cairo_context, temp_rect.x + 5, temp_rect.y + 1.5);
-
- cairo_move_to (cairo_context, temp_rect.x + 2, temp_rect.y + 2.5);
- cairo_line_to (cairo_context, temp_rect.x + 3, temp_rect.y + 2.5);
+ pango_cairo_layout_path (cr, bw->body_layout);
- cairo_move_to (cairo_context, temp_rect.x + 1, temp_rect.y + 3.5);
- cairo_line_to (cairo_context, temp_rect.x + 2, temp_rect.y + 3.5);
+ cairo_fill (cr);
+ cairo_destroy (cr);
+}
- cairo_move_to (cairo_context, temp_rect.x + 1, temp_rect.y + 4.5);
- cairo_line_to (cairo_context, temp_rect.x + 2, temp_rect.y + 4.5);
-
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_MEDIUM);
- cairo_stroke (cairo_context);
-
- cairo_move_to (cairo_context, temp_rect.x + 3, temp_rect.y + 2.5);
- cairo_line_to (cairo_context, temp_rect.x + 5, temp_rect.y + 2.5);
+static gboolean
+egg_notification_bubble_widget_expose (GtkWidget *widget, GdkEventExpose *event)
+{
+ GtkWidgetClass *widget_parent_class;
+ EggNotificationBubbleWidget *bw;
- cairo_move_to (cairo_context, temp_rect.x + 2, temp_rect.y + 3.5);
- cairo_line_to (cairo_context, temp_rect.x + 3, temp_rect.y + 3.5);
-
- cairo_move_to (cairo_context, temp_rect.x + 2, temp_rect.y + 4.5);
- cairo_line_to (cairo_context, temp_rect.x + 3, temp_rect.y + 4.5);
-
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_LIGHT);
- cairo_stroke (cairo_context);
- }
+ bw = EGG_NOTIFICATION_BUBBLE_WIDGET (widget);
- /* Top right */
- if (!(orient == ORIENT_TOP && orient_triangle == TRIANGLE_RIGHT))
- {
- temp_rect.width = 5;
- temp_rect.height = 1;
-
- temp_rect.x = (rectangle->x + rectangle->width) - temp_rect.width;
- temp_rect.y = rectangle->y;
- subtract_rectangle (region, &temp_rect);
+ draw_bubble_widget (bw);
- temp_rect.y += 1;
- temp_rect.x += 2;
- subtract_rectangle (region, &temp_rect);
+ widget_parent_class = (GtkWidgetClass *)parent_class;
+ if (widget_parent_class->expose_event)
+ widget_parent_class->expose_event (widget, event);
+
+ return TRUE;
+}
- temp_rect.y += 1;
- temp_rect.x += 1;
- subtract_rectangle (region, &temp_rect);
+static GdkPoint
+_stencil_bubble_top_right (cairo_t *cr,
+ GdkRectangle *rect,
+ int pos_x, int pos_y)
+{
+ GdkPoint triangle[3];
+ double d, p1x, p2x, p3x, pdx, pvx, p1y, p2y, p3y, pdy, pvy;
- temp_rect.y += 1;
- temp_rect.x += 1;
- temp_rect.height = 2;
- subtract_rectangle (region, &temp_rect);
+ triangle[2].x = rect->x + rect->width - TRIANGLE_START;
+ triangle[2].y = rect->y;
- temp_rect.x = rectangle->x + rectangle->width;
- temp_rect.y = rectangle->y;
+ triangle[0].x = triangle[2].x - TRIANGLE_WIDTH;
+ triangle[0].y = rect->y;
+ triangle[1].x = (triangle[2].x - triangle[0].x) / 2 + triangle[0].x;
+ triangle[1].y = rect->y - BORDER_SIZE + 5;
- cairo_move_to (cairo_context, temp_rect.x - 3, temp_rect.y + 1.5);
- cairo_line_to (cairo_context, temp_rect.x - 5, temp_rect.y + 1.5);
-
- cairo_move_to (cairo_context, temp_rect.x - 2, temp_rect.y + 2.5);
- cairo_line_to (cairo_context, temp_rect.x - 3, temp_rect.y + 2.5);
+#if 0
+ if (triangle[1].x + (BORDER_SIZE - 5) < pos_x)
+ triangle[1].x = pos_x - (BORDER_SIZE + 5);
+#endif
- cairo_move_to (cairo_context, temp_rect.x - 1, temp_rect.y + 3.5);
- cairo_line_to (cairo_context, temp_rect.x - 2, temp_rect.y + 3.5);
+ cairo_move_to (cr, triangle[0].x, triangle[0].y);
+ cairo_line_to (cr, triangle[1].x, triangle[1].y);
+ cairo_line_to (cr, triangle[2].x, triangle[2].y);
- cairo_move_to (cairo_context, temp_rect.x - 1, temp_rect.y + 4.5);
- cairo_line_to (cairo_context, temp_rect.x - 2, temp_rect.y + 4.5);
-
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_MEDIUM);
- cairo_stroke (cairo_context);
-
- cairo_move_to (cairo_context, temp_rect.x - 3, temp_rect.y + 2.5);
- cairo_line_to (cairo_context, temp_rect.x - 5, temp_rect.y + 2.5);
+ cairo_line_to (cr, rect->x + rect->width - CURVE_LENGTH, rect->y);
+ cairo_curve_to (cr,
+ rect->x + rect->width,
+ rect->y,
+ rect->x + rect->width,
+ rect->y,
+ rect->x + rect->width,
+ rect->y + CURVE_LENGTH);
- cairo_move_to (cairo_context, temp_rect.x - 2, temp_rect.y + 3.5);
- cairo_line_to (cairo_context, temp_rect.x - 3, temp_rect.y + 3.5);
-
- cairo_move_to (cairo_context, temp_rect.x - 2, temp_rect.y + 4.5);
- cairo_line_to (cairo_context, temp_rect.x - 3, temp_rect.y + 4.5);
-
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_LIGHT);
- cairo_stroke (cairo_context);
+ cairo_line_to (cr, rect->x + rect->width, rect->y + rect->height - CURVE_LENGTH);
- }
+ p1x = rect->x + rect->width;
+ p2x = rect->x;
+ p1y = rect->y + rect->height + (BORDER_SIZE - 5);
+ p2y = rect->y + rect->height;
+
+ pdx = p1x - p2x;
+ pdy = p1y - p2y;
+
+ d = sqrt (pdx * pdx +
+ pdy * pdy);
- /* Bottom right */
- if (!(orient == ORIENT_BOTTOM && orient_triangle == TRIANGLE_RIGHT))
+ pvx = (pdx / d);
+ pvy = (pdy / d);
+
+ p3x = p1x - CURVE_LENGTH * pvx;
+ p3y = p1y - CURVE_LENGTH * pvy;
+
+ cairo_curve_to (cr,
+ p1x,
+ p1y,
+ p1x,
+ p1y,
+ p3x,
+ p3y);
+
+ p3x = p2x + CURVE_LENGTH * pvx;
+ p3y = p2y + CURVE_LENGTH * pvy;
+
+ cairo_line_to (cr, p3x, p3y);
+
+ cairo_curve_to (cr,
+ p2x,
+ p2y,
+ p2x,
+ p2y,
+ p2x,
+ p2y - CURVE_LENGTH);
+
+ cairo_line_to (cr, rect->x, rect->y + CURVE_LENGTH);
+ p1x = rect->x + CURVE_LENGTH;
+ if (p1x < triangle[0].x)
{
- temp_rect.width = 5;
- temp_rect.height = 1;
+ cairo_curve_to (cr,
+ rect->x,
+ rect->y,
+ rect->x,
+ rect->y,
+ p1x,
+ rect->y);
+ cairo_line_to (cr, triangle[0].x, rect->y);
+ }
+ else
+ {
+ cairo_curve_to (cr,
+ rect->x,
+ rect->y,
+ rect->x,
+ rect->y,
+ triangle[0].x,
+ rect->y);
+ }
- temp_rect.x = (rectangle->x + rectangle->width) - temp_rect.width;
- temp_rect.y = (rectangle->y + rectangle->height) - temp_rect.height;
- subtract_rectangle (region, &temp_rect);
+ return triangle[1];
+}
- temp_rect.y -= 1;
- temp_rect.x += 2;
- subtract_rectangle (region, &temp_rect);
+static GdkPoint
+_stencil_bubble_top_left (cairo_t *cr,
+ GdkRectangle *rect,
+ int pos_x, int pos_y)
+{
+ GdkPoint triangle[3];
+ double d, p1x, p2x, p3x, pdx, pvx, p1y, p2y, p3y, pdy, pvy;
- temp_rect.y -= 1;
- temp_rect.x += 1;
- subtract_rectangle (region, &temp_rect);
+ triangle[0].x = rect->x + TRIANGLE_START;
+ triangle[0].y = rect->y;
+ triangle[2].x = triangle[0].x + TRIANGLE_WIDTH;
+ triangle[2].y = rect->y;
+ triangle[1].x = (triangle[2].x - triangle[0].x) / 2 + triangle[0].x;
+ triangle[1].y = rect->y - BORDER_SIZE + 5;
- temp_rect.y -= 2;
- temp_rect.x += 1;
- temp_rect.height = 2;
- subtract_rectangle (region, &temp_rect);
+ //if (triangle[1].x - (BORDER_SIZE - 5 ) > pos_x)
+ // triangle[1].x = pos_x + (BORDER_SIZE + 5);
- temp_rect.x = rectangle->x + rectangle->width;
- temp_rect.y = rectangle->y + rectangle->height;
+ cairo_move_to (cr, triangle[0].x, triangle[0].y);
+ cairo_line_to (cr, triangle[1].x, triangle[1].y);
+ cairo_line_to (cr, triangle[2].x, triangle[2].y);
- cairo_move_to (cairo_context, temp_rect.x - 3, temp_rect.y - 1.5);
- cairo_line_to (cairo_context, temp_rect.x - 5, temp_rect.y - 1.5);
-
- cairo_move_to (cairo_context, temp_rect.x - 2, temp_rect.y - 2.5);
- cairo_line_to (cairo_context, temp_rect.x - 3, temp_rect.y - 2.5);
+ cairo_line_to (cr, rect->x + rect->width - CURVE_LENGTH, rect->y);
+ cairo_curve_to (cr,
+ rect->x + rect->width,
+ rect->y,
+ rect->x + rect->width,
+ rect->y,
+ rect->x + rect->width,
+ rect->y + CURVE_LENGTH);
- cairo_move_to (cairo_context, temp_rect.x - 1, temp_rect.y - 3.5);
- cairo_line_to (cairo_context, temp_rect.x - 2, temp_rect.y - 3.5);
+ cairo_line_to (cr, rect->x + rect->width, rect->y + rect->height - CURVE_LENGTH);
- cairo_move_to (cairo_context, temp_rect.x - 1, temp_rect.y - 4.5);
- cairo_line_to (cairo_context, temp_rect.x - 2, temp_rect.y - 4.5);
-
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_MEDIUM);
- cairo_stroke (cairo_context);
-
- cairo_move_to (cairo_context, temp_rect.x - 3, temp_rect.y - 2.5);
- cairo_line_to (cairo_context, temp_rect.x - 5, temp_rect.y - 2.5);
+ p1x = rect->x + rect->width;
+ p2x = rect->x;
+ p1y = rect->y + rect->height;
+ p2y = rect->y + rect->height + (BORDER_SIZE - 5);
+
+ pdx = p1x - p2x;
+ pdy = p1y - p2y;
+
+ d = sqrt (pdx * pdx +
+ pdy * pdy);
- cairo_move_to (cairo_context, temp_rect.x - 2, temp_rect.y - 3.5);
- cairo_line_to (cairo_context, temp_rect.x - 3, temp_rect.y - 3.5);
-
- cairo_move_to (cairo_context, temp_rect.x - 2, temp_rect.y - 4.5);
- cairo_line_to (cairo_context, temp_rect.x - 3, temp_rect.y - 4.5);
-
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_LIGHT);
- cairo_stroke (cairo_context);
+ pvx = (pdx / d);
+ pvy = (pdy / d);
+
+ p3x = p1x - CURVE_LENGTH * pvx;
+ p3y = p1y - CURVE_LENGTH * pvy;
- }
+ cairo_curve_to (cr,
+ p1x,
+ p1y,
+ p1x,
+ p1y,
+ p3x,
+ p3y);
- /* Bottom left */
- if (!(orient == ORIENT_BOTTOM && orient_triangle == TRIANGLE_LEFT))
- {
- temp_rect.width = 5;
- temp_rect.height = 1;
+ p3x = p2x + CURVE_LENGTH * pvx;
+ p3y = p2y + CURVE_LENGTH * pvy;
- temp_rect.x = rectangle->x;
- temp_rect.y = rectangle->y + rectangle->height - 1;
- subtract_rectangle (region, &temp_rect);
+ cairo_line_to (cr, p3x, p3y);
- temp_rect.y -= 1;
- temp_rect.width -= 2;
- subtract_rectangle (region, &temp_rect);
+ cairo_curve_to (cr,
+ p2x,
+ p2y,
+ p2x,
+ p2y,
+ p2x,
+ p2y - CURVE_LENGTH);
- temp_rect.y -= 1;
- temp_rect.width -= 1;
- subtract_rectangle (region, &temp_rect);
+ cairo_line_to (cr, rect->x, rect->y + CURVE_LENGTH);
+ p1x = rect->x + CURVE_LENGTH;
+ if (p1x < triangle[0].x)
+ {
+ cairo_curve_to (cr,
+ rect->x,
+ rect->y,
+ rect->x,
+ rect->y,
+ p1x,
+ rect->y);
+ cairo_line_to (cr, triangle[0].x, rect->y);
+ }
+ else
+ {
+ cairo_curve_to (cr,
+ rect->x,
+ rect->y,
+ rect->x,
+ rect->y,
+ triangle[0].x,
+ rect->y);
+ }
- temp_rect.y -= 2;
- temp_rect.width -= 1;
- temp_rect.height = 2;
- subtract_rectangle (region, &temp_rect);
+ return triangle[1];
+}
- temp_rect.x = rectangle->x;
- temp_rect.y = rectangle->y + rectangle->height;
+static GdkPoint
+_stencil_bubble_bottom_right (cairo_t *cr,
+ GdkRectangle *rect,
+ int pos_x, int pos_y)
+{
- cairo_move_to (cairo_context, temp_rect.x + 3, temp_rect.y - 1.5);
- cairo_line_to (cairo_context, temp_rect.x + 5, temp_rect.y - 1.5);
-
- cairo_move_to (cairo_context, temp_rect.x + 2, temp_rect.y - 2.5);
- cairo_line_to (cairo_context, temp_rect.x + 3, temp_rect.y - 2.5);
+}
- cairo_move_to (cairo_context, temp_rect.x + 1, temp_rect.y - 3.5);
- cairo_line_to (cairo_context, temp_rect.x + 2, temp_rect.y - 3.5);
+static GdkPoint
+_stencil_bubble_bottom_left (cairo_t *cr,
+ GdkRectangle *rect,
+ int pos_x, int pos_y)
+{
- cairo_move_to (cairo_context, temp_rect.x + 1, temp_rect.y - 4.5);
- cairo_line_to (cairo_context, temp_rect.x + 2, temp_rect.y - 4.5);
-
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_MEDIUM);
- cairo_stroke (cairo_context);
-
- cairo_move_to (cairo_context, temp_rect.x + 3, temp_rect.y - 2.5);
- cairo_line_to (cairo_context, temp_rect.x + 5, temp_rect.y - 2.5);
+}
- cairo_move_to (cairo_context, temp_rect.x + 2, temp_rect.y - 3.5);
- cairo_line_to (cairo_context, temp_rect.x + 3, temp_rect.y - 3.5);
-
- cairo_move_to (cairo_context, temp_rect.x + 2, temp_rect.y - 4.5);
- cairo_line_to (cairo_context, temp_rect.x + 3, temp_rect.y - 4.5);
-
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_LIGHT);
- cairo_stroke (cairo_context);
- }
+static GdkColor
+_blend_colors (GdkColor color1, GdkColor color2, gdouble factor)
+{
+ GdkColor result;
+ gint channel_intensity;
+
+ channel_intensity = color1.red * factor + color2.red * (1 - factor);
+ result.red = CLAMP (channel_intensity, 0, 65535);
+
+ channel_intensity = color1.green * factor + color2.green * (1 - factor);
+ result.green = CLAMP (channel_intensity, 0, 65535);
- return region;
+ channel_intensity = color1.blue * factor + color2.blue * (1 - factor);
+ result.blue = CLAMP (channel_intensity, 0, 65535);
+
+ return result;
}
static void
+_calculate_colors_from_style (EggNotificationBubbleWidget *bw)
+{
+ GtkStyle *style;
+ GtkWidget *widget;
+ GdkColor header_text_color;
+ GdkColor body_text_color;
+ GdkColor bg_end_gradient;
+ GdkColor border_color;
+ GdkColor bg_start_gradient;
+
+ widget = GTK_WIDGET (bw);
+
+ gtk_widget_ensure_style (widget);
+ style = widget->style;
+
+ header_text_color = style->text[GTK_STATE_NORMAL];
+ body_text_color = style->text[GTK_STATE_NORMAL];
+ bg_start_gradient = style->base[GTK_STATE_NORMAL];
+ bg_end_gradient = style->bg[GTK_STATE_SELECTED];
+ border_color = style->mid[GTK_STATE_NORMAL];
+
+ bg_end_gradient = _blend_colors (bg_start_gradient, bg_end_gradient, 0.25);
+
+ bw->header_text_color = header_text_color;
+ bw->body_text_color = body_text_color;
+ bw->bg_start_gradient = bg_start_gradient;
+ bw->bg_end_gradient = bg_end_gradient;
+ bw->border_color = border_color;
+}
+
+
+static void
draw_bubble_widget (EggNotificationBubbleWidget *bubble_widget)
{
GtkRequisition requisition;
- GtkStyle *style;
gint x, y, w, h;
GdkScreen *screen;
gint monitor_num;
GdkRectangle monitor;
- GdkPoint triangle_points[3];
GdkRectangle rectangle;
- GdkRegion *region;
- GdkRegion *triangle_region;
-
+ cairo_pattern_t *pat;
+ GdkPixmap *mask;
+ GdkPoint arrow_pos;
+ PangoAttribute *body_text_color;
+ PangoAttrList *attrlist;
+
int orient;
int orient_triangle;
guint rectangle_border;
GtkWidget *widget;
cairo_t *cairo_context;
+ cairo_t *mask_cr;
+ gboolean can_composite;
widget = GTK_WIDGET(bubble_widget);
cairo_context = gdk_cairo_create (widget->window);
+ can_composite = bubble_widget->can_composite;
+
+ _calculate_colors_from_style (bubble_widget);
- gtk_widget_ensure_style (widget);
- style = widget->style;
-
+ x = bubble_widget->x;
+ y = bubble_widget->y;
+
+ screen = gtk_window_get_screen (GTK_WINDOW(widget));
+ monitor_num = gdk_screen_get_monitor_at_window (screen, widget->window);
+ gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+
+ if (x < (monitor.x + monitor.width) / 2)
+ {
+ orient_triangle = TRIANGLE_LEFT;
+ }
+ else
+ {
+ orient_triangle = TRIANGLE_RIGHT;
+ }
+
gtk_widget_size_request (widget, &requisition);
w = requisition.width;
h = requisition.height;
- x = bubble_widget->x;
- y = bubble_widget->y;
+ if (!can_composite)
+ {
+ mask = gdk_pixmap_new (NULL, w, h, 1);
+ mask_cr = gdk_cairo_create ((GdkDrawable *) mask);
+ }
orient = ORIENT_TOP;
- screen = gtk_window_get_screen (GTK_WINDOW(widget));
- monitor_num = gdk_screen_get_monitor_at_window (screen, widget->window);
- gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
-
if ((y + h) > monitor.y + monitor.height)
{
y -= (h + 5);
@@ -576,232 +891,131 @@
rectangle.width = w - (rectangle_border * 2);
rectangle.height = h - (rectangle_border * 2);
- if (x < (monitor.x + monitor.width) / 2)
+ if (orient == ORIENT_TOP)
{
- orient_triangle = TRIANGLE_LEFT;
- triangle_points[0].x = rectangle.x;
+ if (orient_triangle == TRIANGLE_LEFT)
+ {
+ arrow_pos =
+ _stencil_bubble_top_left (cairo_context, &rectangle, x, y);
+ if (!can_composite)
+ _stencil_bubble_top_left (mask_cr, &rectangle, x, y);
+ }
+ else
+ {
+ arrow_pos =
+ _stencil_bubble_top_right (cairo_context, &rectangle, x, y);
+ if (!can_composite)
+ _stencil_bubble_top_right (mask_cr, &rectangle, x, y);
+ }
}
else
- {
- orient_triangle = TRIANGLE_RIGHT;
- triangle_points[0].x = rectangle.x + rectangle.width - 10;
- }
-
- cairo_set_line_width (cairo_context, 1.0);
- region = add_bevels_to_rectangle (&rectangle, cairo_context, orient, orient_triangle);
-
- triangle_points[0].y = orient == ORIENT_TOP ? rectangle.y : rectangle.y + rectangle.height;
- triangle_points[1].x = triangle_points[0].x + 10;
- triangle_points[1].y = triangle_points[0].y;
- triangle_points[2].y = orient == ORIENT_TOP ? 0 : h;
-
- if (orient_triangle == TRIANGLE_LEFT)
- triangle_points[2].x = triangle_points[0].x;
- else
- triangle_points[2].x = triangle_points[1].x;
-
- triangle_region = gdk_region_polygon (triangle_points, 3, GDK_WINDING_RULE);
- gdk_region_union (region, triangle_region);
- gdk_region_destroy (triangle_region);
-
- gdk_window_shape_combine_region (widget->window, region, 0, 0);
-
- if (orient == ORIENT_TOP)
{
- /* top from triangle */
if (orient_triangle == TRIANGLE_LEFT)
{
- cairo_move_to (cairo_context, triangle_points[0].x + 0.5, triangle_points[0].y);
- cairo_line_to (cairo_context, triangle_points[2].x + 0.5, triangle_points[2].y);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_MEDIUM);
-
- cairo_move_to (cairo_context, triangle_points[2].x - 0.5, triangle_points[2].y + 0.5);
- cairo_line_to (cairo_context, triangle_points[1].x - 0.5, triangle_points[1].y + 0.5);
- cairo_stroke (cairo_context);
-
- cairo_move_to (cairo_context, triangle_points[0].x + 1.5, triangle_points[0].y + 5);
- cairo_line_to (cairo_context, triangle_points[2].x + 1.5, triangle_points[2].y);
- cairo_line_to (cairo_context, triangle_points[1].x - 1.5, triangle_points[1].y + 1.5);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_LIGHT);
- cairo_stroke (cairo_context);
-
- cairo_move_to (cairo_context, triangle_points[1].x, triangle_points[1].y + 0.5);
- cairo_line_to (cairo_context, rectangle.x + rectangle.width, rectangle.y + 0.5);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_MEDIUM);
- cairo_stroke (cairo_context);
-
- cairo_move_to (cairo_context, triangle_points[1].x + 1, triangle_points[1].y + 1.5);
- cairo_line_to (cairo_context, rectangle.x + rectangle.width - 5, rectangle.y + 1.5);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_LIGHT);
- cairo_stroke (cairo_context);
+ arrow_pos =
+ _stencil_bubble_bottom_left (cairo_context, &rectangle, x, y);
+ if (!can_composite)
+ _stencil_bubble_bottom_left (mask_cr, &rectangle, x, y);
}
-
- /* right */
- cairo_move_to (cairo_context, rectangle.x + rectangle.width - 0.5, rectangle.y + 1.5);
- cairo_line_to (cairo_context, rectangle.x + rectangle.width - 0.5 , rectangle.y + rectangle.height);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_DARK);
- cairo_stroke (cairo_context);
-
- cairo_move_to (cairo_context, rectangle.x + rectangle.width - 1.5, rectangle.y + 4.5);
- cairo_line_to (cairo_context, rectangle.x + rectangle.width - 1.5 , rectangle.y + rectangle.height - 4.5);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_LIGHT);
- cairo_stroke (cairo_context);
-
- /* bottom */
- cairo_move_to (cairo_context, rectangle.x + rectangle.width, rectangle.y + rectangle.height - 0.5);
- cairo_line_to (cairo_context, rectangle.x, rectangle.y + rectangle.height - 0.5);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_DARK);
- cairo_stroke (cairo_context);
-
- cairo_move_to (cairo_context, rectangle.x + rectangle.width - 5, rectangle.y + rectangle.height - 1.5);
- cairo_line_to (cairo_context, rectangle.x + 5, rectangle.y + rectangle.height - 1.5);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_LIGHT);
- cairo_stroke (cairo_context);
-
- /* left */
- cairo_move_to (cairo_context, rectangle.x + 0.5, rectangle.y + rectangle.height);
- cairo_line_to (cairo_context, rectangle.x + 0.5, rectangle.y);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_MEDIUM);
- cairo_stroke (cairo_context);
-
- cairo_move_to (cairo_context, rectangle.x + 1.5, rectangle.y + rectangle.height - 5);
- cairo_line_to (cairo_context, rectangle.x + 1.5, rectangle.y + 5);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_LIGHT);
- cairo_stroke (cairo_context);
-
- /* top back to triangle */
- if (orient_triangle == TRIANGLE_RIGHT)
+ else
{
-
- cairo_move_to (cairo_context, triangle_points[0].x - 0.5, triangle_points[0].y + 0.5);
- cairo_line_to (cairo_context, triangle_points[2].x - 0.5, triangle_points[2].y + 0.5);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_MEDIUM);
- cairo_stroke (cairo_context);
-
- cairo_move_to (cairo_context, triangle_points[2].x - 0.5, triangle_points[2].y);
- cairo_line_to (cairo_context, triangle_points[1].x - 0.5, triangle_points[1].y + 2);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_DARK);
- cairo_stroke (cairo_context);
-
- cairo_move_to (cairo_context, triangle_points[0].x + 1.5, triangle_points[0].y);
- cairo_line_to (cairo_context, triangle_points[2].x, triangle_points[2].y);
- cairo_move_to (cairo_context, triangle_points[1].x - 1.5, triangle_points[2].y);
- cairo_line_to (cairo_context, triangle_points[1].x - 1.5, triangle_points[1].y + 4.5);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_LIGHT);
- cairo_stroke (cairo_context);
-
- cairo_move_to (cairo_context, rectangle.x, rectangle.y + 0.5);
- cairo_line_to (cairo_context, triangle_points[0].x, triangle_points[0].y + 0.5);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_MEDIUM);
- cairo_stroke (cairo_context);
-
- cairo_move_to (cairo_context, rectangle.x + 5, rectangle.y + 1.5);
- cairo_line_to (cairo_context, triangle_points[0].x, triangle_points[0].y + 1.5);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_LIGHT);
- cairo_stroke (cairo_context);
-
+ arrow_pos =
+ _stencil_bubble_bottom_right (cairo_context, &rectangle, x, y);
+ if (!can_composite)
+ _stencil_bubble_bottom_right (mask_cr, &rectangle, x, y);
}
+ }
+ //cairo_set_source_rgba (cairo_context, 0.43, 0.49, 0.55, 1);
- }
+ if (can_composite)
+ cairo_set_source_rgba (cairo_context, 1, 1, 1, 0);
else
- {
- /* bottom from triangle */
- if (orient_triangle == TRIANGLE_LEFT)
- {
- cairo_move_to (cairo_context, triangle_points[0].x + 0.5, triangle_points[0].y);
- cairo_line_to (cairo_context, triangle_points[2].x + 0.5, triangle_points[2].y);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_MEDIUM);
- cairo_stroke (cairo_context);
+ cairo_set_source_rgba (cairo_context,
+ bubble_widget->border_color.red / 65535.0,
+ bubble_widget->border_color.green / 65535.0,
+ bubble_widget->border_color.blue / 65535.0, 1);
+
+ cairo_set_operator (cairo_context, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cairo_context);
- cairo_move_to (cairo_context, triangle_points[2].x, triangle_points[2].y);
- cairo_line_to (cairo_context, triangle_points[1].x, triangle_points[1].y);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_DARK);
- cairo_stroke (cairo_context);
+ cairo_set_operator (cairo_context, CAIRO_OPERATOR_OVER);
- cairo_move_to (cairo_context, triangle_points[0].x + 1.5, triangle_points[0].y);
- cairo_line_to (cairo_context, triangle_points[2].x + 1.5, triangle_points[2].y);
- cairo_line_to (cairo_context, triangle_points[1].x - 1.5, triangle_points[1].y + 1.5);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_LIGHT);
- cairo_stroke (cairo_context);
+#if 0
+ //create shadow
+ if (can_composite)
+ {
+ cairo_path_t *path;
+ cairo_pattern_t *blur;
- cairo_move_to (cairo_context, triangle_points[1].x, triangle_points[1].y - 0.5);
- cairo_line_to (cairo_context, rectangle.x + rectangle.width, rectangle.y + rectangle.height - 0.5);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_DARK);
- cairo_stroke (cairo_context);
+ path = cairo_copy_path_flat (cairo_context);
+ cairo_new_path (cairo_context);
- cairo_move_to (cairo_context, triangle_points[1].x, triangle_points[1].y - 1.5);
- cairo_line_to (cairo_context, rectangle.x + rectangle.width, rectangle.y + rectangle.height - 1.5);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_LIGHT);
- cairo_stroke (cairo_context);
- }
+ cairo_translate (cairo_context, 5, 5);
+ cairo_append_path (cairo_context, path);
+ blur = cairo_pattern_create_rgba (0, 0, 0, .75);
+ cairo_pattern_set_filter (blur, CAIRO_FILTER_GAUSSIAN);
- /* top */
- cairo_move_to (cairo_context, rectangle.x, rectangle.y + 0.5);
- cairo_line_to (cairo_context, rectangle.x + rectangle.width, rectangle.y + 0.5);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_MEDIUM);
- cairo_stroke (cairo_context);
+ cairo_set_source (cairo_context, blur);
+ cairo_fill (cairo_context);
+
+ cairo_identity_matrix (cairo_context);
+ cairo_append_path (cairo_context, path);
+
+ cairo_pattern_destroy (blur);
+ cairo_path_destroy (path);
+ }
- cairo_move_to (cairo_context, rectangle.x, rectangle.y + 1.5);
- cairo_line_to (cairo_context, rectangle.x + rectangle.width, rectangle.y + 1.5);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_LIGHT);
- cairo_stroke (cairo_context);
+#endif
- /* left */
- cairo_move_to (cairo_context, rectangle.x + 0.5, rectangle.y + rectangle.height);
- cairo_line_to (cairo_context, rectangle.x + 0.5, rectangle.y);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_MEDIUM);
- cairo_stroke (cairo_context);
+ pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, h);
+ //cairo_pattern_add_color_stop_rgba (pat, 1, 0.59, 0.76, 0.93, 1);
+ cairo_pattern_add_color_stop_rgba (pat, 0,
+ bubble_widget->bg_start_gradient.red /
+ 65535.0,
+ bubble_widget->bg_start_gradient.green /
+ 65535.0,
+ bubble_widget->bg_start_gradient.blue /
+ 65535.0, 1);
- cairo_move_to (cairo_context, rectangle.x + 1.5, rectangle.y + rectangle.height);
- cairo_line_to (cairo_context, rectangle.x + 1.5, rectangle.y);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_LIGHT);
- cairo_stroke (cairo_context);
+ cairo_pattern_add_color_stop_rgba (pat, 1,
+ bubble_widget->bg_end_gradient.red /
+ 65535.0,
+ bubble_widget->bg_end_gradient.green /
+ 65535.0,
+ bubble_widget->bg_end_gradient.blue /
+ 65535.0, 1);
- /* right */
- cairo_move_to (cairo_context, rectangle.x + rectangle.width - 0.5, rectangle.y + 1);
- cairo_line_to (cairo_context, rectangle.x + rectangle.width - 0.5 , rectangle.y + rectangle.height);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_DARK);
- cairo_stroke (cairo_context);
-
- cairo_move_to (cairo_context, rectangle.x + rectangle.width - 1.5, rectangle.y + 1);
- cairo_line_to (cairo_context, rectangle.x + rectangle.width - 1.5 , rectangle.y + rectangle.height);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_LIGHT);
- cairo_stroke (cairo_context);
+ cairo_set_source (cairo_context, pat);
+ cairo_fill_preserve (cairo_context);
+ cairo_pattern_destroy (pat);
+
+ cairo_set_line_width (cairo_context, 3.5);
+ cairo_set_source_rgba (cairo_context, 0.43, 0.49, 0.55, 1);
+ cairo_stroke (cairo_context);
- /* bottom to triangle */
- if (orient_triangle == TRIANGLE_RIGHT)
- {
- cairo_move_to (cairo_context, triangle_points[0].x + 0.5, triangle_points[0].y);
- cairo_line_to (cairo_context, triangle_points[2].x + 0.5, triangle_points[2].y);
-
- cairo_move_to (cairo_context, triangle_points[2].x - 0.5, triangle_points[2].y);
- cairo_line_to (cairo_context, triangle_points[1].x - 0.5, triangle_points[1].y);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_DARK);
- cairo_stroke (cairo_context);
+ if (!can_composite)
+ {
+ cairo_set_operator (mask_cr, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (mask_cr);
- cairo_move_to (cairo_context, triangle_points[0].x + 1.5, triangle_points[0].y);
- cairo_line_to (cairo_context, triangle_points[2].x - 1.5, triangle_points[2].y);
- cairo_line_to (cairo_context, triangle_points[1].x - 1.5, triangle_points[1].y);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_LIGHT);
- cairo_stroke (cairo_context);
-
- cairo_move_to (cairo_context, triangle_points[0].x, triangle_points[0].y - 0.5);
- cairo_line_to (cairo_context, rectangle.x, rectangle.y + rectangle.height - 0.5);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_DARK);
- cairo_stroke (cairo_context);
+ cairo_set_operator (mask_cr, CAIRO_OPERATOR_OVER);
+ cairo_set_line_width (mask_cr, 3.5);
+ cairo_set_source_rgba (mask_cr, 1, 1, 1, 1);
+ cairo_fill_preserve (mask_cr);
+ cairo_stroke (mask_cr);
- cairo_move_to (cairo_context, triangle_points[0].x, triangle_points[0].y - 1.5);
- cairo_line_to (cairo_context, rectangle.x, rectangle.y + rectangle.height - 1.5);
- cairo_set_source_rgba (cairo_context, 0.0, 0.0, 0.0, BEVEL_ALPHA_LIGHT);
- cairo_stroke (cairo_context);
- }
-
+ gdk_window_shape_combine_mask (widget->window,
+ (GdkBitmap *) mask,
+ 0,
+ 0);
+ gdk_pixmap_unref (mask);
+ cairo_destroy (mask_cr);
}
- region = add_bevels_to_rectangle (&rectangle, cairo_context, orient, orient_triangle);
-
- gtk_window_move (GTK_WINDOW (widget), x - triangle_points[2].x, y);
+ cairo_destroy (cairo_context);
+
+ gtk_window_move (GTK_WINDOW (widget), x - arrow_pos.x, y + 5);
bubble_widget->active = TRUE;
}
@@ -821,9 +1035,18 @@
EggNotificationBubbleWidget*
egg_notification_bubble_widget_new (void)
{
- return g_object_new (EGG_TYPE_NOTIFICATION_BUBBLE_WIDGET, "type", GTK_WINDOW_POPUP, NULL);
+ return g_object_new (EGG_TYPE_NOTIFICATION_BUBBLE_WIDGET,
+ "type", GTK_WINDOW_POPUP,
+ NULL);
}
+static void
+egg_notification_bubble_widget_context_changed_handler (EggNotificationBubbleWidget *bubble_widget)
+{
+ pango_layout_context_changed (bubble_widget->body_layout);
+}
+
+
static void
egg_notification_bubble_widget_event_handler (GtkWidget *widget,
GdkEvent *event,
Modified: trunk/notify-daemon-ng/src/eggnotificationbubblewidget.h
===================================================================
--- trunk/notify-daemon-ng/src/eggnotificationbubblewidget.h 2005-11-21 09:36:06 UTC (rev 2341)
+++ trunk/notify-daemon-ng/src/eggnotificationbubblewidget.h 2005-11-22 22:00:12 UTC (rev 2342)
@@ -44,11 +44,19 @@
GtkWidget *icon;
gboolean active;
- GtkWidget *main_hbox;
+ GtkWidget *table;
GtkWidget *bubble_widget_header_label;
GtkWidget *bubble_widget_body_label;
+ PangoLayout *body_layout;
gint x, y;
+ gboolean can_composite;
+
+ GdkColor header_text_color;
+ GdkColor body_text_color;
+ GdkColor bg_start_gradient;
+ GdkColor bg_end_gradient;
+ GdkColor border_color;
};
struct _EggNotificationBubbleWidgetClass
More information about the galago-commits
mailing list