зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1308936 - Draw tooltips correctly r=karlt
Tooltip widget is made in GTK3 as following tree: * Tooltip window * Horizontal Box * Icon (not supported by Firefox) * Label Each element can be fully styled by CSS of GTK theme so we have to draw all elements with appropriate offset and full box model. MozReview-Commit-ID: E9yYd5UWBu4 --HG-- extra : amend_source : 99539e914e8d3fa07f6bed8a315e40c7d593f277
This commit is contained in:
Родитель
60c50c3f43
Коммит
cf2b65692c
|
@ -80,8 +80,6 @@ panel[type="arrow"][side="right"] {
|
|||
tooltip {
|
||||
-moz-appearance: tooltip;
|
||||
margin-top: 21px;
|
||||
/* GTK hardcodes this to 4px */
|
||||
padding: 4px;
|
||||
max-width: 40em;
|
||||
color: InfoText;
|
||||
font: message-box;
|
||||
|
|
|
@ -2977,6 +2977,10 @@ moz_gtk_get_widget_border(WidgetNodeType widget, gint* left, gint* top,
|
|||
ensure_tab_widget();
|
||||
w = gTabWidget;
|
||||
break;
|
||||
case MOZ_GTK_TOOLTIP:
|
||||
// In GTK 2 the spacing between box is set to 4.
|
||||
*left = *top = *right = *bottom = 4;
|
||||
return MOZ_GTK_SUCCESS;
|
||||
/* These widgets have no borders, since they are not containers. */
|
||||
case MOZ_GTK_SPLITTER_HORIZONTAL:
|
||||
case MOZ_GTK_SPLITTER_VERTICAL:
|
||||
|
@ -2998,7 +3002,6 @@ moz_gtk_get_widget_border(WidgetNodeType widget, gint* left, gint* top,
|
|||
case MOZ_GTK_MENUSEPARATOR:
|
||||
/* These widgets have no borders.*/
|
||||
case MOZ_GTK_SPINBUTTON:
|
||||
case MOZ_GTK_TOOLTIP:
|
||||
case MOZ_GTK_WINDOW:
|
||||
case MOZ_GTK_RESIZER:
|
||||
case MOZ_GTK_MENUARROW:
|
||||
|
|
|
@ -450,6 +450,16 @@ moz_gtk_get_widget_min_size(WidgetNodeType aGtkWidgetType, int* width,
|
|||
padding.top + padding.bottom;
|
||||
}
|
||||
|
||||
static void
|
||||
moz_gtk_rectangle_inset(GdkRectangle* rect, GtkBorder& aBorder)
|
||||
{
|
||||
MOZ_ASSERT(rect);
|
||||
rect->x += aBorder.left;
|
||||
rect->y += aBorder.top;
|
||||
rect->width -= aBorder.left + aBorder.right;
|
||||
rect->height -= aBorder.top + aBorder.bottom;
|
||||
}
|
||||
|
||||
/* Subtracting margin is used to inset drawing of element which can have margins,
|
||||
* like scrollbar, scrollbar's trough, thumb and scrollbar's button */
|
||||
static void
|
||||
|
@ -460,10 +470,7 @@ moz_gtk_subtract_margin(GtkStyleContext* style, GdkRectangle* rect)
|
|||
|
||||
gtk_style_context_get_margin(style, gtk_style_context_get_state(style),
|
||||
&margin);
|
||||
rect->x += margin.left;
|
||||
rect->y += margin.top;
|
||||
rect->width -= margin.right + margin.left;
|
||||
rect->height -= margin.top + margin.bottom;
|
||||
moz_gtk_rectangle_inset(rect, margin);
|
||||
}
|
||||
|
||||
static gint
|
||||
|
@ -1247,12 +1254,57 @@ moz_gtk_toolbar_separator_paint(cairo_t *cr, GdkRectangle* rect,
|
|||
}
|
||||
|
||||
static gint
|
||||
moz_gtk_tooltip_paint(cairo_t *cr, GdkRectangle* rect,
|
||||
moz_gtk_tooltip_paint(cairo_t *cr, const GdkRectangle* aRect,
|
||||
GtkTextDirection direction)
|
||||
{
|
||||
// Tooltip widget is made in GTK3 as following tree:
|
||||
// Tooltip window
|
||||
// Horizontal Box
|
||||
// Icon (not supported by Firefox)
|
||||
// Label
|
||||
// Each element can be fully styled by CSS of GTK theme.
|
||||
// We have to draw all elements with appropriate offset and right dimensions.
|
||||
|
||||
// Tooltip drawing
|
||||
GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_TOOLTIP, direction);
|
||||
gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
|
||||
gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
|
||||
GdkRectangle rect = *aRect;
|
||||
gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height);
|
||||
gtk_render_frame(style, cr, rect.x, rect.y, rect.width, rect.height);
|
||||
|
||||
// Horizontal Box drawing
|
||||
//
|
||||
// The box element has hard-coded 6px margin-* GtkWidget properties, which
|
||||
// are added between the window dimensions and the CSS margin box of the
|
||||
// horizontal box. The frame of the tooltip window is drawn in the
|
||||
// 6px margin.
|
||||
// For drawing Horizontal Box we have to inset drawing area by that 6px
|
||||
// plus its CSS margin.
|
||||
GtkStyleContext* boxStyle =
|
||||
CreateStyleForWidget(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0), style);
|
||||
|
||||
rect.x += 6;
|
||||
rect.y += 6;
|
||||
rect.width -= 12;
|
||||
rect.height -= 12;
|
||||
|
||||
moz_gtk_subtract_margin(boxStyle, &rect);
|
||||
gtk_render_background(boxStyle, cr, rect.x, rect.y, rect.width, rect.height);
|
||||
gtk_render_frame(boxStyle, cr, rect.x, rect.y, rect.width, rect.height);
|
||||
|
||||
// Label drawing
|
||||
GtkBorder padding, border;
|
||||
gtk_style_context_get_padding(boxStyle, GTK_STATE_FLAG_NORMAL, &padding);
|
||||
moz_gtk_rectangle_inset(&rect, padding);
|
||||
gtk_style_context_get_border(boxStyle, GTK_STATE_FLAG_NORMAL, &border);
|
||||
moz_gtk_rectangle_inset(&rect, border);
|
||||
|
||||
GtkStyleContext* labelStyle =
|
||||
CreateStyleForWidget(gtk_label_new(nullptr), boxStyle);
|
||||
moz_gtk_draw_styled_frame(labelStyle, cr, &rect, false);
|
||||
g_object_unref(labelStyle);
|
||||
|
||||
g_object_unref(boxStyle);
|
||||
|
||||
ReleaseStyleContext(style);
|
||||
return MOZ_GTK_SUCCESS;
|
||||
}
|
||||
|
@ -2126,8 +2178,28 @@ moz_gtk_get_widget_border(WidgetNodeType widget, gint* left, gint* top,
|
|||
case MOZ_GTK_TOOLTIP:
|
||||
{
|
||||
style = ClaimStyleContext(MOZ_GTK_TOOLTIP);
|
||||
moz_gtk_add_style_border(style, left, top, right, bottom);
|
||||
moz_gtk_add_style_padding(style, left, top, right, bottom);
|
||||
// In GTK 3 there are 6 pixels of additional margin around the box.
|
||||
// See details there:
|
||||
// https://github.com/GNOME/gtk/blob/5ea69a136bd7e4970b3a800390e20314665aaed2/gtk/ui/gtktooltipwindow.ui#L11
|
||||
*left = *right = *top = *bottom = 6;
|
||||
|
||||
// We also need to add margin/padding/borders from Tooltip content.
|
||||
// Tooltip contains horizontal box, where icon and label is put.
|
||||
// We ignore icon as long as we don't have support for it.
|
||||
GtkStyleContext* boxStyle =
|
||||
CreateStyleForWidget(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0),
|
||||
style);
|
||||
moz_gtk_add_margin_border_padding(boxStyle,
|
||||
left, top, right, bottom);
|
||||
|
||||
GtkStyleContext* labelStyle =
|
||||
CreateStyleForWidget(gtk_label_new(nullptr), boxStyle);
|
||||
moz_gtk_add_margin_border_padding(labelStyle,
|
||||
left, top, right, bottom);
|
||||
|
||||
g_object_unref(labelStyle);
|
||||
g_object_unref(boxStyle);
|
||||
|
||||
ReleaseStyleContext(style);
|
||||
return MOZ_GTK_SUCCESS;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче