Chapter 6:
Processing Selections
|
User selections in a graph are made by the detection of a mouse click on a chart object. During the chart drawing process a detection node (detnode) is created for each object on the screen. A detnode describes the object, e.g. its position on the screen, series and group number, color, font, line size, object type, etc. Detnodes are created for all the objects on the chart, title, frame, risers, legend, grid lines, areas, etc. The detnode is passed to a selection list API to add the object to the selection list. A selection list is a linked list of objects selected by the user. This allows the user to use SHIFT-left-click to keep adding objects to the selection list and modify an attribute to effect all selected objects. This chapter describes the process of building and manipulating detection nodes and selections lists: |
|
|
|
Detection Nodes |
|
|
Selection Lists |
|
The Detection Nodes are the internal data structures that the system uses to keep track of and manage objects in the graph. While you have access to these data structures through some API functions, it is not recommended. Selection Lists are the application's equivalent data structures that you can use to keep track of and manage objects in the graph. A complete set of API functions is available to help you create and manage selection lists and the objects they represent. |
|
NOTE: |
If your application does not draw the graph to a display or memory device, Detection Nodes are not created. Also note that you may disable this feature entirely by calling DESetDrawProcs (pDE, DE_PROCS_DRAWING_ONLY) after the call to DESetPortInfo(). This mechanism is not necessary if your application does not allow user interaction with the graph. |
|
|
||
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
Detection Nodes (also called DetNodes) are a linked list of data structures that define each element in a graph. Anytime your application calls the DrawTheGraph() or DryRunTheGraph() API function, the system will create a new linked-list of detection node records (DetNodeRec) -- one record for each object in the graph. A DetNodeRec is not created for objects that are made invisible (e.g., see the A_SHOW_... and A2D_SHOW... attributes). There is only one DetNodeList and the system maintains exclusive control of it. It is never made available to the application. The DetNodeList keeps track of all of the DetNodeRecs that were created after the most recent DrawTheGraph() or DryRunTheGraph(): |
|
|
|
Each DetNodeRec completely defines an object in the graph -- its virtual coordinates, object ID, series and groupID (where applicable), color, etc. See PGSDK API Guide for a complete description of this data structure. As objects in the graph are selected (mouse-clicked), moved, modified, or manipulated in any way, the system keeps track of the current status of the object in each DetNodeRec. With each call to DrawTheGraph() or DryRunTheGraph(), the system destroys the old DetNodeList and DetNodeRecs and creates a new DetNodeList and a complete new set of DetNodeRecs. |
|
While you have access to each DetNodeRec through API functions, it is not recommended and it is a less efficient method of using the library. The recommended and more efficient procedure is through the use of Selection Lists (SelList) and Selection Items (SelItem) which provide you with a reference into each DetNodeRec. |
|
|
|
See the PGSDK API Guide for a complete description of each of the data structures referenced here. |
|
Selection Lists are created and maintained by your application using the library's API functions. A Selection List (SelList) is a linked list of Selection Items. Each Selection Item record (SelItem) defines an object in the graph and includes all the information your application needs to manipulate the object. Each SelItem contains information from and a reference to the object's DetNodeRec. Your application can create multiple selection lists for a chart -- limited by the amount of memory available your application's environment. The library does all the dirty work for you through the use of the API functions. Many objects in the graph can be added to a selection list. This allows you to select multiple objects and perform actions on all of them with a single API function. For example, the following API function will set all line objects in the selection list at gpList to the color specified at aRGB[i]: |
|
SetGraphAttrSL (gpGraph,gpList,A_LINECOLOR_RGB,&aRGB[i]); |
|
The Selection Lists and the Selection Items they contain are created and maintained in your application. It is your application's responsibility to determine when an object in the graph has been selected (mouse-clicked) and to provide that information to the library in the form of a request for a new Selection Item in your list. Your application is responsible for creating, maintaining, and destroying the Selection List and Selection Items in the list. The API functions that are used to complete these tasks are described in the following paragraphs. All API functions that create and manage the Selection Lists are named with a "Select_" prefix (e.g., Select_AllocList, Select_AddItem, etc.). These API functions and the SelList and SelItem data structures are described in the PGSDK API Guide. |
|
The Select_AllocList() function is used to create a Selection List. The prototype is shown below: |
|
SelListPtr Select_AllocList ( void ); |
Example: |
/* Create new empty selection list */ |
|
When successfully executed, this function will return a pointer to the newly created selection list. This pointer is required as input to all other Selection Item and Selection List API functions to identify the Selection List to be manipulated. Your application must free the list when it is no longer needed. See the Select_FreeList API function later in this chapter. |
|
There are three methods that can be used to add items to a selection list. The first method adds an individual item/object definition to the Selection List based on a mouse-clicked object. The following steps are required to complete this process: |
|
|
|
Get the device coordinates of the mouse location |
|
|
Use the dvPoint() function to convert the device coordinates to virtual coordinates |
|
|
Use the FindDetNode() function to get a reference to the DetNodeRec for the object at the virtual coordinates set by dvPoint() |
|
|
Use the Select_AddItem() function to create a new SelItem record and add it to your selection list. |
|
The following example source code illustrates this method of adding a single, selected object/item to a selection list: |
|
|
/*draw environment pointer created by AllocDrawEnvPtr()*/ |
|
|
case WM_LBUTTONDOWN; |
|
|
The second method of adding items/objects to a selection list adds all detection node records (DetNodeRec) to the selection list. This method essentially creates a selection list that contains all objects in the graph as shown in the following example: |
|
|
/* loop to find each DetNodeRec that intersect point pt */ |
|
|
The third method of adding items/objects to a selection list is to programmatically "get" a detnode by specifying which chart object you want as shown in the following example. |
|
|
/*PG - get the DetNode of the frame */ |
|
After a Selection List has been created and Selection Items added to it, the following functions can be used to manipulate the items/objects in: |
|
|
|
Select_CalcHandlesItem(); Make sizing handles for an item |
|
|
Select_DrawXORItem(); Highlight/Unhighlight item |
|
|
Select_CalcHandlesList(); Make sizing handles for all items in a list |
|
|
Select_DrawXORList(); Turn On/Off Highlight for all items in a list |
|
|
Select_RemoveItem(); Remove an item from a selection list |
|
These functions are described in the following paragraphs. Also see the Get/SetGraphAttrSI() and Get/SetGraphAttrSL() functions in Chapter 7 for a description of setting object attributes in a Selection List. |
|
|
Select_CalcHandlesItem: This function calculates moving/sizing handles for the bounding rectangle of a given selection item/object: |
|
|
INT16 Select_CalcHandlesItem ( |
|
|
The input parameter pDE is a pointer to a draw environment created by AllocDrawEnvPtr(). The pSelList parameter is a pointer to a selection list created by Select_AllocList(). |
|
|
Note that moving/sizing handles are only created for moveable/sizeable items (i.e., graph title, graph subtitle, footnote, etc.). |
|
|
Select_DrawXorItem: This function draws the moving/sizing handles calculated by Select_CalcHandlesItem(). A solid XOR line is drawn around non-movable objects. Acting as a toggle, it will highlight/un-highlight any item in a selection list. |
|
|
INT16 Select_DrawXorItem ( |
|
|
The input parameter pDE is a pointer to a draw environment created by AllocDrawEnvPtr(). The pItem parameter is a pointer to an item in a selection list. |
|
|
See the sample source code below for an example of how the Select_CalcHandlesItem() and Select_DrawXORItem() functions are used. |
|
|
/* IF SHIFT KEY */ |
|
|
else |
|
|
/*--------------------------------------------*\ |
|
|
Select_CalcHandlesList: This function calculates moving/sizing handles for the bounding rectangle of all items/object in selection a list. |
|
|
INT16 Select_CalcHandlesList ( |
|
|
The input parameter pDE is a pointer to a draw environment created by AllocDrawEnvPtr(). The pSelList parameter is a pointer to a selection list created by Select_AllocList(). |
|
|
Select_DrawXORList: This function draws XOR lines around every item in a selection list. It is basically the same as the Select_DrawXorItem() function except it will highlight/unhighlight all items in a selection list. |
|
|
INT16 Select_DrawXorList ( |
|
|
The input parameter pDE is a pointer to a draw environment created by AllocDrawEnvPtr(). The pSelList parameter is a pointer to a selection list created by Select_AllocList(). |
|
|
The following example source code demonstrates how the Select_CalcHandlesList() and Select_DrawXORList() functions are used: |
|
|
/* Match up objects in selection list with new detnodes |
|
|
Select_RemoveItem: This function removes a Selection Item record (SelItem) from a selection list: |
|
|
INT16 Select_RemoveItem ( |
|
|
The input parameter pSelList is a pointer to a selection list created by Select_AllocList() and identifies the selection list from which the item is to be removed. The pItem parameter identifies the specific item to be removed. The following example code demonstrates how this function is used: |
|
|
/* IF SHIFT KEY */ |
|
The following API functions can be used to manage the selection list(s): |
|
|
|
Select_ClearList(); Removes all item records from the selection list |
|
|
Select_DuplicateList(); Makes a duplicate copy of a selection list |
|
|
Select_RebuildList(); Rebuilds a selection list based on the current DetNode List |
|
Select_ClearList: This function removes all items from a selection list. However, it does not destroy the list itself or free any memory associated with it. It simply removes the pointers to the SelItem records and frees the memory used by the selection items: |
|
|
INT16 Select_ClearList ( |
|
|
The input parameter pSelList is a pointer to a selection list created by Select_AllocList() and identifies the list to be cleared. |
|
|
/* Un-Highlight selected items */ |
|
|
Select_DuplicateList: This function creates a copy of a selection list. |
|
|
SelListPtr Select_DuplicateList ( |
|
|
The input parameter pSelList is a pointer to a selection list created by Select_AllocList() and identifies the selection list to be duplicated. |
|
|
pNewList=Select_DuplicateList(pSelList); |
|
|
Select_RebuildList: This function recalculates selection list object IDs and locations. |
|
|
INT16 Select_RebuildList ( |
|
|
The input parameter pGraph is a pointer to a graph created by AllocGraphPtr(). The pSelList parameter is a pointer to a selection list created by Select_AllocList() and identifies the selection list to be rebuilt. After a DrawTheGraph() or DryRunTheGraph(), use the Select_RebuildList() function to ensure that only valid objects are in the selection list. If objects have been made invisible, they will no longer appear in the Selection List. Select_CalcHandlesList() and Select_DrawXorList() should also be called after Select_RebuildList() so that handles also remain valid after a graph re-draw. |
|
|
/* DRAW THE GRAPH */ |
Getting Information from a Selection List
|
The following API functions can be used to get information from a Selection List: |
|
|
|
Select_GetFirstItem(); Returns a pointer to the first item in a selection list. |
|
|
Select_GetNextItem(); Returns a pointer to the next item in a selection list. |
|
|
Select_IsEqual(); Compares two SelItem records. |
|
|
Select_IsObjectSelected(); Determines if an ObjectID is in a selection list. |
|
|
Select_HandleHitTest(); Determines if mouse pointer is over a sizing handle. |
|
|
Select_GetListBounds(); Gets the boundary of a selection list. |
|
|
Select_SearchList(); Determines if a given item is in a list. |
|
Select_GetFirstItem: This function returns a pointer to the first item in a given selection list. |
|
|
SelItemPtr Select_GetFirstItem ( |
|
|
The input parameter pSelList is a pointer to a selection list created by Select_AllocList(). |
|
Example: |
SelItemPtr pSel; |
|
|
Select_GetNextItem: This function returns a pointer to the next selection item in a given selection list. |
|
|
SelItemPtr Select_GetNextItem ( |
|
|
The input parameter pSelList is a pointer to a selection list created by Select_AllocList(). |
|
|
/* Look for next item in list */ |
|
|
The Select_GetFirstItem() and Select_GetNextItem() functions can be used to go through (walk) a selection list and perform a function on each item in the list. The following sample code validates each selection item pointer in a selection list: |
|
|
BOOLEAN ValidSelItemPtr( |
|
|
Select_IsEqual: This function compares two selection list items and returns TRUE if two items are identical |
|
|
INT16 Select_IsEqual ( |
|
|
The input parameters pOne and pTwo are pointers to SelItem records in a selection list. It is not necessary that the two records reside in the same list. |
|
|
Select_IsObjectSelected: This function determines if an object is in a selection list and returns TRUE if object is in the list. |
|
|
INT16 Select_IsObjectSelected ( |
|
|
Select_HandleHitTest: This function can be used to determine if the mouse pointer is over one of an object's moving/sizing handles. It will search the selection list for handle coordinates in a SelItem record that match the mouse coordinates identified by Point. |
|
|
SelItemPtr Select_HandleHitTest ( |
|
|
If this function finds matching coordinates (i.e., mouse pointer is over a moving/sizing handle), it will set whichHandle to the handle number (0-3) and pItemRect to the virtual coordinates of the bounding rectangle. This function will return a pointer to the SelItem record where the matching coordinates were found. |
|
|
Select_GetListBounds: This function returns the bounding rectangle for all items in selection list. |
|
|
INT16 Select_GetListBounds ( |
|
|
The input parameter pSelList is a pointer to a selection list created by Select_AllocList(). The pRect parameter is a pointer to a rectangle data structure where the virtual coordinates of the resulting bounding rectangle will be stored. |
|
Example: |
Select_GetListBounds (pSelList, &rcVirt); |
|
|
Select_SearchList: This function searches a selection list for a particular detection node reference. |
|
|
SelItemPtr Select_SearchList ( |
|
|
The input parameter pSelList is a pointer to a selection list created by Select_AllocList(). The pDetRef parameter is a pointer returned from FindDetRef(). The following example demonstrates how this function is used: |
|
|
/* IF SHIFT KEY */ |
|
When your application is finished using a selection list, it must free the memory previously allocated by Select_AllocList(). Use the Select_FreeList() function to free the memory used by the selection list and any links associated with it. The prototype for this function is shown below: |
|
INT16 Select_FreeList ( SelListPtr pSelList ); |
Example: |
/* Free Mem used by Sel List */ |
|
In summary, the selection lists and selection items allow your application to determine which object(s) are selected in a chart and, based on your requirements, perform an action on one, all, or selected items in the list. |
|
The following example code illustrated how the application program can determine if an object in the graph is selected by the user/mouse button: |
|
DetNodeRef gDetNode; /* DetNode */ |
|
int i; |
|
if (FindDetNode( |
|
{ |
|
break; |
Highlighting a Selected Object
|
This following example code illustrates how your application program can highlight items/objects in a selection list. |
|
HDC hdc; |