hide random home http://www.be.com/documentation/be_book/interface/View.html (Amiga Plus Extra No. 5/97, 05/1997)


The Interface Kit: BView

Derived from: public BHandler

Declared in: <interface/View.h>


Overview

BView objects are the agents for drawing and message handling within windows. Each object sets up and takes responsibility for a particular view, a rectangular area that's associated with at most one window at a time. The object draws within the view rectangle and responds to reports of events elicited by the images drawn.

Classes derived from BView implement the actual functions that draw and handle messages; BView merely provides the framework. For example, a BTextView object draws and edits text in response to the user's activity on the keyboard and mouse. A BButton draws the image of a button on-screen and responds when the button is clicked. BTextView and BButton inherit from the BView class--as do most classes in the Interface Kit.

The following kit classes derive, directly or indirectly, from BView:

BScrollBar BControl BMenu
BScrollView BButton BMenuBar
BStatusBar BPictureButton BMenuField
BDragger BRadioButton BPopUpMenu
BBox BCheckBox BListView
BStringView BColorControl BOutlineListView
BTextView BTextControl

Serious applications will need to define their own classes derived from BView.


Views and Windows

For a BView to do its work, you must attach it to a window. The views in a window are arranged in a hierarchy--there can be views within views--with those that are most directly responsible for drawing and message handling located at the terminal branches of the hierarchy and those that contain and organize other views situated closer to its trunk and root. A BView begins life unattached. You can add it to a hierarchy by calling the AddChild() function of the BWindow or of another BView.

Within the hierarchy, a BView object plays two roles:

The relationship of BViews to BWindows and the framework for drawing and responding to the user were discussed in the introduction to this chapter. The concepts and terminology presented there are assumed in this class description. See especially BView Objects , The View Hierarchy , Drawing beginning on page 19, and Responding to the User beginning on page 39.

BViews can also be called upon to create bitmap images. See the BBitmap class for details.


Locking the Window

If a BView is attached to a window, any operation that affects the view might also affect the window and the BView's shadow counterpart in the Application Server. For this reason, any code that calls a BView function should first lock the window--so that one thread can't modify essential data structures while another thread is using them. A window can be locked by only one thread at a time.

Locking is accomplished through the BLooper Lock() and Unlock() functions inherited by BWindow:

   if ( Window()->Lock() ) {
       . . .
       Window()->Unlock();
   }

Before they do anything else, almost all BView functions check to be sure the caller has the window locked. If the window isn't properly locked, they print warning messages and fail.

Of course, a BView function can require the window to be locked only if the view has a window to lock; the requirement can't be enforced if the BView isn't attached to a window. However, as discussed under Views and the Server of the introduction to this chapter, some BView functions don't work at all unless the view is attached--in which case the window must be locked.

Whenever the system calls a BView function to notify it of something--whenever it calls WindowActivated(), Draw(), MessageReceived() or another hook function--it first locks the window thread. The application doesn't have to explicitly lock the window when responding to an update, an interface message, or some other notification; the window is already locked.


Derived Classes

When it comes time for a BView to draw, its Draw() virtual function is called automatically. When it needs to respond to an event, a virtual function named after the kind of event is called--MouseMoved(), KeyDown(), and so on. Classes derived from BView implement these hook functions to do the particular kind of drawing and message handling characteristic of the derived class.

Almost all the BView classes defined in the Interface Kit fall into the first two of these groups. Control devices and organizational views can serve a variety of different kinds of applications, and therefore can be implemented in a kit that's common to all applications.

However, the BViews that will be central to most applications fall into the last two groups. Of particular importance are the BViews that manage editable data. Unfortunately, these are not views that can be easily implemented in a common kit. Just as most applications devise their own data formats, most applications will need to define their own data-handling views.

Nevertheless, the BView class structures and simplifies the task of developing application-specific objects that draw in windows and interact with the user. It takes care of the lower-level details and manages the view's relationship to the window and other views in the hierarchy. You should make yourself familiar with this class before implementing your own application-specific BViews.


Hook Functions

AllAttached() Can be implemented to finish initializing the BView after it's attached to a window, where the initialization depends on a descendant view's AttachedToWindow() function having been called.
AllDetached() Can be implemented to prepare the BView for being detached from a window, where the preparations depend on a descendant view's DetachedFromWindow() function having been called.
AttachedToWindow() Can be implemented to finish initializing the BView after it becomes part of a window's view hierarchy.
DetachedFromWindow() Can be implemented to prepare the BView for its impending removal from a window's view hierarchy.
Draw() Can be implemented to draw the view.
FrameMoved() Can be implemented to respond to a message notifying the BView that it has moved in its parent's coordinate system.
FrameResized() Can be implemented to respond to a message informing the BView that its frame rectangle has been resized.
GetPreferredSize() Can be implemented to calculate the optimal size of the view.
KeyDown() Can be implemented to respond to a message reporting character input from the keyboard (a key-down event).
KeyUp) Can be implemented to respond to a message reporting a key-up event.
MakeFocus() Makes the BView the focus view, or causes it to give up being the focus view; can be augmented to take any action the change in status may require.
MouseDown() Can be implemented to respond to a message reporting a mouse-down event.
MouseMoved() Can be implemented to respond to a notification that the cursor has entered the view's visible region, moved within the visible region, or exited from the view.
Pulse() Can be implemented to do something at regular intervals. This function is called repeatedly when no other messages are pending.
TargetedByScrollView() Can be implemented to react when the BView becomes the target of a BScrollView.
WindowActivated() Can be implemented to respond to a notification that the BView's window has become the active window, or has lost that status.


Constructor and Destructor


BView()


      BView(BRect frame, const char *name, uint32 resizingMode, uint32 flags) 
      BView(BMessage *archive) 

Sets up a view with the frame rectangle, which is specified in the coordinate system of its eventual parent, and assigns the BView an identifying name, which can be NULL.

When it's created, a BView doesn't belong to a window and has no parent. It's assigned a parent by having another BView adopt it with the AddChild() function. If the other view is in a window, the BView becomes part of that window's view hierarchy. A BView can be made a child of the window's top view by calling BWindow's version of the AddChild() function.

When the BView gains a parent, the values in frame are interpreted in the parent's coordinate system. The sides of the view must be aligned on screen pixels. Therefore, the frame rectangle should not contain coordinates with fractional values. Fractional coordinates will be rounded to the nearest whole number.

The resizingMode mask determines the behavior of the view when its parent is resized. It should combine one constant for horizontal resizing,

B_FOLLOW_LEFT
B_FOLLOW_RIGHT
B_FOLLOW_LEFT_RIGHT
B_FOLLOW_H_CENTER

with one for vertical resizing:

B_FOLLOW_TOP
B_FOLLOW_BOTTOM
B_FOLLOW_TOP_BOTTOM
B_FOLLOW_V_CENTER

For example, if B_FOLLOW_LEFT is chosen, the margin between the left side of the view and the left side of its parent will remain constant--the view will "follow" the parent's left side. Similarly, if B_FOLLOW_RIGHT is chosen, the view will follow the parent's right side. If B_FOLLOW_H_CENTER is chosen, the view will maintain a constant relationship to the horizontal center of the parent.

If the constants name opposite sides of the view rectangle--left and right, or top and bottom--the view will necessarily be resized in that dimension when the parent is. For example, B_FOLLOW_LEFT_RIGHT means that the margin between the left side of the view and left side of the parent will remain constant, as will the margin between the right side of the view and the right side of the parent. As the parent is resized horizontally, the child will be resized with it. Note that B_FOLLOW_LEFT_RIGHT is not the same as combining B_FOLLOW_LEFT and B_FOLLOW_RIGHT, an illegal move. The resizingMode mask can contain only one horizontal constant and one vertical constant.

If a side is not mentioned in the mask, the distance between that side of the view and the corresponding side of the parent is free to fluctuate. This may mean that the view will move within its parent's coordinate system when the parent is resized. B_FOLLOW_RIGHT plus B_FOLLOW_BOTTOM, for example, would keep a view from being resized, but the view will move to follow the right bottom corner of its parent whenever the parent is resized. B_FOLLOW_LEFT plus B_FOLLOW_TOP prevents a view from being resized and from being moved.

In addition to the constants listed above, there are two other possibilities:

B_FOLLOW_ALL_SIDES
B_FOLLOW_NONE

B_FOLLOW_ALL_SIDES is a shorthand for B_FOLLOW_LEFT_RIGHT and B_FOLLOW_TOP_BOTTOM. It means that the view will be resized in tandem with its parent, both horizontally and vertically.

B_FOLLOW_NONE keeps the view at its absolute position on-screen; the parent view is resized around it. (Nevertheless, because the parent is resized, the view may wind up being moved in its parent's coordinate system.)

Typically, a parent view is resized because the user resizes the window it's in. When the window is resized, the top view is too. Depending on how the resizingMode flag is set for the top view's children and for the descendants of its children, automatic resizing can cascade down the view hierarchy. A view can also be resized programmatically by the ResizeTo() and ResizeBy() functions.

The resizing mode can be changed after construction with the SetResizingMode() function.

The flags mask determines what kinds of notifications the BView will receive. It can be any combination of the following constants:

B_WILL_DRAW Indicates that the BView does some drawing of its own and therefore can't be ignored when the window is updated. If this flag isn't set, the BView won't receive update notifications--its Draw() function won't be called--and it won't be erased to its background view color if the color is other than white.
B_PULSE_NEEDED Indicates that the BView should receive Pulse() notifications.
B_FRAME_EVENTS Indicates that the BView should receive FrameResized() and FrameMoved() notifications when its frame rectangle changes--typically as a result of the automatic resizing behavior described above. FrameResized() is called when the dimensions of the view change; FrameMoved() is called when the position of its left top corner in its parent's coordinate system changes.
B_FULL_UPDATE_ON_RESIZE Indicates that the entire view should be updated when it's resized. If this flag isn't set, only the portions that resizing adds to the view will be included in the clipping region.
B_NAVIGABLE Indicates that the BView can become the focus view for keyboard actions. This flag makes it possible for the user to navigate to the view and put it in focus by pressing the Tab key. See Keyboard Navigation at the beginning of this chapter.
B_NAVIGABLE_JUMP Marks the position of a group of views for keyboard navigation. By pressing Control-Tab, the user can jump from group to group. The focus lands on the first BView in the group that has the B_NAVIGABLE flag set. This may be the same BView that has the B_NAVIGABLE_JUMP marker, or the B_NAVIGABLE_JUMP BView may be the parent of a group of B_NAVIGABLE views.

If none of these constants apply, flags can be NULL. The flags can be reset after construction with the SetFlags() function.

See also: SetResizingMode(), SetFlags(), BHandler::SetName()


~BView()


      virtual ~BView(void)

Frees all memory the BView allocated, and ensures that each of the BView's descendants in the view hierarchy is also destroyed.

It's an error to delete a BView while it remains attached to a window. Call RemoveChild() or RemoveSelf() before using the delete operator.

See also: RemoveChild()


Static Functions


Instantiate()


      static BView *Instantiate(BMessage *archive) 

Returns a new BView object, allocated by new and created with the version of the constructor that takes a BMessage archive. However, if the message doesn't contain archived data for a BView, Instantiate() returns NULL.

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


Member Functions


AddChild(), RemoveChild()


      void AddChild(BView *aView, BView *sibling = NULL) 

      bool RemoveChild(BView *aView)

AddChild() makes aView a child of the BView, provided that aView doesn't already have a parent. The new child is added to the BView's list of children immediately before the named sibling BView. If the sibling is NULL (as it is by default), aView isn't added in front of any other view--in other words, it's added to the end of the list. If the BView is attached to a window, aView and all its descendants become attached to the same window. Each of them is notified of this change through AttachedToWindow() and AllAttached() function calls.

AddChild() fails if aView already belongs to a view hierarchy. A view can live with only one parent at a time. It also fails if sibling is not already a child of the BView.

RemoveChild() severs the link between the BView and aView, so that aView is no longer a child of the BView; aView retains all its own children and descendants, but they become an isolated fragment of a view hierarchy, unattached to a window. Each removed view is notified of this change through DetachedFromWindow() and AllDetached() function calls.

A BView must be removed from a window before it can be destroyed.

If it succeeds in removing aView, RemoveChild() returns true. If it fails, it returns false. It will fail if aView is not, in fact, a current child of the BView.

When a BView object becomes attached to a BWindow, two other connections are automatically established for it:

Removing a BView from a window's view hierarchy also removes it from the BWindow's flat list of BHandler objects; the BView will no longer be eligible to handle messages dispatched by the BWindow.

See also: BWindow::AddChild(), BLooper::AddHandler(), BHandler::SetNextHandler(), RemoveSelf(), AttachedToWindow(), DetachedFromWindow()


AddLine() see BeginLineArray()


AllAttached() see AttachedToWindow()


AllDetached() see DetachedFromWindow()


Archive()


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

Calls the inherited version of Archive(), then records the following BView attributes in the BMessage archive:

The frame rectangle
The resizing mode
The flags mask
All aspects of its current graphics state (font, high and low color, and so on)

If the deep flag is true, all of the BView's descendants in the view hierarchy are also archived. If deep is false, only the BView itself is archived.

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


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());
       inherited::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()


BeginLineArray(), AddLine(), EndLineArray()


      void BeginLineArray(int32 count)

      void AddLine(BPoint start, BPoint end, rgb_color color)

      void EndLineArray(void)

These functions provide a more efficient way of drawing a large number of lines than repeated calls to StrokeLine(). BeginLineArray() signals the beginning of a series of up to count AddLine() calls; EndLineArray() signals the end of the series. Each AddLine() call defines a line from the start point to the end point, associates it with a particular color, and adds it to the array. The lines can each be a different color; they don't have to be contiguous. When EndLineArray() is called, all the lines are drawn--using the then current pen size--in the order that they were added to the array.

These functions don't change any graphics parameters. For example, they don't move the pen or change the current high and low colors. Parameter values that are in effect when EndLineArray() is called are the ones used to draw the lines. The high and low colors are ignored in favor of the color specified for each line.

The count passed to BeginLineArray() is an upper limit on the number of lines that can be drawn. Keeping the count close to accurate and within reasonable bounds helps the efficiency of the line-array mechanism. It's a good idea to keep it less than 256; above that number, memory requirements begin to impinge on performance.

See also: StrokeLine()


BeginPicture(), EndPicture()


      void BeginPicture(BPicture *picture)

      BPicture *EndPicture(void)

BeginPicture() instructs the Application Server to begin recording a set of drawing instructions for a picture. EndPicture() instructs the server to end the recording session; it returns the same object that was passed to BeginPicture().

The BPicture records exactly what the BView would draw--and only what the BView would draw--were the instructions not bracketed by BeginPicture() and EndPicture() calls. The drawing of other views is ignored, as are function calls that don't draw or affect graphics parameters. The picture captures only primitive graphics operations--that is, functions defined in this class, such as DrawString(), FillArc(), and SetFont(). If a complex drawing function (such as Draw()) is called, only the primitive operations that it contains are recorded.

A BPicture can be recorded only if the BView is attached to a window. The window can be off-screen and the view itself can be hidden or reside outside the current clipping region. However, the drawing the BView does will not be seen even if the window is on-screen and the view is visible--it's captured in the picture rather than rendered in the window.

See also: the BPicture class, DrawPicture()


BeginRectTracking(), EndRectTracking()


      void BeginRectTracking(BRect rect, uint32 how = B_TRACK_WHOLE_RECT)

      void EndRectTracking(void)

These functions instruct the Application Server to display a rectangular outline that will track the movement of the cursor. BeginRectTracking() puts the rectangle on-screen and initiates tracking; EndRectTracking() terminates tracking and removes the rectangle. The initial rectangle, rect, is specified in the BView's coordinate system.

This function supports two kinds of tracking, depending on the constant passed as the how argument:

B_TRACK_WHOLE_RECT The whole rectangle moves with the cursor. Its position changes, but its size remains fixed.
B_TRACK_RECT_CORNER The left top corner of the rectangle remains fixed within the view while its right and bottom edges move with the cursor.

Tracking is typically initiated from within a BView's MouseDown() function and is allowed to continue as long as a mouse button is held down. For example:

   void MyView::MouseDown(BPoint point)
   {
       unit32 buttons;
   
       BRect rect(point, point);
       BeginRectTracking(rect, B_TRACK_RECT_CORNER);
       do {
           snooze(30 * 1000);
           GetMouse(&point, &buttons);
       } while ( buttons );
       EndRectTracking();
   
       rect.SetRightBottom(point);
       . . .
   }

This example uses BeginRectTracking() to drag out a rectangle from the point recorded for a mouse-down event. It sets up a modal loop to periodically check on the state of the mouse buttons. Tracking ends when the user releases all buttons. The right and bottom sides of the rectangle are then updated from the cursor location last reported by the GetMouse() function.

See also: ConvertToScreen(), GetMouse()


Bounds()


      BRect Bounds(void) const

Returns the BView's bounds rectangle. If the BView is attached to a window, this function returns the rectangle kept by the Application Server. If not, it returns a rectangle the same size as the BView's frame rectangle, but with the left and top sides at 0.0.

If Bounds() is called during an update, the BView is already aware of the current rectangle (the update message included it); it can therefore return it directly without communicating with the Application Server. However, if called at other times, Bounds() must get the latest rectangle from the server, an interaction that has a certain amount of overhead.

See also: Frame()


ChildAt() see Parent()


ConstrainClippingRegion()


      virtual void ConstrainClippingRegion(BRegion *region)

Restricts the drawing that the BView can do to region.

The Application Server keeps track of a clipping region for each BView that's attached to a window. It clips all drawing the BView does to that region; the BView can't draw outside of it.

By default, the clipping region contains only the visible area of the view and, during an update, only the area that actually needs to be drawn. By passing a region to this function, an application can further restrict the clipping region. When calculating the clipping region, the server intersects it with the region provided. The BView can draw only in areas common to the region passed and the clipping region as the server would otherwise calculate it. The region passed can't expand the clipping region beyond what it otherwise would be.

If called during an update, ConstrainClippingRegion() restricts the clipping region only for the duration of the update.

Calls to ConstrainClippingRegion() are not additive; each region that's passed replaces the one that was passed in the previous call. Passing a NULL pointer removes the previous region without replacing it. The function works only for BViews that are attached to a window.

See also: GetClippingRegion(), Draw()


ConvertToParent(), ConvertFromParent()


      BPoint ConvertToParent(BPoint localPoint) const
      void ConvertToParent(BPoint *localPoint) const

      BRect ConvertToParent(BRect localRect) const
      void ConvertToParent(BRect *localRect) const

      BPoint ConvertFromParent(BPoint parentPoint) const
      void ConvertFromParent(BPoint *parentPoint) const

      BRect ConvertFromParent(BRect parentRect) const
      void ConvertFromParent(BRect *parentRect) const

These functions convert points and rectangles to and from the coordinate system of the BView's parent. ConvertToParent() converts localPoint or localRect from the BView's coordinate system to the coordinate system of its parent BView. ConvertFromParent() does the opposite; it converts parentPoint or parentRect from the coordinate system of the BView's parent to the BView's own coordinate system.

If the point or rectangle is passed by value, the function returns the converted value. If a pointer is passed, the conversion is done in place.

Both functions fail if the BView isn't attached to a window.

See also: ConvertToScreen()


ConvertToScreen(), ConvertFromScreen()


      BPoint ConvertToScreen(BPoint localPoint) const
      void ConvertToScreen(BPoint *localPoint) const

      BRect ConvertToScreen(BRect localRect) const
      void ConvertToScreen(BRect *localRect) const

      BPoint ConvertFromScreen(BPoint screenPoint) const
      void ConvertFromScreen(BPoint *screenPoint) const

      BRect ConvertFromScreen(BRect screenRect) const
      void ConvertFromScreen(BRect *screenRect) const

ConvertToScreen() converts localPoint or localRect from the BView's coordinate system to the global screen coordinate system. ConvertFromScreen() makes the opposite conversion; it converts screenPoint or screenRect from the screen coordinate system to the BView's local coordinate system.

If the point or rectangle is passed by value, the function returns the converted value. If a pointer is passed, the conversion is done in place.

The screen coordinate system has its origin, (0.0, 0.0), at the left top corner of the main screen.

Neither function will work if the BView isn't attached to a window.

See also: BWindow::ConvertToScreen(), ConvertToParent()


CopyBits()


      void CopyBits(BRect source, BRect destination)

Copies the image displayed in the source rectangle to the destination rectangle, where both rectangles lie within the view and are stated in the BView's coordinate system.

If the two rectangles aren't the same size, the source image is scaled to fit.

If not all of the destination rectangle lies within the BView's visible region, the source image is clipped rather than scaled.

If not all of the source rectangle lies within the BView's visible region, only the visible portion is copied. It's mapped to the corresponding portion of the destination rectangle. The BView is then invalidated so its Draw() function will be called to update the part of the destination rectangle that can't be filled with the source image.

The BView must be attached to a window.


CountChildren() see Parent()


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()


DragMessage()


      void DragMessage(BMessage *message, BBitmap *image, BPoint point, 
         BHandler *replyTarget = NULL)
      void DragMessage(BMessage *message, BRect rect, 
         BHandler *replyTarget = NULL)

Initiates a drag-and-drop session. The first argument, message, is a BMessage object that bundles the information that will be dragged and dropped on the destination view. The caller retains responsibility for this object and can delete it after DragMessage() returns; the BView makes a copy.

The second argument, image, represents the message on-screen; it's the visible image that the user drags. Unlike the BMessage, this BBitmap object becomes the responsibility of the system; it will be freed when the message is dropped. If you want to keep the image yourself, make a copy to pass to DragMessage(). The image isn't dropped on the destination BView; if you want the destination to have the image, you must add it to the message as well as pass it as the image argument.

The third argument, point, locates the point within the image that's aligned with the hot spot of the cursor--that is, the point that's aligned with the location passed to MouseDown() or returned by GetMouse(). It's stated within the coordinate system of the source image and should lie somewhere within its bounds rectangle. The bounds rectangle and coordinate system of a BBitmap are set when the object is constructed.

Alternatively, you can specify that an outline of a rectangle, rect, should be dragged instead of an image. The rectangle is stated in the BView's coordinate system. (Therefore, a point argument isn't needed to align it with the cursor.)

The final argument, replyTarget, names the object that you want to handle a message that might be sent in reply to the dragged message. If replyTarget is NULL, as it is by default, any reply that's received will be directed to the BView object that initiated the drag-and-drop session.

This function works only for BViews that are attached to a window.

See also: BMessage::WasDropped(), the BBitmap class


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:

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()


DrawBitmap(), DrawBitmapAsync()


      void DrawBitmap(const BBitmap *image)
      void DrawBitmap(const BBitmap *image, BPoint point)
      void DrawBitmap(const BBitmap *image, BRect destination)
      void DrawBitmap(const BBitmap *image, BRect source, BRect destination)

      void DrawBitmapAsync(const BBitmap *image)
      void DrawBitmapAsync(const BBitmap *image, BPoint point)
      void DrawBitmapAsync(const BBitmap *image, BRect destination)
      void DrawBitmapAsync(const BBitmap *image, BRect source, BRect destination)

These functions place a bitmap image in the view at the current pen position, at the point specified, or within the designated destination rectangle. The point and the destination rectangle are stated in the BView's coordinate system.

If a source rectangle is given, only that part of the bitmap image is drawn. Otherwise, the entire bitmap is placed in the view. The source rectangle is stated in the internal coordinates of the BBitmap object.

If the source image is bigger than the destination rectangle, it's scaled to fit.

The two functions differ in only one respect: DrawBitmap() waits for the Application Server to finish rendering the image before it returns. DrawBitmapAsync() doesn't wait; it passes the image to the server and returns immediately. The latter function can be more efficient in some cases--for example, you might use an asynchronous function to draw several bitmaps and then call Sync() to wait for them all to finish rather than wait for each one individually:

   DrawBitmapAsync(bitmapOne, firstPoint);
   DrawBitmapAsync(bitmapTwo, secondPoint);
   DrawBitmapAsync(bitmapThree, thirdPoint);
   Sync();

Or, if you can cram some useful work between the time you send the bitmap to the Application Server and the time you need to be sure that it has appeared on-screen, DrawBitmapAsync() will free your thread to do that work immediately:

   DrawBitmapAsync(someBitmap, somePoint);
   /* do something else */ 
   Sync();

See also: Drawing Modes in the chapter introduction, the BBitmap class, Sync()


DrawChar()


      void DrawChar(char c)
      void DrawChar(char c, BPoint point)

Draws the character c at the current pen position--or at the point specified--and moves the pen to a position immediately to the right of the character. This function is equivalent to passing a string of one character to DrawString(). The point is specified in the BView's coordinate system.

See also: DrawString()


DrawingMode() see SetDrawingMode()


DrawPicture()


      void DrawPicture(const BPicture *picture)
      void DrawPicture(const BPicture *picture, BPoint point) 

Draws the previously recorded picture at the current pen position--or at the specified point in the BView's coordinate system. The point or pen position is taken as the coordinate origin for all the drawing instructions recorded in the BPicture.

Nothing that's done in the BPicture can affect anything in the BView's graphics state--for example, the BPicture can't reset the current high color or the pen position. Conversely, nothing in the BView's current graphics state affects the drawing instructions captured in the picture. The graphics parameters that were in effect when the picture was recorded determine what the picture looks like.

See also: BeginPicture(), the BPicture class


DrawString()


      void DrawString(const char *string, 
         escapement_delta *delta = NULL)
      void DrawString(const char *string, int32 length, 
         escapement_delta *delta = NULL)
      void DrawString(const char *string, BPoint point, 
         escapement_delta *delta = NULL)
      void DrawString(const char *string, int32 length, BPoint point, 
         escapement_delta *delta = NULL)

Draws the characters encoded in length bytes of string--or, if the number of bytes isn't specified, all the characters in the string, up to the null terminator ('\0'). Characters are drawn in the BView's current font. The font's direction determines whether the string is drawn left-to-right or right-to-left. Its rotation determines the angle of the baseline (horizontal for an unrotated font). The spacing mode of the font determines how characters are positioned within the string and the string width.

This function places the characters on a baseline that begins at the current pen position--or at the specified point in the BView's coordinate system. It draws the characters to the right (assuming an unrotated font) and moves the pen to the baseline immediately past the characters drawn. For a left-to-right font, the pen will be in position to draw the next character, as shown below:

The characters are drawn in the opposite direction for a right-to-left font, but the pen still moves left-to-right:

For a font that's read from left-to-right, a series of simple DrawString() calls (with no point specified) will produce a continuous string. For example, these two lines of code,

   DrawString("tog");
   DrawString("ether");

will produce the same result as this one,

   DrawString("together");

except if the spacing mode is B_STRING_SPACING. Under B_STRING_SPACING, character placements are adjusted keeping the string width constant. The adjustments are contextually dependent on the string and may therefore differ depending on whether there are two strings ("tog" and "ether") or just one ("together").

If a delta argument is provided, DrawString() adds the additional amounts specified in the escapement_delta structure to the width of each character. This structure has two fields:

float nonspace The amount to add to the width of characters that have visible glyphs (that put ink on the printed page).
float space The amount to add to the width of characters that have escapements, but don't have visible glyphs (characters that affect the position of surrounding characters but don't put ink on the page).

When drawing to the screen, DrawString() uses antialiasing--unless the BView's font disables it or the font size is large enough (over 1,000.0 points) so that its benefits aren't required. Antialiasing produces colors at the margins of character outlines that are intermediate between the color of the text (the BView's high color) and the color of the background against which the text is drawn. When drawing in B_OP_COPY mode, antialiasing requires the BView's low color to match the background color.

It's much faster to draw a string in B_OP_COPY mode than in any other mode. If you draw the same string repeatedly in the same location in B_OP_OVER mode without erasing, antialiasing will produce different, and worse, results each time as the intermediate color it previously produced is treated as the new background each time. Antialiasing doesn't produce pleasing results in B_OP_SELECT mode.

This is a graphical drawing function, so any character that doesn't have an escapement or a visible representation (including white space) is replaced by an undefined character that can be drawn (currently an empty box). This includes all control characters (those with values less than B_SPACE, 0x20).

DrawString() doesn't erase before drawing.

See also: MovePenBy(), SetFontName(), the BFont class


EndLineArray() see BeginLineArray()


EndPicture() see BeginPicture()


EndRectTracking() see BeginRectTracking()


FillArc() see StrokeArc()


FillEllipse() see StrokeEllipse()


FillPolygon() see StrokePolygon()


FillRect() see StrokeRect()


FillRegion()


      void FillRegion(BRegion *region, pattern aPattern = B_SOLID_HIGH) const

Fills the region with the pattern specified by aPattern--or, if no pattern is specified, with the current high color. Filling a region is equivalent to filling all the rectangles that define the region.

See also: the BRegion class


FillRoundRect() see StrokeRoundRect()


FillTriangle() see StrokeTriangle()


FindView()


      BView *FindView(const char *name) const

Returns the BView identified by name, or NULL if the view can't be found. Names are assigned by the BView constructor and can be modified by the SetName() function inherited from BHandler.

FindView() begins the search by checking whether the BView's name matches name. If not, it continues to search down the view hierarchy, among the BView's children and more distant descendants. To search the entire view hierarchy, use the BWindow version of this function.

See also: BWindow::FindView(), BHandler::SetName()


Flags() see SetFlags()


Flush(), Sync()


      void Flush(void) const

      void Sync(void) const

These functions flush the window's connection to the Application Server. If the BView isn't attached to a window, neither function has an effect.

For reasons of efficiency, the window's connection to the Application Server is buffered. Drawing instructions destined for the server are placed in the buffer and dispatched as a group when the buffer becomes full. Flushing empties the buffer, sending whatever it contains to the server, even if it's not yet full.

The buffer is automatically flushed on every update. However, if you do any drawing outside the update mechanism--in response to interface messages, for example--you need to explicitly flush the connection so that drawing instructions won't languish in the buffer while waiting for it to fill up or for the next update. You should also flush it if you call any drawing functions from outside the window's thread.

Flush() simply flushes the buffer and returns. It does the same work as BWindow's function of the same name.

Sync() flushes the connection, then waits until the server has executed the last instruction that was in the buffer before returning. This alternative to Flush() prevents the application from getting ahead of the server (ahead of what the user sees on-screen) and keeps both processes synchronized.

It's a good idea, for example, to call


Flags() see SetFlags()


Flush(), Sync()


      void Flush(void) const

      void Sync(void) const

These functions flush the window's connection to the Application Server. If the BView isn't attached to a window, neither function has an effect.

For reasons of efficiency, the window's connection to the Application Server is buffered. Drawing instructions destined for the server are placed in the buffer and dispatched as a group when the buffer becomes full. Flushing empties the buffer, sending whatever it contains to the server, even if it's not yet full.

The buffer is automatically flushed on every update. However, if you do any drawing outside the update mechanism--in response to interface messages, for example--you need to explicitly flush the connection so that drawing instructions won't languish in the buffer while waiting for it to fill up or for the next update. You should also flush it if you call any drawing functions from outside the window's thread.

Flush() simply flushes the buffer and returns. It does the same work as BWindow's function of the same name.

Sync() flushes the connection, then waits until the server has executed the last instruction that was in the buffer before returning. This alternative to Flush() prevents the application from getting ahead of the server (ahead of what the user sees on-screen) and keeps both processes synchronized.

It's a good idea, for example, to call Sync(), rather than Flush(), after employing BViews to produce a bitmap image (a BBitmap object). Sync() is the only way you can be sure the image has been completely rendered before you attempt to draw with it.

(Note that all BViews attached to a window share the same connection to the Application Server. Calling Flush() or Sync() for any one of them flushes the buffer for all of them.)

See also: BWindow::Flush(), the BBitmap class


Frame()


      BRect Frame(void) const

Returns the BView's frame rectangle. The frame rectangle is first set by the BView constructor and is altered only when the view is moved or resized. It's stated in the coordinate system of the BView's parent.

If the BView is not attached to a window, Frame() reports the object's own cached conception of its frame rectangle. If it is attached, Frame() reports the Application Server's conception of the rectangle. When a BView is added to a window, its cached rectangle is communicated to the server. While it remains attached, the functions that move and resize the frame rectangle affect the server's conception of the view, but don't alter the rectangle kept by the object. Therefore, if the BView is removed from the window, Frame() will again report the frame rectangle that it had before it was attached, no matter how much it was moved and resized while it belonged to the window.

See also: