-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Add custom cursors #14284
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 custom cursors #14284
Conversation
Would it be more clear to have |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really want this feature, and I'm excited to see that there's a path forward.
That said, I really dislike the custom image buffer :( That's really unpleasant to use, and hard to maintain. Can you say more about the circular dependency? What exactly is going on here: can we refactor things to get a nice API?
We also can't use |
Is moving |
I'd really prefer not to move that into For reference, the same problem is encountered with #1031: we really want to feed normal image data (loaded via the asset system) back into windowing. |
Having |
Great. Can you link to the Android stuff? We should pull this out into its own issue; I think this is a pretty reasonable plan of attack. |
bevy/crates/bevy_asset/src/io/android.rs Line 20 in e512cb6
On android, we get the asset path from winit. It should be possible to just reverse the dependency and smuggle the paths with resources or call functions the other way. (Or I guess its a whole asset manager, so might be more difficult) |
46da546
to
cbafc20
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really great change, thank you for doing this! It would be awesome to have an example demonstrating the new feature, but this looks great as is.
The window_settings example is modified to include an image cursor. |
Ah great :) I just saw the system cursors and missed the custom. Perfect! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great API, good work!
Co-authored-by: Jan Hohenheim <[email protected]>
For folks looking in the future, #14351 talks about the web of dependencies and why this implementation was chosen. |
# Objective - CI broke after #14284 because of the `cursor_options` rename ## Solution - Update the broken patch ## Testing - Patch tested with `git apply`.
Thank you to everyone involved with the authoring or reviewing of this PR! This work is relatively important and needs release notes! Head over to bevyengine/bevy-website#1670 if you'd like to help out. |
# Objective - Bevy 0.15 added support for custom cursor images in #14284. - However, to do animated cursors using the initial support shipped in 0.15 means you'd have to animate the `Handle<Image>`: You can't use a `TextureAtlas` like you can with sprites and UI images. - For my use case, my cursors are spritesheets. To animate them, I'd have to break them down into multiple `Image` assets, but that seems less than ideal. ## Solution - Allow users to specify a `TextureAtlas` field when creating a custom cursor image. - To create parity with Bevy's `TextureAtlas` support on `Sprite`s and `ImageNode`s, this also allows users to specify `rect`, `flip_x` and `flip_y`. In fact, for my own use case, I need to `flip_y`. ## Testing - I added unit tests for `calculate_effective_rect` and `extract_and_transform_rgba_pixels`. - I added a brand new example for custom cursor images. It has controls to toggle fields on and off. I opted to add a new example because the existing cursor example (`window_settings`) would be far too messy for showcasing these custom cursor features (I did start down that path but decided to stop and make a brand new example). - The new example uses a [Kenny cursor icon] sprite sheet. I included the licence even though it's not required (and it's CC0). - I decided to make the example just loop through all cursor icons for its animation even though it's not a _realistic_ in-game animation sequence. - I ran the PNG through https://tinypng.com. Looks like it's about 35KB. - I'm open to adjusting the example spritesheet if required, but if it's fine as is, great. [Kenny cursor icon]: https://kenney-assets.itch.io/crosshair-pack --- ## Showcase https://github.com/user-attachments/assets/8f6be8d7-d1d4-42f9-b769-ef8532367749 ## Migration Guide The `CustomCursor::Image` enum variant has some new fields. Update your code to set them. Before: ```rust CustomCursor::Image { handle: asset_server.load("branding/icon.png"), hotspot: (128, 128), } ``` After: ```rust CustomCursor::Image { handle: asset_server.load("branding/icon.png"), texture_atlas: None, flip_x: false, flip_y: false, rect: None, hotspot: (128, 128), } ``` ## References - Feature request [originally raised in Discord]. [originally raised in Discord]: https://discord.com/channels/691052431525675048/692572690833473578/1319836362219847681
# Objective - Bevy 0.15 added support for custom cursor images in bevyengine#14284. - However, to do animated cursors using the initial support shipped in 0.15 means you'd have to animate the `Handle<Image>`: You can't use a `TextureAtlas` like you can with sprites and UI images. - For my use case, my cursors are spritesheets. To animate them, I'd have to break them down into multiple `Image` assets, but that seems less than ideal. ## Solution - Allow users to specify a `TextureAtlas` field when creating a custom cursor image. - To create parity with Bevy's `TextureAtlas` support on `Sprite`s and `ImageNode`s, this also allows users to specify `rect`, `flip_x` and `flip_y`. In fact, for my own use case, I need to `flip_y`. ## Testing - I added unit tests for `calculate_effective_rect` and `extract_and_transform_rgba_pixels`. - I added a brand new example for custom cursor images. It has controls to toggle fields on and off. I opted to add a new example because the existing cursor example (`window_settings`) would be far too messy for showcasing these custom cursor features (I did start down that path but decided to stop and make a brand new example). - The new example uses a [Kenny cursor icon] sprite sheet. I included the licence even though it's not required (and it's CC0). - I decided to make the example just loop through all cursor icons for its animation even though it's not a _realistic_ in-game animation sequence. - I ran the PNG through https://tinypng.com. Looks like it's about 35KB. - I'm open to adjusting the example spritesheet if required, but if it's fine as is, great. [Kenny cursor icon]: https://kenney-assets.itch.io/crosshair-pack --- ## Showcase https://github.com/user-attachments/assets/8f6be8d7-d1d4-42f9-b769-ef8532367749 ## Migration Guide The `CustomCursor::Image` enum variant has some new fields. Update your code to set them. Before: ```rust CustomCursor::Image { handle: asset_server.load("branding/icon.png"), hotspot: (128, 128), } ``` After: ```rust CustomCursor::Image { handle: asset_server.load("branding/icon.png"), texture_atlas: None, flip_x: false, flip_y: false, rect: None, hotspot: (128, 128), } ``` ## References - Feature request [originally raised in Discord]. [originally raised in Discord]: https://discord.com/channels/691052431525675048/692572690833473578/1319836362219847681
Objective
Solution
Handle<Image>
directly. I would need to importbevy_assets
and that causes a circular dependency. Alternatively we could use winit'sCustomCursor
smart pointers, but that seems hard because the event loop is needed to create those and is not easily accessable for users. So now I need to copy around rgba buffers which is sad.Update:
Handle<Image>
, reads rgba data inbevy_render
and uses resources to send the data tobevy_winit
, where the final cursors are created.Testing
Migration Guide
CursorIcon
is no longer a field inWindow
, but a separate component can be inserted to a window entity. It has been changed to an enum that can hold custom images in addition to system icons.Cursor
is renamed toCursorOptions
andcursor
field ofWindow
is renamed tocursor_options
CursorIcon
is renamed toSystemCursorIcon