Caution: This version of this document is no longer maintained. For the latest documentation, see http://www.qnx.com/developers/docs.

PtRaw

A widget for use with Photon drawing primitives

Class hierarchy:

PtWidget --> PtBasic --> PtRaw

For more information, see the diagram of the widget hierarchy.

PhAB icon:

PtRaw button in PhAB

Public header:

<photon/PtRaw.h>

Description:

The PtRaw widget lets you use the Photon graphics drawing functions in applications that use widgets.


Note: The PtRaw class provides a good starting point for creating custom widgets. However, custom widgets require their own Initialization, Extent, and Connect methods in addition to a Draw method. Since the PtRaw widget is typically used for drawing, the Draw function PtRaw supports is described in detail in this chapter. If you'd like more information about when to use an Initialization, Extent, or Connect function, see Building Custom Widgets.

With a PtRaw widget, you can draw using raw Photon graphics primitives without completely losing what you've drawn when the widget is damaged. If the widget is damaged, your application is notified so that it may redraw whatever it had previously drawn.

You must refresh the contents of the canvas whenever they become damaged. This is necessary because Photon doesn't keep track of the widget's raw contents for you. It's more efficient to have you, as application programmer, maintain the original data structure and redraw the contents of the canvas. If it takes a long time to render the contents of the canvas, consider rendering them into an image and copying the image into the canvas when it's damaged.

The canvas is considered damaged whenever one of the following situations occurs:

Draw function

The PtRaw widget defines a drawing function, Pt_ARG_RAW_DRAW_F, which is invoked any time the contents of the canvas have to be refreshed due to damage.


Note: Don't call the drawing function directly from your program. Instead, damage the widget by calling PtDamageWidget(), and let the library call the drawing function.

The drawing function you provide for the canvas gets two arguments when it's invoked:

For simple situations where the widget's contents don't change, you could put the drawing primitives in the draw function directly. But it's more likely that the contents change dynamically. In this case, you should create a data structure, or model, that defines the contents of the canvas.

Place a pointer to this data structure in the Pt_ARG_POINTER or Pt_ARG_USER_DATA resource of the PtRaw widget, so that your draw function can get it easily. This function should be able to walk the data structure you've provided and to render the contents of the canvas, based on that information. The draw function must handle its own clipping and highlighting.

Before your function begins drawing, it should establish its coordinate space correctly. First, get the coordinates of the clip rectangle or the widget canvas, by calling PtCalcCanvas() with the raw widget and the address of a rectangle to be filled with the boundaries of the raw widget's clip region.

Once you've determined the clip region, you should determine a scale factor, based on:

The coordinates for the Pg* calls made within the draw function are relative to the canvas of PtRaw's parent. You need to translate the coordinates to compensate for the raw widget's margins. The edge of the margins is given as the rectangle's upper-left corner given by the PtCalcCanvas() function. Add the rectangle's upper-left corner to any translation you wish to perform on the model and pass this value to PgSetTranslation().

This function takes two parameters. The second parameter should be set to the constant Pg_RELATIVE. When rendering your model, scale the values by your scale factor. The coordinates are automatically translated by the amount you specified in the call to PgSetTranslation().


Note: If your draw function changes the current clipping (PtClipAdd()) or translation (PgSetTranslation()), be sure to restore them before returning from the draw function.

The simple example below shows a drawing function that fills the entire canvas with blue:

void raw_draw(PtWidget_t *widget, PhTile_t *damage)
{
   PhRect_t     rect;

   PtCalcCanvas(widget, &rect);

   PgSetFillColor(Pg_BLUE);
   PgDrawRect(&rect, Pg_DRAW_FILL);
}

If your model doesn't explicitly represent color information, make sure you set the stroke color to the value contained in the Pt_ARG_COLOR resource and the fill color to the value specified in the Pt_ARG_FILL_COLOR resource.

Here's a more detailed example of setting up and using a PtRaw widget:

    pos.x = 220;
    dim.w = 200, dim.h = 200;
    n=0;
    PtSetArg( &args[n], Pt_ARG_DIM, &dim, 0 );n++;
    PtSetArg( &args[n], Pt_ARG_POS, &pos, 0 );n++;
    PtSetArg( &args[n], Pt_ARG_RAW_DRAW_F, &draw, 1 );n++;
    PtSetArg( &args[n], Pt_ARG_BEVEL_WIDTH, 2, 0 );n++;
    PtSetArg( &args[n], Pt_ARG_FLAGS, Pt_TRUE,
              Pt_SELECTABLE | Pt_HIGHLIGHTED );n++;
    PtSetArg( &args[n], Pt_CB_ARM, &aback, 1 );n++;
    PtCreateWidget(PtRaw, Pt_DEFAULT_PARENT, n, &args[0] );
    ...

void draw( PtWidget_t *widget, PhTile_t *damage )
{
    PhRect_t rect;

    damage = damage;

    PtSuperClassDraw( PtBasic, widget, damage );

    /* Find our canvas. */
    PtCalcCanvas( widget, &rect );

    /* Clip to our basic canvas (it's only polite). */
    PtClipAdd( widget, &rect );

    /* Do our drawing... */
    PgSetStrokeColor( Pg_RED );
    PgDrawRect( &rect , Pg_DRAW_STROKE );
    rect.ul.x++;
    rect.ul.y++;
    rect.lr.y--;
    rect.lr.x--;
    PgSetStrokeColor( Pg_WHITE );
    PgDrawRect( &rect , Pg_DRAW_STROKE );

    /* Remove our clipping */
    PtClipRemove();

}

For more information, see the Raw Drawing and Animation chapter of the Photon Programmer's Guide.

New resources:

Resource C type Pt type Default
Pt_ARG_RAW_CALC_OPAQUE_F See below Pointer NULL
Pt_ARG_RAW_CONNECT_F See below Pointer NULL
Pt_ARG_RAW_DRAW_F See below Pointer NULL
Pt_ARG_RAW_EXTENT_F See below Pointer NULL
Pt_ARG_RAW_INIT_F See below Pointer NULL

Pt_ARG_RAW_CALC_OPAQUE_F

C type Pt type Default
See below Pointer NULL

A function that calculates the raw widget's opacity tile list:

int (*calc_opaque_f) (PtWidget_t *widget)

If this resource isn't set, the raw widget uses the function defined by PtBasic.

Pt_ARG_RAW_CONNECT_F

C type Pt type Default
See below Pointer NULL

A function that creates any regions needed by the widget (normally PtWidget does this for you):

int (*connect_f) (PtWidget_t *widget)

If this resource isn't set, the raw widget uses the function defined by PtBasic.

Pt_ARG_RAW_DRAW_F

C type Pt type Default
See below Pointer NULL

A function that renders the widget on the screen:

void (*draw_f) (PtWidget_t *widget, PhTile_t *damage)

The damage argument points to a linked list of PhTile_t structures (see the Photon Library Reference) that identify which areas of the widget have been damaged.

If this resource isn't set, the raw widget uses the function defined by PtBasic.

For more information, see the Raw Drawing and Animation chapter of the Photon Programmer's Guide.

Pt_ARG_RAW_EXTENT_F

C type Pt type Default
See below Pointer NULL

A function that determines the exact size of the widget based on default values and/or the widget's position, size, margins, borders, and highlighting information:

void (*extent_f) (PtWidget_t *widget)

If this resource isn't set, the raw widget uses the function defined by PtBasic.

Pt_ARG_RAW_INIT_F

C type Pt type Default
See below Pointer NULL

This function is typically used by widgets that create children. It checks to ensure that all members used in a subsequent call to the extent function are correctly assigned.

int (*init_f) (PtWidget_t *widget)

If this resource isn't set, the raw widget uses the function defined by PtBasic.

Inherited resources:

If the widget modifies an inherited resource, the "Default override" column indicates the new value. This modification affects any subclasses of the widget.

Resource Inherited from Default override
Pt_ARG_ANCHOR_FLAGS PtWidget
Pt_ARG_ANCHOR_OFFSETS PtWidget
Pt_ARG_AREA PtWidget
Pt_ARG_BANDWIDTH_THRESHOLD PtBasic Not used by this class.
Pt_ARG_BASIC_FLAGS PtBasic
Pt_ARG_BEVEL_WIDTH PtWidget 0
Pt_ARG_BITMAP_CURSOR PtWidget
Pt_ARG_BEVEL_COLOR PtBasic
Pt_ARG_BEVEL_CONTRAST PtBasic
Pt_ARG_COLOR PtBasic
Pt_ARG_CONTRAST PtBasic
Pt_ARG_CURSOR_COLOR PtWidget
Pt_ARG_CURSOR_TYPE PtWidget
Pt_ARG_DARK_BEVEL_COLOR PtBasic
Pt_ARG_DARK_FILL_COLOR PtBasic
Pt_ARG_DATA PtWidget
Pt_ARG_DIM PtWidget
Pt_ARG_EFLAGS PtWidget
Pt_ARG_EXTENT PtWidget
Pt_ARG_FILL_COLOR PtBasic
Pt_ARG_FILL_PATTERN PtBasic
Pt_ARG_FLAGS PtWidget
Pt_ARG_GRID_LAYOUT_DATA PtWidget
Pt_ARG_HEIGHT PtWidget
Pt_ARG_HELP_TOPIC PtWidget
Pt_ARG_HIGHLIGHT_ROUNDNESS PtBasic
Pt_ARG_INLINE_COLOR PtBasic
Pt_ARG_LAYOUT_DATA PtWidget
Pt_ARG_LIGHT_BEVEL_COLOR PtBasic
Pt_ARG_LIGHT_FILL_COLOR PtBasic
Pt_ARG_MARGIN_HEIGHT PtBasic
Pt_ARG_MARGIN_WIDTH PtBasic
Pt_ARG_MAXIMUM_DIM PtWidget
Pt_ARG_MINIMUM_DIM PtWidget
Pt_ARG_OUTLINE_COLOR PtBasic
Pt_ARG_POINTER PtWidget
Pt_ARG_POS PtWidget
Pt_ARG_RESIZE_FLAGS PtWidget
Pt_ARG_ROW_LAYOUT_DATA PtWidget
Pt_ARG_STYLE PtBasic
Pt_ARG_TRANS_PATTERN PtBasic
Pt_ARG_USER_DATA PtWidget
Pt_ARG_WIDTH PtWidget
Pt_CB_ACTIVATE PtBasic
Pt_CB_ARM PtBasic
Pt_CB_BLOCKED PtWidget
Pt_CB_DESTROYED PtWidget
Pt_CB_DISARM PtBasic
Pt_CB_DND PtWidget
Pt_CB_FILTER PtWidget
Pt_CB_GOT_FOCUS PtBasic
Pt_CB_HOTKEY PtWidget
Pt_CB_IS_DESTROYED PtWidget
Pt_CB_LOST_FOCUS PtBasic
Pt_CB_MENU PtBasic
Pt_CB_OUTBOUND PtWidget
Pt_CB_RAW PtWidget
Pt_CB_REALIZED PtWidget
Pt_CB_REPEAT PtBasic
Pt_CB_UNREALIZED PtWidget