forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Left click on bitmap - how to find its handle?

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> ClearWin+
View previous topic :: View next topic  
Author Message
Kenneth_Smith



Joined: 18 May 2012
Posts: 697
Location: Hamilton, Lanarkshire, Scotland.

PostPosted: Wed Nov 06, 2019 11:28 pm    Post subject: Left click on bitmap - how to find its handle? Reply with quote

I’ve now got my popup menus working and I have been using them to add bitmaps to the %gr region, and I can move them around the graphics area.

Suppose I now want to select a bitmap and process some data associated with the item represented by the bitmap.

If I left click on an area without a bitmap, using clearwin_string@(‘callback_reason’) in the %^gr call back will return MOUSE_LEFT_CLICK followed by MOUSE_LEFT_RELEASE. If I left click and release on a bitmap it returns LEFT_MOUSE_PRESS – so I can differentiate between a left click on a free area and on a bitmap. (LEFT_MOUSE_PRESS does not appear in the CW documentation.)

If I click left on a bitmap, followed by a right click to activate the popup menu, the initial left click %gr call back reason MOUSE_LEFT_PRESS can be saved along with the mouse coordinates from GRAPHICS_MOUSE_X and GRAPHICS_MOUSE_Y and passed to the %pm call back. If the %gr call back reason is not MOUSE_LEFT_PRESS, then the %pm returns without doing anything.

Otherwise, as I know the top left coordinates of each bitmap and the size of each bitmap, I could then do a “point in rectangle” test to identify the selected bitmap, and then carry out whatever actions are required.

I suspect (or perhaps I should say hope) that there may be a more direct approach to identify the handle of a bitmap when the user clicks on (but does not move) it, but I’ve failed to find it. Does it exist?

Clearwin_info@(‘DRAGGED_ICON’) is not what
I am looking for as the bitmap is not being moved in this case.

Thanks

Ken
Back to top
View user's profile Send private message Visit poster's website
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Thu Nov 07, 2019 11:11 am    Post subject: Reply with quote

Can you provide a minimal sample program for me to look at? I can provide my own bitmap.
Back to top
View user's profile Send private message AIM Address
Kenneth_Smith



Joined: 18 May 2012
Posts: 697
Location: Hamilton, Lanarkshire, Scotland.

PostPosted: Thu Nov 07, 2019 2:50 pm    Post subject: Reply with quote

Paul,

Hopefully you will be able to see what I am trying to do in the following code. Essentially, left click on bitmap, followed by right click to bring up %pm, then select do something, at which point I need a means of identifying the handle of the selected bitmap.

Part 1

Code:
! Compile with Win32
module component_mod
implicit none
private
public init_all_component, component, component_type, next_available_component

integer, parameter :: dp = kind(1.d0)
  type component_type
!   This type defines a generic component type
!     x, y                 - integer global coordinates of bitmap representing component on graphics area
!     handle               - integer windows handle created when the bitmap is drawn on the graphics area
!     used                 - logical variable, set to .TRUE. if the component is in use, .FALSE. otherwise
!     orient               - character string describing orientation of component in bitmap
!     description          - character string describing circuit element
    integer          :: x
    integer          :: y
    integer(kind=7)  :: handle
    logical          :: used
    character(len=5) :: orient
    character(len=20):: description
  end type component_type
integer, parameter :: no_component_max = 100            !Maximum size of array for component storage
type(component_type) :: component(1:no_component_max)   !Static array for component storage

  contains

  integer function reset_component(n)
! This function resets the content of single component n to unused state 
  integer, intent(in) ::n
    component(n)%x            = 0
    component(n)%y            = 0
    component(n)%handle       = 0
    component(n)%used         = .false.
    component(n)%orient       = ' '
    component(n)%description  = ' '
    reset_component = 1
  end function reset_component

  integer function init_all_component()
! This function resets all components to unused state
  include<windows.ins>
  integer i, j
    do i = 1, no_component_max, 1
       j = reset_component(i)
    end do
    init_all_component = 1
  end function init_all_component

  integer function next_available_component()
! This function returns the next available component slot.
! Returns 0 if no slots are available. 
  integer i
      print*
      print*, 'Beginning next_available_component'
      next_available_component = 0
      do i = 1, no_component_max, 1
        if ( .not.(component(i)%used) ) then
          next_available_component = i
          exit
        end if
      end do
      print*, 'Component allocated ', i
  end function next_available_component

end module component_mod
Back to top
View user's profile Send private message Visit poster's website
Kenneth_Smith



Joined: 18 May 2012
Posts: 697
Location: Hamilton, Lanarkshire, Scotland.

PostPosted: Thu Nov 07, 2019 2:53 pm    Post subject: Reply with quote

Part 2

Code:

module gui_mod
use component_mod
implicit none
  private
  public build_gui_func
  integer, parameter :: dp = kind(1.d0)
  integer :: graphics_size_x = 400, graphics_size_y = 400, x1, y1
  integer(kind=7) :: gr_handle, win_handle
  character(len=20) gr_cb_reason
 
  contains
 
    integer function build_gui_func()
      include<windows.ins>
      integer, save :: iw
        iw = init_all_component()
        iw = winio@('%mn[Exit]&','EXIT')
        iw = winio@('%hw&', win_handle)
        iw = winio@('%^gr[white,FULL_MOUSE_INPUT,POPUP]&',graphics_size_x, graphics_size_y, gr_cb)
        iw = winio@('%lc&',gr_handle)
        iw = winio@('%pm[ Add[Resistor],Do something]&',  &
                     add_resistor_cb,               &
                     do_something_cb)
        call SET_GRAPHICS_SELECTION@(0)
        iw = winio@(' ')
        build_gui_func = 1
    end function build_gui_func

    integer function gr_cb()
    include<windows.ins>
    integer, save :: call_no = 0
      call_no = call_no + 1
      print*; print*,'Beginning GR_CB. Call: ', call_no
      gr_cb_reason = trim(clearwin_string@('CALLBACK_REASON'))
      print*,'gr_cb_reason: ',gr_cb_reason
      if (gr_cb_reason .eq. 'LEFT_MOUSE_PRESS') then
        print*, 'This may be a good point to be able to identify the bitmap handle'
      end if
      print*, 'Completed GR_CB'
      gr_cb = 1
    end function gr_cb

    integer function get_popup_x_y_gr()
      include<windows.ins>
      integer x(0:2), y(0:2), g_width, g_height
!     Note: x1, y1, win_handle, gr_handle are module variables     
       call GET_WINDOW_LOCATION@(win_handle,x(0),y(0),g_width,g_height)
       call GET_WINDOW_LOCATION@(gr_handle, x(1),y(1),g_width,g_height)
       x(2) = clearwin_info@('POPUP_X') ; y(2) = clearwin_info@('POPUP_Y')
       x1 = x(2) - x(0) - x(1) ; y1 = y(2) - y(0) - y(1)
       get_popup_x_y_gr = 1
    end function get_popup_x_y_gr
Back to top
View user's profile Send private message Visit poster's website
Kenneth_Smith



Joined: 18 May 2012
Posts: 697
Location: Hamilton, Lanarkshire, Scotland.

PostPosted: Thu Nov 07, 2019 2:57 pm    Post subject: Reply with quote

Part 3 (final)

Code:

    integer function do_something_cb()
    include<windows.ins>
    integer(kind=7) i
      print* ; print*,'Beginning rotate_cb'
      print*,trim(clearwin_string@('CALLBACK_REASON'))
      if (gr_cb_reason .eq. 'LEFT_MOUSE_PRESS') then
       
        i = clearwin_info@('GRAPHICS_MOUSE_X')
        print*, 'GRAPHICS_MOUSE_X', i
        i = clearwin_info@('GRAPHICS_MOUSE_Y')
        print*, 'GRAPHICS_MOUSE_Y', i ; print*
        print*, 'THIS IS THE POINT WHERE I NEED TO IDENTIFY THE HANDLE OF THE BITMAP'
      end if
      do_something_cb = 1
    end function do_something_cb
     
    integer function add_resistor_cb()
!     This is the call back function which is called when the user selects menu item ADD_RESISTOR
      include<windows.ins>
      integer(kind=7),save :: i, i2
        print* ; print*,'Beginning call back add_resistor'
        ! 1. Get coordinates where the right mouse click occured
             i = get_popup_x_y_gr()
        ! 2. Find next available component slot
             i = next_available_component()
             if ( i .eq. 0) STOP 'No component slots available'
        ! 3. Copy coordinates of right mouse click to x, y coordinates where mouse was clicked
             component(i)%x  = x1
             component(i)%y  = y1
        ! 4. Mark the selected component slot as used
             component(i)%used  = .true.
        ! 5. Attach horizontal resistor bmp at location where mouse click occured
             i2 = add_graphics_icon@('resistor_h',component(i)%x,component(i)%y,0,0)
        ! 6. Log windows handle of the bpm icon.  This is the value of i set by call to add_graphics_icon@
             component(i)%handle = i2
        ! 7. Log the resistor oritentation as 'H'
             component(i)%orient = 'H'
        ! 8. Log the component description as a 'resistor'
             component(i)%description  = 'resistor'
        print*,'Completed call back add_resistor. Handle: ', component(i)%handle
        add_resistor_cb = 1
    end function add_resistor_cb
   
end module gui_mod

program main
use gui_mod, only : build_gui_func
implicit none
integer i
i = build_gui_func()
end program main

resources
resistor_h BITMAP "c:/gui/resistor_h"     ! 50x50 bitmap of resistor

Back to top
View user's profile Send private message Visit poster's website
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Thu Nov 07, 2019 5:05 pm    Post subject: Reply with quote

The call to add_graphics_icon@ uses (x,y) coordinates for the initial position. When the image is dragged, your variables (x,y) are updated to the new position of the image.

So you can get work out the handle (which is i2, the result of calling add_graphics_icon@) from the current left mouse click position, the current values of (x,y) and the dimensions of the image.

There may be problems if/when images overlap. Your code may need to work out which image is on top. This might be the last one to be moved.
Back to top
View user's profile Send private message AIM Address
Kenneth_Smith



Joined: 18 May 2012
Posts: 697
Location: Hamilton, Lanarkshire, Scotland.

PostPosted: Thu Nov 07, 2019 7:42 pm    Post subject: Reply with quote

Thanks Paul, I can see how that works.
I am looking at schematic capture again in order to overcome a number of limitations in the code I originally pulled together last year, which does not use bitmaps. Other users tell me it's "too clunky" to use, and there were some unfortunate decisions made at the beginning related to storage of data. So I am trying to address both of these issues now.
Cheers
Ken
Back to top
View user's profile Send private message Visit poster's website
Kenneth_Smith



Joined: 18 May 2012
Posts: 697
Location: Hamilton, Lanarkshire, Scotland.

PostPosted: Fri Nov 15, 2019 12:37 pm    Post subject: Reply with quote

Making progress over the last few evenings.

https://www.youtube.com/watch?v=E2TVZX-rFT0

Watch out for the guest appearance of the native %pl Very Happy Not perfect yet, but very happy with this. Significantly less coding required compared to my previous schematic capture attempts.
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> ClearWin+ All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group