GnuCash c935c2f+
Loading...
Searching...
No Matches
gnucash-sheet-private.c
1/********************************************************************\
2 * This program is free software; you can redistribute it and/or *
3 * modify it under the terms of the GNU General Public License as *
4 * published by the Free Software Foundation; either version 2 of *
5 * the License, or (at your option) any later version. *
6 * *
7 * This program is distributed in the hope that it will be useful, *
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
10 * GNU General Public License for more details. *
11 * *
12 * You should have received a copy of the GNU General Public License*
13 * along with this program; if not, contact: *
14 * *
15 * Free Software Foundation Voice: +1-617-542-5942 *
16 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
17 * Boston, MA 02110-1301, USA gnu@gnu.org *
18 * *
19\********************************************************************/
20
21/*
22 * The Gnucash Grid drawing functions
23 *
24 * The gnucash grid used to be a fully fledged object. However it has no
25 * intelligence of its own, so instead I have reduced it to just a complex
26 * drawing function.
27 * It specializes in drawing the non-editable parts of a gnucash sheet, that is
28 * - the rows and columns with proper backgrounds and borders
29 * - the text for each cell in the table
30 * - dividing lines (red and blue)
31 *
32 * This could have been addedi directly into gnucash_sheet.c, but is kept
33 * separate to not oversize that file.
34 */
35
36#include <config.h>
37
38#include <string.h>
39
40#include "gnucash-sheet.h"
41#include "gnucash-sheetP.h"
42#include "gnucash-color.h"
43#include "gnucash-style.h"
44#include "gnc-gtk-utils.h"
45
46/*
47 * Sets virt_row, virt_col to the block coordinates for the
48 * block containing pixel (x, y). Also sets o_x, o_y, to the
49 * pixel coordinates of the origin of the block. Returns
50 * TRUE if a block is found, FALSE if (x,y) is not
51 * in any block.
52 *
53 * All coordinates are with respect to the canvas origin.
54 */
55static SheetBlock *
56find_block_by_pixel (GnucashSheet *sheet,
57 gint x, gint y,
58 VirtualCellLocation *vcell_loc)
59{
60 SheetBlock *block;
61 VirtualCellLocation vc_loc = { 1, 0 };
62
63 g_return_val_if_fail (y >= 0, NULL);
64 g_return_val_if_fail (x >= 0, NULL);
65
66 do
67 {
68 block = gnucash_sheet_get_block (sheet, vc_loc);
69 if (!block)
70 return NULL;
71
72 if (block->visible &&
73 y >= block->origin_y &&
74 y < block->origin_y + block->style->dimensions->height)
75 {
76 if (vcell_loc)
77 vcell_loc->virt_row = vc_loc.virt_row;
78 break;
79 }
80 vc_loc.virt_row++;
81 }
82 while (vc_loc.virt_row < sheet->num_virt_rows);
83
84 if (vc_loc.virt_row == sheet->num_virt_rows)
85 return NULL;
86
87 do
88 {
89 block = gnucash_sheet_get_block (sheet, vc_loc);
90 if (!block)
91 return NULL;
92
93 if (block->visible &&
94 x >= block->origin_x &&
95 x < block->origin_x + block->style->dimensions->width)
96 {
97 if (vcell_loc)
98 vcell_loc->virt_col = vc_loc.virt_col;
99 break;
100 }
101 vc_loc.virt_col++;
102 }
103 while (vc_loc.virt_col < sheet->num_virt_cols);
104
105 if (vc_loc.virt_col == sheet->num_virt_cols)
106 return NULL;
107
108 return block;
109}
110
111static gboolean
112find_cell_by_pixel (GnucashSheet *sheet, gint x, gint y,
113 VirtualLocation *virt_loc)
114{
115 SheetBlock *block;
116 SheetBlockStyle *style;
117 CellDimensions *cd;
118 gint row = 0;
119 gint col = 0;
120
121 g_return_val_if_fail (virt_loc != NULL, FALSE);
122
123 block = gnucash_sheet_get_block (sheet, virt_loc->vcell_loc);
124 if (block == NULL)
125 return FALSE;
126
127 /* now make x, y relative to the block origin */
128 x -= block->origin_x;
129 y -= block->origin_y;
130
131 style = block->style;
132 if (style == NULL)
133 return FALSE;
134
135 do
136 {
137 cd = gnucash_style_get_cell_dimensions (style, row, 0);
138
139 if (cd && y >= cd->origin_y && y < cd->origin_y + cd->pixel_height)
140 break;
141
142 row++;
143 }
144 while (row < style->nrows);
145
146 if (row == style->nrows)
147 return FALSE;
148
149 do
150 {
151 cd = gnucash_style_get_cell_dimensions (style, row, col);
152
153 if (cd && x >= cd->origin_x && x < cd->origin_x + cd->pixel_width)
154 break;
155
156 col++;
157 }
158 while (col < style->ncols);
159
160 if (col == style->ncols)
161 return FALSE;
162
163 if (virt_loc)
164 virt_loc->phys_row_offset = row;
165 if (virt_loc)
166 virt_loc->phys_col_offset = col;
167
168 return TRUE;
169}
170
171gboolean
172gnucash_sheet_find_loc_by_pixel (GnucashSheet *sheet, gint x, gint y,
173 VirtualLocation *virt_loc)
174{
175 SheetBlock *block;
176
177 if (virt_loc == NULL)
178 return FALSE;
179
180 block = find_block_by_pixel (sheet, x, y,
181 &virt_loc->vcell_loc);
182 if (block == NULL)
183 return FALSE;
184
185 return find_cell_by_pixel (sheet, x, y, virt_loc);
186}
187
188static void
189get_cell_borders (GnucashSheet *sheet, VirtualLocation virt_loc,
190 PhysicalCellBorders *borders)
191{
192 VirtualLocation v_loc;
193 PhysicalCellBorders neighbor;
194
195 gnucash_sheet_get_borders (sheet, virt_loc, borders);
196
197 /* top */
198 v_loc = virt_loc;
199 if (gnc_table_move_vertical_position (sheet->table, &v_loc, -1))
200 {
201 gnucash_sheet_get_borders (sheet, v_loc, &neighbor);
202 borders->top = MAX(borders->top, neighbor.bottom);
203 }
204
205 /* bottom */
206 v_loc = virt_loc;
207 if (gnc_table_move_vertical_position (sheet->table, &v_loc, 1))
208 {
209 gnucash_sheet_get_borders (sheet, v_loc, &neighbor);
210 borders->bottom = MAX(borders->bottom, neighbor.top);
211 }
212
213 /* left */
214 v_loc = virt_loc;
215 v_loc.phys_col_offset--;
216 if (gnc_table_virtual_loc_valid (sheet->table, v_loc, TRUE))
217 {
218 gnucash_sheet_get_borders (sheet, v_loc, &neighbor);
219 borders->left = MAX(borders->left, neighbor.right);
220 }
221
222 /* right */
223 v_loc = virt_loc;
224 v_loc.phys_col_offset++;
225 if (gnc_table_virtual_loc_valid (sheet->table, v_loc, TRUE))
226 {
227 gnucash_sheet_get_borders (sheet, v_loc, &neighbor);
228 borders->right = MAX(borders->right, neighbor.left);
229 }
230}
231
232
233#ifdef READONLY_LINES_WITH_CHANGED_FG_COLOR
238static guint8 inc_intensity_byte (guint8 input, int numerator, int denominator)
239{
240 guint8 result_inv, result;
241 guint8 input_inv = 0xff - input;
242 result_inv = (input_inv * numerator) / denominator;
243 result = 0xff - result_inv;
244 return result;
245}
246
250static guint32 inc_intensity_10percent (guint32 argb)
251{
252 guint32 result =
253 (inc_intensity_byte ((argb & 0x00FF0000) >> 16, 8, 10) << 16)
254 + (inc_intensity_byte ((argb & 0x0000FF00) >> 8, 8, 10) << 8)
255 + (inc_intensity_byte (argb & 0x000000FF, 8, 10));
256 return result;
257}
258#endif
259
260/* Actual drawing routines */
261
262static inline void
263draw_cell_line (cairo_t *cr, GdkRGBA *bg_color,
264 double x1, double y1, double x2, double y2,
265 PhysicalCellBorderLineStyle style);
266
267void
268draw_cell_line (cairo_t *cr, GdkRGBA *bg_color,
269 double x1, double y1, double x2, double y2,
270 PhysicalCellBorderLineStyle style)
271{
272 GdkRGBA *fg_color;
273
274 switch (style)
275 {
276 case CELL_BORDER_LINE_NONE:
277 fg_color = bg_color;
278 break;
279
280 case CELL_BORDER_LINE_LIGHT:
281 fg_color = &gn_light_gray;
282 break;
283
284 case CELL_BORDER_LINE_NORMAL:
285 case CELL_BORDER_LINE_HEAVY:
286 fg_color = &gn_black;
287 break;
288
289 case CELL_BORDER_LINE_HIGHLIGHT:
290 fg_color = &gn_red;
291 break;
292
293 default:
294 return;
295 }
296
297 cairo_set_line_width (cr, 1.0);
298 cairo_set_source_rgb (cr, fg_color->red, fg_color->green, fg_color->blue);
299 cairo_move_to (cr, x1, y1);
300 cairo_line_to (cr, x2, y2);
301 cairo_stroke (cr);
302}
303
304static void
305draw_hatching (cairo_t *cr, double x, double y,
306 G_GNUC_UNUSED double width, double height)
307{
308 GdkRGBA *fg_color;
309 double h_x = x + 2.5;
310 double h_y = y + 2.5;
311 double h_size = height / 3 - 1;
312
313 cairo_set_line_width (cr, 1.0);
314 fg_color = &gn_light_gray;
315 cairo_set_source_rgb (cr, fg_color->red, fg_color->green, fg_color->blue);
316
317 cairo_rectangle (cr, h_x, h_y, h_size, h_size);
318 cairo_move_to (cr, h_x, h_y);
319 cairo_rel_line_to (cr, h_size, h_size);
320 cairo_rel_move_to (cr, -h_size, 0);
321 cairo_rel_line_to (cr, h_size, -h_size);
322 cairo_stroke (cr);
323}
324
325static void
326draw_divider_line (cairo_t *cr, VirtualLocation virt_loc,
327 int div_row, int n_phys_rows, GdkRGBA *fg_color,
328 double x, double y, double width, double height)
329{
330 double offset;
331 if (div_row < 0)
332 return;
333
334 /* Test if divider line should be drawn before the current row */
335 if ((virt_loc.phys_row_offset == 0) &&
336 (virt_loc.vcell_loc.virt_row == div_row))
337 offset = 0.0;
338 /* Test if divider line should be drawn after the current row */
339 else if ((virt_loc.phys_row_offset == n_phys_rows - 1) &&
340 (virt_loc.vcell_loc.virt_row == div_row - 1))
341 offset = height;
342 else
343 return;
344
345 cairo_set_source_rgb (cr, fg_color->red, fg_color->green, fg_color->blue);
346
347 cairo_set_line_width (cr, 3.0);
348 cairo_move_to (cr, x, y - 0.5 + offset);
349 cairo_rel_line_to (cr, width, 0);
350 cairo_stroke (cr);
351}
352
353static void
354set_cell_insensitive (GtkStyleContext *stylectxt)
355{
356 if (!gtk_style_context_has_class (stylectxt, GTK_STYLE_CLASS_BACKGROUND))
357 gtk_style_context_set_state (stylectxt, GTK_STATE_FLAG_INSENSITIVE);
358}
359
360static void
361draw_cell (GnucashSheet *sheet, SheetBlock *block,
362 VirtualLocation virt_loc, cairo_t *cr,
363 int x, int y, int width, int height)
364{
365 GncItemEdit *item_edit = GNC_ITEM_EDIT(sheet->item_editor);
366 Table *table = sheet->table;
367 PhysicalCellBorders borders;
368 const char *text;
369 PangoLayout *layout;
370 PangoContext *context;
371 PangoFontDescription *font;
372 PangoRectangle logical_rect;
373 GdkRGBA *bg_color, *fg_color;
374 GdkRectangle rect;
375 gboolean hatching;
376 guint32 color_type;
377 int x_offset;
378 GtkStyleContext *stylectxt = gtk_widget_get_style_context (GTK_WIDGET(sheet));
379 GdkRGBA color;
380 gboolean use_neg_class = TRUE;
381
382 gtk_style_context_save (stylectxt);
383
384 text = gnc_table_get_entry (table, virt_loc);
385
386 // test for any text, if no text we do not want to add gnc-class-negative-numbers
387 if (!text || *text == '\0')
388 use_neg_class = FALSE;
389
390 // Get the color type and apply the css class
391 color_type = gnc_table_get_color (table, virt_loc, &hatching);
392 gnucash_get_style_classes (sheet, stylectxt, color_type, use_neg_class);
393
394 if (sheet->read_only)
395 set_cell_insensitive (stylectxt);
396 else
397 {
398 if (gtk_style_context_has_class (stylectxt, GTK_STYLE_CLASS_BACKGROUND))
399 gtk_style_context_set_state (stylectxt, GTK_STATE_FLAG_NORMAL);
400 }
401
402 // Are we in a read-only row? Then make the background color somewhat more grey.
403 if ((virt_loc.phys_row_offset < block->style->nrows)
404 && (table->model->dividing_row_upper >= 0))
405 {
406 if (table->model->reverse_sort)
407 {
408 if ((table->model->blank_trans_row < table->model->dividing_row_upper)
409 && (virt_loc.vcell_loc.virt_row >= table->model->dividing_row_upper))
410 {
411 set_cell_insensitive (stylectxt); // future trans after blank
412 }
413
414 if ((virt_loc.vcell_loc.virt_row >= table->model->dividing_row_upper)
415 && (virt_loc.vcell_loc.virt_row < table->model->blank_trans_row))
416 {
417 set_cell_insensitive (stylectxt);
418 }
419 }
420 else // normal order
421 {
422 if (virt_loc.vcell_loc.virt_row < table->model->dividing_row_upper)
423 set_cell_insensitive (stylectxt);
424 }
425 }
426
427 gtk_render_background (stylectxt, cr, x, y, width, height);
428
429 gdk_rgba_parse (&color, "black");
430 gnc_style_context_get_background_color (stylectxt, gtk_style_context_get_state (stylectxt),
431 &color);
432 bg_color = &color;
433
434 get_cell_borders (sheet, virt_loc, &borders);
435
436 /* top */
437 draw_cell_line (cr, bg_color,
438 (borders.top >= borders.left ? x : x + 1.0),
439 y - 0.5,
440 (borders.top >= borders.right ?
441 x + width : x + width - 1),
442 y - 0.5,
443 borders.top);
444
445 /* bottom */
446 draw_cell_line (cr, bg_color,
447 (borders.bottom >= borders.left ? x : x + 1.0),
448 y + height - 0.5,
449 (borders.bottom >= borders.right ?
450 x + width : x + width - 1),
451 y + height - 0.5,
452 borders.bottom);
453
454 /* left */
455 draw_cell_line (cr, bg_color,
456 (x == 0 ? x + 0.5 : x - 0.5),
457 (borders.left > borders.top ? y : y),
458 (x == 0 ? x + 0.5 : x - 0.5),
459 (borders.left > borders.bottom ?
460 y + height : y + height),
461 borders.left);
462
463 /* right */
464 draw_cell_line (cr, bg_color,
465 x + width - 0.5,
466 (borders.right > borders.top ? y : y),
467 x + width - 0.5,
468 (borders.right > borders.bottom ?
469 y + height : y + height),
470 borders.right);
471
472 if (hatching)
473 draw_hatching (cr, x, y, width, height);
474
475 /* dividing line upper (red) */
476 fg_color = &gn_red;
477 draw_divider_line (cr, virt_loc,
478 table->model->dividing_row_upper, block->style->nrows,
479 fg_color, x, y, width, height);
480
481 /* dividing line (blue) */
482 fg_color = &gn_blue;
483 draw_divider_line (cr, virt_loc,
484 table->model->dividing_row, block->style->nrows,
485 fg_color, x, y, width, height);
486
487 /* dividing line lower (blue) */
488 draw_divider_line (cr, virt_loc,
489 table->model->dividing_row_lower, block->style->nrows,
490 fg_color, x, y, width, height);
491
492 layout = gtk_widget_create_pango_layout (GTK_WIDGET (sheet), text);
493
494 if (gtk_style_context_has_class (stylectxt, GTK_STYLE_CLASS_VIEW))
495 gtk_style_context_remove_class (stylectxt, GTK_STYLE_CLASS_VIEW);
496
497 // We don't need word wrap or line wrap
498 pango_layout_set_width (layout, -1);
499 context = pango_layout_get_context (layout);
500 font = pango_font_description_copy (pango_context_get_font_description (context));
501
502#ifdef READONLY_LINES_WITH_CHANGED_FG_COLOR
503 // Are we in a read-only row? Then make the foreground color somewhat less black
504 if ((virt_loc.phys_row_offset < block->style->nrows)
505 && (table->model->dividing_row_upper >= 0)
506 && (virt_loc.vcell_loc.virt_row < table->model->dividing_row_upper))
507 {
508 // Make text color greyed
509 gtk_style_context_add_class (stylectxt, "gnc-class-lighter-grey-mix");
510 }
511#endif
512
513 if ((text != NULL) && (*text != '\0') && g_strcmp0 (PRICE_CELL_TYPE_NAME,
514 gnc_table_get_cell_type_name (table, virt_loc)) == 0)
515 {
516 int text_width;
517 int text_border_padding;
518
519 pango_layout_get_pixel_size (layout, &text_width, NULL);
520
521 text_border_padding = gnc_item_edit_get_margin (item_edit, left_right) +
522 gnc_item_edit_get_padding_border (item_edit, left_right);
523
524 if (text_width + text_border_padding > width)
525 {
526 int pango_width = (width - text_border_padding) * PANGO_SCALE;
527
528 pango_layout_set_width (layout, pango_width); //pango units
529 pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
530 }
531 }
532
533 /* If this is the currently open transaction and
534 there is no text in this cell */
535 if ((table->current_cursor_loc.vcell_loc.virt_row ==
536 virt_loc.vcell_loc.virt_row) &&
537 (!text || strlen(text) == 0))
538 {
539 text = gnc_table_get_label (table, virt_loc);
540 if ((text == NULL) || (*text == '\0'))
541 goto exit;
542
543 // Make text color greyed
544 gtk_style_context_add_class (stylectxt, "gnc-class-lighter-grey-mix");
545
546 pango_layout_set_text (layout, text, strlen (text));
547 pango_font_description_set_style (font, PANGO_STYLE_ITALIC);
548 pango_context_set_font_description (context, font);
549 }
550
551 if ((text == NULL) || (*text == '\0'))
552 {
553 goto exit;
554 }
555
556 pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
557
558 gnucash_sheet_set_text_bounds (sheet, &rect, x, y, width, height);
559
560 cairo_save (cr);
561 cairo_rectangle (cr, rect.x, rect.y, rect.width, rect.height);
562 cairo_clip (cr);
563
564 x_offset = gnucash_sheet_get_text_offset (sheet, virt_loc,
565 rect.width, logical_rect.width);
566
567 gtk_render_layout (stylectxt, cr, rect.x + x_offset,
568 rect.y + gnc_item_edit_get_padding_border (item_edit, top), layout);
569
570 cairo_restore (cr);
571
572exit:
573 pango_font_description_set_style (font, PANGO_STYLE_NORMAL);
574 pango_context_set_font_description (context, font);
575 pango_font_description_free (font);
576 g_object_unref (layout);
577
578 gtk_style_context_restore (stylectxt);
579}
580
581static void
582draw_block (GnucashSheet *sheet, SheetBlock *block,
583 VirtualLocation virt_loc, cairo_t *cr,
584 int x, int y, int width, int height)
585{
586 CellDimensions *cd;
587 gint x_paint;
588 gint y_paint;
589 gint w, h;
590
591 for (virt_loc.phys_row_offset = 0;
592 virt_loc.phys_row_offset < block->style->nrows ;
593 virt_loc.phys_row_offset++)
594 {
595 for (virt_loc.phys_col_offset = 0;
596 virt_loc.phys_col_offset < block->style->ncols ;
597 virt_loc.phys_col_offset++)
598 {
599 cd = gnucash_style_get_cell_dimensions
600 (block->style,
601 virt_loc.phys_row_offset,
602 virt_loc.phys_col_offset);
603
604 if (!cd) break;
605
606 x_paint = block->origin_x + cd->origin_x - x;
607 if (x_paint > width)
608 break;
609
610 y_paint = block->origin_y + cd->origin_y - y;
611 if (y_paint > height)
612 return;
613
614 h = cd->pixel_height;
615 w = cd->pixel_width;
616
617 if (w == 0)
618 continue;
619
620 if (x_paint + w < 0)
621 continue;
622
623 if (y_paint + h < 0)
624 continue;
625
626 draw_cell (sheet, block, virt_loc, cr,
627 x_paint, y_paint, w, h);
628 }
629 }
630}
631
632gboolean
633gnucash_sheet_draw_internal (GnucashSheet* sheet, cairo_t* cr,
634 GtkAllocation* alloc)
635{
636 VirtualLocation virt_loc = {{0, 0}, 0, 0};
637 SheetBlock *sheet_block;
638 int x = 0;
639 int y = 0;
640 int width = alloc->width;
641 int height = alloc->height;
642 GtkAdjustment * adj;
643
644 adj = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE(sheet));
645 x = (gint) gtk_adjustment_get_value (adj);
646 adj = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE(sheet));
647 y = (gint) gtk_adjustment_get_value (adj);
648
649 if (x < 0 || y < 0)
650 return FALSE;
651
652 /* compute our initial values where we start drawing */
653 sheet_block = find_block_by_pixel (sheet, x, y, &virt_loc.vcell_loc);
654 if (!sheet_block || !sheet_block->style)
655 return FALSE;
656
657 sheet->read_only = gnc_table_model_read_only (sheet->table->model);
658
659 for ( ; virt_loc.vcell_loc.virt_row < sheet->num_virt_rows;
660 virt_loc.vcell_loc.virt_row++ )
661 {
662 while (TRUE)
663 {
664 sheet_block = gnucash_sheet_get_block (sheet, virt_loc.vcell_loc);
665
666 if (!sheet_block || !sheet_block->style)
667 return TRUE;
668
669 if (sheet_block->visible)
670 break;
671
672 virt_loc.vcell_loc.virt_row++;
673 }
674
675 if (y + height < sheet_block->origin_y)
676 return TRUE;
677
678 draw_block (sheet, sheet_block, virt_loc, cr,
679 x, y, width, height);
680 }
681 return TRUE;
682}
683
684
685void
686gnucash_sheet_draw_cursor (GnucashCursor *cursor, cairo_t *cr)
687{
688 GnucashCursorCell *cc = &(cursor->cell);
689 GdkRGBA *fg_color;
690 int x = 0;
691 int y = 0;
692 GtkAdjustment * adj;
693
694 adj = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE(cursor->sheet));
695 x = (gint) gtk_adjustment_get_value (adj);
696 adj = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE(cursor->sheet));
697 y = (gint) gtk_adjustment_get_value (adj);
698
699 fg_color = &gn_black;
700
701 /* draw the rectangle around the entire active virtual row - transaction rows only - double line */
702 cairo_set_source_rgb (cr, fg_color->red, fg_color->green, fg_color->blue);
703 if (cursor->x == 0)
704 cairo_rectangle (cr, cursor->x - x + 0.5, cursor->y - y - 0.5, cursor->w - 1.0, cursor->h - 2.0);
705 else
706 cairo_rectangle (cr, cursor->x - x - 0.5, cursor->y - y - 0.5, cursor->w, cursor->h - 2.0);
707
708 cairo_set_line_width (cr, 1.0);
709 cairo_stroke (cr);
710
711 // make the bottom line thicker
712 cairo_move_to (cr, cursor->x - x + 0.5, cursor->y - y + cursor->h - 3.5);
713 cairo_rel_line_to (cr, cursor->w, 0);
714 cairo_set_line_width (cr, 1.0);
715 cairo_stroke (cr);
716
717 /* draw rectangle around the active cell */
718 cairo_set_source_rgb (cr, fg_color->red, fg_color->green, fg_color->blue);
719 if (cc->x != 0)
720 cairo_rectangle (cr, cc->x - x - 0.5, cursor->y + cc->y - y - 0.5, cc->w, cc->h);
721 else
722 cairo_rectangle (cr, cc->x - x + 0.5, cursor->y + cc->y - y - 0.5, cc->w - 1.0, cc->h);
723
724 cairo_set_line_width (cr, 1.0);
725 cairo_stroke (cr);
726}
gtk helper routines.
Convenience wrapper around GdkRGBA for use in Register Gnome classes.
Private declarations for GnucashSheet class.
Public declarations of GnucashRegister class.
Styling functions for RegisterGnome.
void gnucash_get_style_classes(GnucashSheet *sheet, GtkStyleContext *stylectxt, RegisterColor field_type, gboolean use_neg_class)
Map a cell color type to a css style class.
void gnc_style_context_get_background_color(GtkStyleContext *context, GtkStateFlags state, GdkRGBA *color)
Wrapper to get the background color of a widget for a given state.
gboolean gnc_table_move_vertical_position(Table *table, VirtualLocation *virt_loc, int phys_row_offset)
Moves away from virtual location virt_loc by phys_row_offset physical rows.
SheetBlockStyle * style
The style for this block.
gboolean visible
y origin of block
gint origin_y
x origin of block