Contents of /trunk/src/bct.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 129 - (hide annotations)
Tue Sep 29 14:30:16 2009 UTC (14 years, 8 months ago) by harbaum
File MIME type: text/plain
File size: 4317 byte(s)
BCT cleanup
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 harbaum 129
72     GtkWidget *label = gtk_bin_get_child(GTK_BIN(crumb->button));
73     gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_NONE);
74 harbaum 128 }
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 harbaum 129
128     GtkWidget *label = gtk_bin_get_child(GTK_BIN(crumb->button));
129     gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_END);
130 harbaum 128 }
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     }