GenView: 4.8 Advanced Concepts and Uses: Monitoring Input

Up: GEOS SDK TechDocs | Up | Prev: 4.7 Scrolling | Next: 4.9 Linking Views

Often, applications will want to receive input--keyboard, mouse, or pen events--through the view. While keyboard events are fairly straightforward, receiving mouse and pen events can be somewhat more complicated. Depending on the types of events you choose to receive, however, input handling can be quite simple.

Mouse Events

Many applications will want to receive mouse events through the view. By default, the view's content will receive all pointer events, whether or not a mouse button has been pressed. However, you can determine which types of events you want to receive by setting the appropriate attributes in the GVI_attrs field:

Both of the above attributes may be set either in your geode's Goc code or with MSG_GEN_VIEW_SET_ATTRS . To retrieve which attributes are set, use MSG_GEN_VIEW_GET_ATTRS . Due to overhead incurred by passing input events, you should only set the attributes you need. (See The GVI_attrs Attribute for more detail on these messages.)

Handling 32-Bit Input Events

Because normal pointer events use the standard GEOS 16-bit coordinate system, large documents must be able to translate these 16-bit events into 32-bit coordinates. The GenView makes this easy for you.

First, set the attribute GVA_WINDOW_COORDINATE_MOUSE_EVENTS in the GVI_attrs record. This will change the format of pointer data passed from the view to the content object. The new format will contain offset coordinates describing the pointer's position relative to the view's screen origin (in screen coordinates).

When you receive one of these events (called "large" mouse events), you can apply the simple formula shown in the figure below to get 32-bit document coordinates. Once you have the coordinates of the pointer event, you can deal with it appropriately.

To keep track of the view's origin and scale factor, you should intercept the messages MSG_META_CONTENT_VIEW_ORIGIN_CHANGED and MSG_META_CONTENT_VIEW_SCALE_FACTOR_CHANGED

Losing Mouse Grabs

During certain operations--for example, quick-transfers--your geode will have the mouse grab. When it loses the grab, it will be notified with a MSG_META_CONTENT_LOST_GADGET_EXCLUSIVE .

Supporting Quick-Transfer

MSG_GEN_VIEW_ALLOW_GLOBAL_TRANSFER

When using a view and supporting the quick-transfer mechanism, the view will grab the mouse when a quick-transfer operation is invoked. Conclusion of the quick-transfer operation, requires, however, that other objects know when the mouse crosses their bounds; otherwise, no other object in the system could ever become a destination for the transfer.

To relinquish the mouse grab while continuing the transfer operation, you must send MSG_GEN_VIEW_ALLOW_GLOBAL_TRANSFER to the view. The view will then let other objects get pointer events, thus letting them know when they become a potential destination for the transfer.

MSG_GEN_VIEW_ALLOW_GLOBAL_TRANSFER

void	MSG_GEN_VIEW_ALLOW_GLOBAL_TRANSFER();

This message indicates to the view that it should relinquish the mouse grab to allow a quick-transfer operation to continue. Pointer events will then be sent to other objects in the system, allowing them to accept or reject the transfer.

Source: The object with the mouse grab in the view.

Destination: The GenView displaying the caller object.

Interception: Generally not intercepted.

Keyboard Events

By default, all keyboard events not handled by the Specific UI library are passed through to the content when the view has the keyboard focus. Only views with the GVA_FOCUSABLE flags set in GVI_attrs will ever gain the focus (this is the default). Many character strokes are used for keyboard navigation or as mnemonics or accelerators and will therefore be intercepted by the Specific UI. Those that aren't will be passed on to your content.

You can set up your content to receive all keyboard events before the Specific UI has a chance to intercept them. This can have unpredictable results, however, and should be avoided unless absolutely necessary. To set up your content in this manner, set the flag GVA_SEND_ALL_KBD_CHARS in the view's GVI_attrs field. If you handle keyboard events before passing them on, you must be sure to pass every unused MSG_META_KBD_CHAR on to the UI in the form of MSG_META_VUP_KBD_CHAR . If you do not, undesirable synchronization problems could result.

You can indicate that you do not want to receive keyboard releases by setting the attribute GVA_DONT_SEND_KBD_RELEASES in the GVI_attrs record. This is provided as an optimization to improve keyboard response in applications. Most applications need to know when a key has been pressed but do not care when it has been released.

A better way to handle accelerator characters that don't appear in your UI objects is to subclass GenViewClass and intercept MSG_META_KBD_CHAR ; in the handler, take the characters you want and then call the superclass with @callsuper() to make sure unused events get passed on. As an alternative, you can subclass GenApplicationClass and change the handler for MSG_META_VUP_KBD_CHAR ; in the method, take the events you want and then call the superclass with @callsuper() .

Pen Input and Ink

GVI_inkType, MSG_GEN_VIEW_SET_INK_TYPE, MSG_GEN_VIEW_SET_EXTENDED_INK_TYPE, MSG_GEN_VIEW_RESET_EXTENDED_INK_TYPE, ATTR_GEN_VIEW_DOES_NOT_ACCEPT_TEXT_INPUT

It is suggested that you read the Input chapter, before working with Ink in the view. The GenView accepts Ink input events and can pass them to the content either as ink or as mouse events. How the view determines which type of events are desired is mandated by the value of the instance field GVI_inkType .

In addition, some views that get the focus do not accept text input. By default on many pen systems, focusable GenViews will cause an on-screen keyboard to come up on the assumption that the user may wish to enter text to objects within the view. ATTR_GEN_VIEW_DOES_NOT_ACCEPT_TEXT_INPUT allows you to specify that your view does not accept text input and therefore should not cause a floating keyboard to come up. Non-textual keyboard events (e.g. up-arrow used for scrolling) will still be transmitted to the GenView.

The GVI_inkType field will contain one of the following values (each is an enumeration of GenViewInkType ):

GVIT_PRESSES_ARE_NOT_INK
Mouse press events are not Ink input, and Ink input is not expected by the content. This is the default for views.
GVIT_INK_WITH_STANDARD_OVERRIDE
Mouse press events are considered and expected to be Ink events, but they can be overridden by the user in the normal way.
GVIT_PRESSES_ARE_INK
Mouse press events are considered and expected to be Ink.
GVIT_QUERY_OUTPUT
This value indicates that the content will expect Ink events only in certain contexts. Note that if this attribute is set, the content must handle the MSG_META_QUERY_IF_PRESS_IS_INK message.

The GVI_inkType field may be set either in your Goc code or with the message MSG_GEN_VIEW_SET_INK_TYPE , shown below.

Applications that handle Ink input can also set extended information about the Ink. The type of extended information you can set includes the color of the Ink as it's drawn, the thickness of the Ink brush, etc. Use the messages MSG_GEN_VIEW_SET_EXTENDED_INK_TYPE and MSG_GEN_VIEW_RESET_EXTENDED_INK_TYPE , shown below.

You can also pre-set the extended Ink information with the vardata attribute ATTR_GEN_VIEW_INK_DESTINATION_INFO . This attribute has an extra data structure of type InkDestinationInfoParams , shown below.

typedef struct {
	optr		IDIP_dest;
				/* destination object
				 * for Ink output. */
	word		IDIP_brushSize;
				/* Size of Ink brush. 
				 * High byte is x size,
				 * Low byte is y size. */
	byte		IDIP_color;		/* Color of Ink */
	Boolean		IDIP_createGState;
					/* Boolean indicating
					 * if the Ink should
					 * have its own
					 * GState. */
} InkDestinationInfoParams;

MSG_GEN_VIEW_SET_INK_TYPE

void	MSG_GEN_VIEW_SET_INK_TYPE(
        GenViewInkType inkType);				/* value of GenViewInkType */

This message sets the type of Ink input expected by the view's content.

Source: Unrestricted.

Destination: Any GenView object.

Parameters: inkType The type of Ink input expected.

Return: Nothing.

Interception: Generally not intercepted.

MSG_GEN_VIEW_SET_EXTENDED_INK_TYPE

void	MSG_GEN_VIEW_SET_EXTENDED_INK_TYPE(@stack
        Boolean createGState,
        Color	inkColor,
        word	brushSize,
        optr	destObj);

This message sets the extended Ink type for the GenView. The extended Ink type is stored in the vardata ATTR_GEN_VIEW_INK_DESTINATION_INFO .

Source: Unrestricted.

Destination: Any GenView object.

Parameters: createGState A boolean specifying whether the view should create a new GState for the Ink or not.

inkColor
A palette index to use as the color of the Ink.
brushSize
The brush size, in points, to be used for the Ink.
destObj
The optr of the destination object for Ink input to this view. After the Ink is collected, it will be sent to this object.

Return: Nothing.

Interception: Generally not intercepted.

MSG_GEN_VIEW_RESET_EXTENDED_INK_TYPE

void	MSG_GEN_VIEW_RESET_EXTENDED_INK_TYPE();

This message resets the extended Ink type to default values.

Source: Unrestricted.

Destination: Any GenView object.

Interception: Generally not intercepted.

Target and Focus

MSG_GEN_VIEW_UPDATE_CONTENT_TARGET_INFO

Some applications may draw some portion of their documents differently if they have the target or focus. The view will pass along the following target/focus messages: MSG_META_CONTENT_ENTER , MSG_META_CONTENT_LEAVE , MSG_META_RAW_UNIV_ENTER , MSG_META_RAW_UNIV_LEAVE , and MSG_META_CONTENT_VIEW_LOST_GADGET_EXCLUSIVE .

If you want your geode to be able to grab the focus, you must set the GVA_FOCUSABLE attribute in the GVI_attrs record.

MSG_GEN_VIEW_UPDATE_CONTENT_TARGET_INFO

void	MSG_GEN_VIEW_UPDATE_CONTENT_TARGET_INFO(
        ViewTargetInfo *targetInfo);

This message is sent to the view from VisContentClass contents whenever target information within the view changes. This is done so that MSG_META_GET_TARGET_EXCL may be used to retrieve target information about the portion of the target hierarchy which is within the content itself. (The UI can't directly call objects running in other threads, so this message is required to update it with the latest information.)

Source: A VisContent within the view.

Destination: The GenView associated with the caller.

Parameters: targetInfo A pointer to a ViewTargetInfo structure, shown below.

Return: Nothing.

Structures: The ViewTargetInfo structure has two fields, as shown:

 typedef struct {
 	optr		TR_object;		/* optr of object */
	ClassStruct		*TR_class;		/* class of object */
} TargetReference;
 typedef struct {
 	TargetReference			VTI_target;
	TargetReference			VTI_content;
} ViewTargetInfo;

The VTI_target field contains the optr and class pointer of the object in the view that currently has the target exclusive. The VTI_content field contains the optr and class pointer of the view's content object.

Interception: Generally not intercepted.

Setting the Pointer Image

MSG_GEN_VIEW_SET_PTR_IMAGE

If you want to change the pointer's image while it is over your view or while the view has the focus, use MSG_GEN_VIEW_SET_PTR_IMAGE . To use this message, you must create the new pointer image in a sharable memory block, lock the block, and pass the pointer to the locked block. To reset your request (return to the default pointer), send the same message with the pointer zeroed. The pointer image structure is detailed in the Input chapter.

MSG_GEN_VIEW_SET_PTR_IMAGE

void	MSG_GEN_VIEW_SET_PTR_IMAGE(
        optr		pointerDef;					/* Optr of pointer definition */
        PtrImageLevel		level);					/* Image level of pointer */

This message causes the view to set the pointer image to a custom image whenever the pointer is over the view.

Source: Unrestricted.

Destination: Any GenView object.

Parameters: pointerDef The optr of a chunk containing the PointerDef32 structure of the new pointer definition for the GenView (this chunk must be in a sharable memory block). Pass NullOptr for no image request. Pass the handle portion of the optr as a NullHandle and the chunk portion of the optr as a PtrImageValue value (see below).

level
A value of PtrImageLevel . This should be either PIL_GADGET, to allow individual gadgets within the view to set the pointer, or PIL_WINDOW, to set the background cursor of the view. Note that if PIV_UPDATE is passed in pointerDef , the level parameter is not used.

Return: Nothing.

Structures: PointerDef16 has the following structure (see the appropriate reference entry for a full description):

  typedef struct {
    byte		PD_width;
    byte		PD_height
    sbyte		PD_hotX;
    sbyte		PD_hotY;
    byte		PD_mask[STANDARD_CURSOR_IMAGE_SIZE];
    byte		PD_image[STANDARD_CURSOR_IMAGE_SIZE];
} PointerDef16;

Interception: Generally not intercepted.


Up: GEOS SDK TechDocs | Up | Prev: 4.7 Scrolling | Next: 4.9 Linking Views