2012-02-10 17:15:28 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2012-02-10 17:15:28 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* This file contains painting functions for each of the gtk2 widgets.
|
|
|
|
* Adapted from the gtkdrawing.c, and gtk+2.0 source.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <gtk/gtk.h>
|
|
|
|
#include <gdk/gdkprivate.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include "gtkdrawing.h"
|
2015-01-30 02:53:46 +03:00
|
|
|
#include "mozilla/Assertions.h"
|
2012-02-10 17:15:28 +04:00
|
|
|
#include "prinrval.h"
|
2016-05-09 02:08:26 +03:00
|
|
|
#include "WidgetStyleCache.h"
|
2017-10-26 21:14:53 +03:00
|
|
|
#include "nsDebug.h"
|
2012-02-10 17:15:28 +04:00
|
|
|
|
|
|
|
#include <math.h>
|
2018-02-20 18:16:23 +03:00
|
|
|
#include <dlfcn.h>
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2014-12-02 15:14:00 +03:00
|
|
|
static gboolean checkbox_check_state;
|
2015-04-30 08:31:00 +03:00
|
|
|
static gboolean notebook_has_tab_gap;
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2017-03-27 21:32:25 +03:00
|
|
|
static ScrollbarGTKMetrics sScrollbarMetrics[2];
|
2017-10-10 14:35:56 +03:00
|
|
|
static ToggleGTKMetrics sCheckboxMetrics;
|
|
|
|
static ToggleGTKMetrics sRadioMetrics;
|
2018-01-25 13:13:12 +03:00
|
|
|
static ToolbarGTKMetrics sToolbarMetrics;
|
2017-03-27 21:32:25 +03:00
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
#define ARROW_UP 0
|
|
|
|
#define ARROW_DOWN G_PI
|
|
|
|
#define ARROW_RIGHT G_PI_2
|
|
|
|
#define ARROW_LEFT (G_PI+G_PI_2)
|
|
|
|
|
2014-12-02 15:14:00 +03:00
|
|
|
#if !GTK_CHECK_VERSION(3,14,0)
|
|
|
|
#define GTK_STATE_FLAG_CHECKED (1 << 11)
|
|
|
|
#endif
|
|
|
|
|
2016-08-22 06:13:00 +03:00
|
|
|
static gint
|
|
|
|
moz_gtk_get_tab_thickness(GtkStyleContext *style);
|
|
|
|
|
2016-11-17 01:04:13 +03:00
|
|
|
static gint
|
|
|
|
moz_gtk_menu_item_paint(WidgetNodeType widget, cairo_t *cr, GdkRectangle* rect,
|
|
|
|
GtkWidgetState* state, GtkTextDirection direction);
|
|
|
|
|
2017-03-27 21:32:55 +03:00
|
|
|
static GtkBorder
|
|
|
|
GetMarginBorderPadding(GtkStyleContext* aStyle);
|
|
|
|
|
2018-02-23 12:37:07 +03:00
|
|
|
static void
|
|
|
|
Inset(GdkRectangle* rect, const GtkBorder& aBorder);
|
|
|
|
|
2017-09-19 22:15:12 +03:00
|
|
|
static void
|
|
|
|
InsetByMargin(GdkRectangle* rect, GtkStyleContext* style);
|
|
|
|
|
2017-10-23 16:16:02 +03:00
|
|
|
static void
|
|
|
|
moz_gtk_add_style_margin(GtkStyleContext* style,
|
|
|
|
gint* left, gint* top, gint* right, gint* bottom)
|
|
|
|
{
|
|
|
|
GtkBorder margin;
|
|
|
|
|
2018-02-23 12:37:07 +03:00
|
|
|
gtk_style_context_get_margin(style, gtk_style_context_get_state(style),
|
|
|
|
&margin);
|
2017-10-23 16:16:02 +03:00
|
|
|
*left += margin.left;
|
|
|
|
*right += margin.right;
|
|
|
|
*top += margin.top;
|
|
|
|
*bottom += margin.bottom;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
moz_gtk_add_style_border(GtkStyleContext* style,
|
|
|
|
gint* left, gint* top, gint* right, gint* bottom)
|
|
|
|
{
|
|
|
|
GtkBorder border;
|
|
|
|
|
|
|
|
gtk_style_context_get_border(style, GTK_STATE_FLAG_NORMAL, &border);
|
|
|
|
|
|
|
|
*left += border.left;
|
|
|
|
*right += border.right;
|
|
|
|
*top += border.top;
|
|
|
|
*bottom += border.bottom;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
moz_gtk_add_style_padding(GtkStyleContext* style,
|
|
|
|
gint* left, gint* top, gint* right, gint* bottom)
|
|
|
|
{
|
|
|
|
GtkBorder padding;
|
|
|
|
|
|
|
|
gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding);
|
|
|
|
|
|
|
|
*left += padding.left;
|
|
|
|
*right += padding.right;
|
|
|
|
*top += padding.top;
|
|
|
|
*bottom += padding.bottom;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
moz_gtk_add_margin_border_padding(GtkStyleContext *style,
|
|
|
|
gint* left, gint* top,
|
|
|
|
gint* right, gint* bottom)
|
|
|
|
{
|
|
|
|
moz_gtk_add_style_margin(style, left, top, right, bottom);
|
|
|
|
moz_gtk_add_style_border(style, left, top, right, bottom);
|
|
|
|
moz_gtk_add_style_padding(style, left, top, right, bottom);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
moz_gtk_add_border_padding(GtkStyleContext *style,
|
|
|
|
gint* left, gint* top,
|
|
|
|
gint* right, gint* bottom)
|
|
|
|
{
|
|
|
|
moz_gtk_add_style_border(style, left, top, right, bottom);
|
|
|
|
moz_gtk_add_style_padding(style, left, top, right, bottom);
|
|
|
|
}
|
|
|
|
|
2017-01-17 04:48:55 +03:00
|
|
|
// GetStateFlagsFromGtkWidgetState() can be safely used for the specific
|
|
|
|
// GtkWidgets that set both prelight and active flags. For other widgets,
|
|
|
|
// either the GtkStateFlags or Gecko's GtkWidgetState need to be carefully
|
|
|
|
// adjusted to match GTK behavior. Although GTK sets insensitive and focus
|
|
|
|
// flags in the generic GtkWidget base class, GTK adds prelight and active
|
|
|
|
// flags only to widgets that are expected to demonstrate prelight or active
|
|
|
|
// states. This contrasts with HTML where any element may have :active and
|
|
|
|
// :hover states, and so Gecko's GtkStateFlags do not necessarily map to GTK
|
|
|
|
// flags. Failure to restrict the flags in the same way as GTK can cause
|
|
|
|
// generic CSS selectors from some themes to unintentionally match elements
|
|
|
|
// that are not expected to change appearance on hover or mouse-down.
|
2012-02-10 17:15:28 +04:00
|
|
|
static GtkStateFlags
|
|
|
|
GetStateFlagsFromGtkWidgetState(GtkWidgetState* state)
|
|
|
|
{
|
|
|
|
GtkStateFlags stateFlags = GTK_STATE_FLAG_NORMAL;
|
|
|
|
|
|
|
|
if (state->disabled)
|
|
|
|
stateFlags = GTK_STATE_FLAG_INSENSITIVE;
|
2017-12-19 13:38:59 +03:00
|
|
|
else {
|
2012-02-10 17:15:28 +04:00
|
|
|
if (state->depressed || state->active)
|
2016-03-23 05:49:00 +03:00
|
|
|
stateFlags = static_cast<GtkStateFlags>(stateFlags|GTK_STATE_FLAG_ACTIVE);
|
2012-02-10 17:15:28 +04:00
|
|
|
if (state->inHover)
|
2016-03-23 05:49:00 +03:00
|
|
|
stateFlags = static_cast<GtkStateFlags>(stateFlags|GTK_STATE_FLAG_PRELIGHT);
|
2012-02-10 17:15:28 +04:00
|
|
|
if (state->focused)
|
2016-03-23 05:49:00 +03:00
|
|
|
stateFlags = static_cast<GtkStateFlags>(stateFlags|GTK_STATE_FLAG_FOCUSED);
|
2012-02-10 17:15:28 +04:00
|
|
|
}
|
2017-12-19 13:38:59 +03:00
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
return stateFlags;
|
|
|
|
}
|
|
|
|
|
2016-08-22 06:13:00 +03:00
|
|
|
static GtkStateFlags
|
|
|
|
GetStateFlagsFromGtkTabFlags(GtkTabFlags flags)
|
|
|
|
{
|
|
|
|
return ((flags & MOZ_GTK_TAB_SELECTED) == 0) ?
|
|
|
|
GTK_STATE_FLAG_NORMAL : GTK_STATE_FLAG_ACTIVE;
|
|
|
|
}
|
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
gint
|
|
|
|
moz_gtk_init()
|
|
|
|
{
|
2014-12-02 15:14:00 +03:00
|
|
|
if (gtk_major_version > 3 ||
|
|
|
|
(gtk_major_version == 3 && gtk_minor_version >= 14))
|
|
|
|
checkbox_check_state = GTK_STATE_FLAG_CHECKED;
|
|
|
|
else
|
|
|
|
checkbox_check_state = GTK_STATE_FLAG_ACTIVE;
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2017-03-27 21:32:38 +03:00
|
|
|
moz_gtk_refresh();
|
|
|
|
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
moz_gtk_refresh()
|
|
|
|
{
|
2016-08-22 06:13:00 +03:00
|
|
|
if (gtk_check_version(3, 12, 0) == nullptr &&
|
|
|
|
gtk_check_version(3, 20, 0) != nullptr)
|
|
|
|
{
|
|
|
|
// Deprecated for Gtk >= 3.20+
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext *style = GetStyleContext(MOZ_GTK_TAB_TOP);
|
2016-08-22 06:13:00 +03:00
|
|
|
gtk_style_context_get_style(style,
|
2016-04-01 00:21:15 +03:00
|
|
|
"has-tab-gap", ¬ebook_has_tab_gap, NULL);
|
2015-04-30 08:31:00 +03:00
|
|
|
}
|
|
|
|
else {
|
2016-08-22 06:13:00 +03:00
|
|
|
notebook_has_tab_gap = true;
|
2015-04-30 08:31:00 +03:00
|
|
|
}
|
|
|
|
|
2017-03-27 21:32:38 +03:00
|
|
|
sScrollbarMetrics[GTK_ORIENTATION_HORIZONTAL].initialized = false;
|
|
|
|
sScrollbarMetrics[GTK_ORIENTATION_VERTICAL].initialized = false;
|
2017-10-10 14:35:56 +03:00
|
|
|
sCheckboxMetrics.initialized = false;
|
|
|
|
sRadioMetrics.initialized = false;
|
2018-01-25 13:13:12 +03:00
|
|
|
sToolbarMetrics.initialized = false;
|
2018-02-20 15:15:52 +03:00
|
|
|
|
|
|
|
/* This will destroy all of our widgets */
|
|
|
|
ResetWidgetCache();
|
2012-02-10 17:15:28 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
|
|
|
moz_gtk_checkbox_get_metrics(gint* indicator_size, gint* indicator_spacing)
|
|
|
|
{
|
2016-05-13 02:59:17 +03:00
|
|
|
gtk_widget_style_get(GetWidget(MOZ_GTK_CHECKBUTTON_CONTAINER),
|
|
|
|
"indicator_size", indicator_size,
|
|
|
|
"indicator_spacing", indicator_spacing,
|
|
|
|
NULL);
|
2012-02-10 17:15:28 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
|
|
|
moz_gtk_radio_get_metrics(gint* indicator_size, gint* indicator_spacing)
|
|
|
|
{
|
2016-05-13 02:59:17 +03:00
|
|
|
gtk_widget_style_get(GetWidget(MOZ_GTK_RADIOBUTTON_CONTAINER),
|
|
|
|
"indicator_size", indicator_size,
|
|
|
|
"indicator_spacing", indicator_spacing,
|
|
|
|
NULL);
|
2012-02-10 17:15:28 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-10-19 05:13:25 +03:00
|
|
|
static gint
|
|
|
|
moz_gtk_get_focus_outline_size(GtkStyleContext* style,
|
|
|
|
gint* focus_h_width, gint* focus_v_width)
|
2014-06-14 16:48:08 +04:00
|
|
|
{
|
2015-03-25 21:41:01 +03:00
|
|
|
GtkBorder border;
|
|
|
|
GtkBorder padding;
|
2016-03-23 05:49:00 +03:00
|
|
|
gtk_style_context_get_border(style, GTK_STATE_FLAG_NORMAL, &border);
|
|
|
|
gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding);
|
2015-03-25 21:41:01 +03:00
|
|
|
*focus_h_width = border.left + padding.left;
|
|
|
|
*focus_v_width = border.top + padding.top;
|
2016-10-19 05:13:25 +03:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
|
|
|
moz_gtk_get_focus_outline_size(gint* focus_h_width, gint* focus_v_width)
|
|
|
|
{
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext *style = GetStyleContext(MOZ_GTK_ENTRY);
|
2016-10-19 05:13:25 +03:00
|
|
|
moz_gtk_get_focus_outline_size(style, focus_h_width, focus_v_width);
|
2012-02-10 17:15:28 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
|
|
|
moz_gtk_menuitem_get_horizontal_padding(gint* horizontal_padding)
|
|
|
|
{
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext *style = GetStyleContext(MOZ_GTK_MENUITEM);
|
2016-11-15 06:11:38 +03:00
|
|
|
gtk_style_context_get_style(style,
|
|
|
|
"horizontal-padding", horizontal_padding,
|
|
|
|
nullptr);
|
2012-02-10 17:15:28 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
|
|
|
moz_gtk_checkmenuitem_get_horizontal_padding(gint* horizontal_padding)
|
|
|
|
{
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext *style = GetStyleContext(MOZ_GTK_CHECKMENUITEM);
|
2016-07-28 04:54:00 +03:00
|
|
|
gtk_style_context_get_style(style,
|
2016-04-01 00:21:15 +03:00
|
|
|
"horizontal-padding", horizontal_padding,
|
2016-11-15 06:11:38 +03:00
|
|
|
nullptr);
|
2012-02-10 17:15:28 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
|
|
|
moz_gtk_button_get_default_overflow(gint* border_top, gint* border_left,
|
|
|
|
gint* border_bottom, gint* border_right)
|
|
|
|
{
|
|
|
|
GtkBorder* default_outside_border;
|
|
|
|
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext *style = GetStyleContext(MOZ_GTK_BUTTON);
|
2016-07-20 02:57:00 +03:00
|
|
|
gtk_style_context_get_style(style,
|
2016-04-01 00:21:15 +03:00
|
|
|
"default-outside-border", &default_outside_border,
|
|
|
|
NULL);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
|
|
|
if (default_outside_border) {
|
|
|
|
*border_top = default_outside_border->top;
|
|
|
|
*border_left = default_outside_border->left;
|
|
|
|
*border_bottom = default_outside_border->bottom;
|
|
|
|
*border_right = default_outside_border->right;
|
|
|
|
gtk_border_free(default_outside_border);
|
|
|
|
} else {
|
|
|
|
*border_top = *border_left = *border_bottom = *border_right = 0;
|
|
|
|
}
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
moz_gtk_button_get_default_border(gint* border_top, gint* border_left,
|
|
|
|
gint* border_bottom, gint* border_right)
|
|
|
|
{
|
|
|
|
GtkBorder* default_border;
|
|
|
|
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext *style = GetStyleContext(MOZ_GTK_BUTTON);
|
2016-07-20 02:57:00 +03:00
|
|
|
gtk_style_context_get_style(style,
|
2016-04-01 00:21:15 +03:00
|
|
|
"default-border", &default_border,
|
|
|
|
NULL);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
|
|
|
if (default_border) {
|
|
|
|
*border_top = default_border->top;
|
|
|
|
*border_left = default_border->left;
|
|
|
|
*border_bottom = default_border->bottom;
|
|
|
|
*border_right = default_border->right;
|
|
|
|
gtk_border_free(default_border);
|
|
|
|
} else {
|
|
|
|
/* see gtkbutton.c */
|
|
|
|
*border_top = *border_left = *border_bottom = *border_right = 1;
|
|
|
|
}
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
|
|
|
moz_gtk_splitter_get_metrics(gint orientation, gint* size)
|
|
|
|
{
|
2016-07-29 06:30:00 +03:00
|
|
|
GtkStyleContext *style;
|
2012-02-10 17:15:28 +04:00
|
|
|
if (orientation == GTK_ORIENTATION_HORIZONTAL) {
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext(MOZ_GTK_SPLITTER_HORIZONTAL);
|
2012-02-10 17:15:28 +04:00
|
|
|
} else {
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext(MOZ_GTK_SPLITTER_VERTICAL);
|
2012-02-10 17:15:28 +04:00
|
|
|
}
|
2016-07-29 06:30:00 +03:00
|
|
|
gtk_style_context_get_style(style, "handle_size", size, NULL);
|
2012-02-10 17:15:28 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2018-01-25 13:13:12 +03:00
|
|
|
static void
|
2018-02-23 12:37:07 +03:00
|
|
|
CalculateToolbarButtonMetrics(WidgetNodeType aWidgetType,
|
|
|
|
ToolbarButtonGTKMetrics* aMetrics)
|
2018-01-22 14:14:13 +03:00
|
|
|
{
|
2018-01-25 13:13:12 +03:00
|
|
|
gint iconWidth, iconHeight;
|
|
|
|
if (!gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &iconWidth, &iconHeight)) {
|
|
|
|
NS_WARNING("Failed to get Gtk+ icon size for titlebar button!");
|
2018-01-22 14:14:13 +03:00
|
|
|
|
2018-01-25 13:13:12 +03:00
|
|
|
// Use some reasonable fallback size
|
|
|
|
iconWidth = 16;
|
|
|
|
iconHeight = 16;
|
|
|
|
}
|
2018-01-22 14:14:13 +03:00
|
|
|
|
2018-02-23 12:37:07 +03:00
|
|
|
GtkStyleContext* style = GetStyleContext(aWidgetType);
|
2018-01-25 13:13:12 +03:00
|
|
|
gint width = 0, height = 0;
|
|
|
|
if (gtk_check_version(3, 20, 0) == nullptr) {
|
|
|
|
gtk_style_context_get(style, gtk_style_context_get_state(style),
|
|
|
|
"min-width", &width,
|
|
|
|
"min-height", &height, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Cover cases when min-width/min-height is not set, it's invalid
|
|
|
|
// or we're running on Gtk+ < 3.20.
|
|
|
|
if (width < iconWidth)
|
|
|
|
width = iconWidth;
|
|
|
|
if (height < iconHeight)
|
|
|
|
height = iconHeight;
|
|
|
|
|
|
|
|
gint left = 0, top = 0, right = 0, bottom = 0;
|
2018-02-23 12:37:07 +03:00
|
|
|
moz_gtk_add_border_padding(style, &left, &top, &right, &bottom);
|
2018-01-22 14:14:13 +03:00
|
|
|
|
2018-02-23 12:37:07 +03:00
|
|
|
// Button size is calculated as min-width/height + border/padding.
|
2018-01-25 13:13:12 +03:00
|
|
|
width += left + right;
|
|
|
|
height += top + bottom;
|
|
|
|
|
2018-02-23 12:37:07 +03:00
|
|
|
// Place icon at button center.
|
|
|
|
aMetrics->iconXPosition = (width - iconWidth) / 2;
|
|
|
|
aMetrics->iconYPosition = (height - iconHeight) / 2;
|
|
|
|
|
|
|
|
aMetrics->minSizeWithBorderMargin.width = width;
|
|
|
|
aMetrics->minSizeWithBorderMargin.height = height;
|
|
|
|
}
|
|
|
|
|
|
|
|
// We support LTR layout only here for now.
|
|
|
|
static void
|
|
|
|
CalculateToolbarButtonSpacing(WidgetNodeType aWidgetType,
|
|
|
|
ToolbarButtonGTKMetrics* aMetrics)
|
|
|
|
{
|
|
|
|
GtkStyleContext* style = GetStyleContext(aWidgetType);
|
|
|
|
gtk_style_context_get_margin(style, gtk_style_context_get_state(style),
|
|
|
|
&aMetrics->buttonMargin);
|
|
|
|
|
|
|
|
// Get titlebar spacing, a default one is 6 pixels (gtk/gtkheaderbar.c)
|
|
|
|
gint buttonSpacing = 6;
|
|
|
|
g_object_get(GetWidget(MOZ_GTK_HEADER_BAR),
|
|
|
|
"spacing", &buttonSpacing, nullptr);
|
|
|
|
|
|
|
|
// We apply spacing as a margin equaly to both adjacent buttons.
|
|
|
|
buttonSpacing /= 2;
|
|
|
|
|
|
|
|
if (!aMetrics->firstButton) {
|
|
|
|
aMetrics->buttonMargin.left += buttonSpacing;
|
|
|
|
}
|
|
|
|
if (!aMetrics->lastButton) {
|
|
|
|
aMetrics->buttonMargin.right += buttonSpacing;
|
|
|
|
}
|
|
|
|
|
|
|
|
aMetrics->iconXPosition += aMetrics->buttonMargin.left;
|
|
|
|
aMetrics->iconYPosition += aMetrics->buttonMargin.top;
|
|
|
|
|
|
|
|
aMetrics->minSizeWithBorderMargin.width +=
|
|
|
|
aMetrics->buttonMargin.right + aMetrics->buttonMargin.left;
|
|
|
|
aMetrics->minSizeWithBorderMargin.height +=
|
|
|
|
aMetrics->buttonMargin.top + aMetrics->buttonMargin.bottom;
|
|
|
|
}
|
|
|
|
|
2018-02-23 23:28:37 +03:00
|
|
|
int
|
2018-02-23 12:37:07 +03:00
|
|
|
GetGtkHeaderBarButtonLayout(WidgetNodeType* aButtonLayout, int aMaxButtonNums)
|
|
|
|
{
|
|
|
|
NS_ASSERTION(aMaxButtonNums >= TOOLBAR_BUTTONS,
|
|
|
|
"Requested number of buttons is higher than storage capacity!");
|
|
|
|
|
|
|
|
static auto sGtkHeaderBarGetDecorationLayoutPtr =
|
|
|
|
(const gchar* (*)(GtkWidget*))
|
|
|
|
dlsym(RTLD_DEFAULT, "gtk_header_bar_get_decoration_layout");
|
|
|
|
|
|
|
|
const gchar* decorationLayout = nullptr;
|
|
|
|
if (sGtkHeaderBarGetDecorationLayoutPtr) {
|
|
|
|
GtkWidget* headerBar = GetWidget(MOZ_GTK_HEADER_BAR);
|
|
|
|
decorationLayout = sGtkHeaderBarGetDecorationLayoutPtr(headerBar);
|
|
|
|
if (!decorationLayout) {
|
|
|
|
GtkSettings *settings = gtk_settings_get_for_screen(
|
|
|
|
gdk_screen_get_default());
|
|
|
|
g_object_get(settings, "gtk-decoration-layout",
|
|
|
|
&decorationLayout,
|
|
|
|
nullptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Use a default layout
|
|
|
|
if (!decorationLayout) {
|
|
|
|
decorationLayout = "minimize,maximize,close";
|
|
|
|
}
|
|
|
|
|
|
|
|
// We support only default button order now:
|
|
|
|
// minimize/maximize/close
|
|
|
|
int activeButtonNums = 0;
|
|
|
|
if (strstr(decorationLayout, "minimize") != nullptr) {
|
|
|
|
aButtonLayout[activeButtonNums++] = MOZ_GTK_HEADER_BAR_BUTTON_MINIMIZE;
|
|
|
|
}
|
|
|
|
if (strstr(decorationLayout, "maximize") != nullptr) {
|
|
|
|
aButtonLayout[activeButtonNums++] = MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE;
|
|
|
|
}
|
|
|
|
if (strstr(decorationLayout, "close") != nullptr) {
|
|
|
|
aButtonLayout[activeButtonNums++] = MOZ_GTK_HEADER_BAR_BUTTON_CLOSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return activeButtonNums;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
EnsureToolbarMetrics(void)
|
|
|
|
{
|
|
|
|
if (!sToolbarMetrics.initialized) {
|
|
|
|
// Make sure we have clean cache after theme reset, etc.
|
|
|
|
memset(&sToolbarMetrics, 0, sizeof(sToolbarMetrics));
|
|
|
|
|
|
|
|
// We're running on old Gtk+ version. Leave the cache empty
|
|
|
|
// which means all buttons are disabled.
|
|
|
|
if (gtk_check_version(3, 10, 0) != nullptr) {
|
|
|
|
sToolbarMetrics.initialized = true;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Calculate titlebar button visibility and positions.
|
|
|
|
WidgetNodeType aButtonLayout[TOOLBAR_BUTTONS];
|
|
|
|
int activeButtonNums =
|
|
|
|
GetGtkHeaderBarButtonLayout(aButtonLayout, TOOLBAR_BUTTONS);
|
|
|
|
|
|
|
|
for (int i = 0; i < activeButtonNums; i++) {
|
|
|
|
int buttonIndex = (aButtonLayout[i] - MOZ_GTK_HEADER_BAR_BUTTON_CLOSE);
|
|
|
|
ToolbarButtonGTKMetrics* metrics = sToolbarMetrics.button + buttonIndex;
|
|
|
|
metrics->visible = true;
|
|
|
|
// Mark first button
|
|
|
|
if (!i) {
|
|
|
|
metrics->firstButton = true;
|
|
|
|
}
|
|
|
|
// Mark last button.
|
|
|
|
if (i == (activeButtonNums-1)) {
|
|
|
|
metrics->lastButton = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
CalculateToolbarButtonMetrics(aButtonLayout[i], metrics);
|
|
|
|
CalculateToolbarButtonSpacing(aButtonLayout[i], metrics);
|
|
|
|
}
|
|
|
|
|
|
|
|
sToolbarMetrics.initialized = true;
|
|
|
|
}
|
2018-01-25 13:13:12 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
const ToolbarButtonGTKMetrics*
|
|
|
|
GetToolbarButtonMetrics(WidgetNodeType aWidgetType)
|
|
|
|
{
|
2018-02-23 12:37:07 +03:00
|
|
|
EnsureToolbarMetrics();
|
2018-01-22 14:14:13 +03:00
|
|
|
|
2018-01-25 13:13:12 +03:00
|
|
|
int buttonIndex = (aWidgetType - MOZ_GTK_HEADER_BAR_BUTTON_CLOSE);
|
|
|
|
NS_ASSERTION(buttonIndex >= 0 &&
|
|
|
|
buttonIndex <= TOOLBAR_BUTTONS,
|
|
|
|
"GetToolbarButtonMetrics(): Wrong titlebar button!");
|
|
|
|
return sToolbarMetrics.button + buttonIndex;
|
2018-01-22 14:14:13 +03:00
|
|
|
}
|
|
|
|
|
2015-08-06 21:20:00 +03:00
|
|
|
static gint
|
|
|
|
moz_gtk_window_paint(cairo_t *cr, GdkRectangle* rect,
|
|
|
|
GtkTextDirection direction)
|
|
|
|
{
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style = GetStyleContext(MOZ_GTK_WINDOW, direction);
|
2015-08-06 21:20:00 +03:00
|
|
|
|
|
|
|
gtk_style_context_save(style);
|
|
|
|
gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND);
|
|
|
|
gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
|
|
|
|
gtk_style_context_restore(style);
|
|
|
|
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
static gint
|
|
|
|
moz_gtk_button_paint(cairo_t *cr, GdkRectangle* rect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkWidgetState* state,
|
2012-02-10 17:15:28 +04:00
|
|
|
GtkReliefStyle relief, GtkWidget* widget,
|
|
|
|
GtkTextDirection direction)
|
|
|
|
{
|
|
|
|
GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
|
2017-12-19 13:38:59 +03:00
|
|
|
GtkStyleContext* style = gtk_widget_get_style_context(widget);
|
2012-02-10 17:15:28 +04:00
|
|
|
gint x = rect->x, y=rect->y, width=rect->width, height=rect->height;
|
|
|
|
|
|
|
|
gtk_widget_set_direction(widget, direction);
|
2017-12-19 13:38:59 +03:00
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
gtk_style_context_save(style);
|
|
|
|
gtk_style_context_set_state(style, state_flags);
|
|
|
|
|
|
|
|
if (state->isDefault && relief == GTK_RELIEF_NORMAL) {
|
|
|
|
/* handle default borders both outside and inside the button */
|
|
|
|
gint default_top, default_left, default_bottom, default_right;
|
|
|
|
moz_gtk_button_get_default_overflow(&default_top, &default_left,
|
|
|
|
&default_bottom, &default_right);
|
|
|
|
x -= default_left;
|
|
|
|
y -= default_top;
|
|
|
|
width += default_left + default_right;
|
|
|
|
height += default_top + default_bottom;
|
|
|
|
gtk_render_background(style, cr, x, y, width, height);
|
|
|
|
gtk_render_frame(style, cr, x, y, width, height);
|
|
|
|
moz_gtk_button_get_default_border(&default_top, &default_left,
|
|
|
|
&default_bottom, &default_right);
|
|
|
|
x += default_left;
|
|
|
|
y += default_top;
|
|
|
|
width -= (default_left + default_right);
|
|
|
|
height -= (default_top + default_bottom);
|
2015-07-27 22:08:00 +03:00
|
|
|
} else if (relief != GTK_RELIEF_NONE || state->depressed ||
|
2012-02-10 17:15:28 +04:00
|
|
|
(state_flags & GTK_STATE_FLAG_PRELIGHT)) {
|
|
|
|
/* the following line can trigger an assertion (Crux theme)
|
|
|
|
file ../../gdk/gdkwindow.c: line 1846 (gdk_window_clear_area):
|
|
|
|
assertion `GDK_IS_WINDOW (window)' failed */
|
|
|
|
gtk_render_background(style, cr, x, y, width, height);
|
|
|
|
gtk_render_frame(style, cr, x, y, width, height);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state->focused) {
|
2015-03-25 21:41:21 +03:00
|
|
|
GtkBorder border;
|
|
|
|
gtk_style_context_get_border(style, state_flags, &border);
|
|
|
|
x += border.left;
|
|
|
|
y += border.top;
|
|
|
|
width -= (border.left + border.right);
|
|
|
|
height -= (border.top + border.bottom);
|
2012-02-10 17:15:28 +04:00
|
|
|
gtk_render_focus(style, cr, x, y, width, height);
|
|
|
|
}
|
|
|
|
gtk_style_context_restore(style);
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-09-19 22:15:12 +03:00
|
|
|
static gint
|
|
|
|
moz_gtk_header_bar_button_paint(cairo_t *cr, GdkRectangle* rect,
|
|
|
|
GtkWidgetState* state,
|
2018-01-25 13:13:12 +03:00
|
|
|
GtkReliefStyle relief,
|
2018-02-23 23:28:37 +03:00
|
|
|
WidgetNodeType aIconWidgetType,
|
2017-09-19 22:15:12 +03:00
|
|
|
GtkTextDirection direction)
|
|
|
|
{
|
2018-02-23 23:28:37 +03:00
|
|
|
WidgetNodeType buttonWidgetType =
|
|
|
|
(aIconWidgetType == MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE_RESTORE) ?
|
|
|
|
MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE : aIconWidgetType;
|
|
|
|
|
2018-02-23 12:37:07 +03:00
|
|
|
// We need to inset our calculated margin because it also
|
|
|
|
// contains titlebar button spacing.
|
|
|
|
const ToolbarButtonGTKMetrics* metrics =
|
2018-02-23 23:28:37 +03:00
|
|
|
GetToolbarButtonMetrics(buttonWidgetType);
|
2018-02-23 12:37:07 +03:00
|
|
|
Inset(rect, metrics->buttonMargin);
|
|
|
|
|
2018-02-23 23:28:37 +03:00
|
|
|
GtkWidget *buttonWidget = GetWidget(buttonWidgetType);
|
|
|
|
moz_gtk_button_paint(cr, rect, state, relief, buttonWidget, direction);
|
2018-01-25 13:13:12 +03:00
|
|
|
|
2018-02-23 23:28:37 +03:00
|
|
|
GtkWidget* iconWidget =
|
|
|
|
gtk_bin_get_child(GTK_BIN(GetWidget(aIconWidgetType)));
|
2018-02-20 18:16:23 +03:00
|
|
|
cairo_surface_t *surface = GetWidgetIconSurface(iconWidget, state->scale);
|
2018-01-25 13:13:12 +03:00
|
|
|
|
2018-02-20 18:16:23 +03:00
|
|
|
if (surface) {
|
2018-02-23 23:28:37 +03:00
|
|
|
GtkStyleContext* style = gtk_widget_get_style_context(buttonWidget);
|
2018-01-25 13:13:12 +03:00
|
|
|
GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
|
|
|
|
|
|
|
|
gtk_style_context_save(style);
|
|
|
|
gtk_style_context_set_state(style, state_flags);
|
|
|
|
|
|
|
|
const ToolbarButtonGTKMetrics *metrics =
|
2018-02-23 23:28:37 +03:00
|
|
|
GetToolbarButtonMetrics(buttonWidgetType);
|
2018-01-25 13:13:12 +03:00
|
|
|
|
2018-02-20 18:16:23 +03:00
|
|
|
/* This is available since Gtk+ 3.10 as well as GtkHeaderBar */
|
|
|
|
static auto sGtkRenderIconSurfacePtr =
|
|
|
|
(void (*)(GtkStyleContext *, cairo_t *, cairo_surface_t *, gdouble, gdouble))
|
|
|
|
dlsym(RTLD_DEFAULT, "gtk_render_icon_surface");
|
|
|
|
|
|
|
|
sGtkRenderIconSurfacePtr(style, cr, surface,
|
|
|
|
metrics->iconXPosition, metrics->iconYPosition);
|
2018-01-25 13:13:12 +03:00
|
|
|
gtk_style_context_restore(style);
|
|
|
|
}
|
|
|
|
|
|
|
|
return MOZ_GTK_SUCCESS;
|
2017-09-19 22:15:12 +03:00
|
|
|
}
|
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
static gint
|
|
|
|
moz_gtk_toggle_paint(cairo_t *cr, GdkRectangle* rect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkWidgetState* state,
|
2012-02-10 17:15:28 +04:00
|
|
|
gboolean selected, gboolean inconsistent,
|
|
|
|
gboolean isradio, GtkTextDirection direction)
|
|
|
|
{
|
2015-05-27 21:27:00 +03:00
|
|
|
GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
|
2012-02-10 17:15:28 +04:00
|
|
|
gint x, y, width, height;
|
|
|
|
GtkStyleContext *style;
|
|
|
|
|
2017-10-10 14:35:56 +03:00
|
|
|
const ToggleGTKMetrics* metrics = GetToggleMetrics(isradio);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2017-11-17 09:20:42 +03:00
|
|
|
// Clamp the rect and paint it center aligned in the rect.
|
|
|
|
x = rect->x;
|
|
|
|
y = rect->y;
|
|
|
|
width = rect->width;
|
|
|
|
height = rect->height;
|
|
|
|
|
|
|
|
if (rect->width < rect->height) {
|
|
|
|
y = rect->y + (rect->height - rect->width) / 2;
|
|
|
|
height = rect->width;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rect->height < rect->width) {
|
|
|
|
x = rect->x + (rect->width - rect->height) / 2;
|
|
|
|
width = rect->height;
|
|
|
|
}
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2015-05-27 21:27:00 +03:00
|
|
|
if (selected)
|
2016-03-23 05:49:00 +03:00
|
|
|
state_flags = static_cast<GtkStateFlags>(state_flags|checkbox_check_state);
|
2015-05-27 21:27:00 +03:00
|
|
|
|
|
|
|
if (inconsistent)
|
2016-03-23 05:49:00 +03:00
|
|
|
state_flags = static_cast<GtkStateFlags>(state_flags|GTK_STATE_FLAG_INCONSISTENT);
|
2015-05-27 21:27:00 +03:00
|
|
|
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext(isradio ? MOZ_GTK_RADIOBUTTON : MOZ_GTK_CHECKBUTTON,
|
|
|
|
direction, state_flags);
|
2016-05-13 02:59:17 +03:00
|
|
|
|
|
|
|
if (gtk_check_version(3, 20, 0) == nullptr) {
|
|
|
|
gtk_render_background(style, cr, x, y, width, height);
|
|
|
|
gtk_render_frame(style, cr, x, y, width, height);
|
2017-10-10 14:35:56 +03:00
|
|
|
// Indicator is inset by the toggle's padding and border.
|
|
|
|
gint indicator_x = x + metrics->borderAndPadding.left;
|
|
|
|
gint indicator_y = y + metrics->borderAndPadding.top;
|
|
|
|
gint indicator_width = metrics->minSizeWithBorder.width -
|
|
|
|
metrics->borderAndPadding.left - metrics->borderAndPadding.right;
|
|
|
|
gint indicator_height = metrics->minSizeWithBorder.height -
|
|
|
|
metrics->borderAndPadding.top - metrics->borderAndPadding.bottom;
|
|
|
|
if (isradio) {
|
|
|
|
gtk_render_option(style, cr, indicator_x, indicator_y,
|
|
|
|
indicator_width, indicator_height);
|
|
|
|
} else {
|
|
|
|
gtk_render_check(style, cr, indicator_x, indicator_y,
|
|
|
|
indicator_width, indicator_height);
|
2012-02-10 17:15:28 +04:00
|
|
|
}
|
2017-10-10 14:35:56 +03:00
|
|
|
} else {
|
|
|
|
if (isradio) {
|
|
|
|
gtk_render_option(style, cr, x, y, width, height);
|
|
|
|
} else {
|
|
|
|
gtk_render_check(style, cr, x, y, width, height);
|
2012-02-10 17:15:28 +04:00
|
|
|
}
|
|
|
|
}
|
2016-05-13 02:59:17 +03:00
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
calculate_button_inner_rect(GtkWidget* button, GdkRectangle* rect,
|
|
|
|
GdkRectangle* inner_rect,
|
2015-11-18 04:11:58 +03:00
|
|
|
GtkTextDirection direction)
|
2012-02-10 17:15:28 +04:00
|
|
|
{
|
|
|
|
GtkStyleContext* style;
|
|
|
|
GtkBorder border;
|
2015-03-25 21:41:01 +03:00
|
|
|
GtkBorder padding = {0, 0, 0, 0};
|
2012-02-10 17:15:28 +04:00
|
|
|
|
|
|
|
style = gtk_widget_get_style_context(button);
|
|
|
|
|
|
|
|
/* This mirrors gtkbutton's child positioning */
|
2016-03-23 05:49:00 +03:00
|
|
|
gtk_style_context_get_border(style, GTK_STATE_FLAG_NORMAL, &border);
|
|
|
|
gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2015-03-25 21:41:01 +03:00
|
|
|
inner_rect->x = rect->x + border.left + padding.left;
|
|
|
|
inner_rect->y = rect->y + padding.top + border.top;
|
|
|
|
inner_rect->width = MAX(1, rect->width - padding.left -
|
|
|
|
padding.right - border.left * 2);
|
|
|
|
inner_rect->height = MAX(1, rect->height - padding.top -
|
|
|
|
padding.bottom - border.top * 2);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static gint
|
|
|
|
calculate_arrow_rect(GtkWidget* arrow, GdkRectangle* rect,
|
|
|
|
GdkRectangle* arrow_rect, GtkTextDirection direction)
|
|
|
|
{
|
|
|
|
/* defined in gtkarrow.c */
|
|
|
|
gfloat arrow_scaling = 0.7;
|
|
|
|
gfloat xalign, xpad;
|
|
|
|
gint extent;
|
|
|
|
gint mxpad, mypad;
|
|
|
|
gfloat mxalign, myalign;
|
|
|
|
GtkMisc* misc = GTK_MISC(arrow);
|
|
|
|
|
2017-03-27 21:32:33 +03:00
|
|
|
gtk_style_context_get_style(gtk_widget_get_style_context(arrow),
|
|
|
|
"arrow_scaling", &arrow_scaling, NULL);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2017-12-19 13:38:59 +03:00
|
|
|
gtk_misc_get_padding(misc, &mxpad, &mypad);
|
2012-02-10 17:15:28 +04:00
|
|
|
extent = MIN((rect->width - mxpad * 2),
|
|
|
|
(rect->height - mypad * 2)) * arrow_scaling;
|
|
|
|
|
|
|
|
gtk_misc_get_alignment(misc, &mxalign, &myalign);
|
2017-12-19 13:38:59 +03:00
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
xalign = direction == GTK_TEXT_DIR_LTR ? mxalign : 1.0 - mxalign;
|
|
|
|
xpad = mxpad + (rect->width - extent) * xalign;
|
|
|
|
|
|
|
|
arrow_rect->x = direction == GTK_TEXT_DIR_LTR ?
|
|
|
|
floor(rect->x + xpad) : ceil(rect->x + xpad);
|
|
|
|
arrow_rect->y = floor(rect->y + mypad +
|
|
|
|
((rect->height - extent) * myalign));
|
|
|
|
|
|
|
|
arrow_rect->width = arrow_rect->height = extent;
|
|
|
|
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-03-27 21:32:51 +03:00
|
|
|
static MozGtkSize
|
|
|
|
GetMinContentBox(GtkStyleContext* style)
|
|
|
|
{
|
|
|
|
GtkStateFlags state_flags = gtk_style_context_get_state(style);
|
|
|
|
gint width, height;
|
|
|
|
gtk_style_context_get(style, state_flags,
|
|
|
|
"min-width", &width,
|
|
|
|
"min-height", &height,
|
|
|
|
nullptr);
|
|
|
|
return {width, height};
|
|
|
|
}
|
|
|
|
|
2017-03-27 21:32:25 +03:00
|
|
|
/**
|
|
|
|
* Get minimum widget size as sum of margin, padding, border and
|
|
|
|
* min-width/min-height.
|
|
|
|
*/
|
|
|
|
static void
|
Bug 1289148 - Fixing scrollbar metrics for GTK >= 3.20 r=karlt
The Gtk 3.20 scrollbars has moved towards usual box model. The scrollbar,
trough,thumb and scrollbar button can now have margin, padding and border set,
different for each direction (ie. left, right, bottom, top). The scrollbar
metrics become ignored in Gtk 3.20 and later.
* Draw scrollbar element [for GTK 3.20+]
* The border for scrollbar, trough, thumb and scrollbar buttons is newly
calculated as margin+padding+border [for GTK 3.20+].
* The margin is subtracted for scrollbar, trough and sb buttons during paint
function [for GTK 3.6+]
* All scrollbar widget's borders transfered from
nsNativeThemeGTK::GetWidgetBorder to the moz_gtk_get_widget_border.
* Added helper function NativeThemeToGtkTheme for mapping mozilla's widget type
to the gtk widget type.
* Scrollbar troughs are now drawn even when there is not enough room for
the thumb [GTK 3.20+]
MozReview-Commit-ID: jd2q67gKM1
--HG--
extra : rebase_source : ecc8b85401845113d84c6c5a48219a0c3d4f8de3
2016-10-17 01:37:13 +03:00
|
|
|
moz_gtk_get_widget_min_size(WidgetNodeType aGtkWidgetType, int* width,
|
|
|
|
int* height)
|
|
|
|
{
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style = GetStyleContext(aGtkWidgetType);
|
Bug 1289148 - Fixing scrollbar metrics for GTK >= 3.20 r=karlt
The Gtk 3.20 scrollbars has moved towards usual box model. The scrollbar,
trough,thumb and scrollbar button can now have margin, padding and border set,
different for each direction (ie. left, right, bottom, top). The scrollbar
metrics become ignored in Gtk 3.20 and later.
* Draw scrollbar element [for GTK 3.20+]
* The border for scrollbar, trough, thumb and scrollbar buttons is newly
calculated as margin+padding+border [for GTK 3.20+].
* The margin is subtracted for scrollbar, trough and sb buttons during paint
function [for GTK 3.6+]
* All scrollbar widget's borders transfered from
nsNativeThemeGTK::GetWidgetBorder to the moz_gtk_get_widget_border.
* Added helper function NativeThemeToGtkTheme for mapping mozilla's widget type
to the gtk widget type.
* Scrollbar troughs are now drawn even when there is not enough room for
the thumb [GTK 3.20+]
MozReview-Commit-ID: jd2q67gKM1
--HG--
extra : rebase_source : ecc8b85401845113d84c6c5a48219a0c3d4f8de3
2016-10-17 01:37:13 +03:00
|
|
|
GtkStateFlags state_flags = gtk_style_context_get_state(style);
|
|
|
|
gtk_style_context_get(style, state_flags,
|
|
|
|
"min-height", height,
|
|
|
|
"min-width", width,
|
|
|
|
nullptr);
|
|
|
|
|
|
|
|
GtkBorder border, padding, margin;
|
|
|
|
gtk_style_context_get_border(style, state_flags, &border);
|
|
|
|
gtk_style_context_get_padding(style, state_flags, &padding);
|
|
|
|
gtk_style_context_get_margin(style, state_flags, &margin);
|
|
|
|
|
|
|
|
*width += border.left + border.right + margin.left + margin.right +
|
|
|
|
padding.left + padding.right;
|
|
|
|
*height += border.top + border.bottom + margin.top + margin.bottom +
|
|
|
|
padding.top + padding.bottom;
|
|
|
|
}
|
|
|
|
|
2017-03-27 21:32:25 +03:00
|
|
|
static MozGtkSize
|
|
|
|
GetMinMarginBox(WidgetNodeType aNodeType)
|
|
|
|
{
|
|
|
|
gint width, height;
|
|
|
|
moz_gtk_get_widget_min_size(aNodeType, &width, &height);
|
|
|
|
return {width, height};
|
|
|
|
}
|
|
|
|
|
2016-11-11 01:31:29 +03:00
|
|
|
static void
|
2018-02-23 12:37:07 +03:00
|
|
|
Inset(GdkRectangle* rect, const GtkBorder& aBorder)
|
2016-11-11 01:31:29 +03:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(rect);
|
|
|
|
rect->x += aBorder.left;
|
|
|
|
rect->y += aBorder.top;
|
|
|
|
rect->width -= aBorder.left + aBorder.right;
|
|
|
|
rect->height -= aBorder.top + aBorder.bottom;
|
|
|
|
}
|
|
|
|
|
2016-11-21 07:16:37 +03:00
|
|
|
// Inset a rectangle by the margins specified in a style context.
|
Bug 1289148 - Fixing scrollbar metrics for GTK >= 3.20 r=karlt
The Gtk 3.20 scrollbars has moved towards usual box model. The scrollbar,
trough,thumb and scrollbar button can now have margin, padding and border set,
different for each direction (ie. left, right, bottom, top). The scrollbar
metrics become ignored in Gtk 3.20 and later.
* Draw scrollbar element [for GTK 3.20+]
* The border for scrollbar, trough, thumb and scrollbar buttons is newly
calculated as margin+padding+border [for GTK 3.20+].
* The margin is subtracted for scrollbar, trough and sb buttons during paint
function [for GTK 3.6+]
* All scrollbar widget's borders transfered from
nsNativeThemeGTK::GetWidgetBorder to the moz_gtk_get_widget_border.
* Added helper function NativeThemeToGtkTheme for mapping mozilla's widget type
to the gtk widget type.
* Scrollbar troughs are now drawn even when there is not enough room for
the thumb [GTK 3.20+]
MozReview-Commit-ID: jd2q67gKM1
--HG--
extra : rebase_source : ecc8b85401845113d84c6c5a48219a0c3d4f8de3
2016-10-17 01:37:13 +03:00
|
|
|
static void
|
2016-11-21 07:16:37 +03:00
|
|
|
InsetByMargin(GdkRectangle* rect, GtkStyleContext* style)
|
Bug 1289148 - Fixing scrollbar metrics for GTK >= 3.20 r=karlt
The Gtk 3.20 scrollbars has moved towards usual box model. The scrollbar,
trough,thumb and scrollbar button can now have margin, padding and border set,
different for each direction (ie. left, right, bottom, top). The scrollbar
metrics become ignored in Gtk 3.20 and later.
* Draw scrollbar element [for GTK 3.20+]
* The border for scrollbar, trough, thumb and scrollbar buttons is newly
calculated as margin+padding+border [for GTK 3.20+].
* The margin is subtracted for scrollbar, trough and sb buttons during paint
function [for GTK 3.6+]
* All scrollbar widget's borders transfered from
nsNativeThemeGTK::GetWidgetBorder to the moz_gtk_get_widget_border.
* Added helper function NativeThemeToGtkTheme for mapping mozilla's widget type
to the gtk widget type.
* Scrollbar troughs are now drawn even when there is not enough room for
the thumb [GTK 3.20+]
MozReview-Commit-ID: jd2q67gKM1
--HG--
extra : rebase_source : ecc8b85401845113d84c6c5a48219a0c3d4f8de3
2016-10-17 01:37:13 +03:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(rect);
|
|
|
|
GtkBorder margin;
|
|
|
|
|
|
|
|
gtk_style_context_get_margin(style, gtk_style_context_get_state(style),
|
|
|
|
&margin);
|
2016-11-21 07:16:37 +03:00
|
|
|
Inset(rect, margin);
|
Bug 1289148 - Fixing scrollbar metrics for GTK >= 3.20 r=karlt
The Gtk 3.20 scrollbars has moved towards usual box model. The scrollbar,
trough,thumb and scrollbar button can now have margin, padding and border set,
different for each direction (ie. left, right, bottom, top). The scrollbar
metrics become ignored in Gtk 3.20 and later.
* Draw scrollbar element [for GTK 3.20+]
* The border for scrollbar, trough, thumb and scrollbar buttons is newly
calculated as margin+padding+border [for GTK 3.20+].
* The margin is subtracted for scrollbar, trough and sb buttons during paint
function [for GTK 3.6+]
* All scrollbar widget's borders transfered from
nsNativeThemeGTK::GetWidgetBorder to the moz_gtk_get_widget_border.
* Added helper function NativeThemeToGtkTheme for mapping mozilla's widget type
to the gtk widget type.
* Scrollbar troughs are now drawn even when there is not enough room for
the thumb [GTK 3.20+]
MozReview-Commit-ID: jd2q67gKM1
--HG--
extra : rebase_source : ecc8b85401845113d84c6c5a48219a0c3d4f8de3
2016-10-17 01:37:13 +03:00
|
|
|
}
|
|
|
|
|
2016-11-21 07:27:11 +03:00
|
|
|
// Inset a rectangle by the border and padding specified in a style context.
|
|
|
|
static void
|
|
|
|
InsetByBorderPadding(GdkRectangle* rect, GtkStyleContext* style)
|
|
|
|
{
|
|
|
|
GtkStateFlags state = gtk_style_context_get_state(style);
|
|
|
|
GtkBorder padding, border;
|
|
|
|
|
|
|
|
gtk_style_context_get_padding(style, state, &padding);
|
|
|
|
Inset(rect, padding);
|
|
|
|
gtk_style_context_get_border(style, state, &border);
|
|
|
|
Inset(rect, border);
|
|
|
|
}
|
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
static gint
|
Bug 1289148 - Fixing scrollbar metrics for GTK >= 3.20 r=karlt
The Gtk 3.20 scrollbars has moved towards usual box model. The scrollbar,
trough,thumb and scrollbar button can now have margin, padding and border set,
different for each direction (ie. left, right, bottom, top). The scrollbar
metrics become ignored in Gtk 3.20 and later.
* Draw scrollbar element [for GTK 3.20+]
* The border for scrollbar, trough, thumb and scrollbar buttons is newly
calculated as margin+padding+border [for GTK 3.20+].
* The margin is subtracted for scrollbar, trough and sb buttons during paint
function [for GTK 3.6+]
* All scrollbar widget's borders transfered from
nsNativeThemeGTK::GetWidgetBorder to the moz_gtk_get_widget_border.
* Added helper function NativeThemeToGtkTheme for mapping mozilla's widget type
to the gtk widget type.
* Scrollbar troughs are now drawn even when there is not enough room for
the thumb [GTK 3.20+]
MozReview-Commit-ID: jd2q67gKM1
--HG--
extra : rebase_source : ecc8b85401845113d84c6c5a48219a0c3d4f8de3
2016-10-17 01:37:13 +03:00
|
|
|
moz_gtk_scrollbar_button_paint(cairo_t *cr, const GdkRectangle* aRect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkWidgetState* state,
|
2012-02-10 17:15:28 +04:00
|
|
|
GtkScrollbarButtonFlags flags,
|
|
|
|
GtkTextDirection direction)
|
|
|
|
{
|
|
|
|
GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
|
|
|
|
GdkRectangle arrow_rect;
|
|
|
|
gdouble arrow_angle;
|
|
|
|
GtkStyleContext* style;
|
|
|
|
gint arrow_displacement_x, arrow_displacement_y;
|
|
|
|
|
2016-05-09 02:08:26 +03:00
|
|
|
GtkWidget *scrollbar =
|
|
|
|
GetWidget(flags & MOZ_GTK_STEPPER_VERTICAL ?
|
|
|
|
MOZ_GTK_SCROLLBAR_VERTICAL : MOZ_GTK_SCROLLBAR_HORIZONTAL);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
|
|
|
gtk_widget_set_direction(scrollbar, direction);
|
|
|
|
|
|
|
|
if (flags & MOZ_GTK_STEPPER_VERTICAL) {
|
2017-12-19 13:38:59 +03:00
|
|
|
arrow_angle = (flags & MOZ_GTK_STEPPER_DOWN) ? ARROW_DOWN : ARROW_UP;
|
2012-02-10 17:15:28 +04:00
|
|
|
} else {
|
2017-12-19 13:38:59 +03:00
|
|
|
arrow_angle = (flags & MOZ_GTK_STEPPER_DOWN) ? ARROW_RIGHT : ARROW_LEFT;
|
2012-02-10 17:15:28 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
style = gtk_widget_get_style_context(scrollbar);
|
2017-12-19 13:38:59 +03:00
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
gtk_style_context_save(style);
|
2015-10-22 02:00:00 +03:00
|
|
|
gtk_style_context_add_class(style, GTK_STYLE_CLASS_BUTTON);
|
2012-02-10 17:15:28 +04:00
|
|
|
gtk_style_context_set_state(style, state_flags);
|
2015-10-22 02:00:00 +03:00
|
|
|
if (arrow_angle == ARROW_RIGHT) {
|
|
|
|
gtk_style_context_add_class(style, GTK_STYLE_CLASS_RIGHT);
|
|
|
|
} else if (arrow_angle == ARROW_DOWN) {
|
|
|
|
gtk_style_context_add_class(style, GTK_STYLE_CLASS_BOTTOM);
|
|
|
|
} else if (arrow_angle == ARROW_LEFT) {
|
|
|
|
gtk_style_context_add_class(style, GTK_STYLE_CLASS_LEFT);
|
|
|
|
} else {
|
|
|
|
gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOP);
|
|
|
|
}
|
2016-01-07 07:55:00 +03:00
|
|
|
|
Bug 1289148 - Fixing scrollbar metrics for GTK >= 3.20 r=karlt
The Gtk 3.20 scrollbars has moved towards usual box model. The scrollbar,
trough,thumb and scrollbar button can now have margin, padding and border set,
different for each direction (ie. left, right, bottom, top). The scrollbar
metrics become ignored in Gtk 3.20 and later.
* Draw scrollbar element [for GTK 3.20+]
* The border for scrollbar, trough, thumb and scrollbar buttons is newly
calculated as margin+padding+border [for GTK 3.20+].
* The margin is subtracted for scrollbar, trough and sb buttons during paint
function [for GTK 3.6+]
* All scrollbar widget's borders transfered from
nsNativeThemeGTK::GetWidgetBorder to the moz_gtk_get_widget_border.
* Added helper function NativeThemeToGtkTheme for mapping mozilla's widget type
to the gtk widget type.
* Scrollbar troughs are now drawn even when there is not enough room for
the thumb [GTK 3.20+]
MozReview-Commit-ID: jd2q67gKM1
--HG--
extra : rebase_source : ecc8b85401845113d84c6c5a48219a0c3d4f8de3
2016-10-17 01:37:13 +03:00
|
|
|
GdkRectangle rect = *aRect;
|
|
|
|
if (gtk_check_version(3,20,0) == nullptr) {
|
|
|
|
// The "trough-border" is not used since GTK 3.20. The stepper margin
|
|
|
|
// box occupies the full width of the "contents" gadget content box.
|
2016-11-21 07:16:37 +03:00
|
|
|
InsetByMargin(&rect, style);
|
2016-01-07 07:55:00 +03:00
|
|
|
} else {
|
2017-03-27 21:32:25 +03:00
|
|
|
// Scrollbar button has to be inset by trough_border because its DOM
|
|
|
|
// element is filling width of vertical scrollbar's track (or height
|
|
|
|
// in case of horizontal scrollbars).
|
|
|
|
GtkOrientation orientation = flags & MOZ_GTK_STEPPER_VERTICAL ?
|
|
|
|
GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL;
|
|
|
|
const auto& metrics = sScrollbarMetrics[orientation];
|
|
|
|
if (!metrics.initialized) {
|
|
|
|
NS_WARNING("Didn't measure before drawing?");
|
|
|
|
}
|
|
|
|
if (flags & MOZ_GTK_STEPPER_VERTICAL) {
|
|
|
|
rect.x += metrics.border.track.left;
|
|
|
|
rect.width = metrics.size.thumb.width;
|
|
|
|
} else {
|
|
|
|
rect.y += metrics.border.track.top;
|
|
|
|
rect.height = metrics.size.thumb.height;
|
|
|
|
}
|
2016-01-07 07:55:00 +03:00
|
|
|
}
|
|
|
|
|
Bug 1289148 - Fixing scrollbar metrics for GTK >= 3.20 r=karlt
The Gtk 3.20 scrollbars has moved towards usual box model. The scrollbar,
trough,thumb and scrollbar button can now have margin, padding and border set,
different for each direction (ie. left, right, bottom, top). The scrollbar
metrics become ignored in Gtk 3.20 and later.
* Draw scrollbar element [for GTK 3.20+]
* The border for scrollbar, trough, thumb and scrollbar buttons is newly
calculated as margin+padding+border [for GTK 3.20+].
* The margin is subtracted for scrollbar, trough and sb buttons during paint
function [for GTK 3.6+]
* All scrollbar widget's borders transfered from
nsNativeThemeGTK::GetWidgetBorder to the moz_gtk_get_widget_border.
* Added helper function NativeThemeToGtkTheme for mapping mozilla's widget type
to the gtk widget type.
* Scrollbar troughs are now drawn even when there is not enough room for
the thumb [GTK 3.20+]
MozReview-Commit-ID: jd2q67gKM1
--HG--
extra : rebase_source : ecc8b85401845113d84c6c5a48219a0c3d4f8de3
2016-10-17 01:37:13 +03:00
|
|
|
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);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
Bug 1289148 - Fixing scrollbar metrics for GTK >= 3.20 r=karlt
The Gtk 3.20 scrollbars has moved towards usual box model. The scrollbar,
trough,thumb and scrollbar button can now have margin, padding and border set,
different for each direction (ie. left, right, bottom, top). The scrollbar
metrics become ignored in Gtk 3.20 and later.
* Draw scrollbar element [for GTK 3.20+]
* The border for scrollbar, trough, thumb and scrollbar buttons is newly
calculated as margin+padding+border [for GTK 3.20+].
* The margin is subtracted for scrollbar, trough and sb buttons during paint
function [for GTK 3.6+]
* All scrollbar widget's borders transfered from
nsNativeThemeGTK::GetWidgetBorder to the moz_gtk_get_widget_border.
* Added helper function NativeThemeToGtkTheme for mapping mozilla's widget type
to the gtk widget type.
* Scrollbar troughs are now drawn even when there is not enough room for
the thumb [GTK 3.20+]
MozReview-Commit-ID: jd2q67gKM1
--HG--
extra : rebase_source : ecc8b85401845113d84c6c5a48219a0c3d4f8de3
2016-10-17 01:37:13 +03:00
|
|
|
arrow_rect.width = rect.width / 2;
|
|
|
|
arrow_rect.height = rect.height / 2;
|
2017-12-19 13:38:59 +03:00
|
|
|
|
2015-10-22 02:00:00 +03:00
|
|
|
gfloat arrow_scaling;
|
2016-04-01 00:21:15 +03:00
|
|
|
gtk_style_context_get_style(style, "arrow-scaling", &arrow_scaling, NULL);
|
2015-10-22 02:00:00 +03:00
|
|
|
|
Bug 1289148 - Fixing scrollbar metrics for GTK >= 3.20 r=karlt
The Gtk 3.20 scrollbars has moved towards usual box model. The scrollbar,
trough,thumb and scrollbar button can now have margin, padding and border set,
different for each direction (ie. left, right, bottom, top). The scrollbar
metrics become ignored in Gtk 3.20 and later.
* Draw scrollbar element [for GTK 3.20+]
* The border for scrollbar, trough, thumb and scrollbar buttons is newly
calculated as margin+padding+border [for GTK 3.20+].
* The margin is subtracted for scrollbar, trough and sb buttons during paint
function [for GTK 3.6+]
* All scrollbar widget's borders transfered from
nsNativeThemeGTK::GetWidgetBorder to the moz_gtk_get_widget_border.
* Added helper function NativeThemeToGtkTheme for mapping mozilla's widget type
to the gtk widget type.
* Scrollbar troughs are now drawn even when there is not enough room for
the thumb [GTK 3.20+]
MozReview-Commit-ID: jd2q67gKM1
--HG--
extra : rebase_source : ecc8b85401845113d84c6c5a48219a0c3d4f8de3
2016-10-17 01:37:13 +03:00
|
|
|
gdouble arrow_size = MIN(rect.width, rect.height) * arrow_scaling;
|
|
|
|
arrow_rect.x = rect.x + (rect.width - arrow_size) / 2;
|
|
|
|
arrow_rect.y = rect.y + (rect.height - arrow_size) / 2;
|
2012-02-10 17:15:28 +04:00
|
|
|
|
|
|
|
if (state_flags & GTK_STATE_FLAG_ACTIVE) {
|
2016-04-01 00:21:15 +03:00
|
|
|
gtk_style_context_get_style(style,
|
|
|
|
"arrow-displacement-x", &arrow_displacement_x,
|
|
|
|
"arrow-displacement-y", &arrow_displacement_y,
|
|
|
|
NULL);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
|
|
|
arrow_rect.x += arrow_displacement_x;
|
|
|
|
arrow_rect.y += arrow_displacement_y;
|
|
|
|
}
|
2017-12-19 13:38:59 +03:00
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
gtk_render_arrow(style, cr, arrow_angle,
|
|
|
|
arrow_rect.x,
|
2017-12-19 13:38:59 +03:00
|
|
|
arrow_rect.y,
|
2015-10-22 02:00:00 +03:00
|
|
|
arrow_size);
|
2017-12-19 13:38:59 +03:00
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
gtk_style_context_restore(style);
|
|
|
|
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-06-13 05:35:00 +03:00
|
|
|
static void
|
|
|
|
moz_gtk_update_scrollbar_style(GtkStyleContext* style,
|
|
|
|
WidgetNodeType widget,
|
|
|
|
GtkTextDirection direction)
|
|
|
|
{
|
|
|
|
if (widget == MOZ_GTK_SCROLLBAR_HORIZONTAL) {
|
|
|
|
gtk_style_context_add_class(style, GTK_STYLE_CLASS_BOTTOM);
|
|
|
|
} else {
|
|
|
|
if (direction == GTK_TEXT_DIR_LTR) {
|
|
|
|
gtk_style_context_add_class(style, GTK_STYLE_CLASS_RIGHT);
|
|
|
|
gtk_style_context_remove_class(style, GTK_STYLE_CLASS_LEFT);
|
|
|
|
} else {
|
|
|
|
gtk_style_context_add_class(style, GTK_STYLE_CLASS_LEFT);
|
|
|
|
gtk_style_context_remove_class(style, GTK_STYLE_CLASS_RIGHT);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
moz_gtk_draw_styled_frame(GtkStyleContext* style, cairo_t *cr,
|
Bug 1289148 - Fixing scrollbar metrics for GTK >= 3.20 r=karlt
The Gtk 3.20 scrollbars has moved towards usual box model. The scrollbar,
trough,thumb and scrollbar button can now have margin, padding and border set,
different for each direction (ie. left, right, bottom, top). The scrollbar
metrics become ignored in Gtk 3.20 and later.
* Draw scrollbar element [for GTK 3.20+]
* The border for scrollbar, trough, thumb and scrollbar buttons is newly
calculated as margin+padding+border [for GTK 3.20+].
* The margin is subtracted for scrollbar, trough and sb buttons during paint
function [for GTK 3.6+]
* All scrollbar widget's borders transfered from
nsNativeThemeGTK::GetWidgetBorder to the moz_gtk_get_widget_border.
* Added helper function NativeThemeToGtkTheme for mapping mozilla's widget type
to the gtk widget type.
* Scrollbar troughs are now drawn even when there is not enough room for
the thumb [GTK 3.20+]
MozReview-Commit-ID: jd2q67gKM1
--HG--
extra : rebase_source : ecc8b85401845113d84c6c5a48219a0c3d4f8de3
2016-10-17 01:37:13 +03:00
|
|
|
const GdkRectangle* aRect, bool drawFocus)
|
2016-06-13 05:35:00 +03:00
|
|
|
{
|
Bug 1289148 - Fixing scrollbar metrics for GTK >= 3.20 r=karlt
The Gtk 3.20 scrollbars has moved towards usual box model. The scrollbar,
trough,thumb and scrollbar button can now have margin, padding and border set,
different for each direction (ie. left, right, bottom, top). The scrollbar
metrics become ignored in Gtk 3.20 and later.
* Draw scrollbar element [for GTK 3.20+]
* The border for scrollbar, trough, thumb and scrollbar buttons is newly
calculated as margin+padding+border [for GTK 3.20+].
* The margin is subtracted for scrollbar, trough and sb buttons during paint
function [for GTK 3.6+]
* All scrollbar widget's borders transfered from
nsNativeThemeGTK::GetWidgetBorder to the moz_gtk_get_widget_border.
* Added helper function NativeThemeToGtkTheme for mapping mozilla's widget type
to the gtk widget type.
* Scrollbar troughs are now drawn even when there is not enough room for
the thumb [GTK 3.20+]
MozReview-Commit-ID: jd2q67gKM1
--HG--
extra : rebase_source : ecc8b85401845113d84c6c5a48219a0c3d4f8de3
2016-10-17 01:37:13 +03:00
|
|
|
GdkRectangle rect = *aRect;
|
|
|
|
if (gtk_check_version(3, 6, 0) == nullptr) {
|
2016-11-21 07:16:37 +03:00
|
|
|
InsetByMargin(&rect, style);
|
Bug 1289148 - Fixing scrollbar metrics for GTK >= 3.20 r=karlt
The Gtk 3.20 scrollbars has moved towards usual box model. The scrollbar,
trough,thumb and scrollbar button can now have margin, padding and border set,
different for each direction (ie. left, right, bottom, top). The scrollbar
metrics become ignored in Gtk 3.20 and later.
* Draw scrollbar element [for GTK 3.20+]
* The border for scrollbar, trough, thumb and scrollbar buttons is newly
calculated as margin+padding+border [for GTK 3.20+].
* The margin is subtracted for scrollbar, trough and sb buttons during paint
function [for GTK 3.6+]
* All scrollbar widget's borders transfered from
nsNativeThemeGTK::GetWidgetBorder to the moz_gtk_get_widget_border.
* Added helper function NativeThemeToGtkTheme for mapping mozilla's widget type
to the gtk widget type.
* Scrollbar troughs are now drawn even when there is not enough room for
the thumb [GTK 3.20+]
MozReview-Commit-ID: jd2q67gKM1
--HG--
extra : rebase_source : ecc8b85401845113d84c6c5a48219a0c3d4f8de3
2016-10-17 01:37:13 +03:00
|
|
|
}
|
|
|
|
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);
|
2016-06-13 05:35:00 +03:00
|
|
|
if (drawFocus) {
|
|
|
|
gtk_render_focus(style, cr,
|
Bug 1289148 - Fixing scrollbar metrics for GTK >= 3.20 r=karlt
The Gtk 3.20 scrollbars has moved towards usual box model. The scrollbar,
trough,thumb and scrollbar button can now have margin, padding and border set,
different for each direction (ie. left, right, bottom, top). The scrollbar
metrics become ignored in Gtk 3.20 and later.
* Draw scrollbar element [for GTK 3.20+]
* The border for scrollbar, trough, thumb and scrollbar buttons is newly
calculated as margin+padding+border [for GTK 3.20+].
* The margin is subtracted for scrollbar, trough and sb buttons during paint
function [for GTK 3.6+]
* All scrollbar widget's borders transfered from
nsNativeThemeGTK::GetWidgetBorder to the moz_gtk_get_widget_border.
* Added helper function NativeThemeToGtkTheme for mapping mozilla's widget type
to the gtk widget type.
* Scrollbar troughs are now drawn even when there is not enough room for
the thumb [GTK 3.20+]
MozReview-Commit-ID: jd2q67gKM1
--HG--
extra : rebase_source : ecc8b85401845113d84c6c5a48219a0c3d4f8de3
2016-10-17 01:37:13 +03:00
|
|
|
rect.x, rect.y, rect.width, rect.height);
|
2016-06-13 05:35:00 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
static gint
|
2016-04-14 08:47:20 +03:00
|
|
|
moz_gtk_scrollbar_trough_paint(WidgetNodeType widget,
|
2017-03-27 21:32:55 +03:00
|
|
|
cairo_t *cr, const GdkRectangle* aRect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkWidgetState* state,
|
2012-02-10 17:15:28 +04:00
|
|
|
GtkTextDirection direction)
|
|
|
|
{
|
2017-03-27 21:32:55 +03:00
|
|
|
GdkRectangle rect = *aRect;
|
|
|
|
GtkStyleContext* style;
|
|
|
|
|
|
|
|
if (gtk_get_minor_version() >= 20) {
|
|
|
|
WidgetNodeType thumb = widget == MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL ?
|
|
|
|
MOZ_GTK_SCROLLBAR_THUMB_VERTICAL :
|
|
|
|
MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL;
|
|
|
|
MozGtkSize thumbSize = GetMinMarginBox(thumb);
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext(widget, direction);
|
2017-03-27 21:32:55 +03:00
|
|
|
MozGtkSize trackSize = GetMinContentBox(style);
|
|
|
|
trackSize.Include(thumbSize);
|
|
|
|
trackSize += GetMarginBorderPadding(style);
|
|
|
|
// Gecko's trough |aRect| fills available breadth, but GTK's trough is
|
|
|
|
// centered in the contents_gadget. The centering here round left
|
|
|
|
// and up, like gtk_box_gadget_allocate_child().
|
|
|
|
if (widget == MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL) {
|
|
|
|
rect.x += (rect.width - trackSize.width)/2;
|
|
|
|
rect.width = trackSize.width;
|
|
|
|
} else {
|
|
|
|
rect.y += (rect.height - trackSize.height)/2;
|
|
|
|
rect.height = trackSize.height;
|
|
|
|
}
|
|
|
|
} else {
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext(widget, direction);
|
2017-03-27 21:32:55 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
moz_gtk_draw_styled_frame(style, cr, &rect, state->focused);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
Bug 1289148 - Fixing scrollbar metrics for GTK >= 3.20 r=karlt
The Gtk 3.20 scrollbars has moved towards usual box model. The scrollbar,
trough,thumb and scrollbar button can now have margin, padding and border set,
different for each direction (ie. left, right, bottom, top). The scrollbar
metrics become ignored in Gtk 3.20 and later.
* Draw scrollbar element [for GTK 3.20+]
* The border for scrollbar, trough, thumb and scrollbar buttons is newly
calculated as margin+padding+border [for GTK 3.20+].
* The margin is subtracted for scrollbar, trough and sb buttons during paint
function [for GTK 3.6+]
* All scrollbar widget's borders transfered from
nsNativeThemeGTK::GetWidgetBorder to the moz_gtk_get_widget_border.
* Added helper function NativeThemeToGtkTheme for mapping mozilla's widget type
to the gtk widget type.
* Scrollbar troughs are now drawn even when there is not enough room for
the thumb [GTK 3.20+]
MozReview-Commit-ID: jd2q67gKM1
--HG--
extra : rebase_source : ecc8b85401845113d84c6c5a48219a0c3d4f8de3
2016-10-17 01:37:13 +03:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
2012-02-10 17:15:28 +04:00
|
|
|
|
Bug 1289148 - Fixing scrollbar metrics for GTK >= 3.20 r=karlt
The Gtk 3.20 scrollbars has moved towards usual box model. The scrollbar,
trough,thumb and scrollbar button can now have margin, padding and border set,
different for each direction (ie. left, right, bottom, top). The scrollbar
metrics become ignored in Gtk 3.20 and later.
* Draw scrollbar element [for GTK 3.20+]
* The border for scrollbar, trough, thumb and scrollbar buttons is newly
calculated as margin+padding+border [for GTK 3.20+].
* The margin is subtracted for scrollbar, trough and sb buttons during paint
function [for GTK 3.6+]
* All scrollbar widget's borders transfered from
nsNativeThemeGTK::GetWidgetBorder to the moz_gtk_get_widget_border.
* Added helper function NativeThemeToGtkTheme for mapping mozilla's widget type
to the gtk widget type.
* Scrollbar troughs are now drawn even when there is not enough room for
the thumb [GTK 3.20+]
MozReview-Commit-ID: jd2q67gKM1
--HG--
extra : rebase_source : ecc8b85401845113d84c6c5a48219a0c3d4f8de3
2016-10-17 01:37:13 +03:00
|
|
|
static gint
|
|
|
|
moz_gtk_scrollbar_paint(WidgetNodeType widget,
|
|
|
|
cairo_t *cr, const GdkRectangle* rect,
|
|
|
|
GtkWidgetState* state,
|
|
|
|
GtkTextDirection direction)
|
|
|
|
{
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style = GetStyleContext(widget, direction);
|
Bug 1289148 - Fixing scrollbar metrics for GTK >= 3.20 r=karlt
The Gtk 3.20 scrollbars has moved towards usual box model. The scrollbar,
trough,thumb and scrollbar button can now have margin, padding and border set,
different for each direction (ie. left, right, bottom, top). The scrollbar
metrics become ignored in Gtk 3.20 and later.
* Draw scrollbar element [for GTK 3.20+]
* The border for scrollbar, trough, thumb and scrollbar buttons is newly
calculated as margin+padding+border [for GTK 3.20+].
* The margin is subtracted for scrollbar, trough and sb buttons during paint
function [for GTK 3.6+]
* All scrollbar widget's borders transfered from
nsNativeThemeGTK::GetWidgetBorder to the moz_gtk_get_widget_border.
* Added helper function NativeThemeToGtkTheme for mapping mozilla's widget type
to the gtk widget type.
* Scrollbar troughs are now drawn even when there is not enough room for
the thumb [GTK 3.20+]
MozReview-Commit-ID: jd2q67gKM1
--HG--
extra : rebase_source : ecc8b85401845113d84c6c5a48219a0c3d4f8de3
2016-10-17 01:37:13 +03:00
|
|
|
moz_gtk_update_scrollbar_style(style, widget, direction);
|
|
|
|
|
|
|
|
moz_gtk_draw_styled_frame(style, cr, rect, state->focused);
|
|
|
|
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext((widget == MOZ_GTK_SCROLLBAR_HORIZONTAL) ?
|
|
|
|
MOZ_GTK_SCROLLBAR_CONTENTS_HORIZONTAL :
|
|
|
|
MOZ_GTK_SCROLLBAR_CONTENTS_VERTICAL,
|
|
|
|
direction);
|
2016-06-13 05:35:00 +03:00
|
|
|
moz_gtk_draw_styled_frame(style, cr, rect, state->focused);
|
2016-05-09 02:08:26 +03:00
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
2016-04-14 08:47:20 +03:00
|
|
|
moz_gtk_scrollbar_thumb_paint(WidgetNodeType widget,
|
Bug 1289148 - Fixing scrollbar metrics for GTK >= 3.20 r=karlt
The Gtk 3.20 scrollbars has moved towards usual box model. The scrollbar,
trough,thumb and scrollbar button can now have margin, padding and border set,
different for each direction (ie. left, right, bottom, top). The scrollbar
metrics become ignored in Gtk 3.20 and later.
* Draw scrollbar element [for GTK 3.20+]
* The border for scrollbar, trough, thumb and scrollbar buttons is newly
calculated as margin+padding+border [for GTK 3.20+].
* The margin is subtracted for scrollbar, trough and sb buttons during paint
function [for GTK 3.6+]
* All scrollbar widget's borders transfered from
nsNativeThemeGTK::GetWidgetBorder to the moz_gtk_get_widget_border.
* Added helper function NativeThemeToGtkTheme for mapping mozilla's widget type
to the gtk widget type.
* Scrollbar troughs are now drawn even when there is not enough room for
the thumb [GTK 3.20+]
MozReview-Commit-ID: jd2q67gKM1
--HG--
extra : rebase_source : ecc8b85401845113d84c6c5a48219a0c3d4f8de3
2016-10-17 01:37:13 +03:00
|
|
|
cairo_t *cr, const GdkRectangle* aRect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkWidgetState* state,
|
2012-02-10 17:15:28 +04:00
|
|
|
GtkTextDirection direction)
|
|
|
|
{
|
|
|
|
GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
|
|
|
|
|
Bug 1289148 - Fixing scrollbar metrics for GTK >= 3.20 r=karlt
The Gtk 3.20 scrollbars has moved towards usual box model. The scrollbar,
trough,thumb and scrollbar button can now have margin, padding and border set,
different for each direction (ie. left, right, bottom, top). The scrollbar
metrics become ignored in Gtk 3.20 and later.
* Draw scrollbar element [for GTK 3.20+]
* The border for scrollbar, trough, thumb and scrollbar buttons is newly
calculated as margin+padding+border [for GTK 3.20+].
* The margin is subtracted for scrollbar, trough and sb buttons during paint
function [for GTK 3.6+]
* All scrollbar widget's borders transfered from
nsNativeThemeGTK::GetWidgetBorder to the moz_gtk_get_widget_border.
* Added helper function NativeThemeToGtkTheme for mapping mozilla's widget type
to the gtk widget type.
* Scrollbar troughs are now drawn even when there is not enough room for
the thumb [GTK 3.20+]
MozReview-Commit-ID: jd2q67gKM1
--HG--
extra : rebase_source : ecc8b85401845113d84c6c5a48219a0c3d4f8de3
2016-10-17 01:37:13 +03:00
|
|
|
GdkRectangle rect = *aRect;
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style = GetStyleContext(widget, direction, state_flags);
|
2016-11-21 07:16:37 +03:00
|
|
|
InsetByMargin(&rect, style);
|
2015-03-16 15:00:00 +03:00
|
|
|
|
|
|
|
gtk_render_slider(style, cr,
|
Bug 1289148 - Fixing scrollbar metrics for GTK >= 3.20 r=karlt
The Gtk 3.20 scrollbars has moved towards usual box model. The scrollbar,
trough,thumb and scrollbar button can now have margin, padding and border set,
different for each direction (ie. left, right, bottom, top). The scrollbar
metrics become ignored in Gtk 3.20 and later.
* Draw scrollbar element [for GTK 3.20+]
* The border for scrollbar, trough, thumb and scrollbar buttons is newly
calculated as margin+padding+border [for GTK 3.20+].
* The margin is subtracted for scrollbar, trough and sb buttons during paint
function [for GTK 3.6+]
* All scrollbar widget's borders transfered from
nsNativeThemeGTK::GetWidgetBorder to the moz_gtk_get_widget_border.
* Added helper function NativeThemeToGtkTheme for mapping mozilla's widget type
to the gtk widget type.
* Scrollbar troughs are now drawn even when there is not enough room for
the thumb [GTK 3.20+]
MozReview-Commit-ID: jd2q67gKM1
--HG--
extra : rebase_source : ecc8b85401845113d84c6c5a48219a0c3d4f8de3
2016-10-17 01:37:13 +03:00
|
|
|
rect.x,
|
|
|
|
rect.y,
|
|
|
|
rect.width,
|
|
|
|
rect.height,
|
2012-02-10 17:15:28 +04:00
|
|
|
(widget == MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL) ?
|
|
|
|
GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL);
|
|
|
|
|
|
|
|
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-11-29 05:43:13 +03:00
|
|
|
static gint
|
|
|
|
moz_gtk_inner_spin_paint(cairo_t *cr, GdkRectangle* rect,
|
|
|
|
GtkWidgetState* state,
|
|
|
|
GtkTextDirection direction)
|
|
|
|
{
|
|
|
|
GtkStyleContext* style = GetStyleContext(MOZ_GTK_SPINBUTTON, direction,
|
|
|
|
GetStateFlagsFromGtkWidgetState(state));
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
/* hard code these values */
|
|
|
|
GdkRectangle arrow_rect;
|
|
|
|
arrow_rect.width = 6;
|
|
|
|
arrow_rect.height = 6;
|
|
|
|
|
|
|
|
// align spin to the left
|
|
|
|
arrow_rect.x = rect->x;
|
|
|
|
|
|
|
|
// up button
|
|
|
|
arrow_rect.y = rect->y + (rect->height - arrow_rect.height) / 2 - 3;
|
|
|
|
gtk_render_arrow(style, cr, ARROW_UP,
|
|
|
|
arrow_rect.x, arrow_rect.y,
|
|
|
|
arrow_rect.width);
|
|
|
|
|
|
|
|
// down button
|
|
|
|
arrow_rect.y = rect->y + (rect->height - arrow_rect.height) / 2 + 3;
|
|
|
|
gtk_render_arrow(style, cr, ARROW_DOWN,
|
|
|
|
arrow_rect.x, arrow_rect.y,
|
|
|
|
arrow_rect.width);
|
|
|
|
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
static gint
|
|
|
|
moz_gtk_spin_paint(cairo_t *cr, GdkRectangle* rect,
|
|
|
|
GtkTextDirection direction)
|
|
|
|
{
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style = GetStyleContext(MOZ_GTK_SPINBUTTON, direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
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);
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
moz_gtk_spin_updown_paint(cairo_t *cr, GdkRectangle* rect,
|
|
|
|
gboolean isDown, GtkWidgetState* state,
|
|
|
|
GtkTextDirection direction)
|
|
|
|
{
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style = GetStyleContext(MOZ_GTK_SPINBUTTON, direction,
|
2016-07-20 02:57:00 +03:00
|
|
|
GetStateFlagsFromGtkWidgetState(state));
|
2012-02-10 17:15:28 +04:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
/* hard code these values */
|
2016-07-20 02:57:00 +03:00
|
|
|
GdkRectangle arrow_rect;
|
2012-02-10 17:15:28 +04:00
|
|
|
arrow_rect.width = 6;
|
|
|
|
arrow_rect.height = 6;
|
|
|
|
arrow_rect.x = rect->x + (rect->width - arrow_rect.width) / 2;
|
|
|
|
arrow_rect.y = rect->y + (rect->height - arrow_rect.height) / 2;
|
|
|
|
arrow_rect.y += isDown ? -1 : 1;
|
|
|
|
|
2017-12-19 13:38:59 +03:00
|
|
|
gtk_render_arrow(style, cr,
|
2012-02-10 17:15:28 +04:00
|
|
|
isDown ? ARROW_DOWN : ARROW_UP,
|
|
|
|
arrow_rect.x, arrow_rect.y,
|
|
|
|
arrow_rect.width);
|
2016-07-20 02:57:00 +03:00
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2013-07-01 17:48:18 +04:00
|
|
|
/* See gtk_range_draw() for reference.
|
|
|
|
*/
|
2012-02-10 17:15:28 +04:00
|
|
|
static gint
|
|
|
|
moz_gtk_scale_paint(cairo_t *cr, GdkRectangle* rect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkWidgetState* state,
|
2012-02-10 17:15:28 +04:00
|
|
|
GtkOrientation flags, GtkTextDirection direction)
|
|
|
|
{
|
|
|
|
GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
|
2015-07-30 12:29:00 +03:00
|
|
|
gint x, y, width, height, min_width, min_height;
|
2012-02-10 17:15:28 +04:00
|
|
|
GtkStyleContext* style;
|
2013-07-01 17:48:18 +04:00
|
|
|
GtkBorder margin;
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2015-07-30 12:29:00 +03:00
|
|
|
moz_gtk_get_scale_metrics(flags, &min_width, &min_height);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2016-08-19 12:20:00 +03:00
|
|
|
WidgetNodeType widget = (flags == GTK_ORIENTATION_HORIZONTAL) ?
|
|
|
|
MOZ_GTK_SCALE_TROUGH_HORIZONTAL :
|
|
|
|
MOZ_GTK_SCALE_TROUGH_VERTICAL;
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext(widget, direction, state_flags);
|
2016-08-19 12:20:00 +03:00
|
|
|
gtk_style_context_get_margin(style, state_flags, &margin);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2015-07-30 12:29:00 +03:00
|
|
|
// Clamp the dimension perpendicular to the direction that the slider crosses
|
|
|
|
// to the minimum size.
|
2012-02-10 17:15:28 +04:00
|
|
|
if (flags == GTK_ORIENTATION_HORIZONTAL) {
|
2015-07-30 12:29:00 +03:00
|
|
|
width = rect->width - (margin.left + margin.right);
|
|
|
|
height = min_height - (margin.top + margin.bottom);
|
|
|
|
x = rect->x + margin.left;
|
|
|
|
y = rect->y + (rect->height - height)/2;
|
|
|
|
} else {
|
|
|
|
width = min_width - (margin.left + margin.right);
|
|
|
|
height = rect->height - (margin.top + margin.bottom);
|
|
|
|
x = rect->x + (rect->width - width)/2;
|
|
|
|
y = rect->y + margin.top;
|
2012-02-10 17:15:28 +04:00
|
|
|
}
|
|
|
|
|
2015-07-30 12:29:00 +03:00
|
|
|
gtk_render_background(style, cr, x, y, width, height);
|
|
|
|
gtk_render_frame(style, cr, x, y, width, height);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
|
|
|
if (state->focused)
|
2017-12-19 13:38:59 +03:00
|
|
|
gtk_render_focus(style, cr,
|
2012-02-10 17:15:28 +04:00
|
|
|
rect->x, rect->y, rect->width, rect->height);
|
2016-08-19 12:20:00 +03:00
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
moz_gtk_scale_thumb_paint(cairo_t *cr, GdkRectangle* rect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkWidgetState* state,
|
2012-02-10 17:15:28 +04:00
|
|
|
GtkOrientation flags, GtkTextDirection direction)
|
|
|
|
{
|
|
|
|
GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
|
|
|
|
GtkStyleContext* style;
|
|
|
|
gint thumb_width, thumb_height, x, y;
|
|
|
|
|
2017-12-19 13:38:59 +03:00
|
|
|
/* determine the thumb size, and position the thumb in the center in the opposite axis
|
2012-02-10 17:15:28 +04:00
|
|
|
*/
|
|
|
|
if (flags == GTK_ORIENTATION_HORIZONTAL) {
|
|
|
|
moz_gtk_get_scalethumb_metrics(GTK_ORIENTATION_HORIZONTAL, &thumb_width, &thumb_height);
|
|
|
|
x = rect->x;
|
|
|
|
y = rect->y + (rect->height - thumb_height) / 2;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
moz_gtk_get_scalethumb_metrics(GTK_ORIENTATION_VERTICAL, &thumb_height, &thumb_width);
|
|
|
|
x = rect->x + (rect->width - thumb_width) / 2;
|
|
|
|
y = rect->y;
|
|
|
|
}
|
|
|
|
|
2016-08-19 12:20:00 +03:00
|
|
|
WidgetNodeType widget = (flags == GTK_ORIENTATION_HORIZONTAL) ?
|
|
|
|
MOZ_GTK_SCALE_THUMB_HORIZONTAL :
|
|
|
|
MOZ_GTK_SCALE_THUMB_VERTICAL;
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext(widget, direction, state_flags);
|
2012-02-10 17:15:28 +04:00
|
|
|
gtk_render_slider(style, cr, x, y, thumb_width, thumb_height, flags);
|
2016-08-19 12:20:00 +03:00
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
moz_gtk_gripper_paint(cairo_t *cr, GdkRectangle* rect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkWidgetState* state,
|
2012-02-10 17:15:28 +04:00
|
|
|
GtkTextDirection direction)
|
|
|
|
{
|
2016-07-18 06:29:00 +03:00
|
|
|
GtkStyleContext* style =
|
2017-09-05 00:16:01 +03:00
|
|
|
GetStyleContext(MOZ_GTK_GRIPPER, direction,
|
|
|
|
GetStateFlagsFromGtkWidgetState(state));
|
2012-02-10 17:15:28 +04:00
|
|
|
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);
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
moz_gtk_hpaned_paint(cairo_t *cr, GdkRectangle* rect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkWidgetState* state)
|
2012-02-10 17:15:28 +04:00
|
|
|
{
|
2016-07-29 06:30:00 +03:00
|
|
|
GtkStyleContext* style =
|
2017-09-05 00:16:01 +03:00
|
|
|
GetStyleContext(MOZ_GTK_SPLITTER_SEPARATOR_HORIZONTAL,
|
|
|
|
GTK_TEXT_DIR_LTR,
|
|
|
|
GetStateFlagsFromGtkWidgetState(state));
|
2012-02-10 17:15:28 +04:00
|
|
|
gtk_render_handle(style, cr,
|
|
|
|
rect->x, rect->y, rect->width, rect->height);
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
moz_gtk_vpaned_paint(cairo_t *cr, GdkRectangle* rect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkWidgetState* state)
|
2012-02-10 17:15:28 +04:00
|
|
|
{
|
2016-07-29 06:30:00 +03:00
|
|
|
GtkStyleContext* style =
|
2017-09-05 00:16:01 +03:00
|
|
|
GetStyleContext(MOZ_GTK_SPLITTER_SEPARATOR_VERTICAL,
|
|
|
|
GTK_TEXT_DIR_LTR,
|
|
|
|
GetStateFlagsFromGtkWidgetState(state));
|
2012-02-10 17:15:28 +04:00
|
|
|
gtk_render_handle(style, cr,
|
2017-12-19 13:38:59 +03:00
|
|
|
rect->x, rect->y, rect->width, rect->height);
|
2012-02-10 17:15:28 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2013-07-08 00:49:53 +04:00
|
|
|
// See gtk_entry_draw() for reference.
|
2012-02-10 17:15:28 +04:00
|
|
|
static gint
|
|
|
|
moz_gtk_entry_paint(cairo_t *cr, GdkRectangle* rect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkWidgetState* state,
|
2016-10-19 05:13:25 +03:00
|
|
|
GtkStyleContext* style)
|
2012-02-10 17:15:28 +04:00
|
|
|
{
|
|
|
|
gint x = rect->x, y = rect->y, width = rect->width, height = rect->height;
|
2014-06-14 16:48:08 +04:00
|
|
|
int draw_focus_outline_only = state->depressed; // NS_THEME_FOCUS_OUTLINE
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2014-06-14 16:48:08 +04:00
|
|
|
if (draw_focus_outline_only) {
|
|
|
|
// Inflate the given 'rect' with the focus outline size.
|
|
|
|
gint h, v;
|
2016-10-19 05:13:25 +03:00
|
|
|
moz_gtk_get_focus_outline_size(style, &h, &v);
|
2014-06-14 16:48:08 +04:00
|
|
|
rect->x -= h;
|
|
|
|
rect->width += 2 * h;
|
|
|
|
rect->y -= v;
|
|
|
|
rect->height += 2 * v;
|
|
|
|
width = rect->width;
|
|
|
|
height = rect->height;
|
2016-10-19 05:13:25 +03:00
|
|
|
} else {
|
2014-06-14 16:48:08 +04:00
|
|
|
gtk_render_background(style, cr, x, y, width, height);
|
|
|
|
}
|
2012-02-10 17:15:28 +04:00
|
|
|
gtk_render_frame(style, cr, x, y, width, height);
|
|
|
|
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-04-27 02:07:00 +03:00
|
|
|
static gint
|
2016-12-30 02:54:28 +03:00
|
|
|
moz_gtk_text_view_paint(cairo_t *cr, GdkRectangle* aRect,
|
2016-04-27 02:07:00 +03:00
|
|
|
GtkWidgetState* state,
|
|
|
|
GtkTextDirection direction)
|
|
|
|
{
|
2017-01-17 04:48:55 +03:00
|
|
|
// GtkTextView and GtkScrolledWindow do not set active and prelight flags.
|
|
|
|
// The use of focus with MOZ_GTK_SCROLLED_WINDOW here is questionable
|
|
|
|
// because a parent widget will not have focus when its child GtkTextView
|
|
|
|
// has focus, but perhaps this may help identify a focused textarea with
|
|
|
|
// some themes as GtkTextView backgrounds do not typically render
|
|
|
|
// differently with focus.
|
|
|
|
GtkStateFlags state_flags =
|
|
|
|
state->disabled ? GTK_STATE_FLAG_INSENSITIVE :
|
|
|
|
state->focused ? GTK_STATE_FLAG_FOCUSED :
|
|
|
|
GTK_STATE_FLAG_NORMAL;
|
2016-04-27 02:07:00 +03:00
|
|
|
|
2016-07-25 07:46:00 +03:00
|
|
|
GtkStyleContext* style_frame =
|
2017-09-05 00:16:01 +03:00
|
|
|
GetStyleContext(MOZ_GTK_SCROLLED_WINDOW, direction, state_flags);
|
2016-12-30 02:54:28 +03:00
|
|
|
gtk_render_frame(style_frame, cr,
|
|
|
|
aRect->x, aRect->y, aRect->width, aRect->height);
|
|
|
|
|
|
|
|
GdkRectangle rect = *aRect;
|
|
|
|
InsetByBorderPadding(&rect, style_frame);
|
2016-04-27 02:07:00 +03:00
|
|
|
|
2016-07-25 07:46:00 +03:00
|
|
|
GtkStyleContext* style =
|
2017-09-05 00:16:01 +03:00
|
|
|
GetStyleContext(MOZ_GTK_TEXT_VIEW, direction, state_flags);
|
2016-12-30 02:54:28 +03:00
|
|
|
gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height);
|
|
|
|
// There is a separate "text" window, which usually provides the
|
|
|
|
// background behind the text. However, this is transparent in Ambiance
|
|
|
|
// for GTK 3.20, in which case the MOZ_GTK_TEXT_VIEW background is
|
|
|
|
// visible.
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext(MOZ_GTK_TEXT_VIEW_TEXT, direction, state_flags);
|
2016-12-30 02:54:28 +03:00
|
|
|
gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height);
|
2016-04-27 02:07:00 +03:00
|
|
|
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-12-19 13:38:59 +03:00
|
|
|
static gint
|
2012-02-10 17:15:28 +04:00
|
|
|
moz_gtk_treeview_paint(cairo_t *cr, GdkRectangle* rect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkWidgetState* state,
|
2012-02-10 17:15:28 +04:00
|
|
|
GtkTextDirection direction)
|
|
|
|
{
|
|
|
|
gint xthickness, ythickness;
|
|
|
|
GtkStyleContext *style;
|
|
|
|
GtkStyleContext *style_tree;
|
|
|
|
GtkStateFlags state_flags;
|
|
|
|
GtkBorder border;
|
|
|
|
|
|
|
|
/* only handle disabled and normal states, otherwise the whole background
|
|
|
|
* area will be painted differently with other states */
|
|
|
|
state_flags = state->disabled ? GTK_STATE_FLAG_INSENSITIVE : GTK_STATE_FLAG_NORMAL;
|
|
|
|
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext(MOZ_GTK_SCROLLED_WINDOW, direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
gtk_style_context_get_border(style, state_flags, &border);
|
|
|
|
xthickness = border.left;
|
2017-12-19 13:38:59 +03:00
|
|
|
ythickness = border.top;
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2017-09-05 00:16:01 +03:00
|
|
|
style_tree = GetStyleContext(MOZ_GTK_TREEVIEW_VIEW, direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
gtk_render_background(style_tree, cr,
|
|
|
|
rect->x + xthickness, rect->y + ythickness,
|
|
|
|
rect->width - 2 * xthickness,
|
|
|
|
rect->height - 2 * ythickness);
|
2016-07-29 06:15:00 +03:00
|
|
|
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext(MOZ_GTK_SCROLLED_WINDOW, direction);
|
2017-12-19 13:38:59 +03:00
|
|
|
gtk_render_frame(style, cr,
|
|
|
|
rect->x, rect->y, rect->width, rect->height);
|
2012-02-10 17:15:28 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
moz_gtk_tree_header_cell_paint(cairo_t *cr, GdkRectangle* rect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkWidgetState* state,
|
2012-02-10 17:15:28 +04:00
|
|
|
gboolean isSorted, GtkTextDirection direction)
|
|
|
|
{
|
2013-02-20 17:50:51 +04:00
|
|
|
moz_gtk_button_paint(cr, rect, state, GTK_RELIEF_NORMAL,
|
2016-07-29 06:15:00 +03:00
|
|
|
GetWidget(MOZ_GTK_TREE_HEADER_CELL), direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
moz_gtk_tree_header_sort_arrow_paint(cairo_t *cr, GdkRectangle* rect,
|
|
|
|
GtkWidgetState* state, GtkArrowType arrow_type,
|
|
|
|
GtkTextDirection direction)
|
|
|
|
{
|
|
|
|
GdkRectangle arrow_rect;
|
|
|
|
gdouble arrow_angle;
|
|
|
|
GtkStyleContext* style;
|
|
|
|
|
|
|
|
/* hard code these values */
|
|
|
|
arrow_rect.width = 11;
|
|
|
|
arrow_rect.height = 11;
|
|
|
|
arrow_rect.x = rect->x + (rect->width - arrow_rect.width) / 2;
|
|
|
|
arrow_rect.y = rect->y + (rect->height - arrow_rect.height) / 2;
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext(MOZ_GTK_TREE_HEADER_SORTARROW, direction,
|
|
|
|
GetStateFlagsFromGtkWidgetState(state));
|
2012-02-10 17:15:28 +04:00
|
|
|
switch (arrow_type) {
|
|
|
|
case GTK_ARROW_LEFT:
|
|
|
|
arrow_angle = ARROW_LEFT;
|
|
|
|
break;
|
|
|
|
case GTK_ARROW_RIGHT:
|
|
|
|
arrow_angle = ARROW_RIGHT;
|
|
|
|
break;
|
|
|
|
case GTK_ARROW_DOWN:
|
|
|
|
arrow_angle = ARROW_DOWN;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
arrow_angle = ARROW_UP;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (arrow_type != GTK_ARROW_NONE)
|
|
|
|
gtk_render_arrow(style, cr, arrow_angle,
|
|
|
|
arrow_rect.x, arrow_rect.y,
|
|
|
|
arrow_rect.width);
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-12-19 13:38:59 +03:00
|
|
|
/* See gtk_expander_paint() for reference.
|
2013-07-30 18:03:14 +04:00
|
|
|
*/
|
2012-02-10 17:15:28 +04:00
|
|
|
static gint
|
|
|
|
moz_gtk_treeview_expander_paint(cairo_t *cr, GdkRectangle* rect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkWidgetState* state,
|
2012-02-10 17:15:28 +04:00
|
|
|
GtkExpanderStyle expander_state,
|
|
|
|
GtkTextDirection direction)
|
|
|
|
{
|
2013-08-26 19:08:29 +04:00
|
|
|
/* Because the frame we get is of the entire treeview, we can't get the precise
|
|
|
|
* event state of one expander, thus rendering hover and active feedback useless. */
|
2016-07-29 06:15:00 +03:00
|
|
|
GtkStateFlags state_flags = state->disabled ? GTK_STATE_FLAG_INSENSITIVE :
|
|
|
|
GTK_STATE_FLAG_NORMAL;
|
2013-07-30 18:03:14 +04:00
|
|
|
|
|
|
|
/* GTK_STATE_FLAG_ACTIVE controls expanded/colapsed state rendering
|
|
|
|
* in gtk_render_expander()
|
|
|
|
*/
|
2013-08-26 19:08:29 +04:00
|
|
|
if (expander_state == GTK_EXPANDER_EXPANDED)
|
2016-08-03 15:53:00 +03:00
|
|
|
state_flags = static_cast<GtkStateFlags>(state_flags|checkbox_check_state);
|
2013-07-30 18:03:14 +04:00
|
|
|
else
|
2016-08-03 15:53:00 +03:00
|
|
|
state_flags = static_cast<GtkStateFlags>(state_flags&~(checkbox_check_state));
|
2013-07-30 18:03:14 +04:00
|
|
|
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext *style = GetStyleContext(MOZ_GTK_TREEVIEW_EXPANDER,
|
|
|
|
direction, state_flags);
|
2012-02-10 17:15:28 +04:00
|
|
|
gtk_render_expander(style, cr,
|
2013-07-30 18:03:14 +04:00
|
|
|
rect->x,
|
|
|
|
rect->y,
|
|
|
|
rect->width,
|
|
|
|
rect->height);
|
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2013-07-01 17:48:18 +04:00
|
|
|
/* See gtk_separator_draw() for reference.
|
|
|
|
*/
|
2012-02-10 17:15:28 +04:00
|
|
|
static gint
|
|
|
|
moz_gtk_combo_box_paint(cairo_t *cr, GdkRectangle* rect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkWidgetState* state,
|
2015-11-18 04:11:58 +03:00
|
|
|
GtkTextDirection direction)
|
2012-02-10 17:15:28 +04:00
|
|
|
{
|
|
|
|
GdkRectangle arrow_rect, real_arrow_rect;
|
2015-12-17 09:24:21 +03:00
|
|
|
gint separator_width;
|
2012-02-10 17:15:28 +04:00
|
|
|
gboolean wide_separators;
|
|
|
|
GtkStyleContext* style;
|
|
|
|
GtkRequisition arrow_req;
|
|
|
|
|
2016-10-19 05:13:25 +03:00
|
|
|
GtkWidget* comboBoxButton = GetWidget(MOZ_GTK_COMBOBOX_BUTTON);
|
|
|
|
GtkWidget* comboBoxArrow = GetWidget(MOZ_GTK_COMBOBOX_ARROW);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
|
|
|
/* Also sets the direction on gComboBoxButtonWidget, which is then
|
|
|
|
* inherited by the separator and arrow */
|
2013-02-20 17:50:51 +04:00
|
|
|
moz_gtk_button_paint(cr, rect, state, GTK_RELIEF_NORMAL,
|
2016-10-19 05:13:25 +03:00
|
|
|
comboBoxButton, direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2016-10-19 05:13:25 +03:00
|
|
|
calculate_button_inner_rect(comboBoxButton, rect, &arrow_rect, direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
/* Now arrow_rect contains the inner rect ; we want to correct the width
|
|
|
|
* to what the arrow needs (see gtk_combo_box_size_allocate) */
|
2016-10-19 05:13:25 +03:00
|
|
|
gtk_widget_get_preferred_size(comboBoxArrow, NULL, &arrow_req);
|
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
if (direction == GTK_TEXT_DIR_LTR)
|
|
|
|
arrow_rect.x += arrow_rect.width - arrow_req.width;
|
|
|
|
arrow_rect.width = arrow_req.width;
|
|
|
|
|
2016-10-19 05:13:25 +03:00
|
|
|
calculate_arrow_rect(comboBoxArrow,
|
2012-02-10 17:15:28 +04:00
|
|
|
&arrow_rect, &real_arrow_rect, direction);
|
|
|
|
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext(MOZ_GTK_COMBOBOX_ARROW);
|
2012-02-10 17:15:28 +04:00
|
|
|
gtk_render_arrow(style, cr, ARROW_DOWN,
|
|
|
|
real_arrow_rect.x, real_arrow_rect.y,
|
|
|
|
real_arrow_rect.width);
|
|
|
|
|
|
|
|
/* If there is no separator in the theme, there's nothing left to do. */
|
2016-10-19 05:13:25 +03:00
|
|
|
GtkWidget* widget = GetWidget(MOZ_GTK_COMBOBOX_SEPARATOR);
|
|
|
|
if (!widget)
|
2012-02-10 17:15:28 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
2016-10-19 05:13:25 +03:00
|
|
|
style = gtk_widget_get_style_context(widget);
|
2016-04-01 00:21:15 +03:00
|
|
|
gtk_style_context_get_style(style,
|
|
|
|
"wide-separators", &wide_separators,
|
|
|
|
"separator-width", &separator_width,
|
|
|
|
NULL);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
|
|
|
if (wide_separators) {
|
|
|
|
if (direction == GTK_TEXT_DIR_LTR)
|
|
|
|
arrow_rect.x -= separator_width;
|
|
|
|
else
|
|
|
|
arrow_rect.x += arrow_rect.width;
|
2017-12-19 13:38:59 +03:00
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
gtk_render_frame(style, cr, arrow_rect.x, arrow_rect.y, separator_width, arrow_rect.height);
|
|
|
|
} else {
|
|
|
|
if (direction == GTK_TEXT_DIR_LTR) {
|
2013-07-01 17:48:18 +04:00
|
|
|
GtkBorder padding;
|
|
|
|
GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
|
|
|
|
gtk_style_context_get_padding(style, state_flags, &padding);
|
|
|
|
arrow_rect.x -= padding.left;
|
2012-02-10 17:15:28 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
arrow_rect.x += arrow_rect.width;
|
2017-12-19 13:38:59 +03:00
|
|
|
|
|
|
|
gtk_render_line(style, cr,
|
|
|
|
arrow_rect.x, arrow_rect.y,
|
2012-02-10 17:15:28 +04:00
|
|
|
arrow_rect.x, arrow_rect.y + arrow_rect.height);
|
|
|
|
}
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
moz_gtk_arrow_paint(cairo_t *cr, GdkRectangle* rect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkWidgetState* state,
|
2012-02-10 17:15:28 +04:00
|
|
|
GtkArrowType arrow_type, GtkTextDirection direction)
|
|
|
|
{
|
|
|
|
GdkRectangle arrow_rect;
|
2014-06-13 16:04:00 +04:00
|
|
|
gdouble arrow_angle;
|
2012-02-10 17:15:28 +04:00
|
|
|
|
|
|
|
if (direction == GTK_TEXT_DIR_RTL) {
|
2016-10-14 07:37:08 +03:00
|
|
|
if (arrow_type == GTK_ARROW_LEFT) {
|
|
|
|
arrow_type = GTK_ARROW_RIGHT;
|
|
|
|
} else if (arrow_type == GTK_ARROW_RIGHT) {
|
|
|
|
arrow_type = GTK_ARROW_LEFT;
|
|
|
|
}
|
2014-06-13 16:04:00 +04:00
|
|
|
}
|
|
|
|
switch (arrow_type) {
|
|
|
|
case GTK_ARROW_LEFT:
|
|
|
|
arrow_angle = ARROW_LEFT;
|
|
|
|
break;
|
|
|
|
case GTK_ARROW_RIGHT:
|
|
|
|
arrow_angle = ARROW_RIGHT;
|
|
|
|
break;
|
|
|
|
case GTK_ARROW_DOWN:
|
2012-02-10 17:15:28 +04:00
|
|
|
arrow_angle = ARROW_DOWN;
|
2014-06-13 16:04:00 +04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
arrow_angle = ARROW_UP;
|
|
|
|
break;
|
2012-02-10 17:15:28 +04:00
|
|
|
}
|
2016-07-20 02:57:00 +03:00
|
|
|
if (arrow_type == GTK_ARROW_NONE)
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
|
|
|
|
calculate_arrow_rect(GetWidget(MOZ_GTK_BUTTON_ARROW), rect, &arrow_rect,
|
|
|
|
direction);
|
|
|
|
GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style = GetStyleContext(MOZ_GTK_BUTTON_ARROW,
|
|
|
|
direction, state_flags);
|
2016-07-20 02:57:00 +03:00
|
|
|
gtk_render_arrow(style, cr, arrow_angle,
|
|
|
|
arrow_rect.x, arrow_rect.y, arrow_rect.width);
|
2012-02-10 17:15:28 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
moz_gtk_combo_box_entry_button_paint(cairo_t *cr, GdkRectangle* rect,
|
|
|
|
GtkWidgetState* state,
|
|
|
|
gboolean input_focus,
|
|
|
|
GtkTextDirection direction)
|
|
|
|
{
|
|
|
|
gint x_displacement, y_displacement;
|
|
|
|
GdkRectangle arrow_rect, real_arrow_rect;
|
|
|
|
GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
|
|
|
|
GtkStyleContext* style;
|
|
|
|
|
2016-10-19 05:13:25 +03:00
|
|
|
GtkWidget* comboBoxEntry = GetWidget(MOZ_GTK_COMBOBOX_ENTRY_BUTTON);
|
2013-02-20 17:50:51 +04:00
|
|
|
moz_gtk_button_paint(cr, rect, state, GTK_RELIEF_NORMAL,
|
2016-10-19 05:13:25 +03:00
|
|
|
comboBoxEntry, direction);
|
|
|
|
calculate_button_inner_rect(comboBoxEntry, rect, &arrow_rect, direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
|
|
|
if (state_flags & GTK_STATE_FLAG_ACTIVE) {
|
2016-10-19 05:13:25 +03:00
|
|
|
style = gtk_widget_get_style_context(comboBoxEntry);
|
|
|
|
gtk_style_context_get_style(style,
|
2016-04-01 00:21:15 +03:00
|
|
|
"child-displacement-x", &x_displacement,
|
|
|
|
"child-displacement-y", &y_displacement,
|
|
|
|
NULL);
|
2012-02-10 17:15:28 +04:00
|
|
|
arrow_rect.x += x_displacement;
|
|
|
|
arrow_rect.y += y_displacement;
|
|
|
|
}
|
|
|
|
|
2016-10-19 05:13:25 +03:00
|
|
|
calculate_arrow_rect(GetWidget(MOZ_GTK_COMBOBOX_ENTRY_ARROW),
|
2012-02-10 17:15:28 +04:00
|
|
|
&arrow_rect, &real_arrow_rect, direction);
|
|
|
|
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext(MOZ_GTK_COMBOBOX_ENTRY_ARROW);
|
2012-02-10 17:15:28 +04:00
|
|
|
gtk_render_arrow(style, cr, ARROW_DOWN,
|
|
|
|
real_arrow_rect.x, real_arrow_rect.y,
|
|
|
|
real_arrow_rect.width);
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
moz_gtk_container_paint(cairo_t *cr, GdkRectangle* rect,
|
2017-12-19 13:38:59 +03:00
|
|
|
GtkWidgetState* state,
|
2016-05-13 02:59:17 +03:00
|
|
|
WidgetNodeType widget_type,
|
|
|
|
GtkTextDirection direction)
|
2012-02-10 17:15:28 +04:00
|
|
|
{
|
|
|
|
GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style = GetStyleContext(widget_type, direction,
|
|
|
|
state_flags);
|
2012-02-10 17:15:28 +04:00
|
|
|
/* this is for drawing a prelight box */
|
|
|
|
if (state_flags & GTK_STATE_FLAG_PRELIGHT) {
|
|
|
|
gtk_render_background(style, cr,
|
|
|
|
rect->x, rect->y, rect->width, rect->height);
|
|
|
|
}
|
2016-05-13 02:59:17 +03:00
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
moz_gtk_toggle_label_paint(cairo_t *cr, GdkRectangle* rect,
|
2017-12-19 13:38:59 +03:00
|
|
|
GtkWidgetState* state,
|
2012-02-10 17:15:28 +04:00
|
|
|
gboolean isradio, GtkTextDirection direction)
|
|
|
|
{
|
|
|
|
if (!state->focused)
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
|
2016-07-28 11:13:00 +03:00
|
|
|
GtkStyleContext *style =
|
2017-09-05 00:16:01 +03:00
|
|
|
GetStyleContext(isradio ? MOZ_GTK_RADIOBUTTON_CONTAINER :
|
|
|
|
MOZ_GTK_CHECKBUTTON_CONTAINER,
|
|
|
|
direction,
|
|
|
|
GetStateFlagsFromGtkWidgetState(state));
|
2012-02-10 17:15:28 +04:00
|
|
|
gtk_render_focus(style, cr,
|
|
|
|
rect->x, rect->y, rect->width, rect->height);
|
2016-05-13 02:59:17 +03:00
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
moz_gtk_toolbar_paint(cairo_t *cr, GdkRectangle* rect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkTextDirection direction)
|
2012-02-10 17:15:28 +04:00
|
|
|
{
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style = GetStyleContext(MOZ_GTK_TOOLBAR, direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
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);
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2013-07-01 17:48:18 +04:00
|
|
|
/* See _gtk_toolbar_paint_space_line() for reference.
|
|
|
|
*/
|
2012-02-10 17:15:28 +04:00
|
|
|
static gint
|
|
|
|
moz_gtk_toolbar_separator_paint(cairo_t *cr, GdkRectangle* rect,
|
|
|
|
GtkTextDirection direction)
|
|
|
|
{
|
|
|
|
gint separator_width;
|
|
|
|
gint paint_width;
|
|
|
|
gboolean wide_separators;
|
2017-12-19 13:38:59 +03:00
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
/* Defined as constants in GTK+ 2.10.14 */
|
|
|
|
const double start_fraction = 0.2;
|
|
|
|
const double end_fraction = 0.8;
|
|
|
|
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style = GetStyleContext(MOZ_GTK_TOOLBAR);
|
2016-07-18 06:29:00 +03:00
|
|
|
gtk_style_context_get_style(style,
|
2016-04-01 00:21:15 +03:00
|
|
|
"wide-separators", &wide_separators,
|
|
|
|
"separator-width", &separator_width,
|
|
|
|
NULL);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext(MOZ_GTK_TOOLBAR_SEPARATOR, direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
if (wide_separators) {
|
|
|
|
if (separator_width > rect->width)
|
|
|
|
separator_width = rect->width;
|
2017-12-19 13:38:59 +03:00
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
gtk_render_frame(style, cr,
|
|
|
|
rect->x + (rect->width - separator_width) / 2,
|
|
|
|
rect->y + rect->height * start_fraction,
|
|
|
|
separator_width,
|
|
|
|
rect->height * (end_fraction - start_fraction));
|
|
|
|
} else {
|
2013-07-01 17:48:18 +04:00
|
|
|
GtkBorder padding;
|
2016-03-23 05:49:00 +03:00
|
|
|
gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding);
|
2017-12-19 13:38:59 +03:00
|
|
|
|
2013-07-01 17:48:18 +04:00
|
|
|
paint_width = padding.left;
|
2012-02-10 17:15:28 +04:00
|
|
|
if (paint_width > rect->width)
|
|
|
|
paint_width = rect->width;
|
2017-12-19 13:38:59 +03:00
|
|
|
|
|
|
|
gtk_render_line(style, cr,
|
2012-02-10 17:15:28 +04:00
|
|
|
rect->x + (rect->width - paint_width) / 2,
|
|
|
|
rect->y + rect->height * start_fraction,
|
|
|
|
rect->x + (rect->width - paint_width) / 2,
|
|
|
|
rect->y + rect->height * end_fraction);
|
|
|
|
}
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
2016-11-11 01:31:29 +03:00
|
|
|
moz_gtk_tooltip_paint(cairo_t *cr, const GdkRectangle* aRect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkTextDirection direction)
|
2012-02-10 17:15:28 +04:00
|
|
|
{
|
2016-11-11 01:31:29 +03:00
|
|
|
// 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
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style = GetStyleContext(MOZ_GTK_TOOLTIP, direction);
|
2016-11-11 01:31:29 +03:00
|
|
|
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.
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* boxStyle = GetStyleContext(MOZ_GTK_TOOLTIP_BOX, direction);
|
2016-11-11 01:31:29 +03:00
|
|
|
|
|
|
|
rect.x += 6;
|
|
|
|
rect.y += 6;
|
|
|
|
rect.width -= 12;
|
|
|
|
rect.height -= 12;
|
|
|
|
|
2016-11-21 07:16:37 +03:00
|
|
|
InsetByMargin(&rect, boxStyle);
|
2016-11-11 01:31:29 +03:00
|
|
|
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
|
2016-11-21 07:27:11 +03:00
|
|
|
InsetByBorderPadding(&rect, boxStyle);
|
2016-11-11 01:31:29 +03:00
|
|
|
|
|
|
|
GtkStyleContext* labelStyle =
|
2017-09-05 00:16:01 +03:00
|
|
|
GetStyleContext(MOZ_GTK_TOOLTIP_BOX_LABEL, direction);
|
2016-11-11 01:31:29 +03:00
|
|
|
moz_gtk_draw_styled_frame(labelStyle, cr, &rect, false);
|
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
moz_gtk_resizer_paint(cairo_t *cr, GdkRectangle* rect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkWidgetState* state,
|
2012-02-10 17:15:28 +04:00
|
|
|
GtkTextDirection direction)
|
|
|
|
{
|
2016-12-30 03:37:51 +03:00
|
|
|
GtkStyleContext* style =
|
2017-09-05 00:16:01 +03:00
|
|
|
GetStyleContext(MOZ_GTK_RESIZER, GTK_TEXT_DIR_LTR,
|
|
|
|
GetStateFlagsFromGtkWidgetState(state));
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2015-07-08 15:40:00 +03:00
|
|
|
// Workaround unico not respecting the text direction for resizers.
|
|
|
|
// See bug 1174248.
|
|
|
|
cairo_save(cr);
|
|
|
|
if (direction == GTK_TEXT_DIR_RTL) {
|
|
|
|
cairo_matrix_t mat;
|
|
|
|
cairo_matrix_init_translate(&mat, 2 * rect->x + rect->width, 0);
|
|
|
|
cairo_matrix_scale(&mat, -1, 1);
|
|
|
|
cairo_transform(cr, &mat);
|
|
|
|
}
|
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
gtk_render_handle(style, cr, rect->x, rect->y, rect->width, rect->height);
|
2015-07-08 15:40:00 +03:00
|
|
|
cairo_restore(cr);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
moz_gtk_frame_paint(cairo_t *cr, GdkRectangle* rect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkTextDirection direction)
|
2012-02-10 17:15:28 +04:00
|
|
|
{
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style = GetStyleContext(MOZ_GTK_FRAME, direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
moz_gtk_progressbar_paint(cairo_t *cr, GdkRectangle* rect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkTextDirection direction)
|
2012-02-10 17:15:28 +04:00
|
|
|
{
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style = GetStyleContext(MOZ_GTK_PROGRESS_TROUGH,
|
|
|
|
direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
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);
|
|
|
|
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
moz_gtk_progress_chunk_paint(cairo_t *cr, GdkRectangle* rect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkTextDirection direction,
|
2016-04-14 08:47:20 +03:00
|
|
|
WidgetNodeType widget)
|
2012-02-10 17:15:28 +04:00
|
|
|
{
|
2016-11-25 07:51:13 +03:00
|
|
|
GtkStyleContext* style =
|
2017-09-05 00:16:01 +03:00
|
|
|
GetStyleContext(MOZ_GTK_PROGRESS_CHUNK, direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
|
|
|
if (widget == MOZ_GTK_PROGRESS_CHUNK_INDETERMINATE ||
|
|
|
|
widget == MOZ_GTK_PROGRESS_CHUNK_VERTICAL_INDETERMINATE) {
|
|
|
|
/**
|
|
|
|
* The bar's size and the bar speed are set depending of the progress'
|
|
|
|
* size. These could also be constant for all progress bars easily.
|
|
|
|
*/
|
|
|
|
gboolean vertical = (widget == MOZ_GTK_PROGRESS_CHUNK_VERTICAL_INDETERMINATE);
|
|
|
|
|
|
|
|
/* The size of the dimension we are going to use for the animation. */
|
|
|
|
const gint progressSize = vertical ? rect->height : rect->width;
|
|
|
|
|
|
|
|
/* The bar is using a fifth of the element size, based on GtkProgressBar
|
|
|
|
* activity-blocks property. */
|
|
|
|
const gint barSize = MAX(1, progressSize / 5);
|
|
|
|
|
|
|
|
/* Represents the travel that has to be done for a complete cycle. */
|
|
|
|
const gint travel = 2 * (progressSize - barSize);
|
|
|
|
|
|
|
|
/* period equals to travel / pixelsPerMillisecond
|
|
|
|
* where pixelsPerMillisecond equals progressSize / 1000.0.
|
|
|
|
* This is equivalent to 1600. */
|
|
|
|
static const guint period = 1600;
|
|
|
|
const gint t = PR_IntervalToMilliseconds(PR_IntervalNow()) % period;
|
|
|
|
const gint dx = travel * t / period;
|
|
|
|
|
|
|
|
if (vertical) {
|
|
|
|
rect->y += (dx < travel / 2) ? dx : travel - dx;
|
|
|
|
rect->height = barSize;
|
|
|
|
} else {
|
|
|
|
rect->x += (dx < travel / 2) ? dx : travel - dx;
|
|
|
|
rect->width = barSize;
|
|
|
|
}
|
|
|
|
}
|
2015-10-24 08:14:09 +03:00
|
|
|
|
2015-07-15 18:47:00 +03:00
|
|
|
// gtk_render_activity was used to render progress chunks on GTK versions
|
|
|
|
// before 3.13.7, see bug 1173907.
|
2015-10-24 08:14:09 +03:00
|
|
|
if (!gtk_check_version(3, 13, 7)) {
|
|
|
|
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);
|
|
|
|
} else {
|
2015-07-15 18:47:00 +03:00
|
|
|
gtk_render_activity(style, cr, rect->x, rect->y, rect->width, rect->height);
|
2015-10-24 08:14:09 +03:00
|
|
|
}
|
2012-02-10 17:15:28 +04:00
|
|
|
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-08-22 06:13:00 +03:00
|
|
|
static gint
|
|
|
|
moz_gtk_get_tab_thickness(GtkStyleContext *style)
|
2012-02-10 17:15:28 +04:00
|
|
|
{
|
2015-04-30 08:31:00 +03:00
|
|
|
if (!notebook_has_tab_gap)
|
|
|
|
return 0; /* tabs do not overdraw the tabpanel border with "no gap" style */
|
|
|
|
|
2016-08-22 06:13:00 +03:00
|
|
|
GtkBorder border;
|
2016-03-23 05:49:00 +03:00
|
|
|
gtk_style_context_get_border(style, GTK_STATE_FLAG_NORMAL, &border);
|
2012-02-10 17:15:28 +04:00
|
|
|
if (border.top < 2)
|
|
|
|
return 2; /* some themes don't set ythickness correctly */
|
|
|
|
|
|
|
|
return border.top;
|
|
|
|
}
|
|
|
|
|
2016-08-22 06:13:00 +03:00
|
|
|
gint
|
|
|
|
moz_gtk_get_tab_thickness(WidgetNodeType aNodeType)
|
|
|
|
{
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext *style = GetStyleContext(aNodeType);
|
2016-08-22 06:13:00 +03:00
|
|
|
int thickness = moz_gtk_get_tab_thickness(style);
|
|
|
|
return thickness;
|
2014-09-04 07:17:00 +04:00
|
|
|
}
|
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
/* actual small tabs */
|
|
|
|
static gint
|
|
|
|
moz_gtk_tab_paint(cairo_t *cr, GdkRectangle* rect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkWidgetState* state,
|
2016-08-22 06:13:00 +03:00
|
|
|
GtkTabFlags flags, GtkTextDirection direction,
|
|
|
|
WidgetNodeType widget)
|
2012-02-10 17:15:28 +04:00
|
|
|
{
|
|
|
|
/* When the tab isn't selected, we just draw a notebook extension.
|
|
|
|
* When it is selected, we overwrite the adjacent border of the tabpanel
|
|
|
|
* touching the tab with a pierced border (called "the gap") to make the
|
|
|
|
* tab appear physically attached to the tabpanel; see details below. */
|
|
|
|
|
|
|
|
GtkStyleContext* style;
|
2014-09-04 07:17:00 +04:00
|
|
|
GdkRectangle tabRect;
|
2012-02-10 17:15:28 +04:00
|
|
|
GdkRectangle focusRect;
|
2013-12-02 20:53:09 +04:00
|
|
|
GdkRectangle backRect;
|
2014-09-04 07:17:00 +04:00
|
|
|
int initial_gap = 0;
|
2016-08-22 06:13:00 +03:00
|
|
|
bool isBottomTab = (widget == MOZ_GTK_TAB_BOTTOM);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext(widget, direction,
|
|
|
|
GetStateFlagsFromGtkTabFlags(flags));
|
2014-09-04 07:17:00 +04:00
|
|
|
tabRect = *rect;
|
|
|
|
|
|
|
|
if (flags & MOZ_GTK_TAB_FIRST) {
|
2016-04-01 00:21:15 +03:00
|
|
|
gtk_style_context_get_style(style, "initial-gap", &initial_gap, NULL);
|
2014-09-04 07:17:00 +04:00
|
|
|
tabRect.width -= initial_gap;
|
|
|
|
|
|
|
|
if (direction != GTK_TEXT_DIR_RTL) {
|
|
|
|
tabRect.x += initial_gap;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
focusRect = backRect = tabRect;
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2015-04-30 08:31:00 +03:00
|
|
|
if (notebook_has_tab_gap) {
|
|
|
|
if ((flags & MOZ_GTK_TAB_SELECTED) == 0) {
|
|
|
|
/* Only draw the tab */
|
2012-02-10 17:15:28 +04:00
|
|
|
gtk_render_extension(style, cr,
|
2015-04-30 08:31:00 +03:00
|
|
|
tabRect.x, tabRect.y, tabRect.width, tabRect.height,
|
2016-08-22 06:13:00 +03:00
|
|
|
isBottomTab ? GTK_POS_TOP : GTK_POS_BOTTOM );
|
2012-02-10 17:15:28 +04:00
|
|
|
} else {
|
2015-04-30 08:31:00 +03:00
|
|
|
/* Draw the tab and the gap
|
|
|
|
* We want the gap to be positioned exactly on the tabpanel top
|
|
|
|
* border; since tabbox.css may set a negative margin so that the tab
|
|
|
|
* frame rect already overlaps the tabpanel frame rect, we need to take
|
|
|
|
* that into account when drawing. To that effect, nsNativeThemeGTK
|
|
|
|
* passes us this negative margin (bmargin in the graphic below) in the
|
|
|
|
* lowest bits of |flags|. We use it to set gap_voffset, the distance
|
|
|
|
* between the top of the gap and the bottom of the tab (resp. the
|
|
|
|
* bottom of the gap and the top of the tab when we draw a bottom tab),
|
|
|
|
* while ensuring that the gap always touches the border of the tab,
|
|
|
|
* i.e. 0 <= gap_voffset <= gap_height, to avoid surprinsing results
|
|
|
|
* with big negative or positive margins.
|
|
|
|
* Here is a graphical explanation in the case of top tabs:
|
|
|
|
* ___________________________
|
|
|
|
* / \
|
|
|
|
* | T A B |
|
|
|
|
* ----------|. . . . . . . . . . . . . . .|----- top of tabpanel
|
|
|
|
* : ^ bmargin : ^
|
|
|
|
* : | (-negative margin, : |
|
|
|
|
* bottom : v passed in flags) : | gap_height
|
|
|
|
* of -> :.............................: | (the size of the
|
|
|
|
* the tab . part of the gap . | tabpanel top border)
|
|
|
|
* . outside of the tab . v
|
|
|
|
* ----------------------------------------------
|
|
|
|
*
|
2016-11-29 08:50:20 +03:00
|
|
|
* To draw the gap, we use gtk_render_frame_gap(), see comment in
|
|
|
|
* moz_gtk_tabpanels_paint(). This gap is made 3 * gap_height tall,
|
2015-04-30 08:31:00 +03:00
|
|
|
* which should suffice to ensure that the only visible border is the
|
|
|
|
* pierced one. If the tab is in the middle, we make the box_gap begin
|
|
|
|
* a bit to the left of the tab and end a bit to the right, adjusting
|
|
|
|
* the gap position so it still is under the tab, because we want the
|
|
|
|
* rendering of a gap in the middle of a tabpanel. This is the role of
|
|
|
|
* the gints gap_{l,r}_offset. On the contrary, if the tab is the
|
|
|
|
* first, we align the start border of the box_gap with the start
|
|
|
|
* border of the tab (left if LTR, right if RTL), by setting the
|
|
|
|
* appropriate offset to 0.*/
|
|
|
|
gint gap_loffset, gap_roffset, gap_voffset, gap_height;
|
|
|
|
|
|
|
|
/* Get height needed by the gap */
|
2016-08-22 06:13:00 +03:00
|
|
|
gap_height = moz_gtk_get_tab_thickness(style);
|
2015-04-30 08:31:00 +03:00
|
|
|
|
|
|
|
/* Extract gap_voffset from the first bits of flags */
|
|
|
|
gap_voffset = flags & MOZ_GTK_TAB_MARGIN_MASK;
|
|
|
|
if (gap_voffset > gap_height)
|
|
|
|
gap_voffset = gap_height;
|
|
|
|
|
|
|
|
/* Set gap_{l,r}_offset to appropriate values */
|
|
|
|
gap_loffset = gap_roffset = 20; /* should be enough */
|
|
|
|
if (flags & MOZ_GTK_TAB_FIRST) {
|
|
|
|
if (direction == GTK_TEXT_DIR_RTL)
|
|
|
|
gap_roffset = initial_gap;
|
|
|
|
else
|
|
|
|
gap_loffset = initial_gap;
|
|
|
|
}
|
|
|
|
|
2016-11-29 08:50:20 +03:00
|
|
|
GtkStyleContext* panelStyle =
|
2017-09-05 00:16:01 +03:00
|
|
|
GetStyleContext(MOZ_GTK_TABPANELS, direction);
|
2016-11-29 08:50:20 +03:00
|
|
|
|
2016-08-22 06:13:00 +03:00
|
|
|
if (isBottomTab) {
|
2015-04-30 08:31:00 +03:00
|
|
|
/* Draw the tab on bottom */
|
|
|
|
focusRect.y += gap_voffset;
|
|
|
|
focusRect.height -= gap_voffset;
|
|
|
|
|
|
|
|
gtk_render_extension(style, cr,
|
|
|
|
tabRect.x, tabRect.y + gap_voffset, tabRect.width,
|
|
|
|
tabRect.height - gap_voffset, GTK_POS_TOP);
|
|
|
|
|
|
|
|
backRect.y += (gap_voffset - gap_height);
|
|
|
|
backRect.height = gap_height;
|
|
|
|
|
|
|
|
/* Draw the gap; erase with background color before painting in
|
|
|
|
* case theme does not */
|
2016-11-29 08:50:20 +03:00
|
|
|
gtk_render_background(panelStyle, cr, backRect.x, backRect.y,
|
2015-04-30 08:31:00 +03:00
|
|
|
backRect.width, backRect.height);
|
|
|
|
cairo_save(cr);
|
|
|
|
cairo_rectangle(cr, backRect.x, backRect.y, backRect.width, backRect.height);
|
|
|
|
cairo_clip(cr);
|
|
|
|
|
2016-11-29 08:50:20 +03:00
|
|
|
gtk_render_frame_gap(panelStyle, cr,
|
2015-04-30 08:31:00 +03:00
|
|
|
tabRect.x - gap_loffset,
|
|
|
|
tabRect.y + gap_voffset - 3 * gap_height,
|
|
|
|
tabRect.width + gap_loffset + gap_roffset,
|
|
|
|
3 * gap_height, GTK_POS_BOTTOM,
|
|
|
|
gap_loffset, gap_loffset + tabRect.width);
|
|
|
|
cairo_restore(cr);
|
|
|
|
} else {
|
|
|
|
/* Draw the tab on top */
|
|
|
|
focusRect.height -= gap_voffset;
|
|
|
|
gtk_render_extension(style, cr,
|
|
|
|
tabRect.x, tabRect.y, tabRect.width,
|
|
|
|
tabRect.height - gap_voffset, GTK_POS_BOTTOM);
|
|
|
|
|
|
|
|
backRect.y += (tabRect.height - gap_voffset);
|
|
|
|
backRect.height = gap_height;
|
|
|
|
|
|
|
|
/* Draw the gap; erase with background color before painting in
|
|
|
|
* case theme does not */
|
2016-11-29 08:50:20 +03:00
|
|
|
gtk_render_background(panelStyle, cr, backRect.x, backRect.y,
|
2015-04-30 08:31:00 +03:00
|
|
|
backRect.width, backRect.height);
|
|
|
|
|
|
|
|
cairo_save(cr);
|
|
|
|
cairo_rectangle(cr, backRect.x, backRect.y, backRect.width, backRect.height);
|
|
|
|
cairo_clip(cr);
|
|
|
|
|
2016-11-29 08:50:20 +03:00
|
|
|
gtk_render_frame_gap(panelStyle, cr,
|
2015-04-30 08:31:00 +03:00
|
|
|
tabRect.x - gap_loffset,
|
|
|
|
tabRect.y + tabRect.height - gap_voffset,
|
|
|
|
tabRect.width + gap_loffset + gap_roffset,
|
|
|
|
3 * gap_height, GTK_POS_TOP,
|
|
|
|
gap_loffset, gap_loffset + tabRect.width);
|
|
|
|
cairo_restore(cr);
|
|
|
|
}
|
2012-02-10 17:15:28 +04:00
|
|
|
}
|
2015-04-30 08:31:00 +03:00
|
|
|
} else {
|
|
|
|
gtk_render_background(style, cr, tabRect.x, tabRect.y, tabRect.width, tabRect.height);
|
|
|
|
gtk_render_frame(style, cr, tabRect.x, tabRect.y, tabRect.width, tabRect.height);
|
2012-02-10 17:15:28 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (state->focused) {
|
|
|
|
/* Paint the focus ring */
|
2015-04-30 08:31:00 +03:00
|
|
|
GtkBorder padding;
|
|
|
|
gtk_style_context_get_padding(style, GetStateFlagsFromGtkWidgetState(state), &padding);
|
|
|
|
|
|
|
|
focusRect.x += padding.left;
|
|
|
|
focusRect.width -= (padding.left + padding.right);
|
|
|
|
focusRect.y += padding.top;
|
|
|
|
focusRect.height -= (padding.top + padding.bottom);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
|
|
|
gtk_render_focus(style, cr,
|
|
|
|
focusRect.x, focusRect.y, focusRect.width, focusRect.height);
|
|
|
|
}
|
|
|
|
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* tab area*/
|
|
|
|
static gint
|
|
|
|
moz_gtk_tabpanels_paint(cairo_t *cr, GdkRectangle* rect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkTextDirection direction)
|
2012-02-10 17:15:28 +04:00
|
|
|
{
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style = GetStyleContext(MOZ_GTK_TABPANELS, direction);
|
2017-12-19 13:38:59 +03:00
|
|
|
gtk_render_background(style, cr, rect->x, rect->y,
|
2012-02-10 17:15:28 +04:00
|
|
|
rect->width, rect->height);
|
|
|
|
/*
|
2017-12-19 13:38:59 +03:00
|
|
|
* The gap size is not needed in moz_gtk_tabpanels_paint because
|
2012-02-10 17:15:28 +04:00
|
|
|
* the gap will be painted with the foreground tab in moz_gtk_tab_paint.
|
|
|
|
*
|
2017-12-19 13:38:59 +03:00
|
|
|
* However, if moz_gtk_tabpanels_paint just uses gtk_render_frame(),
|
|
|
|
* the theme will think that there are no tabs and may draw something
|
|
|
|
* different.Hence the trick of using two clip regions, and drawing the
|
|
|
|
* gap outside each clip region, to get the correct frame for
|
2012-02-10 17:15:28 +04:00
|
|
|
* a tabpanel with tabs.
|
|
|
|
*/
|
|
|
|
/* left side */
|
|
|
|
cairo_save(cr);
|
2012-05-28 02:39:57 +04:00
|
|
|
cairo_rectangle(cr, rect->x, rect->y,
|
2012-02-10 17:15:28 +04:00
|
|
|
rect->x + rect->width / 2,
|
2012-05-28 02:39:57 +04:00
|
|
|
rect->y + rect->height);
|
2012-02-10 17:15:28 +04:00
|
|
|
cairo_clip(cr);
|
|
|
|
gtk_render_frame_gap(style, cr,
|
|
|
|
rect->x, rect->y,
|
|
|
|
rect->width, rect->height,
|
|
|
|
GTK_POS_TOP, rect->width - 1, rect->width);
|
|
|
|
cairo_restore(cr);
|
2016-08-22 06:13:00 +03:00
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
/* right side */
|
|
|
|
cairo_save(cr);
|
2012-05-28 02:39:57 +04:00
|
|
|
cairo_rectangle(cr, rect->x + rect->width / 2, rect->y,
|
2012-02-10 17:15:28 +04:00
|
|
|
rect->x + rect->width,
|
2012-05-28 02:39:57 +04:00
|
|
|
rect->y + rect->height);
|
2012-02-10 17:15:28 +04:00
|
|
|
cairo_clip(cr);
|
|
|
|
gtk_render_frame_gap(style, cr,
|
|
|
|
rect->x, rect->y,
|
|
|
|
rect->width, rect->height,
|
|
|
|
GTK_POS_TOP, 0, 1);
|
|
|
|
cairo_restore(cr);
|
|
|
|
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
moz_gtk_tab_scroll_arrow_paint(cairo_t *cr, GdkRectangle* rect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkWidgetState* state,
|
2012-02-10 17:15:28 +04:00
|
|
|
GtkArrowType arrow_type,
|
|
|
|
GtkTextDirection direction)
|
|
|
|
{
|
|
|
|
GtkStyleContext* style;
|
|
|
|
gdouble arrow_angle;
|
|
|
|
gint arrow_size = MIN(rect->width, rect->height);
|
|
|
|
gint x = rect->x + (rect->width - arrow_size) / 2;
|
|
|
|
gint y = rect->y + (rect->height - arrow_size) / 2;
|
|
|
|
|
|
|
|
if (direction == GTK_TEXT_DIR_RTL) {
|
|
|
|
arrow_type = (arrow_type == GTK_ARROW_LEFT) ?
|
|
|
|
GTK_ARROW_RIGHT : GTK_ARROW_LEFT;
|
2017-12-19 13:38:59 +03:00
|
|
|
}
|
2012-02-10 17:15:28 +04:00
|
|
|
switch (arrow_type) {
|
|
|
|
case GTK_ARROW_LEFT:
|
|
|
|
arrow_angle = ARROW_LEFT;
|
|
|
|
break;
|
|
|
|
case GTK_ARROW_RIGHT:
|
|
|
|
arrow_angle = ARROW_RIGHT;
|
|
|
|
break;
|
|
|
|
case GTK_ARROW_DOWN:
|
|
|
|
arrow_angle = ARROW_DOWN;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
arrow_angle = ARROW_UP;
|
2017-12-19 13:38:59 +03:00
|
|
|
break;
|
2012-02-10 17:15:28 +04:00
|
|
|
}
|
2017-12-19 13:38:59 +03:00
|
|
|
if (arrow_type != GTK_ARROW_NONE) {
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext(MOZ_GTK_TAB_SCROLLARROW, direction,
|
|
|
|
GetStateFlagsFromGtkWidgetState(state));
|
2012-02-10 17:15:28 +04:00
|
|
|
gtk_render_arrow(style, cr, arrow_angle,
|
|
|
|
x, y, arrow_size);
|
|
|
|
}
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
moz_gtk_menu_bar_paint(cairo_t *cr, GdkRectangle* rect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkTextDirection direction)
|
2012-02-10 17:15:28 +04:00
|
|
|
{
|
|
|
|
GtkStyleContext* style;
|
|
|
|
|
2016-05-17 09:24:55 +03:00
|
|
|
GtkWidget* widget = GetWidget(MOZ_GTK_MENUBAR);
|
|
|
|
gtk_widget_set_direction(widget, direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2016-05-17 09:24:55 +03:00
|
|
|
style = gtk_widget_get_style_context(widget);
|
2012-02-10 17:15:28 +04:00
|
|
|
gtk_style_context_save(style);
|
|
|
|
gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUBAR);
|
|
|
|
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);
|
|
|
|
gtk_style_context_restore(style);
|
2017-12-19 13:38:59 +03:00
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
moz_gtk_menu_popup_paint(cairo_t *cr, GdkRectangle* rect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkTextDirection direction)
|
2012-02-10 17:15:28 +04:00
|
|
|
{
|
|
|
|
GtkStyleContext* style;
|
|
|
|
|
2016-05-17 09:24:55 +03:00
|
|
|
GtkWidget* widget = GetWidget(MOZ_GTK_MENUPOPUP);
|
|
|
|
gtk_widget_set_direction(widget, direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2015-08-06 21:20:00 +03:00
|
|
|
// Draw a backing toplevel. This fixes themes that don't provide a menu
|
|
|
|
// background, and depend on the GtkMenu's implementation window to provide it.
|
|
|
|
moz_gtk_window_paint(cr, rect, direction);
|
|
|
|
|
2016-05-17 09:24:55 +03:00
|
|
|
style = gtk_widget_get_style_context(widget);
|
2012-02-10 17:15:28 +04:00
|
|
|
gtk_style_context_save(style);
|
|
|
|
gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENU);
|
|
|
|
|
|
|
|
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);
|
|
|
|
gtk_style_context_restore(style);
|
|
|
|
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2013-07-01 17:26:53 +04:00
|
|
|
// See gtk_menu_item_draw() for reference.
|
2012-02-10 17:15:28 +04:00
|
|
|
static gint
|
|
|
|
moz_gtk_menu_separator_paint(cairo_t *cr, GdkRectangle* rect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkTextDirection direction)
|
2012-02-10 17:15:28 +04:00
|
|
|
{
|
2016-11-17 01:04:13 +03:00
|
|
|
GtkWidgetState defaultState = { 0 };
|
|
|
|
moz_gtk_menu_item_paint(MOZ_GTK_MENUSEPARATOR, cr, rect,
|
|
|
|
&defaultState, direction);
|
|
|
|
|
2016-11-17 01:08:33 +03:00
|
|
|
if (gtk_get_minor_version() >= 20)
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
GtkStyleContext* style;
|
|
|
|
gboolean wide_separators;
|
|
|
|
gint separator_height;
|
2015-12-17 09:24:21 +03:00
|
|
|
gint x, y, w;
|
2013-07-01 17:26:53 +04:00
|
|
|
GtkBorder padding;
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext(MOZ_GTK_MENUSEPARATOR, direction);
|
2016-03-23 05:49:00 +03:00
|
|
|
gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2016-11-14 06:13:50 +03:00
|
|
|
x = rect->x;
|
|
|
|
y = rect->y;
|
|
|
|
w = rect->width;
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2014-07-23 03:30:12 +04:00
|
|
|
gtk_style_context_save(style);
|
|
|
|
gtk_style_context_add_class(style, GTK_STYLE_CLASS_SEPARATOR);
|
|
|
|
|
2016-04-01 00:21:15 +03:00
|
|
|
gtk_style_context_get_style(style,
|
|
|
|
"wide-separators", &wide_separators,
|
|
|
|
"separator-height", &separator_height,
|
|
|
|
NULL);
|
2014-07-23 03:30:12 +04:00
|
|
|
|
2013-07-01 17:26:53 +04:00
|
|
|
if (wide_separators) {
|
|
|
|
gtk_render_frame(style, cr,
|
|
|
|
x + padding.left,
|
|
|
|
y + padding.top,
|
|
|
|
w - padding.left - padding.right,
|
|
|
|
separator_height);
|
2012-02-10 17:15:28 +04:00
|
|
|
} else {
|
2013-07-01 17:26:53 +04:00
|
|
|
gtk_render_line(style, cr,
|
|
|
|
x + padding.left,
|
|
|
|
y + padding.top,
|
|
|
|
x + w - padding.right - 1,
|
|
|
|
y + padding.top);
|
2012-02-10 17:15:28 +04:00
|
|
|
}
|
|
|
|
|
2014-07-23 03:30:12 +04:00
|
|
|
gtk_style_context_restore(style);
|
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2013-07-01 17:26:53 +04:00
|
|
|
// See gtk_menu_item_draw() for reference.
|
2012-02-10 17:15:28 +04:00
|
|
|
static gint
|
2016-05-19 07:55:04 +03:00
|
|
|
moz_gtk_menu_item_paint(WidgetNodeType widget, cairo_t *cr, GdkRectangle* rect,
|
|
|
|
GtkWidgetState* state, GtkTextDirection direction)
|
2012-02-10 17:15:28 +04:00
|
|
|
{
|
2013-07-01 17:26:53 +04:00
|
|
|
gint x, y, w, h;
|
2017-01-03 23:57:48 +03:00
|
|
|
guint minorVersion = gtk_get_minor_version();
|
2016-07-21 03:49:31 +03:00
|
|
|
GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
|
2017-01-03 23:57:48 +03:00
|
|
|
|
|
|
|
// GTK versions prior to 3.8 render the background and frame only when not
|
|
|
|
// a separator and in hover prelight.
|
|
|
|
if (minorVersion < 8 && (widget == MOZ_GTK_MENUSEPARATOR ||
|
|
|
|
!(state_flags & GTK_STATE_FLAG_PRELIGHT)))
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style = GetStyleContext(widget, direction, state_flags);
|
2016-07-21 03:49:31 +03:00
|
|
|
|
2017-01-03 23:57:48 +03:00
|
|
|
if (minorVersion < 6) {
|
2016-07-21 03:49:31 +03:00
|
|
|
// GTK+ 3.4 saves the style context and adds the menubar class to
|
|
|
|
// menubar children, but does each of these only when drawing, not
|
|
|
|
// during layout.
|
|
|
|
gtk_style_context_save(style);
|
|
|
|
if (widget == MOZ_GTK_MENUBARITEM) {
|
|
|
|
gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUBAR);
|
2012-05-28 02:39:57 +04:00
|
|
|
}
|
2016-07-21 03:49:31 +03:00
|
|
|
}
|
2012-05-28 02:39:57 +04:00
|
|
|
|
2016-07-21 03:49:31 +03:00
|
|
|
x = rect->x;
|
|
|
|
y = rect->y;
|
|
|
|
w = rect->width;
|
|
|
|
h = rect->height;
|
2013-07-01 17:26:53 +04:00
|
|
|
|
2016-07-21 03:49:31 +03:00
|
|
|
gtk_render_background(style, cr, x, y, w, h);
|
|
|
|
gtk_render_frame(style, cr, x, y, w, h);
|
2016-05-09 05:17:00 +03:00
|
|
|
|
2017-01-03 23:57:48 +03:00
|
|
|
if (minorVersion < 6) {
|
2016-07-21 03:49:31 +03:00
|
|
|
gtk_style_context_restore(style);
|
2012-02-10 17:15:28 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
moz_gtk_menu_arrow_paint(cairo_t *cr, GdkRectangle* rect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkWidgetState* state,
|
2012-02-10 17:15:28 +04:00
|
|
|
GtkTextDirection direction)
|
|
|
|
{
|
|
|
|
GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style = GetStyleContext(MOZ_GTK_MENUITEM,
|
|
|
|
direction, state_flags);
|
2012-02-10 17:15:28 +04:00
|
|
|
gtk_render_arrow(style, cr,
|
|
|
|
(direction == GTK_TEXT_DIR_LTR) ? ARROW_RIGHT : ARROW_LEFT,
|
|
|
|
rect->x, rect->y, rect->width);
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-11-21 07:27:11 +03:00
|
|
|
// For reference, see gtk_check_menu_item_size_allocate() in GTK versions after
|
|
|
|
// 3.20 and gtk_real_check_menu_item_draw_indicator() in earlier versions.
|
2012-02-10 17:15:28 +04:00
|
|
|
static gint
|
2016-11-18 03:01:27 +03:00
|
|
|
moz_gtk_check_menu_item_paint(WidgetNodeType widgetType,
|
|
|
|
cairo_t *cr, GdkRectangle* rect,
|
2013-02-20 17:50:51 +04:00
|
|
|
GtkWidgetState* state,
|
2016-11-18 03:01:27 +03:00
|
|
|
gboolean checked, GtkTextDirection direction)
|
2012-02-10 17:15:28 +04:00
|
|
|
{
|
|
|
|
GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
|
|
|
|
GtkStyleContext* style;
|
|
|
|
gint indicator_size, horizontal_padding;
|
|
|
|
gint x, y;
|
|
|
|
|
2016-05-19 07:55:04 +03:00
|
|
|
moz_gtk_menu_item_paint(MOZ_GTK_MENUITEM, cr, rect, state, direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2016-07-28 04:54:00 +03:00
|
|
|
if (checked) {
|
|
|
|
state_flags = static_cast<GtkStateFlags>(state_flags|checkbox_check_state);
|
|
|
|
}
|
2016-04-01 00:21:15 +03:00
|
|
|
|
2016-11-21 07:27:11 +03:00
|
|
|
bool pre_3_20 = gtk_get_minor_version() < 20;
|
|
|
|
gint offset;
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext(widgetType, direction);
|
2016-04-01 00:21:15 +03:00
|
|
|
gtk_style_context_get_style(style,
|
|
|
|
"indicator-size", &indicator_size,
|
|
|
|
"horizontal-padding", &horizontal_padding,
|
|
|
|
NULL);
|
2016-11-21 07:27:11 +03:00
|
|
|
if (pre_3_20) {
|
|
|
|
GtkBorder padding;
|
|
|
|
gtk_style_context_get_padding(style, state_flags, &padding);
|
|
|
|
offset = horizontal_padding + padding.left + 2;
|
|
|
|
} else {
|
|
|
|
GdkRectangle r = { 0 };
|
|
|
|
InsetByMargin(&r, style);
|
|
|
|
InsetByBorderPadding(&r, style);
|
|
|
|
offset = r.x;
|
|
|
|
}
|
2016-04-01 00:21:15 +03:00
|
|
|
|
2016-11-18 03:01:27 +03:00
|
|
|
bool isRadio = (widgetType == MOZ_GTK_RADIOMENUITEM);
|
|
|
|
WidgetNodeType indicatorType = isRadio ? MOZ_GTK_RADIOMENUITEM_INDICATOR
|
|
|
|
: MOZ_GTK_CHECKMENUITEM_INDICATOR;
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext(indicatorType, direction, state_flags);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2013-07-01 17:26:53 +04:00
|
|
|
if (direction == GTK_TEXT_DIR_RTL) {
|
2016-11-21 07:27:11 +03:00
|
|
|
x = rect->width - indicator_size - offset;
|
2013-07-01 17:26:53 +04:00
|
|
|
}
|
|
|
|
else {
|
2016-11-21 07:27:11 +03:00
|
|
|
x = rect->x + offset;
|
2013-07-01 17:26:53 +04:00
|
|
|
}
|
2012-02-10 17:15:28 +04:00
|
|
|
y = rect->y + (rect->height - indicator_size) / 2;
|
|
|
|
|
2016-11-21 07:27:11 +03:00
|
|
|
if (!pre_3_20) {
|
2016-07-28 04:54:00 +03:00
|
|
|
gtk_render_background(style, cr, x, y, indicator_size, indicator_size);
|
|
|
|
gtk_render_frame(style, cr, x, y, indicator_size, indicator_size);
|
|
|
|
}
|
|
|
|
|
2016-11-18 03:01:27 +03:00
|
|
|
if (isRadio) {
|
2012-02-10 17:15:28 +04:00
|
|
|
gtk_render_option(style, cr, x, y, indicator_size, indicator_size);
|
|
|
|
} else {
|
|
|
|
gtk_render_check(style, cr, x, y, indicator_size, indicator_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2015-08-19 22:42:17 +03:00
|
|
|
static gint
|
|
|
|
moz_gtk_info_bar_paint(cairo_t *cr, GdkRectangle* rect,
|
|
|
|
GtkWidgetState* state)
|
|
|
|
{
|
2016-07-19 07:03:00 +03:00
|
|
|
GtkStyleContext *style =
|
2017-09-05 00:16:01 +03:00
|
|
|
GetStyleContext(MOZ_GTK_INFO_BAR, GTK_TEXT_DIR_LTR,
|
|
|
|
GetStateFlagsFromGtkWidgetState(state));
|
2015-08-19 22:42:17 +03:00
|
|
|
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);
|
|
|
|
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-09-19 22:15:12 +03:00
|
|
|
static gint
|
|
|
|
moz_gtk_header_bar_paint(WidgetNodeType widgetType,
|
|
|
|
cairo_t *cr, GdkRectangle* rect, GtkWidgetState* state)
|
|
|
|
{
|
|
|
|
GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
|
|
|
|
GtkStyleContext *style = GetStyleContext(widgetType, GTK_TEXT_DIR_LTR,
|
|
|
|
state_flags);
|
|
|
|
InsetByMargin(rect, style);
|
2018-02-28 16:28:40 +03:00
|
|
|
|
|
|
|
// Some themes (Adwaita for instance) draws bold dark line at
|
|
|
|
// titlebar bottom. It does not fit well with Firefox tabs so
|
|
|
|
// draw with some extent to make the titlebar bottom part invisible.
|
|
|
|
#define TITLEBAR_EXTENT 4
|
|
|
|
gtk_render_background(style, cr, rect->x, rect->y,
|
|
|
|
rect->width, rect->height + TITLEBAR_EXTENT);
|
|
|
|
gtk_render_frame(style, cr, rect->x, rect->y,
|
|
|
|
rect->width, rect->height + TITLEBAR_EXTENT);
|
2017-09-19 22:15:12 +03:00
|
|
|
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2013-08-19 16:48:40 +04:00
|
|
|
|
Bug 1289148 - Fixing scrollbar metrics for GTK >= 3.20 r=karlt
The Gtk 3.20 scrollbars has moved towards usual box model. The scrollbar,
trough,thumb and scrollbar button can now have margin, padding and border set,
different for each direction (ie. left, right, bottom, top). The scrollbar
metrics become ignored in Gtk 3.20 and later.
* Draw scrollbar element [for GTK 3.20+]
* The border for scrollbar, trough, thumb and scrollbar buttons is newly
calculated as margin+padding+border [for GTK 3.20+].
* The margin is subtracted for scrollbar, trough and sb buttons during paint
function [for GTK 3.6+]
* All scrollbar widget's borders transfered from
nsNativeThemeGTK::GetWidgetBorder to the moz_gtk_get_widget_border.
* Added helper function NativeThemeToGtkTheme for mapping mozilla's widget type
to the gtk widget type.
* Scrollbar troughs are now drawn even when there is not enough room for
the thumb [GTK 3.20+]
MozReview-Commit-ID: jd2q67gKM1
--HG--
extra : rebase_source : ecc8b85401845113d84c6c5a48219a0c3d4f8de3
2016-10-17 01:37:13 +03:00
|
|
|
|
2017-03-27 21:32:25 +03:00
|
|
|
static GtkBorder
|
|
|
|
GetMarginBorderPadding(GtkStyleContext* aStyle)
|
|
|
|
{
|
|
|
|
gint left = 0, top = 0, right = 0, bottom = 0;
|
|
|
|
moz_gtk_add_margin_border_padding(aStyle, &left, &top, &right, &bottom);
|
|
|
|
// narrowing conversions to gint16:
|
|
|
|
GtkBorder result;
|
|
|
|
result.left = left;
|
|
|
|
result.right = right;
|
|
|
|
result.top = top;
|
|
|
|
result.bottom = bottom;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
gint
|
2016-04-14 08:47:20 +03:00
|
|
|
moz_gtk_get_widget_border(WidgetNodeType widget, gint* left, gint* top,
|
2017-06-07 08:27:18 +03:00
|
|
|
gint* right, gint* bottom,
|
|
|
|
// NOTE: callers depend on direction being used
|
|
|
|
// only for MOZ_GTK_DROPDOWN widgets.
|
|
|
|
GtkTextDirection direction)
|
2012-02-10 17:15:28 +04:00
|
|
|
{
|
|
|
|
GtkWidget* w;
|
|
|
|
GtkStyleContext* style;
|
2013-08-19 16:48:40 +04:00
|
|
|
*left = *top = *right = *bottom = 0;
|
2012-02-10 17:15:28 +04:00
|
|
|
|
|
|
|
switch (widget) {
|
|
|
|
case MOZ_GTK_BUTTON:
|
2015-08-07 08:09:00 +03:00
|
|
|
case MOZ_GTK_TOOLBAR_BUTTON:
|
2012-02-10 17:15:28 +04:00
|
|
|
{
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext(MOZ_GTK_BUTTON);
|
2015-03-25 21:41:01 +03:00
|
|
|
|
2016-07-20 02:57:00 +03:00
|
|
|
*left = *top = *right = *bottom =
|
|
|
|
gtk_container_get_border_width(GTK_CONTAINER(GetWidget(MOZ_GTK_BUTTON)));
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2015-11-30 07:26:00 +03:00
|
|
|
if (widget == MOZ_GTK_TOOLBAR_BUTTON) {
|
|
|
|
gtk_style_context_save(style);
|
|
|
|
gtk_style_context_add_class(style, "image-button");
|
|
|
|
}
|
2016-07-20 02:57:00 +03:00
|
|
|
|
2015-11-30 07:26:00 +03:00
|
|
|
moz_gtk_add_style_padding(style, left, top, right, bottom);
|
2016-07-20 02:57:00 +03:00
|
|
|
|
2015-11-30 07:26:00 +03:00
|
|
|
if (widget == MOZ_GTK_TOOLBAR_BUTTON)
|
|
|
|
gtk_style_context_restore(style);
|
2013-08-19 16:48:40 +04:00
|
|
|
|
2015-03-25 21:41:01 +03:00
|
|
|
moz_gtk_add_style_border(style, left, top, right, bottom);
|
2016-07-20 02:57:00 +03:00
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
case MOZ_GTK_ENTRY:
|
2013-07-08 00:49:53 +04:00
|
|
|
{
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext(MOZ_GTK_ENTRY);
|
2015-10-08 22:57:57 +03:00
|
|
|
|
|
|
|
// XXX: Subtract 1 pixel from the padding to account for the default
|
|
|
|
// padding in forms.css. See bug 1187385.
|
|
|
|
*left = *top = *right = *bottom = -1;
|
2017-10-23 16:16:02 +03:00
|
|
|
moz_gtk_add_border_padding(style, left, top, right, bottom);
|
2015-03-25 21:41:01 +03:00
|
|
|
|
2013-07-08 00:49:53 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
2016-04-27 02:07:00 +03:00
|
|
|
case MOZ_GTK_TEXT_VIEW:
|
2012-02-10 17:15:28 +04:00
|
|
|
case MOZ_GTK_TREEVIEW:
|
2013-08-19 16:48:40 +04:00
|
|
|
{
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext(MOZ_GTK_SCROLLED_WINDOW);
|
2013-08-19 16:48:40 +04:00
|
|
|
moz_gtk_add_style_border(style, left, top, right, bottom);
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
2012-02-10 17:15:28 +04:00
|
|
|
case MOZ_GTK_TREE_HEADER_CELL:
|
|
|
|
{
|
2015-08-24 03:55:09 +03:00
|
|
|
/* A Tree Header in GTK is just a different styled button
|
2012-02-10 17:15:28 +04:00
|
|
|
* It must be placed in a TreeView for getting the correct style
|
|
|
|
* assigned.
|
2015-08-24 03:55:09 +03:00
|
|
|
* That is why the following code is the same as for MOZ_GTK_BUTTON.
|
2012-02-10 17:15:28 +04:00
|
|
|
* */
|
2016-07-29 06:15:00 +03:00
|
|
|
*left = *top = *right = *bottom =
|
|
|
|
gtk_container_get_border_width(GTK_CONTAINER(
|
|
|
|
GetWidget(MOZ_GTK_TREE_HEADER_CELL)));
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext(MOZ_GTK_TREE_HEADER_CELL);
|
2017-10-23 16:16:02 +03:00
|
|
|
moz_gtk_add_border_padding(style, left, top, right, bottom);
|
2012-02-10 17:15:28 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
case MOZ_GTK_TREE_HEADER_SORTARROW:
|
2016-07-29 06:15:00 +03:00
|
|
|
w = GetWidget(MOZ_GTK_TREE_HEADER_SORTARROW);
|
2012-02-10 17:15:28 +04:00
|
|
|
break;
|
|
|
|
case MOZ_GTK_DROPDOWN_ENTRY:
|
2016-10-19 05:13:25 +03:00
|
|
|
w = GetWidget(MOZ_GTK_COMBOBOX_ENTRY_TEXTAREA);
|
2012-02-10 17:15:28 +04:00
|
|
|
break;
|
|
|
|
case MOZ_GTK_DROPDOWN_ARROW:
|
2016-10-19 05:13:25 +03:00
|
|
|
w = GetWidget(MOZ_GTK_COMBOBOX_ENTRY_BUTTON);
|
2012-02-10 17:15:28 +04:00
|
|
|
break;
|
|
|
|
case MOZ_GTK_DROPDOWN:
|
|
|
|
{
|
|
|
|
/* We need to account for the arrow on the dropdown, so text
|
|
|
|
* doesn't come too close to the arrow, or in some cases spill
|
|
|
|
* into the arrow. */
|
2015-03-25 21:41:01 +03:00
|
|
|
gboolean wide_separators;
|
|
|
|
gint separator_width;
|
2012-02-10 17:15:28 +04:00
|
|
|
GtkRequisition arrow_req;
|
2013-08-19 16:48:40 +04:00
|
|
|
GtkBorder border;
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2016-10-19 05:13:25 +03:00
|
|
|
*left = *top = *right = *bottom =
|
|
|
|
gtk_container_get_border_width(GTK_CONTAINER(
|
|
|
|
GetWidget(MOZ_GTK_COMBOBOX_BUTTON)));
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext(MOZ_GTK_COMBOBOX_BUTTON);
|
2017-10-23 16:16:02 +03:00
|
|
|
moz_gtk_add_border_padding(style, left, top, right, bottom);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
|
|
|
/* If there is no separator, don't try to count its width. */
|
|
|
|
separator_width = 0;
|
2016-10-19 05:13:25 +03:00
|
|
|
GtkWidget* comboBoxSeparator = GetWidget(MOZ_GTK_COMBOBOX_SEPARATOR);
|
|
|
|
if (comboBoxSeparator) {
|
|
|
|
style = gtk_widget_get_style_context(comboBoxSeparator);
|
2016-04-01 00:21:15 +03:00
|
|
|
gtk_style_context_get_style(style,
|
|
|
|
"wide-separators", &wide_separators,
|
|
|
|
"separator-width", &separator_width,
|
|
|
|
NULL);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
|
|
|
if (!wide_separators) {
|
2016-10-19 05:13:25 +03:00
|
|
|
gtk_style_context_get_border(style, GTK_STATE_FLAG_NORMAL,
|
|
|
|
&border);
|
2012-02-10 17:15:28 +04:00
|
|
|
separator_width = border.left;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-19 05:13:25 +03:00
|
|
|
gtk_widget_get_preferred_size(GetWidget(MOZ_GTK_COMBOBOX_ARROW),
|
|
|
|
NULL, &arrow_req);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
|
|
|
if (direction == GTK_TEXT_DIR_RTL)
|
|
|
|
*left += separator_width + arrow_req.width;
|
|
|
|
else
|
|
|
|
*right += separator_width + arrow_req.width;
|
|
|
|
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
case MOZ_GTK_TABPANELS:
|
2016-08-22 06:13:00 +03:00
|
|
|
w = GetWidget(MOZ_GTK_TABPANELS);
|
2012-02-10 17:15:28 +04:00
|
|
|
break;
|
|
|
|
case MOZ_GTK_PROGRESSBAR:
|
2016-05-24 14:43:00 +03:00
|
|
|
w = GetWidget(MOZ_GTK_PROGRESSBAR);
|
2012-02-10 17:15:28 +04:00
|
|
|
break;
|
|
|
|
case MOZ_GTK_SPINBUTTON_ENTRY:
|
|
|
|
case MOZ_GTK_SPINBUTTON_UP:
|
|
|
|
case MOZ_GTK_SPINBUTTON_DOWN:
|
2016-07-20 02:57:00 +03:00
|
|
|
w = GetWidget(MOZ_GTK_SPINBUTTON);
|
2012-02-10 17:15:28 +04:00
|
|
|
break;
|
|
|
|
case MOZ_GTK_SCALE_HORIZONTAL:
|
|
|
|
case MOZ_GTK_SCALE_VERTICAL:
|
2016-08-19 12:20:00 +03:00
|
|
|
w = GetWidget(widget);
|
2012-02-10 17:15:28 +04:00
|
|
|
break;
|
|
|
|
case MOZ_GTK_FRAME:
|
2016-07-18 06:29:00 +03:00
|
|
|
w = GetWidget(MOZ_GTK_FRAME);
|
2012-02-10 17:15:28 +04:00
|
|
|
break;
|
|
|
|
case MOZ_GTK_CHECKBUTTON_CONTAINER:
|
|
|
|
case MOZ_GTK_RADIOBUTTON_CONTAINER:
|
|
|
|
{
|
2016-05-13 02:59:17 +03:00
|
|
|
w = GetWidget(widget);
|
2015-03-25 21:41:01 +03:00
|
|
|
style = gtk_widget_get_style_context(w);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
|
|
|
*left = *top = *right = *bottom = gtk_container_get_border_width(GTK_CONTAINER(w));
|
2017-10-23 16:16:02 +03:00
|
|
|
moz_gtk_add_border_padding(style,
|
|
|
|
left, top, right, bottom);
|
2012-02-10 17:15:28 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
case MOZ_GTK_MENUPOPUP:
|
2016-05-17 09:24:55 +03:00
|
|
|
w = GetWidget(MOZ_GTK_MENUPOPUP);
|
2012-02-10 17:15:28 +04:00
|
|
|
break;
|
2016-05-19 07:55:04 +03:00
|
|
|
case MOZ_GTK_MENUBARITEM:
|
2012-02-10 17:15:28 +04:00
|
|
|
case MOZ_GTK_MENUITEM:
|
2014-04-23 00:59:39 +04:00
|
|
|
case MOZ_GTK_CHECKMENUITEM:
|
|
|
|
case MOZ_GTK_RADIOMENUITEM:
|
2013-07-01 17:26:53 +04:00
|
|
|
{
|
2016-11-15 06:11:38 +03:00
|
|
|
// Bug 1274143 for MOZ_GTK_MENUBARITEM
|
|
|
|
WidgetNodeType type =
|
2016-11-18 03:01:27 +03:00
|
|
|
widget == MOZ_GTK_MENUBARITEM ? MOZ_GTK_MENUITEM : widget;
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext(type);
|
2014-04-23 00:59:39 +04:00
|
|
|
|
2016-11-21 07:27:11 +03:00
|
|
|
if (gtk_get_minor_version() < 20) {
|
|
|
|
moz_gtk_add_style_padding(style, left, top, right, bottom);
|
|
|
|
} else {
|
|
|
|
moz_gtk_add_margin_border_padding(style,
|
|
|
|
left, top, right, bottom);
|
|
|
|
}
|
2013-07-01 17:26:53 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
2015-08-19 22:42:17 +03:00
|
|
|
case MOZ_GTK_INFO_BAR:
|
2016-07-19 07:03:00 +03:00
|
|
|
w = GetWidget(MOZ_GTK_INFO_BAR);
|
2015-08-19 22:42:17 +03:00
|
|
|
break;
|
2016-06-07 07:22:00 +03:00
|
|
|
case MOZ_GTK_TOOLTIP:
|
|
|
|
{
|
2016-11-11 01:31:29 +03:00
|
|
|
// 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.
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* boxStyle = GetStyleContext(MOZ_GTK_TOOLTIP_BOX);
|
2016-11-11 01:31:29 +03:00
|
|
|
moz_gtk_add_margin_border_padding(boxStyle,
|
|
|
|
left, top, right, bottom);
|
|
|
|
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* labelStyle = GetStyleContext(MOZ_GTK_TOOLTIP_BOX_LABEL);
|
2016-11-11 01:31:29 +03:00
|
|
|
moz_gtk_add_margin_border_padding(labelStyle,
|
|
|
|
left, top, right, bottom);
|
|
|
|
|
2016-06-07 07:22:00 +03:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
2017-09-19 22:15:12 +03:00
|
|
|
case MOZ_GTK_HEADER_BAR:
|
|
|
|
case MOZ_GTK_HEADER_BAR_MAXIMIZED:
|
|
|
|
{
|
|
|
|
style = GetStyleContext(widget);
|
2017-10-23 16:16:02 +03:00
|
|
|
moz_gtk_add_border_padding(style, left, top, right, bottom);
|
2018-02-21 18:43:11 +03:00
|
|
|
*top = *bottom = 0;
|
2017-09-19 22:15:12 +03:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
2012-02-10 17:15:28 +04:00
|
|
|
/* These widgets have no borders, since they are not containers. */
|
2015-03-25 21:41:01 +03:00
|
|
|
case MOZ_GTK_CHECKBUTTON_LABEL:
|
|
|
|
case MOZ_GTK_RADIOBUTTON_LABEL:
|
2012-02-10 17:15:28 +04:00
|
|
|
case MOZ_GTK_SPLITTER_HORIZONTAL:
|
|
|
|
case MOZ_GTK_SPLITTER_VERTICAL:
|
|
|
|
case MOZ_GTK_CHECKBUTTON:
|
|
|
|
case MOZ_GTK_RADIOBUTTON:
|
|
|
|
case MOZ_GTK_SCROLLBAR_BUTTON:
|
2017-03-27 21:32:20 +03:00
|
|
|
case MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL:
|
|
|
|
case MOZ_GTK_SCROLLBAR_THUMB_VERTICAL:
|
2012-02-10 17:15:28 +04:00
|
|
|
case MOZ_GTK_SCALE_THUMB_HORIZONTAL:
|
|
|
|
case MOZ_GTK_SCALE_THUMB_VERTICAL:
|
|
|
|
case MOZ_GTK_GRIPPER:
|
|
|
|
case MOZ_GTK_PROGRESS_CHUNK:
|
|
|
|
case MOZ_GTK_PROGRESS_CHUNK_INDETERMINATE:
|
|
|
|
case MOZ_GTK_PROGRESS_CHUNK_VERTICAL_INDETERMINATE:
|
|
|
|
case MOZ_GTK_TREEVIEW_EXPANDER:
|
|
|
|
case MOZ_GTK_TOOLBAR_SEPARATOR:
|
|
|
|
case MOZ_GTK_MENUSEPARATOR:
|
2018-01-25 13:13:12 +03:00
|
|
|
case MOZ_GTK_HEADER_BAR_BUTTON_CLOSE:
|
|
|
|
case MOZ_GTK_HEADER_BAR_BUTTON_MINIMIZE:
|
|
|
|
case MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE:
|
2018-02-23 23:28:37 +03:00
|
|
|
case MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE_RESTORE:
|
2012-02-10 17:15:28 +04:00
|
|
|
/* These widgets have no borders.*/
|
2017-11-29 05:43:13 +03:00
|
|
|
case MOZ_GTK_INNER_SPIN_BUTTON:
|
2012-02-10 17:15:28 +04:00
|
|
|
case MOZ_GTK_SPINBUTTON:
|
|
|
|
case MOZ_GTK_WINDOW:
|
|
|
|
case MOZ_GTK_RESIZER:
|
|
|
|
case MOZ_GTK_MENUARROW:
|
|
|
|
case MOZ_GTK_TOOLBARBUTTON_ARROW:
|
|
|
|
case MOZ_GTK_TOOLBAR:
|
|
|
|
case MOZ_GTK_MENUBAR:
|
|
|
|
case MOZ_GTK_TAB_SCROLLARROW:
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
default:
|
|
|
|
g_warning("Unsupported widget type: %d", widget);
|
|
|
|
return MOZ_GTK_UNKNOWN_WIDGET;
|
|
|
|
}
|
|
|
|
/* TODO - we're still missing some widget implementations */
|
2013-08-19 16:48:40 +04:00
|
|
|
if (w) {
|
2017-12-19 13:38:59 +03:00
|
|
|
moz_gtk_add_style_border(gtk_widget_get_style_context(w),
|
2013-08-19 16:48:40 +04:00
|
|
|
left, top, right, bottom);
|
2012-02-10 17:15:28 +04:00
|
|
|
}
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2014-09-04 07:17:00 +04:00
|
|
|
gint
|
2017-12-19 13:38:59 +03:00
|
|
|
moz_gtk_get_tab_border(gint* left, gint* top, gint* right, gint* bottom,
|
|
|
|
GtkTextDirection direction, GtkTabFlags flags,
|
2016-08-22 06:13:00 +03:00
|
|
|
WidgetNodeType widget)
|
2014-09-04 07:17:00 +04:00
|
|
|
{
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style = GetStyleContext(widget, direction,
|
2016-08-22 06:13:00 +03:00
|
|
|
GetStateFlagsFromGtkTabFlags(flags));
|
2014-09-04 07:17:00 +04:00
|
|
|
|
|
|
|
*left = *top = *right = *bottom = 0;
|
|
|
|
moz_gtk_add_style_padding(style, left, top, right, bottom);
|
|
|
|
|
2016-08-22 06:13:00 +03:00
|
|
|
// Gtk >= 3.20 does not use those styles
|
|
|
|
if (gtk_check_version(3, 20, 0) != nullptr) {
|
|
|
|
int tab_curvature;
|
2014-09-04 07:17:00 +04:00
|
|
|
|
2016-08-22 06:13:00 +03:00
|
|
|
gtk_style_context_get_style(style, "tab-curvature", &tab_curvature, NULL);
|
|
|
|
*left += tab_curvature;
|
|
|
|
*right += tab_curvature;
|
2014-09-04 07:17:00 +04:00
|
|
|
|
2016-08-22 06:13:00 +03:00
|
|
|
if (flags & MOZ_GTK_TAB_FIRST) {
|
|
|
|
int initial_gap = 0;
|
|
|
|
gtk_style_context_get_style(style, "initial-gap", &initial_gap, NULL);
|
|
|
|
if (direction == GTK_TEXT_DIR_RTL)
|
|
|
|
*right += initial_gap;
|
|
|
|
else
|
|
|
|
*left += initial_gap;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
GtkBorder margin;
|
2014-09-04 07:17:00 +04:00
|
|
|
|
2016-08-22 06:13:00 +03:00
|
|
|
gtk_style_context_get_margin(style, GTK_STATE_FLAG_NORMAL, &margin);
|
|
|
|
*left += margin.left;
|
|
|
|
*right += margin.right;
|
|
|
|
|
|
|
|
if (flags & MOZ_GTK_TAB_FIRST) {
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext(MOZ_GTK_NOTEBOOK_HEADER, direction);
|
2016-08-22 06:13:00 +03:00
|
|
|
gtk_style_context_get_margin(style, GTK_STATE_FLAG_NORMAL, &margin);
|
|
|
|
*left += margin.left;
|
|
|
|
*right += margin.right;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-04 07:17:00 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
gint
|
|
|
|
moz_gtk_get_combo_box_entry_button_size(gint* width, gint* height)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* We get the requisition of the drop down button, which includes
|
|
|
|
* all padding, border and focus line widths the button uses,
|
|
|
|
* as well as the minimum arrow size and its padding
|
|
|
|
* */
|
|
|
|
GtkRequisition requisition;
|
|
|
|
|
2016-10-19 05:13:25 +03:00
|
|
|
gtk_widget_get_preferred_size(GetWidget(MOZ_GTK_COMBOBOX_ENTRY_BUTTON),
|
|
|
|
NULL, &requisition);
|
2012-02-10 17:15:28 +04:00
|
|
|
*width = requisition.width;
|
|
|
|
*height = requisition.height;
|
|
|
|
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
|
|
|
moz_gtk_get_tab_scroll_arrow_size(gint* width, gint* height)
|
|
|
|
{
|
|
|
|
gint arrow_size;
|
|
|
|
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext *style = GetStyleContext(MOZ_GTK_TABPANELS);
|
2016-08-22 06:13:00 +03:00
|
|
|
gtk_style_context_get_style(style,
|
2016-04-01 00:21:15 +03:00
|
|
|
"scroll-arrow-hlength", &arrow_size,
|
|
|
|
NULL);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
|
|
|
*height = *width = arrow_size;
|
|
|
|
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-03-01 03:12:03 +03:00
|
|
|
void
|
2016-04-14 08:47:20 +03:00
|
|
|
moz_gtk_get_arrow_size(WidgetNodeType widgetType, gint* width, gint* height)
|
2012-02-10 17:15:28 +04:00
|
|
|
{
|
2016-03-01 03:12:03 +03:00
|
|
|
GtkWidget* widget;
|
|
|
|
switch (widgetType) {
|
|
|
|
case MOZ_GTK_DROPDOWN:
|
2016-10-19 05:13:25 +03:00
|
|
|
widget = GetWidget(MOZ_GTK_COMBOBOX_ARROW);
|
2016-03-01 03:12:03 +03:00
|
|
|
break;
|
|
|
|
default:
|
2016-07-20 02:57:00 +03:00
|
|
|
widget = GetWidget(MOZ_GTK_BUTTON_ARROW);
|
2016-03-01 03:12:03 +03:00
|
|
|
break;
|
|
|
|
}
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2016-03-01 03:12:03 +03:00
|
|
|
GtkRequisition requisition;
|
|
|
|
gtk_widget_get_preferred_size(widget, NULL, &requisition);
|
2012-02-10 17:15:28 +04:00
|
|
|
*width = requisition.width;
|
|
|
|
*height = requisition.height;
|
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
|
|
|
moz_gtk_get_toolbar_separator_width(gint* size)
|
|
|
|
{
|
|
|
|
gboolean wide_separators;
|
|
|
|
gint separator_width;
|
|
|
|
GtkBorder border;
|
|
|
|
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style = GetStyleContext(MOZ_GTK_TOOLBAR);
|
2016-04-01 00:21:15 +03:00
|
|
|
gtk_style_context_get_style(style,
|
|
|
|
"space-size", size,
|
|
|
|
"wide-separators", &wide_separators,
|
|
|
|
"separator-width", &separator_width,
|
|
|
|
NULL);
|
2012-02-10 17:15:28 +04:00
|
|
|
/* Just in case... */
|
2016-03-23 05:49:00 +03:00
|
|
|
gtk_style_context_get_border(style, GTK_STATE_FLAG_NORMAL, &border);
|
2012-02-10 17:15:28 +04:00
|
|
|
*size = MAX(*size, (wide_separators ? separator_width : border.left));
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
|
|
|
moz_gtk_get_expander_size(gint* size)
|
|
|
|
{
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style = GetStyleContext(MOZ_GTK_EXPANDER);
|
2016-07-18 05:27:00 +03:00
|
|
|
gtk_style_context_get_style(style,
|
2016-04-01 00:21:15 +03:00
|
|
|
"expander-size", size,
|
|
|
|
NULL);
|
2012-02-10 17:15:28 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
|
|
|
moz_gtk_get_treeview_expander_size(gint* size)
|
|
|
|
{
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style = GetStyleContext(MOZ_GTK_TREEVIEW);
|
2016-07-29 06:15:00 +03:00
|
|
|
gtk_style_context_get_style(style, "expander-size", size, NULL);
|
2012-02-10 17:15:28 +04:00
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2013-07-01 17:26:53 +04:00
|
|
|
// See gtk_menu_item_draw() for reference.
|
2012-02-10 17:15:28 +04:00
|
|
|
gint
|
|
|
|
moz_gtk_get_menu_separator_height(gint *size)
|
|
|
|
{
|
|
|
|
gboolean wide_separators;
|
|
|
|
gint separator_height;
|
2013-07-01 17:26:53 +04:00
|
|
|
GtkBorder padding;
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style = GetStyleContext(MOZ_GTK_MENUSEPARATOR);
|
2016-03-23 05:49:00 +03:00
|
|
|
gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding);
|
2014-07-23 03:30:12 +04:00
|
|
|
|
|
|
|
gtk_style_context_save(style);
|
|
|
|
gtk_style_context_add_class(style, GTK_STYLE_CLASS_SEPARATOR);
|
|
|
|
|
2016-04-01 00:21:15 +03:00
|
|
|
gtk_style_context_get_style(style,
|
|
|
|
"wide-separators", &wide_separators,
|
|
|
|
"separator-height", &separator_height,
|
|
|
|
NULL);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2014-07-23 03:30:12 +04:00
|
|
|
gtk_style_context_restore(style);
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2016-11-14 06:13:50 +03:00
|
|
|
*size = padding.top + padding.bottom;
|
2013-07-01 17:26:53 +04:00
|
|
|
*size += (wide_separators) ? separator_height : 1;
|
2012-02-10 17:15:28 +04:00
|
|
|
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-04-01 05:43:00 +03:00
|
|
|
void
|
|
|
|
moz_gtk_get_entry_min_height(gint* height)
|
|
|
|
{
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style = GetStyleContext(MOZ_GTK_ENTRY);
|
2016-04-01 05:43:00 +03:00
|
|
|
if (!gtk_check_version(3, 20, 0)) {
|
|
|
|
gtk_style_context_get(style, gtk_style_context_get_state(style),
|
|
|
|
"min-height", height,
|
|
|
|
nullptr);
|
|
|
|
} else {
|
|
|
|
*height = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
GtkBorder border;
|
|
|
|
GtkBorder padding;
|
|
|
|
gtk_style_context_get_border(style, GTK_STATE_FLAG_NORMAL, &border);
|
|
|
|
gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding);
|
|
|
|
|
|
|
|
*height += (border.top + border.bottom + padding.top + padding.bottom);
|
|
|
|
}
|
|
|
|
|
2015-07-30 12:29:00 +03:00
|
|
|
void
|
|
|
|
moz_gtk_get_scale_metrics(GtkOrientation orient, gint* scale_width,
|
|
|
|
gint* scale_height)
|
|
|
|
{
|
2016-08-19 12:20:00 +03:00
|
|
|
if (gtk_check_version(3, 20, 0) != nullptr) {
|
2017-02-22 13:56:28 +03:00
|
|
|
WidgetNodeType widget = (orient == GTK_ORIENTATION_HORIZONTAL) ?
|
|
|
|
MOZ_GTK_SCALE_HORIZONTAL :
|
|
|
|
MOZ_GTK_SCALE_VERTICAL;
|
|
|
|
|
2016-08-19 12:20:00 +03:00
|
|
|
gint thumb_length, thumb_height, trough_border;
|
|
|
|
moz_gtk_get_scalethumb_metrics(orient, &thumb_length, &thumb_height);
|
2015-07-30 12:29:00 +03:00
|
|
|
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style = GetStyleContext(widget);
|
2016-08-19 12:20:00 +03:00
|
|
|
gtk_style_context_get_style(style, "trough-border", &trough_border, NULL);
|
|
|
|
|
|
|
|
if (orient == GTK_ORIENTATION_HORIZONTAL) {
|
|
|
|
*scale_width = thumb_length + trough_border * 2;
|
|
|
|
*scale_height = thumb_height + trough_border * 2;
|
|
|
|
} else {
|
|
|
|
*scale_width = thumb_height + trough_border * 2;
|
|
|
|
*scale_height = thumb_length + trough_border * 2;
|
|
|
|
}
|
2015-07-30 12:29:00 +03:00
|
|
|
} else {
|
2017-02-22 13:56:28 +03:00
|
|
|
WidgetNodeType widget = (orient == GTK_ORIENTATION_HORIZONTAL) ?
|
|
|
|
MOZ_GTK_SCALE_TROUGH_HORIZONTAL :
|
|
|
|
MOZ_GTK_SCALE_TROUGH_VERTICAL;
|
|
|
|
moz_gtk_get_widget_min_size(widget, scale_width, scale_height);
|
2015-07-30 12:29:00 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
gint
|
|
|
|
moz_gtk_get_scalethumb_metrics(GtkOrientation orient, gint* thumb_length, gint* thumb_height)
|
|
|
|
{
|
|
|
|
|
2016-08-19 12:20:00 +03:00
|
|
|
if (gtk_check_version(3, 20, 0) != nullptr) {
|
|
|
|
WidgetNodeType widget = (orient == GTK_ORIENTATION_HORIZONTAL) ?
|
|
|
|
MOZ_GTK_SCALE_HORIZONTAL:
|
|
|
|
MOZ_GTK_SCALE_VERTICAL;
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style = GetStyleContext(widget);
|
2016-08-19 12:20:00 +03:00
|
|
|
gtk_style_context_get_style(style,
|
|
|
|
"slider_length", thumb_length,
|
|
|
|
"slider_width", thumb_height,
|
|
|
|
NULL);
|
|
|
|
} else {
|
|
|
|
WidgetNodeType widget = (orient == GTK_ORIENTATION_HORIZONTAL) ?
|
|
|
|
MOZ_GTK_SCALE_THUMB_HORIZONTAL:
|
|
|
|
MOZ_GTK_SCALE_THUMB_VERTICAL;
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style = GetStyleContext(widget);
|
2017-02-23 12:52:55 +03:00
|
|
|
|
|
|
|
gint min_width, min_height;
|
|
|
|
GtkStateFlags state = gtk_style_context_get_state(style);
|
|
|
|
gtk_style_context_get(style, state,
|
|
|
|
"min-width", &min_width,
|
|
|
|
"min-height", &min_height,
|
2016-08-19 12:20:00 +03:00
|
|
|
nullptr);
|
2017-02-23 12:52:55 +03:00
|
|
|
GtkBorder margin;
|
|
|
|
gtk_style_context_get_margin(style, state, &margin);
|
|
|
|
gint margin_width = margin.left + margin.right;
|
|
|
|
gint margin_height = margin.top + margin.bottom;
|
|
|
|
|
|
|
|
// Negative margin of slider element also determines its minimal size
|
|
|
|
// so use bigger of those two values.
|
|
|
|
if (min_width < -margin_width)
|
|
|
|
min_width = -margin_width;
|
|
|
|
if (min_height < -margin_height)
|
|
|
|
min_height = -margin_height;
|
|
|
|
|
|
|
|
*thumb_length = min_width;
|
|
|
|
*thumb_height = min_height;
|
2016-08-19 12:20:00 +03:00
|
|
|
}
|
2012-02-10 17:15:28 +04:00
|
|
|
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-03-27 21:32:25 +03:00
|
|
|
static MozGtkSize
|
|
|
|
SizeFromLengthAndBreadth(GtkOrientation aOrientation,
|
|
|
|
gint aLength, gint aBreadth)
|
2017-03-23 08:23:26 +03:00
|
|
|
{
|
2017-03-27 21:32:25 +03:00
|
|
|
return aOrientation == GTK_ORIENTATION_HORIZONTAL ?
|
|
|
|
MozGtkSize({aLength, aBreadth}) : MozGtkSize({aBreadth, aLength});
|
|
|
|
}
|
2017-03-23 08:23:26 +03:00
|
|
|
|
2017-10-10 14:35:56 +03:00
|
|
|
const ToggleGTKMetrics*
|
|
|
|
GetToggleMetrics(bool isRadio)
|
|
|
|
{
|
|
|
|
ToggleGTKMetrics* metrics;
|
|
|
|
if (isRadio) {
|
|
|
|
metrics = &sRadioMetrics;
|
|
|
|
} else {
|
|
|
|
metrics = &sCheckboxMetrics;
|
|
|
|
}
|
|
|
|
if (metrics->initialized)
|
|
|
|
return metrics;
|
|
|
|
|
|
|
|
metrics->initialized = true;
|
|
|
|
if (gtk_check_version(3,20,0) == nullptr) {
|
|
|
|
GtkStyleContext* style;
|
|
|
|
if (isRadio) {
|
|
|
|
style = GetStyleContext(MOZ_GTK_RADIOBUTTON);
|
|
|
|
} else {
|
|
|
|
style = GetStyleContext(MOZ_GTK_CHECKBUTTON);
|
|
|
|
}
|
|
|
|
GtkStateFlags state_flags = gtk_style_context_get_state(style);
|
|
|
|
gtk_style_context_get(style, state_flags,
|
|
|
|
"min-height",&(metrics->minSizeWithBorder.height),
|
|
|
|
"min-width", &(metrics->minSizeWithBorder.width),
|
|
|
|
nullptr);
|
|
|
|
// Fallback to indicator size if min dimensions are zero
|
|
|
|
if (metrics->minSizeWithBorder.height == 0 ||
|
|
|
|
metrics->minSizeWithBorder.width == 0) {
|
|
|
|
gint indicator_size;
|
|
|
|
gtk_widget_style_get(GetWidget(MOZ_GTK_CHECKBUTTON_CONTAINER),
|
|
|
|
"indicator_size", &indicator_size, nullptr);
|
|
|
|
if (metrics->minSizeWithBorder.height == 0) {
|
|
|
|
metrics->minSizeWithBorder.height = indicator_size;
|
|
|
|
}
|
|
|
|
if (metrics->minSizeWithBorder.width == 0) {
|
|
|
|
metrics->minSizeWithBorder.width = indicator_size;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
GtkBorder border, padding;
|
|
|
|
gtk_style_context_get_border(style, state_flags, &border);
|
|
|
|
gtk_style_context_get_padding(style, state_flags, &padding);
|
|
|
|
metrics->borderAndPadding.left = border.left + padding.left;
|
|
|
|
metrics->borderAndPadding.right = border.right + padding.right;
|
|
|
|
metrics->borderAndPadding.top = border.top + padding.top;
|
|
|
|
metrics->borderAndPadding.bottom = border.bottom + padding.bottom;
|
|
|
|
metrics->minSizeWithBorder.width += metrics->borderAndPadding.left +
|
|
|
|
metrics->borderAndPadding.right;
|
|
|
|
metrics->minSizeWithBorder.height += metrics->borderAndPadding.top +
|
|
|
|
metrics->borderAndPadding.bottom;
|
|
|
|
} else {
|
|
|
|
gint indicator_size, indicator_spacing;
|
|
|
|
gtk_widget_style_get(GetWidget(MOZ_GTK_CHECKBUTTON_CONTAINER),
|
|
|
|
"indicator_size", &indicator_size,
|
|
|
|
"indicator_spacing", &indicator_spacing,
|
|
|
|
nullptr);
|
|
|
|
metrics->minSizeWithBorder.width =
|
|
|
|
metrics->minSizeWithBorder.height = indicator_size;
|
|
|
|
}
|
|
|
|
return metrics;
|
|
|
|
}
|
|
|
|
|
2017-03-27 21:32:25 +03:00
|
|
|
const ScrollbarGTKMetrics*
|
|
|
|
GetScrollbarMetrics(GtkOrientation aOrientation)
|
|
|
|
{
|
|
|
|
auto metrics = &sScrollbarMetrics[aOrientation];
|
|
|
|
if (metrics->initialized)
|
|
|
|
return metrics;
|
|
|
|
|
|
|
|
metrics->initialized = true;
|
|
|
|
|
|
|
|
WidgetNodeType scrollbar = aOrientation == GTK_ORIENTATION_HORIZONTAL ?
|
|
|
|
MOZ_GTK_SCROLLBAR_HORIZONTAL : MOZ_GTK_SCROLLBAR_VERTICAL;
|
|
|
|
|
2017-03-27 21:32:42 +03:00
|
|
|
gboolean backward, forward, secondary_backward, secondary_forward;
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style = GetStyleContext(scrollbar);
|
2017-03-27 21:32:42 +03:00
|
|
|
gtk_style_context_get_style(style,
|
|
|
|
"has-backward-stepper", &backward,
|
|
|
|
"has-forward-stepper", &forward,
|
|
|
|
"has-secondary-backward-stepper",
|
|
|
|
&secondary_backward,
|
|
|
|
"has-secondary-forward-stepper",
|
|
|
|
&secondary_forward, nullptr);
|
|
|
|
bool hasButtons =
|
|
|
|
backward || forward || secondary_backward || secondary_forward;
|
|
|
|
|
2017-03-27 21:32:25 +03:00
|
|
|
if (gtk_get_minor_version() < 20) {
|
|
|
|
gint slider_width, trough_border, stepper_size, min_slider_size;
|
|
|
|
|
|
|
|
gtk_style_context_get_style(style,
|
|
|
|
"slider-width", &slider_width,
|
|
|
|
"trough-border", &trough_border,
|
|
|
|
"stepper-size", &stepper_size,
|
|
|
|
"min-slider-length", &min_slider_size,
|
2017-03-27 21:32:42 +03:00
|
|
|
nullptr);
|
2017-03-27 21:32:25 +03:00
|
|
|
|
|
|
|
metrics->size.thumb =
|
|
|
|
SizeFromLengthAndBreadth(aOrientation, min_slider_size, slider_width);
|
|
|
|
metrics->size.button =
|
|
|
|
SizeFromLengthAndBreadth(aOrientation, stepper_size, slider_width);
|
|
|
|
// overall scrollbar
|
|
|
|
gint breadth = slider_width + 2 * trough_border;
|
|
|
|
// Require room for the slider in the track if we don't have buttons.
|
|
|
|
gint length = hasButtons ? 0 : min_slider_size + 2 * trough_border;
|
|
|
|
metrics->size.scrollbar =
|
|
|
|
SizeFromLengthAndBreadth(aOrientation, length, breadth);
|
|
|
|
|
|
|
|
// Borders on the major axis are set on the outermost scrollbar
|
|
|
|
// element to correctly position the buttons when
|
|
|
|
// trough-under-steppers is true.
|
|
|
|
// Borders on the minor axis are set on the track element so that it
|
|
|
|
// receives mouse events, as in GTK.
|
|
|
|
// Other borders have been zero-initialized.
|
|
|
|
if (aOrientation == GTK_ORIENTATION_HORIZONTAL) {
|
|
|
|
metrics->border.scrollbar.left =
|
|
|
|
metrics->border.scrollbar.right =
|
|
|
|
metrics->border.track.top =
|
|
|
|
metrics->border.track.bottom = trough_border;
|
|
|
|
} else {
|
|
|
|
metrics->border.scrollbar.top =
|
|
|
|
metrics->border.scrollbar.bottom =
|
|
|
|
metrics->border.track.left =
|
|
|
|
metrics->border.track.right = trough_border;
|
|
|
|
}
|
|
|
|
|
|
|
|
return metrics;
|
|
|
|
}
|
|
|
|
|
|
|
|
// GTK version > 3.20
|
2017-03-27 21:32:42 +03:00
|
|
|
// scrollbar
|
|
|
|
metrics->border.scrollbar = GetMarginBorderPadding(style);
|
|
|
|
|
2017-03-27 21:32:25 +03:00
|
|
|
WidgetNodeType contents, track, thumb;
|
|
|
|
if (aOrientation == GTK_ORIENTATION_HORIZONTAL) {
|
|
|
|
contents = MOZ_GTK_SCROLLBAR_CONTENTS_HORIZONTAL;
|
|
|
|
track = MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL;
|
|
|
|
thumb = MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL;
|
|
|
|
} else {
|
|
|
|
contents = MOZ_GTK_SCROLLBAR_CONTENTS_VERTICAL;
|
|
|
|
track = MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL;
|
|
|
|
thumb = MOZ_GTK_SCROLLBAR_THUMB_VERTICAL;
|
|
|
|
}
|
|
|
|
// thumb
|
|
|
|
metrics->size.thumb = GetMinMarginBox(thumb);
|
|
|
|
// track
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext(track);
|
2017-03-27 21:32:25 +03:00
|
|
|
metrics->border.track = GetMarginBorderPadding(style);
|
2017-03-27 21:32:51 +03:00
|
|
|
MozGtkSize trackMinSize = GetMinContentBox(style) + metrics->border.track;
|
2017-03-27 21:32:42 +03:00
|
|
|
MozGtkSize trackSizeForThumb = metrics->size.thumb + metrics->border.track;
|
2017-03-27 21:32:25 +03:00
|
|
|
// button
|
2017-03-27 21:32:42 +03:00
|
|
|
if (hasButtons) {
|
|
|
|
metrics->size.button = GetMinMarginBox(MOZ_GTK_SCROLLBAR_BUTTON);
|
2017-03-27 21:32:51 +03:00
|
|
|
} else {
|
|
|
|
metrics->size.button = {0, 0};
|
|
|
|
}
|
|
|
|
if (aOrientation == GTK_ORIENTATION_HORIZONTAL) {
|
|
|
|
metrics->size.button.Rotate();
|
|
|
|
// If the track is wider than necessary for the thumb, including when
|
|
|
|
// the buttons will cause Gecko to expand the track to fill
|
|
|
|
// available breadth, then add to the track border to prevent Gecko
|
|
|
|
// from expanding the thumb to fill available breadth.
|
|
|
|
gint extra =
|
|
|
|
std::max(trackMinSize.height,
|
|
|
|
metrics->size.button.height) - trackSizeForThumb.height;
|
|
|
|
if (extra > 0) {
|
|
|
|
// If extra is odd, then the thumb is 0.5 pixels above
|
|
|
|
// center as in gtk_range_compute_slider_position().
|
|
|
|
metrics->border.track.top += extra / 2;
|
|
|
|
metrics->border.track.bottom += extra - extra / 2;
|
|
|
|
// Update size for change in border.
|
|
|
|
trackSizeForThumb.height += extra;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
gint extra =
|
|
|
|
std::max(trackMinSize.width,
|
|
|
|
metrics->size.button.width) - trackSizeForThumb.width;
|
|
|
|
if (extra > 0) {
|
|
|
|
// If extra is odd, then the thumb is 0.5 pixels to the left
|
|
|
|
// of center as in gtk_range_compute_slider_position().
|
|
|
|
metrics->border.track.left += extra / 2;
|
|
|
|
metrics->border.track.right += extra - extra / 2;
|
|
|
|
trackSizeForThumb.width += extra;
|
2017-03-27 21:32:42 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-05 00:16:01 +03:00
|
|
|
style = GetStyleContext(contents);
|
2017-03-27 21:32:25 +03:00
|
|
|
GtkBorder contentsBorder = GetMarginBorderPadding(style);
|
2017-03-27 21:32:42 +03:00
|
|
|
|
|
|
|
metrics->size.scrollbar =
|
|
|
|
trackSizeForThumb + contentsBorder + metrics->border.scrollbar;
|
2012-02-10 17:15:28 +04:00
|
|
|
|
2017-03-27 21:32:25 +03:00
|
|
|
return metrics;
|
2012-02-10 17:15:28 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* cairo_t *cr argument has to be a system-cairo. */
|
|
|
|
gint
|
2016-04-14 08:47:20 +03:00
|
|
|
moz_gtk_widget_paint(WidgetNodeType widget, cairo_t *cr,
|
2013-02-20 17:50:51 +04:00
|
|
|
GdkRectangle* rect,
|
2012-02-10 17:15:28 +04:00
|
|
|
GtkWidgetState* state, gint flags,
|
|
|
|
GtkTextDirection direction)
|
|
|
|
{
|
2013-07-24 17:07:09 +04:00
|
|
|
/* A workaround for https://bugzilla.gnome.org/show_bug.cgi?id=694086
|
|
|
|
*/
|
|
|
|
cairo_new_path(cr);
|
|
|
|
|
2012-02-10 17:15:28 +04:00
|
|
|
switch (widget) {
|
|
|
|
case MOZ_GTK_BUTTON:
|
2015-08-07 08:09:00 +03:00
|
|
|
case MOZ_GTK_TOOLBAR_BUTTON:
|
2012-02-10 17:15:28 +04:00
|
|
|
if (state->depressed) {
|
2013-02-20 17:50:51 +04:00
|
|
|
return moz_gtk_button_paint(cr, rect, state,
|
2012-02-10 17:15:28 +04:00
|
|
|
(GtkReliefStyle) flags,
|
2016-07-20 02:57:00 +03:00
|
|
|
GetWidget(MOZ_GTK_TOGGLE_BUTTON),
|
|
|
|
direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
}
|
2013-02-20 17:50:51 +04:00
|
|
|
return moz_gtk_button_paint(cr, rect, state,
|
2016-07-20 02:57:00 +03:00
|
|
|
(GtkReliefStyle) flags,
|
|
|
|
GetWidget(MOZ_GTK_BUTTON),
|
2012-02-10 17:15:28 +04:00
|
|
|
direction);
|
|
|
|
break;
|
2017-09-19 22:15:12 +03:00
|
|
|
case MOZ_GTK_HEADER_BAR_BUTTON_CLOSE:
|
|
|
|
case MOZ_GTK_HEADER_BAR_BUTTON_MINIMIZE:
|
|
|
|
case MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE:
|
2018-02-23 23:28:37 +03:00
|
|
|
case MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE_RESTORE:
|
2017-09-19 22:15:12 +03:00
|
|
|
return moz_gtk_header_bar_button_paint(cr, rect, state,
|
|
|
|
(GtkReliefStyle) flags,
|
2018-01-25 13:13:12 +03:00
|
|
|
widget,
|
2017-09-19 22:15:12 +03:00
|
|
|
direction);
|
|
|
|
break;
|
2012-02-10 17:15:28 +04:00
|
|
|
case MOZ_GTK_CHECKBUTTON:
|
|
|
|
case MOZ_GTK_RADIOBUTTON:
|
2013-02-20 17:50:51 +04:00
|
|
|
return moz_gtk_toggle_paint(cr, rect, state,
|
2012-02-10 17:15:28 +04:00
|
|
|
!!(flags & MOZ_GTK_WIDGET_CHECKED),
|
|
|
|
!!(flags & MOZ_GTK_WIDGET_INCONSISTENT),
|
|
|
|
(widget == MOZ_GTK_RADIOBUTTON),
|
|
|
|
direction);
|
|
|
|
break;
|
|
|
|
case MOZ_GTK_SCROLLBAR_BUTTON:
|
2013-02-20 17:50:51 +04:00
|
|
|
return moz_gtk_scrollbar_button_paint(cr, rect, state,
|
2012-02-10 17:15:28 +04:00
|
|
|
(GtkScrollbarButtonFlags) flags,
|
|
|
|
direction);
|
|
|
|
break;
|
2015-12-22 07:05:00 +03:00
|
|
|
case MOZ_GTK_SCROLLBAR_HORIZONTAL:
|
|
|
|
case MOZ_GTK_SCROLLBAR_VERTICAL:
|
2017-03-16 08:02:27 +03:00
|
|
|
if (flags & MOZ_GTK_TRACK_OPAQUE) {
|
|
|
|
GtkStyleContext* style =
|
2017-09-05 00:16:01 +03:00
|
|
|
GetStyleContext(MOZ_GTK_WINDOW, direction);
|
2017-03-16 08:02:27 +03:00
|
|
|
gtk_render_background(style, cr,
|
|
|
|
rect->x, rect->y, rect->width, rect->height);
|
|
|
|
}
|
Bug 1289148 - Fixing scrollbar metrics for GTK >= 3.20 r=karlt
The Gtk 3.20 scrollbars has moved towards usual box model. The scrollbar,
trough,thumb and scrollbar button can now have margin, padding and border set,
different for each direction (ie. left, right, bottom, top). The scrollbar
metrics become ignored in Gtk 3.20 and later.
* Draw scrollbar element [for GTK 3.20+]
* The border for scrollbar, trough, thumb and scrollbar buttons is newly
calculated as margin+padding+border [for GTK 3.20+].
* The margin is subtracted for scrollbar, trough and sb buttons during paint
function [for GTK 3.6+]
* All scrollbar widget's borders transfered from
nsNativeThemeGTK::GetWidgetBorder to the moz_gtk_get_widget_border.
* Added helper function NativeThemeToGtkTheme for mapping mozilla's widget type
to the gtk widget type.
* Scrollbar troughs are now drawn even when there is not enough room for
the thumb [GTK 3.20+]
MozReview-Commit-ID: jd2q67gKM1
--HG--
extra : rebase_source : ecc8b85401845113d84c6c5a48219a0c3d4f8de3
2016-10-17 01:37:13 +03:00
|
|
|
if (gtk_check_version(3,20,0) == nullptr) {
|
|
|
|
return moz_gtk_scrollbar_paint(widget, cr, rect, state, direction);
|
|
|
|
} else {
|
|
|
|
WidgetNodeType trough_widget = (widget == MOZ_GTK_SCROLLBAR_HORIZONTAL) ?
|
|
|
|
MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL : MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL;
|
|
|
|
return moz_gtk_scrollbar_trough_paint(trough_widget, cr, rect,
|
2017-03-16 08:02:27 +03:00
|
|
|
state, direction);
|
Bug 1289148 - Fixing scrollbar metrics for GTK >= 3.20 r=karlt
The Gtk 3.20 scrollbars has moved towards usual box model. The scrollbar,
trough,thumb and scrollbar button can now have margin, padding and border set,
different for each direction (ie. left, right, bottom, top). The scrollbar
metrics become ignored in Gtk 3.20 and later.
* Draw scrollbar element [for GTK 3.20+]
* The border for scrollbar, trough, thumb and scrollbar buttons is newly
calculated as margin+padding+border [for GTK 3.20+].
* The margin is subtracted for scrollbar, trough and sb buttons during paint
function [for GTK 3.6+]
* All scrollbar widget's borders transfered from
nsNativeThemeGTK::GetWidgetBorder to the moz_gtk_get_widget_border.
* Added helper function NativeThemeToGtkTheme for mapping mozilla's widget type
to the gtk widget type.
* Scrollbar troughs are now drawn even when there is not enough room for
the thumb [GTK 3.20+]
MozReview-Commit-ID: jd2q67gKM1
--HG--
extra : rebase_source : ecc8b85401845113d84c6c5a48219a0c3d4f8de3
2016-10-17 01:37:13 +03:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL:
|
|
|
|
case MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL:
|
|
|
|
if (gtk_check_version(3,20,0) == nullptr) {
|
|
|
|
return moz_gtk_scrollbar_trough_paint(widget, cr, rect,
|
2017-03-16 08:02:27 +03:00
|
|
|
state, direction);
|
Bug 1289148 - Fixing scrollbar metrics for GTK >= 3.20 r=karlt
The Gtk 3.20 scrollbars has moved towards usual box model. The scrollbar,
trough,thumb and scrollbar button can now have margin, padding and border set,
different for each direction (ie. left, right, bottom, top). The scrollbar
metrics become ignored in Gtk 3.20 and later.
* Draw scrollbar element [for GTK 3.20+]
* The border for scrollbar, trough, thumb and scrollbar buttons is newly
calculated as margin+padding+border [for GTK 3.20+].
* The margin is subtracted for scrollbar, trough and sb buttons during paint
function [for GTK 3.6+]
* All scrollbar widget's borders transfered from
nsNativeThemeGTK::GetWidgetBorder to the moz_gtk_get_widget_border.
* Added helper function NativeThemeToGtkTheme for mapping mozilla's widget type
to the gtk widget type.
* Scrollbar troughs are now drawn even when there is not enough room for
the thumb [GTK 3.20+]
MozReview-Commit-ID: jd2q67gKM1
--HG--
extra : rebase_source : ecc8b85401845113d84c6c5a48219a0c3d4f8de3
2016-10-17 01:37:13 +03:00
|
|
|
}
|
2012-02-10 17:15:28 +04:00
|
|
|
break;
|
|
|
|
case MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL:
|
|
|
|
case MOZ_GTK_SCROLLBAR_THUMB_VERTICAL:
|
|
|
|
return moz_gtk_scrollbar_thumb_paint(widget, cr, rect,
|
2013-02-20 17:50:51 +04:00
|
|
|
state, direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
break;
|
|
|
|
case MOZ_GTK_SCALE_HORIZONTAL:
|
|
|
|
case MOZ_GTK_SCALE_VERTICAL:
|
2013-02-20 17:50:51 +04:00
|
|
|
return moz_gtk_scale_paint(cr, rect, state,
|
2012-02-10 17:15:28 +04:00
|
|
|
(GtkOrientation) flags, direction);
|
|
|
|
break;
|
|
|
|
case MOZ_GTK_SCALE_THUMB_HORIZONTAL:
|
|
|
|
case MOZ_GTK_SCALE_THUMB_VERTICAL:
|
2013-02-20 17:50:51 +04:00
|
|
|
return moz_gtk_scale_thumb_paint(cr, rect, state,
|
2012-02-10 17:15:28 +04:00
|
|
|
(GtkOrientation) flags, direction);
|
|
|
|
break;
|
2017-11-29 05:43:13 +03:00
|
|
|
case MOZ_GTK_INNER_SPIN_BUTTON:
|
|
|
|
return moz_gtk_inner_spin_paint(cr, rect, state, direction);
|
|
|
|
break;
|
2012-02-10 17:15:28 +04:00
|
|
|
case MOZ_GTK_SPINBUTTON:
|
|
|
|
return moz_gtk_spin_paint(cr, rect, direction);
|
|
|
|
break;
|
|
|
|
case MOZ_GTK_SPINBUTTON_UP:
|
|
|
|
case MOZ_GTK_SPINBUTTON_DOWN:
|
|
|
|
return moz_gtk_spin_updown_paint(cr, rect,
|
|
|
|
(widget == MOZ_GTK_SPINBUTTON_DOWN),
|
|
|
|
state, direction);
|
|
|
|
break;
|
|
|
|
case MOZ_GTK_SPINBUTTON_ENTRY:
|
2016-10-19 05:13:25 +03:00
|
|
|
{
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style =
|
|
|
|
GetStyleContext(MOZ_GTK_SPINBUTTON_ENTRY, direction,
|
|
|
|
GetStateFlagsFromGtkWidgetState(state));
|
2016-10-19 05:13:25 +03:00
|
|
|
gint ret = moz_gtk_entry_paint(cr, rect, state, style);
|
|
|
|
return ret;
|
|
|
|
}
|
2012-02-10 17:15:28 +04:00
|
|
|
break;
|
|
|
|
case MOZ_GTK_GRIPPER:
|
2013-02-20 17:50:51 +04:00
|
|
|
return moz_gtk_gripper_paint(cr, rect, state,
|
2012-02-10 17:15:28 +04:00
|
|
|
direction);
|
|
|
|
break;
|
|
|
|
case MOZ_GTK_TREEVIEW:
|
2013-02-20 17:50:51 +04:00
|
|
|
return moz_gtk_treeview_paint(cr, rect, state,
|
2012-02-10 17:15:28 +04:00
|
|
|
direction);
|
|
|
|
break;
|
|
|
|
case MOZ_GTK_TREE_HEADER_CELL:
|
2013-02-20 17:50:51 +04:00
|
|
|
return moz_gtk_tree_header_cell_paint(cr, rect, state,
|
2012-02-10 17:15:28 +04:00
|
|
|
flags, direction);
|
|
|
|
break;
|
|
|
|
case MOZ_GTK_TREE_HEADER_SORTARROW:
|
2017-12-19 13:38:59 +03:00
|
|
|
return moz_gtk_tree_header_sort_arrow_paint(cr, rect,
|
2012-02-10 17:15:28 +04:00
|
|
|
state,
|
|
|
|
(GtkArrowType) flags,
|
|
|
|
direction);
|
|
|
|
break;
|
|
|
|
case MOZ_GTK_TREEVIEW_EXPANDER:
|
2013-02-20 17:50:51 +04:00
|
|
|
return moz_gtk_treeview_expander_paint(cr, rect, state,
|
2012-02-10 17:15:28 +04:00
|
|
|
(GtkExpanderStyle) flags, direction);
|
|
|
|
break;
|
|
|
|
case MOZ_GTK_ENTRY:
|
2016-10-19 05:13:25 +03:00
|
|
|
{
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style =
|
|
|
|
GetStyleContext(MOZ_GTK_ENTRY, direction,
|
|
|
|
GetStateFlagsFromGtkWidgetState(state));
|
2016-10-19 05:13:25 +03:00
|
|
|
gint ret = moz_gtk_entry_paint(cr, rect, state, style);
|
|
|
|
return ret;
|
|
|
|
}
|
2016-04-27 02:07:00 +03:00
|
|
|
case MOZ_GTK_TEXT_VIEW:
|
|
|
|
return moz_gtk_text_view_paint(cr, rect, state, direction);
|
|
|
|
break;
|
2012-02-10 17:15:28 +04:00
|
|
|
case MOZ_GTK_DROPDOWN:
|
2015-11-18 04:11:58 +03:00
|
|
|
return moz_gtk_combo_box_paint(cr, rect, state, direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
break;
|
|
|
|
case MOZ_GTK_DROPDOWN_ARROW:
|
2013-06-04 16:23:29 +04:00
|
|
|
return moz_gtk_combo_box_entry_button_paint(cr, rect,
|
2012-02-10 17:15:28 +04:00
|
|
|
state, flags, direction);
|
|
|
|
break;
|
|
|
|
case MOZ_GTK_DROPDOWN_ENTRY:
|
2016-10-19 05:13:25 +03:00
|
|
|
{
|
2017-09-05 00:16:01 +03:00
|
|
|
GtkStyleContext* style =
|
|
|
|
GetStyleContext(MOZ_GTK_COMBOBOX_ENTRY_TEXTAREA, direction,
|
|
|
|
GetStateFlagsFromGtkWidgetState(state));
|
2016-10-19 05:13:25 +03:00
|
|
|
gint ret = moz_gtk_entry_paint(cr, rect, state, style);
|
|
|
|
return ret;
|
|
|
|
}
|
2012-02-10 17:15:28 +04:00
|
|
|
break;
|
|
|
|
case MOZ_GTK_CHECKBUTTON_CONTAINER:
|
|
|
|
case MOZ_GTK_RADIOBUTTON_CONTAINER:
|
2016-05-13 02:59:17 +03:00
|
|
|
return moz_gtk_container_paint(cr, rect, state, widget, direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
break;
|
|
|
|
case MOZ_GTK_CHECKBUTTON_LABEL:
|
|
|
|
case MOZ_GTK_RADIOBUTTON_LABEL:
|
2013-02-20 17:50:51 +04:00
|
|
|
return moz_gtk_toggle_label_paint(cr, rect, state,
|
2012-02-10 17:15:28 +04:00
|
|
|
(widget == MOZ_GTK_RADIOBUTTON_LABEL),
|
|
|
|
direction);
|
|
|
|
break;
|
|
|
|
case MOZ_GTK_TOOLBAR:
|
2013-02-20 17:50:51 +04:00
|
|
|
return moz_gtk_toolbar_paint(cr, rect, direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
break;
|
|
|
|
case MOZ_GTK_TOOLBAR_SEPARATOR:
|
2013-06-04 16:23:29 +04:00
|
|
|
return moz_gtk_toolbar_separator_paint(cr, rect,
|
2012-02-10 17:15:28 +04:00
|
|
|
direction);
|
|
|
|
break;
|
|
|
|
case MOZ_GTK_TOOLTIP:
|
2013-02-20 17:50:51 +04:00
|
|
|
return moz_gtk_tooltip_paint(cr, rect, direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
break;
|
|
|
|
case MOZ_GTK_FRAME:
|
2013-02-20 17:50:51 +04:00
|
|
|
return moz_gtk_frame_paint(cr, rect, direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
break;
|
|
|
|
case MOZ_GTK_RESIZER:
|
2013-02-20 17:50:51 +04:00
|
|
|
return moz_gtk_resizer_paint(cr, rect, state,
|
2012-02-10 17:15:28 +04:00
|
|
|
direction);
|
|
|
|
break;
|
|
|
|
case MOZ_GTK_PROGRESSBAR:
|
2013-02-20 17:50:51 +04:00
|
|
|
return moz_gtk_progressbar_paint(cr, rect, direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
break;
|
|
|
|
case MOZ_GTK_PROGRESS_CHUNK:
|
|
|
|
case MOZ_GTK_PROGRESS_CHUNK_INDETERMINATE:
|
|
|
|
case MOZ_GTK_PROGRESS_CHUNK_VERTICAL_INDETERMINATE:
|
2013-06-04 16:23:29 +04:00
|
|
|
return moz_gtk_progress_chunk_paint(cr, rect,
|
2012-02-10 17:15:28 +04:00
|
|
|
direction, widget);
|
|
|
|
break;
|
2016-08-22 06:13:00 +03:00
|
|
|
case MOZ_GTK_TAB_TOP:
|
|
|
|
case MOZ_GTK_TAB_BOTTOM:
|
2013-02-20 17:50:51 +04:00
|
|
|
return moz_gtk_tab_paint(cr, rect, state,
|
2016-08-22 06:13:00 +03:00
|
|
|
(GtkTabFlags) flags, direction, widget);
|
2012-02-10 17:15:28 +04:00
|
|
|
break;
|
|
|
|
case MOZ_GTK_TABPANELS:
|
2013-02-20 17:50:51 +04:00
|
|
|
return moz_gtk_tabpanels_paint(cr, rect, direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
break;
|
|
|
|
case MOZ_GTK_TAB_SCROLLARROW:
|
2013-02-20 17:50:51 +04:00
|
|
|
return moz_gtk_tab_scroll_arrow_paint(cr, rect, state,
|
2012-02-10 17:15:28 +04:00
|
|
|
(GtkArrowType) flags, direction);
|
|
|
|
break;
|
|
|
|
case MOZ_GTK_MENUBAR:
|
2013-02-20 17:50:51 +04:00
|
|
|
return moz_gtk_menu_bar_paint(cr, rect, direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
break;
|
|
|
|
case MOZ_GTK_MENUPOPUP:
|
2013-02-20 17:50:51 +04:00
|
|
|
return moz_gtk_menu_popup_paint(cr, rect, direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
break;
|
|
|
|
case MOZ_GTK_MENUSEPARATOR:
|
2013-06-04 16:23:29 +04:00
|
|
|
return moz_gtk_menu_separator_paint(cr, rect,
|
2012-02-10 17:15:28 +04:00
|
|
|
direction);
|
|
|
|
break;
|
2016-05-19 07:55:04 +03:00
|
|
|
case MOZ_GTK_MENUBARITEM:
|
2012-02-10 17:15:28 +04:00
|
|
|
case MOZ_GTK_MENUITEM:
|
2016-05-19 07:55:04 +03:00
|
|
|
return moz_gtk_menu_item_paint(widget, cr, rect, state, direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
break;
|
|
|
|
case MOZ_GTK_MENUARROW:
|
2013-02-20 17:50:51 +04:00
|
|
|
return moz_gtk_menu_arrow_paint(cr, rect, state,
|
2012-02-10 17:15:28 +04:00
|
|
|
direction);
|
|
|
|
break;
|
|
|
|
case MOZ_GTK_TOOLBARBUTTON_ARROW:
|
2013-02-20 17:50:51 +04:00
|
|
|
return moz_gtk_arrow_paint(cr, rect, state,
|
2012-02-10 17:15:28 +04:00
|
|
|
(GtkArrowType) flags, direction);
|
|
|
|
break;
|
|
|
|
case MOZ_GTK_CHECKMENUITEM:
|
|
|
|
case MOZ_GTK_RADIOMENUITEM:
|
2016-11-18 03:01:27 +03:00
|
|
|
return moz_gtk_check_menu_item_paint(widget, cr, rect, state,
|
|
|
|
(gboolean) flags, direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
break;
|
|
|
|
case MOZ_GTK_SPLITTER_HORIZONTAL:
|
2013-02-20 17:50:51 +04:00
|
|
|
return moz_gtk_vpaned_paint(cr, rect, state);
|
2012-02-10 17:15:28 +04:00
|
|
|
break;
|
|
|
|
case MOZ_GTK_SPLITTER_VERTICAL:
|
2013-02-20 17:50:51 +04:00
|
|
|
return moz_gtk_hpaned_paint(cr, rect, state);
|
2012-02-10 17:15:28 +04:00
|
|
|
break;
|
|
|
|
case MOZ_GTK_WINDOW:
|
2013-02-20 17:50:51 +04:00
|
|
|
return moz_gtk_window_paint(cr, rect, direction);
|
2012-02-10 17:15:28 +04:00
|
|
|
break;
|
2015-08-19 22:42:17 +03:00
|
|
|
case MOZ_GTK_INFO_BAR:
|
|
|
|
return moz_gtk_info_bar_paint(cr, rect, state);
|
|
|
|
break;
|
2017-09-19 22:15:12 +03:00
|
|
|
case MOZ_GTK_HEADER_BAR:
|
|
|
|
case MOZ_GTK_HEADER_BAR_MAXIMIZED:
|
|
|
|
return moz_gtk_header_bar_paint(widget, cr, rect, state);
|
|
|
|
break;
|
2012-02-10 17:15:28 +04:00
|
|
|
default:
|
|
|
|
g_warning("Unknown widget type: %d", widget);
|
|
|
|
}
|
|
|
|
|
|
|
|
return MOZ_GTK_UNKNOWN_WIDGET;
|
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
|
|
|
moz_gtk_shutdown()
|
|
|
|
{
|
|
|
|
/* This will destroy all of our widgets */
|
2016-05-09 02:08:26 +03:00
|
|
|
ResetWidgetCache();
|
2012-02-10 17:15:28 +04:00
|
|
|
|
|
|
|
return MOZ_GTK_SUCCESS;
|
|
|
|
}
|