Keywords: Renaissance

Next: 6 Changing the window Up: GNUstep Renaissance Previous: 4 Loading the gsmarkup

# 5 Adding a menu

We now want to add a very simple menu, containing a simple `Quit` item. Clicking on the item should quit the application. Here is the required gsmarkup file:

    <gsmarkup>

      <objects>

        <menu type="main">
          <menuItem title="Quit" key="q" action="terminate:" />
        </menu>

      </objects>

    </gsmarkup>

In this file, the `<objects>` tag contains a single `menu` object, which contains a single `menuItem`.

When GNUstep Renaissance loads the file, it will create a menu object (corresponding to the `<menu type="main">` tag inside the `<objects>` tag). This menu will be the application main menu, because `type="main"` has been used as attribute of the menu tag. Inside the menu, GNUstep Renaissance will create a single item, with title `Quit`, key equivalent `q`, and which, when clicked, will execute the action `terminate:`.

Please note that the menuItem object is inside the menu object because the `<menuItem>` tag is inside the `<menu>` tag. Generally, the nesting of tags represents a corresponding nesting of objects.

Because the menus are organized in a completely different way on Apple Mac OS X, this file won't really generate a proper menu on Apple Mac OS X. If you are using Apple Mac OS X, you should rather use the following gsmarkup file for your menu:

    <gsmarkup>

      <objects>

        <menu type="main">
          <menu title="Example" type="apple">
            <menuItem title="Quit Example" key="q" action="terminate:" />
          </menu>
        </menu>

      </objects>

    </gsmarkup>

The structure in this case is more complex: inside the main menu (displayed horizontally on Apple), there is a submenu called `Example`. In the submenu there is a single menu item, with title `Quit Example`, key equivalent `q`, calling the action `terminate:`. Please note that this menu has `type="apple"`. This attribute is ignored under GNUstep, and only used by Apple Mac OS X; you should always have one and only one submenu (the first one) with type `apple` for Apple Mac OS X menus; it is used to identify the first compulsory submenu of an application menu, the one with the title displayed in bold, and containing the `Quit XXX` menu item.

If you need your application to run on both systems, you will need to provide two separate gsmarkup files, each one using its system specific menu layouts: one for GNUstep, the other one for Apple Mac OS X; and then load the specific one depending on the platform you are running on (you can use the `GNUSTEP` preprocessor defined symbol to know on which platform you are; the symbol is defined on GNUstep, but not on Apple Mac OS X). Conventionally, you can call the first one `Menu-GNUstep.gsmarkup`, and the second one `Menu-OSX.gsmarkup`.

Menus are really the only part of the user interface where such a strong distinction is required. You can usually use the same window (and gsmarkup file) on both systems; but because menus need to comply more strictly with the platform in terms of the names and positions of the menu items and of the submenus, at the moment to get a real native feel on the two platforms, you need separate menus.

The gsmarkup file containing the main menu has to be loaded before calling `NSApplicationMain()`; this is the most portable way of loading it. Here is the new `main.m` file, with the required changes to load our new `Menu-GNUstep.gsmarkup` (or `Menu-OSX.gsmarkup`) file:

    #include <Foundation/Foundation.h>
    #include <AppKit/AppKit.h>
    #include <Renaissance/Renaissance.h>

    @interface MyDelegate : NSObject
    {}
    - (void) applicationDidFinishLaunching: (NSNotification *)not;
    @end

    @implementation MyDelegate : NSObject

    - (void) applicationDidFinishLaunching: (NSNotification *)not;
    {
      [NSBundle loadGSMarkupNamed: @"Window"  owner: self];
    }
    @end

    int main (int argc, const char **argv)
    {
      CREATE_AUTORELEASE_POOL (pool);
      MyDelegate *delegate;
      [NSApplication sharedApplication];

      delegate = [MyDelegate new];
      [NSApp setDelegate: delegate];

    #ifdef GNUSTEP
      [NSBundle loadGSMarkupNamed: @"Menu-GNUstep"  owner: delegate];
    #else
      [NSBundle loadGSMarkupNamed: @"Menu-OSX"  owner: delegate];
    #endif

      RELEASE (pool);
      return NSApplicationMain (argc, argv);
    }

Here we use `delegate` as the `owner` argument of the `loadGSMarkupNamed:owner:` method. Because we are not using the owner yet, it is not important which object is passed - except for a detail, which is that the owner is used to determine in which bundle to look for the gsmarkup file to load; passing an object of a class defined in your application makes sure that the file is looked for in the main application bundle. In practice, if you are loading files from your application main bundle, you should always pass an instance of an object defined in your application as the owner.

We have also enclosed the loading of the Menu gsmarkup file inside the creation and release of an autorelease pool; this is needed because otherwise no autorelease pool would in place at that point. Generally, whenever you need to do anything non-trivial inside your `main` function, you need to create an autorelease pool at the beginning, and release it at the end.

Do not forget to add `Menu-GNUstep.gsmarkup` and `Menu-OSX.gsmarkup` to the resource files (listed in the `Example_RESOURCE_FILES` variable) in the `GNUmakefile`:

    include $(GNUSTEP_MAKEFILES)/common.make

    APP_NAME = Example
    Example_OBJC_FILES = main.m
    Example_RESOURCE_FILES = \
      Menu-GNUstep.gsmarkup \
      Menu-OSX.gsmarkup \
      Window.gsmarkup \

    ifeq ($(FOUNDATION_LIB), apple)
      ADDITIONAL_INCLUDE_DIRS += -framework Renaissance
      ADDITIONAL_GUI_LIBS += -framework Renaissance
    else
      ADDITIONAL_GUI_LIBS += -lRenaissance
    endif

    include $(GNUSTEP_MAKEFILES)/application.make

The application should now build and run, and display an empty window and a very simple menu with a single ``Quit'' menu item, which quits the application.

Next: 6 Changing the window Up: GNUstep Renaissance Previous: 4 Loading the gsmarkup