This chapter covers the following topics:
This chapter describes the common widget superclasses. Use this information to determine whether a superclass's method does what you need for your widget. With this knowledge you can decide whether to take over the method (override inheritance), add a method to the chain, or use the PtSuperClass* functions.
It's important to read the specifications of each of your widget's superclasses before using any of the PtSuperClass*() functions. |
The PtWidget superclass provides the fundamental functionality of all Photon widgets.
PtWidget
Pt_RECTANGULAR
PtWidget defines the class methods described below.
None.
None.
Calculates the extent of the widget without accounting for borders or margins. The extent is calculated based on the widget's position (Pt_ARG_POS) and dimension (Pt_ARG_DIM). For disjoint widgets (e.g. PtWindow widgets), the position is assumed to be (0, 0).
Determines if the widget needs a region, and if so, what events the region should be opaque and/or sensitive to.
If the widget has a bitmap cursor defined, it's set up as region data. If the widget already has a region, that region is updated with the opaque/sense and region data. This is done through PhRegionChange().
If the widget doesn't have a region but one is required, it's created through PhRegionOpen().
Finally, if the widget isn't a window, any hotkey callbacks attached to the widget are registered with the nearest disjoint parent (of PtWindow class). This is done through PtSetResources().
None.
If the widget has a region, the region is closed. All descendants (widget->rid members) are set to 0. If the widget isn't a window, any attached hotkey callbacks are detached from its disjoint parent.
The extent of this widget is damaged on the parent. All children of this widget are unrealized. Any of these widgets having a constraining parent with Pt_SET_CHILD_UNREALIZED_F defined has that function invoked. Any of these having a Pt_CB_UNREALIZED callback chain has that callback chain invoked (from the top down).
Called when a widget instance is being removed. Frees widget->widget_data. Any memory automatically allocated by a resource is released (this memory shouldn't be freed in the Destruction method). Any resources you free must have the pointer set to NULL to prevent the widget engine from freeing the memory a second time. The following resource types automatically allocate and release memory:
None.
Pt_ARG_AREA, Pt_CHANGE_RESIZE, 0, Pt_ARG_IS_STRUCT( PtWidget_t, area ), 0, Pt_ARG_CURSOR_TYPE, core_modify_cursor, 0, Pt_ARG_IS_NUMBER( PtWidget_t, cursor_type ), 0, Pt_ARG_CURSOR_COLOR, core_modify_cursor, 0, Pt_ARG_IS_NUMBER( PtWidget_t, cursor_color ), 0, Pt_ARG_DATA, Pt_CHANGE_INVISIBLE, 0, Pt_ARG_IS_ALLOC( PtWidget_t, data ), 0, Pt_ARG_DIM, Pt_CHANGE_RESIZE, 0, Pt_ARG_IS_STRUCT( PtWidget_t, area.size ), 0, Pt_ARG_FLAGS, PtModifyFlags, 0, Pt_ARG_IS_NUMBER( PtWidget_t, flags ), 0, Pt_ARG_EFLAGS, PtModifyEflags, 0, Pt_ARG_IS_FLAGS( PtWidget_t, eflags), Pt_ARG_POS, Pt_CHANGE_RESIZE, 0, Pt_ARG_IS_STRUCT( PtWidget_t, area.pos ), 0, Pt_ARG_RESIZE_FLAGS, Pt_CHANGE_RESIZE, 0, Pt_ARG_IS_FLAGS( PtWidget_t, resize_flags ), 0, Pt_CB_DESTROYED, Pt_CHANGE_INVISIBLE, 0, Pt_ARG_IS_LINK( PtWidget_t, destroyed ), 0, Pt_CB_HOTKEY, core_modify_hotkey_callbacks, 0, Pt_ARG_IS_LINK( PtWidget_t, hotkeys ), 0, Pt_CB_RAW, core_modify_raw_callbacks, 0, Pt_ARG_IS_LINK( PtWidget_t, callbacks ), 0, Pt_CB_REALIZED, Pt_CHANGE_INVISIBLE, 0, Pt_ARG_IS_LINK( PtWidget_t, realized ), 0, Pt_CB_UNREALIZED, Pt_CHANGE_INVISIBLE, 0, Pt_ARG_IS_LINK( PtWidget_t, unrealized ), 0, Pt_ARG_USER_DATA, Pt_CHANGE_INVISIBLE, 0, Pt_ARG_IS_ALLOC( PtWidget_t, user_data ), 0, Pt_ARG_HELP_TOPIC, Pt_CHANGE_INVISIBLE, 0, Pt_ARG_IS_ALLOC( PtWidget_t, help_topic ), 0, Pt_CB_BLOCKED, Pt_CHANGE_INVISIBLE, 0, Pt_ARG_IS_LINK( PtWidget_t, blocked ), 0, Pt_ARG_BITMAP_CURSOR, bitmap_cursor_change, 0, Pt_ARG_IS_ALLOC( PtWidget_t, bitmap_cursor ), 0,
Provides fundamental Photon widget behavior and callbacks.
PtWidget --> PtBasic
The PtBasic widget adds three class-level methods to fundamental widget functionality. For complete descriptions, see "Class methods" in the Anatomy of a Widget chapter.
typedef struct Pt_basic_widget_class { PtWidgetClass_t core; void (*got_focus_f)( PtWidget_t *, PhEvent_t * ); void (*lost_focus_f)( PtWidget_t *, PhEvent_t * ); void (*calc_opaque_f)( PtWidget_t * ); } PtBasicWidgetClass_t; #define Pt_SET_GOT_FOCUS_F (Pt_ARG_IS_POINTER(PtBasicWidgetClass_t,got_focus_f)) #define Pt_SET_LOST_FOCUS_F (Pt_ARG_IS_POINTER(PtBasicWidgetClass_t,lost_focus_f)) #define Pt_SET_CALC_OPAQUE_F (Pt_ARG_IS_POINTER(PtBasicWidgetClass_t,calc_opaque_f))
PtBasic defines the class methods described below.
widget->border_width = 2; widget->cursor_color = Ph_CURSOR_DEFAULT_COLOR; widget->resize_flags |= Pt_RESIZE_XY_AS_REQUIRED; basic->color = Pg_BLACK; basic->fill_color = Pg_GREY; basic->top_border_color = Pg_WHITE; basic->bot_border_color = Pg_DGREY; basic->flags = Pt_DAMAGE_ON_FOCUS;
None.
Invokes the Extent method of PtWidget via PtSuperClassExtent(). The resulting extent is then adjusted to account for borders and margins.
The Extent method calculates the widget's opaque rectangle and determines whether the widget's Pt_OPAQUE flag is set. The opaque rectangle, widget->opaque, indicates:
This rectangle is the area capable of obscuring any widgets beneath. Widgets completely obscured by another widget aren't drawn.
Checks the PtBasic class structure member calc_opaque_f. If not NULL, the function is invoked. The calc_opaque_f() function is responsible for setting or clearing a widget's Pt_OPAQUE flag. If the widget has a rectangular area blocking anything beneath, the Pt_OPAQUE flag should be set and widget->opaque_rect should identify that rectangular area. Otherwise, the Pt_OPAQUE flag should be cleared.
If a widget's fill color is Pg_TRANSPARENT or has a basic->roundness that's greater than 0, the widget shouldn't be flagged as opaque. |
Inherited from PtWidget.
PtBasic's Draw method draws a rectangle filled with the current fill color. The widget's border is rendered if the Pt_HIGHLIGHTED bit of the widget flags is set and the border width is greater than 0.
If the Pt_SET bit is set, the border is rendered inverted (i.e. the top border color is used to draw the bottom border and vice versa). PtBasic's Draw method also handles focus rendering.
None.
None.
Damages widgets having both the Pt_FOCUS_RENDER and Pt_DAMAGE_ON_FOCUS flags set. Highlights and invokes the basic->arm (Pt_CB_ARM) callback list if this widget has the Pt_AUTOHIGHLIGHT flag set. Invokes the basic->got_focus (Pt_CB_GOT_FOCUS) callback list using PtInvokeCallbackList().
Damages widgets having both the Pt_FOCUS_RENDER and Pt_DAMAGE_ON_FOCUS flags set. Unhighlights and invokes the basic->disarm (Pt_CB_DISARM) callback list if this widget has the Pt_AUTOHIGHLIGHT flag set. Invokes the basic->got_focus (Pt_CB_LOST_FOCUS) callback list via PtInvokeCallbackList().
Sets or clears the widget's Pt_OPAQUE flag (Pt_ARG_FLAGS resource) based on the widget's fill color, roundness, and current value of the Pt_RECTANGULAR flag in the widget class structure.
PtBasic is sensitive to the following events:
The raw callbacks return Pt_CONTINUE to allow chaining to continue.
If your widget class defines Pt_SET_RAW_CALLBACKS, keep this in mind: if your raw callback is sensitive to one of the events listed above and the callback returns Pt_END or Pt_HALT, PtBasic behavior for that event won't occur unless you invoke PtBasic's raw handlers within the callback prior to returning. This can be done via PtSuperClassRawEvent(). |
Pt_ARG_BORDER_WIDTH, Pt_CHANGE_RESIZE, 0, Pt_ARG_IS_NUMBER( PtWidget_t, border_width ), 0, Pt_ARG_FLAGS, basic_modify_flags, 0, Pt_ARG_IS_FLAGS( PtWidget_t, flags ), 0, Pt_ARG_BOT_BORDER_COLOR, Pt_CHANGE_REDRAW, 0, Pt_ARG_IS_NUMBER( PtBasicWidget_t, bot_border_color ), 0, Pt_ARG_COLOR, Pt_CHANGE_REDRAW, 0, Pt_ARG_IS_NUMBER( PtBasicWidget_t, color ), 0, Pt_ARG_FILL_COLOR, basic_modify, 0, Pt_ARG_IS_NUMBER( PtBasicWidget_t, fill_color ), 0, Pt_ARG_FILL_PATTERN, Pt_CHANGE_REDRAW, 0, Pt_ARG_IS_STRUCT( PtBasicWidget_t, fill_pattern ), 0, Pt_ARG_MARGIN_HEIGHT, Pt_CHANGE_RESIZE_REDRAW, 0, Pt_ARG_IS_NUMBER( PtBasicWidget_t, margin_height ), 0, Pt_ARG_MARGIN_WIDTH, Pt_CHANGE_RESIZE_REDRAW, 0, Pt_ARG_IS_NUMBER( PtBasicWidget_t, margin_width ), 0, Pt_ARG_TOP_BORDER_COLOR, Pt_CHANGE_REDRAW, 0, Pt_ARG_IS_NUMBER( PtBasicWidget_t, top_border_color ), 0, Pt_CB_ARM, Pt_CHANGE_INVISIBLE, 0, Pt_ARG_IS_CALLBACK_LIST( PtBasicWidget_t, arm ), 0, Pt_CB_DISARM, Pt_CHANGE_INVISIBLE, 0, Pt_ARG_IS_CALLBACK_LIST( PtBasicWidget_t, disarm ), 0, Pt_CB_ACTIVATE, Pt_CHANGE_INVISIBLE, 0, Pt_ARG_IS_CALLBACK_LIST( PtBasicWidget_t, activate ), 0, Pt_CB_GOT_FOCUS, Pt_CHANGE_INVISIBLE, 0, Pt_ARG_IS_CALLBACK_LIST( PtBasicWidget_t, got_focus ), 0, Pt_CB_LOST_FOCUS, Pt_CHANGE_INVISIBLE, 0, Pt_ARG_IS_CALLBACK_LIST( PtBasicWidget_t, lost_focus ), 0, Pt_CB_REPEAT, Pt_CHANGE_INVISIBLE, 0, Pt_ARG_IS_CALLBACK_LIST( PtBasicWidget_t, repeat ), 0, Pt_ARG_TRANS_PATTERN, Pt_CHANGE_REDRAW, 0, Pt_ARG_IS_STRUCT( PtBasicWidget_t, trans_pattern ), 0, Pt_ARG_HIGHLIGHT_ROUNDNESS, basic_modify, 0, Pt_ARG_IS_NUMBER( PtBasicWidget_t, roundness ), 0,
Setting the Pt_CONSUME_EVENTS bit of PtWidget's eflags resource controls whether a widget consumes any event it's given. Container widgets set this bit by default to prevent events from passing through to the subclassed widgets beneath them. |
This superclass provides a new origin, clipping, and constraints for widget children. If you're creating a widget with children, we recommend you make your widget a subclass of PtContainer or one of its subclasses.
A container can have its own Draw method to render any widget-specific data (other than children). |
PtWidget --> PtBasic --> PtContainer
typedef struct Pt_container_widget_class { PtBasicWidgetClass_t basic; void (*child_created_f)( PtWidget_t *widget, PtWidget_t *child ); int (*child_settingresource_f)(PtWidget_t *widget, PtWidget_t *child, PtArg_t *argt); int (*child_gettingresource_f)(PtWidget_t *widget, PtWidget_t *child, PtArg_t *argt ); void (*child_realized_f)( PtWidget_t *widget, PtWidget_t *child ); void (*child_unrealized_f)( PtWidget_t *widget, PtWidget_t *child ); void (*child_destroyed_f)( PtWidget_t *widget, PtWidget_t *child ); void (*child_move_resize_f)( PtWidget_t *widget, PtWidget_t *child, PhArea_t *current_area, PhRect_t *current_extent, PhArea_t *old_area, PhRect_t *old_extent ); int (*child_getting_focus_f)( PtWidget_t *widget, PtWidget_t *child, PhEvent_t *event ); int (*child_losing_focus_f)( PtWidget_t *widget, PtWidget_t *child, PhEvent_t *event ); } PtContainerClass_t; #define Pt_SET_CHILD_SETTINGRESOURCE_F \ (Pt_ARG_IS_POINTER(PtContainerClass_t, \ child_settingresource_f)) #define Pt_SET_CHILD_GETTINGRESOURCE_F \ (Pt_ARG_IS_POINTER(PtContainerClass_t, \ child_gettingresource_f)) #define Pt_SET_CHILD_REALIZED_F \ (Pt_ARG_IS_POINTER(PtContainerClass_t, child_realized_f)) #define Pt_SET_CHILD_UNREALIZED_F \ (Pt_ARG_IS_POINTER(PtContainerClass_t, child_unrealized_f)) #define Pt_SET_CHILD_CREATED_F \ (Pt_ARG_IS_POINTER(PtContainerClass_t, child_created_f)) #define Pt_SET_CHILD_DESTROYED_F \ (Pt_ARG_IS_POINTER(PtContainerClass_t, child_destroyed_f)) #define Pt_SET_CHILD_MOVED_RESIZED_F \ (Pt_ARG_IS_POINTER(PtContainerClass_t, \ child_move_resize_f)) #define Pt_SET_CHILD_GETTING_FOCUS_F \ (Pt_ARG_IS_POINTER(PtContainerClass_t, \ child_getting_focus_f)) #define Pt_SET_CHILD_LOSING_FOCUS_F \ (Pt_ARG_IS_POINTER(PtContainerClass_t, child_lost_focus_f))
PtContainer defines the class methods described below.
PtBasicWidget_t *basic = (PtBasicWidget_t *)widget; PtContainerWidget_t *ctnr =(PtContainerWidget_t *)widget; // Disjoint widgets store the system info in effect at // their coordinates. if( widget->class_rec->flags & Pt_DISJOINT ) ctnr->sysinfo = calloc( 1, sizeof( PhSysInfo_t ) ); basic->margin_width = 0; basic->margin_height = 0; // containers, by default are to consume forwarded events // even if they are not selectable. widget->eflags |= Pt_CONSUME_EVENTS; widget->border_width = 0; widget->resize_flags &= ~Pt_RESIZE_XY_BITS; ctnr->anchor_flags = Pt_ANCHORS_INVALID; ctnr->flags = Pt_CANVAS_INVALID; PtSetParentWidget( widget );
Registers with its parent for anchoring services. Registration is done via PtContainerRegister().
Finds the bounding box of widget children and applies its resize policy. The extent is calculated, and if the canvas is different as a result, all registered child containers are anchored. If the extent or canvas is different, the resize callback list of the widget is invoked. See PtSuperClassExtent() for a sample Extent method of a container.
None.
None.
Inherited from PtBasic.
Deregisters a widget from its parent. Destroys the current_balloon and sets it to NULL (if not NULL already).
Deregisters a widget from its parent.
Inherited from PtBasic.
Inherited from PtBasic.
Inherited from PtBasic.
None.
static void container_child_realized( PtWidget_t *widget, PtWidget_t *child ) { PtContainerWidget_t *ctnr = (PtContainerWidget_t *)widget; PhRect_t canvas; if( ( ctnr->flags & Pt_IGNORE_CONSTRAINTS ) || ( child->flags & Pt_PROCREATED ) ) return; if( ctnr->flags & Pt_AUTO_EXTENT ) { // do an extent, which may cause children to be // rearranged/resized - if so, ignore resize changes ctnr->flags |= Pt_IGNORE_CONSTRAINTS; PtMoveResizeWidget( widget, 0 ); ctnr->flags &= ~Pt_IGNORE_CONSTRAINTS; } }
Calls the Child Realized method with correct parameters:
static void container_child_moved_resized( PtWidget_t *wp, PtWidget_t *child, PhArea_t *current_area, PhRect_t *current_extent, PhArea_t *old_area, PhRect_t *old_extent ); { container_child_realized( wp, child ); }
None.
None.
None.
None.
None.
None.
Raw callbacks are supported for Ph_EV_BUT_PRESS, Ph_EV_BUT_RELEASE, Ph_EV_BUT_REPEAT, and Ph_EV_KEY events.
If there are callbacks in the Pt_CB_FILTER callback chain having an event mask that matches the current event type, those callbacks are invoked. If the value returned by a filter callback is greater than 0, that value is returned. If there are balloons registered with this container, the balloon list is checked to determine if a balloon needs to be inflated and/or deflated.
If the event is a Ph_EV_KEY event, the event is given to the focused child of the container, if there is one. If the event isn't consumed by the container, the hotkey chain of the nearest disjoint parent is processed to see if the key is a hotkey. If a matching hotkey definition is found, the hotkey callback is invoked and the event is consumed (by returning Pt_END).
If the event is a button press, release, or repeat, each child widget intersecting the event is found via PtContainerHit() until one of these widgets consumes the event.
When an intersecting widget is found, the event rectangle is translated relative to the upper-left corner of the intersecting widget's canvas. Once translation has been performed, the event is given to the intersecting widget via absorbed = PtEventHandler(). Upon return, the event rectangle is detranslated by the same amount.
If all the following are true:
then focus is given to that widget and event->processing_flags has its Ph_DIRECTED_FOCUS bit set. If the return from PtEventHandler() was Pt_END, the event is considered consumed and Pt_END is returned.
An extra step is performed if the event is a press and _Pt_->current is NULL: the absorbing widget is recorded for the purposes of delivering phantom releases to the appropriate widget at a later time.
if( ( absorbed != Pt_CONTINUE ) && wp && cbinfo->event->type == Ph_EV_BUT_PRESS && !_Pt_->current ) { if ( wp->flags & Pt_DESTROYED ) _Pt_->current = (PtWidget_t *)Pt_END; else _Pt_->current = wp; }
Once the event has been consumed or there are no more intersecting events, Pt_END is returned. Otherwise, absorbed is returned.
static const PtRawCallback_t callback = { Pt_EV_REDIRECTED, container_callback, NULL }; static const PtResourceRec_t resources[] = { // overridden resources Pt_ARG_AREA, container_modify_area, 0, Pt_ARG_IS_STRUCT( PtWidget_t, area ), 0, Pt_ARG_DIM, container_modify_area, 0, Pt_ARG_IS_STRUCT( PtWidget_t, area.size ), 0, Pt_ARG_POS, container_modify_area, 0, Pt_ARG_IS_STRUCT( PtWidget_t, area.pos ), 0, Pt_ARG_RESIZE_FLAGS, container_modify_area, 0, Pt_ARG_IS_FLAGS( PtWidget_t, resize_flags ), 0, // new resources Pt_ARG_ANCHOR_OFFSETS, container_modify_area, 0, Pt_ARG_IS_STRUCT( PtContainerWidget_t, anchor_offset), 0, Pt_ARG_ANCHOR_FLAGS, container_modify_area, 0, Pt_ARG_IS_NUMBER( PtContainerWidget_t, anchor_flags ), 0, Pt_ARG_FOCUS, container_modify, 0, Pt_ARG_IS_POINTER( PtContainerWidget_t, focus ), 0, Pt_CB_RESIZE, Pt_CHANGE_INVISIBLE, 0, Pt_ARG_IS_CALLBACK_LIST( PtContainerWidget_t, resize ), 0, Pt_CB_BALLOONS, container_set_balloons, 0, Pt_ARG_IS_LINK( PtContainerWidget_t, balloons ), 0, Pt_ARG_CONTAINER_FLAGS, container_modify_flags, 0, Pt_ARG_IS_FLAGS( PtContainerWidget_t, flags ), 0, Pt_CB_FILTER, Pt_CHANGE_INVISIBLE, 0, Pt_ARG_IS_LINK( PtContainerWidget_t, filters ), 0, };
container->flags |= Pt_ANCHORS_INVALID; container->flags &= ~Pt_ANCHORS_LOCKED;
The Pt_ANCHORS_INVALID bit indicates that the widget can't be anchored using the values in the anchor offsets member until these values are recalculated.
The Pt_ANCHORS_LOCKED bit indicates that the anchor offsets for the container are valid and shouldn't be recalculated due to the change that just occurred. This bit is set when Pt_ARG_ANCHOR_OFFSETS is set. If Pt_ARG_ANCHOR_OFFSETS is set, the anchors are validated and locked. If Pt_ARG_RESIZE_FLAGS is being modified, the anchors are invalidated and the widget is flagged for resize:
widget->flags |= Pt_WIDGET_RESIZE;
static void container_modify( PtWidget_t *widget, PtArg_t *arg ) { PtContainerWidget_t *container = (PtContainerWidget_t *)widget; PhEvent_t event; memset( &event, 0, sizeof( event ) ); switch( arg->type ) { case Pt_ARG_FOCUS: // If the widget is already focused or isn't // the immediate child of this container, // do nothing. if (( container->focus == (PtWidget_t *)arg->value ) || ( !arg->value ) || (((PtWidget_t *)arg->value)->parent != widget)) return; // otherwise, give the target widget focus. PtContainerGiveFocus( (PtWidget_t *)arg->value, &event ); } }
A raw callback function to check the balloon list is added if the balloon count is nonzero and the balloons_active bit was not set. The callback is removed if the balloon count goes to zero and the balloons_active bit was set.
container_modify_flags( PtWidget_t *widget, PtArg_t *argt ) { PtContainerWidget_t *ctnr = (PtContainerWidget_t *)widget; int changed; argt->len &= ~Pt_CONTAINER_RO_FLAGS; changed = ctnr->flags; changed ^= ctnr->flags = ( ctnr->flags & ~argt->len ) | ( argt->value & argt->len ); if( changed & Pt_AUTO_EXTENT ) { if( ctnr->flags & Pt_AUTO_EXTENT ) { // Turn on constraints and schedule // for extenting. ctnr->flags |= Pt_CHILD_REALIZED | Pt_CHILD_UNREALIZED | Pt_CHILD_MOVED_RESIZED; widget->flags |= Pt_WIDGET_RESIZE; }else { //turn off constraints. ctnr->flags &= ~(Pt_CHILD_REALIZED | Pt_CHILD_UNREALIZED | Pt_CHILD_MOVED_RESIZED ); } } }
This class is used for creating widgets whose functionality (in part) is derived from exported subordinate widgets.
PtWidget --> PtBasic --> PtContainer --> PtCompound
typedef struct Pt_compound_class { PtContainerClass_t container; ushort_t num_subordinates; ushort_t *subordinates; ushort_t num_blocked_resources; ulong_t *blocked_resources; } PtCompoundClass_t; #define Pt_SET_NUM_SUBORDINATES \ (Pt_ARG_IS_NUMBER(PtCompoundClass_t,num_subordinates)) #define Pt_SET_SUBORDINATES \ (Pt_ARG_IS_POINTER(PtCompoundClass_t,subordinates) #define Pt_SET_NUM_BLOCKED_RESOURCES \ (Pt_ARG_IS_NUMBER(PtCompoundClass_t,num_blocked_resources)) #define Pt_SET_BLOCKED_RESOURCES \ (Pt_ARG_IS_POINTER(PtCompoundClass_t,blocked_resources)
PtCompound defines the class methods described below.
Inherits all defaults from PtContainer.
None.
Inherited from PtContainer.
None.
None.
Inherited from PtContainer.
None.
Destroys the redirected callback lists of exported subordinates having callback resources set on them.
Inherited from PtBasic.
Inherited from PtContainer.
Inherited from PtBasic.
None.
None.
None.
This class is used for creating list widgets.
PtWidget --> PtBasic --> PtContainer --> PtCompound --> PtGenList
typedef void PtGenListDrawF_t( PtGenListWidget_t *widget, PtGenListItem_t *item, unsigned index,unsigned nitems, PhRect_t *where ); typedef int PtGenListMouseF_t( PtGenListWidget_t *wgt, PtGenListItem_t *item, unsigned index, PhPoint_t *where, PhEvent_t const *ev ); typedef int PtGenListKeyF_t( PtGenListWidget_t *wgt, PhEvent_t const *ev, PhKeyEvent_t *kev,PtGenListItem_t *newcur, unsigned newpos ); typedef void PtGenListSelectF_t( PtGenListWidget_t *wgt, PtGenListItem_t *item, int pos, int nitems, int subtype, PhEvent_t const *ev ); typedef PtWidget_t *PtGenListInflateF_t( PtWidget_t *widget, PtWidget_t *parent, PtGenListItem_t *item, unsigned index, int column, PhArea_t *area ); typedef struct Pt_gen_list_widget_class { PtCompoundClass_t compound; PtGenListDrawF_t *list_draw_f; PtGenListMouseF_t *list_mouse_f; PtGenListKeyF_t *list_key_f; PtGenListSelectF_t *list_select_f; PtGenListInflateF_t *list_inflate_f; } PtGenListClass_t; #define Pt_SET_LIST_DRAW_F \ Pt_ARG_IS_POINTER( PtGenListClass_t, list_draw_f ) #define Pt_SET_LIST_MOUSE_F \ Pt_ARG_IS_POINTER( PtGenListClass_t, list_mouse_f ) #define Pt_SET_LIST_KEY_F \ Pt_ARG_IS_POINTER( PtGenListClass_t, list_key_f ) #define Pt_SET_LIST_SELECT_F \ Pt_ARG_IS_POINTER( PtGenListClass_t, list_select_f ) #define Pt_SET_LIST_INFLATE_F \ Pt_ARG_IS_POINTER( PtGenListClass_t, list_inflate_f )
PtGenList defines the class methods described below.
widget->flags |= Pt_HIGHLIGHTED | Pt_ETCH_HIGHLIGHT | Pt_SET | Pt_GETS_FOCUS | Pt_FOCUS_RENDER; widget->eflags &= ~Pt_DAMAGE_ON_FOCUS; widget->resize_flags &= ~Pt_RESIZE_XY_BITS; widget->border_width = 2; list->flags = Pt_LIST_SCROLLBAR_AS_REQUIRED; list->sel_mode = Pt_BROWSE_MODE; list->scroll_rate = 2; list->selection_fill_color = Pg_BLUE; list->selection_text_color = Pg_WHITE; list->balloon_bg = Pg_BALLOONCOLOR; list->balloon_fg = Pg_BLACK; list->font = strdup( "helv12" ); basic->margin_width = basic->margin_height = 0; basic->flags &= ~Pt_DAMAGE_ON_FOCUS; list->slider_width = 15; list->top_item = 1;
None.
If a PtDivider widget is the child, the Extent method:
Then the Extent method of PtCompound is invoked via PtSuperClassExtent().
None.
Realizes the scrollbar if necessary and registers a balloon callback with the parent.
Renders the widget's border, margins, and (possibly) background. Then the List Draw method is called to draw the list.
Deregisters a balloon callback with the parent.
None.
If the Pt_FOCUS_RENDER flag is set, the Got Focus method damages the current item. If the Pt_SELECTION_MODE_AUTO flag is set but the Pt_SELECTION_MODE_NOFOCUS flag isn't set and no items are selected, the current item is selected. Then the Got Focus method of PtCompound is invoked via PtSuperClassGotFocus().
If necessary, the current item is damaged. Then the Lost Focus method of PtCompound is invoked via PtSuperClassLostFocus().
Inherited from PtBasic.
Sets the child-redirector function to PtCompoundRedirect() via PtContainerChildRedirect(). This prevents the list widget from having more than one PtDivider child.
If the child isn't the scrollbar (it's a divider), the Child Realized method:
If the child is a divider (i.e. list->divider), the Child Moved/Resized method sets the divider's Pt_ARG_DIVIDER_OFFSET resource and adjusts the top margin of the list widget.
If the child is the same as list->divider, the Child Unrealized method adjusts the top margin, removes the callback, and sets list->divider to NULL.
Sets the child-redirector function to a private function that accepts a PtDivider child only.
Inherited from PtContainer.
Inherited from PtContainer.
Inherited from PtContainer.
Inherited from PtContainer.
None.
None.
None.
None.
None.
PtGenList is sensitive to the following events:
The callback function invokes the List Key or List Mouse method and performs the selection.
If your widget class defines Pt_SET_RAW_CALLBACKS, keep this in mind: if your raw callback is sensitive to one of the events listed above and the callback returns Pt_END or Pt_HALT, PtGenList behavior for that event won't occur unless you invoke PtGenList's raw handlers within the callback prior to returning. This can be done via PtSuperClassRawEvent(). |
{ Pt_ARG_AREA, arg_resize, NULL, Pt_ARG_IS_STRUCT( PtWidget_t, area ) }, { Pt_ARG_DIM, arg_resize, NULL, Pt_ARG_IS_STRUCT( PtWidget_t, area.size ) }, { Pt_ARG_POS, arg_resize, NULL, Pt_ARG_IS_STRUCT( PtWidget_t, area.pos ) }, { Pt_ARG_MARGIN_HEIGHT, arg_resize, NULL, Pt_ARG_IS_NUMBER( PtGenListWidget_t, bot_margin ) }, { Pt_ARG_MARGIN_WIDTH, arg_resize, NULL, Pt_ARG_IS_NUMBER( PtGenListWidget_t, margin_width ) }, { Pt_ARG_LIST_FLAGS, arg_flags, NULL, Pt_ARG_IS_FLAGS( PtGenListWidget_t, flags ) }, { Pt_ARG_LIST_FONT, arg_font, NULL, Pt_ARG_IS_STRING( PtGenListWidget_t, font ) }, { Pt_ARG_SCROLLBAR_WIDTH, arg_resize, NULL, Pt_ARG_IS_NUMBER( PtGenListWidget_t, slider_width ) }, { Pt_ARG_SELECTION_MODE, arg_selmode, NULL, Pt_ARG_IS_NUMBER( PtGenListWidget_t, sel_mode ) }, { Pt_ARG_TOP_ITEM_POS, arg_top_pos, NULL, Pt_ARG_IS_NUMBER( PtGenListWidget_t, top_item ) }, { Pt_ARG_VISIBLE_COUNT, Pt_CHANGE_PREVENT, NULL, Pt_ARG_IS_NUMBER( PtGenListWidget_t, displayed_count ) }, { Pt_ARG_SELECTION_FILL_COLOR, Pt_CHANGE_REDRAW, NULL, Pt_ARG_IS_NUMBER( PtGenListWidget_t, selection_fill_color ) }, { Pt_ARG_SELECTION_TEXT_COLOR, Pt_CHANGE_REDRAW, NULL, Pt_ARG_IS_NUMBER( PtGenListWidget_t, selection_text_color) }, { Pt_ARG_LIST_ITEM_COUNT, Pt_CHANGE_PREVENT, NULL, Pt_ARG_IS_NUMBER( PtGenListWidget_t, item_count ) }, { Pt_ARG_LIST_SEL_COUNT, Pt_CHANGE_PREVENT, NULL, Pt_ARG_IS_NUMBER( PtGenListWidget_t, sel_count ) }, { Pt_ARG_LIST_TOTAL_HEIGHT, Pt_CHANGE_PREVENT, NULL, Pt_ARG_IS_NUMBER( PtGenListWidget_t, total_height ) }, { Pt_ARG_LIST_SB_RES, arg_setsb, arg_getsb }, { Pt_ARG_LIST_SCROLL_RATE, Pt_CHANGE_INVISIBLE, NULL, Pt_ARG_IS_NUMBER( PtGenListWidget_t, scroll_rate ) }, { Pt_ARG_LIST_COLUMN_POS, arg_columns, NULL, Pt_ARG_IS_ARRAY( PtGenListWidget_t, columns ), Pt_ARG_IS_NUMBER( PtGenListWidget_t, ncolumns ) }, { Pt_ARG_LIST_COLUMN_ATTR, Pt_CHANGE_REDRAW, NULL, Pt_ARG_IS_ARRAY( PtGenListWidget_t, col_attrs ), Pt_ARG_IS_NUMBER( PtGenListWidget_t, ncol_attrs ) }, { Pt_CB_SCROLL_MOVE, Pt_CHANGE_INVISIBLE, NULL, Pt_ARG_IS_CALLBACK_LIST( PtGenListWidget_t, scroll ) } };
For more information, see the chapter on Creating a List Widget.
This class is used for creating tree widgets.
PtWidget --> PtBasic --> PtContainer --> PtCompound --> PtGenList --> PtGenTree
typedef void PtGenTreeDrawItemF_t( PtGenTreeWidget_t *wgt, PtGenTreeItem_t *item, PhRect_t const *where, int lmargin, int rmargin ); typedef int PtGenTreeItemStateF_t( PtGenTreeWidget_t *wgt, PtGenTreeItem_t *item, PhEvent_t const *event, int reason ); typedef struct Pt_gen_tree_widget_class { PtGenListClass_t list; PtGenTreeDrawItemF_t *tree_draw_item_f; PtGenTreeItemStateF_t *tree_state_f; } PtGenTreeClass_t; #define Pt_SET_TREE_DRAW_F \ Pt_ARG_IS_POINTER( PtGenTreeClass_t, tree_draw_item_f ) #define Pt_SET_TREE_STATE_F \ Pt_ARG_IS_POINTER( PtGenTreeClass_t, tree_state_f )
PtGenTree defines the class methods described below.
tree->flags = Pt_TREE_HAS_BUTTONS | Pt_TREE_HAS_LINES | Pt_TREE_ROOT_LINES; tree->list.gflags = Pt_GEN_LIST_SHOW_DAMAGED | Pt_GEN_LIST_ITEM_BACKGROUND;
None.
Inherited from PtGenList.
None.
None.
Inherited from PtGenList.
None.
None.
Inherited from PtGenList.
Inherited from PtGenList.
Inherited from PtBasic.
Inherited from PtGenList.
Inherited from PtGenList.
Inherited from PtGenList.
Inherited from PtGenList.
Inherited from PtGenList.
Inherited from PtContainer.
Inherited from PtContainer.
Inherited from PtContainer.
Inherited from PtContainer.
For each visible item that has the Pt_LIST_ITEM_DAMAGED flag set, the List Draw method calls the Tree Draw Item method and draws the tree ornaments.
Invokes the Pt_CB_GEN_TREE_INPUT callback list. Depending on the result of the callback and the pointer position, the List Mouse method returns Pt_CONTINUE, returns Pt_END, or calls PtGenTreeCollapse() or PtGenTreeExpand() and returns Pt_END.
Invokes the Pt_CB_GEN_TREE_INPUT callback list. Depending on the result of the callback and the key code, the List Key method returns Pt_CONTINUE, returns Pt_END, or calls PtGenTreeCollapse() or PtGenTreeExpand() and returns Pt_HALT.
None.
None.
None.
{ Pt_ARG_TREE_FLAGS, arg_flags, NULL, Pt_ARG_IS_FLAGS( PtGenTreeWidget_t, flags ) }, { Pt_CB_GEN_TREE_INPUT, Pt_CHANGE_INVISIBLE, NULL, Pt_ARG_IS_CALLBACK_LIST( PtGenTreeWidget_t, input_cb ) } };
For more information, see the chapter on Creating a Tree Widget.
The PtLabel class provides fundamental multiline-text string and image handling.
PtWidget --> PtBasic --> PtLabel
PtLabel defines the class methods described below.
widget->flags |= Pt_FOCUS_RENDER; widget->resize_flags |= Pt_RESIZE_XY_AS_REQUIRED; label->basic.fill_color = Pg_TRANSPARENT; label->font = strdup( "helv12" ); label->flags |= Pt_LABEL_SELECT_SHIFT; label->uline1 = Pg_BLACK; label->uline2 = Pg_TRANSPARENT; label->uline_type =(ushort_t) Pt_NO_ULINE; label->type = Pt_Z_STRING; label->basic.margin_width = 2; label->basic.margin_height = 2; label->margin_top = 0; label->margin_bottom = 0; label->margin_left = 0; label->margin_right = 0; label->h_alignment = Pt_LEFT; label->v_alignment = Pt_CENTER; label->string = strdup(""); label->inflate_f = PtInflateBalloon; label->balloon_fill_color = Pg_BALLOONCOLOR; label->balloon_color = Pg_BLACK;
None.
Determines the required canvas size based on the widget's text string or image data in conjunction with label->type (Pt_Z_STRING, Pt_TEXT_IMAGE ), margins, etc. The Extent method also takes into account multiple lines of text and underlining.
If label->flags has the Pt_SHOW_BALLOON flag set, a balloon callback is attached to the parent widget.
Inherited from PtBasic.
Calls the Draw method of PtBasic via PtSuperClassDraw(). Draws the text in the label using the specified font, color, etc.
If this label has a balloon displayed (label->balloon_widget != NULL), that widget is destroyed. If label->flags has the Pt_SHOW_BALLOON flag set, it detaches the balloon callback from the parent.
If widget->flags has the Pt_FREE_MEMORY flag set, any memory used for the label's image and palette is freed.
Inherited from PtBasic.
Inherited from PtBasic.
If label->type is Pt_Z_STRING, the Calc Opaque Rect method is called via PtSuperClassCalcOpaque().
If label->type is Pt_IMAGE, label->flags has its Pt_OPAQUE flag set.
If label->type is Pt_BITMAP and label->data->image->type is Pg_BITMAP_BACKFILL, the Pt_OPAQUE bit of widget->flags is set.
None.
Pt_ARG_HORIZONTAL_ALIGNMENT, Pt_CHANGE_REDRAW, 0, Pt_ARG_IS_NUMBER( PtLabelWidget_t, h_alignment ), 0, Pt_ARG_LABEL_DATA, Pt_CHANGE_RESIZE_REDRAW, 0, Pt_ARG_IS_ALLOC( PtLabelWidget_t, data ), 0, Pt_ARG_LABEL_FLAGS, label_modify_flags, 0, Pt_ARG_IS_FLAGS( PtLabelWidget_t, flags ),0, Pt_ARG_LABEL_TYPE, Pt_CHANGE_RESIZE_REDRAW, 0, Pt_ARG_IS_NUMBER( PtLabelWidget_t, type), 0, Pt_ARG_MARGIN_BOTTOM, Pt_CHANGE_RESIZE_REDRAW, 0, Pt_ARG_IS_NUMBER( PtLabelWidget_t, margin_bottom ), 0, Pt_ARG_MARGIN_LEFT, Pt_CHANGE_RESIZE_REDRAW, 0, Pt_ARG_IS_NUMBER( PtLabelWidget_t, margin_left ), 0, Pt_ARG_MARGIN_RIGHT, Pt_CHANGE_RESIZE_REDRAW, 0, Pt_ARG_IS_NUMBER( PtLabelWidget_t, margin_right ), 0, Pt_ARG_MARGIN_TOP, Pt_CHANGE_RESIZE_REDRAW, 0, Pt_ARG_IS_NUMBER( PtLabelWidget_t, margin_top ), 0, Pt_ARG_SELECT_SHIFT, Pt_CHANGE_REDRAW, 0, Pt_ARG_IS_BOOLEAN( PtLabelWidget_t, flags ), Pt_LABEL_SELECT_SHIFT, Pt_ARG_TEXT_FONT, Pt_CHANGE_RESIZE_REDRAW, 0, Pt_ARG_IS_STRING( PtLabelWidget_t, font ), 0, Pt_ARG_TEXT_STRING, PtModifyLabelString, 0, Pt_ARG_IS_STRING( PtLabelWidget_t, string ), 0, Pt_ARG_UNDERLINE1, Pt_CHANGE_RESIZE_REDRAW, 0, Pt_ARG_IS_NUMBER( PtLabelWidget_t, uline1), 0, Pt_ARG_UNDERLINE2, Pt_CHANGE_RESIZE_REDRAW, 0, Pt_ARG_IS_NUMBER( PtLabelWidget_t, uline2), 0, Pt_ARG_UNDERLINE_TYPE, Pt_CHANGE_RESIZE_REDRAW, 0, Pt_ARG_IS_NUMBER( PtLabelWidget_t, uline_type), 0 , Pt_ARG_VERTICAL_ALIGNMENT, Pt_CHANGE_REDRAW, 0, Pt_ARG_IS_NUMBER( PtLabelWidget_t, v_alignment ), 0, Pt_ARG_BALLOON_POSITION, Pt_CHANGE_INVISIBLE, 0, Pt_ARG_IS_NUMBER( PtLabelWidget_t, balloon_pos ), 0, Pt_ARG_LABEL_BALLOON, Pt_CHANGE_INVISIBLE, 0, Pt_ARG_IS_POINTER( PtLabelWidget_t, inflate_f), 0, Pt_ARG_ACCEL_KEY, Pt_CHANGE_RESIZE_REDRAW, 0, Pt_ARG_IS_STRING( PtLabelWidget_t, accel_key ), 0, Pt_ARG_BALLOON_FILL_COLOR, Pt_CHANGE_INVISIBLE, 0, Pt_ARG_IS_NUMBER( PtLabelWidget_t, balloon_fill_color ), 0, Pt_ARG_BALLOON_COLOR, Pt_CHANGE_INVISIBLE, 0, Pt_ARG_IS_NUMBER( PtLabelWidget_t, balloon_color ), 0, Pt_ARG_LINE_SPACING, Pt_CHANGE_RESIZE_REDRAW, 0, Pt_ARG_IS_NUMBER( PtLabelWidget_t, line_spacing ), 0,
static int label_modify_flags( PtWidget_t *widget, PtArg_t *argt );
If the Pt_SHOW_BALLOON flag is being set, the balloon callback is attached to the parent. If the Pt_SHOW_BALLOON flag is being cleared, the balloon callback is detached from the parent. The value of label->flags is based on argt->value and argt->len. This is typically done as follows:
label->flags = (label->flags & ~argt->len) | argt->value;
int PtModifyLabelString( PtWidget_t *widget, PtArg_t *argt );
This frees the current string, allocates enough space for the new string, copies in the new string, flags the widget to be resized (widget->flags |= Pt_WIDGET_RESIZE;), and damages the widget.
If a balloon is displayed, the balloon is destroyed and a new balloon is inflated with the new string. If label->flags has the Pt_BALLOON_AS_REQUIRED bit set, the new balloon will be created only if the label will be clipped by its parent.
This class provides standard graphic resources such as Pt_ARG_POINTS and Pt_ARG_ORIGIN.
PtWidget --> PtBasic --> PtGraphic
PtGraphic defines the class methods described below.
static void graphic_dflts( PtWidget_t *widget ) { PtGraphicWidget_t *graphic = (PtGraphicWidget_t *)widget; graphic->line_width = 0L; graphic->line_cap = Pg_BUTT_CAP; graphic->line_join = Pg_MITER_JOIN; graphic->basic.margin_height = 0; graphic->basic.margin_width = 0; graphic->basic.fill_color = Pg_TRANSPARENT; graphic->npoints = 0; graphic->point_array = NULL; }
None.
Determines the render rectangle for the graphic widget, given the area, point array, and current settings of graphic flags.
None.
None.
Inherited from PtBasic.
None.
None.
Inherited from PtBasic.
Inherited from PtBasic.
Inherited from PtBasic.
None.
static PtResourceRec_t resources[] = { Pt_ARG_AREA, graphic_modify_area, 0, Pt_ARG_IS_STRUCT( PtWidget_t, area ), 0, Pt_ARG_DIM, graphic_modify_area, 0, Pt_ARG_IS_STRUCT( PtWidget_t, area.size ), 0, Pt_ARG_DASH_LIST, Pt_CHANGE_REDRAW, 0, Pt_ARG_IS_ARRAY( PtGraphicWidget_t, dash_list ), Pt_ARG_IS_NUMBER( PtGraphicWidget_t, dash_len ), Pt_ARG_GRAPHIC_FLAGS, Pt_CHANGE_RESIZE, 0, Pt_ARG_IS_FLAGS( PtGraphicWidget_t, flags ),0, Pt_ARG_LINE_WIDTH, Pt_CHANGE_RESIZE_REDRAW, 0, Pt_ARG_IS_NUMBER( PtGraphicWidget_t, line_width ), 0, Pt_ARG_LINE_JOIN, Pt_CHANGE_REDRAW, 0, Pt_ARG_IS_NUMBER( PtGraphicWidget_t, line_join ), 0, Pt_ARG_LINE_CAP, Pt_CHANGE_REDRAW, 0, Pt_ARG_IS_NUMBER( PtGraphicWidget_t, line_cap ), 0, Pt_ARG_ORIGIN, Pt_CHANGE_RESIZE_REDRAW, 0, Pt_ARG_IS_STRUCT( PtGraphicWidget_t, origin ), 0, Pt_ARG_POINTS, Pt_CHANGE_RESIZE_REDRAW, 0, Pt_ARG_IS_ARRAY( PtGraphicWidget_t, point_array), Pt_ARG_IS_NUMBER( PtGraphicWidget_t, npoints), Pt_CB_RESCALE, Pt_CHANGE_INVISIBLE, 0, Pt_ARG_IS_LINK( PtGraphicWidget_t, rescale ) | Pt_ARG_PARM(sizeof( PtCallback_t)), 0, Pt_ARG_DASH_SCALE, Pt_CHANGE_REDRAW, 0, Pt_ARG_IS_NUMBER( PtGraphicWidget_t, dash_scale ), 0, };
This class provides standard gauge resources such as maximum, minimum, and orientation.
PtWidget --> PtBasic --> PtGauge
PtGauge defines the class methods described below.
static void gauge_dflts( PtWidget_t *widget ) { PtGaugeWidget_t *gauge = (PtGaugeWidget_t *)widget; static const char helv12[] = "helv12"; gauge->font = malloc( sizeof(helv12) ); if( gauge->font != NULL ) strcpy( gauge->font, helv12 ); gauge->flags = 0; gauge->orientation = Pt_HORIZONTAL; gauge->value = 0; gauge->minimum = 0; gauge->maximum = 100; }
None.
Inherited from PtBasic.
None.
None.
Inherited from PtBasic.
None.
None.
Inherited from PtBasic.
Inherited from PtBasic.
Inherited from PtBasic
None.
static const PtResourceRec_t resources[] = { Pt_ARG_GAUGE_FLAGS, Pt_CHANGE_INVISIBLE, 0, Pt_ARG_IS_FLAGS( PtGaugeWidget_t, flags ), 0, Pt_ARG_GAUGE_FONT, Pt_CHANGE_INVISIBLE, 0, Pt_ARG_IS_STRING( PtGaugeWidget_t, font ), 0, Pt_ARG_GAUGE_MINIMUM, Pt_CHANGE_INVISIBLE, 0, Pt_ARG_IS_NUMBER( PtGaugeWidget_t, minimum ), 0, Pt_ARG_GAUGE_MAXIMUM, Pt_CHANGE_INVISIBLE, 0, Pt_ARG_IS_NUMBER( PtGaugeWidget_t, maximum ), 0, Pt_ARG_GAUGE_VALUE, Pt_CHANGE_INVISIBLE, 0, Pt_ARG_IS_NUMBER( PtGaugeWidget_t, value ), 0, Pt_ARG_GAUGE_ORIENTATION, Pt_CHANGE_INVISIBLE, 0, Pt_ARG_IS_NUMBER( PtGaugeWidget_t, orientation ), 0, };
None.