In this section:
It is possible to supply the user with more interesting ways to interact with your graphics area than merely clicking with the mouse. A %gr (Graphics Region) drawing surface can have an icon resource 'attached' to it. The icon can be moved freely around the graphics window with the mouse. Control of the icon is maintained by the call-back function attached to %gr.
ADD_GRAPHICS_ICON@ is used to attach an icon resource (defined in a resource script) to the current screen drawing surface. A NAME argument is used to stipulate the resource. X and Y variables are used as arguments that hold the initial location of the image. These variables also hold the new position when the image is moved. The call-back function for %gr can modify the X and Y values if required. In this way it is possible to 'lock' the image on to a horizontal or vertical plane by repeatedly setting either X or Y to a constant value.
The width and height arguments of ADD_GRAPHICS_ICON@ should be set to zero except when the icon image is less than 32x32 pixels. A smaller icon is constructed by starting at the top-left corner and by filling the remaining unused area with the 'transparent' colour. In this case, if you do not specify the correct size of the icon then the unused area will be detected by the mouse.
CLEARWIN_INFO@('DRAGGED_ICON') returns the handle of the icon that has moved. This handle is initially obtained as the value returned by ADD_GRAPHICS_ICON@.
When the icon is dropped, CLEARWIN_INFO@('DROPPED_ICON') returns the handle of the associated icon. A graphics icon can be removed with a call to REMOVE_GRAPHICS_ICON@.
The following program draws a horizontal scale with an icon that can be dragged across it. The resource script attaches an icon file to the 'arrow_r' resource in the program. The Windows API function ClipCursor is used to provide a clipping rectangle for the mouse cursor when the left mouse button is held down over the icon. The Silverfrost intrinsic CORE4 is used to pass a NULL pointer to ClipCursor.
WINAPP 0,0,'gr15x.rc'
INCLUDE <windows.ins>
INTEGER i,x,y
COMMON x,y
EXTERNAL start_cb,gr_cb
x=46
y=50
i=winio@('%ww[no_border]%ca[Movable icon]&')
i=winio@('%`cu&',CURSOR_ARROW)
i=winio@('%^gr[grey,rgb_colours,full_mouse_input]&',
+ 300,100,gr_cb)
i=winio@('%sc',start_cb)
END
INTEGER FUNCTION start_cb()
INCLUDE <clearwin.ins>
INTEGER i,x,y,xx,green
COMMON x,y
i=add_graphics_icon@('arrow_r',x,y,10,26)
green=RGB@(0,255,0)
CALL draw_line_between@(50,y,251,y,green)
DO xx=50,245,5
CALL draw_line_between@(xx,y-5,xx,y,green)
ENDDO
DO xx=50,250,50
CALL draw_line_between@(xx,y-10,xx,y,green)
ENDDO
start_cb=1
END
INTEGER FUNCTION gr_cb()
INCLUDE <windows.ins>
INTEGER mx,my,mf,x0,y0,w0,h0,x,y,hwnd,rc(4)
COMMON x,y
LOGICAL L,WasDrag,IsDrag
DATA WasDrag/.FALSE./
CALL get_mouse_info@(mx,my,mf)
IsDrag=clearwin_info@('dropped_icon').NE.0
IF(.NOT.WasDrag.AND.IsDrag)THEN
IF(mx.GE.x.AND.mx.LE.x+10.AND.my.GE.50.AND.my.LE.75)THEN
hwnd=clearwin_info@('latest_formatted_window')
CALL get_window_location@(hwnd,x0,y0,w0,h0)
rc(1)=x0+48
rc(2)=y0+70
rc(3)=x0+256
rc(4)=y0+95
L=ClipCursor(rc)
WasDrag=.TRUE.
ENDIF
ENDIF
IF(WasDrag.AND..NOT.IsDrag)THEN
L=ClipCursor(CORE4(0))
WasDrag=.FALSE.
ENDIF
y=50
IF(x.LT.46) x=46
IF(x.GT.246)x=246
gr_cb=1
END