Page 1 of 1

Linux : Working With GTK+ Menus - Part II The second part of the menu tutorial Rate Topic: -----

#1 Martyn.Rae  Icon User is offline

  • The programming dinosaur
  • member icon

Reputation: 540
  • View blog
  • Posts: 1,406
  • Joined: 22-August 09

Posted 19 April 2010 - 05:11 AM

Linux : Working With GTK+ Menus - Part II

Introduction

In this, the second part of my tutorial on GTK+ menus, we shall look at how we process menu actions etc.

The most usual action that is intercepted for a menu item is the activate action. For example, in the code snippet below (taken from the full example at the end of this tutorial), we are associating a callback routine with the user selecting the load_menu_item ('Load'). This callback routine is prototyped as void load_menu_proc(GtkMenuItem *menuitem, gpointer user_data);.

      void load_menu_proc(GtkMenuItem *menuitem, gpointer user_data) {
      }

      ...

      g_signal_connect(load_menu_item, "activate",
                       G_CALLBACK(load_menu_proc), this);



Introducing GtkAction

In order to provide more functionality to a menu item, say for example the ability to stop the user from selecting an item because the state of the application is not correct, we have to use a GtkAction mechanism.

The code snippet below shows us how to do this.

      /* create edit menu item */
      edit_action = gtk_action_new("Edit Action", "Edit", NULL, NULL);
      edit_menu_item = gtk_action_create_menu_item(edit_action);
      gtk_menu_shell_append(GTK_MENU_SHELL(menu_window), edit_menu_item);



The first parameter of the gtk_action_new function call is a unique identifier for this action. The second parameter is the text to be associated with this menu item and the third and fourth parameters are not being used. Once we have the GtkAction object, we use that to actually create our menu item using gtk_action_create_menu_item.

Using the GtkAction routines, we can now perform actions such as making the menu item visible or invisible and permitting user selection or not.

The Full Code Example

Here is the full code example for this tutorial.

The application displays a single menu item called 'File', which when selected displays a drop-down menu containing a 'Load', 'Save' and 'Close' menu item. If the user selects the 'Load' menu item, a file chooser dialog is displayed permitting the selection of the file to edit (don't worry, there is no code for doing that). Regardless of whether the user presses the cancel button or the 'Open File' button, the dialog is closed and the application makes the 'Edit' menu bar item visible.

If the user now selects the 'Save' menu item, a file chooser dialog is displayed permitting the selection of where to save the file (don't worry, there is no code for doing that). Regardless of whether the user presses the cancel button or the 'Save File' button, the dialog is closed and the application makes the 'Edit' menu bar item invisible.

#include <gtk/gtk.h>

class application {
  private:
    GtkWidget *frame_window;
    GtkWidget *vbox_window;
    GtkWidget *menu_window;
    GtkWidget *file_menu_item;
    GtkWidget *file_submenu;
    GtkWidget *load_menu_item;
    GtkWidget *save_menu_item;
    GtkWidget *separator_menu_item;
    GtkWidget *close_menu_item;
    GtkWidget *edit_menu_item;
    GtkAction *edit_action;
  public:
    application(int argc, char *argv[]) : frame_window(NULL),
                                          vbox_window(NULL),
                                          menu_window(NULL),
                                          file_menu_item(NULL),
                                          file_submenu(NULL),
                                          load_menu_item(NULL),
                                          save_menu_item(NULL),
                                          separator_menu_item(NULL),
                                          close_menu_item(NULL),
                                          edit_menu_item(NULL),
                                          edit_action(NULL) {
      /* Initialize GTK+ */
      gtk_init(&argc, &argv);

      /* Create the main window */
      frame_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
      gtk_container_set_border_width(GTK_CONTAINER(frame_window), 2);
      gtk_window_set_title(GTK_WINDOW(frame_window), "Editor");
      gtk_window_set_default_size(GTK_WINDOW(frame_window), 800, 600);
      gtk_window_set_position(GTK_WINDOW(frame_window), GTK_WIN_POS_CENTER);

      /* create a vertical box */
      vbox_window = gtk_vbox_new(false, 0);
      gtk_container_add(GTK_CONTAINER(frame_window), vbox_window);

      /* Create a menu bar*/
      menu_window = gtk_menu_bar_new();

      /* create file menu item */
      file_menu_item = gtk_menu_item_new_with_label("File");
      gtk_menu_shell_append(GTK_MENU_SHELL(menu_window), file_menu_item);

      /* create edit menu item providing action support */
      edit_action = gtk_action_new("Edit Action", "Edit", NULL, NULL);
      edit_menu_item = gtk_action_create_menu_item(edit_action);
      gtk_menu_shell_append(GTK_MENU_SHELL(menu_window), edit_menu_item);

      /* create file sub-menu and attach it to the file menu item*/
      file_submenu = gtk_menu_new();
      gtk_menu_item_set_submenu(GTK_MENU_ITEM(file_menu_item), file_submenu);

      /* create load menu item */
      load_menu_item = gtk_menu_item_new_with_label("Load");
      gtk_menu_shell_append(GTK_MENU_SHELL(file_submenu), load_menu_item);

      /* create save menu item */
      save_menu_item = gtk_menu_item_new_with_label("Save");
      gtk_menu_shell_append(GTK_MENU_SHELL(file_submenu), save_menu_item);

      separator_menu_item = gtk_separator_menu_item_new();
      gtk_menu_shell_append(GTK_MENU_SHELL(file_submenu), separator_menu_item);

      /* create close menu item */
      close_menu_item = gtk_menu_item_new_with_label("Close");
      gtk_menu_shell_append(GTK_MENU_SHELL(file_submenu), close_menu_item);

      g_signal_connect(load_menu_item, "activate",
                       G_CALLBACK(load_menu_proc), this);
      g_signal_connect(save_menu_item, "activate",
                       G_CALLBACK(save_menu_proc), this);
      g_signal_connect(close_menu_item, "activate", gtk_main_quit, NULL);

      gtk_container_add(GTK_CONTAINER(vbox_window), menu_window);
      gtk_box_set_child_packing(GTK_BOX(vbox_window), menu_window,
                                FALSE, FALSE, FALSE, GTK_PACK_START);

      g_signal_connect(frame_window, "destroy", gtk_main_quit, NULL);
      gtk_widget_realize(frame_window);

      /* Enter the main loop */
      gtk_widget_show_all(frame_window);
      /* Hide the Edit menu item as no file has been selected */
      gtk_action_set_visible(edit_action, false);
    }
    ~application() {
      gtk_widget_destroy(frame_window);
      gtk_widget_destroy(vbox_window);
      gtk_widget_destroy(menu_window);
      gtk_widget_destroy(file_menu_item);
      gtk_widget_destroy(file_submenu);
      gtk_widget_destroy(load_menu_item);
      gtk_widget_destroy(save_menu_item);
      gtk_widget_destroy(separator_menu_item);
      gtk_widget_destroy(close_menu_item);
      gtk_widget_destroy(edit_menu_item);
    }
    static void load_menu_proc(GtkMenuItem *menuitem, gpointer user_data);
    static void save_menu_proc(GtkMenuItem *menuitem, gpointer user_data);
};

void application::load_menu_proc(GtkMenuItem *menuitem, gpointer user_data) {
    application * This = static_cast<application *>(user_data);
    GtkWidget * file_chooser;

    file_chooser = gtk_file_chooser_dialog_new("Open Files", GTK_WINDOW(This->frame_window),
                                               GTK_FILE_CHOOSER_ACTION_OPEN,
                                               GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
				                               GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
                                               NULL);
    gtk_dialog_run(GTK_DIALOG(file_chooser));
    gtk_widget_destroy(file_chooser);
    gtk_action_set_visible(This->edit_action, true);
}

void application::save_menu_proc(GtkMenuItem *menuitem, gpointer user_data) {
    application * This = static_cast<application *>(user_data);
    GtkWidget * file_chooser;

    file_chooser = gtk_file_chooser_dialog_new("Save Files", GTK_WINDOW(This->frame_window),
                                               GTK_FILE_CHOOSER_ACTION_SAVE,
                                               GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
				                               GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
                                               NULL);
    gtk_dialog_run(GTK_DIALOG(file_chooser));
    gtk_widget_destroy(file_chooser);
    gtk_action_set_visible(This->edit_action, false);
}

int main (int argc, char *argv[]) {
  application this_application(argc, argv);
  gtk_main();
  return 0;
}



Is This A Good Question/Topic? 0
  • +

Page 1 of 1