Parent Directory
|
Revision Log
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 | } |