Contents of /trunk/src/iconbar.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 207 - (show annotations)
Fri Jul 10 12:13:34 2009 UTC (14 years, 11 months ago) by harbaum
File MIME type: text/plain
File size: 11847 byte(s)
Project consistency fix
1 /*
2 * Copyright (C) 2008 Till Harbaum <till@harbaum.org>.
3 *
4 * This file is part of OSM2Go.
5 *
6 * OSM2Go 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 * OSM2Go 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 OSM2Go. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "appdata.h"
21
22 #ifdef FINGER_UI
23 #define TOOL_ICON(a) a "_thumb"
24 #define MENU_ICON(a) a "_thumb"
25 #else
26 #define TOOL_ICON(a) a
27 #define MENU_ICON(a) a
28 #endif
29
30 static void on_info_clicked(GtkButton *button, gpointer data) {
31 appdata_t *appdata = (appdata_t*)data;
32
33 info_dialog(GTK_WIDGET(appdata->window), appdata, NULL);
34 }
35
36 static void on_node_add_clicked(GtkButton *button, gpointer data) {
37 map_action_set((appdata_t*)data, MAP_ACTION_NODE_ADD);
38 }
39
40 static void on_way_add_clicked(GtkButton *button, gpointer data) {
41 map_action_set((appdata_t*)data, MAP_ACTION_WAY_ADD);
42 }
43
44 static void on_way_node_add_clicked(GtkButton *button, gpointer data) {
45 map_action_set((appdata_t*)data, MAP_ACTION_WAY_NODE_ADD);
46 }
47
48 static void on_way_reverse_clicked(GtkButton *button, gpointer data) {
49 map_edit_way_reverse((appdata_t*)data);
50 }
51
52 static void on_way_cut_clicked(GtkButton *button, gpointer data) {
53 map_action_set((appdata_t*)data, MAP_ACTION_WAY_CUT);
54 }
55
56 #ifdef FINGER_UI
57 static GtkWidget *menu_add(GtkWidget *menu, appdata_t *appdata,
58 char *icon_str, char *menu_str,
59 void(*func)(GtkButton*, gpointer)) {
60
61 GtkWidget *item = gtk_image_menu_item_new_with_label(menu_str);
62
63 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item),
64 icon_widget_load(&appdata->icon, icon_str));
65
66 if(func)
67 gtk_signal_connect(GTK_OBJECT(item), "activate",
68 (GtkSignalFunc)func, appdata);
69
70 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
71
72 return item;
73 }
74
75 static gint on_way_button_press(GtkWidget *button, GdkEventButton *event,
76 gpointer data) {
77 appdata_t *appdata = (appdata_t*)data;
78
79 if(event->type == GDK_BUTTON_PRESS) {
80 // map_action_set((appdata_t*)data, MAP_ACTION_WAY_ADD);
81 printf("way clicked\n");
82
83 /* draw a popup menu */
84 gtk_menu_popup(GTK_MENU(appdata->iconbar->menu), NULL, NULL, NULL, NULL,
85 event->button, event->time);
86 return TRUE;
87 }
88 return FALSE;
89 }
90
91 static GtkWidget *popup_menu_create(appdata_t *appdata) {
92 GtkWidget *menu = gtk_menu_new();
93
94 appdata->iconbar->way_add =
95 menu_add(menu, appdata, MENU_ICON("way_add"),
96 _("Add new way"), on_way_add_clicked);
97 appdata->iconbar->way_node_add =
98 menu_add(menu, appdata, MENU_ICON("way_node_add"),
99 _("Add new node to way"), on_way_node_add_clicked);
100 appdata->iconbar->way_cut =
101 menu_add(menu, appdata, MENU_ICON("way_cut"),
102 _("Split way"), on_way_cut_clicked);
103 appdata->iconbar->way_reverse =
104 menu_add(menu, appdata, MENU_ICON("way_reverse"),
105 _("Reverse way"), on_way_reverse_clicked);
106
107 gtk_widget_show_all(menu);
108
109 return menu;
110 }
111 #endif
112
113 #ifdef MAIN_GUI_RELATION
114 static void on_relation_add_clicked(GtkButton *button, gpointer data) {
115 appdata_t *appdata = (appdata_t*)data;
116
117 g_assert((appdata->map->selected.object.type == NODE) ||
118 (appdata->map->selected.object.type == WAY));
119
120 relation_add_dialog(GTK_WIDGET(appdata->window), appdata,
121 &appdata->map->selected.object);
122 }
123 #endif
124
125 static void on_trash_clicked(GtkButton *button, gpointer data) {
126 map_delete_selected((appdata_t*)data);
127 }
128
129 static void on_ok_clicked(GtkButton *button, gpointer data) {
130 printf("User ok\n");
131 map_action_ok((appdata_t*)data);
132 }
133
134 static void on_cancel_clicked(GtkButton *button, gpointer data) {
135 printf("User cancel\n");
136 map_action_cancel((appdata_t*)data);
137 }
138
139 /* enable/disable ok and cancel button */
140 void icon_bar_map_cancel_ok(appdata_t *appdata,
141 gboolean cancel, gboolean ok) {
142 iconbar_t *iconbar = appdata->iconbar;
143 gtk_widget_set_sensitive(iconbar->ok, ok);
144 gtk_widget_set_sensitive(iconbar->cancel, cancel);
145 }
146
147 void icon_bar_map_item_selected(appdata_t *appdata,
148 map_item_t *map_item, gboolean selected) {
149 iconbar_t *iconbar = appdata->iconbar;
150
151 /* one can't remove relations by clicking this while they are */
152 /* selected. May change in the future */
153 if(selected && (!map_item || map_item->object.type != RELATION))
154 gtk_widget_set_sensitive(iconbar->trash, TRUE);
155 else
156 gtk_widget_set_sensitive(iconbar->trash, FALSE);
157
158 gtk_widget_set_sensitive(iconbar->info, map_item && selected);
159
160 #ifdef MAIN_GUI_RELATION
161 gtk_widget_set_sensitive(iconbar->relation_add, map_item && selected);
162 #endif
163
164 if(selected && map_item && map_item->object.type == WAY) {
165 gtk_widget_set_sensitive(iconbar->way_node_add, TRUE);
166 gtk_widget_set_sensitive(iconbar->way_cut, TRUE);
167 gtk_widget_set_sensitive(iconbar->way_reverse, TRUE);
168 } else {
169 gtk_widget_set_sensitive(iconbar->way_node_add, FALSE);
170 gtk_widget_set_sensitive(iconbar->way_cut, FALSE);
171 gtk_widget_set_sensitive(iconbar->way_reverse, FALSE);
172 }
173 }
174
175 /* if a user action is on progress, then disable all buttons that */
176 /* cause an action to take place or interfere with the action */
177 void icon_bar_map_action_idle(appdata_t *appdata, gboolean idle) {
178 gint i;
179
180 /* icons that are enabled in idle mode */
181 GtkWidget *action_idle_widgets[] = {
182 appdata->iconbar->node_add,
183 appdata->iconbar->way_add,
184 NULL
185 };
186
187 /* icons that are disabled in idle mode */
188 GtkWidget *action_disable_widgets[] = {
189 appdata->iconbar->trash,
190 appdata->iconbar->info,
191 #ifdef MAIN_GUI_RELATION
192 appdata->iconbar->relation_add,
193 #endif
194 NULL
195 };
196
197 for(i=0;action_idle_widgets[i];i++)
198 gtk_widget_set_sensitive(action_idle_widgets[i], idle);
199
200 for(i=0;action_disable_widgets[i];i++)
201 gtk_widget_set_sensitive(action_disable_widgets[i], FALSE);
202
203 /* special handling for icons that depend on further state */
204 if(!idle) {
205 gtk_widget_set_sensitive(appdata->iconbar->way_node_add, FALSE);
206 gtk_widget_set_sensitive(appdata->iconbar->way_cut, FALSE);
207 gtk_widget_set_sensitive(appdata->iconbar->way_reverse, FALSE);
208 } else {
209 if(appdata->map->selected.object.type == WAY) {
210 gtk_widget_set_sensitive(appdata->iconbar->way_node_add, TRUE);
211 gtk_widget_set_sensitive(appdata->iconbar->way_cut, TRUE);
212 gtk_widget_set_sensitive(appdata->iconbar->way_reverse, TRUE);
213 } else {
214 gtk_widget_set_sensitive(appdata->iconbar->way_node_add, FALSE);
215 gtk_widget_set_sensitive(appdata->iconbar->way_cut, FALSE);
216 gtk_widget_set_sensitive(appdata->iconbar->way_reverse, FALSE);
217 }
218 }
219 }
220
221 GtkWidget *icon_add(GtkWidget *vbox, appdata_t *appdata,
222 char *icon_str,
223 void(*func)(GtkButton*, gpointer)) {
224 GtkWidget *but = gtk_button_new();
225 GtkWidget *icon = gtk_image_new_from_pixbuf(
226 icon_load(&appdata->icon, icon_str));
227 gtk_button_set_image(GTK_BUTTON(but), icon);
228 gtk_signal_connect(GTK_OBJECT(but), "clicked",
229 (GtkSignalFunc)func, appdata);
230
231 gtk_box_pack_start(GTK_BOX(vbox), but, FALSE, FALSE, 0);
232 return but;
233 }
234
235 static GtkWidget *tool_add(GtkWidget *toolbar, appdata_t *appdata,
236 char *icon_str,
237 char *tooltip_str,
238 void(*func)(GtkButton*, gpointer)) {
239 GtkWidget *item =
240 GTK_WIDGET(gtk_tool_button_new(
241 icon_widget_load(&appdata->icon, icon_str), NULL));
242
243 #ifndef USE_HILDON
244 gtk_widget_set_tooltip_text(item, tooltip_str);
245 #endif
246
247 if(func)
248 gtk_signal_connect(GTK_OBJECT(item), "clicked",
249 (GtkSignalFunc)func, appdata);
250
251 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), GTK_TOOL_ITEM(item), -1);
252
253 return item;
254 }
255
256 GtkWidget *iconbar_new(appdata_t *appdata) {
257 appdata->iconbar = g_new0(iconbar_t, 1);
258 iconbar_t *iconbar = appdata->iconbar;
259
260 iconbar->toolbar = gtk_toolbar_new();
261
262 #ifndef PORTRAIT
263 GtkWidget *box = gtk_vbox_new(FALSE, 0);
264 gtk_toolbar_set_orientation(GTK_TOOLBAR(iconbar->toolbar),
265 GTK_ORIENTATION_VERTICAL);
266 #else
267 GtkWidget *box = gtk_hbox_new(FALSE, 0);
268 #endif
269
270 gtk_toolbar_set_style(GTK_TOOLBAR(iconbar->toolbar), GTK_TOOLBAR_ICONS);
271
272 /* -------------------------------------------------------- */
273 iconbar->trash = tool_add(iconbar->toolbar, appdata,
274 TOOL_ICON("trash"), _("Delete item"), on_trash_clicked);
275
276 #ifndef FINGER_UI
277 /* -------------------------------------------------------- */
278 gtk_toolbar_insert(GTK_TOOLBAR(iconbar->toolbar),
279 gtk_separator_tool_item_new(),-1);
280 #endif
281
282 iconbar->info = tool_add(iconbar->toolbar, appdata,
283 TOOL_ICON("info"), _("Properties"), on_info_clicked);
284
285 /* -------------------------------------------------------- */
286 gtk_toolbar_insert(GTK_TOOLBAR(iconbar->toolbar),
287 gtk_separator_tool_item_new(),-1);
288
289 iconbar->node_add = tool_add(iconbar->toolbar, appdata,
290 TOOL_ICON("node_add"), _("Add node"), on_node_add_clicked);
291
292 /* -------------------------------------------------------- */
293 gtk_toolbar_insert(GTK_TOOLBAR(iconbar->toolbar),
294 gtk_separator_tool_item_new(),-1);
295
296 #ifdef FINGER_UI
297 iconbar->menu = popup_menu_create(appdata);
298
299 /* the way button is special as it pops up a menu for */
300 /* further too selection */
301 GtkWidget *way =
302 GTK_WIDGET(gtk_tool_button_new(
303 icon_widget_load(&appdata->icon, TOOL_ICON("way")), NULL));
304
305 gtk_widget_set_tooltip_text(way, "Way");
306
307 gtk_toolbar_insert(GTK_TOOLBAR(iconbar->toolbar), GTK_TOOL_ITEM(way), -1);
308
309 gtk_widget_set_size_request(GTK_WIDGET(way), -1, 40);
310
311 gtk_widget_set_events(way, GDK_EXPOSURE_MASK);
312 gtk_widget_add_events(way, GDK_BUTTON_PRESS_MASK);
313 gtk_signal_connect(GTK_OBJECT(gtk_bin_get_child(GTK_BIN(way))),
314 "button-press-event",
315 (GtkSignalFunc)on_way_button_press, appdata);
316
317 #else
318 iconbar->way_add = tool_add(iconbar->toolbar, appdata,
319 TOOL_ICON("way_add"), _("Add way"), on_way_add_clicked);
320 iconbar->way_node_add = tool_add(iconbar->toolbar, appdata,
321 TOOL_ICON("way_node_add"), _("Add a node to a way"),
322 on_way_node_add_clicked);
323 iconbar->way_cut = tool_add(iconbar->toolbar, appdata,
324 TOOL_ICON("way_cut"), _("Split a way"), on_way_cut_clicked);
325 iconbar->way_reverse = tool_add(iconbar->toolbar, appdata,
326 TOOL_ICON("way_reverse"), _("Reverse way"), on_way_reverse_clicked);
327 #endif
328
329 #ifdef MAIN_GUI_RELATION
330 #ifndef FINGER_UI
331 /* -------------------------------------------------------- */
332 gtk_toolbar_insert(GTK_TOOLBAR(iconbar->toolbar),
333 gtk_separator_tool_item_new(),-1);
334 #endif
335
336 iconbar->relation_add = tool_add(iconbar->toolbar, appdata,
337 TOOL_ICON("relation_add"), _("Edit item's relations"),
338 on_relation_add_clicked);
339 #endif
340
341 gtk_box_pack_start(GTK_BOX(box), iconbar->toolbar, TRUE, TRUE, 0);
342
343 /* -------------------------------------------------------- */
344
345 GtkWidget *hbox = gtk_hbox_new(FALSE, 0);
346
347 #if defined(USE_HILDON) && !defined(FINGER_UI)
348 /* make buttons smaller for non-finger maemo */
349 gtk_widget_set_size_request(GTK_WIDGET(hbox), -1, 32);
350 #endif
351
352 iconbar->ok = icon_add(hbox, appdata, TOOL_ICON("ok"), on_ok_clicked);
353 iconbar->cancel = icon_add(hbox, appdata, TOOL_ICON("cancel"), on_cancel_clicked);
354 gtk_box_pack_end(GTK_BOX(box), hbox, FALSE, FALSE, 0);
355
356 /* --------------------------------------------------------- */
357
358 icon_bar_map_item_selected(appdata, NULL, FALSE);
359 icon_bar_map_cancel_ok(appdata, FALSE, FALSE);
360
361 return box;
362 }
363
364 void iconbar_free(iconbar_t *iconbar) {
365 if(iconbar)
366 g_free(iconbar);
367 }