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

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 class provides you with widget that lets you use the Photon graphics drawing functions.


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 the Building Custom Widgets manual.

With a PtRaw canvas, 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, the 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 allow the application programmer to maintain the original data structure and re-render the contents of the canvas. If a significant amount of time must be expended rendering the contents of the canvas, it's better to render them into an image and copy the image into the canvas when it is 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 will 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_USER_DATA resource of the PtRaw widget, so that it can be obtained easily by your draw function. 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.

Before your function begins drawing, it should establish its coordinate space correctly. First, obtain the coordinates of the clip rectangle or the widget canvas. This is done by calling PtBasicWidgetCanvas() 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 and translation for drawing. You determine the scale factor based on:

You should also set a translation 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 PtBasicWidgetCanvas() 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 will automatically be translated by the amount you specified in the call to PgSetTranslation().

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;
    
   PtBasicWidgetCanvas(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.

PtRaw lets you combine widgets and Pg* functions. You should use this widget to cover any area in which "raw drawing" is to take place. The draw function you specify for this widget will be called whenever the area needs repair.

The coordinates for the Pg* calls made within the draw function are relative to the canvas of PtRaw's parent. The draw function must handle its own clipping and highlighting.

If the draw function changes clipping (PtClipAdd()) or the current translation (PgSetTranslation()) they must be restored before the draw function returns.

Here's an 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_BORDER_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, NULL, n, &args[0] );
    ...

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

    damage = damage;

    PtSuperClassDraw( PtBasic, widget, damage );

    //find our canvas 
    PtBasicWidgetCanvas( 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_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_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)

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)

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)

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)

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_AREA PtWidget
Pt_ARG_BANDWIDTH_THRESHOLD PtBasic Not used by this class.
Pt_ARG_BITMAP_CURSOR PtWidget
Pt_ARG_BORDER_WIDTH PtWidget 0
Pt_ARG_BOT_BORDER_COLOR PtBasic
Pt_ARG_COLOR PtBasic
Pt_ARG_CURSOR_COLOR PtWidget
Pt_ARG_CURSOR_TYPE PtWidget
Pt_ARG_DATA PtWidget
Pt_ARG_DIM PtWidget
Pt_ARG_EFLAGS PtWidget
Pt_ARG_FILL_COLOR PtBasic
Pt_ARG_FILL_PATTERN PtBasic
Pt_ARG_FLAGS PtWidget
Pt_ARG_HELP_TOPIC PtWidget
Pt_ARG_HIGHLIGHT_ROUNDNESS PtBasic
Pt_ARG_MARGIN_HEIGHT PtBasic
Pt_ARG_MARGIN_WIDTH PtBasic
Pt_ARG_POS PtWidget
Pt_ARG_RESIZE_FLAGS PtWidget
Pt_ARG_TOP_BORDER_COLOR PtBasic
Pt_ARG_TRANS_PATTERN PtBasic
Pt_ARG_USER_DATA PtWidget
Pt_CB_ACTIVATE PtBasic
Pt_CB_ARM PtBasic
Pt_CB_BLOCKED PtWidget
Pt_CB_DESTROYED PtWidget
Pt_CB_DISARM PtBasic
Pt_CB_GOT_FOCUS PtBasic
Pt_CB_HOTKEY PtWidget
Pt_CB_LOST_FOCUS PtBasic
Pt_CB_MENU PtBasic
Pt_CB_RAW PtWidget
Pt_CB_REALIZED PtWidget
Pt_CB_REPEAT PtBasic
Pt_CB_UNREALIZED PtWidget

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