|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
Kenneth_Smith
Joined: 18 May 2012 Posts: 697 Location: Hamilton, Lanarkshire, Scotland.
|
Posted: Wed Nov 06, 2019 11:28 pm Post subject: Left click on bitmap - how to find its handle? |
|
|
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 |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7933 Location: Salford, UK
|
Posted: Thu Nov 07, 2019 11:11 am Post subject: |
|
|
Can you provide a minimal sample program for me to look at? I can provide my own bitmap. |
|
Back to top |
|
|
Kenneth_Smith
Joined: 18 May 2012 Posts: 697 Location: Hamilton, Lanarkshire, Scotland.
|
Posted: Thu Nov 07, 2019 2:50 pm Post subject: |
|
|
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 |
|
|
Kenneth_Smith
Joined: 18 May 2012 Posts: 697 Location: Hamilton, Lanarkshire, Scotland.
|
Posted: Thu Nov 07, 2019 2:53 pm Post subject: |
|
|
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 |
|
|
Kenneth_Smith
Joined: 18 May 2012 Posts: 697 Location: Hamilton, Lanarkshire, Scotland.
|
Posted: Thu Nov 07, 2019 2:57 pm Post subject: |
|
|
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 |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7933 Location: Salford, UK
|
Posted: Thu Nov 07, 2019 5:05 pm Post subject: |
|
|
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 |
|
|
Kenneth_Smith
Joined: 18 May 2012 Posts: 697 Location: Hamilton, Lanarkshire, Scotland.
|
Posted: Thu Nov 07, 2019 7:42 pm Post subject: |
|
|
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 |
|
|
Kenneth_Smith
Joined: 18 May 2012 Posts: 697 Location: Hamilton, Lanarkshire, Scotland.
|
Posted: Fri Nov 15, 2019 12:37 pm Post subject: |
|
|
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 Not perfect yet, but very happy with this. Significantly less coding required compared to my previous schematic capture attempts. |
|
Back to top |
|
|
|
|
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
|