Page 1 of 1

Native Cursor functions

Posted: Thu Jul 21, 2022 6:44 am
by jacdelad
I don't know if that's easily implementable, but I feel like PureBasic should have some basic functions regarding the mouse cursor, like changing for the whole program or single gadgets, loading external cursors etc.

Re: Native Cursor functions

Posted: Sat Jul 23, 2022 7:34 am
by Olli
Hello, actually a canvas allows us to change the mouse cursor (container canvas option). Does it already miss anything in this option ?

Re: Native Cursor functions

Posted: Sat Jul 23, 2022 7:44 am
by jacdelad
You mean putting a canvas in the background of the whole window?

Re: Native Cursor functions

Posted: Sat Jul 23, 2022 7:02 pm
by Olli
Doc page about canvas

<<
#PB_Canvas_CustomCursor

Changes the cursor that is displayed when the mouse is over the gadget to a custom cursor handle created using the corresponding OS API. This attribute expects the following kind of input:

Windows: a HCURSOR handle
Linux: a GtkCursor pointer
Mac OSX: a pointer to a Cursor structure
>>

Re: Native Cursor functions

Posted: Sat Jul 23, 2022 10:39 pm
by jacdelad
What about other gadgets? The whole window? Systemwide?
I found a few examples but none does really work reliable.

Re: Native Cursor functions

Posted: Mon Jul 25, 2022 2:13 pm
by benubi
This would require it's own little sub-library. As you can see every OS requires a different structure, pointer or handler for the mouse cursor object - different from the Image objects or the ImageID that is used inside the drawing libraries.

It may not be so trivial; it seems that generally you could associate a cursor for each class of (and / or individual) gadgets, at least that's how I know it from the Windows API. As for animated cursors, they may have different features for each OS (play once, loop, on mouse click or something like that - idk) so this may also need some deeper consideration.

This would be my first "proposal" of how a cursor library could look like.

Code: Select all

; Mouse Cursor
; Pseudo PB library

Structure PBMouseCursor
       OSHandle.i ; HCursor, *GtkCursor, *Cursor
       flags.i ;  1=is animated
       hotspot_x.i ;
       hotspot_y.i ;
       Image.i      ;  
       List AssociatedGadgets.i() ; points to a structure or element that contains #Gadget and the default/old cursor value to be reset on FreeCursor()
       List AssociatedWindows.i()
EndStructure

; following procedures would have to be implemented for each platform independently, currently that would be 3x at least

; "Minimum" functionality
Declare LoadCursor(#Cursor, File$ [, flags])
Declare CatchCursor(#Cursor, *Memory [, Length [, flags]])
Declare FreeCursor(#Cursor)
Declare CreateCursor(#Cursor, #Image, HotspotX, HotspotY [, flags])

Declare SetWindowCursor(#Window, #Cursor)
Declare SetGadgetCursor(#Gadget, #Cursor)

; More functionality:
Declare GetWindowCursor(#Window)
Declare GetGadgetCursor(#Gadget)

Declare GetCursorHotspotX(#Cursor)
Declare GetCursorHotspotY(#Cursor)
Declare GetCursorHeight(#Cursor)
Declare GetCursorWidth(#Cursor)

Declare GetCursorImage(#Cursor)
;Declare SetCursorImage(#Cursor, #Image)
; (...)

Declare SaveCursor(#Cursor, File$ [, format])
Declare ExportCursor(#Cursor [, format])

I count at least 6 procedure for basic functionality. When a cursor is released all windows and gadgets using it must have their associated cursor reset. This must also be considered by the window & gadget libraries when they free their windows and gadget to update the cursor association lists. So there would be work to be done on 3 libraries at least, including the new one.

The Image may have to be released, it may also only be present when creating the cursor with CreateCursor(); because the loadcursor() and catchcursor() would have to extract the image from the platform dependent cursor objects, most probably. So this is relatively labor intensive, especially when you want to have the image accessible for PB drawing. For example windows cursors, icons etc. are based on the bitmap format and bit-masks for transparency, but there are also possibly newer formats like png; and other platforms most probably use completely different image and mask formats. It may be easier to use the API to draw the cursor into a new image, instead of extracting it manually, when the cursor file is loaded or caught...

Not so trivial if you want to make it "perfect". :lol:

Re: Native Cursor functions

Posted: Mon Jul 25, 2022 3:52 pm
by Paul
Just a side note, PureVision comes with a PurePoint library which allows its users to design Windows cursors and then use them in their Projects.
Cursors can be global to a Form or change depending on what Gadget is hovered over.

Here is a video showing a PurePoint Windows Cursor and this is the code to make it work...
https://youtu.be/lGgNLCdXlyU

Code: Select all

XIncludeFile "C:\PureVision64\Modules\Module_PVGadgets.pbi"

#Main=0
#List1=1
#List2=2

If OpenWindow(#Main,0,0,450,300,"Demo",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  ListIconGadget(#List1,10,10,200,200,"Demo",100)
  ListIconGadget(#List2,220,10,200,200,"Demo",100)
  
  hPoint1=PVX::PurePoint("cross.pvp")               ;<-- Load PurePoint1 from File
  hPoint2=PVX::PurePoint("pencil.pvp")              ;<-- Load PurePoint2 from File
  
  quitMain=0
  Repeat
   
    If PVX::PurePointChild(#Main)=GadgetID(#List1)  ;<-- If PurePoint is over ListIconGadget 1
      PVX::UsePurePoint(hPoint1)                    ;<-- Display PurePoint
    EndIf
    If PVX::PurePointChild(#Main)=GadgetID(#List2)  ;<-- If PurePoint is over ListIconGadget 2
      PVX::UsePurePoint(hPoint2)                    ;<-- Display PurePoint
    EndIf
        
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        quitMain=1
        
    EndSelect
        
  Until quitMain
  
  PVX::FreePurePoint(hPoint1)                       ;<-- Free PurePoint1
  PVX::FreePurePoint(hPoint2)                       ;<-- Free PurePoint2
EndIf

Re: Native Cursor functions

Posted: Mon Jul 25, 2022 4:28 pm
by jacdelad
Aye ok, thought it would be easier. I'm firm with Windows API, so maybe I can make a little module (at least for Windows).