libyui-gtk  2.43.7
 All Classes
ygtkbargraph.c
1 /********************************************************************
2  * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
3  ********************************************************************/
4 
5 /* YGtkBarGraph widget */
6 // check the header file for information about this widget
7 
8 #include <yui/Libyui_config.h>
9 #include "ygtkratiobox.h"
10 #include "ygtkbargraph.h"
11 #include <gtk/gtk.h>
12 
13 G_DEFINE_TYPE (YGtkBarGraph, ygtk_bar_graph, GTK_TYPE_FRAME)
14 
15 static void ygtk_bar_graph_init (YGtkBarGraph *bar)
16 {
17  GtkWidget *box = ygtk_ratio_hbox_new (0);
18  gtk_widget_show (box);
19  gtk_container_add (GTK_CONTAINER (bar), box);
20  ygtk_bar_graph_set_style (bar, TRUE);
21 }
22 
23 static void
24 ygtk_bar_graph_get_preferred_height (GtkWidget *widget,
25  gint *minimal_height,
26  gint *natural_height)
27 {
28  GTK_WIDGET_CLASS (ygtk_bar_graph_parent_class)->get_preferred_height (widget, minimal_height, natural_height);
29  *natural_height = *minimal_height = *minimal_height + 18; // give room for the labels
30 }
31 
32 static void
33 ygtk_bar_graph_get_preferred_width (GtkWidget *widget,
34  gint *minimal_width,
35  gint *natural_width)
36 {
37  GTK_WIDGET_CLASS (ygtk_bar_graph_parent_class)->get_preferred_width (widget, minimal_width, natural_width);
38 }
39 
40 GtkWidget *ygtk_bar_graph_new (void)
41 {
42  return g_object_new (YGTK_TYPE_BAR_GRAPH, NULL);
43 }
44 
45 void ygtk_bar_graph_create_entries (YGtkBarGraph *bar, guint entries)
46 {
47  YGtkRatioBox *box = YGTK_RATIO_BOX (gtk_bin_get_child(GTK_BIN (bar)));
48 
49  // Remove the ones in excess
50  guint i;
51  for (i = entries; i < g_list_length (box->children); i++)
52  gtk_container_remove (GTK_CONTAINER (box),
53  (GtkWidget*) g_list_nth_data (box->children, i));
54 
55  // Add new ones, if missing
56  for (i = g_list_length (box->children); i < entries; i++) {
57  GtkWidget *label = ygtk_colored_label_new();
58  gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
59 
60  // we need a GtkEventBox or something, so we may assign a tooltip to it
61  GtkWidget *lbox = gtk_event_box_new();
62  gtk_container_add (GTK_CONTAINER (lbox), label);
63  gtk_widget_show_all (lbox);
64  gtk_container_add (GTK_CONTAINER (box), lbox);
65  }
66 }
67 
68 static GtkWidget *ygtk_bar_graph_get_label (YGtkBarGraph *bar, int index, GtkWidget **b)
69 {
70  YGtkRatioBox *hbox = YGTK_RATIO_BOX (gtk_bin_get_child(GTK_BIN (bar)));
71  GtkWidget *box = ((YGtkRatioBoxChild *) g_list_nth_data (hbox->children, index))->widget;
72  if (b) *b = box;
73  return gtk_bin_get_child (GTK_BIN (box));
74 }
75 
76 void ygtk_bar_graph_setup_entry (YGtkBarGraph *bar, int index, const gchar *label_entry, int value)
77 {
78  GtkWidget *box, *label;
79  label = ygtk_bar_graph_get_label (bar, index, &box);
80 
81  if (value < 0)
82  value = 0;
83 
84  // Reading label text
85  if (label_entry) {
86  GString *label_text = g_string_new (label_entry);
87  { // Replace %1 by value(i)
88  guint i;
89  for (i = 0; i < label_text->len; i++)
90  if (label_text->str[i] == '%' && label_text->str[i+1] == '1') {
91  gchar *value_str = g_strdup_printf ("%d", value);
92  label_text = g_string_erase (label_text, i, 2);
93  label_text = g_string_insert (label_text, i, value_str);
94  g_free (value_str);
95  }
96  }
97  gtk_label_set_label (GTK_LABEL (label), label_text->str);
98 
99  // tooltip for the labels -- useful if the bar entry gets too small
100  gtk_widget_set_tooltip_text (box, label_text->str);
101  g_string_free (label_text, TRUE);
102  }
103 
104  // Set proportion
105  gtk_widget_set_size_request (box, 0, -1);
106  YGtkRatioBox *hbox = YGTK_RATIO_BOX (gtk_bin_get_child(GTK_BIN (bar)));
107  ygtk_ratio_box_set_child_packing (hbox, box, MAX (value, 1));
108 
109  // Set background color
110  // The Tango palette
111  const guint palette [][3] = {
112  { 138, 226, 52 }, // Chameleon 1
113  { 252, 175, 62 }, // Orange 1
114  { 114, 159, 207 }, // Sky Blue 1
115  { 233, 185, 110 }, // Chocolate 1
116  { 239, 41, 41 }, // Scarlet Red 1
117  { 252, 233, 79 }, // Butter 1
118  { 173, 127, 168 }, // Plum 1
119  { 115, 210, 22 }, // Chameleon 2
120  { 245, 121, 0 }, // Orange 2
121  { 52, 101, 164 }, // Sky Blue 2
122  { 193, 125, 17 }, // Chocolate 2
123  { 204, 0, 0 }, // Scarlet Red 2
124  { 237, 212, 0 }, // Butter 2
125  { 117, 80, 123 }, // Plum 2
126  { 78, 154, 6 }, // Chameleon 3
127  { 206, 92, 0 }, // Orange 3
128  { 32, 74, 135 }, // Sky Blue 3
129  { 143, 89, 2 }, // Chocolate 3
130  { 164, 0, 0 }, // Scarlet Red 3
131  { 196, 160, 0 }, // Butter 3
132  { 92, 53, 102 }, // Plum 3
133  { 238, 238, 236 }, // Aluminium 1
134  { 211, 215, 207 }, // Aluminium 2
135  { 186, 189, 182 }, // Aluminium 3
136  { 136, 138, 133 }, // Aluminium 4
137  { 85, 87, 83 }, // Aluminium 5
138  { 46, 52, 54 }, // Aluminium 6
139  };
140 
141  YGtkColoredLabel *color_label = YGTK_COLORED_LABEL (label);
142  const guint *color = palette [index % G_N_ELEMENTS (palette)];
143  GdkRGBA gcolor = { color[0] / 255., color[1] / 255., color[2] / 255., 0 };
144  ygtk_colored_label_set_background (color_label, &gcolor);
145 }
146 
147 void ygtk_bar_graph_set_style (YGtkBarGraph *bar, gboolean flat)
148 {
149  bar->flat = flat;
150  GtkShadowType shadow = flat ? GTK_SHADOW_OUT : GTK_SHADOW_NONE;
151  gtk_frame_set_shadow_type (GTK_FRAME (bar), shadow);
152 }
153 
154 void ygtk_bar_graph_customize_bg (YGtkBarGraph *bar, int index, GdkRGBA *color)
155 {
156  GtkWidget *label = ygtk_bar_graph_get_label (bar, index, NULL);
157  ygtk_colored_label_set_background (YGTK_COLORED_LABEL (label), color);
158 }
159 
160 void ygtk_bar_graph_customize_fg (YGtkBarGraph *bar, int index, GdkRGBA *color)
161 {
162  GtkWidget *label = ygtk_bar_graph_get_label (bar, index, NULL);
163  ygtk_colored_label_set_foreground (YGTK_COLORED_LABEL (label), color);
164 }
165 
166 static void ygtk_bar_graph_class_init (YGtkBarGraphClass *klass)
167 {
168  ygtk_bar_graph_parent_class = g_type_class_peek_parent (klass);
169 
170  GtkWidgetClass* widget_class = GTK_WIDGET_CLASS (klass);
171  widget_class->get_preferred_width = ygtk_bar_graph_get_preferred_width;
172  widget_class->get_preferred_height = ygtk_bar_graph_get_preferred_height;
173 }
174 
175 //** YGtkColoredLabel
176 
177 #include <stdlib.h>
178 
179 G_DEFINE_TYPE (YGtkColoredLabel, ygtk_colored_label, GTK_TYPE_LABEL)
180 
181 static void ygtk_colored_label_init (YGtkColoredLabel *label)
182 {}
183 
184 static inline double pixel_clamp (double val)
185 { return MAX (0, MIN (1, val)); }
186 
187 static gboolean ygtk_colored_label_on_draw (GtkWidget *widget, cairo_t *cr)
188 {
189  GtkStyleContext *ctx;
190  ctx = gtk_widget_get_style_context(widget);
191 
192  GdkRGBA color;
193  gtk_style_context_get_background_color(ctx, GTK_STATE_NORMAL, &color);
194 
195  cairo_save(cr);
196  int width = gtk_widget_get_allocated_width (widget);
197  int height = gtk_widget_get_allocated_height (widget);
198  cairo_scale (cr, width, height);
199 
200  cairo_pattern_t *grad = cairo_pattern_create_linear (0, 0, 0, 1);
201 
202  cairo_pattern_add_color_stop_rgba (grad, 0, pixel_clamp (color.red+.3), pixel_clamp (color.green+.3), pixel_clamp (color.blue+.3), 1);
203  cairo_pattern_add_color_stop_rgba (grad, 0.70, color.red, color.green, color.blue, 1);
204  cairo_pattern_add_color_stop_rgba (grad, 1, pixel_clamp (color.red-.2), pixel_clamp (color.green-.2), pixel_clamp (color.blue-.2), 1);
205 
206  cairo_rectangle (cr, 0, 0, 1, 1);
207  cairo_set_source (cr, grad);
208  cairo_fill (cr);
209 
210  cairo_pattern_destroy (grad);
211  cairo_restore(cr);
212  GTK_WIDGET_CLASS (ygtk_colored_label_parent_class)->draw (widget, cr);
213  return FALSE;
214 }
215 
216 GtkWidget *ygtk_colored_label_new (void)
217 { return g_object_new (YGTK_TYPE_COLORED_LABEL, NULL); }
218 
219 void ygtk_colored_label_set_background (YGtkColoredLabel *label, GdkRGBA *color)
220 { gtk_widget_override_background_color (GTK_WIDGET (label), GTK_STATE_NORMAL, color); }
221 
222 void ygtk_colored_label_set_foreground (YGtkColoredLabel *label, GdkRGBA *color)
223 { gtk_widget_override_color (GTK_WIDGET (label), GTK_STATE_NORMAL, color); }
224 
225 static void ygtk_colored_label_class_init (YGtkColoredLabelClass *klass)
226 {
227  ygtk_colored_label_parent_class = g_type_class_peek_parent (klass);
228 
229  GtkWidgetClass* widget_class = GTK_WIDGET_CLASS (klass);
230  widget_class->draw = ygtk_colored_label_on_draw;
231 }
232