Silverfrost Forums

Welcome to our forums

rambling enquiry about full_mouse_input and callback_reason

13 Mar 2013 8:24 #11748

I have added mode 4 to SET_GRAPHICS_SELECTION@ but unfortunately the change will not be in time for the next release.

The following sample program previously used [box_selection] and mode 1. Now we will have [free_selection] and mode 4 as an alternative. In the first case (which you can demonstrate at the moment) you get a rubber banded box. In the new mode, no line or box will be displayed.

!FTN95$WINAPP
!------------------------------------------------------------------
    module gr7data
      character*32 cstat
      integer mstat
    end module gr7data
!---------------------------------------------------------------
    program gr7
      use clrwin
      use gr7data
      integer i
      integer,external::gr_func

      cstat=' '
      mstat=0

      i=winio@('%ww[no_border]&')
      i=winio@('%ca[Box Selection]&')
      i=winio@('%mn[E&xit]&','EXIT')
      i=winio@('%ob&')
      i=winio@('%^gr[black,free_selection,full_mouse_input]&',300,300,gr_func)
      i=winio@('%cb&')
      i=winio@('%ob[status]%20st%cb',cstat)

    end
!-----------------------------------------------------------
    integer function gr_func()
      use clrwin
      use gr7data
      integer x1,y1,x2,y2,nstat,a,b
      integer::MK_LBUTTON=1
      integer::MK_SHIFT=4
      integer::MK_CONTROL=8

      call get_mouse_info@(x1,y1,nstat)
      write(cstat(1:30),'(3I7)') x1,y1,nstat
      call window_update@(cstat)

      if(iand(nstat,MK_LBUTTON)==0.and.iand(mstat,MK_LBUTTON)/=0)then
        call get_graphics_selected_area@(x1,y1,x2,y2)
        call set_graphics_selection@(0)
        if(iand(nstat,MK_SHIFT)==MK_SHIFT) then
          call draw_rectangle@(x1,y1,x2,y2,12)
        else if(iand(nstat,MK_CONTROL)==MK_CONTROL) then
          a=0.5*(x2-x1)
          b=0.5*(y2-y1)
          call draw_ellipse@(x1+a,y1+b,a,b,12)
        else
          call draw_line_between@(x1,y1,x2,y2,12)
        endif
        call set_graphics_selection@(4)
      endif
      mstat=nstat
      gr_func=1
    end
13 Mar 2013 9:32 #11749

Excellent news: so when is the release after next? 😄 Eddie

14 Mar 2013 7:32 #11753

I will see if I can make a new DLL available for separate download immediately after the next release.

I have had another look at the sample code above and now realise that [full_mouse_input] is not needed for the basic functionality. In the following adaptation I have restored the [box_selection] and mode 1 and removed the [full_mouse_input]. You get a line drawn by default, a circle if the CTRL key is held down and a box if the SHIFT key is held down.

!FTN95$WINAPP
!------------------------------------------------------------------
    module gr7data
      character*32 cstat
    end module gr7data
!---------------------------------------------------------------
    program gr7
      use gr7data
      integer i,winio@
      integer,external::gr_func
      cstat=' '
      i=winio@('%ww[no_border]&')
      i=winio@('%ca[Box Selection]&')
      i=winio@('%mn[E&xit]&','EXIT')
      i=winio@('%ob&')
      i=winio@('%^gr[black,box_selection]&',300,300,gr_func)
      i=winio@('%cb&')
      i=winio@('%ob[status]%20st%cb',cstat)
    end
!-----------------------------------------------------------
    integer function gr_func()
      use clrwin
      use gr7data
      integer x1,y1,x2,y2,nstat,a,b
      integer::MK_SHIFT=4
      integer::MK_CONTROL=8
      call get_mouse_info@(x1,y1,nstat)
      write(cstat(1:30),'(3I7)') x1,y1,nstat
      call window_update@(cstat)
      if(clearwin_string@('CALLBACK_REASON') == 'MOUSE_LEFT_CLICK')then
        call get_graphics_selected_area@(x1,y1,x2,y2)
        call set_graphics_selection@(0)
        if(iand(nstat,MK_SHIFT)==MK_SHIFT) then
          call draw_rectangle@(x1,y1,x2,y2,12)
        else if(iand(nstat,MK_CONTROL)==MK_CONTROL) then
          a=0.5*(x2-x1)
          b=0.5*(y2-y1)
          call draw_ellipse@(x1+a,y1+b,a,b,12)
        else
          call draw_line_between@(x1,y1,x2,y2,12)
        endif
        call set_graphics_selection@(1)
      endif
      gr_func=1
    end
14 Mar 2013 2:48 #11758

LOL....I've reread the whole thread n-th time again and did not understand what it is about, what did not work, what needed to work, what problem was with full_mouse_input (i know one with right mouse menu in older versions but it is fixed long ago), what is FMI and what was fixed. I am truly amazed with the efforts though 😃

14 Mar 2013 3:48 #11760

FMI is presumably short for [full_mouse_input], an option with %gr.

Nothing has been fixed but I have added an new option [free_selection] for %gr and a new mode (4) for set_graphics_selection@.

14 Mar 2013 9:23 #11768

Dan,

FMI is as Paul stated above. If you use this option, you get overwhelmed by mouse position-and-state callbacks. If you don't use this option, then some mouse actions cannot be discerned, and some Clearwin+ options are not available. Add in to this mix that some things did not work as documented, and you get one of those frustrating situations that you often cite.

Paul,

Without FMI, call set_graphics_selection@(0) has no effect, and one is doomed to draw boxes forever! Thus, even though in the absence of FMI, a basic subset of box_select exists, it isn't much use on its own.

Eddie

15 Mar 2013 3:55 (Edited: 15 Mar 2013 3:21) #11769

I use full mouse_input for 15 years. Surprisingly, despite there was a lot of stability problems with FTN95 back then the only problem i had here i already mentioned. Of latest few years addtions I zoom particular part of x-y plot with the whatever mouse rubberband selection option or use mouse scroll button for the same purpose without slightest problems. It's not easy to extract a small code snippet from that large code but i can post a movie.

Hopefully you ensure that previous call to callback is completed before mouse will automatically generate a dozen new ones and cause conflict - that was the only trick i used.

15 Mar 2013 6:07 #11771

Eddie

Can you run my last sample above and confirm what you say about 'boxes forever'. It runs OK for me.

15 Mar 2013 9:16 #11777

Paul,

If I click-an-drag, I always get a box drawn. If I use SHIFT or CONTROL modifiers, I end up with a drawn box or circle, and with no modifier, I end up with a line. By 'doomed to draw boxes forever', I meant that the click-n-drag always draws a box initially. I tried using call set_graphics_selection@ with different parameters to make it draw (for example) an elastic line but I found that it had no effect, including not being able to turn off box select mode.

Eddie

16 Mar 2013 9:28 (Edited: 16 Mar 2013 9:45) #11788

Eddie, you are fighting with the annoying rubber boxes while it solves very little. For one small specific problem (like showing for customers nice looking zoomable slope with buildings on it) you can get almost complete freedom with 2D array of RGB pixels (put in memory with get_dib_block@ / display_dib_block@ functions) where mathematically you can do whatever you want including your own elastic lines, rubber bands exploding in small pieces when you unclick, flashes, zooms, perspective change, your own set_graphics_selections@ with mode 100 which even Paul working hard to improve CWP will realize only in year 2030.

Another option to make great looking zoomable image is to use OpenGL

16 Mar 2013 9:30 #11789

OK. The new options [free_selection] and mode 4 will provide what you want when the new DLL is available for download.

16 Mar 2013 11:49 #11790

Hi Dan,

No doubt you are right, and if programming was my only, or even main, activity, then I would probably have the knowledge and time to commit to find an alternative approach working from first principles.

What Paul is describing looks like a very welcome addition to me.

Eddie

17 Mar 2013 9:59 #11799

What specifically this option and mode 4 will be doing?

17 Mar 2013 10:40 #11802

If you run my last sample program above then the result will be the same but the rubber-banded box will not be shown.

17 Mar 2013 11:11 #11803

That 's needed option, thanks. And thanks Eddie for swearing too

9 Mar 2014 11:09 #13812

I'm returning to this thread because it seems to address a closely related set of problems.

I am trying to implement user resizing (i.e. the user dragging a window corner). This generates multiple RESIZE interrupts. However, there is too much data to be able to redraw the %gr window after each one of these, and there seems no way to determine which is the LAST resize interrupt of a series, when it is safe and required to redraw.

While the user is dragging the window corner, the left mouse button is held down. After finishing the drag the left mouse button is released. That should be the signal to redraw. However, this mouse-button-up event does not seem to be reflected in the flags returned by GET_MOUSE_INFO@ which are 256 in both conditions. Probably this is because the mouse is not actually within the window but on its border?

Is there any function which will return the current mouse state irrespective of where it is on the screen?

Otherwise it seems I have no way of determining whether the user has finished the resize and wants a redraw. It is messy to require the resize to be followed by a click within the window, which I could detect.

  • Steve
9 Mar 2014 5:04 #13813

Steve,

I was surprised when this old post re-appeared. Those mouse functions only work if one is within a graphics control, and your surmise that you had the mouse on the border seems to me to be correct. There must be a function that gets the mouse position relative to the whole screen, but if it exists in Clearwin+ it isn't documented. The one in MSDN is GetCursorPos, or probably better, GetPhysicalCursorPos.

You could experiment with strictly Clearwin+ code by looking at the parameters returned by GET_WINDOW_LOCATION@, and if the X,Y, WIDTH or HEIGHT values haven't changed by more than a certain number of pixels since the previous RESIZE event, don't bother to redraw. That should wipe out some redraws. (In later Windows, you can resize with all four borders. This changes X and Y, whereas older Windows versions only resized with right and bottom borders, thus changing only WIDTH and HEIGHT).

Eddie

9 Mar 2014 5:47 #13814

Hi Eddie - good thinking, and thanks for the quick response!

In fact it doesn't matter which corner because the mouse button is held down during the resize, and released when the user is happy with the new size. It's not possible to switch to using a different corner during the resize operation.

There are really two problems - one is the multiple redraws, and you answer that one very well - it's the same technique I use in rubberboxing. The other problem is the more serious one - of identifying the last resize interrupt so that the final redraw is correct (and of course if it's possible to identify this one, I can suppress all the preceding redraws). There's a whole series of RESIZE interrupts as you drag the window corner - and then they stop, so you need to detect an absence of interrupts! The only thing that has changed is that the mouse button has been released, and that event is not picked up in the standard Clearwin+ functions. I'll look at the Microsoft options, but I'm not really interested in the x,y position at this stage (I get this from the Clearwin resize handling), only the mouse button state, up or down: if down then the resize operation isn't finished, if up then it is.

  • Steve

  • Stephen

9 Mar 2014 7:42 #13815

Quoted from silicondale ... only the mouse button state, up or down: if down then the resize operation isn't finished, if up then it is.

You can poll the mouse button state using GetAsyncKeyState() or handle the WM_MOUSEMOVE window message.

Probably, you could just handle the WM_SIZE window message that is sent to window after it's size is changed.

10 Mar 2014 8:47 #13816

Many thanks for the suggestions, Jalih... I've tried trapping the WM_SIZE and it seems this is what Clearwin+ already does in its RESIZE message - i.e. you get a whole stream of WM_SIZE messages while dragging the corner of the window, which stop when you release the mouse button. All I want to find is the LAST one of these messages, and I think I'll only get that by using GetAsyncKeyState () or similar - if the left mouse button is down, the callback does nothing, if it's up, the callback does a redraw.

... added09:30. Just tried GetAsyncKeyState. Doesn't seem to help, because it doesn't seem to be recording the button release. Maybe I need to put in a delay loop, but that could cause all sorts of mayhem if there is a stream of WM_SIZE messages coming through that are not being handled. Surely there has to be some way of finding when the user has finished the re-sizing. Windows can't expect the window to be getting repainted for every single WM_SIZE message, can it? It can't be that simple-minded, surely?

Please login to reply.