About Monkey 2 › Forums › Monkey 2 Code Library › SystemCursor (wrapper class for SDL_Cursor)
This topic contains 6 replies, has 2 voices, and was last updated by
AdamStrange
1 year, 7 months ago.
-
AuthorPosts
-
September 13, 2017 at 3:44 am #10438
This class allow us to change system app cursor.
Profit: all raw SDL_ structures are hidden / incapsulated here.
One use case is – If you want to change cursor when mouse enter your view, and restore when mouse leave.
To do that, you need to override OnMouseEvent (or OnContentMouseEvent):
Monkey1234567891011121314151617181920ProtectedMethod OnContentMouseEvent( event:MouseEvent ) OverrideSelect event.TypeCase EventType.MouseEnterSystemCursor.Store( Self )SystemCursor.Set( SystemCursor.Kind.Beam )Case EventType.MouseLeaveSystemCursor.Restore( Self )EndSuper.OnContentMouseEvent( event )EndAvailable cursors:
- Arrow
- Beam
- Wait
- WaitArrow
- Hand
- No
- CrossHair,
- SizeNWSE, SizeNESW, SizeWE, SizeNS, SizeAll
Source code:
Monkey1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071Using sdl2..Class SystemCursorEnum KindArrow,Beam,Wait,WaitArrow,Hand,No,CrossHair,SizeNWSE,SizeNESW,SizeWE,SizeNS,SizeAllEndFunction Set( cursor:Kind )Local c:=_cursors[cursor]If Not cc=Create( cursor )_cursors[cursor]=cEndSDL_SetCursor( c )EndFunction Store( owner:Object )_stored[owner]=SDL_GetCursor()EndFunction Restore( owner:Object )Local c:=_stored[owner]If cSDL_SetCursor( c )_stored.Remove( owner )EndifEndPrivateGlobal _cursors:=New Map<Kind,SDL_Cursor Ptr>Global _stored:=New Map<Object,SDL_Cursor Ptr>Function Create:SDL_Cursor Ptr( cursor:Kind )Local cur:SDL_SystemCursorSelect cursorCase Kind.Arrowcur=SDL_SYSTEM_CURSOR_ARROWCase Kind.Beamcur=SDL_SYSTEM_CURSOR_IBEAMCase Kind.Waitcur=SDL_SYSTEM_CURSOR_WAITCase Kind.CrossHaircur=SDL_SYSTEM_CURSOR_CROSSHAIRCase Kind.WaitArrowcur=SDL_SYSTEM_CURSOR_WAITARROWCase Kind.Nocur=SDL_SYSTEM_CURSOR_NOCase Kind.Handcur=SDL_SYSTEM_CURSOR_HANDCase Kind.SizeNWSEcur=SDL_SYSTEM_CURSOR_SIZENWSECase Kind.SizeNESWcur=SDL_SYSTEM_CURSOR_SIZENESWCase Kind.SizeWEcur=SDL_SYSTEM_CURSOR_SIZEWECase Kind.SizeNScur=SDL_SYSTEM_CURSOR_SIZENSCase Kind.SizeAllcur=SDL_SYSTEM_CURSOR_SIZEALLEndReturn SDL_CreateSystemCursor( cur )EndEndSeptember 13, 2017 at 5:43 am #10440Brilliant work.
Here’s a proper class version of the above for you as well:
Monkey12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182'for dealing with the cursor we need sdlUsing sdl2..Enum KindArrow, Beam, Wait, WaitArrow, Hand, No, CrossHair,SizeNWSE, SizeNESW, SizeWE, SizeNS, SizeAllEndconst CURSOR_ARROW:Kind = Kind.Arrowconst CURSOR_BEAM:Kind = Kind.Beamconst CURSOR_WAIT:Kind = Kind.Waitconst CURSOR_WAITARROW:Kind = Kind.WaitArrowconst CURSOR_HAND:Kind = Kind.Handconst CURSOR_NO:Kind = Kind.Noconst CURSOR_CROSSHAIR:Kind = Kind.CrossHairconst CURSOR_SIZENWSE:Kind = Kind.SizeNWSEconst CURSOR_SIZENESW:Kind = Kind.SizeNESWconst CURSOR_SIZEWE:Kind = Kind.SizeWEconst CURSOR_SIZENS:Kind = Kind.SizeNSconst CURSOR_SIZEEW:Kind = Kind.SizeWEconst CURSOR_SIZESN:Kind = Kind.SizeNSconst CURSOR_SIZEALL:Kind = Kind.SizeAllClass SystemCursormethod New()_cursors = New Map<Kind, SDL_Cursor Ptr>End methodmethod Set( cursor:Kind )Local c:SDL_Cursor ptr = _cursors[cursor]If Not c thenc = Create( cursor )_cursors[cursor] = cEndSDL_SetCursor( c )End methodmethod Restore()Set( CURSOR_ARROW )EndPrivatefield _cursors:Map<Kind, SDL_Cursor Ptr>method Create:SDL_Cursor Ptr( cursor:Kind )Local cur:SDL_SystemCursorSelect cursorCase Kind.Arrowcur = SDL_SYSTEM_CURSOR_ARROWCase Kind.Beamcur = SDL_SYSTEM_CURSOR_IBEAMCase Kind.Waitcur = SDL_SYSTEM_CURSOR_WAITCase Kind.CrossHaircur = SDL_SYSTEM_CURSOR_CROSSHAIRCase Kind.WaitArrowcur = SDL_SYSTEM_CURSOR_WAITARROWCase Kind.Nocur = SDL_SYSTEM_CURSOR_NOCase Kind.Handcur = SDL_SYSTEM_CURSOR_HANDCase Kind.SizeNWSEcur = SDL_SYSTEM_CURSOR_SIZENWSECase Kind.SizeNESWcur = SDL_SYSTEM_CURSOR_SIZENESWCase Kind.SizeWEcur = SDL_SYSTEM_CURSOR_SIZEWECase Kind.SizeNScur = SDL_SYSTEM_CURSOR_SIZENSCase Kind.SizeAllcur = SDL_SYSTEM_CURSOR_SIZEALLEnd SelectReturn SDL_CreateSystemCursor( cur )End methodEndand to use:
Monkey1234567891011field _cursor:SystemCursor = New SystemCursor'depends on how your app is set up for the mouse commandsmethod OnMouseEnter() Override_cursor.Set( CURSOR_NO )End methodmethod OnMouseLeave() Override_cursor.Restore()End methodSeptember 13, 2017 at 6:42 am #10441Here’s a proper class version of the above for you as well
In what place it’s proper?
- System cursor is a global thing, so we can manege it the sane way – via global functions. In your case we must create instance or instances.
- Separated global consts bring some noise in autocompletion, if I would write game for mobiles, I will see them when type cur somewhere.
- You restore CURSOR_ARROW, but cursor might be not an arrow type.
My class present not a single cursor – it is cursor manager.
September 13, 2017 at 7:29 am #10442mmmm, not sure about the cursor and mobile thing. in ‘general’ mobile stuff does not use cursors. Cursors are a desktop thing.
the default cursor IS an Arrow. You are assuming that is ‘could’ be something else. It won’t. it WILL be an arrow. Unless already set by something and not put back to an arrow <- in which case it’s an error and the Arrow should be used.
A control may have different cursors, but the default will always be an arrow. it is up to you to decide, but it should always be set back to an Arrow.
But… There can be issues with controls not setting the cursor back to the default arrow, and thus affecting the required use in other controls. hence using Arrow as the default.
The reason I used ‘proper’ as the use for the class is you are not really using the class. you are using just functions and some globals. you can remove the class entirely and it still functions. So. in this case it is not really a class.
Also you are using globals inside a class, thus breaking the reason for using oop in the first place.
in essence you’ve just got a bunch of functions and some globals wrapped up in a class that doesn’t need them. so either write the code to use a class or don’t use a class at all.
to quote you:
- System cursor is a global thing, so we can manege it the sane way – via global functions. In your case we must create instance or instances.
if it is global and accessed by functions then it is functional programming NOT a class. you don’t need a class and are just adding unneeded code.
You really then just update the functions names with something like:
function CursorStore(
function CursorRestore(
etc
I’m not sure about the following statement:
Separated global consts bring some noise in autocompletion
doesn’t that suggest the possibility that there might be something off with the autocomplete in its operation? I don’t know about that as I don’t use it. But if you need to program something (in a very particular way) to avoid it doing something… possibly?
But as I said, brilliant work, either way
September 13, 2017 at 7:37 am #10443Yes, in some cases I use classes just as a container for functions.
It’s convenient way for me – keep all similar functions in one place / scope / entry_point.
September 14, 2017 at 1:57 am #10453I was confused to know – there is MouseDevice.Cursor property to deal with system cursors.
September 14, 2017 at 5:18 am #10454???? Checked and confirmed in mojo.MouseDevice
tried setting it by using:
Monkey1234Mouse.Cursor = MouseCursor.NoMouse.Cursor = MouseCursor.Arrowand it worked!
-
AuthorPosts
You must be logged in to reply to this topic.