17 |
* along with GPXView. If not, see <http://www.gnu.org/licenses/>. |
* 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" |
#include "gpxview.h" |
26 |
|
|
27 |
GtkWidget *my_bct_new(void) { |
typedef struct { |
28 |
GtkWidget *label = gtk_label_new("BCT"); |
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 |
|
|
|
return label; |
|
144 |
} |
} |