forked from AuroraMiddleware/gtk
tooltip: add tooltip-radius and tooltip-alpha style properties
This allows themes to change the tooltip opacity and radius. Based on a downstream Fedora patch by Matthias Clasen. https://bugzilla.gnome.org/show_bug.cgi?id=683070
This commit is contained in:
parent
3d5cd6e055
commit
af26ec6a73
190
gtk/gtktooltip.c
190
gtk/gtktooltip.c
@ -97,6 +97,7 @@ static void gtk_tooltip_display_closed (GdkDisplay *display,
|
||||
GtkTooltip *tooltip);
|
||||
static void gtk_tooltip_set_last_window (GtkTooltip *tooltip,
|
||||
GdkWindow *window);
|
||||
static void update_shape (GtkTooltip *tooltip);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GtkTooltip, gtk_tooltip, G_TYPE_OBJECT);
|
||||
@ -111,6 +112,39 @@ gtk_tooltip_class_init (GtkTooltipClass *klass)
|
||||
object_class->dispose = gtk_tooltip_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
on_composited_changed (GtkWidget *window,
|
||||
GtkTooltip *tooltip)
|
||||
{
|
||||
update_shape (tooltip);
|
||||
}
|
||||
|
||||
static void
|
||||
on_screen_changed (GtkWidget *window,
|
||||
GdkScreen *previous,
|
||||
GtkTooltip *tooltip)
|
||||
{
|
||||
GdkScreen *screen;
|
||||
GdkColormap *cmap;
|
||||
|
||||
screen = gtk_widget_get_screen (window);
|
||||
|
||||
cmap = NULL;
|
||||
if (gdk_screen_is_composited (screen))
|
||||
cmap = gdk_screen_get_rgba_colormap (screen);
|
||||
if (cmap == NULL)
|
||||
cmap = gdk_screen_get_rgb_colormap (screen);
|
||||
|
||||
gtk_widget_set_colormap (window, cmap);
|
||||
}
|
||||
|
||||
static void
|
||||
on_realized (GtkWidget *window,
|
||||
GtkTooltip *tooltip)
|
||||
{
|
||||
update_shape (tooltip);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tooltip_init (GtkTooltip *tooltip)
|
||||
{
|
||||
@ -129,8 +163,12 @@ gtk_tooltip_init (GtkTooltip *tooltip)
|
||||
tooltip->last_window = NULL;
|
||||
|
||||
tooltip->window = g_object_ref (gtk_window_new (GTK_WINDOW_POPUP));
|
||||
|
||||
on_screen_changed (tooltip->window, NULL, tooltip);
|
||||
|
||||
gtk_window_set_type_hint (GTK_WINDOW (tooltip->window),
|
||||
GDK_WINDOW_TYPE_HINT_TOOLTIP);
|
||||
|
||||
gtk_widget_set_app_paintable (tooltip->window, TRUE);
|
||||
gtk_window_set_resizable (GTK_WINDOW (tooltip->window), FALSE);
|
||||
gtk_widget_set_name (tooltip->window, "gtk-tooltip");
|
||||
@ -164,6 +202,13 @@ gtk_tooltip_init (GtkTooltip *tooltip)
|
||||
gtk_box_pack_start (GTK_BOX (tooltip->box), tooltip->label,
|
||||
FALSE, FALSE, 0);
|
||||
|
||||
g_signal_connect (tooltip->window, "composited-changed",
|
||||
G_CALLBACK (on_composited_changed), tooltip);
|
||||
g_signal_connect (tooltip->window, "screen-changed",
|
||||
G_CALLBACK (on_screen_changed), tooltip);
|
||||
g_signal_connect (tooltip->window, "realize",
|
||||
G_CALLBACK (on_realized), tooltip);
|
||||
|
||||
tooltip->custom_widget = NULL;
|
||||
}
|
||||
|
||||
@ -510,8 +555,152 @@ gtk_tooltip_window_style_set (GtkTooltip *tooltip)
|
||||
gtk_widget_queue_draw (tooltip->window);
|
||||
}
|
||||
|
||||
static void
|
||||
draw_round_rect (cairo_t *cr,
|
||||
gdouble aspect,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
gdouble corner_radius,
|
||||
gdouble width,
|
||||
gdouble height)
|
||||
{
|
||||
gdouble radius = corner_radius / aspect;
|
||||
|
||||
cairo_move_to (cr, x + radius, y);
|
||||
|
||||
/* top-right, left of the corner */
|
||||
cairo_line_to (cr, x + width - radius, y);
|
||||
|
||||
/* top-right, below the corner */
|
||||
cairo_arc (cr,
|
||||
x + width - radius, y + radius, radius,
|
||||
-90.0f * G_PI / 180.0f, 0.0f * G_PI / 180.0f);
|
||||
|
||||
/* bottom-right, above the corner */
|
||||
cairo_line_to (cr, x + width, y + height - radius);
|
||||
|
||||
/* bottom-right, left of the corner */
|
||||
cairo_arc (cr,
|
||||
x + width - radius, y + height - radius, radius,
|
||||
0.0f * G_PI / 180.0f, 90.0f * G_PI / 180.0f);
|
||||
|
||||
/* bottom-left, right of the corner */
|
||||
cairo_line_to (cr, x + radius, y + height);
|
||||
|
||||
/* bottom-left, above the corner */
|
||||
cairo_arc (cr,
|
||||
x + radius, y + height - radius, radius,
|
||||
90.0f * G_PI / 180.0f, 180.0f * G_PI / 180.0f);
|
||||
|
||||
/* top-left, below the corner */
|
||||
cairo_line_to (cr, x, y + radius);
|
||||
|
||||
/* top-left, right of the corner */
|
||||
cairo_arc (cr,
|
||||
x + radius, y + radius, radius,
|
||||
180.0f * G_PI / 180.0f, 270.0f * G_PI / 180.0f);
|
||||
|
||||
cairo_close_path (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
fill_background (GtkWidget *widget,
|
||||
cairo_t *cr,
|
||||
GdkColor *bg_color,
|
||||
GdkColor *border_color,
|
||||
guchar alpha)
|
||||
{
|
||||
gint tooltip_radius;
|
||||
|
||||
if (!gtk_widget_is_composited (widget))
|
||||
alpha = 255;
|
||||
|
||||
gtk_widget_style_get (widget,
|
||||
"tooltip-radius", &tooltip_radius,
|
||||
NULL);
|
||||
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
|
||||
cairo_paint (cr);
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
|
||||
|
||||
draw_round_rect (cr,
|
||||
1.0, 0.5, 0.5, tooltip_radius,
|
||||
widget->allocation.width - 1,
|
||||
widget->allocation.height - 1);
|
||||
|
||||
cairo_set_source_rgba (cr,
|
||||
(float) bg_color->red / 65535.0,
|
||||
(float) bg_color->green / 65535.0,
|
||||
(float) bg_color->blue / 65535.0,
|
||||
(float) alpha / 255.0);
|
||||
cairo_fill_preserve (cr);
|
||||
|
||||
cairo_set_source_rgba (cr,
|
||||
(float) border_color->red / 65535.0,
|
||||
(float) border_color->green / 65535.0,
|
||||
(float) border_color->blue / 65535.0,
|
||||
(float) alpha / 255.0);
|
||||
cairo_set_line_width (cr, 1.0);
|
||||
cairo_stroke (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
update_shape (GtkTooltip *tooltip)
|
||||
{
|
||||
GdkBitmap *mask;
|
||||
cairo_t *cr;
|
||||
gint width, height, tooltip_radius;
|
||||
|
||||
gtk_widget_style_get (tooltip->window,
|
||||
"tooltip-radius", &tooltip_radius,
|
||||
NULL);
|
||||
|
||||
if (tooltip_radius == 0 ||
|
||||
gtk_widget_is_composited (tooltip->window))
|
||||
{
|
||||
gtk_widget_shape_combine_mask (tooltip->window, NULL, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_window_get_size (GTK_WINDOW (tooltip->window), &width, &height);
|
||||
mask = (GdkBitmap *) gdk_pixmap_new (NULL, width, height, 1);
|
||||
cr = gdk_cairo_create (mask);
|
||||
|
||||
fill_background (tooltip->window, cr,
|
||||
&tooltip->window->style->black,
|
||||
&tooltip->window->style->black,
|
||||
255);
|
||||
gtk_widget_shape_combine_mask (tooltip->window, mask, 0, 0);
|
||||
|
||||
cairo_destroy (cr);
|
||||
g_object_unref (mask);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_tooltip_paint_window (GtkTooltip *tooltip)
|
||||
{
|
||||
guchar tooltip_alpha;
|
||||
gint tooltip_radius;
|
||||
|
||||
gtk_widget_style_get (tooltip->window,
|
||||
"tooltip-alpha", &tooltip_alpha,
|
||||
"tooltip-radius", &tooltip_radius,
|
||||
NULL);
|
||||
|
||||
if (tooltip_alpha != 255 || tooltip_radius != 0)
|
||||
{
|
||||
cairo_t *cr;
|
||||
|
||||
cr = gdk_cairo_create (tooltip->window->window);
|
||||
fill_background (tooltip->window, cr,
|
||||
&tooltip->window->style->bg [GTK_STATE_NORMAL],
|
||||
&tooltip->window->style->bg [GTK_STATE_SELECTED],
|
||||
tooltip_alpha);
|
||||
cairo_destroy (cr);
|
||||
|
||||
update_shape (tooltip);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_paint_flat_box (tooltip->window->style,
|
||||
tooltip->window->window,
|
||||
@ -523,6 +712,7 @@ gtk_tooltip_paint_window (GtkTooltip *tooltip)
|
||||
0, 0,
|
||||
tooltip->window->allocation.width,
|
||||
tooltip->window->allocation.height);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -2586,6 +2586,32 @@ gtk_widget_class_init (GtkWidgetClass *klass)
|
||||
P_("The length of vertical scroll arrows"),
|
||||
1, G_MAXINT, 16,
|
||||
GTK_PARAM_READABLE));
|
||||
|
||||
/**
|
||||
* GtkWidget:tooltip-alpha:
|
||||
*
|
||||
* The "tooltip-alpha" style property defines the opacity of
|
||||
* widget tooltips.
|
||||
*/
|
||||
gtk_widget_class_install_style_property (klass,
|
||||
g_param_spec_uchar ("tooltip-alpha",
|
||||
P_("Tooltips opacity"),
|
||||
P_("The opacity to be used when drawing tooltips"),
|
||||
0, 255, 255,
|
||||
GTK_PARAM_READABLE));
|
||||
|
||||
/**
|
||||
* GtkWidget:tooltip-radius:
|
||||
*
|
||||
* The "tooltip-radius" style property defines the radius of
|
||||
* widget tooltips.
|
||||
*/
|
||||
gtk_widget_class_install_style_property (klass,
|
||||
g_param_spec_uint ("tooltip-radius",
|
||||
P_("Tooltips radius"),
|
||||
P_("The radius to be used when drawing tooltips"),
|
||||
0, G_MAXINT, 0,
|
||||
GTK_PARAM_READABLE));
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user