In addition it must implement and export a virtual version of Instantiate called InstantiateView for similar reasons as the UnflattenObject is necessary for IEEditableObject.
Instantiate and InstantiateView does the same, you should implement InstantiateView as
BView *MyEditableView::InstantiateView(BMessage *archive) { return MyEditableView::Instantiate(archive); // call the static function }
status_t EditableBBox::Archive(BMessage *data, bool deep) const { BBox::Archive(data, deep); // replace class with BBox !!! data->RemoveName("class"); data->AddString("class", "BBox"); return B_OK; }
#define SIGNATURE "application/x-company-v3statecheckbox" status_t V3StateCheckBox::Archive(BMessage *data, bool deep) const { BCheckBox::Archive(data, deep); // archive variable definition IEEditableView::Archive(data); // add add-on signature data->AddString("add_on", SIGNATURE); return B_OK; }
You have the choice to link your add-on with the shared ObjectHandlerLib.so or
with the static ObjectHandlerLib.a. It is probably better if you select the static
linking, this way you don't have to ship the ObjectHandlerLib.so library with your
application in the lib
directory.
It is a good idea to exclude the object editor from the add-on when you ship
your application. The add-on file size becomes smaller.
InstantiateView() | Must be implemented to instantiate an object from a message archive. |
UpdateView() | Must be implemented if the view can handle a variable. This method updates the view according to the variable. By default it does nothing. |
UpdateVariable() | Must be implemented if the view can handle a variable. This method updates the variable according to the view. By default it does nothing. |
ViewAdded() | Can be implemented to get notification when a new child view is added to the view. This is almost never needed, only in special cases when a property of an already existing view cannot be changed, only by recreating the view (e.g. BScrollView; the scroll target cannot be changed later after it is set in the constructor). |
ViewRemoved() | Can be implemented to get notification when a new child view is removed. |
IEEditableView(BMessage *data=NULL);The constructor calls the IEEditableObject constructor, clears the
data_types
message, and instantiates the variable definition (variable_definition
).
When you derive from the IEEditableView class, you need to specify the data types it can handle (only if it can handle) in the constructor. The data types are stored in a BMessage named data_types
. The data types are added by data_types->AddString("type", "datatype")
.
The message format for data_types
:
Data name | Type code | Description |
---|---|---|
"type" | B_STRING_TYPE | Data type name, e.g. "int32", "bool", "BFont" |
Don't forget that you also have to specify the add-on info and base classes in the constructor.
For an example see the IEEditableObject constructor.
In addition to the standard information you need to specify a view flag
which provides more information about the view behaviour.
Data name | Type code | Description |
---|---|---|
"ViewFlags" | B_INT32_TYPE | View attributes, see below |
Use the combination of these constants (e.g. "info.AddInt32("ViewFlags", IEEV_CANNOT_HAVE_CHILDREN);
" if you want to prevent the user from adding a child view
to your view):
Name | Description |
---|---|
IEEV_FLAGS_NONE |
No special flags. This is the default. |
IEEV_CANNOT_HAVE_CHILDREN |
The view will not be allowed to have children during editing. This is useful for many views, e.g. it makes no sense for a BButton to have children. The user will be warned if he wants to add a child view to another view which has this flag set. |
IEEV_NOT_RESIZABLE |
The view cannot be resized by the user in the editor. Use this if the size is computed and maintained by the view automatically. |
IEEV_DO_NOT_SHOW_IN_PALETTE |
If the view is an abstract class and you don't want it to appear in the 'Object Editors' window, set this flag. |
IEEV_FORCE_FULL_UPDATE_ON_RESIZE |
Set this flag if the view behaves badly during resizing (e.g. BBox). This causes the B_FULL_UPDATE_ON_RESIZE set for the given view during resizing. |
virtual ~IEEditableView(void);Does nothing.
void Archive(BMessage *data) const;
Flatten is implemented in IEEditableView so that it can archive the variable settings.
Therefore be sure to call IEEditableView::Archive()
in the Archive method
of the derived class.
void AdjustParentViewFrame(void);
Call this if the frame of the view changes to ensure that the parent view has the same size. It is necessary only during editing.
int32 GetUniqueID(void);
Returns a window-wide unique ID which is useful for creating unique BMessages.
virtual BView *InstantiateView(BMessage *archive)=0;
This is mandatory to implement, and has the same functionality as the static Instantiate function (which you have to implement too). It is sufficient if you implement it as
BView *MyEditableView::InstantiateView(BMessage *archive) { return MyEditableView::Instantiate(archive); // call the static function }
BMessage *GetAvailableTypes(void);
It returns the data_types
message which stores the data types which this
view can handle. If you don't add new data type in the constructor, this message will be empty.
virtual void SetVariable(void *pointer, const char *type=NULL); virtual void *Variable(void);
Sets and returns the variable address which the view operates on. If type is NULL it will not be changed.
There is no need to override these methods.
virtual void UpdateVariable(void);
You have to implement UpdateVariable only if your view is able to handle a variable. The purpose of this method is to convert the state of the view to the variable.
E.g. if a view displays a text, but there is a long variable type set, UpdateVariable has to convert the text to the long variable. This way all variable conversion tasks are done by the add-on, not the user.
virtual void UpdateView(void);
You have to implement UpdateView only if your view is able to handle a variable. The purpose of this method is to update a view according to the variable value.
E.g. if a view displays a text, but there is a long variable type set, UpdateView has to convert the long to text and display it in the view. This way all variable conversion tasks are done by the add-on, not the user.
virtual bool ViewAdded(BView *new_child, BView **new_view=NULL);
Can be implemented to get notification when a new child view is added to the view. This is almost never needed, only in special cases when a property of an already existing view cannot be changed, only by recreating the view (e.g. BScrollView; the scroll target cannot be changed later after it is set in the constructor).
If you recreate the view, you need to return the new view in new_view
and return false
.
Return true
if you want to refuse adding the new view.
By default this method returns false
.
virtual void ViewRemoved(void);
Can be implemented to get notification when a new child view is removed. In most cases this hook function is not needed.