Contents of /trunk/src/bct.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 136 - (show annotations)
Mon Oct 19 13:02:41 2009 UTC (14 years, 7 months ago) by harbaum
File MIME type: text/plain
File size: 4337 byte(s)
Balloon callback extensions
1 /*
2 * Copyright (C) 2009 Till Harbaum <till@harbaum.org>.
3 *
4 * This file is part of GPXView.
5 *
6 * GPXView is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * GPXView is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GPXView. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 /*
21 * This simple breadcrumbtrail replacement is a simple hbox with
22 * buttons inside
23 */
24
25 #include "gpxview.h"
26
27 typedef struct {
28 GtkWidget *button;
29 GDestroyNotify destroy;
30 gpointer id;
31 } crumb_t;
32
33 typedef struct {
34 GtkWidget *back;
35
36 GSList *crumbs;
37 } bct_priv_t;
38
39 static void bct_free(gpointer data, gpointer user_data) {
40 g_free(data);
41 }
42
43 static gint bct_destroy_event(GtkWidget *widget, gpointer data ) {
44 bct_priv_t *priv = (bct_priv_t*)data;
45
46 g_slist_foreach(priv->crumbs, bct_free, NULL);
47 g_free(priv);
48
49 return FALSE;
50 }
51
52 static void crumb_destroy(bct_priv_t *priv, crumb_t *crumb) {
53 /* call destroy callback */
54 crumb->destroy(crumb->id);
55
56 /* destroy it */
57 gtk_widget_destroy(crumb->button);
58
59 /* remove element from list */
60 priv->crumbs = g_slist_remove(priv->crumbs, crumb);
61
62 g_free(crumb);
63 }
64
65 static void bct_update(bct_priv_t *priv) {
66 /* still something in list? */
67 if(g_slist_length(priv->crumbs)) {
68 crumb_t *crumb = g_slist_last(priv->crumbs)->data;
69 /* disable button now last in chain */
70 gtk_widget_set_sensitive(crumb->button, FALSE);
71
72 // GtkWidget *label = gtk_bin_get_child(GTK_BIN(crumb->button));
73 // gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_NONE);
74 }
75
76 /* disable back button if crumb trail has 1 item or less */
77 if(g_slist_length(priv->crumbs) <= 1)
78 gtk_widget_set_sensitive(priv->back, FALSE);
79 }
80
81 static void on_back_clicked(GtkButton *button, bct_priv_t *priv) {
82 crumb_destroy(priv, g_slist_last(priv->crumbs)->data);
83 bct_update(priv);
84 }
85
86 static void on_crumb_clicked(GtkButton *button, bct_priv_t *priv) {
87 /* clear crumb trail until we reach the button that was clicked */
88 crumb_t *crumb = g_slist_last(priv->crumbs)->data;
89 while(crumb->button != (GtkWidget*)button) {
90 crumb_destroy(priv, crumb);
91 crumb = g_slist_last(priv->crumbs)->data;
92 }
93 bct_update(priv);
94 }
95
96 GtkWidget *bct_new(void) {
97 bct_priv_t *priv = g_new0(bct_priv_t, 1);
98
99 GtkWidget *hbox = gtk_hbox_new(FALSE, 0);
100 g_object_set_data(G_OBJECT(hbox), "priv", priv);
101
102 priv->back = gtk_button_new();
103 gtk_button_set_image(GTK_BUTTON(priv->back),
104 gtk_image_new_from_stock(GTK_STOCK_GO_BACK, GTK_ICON_SIZE_BUTTON));
105 gtk_widget_set_sensitive(priv->back, FALSE);
106 g_signal_connect(priv->back, "clicked",
107 G_CALLBACK(on_back_clicked), priv);
108
109 gtk_box_pack_start(GTK_BOX(hbox), priv->back, FALSE, FALSE, 0);
110
111 g_signal_connect(G_OBJECT(hbox), "destroy",
112 G_CALLBACK(bct_destroy_event), priv);
113
114 return hbox;
115 }
116
117 void bct_push_text(GtkWidget *bct, const gchar *text, gpointer id,
118 GDestroyNotify destroy) {
119 bct_priv_t *priv = g_object_get_data(G_OBJECT(bct), "priv");
120 g_return_if_fail (priv);
121
122 /* enable last crumb */
123 if(g_slist_length(priv->crumbs)) {
124 crumb_t *crumb = g_slist_last(priv->crumbs)->data;
125 gtk_widget_set_sensitive(crumb->button, TRUE);
126 gtk_widget_set_sensitive(priv->back, TRUE);
127
128 // GtkWidget *label = gtk_bin_get_child(GTK_BIN(crumb->button));
129 // gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_END);
130 }
131
132 /* create a new crumb */
133 crumb_t *crumb = g_new0(crumb_t, 1);
134
135 /* append a new crumb */
136 crumb->button = gtk_button_new_with_label(text);
137 crumb->destroy = destroy;
138 crumb->id = id;
139
140 gtk_box_pack_start(GTK_BOX(bct), crumb->button, FALSE, FALSE, 0);
141 gtk_widget_set_sensitive(crumb->button, FALSE);
142 gtk_widget_show(crumb->button);
143
144 g_signal_connect(crumb->button, "clicked",
145 G_CALLBACK(on_crumb_clicked), priv);
146
147 /* append to list of crumbs */
148 priv->crumbs = g_slist_append(priv->crumbs, crumb);
149
150 }