2da2dcef8e87d57f966488654473db78d8ef039e
[hildon] / src / hildon-bread-crumb.c
1 /*
2  * This file is a part of hildon
3  *
4  * Copyright (C) 2007 Nokia Corporation, all rights reserved.
5  *
6  * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
7  * Author: Xan Lopez <xan.lopez@nokia.com>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; version 2.1 of
12  * the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22  * 02110-1301 USA
23  *
24  */
25
26 #include "hildon-bread-crumb.h"
27
28 #define HILDON_BREAD_CRUMB_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), HILDON_TYPE_BREAD_CRUMB, HildonBreadCrumbPrivate))
29
30 struct _HildonBreadCrumbPrivate
31 {
32   GtkWidget *icon;
33   GtkWidget *label;
34   GtkWidget *arrow;
35   gchar *text;
36
37   gboolean show_separator;
38 };
39
40 /* Signals */
41
42 enum {
43   LAST_SIGNAL
44 };
45
46 /* Properties */
47
48 enum {
49   PROP_0,
50   PROP_TEXT,
51   PROP_SHOW_SEPARATOR
52 };
53
54 /*
55 static guint bread_crumb_item_signals[LAST_SIGNAL] = { 0 };
56 */
57
58 /* GType methods */
59
60 static void hildon_bread_crumb_finalize (GObject *object);
61 static void hildon_bread_crumb_set_property (GObject *object, guint prop_id,
62                                                   const GValue *value, GParamSpec *pspec);
63 static void hildon_bread_crumb_get_property (GObject *object, guint prop_id,
64                                                   GValue *value, GParamSpec *pspec);
65
66 G_DEFINE_TYPE (HildonBreadCrumb, hildon_bread_crumb, GTK_TYPE_BUTTON)
67
68 static void
69 hildon_bread_crumb_class_init (HildonBreadCrumbClass *klass)
70 {
71   GObjectClass *gobject_class = (GObjectClass*)klass;
72
73   /* GObject signals */
74   gobject_class->finalize = hildon_bread_crumb_finalize;
75   gobject_class->set_property = hildon_bread_crumb_set_property;
76   gobject_class->get_property = hildon_bread_crumb_get_property;
77
78   /* Properties */
79   g_object_class_install_property (gobject_class,
80                                    PROP_TEXT,
81                                    g_param_spec_string ("text",
82                                                         "Text",
83                                                         "Text displayed as the name of the item",
84                                                         NULL,
85                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
86
87   g_object_class_install_property (gobject_class,
88                                    PROP_SHOW_SEPARATOR,
89                                    g_param_spec_boolean ("show-separator",
90                                                          "Show separator",
91                                                          "Show the separator attached to the item",
92                                                          TRUE,
93                                                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
94
95   /* Private data */
96   g_type_class_add_private (gobject_class, sizeof (HildonBreadCrumbPrivate));
97 }
98
99 static void
100 hildon_bread_crumb_init (HildonBreadCrumb *item)
101 {
102   GtkWidget *hbox;
103   HildonBreadCrumbPrivate *priv = HILDON_BREAD_CRUMB_GET_PRIVATE (item);
104
105   item->priv = priv;
106
107   hbox = gtk_hbox_new (FALSE, 6);
108   gtk_container_add (GTK_CONTAINER (item), hbox);
109
110   priv->arrow = gtk_arrow_new (GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
111   gtk_widget_set_name (priv->arrow, "hildon-bread-crumb-separator-arrow");
112   gtk_box_pack_start (GTK_BOX (hbox), priv->arrow, FALSE, FALSE, 0);
113
114   if (priv->show_separator)
115     gtk_widget_show (priv->arrow);
116
117   priv->label = gtk_label_new ("");
118   gtk_box_pack_start (GTK_BOX (hbox), priv->label, TRUE, TRUE, 0);
119   gtk_widget_show (priv->label);
120
121   gtk_widget_show (hbox);
122 }
123
124 static void
125 hildon_bread_crumb_finalize (GObject *object)
126 {
127   HildonBreadCrumbPrivate *priv = HILDON_BREAD_CRUMB (object)->priv;
128
129   g_free (priv->text);
130
131   G_OBJECT_CLASS (hildon_bread_crumb_parent_class)->finalize (object);
132 }
133
134 static void
135 hildon_bread_crumb_set_property (GObject *object, guint prop_id,
136                                       const GValue *value, GParamSpec *pspec)
137 {
138   HildonBreadCrumb *item = HILDON_BREAD_CRUMB (object);
139
140   switch (prop_id)
141     {
142     case PROP_TEXT:
143       hildon_bread_crumb_set_text (item, g_value_get_string (value));
144       break;
145     case PROP_SHOW_SEPARATOR:
146       hildon_bread_crumb_set_show_separator (item, g_value_get_boolean (value));
147       break;
148     default:
149       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
150       break;
151     }
152 }
153
154 static void
155 hildon_bread_crumb_get_property (GObject *object, guint prop_id,
156                                       GValue *value, GParamSpec *pspec)
157 {
158   HildonBreadCrumb *item = HILDON_BREAD_CRUMB (object);
159
160   switch (prop_id)
161     {
162     case PROP_TEXT:
163       g_value_set_string (value, item->priv->text);
164       break;
165     case PROP_SHOW_SEPARATOR:
166       g_value_set_boolean (value, item->priv->show_separator);
167       break;
168     default:
169       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
170       break;
171     }
172 }
173
174 void
175 hildon_bread_crumb_set_text (HildonBreadCrumb *item,
176                                   const gchar *text)
177 {
178   HildonBreadCrumbPrivate *priv;
179
180   g_return_if_fail (HILDON_IS_BREAD_CRUMB (item));
181
182   priv = item->priv;
183
184   if (priv->text)
185     g_free (priv->text);
186
187   priv->text = g_strdup (text);
188
189   gtk_label_set_label (GTK_LABEL (priv->label), text);
190   gtk_label_set_ellipsize (GTK_LABEL (item->priv->label),
191                            PANGO_ELLIPSIZE_START);
192   gtk_widget_show (priv->label);
193
194   g_object_notify (G_OBJECT (item), "text");
195 }
196
197 const gchar*
198 hildon_bread_crumb_get_text (HildonBreadCrumb *item)
199 {
200   HildonBreadCrumbPrivate *priv;
201
202   g_return_val_if_fail (HILDON_IS_BREAD_CRUMB (item), NULL);
203
204   priv = item->priv;
205
206   return priv->text;
207 }
208
209 void
210 hildon_bread_crumb_set_show_separator (HildonBreadCrumb *item,
211                                             gboolean show_separator)
212 {
213   HildonBreadCrumbPrivate *priv;
214
215   g_return_if_fail (HILDON_IS_BREAD_CRUMB (item));
216
217   priv = item->priv;
218
219   if (priv->show_separator == show_separator)
220     return;
221   
222   priv->show_separator = show_separator;
223
224   if (show_separator)
225     gtk_widget_show (priv->arrow);
226   else
227     gtk_widget_hide (priv->arrow);
228
229   g_object_notify (G_OBJECT (item), "show-separator");
230 }
231
232 void
233 hildon_bread_crumb_get_natural_size (HildonBreadCrumb *item,
234                                           gint *natural_width,
235                                           gint *natural_height)
236 {
237   GtkRequisition req;
238   gint width, height;
239   PangoLayout *layout;
240   HildonBreadCrumbPrivate *priv;
241
242   g_return_if_fail (HILDON_IS_BREAD_CRUMB (item));
243
244   priv = item->priv;
245
246   gtk_widget_size_request (GTK_WIDGET (item), &req);
247   if (natural_width)
248     *natural_width = req.width;
249
250   if (natural_height)
251     *natural_height = req.height;
252   /* Substract the size request of the label */
253   gtk_widget_size_request (priv->label, &req);
254   if (natural_width)
255     *natural_width -= req.width;
256   layout = gtk_widget_create_pango_layout (priv->label, priv->text);
257   pango_layout_get_size (layout, &width, &height);
258
259   if (natural_width)
260     *natural_width += PANGO_PIXELS (width);
261   /* Border width */
262   if (natural_width)
263     *natural_width += GTK_CONTAINER (item)->border_width * 2;
264
265   if (natural_height)
266     *natural_height += GTK_CONTAINER (item)->border_width * 2;
267 }
268
269 GtkWidget*
270 hildon_bread_crumb_new (const gchar* text)
271 {
272   return GTK_WIDGET (g_object_new (HILDON_TYPE_BREAD_CRUMB,
273                                    "text", text,
274                                    NULL));
275 }
276