[Previous] [Contents] [Index] [Next]

Binding Widgets into PhAB

This chapter discusses adding custom widgets to PhAB, including widget design considerations as well as the steps to follow for:


Note: Since PhAB hasn't been linked to include your custom widget, PhAB won't be able to display it. Instead, PhAB will display a default widget (PtBasic or PtContainer) in its place for visual feedback and dimensions.

The Control Panel will let you access all the resources and callbacks you defined in the widget description table for your custom widget, but they won't take effect until you actually run the application.


Widget design considerations

This section describes the issues you need to consider when you add custom widgets to the PhAB widget bar:

Single-value resources

PhAB has builtin editors for handling certain types of single-value resources. It also provides multiple-value editors for some resource types. If you design your resources to use the types supported by PhAB, developers will be able to use the widget in PhAB easily. If you define resources that have no associated editor in PhAB, developers will be able to set and use these resources only through application code. The list of currently supported types can be found in the section on "Creating a widget description table."

When to add custom widgets to palette files

When you define a widget class, you assign it a widget number. This number is combined with the resource number to create a series of unique resource numbers for the widget. When you add the widget to the PhAB widget palette, you define these resource values in the widget palette file.

PhAB uses these numbers when it stores the widget in the module files. If you change the resource number or widget number after it has been used in a PhAB application, you won't be able to continue using the old widget (defined in the PhAB module) because the resource numbers will no longer match. For this reason, you should add widgets to the PhAB palette file only when almost all the widget's functionality has been completed and the resource numbers will no longer change.

Displaying your custom widget

Since PhAB doesn't link your widget directly into its executable, you won't be able to see the widget change visually when you make changes to the resources. The widget will display properly when you actually compile, link, and test the application.

Remember to include the widget header file in the application header so that the generated abmain.c file will know about your widget. Also, add your widget to the MYOBJ object list in the Makefile.


Note: If you're using Watcom 10.6 or later, the MYOBJ object list will be defined in the indOfiles file.

Creating an icon for the PhAB widget bar

Widget icons are stored in picture modules. A picture module can contain any number of widgets icons. You can create icons in PhAB by creating an application with a single picture module (see "Importing a picture module" below).

In the picture module, create a PtBitmap widget for each custom widget you build. To ensure that your icons fit in the widget bar, make each of these PtBitmap widgets 20 pixels high and 28 pixels wide.

Using the pixmap editor, draw a picture that represents the type of custom widget you built.

Give the PtBitmap widget an instance name. The instance name must be formatted as follows:

classname_wgt

For example, you could call a PtSlider widget PtSlider_wgt.

Importing a picture module

A good way to create a new picture module is to import one of PhAB's existing palette picture modules. To do this:

  1. Create a new PhAB application.
  2. Choose the Import/PhAB module option.
  3. Change to the /qnx4/phtk/appbuilder directory and load the ptpalette.wgtp file.

    This will show you an example layout that works well in the PhAB widget selector. This picture module has a lot more widgets than just the PtBitmap widgets; when PhAB loads the picture module as a database, any widget that isn't a PtBitmap widget (i.e. whose name doesn't conform to the classname_wgt naming convention) will be ignored.

  4. Delete all the icons you don't need and leave yourself enough to match the number of custom widgets you've made.
  5. Use the pixmap editor to change the icon(s) into something appropriate for your widget(s).
  6. Rename the instance name to match your widget's class name (e.g. ShadowedBox_wgt).
  7. Rename the picture module from ptpalette to another name of your preference.
  8. Save the application.

Creating a widget description table

The description table for a single widget is stored in a widget palette file. The widget description table must describe all the resources and callbacks your custom widget understands.

The palette file can contain any number of widget description tables but must contain at least one. The name of your palette file must end with a .pal extension (e.g. mywidgets.pal). To get a good idea of what a palette file should contain, look at the /qnx4/phtk/appbuilder/ptpalette.pal file.

The start of a new widget in the file is defined by a widget class name definition. This is followed by the widget hierarchy, resources, callbacks, type definition, and finally some initial default values to use when the widget is first created.

The widget description table defines the following settings:

Widget class name (w=)

This setting starts the definition of a new widget:

w=class_name

Example:

w=ShadowedBox

Note: Don't include spaces before or after the equals sign (=).

When PhAB encounters a class name setting, it allocates space in its internal list for the widget. Any settings found afterwards are applied to this widget until a new widget class name setting is encountered.

Widget hierarchy (h=)

This setting defines the widget hierarchy:

h=number_of_levels
highest_class_name
[next_highest_class_name]
...
custom_widget_class_name

Example:

h=3
PtWidget
PtBasic
ShadowedBox

The h= setting indicates the number of levels in the hierarchy. This is followed by the widget class hierarchy names in descending order of inheritance.

The widget hierarchy setting tells PhAB which class in the widget's hierarchy to use when different classes of widgets are selected. For example, if you select a PtLabel and PtButton widget at the same time, the PhAB Control Panel must show you resources that apply to both widgets. PhAB does this by walking up the hierarchy list until it finds the identical class name for both widgets.

List of resources (r=)

If you want to be able to edit a resource in PhAB, you'll need either an r= entry (for new resources or inherited resources with a different default value) or an i= entry (for inherited resources) - see "Inherited resources and callbacks (i=, n=)" below.

The r= setting defines a resource for the widget:

r=manifest_name,desc_name,resource_no,reserved,select_ind,type,default_value[,additional_info]
[additional_info_1
additional_info_2
...
additional_info_n]

Example:

r=SBW_SHADOW_COLOR,Shadow Color,5000000,0,1,crgb,0x0
r=Pt_ARG_HORIZONTAL_ALIGNMENT,Horizontal Alignment,3000,0,1,short,2,3
Pt_LEFT,0
Pt_RIGHT,1
Pt_CENTER,2

Note: Don't create resource entries for the Pt_ARG_POS and Pt_ARG_DIM resources. All widgets must support these, so PhAB handles them internally.

The arguments of the resource entry have the following meanings:

manifest_name
The valid C manifest name to access this resource from application code.
desc_name
A descriptive version of the manifest name, which is easier to understand and takes up less space (allowing the Control Panel to stay small).
resource_no
The actual resource number (e.g. Pt_USER(0)=5000000, Pt_USER(1)=5001000, and so on - Pt_RESOURCE(Pt_USER(2),5)=5002005).
reserved
Always use a value of 0.
select_ind
Indicates whether this resource supports multiple selections. A value of 0 will hide the resource when two or more widgets are selected. A value of 1 enables the resource.
type
Indicates the type of editor PhAB should use for this resource. Valid types are:
pixmap
Supports the creation/modification of PhImage_t structures.
bitmap
Used only by PtBitmap widget (don't use this).
points
Used internally by PhAB for multisegment lines. PhAB manages this resource type so you can use the points array provided by PtGraphic.
list
Array of text strings.
crgb
Color value made of PgColor_t.
font
Font specification (string).
multi
Multiline text string.
short
Numeric value.
string
Single-line text string.
datas
Single-line text string (Alloc type).
flag
Flag resource.
code
A pointer to a function (see Pointer-to-function resources below).
double
A double value.
float
A float value.
default_value
This is the default value in the widget code itself. It's very important for this value to exactly match the real default value in the widget, because PhAB doesn't generate resource entries in the module files if it seems the resource matches the default value. This keeps the size of the module file to a minimum. If the default value you specify doesn't match, the widget may not behave as expected because a required resource setting will be missing from the module file.
additional_info
This optional value can be used to specify additional information about the resource:

The value can be specified as:

Option and flag pairs

For short and flag resources, additional_info specifies the possible values. Each line is in the form:

description,value

where description is the text that PhAB is to display in the editor, and value is the corresponding value.

Pointer-to-function resources

For a resource that's a pointer to a function (i.e. type is code), additional_info specifies the number of following lines that define the function's prototype. The prototype should contain an @ in place of the function name, but no terminating semicolon.

The default_value specifies the code that will be used for the function body whenever PhAB generates a function for the resource. If the code will fit on the line and doesn't contain any commas, you can specify it directly as default_value. Otherwise, put the code on the lines that follow the function prototype, and set default_value to be the number of lines of code.

Here are some examples:

r=ARG_SIMPLEFUNCTION,A function,5000001,5000001,1,return 0;,1
int @( void )

r=Pt_ARG_RAW_DRAW_F,Draw Function,24000,24000,1,code,1,1
void @( PtWidget_t *widget, PhTile_t *damage )
    PtSuperClassDraw( PtBasic, widget, damage );

r=Pt_ARG_LIST_BALLOON,Inflate Function,23031,23031,1,code,6,5
PtWidget_t *@(
        PtWidget_t *widget, PtWidget_t *parent,
        PhArea_t *area, PtListColumn_t const *column, int coln,
        const char *item, unsigned index, const char *font
        )
    return
        PtGenListCreateTextBalloon(
            widget, parent,
            PtGenListSetColumnBalloon( area, column ),
            item, coln, font
            );

List of callbacks (c=, k=, e=)

These settings define callbacks:

c|k|e=manifest_name,desc_name,resource_num,reserved

Example:

c=Pt_CB_ACTIVATE,Activate,2009,0
k=Pt_CB_HOTKEY,Hotkey,1010,0
e=Pt_CB_RAW,Raw Event,1011,0

Photon supports three different types of callbacks. These are standard widget callbacks (c=), hotkey callbacks (k=), and raw event callbacks (e=). Make sure you use the type that matches the definition of the callback in the widget.

The arguments of the callback entries are identical and have the following meanings:

manifest_name
The valid C manifest name to access this resource through application code.
desc_name
A descriptive version of the manifest name, which is easier to understand and takes up less space (allowing the Control Panel to stay small).
resource_no
The actual resource number (e.g. Pt_USER(0)=5000000, Pt_USER(1)=5001000, and so on - Pt_RESOURCE(Pt_USER(2),5)=5002005).
reserved
Always use a value of 0.

Callbacks can also be inherited from other widgets. See "Inherited resources and callbacks (i=, n=)", below.

Inherited resources and callbacks (i=, n=)

Resource descriptions can be shared by multiple widget classes. This saves memory on runtime and helps keep the palette files consistent (e.g. if a new flag is added to a resource of a parent class, you don't have to add it to the description of each child class manually).

These settings can be used to inherit resource or callback definitions from a widget defined earlier:

i=widget[,from[,to]]
n=widget[,from[,to]]

The i= line copies resources (defined by r= or i= lines). The n= line copies callbacks (defined by c=, k=, e=, or i= lines).

The from and to values are numbers that specify the resource numbers to be copied. If both are given, they define a range. If only the from value is given, it specifies one resource. If neither from nor to is given, all resources/callbacks will be copied.

The i= entry can be used only if the resource definitions for the child and parent classes are identical. If there are any differences (for example, the child class overrides the default value), you'll need to use an r= resource definition - but the child class can still inherit any additional_info that the parent class defines or inherits. For more information, see "List of resources (r=)."

Base widget (b=)

This setting tells PhAB to use container emulation:

b=Container

Since PhAB can't display your widget directly, it must use a substitute widget in its place. If the widget isn't a container and you don't set this value, PhAB will use a PtBasic widget to emulate your widget. If the widget is a container, set the value as shown above and PhAB will use PtContainer to emulate your widget.

Create-type definition (t=)

This setting defines the type of creation mode to use:

t=number 

Example:

t=2

The type definition tells PhAB how this widget should be created. For example, if t=1, PhAB automatically creates the widget as soon as the user clicks in the module. This is because type 1 indicates the widget has a preset size. A value of t=2 means the user can drag out the size when creating the widget.

Valid values for number range from 1 through 6 and have the following meanings:

When number is: Create type is:
1 Preset, resizable
2 Resizable on create
3 Line (2 points)
4 Preset, Nonresizable
5 Polygon (multipoint)
6 Bezier (multipoint with handles)

For more information, see "Creating a widget" in the Creating Widgets in PhAB chapter of the Photon Programmer's Guide.

Cursor styles (s=)

This setting determines the cursor style when creating the widget:

s=start_cursor_style[,drag_cursor_style]

Example:

s=0xe914,0xe914

This setting defines the look of the cursor when the widget is being created in PhAB. The value you choose for a cursor style setting (s=) will depend on the value you specify for the create type setting (t=). For consistency with other widgets in PhAB, we recommend that you assign cursor style values according to the table below:

If create type is: Cursor style should be:
t=1 s=0xe906
t=2 s=0xe914,0xe914
t=3 s=0xe906
t=4 s=0xe906
t=5 s=0xe906
t=6 s=0xe906

Default values (d=)

This setting lets you give the widget some default values to override the defaults built into the widget:

d=class_name,no_of_resource_definitions
definition_1
definition_2
...
definition_n

Each definition consists of three values:

For example:

// Resizable example.
d=ShadowedBox,1
1005
dim
1,1

// Preset example.
d=PtPrintSel,1
1005
dim
418,285

Each resource definition is made up of three lines, and only simple resource types can be used. In the example above, the Pt_ARG_DIM (1005) resource is set to 1 pixel high and 1 pixel wide. This is a good starting point for a widget with a create type number of 2.


Caution: You must always give a widget a default value and starting dimension. If you don't, you'll get unexpected results.

If t=1 or t=4, set the dim resource to the preset size. If the value is anything else, set dim to 1,1. The dim resource is defined as "width,height" in pixels.


Adding the widget palette file to PhAB

To add the widget palette file to PhAB:

  1. After creating the palette picture module and palette description file, make sure both files have consistent names (e.g. mywidgets.wgtp and mywidgets.pal).
  2. Copy both files to the /qnx4/phtk/appbuilder directory.
  3. Add a line for your new palette to the palette definition file, palette.def. The syntax of the entry is:

    p=palette_file_name,description

    (e.g. p=mywidgets,My_Custom_Widgets).

  4. Save the palette definition file and restart PhAB.

You should now be able to go into the Options/Customize WidgetBar option in PhAB and select your widget. This will add your widget to the PhAB widget bar.


Note: Be sure to modify your application's Makefile so that it's linked with your new widget. Include your widget header in the global application header defined in the Application Start-up Info dialog.


[Previous] [Contents] [Index] [Next]