-
-
Notifications
You must be signed in to change notification settings - Fork 78
feat: added SDL_SetWindowHitTest wrapper #268
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
Changes from 2 commits
9354c8a
760594f
b90ccb6
96e8623
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -721,6 +721,55 @@ impl FlashOperation { | |
| } | ||
| } | ||
|
|
||
| // Represents the result of a hit test. | ||
| #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] | ||
| #[repr(i32)] | ||
| pub enum HitTestResult { | ||
| Normal = sys::video::SDL_HITTEST_NORMAL.0, | ||
| Draggable = sys::video::SDL_HITTEST_DRAGGABLE.0, | ||
| ResizeTopLeft = sys::video::SDL_HITTEST_RESIZE_TOPLEFT.0, | ||
| ResizeTop = sys::video::SDL_HITTEST_RESIZE_TOP.0, | ||
| ResizeTopRight = sys::video::SDL_HITTEST_RESIZE_TOPRIGHT.0, | ||
| ResizeRight = sys::video::SDL_HITTEST_RESIZE_RIGHT.0, | ||
| ResizeBottomRight = sys::video::SDL_HITTEST_RESIZE_BOTTOMRIGHT.0, | ||
| ResizeBottom = sys::video::SDL_HITTEST_RESIZE_BOTTOM.0, | ||
| ResizeBottomLeft = sys::video::SDL_HITTEST_RESIZE_BOTTOMLEFT.0, | ||
| ResizeLeft = sys::video::SDL_HITTEST_RESIZE_LEFT.0, | ||
| } | ||
|
|
||
| impl HitTestResult { | ||
| pub fn from_ll(result: sys::video::SDL_HitTestResult) -> HitTestResult { | ||
| match result { | ||
| sys::video::SDL_HITTEST_NORMAL => HitTestResult::Normal, | ||
| sys::video::SDL_HITTEST_DRAGGABLE => HitTestResult::Draggable, | ||
| sys::video::SDL_HITTEST_RESIZE_TOPLEFT => HitTestResult::ResizeTopLeft, | ||
| sys::video::SDL_HITTEST_RESIZE_TOP => HitTestResult::ResizeTop, | ||
| sys::video::SDL_HITTEST_RESIZE_TOPRIGHT => HitTestResult::ResizeTopRight, | ||
| sys::video::SDL_HITTEST_RESIZE_RIGHT => HitTestResult::ResizeRight, | ||
| sys::video::SDL_HITTEST_RESIZE_BOTTOMRIGHT => HitTestResult::ResizeBottomRight, | ||
| sys::video::SDL_HITTEST_RESIZE_BOTTOM => HitTestResult::ResizeBottom, | ||
| sys::video::SDL_HITTEST_RESIZE_BOTTOMLEFT => HitTestResult::ResizeBottomLeft, | ||
| sys::video::SDL_HITTEST_RESIZE_LEFT => HitTestResult::ResizeLeft, | ||
| _ => HitTestResult::Normal, | ||
| } | ||
| } | ||
|
|
||
| pub fn to_ll(self) -> sys::video::SDL_HitTestResult { | ||
| match self { | ||
| HitTestResult::Normal => sys::video::SDL_HITTEST_NORMAL, | ||
| HitTestResult::Draggable => sys::video::SDL_HITTEST_DRAGGABLE, | ||
| HitTestResult::ResizeTopLeft => sys::video::SDL_HITTEST_RESIZE_TOPLEFT, | ||
| HitTestResult::ResizeTop => sys::video::SDL_HITTEST_RESIZE_TOP, | ||
| HitTestResult::ResizeTopRight => sys::video::SDL_HITTEST_RESIZE_TOPRIGHT, | ||
| HitTestResult::ResizeRight => sys::video::SDL_HITTEST_RESIZE_RIGHT, | ||
| HitTestResult::ResizeBottomRight => sys::video::SDL_HITTEST_RESIZE_BOTTOMRIGHT, | ||
| HitTestResult::ResizeBottom => sys::video::SDL_HITTEST_RESIZE_BOTTOM, | ||
| HitTestResult::ResizeBottomLeft => sys::video::SDL_HITTEST_RESIZE_BOTTOMLEFT, | ||
| HitTestResult::ResizeLeft => sys::video::SDL_HITTEST_RESIZE_LEFT, | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// Represents the "shell" of a `Window`. | ||
| /// | ||
| /// You can set get and set many of the `SDL_Window` properties (i.e., border, size, `PixelFormat`, etc) | ||
|
|
@@ -2281,6 +2330,40 @@ impl Window { | |
| Err(get_error()) | ||
| } | ||
| } | ||
|
|
||
| /// Sets a hit test function for the window. | ||
| #[doc(alias = "SDL_SetWindowHitTest")] | ||
| pub fn set_hit_test( | ||
| &mut self, | ||
| hit_test: impl Fn(crate::rect::Point) -> HitTestResult, | ||
maik205 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| ) -> Result<(), Error> { | ||
| // Box the closure to extend its lifetime and convert it to a raw pointer. | ||
| let boxed: Box<Box<dyn Fn(crate::rect::Point) -> HitTestResult>> = | ||
| Box::new(Box::new(hit_test)); | ||
|
Comment on lines
+2346
to
+2347
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why is it in two boxes?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wrapped the closure twice to relax the trait bounds when dereferencing the callback from
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried your solution but it seems the compiler still stops us from casting it into a trait pointer... Casting the void pointer into the trait pointer still requires the void pointer to implement that trait (which |
||
| let userdata = Box::into_raw(boxed) as *mut c_void; | ||
|
|
||
| unsafe extern "C" fn hit_test_sys( | ||
| _: *mut sys::video::SDL_Window, | ||
| point: *const sys::rect::SDL_Point, | ||
| data: *mut c_void, | ||
| ) -> sys::video::SDL_HitTestResult { | ||
| // Reborrow the boxed closure. | ||
| let callback = data as *mut Box<dyn Fn(crate::rect::Point) -> HitTestResult>; | ||
| let point = crate::rect::Point::from_ll(*point); | ||
|
|
||
| (*callback)(point).to_ll() | ||
| } | ||
|
|
||
| unsafe { | ||
| let result = | ||
| sys::video::SDL_SetWindowHitTest(self.context.raw, Some(hit_test_sys), userdata); | ||
|
||
| if result { | ||
| Ok(()) | ||
| } else { | ||
| Err(get_error()) | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| #[derive(Copy, Clone)] | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.