From 9973bbe6eb1594912703ba91734a545ede752855 Mon Sep 17 00:00:00 2001 From: Robert Fewell <14uBobIT@gmail.com> Date: Mon, 4 Sep 2017 15:53:08 +0100 Subject: [PATCH] Change the register to be based on CSS Change the colours of the register to be based on CSS. Use the register default colours or by using the preference setting user / theme set ones can be used. --- gnucash/gnome-utils/ui/gnucash-fallback.css | 9 ++ gnucash/gnome-utils/ui/gnucash.css | 84 +++++++++++++ .../register/register-gnome/gnucash-header.c | 49 ++++---- .../register-gnome/gnucash-sheet-private.c | 95 ++++++++------- .../register/register-gnome/gnucash-sheet.c | 112 +++++++----------- .../register/register-gnome/gnucash-sheet.h | 3 +- .../register/register-gnome/gnucash-sheetP.h | 1 + 7 files changed, 205 insertions(+), 148 deletions(-) diff --git a/gnucash/gnome-utils/ui/gnucash-fallback.css b/gnucash/gnome-utils/ui/gnucash-fallback.css index 21cb6164a8..8da155d3c5 100644 --- a/gnucash/gnome-utils/ui/gnucash-fallback.css +++ b/gnucash/gnome-utils/ui/gnucash-fallback.css @@ -41,6 +41,15 @@ color: rgb(75%, 0%, 0%); } +/* Change font color by mixing with grey */ +.lighter-grey-mix { + color: mix (currentColor, grey, 0.8); +} + +.darker-grey-mix { + color: mix (currentColor, grey, 0.2); +} + /* Register2 grid lines color */ .register2_grid_lines { border-color: black; diff --git a/gnucash/gnome-utils/ui/gnucash.css b/gnucash/gnome-utils/ui/gnucash.css index 469de9f3d4..e4a985aa52 100644 --- a/gnucash/gnome-utils/ui/gnucash.css +++ b/gnucash/gnome-utils/ui/gnucash.css @@ -10,3 +10,87 @@ cursor entry { cursor button { padding: 1px 1px 1px 1px; } + +/* Register defaults */ +@define-color register_header_bg_color #96B183; +@define-color register_primary_bg_color #BFDEB9; +@define-color register_secondary_bg_color #F6FFDA; +@define-color register_split_bg_color #EDE7D3; +@define-color register_cursor_bg_color #FFEF98; + +.app-header { + background-color: @register_header_bg_color; +} + +.app-header-dark { + background-color: shade (@register_header_bg_color, 0.7); +} + + +*.app-primary { + background-color: @register_primary_bg_color; +} + +*.app-primary:insensitive { + background-color: mix (@register_primary_bg_color, grey, 0.2); +} + +*.app-primary-dark { + background-color: shade (@register_primary_bg_color, 0.7); +} + +*.app-primary-dark:insensitive { + background-color: mix (shade (@register_primary_bg_color, 0.7), grey, 0.3); +} + + +*.app-secondary { + background-color: @register_secondary_bg_color; +} + +*.app-secondary:insensitive { + background-color: mix (@register_secondary_bg_color, grey, 0.2); +} + +*.app-secondary-dark { + background-color: shade (@register_secondary_bg_color, 0.5); +} + +*.app-secondary-dark:insensitive { + background-color: mix (shade (@register_secondary_bg_color, 0.5), grey, 0.3); +} + + +*.app-split { + background-color: @register_split_bg_color; +} + +*.app-split:insensitive { + background-color: mix (@register_split_bg_color, grey, 0.2); +} + +*.app-split-dark { + background-color: shade (@register_split_bg_color, 0.5); +} + +*.app-split-dark:insensitive { + background-color: mix (shade (@register_split_bg_color, 0.5), grey, 0.3); +} + + +*.app-cursor { + background-color: @register_cursor_bg_color; +} + +*.app-cursor:insensitive { + background-color: mix (@register_cursor_bg_color, grey, 0.2); +} + +*.app-cursor-dark { + background-color: shade (@register_cursor_bg_color, 0.6); +} + +*.app-cursor-dark:insensitive { + background-color: mix (shade (@register_cursor_bg_color, 0.6), grey, 0.3); +} + diff --git a/gnucash/register/register-gnome/gnucash-header.c b/gnucash/register/register-gnome/gnucash-header.c index 14fca91ef1..feb75f6cff 100644 --- a/gnucash/register/register-gnome/gnucash-header.c +++ b/gnucash/register/register-gnome/gnucash-header.c @@ -36,6 +36,7 @@ #include "gnucash-style.h" #include "gnucash-cursor.h" #include "gnucash-item-edit.h" +#include "gnc-gtk-utils.h" #include "gnucash-header.h" @@ -71,7 +72,9 @@ gnc_header_draw_offscreen (GncHeader *header) Table *table = header->sheet->table; VirtualLocation virt_loc; VirtualCell *vcell; - GdkRGBA *fg_color, *bg_color; + guint32 color_type; + GtkStyleContext *stylectxt = gtk_widget_get_style_context (GTK_WIDGET(header)); + GdkRGBA color; int row_offset; CellBlock *cb; int i; @@ -82,22 +85,11 @@ gnc_header_draw_offscreen (GncHeader *header) virt_loc.phys_row_offset = 0; virt_loc.phys_col_offset = 0; - if (header->sheet->use_theme_colors) - { - guint32 color_type; - color_type = gnc_table_get_gtkrc_bg_color (table, virt_loc, NULL); - bg_color = get_gtkrc_color(header->sheet, color_type); - color_type = gnc_table_get_gtkrc_fg_color (table, virt_loc); - fg_color = get_gtkrc_color(header->sheet, color_type); - } - else - { - guint32 argb; - argb = gnc_table_get_bg_color (table, virt_loc, NULL); - bg_color = gnucash_color_argb_to_gdk (argb); - argb = gnc_table_get_fg_color (table, virt_loc); - fg_color = gnucash_color_argb_to_gdk (argb); - } + gtk_style_context_save (stylectxt); + + // Get the background color type and apply the css class + color_type = gnc_table_get_gtkrc_bg_color (table, virt_loc, NULL); + gnucash_get_style_classes (header->sheet, stylectxt, color_type); if (header->surface) cairo_surface_destroy (header->surface); @@ -106,13 +98,17 @@ gnc_header_draw_offscreen (GncHeader *header) header->height); cr = cairo_create (header->surface); + // Fill background color of header + gtk_render_background (stylectxt, cr, 0, 0, header->width, header->height); + + gdk_rgba_parse (&color, "black"); + cairo_set_source_rgb (cr, color.red, color.green, color.blue); cairo_rectangle (cr, 0.5, 0.5, header->width - 1.0, header->height - 1.0); - cairo_set_source_rgb (cr, bg_color->red, bg_color->green, bg_color->blue); - cairo_fill_preserve (cr); + cairo_set_line_width (cr, 1.0); + cairo_stroke (cr); // Draw bottom horizontal line, makes bottom line thicker - cairo_set_source_rgb (cr, fg_color->red, fg_color->green, fg_color->blue); cairo_move_to (cr, 0.5, header->height - 1.5); cairo_line_to (cr, header->width - 1.0, header->height - 1.5); cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE); @@ -195,24 +191,19 @@ gnc_header_draw_offscreen (GncHeader *header) text_h = h - 2; cairo_save (cr); cairo_rectangle (cr, text_x, text_y, text_w, text_h); - cairo_set_source_rgb (cr, fg_color->red, fg_color->green, fg_color->blue); cairo_clip (cr); - cairo_move_to (cr, text_x, text_y); - pango_cairo_show_layout (cr, layout); + + gtk_render_layout (stylectxt, cr, text_x, text_y, layout); + cairo_restore (cr); g_object_unref (layout); col_offset += w; } - row_offset += h; } + gtk_style_context_restore (stylectxt); - if (header->sheet->use_theme_colors) - { - gdk_rgba_free(bg_color); - gdk_rgba_free(fg_color); - } cairo_destroy (cr); } diff --git a/gnucash/register/register-gnome/gnucash-sheet-private.c b/gnucash/register/register-gnome/gnucash-sheet-private.c index 6f205147ca..3cc8614a06 100644 --- a/gnucash/register/register-gnome/gnucash-sheet-private.c +++ b/gnucash/register/register-gnome/gnucash-sheet-private.c @@ -41,6 +41,7 @@ #include "gnucash-sheetP.h" #include "gnucash-color.h" #include "gnucash-style.h" +#include "gnc-gtk-utils.h" /* * Sets virt_row, virt_col to the block coordinates for the @@ -390,31 +391,34 @@ draw_cell (GnucashSheet *sheet, GdkRGBA *bg_color, *fg_color; GdkRectangle rect; gboolean hatching; - guint32 argb, color_type; + guint32 color_type; int x_offset; + GtkStyleContext *stylectxt = gtk_widget_get_style_context (GTK_WIDGET(sheet)); + GdkRGBA color; - if (sheet->use_theme_colors) - { - color_type = gnc_table_get_gtkrc_bg_color (table, virt_loc, - &hatching); - bg_color = get_gtkrc_color(sheet, color_type); - } - else - { - argb = gnc_table_get_bg_color (table, virt_loc, &hatching); - // Are we in a read-only row? Then make the background color somewhat more gray. - if ((virt_loc.phys_row_offset == (block->style->nrows - 1)) + gtk_style_context_save (stylectxt); + + // Get the background and foreground color types and apply the css class + color_type = gnc_table_get_gtkrc_bg_color (table, virt_loc, &hatching); + gnucash_get_style_classes (sheet, stylectxt, color_type); + + color_type = gnc_table_get_gtkrc_fg_color (table, virt_loc); + gnucash_get_style_classes (sheet, stylectxt, color_type); + + // Are we in a read-only row? Then make the background color somewhat more grey. + if ((virt_loc.phys_row_offset < block->style->nrows) && (table->model->dividing_row_upper >= 0) && (virt_loc.vcell_loc.virt_row < table->model->dividing_row_upper)) - { - argb = dec_intensity_10percent(argb); - } - bg_color = gnucash_color_argb_to_gdk (argb); + { + if (!gtk_style_context_has_class (stylectxt, GTK_STYLE_CLASS_BACKGROUND)) + gtk_style_context_set_state (stylectxt, GTK_STATE_FLAG_INSENSITIVE); } - cairo_set_source_rgb (cr, bg_color->red, bg_color->green, bg_color->blue); - cairo_rectangle (cr, x, y, width, height); - cairo_fill (cr); + gtk_render_background (stylectxt, cr, x, y, width, height); + + gdk_rgba_parse (&color, "black"); + gnc_style_context_get_background_color (stylectxt, GTK_STATE_FLAG_NORMAL, &color); + bg_color = gdk_rgba_copy (&color); get_cell_borders (sheet, virt_loc, &borders); @@ -477,30 +481,28 @@ draw_cell (GnucashSheet *sheet, text = gnc_table_get_entry (table, virt_loc); layout = gtk_widget_create_pango_layout (GTK_WIDGET (sheet), text); + + if (gtk_style_context_has_class (stylectxt, GTK_STYLE_CLASS_VIEW)) + gtk_style_context_remove_class (stylectxt, GTK_STYLE_CLASS_VIEW); + // We don't need word wrap or line wrap pango_layout_set_width (layout, -1); context = pango_layout_get_context (layout); font = pango_font_description_copy (pango_context_get_font_description (context)); - if (sheet->use_theme_colors) - { - color_type = gnc_table_get_gtkrc_fg_color (table, virt_loc); - fg_color = get_gtkrc_color(sheet, color_type); - } - else - { - argb = gnc_table_get_fg_color (table, virt_loc); #ifdef READONLY_LINES_WITH_CHANGED_FG_COLOR - // Are we in a read-only row? Then make the foreground color somewhat less black - if ((virt_loc.phys_row_offset == (block->style->nrows - 1)) - && (table->model->dividing_row_upper >= 0) - && (virt_loc.vcell_loc.virt_row < table->model->dividing_row_upper)) - { - argb = inc_intensity_10percent(argb); - } -#endif - fg_color = gnucash_color_argb_to_gdk (argb); + // Are we in a read-only row? Then make the foreground color somewhat less black + if ((virt_loc.phys_row_offset < block->style->nrows) + && (table->model->dividing_row_upper >= 0) + && (virt_loc.vcell_loc.virt_row < table->model->dividing_row_upper)) + { + // Make text color greyed + if (sheet->dark_theme) + gtk_style_context_add_class (stylectxt, "darker-grey-mix"); + else + gtk_style_context_add_class (stylectxt, "lighter-grey-mix"); } +#endif /* If this is the currently open transaction and there is no text in this cell */ @@ -511,12 +513,17 @@ draw_cell (GnucashSheet *sheet, text = gnc_table_get_label (table, virt_loc); if ((text == NULL) || (*text == '\0')) goto exit; - fg_color = &gn_light_gray; + + // Make text color greyed + if (sheet->dark_theme) + gtk_style_context_add_class (stylectxt, "darker-grey-mix"); + else + gtk_style_context_add_class (stylectxt, "lighter-grey-mix"); + pango_layout_set_text (layout, text, strlen (text)); pango_font_description_set_style (font, PANGO_STYLE_ITALIC); pango_context_set_font_description (context, font); } - cairo_set_source_rgb (cr, fg_color->red, fg_color->green, fg_color->blue); if ((text == NULL) || (*text == '\0')) { @@ -555,11 +562,7 @@ draw_cell (GnucashSheet *sheet, logical_rect.width) / 2; break; } - - - - cairo_move_to (cr, rect.x + x_offset, rect.y + 1); - pango_cairo_show_layout (cr, layout); + gtk_render_layout (stylectxt, cr, rect.x + x_offset, rect.y + 1, layout); cairo_restore (cr); @@ -569,11 +572,7 @@ exit: pango_font_description_free (font); g_object_unref (layout); - if (sheet->use_theme_colors) - { - gdk_rgba_free(bg_color); - gdk_rgba_free(fg_color); - } + gtk_style_context_restore (stylectxt); } static void diff --git a/gnucash/register/register-gnome/gnucash-sheet.c b/gnucash/register/register-gnome/gnucash-sheet.c index 4ab7f96813..090156f375 100644 --- a/gnucash/register/register-gnome/gnucash-sheet.c +++ b/gnucash/register/register-gnome/gnucash-sheet.c @@ -1055,10 +1055,17 @@ gnucash_sheet_draw_cb (GtkWidget *widget, cairo_t *cr, G_GNUC_UNUSED gpointer da GnucashSheet *sheet = GNUCASH_SHEET (widget); GtkStyleContext *context = gtk_widget_get_style_context (widget); GtkAllocation alloc; + GdkRGBA color; gboolean result; //FIXME gtk_widget_get_allocation(widget, &alloc); - gtk_render_background (context, cr, alloc.x, alloc.y, alloc.width, alloc.height); + + gtk_style_context_add_class (context, GTK_STYLE_CLASS_BACKGROUND); + gtk_render_background (context, cr, 0, 0, alloc.width, alloc.height); + gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &color); + sheet->dark_theme = gnc_is_dark_theme (&color); + gtk_style_context_remove_class (context, GTK_STYLE_CLASS_BACKGROUND); + //FIXME what should be done with result being TRUE or FALSE result = gnucash_sheet_draw_internal (sheet, cr, &alloc); gnucash_sheet_draw_cursor (sheet->cursor, cr); @@ -2321,104 +2328,69 @@ gnucash_sheet_realize_entry (GnucashSheet *sheet, GtkWidget *entry) /*************************************************************/ -/* This code is one big hack to use gtkrc to set cell colors in a - * register. Because the cells are just boxes drawn on a gnome - * canvas, there's no way to specify the individual cells in a gtkrc - * file. This code creates four hidden GtkEntry widgets and names - * them so that they *can* be specified in gtkrc. It then looks up - * the colors specified on these hidden widgets and uses it for the - * cells drawn on the canvas. This code should all go away whenever - * the register is rewritten. - */ - -/** Map a cell type to a gtkrc specified color. */ -GdkRGBA * -get_gtkrc_color (GnucashSheet *sheet, - RegisterColor field_type) +/** Map a cell type to a css style class. */ +void +gnucash_get_style_classes (GnucashSheet *sheet, GtkStyleContext *stylectxt, + RegisterColor field_type) { - GtkWidget *widget = NULL; - GtkStyleContext *stylectxt; - GdkRGBA color; + gchar *full_class, *style_class = NULL; switch (field_type) { default: - return gdk_rgba_copy (&gn_white); - case COLOR_UNKNOWN_BG: - return gdk_rgba_copy (&gn_white); - case COLOR_UNKNOWN_FG: - return gdk_rgba_copy (&gn_black); + gtk_style_context_add_class (stylectxt, GTK_STYLE_CLASS_BACKGROUND); + return; case COLOR_NEGATIVE: - return gdk_rgba_copy (&gn_red); // FIXME shouldn't be hardcoded... + gtk_style_context_add_class (stylectxt, "negative-numbers"); + return; case COLOR_HEADER_BG: case COLOR_HEADER_FG: - widget = sheet->header_color; + style_class = "header"; break; case COLOR_PRIMARY_BG: - case COLOR_PRIMARY_BG_ACTIVE: case COLOR_PRIMARY_FG: + style_class = "primary"; + break; + + case COLOR_PRIMARY_BG_ACTIVE: case COLOR_PRIMARY_FG_ACTIVE: - widget = sheet->primary_color; + case COLOR_SECONDARY_BG_ACTIVE: + case COLOR_SECONDARY_FG_ACTIVE: + case COLOR_SPLIT_BG_ACTIVE: + case COLOR_SPLIT_FG_ACTIVE: + gtk_style_context_set_state (stylectxt, GTK_STATE_FLAG_SELECTED); + style_class = "cursor"; break; case COLOR_SECONDARY_BG: - case COLOR_SECONDARY_BG_ACTIVE: case COLOR_SECONDARY_FG: - case COLOR_SECONDARY_FG_ACTIVE: - widget = sheet->secondary_color; + style_class = "secondary"; break; case COLOR_SPLIT_BG: - case COLOR_SPLIT_BG_ACTIVE: case COLOR_SPLIT_FG: - case COLOR_SPLIT_FG_ACTIVE: - widget = sheet->split_color; + style_class = "split"; break; } - stylectxt = gtk_widget_get_style_context (widget); - if (!stylectxt) - return gdk_rgba_copy (&gn_white); - - switch (field_type) + if (sheet->use_theme_colors) { - default: - return gdk_rgba_copy (&gn_white); - - case COLOR_HEADER_BG: - case COLOR_PRIMARY_BG: - case COLOR_SECONDARY_BG: - case COLOR_SPLIT_BG: - gnc_style_context_get_background_color(stylectxt, GTK_STATE_FLAG_NORMAL, &color); - break; - - case COLOR_PRIMARY_BG_ACTIVE: - case COLOR_SECONDARY_BG_ACTIVE: - case COLOR_SPLIT_BG_ACTIVE: - gnc_style_context_get_background_color(stylectxt, GTK_STATE_FLAG_SELECTED, &color); - break; - - case COLOR_HEADER_FG: - case COLOR_PRIMARY_FG: - case COLOR_SECONDARY_FG: - case COLOR_SPLIT_FG: - gtk_style_context_get_color(stylectxt, GTK_STATE_FLAG_NORMAL, &color); - break; - - case COLOR_PRIMARY_FG_ACTIVE: - case COLOR_SECONDARY_FG_ACTIVE: - case COLOR_SPLIT_FG_ACTIVE: - gtk_style_context_get_color(stylectxt, GTK_STATE_FLAG_SELECTED, &color); - break; + gtk_style_context_add_class (stylectxt, GTK_STYLE_CLASS_VIEW); + full_class = g_strconcat (style_class, "-color", NULL); } - - return gdk_rgba_copy (&color); -} + else + { + if (sheet->dark_theme) + full_class = g_strconcat ("app-", style_class, "-dark", NULL); + else + full_class = g_strconcat ("app-", style_class, NULL); + } + gtk_style_context_add_class (stylectxt, full_class); /** Create the entries used for nameing register colors in gtkrc. */ static void @@ -2446,6 +2418,7 @@ gnucash_sheet_create_color_hack(GnucashSheet *sheet) g_signal_connect_after(sheet, "realize", G_CALLBACK(gnucash_sheet_realize_entry), sheet->split_color); + g_free (full_class); } /*************************************************************/ @@ -2591,7 +2564,6 @@ gnucash_sheet_new (Table *table) g_free, NULL); gnucash_sheet_refresh_from_prefs(sheet); - gnucash_sheet_create_color_hack(sheet); return GTK_WIDGET(sheet); } diff --git a/gnucash/register/register-gnome/gnucash-sheet.h b/gnucash/register/register-gnome/gnucash-sheet.h index 76a81c6048..b571d035ac 100644 --- a/gnucash/register/register-gnome/gnucash-sheet.h +++ b/gnucash/register/register-gnome/gnucash-sheet.h @@ -105,7 +105,8 @@ void gnucash_sheet_update_adjustments (GnucashSheet *sheet); void gnucash_sheet_set_window (GnucashSheet *sheet, GtkWidget *window); -GdkRGBA *get_gtkrc_color (GnucashSheet *sheet, RegisterColor field_type); +void gnucash_get_style_classes (GnucashSheet *sheet, GtkStyleContext *stylectxt, + RegisterColor field_type); /** @} */ #endif diff --git a/gnucash/register/register-gnome/gnucash-sheetP.h b/gnucash/register/register-gnome/gnucash-sheetP.h index 408b0da668..4ae84479cf 100644 --- a/gnucash/register/register-gnome/gnucash-sheetP.h +++ b/gnucash/register/register-gnome/gnucash-sheetP.h @@ -70,6 +70,7 @@ struct _GnucashSheet GtkWidget *primary_color; GtkWidget *secondary_color; GtkWidget *split_color; + gboolean dark_theme; gboolean input_cancelled;