Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add/Allow custom CursorShapes to allow additional custom mouse cursors #9958

Open
lostminds opened this issue Jun 14, 2024 · 3 comments
Open

Comments

@lostminds
Copy link

Describe the project you are working on

A parametric design application

Describe the problem or limitation you are having in your project

For different tools and UI interactions I want to use different custom mouse cursors.

The current implementation is based on a set of predefined CursorShapes. The way you change the cursor is to set the shape to one of these with 'DisplayServer.cursor_set_shape()', and the way you customize a cursor is to set a custom image to be used for one of these shapes using DisplayServer.cursor_set_custom_image()

This is fine if you want to customize the existing cursors, like making the arrow cursor fit your game theme, but it is limiting if you want to introduce a cursor that is not in the predefined set. Maybe you want a "cast fireball" cursor or "sell item" cursor, or in my case a "edit path point" cursor. The only option you have then is to use one of the existing set of CursorShapes that you think will not be used (like CursorShape.CURSOR_HELP), which is problematic since they're all cursors that could potentially be needed by the system or UI elements, and it's also limited to the few cursors that aren't commonly used.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

A better way of implementing cursors would I think be to drop the entire CursorShape concept in favor of a new Cursor type object with all the properties of the cursor. DisplayServer.cursor_set_shape(CursorShape) could be replaced by DisplayServer.cursor_set(Cursor) and you could access all the default cursors via for example Cursor.ARROW. This way it would be easy to maintain and set up additional custom cursors you can use just the same way as the default system ones, and we could get rid of the CursorShape concept. This could also be made backward compatible by allowing DisplayServer.cursor_set_shape(CursorShape) remain with a deprecation warning, just setting the corresponding DisplayServer.cursor_set(Cursor), and all old CursorShape.XX presets could map to a Cursor.XX global Cursor object for easy conversion.

A much simpler and perhaps more realistic way to solve the immediate problem would be to keep the current system with CursorShapes, but allow the user to use additional custom ones. So I could use CursorShapes.CUSTOM_CURSOR_1 instead of overwriting CursorShape.CURSOR_HELP, or maybe CursorShapes.CURSOR_MAX + MyCustomCursors.FIREBALL if it would accept shape ids outside of the CursorShape enum list.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

The simplest option would be to just add a bunch of custom CursorShape enum items (like CursorShapes.CUSTOM_1, CursorShapes.CUSTOM_2 ... CursorShapes.CUSTOM_10) to be used as open slots. They could all be set to the default CursorShapes.ARROW graphic and settings from the start to ensure they're valid. But it would then allow at least a couple of new slots that can be used without overwriting any existing cursor.

A slightly less simple option would be to change DisplayServer.cursor_set_shape(), DisplayServer.cursor_set_custom_image() etc to allow any int instead of just CursorShapes enums for the shape parameter. This could then instead be validated to see if the int is either a CursorShape enum value or if it's a value that has been used to set up a custom cursor using DisplayServer.cursor_set_custom_image(). This would avoid the need for CursorShapes.CUSTOM_1 and instead you could use your own custom cursor shape IDs like 'CursorShapes.CURSOR_MAX + MyCustomCursors.FIREBALL' for any number of custom cursor shapes.

If this enhancement will not be used often, can it be worked around with a few lines of script?

The main workaround is to re-use an existing CursorShape that is not used in your project, but this is limited as described above.

The other alternative I can see is to use one CursorShape and just change the appearance and info of it by modifying the image and target point when you want to change the cursor, instead of changing CursorShape. This feels quite backwards and also means you can't make use of automated cursor change functionality like assigning what cursor a control should use, since you're then technically never changing cursor, just modifying the same one.

Is there a reason why this should be core and not an add-on in the asset library?

Mouse cursors are a core component of most non-touch UIs

@yankscally
Copy link

yankscally commented Jun 17, 2024

I really like this idea. My main project changes between custom mouse cursors often, but I just replaced the texture on the custom cursor every time.

Maybe it would be cool if there was a CursorMap, similar to InputMap but for cursors. you can name them and give them textures in there - aswell as seeing all of the currently default ones as undeletable to not break compatibility.

That way its easy to see in each project settings which cursors you are using, which seems like a good place to store these.

@lostminds
Copy link
Author

Maybe it would be cool if there was a CursorMap

This sounds like a good idea to me, to allow users to more visually set up their cursors and see the available standard ones in the project settings would certainly make that easier for people. And like input maps the list of cursors would likely remain pretty static if you allow additional ones to be added (or just provide enough unused custom slots) so you don't need to change the default ones.

That being said I think that is more of a nice to have feature that would work great on top of adding the possibility to have additional custom cursors at all, which I think is the big current limitation in the system.

@lostminds
Copy link
Author

Having considered this some more I think a Cursors setup tab in the project settings might be a good way to also potentially address the issue with high-resolution cursors #9262 Since this could enable the project to generate the specific cursor resources required on some platforms on export/build, which will be difficult to do when setting up custom cursors in code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants