1 /*
2 * palettes.c
3 *
4 * Copyright 2013 Richard Shann <rshann@virgin.net>
5 *
6 * This program 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 * This program 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 this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 * MA 02110-1301, USA.
20 */
21 #include "ui/palettes.h"
22 #include "core/view.h"
23 #include "core/utils.h"
24 #include "ui/texteditors.h"
25 #include <librsvg/rsvg.h>
26
27
28 #if GTK_MAJOR_VERSION==2
29 #define gtk_grid_new() (pal->rows?gtk_hbox_new (FALSE, 1):gtk_vbox_new (FALSE, 1))
30 #define gtk_grid_attach(widget, obj, a,b,c,d) gtk_box_pack_start(widget, obj, FALSE, TRUE, 0)
31 #define GTK_GRID(a) a
32 #endif
hide_palette_widget(GtkWidget * w)33 static void hide_palette_widget (GtkWidget *w) {
34 GtkWidget *parent = gtk_widget_get_parent (w);
35 if(GTK_IS_WINDOW(parent))
36 gtk_widget_hide (parent);
37 else
38 gtk_widget_hide (w);
39 }
hide_docked_palettes(void)40 static void hide_docked_palettes (void) {
41 GList *g;
42 for (g=Denemo.palettes;g;g=g->next)
43 {
44 DenemoPalette *pal = g->data;
45 if(pal->docked)
46 hide_palette_widget (pal->box);
47 }
48 }
49
hide_all_palettes(void)50 static void hide_all_palettes (void) {
51 GList *g;
52 for (g=Denemo.palettes;g;g=g->next)
53 {
54 DenemoPalette *pal = g->data;
55 hide_palette_widget (pal->box);
56 }
57 }
58
destroy_all_palettes(void)59 static void destroy_all_palettes (void) {
60 if(confirm(_("Destroy All Palettes"), _("Get rid of all palettes permanently?")))
61 {
62 hide_all_palettes();
63 Denemo.palettes = NULL;//on exit an empty palettes.xml will be written
64 }
65 }
66
popupmenu(GtkWidget * menu)67 static void popupmenu (GtkWidget *menu) {
68 g_signal_connect (menu, "selection-done", gtk_main_quit, NULL);
69 gtk_widget_show_all (menu);
70 gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time ());
71 gtk_main ();
72 }
73
repack_palette(DenemoPalette * pal)74 void repack_palette (DenemoPalette *pal)
75 {
76 gint i;
77 GList *g;
78 GtkWidget *parent = gtk_widget_get_parent(pal->box);
79 for(g=pal->buttons;g;g=g->next)
80 {
81 if(gtk_widget_get_parent(g->data))
82 gtk_container_remove(GTK_CONTAINER(pal->box), g->data);
83 }
84 gtk_widget_destroy (pal->box);
85 pal->box = gtk_grid_new();
86 gchar *tooltip = g_strdup_printf("The \"%s\" Palette:\n%s", pal->name, _("To edit this palette, dock/undock, hide etc, right click on a button and choose Edit Palette."));
87 gtk_widget_set_tooltip_text (pal->box, tooltip);
88 g_free(tooltip);
89 for (i=0, g=pal->buttons;g;i++, g=g->next)
90 {
91 if(pal->rows)
92 gtk_grid_attach (GTK_GRID(pal->box), g->data, i/pal->limit, i%pal->limit, 1, 1);
93 else
94 gtk_grid_attach (GTK_GRID(pal->box), g->data, i%pal->limit, i/pal->limit, 1, 1);
95 gtk_widget_show (GTK_WIDGET(g->data));
96 }
97 gtk_container_add (GTK_CONTAINER (parent), pal->box);
98 if(pal->docked)
99 {
100 gtk_widget_hide (pal->window);
101 pal->rows? gtk_widget_reparent (pal->box, Denemo.vpalettes):gtk_widget_reparent (pal->box, Denemo.hpalettes);
102 }
103 else
104 {
105 gtk_window_resize (GTK_WINDOW(pal->window), 1, 1);
106 gtk_widget_show (pal->window);
107 gtk_widget_set_can_focus (pal->window, FALSE);
108 switch_back_to_main_window ();
109 }
110 gtk_widget_show(pal->box);
111
112 }
113
114
toggle_rows(DenemoPalette * pal)115 static void toggle_rows (DenemoPalette *pal) {
116 pal->rows = !pal->rows;
117 repack_palette (pal);
118 }
toggle_dock(DenemoPalette * pal)119 static void toggle_dock (DenemoPalette *pal) {
120 if(pal->docked)
121 gtk_widget_reparent (pal->box, pal->window), gtk_window_set_keep_above (GTK_WINDOW (pal->window), TRUE);
122 else
123 pal->rows? gtk_widget_reparent (pal->box, Denemo.vpalettes):gtk_widget_reparent (pal->box, Denemo.hpalettes);
124 pal->docked = !pal->docked;
125 pal->docked?
126 gtk_widget_hide (pal->window):
127 gtk_widget_show (pal->window);
128 }
set_limit(DenemoPalette * pal)129 static void set_limit (DenemoPalette *pal) {
130 gchar *initial = g_strdup_printf("%d", pal->limit);
131 gchar *response = string_dialog_entry (Denemo.project, "Palette Layout", _("Give Limit"), initial);
132 g_free(initial);
133 if(response && atoi(response))
134 {
135 pal->limit = atoi(response);
136 repack_palette (pal);
137 } else g_warning("Cancelled %s", response);
138 }
139
140
get_palette_menu(DenemoPalette * pal)141 static GtkWidget *get_palette_menu(DenemoPalette *pal) {
142 GtkWidget *menu = gtk_menu_new ();
143 GtkWidget *item = gtk_menu_item_new_with_label (_("Hide"));
144 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
145 g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (hide_palette_widget), (gpointer) pal->box);
146 if(!pal->rows)
147 {
148 item = gtk_menu_item_new_with_label (_("Make Horizontal"));
149 gtk_widget_set_tooltip_text (item, _("Arrange the buttons extending horizontally"));
150 //gtk_widget_add_events (item, GDK_ENTER_NOTIFY_MASK);
151 //g_signal_connect (item, "enter-notify-event", show_tooltip, _("Arrange the buttons extending horizontally"));
152
153
154
155 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
156 g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (toggle_rows), (gpointer) pal);
157 } else
158 {
159 item = gtk_menu_item_new_with_label (_("Make Vertical"));
160 gtk_widget_set_tooltip_text (item, _("Arrange the buttons extending vertically"));
161 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
162 g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (toggle_rows), (gpointer) pal);
163 }
164
165 {
166 item = gtk_menu_item_new_with_label (pal->rows?_("Vertical Limit"): _("Horizontal Limit"));
167 gtk_widget_set_tooltip_text (item, pal->rows? _("Set maximum extent vertically") : _("Set maximum extent horizontally") );
168 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
169 g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (set_limit), (gpointer) pal);
170 }
171 {
172 item = gtk_menu_item_new_with_label ( pal->docked?_("Undock"):_("Dock"));
173 gtk_widget_set_tooltip_text (item, pal->docked?_("Dock this palette in the main display"):_("Undock this palette from the main display") );
174 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
175 g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (toggle_dock), (gpointer) pal);
176 }
177 if (pal->docked) {
178 item = gtk_menu_item_new_with_label ( _("Hide All Docked"));
179 gtk_widget_set_tooltip_text (item, _("Hide all the docked palettes"));
180 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
181 g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (hide_docked_palettes), (gpointer) pal);
182 }
183 {
184 item = gtk_menu_item_new_with_label ( _("Hide All Palettes"));
185 gtk_widget_set_tooltip_text (item, _("Hide all the palettes"));
186 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
187 g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (hide_all_palettes), (gpointer) pal);
188 }
189 {
190 item = gtk_menu_item_new_with_label ( _("Destroy All Palettes"));
191 gtk_widget_set_tooltip_text (item, _("Destroy all the palettes - this will save time at startup, and shorten the palette menu."));
192 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
193 g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (destroy_all_palettes), (gpointer) pal);
194 }
195 return menu;
196 }
197
get_script_for_button(GtkWidget * button)198 static void get_script_for_button (GtkWidget *button) {
199 gchar *script = g_object_get_data (G_OBJECT(button), "script");
200 appendSchemeText (script);
201 gboolean sensitive = gtk_widget_get_visible (gtk_widget_get_toplevel (Denemo.script_view));
202 if(!sensitive) activate_action ("/MainMenu/ViewMenu/ToggleScript");
203 }
204
put_script_for_button(GtkWidget * button)205 static void put_script_for_button (GtkWidget *button) {
206 gchar *text = g_strdup_printf(_("Overwrite script for button \"%s\"?"), gtk_button_get_label(GTK_BUTTON(button)));
207 if(confirm (_("Re-write Script"), text))
208 {
209 gchar *script = get_script_view_text ();
210 gchar *oldscript = (gchar*) g_object_get_data (G_OBJECT(button), "script");
211 g_object_set_data (G_OBJECT(button), "script", script);
212 g_signal_handlers_block_by_func(G_OBJECT(button), G_CALLBACK (call_out_to_guile), oldscript);
213 g_free(oldscript);
214 g_signal_connect_swapped ( G_OBJECT (button), "clicked", G_CALLBACK (call_out_to_guile), script);
215 }
216 else
217 infodialog (_("Cancelled"));
218 g_free(text);
219 }
220
set_image_for_button(GtkWidget * button,gchar * name)221 static void set_image_for_button (GtkWidget *button, gchar *name)
222 {
223 gchar *icon = find_denemo_file (DENEMO_DIR_PIXMAPS, name);
224 GtkWidget *child_widget = gtk_bin_get_child(GTK_BIN(button));
225 if(GTK_IS_LABEL(child_widget)) {
226 gtk_button_set_label (GTK_BUTTON(button), "");
227 //g_debug("destroy %p, \n", child_widget);
228 child_widget = gtk_bin_get_child(GTK_BIN(button));
229 //g_debug("or rather destroy %p, is %d \n", child_widget, GTK_IS_WIDGET(child_widget));
230 gtk_widget_destroy (child_widget);
231 }
232 GdkPixbuf *pb = //gdk_pixbuf_new_from_file(icon, NULL); Works on GNU/Linux but not windows - pixbuf loader not working...
233 rsvg_pixbuf_from_file (icon, NULL);
234 if(pb)
235 gtk_button_set_image(GTK_BUTTON(button),gtk_image_new_from_pixbuf(pb));
236 else
237 gtk_button_set_label (GTK_BUTTON(button), name);
238 //gtk_button_set_always_show_image (button, TRUE);
239 g_object_set_data (G_OBJECT(button), "icon", (gpointer)g_strdup(name));
240 g_type_class_unref (g_type_class_ref (GTK_TYPE_BUTTON));
241 g_object_set (gtk_settings_get_default (), "gtk-button-images", TRUE, NULL);
242 gtk_widget_show_all(button);
243 g_free (icon);
244 }
245
edit_label_for_button(GtkWidget * button)246 static void edit_label_for_button (GtkWidget *button) {
247 const gchar *label;
248 label = g_object_get_data (G_OBJECT(button), "icon");
249 if(label==NULL)
250 label = gtk_button_get_label (GTK_BUTTON(button));
251 gchar *newlabel = string_dialog_entry (Denemo.project, _("Write Label"), _("Write a label for this button"), (gchar*)label);
252
253 if(newlabel && *newlabel) {
254 gchar *icon = find_denemo_file (DENEMO_DIR_PIXMAPS, newlabel);
255 if(icon) {
256 set_image_for_button (button, newlabel);
257 g_free (icon);
258 }
259 else
260 {
261 gtk_button_set_label (GTK_BUTTON(button), newlabel); //setting the label changes the widget: this works around a bizarre bug, if you just set the markup on the label the button has two labels
262 GtkWidget *label_widget = gtk_bin_get_child(GTK_BIN(button));
263 gtk_label_set_use_markup (GTK_LABEL(label_widget), TRUE);
264 gtk_label_set_markup (GTK_LABEL (label_widget), newlabel);
265 }
266 }
267 g_free(newlabel);
268
269 }
edit_tooltip_for_button(GtkWidget * button)270 static void edit_tooltip_for_button (GtkWidget *button) {
271 const gchar *tooltip = gtk_widget_get_tooltip_text (button);
272 gchar *newtooltip = string_dialog_entry (Denemo.project, _("Write Tooltip"), _("Write a tooltip for this button"), (gchar*)tooltip);
273 if(newtooltip) {
274 gtk_widget_set_tooltip_text (button, newtooltip);
275 }
276 g_free(newtooltip);
277 }
help_for_button(GtkWidget * button)278 static void help_for_button (GtkWidget *button) {
279 gchar *tooltip = gtk_widget_get_tooltip_text (button);
280 if (tooltip)
281 infodialog (tooltip);
282 }
remove_button(GtkWidget * button)283 static void remove_button (GtkWidget *button) {
284 DenemoPalette *pal = g_object_get_data (G_OBJECT(button), "palette");
285 palette_delete_button (pal, button);
286
287 }
288
move_button_to_start(GtkWidget * button)289 static void move_button_to_start (GtkWidget *button) {
290 DenemoPalette *pal = g_object_get_data (G_OBJECT(button), "palette");
291 pal->buttons = g_list_remove (pal->buttons, button);
292 pal->buttons = g_list_prepend (pal->buttons, button);
293 repack_palette (pal);
294 }
move_button_to_end(GtkWidget * button)295 static void move_button_to_end (GtkWidget *button) {
296 DenemoPalette *pal = g_object_get_data (G_OBJECT(button), "palette");
297 pal->buttons = g_list_remove (pal->buttons, button);
298 pal->buttons = g_list_append (pal->buttons, button);
299 repack_palette (pal);
300 }
copy_button(GtkWidget * button)301 static void copy_button (GtkWidget *button) {
302 gchar *tooltip = gtk_widget_get_tooltip_text (button);
303 gchar *label = (gchar*)gtk_button_get_label (GTK_BUTTON(button));
304 gchar *script = g_object_get_data (G_OBJECT(button), "script");
305 gchar *name = get_palette_name (TRUE);
306 if(name)
307 {
308 DenemoPalette *pal = get_palette (name);
309 if(pal==NULL)
310 pal = create_palette (name, FALSE, TRUE);
311 palette_add_button (pal, label, tooltip, script);
312 }
313 }
duplicate_button(GtkWidget * button)314 static void duplicate_button (GtkWidget *button) {
315 DenemoPalette *pal = g_object_get_data (G_OBJECT(button), "palette");
316 gchar *tooltip = gtk_widget_get_tooltip_text (button);
317 gchar *label = _("Duplicate Button");
318 gchar *script = g_object_get_data (G_OBJECT(button), "script");
319 palette_add_button (pal, label, tooltip, script);
320 }
popup_button_menu(DenemoPalette * pal,GtkWidget * button)321 static void popup_button_menu(DenemoPalette *pal, GtkWidget *button) {
322 GtkWidget *menu = gtk_menu_new ();
323 GtkWidget *item;
324 gboolean sensitive = gtk_widget_get_visible (gtk_widget_get_toplevel (Denemo.script_view));//some menu items should be insensitive if the Scheme window is not visible
325 item = gtk_menu_item_new_with_label (_("Help"));
326 gtk_widget_set_tooltip_text (item, _("Show the help for this button"));
327 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
328 g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (help_for_button), (gpointer) button);
329
330 item = gtk_menu_item_new_with_label (_("Edit Label"));
331 gtk_widget_set_tooltip_text (item, _("Edit the label of this button"));
332 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
333 g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (edit_label_for_button), (gpointer) button);
334
335 item = gtk_menu_item_new_with_label (_("Edit Tooltip"));
336 gtk_widget_set_tooltip_text (item, _("Edit the tooltip of this button"));
337 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
338 g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (edit_tooltip_for_button), (gpointer) button);
339
340
341
342 item = gtk_menu_item_new_with_label (_("Copy to another Palette"));
343 gtk_widget_set_tooltip_text (item, _("Copy this button to another palette"));
344 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
345 g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (copy_button), (gpointer) button);
346
347 item = gtk_menu_item_new_with_label (_("Duplicate this button"));
348 gtk_widget_set_tooltip_text (item, _("Create a new button with the same effect"));
349 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
350 g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (duplicate_button), (gpointer) button);
351
352 item = gtk_menu_item_new_with_label (_("Remove from Palette"));
353 gtk_widget_set_tooltip_text (item, _("Remove this button from this palette"));
354 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
355 g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (remove_button), (gpointer) button);
356
357 item = gtk_menu_item_new_with_label (_("Get Script into Scheme Window"));
358 gtk_widget_set_tooltip_text (item, _("Places the script that this button executes into the Scheme window"));
359 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
360 g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (get_script_for_button), (gpointer) button);
361
362 item = gtk_menu_item_new_with_label (_("Save Script from Scheme Window"));
363 gtk_widget_set_tooltip_text (item, _("Uses the script in the Scheme Window as the one that this button executes when clicked"));
364 gtk_widget_set_sensitive (item, sensitive);
365 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
366 g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (put_script_for_button), (gpointer) button);
367
368 item = gtk_menu_item_new_with_label (_("Move to Start"));
369 gtk_widget_set_tooltip_text (item, _("Moves this button to the start of the palette"));
370 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
371 g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (move_button_to_start), (gpointer) button);
372
373 item = gtk_menu_item_new_with_label (_("Move to End"));
374 gtk_widget_set_tooltip_text (item, _("Moves this button to the end of the palette"));
375 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
376 g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (move_button_to_end), (gpointer) button);
377
378 item = gtk_menu_item_new_with_label (_("Edit this Palette"));
379 gtk_widget_set_tooltip_text (item, _("Edits the palette containing this button"));
380 gtk_menu_item_set_submenu (GTK_MENU_ITEM(item), (gpointer)get_palette_menu(pal));
381 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
382
383
384
385 g_signal_connect (menu, "selection-done", gtk_main_quit, NULL);
386 gtk_widget_show_all (menu);
387 gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time ());
388 gtk_main ();
389 }
new_palette(gchar * name,gboolean by_row)390 static DenemoPalette *new_palette (gchar *name, gboolean by_row)
391 {
392 DenemoPalette *pal = g_malloc0(sizeof (DenemoPalette));
393 pal->name = g_strdup(_(name));
394 pal->limit = 1;
395 pal->rows = by_row;
396 pal->box = gtk_grid_new();
397 Denemo.palettes = g_list_append(Denemo.palettes, (gpointer)pal);
398 return pal;
399 }
400
get_palette(gchar * name)401 DenemoPalette *get_palette (gchar *name)
402 {
403 GList *g;
404 for( g = Denemo.palettes; g; g = g->next)
405 {
406 DenemoPalette *pal = (DenemoPalette*)g->data;
407 if (!strcmp(name, pal->name))
408 return pal;
409 }
410 return NULL;
411 }
412
button_pressed(GtkWidget * button,GdkEventButton * event,DenemoPalette * pal)413 static gboolean button_pressed (GtkWidget *button, GdkEventButton *event, DenemoPalette *pal)
414 {
415 Denemo.currentpalette = pal;
416 if (event->button == 1)
417 return FALSE;
418 popup_button_menu(pal, button);
419 return TRUE;
420 }
already_present(DenemoPalette * pal,gchar * label)421 static gboolean already_present (DenemoPalette *pal, gchar *label) {
422 GList *g;
423 for(g=pal->buttons;g;g=g->next) {
424 gchar *icon = g_object_get_data (G_OBJECT(g->data), "icon");
425 if (!strcmp(label, gtk_button_get_label (GTK_BUTTON(g->data))) || (icon && !strcmp(icon, label)))
426 return TRUE;
427 }
428 return FALSE;
429 }
430
fixup_image(GtkWidget * button,gchar * label)431 static void fixup_image (GtkWidget *button, gchar *label) {
432 //g_debug("Fixing up image");
433 set_image_for_button (button, label);
434 }
palette_add_button(DenemoPalette * pal,gchar * label,const gchar * tooltip,gchar * script)435 gboolean palette_add_button (DenemoPalette *pal, gchar *label, const gchar *tooltip, gchar *script)
436 {
437 if (already_present(pal, label))
438 return FALSE;
439 gchar *thescript = g_strdup(script);
440 GtkWidget *button = gtk_button_new_with_label (label);
441 gchar *icon = find_denemo_file (DENEMO_DIR_PIXMAPS, label);
442 if(icon)
443 {
444 g_signal_connect (button, "realize", G_CALLBACK (fixup_image), label);
445 } else
446 {
447 GtkWidget *label_widget = gtk_bin_get_child(GTK_BIN(button));//g_debug("is %s\n", g_type_name(G_TYPE_FROM_INSTANCE(label_widget)));
448 gtk_label_set_use_markup (GTK_LABEL(label_widget), TRUE);
449 }
450 //put button in a list pal->buttons and then call repack_palette.
451 //REF it for repacking
452 g_object_ref (button);
453 pal->buttons = g_list_append(pal->buttons, (gpointer)button);
454 repack_palette (pal);
455
456 gtk_widget_set_tooltip_text (button, _(tooltip));
457 g_object_set_data (G_OBJECT(button), "script", thescript);
458 g_object_set_data (G_OBJECT(button), "palette", pal);
459 g_signal_connect_swapped ( G_OBJECT (button), "clicked", G_CALLBACK (call_out_to_guile), thescript);
460 g_signal_connect_after ( G_OBJECT (button), "clicked", G_CALLBACK (switch_back_to_main_window), NULL);
461 g_signal_connect (G_OBJECT (button), "button-press-event", G_CALLBACK (button_pressed), (gpointer)pal);
462 Denemo.currentpalette = pal;
463
464 return TRUE;
465 }
466
palette_delete_button(DenemoPalette * pal,GtkWidget * button)467 void palette_delete_button (DenemoPalette *pal, GtkWidget *button)
468 {
469 g_free( g_object_get_data (G_OBJECT(button), "script"));
470 pal->buttons = g_list_remove (pal->buttons, button);
471 gtk_widget_destroy(button);
472 }
473
palette_action_button(DenemoPalette * pal,gchar * label)474 gboolean palette_action_button (DenemoPalette *pal, gchar *label)
475 {
476 gboolean ret = FALSE;
477 GList *g;
478 for (g=pal->buttons;g;g=g->next)
479 {
480 GtkWidget *button = g->data;
481 const gchar *this = gtk_button_get_label (GTK_BUTTON(button));
482 if (*this=='<')
483 {
484 while (*this && *this != '>')
485 this++;
486 if(*this) this++;
487 }
488 // g_print ("this %s and %s %d\n", this, label, g_str_has_prefix (this, label));
489 if(*this && g_str_has_prefix (this, label))
490 {
491 ret = gtk_widget_activate (button);
492 break;
493 }
494 }
495 Denemo.currentpalette = pal;
496 return ret;
497 }
create_palette(gchar * name,gboolean docked,gboolean rows)498 DenemoPalette *create_palette (gchar *name, gboolean docked, gboolean rows) {
499 DenemoPalette *pal = get_palette (name);
500
501 if(pal==NULL)
502 {
503 pal = new_palette (name, TRUE);
504 pal->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
505 gtk_window_set_title (GTK_WINDOW (pal->window), pal->name);
506 if(!docked)
507 {
508 gtk_window_set_default_size (GTK_WINDOW (pal->window), 200, 100);//try and get folk to notice it!
509 gtk_window_present (GTK_WINDOW (pal->window));
510 gtk_window_set_transient_for (GTK_WINDOW(pal->window), GTK_WINDOW(Denemo.window));
511 gtk_window_set_keep_above (GTK_WINDOW (pal->window), TRUE);
512 }
513
514 g_signal_connect (G_OBJECT (pal->window), "delete-event", G_CALLBACK (gtk_widget_hide_on_delete), NULL);
515 pal->rows = rows;
516 if(docked)
517 {
518 pal->docked = TRUE;
519 pal->rows?
520 gtk_box_pack_start (GTK_BOX(Denemo.vpalettes), pal->box, FALSE, TRUE, 0):
521 gtk_box_pack_start (GTK_BOX(Denemo.hpalettes), pal->box, FALSE, TRUE, 0);
522 }
523 else
524 {
525 gtk_widget_show (pal->window);
526 gtk_container_add (GTK_CONTAINER (pal->window), pal->box);
527 }
528 }
529 Denemo.currentpalette = pal;
530 return pal;
531 }
532
set_palate_shape(gchar * name,gboolean row_wise,gint limit)533 DenemoPalette *set_palate_shape (gchar *name, gboolean row_wise, gint limit)
534 {
535 DenemoPalette *pal = create_palette (name, FALSE, row_wise);
536 if (limit>0) {
537 pal->limit = limit;
538 pal->rows = row_wise;
539 repack_palette (pal);
540 //gtk_window_resize (GTK_WINDOW (window), 1, 1);
541 Denemo.currentpalette = pal;
542 return pal;
543 }
544 return NULL;
545 }
546
delete_palette(DenemoPalette * pal)547 void delete_palette (DenemoPalette *pal) {
548 GList *g;
549 for(g=pal->buttons;g;g=g->next)
550 palette_delete_button (pal, GTK_WIDGET(g->data));
551 gtk_widget_destroy (gtk_widget_get_parent (pal->box));//FIXME if docked this will not be a toplevel
552 Denemo.palettes = g_list_remove (Denemo.palettes, pal);
553 Denemo.currentpalette = NULL;
554 }
555
556 static gchar *selected_palette_name = NULL;
palette_selected(gchar * name)557 static void palette_selected (gchar *name)
558 {
559 selected_palette_name = name;
560 }
user_palette_name(void)561 static void user_palette_name (void)
562 {
563 gchar *name;
564 name = string_dialog_entry (Denemo.project, _("Palette Name"), _("Give name for Palette: "), _("MyPalette"));
565 selected_palette_name = name;
566 }
567
568
choose_palette_by_name(gboolean allow_custom,gboolean non_showing)569 gchar *choose_palette_by_name (gboolean allow_custom, gboolean non_showing)
570 {
571
572 GtkWidget *menu = gtk_menu_new ();
573 GtkWidget *item;
574 GList *g;
575 selected_palette_name = NULL;
576 if(Denemo.palettes) {
577 if(allow_custom) {
578 item = gtk_menu_item_new_with_label (_("Create Custom Palette"));
579 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
580 }
581 //g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (user_palette_name), NULL);
582 for (g=Denemo.palettes;g;g=g->next)
583 {
584 DenemoPalette *pal = (DenemoPalette *)g->data;
585 if(non_showing && pal->docked && gtk_widget_get_visible (pal->box))
586 continue;//g_debug("palette %s is %d\n", pal->name, gtk_widget_get_visible (pal->box));//continue;
587 if(non_showing && (!pal->docked) && gtk_widget_get_visible (gtk_widget_get_parent(pal->box)))
588 continue;
589 item = gtk_menu_item_new_with_label (pal->name);
590 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
591 g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (palette_selected), (gpointer) pal->name);
592 }
593
594 popupmenu (menu);
595 }
596 if(allow_custom && (selected_palette_name==NULL))
597 {
598 user_palette_name ();
599 }
600 return selected_palette_name;
601 }
602
get_palette_name(gboolean allow_custom)603 gchar *get_palette_name (gboolean allow_custom)
604 {
605 return choose_palette_by_name (allow_custom, FALSE);
606 }
607
place_action_in_palette(gint idx,const gchar * name)608 void place_action_in_palette (gint idx, const gchar *name)
609 {
610 gchar *label = (gchar *) lookup_label_from_idx (Denemo.map, idx);
611 if(name==NULL)
612 name = lookup_name_from_idx (Denemo.map, idx);
613 gchar *script = g_strdup_printf ("(d-%s)", name);
614 const gchar *tooltip = lookup_tooltip_from_idx (Denemo.map, idx);
615 gchar *palette_name = get_palette_name (TRUE);g_print("palette name %s\n", palette_name);
616 if(palette_name) {
617 DenemoPalette *pal = get_palette (palette_name);
618 if(pal==NULL)
619 {
620 pal = set_palate_shape (palette_name, TRUE, 1);
621 }
622 if(pal)
623 palette_add_button (pal, label, tooltip, script);
624 }
625 g_free (script);
626
627 }
628
629
630
631