Function GraSegFind() Foundation

Identifies graphic segment based on a given point in the coordinate system.

Syntax
GraSegFind( [<oPS>], <aPoint> ) --> aSegmentIDs
Parameters
<oPS>
The argument <oPS> specifies the presentation space in which to search for graphic segments. If the current window is an XbpCrt window, <oPS>is optional. If it is NIL, the return value of SetAppWindow():presSpace() is used. In all other cases <oPS> is not optional. It must be created using XbpPresSpace():new(). A "Micro PS" cannot be used for this function.
<aPoint> := { <nX>, <nY> }
<aPoint> is an array of two elements which determines the coordinates for the point by which segments are searched and identified. The first element <nX> specifies the x coordinate and the second element <nY> specifies the y coordinate. The unit for the coordinates depends on the coordinate system defined for the presentation space. If no presentation space is specified, the values for the coordinates are given in pixels, which is the unit for a window. The origin for the coordinates (the point {0,0}) is the lower left.
Return

The return value of GraSegFind() is an array containing the numeric codes (segment IDs) for all graphic segments which encompass the point <aPoint>. If no such segment exists, an empty array is returned. The segment IDs are listed in the array according to the priority of the segments. The segment ID of the segment with the highest priority is the first array element, and remaining segments are ordered by decreasing priority. The priority is analogous to a z axis in a three dimensional coordinate system.

Description

Graphic segments are searched by specifying a point. When the coordinates of <aPoint> lie within a segment, the function GraSegFind() includes the numeric segment ID in the return array of all segments encompassing the indicated point<aPoint>.

This function is also used to identify or to find a graphic segment based on the position of the mouse pointer. Be aware that segments are able to overlap each other so that a given point may be in several segments. In such a case it is not clearly determined in which segment the mouse pointer is located.

The resolution with which segments are searched is set by the function GraSegPickResolution().

The position of the mouse pointer is established by the function AppEvent(). The coordinates for the mouse pointer are found in the first message parameter. For an XbpCrt window, only the text mode row and column coordinates {nRow, nCol} are included. For the message parameters to return graphic coordinates {nX, nY}, the mode for the mouse coordinates must be switched for an XbpCrt window:

                                      // graphic coordinates 
SetAppWindow():mouseMode := XBPCRT_MOUSEMODE_PM 
                                      // text coordinates 
SetAppWindow():mouseMode := XBPCRT_MOUSEMODE_VIO 

Examples
Finding graphic segments
// The example defines 3 segments and indicates the color of all 
// segments which are clicked with the left mouse button 

#include "Gra.ch" 
#include "Xbp.ch" 
#include "Appevent.ch" 

PROCEDURE Main 
   LOCAL nBox1, nBox2, nArc, aAttrBox1, aAttrBox2, aAttrArc 
   LOCAL aSegment, mp1, mp2, nEvent := xbe_None 

   CLS 

   aAttrBox1 := Array( GRA_AA_COUNT )  // fill attributes for areas 
   aAttrBox1 [ GRA_AA_COLOR ] := GRA_CLR_RED 
   aAttrBox1 [ GRA_AA_MIXMODE] := GRA_FGMIX_OR 

   aAttrBox2 := Array( GRA_AA_COUNT ) 
   aAttrBox2 [ GRA_AA_COLOR ] := GRA_CLR_GREEN 
   aAttrBox2 [ GRA_AA_MIXMODE] := GRA_FGMIX_OR 

   aAttrArc := Array( GRA_AA_COUNT ) 
   aAttrArc [ GRA_AA_COLOR ] := GRA_CLR_BLUE 
   aAttrArc [ GRA_AA_MIXMODE] := GRA_FGMIX_OR 

                                       // graphic coordinates 
   SetAppWindow():mouseMode := XBPCRT_MOUSEMODE_PM 
   SetMouse(.T.)                       // activate mouse 

   GraSetAttrArea( NIL, aAttrBox1 )    // first segment: box 
   nBox1 := GraSegOpen( NIL, GRA_SEG_MODIFIABLE ) 
   GraBox( NIL, { 80,120}, {200,200}, GRA_FILL ) 
   GraSegClose() 
   GraSegDraw( NIL, nBox1 ) 

   GraSetAttrArea( NIL, aAttrBox2 )    // second segment: box 
   nBox2 := GraSegOpen( NIL, GRA_SEG_MODIFIABLE ) 
   GraBox( NIL, {150, 70}, {330,150}, GRA_FILL ) 
   GraSegClose() 
   GraSegDraw( NIL, nBox2 ) 

   GraSetAttrArea( NIL, aAttrArc )     // third segment: circle 
   nArc := GraSegOpen( NIL, GRA_SEG_MODIFIABLE ) 
   GraArc( NIL, {120,100},  70,,,, GRA_FILL ) 
   GraSegClose() 
   GraSegDraw( NIL, nArc ) 

   DO WHILE nEvent <> xbeM_RbClick     // exit with right 
                                       // mouse click 
      nEvent := AppEvent( @mp1, @mp2,,0 ) 

      IF nEvent == xbeM_LbDown         // left button pressed 
                                       // search segments 
         aSegment := GraSegFind(NIL, mp1 ) 

         @ MaxRow(),0 SAY Space(80) 
         SetPos(MaxRow(),0) 

         IF Empty(aSegment)            // no segment found 
            ?? "Outside" 
            LOOP 
         ENDIF 

         IF AScan(aSegment, nBox1) > 0 
            ?? " Red"                  // first segment 
         ENDIF 

         IF AScan(aSegment, nBox2) > 0 
            ?? " Green"                // second segment 
         ENDIF 

         IF AScan(aSegment, nArc) > 0 
            ?? " Blue"                 // third segment 
         ENDIF 

      ENDIF 
   ENDDO 

RETURN 
Feedback

If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.