Contents of /trunk/src/bct.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 211 - (hide annotations)
Wed Nov 25 10:13:26 2009 UTC (14 years, 6 months ago) by harbaum
File MIME type: text/plain
File size: 4216 byte(s)
GeoToad UI interaction
1 harbaum 127 /*
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 harbaum 128 /*
21     * This simple breadcrumbtrail replacement is a simple hbox with
22     * buttons inside
23     */
24    
25 harbaum 127 #include "gpxview.h"
26    
27 harbaum 128 typedef struct {
28     GtkWidget *button;
29     GDestroyNotify destroy;
30     gpointer id;
31     } crumb_t;
32 harbaum 127
33 harbaum 128 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 harbaum 127 }
42 harbaum 128
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 harbaum 211
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     }