Menu Widget, ItemFactory, and Popup Menu Widgets

only for RuBoard - do not distribute or recompile

Menu Widget, ItemFactory, and Popup Menu Widgets

Finally, I will cover the Menu widgets. In any part of a finished application, a menu at the top of the main application window is something users have come to expect, but somehow it also manages to be one of the things that gets left behind in the rush to deliver the application. Figure 3.8 shows the program compiled from Listing 3.5, which provides the menu options available in GTK+.

Figure 3.8. The Menu widgets demo.
graphics/03fig08.gif
Listing 3.5 Demo of the Menu Widgets: Menu, ItemFactory, and Popup Menu Widgets
 #include <gtk/gtk.h>  GtkWidget *frm_menus;  GtkWidget *frm_item_factory;  GtkWidget *frm_popup;  GtkWidget *popup_menu;  void destroy_main();  void cmd_manual_menu_clicked();  void cmd_item_factory_clicked();  void item_factory_clicked();  void cmd_popup_clicked();  void popup_mnu_1_clicked();  void popup_mnu_2_clicked();  void popup_mnu_3_clicked();  void text_right_click_event();  gint main(gint argc, gchar *argv[])  {    GtkWidget *vbox_main;     GtkWidget *cmd_manual_menu;     GtkWidget *cmd_item_factory;     GtkWidget *cmd_popup;     gtk_init(&argc, &argv);     frm_menus = gtk_window_new(GTK_WINDOW_TOPLEVEL);     gtk_window_set_title(GTK_WINDOW(frm_menus), "Menus Demo");     gtk_signal_connect(GTK_OBJECT(frm_menus),          "destroy",          GTK_SIGNAL_FUNC(destroy_main),          NULL);     vbox_main = gtk_vbox_new(TRUE, 2);     cmd_manual_menu = gtk_button_new_with_label("Manual Menus Demo");     gtk_signal_connect(GTK_OBJECT(cmd_manual_menu),        "clicked",        GTK_SIGNAL_FUNC(cmd_manual_menu_clicked),        NULL);     cmd_item_factory = gtk_button_new_with_label("Item Factory Demo");     gtk_signal_connect(GTK_OBJECT(cmd_item_factory),        "clicked",        GTK_SIGNAL_FUNC(cmd_item_factory_clicked),        NULL);     cmd_popup = gtk_button_new_with_label("Popup Demo");     gtk_signal_connect(GTK_OBJECT(cmd_popup),        "clicked",        GTK_SIGNAL_FUNC(cmd_popup_clicked),        NULL);     gtk_box_pack_start(GTK_BOX(vbox_main), cmd_manual_menu, TRUE, TRUE, 0);     gtk_box_pack_start(GTK_BOX(vbox_main), cmd_item_factory, TRUE, TRUE, 0);     gtk_box_pack_start(GTK_BOX(vbox_main), cmd_popup, TRUE, TRUE, 0);     gtk_container_add(GTK_CONTAINER(frm_menus), vbox_main);     gtk_widget_show_all (frm_menus);     gtk_main ();     return 0;  }  void destroy_main()  {   gtk_main_quit(); }  /* ============= Creating a Menu the Hard Way =============== */  void cmd_manual_menu_clicked()  {    GtkWidget *frm_manual;     GtkWidget *vbox_manual;     GtkWidget *menu_bar_manual;     GtkWidget *menu_file, *menu_edit, *menu_widgets;     GtkWidget *menu_item_tearoff1, *menu_item_separator1;     GtkWidget *menu_item_file, *menu_item_open,               *menu_item_exit, *menu_item_widgets;     GtkWidget *menu_item_edit, *menu_item_cut, *menu_item_copy, *menu_item_paste;     GtkWidget *hbox_cut;     GtkWidget *icon_scissors;     GdkPixmap *xpm_scissors;     GdkBitmap *bmp;     GtkWidget *lbl_cut, *lbl_ctrl_X;     GtkAccelGroup *hot_keys;     GtkWidget *menu_item_check, *chk_box_demo;     GtkWidget *menu_item_cmd, *cmd_button_demo;     GtkWidget *menu_item_check2;     GtkWidget *text_manual;     frm_manual = gtk_window_new(GTK_WINDOW_TOPLEVEL);     gtk_window_set_title(GTK_WINDOW(frm_manual), "Manual Menu Demo");     vbox_manual = gtk_vbox_new(FALSE, 0);       menu_bar_manual = gtk_menu_bar_new();     menu_file = gtk_menu_new();     menu_edit = gtk_menu_new();     menu_widgets = gtk_menu_new();  /* File Menu */  menu_item_file = gtk_menu_item_new_with_label("File");     menu_item_tearoff1 = gtk_tearoff_menu_item_new();     menu_item_open = gtk_menu_item_new_with_label("Open");     menu_item_separator1 = gtk_menu_item_new();     menu_item_exit = gtk_menu_item_new_with_label("Exit - Not!");  /* Edit Menu */  menu_item_edit = gtk_menu_item_new_with_label("Edit");     menu_item_copy = gtk_menu_item_new_with_label("Copy");     menu_item_cut = gtk_menu_item_new();     hbox_cut = gtk_hbox_new(FALSE, 0);     gtk_container_add(GTK_CONTAINER(menu_item_cut), hbox_cut);     xpm_scissors = gdk_pixmap_colormap_create_from_xpm(NULL,                         gdk_colormap_get_system(),                         &bmp,                         NULL,                         "/usr/share/icons/mini/mini.cut.xpm");     icon_scissors = gtk_pixmap_new(xpm_scissors, bmp);     gdk_pixmap_unref(xpm_scissors);     gtk_box_pack_start_defaults(GTK_BOX(hbox_cut), icon_scissors);     lbl_cut = gtk_label_new("Cut");     lbl_ctrl_X = gtk_label_new("Ctl+X");     gtk_label_set_justify(GTK_LABEL(lbl_ctrl_X), GTK_JUSTIFY_RIGHT);     gtk_box_pack_start(GTK_BOX(hbox_cut), lbl_cut, TRUE, FALSE, 0);     gtk_box_pack_start(GTK_BOX(hbox_cut), lbl_ctrl_X, FALSE, FALSE, 3);     menu_item_paste = gtk_menu_item_new_with_label("Paste");  /* As shown above, creating a menu item with an associated icon   * is relatively straightforward. Because the menu item widget   * is a descendant from GtkBin (which can hold only one child   * widget), you have to put a horizontal packing box widget into   * the menu item. Then put the pixmap on the left and   * a label widget on the right.   *   * See   Listing 2.2   for an example of how to place the pixmap   * within the same program that uses itspecifically, the   * list widget demo.   *   * If you are running this and an icon isn't showing,   * it may be because the icon used above is not   * on your system (the final parameter of the   *  gdk_pixmap_colormap_create_from_xpm()  call).   *   * Either you can edit the line to use a pixmap on your system,   * or you can copy a pixmap to the same directory as this program,   * and then just put in the nameleaving off the path information.   */  hot_keys = gtk_accel_group_new();     gtk_accel_group_attach(hot_keys, GTK_OBJECT(frm_manual));     gtk_widget_add_accelerator(menu_item_copy,                                "activate",                                hot_keys,                                'C',                                GDK_CONTROL_MASK,                                GTK_ACCEL_VISIBLE);     gtk_widget_add_accelerator(menu_item_cut,                                "activate",                                hot_keys,                                'X',                                GDK_CONTROL_MASK,                                GTK_ACCEL_VISIBLE);     gtk_widget_add_accelerator(menu_item_paste,                                "activate",                                hot_keys,                                'V',                                GDK_CONTROL_MASK,                                GTK_ACCEL_VISIBLE);  /* Widgets Menu */  menu_item_widgets = gtk_menu_item_new_with_label("Widgets");  /* Because the menu item widget is a descendant of GtkBin, as   * demonstrated above, you can (theoretically) put   * any widget into a menu item.   */  menu_item_check = gtk_menu_item_new();     chk_box_demo = gtk_check_button_new_with_label("Check me");     gtk_container_add(GTK_CONTAINER(menu_item_check), chk_box_demo);  /* Check boxes in menus are pretty standard for showing the   * on/off setting of an attribute or such. But try   * something a little different   */  menu_item_cmd = gtk_menu_item_new();     cmd_button_demo = gtk_button_new_with_label("Push me");     gtk_container_add(GTK_CONTAINER(menu_item_cmd), cmd_button_demo);  /* Because putting a check box into a menu is so common,   * there is a widget specifically for that purpose.   * The primary difference between this one and the previous   * check button is that  *_check_menu_item_*  will not   * show the box part of the check box when the item is not checked.   */  menu_item_check2 = gtk_check_menu_item_new_with_label ("Check2");  /* Put it all together. */  gtk_menu_bar_append(GTK_MENU_BAR(menu_bar_manual), menu_item_file);     gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item_file), menu_file);     gtk_menu_append(GTK_MENU(menu_file), menu_item_tearoff1);     gtk_menu_append(GTK_MENU(menu_file), menu_item_open);     gtk_menu_append(GTK_MENU(menu_file), menu_item_separator1);     gtk_menu_append(GTK_MENU(menu_file), menu_item_exit);     gtk_menu_bar_append(GTK_MENU_BAR(menu_bar_manual), menu_item_edit);     gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item_edit), menu_edit);     gtk_menu_append(GTK_MENU(menu_edit), menu_item_cut);     gtk_menu_append(GTK_MENU(menu_edit), menu_item_copy);     gtk_menu_append(GTK_MENU(menu_edit), menu_item_paste);     gtk_menu_bar_append(GTK_MENU_BAR(menu_bar_manual), menu_item_widgets);     gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item_widgets), menu_widgets);     gtk_menu_append(GTK_MENU(menu_widgets), menu_item_check);     gtk_menu_append(GTK_MENU(menu_widgets), menu_item_cmd);     gtk_menu_append(GTK_MENU(menu_widgets), menu_item_check2);     text_manual = gtk_text_new(NULL, NULL);     gtk_box_pack_start(GTK_BOX(vbox_manual), menu_bar_manual, FALSE, FALSE, 0);     gtk_box_pack_start(GTK_BOX(vbox_manual), text_manual, TRUE, TRUE, 0);     gtk_container_add(GTK_CONTAINER(frm_manual), vbox_manual);     gtk_widget_show_all(frm_manual);  }  /* ============= Creating a Menu the Easy Way =============== */   /* The following are notes regarding the  GtkItemFactoryEntry  structure:   *   * First, the parameters that are passed as strings are, of   * course, case sensitive.  "<separators>"  will cause an   * errorbut at run time instead of compile time.   * The same is true of  checkitem  or  Checkitem  instead of  CheckItem.  *   * Second, when using underscores for names, it would probably   * be best to avoid them for things like separators. However,   * you could use  sep_1  in the following instead of  sep1  . In   * that case, you should avoid it because in this context, the   * underscore has a meaning other than to separate words   * for readability: It identifies accelerator characters   * as well.   */  static GtkItemFactoryEntry items[] = {    {"/_File", NULL, 0, 0, "<Branch>"},     {"/File/tear1", NULL, NULL, 0, "<Tearoff>"},     {"/File/_Open", "<control>O", item_factory_clicked, 0},     {"/File/sep1", NULL, NULL, 0, "<Separator>"},     {"/File/_Exit", "<alt>E", item_factory_clicked, 0},     {"/_Help", NULL, 0, 0, "<LastBranch>"},     {"/Help/_CheckBox", NULL, NULL, 0, "<CheckItem>"},     {"/Help/_About", "<shift>A", item_factory_clicked, 0}  };  /* As you might expect, there are tradeoffs to using an item   * factory. With an Item Factory, you can't add images, the front slash   * character '/', or other fancy widgets. Basically, you're limited   * to a very standard text-based menu.   */  void cmd_item_factory_clicked()  {    GtkWidget *vbox_item_factory;     GtkWidget *text_item_factory;     GtkItemFactory *menu_item_factory;     GtkWidget *menu_bar_item_factory;     GtkAccelGroup *accel_group_item_factory;     frm_item_factory = gtk_window_new(GTK_WINDOW_TOPLEVEL);     gtk_window_set_title(GTK_WINDOW(frm_item_factory), "Item Factory Menu Demo");     vbox_item_factory = gtk_vbox_new(FALSE, 0);     accel_group_item_factory = gtk_accel_group_new();     gtk_accel_group_attach(accel_group_item_factory,                            GTK_OBJECT(frm_item_factory));  /* Technically, an accelerator group is not absolutely necessary,   * but without it, the underlined characters that should work with   * ALT, such as ALT+F for "File", would not be active.   */   /* Hardware Note:   * Be sure to try both ALT keys on your machine to test the   * accelerators. On my laptop, only the left ALT key works to   * bring up a menu. This is a limitation of the machine on   * which I am running Linux, not of GTK+.   */  menu_item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR,                                              "<no_path>",                                              accel_group_item_factory);     gtk_item_factory_create_items(menu_item_factory,                                   sizeof(items)/sizeof(items[0]),                                   items,                                   NULL);     menu_bar_item_factory = gtk_item_factory_get_widget(menu_item_factory,                                                         "<no_path>");     text_item_factory = gtk_text_new(NULL, NULL);     gtk_box_pack_start(GTK_BOX(vbox_item_factory), menu_bar_item_factory,                        TRUE, TRUE, 0);     gtk_box_pack_start(GTK_BOX(vbox_item_factory), text_item_factory,                        TRUE, TRUE, 0);     gtk_container_add(GTK_CONTAINER(frm_item_factory), vbox_item_factory);     gtk_widget_show_all(frm_item_factory);  }  /* As you can see, considerably less code is required with this   * method than when you create the menu bar by hand.   */  void item_factory_clicked()  {    g_print("Item factory clicked...\n");  }  /* ============= Popup Menu on Right Click ==================== */  void cmd_popup_clicked()  {    GtkWidget *vbox_popup;     GtkWidget *lbl_right_click;     GtkWidget *text_right_click;     GtkWidget *mnu_1, *mnu_2, *mnu_3;     frm_popup = gtk_window_new(GTK_WINDOW_TOPLEVEL);     gtk_window_set_title(GTK_WINDOW(frm_popup), "Popup Menu Demo");     vbox_popup = gtk_vbox_new(TRUE, 0);     lbl_right_click = gtk_label_new("Popup Demo\nRight Click\nIn The Text Box  Below");     text_right_click = gtk_text_new(NULL, NULL);  /* Catch events that happen for the text box. The following   * signal handler will catch all events; in the function,   * it can be narrowed down to the desired events.   */  gtk_signal_connect(GTK_OBJECT(text_right_click),                        "event",                        GTK_SIGNAL_FUNC(text_right_click_event),                        popup_menu);  /* Now build the popup menu; it is very simple, with   * three very non-descriptive choices.   */  popup_menu = gtk_menu_new();     mnu_1 = gtk_menu_item_new_with_label("Choice 1");     mnu_2 = gtk_menu_item_new_with_label("Choice 2");     mnu_3 = gtk_menu_item_new_with_label("Choice 3");     gtk_signal_connect(GTK_OBJECT(mnu_1),                        "activate",                        GTK_SIGNAL_FUNC(popup_mnu_1_clicked),                        NULL);     gtk_signal_connect(GTK_OBJECT(mnu_2),                        "activate",                        GTK_SIGNAL_FUNC(popup_mnu_2_clicked),                        NULL);     gtk_signal_connect(GTK_OBJECT(mnu_3),                        "activate",                        GTK_SIGNAL_FUNC(popup_mnu_3_clicked),                        NULL);     gtk_box_pack_start(GTK_BOX(vbox_popup), lbl_right_click, TRUE, TRUE, 0);     gtk_box_pack_start(GTK_BOX(vbox_popup), text_right_click, TRUE, TRUE, 0);     gtk_container_add(GTK_CONTAINER(frm_popup), vbox_popup);  /* Add the menu items to the menu. */  gtk_menu_append(GTK_MENU(popup_menu), mnu_1);     gtk_menu_append(GTK_MENU(popup_menu), mnu_2);     gtk_menu_append(GTK_MENU(popup_menu), mnu_3);     gtk_widget_show_all(frm_popup);  }  void popup_mnu_1_clicked()  {    g_print("popup menu item 1 clicked...\n");  }    void popup_mnu_2_clicked()  {    g_print("popup menu item 2 clicked...\n");  }  void popup_mnu_3_clicked()  {    g_print("popup menu item 3 clicked...\n");  }  void text_right_click_event(GtkWidget *Widget, GdkEvent *event)  {  /* g_print("inside text box event...\n"); */  if (event->type == GDK_BUTTON_PRESS)       {         GdkEventButton *buttonevent = (GdkEventButton *) event;  /* g_print("inside button press event...\n"); */  if (buttonevent->button == 3)             {  /* g_print("inside right click event...\n"); */  gtk_widget_show_all(popup_menu);                gtk_menu_popup(GTK_MENU(popup_menu),                               NULL, NULL, NULL, NULL,                               buttonevent->button,                               0);             }       }  } 
only for RuBoard - do not distribute or recompile


MySQL Building User Interfaces
MySQL: Building User Interfaces (Landmark)
ISBN: 073571049X
EAN: 2147483647
Year: 2001
Pages: 119

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net