I have tried various ways of displaying coordinates interactively as the mouse moves across a %pl graph. After much experimenting, I have concluded that the method outlined in the code below is the most flexible and I shall be using this as the basis for new code.
I am sharing this demonstration code, in the hope that other %pl users may find this useful.
module p
use clrwin
implicit none
real*8 :: plx(5) = [0,1,2,3,4]
real*8 :: ply(5) = [0,1,4,9,16]
integer :: pl_handle = 1, gr_handle = 2, follow_mouse = 1
contains
integer function g()
integer :: iw, i
i = create_graphics_region@(gr_handle,900,620)
call winop@('%pl[y_min=0,y_max=16,x_min=0,x_max=4]')
iw = winio@('%fn[Consolas]%ts%mn[Exit]%`rb[Follow mouse]%ff&',1.5d0,'exit',follow_mouse)
iw = winio@('%`^pl[native,frame,etched,gridlines,x_array,full_mouse_input]&',900,620,5,plx,ply,pl_handle,pl_cb)
iw = winio@('')
g = 1
end function g
integer function pl_cb()
character(len=256) CLEARWIN_STRING@, callback_reason
logical, save :: active = .false., first = .true.
integer :: i, xpixel, ypixel
integer, save :: black, light_yellow
real*8 :: xx, yy, x(1), y(1)
character(len=12) xstr, ystr
character(len=36) str
if (active) then
pl_cb = 2
return
end if
if (first) then ; black = rgb@(0,0,0) ; light_yellow = rgb@(255,255,204)
first = .false.
end if
active = .true.
callback_reason = clearwin_string@('CALLBACK_REASON')
if ( CALLBACK_REASON .eq. 'PLOT_ADJUST' ) then
call SET_PLOT_MODE@(1)
call DRAW_SYMBOLSD@(plx,ply,5,6,5,rgb@(255,0,0)) ! Use this to draw the symbols at the data points
call SET_PLOT_MODE@(0)
i = copy_graphics_region@(gr_handle,0,0,900,620,pl_handle,0,0,900,620, 13369376)
else if (callback_reason .eq. 'MOUSE_MOVE') then
if (follow_mouse .eq. 1) then
i = copy_graphics_region@(pl_handle,0,0,900,620,gr_handle,0,0,900,620, 13369376)
xpixel = CLEARWIN_INFO@('GRAPHICS_MOUSE_X') ; ypixel = CLEARWIN_INFO@('GRAPHICS_MOUSE_Y')
i = GET_PLOT_DATA@(xpixel, ypixel, xx, yy)
if (xx .ge. minval(plx)) then ! better to evalute this limits prior to the plot being generated
if (xx .le. maxval(plx)) then
if (yy .ge. minval(ply)) then
if (yy .le. maxval(ply)) then
write(xstr,'(EN12.3)') xx ; write(ystr,'(EN12.3)') yy
xstr = adjustl(xstr) ; ystr = adjustl(ystr)
write(str,'(a)') trim(xstr)//achar(13)//char(10)//trim(ystr)
call size_in_pixels@(18,9)
call draw_filled_rectangle@(xpixel+5,ypixel+5,xpixel+10+100,ypixel+45,light_yellow)
call draw_characters@(str,xpixel+10,ypixel+30,black)
end if
end if
end if
end if
end if
end if
active = .false.
pl_cb = 1
end function pl_cb
end module p
program main
use p
implicit none
integer :: i
i = g()
end program main