The Interface Kit: BView Hook Functions

The Interface Kit Table of Contents | The Interface Kit Index

# BView Hook Functions

###### Summary

The functions in this section are called in response to particular events, and are intended to be overridden in a BView subclass. (The default implementations of the BView hook functions do nothing.) They include functions to respond to input, draw when necessary, perform actions periodically, and various others.

### AllAttached() see AttachedToWindow()

### AllDetached() see DetachedFromWindow()

### AttachedToWindow() , AllAttached()

virtual void `AttachedToWindow(`void`) `
virtual void `AllAttached(`void`) `

Implemented by derived classes to complete the initialization of the BView when it's assigned to a window. A BView is assigned to a window when it, or one of its ancestors in the view hierarchy, becomes a child of a view already attached to a window.

`AttachedToWindow()` is called immediately after the BView is formally made a part of the window's view hierarchy and after it has become known to the Application Server and its graphics parameters are set. The `Window()` function can identify which BWindow the BView belongs to.

All of the BView's children, if it has any, also become attached to the window and receive their own `AttachedToWindow()` notifications. Parents receive the notification before their children, but only after all views have become attached to the window and recognized as part of the window's view hierarchy. This function can therefore depend on all ancestor and descendant views being in place.

For example, `AttachedToWindow()` can be implemented to set a view's background color to the same color as its parent, something that can't be done before the view belongs to a window and knows who its parent is.

       void MyView::AttachedToWindow()
       {
           if ( Parent() )
               SetViewColor(Parent()->ViewColor());
           baseClass::AttachedToWindow();
       }

The `AllAttached()` notification follows on the heels of `AttachedToWindow()`, but works its way up the view hierarchy rather than down. When `AllAttached()` is called for a BView, all its descendants have received both `AttachedToWindow()` and `AllAttached()` notifications. Therefore, parent views can depend on any calculations that their children make in either function. For example, a parent can resize itself to fit the size of its children, where their sizes depend on calculations done in `AttachedToWindow()`.

The default (BView) version of both these functions are empty.

See also: `AddChild()`, `Window()`

### DetachedFromWindow() , AllDetached()

virtual void `DetachedFromWindow(`void`) `
virtual void `AllDetached(`void`) `

Implemented by derived classes to make any adjustments necessary when the BView is about to be removed from a window's view hierarchy. These two functions parallel the more commonly implemented `AttachedToWindow()` and `AllAttached()` functions.

`DetachedFromWindow()` notifications work their way down the hierarchy of views being detached, followed by `AllDetached()` notifications, which work their way up the hierarchy. The second function call permits an ancestor view to take actions that depend on calculations a descendant might have to make when it's first notified of being detached.

The BView is still attached to the window when both functions are called.

See also: `AttachedToWindow()`

### Draw()

virtual void `Draw(` BRect updateRect`) `

Implemented by derived classes to draw the updateRect portion of the view. The update rectangle is stated in the BView's coordinate system.

`Draw()` is called as the result of update messages whenever the view needs to present itself on-screen. This may happen when:

- The window the view is in is first shown on-screen, or shown after being hidden (see the BWindow version of the `Hide()` function).

- The view is made visible after being hidden (see BView's `Hide()` function).

- Obscured parts of the view are revealed, as when a window is moved from in front of the view or an image is dragged across it.

- The view is resized.

- The contents of the view are scrolled (see `ScrollBy()`).

- A child view is added, removed, or resized.

- A rectangle has been invalidated that includes at least some of the view (see `Invalidate()`).

- `CopyBits()` can't completely fill a destination rectangle within the view.

  `Draw()` is also called from a BPrintJob object's `DrawView()` function to draw the view on a printed page. `IsPrinting()` returns `true` when the BView is drawing for the printer and `false` when it's drawing to the screen. When printing, you may want to recalculate layouts, substitute fonts, turn antialiasing off, scale the size of a coordinate unit, or make other adjustments to ensure the quality of the printed image.

  When drawing to the screen, the updateRect is the smallest rectangle that encloses the current clipping region for the view. Since the Application Server won't render anything on-screen that's outside the clipping region, an application will be more efficient if it avoids producing drawing instructions for images that don't intersect with the rectangle. For still more efficiency and precision, you can ask for the clipping region itself (by calling `GetClippingRegion()`) and confine drawing to images that intersect with it.

  When printing, the updateRect matches the rectangle passed to `DrawView()` and may lie outside the clipping region. The clipping region is not enforced for printing, but the Print Server clips the BView's drawing to the specified rectangle.

  See also: `BWindow::UpdateIfNeeded()`, `Invalidate()`, `GetClippingRegion()`, `BPrintJob::DrawView()`, `IsPrinting()`

  ### DrawAfterChildren()

  virtual void `Draw(` BRect updateRect`) `

  This function is similar (in fact, almost identical) to `Draw()`. The only difference is that `DrawAfterChildren()` is called after all children have drawn during a screen update. This is in contrast to `Draw()`, which draws before any children have drawn. In general, `Draw()` will be used for almost all of your drawing needs; `DrawAfterChildren()` is intended for use in the rare circumstances where you wish a view to be able to draw on top of its child views.

  Other details are as for `Draw()`.

  See also: `Draw()`

  ### FrameMoved()

  virtual void `FrameMoved(` BPoint parentPoint`) `

  Implemented by derived classes to respond to a notification that the view has moved within its parent's coordinate system. parentPoint gives the new location of the left top corner of the BView's frame rectangle.

  `FrameMoved()` is called only if the `B_FRAME_EVENTS` flag is set and the BView is attached to a window.

  If the view is both moved and resized, `FrameMoved()` is called before `FrameResized()`. This might happen, for example, if the BView's automatic resizing mode is a combination of `B_FOLLOW_TOP_BOTTOM` and `B_FOLLOW_RIGHT` and its parent is resized both horizontally and vertically.

  The default (BView) version of this function is empty.

  | Currently, `FrameMoved()` is also called when a hidden window is shown on-screen.

  See also: `MoveBy()`, `BWindow::FrameMoved()`, `SetFlags()`

  ### FrameResized()

  virtual void `FrameResized(`float width, float height`) `

  Implemented by derived classes to respond to a notification that the view has been resized. The arguments state the new width and height of the view. The resizing could have been the result of a user action (resizing the window) or of a programmatic one (calling `ResizeTo()` or `ResizeBy()`).

  `FrameResized()` is called only if the `B_FRAME_EVENTS` flag is set and the BView is attached to a window.

  BView's version of this function is empty.

  See also: `ResizeBy()`, `BWindow::FrameResized()`, `SetFlags()`

  ### GetPreferredSize() , ResizeToPreferred()

  virtual void `GetPreferredSize(`float *width, float *height`)`
  virtual void `ResizeToPreferred(`void`)`

  `GetPreferredSize()` is implemented by derived classes to write the preferred width and height of the view into the variables the width and height arguments refer to. Derived classes generally make this calculation based on the view's contents. For example, a BButton object reports the optimal size for displaying the button border and label given the current font.

  `ResizeToPreferred()` resizes the BView's frame rectangle to the preferred size, keeping its left and top sides constant.

  See also: `ResizeTo()`

  ### KeyDown()

  virtual void `KeyDown(`const char *bytes, int32 numBytes`) `

  Implemented by derived classes to respond to a `B_KEY_DOWN` message reporting keyboard input. Whenever a BView is the focus view of the active window, it receives a `KeyDown()` notification for each character the user types, except for those that:

  - Are produced while a Command key is held down. Command key events are interpreted as keyboard shortcuts.

  - Are produced by the Tab key when an Option key is held down. Option-Tab events are invariably interpreted as instructions to change the focus view (for keyboard navigation); they work even where Tab alone does not.

  - Can operate the default button in a window. The BButton object's `KeyDown()` function is called, rather than the focus view's.

  The first argument, bytes, is an array that encodes the character mapped to the key the user pressed. The second argument, numBytes, tells how many bytes are in the array; there will always be at least one. The bytes value follows the character encoding of the BView's font. Typically, the encoding is Unicode UTF-8 (`B_UNICODE_UTF8`), so there may be more than one byte per character. The bytes array is not null-terminated; '0' is a valid character value.

  The character value takes into account any modifier keys that were held down or keyboard locks that were on at the time of the keystroke. For example, Shift-i is reported as uppercase 'I' (0x49) and Control-i is reported as a `B_TAB` (0x09).

  Single-byte characters can be tested against ASCII codes and these constants:

  `B_BACKSPACE` | `B_LEFT_ARROW` | `B_INSERT`
  `B_ENTER` | `B_RIGHT_ARROW` | `B_DELETE`
  `B_RETURN` | `B_UP_ARROW` | `B_HOME`
  `B_SPACE` | `B_DOWN_ARROW` | `B_END`
  `B_TAB` |  | `B_PAGE_UP`
  `B_ESCAPE` | `B_FUNCTION_KEY` | `B_PAGE_DOWN`

  `B_ENTER` and `B_RETURN` are the same character, a newline ('n').

  Only keys that generate characters produce key-down events; the modifier keys on their own do not.

  You can determine which modifier keys were being held down at the time of the event by calling BLooper's `CurrentMessage()` function and looking up the "modifiers" entry in the BMessage it returns. If the bytes character is `B_FUNCTION_KEY` and you want to know which key produced the character, you can look up the "key" entry in the BMessage and test it against these constants:

  `B_F1_KEY` | `B_F6_KEY` | `B_F11_KEY`
  `B_F2_KEY` | `B_F7_KEY` | `B_F12_KEY`
  `B_F3_KEY` | `B_F8_KEY` | `B_PRINT_KEY` (Print Screen)
  `B_F4_KEY` | `B_F9_KEY` | `B_SCROLL_KEY` (Scroll Lock)
  `B_F5_KEY` | `B_F10_KEY` | `B_PAUSE_KEY`

  For example:

         if ( bytes[0] == B_FUNCTION_KEY ) {
             BMessage *msg = Window()->CurrentMessage();
             if ( msg ) {
                 int32 key;
                 msg->FindInt32("key", &key);
                 switch ( key ) {
                 case B_F1_KEY:
                     . . .
                     break;
                 case B_F2_KEY:
                     . . .
                     break;
                  . . .
                 }
             }
         }

  The BView version of `KeyDown()` handles keyboard navigation from view to view through `B_TAB` characters. If the view you define is navigable, its `KeyDown()` function should permit `B_SPACE` characters to operate the object and perhaps allow the arrow keys to navigate inside the view. It should also call the inherited version of `KeyDown()` to enable between-view navigation. For example:

         void MyView::KeyDown(const char *bytes, int32 numBytes)
         {
             if ( numBytes == 1 ) {
                 switch ( bytes[0] ) {
                 case B_SPACE:
                     /* mimic a click in the view */
                     break;
                 case B_RIGHT_ARROW:
                     /* move one position to the right in the view */
                     break;
                 case B_LEFT_ARROW:
                     /* move one position to the left in the view */
                     break;
                 default:
                     baseClass::KeyDown(bytes, numBytes);
                     break;
                 }
             }
         }

  If your BView is navigable but needs to respond to `B_TAB` characters—for example, if it permits users to insert tabs in a text string—its `KeyDown()` function should simply grab the characters and not pass them to the inherited function. Users will have to rely on the Option-Tab combination to navigate from your view.

  See also: the Keyboard Information appendix, "B_KEY_DOWN" in the Message Protocols appendix, `BWindow::SetDefaultButton()`, `modifiers()`

  ### KeyUp()

  virtual void `KeyUp(`const char *bytes, int32 numBytes`) `

  Implemented by derived classes to respond to a `B_KEY_UP` message reporting that the user released a key on the keyboard. The same set of keys that produce `B_KEY_DOWN` messages when they're pressed produce `B_KEY_UP` messages when they're released. The bytes and numBytes arguments encode the character mapped to the key the user released; they work exactly like the same arguments passed to `KeyDown()`.

  Some `B_KEY_DOWN` messages are swallowed by the system and are never dispatched by calling `KeyDown()`; others are dispatched, but not to the focus view. In contrast, all `B_KEY_UP` messages are dispatched by calling `KeyUp()` for the focus view of the active window. Since the focus view and active window can change between the time a key is pressed and the time it's released, this may or may not be the same BView that was notified of the `B_KEY_DOWN` message.

  See also: `KeyDown()`, "B_KEY_DOWN" in the Message Protocols appendix

  ### MouseDown()

  virtual void `MouseDown(` BPoint point`) `

  `MouseDown()` is a hook function that's invoked when the user depresses a mouse button (or other pointing device button, not including joysticks). The location of the cursor at the time of the event is given by point in the BView's coordinates. See `B_MOUSE_DOWN` for the message format. Also see `SetMouseEventMask()` for information on extending the view's event mask while the mouse is being held down.

  The BView version of `MouseDown()` is empty.

  ### MouseMoved()

  virtual void `MouseMoved(` BPoint point, uint32 transit, const BMessage *message`) `

  Implemented by derived classes to respond to reports of mouse-moved events associated with the view. As the user moves the cursor over a window, the Application Server generates a continuous stream of messages reporting where the cursor is located.

  The first argument, point, gives the cursor's new location in the BView's coordinate system. The second argument, transit, is one of four constants,

  `B_ENTERED_VIEW`
  `B_INSIDE_VIEW`
  `B_EXITED_VIEW`
  `B_OUTSIDE_VIEW`

  which explains whether the cursor has just entered the visible region of the view, is now inside the visible region having previously entered, has just exited from the view, or is currently outside the visible region of the view. When the cursor passes from one view to another, `MouseMoved()` is called on each of the BViews, once with a transit code of `B_EXITED_VIEW` and the other with a code of `B_ENTERED_VIEW`.

  If the user is dragging a bundle of information from one location to another, the final argument, message, is a pointer to the BMessage object that holds the information. If a message isn't being dragged, message is `NULL`.

  The default version of `MouseMoved()` is empty.

  ### MouseUp()

  virtual void `MouseUp(` BPoint point`) `

  Implemented by derived classes to respond to a message reporting a mouse-up event within the view. The location of the cursor at the time of the event is given by point in the BView's coordinates.

  ### Pulse()

  virtual void `Pulse(`void`) `

  Implemented by derived classes to do something at regular intervals. Pulses are regularly timed events, like the tick of a clock or the beat of a steady pulse. A BView receives `Pulse()` notifications when no other messages are pending, but only if it asks for them with the `B_PULSE_NEEDED` flag.

  The interval between `Pulse()` calls can be set with BWindow's `SetPulseRate()` function. The default interval is around 500 milliseconds. The pulse rate is the same for all views within a window, but can vary between windows.

  Derived classes can implement a `Pulse()` function to do something that must be repeated continuously. However, for time-critical actions, you should implement your own timing mechanism.

  The BView version of this function is empty.

  See also: `SetFlags()`, the BView constructor, `BWindow::SetPulseRate()`

  ### ResizeToPreferred() see GetPreferredSize()

  ### TargetedByScrollView()

  virtual void `TargetedByScrollView(` BScrollView *scroller`)`

  Implemented by derived classes to respond to a notification that the BView has become the target of the scroller BScrollView object. This function is called when the BScrollView sets its target, which it does on construction. The target is the object whose contents will be scrolled.

  BView's implementation of this function is empty.

  See also: the BScrollView class, and the various scrolling-related functions in Input-Related Functions.

  ### WindowActivated()

  virtual void `WindowActivated(`bool active`) `

  Implemented by derived classes to take whatever steps are necessary when the BView's window becomes the active window, or when the window gives up that status. If active is `true`, the window has become active. If active is `false`, it no longer is the active window.

  All objects in the view hierarchy receive `WindowActivated()` notifications when the status of the window changes.

  BView's version of this function is empty.

  See also: `BWindow::WindowActivated()`

  The Interface Kit Table of Contents | The Interface Kit Index

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

  Copyright © 2000 Be, Inc. All rights reserved..