GnuCash  5.6-150-g038405b370+
gnc-cell-renderer-text-flag.c
1 
8 /* GnuCash is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Library General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * Gnucash is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, contact:
20  *
21  * Free Software Foundation Voice: +1-617-542-5942
22  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
23  * Boston, MA 02110-1301, USA gnu@gnu.org
24  */
25 
26 #include <config.h>
27 #include <gtk/gtk.h>
28 
29 #include "gnc-cell-renderer-text-flag.h"
30 
40 static void gnc_cell_renderer_text_flag_get_property(GObject *object,
41  guint param_id,
42  GValue *value,
43  GParamSpec *pspec);
44 static void gnc_cell_renderer_text_flag_set_property(GObject *object,
45  guint param_id,
46  const GValue *value,
47  GParamSpec *pspec);
48 
49 static void gnc_cell_renderer_text_flag_render(
50  GtkCellRenderer *cell, cairo_t *cr, GtkWidget *widget,
51  const GdkRectangle *background_area, const GdkRectangle *cell_area,
52  GtkCellRendererState flags);
53 
54 enum
55 {
56  PROP_0,
57 
58  PROP_FLAG_SIZE,
59  PROP_FLAG_COLOR,
60  PROP_FLAG_COLOR_RGBA,
61  PROP_FLAGGED,
62  PROP_FLAG_COLOR_SELECTED,
63  PROP_FLAG_COLOR_RGBA_SELECTED,
64 
65  LAST_PROP
66 };
67 
69 {
70  GtkCellRendererText parent;
71 
72  gint size;
73  GdkRGBA color;
74  GdkRGBA color_selected;
75  gboolean flagged;
76 };
77 
78 G_DEFINE_TYPE(GncCellRendererTextFlag,
79  gnc_cell_renderer_text_flag,
80  GTK_TYPE_CELL_RENDERER_TEXT)
81 
82 static void
83 gnc_cell_renderer_text_flag_init(GncCellRendererTextFlag *celltext)
84 {
85  celltext->size = 8;
86  gdk_rgba_parse(&celltext->color, "red");
87  celltext->flagged = FALSE;
88 }
89 
90 static void
91 gnc_cell_renderer_text_flag_class_init(GncCellRendererTextFlagClass *class)
92 {
93  GObjectClass *object_class = G_OBJECT_CLASS(class);
94  GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS(class);
95 
96  object_class->get_property = gnc_cell_renderer_text_flag_get_property;
97  object_class->set_property = gnc_cell_renderer_text_flag_set_property;
98 
99  cell_class->render = gnc_cell_renderer_text_flag_render;
100 
101  g_object_class_install_property(
102  object_class, PROP_FLAG_SIZE,
103  g_param_spec_int("flag-size", "Flag size", "Flag size", 0, 50,
104  8, G_PARAM_READWRITE));
105 
106  g_object_class_install_property(
107  object_class, PROP_FLAG_COLOR,
108  g_param_spec_string("flag-color", "Flag color name",
109  "Flag color as a string", "red",
110  G_PARAM_WRITABLE));
111 
112  g_object_class_install_property(
113  object_class, PROP_FLAG_COLOR_RGBA,
114  g_param_spec_boxed("flag-color-rgba", "Flag color as RGBA",
115  "Flag color as a GdkRGBA", GDK_TYPE_RGBA,
116  G_PARAM_READWRITE));
117 
118  g_object_class_install_property(
119  object_class, PROP_FLAG_COLOR_SELECTED,
120  g_param_spec_string("flag-color-selected", "Flag color name for selected rows",
121  "Flag color as a string, to use in selected rows", "white",
122  G_PARAM_WRITABLE));
123 
124  g_object_class_install_property(
125  object_class, PROP_FLAG_COLOR_RGBA_SELECTED,
126  g_param_spec_boxed("flag-color-rgba-selected", "Flag color as RGBA for selected rows",
127  "Flag color as a GdkRGBA, to use in selected rows", GDK_TYPE_RGBA,
128  G_PARAM_READWRITE));
129 
130  g_object_class_install_property(
131  object_class, PROP_FLAGGED,
132  g_param_spec_boolean("flagged", "Flag set",
133  "Flag indicator is set", FALSE,
134  G_PARAM_READWRITE));
135 }
136 
137 static void
138 gnc_cell_renderer_text_flag_get_property(GObject *object, guint param_id,
139  GValue *value, GParamSpec *pspec)
140 {
141  GncCellRendererTextFlag *celltext = GNC_CELL_RENDERER_TEXT_FLAG(object);
142 
143  switch (param_id)
144  {
145  case PROP_FLAGGED:
146  g_value_set_boolean(value, celltext->flagged);
147  break;
148 
149  case PROP_FLAG_SIZE:
150  g_value_set_int(value, celltext->size);
151  break;
152 
153  case PROP_FLAG_COLOR_RGBA:
154  g_value_set_boxed (value, &celltext->color);
155  break;
156 
157  case PROP_FLAG_COLOR_RGBA_SELECTED:
158  g_value_set_boxed (value, &celltext->color_selected);
159  break;
160 
161  default:
162  G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
163  break;
164  }
165 }
166 
167 static void
168 gnc_cell_renderer_text_flag_set_property(GObject *object, guint param_id,
169  const GValue *value,
170  GParamSpec *pspec)
171 {
172  GncCellRendererTextFlag *celltext = GNC_CELL_RENDERER_TEXT_FLAG(object);
173  switch (param_id)
174  {
175  case PROP_FLAG_COLOR:
176  case PROP_FLAG_COLOR_SELECTED:
177  {
178  GdkRGBA rgba;
179 
180  if (!g_value_get_string(value))
181  break;
182  else if (gdk_rgba_parse(&rgba, g_value_get_string(value)))
183  {
184  if (param_id == PROP_FLAG_COLOR_SELECTED)
185  celltext->color = rgba;
186  else
187  celltext->color_selected = rgba;
188  }
189  else
190  g_warning("Don't know color '%s'", g_value_get_string(value));
191  }
192  break;
193 
194  case PROP_FLAG_COLOR_RGBA:
195  {
196  GdkRGBA *rgba;
197 
198  rgba = g_value_get_boxed(value);
199  if (rgba)
200  celltext->color = *rgba;
201  }
202  break;
203 
204  case PROP_FLAG_COLOR_RGBA_SELECTED:
205  {
206  GdkRGBA *rgba;
207 
208  rgba = g_value_get_boxed(value);
209  if (rgba)
210  celltext->color_selected = *rgba;
211  }
212  break;
213 
214  case PROP_FLAGGED:
215  celltext->flagged = g_value_get_boolean(value);
216  break;
217 
218  case PROP_FLAG_SIZE:
219  celltext->size = g_value_get_int(value);
220  break;
221 
222  default:
223  G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
224  break;
225  }
226 }
227 
237 GtkCellRenderer *
238 gnc_cell_renderer_text_flag_new(void)
239 {
240  return g_object_new(GNC_TYPE_CELL_RENDERER_TEXT_FLAG, NULL);
241 }
242 
243 static void
244 gnc_cell_renderer_text_flag_render(GtkCellRenderer *cell, cairo_t *cr,
245  GtkWidget *widget,
246  const GdkRectangle *background_area,
247  const GdkRectangle *cell_area,
248  GtkCellRendererState flags)
249 
250 {
251  GncCellRendererTextFlag *celltext = GNC_CELL_RENDERER_TEXT_FLAG(cell);
252 
253  // call the parent renderer to do the standard drawing
254  GTK_CELL_RENDERER_CLASS(gnc_cell_renderer_text_flag_parent_class)
255  ->render(cell, cr, widget, background_area, cell_area, flags);
256 
257  // add the flag (triangle in the top right corner)
258  if (celltext->flagged)
259  {
260  guint size = MIN(MIN(background_area->height, celltext->size),
261  background_area->width);
262  double x = background_area->x + background_area->width - size;
263  double y = background_area->y;
264 
265  cairo_move_to(cr, x, y);
266  cairo_rel_line_to(cr, size, 0);
267  cairo_rel_line_to(cr, 0, size);
268  cairo_close_path(cr);
269  gdk_cairo_set_source_rgba(cr, (flags & GTK_CELL_RENDERER_SELECTED)
270  ? &celltext->color_selected
271  : &celltext->color);
272  cairo_fill(cr);
273  }
274 }