mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-18 09:00:34 +00:00
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
210
gtk/gtktooltip.c
210
gtk/gtktooltip.c
@ -97,6 +97,7 @@ static void gtk_tooltip_display_closed (GdkDisplay *display,
|
|||||||
GtkTooltip *tooltip);
|
GtkTooltip *tooltip);
|
||||||
static void gtk_tooltip_set_last_window (GtkTooltip *tooltip,
|
static void gtk_tooltip_set_last_window (GtkTooltip *tooltip,
|
||||||
GdkWindow *window);
|
GdkWindow *window);
|
||||||
|
static void update_shape (GtkTooltip *tooltip);
|
||||||
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (GtkTooltip, gtk_tooltip, G_TYPE_OBJECT);
|
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;
|
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
|
static void
|
||||||
gtk_tooltip_init (GtkTooltip *tooltip)
|
gtk_tooltip_init (GtkTooltip *tooltip)
|
||||||
{
|
{
|
||||||
@ -129,8 +163,12 @@ gtk_tooltip_init (GtkTooltip *tooltip)
|
|||||||
tooltip->last_window = NULL;
|
tooltip->last_window = NULL;
|
||||||
|
|
||||||
tooltip->window = g_object_ref (gtk_window_new (GTK_WINDOW_POPUP));
|
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),
|
gtk_window_set_type_hint (GTK_WINDOW (tooltip->window),
|
||||||
GDK_WINDOW_TYPE_HINT_TOOLTIP);
|
GDK_WINDOW_TYPE_HINT_TOOLTIP);
|
||||||
|
|
||||||
gtk_widget_set_app_paintable (tooltip->window, TRUE);
|
gtk_widget_set_app_paintable (tooltip->window, TRUE);
|
||||||
gtk_window_set_resizable (GTK_WINDOW (tooltip->window), FALSE);
|
gtk_window_set_resizable (GTK_WINDOW (tooltip->window), FALSE);
|
||||||
gtk_widget_set_name (tooltip->window, "gtk-tooltip");
|
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,
|
gtk_box_pack_start (GTK_BOX (tooltip->box), tooltip->label,
|
||||||
FALSE, FALSE, 0);
|
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;
|
tooltip->custom_widget = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -510,19 +555,164 @@ gtk_tooltip_window_style_set (GtkTooltip *tooltip)
|
|||||||
gtk_widget_queue_draw (tooltip->window);
|
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
|
static gboolean
|
||||||
gtk_tooltip_paint_window (GtkTooltip *tooltip)
|
gtk_tooltip_paint_window (GtkTooltip *tooltip)
|
||||||
{
|
{
|
||||||
gtk_paint_flat_box (tooltip->window->style,
|
guchar tooltip_alpha;
|
||||||
tooltip->window->window,
|
gint tooltip_radius;
|
||||||
GTK_STATE_NORMAL,
|
|
||||||
GTK_SHADOW_OUT,
|
gtk_widget_style_get (tooltip->window,
|
||||||
NULL,
|
"tooltip-alpha", &tooltip_alpha,
|
||||||
tooltip->window,
|
"tooltip-radius", &tooltip_radius,
|
||||||
"tooltip",
|
NULL);
|
||||||
0, 0,
|
|
||||||
tooltip->window->allocation.width,
|
if (tooltip_alpha != 255 || tooltip_radius != 0)
|
||||||
tooltip->window->allocation.height);
|
{
|
||||||
|
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,
|
||||||
|
GTK_STATE_NORMAL,
|
||||||
|
GTK_SHADOW_OUT,
|
||||||
|
NULL,
|
||||||
|
tooltip->window,
|
||||||
|
"tooltip",
|
||||||
|
0, 0,
|
||||||
|
tooltip->window->allocation.width,
|
||||||
|
tooltip->window->allocation.height);
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -2586,6 +2586,32 @@ gtk_widget_class_init (GtkWidgetClass *klass)
|
|||||||
P_("The length of vertical scroll arrows"),
|
P_("The length of vertical scroll arrows"),
|
||||||
1, G_MAXINT, 16,
|
1, G_MAXINT, 16,
|
||||||
GTK_PARAM_READABLE));
|
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
|
static void
|
||||||
|
Loading…
Reference in New Issue
Block a user