26 #include <goffice/goffice.h>
30 #include <gsf/gsf-impl-utils.h>
31 #include <glib/gi18n-lib.h>
38 GtkToggleButton* buttons[119];
39 GtkLabel* labels[119];
40 double red[119], blue[119], green[119];
43 gboolean can_unselect;
50 struct _GcuPeriodicClass
52 GtkBinClass parent_class;
54 void (* element_changed_event)(
GcuPeriodic *periodic);
58 gcu_periodic_color_style_get_type (
void)
60 static GType etype = 0;
62 static const GEnumValue values[] = {
63 { GCU_PERIODIC_COLOR_NONE,
"GCU_PERIODIC_COLOR_NONE",
"none" },
64 { GCU_PERIODIC_COLOR_DEFAULT,
"GCU_PERIODIC_COLOR_DEFAULT",
"default" },
67 etype = g_enum_register_static (
"GcuPeriodicColorStyle", values);
71 #define GCU_TYPE_PERIODIC_COLOR_STYLE_TYPE (gcu_periodic_color_style_get_type())
73 static GtkBinClass *parent_class = NULL;
92 static guint gcu_periodic_signals[LAST_SIGNAL] = { 0 };
94 void on_clicked (GtkToggleButton *button,
GcuPeriodic* periodic)
96 static gboolean change = FALSE;
97 if (button != periodic->buttons[0]) {
100 if (periodic->buttons[0])
101 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (periodic->buttons[0]), FALSE);
102 periodic->buttons[0] = button;
103 name = gtk_buildable_get_name (GTK_BUILDABLE (periodic->buttons[0]));
104 periodic->Z = atoi (name + 3);
105 g_signal_emit (periodic, gcu_periodic_signals[ELEMENT_CHANGED], 0, periodic->Z);
107 }
else if (!change) {
108 if (periodic->can_unselect) {
109 periodic->buttons[0] = NULL;
111 g_signal_emit (periodic, gcu_periodic_signals[ELEMENT_CHANGED], 0, 0);
112 }
else if (periodic->buttons[0])
113 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (periodic->buttons[0]), TRUE);
118 gcu_periodic_set_property (GObject *
object,
124 g_return_if_fail (
object != NULL);
130 case PROP_CAN_UNSELECT:
131 periodic->can_unselect = g_value_get_boolean (value);
134 case PROP_COLOR_STYLE: {
135 unsigned style = g_value_get_uint (value);
136 if (style < GCU_PERIODIC_COLOR_MAX + periodic->nbschemes) {
137 periodic->colorstyle = style;
138 int page = (style >= GCU_PERIODIC_COLOR_MAX)?
139 g_array_index (periodic->colorschemes,
struct ColorScheme, style - GCU_PERIODIC_COLOR_MAX).page: 0;
140 gtk_notebook_set_current_page (periodic->book, page);
141 gcu_periodic_set_colors (periodic);
143 g_warning (_(
"Out of range value %d for property \"color-style\" for GcuPeriodic instance %p\n"), style, periodic);
148 G_OBJECT_WARN_INVALID_PROPERTY_ID (
object, param_id, pspec);
154 gcu_periodic_get_property (GObject *
object,
161 g_return_if_fail (
object != NULL);
167 case PROP_CAN_UNSELECT:
168 g_value_set_boolean (value, periodic->can_unselect);
171 case PROP_COLOR_STYLE:
172 g_value_set_uint (value, periodic->colorstyle);
176 G_OBJECT_WARN_INVALID_PROPERTY_ID (
object, param_id, pspec);
181 static void gcu_periodic_get_preferred_height (GtkWidget *w, gint *minimum_height, gint *natural_height)
183 GtkWidget *child = gtk_bin_get_child (GTK_BIN (w));
184 gboolean visible = FALSE;
186 g_object_get (G_OBJECT (child),
"visible", &visible, NULL);
188 gtk_widget_get_preferred_height (child, minimum_height, natural_height);
190 *minimum_height = *natural_height = 0;
193 static void gcu_periodic_get_preferred_width (GtkWidget *w, gint *minimum_width, gint *natural_width)
195 GtkWidget *child = gtk_bin_get_child (GTK_BIN (w));
196 gboolean visible = FALSE;
198 g_object_get (G_OBJECT (child),
"visible", &visible, NULL);
200 gtk_widget_get_preferred_width (child, minimum_width, natural_width);
202 *minimum_width = *natural_width = 0;
205 static void gcu_periodic_size_allocate (GtkWidget *w, GtkAllocation *alloc)
207 GtkWidget *child = gtk_bin_get_child (GTK_BIN (w));
208 gboolean visible = FALSE;
210 g_object_get (G_OBJECT (child),
"visible", &visible, NULL);
212 gtk_widget_size_allocate (child, alloc);
213 (GTK_WIDGET_CLASS (parent_class))->size_allocate (w, alloc);
216 static void gcu_periodic_finalize (GObject *
object)
220 g_array_free (periodic->colorschemes, FALSE);
222 if (G_OBJECT_CLASS (parent_class)->finalize)
223 (* G_OBJECT_CLASS (parent_class)->finalize) (
object);
228 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
229 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
230 parent_class = (GtkBinClass*) g_type_class_peek_parent (klass);
232 gobject_class->set_property = gcu_periodic_set_property;
233 gobject_class->get_property = gcu_periodic_get_property;
234 klass->element_changed_event = NULL;
235 gcu_periodic_signals[ELEMENT_CHANGED] =
236 g_signal_new (
"element_changed",
237 G_TYPE_FROM_CLASS(gobject_class),
241 g_cclosure_marshal_VOID__UINT,
245 g_object_class_install_property
248 g_param_spec_boolean (
"can_unselect", NULL, NULL,
250 (G_PARAM_READABLE | G_PARAM_WRITABLE)));
251 g_object_class_install_property
254 g_param_spec_uint (
"color-style", NULL, NULL,
255 GCU_PERIODIC_COLOR_NONE, G_MAXUINT,
256 GCU_PERIODIC_COLOR_NONE,
257 (G_PARAM_READABLE | G_PARAM_WRITABLE)));
258 gobject_class->finalize = gcu_periodic_finalize;
259 widget_class->get_preferred_height = gcu_periodic_get_preferred_height;
260 widget_class->get_preferred_width = gcu_periodic_get_preferred_width;
261 widget_class->size_allocate = gcu_periodic_size_allocate;
264 static void on_draw (GtkWidget *w, cairo_t *cr,
GcuPeriodic *periodic)
266 if (periodic->colorstyle != GCU_PERIODIC_COLOR_NONE) {
268 unsigned i = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (w),
"elt"));
269 gtk_widget_get_allocation (w, &alloc);
270 cairo_rectangle (cr, 0, 0, alloc.width, alloc.height);
271 cairo_set_source_rgb (cr, periodic->red[i], periodic->green[i], periodic->blue[i]);
274 GTK_WIDGET_CLASS (G_OBJECT_GET_CLASS (w))->draw (w, cr);
277 static void gcu_periodic_init (
GcuPeriodic *periodic)
280 char name[8] =
"elt";
281 GtkToggleButton* button;
283 xml = go_gtk_builder_load (UIDIR
"/gcuperiodic.ui", GETTEXT_PACKAGE, NULL);
284 g_return_if_fail (xml);
285 periodic->grid = GTK_GRID (gtk_builder_get_object (xml,
"periodic-grid"));
286 periodic->book = GTK_NOTEBOOK (gtk_builder_get_object (xml,
"book"));
287 periodic->colorstyle = GCU_PERIODIC_COLOR_NONE;
288 memset(periodic->buttons, 0, sizeof (GtkToggleButton*) * 119);
289 for (i = 1; i <= 118; i++) {
290 sprintf(name + 3,
"%d", i);
291 button = (GtkToggleButton*) gtk_builder_get_object (xml, name);
292 if (GTK_IS_TOGGLE_BUTTON (button)) {
294 periodic->buttons[i] = button;
295 periodic->labels[i] = GTK_LABEL (gtk_bin_get_child (GTK_BIN (button)));
296 g_object_set_data (G_OBJECT (periodic->labels[i]),
"elt", GUINT_TO_POINTER (i));
297 g_signal_connect (G_OBJECT (button),
"toggled", G_CALLBACK (on_clicked), periodic);
298 g_signal_connect (G_OBJECT (periodic->labels[i]),
"draw", G_CALLBACK (on_draw), periodic);
302 gtk_container_add (GTK_CONTAINER (periodic), GTK_WIDGET (periodic->grid));
303 gtk_widget_show_all (GTK_WIDGET (periodic));
304 periodic->colorschemes = g_array_new (FALSE, FALSE,
sizeof (
struct ColorScheme));
305 g_object_unref (xml);
309 gcu_periodic_class_init, gcu_periodic_init,
323 void gcu_periodic_set_element (
GcuPeriodic* periodic, guint element)
326 if (periodic->can_unselect && periodic->buttons[0]) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(periodic->buttons[0]), FALSE);
329 gtk_toggle_button_set_active(periodic->buttons[element], TRUE);
330 periodic->buttons[0] = periodic->buttons[element];
331 periodic->Z = element;
333 else if (periodic->can_unselect)
335 periodic->buttons[0] = NULL;
342 const double *colors;
343 PangoAttribute *attr;
349 gpointer data = NULL;
350 if (periodic->colorstyle >= GCU_PERIODIC_COLOR_MAX) {
351 func = g_array_index (periodic->colorschemes,
struct ColorScheme, periodic->colorstyle - GCU_PERIODIC_COLOR_MAX).f;
352 data = g_array_index (periodic->colorschemes,
struct ColorScheme, periodic->colorstyle - GCU_PERIODIC_COLOR_MAX).data;
354 for (i = 1; i <= 118; i++)
356 if (!periodic->labels[i])
358 switch (periodic->colorstyle)
360 case GCU_PERIODIC_COLOR_NONE:
361 l = pango_attr_list_new ();
362 gtk_label_set_attributes (periodic->labels[i], l);
364 case GCU_PERIODIC_COLOR_DEFAULT:
366 periodic->red[i] = colors[0];
367 periodic->green[i] = colors[1];
368 periodic->blue[i] = colors[2];
369 if (colors[0] > 0.6 || colors[1] > 0.6 || colors[2] > 0.6)
370 attr = pango_attr_foreground_new (0, 0, 0);
372 attr = pango_attr_foreground_new (65535, 65535, 65535);
373 attr->start_index = 0;
374 attr->end_index = 100;
375 l = pango_attr_list_new ();
376 pango_attr_list_insert (l, attr);
377 gtk_label_set_attributes (periodic->labels[i], l);
380 func (i, &rgba, data);
381 periodic->red[i] = rgba.red;
382 periodic->green[i] = rgba.green;
383 periodic->blue[i] = rgba.blue;
384 if (rgba.red > 0.6 || rgba.green > 0.6 || rgba.blue > 0.6)
385 attr = pango_attr_foreground_new (0, 0, 0);
387 attr = pango_attr_foreground_new (65535, 65535, 65535);
388 attr->start_index = 0;
389 attr->end_index = 100;
390 l = pango_attr_list_new ();
391 pango_attr_list_insert (l, attr);
392 gtk_label_set_attributes (periodic->labels[i], l);
402 struct ColorScheme s;
405 s.page = gtk_notebook_append_page (periodic->book, extra_widget, NULL);
409 g_array_append_val (periodic->colorschemes, s);
410 return GCU_PERIODIC_COLOR_MAX + periodic->nbschemes++;
413 void gcu_periodic_set_tips (
GcuPeriodic *periodic,
unsigned scheme)
415 if (scheme != periodic->tips) {
417 periodic->tips = scheme;
421 for (i = 1; i <= 118; i++) {
422 if (periodic->buttons[i])
427 for (i = 1; i <= 118; i++) {
428 GtkWidget *win, *grid, *w;
431 if (!periodic->buttons[i])
433 win = gtk_window_new (GTK_WINDOW_POPUP);
434 gtk_widget_set_name (win,
"gtk-tooltip");
435 grid = gtk_grid_new ();
436 gtk_container_add (GTK_CONTAINER (win), grid);
437 w = GTK_WIDGET (g_object_new (GTK_TYPE_LABEL,
"xalign", 0., NULL));
438 markup = g_strdup_printf (
"%u", i);
439 gtk_label_set_text (GTK_LABEL (w), markup);
441 gtk_grid_attach (GTK_GRID (grid), w, 0, 0, 1, 1);
444 w = GTK_WIDGET (g_object_new (GTK_TYPE_LABEL,
"justify", GTK_JUSTIFY_CENTER, NULL));
445 markup = g_strdup_printf (
"<span face=\"Sans\" size=\"xx-large\">%s</span>\n%s\n%s\n%s",
448 gtk_label_set_markup (GTK_LABEL (w), markup);
450 gtk_grid_attach (GTK_GRID (grid), w, 0, 1, 1, 1);
451 gtk_widget_show_all (grid);
452 gtk_widget_set_tooltip_window (GTK_WIDGET (periodic->buttons[i]), GTK_WINDOW (win));