Mouse over image

Just starting out? Need help? Post your questions and find answers here.
User avatar
le_magn
Enthusiast
Enthusiast
Posts: 289
Joined: Wed Aug 24, 2005 12:11 pm
Location: Italia

Mouse over image

Post by le_magn »

Hi everyone, does anyone know how to detect when the mouse cursor that is over an imagegadget or to buttonimage? thanks:)
Image
infratec
Always Here
Always Here
Posts: 7662
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Mouse over image

Post by infratec »

Use a CanvasGadget to show the image.
User avatar
le_magn
Enthusiast
Enthusiast
Posts: 289
Joined: Wed Aug 24, 2005 12:11 pm
Location: Italia

Re: Mouse over image

Post by le_magn »

infratec wrote: Fri Nov 15, 2024 9:21 pm Use a CanvasGadget to show the image.
I hope to succeed, also because once I fill the box I have to make the side scroll bar appear that allows to go down and display other images, and I'm not sure I know how to do it with canvas gadget, anyway I'll do some experiments in these days
Image
Olli
Addict
Addict
Posts: 1264
Joined: Wed May 27, 2020 12:26 pm

Re: Mouse over image

Post by Olli »

What do you think about WindowMouseX(), which provides you the x position of the mouse pointor ?

Once you have this position, a static image (non nested in a scroll area) could be detected under the mouse pointor.
I hope to succeed, also because once I fill the box I have to make the side scroll bar appear that allows to go down and display other images, and I'm not sure I know how to do it with canvas gadget, anyway I'll do some experiments in these days
We cannot guess the environment in which your images are nested : this requires you write a small prototype source code.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4991
Joined: Sun Apr 12, 2009 6:27 am

Re: Mouse over image

Post by RASHAD »

For PB Native commands
You need to make it detected once per gadget

Code: Select all

Global x,y,result

Procedure ismouse(gad)
  If x >= GadgetX(gad) And x <= (GadgetX(gad)+GadgetWidth(gad)) And y >= GadgetY(gad) And y <= (GadgetY(gad)+GadgetHeight(gad))
    result = 1
  Else
    result = 0
  EndIf
  ProcedureReturn result
EndProcedure

OpenWindow(0,0,0,320,500,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
ImageGadget(0,10,10,200,200,0,#PB_Image_Border)
ButtonGadget(1,220,10,90,24,"TEST")
AddWindowTimer(0,125,50)
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
      
    Case #PB_Event_Timer
      x = WindowMouseX(0)
      y = WindowMouseY(0)
      If x>= 0 And y>=0
        If ismouse(0) And result = 1 And over0 = 0
          over1 = 0
          over0 = 1
          Debug  "Mouse over ImageGadget"
        ElseIf ismouse(1) And result = 1 And over1 = 0
          over0 = 0
          over1 = 1
          Debug  "Mouse over ButtonGadget"
        EndIf 
      EndIf     
        
  EndSelect
      
Until Quit = 1
For Windows

Code: Select all

Global x,y

Procedure ismouse(gad)
  If x >= GadgetX(gad) And x <= (GadgetX(gad)+GadgetWidth(gad)) And y >= GadgetY(gad) And y <= (GadgetY(gad)+GadgetHeight(gad))
    result = 1
  Else
    result = 0
  EndIf
  ProcedureReturn result
EndProcedure

OpenWindow(0,0,0,320,500,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
ImageGadget(0,10,10,200,200,0,#PB_Image_Border)
ButtonGadget(1,220,10,90,24,"TEST")
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
      
    Case #WM_MOUSEMOVE
      x = WindowMouseX(0)
      y = WindowMouseY(0)
      If ismouse(0)
        Debug  "Mouse over ImageGadget"
      ElseIf ismouse(1)
        Debug  "Mouse over ButtonGadget"
      EndIf      
        
  EndSelect
      
Until Quit = 1

Egypt my love
User avatar
le_magn
Enthusiast
Enthusiast
Posts: 289
Joined: Wed Aug 24, 2005 12:11 pm
Location: Italia

Re: Mouse over image

Post by le_magn »

Thank's all, Rashad your code work really well, thank you
Image
Olli
Addict
Addict
Posts: 1264
Joined: Wed May 27, 2020 12:26 pm

Re: Mouse over image

Post by Olli »

I tried to make an example, and I am disappointed :

All is done with WindowMouseX() (and ~Y() ), and these commands are non adapted for the GUI queue. So it seems to stay the suggest from Rashad (use of #WM_MOUSEMOVE).

I will try canvas, but the problem then is the performances, compared to the use of images.

Note : To create the test, I integrated this :
- window resize gadget
- splitter
- scrollArea

The automations of these three objects are shown flickering and displaying artefacts.

It is the same behaviour as in a 16-years old XP computer.

I do not support anymore everything flickers, or freezes, and also what it repeats (popup), bad scaling, etc...
I do not see a real technical progress.

Fortunately, I code, but I imagine everybody who are users only. They might be lost !

I will test two next versions : canvas and full screen (I terminate by the best one). And I will post them three versions (desk, canvas and full screen).

Thank you Rashad for the advices.
AZJIO
Addict
Addict
Posts: 2223
Joined: Sun May 14, 2017 1:48 am

Re: Mouse over image

Post by AZJIO »

Perhaps this other option will suit you:
BCN_HOTITEMCHANGE

Code: Select all

EnableExplicit


Define x,y
Define co.POINT
Define hWnd
Define hWndTmp
Define Quit

Structure GdtID
	id.i
	hdl.i
EndStructure

Global NewList GdtID.GdtID()


Procedure GetGadgetPB(Handle)
	ForEach GdtID()
		If GdtID()\hdl = Handle
			ProcedureReturn GdtID()\id
		EndIf
	Next
	ProcedureReturn -1
EndProcedure


OpenWindow(0,0,0,320,500,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
ImageGadget(0,10,10,200,200,0,#PB_Image_Border)
ButtonGadget(1,220,10,90,24,"TEST")
AddElement(GdtID())
GdtID()\id = 0
GdtID()\hdl = GadgetID(0)
AddElement(GdtID())
GdtID()\id = 1
GdtID()\hdl = GadgetID(1)
Repeat
	Select WaitWindowEvent()
		Case #PB_Event_CloseWindow
			Quit = 1
			
		Case #WM_MOUSEMOVE
			GetCursorPos_(@co.POINT)
			hWnd = WindowFromPoint_(co\x | co\y << 32)
			If hWndTmp <> hWnd
				hWndTmp = hWnd
				Debug GetGadgetPB(hWnd)
; 				Debug hWnd
			EndIf
	EndSelect
	
Until Quit = 1
User avatar
TI-994A
Addict
Addict
Posts: 2749
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Mouse over image

Post by TI-994A »

le_magn wrote: Sat Nov 16, 2024 12:07 am...once I fill the box I have to make the side scroll bar appear that allows to go down and display other images, and I'm not sure I know how to do it with canvas gadget...
If I've understood correctly, you require something like an image picker, where images are selectable from a thumbnail preview page. if that is indeed the case, the CanvasGadget() approach might be better and more lightweight, instead of implementing an array of image gadgets.

Here's an example:

Code: Select all

;==================================================
;   
;   Cross-Platform Canvas Gadget Image Picker
;      
;   tested on Windows, Linux, & MacOS;   
;   with PureBasic v6.12 LTS x64
;
;   by TI-994A - free to use, improve, share...
;
;   17th November 2024 - Singapore
;
;==================================================

EnableExplicit

Enumeration
  #window1
  #window2  
  #scroller = 0
  #canvas
  #image
  #drawFont = 0
EndEnumeration

#canvasWidth = 800
#canvasHeight = 800
#thumbnailSize = 100
#imageSize = 300
#mosaicSize = 64
#mosaicRow = 8

Dim images((#mosaicRow - 1), (#mosaicRow - 1))
Define imgX, imgY, canvasX, canvasY, selectX, selectY, deltaY,
       imgCount, colour, textColour, event, appQuit, scrollSpeed

CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
  scrollSpeed = 1
CompilerElse
  scrollSpeed = 50
CompilerEndIf

; display the selected image (full-sized view)
Procedure displayImage(image_id)
  OpenWindow(#window2, 0, 0, #imageSize, #imageSize, "Selected Image",
             #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ImageGadget(#image, 0, 0, #imageSize, #imageSize, image_id)  
EndProcedure

; create some sample images
LoadFont(#drawFont,"Arial", 36)
While imgY < #mosaicSize / #mosaicRow 
  For imgX = 0 To (#mosaicRow - 1)
    imgCount + 1
    images(imgX, imgY) = CreateImage(#PB_Any, #imageSize, #imageSize, 32)
    Read colour
    textColour = 0
    If colour = #Black Or colour = #Gray Or colour = #Blue
      textColour = #White
    EndIf
    StartDrawing(ImageOutput(images(imgX, imgY)))
    DrawingMode(#PB_2DDrawing_Transparent)
    Box(0, 0, #imageSize, #imageSize, colour)
    DrawingFont(FontID(#drawFont))
    DrawText(60, 120, "Image #" + Str(imgCount), textColour)
    StopDrawing()
    If Mod(imgCount, 9) = 0
      Restore Colours
    EndIf
  Next imgX
  imgY + 1
Wend

OpenWindow(#window1, 0, 0, #canvasWidth, #canvasHeight / 2, "Image Picker", 
           #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ScrollAreaGadget(#scroller, 0, 0, #canvasWidth, #canvasHeight / 2, #canvasWidth, #canvasHeight)
CanvasGadget(#canvas, 0, 0, #canvasWidth, #canvasHeight)

; display the sample images (thumbnail view)
For imgY = 0 To (#mosaicRow - 1)
  For imgX = 0 To (#mosaicRow - 1)
    StartDrawing(CanvasOutput(#canvas))
    DrawImage(ImageID(images(imgX, imgY)), canvasX, canvasY, #thumbnailSize, #thumbnailSize)
    StopDrawing()
    canvasX + #thumbnailSize
    If canvasX => #canvasWidth
      canvasX = 0
      canvasY + #thumbnailSize
    EndIf
  Next imgX
Next imgY

Repeat
  event = WaitWindowEvent()  
  Select event
      
    Case #PB_Event_CloseWindow
      If EventWindow() = #window2
        CloseWindow(1)
      Else
        appQuit = #True
      EndIf
      
    Case #PB_Event_Gadget
      Select EventGadget()
          
        Case #canvas          
          Select EventType()               
              
            Case #PB_EventType_LeftClick
              selectX = Int(GetGadgetAttribute(#canvas, #PB_Canvas_MouseX) / #thumbnailSize)
              selectY = Int(GetGadgetAttribute(#canvas, #PB_Canvas_MouseY) / #thumbnailSize)   
              displayImage(ImageID(images(selectX, selectY)))
              
            Case #PB_EventType_MouseWheel              
              deltaY = GetGadgetAttribute(#canvas, #PB_Canvas_WheelDelta) * scrollSpeed        
              SetGadgetAttribute(#scroller, #PB_ScrollArea_Y, 
                                 GetGadgetAttribute(#scroller, #PB_ScrollArea_Y) - deltaY)              
              
          EndSelect
          
      EndSelect
      
  EndSelect
  
Until appQuit

DataSection
  Colours:    
  Data.i #Red, #Green, #Blue, #Yellow, #White, #Black, #Cyan, #Magenta, #Gray
EndDataSection

It's just a simple POC, and it includes scrollability with the scrollbar as well as the mouse wheel. :D
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
User avatar
le_magn
Enthusiast
Enthusiast
Posts: 289
Joined: Wed Aug 24, 2005 12:11 pm
Location: Italia

Re: Mouse over image

Post by le_magn »

TI-994A wrote: Sun Nov 17, 2024 10:15 am
le_magn wrote: Sat Nov 16, 2024 12:07 am...once I fill the box I have to make the side scroll bar appear that allows to go down and display other images, and I'm not sure I know how to do it with canvas gadget...
If I've understood correctly, you require something like an image picker, where images are selectable from a thumbnail preview page. if that is indeed the case, the CanvasGadget() approach might be better and more lightweight, instead of implementing an array of image gadgets.


It's just a simple POC, and it includes scrollability with the scrollbar as well as the mouse wheel. :D
Thank you very much for this code, i will try to use it in my project in these days
Image
Olli
Addict
Addict
Posts: 1264
Joined: Wed May 27, 2020 12:26 pm

Re: Mouse over image

Post by Olli »

Here is the first example. 256 images in a gui structure as this :
window,resizable>splitter>scrollArea>images

Bug report for WindowMouseX() (and ~Y) ? (flickering, control stop, etc...)

Code: Select all

DisableDebugger
q = 255
Dim img(q)
Dim gad(q)
Dim gadX(q)
Dim gadY(q)
Dim gadW(q)
Dim gadH(q)
win0 = OpenWindow(#PB_Any, 100, 100, 400, 300, "", #PB_Window_SystemMenu | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget)
gad0Y = 64
gad0 = ScrollAreaGadget(#PB_Any, 0, gad0Y, 400, 300, 400, 64 * (q+1), 32)
For i = 0 To q
  img(i) = CreateImage(#PB_Any, 64, 48, 32, RGBA(i >> 4 & 3 * 85, i >> 2 & 3 * 85, i & 3 * 85, 255) )
  gadX(i) = 10 + (1 + Cos(i / 4) ) * 133
  gadY(i) = 10 + 64 * i
  gadW(i) = 64
  gadH(i) = 48
  gad(i) = ImageGadget(#PB_Any, gadX(i), gadY(i), gadW(i), gadH(i), ImageID(img(I) ) )
  TextGadget(#PB_Any, gadX(i) + gadW(i) + 16, gadY(i), gadW(i), gadH(i), Str(i) )
Next
CloseGadgetList()
gad1 = ImageGadget(#PB_Any, 0, 0, 400, 64, ImageID(img(0) ) )
gad2 = SplitterGadget(#PB_Any, 0, 0, 400, 300, gad1, gad0, #PB_Splitter_Separator)
SetGadgetState(gad2, gad0y)
SetGadgetAttribute(gad2, #PB_Splitter_FirstMinimumSize, gad0y)
Repeat
  ev = WaitWindowEvent()
  If ev = #PB_Event_SizeWindow
    ResizeGadget(gad2, 0, 0, WindowWidth(win0), WindowHeight(win0) )
  Else
    If EventType() <> #PB_EventType_Change
      mx0 = mx
      my0 = my
      mX = WindowMouseX(win0)
      my = WindowMouseY(win0)
      If (mx <> mx0) Or (my <> my0)
        gad2y2 = GetGadgetState(gad2)
        gad0y = GadgetY(gad0)
        my + GetGadgetAttribute(gad0, #PB_ScrollArea_Y) - gad0y
        For i = 0 To q
          x = mx - gadX(i)
          If x > 0
            If x < gadW(i)
              y = my - gadY(i)
              If y > 0
                If y < gadH(i)
                  If i <> i0
                    SetGadgetState(gad1, ImageID(img(i) ) )
                    SetGadgetState(gad2, gad2y2)
                    i0 = i
                  EndIf
                  Break
                EndIf
              EndIf
            EndIf
          EndIf
        Next
      EndIf
    EndIf
  EndIf
Until ev = #PB_Event_CloseWindow
This line :

Code: Select all

SetGadgetState(gad2, gad2y2)
It is really crazy ! This also :

Code: Select all

If EventType() <> #PB_EventType_Change
All these strange lines are to reduce the flickering. Note that the number of images can be reduced (variable q.i ).

Now I will do the FullScreen version. I think we will change the scale of the quantity of images (without flickering). And after I will check if the canvas supports it, but I doubt...
Post Reply