Use CSS for window font and colors on GTK3
Avoids deprecated gtk_widget_override_* functions
This commit is contained in:
@@ -1796,41 +1796,6 @@ bool wxTextCtrl::GetStyle(long position, wxTextAttr& style)
|
|||||||
|
|
||||||
void wxTextCtrl::DoApplyWidgetStyle(GtkRcStyle *style)
|
void wxTextCtrl::DoApplyWidgetStyle(GtkRcStyle *style)
|
||||||
{
|
{
|
||||||
#ifdef __WXGTK3__
|
|
||||||
// Preserve selection colors, otherwise the GTK_STATE_FLAG_NORMAL override
|
|
||||||
// will be used, and the selection is invisible
|
|
||||||
const GtkStateFlags selectedFocused =
|
|
||||||
GtkStateFlags(GTK_STATE_FLAG_SELECTED | GTK_STATE_FLAG_FOCUSED);
|
|
||||||
// remove any previous override
|
|
||||||
gtk_widget_override_color(m_text, GTK_STATE_FLAG_NORMAL, NULL);
|
|
||||||
gtk_widget_override_color(m_text, selectedFocused, NULL);
|
|
||||||
gtk_widget_override_background_color(m_text, GTK_STATE_FLAG_NORMAL, NULL);
|
|
||||||
gtk_widget_override_background_color(m_text, selectedFocused, NULL);
|
|
||||||
const bool fg_ok = m_foregroundColour.IsOk();
|
|
||||||
const bool bg_ok = m_backgroundColour.IsOk();
|
|
||||||
if (fg_ok || bg_ok)
|
|
||||||
{
|
|
||||||
GdkRGBA *fg_orig, *bg_orig;
|
|
||||||
GtkStyleContext* context = gtk_widget_get_style_context(m_text);
|
|
||||||
gtk_style_context_save(context);
|
|
||||||
if (IsMultiLine())
|
|
||||||
gtk_style_context_add_class(context, GTK_STYLE_CLASS_VIEW);
|
|
||||||
gtk_style_context_set_state(context, selectedFocused);
|
|
||||||
gtk_style_context_get(context, selectedFocused,
|
|
||||||
"color", &fg_orig, "background-color", &bg_orig,
|
|
||||||
NULL);
|
|
||||||
gtk_style_context_restore(context);
|
|
||||||
|
|
||||||
if (fg_ok)
|
|
||||||
gtk_widget_override_color(m_text, selectedFocused, fg_orig);
|
|
||||||
if (bg_ok)
|
|
||||||
gtk_widget_override_background_color(m_text, selectedFocused, bg_orig);
|
|
||||||
|
|
||||||
gdk_rgba_free(fg_orig);
|
|
||||||
gdk_rgba_free(bg_orig);
|
|
||||||
}
|
|
||||||
#endif // __WXGTK3__
|
|
||||||
|
|
||||||
GTKApplyStyle(m_text, style);
|
GTKApplyStyle(m_text, style);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -4561,27 +4561,121 @@ GtkRcStyle* wxWindowGTK::GTKCreateWidgetStyle()
|
|||||||
|
|
||||||
void wxWindowGTK::GTKApplyWidgetStyle(bool forceStyle)
|
void wxWindowGTK::GTKApplyWidgetStyle(bool forceStyle)
|
||||||
{
|
{
|
||||||
if (forceStyle || m_font.IsOk() ||
|
const wxColour& fg = m_foregroundColour;
|
||||||
m_foregroundColour.IsOk() || m_backgroundColour.IsOk())
|
const wxColour& bg = m_backgroundColour;
|
||||||
|
const bool isFg = fg.IsOk();
|
||||||
|
const bool isBg = bg.IsOk();
|
||||||
|
const bool isFont = m_font.IsOk();
|
||||||
|
if (forceStyle || isFg || isBg || isFont)
|
||||||
{
|
{
|
||||||
#ifdef __WXGTK3__
|
#ifdef __WXGTK3__
|
||||||
if (m_backgroundColour.IsOk())
|
GString* css = g_string_new("*{");
|
||||||
|
if (isFg)
|
||||||
{
|
{
|
||||||
// create a GtkStyleProvider to override "background-image"
|
g_string_append_printf(css, "color:%s;",
|
||||||
if (m_styleProvider == NULL)
|
static_cast<const char*>(fg.GetAsString(wxC2S_HTML_SYNTAX)));
|
||||||
m_styleProvider = GTK_STYLE_PROVIDER(gtk_css_provider_new());
|
}
|
||||||
const char css[] =
|
if (isBg)
|
||||||
"*{background-image:-gtk-gradient(linear,0 0,0 1,"
|
{
|
||||||
"from(rgba(%u,%u,%u,%g)),to(rgba(%u,%u,%u,%g)))}";
|
g_string_append_printf(css, "background:%s;",
|
||||||
char buf[sizeof(css) + 20];
|
static_cast<const char*>(bg.GetAsString(wxC2S_HTML_SYNTAX)));
|
||||||
const unsigned r = m_backgroundColour.Red();
|
}
|
||||||
const unsigned g = m_backgroundColour.Green();
|
if (isFont)
|
||||||
const unsigned b = m_backgroundColour.Blue();
|
{
|
||||||
const double a = m_backgroundColour.Alpha() / 255.0;
|
g_string_append(css, "font:");
|
||||||
g_snprintf(buf, sizeof(buf), css, r, g, b, a, r, g, b, a);
|
const PangoFontDescription* pfd = m_font.GetNativeFontInfo()->description;
|
||||||
gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(m_styleProvider), buf, -1, NULL);
|
if (gtk_check_version(3,22,0))
|
||||||
|
g_string_append(css, wxGtkString(pango_font_description_to_string(pfd)));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const PangoFontMask pfm = pango_font_description_get_set_fields(pfd);
|
||||||
|
if (pfm & PANGO_FONT_MASK_STYLE)
|
||||||
|
{
|
||||||
|
const char* s = "";
|
||||||
|
switch (pango_font_description_get_style(pfd))
|
||||||
|
{
|
||||||
|
case PANGO_STYLE_NORMAL: break;
|
||||||
|
case PANGO_STYLE_OBLIQUE: s = "oblique "; break;
|
||||||
|
case PANGO_STYLE_ITALIC: s = "italic "; break;
|
||||||
|
}
|
||||||
|
g_string_append(css, s);
|
||||||
|
}
|
||||||
|
if (pfm & PANGO_FONT_MASK_VARIANT)
|
||||||
|
{
|
||||||
|
switch (pango_font_description_get_variant(pfd))
|
||||||
|
{
|
||||||
|
case PANGO_VARIANT_NORMAL:
|
||||||
|
break;
|
||||||
|
case PANGO_VARIANT_SMALL_CAPS:
|
||||||
|
g_string_append(css, "small-caps ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pfm & PANGO_FONT_MASK_WEIGHT)
|
||||||
|
{
|
||||||
|
const int weight = pango_font_description_get_weight(pfd);
|
||||||
|
if (weight != PANGO_WEIGHT_NORMAL)
|
||||||
|
g_string_append_printf(css, "%d ", weight);
|
||||||
|
}
|
||||||
|
if (pfm & PANGO_FONT_MASK_STRETCH)
|
||||||
|
{
|
||||||
|
const char* s = "";
|
||||||
|
switch (pango_font_description_get_stretch(pfd))
|
||||||
|
{
|
||||||
|
case PANGO_STRETCH_ULTRA_CONDENSED: s = "ultra-condensed "; break;
|
||||||
|
case PANGO_STRETCH_EXTRA_CONDENSED: s = "extra-condensed "; break;
|
||||||
|
case PANGO_STRETCH_CONDENSED: s = "condensed "; break;
|
||||||
|
case PANGO_STRETCH_SEMI_CONDENSED: s = "semi-condensed "; break;
|
||||||
|
case PANGO_STRETCH_NORMAL: break;
|
||||||
|
case PANGO_STRETCH_SEMI_EXPANDED: s = "semi-expanded "; break;
|
||||||
|
case PANGO_STRETCH_EXPANDED: s = "expanded "; break;
|
||||||
|
case PANGO_STRETCH_EXTRA_EXPANDED: s = "extra-expanded "; break;
|
||||||
|
case PANGO_STRETCH_ULTRA_EXPANDED: s = "ultra-expanded "; break;
|
||||||
|
}
|
||||||
|
g_string_append(css, s);
|
||||||
|
}
|
||||||
|
if (pfm & PANGO_FONT_MASK_SIZE)
|
||||||
|
{
|
||||||
|
const int size = pango_font_description_get_size(pfd);
|
||||||
|
if (pango_font_description_get_size_is_absolute(pfd))
|
||||||
|
g_string_append_printf(css, "%dpx ", size);
|
||||||
|
else
|
||||||
|
g_string_append_printf(css, "%dpt ", size / PANGO_SCALE);
|
||||||
|
}
|
||||||
|
if (pfm & PANGO_FONT_MASK_FAMILY)
|
||||||
|
{
|
||||||
|
g_string_append_printf(css, "\"%s\"",
|
||||||
|
pango_font_description_get_family(pfd));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_string_append_c(css, '}');
|
||||||
|
|
||||||
|
if (isFg && isBg)
|
||||||
|
{
|
||||||
|
// Selection will be invisible, so add textview selection colors.
|
||||||
|
// This is specifically for wxTextCtrl, but may be useful for other
|
||||||
|
// controls, and seems to do no harm to apply to all.
|
||||||
|
const wxColour fg_sel(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT));
|
||||||
|
const wxColour bg_sel(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT));
|
||||||
|
const char* s = "*:selected";
|
||||||
|
if (gtk_check_version(3,20,0) == NULL)
|
||||||
|
s = "selection";
|
||||||
|
g_string_append_printf(css, "%s{color:%s;background:%s}", s,
|
||||||
|
static_cast<const char*>(fg_sel.GetAsString(wxC2S_HTML_SYNTAX)),
|
||||||
|
static_cast<const char*>(bg_sel.GetAsString(wxC2S_HTML_SYNTAX)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_styleProvider == NULL && (isFg || isBg || isFont))
|
||||||
|
m_styleProvider = GTK_STYLE_PROVIDER(gtk_css_provider_new());
|
||||||
|
|
||||||
|
wxGtkString s(g_string_free(css, false));
|
||||||
|
if (m_styleProvider)
|
||||||
|
{
|
||||||
|
gtk_css_provider_load_from_data(
|
||||||
|
GTK_CSS_PROVIDER(m_styleProvider), s, -1, NULL);
|
||||||
|
DoApplyWidgetStyle(NULL);
|
||||||
}
|
}
|
||||||
DoApplyWidgetStyle(NULL);
|
|
||||||
#else
|
#else
|
||||||
GtkRcStyle* style = GTKCreateWidgetStyle();
|
GtkRcStyle* style = GTKCreateWidgetStyle();
|
||||||
DoApplyWidgetStyle(style);
|
DoApplyWidgetStyle(style);
|
||||||
@@ -4599,34 +4693,9 @@ void wxWindowGTK::DoApplyWidgetStyle(GtkRcStyle *style)
|
|||||||
void wxWindowGTK::GTKApplyStyle(GtkWidget* widget, GtkRcStyle* WXUNUSED_IN_GTK3(style))
|
void wxWindowGTK::GTKApplyStyle(GtkWidget* widget, GtkRcStyle* WXUNUSED_IN_GTK3(style))
|
||||||
{
|
{
|
||||||
#ifdef __WXGTK3__
|
#ifdef __WXGTK3__
|
||||||
const PangoFontDescription* pfd = NULL;
|
|
||||||
if (m_font.IsOk())
|
|
||||||
pfd = m_font.GetNativeFontInfo()->description;
|
|
||||||
gtk_widget_override_font(widget, pfd);
|
|
||||||
gtk_widget_override_color(widget, GTK_STATE_FLAG_NORMAL, m_foregroundColour);
|
|
||||||
gtk_widget_override_background_color(widget, GTK_STATE_FLAG_NORMAL, m_backgroundColour);
|
|
||||||
|
|
||||||
// setting background color has no effect with some themes when the widget style
|
|
||||||
// has a "background-image" property, so we need to override that as well
|
|
||||||
|
|
||||||
GtkStyleContext* context = gtk_widget_get_style_context(widget);
|
GtkStyleContext* context = gtk_widget_get_style_context(widget);
|
||||||
if (m_styleProvider)
|
gtk_style_context_add_provider(context,
|
||||||
gtk_style_context_remove_provider(context, m_styleProvider);
|
m_styleProvider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||||
cairo_pattern_t* pattern = NULL;
|
|
||||||
if (m_backgroundColour.IsOk())
|
|
||||||
{
|
|
||||||
gtk_style_context_save(context);
|
|
||||||
gtk_style_context_set_state(context, GTK_STATE_FLAG_NORMAL);
|
|
||||||
gtk_style_context_get(context,
|
|
||||||
GTK_STATE_FLAG_NORMAL, "background-image", &pattern, NULL);
|
|
||||||
gtk_style_context_restore(context);
|
|
||||||
}
|
|
||||||
if (pattern)
|
|
||||||
{
|
|
||||||
cairo_pattern_destroy(pattern);
|
|
||||||
gtk_style_context_add_provider(context,
|
|
||||||
m_styleProvider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
gtk_widget_modify_style(widget, style);
|
gtk_widget_modify_style(widget, style);
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user