# The Interface Kit: BMenuBar

Derived from: public BMenu

Declared in: be/interface/MenuBar.h

Library: libbe.so

## Overview

A BMenuBar is a menu that can stand at the root of a menu hierarchy. Rather than appear on-screen when commanded to do so by a user action, a BMenuBar object has a settled location in a window's view hierarchy, just like other views. Typically, the root menu is the menu bar that's drawn across the top of the window. It's from this use that the class gets its name.

However, instances of this class can also be used in other ways. A BMenuBar might simply display a list of items arranged in a column somewhere in a window. Or it might contain just one item, where that item controls a pop-up menu (a BPopUpMenu object). Rather than look like a "menu bar," the BMenuBar object would look something like a button.

### The Key Menu Bar

The "real" menu bar at the top of the window usually represents an extensive menu hierarchy; each of its items typically controls a submenu.

The user should be able to operate this menu bar from the keyboard (using the arrow keys and Enter). There are two ways that the user can put the BMenuBar and its hierarchy in focus for keyboard events:

- Clicking an item in the menu bar. If the "click to open" preference is not turned off, this opens the submenu the item controls so that it stays visible on-screen and puts the submenu in focus.

- Pressing the Menu key or Command-Escape. This puts the BMenuBar in focus and selects its first item.

Either method opens the entire menu hierarchy to keyboard navigation.

If a window's view hierarchy includes more than one BMenuBar object, the Menu key (or Command-Escape) must choose one of them to put in focus. By default, it picks the last one that was attached to the window. However, the `SetKeyMenuBar()` function defined in the BWindow class can be called to designate a different BMenuBar object as the "key" menu bar for the window.

### A Kind of BMenu

BMenuBar inherits most of its functions from the BMenu class. It reimplements the `AttachedToWindow()`, `Draw()`, and `MouseDown()` functions that set up the object and respond to messages, but these aren't functions that you'd call from application code; they're called for you.

The only real function (other than the constructor) that the BMenuBar class adds to those it inherits is `SetBorder()`, which determines how the list of items is bordered.

Therefore, for most BMenuBar operations--adding submenus, finding items, temporarily disabling the menu bar, and so on--you must call inherited functions and treat the object like the BMenu that it is.

See also: the BMenu class

## Constructor and Destructor

### BMenuBar()

          BMenuBar(BRect frame, const char *name,
             uint32 resizingMode = B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP,
             menu_layout layout = B_ITEMS_IN_ROW,
             bool resizeToFit = true)
          BMenuBar(BMessage *archive)

Initializes the BMenuBar by assigning it a frame rectangle, a name, and a resizingMode, just like other BViews. These values are passed up the inheritance hierarchy to the BView constructor. The default resizing mode (`B_FOLLOW_LEFT_RIGHT` plus `B_FOLLOW_TOP`) is designed for a true menu bar (one that's displayed along the top edge of a window). It permits the menu bar to adjust itself to changes in the window's width, while keeping it glued to the top of the window frame.

The layout argument determines how items are arranged in the menu bar. By default, they're arranged in a row as befits a true menu bar. If an instance of this class is being used to implement something other than a horizontal menu, items can be laid out in a column (`B_ITEMS_IN_COLUMN`) or in a matrix (`B_ITEMS_IN_MATRIX`).

If the resizeToFit flag is turned on, as it is by default, the frame rectangle of the BMenuBar will be automatically resized to fit the items it displays. This is generally a good idea, since it relieves you of the responsibility of testing user preferences to determine what size the menu bar should be. Because the font and font size for menu items are user preferences, items can vary in size from user to user.

When resizeToFit is `true`, the frame rectangle determines only where the menu bar is located, not how large it will be. The rectangle's `left` and `top` data members are respected, but the `right` and `bottom` sides are adjusted to accommodate the items that are added to the menu bar.

Two kinds of adjustments are made if the layout is `B_ITEMS_IN_ROW`, as it typically is for a menu bar:

- The height of the menu bar is adjusted to the height of a single item.

- If the resizingMode includes `B_FOLLOW_LEFT_RIGHT`, the width of the menu bar is adjusted to match the width of its parent view. This means that a true menu bar (one that's a child of the window's top view) will always be as wide as the window.

Two similar adjustments are made if the menu bar layout is `B_ITEMS_IN_COLUMN`:

- The width of the menu bar is adjusted to the width of the widest item.

- If the resizingMode includes `B_FOLLOW_TOP_BOTTOM`, the height of the menu bar is adjusted to match the height of its parent view.

After setting up the key menu bar and adding items to it, you may want to set the minimum width of the window so that certain items won't be hidden when the window is resized smaller.

Change the resizingMode, the layout, and the resizeToFit flag as needed for BMenuBars that are used for a purpose other than to implement a true menu bar.

See also: the BMenu constructor, `BWindow::SetSizeLimits()`

### ~BMenuBar()

          virtual ~BMenuBar()

Frees all the items and submenus in the entire menu hierarchy, and all memory allocated by the BMenuBar.

## Static Functions

### Instantiate()

          static BMenuBar *Instantiate(BMessage *archive)

Returns a new BMenuBar object, allocated by `new` and created with the version of the constructor that takes a BMessage archive. However, if the archive message doesn't contain data for a BMenuBar object, this function returns `NULL`.

See also: `BArchivable::Instantiate()`, `instantiate_object()`, `Archive()`

## Member Functions

### Archive()

          virtual status_t Archive(BMessage *archive, bool deep = true) const

Calls the inherited version of `Archive()`, which serves to archive the BMenuBar's current state and, if the deep flag is `true`, all its menu items. This function then adds the BMenuBar's border style to the BMessage archive.

See also: `BArchivable::Archive()`, `BMenu::Archive()`, `Instantiate()` static function

### AttachedToWindow()

          virtual void AttachedToWindow(void)

Finishes the initialization of the BMenuBar by setting up the whole hierarchy of menus that it controls, and by making the BWindow to which it has become attached the target handler for all items in the menu hierarchy, except for those items for which a target has already been set.

This function also makes the BMenuBar the key menu bar, the BMenuBar object whose menu hierarchy the user can navigate from the keyboard. If a window contains more than one BMenuBar in its view hierarchy, the last one that's added to the window gets to keep this designation. However, the key menu bar should always be the real menu bar at the top of the window. It can be explicitly set with BWindow's `SetKeyMenuBar()` function.

See also: `BWindow::SetKeyMenuBar()`

### Border() see SetBorder()

### Draw()

          virtual void Draw(BRect updateRect)

Draws the menu--whether as a true menu bar, as some other kind of menu list, or as a single item that controls a pop-up menu. This function is called as the result of update messages; you don't need to call it yourself.

See also: `BView::Draw()`

### Hide(), Show()

          virtual void Hide(void)

          virtual void Show(void)

These functions override their BMenu counterparts to restore the normal behavior for views when they're hidden and unhidden. When an ordinary BMenu is hidden, the window that displays it is also removed from the screen. But it would be a mistake to remove the window that displays a BMenuBar. Hiding a BMenuBar is like hiding a typical view; only the view is hidden, not the window.

See also: `BView::Hide()`

### MouseDown()

          virtual void MouseDown(BPoint point)

Initiates mouse tracking and keyboard navigation of the menu hierarchy. This function is called to notify the BMenuBar of a mouse-down event.

See also: `BView::MouseDown()`

### SetBorder(), Border()

          void SetBorder(menu_bar_border border)

          menu_bar_border Border(void) const

`SetBorder()` determines how the menu list is bordered. The border argument can be any of three values:

`B_BORDER_FRAME` | The border is drawn around the entire frame rectangle.
`B_BORDER_CONTENTS` | The border is drawn around just the list of items.
`B_BORDER_EACH_ITEM` | A border is drawn around each item.

`Border()` returns the current setting. The default is `B_BORDER_FRAME`.

## Archived Fields

The `Archive()` function adds the following fields to its BMessage argument:

Field | Type code | Meaning
"_border" | `B_INT32_TYPE` | Menu bar border (exists only if not `B_BORDER_FRAME`)

The Be Book, in lovely HTML, for BeOS Release 3.

Copyright © 1998 Be, Inc. All rights reserved.

Last modified March 26, 1998.