Factor out common checkbox-related code into CheckBoxInfo
No real changes, just extract the same code used in both GTK 2 and GTK 3 implementations of GetCheckBoxSize() and DrawCheckBox() in a helper class which is now just used from both places. This makes the code more clear and hopefully easier to maintain in the future.
This commit is contained in:
@@ -549,24 +549,99 @@ wxRendererGTK::DrawComboBoxDropButton(wxWindow *win,
|
|||||||
DrawDropArrow(win,dc,rect);
|
DrawDropArrow(win,dc,rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __WXGTK3__
|
// Helper used by GetCheckBoxSize() and DrawCheckBox().
|
||||||
static void CheckBoxSize(wxGtkStyleContext& sc, int& w, int& h, GtkBorder* extra = NULL)
|
namespace
|
||||||
{
|
{
|
||||||
gtk_style_context_get(sc, GTK_STATE_FLAG_NORMAL,
|
|
||||||
"min-width", &w, "min-height", &h, NULL);
|
struct CheckBoxInfo
|
||||||
GtkBorder border, padding;
|
{
|
||||||
gtk_style_context_get_border(sc, GTK_STATE_FLAG_NORMAL, &border);
|
#ifdef __WXGTK3__
|
||||||
gtk_style_context_get_padding(sc, GTK_STATE_FLAG_NORMAL, &padding);
|
CheckBoxInfo(wxGtkStyleContext& sc, int flags)
|
||||||
border.left += padding.left;
|
{
|
||||||
border.right += padding.right;
|
wxUnusedVar(flags);
|
||||||
border.top += padding.top;
|
|
||||||
border.bottom += padding.bottom;
|
sc.AddCheckButton();
|
||||||
w += border.left + border.right;
|
if (gtk_check_version(3,20,0) == NULL)
|
||||||
h += border.top + border.bottom;
|
{
|
||||||
if (extra)
|
sc.Add("check");
|
||||||
*extra = border;
|
gtk_style_context_get(sc, GTK_STATE_FLAG_NORMAL,
|
||||||
}
|
"min-width", &indicator_width,
|
||||||
#endif // __WXGTK3__
|
"min-height", &indicator_height,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
GtkBorder border, padding;
|
||||||
|
gtk_style_context_get_border(sc, GTK_STATE_FLAG_NORMAL, &border);
|
||||||
|
gtk_style_context_get_padding(sc, GTK_STATE_FLAG_NORMAL, &padding);
|
||||||
|
|
||||||
|
margin_left = border.left + padding.left;
|
||||||
|
margin_top = border.top + padding.top;
|
||||||
|
margin_right = border.right + padding.right;
|
||||||
|
margin_bottom = border.bottom + padding.bottom;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GValue value = G_VALUE_INIT;
|
||||||
|
g_value_init(&value, G_TYPE_INT);
|
||||||
|
|
||||||
|
gtk_style_context_get_style_property(sc, "indicator-size", &value);
|
||||||
|
indicator_width =
|
||||||
|
indicator_height = g_value_get_int(&value);
|
||||||
|
|
||||||
|
gtk_style_context_get_style_property(sc, "indicator-spacing", &value);
|
||||||
|
margin_left =
|
||||||
|
margin_top =
|
||||||
|
margin_right =
|
||||||
|
margin_bottom = g_value_get_int(&value);
|
||||||
|
|
||||||
|
g_value_unset(&value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else // !__WXGTK3__
|
||||||
|
CheckBoxInfo(GtkWidget* button, int flags)
|
||||||
|
{
|
||||||
|
gint indicator_size, indicator_margin;
|
||||||
|
gtk_widget_style_get(button,
|
||||||
|
"indicator_size", &indicator_size,
|
||||||
|
"indicator_spacing", &indicator_margin,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
// If wxCONTROL_CELL is set then we want to get the size of wxCheckBox
|
||||||
|
// control to draw the check mark centered and at the same position as
|
||||||
|
// wxCheckBox does, so offset the check mark itself by the focus margin
|
||||||
|
// in the same way as gtk_real_check_button_draw_indicator() does it, see
|
||||||
|
// https://github.com/GNOME/gtk/blob/GTK_2_16_0/gtk/gtkcheckbutton.c#L374
|
||||||
|
if ( flags & wxCONTROL_CELL )
|
||||||
|
{
|
||||||
|
gint focus_width, focus_pad;
|
||||||
|
gtk_widget_style_get(button,
|
||||||
|
"focus-line-width", &focus_width,
|
||||||
|
"focus-padding", &focus_pad,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
indicator_margin += focus_width + focus_pad;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In GTK 2 width and height are the same and so are left/right and
|
||||||
|
// top/bottom.
|
||||||
|
indicator_width =
|
||||||
|
indicator_height = indicator_size;
|
||||||
|
|
||||||
|
margin_left =
|
||||||
|
margin_top =
|
||||||
|
margin_right =
|
||||||
|
margin_bottom = indicator_margin;
|
||||||
|
}
|
||||||
|
#endif // __WXGTK3__/!__WXGTK3__
|
||||||
|
|
||||||
|
gint indicator_width,
|
||||||
|
indicator_height;
|
||||||
|
gint margin_left,
|
||||||
|
margin_top,
|
||||||
|
margin_right,
|
||||||
|
margin_bottom;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
wxSize
|
wxSize
|
||||||
wxRendererGTK::GetCheckBoxSize(wxWindow* win, int flags)
|
wxRendererGTK::GetCheckBoxSize(wxWindow* win, int flags)
|
||||||
@@ -578,50 +653,18 @@ wxRendererGTK::GetCheckBoxSize(wxWindow* win, int flags)
|
|||||||
wxCHECK_MSG(win, size, "Must have a valid window");
|
wxCHECK_MSG(win, size, "Must have a valid window");
|
||||||
|
|
||||||
#ifdef __WXGTK3__
|
#ifdef __WXGTK3__
|
||||||
wxUnusedVar(flags);
|
|
||||||
|
|
||||||
wxGtkStyleContext sc(win->GetContentScaleFactor());
|
wxGtkStyleContext sc(win->GetContentScaleFactor());
|
||||||
sc.AddCheckButton();
|
|
||||||
if (gtk_check_version(3,20,0) == NULL)
|
const CheckBoxInfo info(sc, flags);
|
||||||
{
|
|
||||||
sc.Add("check");
|
|
||||||
CheckBoxSize(sc, size.x, size.y);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GValue value = G_VALUE_INIT;
|
|
||||||
g_value_init(&value, G_TYPE_INT);
|
|
||||||
gtk_style_context_get_style_property(sc, "indicator-size", &value);
|
|
||||||
size.x = g_value_get_int(&value);
|
|
||||||
gtk_style_context_get_style_property(sc, "indicator-spacing", &value);
|
|
||||||
size.x += 2 * g_value_get_int(&value);
|
|
||||||
size.y = size.x;
|
|
||||||
g_value_unset(&value);
|
|
||||||
}
|
|
||||||
#else // !__WXGTK3__
|
#else // !__WXGTK3__
|
||||||
gint indicator_size, indicator_spacing, focus_width, focus_pad;
|
GtkWidget* button = wxGTKPrivate::GetCheckButtonWidget();
|
||||||
gtk_widget_style_get(wxGTKPrivate::GetCheckButtonWidget(),
|
|
||||||
"indicator_size", &indicator_size,
|
|
||||||
"indicator_spacing", &indicator_spacing,
|
|
||||||
"focus-line-width", &focus_width,
|
|
||||||
"focus-padding", &focus_pad,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
size.x = indicator_size + indicator_spacing * 2;
|
const CheckBoxInfo info(button, flags);
|
||||||
|
|
||||||
// If wxCONTROL_CELL is set then we want to get the size of wxCheckBox
|
|
||||||
// control to draw the check mark centered and at the same position as
|
|
||||||
// wxCheckBox do. So we should add margins instead of removing.
|
|
||||||
// See gtk_real_check_button_draw_indicator:
|
|
||||||
// https://github.com/GNOME/gtk/blob/GTK_2_16_0/gtk/gtkcheckbutton.c#L374
|
|
||||||
if ( flags & wxCONTROL_CELL )
|
|
||||||
{
|
|
||||||
size.x += 2 * (focus_width + focus_pad);
|
|
||||||
}
|
|
||||||
|
|
||||||
size.y = size.x;
|
|
||||||
#endif // __WXGTK3__/!__WXGTK3__
|
#endif // __WXGTK3__/!__WXGTK3__
|
||||||
|
|
||||||
|
size.x = info.indicator_width + info.margin_left + info.margin_right;
|
||||||
|
size.y = info.indicator_height + info.margin_top + info.margin_bottom;
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -650,41 +693,32 @@ wxRendererGTK::DrawCheckBox(wxWindow*,
|
|||||||
if (flags & wxCONTROL_CURRENT)
|
if (flags & wxCONTROL_CURRENT)
|
||||||
state |= GTK_STATE_FLAG_PRELIGHT;
|
state |= GTK_STATE_FLAG_PRELIGHT;
|
||||||
|
|
||||||
int w, h;
|
|
||||||
wxGtkStyleContext sc(dc.GetContentScaleFactor());
|
wxGtkStyleContext sc(dc.GetContentScaleFactor());
|
||||||
sc.AddCheckButton();
|
|
||||||
|
const CheckBoxInfo info(sc, flags);
|
||||||
|
|
||||||
|
const int w = info.indicator_width + info.margin_left + info.margin_right;
|
||||||
|
const int h = info.indicator_height + info.margin_top + info.margin_bottom;
|
||||||
|
|
||||||
|
const int x = rect.x + (rect.width - w) / 2;
|
||||||
|
const int y = rect.y + (rect.height - h) / 2;
|
||||||
|
|
||||||
if (gtk_check_version(3,20,0) == NULL)
|
if (gtk_check_version(3,20,0) == NULL)
|
||||||
{
|
{
|
||||||
sc.Add("check");
|
|
||||||
GtkBorder extra;
|
|
||||||
CheckBoxSize(sc, w, h, &extra);
|
|
||||||
|
|
||||||
int x = rect.x + (rect.width - w) / 2;
|
|
||||||
int y = rect.y + (rect.height - h) / 2;
|
|
||||||
gtk_style_context_set_state(sc, GtkStateFlags(state));
|
gtk_style_context_set_state(sc, GtkStateFlags(state));
|
||||||
gtk_render_background(sc, cr, x, y, w, h);
|
gtk_render_background(sc, cr, x, y, w, h);
|
||||||
gtk_render_frame(sc, cr, x, y, w, h);
|
gtk_render_frame(sc, cr, x, y, w, h);
|
||||||
|
|
||||||
// check is rendered in content area
|
// check is rendered in content area
|
||||||
x += extra.left;
|
gtk_render_check(sc, cr,
|
||||||
y += extra.top;
|
x + info.margin_left, y + info.margin_top,
|
||||||
w -= extra.left + extra.right;
|
info.indicator_width, info.indicator_height);
|
||||||
h -= extra.top + extra.bottom;
|
|
||||||
gtk_render_check(sc, cr, x, y, w, h);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GValue value = G_VALUE_INIT;
|
|
||||||
g_value_init(&value, G_TYPE_INT);
|
|
||||||
gtk_style_context_get_style_property(sc, "indicator-size", &value);
|
|
||||||
w = h = g_value_get_int(&value);
|
|
||||||
g_value_unset(&value);
|
|
||||||
|
|
||||||
// need save/restore for GTK+ 3.6 & 3.8
|
// need save/restore for GTK+ 3.6 & 3.8
|
||||||
gtk_style_context_save(sc);
|
gtk_style_context_save(sc);
|
||||||
gtk_style_context_set_state(sc, GtkStateFlags(state));
|
gtk_style_context_set_state(sc, GtkStateFlags(state));
|
||||||
const int x = rect.x + (rect.width - w) / 2;
|
|
||||||
const int y = rect.y + (rect.height - h) / 2;
|
|
||||||
gtk_render_background(sc, cr, x, y, w, h);
|
gtk_render_background(sc, cr, x, y, w, h);
|
||||||
gtk_render_frame(sc, cr, x, y, w, h);
|
gtk_render_frame(sc, cr, x, y, w, h);
|
||||||
gtk_style_context_add_class(sc, "check");
|
gtk_style_context_add_class(sc, "check");
|
||||||
@@ -692,15 +726,9 @@ wxRendererGTK::DrawCheckBox(wxWindow*,
|
|||||||
gtk_style_context_restore(sc);
|
gtk_style_context_restore(sc);
|
||||||
}
|
}
|
||||||
#else // !__WXGTK3__
|
#else // !__WXGTK3__
|
||||||
GtkWidget *button = wxGTKPrivate::GetCheckButtonWidget();
|
GtkWidget* button = wxGTKPrivate::GetCheckButtonWidget();
|
||||||
|
|
||||||
gint indicator_size, indicator_spacing, focus_width, focus_pad;
|
const CheckBoxInfo info(button, flags);
|
||||||
gtk_widget_style_get(button,
|
|
||||||
"indicator_size", &indicator_size,
|
|
||||||
"indicator_spacing", &indicator_spacing,
|
|
||||||
"focus-line-width", &focus_width,
|
|
||||||
"focus-padding", &focus_pad,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
GtkStateType state;
|
GtkStateType state;
|
||||||
|
|
||||||
@@ -726,16 +754,6 @@ wxRendererGTK::DrawCheckBox(wxWindow*,
|
|||||||
if (gdk_window == NULL)
|
if (gdk_window == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
gint offsetX = indicator_spacing;
|
|
||||||
|
|
||||||
// If wxCONTROL_CELL is set then we want to draw the check mark
|
|
||||||
// at the same position as wxCheckBox do.
|
|
||||||
// See wxRendererGTK::GetCheckBoxSize.
|
|
||||||
if ( flags & wxCONTROL_CELL )
|
|
||||||
{
|
|
||||||
offsetX += focus_width + focus_pad;
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_paint_check
|
gtk_paint_check
|
||||||
(
|
(
|
||||||
gtk_widget_get_style(button),
|
gtk_widget_get_style(button),
|
||||||
@@ -745,9 +763,9 @@ wxRendererGTK::DrawCheckBox(wxWindow*,
|
|||||||
NULL,
|
NULL,
|
||||||
button,
|
button,
|
||||||
"cellcheck",
|
"cellcheck",
|
||||||
dc.LogicalToDeviceX(rect.x) + offsetX,
|
dc.LogicalToDeviceX(rect.x) + info.margin_left,
|
||||||
dc.LogicalToDeviceY(rect.y) + (rect.height - indicator_size) / 2,
|
dc.LogicalToDeviceY(rect.y) + (rect.height - info.indicator_height) / 2,
|
||||||
indicator_size, indicator_size
|
info.indicator_width, info.indicator_height
|
||||||
);
|
);
|
||||||
#endif // __WXGTK3__/!__WXGTK3__
|
#endif // __WXGTK3__/!__WXGTK3__
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user