# BDeskbar Use Cases and Implementation Details:

This document describes the BDeskbar interface and some basics of how it is implemented. The document has the following sections:

1. BDeskbar Interface
2. BDeskbar Use Cases
3. BDeskbar Implementation

## BDeskbar Interface:

The BDeskbar class is a simple class for getting information from the deskbar and for modifying it from your application. The best source of source of information for the BDeskbar interface can be found here in the Be Book.

## BDeskbar Use Cases:

The following use cases cover the BDeskbar functionality:

1. Construction: A BDeskbar does not take any arguments when it is constructed. The BDeskbar instance creates a connection to the deskbar in order to get and change its state.

2. Destruction: When a BDeskbar is deconstructed, the application's connection to the deskbar is closed. However any change to the deskbar's state made through the BDeskbar instance persists.

3. Add Item 1: The AddItem() member function can be used to take a passed in pointer to a BView and send it to the deskbar for inclusion in its shelf. This BView must be archivable and must be exported by the application (for details on how to do this, this article may help). The item will be added and the id of the new item will be passed back to the caller through a pointer to an int32.

4. Add Item 2: The AddItem() member function can be used to add an item to the deskbar shelf by passing a pointer to an entry_ref. The file pointed to by this entry_ref should be an addon that exports the symbol "BView *instantiate_deskbar_item(float, float)". This entry point is used to get a BView which it can display in the shelf. More information on this mechanism can be found in the Deskbar Release Notes but not in the Be Book proper. The item id of the added item is passed back in an int32 pointer provided by the caller.
   NOTE: The source code for the Deskbar found in TReplicantTray::LoadAddon() indicates that it also looks for a symbol called "BView *instantiate_deskbar_entry(image_id, entry_ref*, float, float)" first, but there is no documentation on this.

5. Remove Item 1: The RemoveItem() member function takes an integer id and removes it from the deskbar shelf if it exists. The member returns B_OK at all times (unless the deskbar is not running or some communication failure occurs). A B_OK result does not mean that an item was actually removed.

6. Remove Item 2: The RemoveItem() member function also takes a string name and removes it from the deskbar shelf if it exists. The member returns B_OK at all times (unless the deskbar is not running or some communication failure occurs). A B_OK result does not mean that an item was actually removed.

7. Count Items: The CountItems() member function takes no arguments. It returns the number of "items" in the deskbar shelf. For example, the small email icon often found in the deskbar is one such item.

8. Has Item 1: The HasItem() member function takes a integer id and returns a true or false value which indicates whether or not an item exists in the deskbar shelf on that id. For example, the small email icon often found in the deskbar is one such item.

9. Has Item 2: The HasItem() member function also takes a string name parameter and returns a true or false value which indicates whether or not an item by than name exists in the deskbar shelf. For example, the small email icon often found in the deskbar is named "mail".

10. Get Item Info 1: The GetItemInfo() member function takes an integer id and a pointer to a const char * (ie a string). It checks to see if the id passed in exists in the deskbar and sets the value of the const char * to point to a allocated buffer which contains the name of the item which corresponds to this id and the function returns B_OK. Ownership of this allocated buffer is assigned to the caller of this member function so it is up to the caller to free the memory. If the id doesn't exist, then it still returns B_OK but the pointer to the string is set to NULL. If the pointer to the string passed in is NULL, the function returns B_BAD_VALUE.

11. Get Item Info 2: The GetItemInfo() member also takes a string (const char *) name and a pointer to an int. If the name matches an item in the deskbar shelf, the id of this item is returned at the location pointed to by the integer pointer and the member returns B_OK. If the name doesn't match an item in the deskbar shelf, the id is set to -1. If the pointer passed in is NULL, the function returns B_BAD_VALUE.

12. Frame: The Frame() member function returns a BRect which describes the location and size of the deskbar on the screen.

13. Location: The Location() member function returns one of B_DESKBAR_TOP, B_DESKBAR_BOTTOM, B_DESKBAR_LEFT_BOTTOM, B_DESKBAR_RIGHT_BOTTOM, B_DESKBAR_LEFT_TOP or B_DESKBAR_RIGHT_TOP. The return value describes where the deskbar currently is located. Also, the Location() member function takes an optional argument which is a pointer to a boolean. If supplied, the boolean which is pointed to is set to true if the deskbar is expanded and false otherwise. A deskbar can only be contracted (ie not expanded) when in the left or right top position.

14. Is Expanded: The IsExpanded() member function returns true if the deskbar is expanded and false if it is contracted. Note, the deskbar can only be contracted when in left or right top position.

15. Set Location: The SetLocation() member function takes the same values returned by the Location() member. The value passed in the first argument sets the position of the deskbar. If the optional second argument is supplied, it is a boolean which indicates whether or not the deskbar is expanded (true) or contracted (false). Note, the deskbar can only be contracted when in left or right top position.

16. Expand: The Expand() member function takes a single boolean argument which sets the deskbar to expanded (true) or contracted (false) mode. Note, the deskbar can only be contracted when in left or right top position.

## BDeskbar Implementation:

Internally, the BDeskbar uses a BMessenger to communicate with the deskbar itself.
The code which handles communicating with the BDeskbar is described below.

### AddItem:

The AddItem() member sends the following message to the deskbar to add an item from an archived BView:

    BMessage theMsg;
    BMessage viewMsg;
    theView.Archive(&viewMsg);              // This takes the target BView to place in the shelf and archives it into viewMsg
    theMsg.what = 'icon'
    theMsg.AddMessage("view", &viewMsg);    // This puts the archived view in the viewMsg and puts it in the message to the deskbar

Or, the AddItem() member sends the following message to the deskbar to add an item from a file that exports the "BView *instantiate_deskbar_item(float, float)" function:

    BMessage theMsg;
    theMsg.what = 'adon'
    theMsg.AddRef("addon", &theAddonRef);    // This is the addon which contains the hook function to get the view to add

The /boot/app/Pulse application exports the necessary symbol for this mechanism to work and is a good candidate to test with.

In either case, the deskbar responds with a message which looks like:

    BMessage theMsg;
    theMsg.AddInt32("id", theID);         // This is the id of the new item

Note that in both cases, the deskbar does not set the what code of the reply. Checking the source code for TBarWindow::AddItem() confirms this.

### HasItem:

The HasItem() member sends the following message to the deskbar:

    BMessage theMsg;
    theMsg.what = 'exst'
    theMsg.AddInt32("id", theID);         // This is the id to check for
       // OR, only one of id or name should be in the message
    theMsg.AddString("name", theName);    // This is the name to check for

The deskbar responds with a message which looks like:

    BMessage theMsg;
    theMsg.AddBool("exists", IDorNameExists());    // This is a true/false value which indicates whether or not the name/id exists in the shelf

Note that the deskbar does not set the what code of the reply. Checking the source code for TBarWindow::ItemExists() confirms this.

### GetItemInfo:

The GetItemInfo() member sends the following message to the deskbar:

    BMessage theMsg;
    theMsg.what = 'info'
    theMsg.AddInt32("id", theID);         // This is the id to check for
       // OR, only one of id or name should be in the message
    theMsg.AddString("name", theName);    // This is the name to check for

The deskbar responds with a message which looks like:

    BMessage theMsg;
    theMsg.AddString("name", theName);    // This is the name corresponding to the id of the original request
       // OR, only one of id or name should be in the response message depending on the request sent
    theMsg.AddInt32("id", theID);         // This is the id corresponding to the name of the original request

Note that the deskbar does not set the what code of the reply. Checking the source code for TBarWindow::ItemInfo() confirms this.

### CountItems:

The CountItems() member sends the following message to the deskbar:

    BMessage theMsg;
    theMsg.what = 'cwnt'

The deskbar responds with a message which looks like:

    BMessage theMsg;
    theMsg.what = 'rply';                     // This means reply
    theMsg.AddInt32("count", ItemCount());    // This is the number of items in the deskbar shelf

### RemoveItem:

The RemoveItem() member sends the following message to the deskbar:

    BMessage theMsg;
    theMsg.what = 'remv'
    theMsg.AddInt32("id", theID);         // This is the id to remove
       // OR, only one of id or name should be in the message
    theMsg.AddString("name", theName);    // This is the name to remove

The deskbar does not send a response.

### Frame:

The Frame() member sends a standard scripting message to get the frame from the deskbar. It sends a B_GET_PROPERTY message to the deskbar asking for the "Frame" property specifying the window by name. The window name is "Deskbar".

The response from deskbar has a what code of B_REPLY and a BRect describing the frame in a value called "result". This is standard BeOS scripting.

### Location:

The Location() member sends the following message to the deskbar:

    BMessage theMsg;
    theMsg.what = 'gloc';    // This means get location

The deskbar responds with a message which looks like:

    BMessage theMsg;
    theMsg.what = 'rply';                              // This means reply
    theMsg.AddInt32("location", DeskbarLocation());    // This is the number which represents the location of the deskbar
    theMsg.AddBool("expanded", Expanded());            // This is true if the deskbar is expanded, false otherwise

### IsExpanded:

The IsExpanded() member sends the following message to the deskbar:

    BMessage theMsg;
    theMsg.what = 'gexp';    // This means get expanded state

The deskbar responds with a message which looks like:

    BMessage theMsg;
    theMsg.what = 'rply';                      // This means reply
    theMsg.AddBool("expanded", Expanded());    // This is true if the deskbar is expanded, false otherwise

### SetLocation:

The SetLocation() member sends the following message to the deskbar:

    BMessage theMsg;
    theMsg.what = 'sloc';                        // This means set location
    theMsg.AddInt32("location", newLocation);    // This is the number which represents the location of the deskbar
    theMsg.AddBool("expand", isExpanded);        // This is true if the deskbar is expanded, false otherwise

The deskbar does not send a reply to this message.

### Expand:

The Expand() member sends the following message to the deskbar:

    BMessage theMsg;
    theMsg.what = 'sexp';                     // This means set expanded state
    theMsg.AddBool("expand", isExpanded);     // This is true if the deskbar is expanded, false otherwise

The deskbar does not send a reply to this message.