# The Interface Kit: BAlert

Derived from: public BWindow

Declared in: be/interface/Alert.h

Library: libbe.so

## Overview

A BAlert displays a modal window that notifies the user of an error (or the like), and provides a set of buttons that lets the user respond to the situation. For example, here's a typical "unsaved changes" alert:

When the user clicks one of the buttons, the alert panel is removed from the screen, the index of the chosen button (0,1, or 2, left to right) is reported to the app, and the BAlert object is deleted.

The panel floats in front of the application's other windows. While it's on-screen, other parts of the application's user interface are disabled.

The rightmost button is automatically mapped to the Enter key (hence the box around the button). You can assign your own shortcuts through the `SetShortcut()` function.

### Creating and Displaying an Alert Panel

The following code creates and displays the alert panel shown above:

       BAlert *alert = new BAlert("window title",
                         "Save changes before quitting?",
                         "Cancel", "Quit", "Save");
       int32 button_index = alert->Go();

The constructor assigns the text that the panel and its buttons display. The `Go()` function does all the actual work: It displays the panel, removes the panel when the user is done, and returns the index of the button that the user clicked.

|  | Keep in mind that the BAlert object is deleted after the index is returned. You never delete the BAlerts that you show.

#### Buttons and Indices

A BAlert can have one, two, or three buttons. Each button is identified by an index (0-based). The set of buttons is right justified within the panel. The rightmost button is automatically mapped to the Return key.

For example, if you create a panel with just one button...

       BAlert *alert = new BAlert("window title", "Designed by committee", "OK");
       alert->Go();

..the button will have an index of 0, and will be displayed at the right side of the panel:

### Asynchronous Alerts

The default (no argument) version of Go() is synchronous with regard to the user's response. To get an asynchronous alert, pass a BInvoker object (which encapsulates a message and a target) to Go(). The function returns immediately; the user's response (the button index) is added as the message's "which" field (type `int32`) and the message is sent to the target. Here we send the result to the BApplication object (via the default messenger):

       alert->Go(new BInvoker(new BMessage('alrt'), be_app_messenger));

And here's `be_app`'s message handling code :

       void MyApp::MessageReceived(BMessage *msg)
       {
          int32 button_index;

          switch (msg->what) {
          case 'alrt':
             msg->FindInt32("which", &button_index);
          ...

If you want your alert panel to run asynchronously but you don't care about the button index value (this is often the case for a one-button alert), pass `NULL` as the argument:

       alert->Go(NULL);

## Constructor

### BAlert(), alert_type

          BAlert(const char *title, const char *text,
             const char *button0Label,
             const char *button1Label = NULL,
             const char *button2Label = NULL,
             button_width widthStyle = B_WIDTH_AS_USUAL,
             alert_type type = B_INFO_ALERT)
          BAlert(BMessage *archive)

          enum alert_type {}

Creates an alert panel that's ready to be displayed. The arguments are:

- title is the ostensible name of the panel; however, since an alert panel doesn't have a title tab, the title isn't actually displayed anywhere. Nonetheless, it can be useful in debugging: The title is used to name the window thread ("w>title").

- text is displayed in the body of the panel; it should describe the reason the panel is being shown ("Are you sure you want to quit?", "Invalid name.", etc.).

- The buttonNLabel arguments are the labels for the panel's buttons. An alert panel can have one, two, or three buttons. The buttons are arranged in a row at the bottom of the panel, as shown in the illustrations above, and each is assigned an index (0, 1, or 2) that's used to identify the button that the user clicked. Button 0 is the always the leftmost button.

- widthStyle is a constant that describes how the buttons should be sized:

Constant | Meaning
`B_WIDTH_AS_USUAL` | A default width is used on all buttons.
`B_WIDTH_FROM_LABEL` | Each button is wide enough to accommodate its own label.
`B_WIDTH_FROM_WIDEST` | All buttons are resized to fit the longest label.

- type is a constant that determines the icon that's displayed in the panel. There are five `alert_type` constants:

`B_EMPTY_ALERT` | `B_INFO_ALERT` | `B_IDEA_ALERT` | `B_WARNING_ALERT` | `B_STOP_ALERT`
``(none) |  |  |  |

After the BAlert is constructed, `Go()` must be called to display it. The object is automatically deleted when the user clicks a button in the alert panel.

## Member Functions

### AlertPosition()

          BPoint AlertPosition(float width, float height) const

Computes the "best" frame for an alert of the given width and height, and returns the top left corner of the computed frame in screen coordinates. This function is called automatically when you construct your BAlert; you never have to invoke it yourself.

### ButtonAt()

          BButton *ButtonAt(int32 index) const

Returns a pointer to the BButton object identified by index. Indices begin at 0 and count buttons from left to right. The BButton belongs to the BAlert object and should not be freed.

### FrameResized()

Implementation detail.

### GetSupportedSuites()

Implementation detail.

### Go()

          int32 Go(void)
          status_t Go(BInvoker *invoker)

Displays the alert panel. `Go()` can operate synchronously or asynchronously:

- The no-argument version is synchronous: The function doesn't return until the user has clicked a button and the panel has been removed from the screen.. The value it returns is the index of the clicked button (0,1, or 2, left-to-right). If the BAlert is sent a `B_QUIT_REQUESTED` message while the panel is still on-screen, `Go()` returns -1.

- The BInvoker argument version is asynchronous: The function returns immediately (the return value is always `B_OK`) and the button index is delivered in a BMessage that's sent to the target of the BInvoker. Within the message, the index can be found in the `int32` field named "which". If the BAlert is sent B_QUIT_REQUESTED while the panel is still on-screen, the index-reporting message isn't sent.

If you call `Go()` with a (literal) `NULL` argument...

       alert->Go(NULL);

...the asynchronous version is used, but the BMessage isn't sent.

The synchronous version deletes the object before it returns; the asynchronous version deletes it after the message is sent. In either case, you should consider the BAlert object to be invalid after you call `Go()`.

### MessageReceived()

          virtual void MessageReceived(BMessage *message)

BAlert uses `MessageReceived()` to clean up after itself. If you need to override this function, you should call the BAlert version to handle any messages that your version doesn't understand:

       void MyAlert::MessageReceived(BMessage *msg)
       {
          switch(msg->what) {
          /* Cases that your BAlert subclass understands go here. */
          ...
          default:
             BAlert::MessageReceived(msg);
             break;
          }
       }

### ResolveSpecifier()

Implementation detail.

### SetShortcut(), Shortcut()

          void SetShortcut(int32 index, char shortcut)

          char Shortcut(int32 index) const

These functions set and return the shortcut character that's mapped to the button at index. A given button can have only one shortcut at a time. By default, the rightmost button's shortcut is B_ENTER; setting the rightmost button's shortcut does not undo the B_ENTER shortcut.

If you create a "Cancel" button, you should give it a shortcut of `B_ESCAPE`.

### TextView()

          BTextView *TextView(void) const

Returns a pointer to the BTextView object that contains the textual information that's displayed in the panel. The object is created and the text is set when the BAlert is constructed. You can fiddle with the BTextView object but you mustn't delete it

## Archived Fields

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

Field | Type code | Meaning
"_text" | `B_STRING_TYPE` | The alert's descriptive text.
"_atype" | `B_INT32_TYPE` | The `alert_type` value.
"_but_width" | `B_INT32_TYPE` | The `button_width` value.
"_but_key" (array) | `B_INT32_TYPE` | Keyboard shortcut values (one field per button).

The following views are added to the "_views" field (deep copy only):

Name | Level | Meaning
"_master_" | 0 | Background view.
"_tv_" | 1 | BTextView for the alert panel's text.
"_b0_" | 1 | BButton with index 0.
"_b1_" | 1 | BButton with index 1.
"_b2_" | 1 | BButton with index 2.

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

Copyright © 1998 Be, Inc. All rights reserved.

Last modified March 26, 1998.