Contents of /trunk/src/bct.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 211 - (show annotations)
Wed Nov 25 10:13:26 2009 UTC (14 years, 5 months ago) by harbaum
File MIME type: text/plain
File size: 4216 byte(s)
GeoToad UI interaction
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
73 /* disable back button if crumb trail has 1 item or less */
74 if(g_slist_length(priv->crumbs) <= 1)
75 gtk_widget_set_sensitive(priv->back, FALSE);
76 }
77
78 static void on_back_clicked(GtkButton *button, bct_priv_t *priv) {
79 crumb_destroy(priv, g_slist_last(priv->crumbs)->data);
80 bct_update(priv);
81 }
82
83 static void on_crumb_clicked(GtkButton *button, bct_priv_t *priv) {
84 /* clear crumb trail until we reach the button that was clicked */
85 crumb_t *crumb = g_slist_last(priv->crumbs)->data;
86 while(crumb->button != (GtkWidget*)button) {
87 crumb_destroy(priv, crumb);
88 crumb = g_slist_last(priv->crumbs)->data;
89 }
90 bct_update(priv);
91 }
92
93 GtkWidget *bct_new(void) {
94 bct_priv_t *priv = g_new0(bct_priv_t, 1);
95
96 GtkWidget *hbox = gtk_hbox_new(FALSE, 0);
97 g_object_set_data(G_OBJECT(hbox), "priv", priv);
98
99 priv->back = gtk_button_new();
100 gtk_button_set_image(GTK_BUTTON(priv->back),
101 gtk_image_new_from_stock(GTK_STOCK_GO_BACK, GTK_ICON_SIZE_BUTTON));
102 gtk_widget_set_sensitive(priv->back, FALSE);
103 g_signal_connect(priv->back, "clicked",
104 G_CALLBACK(on_back_clicked), priv);
105
106 gtk_box_pack_start(GTK_BOX(hbox), priv->back, FALSE, FALSE, 0);
107
108 g_signal_connect(G_OBJECT(hbox), "destroy",
109 G_CALLBACK(bct_destroy_event), priv);
110
111 return hbox;
112 }
113
114 void bct_push_text(GtkWidget *bct, const gchar *text, gpointer id,
115 GDestroyNotify destroy) {
116 bct_priv_t *priv = g_object_get_data(G_OBJECT(bct), "priv");
117 g_return_if_fail (priv);
118
119 /* enable last crumb */
120 if(g_slist_length(priv->crumbs)) {
121 crumb_t *crumb = g_slist_last(priv->crumbs)->data;
122 gtk_widget_set_sensitive(crumb->button, TRUE);
123 gtk_widget_set_sensitive(priv->back, TRUE);
124 }
125
126 /* create a new crumb */
127 crumb_t *crumb = g_new0(crumb_t, 1);
128
129 /* append a new crumb */
130 crumb->button = gtk_button_new_with_label(text);
131 crumb->destroy = destroy;
132 crumb->id = id;
133
134 gtk_box_pack_start(GTK_BOX(bct), crumb->button, FALSE, FALSE, 0);
135 gtk_widget_set_sensitive(crumb->button, FALSE);
136 gtk_widget_show(crumb->button);
137
138 g_signal_connect(crumb->button, "clicked",
139 G_CALLBACK(on_crumb_clicked), priv);
140
141 /* append to list of crumbs */
142 priv->crumbs = g_slist_append(priv->crumbs, crumb);
143
144 }
145
146 void bct_pop(GtkWidget *bct) {
147 bct_priv_t *priv = g_object_get_data(G_OBJECT(bct), "priv");
148 g_assert(priv);
149 crumb_destroy(priv, g_slist_last(priv->crumbs)->data);
150 }