diff options
Diffstat (limited to 'tools/glade/glade/glade_palette.c')
-rw-r--r-- | tools/glade/glade/glade_palette.c | 544 |
1 files changed, 544 insertions, 0 deletions
diff --git a/tools/glade/glade/glade_palette.c b/tools/glade/glade/glade_palette.c new file mode 100644 index 00000000..a8c8b9e1 --- /dev/null +++ b/tools/glade/glade/glade_palette.c @@ -0,0 +1,544 @@ +/* Gtk+ User Interface Builder + * Copyright (C) 1998 Damon Chaplin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "gladeconfig.h" + +#include <string.h> + +#include <gtk/gtkhbox.h> +#include <gtk/gtkhseparator.h> +#include <gtk/gtklabel.h> +#include <gtk/gtknotebook.h> +#include <gtk/gtkpixmap.h> +#include <gtk/gtkradiobutton.h> +#include <gtk/gtktable.h> +#include <gtk/gtkvbox.h> +#include <gtk/gtksignal.h> + +#include "graphics/selector.xpm" +#include "glade_palette.h" +#include "glade.h" + +GtkWidget *glade_palette = NULL; + +#define GLADE_CLASS_ID_KEY "GladeClassID" + +static void glade_palette_class_init (GladePaletteClass * klass); +static void glade_palette_init (GladePalette * glade_palette); + +static GladePaletteSection *new_section (GladePalette * palette, + const gchar * section); +static void rebuild_page (gpointer key, + GladePaletteSection * page, + GladePalette * palette); +static void remove_button (gpointer button, + gpointer table); +static void add_button (GtkWidget * button, + GladePaletteSection * sect); +static void on_palette_button_toggled (GtkWidget * button, + GladePalette * palette); +static void on_section_button_clicked (GtkWidget * button, + GladePalette * palette); + +enum +{ + SELECT_ITEM, + UNSELECT_ITEM, + LAST_SIGNAL +}; + +static guint glade_palette_signals[LAST_SIGNAL] = {0}; + +static GtkWindowClass *parent_class = NULL; + + +GType +glade_palette_get_type (void) +{ + static GType palette_type = 0; + + if (!palette_type) + { + GtkTypeInfo palette_info = + { + "GladePalette", + sizeof (GladePalette), + sizeof (GladePaletteClass), + (GtkClassInitFunc) glade_palette_class_init, + (GtkObjectInitFunc) glade_palette_init, + /* reserved_1 */ NULL, + /* reserved_2 */ NULL, + (GtkClassInitFunc) NULL, + }; + + palette_type = gtk_type_unique (gtk_window_get_type (), &palette_info); + } + return palette_type; +} + + +static void +glade_palette_class_init (GladePaletteClass * klass) +{ + GtkObjectClass *object_class; + + object_class = (GtkObjectClass *) klass; + + parent_class = gtk_type_class (gtk_window_get_type ()); + + glade_palette_signals[SELECT_ITEM] = + gtk_signal_new ("select_item", + GTK_RUN_LAST, + GTK_CLASS_TYPE (object_class), + GTK_SIGNAL_OFFSET (GladePaletteClass, select_item), + gtk_marshal_VOID__STRING, + GTK_TYPE_NONE, 1, GTK_TYPE_STRING); + glade_palette_signals[UNSELECT_ITEM] = + gtk_signal_new ("unselect_item", + GTK_RUN_LAST, + GTK_CLASS_TYPE (object_class), + GTK_SIGNAL_OFFSET (GladePaletteClass, unselect_item), + gtk_marshal_VOID__STRING, + GTK_TYPE_NONE, 1, GTK_TYPE_STRING); + + klass->select_item = NULL; + klass->unselect_item = NULL; +} + + +/* Ensure the correct button is depressed when the page is switched with + keyboard accelerators. */ +static void +on_notebook_switch_page (GtkNotebook *notebook, GtkNotebookPage *page, + guint page_num, GladePalette *palette) +{ + GSList *elem; + gint last_page; + + last_page = g_list_length (notebook->children) - 1; + + for (elem = palette->section_button_group; elem; elem = elem->next) + { + GladePaletteSection *sect = gtk_object_get_data (GTK_OBJECT (elem->data), "section"); + + if ((sect->page == -1 && page_num == last_page) + || sect->page == page_num) + { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (elem->data), TRUE); + break; + } + } +} + + +static void +glade_palette_init (GladePalette * palette) +{ + GtkWidget *seperator, *hbox; + GdkPixmap *gdkpixmap; + GdkBitmap *gdkmask; + GtkWidget *pixmap; + GtkReliefStyle relief_style; + + palette->width = 4; + palette->selected_widget = NULL; + palette->hold_selected_widget = FALSE; + palette->sections = g_hash_table_new (g_str_hash, g_str_equal); + palette->tooltips = gtk_tooltips_new (); + + palette->vbox = gtk_vbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (palette), palette->vbox); + gtk_widget_show (palette->vbox); + + hbox = gtk_hbox_new (FALSE, 2); + gtk_box_pack_start (GTK_BOX (palette->vbox), hbox, FALSE, TRUE, 0); + gtk_widget_show (hbox); + + relief_style = GTK_RELIEF_NONE; + + palette->selector = gtk_radio_button_new (NULL); + gtk_button_set_relief (GTK_BUTTON (palette->selector), relief_style); + + gdkpixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, gtk_widget_get_colormap (GTK_WIDGET (palette)), &gdkmask, NULL, selector_xpm); + pixmap = gtk_pixmap_new (gdkpixmap, gdkmask); + gtk_container_add (GTK_CONTAINER (GLADE_PALETTE (palette)->selector), + pixmap); + gtk_widget_show (pixmap); + + palette->widget_button_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (palette->selector)); + gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (palette->selector), FALSE); + gtk_box_pack_start (GTK_BOX (hbox), palette->selector, FALSE, TRUE, 0); + gtk_signal_connect (GTK_OBJECT (palette->selector), "toggled", + (GtkSignalFunc) on_palette_button_toggled, palette); + gtk_widget_show (palette->selector); + /* Don't translate 'Selector' here, since it is not displayed, and we test + for it later. */ + gtk_object_set_data (GTK_OBJECT (palette->selector), GLADE_CLASS_ID_KEY, + "Selector"); + gtk_tooltips_set_tip (palette->tooltips, palette->selector, + _ ("Selector"), NULL); + + palette->selected_item_label = gtk_label_new (_ ("Selector")); + gtk_misc_set_alignment (GTK_MISC (palette->selected_item_label), 0, 0.5); + gtk_widget_show (palette->selected_item_label); + + gtk_widget_set_usize (palette->selected_item_label, 10, -1); + gtk_box_pack_start (GTK_BOX (hbox), palette->selected_item_label, + TRUE, TRUE, 0); + + seperator = gtk_hseparator_new (); + gtk_box_pack_start (GTK_BOX (palette->vbox), seperator, FALSE, TRUE, 3); + gtk_widget_show (seperator); + + palette->notebook = gtk_notebook_new (); + /* We use gtk_box_pack_end, so we can later add buttons for new categories + at the right place with gtk_box_pack_start */ + gtk_box_pack_end (GTK_BOX (palette->vbox), palette->notebook, + TRUE, TRUE, 0); + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (palette->notebook), FALSE); + gtk_notebook_set_show_border (GTK_NOTEBOOK (palette->notebook), FALSE); + gtk_widget_show (palette->notebook); + + gtk_signal_connect (GTK_OBJECT (palette->notebook), "switch_page", + GTK_SIGNAL_FUNC (on_notebook_switch_page), palette); + + seperator = gtk_hseparator_new (); + gtk_box_pack_end (GTK_BOX (palette->vbox), seperator, FALSE, TRUE, 3); + gtk_widget_show (seperator); +} + + +GtkWidget * +glade_palette_new () +{ + return GTK_WIDGET (gtk_type_new (glade_palette_get_type ())); +} + + +void +glade_palette_add_widget (GladePalette *palette, + const gchar *section, + const gchar *name, + GdkPixmap *gdkpixmap, + GdkBitmap *mask, + const gchar *tooltip) +{ + GladePaletteSection *sect; + GtkWidget *button; + GtkWidget *pixmap; + GtkReliefStyle relief_style; + + g_return_if_fail (palette != NULL); + g_return_if_fail (GLADE_IS_PALETTE (palette)); + g_return_if_fail (gdkpixmap != NULL); + + if (!(sect = g_hash_table_lookup (palette->sections, section))) + sect = new_section (palette, section); + + relief_style = GTK_RELIEF_NONE; + + button = gtk_radio_button_new (palette->widget_button_group); + gtk_button_set_relief (GTK_BUTTON (button), relief_style); + gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE); + palette->widget_button_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)); + + pixmap = gtk_pixmap_new (gdkpixmap, mask); + gtk_container_add (GTK_CONTAINER (button), pixmap); + gtk_widget_show (pixmap); + + gtk_widget_show (button); + gtk_object_set_data (GTK_OBJECT (button), GLADE_CLASS_ID_KEY, + (gpointer) name); + gtk_signal_connect (GTK_OBJECT (button), "toggled", + (GtkSignalFunc) on_palette_button_toggled, palette); + + gtk_tooltips_set_tip (palette->tooltips, button, tooltip, NULL); + + sect->buttons = g_list_append (sect->buttons, button); + g_hash_table_insert (sect->buttonhash, (gpointer) name, button); + /* so we can use the same code as from rebuild_page */ + gtk_widget_ref (button); + add_button (button, sect); +} + + +void +glade_palette_remove_widget (GladePalette * palette, + const gchar * section, + const gchar * name) +{ + GladePaletteSection *sect; + GtkWidget *button; + + sect = g_hash_table_lookup (palette->sections, section); + g_return_if_fail (sect != NULL); + button = GTK_WIDGET (g_hash_table_lookup (sect->buttonhash, name)); + g_return_if_fail (button != NULL); + g_hash_table_remove (sect->buttonhash, name); + sect->buttons = g_list_remove (sect->buttons, button); + gtk_container_remove (GTK_CONTAINER (sect->table), button); + rebuild_page ((gpointer)section, sect, palette); +} + + +void +glade_palette_set_width (GladePalette * palette, guint columns) +{ + palette->width = columns; + g_hash_table_foreach (palette->sections, (GHFunc) rebuild_page, palette); +} + + +static GladePaletteSection * +new_section (GladePalette * palette, + const gchar * section) +{ + GladePaletteSection *sect; + GtkWidget *button; + gboolean deprecated_page = FALSE; + + if (!strcmp (section, _("Dep_recated"))) + deprecated_page = TRUE; + + sect = g_new (GladePaletteSection, 1); + sect->x = sect->y = 0; + sect->table = gtk_table_new (1, palette->width, TRUE); + gtk_widget_show (sect->table); + sect->buttons = NULL; + sect->buttonhash = g_hash_table_new (g_str_hash, g_str_equal); + + sect->section_button = button = gtk_radio_button_new_with_mnemonic (palette->section_button_group, section); + gtk_widget_set_name (button, section); + gtk_widget_set_usize (button, 20, -1); + gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE); + palette->section_button_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)); + gtk_widget_show (button); + gtk_object_set_data (GTK_OBJECT (button), "section", sect); + gtk_signal_connect (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (on_section_button_clicked), palette); + g_hash_table_insert (palette->sections, (gpointer) section, sect); + + /* Place the deprecated section last. */ + if (deprecated_page) + { + sect->page = -1; + gtk_notebook_append_page (GTK_NOTEBOOK (palette->notebook), sect->table, + NULL); + gtk_box_pack_end (GTK_BOX (palette->vbox), button, FALSE, TRUE, 0); + } + else + { + sect->page = palette->next_page_to_add++; + gtk_notebook_insert_page (GTK_NOTEBOOK (palette->notebook), sect->table, + NULL, sect->page); + gtk_box_pack_start (GTK_BOX (palette->vbox), button, FALSE, TRUE, 0); + } + + return sect; +} + +static void +rebuild_page (gpointer key, + GladePaletteSection * sect, + GladePalette * palette) +{ + g_list_foreach (g_list_first (sect->buttons), remove_button, sect->table); + sect->x = 0; + sect->y = 0; + gtk_table_resize (GTK_TABLE (sect->table), 1, palette->width); + g_list_foreach (g_list_first (sect->buttons), (GFunc) add_button, sect); +} + +static void +remove_button (gpointer button, + gpointer table) +{ + g_return_if_fail (button != NULL); + g_return_if_fail (table != NULL); + g_return_if_fail (GTK_IS_CONTAINER (table)); + g_return_if_fail (GTK_IS_WIDGET (button)); + gtk_widget_ref (GTK_WIDGET (button)); + gtk_container_remove (GTK_CONTAINER (table), GTK_WIDGET (button)); +} + +static void +add_button (GtkWidget * button, + GladePaletteSection * sect) +{ + GladePalette *palette; + + /* notebook vbox palette */ + palette = GLADE_PALETTE (GTK_WIDGET (sect->table)->parent->parent->parent); + if (sect->x >= palette->width) + { + /* new row */ + sect->x = 0; + sect->y++; + } + gtk_table_attach (GTK_TABLE (sect->table), button, sect->x, sect->x + 1, + sect->y, sect->y + 1, 0, 0, 0, 0); + gtk_widget_unref (button); + sect->x++; +} + + +static void +on_palette_button_toggled (GtkWidget * button, + GladePalette * palette) +{ + GdkModifierType modifiers; + + if ((GTK_TOGGLE_BUTTON (button)->active)) + { + if (button == palette->selector) + { + palette->selected_widget = NULL; + gtk_label_set_text (GTK_LABEL (palette->selected_item_label), + _("Selector")); + palette->hold_selected_widget = FALSE; + } + else + { + palette->selected_widget = gtk_object_get_data (GTK_OBJECT (button), + GLADE_CLASS_ID_KEY); + gtk_label_set_text (GTK_LABEL (palette->selected_item_label), + palette->selected_widget); + gdk_window_get_pointer (button->window, NULL, NULL, &modifiers); + palette->hold_selected_widget = (modifiers & GDK_CONTROL_MASK) + ? TRUE : FALSE; + } + gtk_signal_emit (GTK_OBJECT (palette), + glade_palette_signals[SELECT_ITEM], + palette->selected_widget); + } + else + { + gtk_signal_emit (GTK_OBJECT (palette), + glade_palette_signals[UNSELECT_ITEM], + palette->selected_widget); + } +} + + +static void +on_section_button_clicked (GtkWidget * button, + GladePalette * palette) +{ + GladePaletteSection *sect; + + sect = (GladePaletteSection*) gtk_object_get_data (GTK_OBJECT (button), + "section"); + gtk_notebook_set_current_page (GTK_NOTEBOOK (palette->notebook), sect->page); +} + + +/* Resets the palette so that the selector is selected, unless the existing + item was selected while holding the Ctrl key. */ +void +glade_palette_reset_selection (GladePalette *palette, + gboolean allow_hold) +{ + if (!palette->hold_selected_widget || !allow_hold) + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (palette->selector), TRUE); +} + + +/* Returns TRUE if the selector is currently selected. */ +gboolean +glade_palette_is_selector_on (GladePalette *palette) +{ + return (palette->selected_widget == NULL) ? TRUE : FALSE; +} + + +/* Returns the class name of the currently selected widget. */ +gchar * +glade_palette_get_widget_class (GladePalette *palette) +{ + return palette->selected_widget; +} + + +static void +glade_palette_set_show_section (GladePalette *palette, + GladePaletteSection *sect, + gboolean show) +{ + if (show) + gtk_widget_show (sect->section_button); + else + gtk_widget_hide (sect->section_button); +} + + +static void +set_button_visibility (GladePaletteSection *sect, + const gchar *name, + gboolean show) +{ + GtkWidget *button = g_hash_table_lookup (sect->buttonhash, name); + if (button) + { + if (show) + gtk_widget_show (button); + else + gtk_widget_hide (button); + } +} + + +/* Shows or hides the GNOME widgets. */ +void +glade_palette_set_show_gnome_widgets (GladePalette *palette, + gboolean show_gnome, + gboolean show_gnome_db) +{ + GladePaletteSection *sect; + + /* Show the main page, and make the selector active. */ + gtk_notebook_set_current_page (GTK_NOTEBOOK (palette->notebook), 0); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (palette->selector), TRUE); + + /* Show or hide the Gnome page if it exists. */ + sect = g_hash_table_lookup (palette->sections, "_Gnome"); + if (sect) + glade_palette_set_show_section (palette, sect, show_gnome); + + /* Show or hide the GnomeDB page if it exists. */ + sect = g_hash_table_lookup (palette->sections, "Gnome _DB"); + if (sect) + glade_palette_set_show_section (palette, sect, show_gnome_db); + + /* Show or hide the GNOME widgets on the Deprecated page if they exist. */ + sect = g_hash_table_lookup (palette->sections, "Dep_recated"); + if (sect) + { + set_button_visibility (sect, "GnomeDialog", show_gnome); + set_button_visibility (sect, "GnomeMessageBox", show_gnome); + set_button_visibility (sect, "GnomePropertyBox", show_gnome); + set_button_visibility (sect, "GnomePixmap", show_gnome); + set_button_visibility (sect, "GnomeColorPicker", show_gnome); + set_button_visibility (sect, "GnomeFontPicker", show_gnome); + set_button_visibility (sect, "GnomeAbout", show_gnome); + set_button_visibility (sect, "GnomeIconList", show_gnome); + set_button_visibility (sect, "GnomeEntry", show_gnome); + set_button_visibility (sect, "GnomeFileEntry", show_gnome); + set_button_visibility (sect, "GnomePixmapEntry", show_gnome); + } +} + |