Skip to content

Commit 1571027

Browse files
authored
Replace eframe::Frame commands and WindowInfo with egui (#3564)
* Part of #3556 ## In short You now almost never need to use `eframe::Frame` - instead use `ui.input(|i| i.viewport())` for information about the current viewport (native window), and use `ctx.send_viewport_cmd` to modify it. ## In detail This PR removes most commands from `eframe::Frame`, and replaces them with `ViewportCommand`. So `frame.close()` becomes `ctx.send_viewport_cmd(ViewportCommand::Close)`, etc. `frame.info().window_info` is now also gone, replaced with `ui.input(|i| i.viewport())`. `frame.info().native_pixels_per_point` is replaced with `ui.input(|i| i.raw.native_pixels_per_point)`. `RawInput` now contains one `ViewportInfo` for each viewport. Screenshots are taken with `ctx.send_viewport_cmd(ViewportCommand::Screenshots)` and are returned in `egui::Event` which you can check with: ``` ust ui.input(|i| { for event in &i.raw.events { if let egui::Event::Screenshot { viewport_id, image } = event { // handle it here } } }); ``` ### Motivation You no longer need to pass around the `&eframe::Frame` everywhere. This also opens the door for other integrations to use the same API of `ViewportCommand`s.
1 parent 3e37e9d commit 1571027

29 files changed

Lines changed: 904 additions & 914 deletions

File tree

crates/eframe/src/epi/mod.rs

Lines changed: 0 additions & 313 deletions
Original file line numberDiff line numberDiff line change
@@ -230,11 +230,6 @@ pub trait App {
230230
fn warm_up_enabled(&self) -> bool {
231231
false
232232
}
233-
234-
/// Called each time after the rendering the UI.
235-
///
236-
/// Can be used to access pixel data with [`Frame::screenshot`]
237-
fn post_rendering(&mut self, _window_size_px: [u32; 2], _frame: &Frame) {}
238233
}
239234

240235
/// Selects the level of hardware graphics acceleration.
@@ -732,9 +727,6 @@ pub struct Frame {
732727
/// Information about the integration.
733728
pub(crate) info: IntegrationInfo,
734729

735-
/// Where the app can issue commands back to the integration.
736-
pub(crate) output: backend::AppOutput,
737-
738730
/// A place where you can store custom data in a way that persists when you restart the app.
739731
pub(crate) storage: Option<Box<dyn Storage>>,
740732

@@ -746,11 +738,6 @@ pub struct Frame {
746738
#[cfg(feature = "wgpu")]
747739
pub(crate) wgpu_render_state: Option<egui_wgpu::RenderState>,
748740

749-
/// If [`Frame::request_screenshot`] was called during a frame, this field will store the screenshot
750-
/// such that it can be retrieved during [`App::post_rendering`] with [`Frame::screenshot`]
751-
#[cfg(not(target_arch = "wasm32"))]
752-
pub(crate) screenshot: std::cell::Cell<Option<egui::ColorImage>>,
753-
754741
/// Raw platform window handle
755742
#[cfg(not(target_arch = "wasm32"))]
756743
pub(crate) raw_window_handle: RawWindowHandle,
@@ -799,67 +786,6 @@ impl Frame {
799786
self.storage.as_deref()
800787
}
801788

802-
/// Request the current frame's pixel data. Needs to be retrieved by calling [`Frame::screenshot`]
803-
/// during [`App::post_rendering`].
804-
#[cfg(not(target_arch = "wasm32"))]
805-
pub fn request_screenshot(&mut self) {
806-
self.output.screenshot_requested = true;
807-
}
808-
809-
/// Cancel a request made with [`Frame::request_screenshot`].
810-
#[cfg(not(target_arch = "wasm32"))]
811-
pub fn cancel_screenshot_request(&mut self) {
812-
self.output.screenshot_requested = false;
813-
}
814-
815-
/// During [`App::post_rendering`], use this to retrieve the pixel data that was requested during
816-
/// [`App::update`] via [`Frame::request_screenshot`].
817-
///
818-
/// Returns None if:
819-
/// * Called in [`App::update`]
820-
/// * [`Frame::request_screenshot`] wasn't called on this frame during [`App::update`]
821-
/// * The rendering backend doesn't support this feature (yet). Currently implemented for wgpu and glow, but not with wasm as target.
822-
/// * Wgpu's GL target is active (not yet supported)
823-
/// * Retrieving the data was unsuccessful in some way.
824-
///
825-
/// See also [`egui::ColorImage::region`]
826-
///
827-
/// ## Example generating a capture of everything within a square of 100 pixels located at the top left of the app and saving it with the [`image`](crates.io/crates/image) crate:
828-
/// ```
829-
/// struct MyApp;
830-
///
831-
/// impl eframe::App for MyApp {
832-
/// fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
833-
/// // In real code the app would render something here
834-
/// frame.request_screenshot();
835-
/// // Things that are added to the frame after the call to
836-
/// // request_screenshot() will still be included.
837-
/// }
838-
///
839-
/// fn post_rendering(&mut self, _window_size: [u32; 2], frame: &eframe::Frame) {
840-
/// if let Some(screenshot) = frame.screenshot() {
841-
/// let pixels_per_point = frame.info().native_pixels_per_point;
842-
/// let region = egui::Rect::from_two_pos(
843-
/// egui::Pos2::ZERO,
844-
/// egui::Pos2{ x: 100., y: 100. },
845-
/// );
846-
/// let top_left_corner = screenshot.region(&region, pixels_per_point);
847-
/// image::save_buffer(
848-
/// "top_left.png",
849-
/// top_left_corner.as_raw(),
850-
/// top_left_corner.width() as u32,
851-
/// top_left_corner.height() as u32,
852-
/// image::ColorType::Rgba8,
853-
/// ).unwrap();
854-
/// }
855-
/// }
856-
/// }
857-
/// ```
858-
#[cfg(not(target_arch = "wasm32"))]
859-
pub fn screenshot(&self) -> Option<egui::ColorImage> {
860-
self.screenshot.take()
861-
}
862-
863789
/// A place where you can store custom data in a way that persists when you restart the app.
864790
pub fn storage_mut(&mut self) -> Option<&mut (dyn Storage + 'static)> {
865791
self.storage.as_deref_mut()
@@ -891,141 +817,6 @@ impl Frame {
891817
pub fn wgpu_render_state(&self) -> Option<&egui_wgpu::RenderState> {
892818
self.wgpu_render_state.as_ref()
893819
}
894-
895-
/// Tell `eframe` to close the desktop window.
896-
///
897-
/// The window will not close immediately, but at the end of the this frame.
898-
///
899-
/// Calling this will likely result in the app quitting, unless
900-
/// you have more code after the call to [`crate::run_native`].
901-
#[cfg(not(target_arch = "wasm32"))]
902-
#[doc(alias = "exit")]
903-
#[doc(alias = "quit")]
904-
pub fn close(&mut self) {
905-
log::debug!("eframe::Frame::close called");
906-
self.output.close = true;
907-
}
908-
909-
/// Minimize or unminimize window. (native only)
910-
#[cfg(not(target_arch = "wasm32"))]
911-
pub fn set_minimized(&mut self, minimized: bool) {
912-
self.output.minimized = Some(minimized);
913-
}
914-
915-
/// Bring the window into focus (native only). Has no effect on Wayland, or if the window is minimized or invisible.
916-
///
917-
/// This method puts the window on top of other applications and takes input focus away from them,
918-
/// which, if unexpected, will disturb the user.
919-
#[cfg(not(target_arch = "wasm32"))]
920-
pub fn focus(&mut self) {
921-
self.output.focus = Some(true);
922-
}
923-
924-
/// If the window is unfocused, attract the user's attention (native only).
925-
///
926-
/// Typically, this means that the window will flash on the taskbar, or bounce, until it is interacted with.
927-
///
928-
/// When the window comes into focus, or if `None` is passed, the attention request will be automatically reset.
929-
///
930-
/// See [winit's documentation][user_attention_details] for platform-specific effect details.
931-
///
932-
/// [user_attention_details]: https://docs.rs/winit/latest/winit/window/enum.UserAttentionType.html
933-
#[cfg(not(target_arch = "wasm32"))]
934-
pub fn request_user_attention(&mut self, kind: egui::UserAttentionType) {
935-
self.output.attention = Some(kind);
936-
}
937-
938-
/// Maximize or unmaximize window. (native only)
939-
#[cfg(not(target_arch = "wasm32"))]
940-
pub fn set_maximized(&mut self, maximized: bool) {
941-
self.output.maximized = Some(maximized);
942-
}
943-
944-
/// Tell `eframe` to close the desktop window.
945-
#[cfg(not(target_arch = "wasm32"))]
946-
#[deprecated = "Renamed `close`"]
947-
pub fn quit(&mut self) {
948-
self.close();
949-
}
950-
951-
/// Set the desired inner size of the window (in egui points).
952-
#[cfg(not(target_arch = "wasm32"))]
953-
pub fn set_window_size(&mut self, size: egui::Vec2) {
954-
self.output.window_size = Some(size);
955-
self.info.window_info.size = size; // so that subsequent calls see the updated value
956-
}
957-
958-
/// Set the desired title of the window.
959-
#[cfg(not(target_arch = "wasm32"))]
960-
pub fn set_window_title(&mut self, title: &str) {
961-
self.output.window_title = Some(title.to_owned());
962-
}
963-
964-
/// Set whether to show window decorations (i.e. a frame around you app).
965-
///
966-
/// If false it will be difficult to move and resize the app.
967-
#[cfg(not(target_arch = "wasm32"))]
968-
pub fn set_decorations(&mut self, decorated: bool) {
969-
self.output.decorated = Some(decorated);
970-
}
971-
972-
/// Turn borderless fullscreen on/off (native only).
973-
#[cfg(not(target_arch = "wasm32"))]
974-
pub fn set_fullscreen(&mut self, fullscreen: bool) {
975-
self.output.fullscreen = Some(fullscreen);
976-
self.info.window_info.fullscreen = fullscreen; // so that subsequent calls see the updated value
977-
}
978-
979-
/// set the position of the outer window.
980-
#[cfg(not(target_arch = "wasm32"))]
981-
pub fn set_window_pos(&mut self, pos: egui::Pos2) {
982-
self.output.window_pos = Some(pos);
983-
self.info.window_info.position = Some(pos); // so that subsequent calls see the updated value
984-
}
985-
986-
/// When called, the native window will follow the
987-
/// movement of the cursor while the primary mouse button is down.
988-
///
989-
/// Does not work on the web.
990-
#[cfg(not(target_arch = "wasm32"))]
991-
pub fn drag_window(&mut self) {
992-
self.output.drag_window = true;
993-
}
994-
995-
/// Set the visibility of the window.
996-
#[cfg(not(target_arch = "wasm32"))]
997-
pub fn set_visible(&mut self, visible: bool) {
998-
self.output.visible = Some(visible);
999-
}
1000-
1001-
/// On desktop: Set the window always on top.
1002-
///
1003-
/// (Wayland desktop currently not supported)
1004-
#[cfg(not(target_arch = "wasm32"))]
1005-
pub fn set_always_on_top(&mut self, always_on_top: bool) {
1006-
self.output.always_on_top = Some(always_on_top);
1007-
}
1008-
1009-
/// On desktop: Set the window to be centered.
1010-
///
1011-
/// (Wayland desktop currently not supported)
1012-
#[cfg(not(target_arch = "wasm32"))]
1013-
pub fn set_centered(&mut self) {
1014-
if let Some(monitor_size) = self.info.window_info.monitor_size {
1015-
let inner_size = self.info.window_info.size;
1016-
if monitor_size.x > 1.0 && monitor_size.y > 1.0 {
1017-
let x = (monitor_size.x - inner_size.x) / 2.0;
1018-
let y = (monitor_size.y - inner_size.y) / 2.0;
1019-
self.set_window_pos(egui::Pos2 { x, y });
1020-
}
1021-
}
1022-
}
1023-
1024-
/// for integrations only: call once per frame
1025-
#[cfg(any(feature = "glow", feature = "wgpu"))]
1026-
pub(crate) fn take_app_output(&mut self) -> backend::AppOutput {
1027-
std::mem::take(&mut self.output)
1028-
}
1029820
}
1030821

1031822
/// Information about the web environment (if applicable).
@@ -1039,38 +830,6 @@ pub struct WebInfo {
1039830
pub location: Location,
1040831
}
1041832

1042-
/// Information about the application's main window, if available.
1043-
#[cfg(not(target_arch = "wasm32"))]
1044-
#[derive(Clone, Debug)]
1045-
pub struct WindowInfo {
1046-
/// Coordinates of the window's outer top left corner, relative to the top left corner of the first display.
1047-
///
1048-
/// Unit: egui points (logical pixels).
1049-
///
1050-
/// `None` = unknown.
1051-
pub position: Option<egui::Pos2>,
1052-
1053-
/// Are we in fullscreen mode?
1054-
pub fullscreen: bool,
1055-
1056-
/// Are we minimized?
1057-
pub minimized: bool,
1058-
1059-
/// Are we maximized?
1060-
pub maximized: bool,
1061-
1062-
/// Is the window focused and able to receive input?
1063-
///
1064-
/// This should be the same as [`egui::InputState::focused`].
1065-
pub focused: bool,
1066-
1067-
/// Window inner size in egui points (logical pixels).
1068-
pub size: egui::Vec2,
1069-
1070-
/// Current monitor size in egui points (logical pixels)
1071-
pub monitor_size: Option<egui::Vec2>,
1072-
}
1073-
1074833
/// Information about the URL.
1075834
///
1076835
/// Everything has been percent decoded (`%20` -> ` ` etc).
@@ -1141,13 +900,6 @@ pub struct IntegrationInfo {
1141900
/// Seconds of cpu usage (in seconds) of UI code on the previous frame.
1142901
/// `None` if this is the first frame.
1143902
pub cpu_usage: Option<f32>,
1144-
1145-
/// The OS native pixels-per-point
1146-
pub native_pixels_per_point: Option<f32>,
1147-
1148-
/// The position and size of the native window.
1149-
#[cfg(not(target_arch = "wasm32"))]
1150-
pub window_info: WindowInfo,
1151903
}
1152904

1153905
// ----------------------------------------------------------------------------
@@ -1211,68 +963,3 @@ pub fn set_value<T: serde::Serialize>(storage: &mut dyn Storage, key: &str, valu
1211963

1212964
/// [`Storage`] key used for app
1213965
pub const APP_KEY: &str = "app";
1214-
1215-
// ----------------------------------------------------------------------------
1216-
1217-
/// You only need to look here if you are writing a backend for `epi`.
1218-
pub(crate) mod backend {
1219-
/// Action that can be taken by the user app.
1220-
#[derive(Clone, Debug, Default)]
1221-
#[must_use]
1222-
pub struct AppOutput {
1223-
/// Set to `true` to close the native window (which often quits the app).
1224-
#[cfg(not(target_arch = "wasm32"))]
1225-
pub close: bool,
1226-
1227-
/// Set to some size to resize the outer window (e.g. glium window) to this size.
1228-
#[cfg(not(target_arch = "wasm32"))]
1229-
pub window_size: Option<egui::Vec2>,
1230-
1231-
/// Set to some string to rename the outer window (e.g. glium window) to this title.
1232-
#[cfg(not(target_arch = "wasm32"))]
1233-
pub window_title: Option<String>,
1234-
1235-
/// Set to some bool to change window decorations.
1236-
#[cfg(not(target_arch = "wasm32"))]
1237-
pub decorated: Option<bool>,
1238-
1239-
/// Set to some bool to change window fullscreen.
1240-
#[cfg(not(target_arch = "wasm32"))] // TODO: implement fullscreen on web
1241-
pub fullscreen: Option<bool>,
1242-
1243-
/// Set to true to drag window while primary mouse button is down.
1244-
#[cfg(not(target_arch = "wasm32"))]
1245-
pub drag_window: bool,
1246-
1247-
/// Set to some position to move the outer window (e.g. glium window) to this position
1248-
#[cfg(not(target_arch = "wasm32"))]
1249-
pub window_pos: Option<egui::Pos2>,
1250-
1251-
/// Set to some bool to change window visibility.
1252-
#[cfg(not(target_arch = "wasm32"))]
1253-
pub visible: Option<bool>,
1254-
1255-
/// Set to some bool to tell the window always on top.
1256-
#[cfg(not(target_arch = "wasm32"))]
1257-
pub always_on_top: Option<bool>,
1258-
1259-
/// Set to some bool to minimize or unminimize window.
1260-
#[cfg(not(target_arch = "wasm32"))]
1261-
pub minimized: Option<bool>,
1262-
1263-
/// Set to some bool to maximize or unmaximize window.
1264-
#[cfg(not(target_arch = "wasm32"))]
1265-
pub maximized: Option<bool>,
1266-
1267-
/// Set to some bool to focus window.
1268-
#[cfg(not(target_arch = "wasm32"))]
1269-
pub focus: Option<bool>,
1270-
1271-
/// Set to request a user's attention to the native window.
1272-
#[cfg(not(target_arch = "wasm32"))]
1273-
pub attention: Option<egui::UserAttentionType>,
1274-
1275-
#[cfg(not(target_arch = "wasm32"))]
1276-
pub screenshot_requested: bool,
1277-
}
1278-
}

0 commit comments

Comments
 (0)