mirror of
https://github.com/emilk/egui.git
synced 2026-09-03 23:30:04 -04:00
Allow attaching custom user data to a screenshot command (#5416)
This lets users trigger a screenshot from anywhere, and then when they get back the results they have some context about what part of their code triggered the screenshot.
This commit is contained in:
@@ -529,6 +529,10 @@ pub enum Event {
|
||||
/// The reply of a screenshot requested with [`crate::ViewportCommand::Screenshot`].
|
||||
Screenshot {
|
||||
viewport_id: crate::ViewportId,
|
||||
|
||||
/// Whatever was passed to [`crate::ViewportCommand::Screenshot`].
|
||||
user_data: crate::UserData,
|
||||
|
||||
image: std::sync::Arc<ColorImage>,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -3,5 +3,7 @@
|
||||
pub mod input;
|
||||
mod key;
|
||||
pub mod output;
|
||||
mod user_data;
|
||||
|
||||
pub use key::Key;
|
||||
pub use user_data::UserData;
|
||||
|
||||
74
crates/egui/src/data/user_data.rs
Normal file
74
crates/egui/src/data/user_data.rs
Normal file
@@ -0,0 +1,74 @@
|
||||
use std::{any::Any, sync::Arc};
|
||||
|
||||
/// A wrapper around `dyn Any`, used for passing custom user data
|
||||
/// to [`crate::ViewportCommand::Screenshot`].
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct UserData {
|
||||
/// A user value given to the screenshot command,
|
||||
/// that will be returned in [`crate::Event::Screenshot`].
|
||||
pub data: Option<Arc<dyn Any + Send + Sync>>,
|
||||
}
|
||||
|
||||
impl UserData {
|
||||
/// You can also use [`Self::default`].
|
||||
pub fn new(user_info: impl Any + Send + Sync) -> Self {
|
||||
Self {
|
||||
data: Some(Arc::new(user_info)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for UserData {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (&self.data, &other.data) {
|
||||
(Some(a), Some(b)) => Arc::ptr_eq(a, b),
|
||||
(None, None) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for UserData {}
|
||||
|
||||
impl std::hash::Hash for UserData {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.data.as_ref().map(Arc::as_ptr).hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl serde::Serialize for UserData {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
serializer.serialize_none() // can't serialize an `Any`
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de> serde::Deserialize<'de> for UserData {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
struct UserDataVisitor;
|
||||
|
||||
impl<'de> serde::de::Visitor<'de> for UserDataVisitor {
|
||||
type Value = UserData;
|
||||
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
formatter.write_str("a None value")
|
||||
}
|
||||
|
||||
fn visit_none<E>(self) -> Result<UserData, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
Ok(UserData::default())
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_option(UserDataVisitor)
|
||||
}
|
||||
}
|
||||
@@ -471,7 +471,7 @@ pub use self::{
|
||||
output::{
|
||||
self, CursorIcon, FullOutput, OpenUrl, PlatformOutput, UserAttentionType, WidgetInfo,
|
||||
},
|
||||
Key,
|
||||
Key, UserData,
|
||||
},
|
||||
drag_and_drop::DragAndDrop,
|
||||
epaint::text::TextWrapMode,
|
||||
|
||||
@@ -1058,8 +1058,8 @@ pub enum ViewportCommand {
|
||||
|
||||
/// Take a screenshot.
|
||||
///
|
||||
/// The results are returned in `crate::Event::Screenshot`.
|
||||
Screenshot,
|
||||
/// The results are returned in [`crate::Event::Screenshot`].
|
||||
Screenshot(crate::UserData),
|
||||
|
||||
/// Request cut of the current selection
|
||||
///
|
||||
@@ -1100,6 +1100,8 @@ impl ViewportCommand {
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/// Describes a viewport, i.e. a native window.
|
||||
///
|
||||
/// This is returned by [`crate::Context::run`] on each frame, and should be applied
|
||||
|
||||
Reference in New Issue
Block a user