Fix rendering of check and radio buttons with GTK+ >= 3.20
(cherry picked from commit e627970ba6
)
This commit is contained in:
@@ -503,6 +503,49 @@ wxRendererGTK::DrawComboBoxDropButton(wxWindow *win,
|
|||||||
wxSize
|
wxSize
|
||||||
wxRendererGTK::GetCheckBoxSize(wxWindow *WXUNUSED(win))
|
wxRendererGTK::GetCheckBoxSize(wxWindow *WXUNUSED(win))
|
||||||
{
|
{
|
||||||
|
#ifdef __WXGTK3__
|
||||||
|
int min_width, min_height;
|
||||||
|
GtkWidgetPath* path = gtk_widget_path_new();
|
||||||
|
GtkStyleContext* sc = gtk_style_context_new();
|
||||||
|
GtkStyleContext* sc1 = NULL;
|
||||||
|
gtk_widget_path_append_type(path, GTK_TYPE_CHECK_BUTTON);
|
||||||
|
#if GTK_CHECK_VERSION(3,20,0)
|
||||||
|
if (gtk_check_version(3,20,0) == NULL)
|
||||||
|
{
|
||||||
|
gtk_widget_path_iter_set_object_name(path, -1, "checkbutton");
|
||||||
|
sc1 = gtk_style_context_new();
|
||||||
|
gtk_style_context_set_path(sc1, path);
|
||||||
|
gtk_widget_path_append_type(path, G_TYPE_NONE);
|
||||||
|
gtk_widget_path_iter_set_object_name(path, -1, "check");
|
||||||
|
gtk_style_context_set_path(sc, path);
|
||||||
|
gtk_style_context_set_parent(sc, sc1);
|
||||||
|
gtk_style_context_get(sc, GTK_STATE_FLAG_NORMAL,
|
||||||
|
"min-width", &min_width, "min-height", &min_height, NULL);
|
||||||
|
GtkBorder margin;
|
||||||
|
gtk_style_context_get_margin(sc, GTK_STATE_FLAG_NORMAL, &margin);
|
||||||
|
min_width += margin.left + margin.right;
|
||||||
|
min_height += margin.top + margin.bottom;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
gtk_style_context_set_path(sc, path);
|
||||||
|
GValue value = G_VALUE_INIT;
|
||||||
|
g_value_init(&value, G_TYPE_INT);
|
||||||
|
gtk_style_context_get_style_property(sc, "indicator-size", &value);
|
||||||
|
min_width = g_value_get_int(&value);
|
||||||
|
gtk_style_context_get_style_property(sc, "indicator-spacing", &value);
|
||||||
|
min_width += 2 * g_value_get_int(&value);
|
||||||
|
min_height = min_width;
|
||||||
|
g_value_unset(&value);
|
||||||
|
}
|
||||||
|
gtk_widget_path_unref(path);
|
||||||
|
g_object_unref(sc);
|
||||||
|
if (sc1)
|
||||||
|
g_object_unref(sc1);
|
||||||
|
|
||||||
|
return wxSize(min_width, min_height);
|
||||||
|
#else // !__WXGTK3__
|
||||||
gint indicator_size, indicator_spacing;
|
gint indicator_size, indicator_spacing;
|
||||||
gtk_widget_style_get(wxGTKPrivate::GetCheckButtonWidget(),
|
gtk_widget_style_get(wxGTKPrivate::GetCheckButtonWidget(),
|
||||||
"indicator_size", &indicator_size,
|
"indicator_size", &indicator_size,
|
||||||
@@ -511,6 +554,7 @@ wxRendererGTK::GetCheckBoxSize(wxWindow *WXUNUSED(win))
|
|||||||
|
|
||||||
int size = indicator_size + indicator_spacing * 2;
|
int size = indicator_size + indicator_spacing * 2;
|
||||||
return wxSize(size, size);
|
return wxSize(size, size);
|
||||||
|
#endif // !__WXGTK3__
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -519,6 +563,7 @@ wxRendererGTK::DrawCheckBox(wxWindow* win,
|
|||||||
const wxRect& rect,
|
const wxRect& rect,
|
||||||
int flags )
|
int flags )
|
||||||
{
|
{
|
||||||
|
#ifndef __WXGTK3__
|
||||||
GtkWidget *button = wxGTKPrivate::GetCheckButtonWidget();
|
GtkWidget *button = wxGTKPrivate::GetCheckButtonWidget();
|
||||||
|
|
||||||
gint indicator_size, indicator_spacing;
|
gint indicator_size, indicator_spacing;
|
||||||
@@ -527,7 +572,6 @@ wxRendererGTK::DrawCheckBox(wxWindow* win,
|
|||||||
"indicator_spacing", &indicator_spacing,
|
"indicator_spacing", &indicator_spacing,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
#ifndef __WXGTK3__
|
|
||||||
GtkStateType state;
|
GtkStateType state;
|
||||||
|
|
||||||
if ( flags & wxCONTROL_PRESSED )
|
if ( flags & wxCONTROL_PRESSED )
|
||||||
@@ -551,31 +595,68 @@ wxRendererGTK::DrawCheckBox(wxWindow* win,
|
|||||||
|
|
||||||
#ifdef __WXGTK3__
|
#ifdef __WXGTK3__
|
||||||
cairo_t* cr = wxGetGTKDrawable(win, dc);
|
cairo_t* cr = wxGetGTKDrawable(win, dc);
|
||||||
if (cr)
|
if (cr == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int state = GTK_STATE_FLAG_NORMAL;
|
||||||
|
if (flags & wxCONTROL_CHECKED)
|
||||||
{
|
{
|
||||||
int stateFlags = GTK_STATE_FLAG_NORMAL;
|
state = GTK_STATE_FLAG_ACTIVE;
|
||||||
if (flags & wxCONTROL_CHECKED)
|
if (gtk_check_version(3,14,0) == NULL)
|
||||||
{
|
state = GTK_STATE_FLAG_CHECKED;
|
||||||
stateFlags = GTK_STATE_FLAG_ACTIVE;
|
|
||||||
if (gtk_check_version(3,14,0) == NULL)
|
|
||||||
stateFlags = GTK_STATE_FLAG_CHECKED;
|
|
||||||
}
|
|
||||||
if (flags & wxCONTROL_DISABLED)
|
|
||||||
stateFlags |= GTK_STATE_FLAG_INSENSITIVE;
|
|
||||||
if (flags & wxCONTROL_UNDETERMINED)
|
|
||||||
stateFlags |= GTK_STATE_FLAG_INCONSISTENT;
|
|
||||||
if (flags & wxCONTROL_CURRENT)
|
|
||||||
stateFlags |= GTK_STATE_FLAG_PRELIGHT;
|
|
||||||
GtkStyleContext* sc = gtk_widget_get_style_context(button);
|
|
||||||
gtk_style_context_save(sc);
|
|
||||||
gtk_style_context_set_state(sc, GtkStateFlags(stateFlags));
|
|
||||||
gtk_style_context_add_class(sc, GTK_STYLE_CLASS_CHECK);
|
|
||||||
gtk_render_check(sc, cr,
|
|
||||||
rect.x + (rect.width - indicator_size) / 2,
|
|
||||||
rect.y + (rect.height - indicator_size) / 2,
|
|
||||||
indicator_size, indicator_size);
|
|
||||||
gtk_style_context_restore(sc);
|
|
||||||
}
|
}
|
||||||
|
if (flags & wxCONTROL_DISABLED)
|
||||||
|
state |= GTK_STATE_FLAG_INSENSITIVE;
|
||||||
|
if (flags & wxCONTROL_UNDETERMINED)
|
||||||
|
state |= GTK_STATE_FLAG_INCONSISTENT;
|
||||||
|
if (flags & wxCONTROL_CURRENT)
|
||||||
|
state |= GTK_STATE_FLAG_PRELIGHT;
|
||||||
|
|
||||||
|
int min_width, min_height;
|
||||||
|
GtkWidgetPath* path = gtk_widget_path_new();
|
||||||
|
GtkStyleContext* sc = gtk_style_context_new();
|
||||||
|
GtkStyleContext* sc1 = NULL;
|
||||||
|
gtk_widget_path_append_type(path, GTK_TYPE_CHECK_BUTTON);
|
||||||
|
#if GTK_CHECK_VERSION(3,20,0)
|
||||||
|
if (gtk_check_version(3,20,0) == NULL)
|
||||||
|
{
|
||||||
|
gtk_widget_path_iter_set_object_name(path, -1, "checkbutton");
|
||||||
|
sc1 = gtk_style_context_new();
|
||||||
|
gtk_style_context_set_path(sc1, path);
|
||||||
|
gtk_widget_path_append_type(path, G_TYPE_NONE);
|
||||||
|
gtk_widget_path_iter_set_object_name(path, -1, "check");
|
||||||
|
gtk_style_context_set_path(sc, path);
|
||||||
|
gtk_style_context_set_parent(sc, sc1);
|
||||||
|
gtk_style_context_get(sc, GTK_STATE_FLAG_NORMAL,
|
||||||
|
"min-width", &min_width, "min-height", &min_height, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
gtk_style_context_set_path(sc, path);
|
||||||
|
GValue value = G_VALUE_INIT;
|
||||||
|
g_value_init(&value, G_TYPE_INT);
|
||||||
|
gtk_style_context_get_style_property(sc, "indicator-size", &value);
|
||||||
|
min_width = g_value_get_int(&value);
|
||||||
|
min_height = min_width;
|
||||||
|
g_value_unset(&value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// need save/restore for GTK+ 3.6 & 3.8
|
||||||
|
gtk_style_context_save(sc);
|
||||||
|
gtk_style_context_set_state(sc, GtkStateFlags(state));
|
||||||
|
const int x = rect.x + (rect.width - min_width) / 2;
|
||||||
|
const int y = rect.y + (rect.height - min_height) / 2;
|
||||||
|
gtk_render_background(sc, cr, x, y, min_width, min_height);
|
||||||
|
gtk_render_frame(sc, cr, x, y, min_width, min_height);
|
||||||
|
gtk_style_context_add_class(sc, "check");
|
||||||
|
gtk_render_check(sc, cr, x, y, min_width, min_height);
|
||||||
|
gtk_style_context_restore(sc);
|
||||||
|
|
||||||
|
gtk_widget_path_unref(path);
|
||||||
|
g_object_unref(sc);
|
||||||
|
if (sc1)
|
||||||
|
g_object_unref(sc1);
|
||||||
#else
|
#else
|
||||||
GdkWindow* gdk_window = wxGetGTKDrawable(win, dc);
|
GdkWindow* gdk_window = wxGetGTKDrawable(win, dc);
|
||||||
if (gdk_window == NULL)
|
if (gdk_window == NULL)
|
||||||
@@ -869,8 +950,6 @@ void wxRendererGTK::DrawRadioBitmap(wxWindow* win, wxDC& dc, const wxRect& rect,
|
|||||||
if (drawable == NULL)
|
if (drawable == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GtkWidget* button = wxGTKPrivate::GetRadioButtonWidget();
|
|
||||||
|
|
||||||
#ifdef __WXGTK3__
|
#ifdef __WXGTK3__
|
||||||
int state = GTK_STATE_FLAG_NORMAL;
|
int state = GTK_STATE_FLAG_NORMAL;
|
||||||
if (flags & wxCONTROL_CHECKED)
|
if (flags & wxCONTROL_CHECKED)
|
||||||
@@ -879,18 +958,61 @@ void wxRendererGTK::DrawRadioBitmap(wxWindow* win, wxDC& dc, const wxRect& rect,
|
|||||||
if (gtk_check_version(3,14,0) == NULL)
|
if (gtk_check_version(3,14,0) == NULL)
|
||||||
state = GTK_STATE_FLAG_CHECKED;
|
state = GTK_STATE_FLAG_CHECKED;
|
||||||
}
|
}
|
||||||
else if (flags & wxCONTROL_UNDETERMINED)
|
|
||||||
state = GTK_STATE_FLAG_INCONSISTENT;
|
|
||||||
if (flags & wxCONTROL_DISABLED)
|
if (flags & wxCONTROL_DISABLED)
|
||||||
state |= GTK_STATE_FLAG_INSENSITIVE;
|
state |= GTK_STATE_FLAG_INSENSITIVE;
|
||||||
|
if (flags & wxCONTROL_UNDETERMINED)
|
||||||
|
state |= GTK_STATE_FLAG_INCONSISTENT;
|
||||||
|
if (flags & wxCONTROL_CURRENT)
|
||||||
|
state |= GTK_STATE_FLAG_PRELIGHT;
|
||||||
|
|
||||||
GtkStyleContext* sc = gtk_widget_get_style_context(button);
|
int min_width, min_height;
|
||||||
|
GtkWidgetPath* path = gtk_widget_path_new();
|
||||||
|
GtkStyleContext* sc = gtk_style_context_new();
|
||||||
|
GtkStyleContext* sc1 = NULL;
|
||||||
|
gtk_widget_path_append_type(path, GTK_TYPE_RADIO_BUTTON);
|
||||||
|
#if GTK_CHECK_VERSION(3,20,0)
|
||||||
|
if (gtk_check_version(3,20,0) == NULL)
|
||||||
|
{
|
||||||
|
gtk_widget_path_iter_set_object_name(path, -1, "radiobutton");
|
||||||
|
sc1 = gtk_style_context_new();
|
||||||
|
gtk_style_context_set_path(sc1, path);
|
||||||
|
gtk_widget_path_append_type(path, G_TYPE_NONE);
|
||||||
|
gtk_widget_path_iter_set_object_name(path, -1, "radio");
|
||||||
|
gtk_style_context_set_path(sc, path);
|
||||||
|
gtk_style_context_set_parent(sc, sc1);
|
||||||
|
gtk_style_context_get(sc, GTK_STATE_FLAG_NORMAL,
|
||||||
|
"min-width", &min_width, "min-height", &min_height, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
gtk_style_context_set_path(sc, path);
|
||||||
|
GValue value = G_VALUE_INIT;
|
||||||
|
g_value_init(&value, G_TYPE_INT);
|
||||||
|
gtk_style_context_get_style_property(sc, "indicator-size", &value);
|
||||||
|
min_width = g_value_get_int(&value);
|
||||||
|
min_height = min_width;
|
||||||
|
g_value_unset(&value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// need save/restore for GTK+ 3.6 & 3.8
|
||||||
gtk_style_context_save(sc);
|
gtk_style_context_save(sc);
|
||||||
gtk_style_context_add_class(sc, GTK_STYLE_CLASS_RADIO);
|
|
||||||
gtk_style_context_set_state(sc, GtkStateFlags(state));
|
gtk_style_context_set_state(sc, GtkStateFlags(state));
|
||||||
gtk_render_option(sc, drawable, rect.x, rect.y, rect.width, rect.height);
|
const int x = rect.x + (rect.width - min_width) / 2;
|
||||||
|
const int y = rect.y + (rect.height - min_height) / 2;
|
||||||
|
gtk_render_background(sc, drawable, x, y, min_width, min_height);
|
||||||
|
gtk_render_frame(sc, drawable, x, y, min_width, min_height);
|
||||||
|
gtk_style_context_add_class(sc, "radio");
|
||||||
|
gtk_render_option(sc, drawable, x, y, min_width, min_height);
|
||||||
gtk_style_context_restore(sc);
|
gtk_style_context_restore(sc);
|
||||||
|
|
||||||
|
gtk_widget_path_unref(path);
|
||||||
|
g_object_unref(sc);
|
||||||
|
if (sc1)
|
||||||
|
g_object_unref(sc1);
|
||||||
#else
|
#else
|
||||||
|
GtkWidget* button = wxGTKPrivate::GetRadioButtonWidget();
|
||||||
|
|
||||||
GtkShadowType shadow_type = GTK_SHADOW_OUT;
|
GtkShadowType shadow_type = GTK_SHADOW_OUT;
|
||||||
if ( flags & wxCONTROL_CHECKED )
|
if ( flags & wxCONTROL_CHECKED )
|
||||||
shadow_type = GTK_SHADOW_IN;
|
shadow_type = GTK_SHADOW_IN;
|
||||||
|
Reference in New Issue
Block a user