evolution-3.6.4/widgets/table/e-cell-hbox.c

No issues found

  1 /*
  2  * This program is free software; you can redistribute it and/or
  3  * modify it under the terms of the GNU Lesser General Public
  4  * License as published by the Free Software Foundation; either
  5  * version 2 of the License, or (at your option) version 3.
  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 GNU
 10  * Lesser General Public License for more details.
 11  *
 12  * You should have received a copy of the GNU Lesser General Public
 13  * License along with the program; if not, see <http://www.gnu.org/licenses/>
 14  *
 15  *
 16  * Authors:
 17  *		Srinivasa Ragavan <sragavan@novell.com>
 18  *
 19  * A majority of code taken from:
 20  *
 21  * the ECellText renderer.
 22  *
 23  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 24  *
 25  */
 26 
 27 #ifdef HAVE_CONFIG_H
 28 #include <config.h>
 29 #endif
 30 
 31 #include <ctype.h>
 32 #include <math.h>
 33 #include <stdio.h>
 34 
 35 #include <gtk/gtk.h>
 36 
 37 /* #include "a11y/gal-a11y-e-cell-registry.h" */
 38 /* #include "a11y/gal-a11y-e-cell-vbox.h" */
 39 #include "e-util/e-util.h"
 40 
 41 #include "e-cell-hbox.h"
 42 #include "e-table-item.h"
 43 
 44 G_DEFINE_TYPE (ECellHbox, e_cell_hbox, E_TYPE_CELL)
 45 
 46 #define INDENT_AMOUNT 16
 47 #define MAX_CELL_SIZE 25
 48 
 49 /*
 50  * ECell::new_view method
 51  */
 52 static ECellView *
 53 ecv_new_view (ECell *ecell,
 54               ETableModel *table_model,
 55               gpointer e_table_item_view)
 56 {
 57 	ECellHbox *ecv = E_CELL_HBOX (ecell);
 58 	ECellHboxView *hbox_view = g_new0 (ECellHboxView, 1);
 59 	gint i;
 60 
 61 	hbox_view->cell_view.ecell = ecell;
 62 	hbox_view->cell_view.e_table_model = table_model;
 63 	hbox_view->cell_view.e_table_item_view = e_table_item_view;
 64 	hbox_view->cell_view.kill_view_cb = NULL;
 65 	hbox_view->cell_view.kill_view_cb_data = NULL;
 66 
 67 	/* create our subcell view */
 68 	hbox_view->subcell_view_count = ecv->subcell_count;
 69 	hbox_view->subcell_views = g_new (ECellView *, hbox_view->subcell_view_count);
 70 	hbox_view->model_cols = g_new (int, hbox_view->subcell_view_count);
 71 	hbox_view->def_size_cols = g_new (int, hbox_view->subcell_view_count);
 72 
 73 	for (i = 0; i < hbox_view->subcell_view_count; i++) {
 74 		hbox_view->subcell_views[i] = e_cell_new_view (ecv->subcells[i], table_model, e_table_item_view /* XXX */);
 75 		hbox_view->model_cols[i] = ecv->model_cols[i];
 76 		hbox_view->def_size_cols[i] = ecv->def_size_cols[i];
 77 	}
 78 
 79 	return (ECellView *) hbox_view;
 80 }
 81 
 82 /*
 83  * ECell::kill_view method
 84  */
 85 static void
 86 ecv_kill_view (ECellView *ecv)
 87 {
 88 	ECellHboxView *hbox_view = (ECellHboxView *) ecv;
 89 	gint i;
 90 
 91 	if (hbox_view->cell_view.kill_view_cb)
 92 	    (hbox_view->cell_view.kill_view_cb)(ecv, hbox_view->cell_view.kill_view_cb_data);
 93 
 94 	if (hbox_view->cell_view.kill_view_cb_data)
 95 	    g_list_free (hbox_view->cell_view.kill_view_cb_data);
 96 
 97 	/* kill our subcell view */
 98 	for (i = 0; i < hbox_view->subcell_view_count; i++)
 99 		e_cell_kill_view (hbox_view->subcell_views[i]);
100 
101 	g_free (hbox_view->model_cols);
102 	g_free (hbox_view->def_size_cols);
103 	g_free (hbox_view->subcell_views);
104 	g_free (hbox_view);
105 }
106 
107 /*
108  * ECell::realize method
109  */
110 static void
111 ecv_realize (ECellView *ecell_view)
112 {
113 	ECellHboxView *hbox_view = (ECellHboxView *) ecell_view;
114 	gint i;
115 
116 	/* realize our subcell view */
117 	for (i = 0; i < hbox_view->subcell_view_count; i++)
118 		e_cell_realize (hbox_view->subcell_views[i]);
119 
120 	if (E_CELL_CLASS (e_cell_hbox_parent_class)->realize)
121 		(* E_CELL_CLASS (e_cell_hbox_parent_class)->realize) (ecell_view);
122 }
123 
124 /*
125  * ECell::unrealize method
126  */
127 static void
128 ecv_unrealize (ECellView *ecv)
129 {
130 	ECellHboxView *hbox_view = (ECellHboxView *) ecv;
131 	gint i;
132 
133 	/* unrealize our subcell view. */
134 	for (i = 0; i < hbox_view->subcell_view_count; i++)
135 		e_cell_unrealize (hbox_view->subcell_views[i]);
136 
137 	if (E_CELL_CLASS (e_cell_hbox_parent_class)->unrealize)
138 		(* E_CELL_CLASS (e_cell_hbox_parent_class)->unrealize) (ecv);
139 }
140 
141 /*
142  * ECell::draw method
143  */
144 static void
145 ecv_draw (ECellView *ecell_view,
146           cairo_t *cr,
147           gint model_col,
148           gint view_col,
149           gint row,
150           ECellFlags flags,
151           gint x1,
152           gint y1,
153           gint x2,
154           gint y2)
155 {
156 	ECellHboxView *hbox_view = (ECellHboxView *) ecell_view;
157 
158 	gint subcell_offset = 0;
159 	gint i;
160 	gint allotted_width = x2 - x1;
161 
162 	for (i = 0; i < hbox_view->subcell_view_count; i++) {
163 		/* Now cause our subcells to draw their contents,
164 		 * shifted by subcell_offset pixels */
165 		gint width = allotted_width * hbox_view->def_size_cols[i] / 100;
166 			/* e_cell_max_width_by_row (hbox_view->subcell_views[i], hbox_view->model_cols[i], view_col, row);
167 		if (width < hbox_view->def_size_cols[i])
168 			width = hbox_view->def_size_cols[i];
169 		printf ("width of %d %d of %d\n", width,hbox_view->def_size_cols[i], allotted_width); */
170 
171 		e_cell_draw (
172 			hbox_view->subcell_views[i], cr,
173 			hbox_view->model_cols[i], view_col, row, flags,
174 			x1 + subcell_offset , y1,
175 			x1 + subcell_offset + width, y2);
176 
177 		subcell_offset += width; /* e_cell_max_width_by_row (hbox_view->subcell_views[i], hbox_view->model_cols[i], view_col, row); */
178 	}
179 }
180 
181 /*
182  * ECell::event method
183  */
184 static gint
185 ecv_event (ECellView *ecell_view,
186            GdkEvent *event,
187            gint model_col,
188            gint view_col,
189            gint row,
190            ECellFlags flags,
191            ECellActions *actions)
192 {
193 	ECellHboxView *hbox_view = (ECellHboxView *) ecell_view;
194 	gint y = 0;
195 	gint i;
196 	gint subcell_offset = 0;
197 
198 	switch (event->type) {
199 	case GDK_BUTTON_PRESS:
200 	case GDK_BUTTON_RELEASE:
201 	case GDK_2BUTTON_PRESS:
202 	case GDK_3BUTTON_PRESS:
203 		y = event->button.y;
204 		break;
205 	case GDK_MOTION_NOTIFY:
206 		y = event->motion.y;
207 		break;
208 	default:
209 		/* nada */
210 		break;
211 	}
212 
213 	for (i = 0; i < hbox_view->subcell_view_count; i++) {
214 		gint width = e_cell_max_width_by_row (hbox_view->subcell_views[i], hbox_view->model_cols[i], view_col, row);
215 		if (width < hbox_view->def_size_cols[i])
216 			width = hbox_view->def_size_cols[i];
217 		if (y < subcell_offset + width)
218 			return e_cell_event (hbox_view->subcell_views[i], event, hbox_view->model_cols[i], view_col, row, flags, actions);
219 		subcell_offset += width;
220 	}
221 	return 0;
222 }
223 
224 /*
225  * ECell::height method
226  */
227 static gint
228 ecv_height (ECellView *ecell_view,
229             gint model_col,
230             gint view_col,
231             gint row)
232 {
233 	ECellHboxView *hbox_view = (ECellHboxView *) ecell_view;
234 	gint height = 0, max_height = 0;
235 	gint i;
236 
237 	for (i = 0; i < hbox_view->subcell_view_count; i++) {
238 		height = e_cell_height (hbox_view->subcell_views[i], hbox_view->model_cols[i], view_col, row);
239 		max_height = MAX (max_height, height);
240 	}
241 	return max_height;
242 }
243 
244 /*
245  * ECell::max_width method
246  */
247 static gint
248 ecv_max_width (ECellView *ecell_view,
249                gint model_col,
250                gint view_col)
251 {
252 	ECellHboxView *hbox_view = (ECellHboxView *) ecell_view;
253 	gint width = 0;
254 	gint i;
255 
256 	for (i = 0; i < hbox_view->subcell_view_count; i++) {
257 		gint cell_width = e_cell_max_width (hbox_view->subcell_views[i], hbox_view->model_cols[i], view_col);
258 
259 		if (cell_width < hbox_view->def_size_cols[i])
260 			cell_width = hbox_view->def_size_cols[i];
261 		width += cell_width;
262 	}
263 
264 	return width;
265 }
266 
267 /*
268  * GObject::dispose method
269  */
270 static void
271 ecv_dispose (GObject *object)
272 {
273 	ECellHbox *ecv = E_CELL_HBOX (object);
274 	gint i;
275 
276 	/* destroy our subcell */
277 	for (i = 0; i < ecv->subcell_count; i++)
278 		if (ecv->subcells[i])
279 			g_object_unref (ecv->subcells[i]);
280 	g_free (ecv->subcells);
281 	ecv->subcells = NULL;
282 	ecv->subcell_count = 0;
283 
284 	g_free (ecv->model_cols);
285 	ecv->model_cols = NULL;
286 
287 	g_free (ecv->def_size_cols);
288 	ecv->def_size_cols = NULL;
289 
290 	G_OBJECT_CLASS (e_cell_hbox_parent_class)->dispose (object);
291 }
292 
293 static void
294 e_cell_hbox_class_init (ECellHboxClass *class)
295 {
296 	GObjectClass *object_class = G_OBJECT_CLASS (class);
297 	ECellClass *ecc = E_CELL_CLASS (class);
298 
299 	object_class->dispose = ecv_dispose;
300 
301 	ecc->new_view         = ecv_new_view;
302 	ecc->kill_view        = ecv_kill_view;
303 	ecc->realize          = ecv_realize;
304 	ecc->unrealize        = ecv_unrealize;
305 	ecc->draw             = ecv_draw;
306 	ecc->event            = ecv_event;
307 	ecc->height           = ecv_height;
308 
309 	ecc->max_width        = ecv_max_width;
310 
311 /*	gal_a11y_e_cell_registry_add_cell_type (NULL, E_TYPE_CELL_HBOX, gal_a11y_e_cell_hbox_new); */
312 }
313 
314 static void
315 e_cell_hbox_init (ECellHbox *ecv)
316 {
317 	ecv->subcells = NULL;
318 	ecv->subcell_count = 0;
319 }
320 
321 /**
322  * e_cell_hbox_new:
323  *
324  * Creates a new ECell renderer that can be used to render multiple
325  * child cells.
326  *
327  * Return value: an ECell object that can be used to render multiple
328  * child cells.
329  **/
330 ECell *
331 e_cell_hbox_new (void)
332 {
333 	return g_object_new (E_TYPE_CELL_HBOX, NULL);
334 }
335 
336 void
337 e_cell_hbox_append (ECellHbox *hbox,
338                     ECell *subcell,
339                     gint model_col,
340                     gint size)
341 {
342 	hbox->subcell_count++;
343 
344 	hbox->subcells   = g_renew (ECell *, hbox->subcells,   hbox->subcell_count);
345 	hbox->model_cols = g_renew (int,     hbox->model_cols, hbox->subcell_count);
346 	hbox->def_size_cols = g_renew (int,     hbox->def_size_cols, hbox->subcell_count);
347 
348 	hbox->subcells[hbox->subcell_count - 1]   = subcell;
349 	hbox->model_cols[hbox->subcell_count - 1] = model_col;
350 	hbox->def_size_cols[hbox->subcell_count - 1] = size;
351 
352 	if (subcell)
353 		g_object_ref_sink (subcell);
354 }