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

Replace eframe::Frame commands and WindowInfo with egui #3564

Merged
merged 36 commits into from
Nov 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
9c5ff1d
emath: allow mul/div Pos2+Rect with f32 for scale converions
emilk Nov 17, 2023
136a149
Use ui points for the rectangles in `ViewportInfo`
emilk Nov 17, 2023
4d5721b
Make `ViewportInfo` more informative
emilk Nov 17, 2023
0bc7e89
Give a map of all viewports to RawInput
emilk Nov 17, 2023
3e84354
Nicer ui for ViewportInfo
emilk Nov 17, 2023
be0ae95
Add demo of extra viewport
emilk Nov 17, 2023
a1733fa
Fix: give all viewports as input to `RawInput`
emilk Nov 18, 2023
bf4222c
Refactor code
emilk Nov 18, 2023
a73a194
Remove dead code
emilk Nov 18, 2023
d95cf23
Add minimized/maximized to ViewportInfo
emilk Nov 18, 2023
b55e06d
Use viewport commands in custom_window_frame example
emilk Nov 18, 2023
2c7d6fb
Use viewport commands in the demo app
emilk Nov 18, 2023
9712ff1
Code simplification
emilk Nov 18, 2023
6aa25d7
Repaint viewports we send events to
emilk Nov 18, 2023
d3113dc
Replace eframe::Frame::close with viewport command
emilk Nov 18, 2023
a856744
Add a TODO
emilk Nov 18, 2023
4122fcf
Refactor user attention request
emilk Nov 18, 2023
3dffaf8
Remove most commands from `eframe::Frame`
emilk Nov 18, 2023
5d6a30f
Make Focus a viewport command
emilk Nov 18, 2023
77a5f8b
Fix: make sure window is visible
emilk Nov 18, 2023
1bda14e
Handle screenshots via `ViewportCommand`
emilk Nov 18, 2023
01c273a
Return screenshots as an egui Event
emilk Nov 18, 2023
1e02144
Shorten `send_viewport_command` -> `send_viewport_cmd`
emilk Nov 18, 2023
7075d93
Fix web build
emilk Nov 18, 2023
f91268f
Web backend: warn when a command is not handled
emilk Nov 18, 2023
c0f6fae
Fix typos
emilk Nov 18, 2023
3b0482c
Build fixes
emilk Nov 18, 2023
d8c0198
Remove `App::post_rendering`
emilk Nov 18, 2023
eeaaa40
Fix some doclinks
emilk Nov 18, 2023
618caee
check.sh: check fast things first
emilk Nov 18, 2023
66c5a90
Some vertical spacing
emilk Nov 18, 2023
3934b95
Move `native_pixels_per_point` to `RawInput`
emilk Nov 18, 2023
26b2382
Fix web build
emilk Nov 18, 2023
7652041
Update check.sh
emilk Nov 18, 2023
e53b7a7
Fix doctest
emilk Nov 18, 2023
271064d
Add docs about the new stuff
emilk Nov 18, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
313 changes: 0 additions & 313 deletions crates/eframe/src/epi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,11 +230,6 @@ pub trait App {
fn warm_up_enabled(&self) -> bool {
false
}

/// Called each time after the rendering the UI.
///
/// Can be used to access pixel data with [`Frame::screenshot`]
fn post_rendering(&mut self, _window_size_px: [u32; 2], _frame: &Frame) {}
}

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

/// Where the app can issue commands back to the integration.
pub(crate) output: backend::AppOutput,

/// A place where you can store custom data in a way that persists when you restart the app.
pub(crate) storage: Option<Box<dyn Storage>>,

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

/// If [`Frame::request_screenshot`] was called during a frame, this field will store the screenshot
/// such that it can be retrieved during [`App::post_rendering`] with [`Frame::screenshot`]
#[cfg(not(target_arch = "wasm32"))]
pub(crate) screenshot: std::cell::Cell<Option<egui::ColorImage>>,

/// Raw platform window handle
#[cfg(not(target_arch = "wasm32"))]
pub(crate) raw_window_handle: RawWindowHandle,
Expand Down Expand Up @@ -799,67 +786,6 @@ impl Frame {
self.storage.as_deref()
}

/// Request the current frame's pixel data. Needs to be retrieved by calling [`Frame::screenshot`]
/// during [`App::post_rendering`].
#[cfg(not(target_arch = "wasm32"))]
pub fn request_screenshot(&mut self) {
self.output.screenshot_requested = true;
}

/// Cancel a request made with [`Frame::request_screenshot`].
#[cfg(not(target_arch = "wasm32"))]
pub fn cancel_screenshot_request(&mut self) {
self.output.screenshot_requested = false;
}

/// During [`App::post_rendering`], use this to retrieve the pixel data that was requested during
/// [`App::update`] via [`Frame::request_screenshot`].
///
/// Returns None if:
/// * Called in [`App::update`]
/// * [`Frame::request_screenshot`] wasn't called on this frame during [`App::update`]
/// * The rendering backend doesn't support this feature (yet). Currently implemented for wgpu and glow, but not with wasm as target.
/// * Wgpu's GL target is active (not yet supported)
/// * Retrieving the data was unsuccessful in some way.
///
/// See also [`egui::ColorImage::region`]
///
/// ## 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:
/// ```
/// struct MyApp;
///
/// impl eframe::App for MyApp {
/// fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
/// // In real code the app would render something here
/// frame.request_screenshot();
/// // Things that are added to the frame after the call to
/// // request_screenshot() will still be included.
/// }
///
/// fn post_rendering(&mut self, _window_size: [u32; 2], frame: &eframe::Frame) {
/// if let Some(screenshot) = frame.screenshot() {
/// let pixels_per_point = frame.info().native_pixels_per_point;
/// let region = egui::Rect::from_two_pos(
/// egui::Pos2::ZERO,
/// egui::Pos2{ x: 100., y: 100. },
/// );
/// let top_left_corner = screenshot.region(&region, pixels_per_point);
/// image::save_buffer(
/// "top_left.png",
/// top_left_corner.as_raw(),
/// top_left_corner.width() as u32,
/// top_left_corner.height() as u32,
/// image::ColorType::Rgba8,
/// ).unwrap();
/// }
/// }
/// }
/// ```
#[cfg(not(target_arch = "wasm32"))]
pub fn screenshot(&self) -> Option<egui::ColorImage> {
self.screenshot.take()
}

/// A place where you can store custom data in a way that persists when you restart the app.
pub fn storage_mut(&mut self) -> Option<&mut (dyn Storage + 'static)> {
self.storage.as_deref_mut()
Expand Down Expand Up @@ -891,141 +817,6 @@ impl Frame {
pub fn wgpu_render_state(&self) -> Option<&egui_wgpu::RenderState> {
self.wgpu_render_state.as_ref()
}

/// Tell `eframe` to close the desktop window.
///
/// The window will not close immediately, but at the end of the this frame.
///
/// Calling this will likely result in the app quitting, unless
/// you have more code after the call to [`crate::run_native`].
#[cfg(not(target_arch = "wasm32"))]
#[doc(alias = "exit")]
#[doc(alias = "quit")]
pub fn close(&mut self) {
log::debug!("eframe::Frame::close called");
self.output.close = true;
}

/// Minimize or unminimize window. (native only)
#[cfg(not(target_arch = "wasm32"))]
pub fn set_minimized(&mut self, minimized: bool) {
self.output.minimized = Some(minimized);
}

/// Bring the window into focus (native only). Has no effect on Wayland, or if the window is minimized or invisible.
///
/// This method puts the window on top of other applications and takes input focus away from them,
/// which, if unexpected, will disturb the user.
#[cfg(not(target_arch = "wasm32"))]
pub fn focus(&mut self) {
self.output.focus = Some(true);
}

/// If the window is unfocused, attract the user's attention (native only).
///
/// Typically, this means that the window will flash on the taskbar, or bounce, until it is interacted with.
///
/// When the window comes into focus, or if `None` is passed, the attention request will be automatically reset.
///
/// See [winit's documentation][user_attention_details] for platform-specific effect details.
///
/// [user_attention_details]: https://docs.rs/winit/latest/winit/window/enum.UserAttentionType.html
#[cfg(not(target_arch = "wasm32"))]
pub fn request_user_attention(&mut self, kind: egui::UserAttentionType) {
self.output.attention = Some(kind);
}

/// Maximize or unmaximize window. (native only)
#[cfg(not(target_arch = "wasm32"))]
pub fn set_maximized(&mut self, maximized: bool) {
self.output.maximized = Some(maximized);
}

/// Tell `eframe` to close the desktop window.
#[cfg(not(target_arch = "wasm32"))]
#[deprecated = "Renamed `close`"]
pub fn quit(&mut self) {
self.close();
}

/// Set the desired inner size of the window (in egui points).
#[cfg(not(target_arch = "wasm32"))]
pub fn set_window_size(&mut self, size: egui::Vec2) {
self.output.window_size = Some(size);
self.info.window_info.size = size; // so that subsequent calls see the updated value
}

/// Set the desired title of the window.
#[cfg(not(target_arch = "wasm32"))]
pub fn set_window_title(&mut self, title: &str) {
self.output.window_title = Some(title.to_owned());
}

/// Set whether to show window decorations (i.e. a frame around you app).
///
/// If false it will be difficult to move and resize the app.
#[cfg(not(target_arch = "wasm32"))]
pub fn set_decorations(&mut self, decorated: bool) {
self.output.decorated = Some(decorated);
}

/// Turn borderless fullscreen on/off (native only).
#[cfg(not(target_arch = "wasm32"))]
pub fn set_fullscreen(&mut self, fullscreen: bool) {
self.output.fullscreen = Some(fullscreen);
self.info.window_info.fullscreen = fullscreen; // so that subsequent calls see the updated value
}

/// set the position of the outer window.
#[cfg(not(target_arch = "wasm32"))]
pub fn set_window_pos(&mut self, pos: egui::Pos2) {
self.output.window_pos = Some(pos);
self.info.window_info.position = Some(pos); // so that subsequent calls see the updated value
}

/// When called, the native window will follow the
/// movement of the cursor while the primary mouse button is down.
///
/// Does not work on the web.
#[cfg(not(target_arch = "wasm32"))]
pub fn drag_window(&mut self) {
self.output.drag_window = true;
}

/// Set the visibility of the window.
#[cfg(not(target_arch = "wasm32"))]
pub fn set_visible(&mut self, visible: bool) {
self.output.visible = Some(visible);
}

/// On desktop: Set the window always on top.
///
/// (Wayland desktop currently not supported)
#[cfg(not(target_arch = "wasm32"))]
pub fn set_always_on_top(&mut self, always_on_top: bool) {
self.output.always_on_top = Some(always_on_top);
}

/// On desktop: Set the window to be centered.
///
/// (Wayland desktop currently not supported)
#[cfg(not(target_arch = "wasm32"))]
pub fn set_centered(&mut self) {
if let Some(monitor_size) = self.info.window_info.monitor_size {
let inner_size = self.info.window_info.size;
if monitor_size.x > 1.0 && monitor_size.y > 1.0 {
let x = (monitor_size.x - inner_size.x) / 2.0;
let y = (monitor_size.y - inner_size.y) / 2.0;
self.set_window_pos(egui::Pos2 { x, y });
}
}
}

/// for integrations only: call once per frame
#[cfg(any(feature = "glow", feature = "wgpu"))]
pub(crate) fn take_app_output(&mut self) -> backend::AppOutput {
std::mem::take(&mut self.output)
}
}

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

/// Information about the application's main window, if available.
#[cfg(not(target_arch = "wasm32"))]
#[derive(Clone, Debug)]
pub struct WindowInfo {
/// Coordinates of the window's outer top left corner, relative to the top left corner of the first display.
///
/// Unit: egui points (logical pixels).
///
/// `None` = unknown.
pub position: Option<egui::Pos2>,

/// Are we in fullscreen mode?
pub fullscreen: bool,

/// Are we minimized?
pub minimized: bool,

/// Are we maximized?
pub maximized: bool,

/// Is the window focused and able to receive input?
///
/// This should be the same as [`egui::InputState::focused`].
pub focused: bool,

/// Window inner size in egui points (logical pixels).
pub size: egui::Vec2,

/// Current monitor size in egui points (logical pixels)
pub monitor_size: Option<egui::Vec2>,
}

/// Information about the URL.
///
/// Everything has been percent decoded (`%20` -> ` ` etc).
Expand Down Expand Up @@ -1141,13 +900,6 @@ pub struct IntegrationInfo {
/// Seconds of cpu usage (in seconds) of UI code on the previous frame.
/// `None` if this is the first frame.
pub cpu_usage: Option<f32>,

/// The OS native pixels-per-point
pub native_pixels_per_point: Option<f32>,

/// The position and size of the native window.
#[cfg(not(target_arch = "wasm32"))]
pub window_info: WindowInfo,
}

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

/// [`Storage`] key used for app
pub const APP_KEY: &str = "app";

// ----------------------------------------------------------------------------

/// You only need to look here if you are writing a backend for `epi`.
pub(crate) mod backend {
/// Action that can be taken by the user app.
#[derive(Clone, Debug, Default)]
#[must_use]
pub struct AppOutput {
/// Set to `true` to close the native window (which often quits the app).
#[cfg(not(target_arch = "wasm32"))]
pub close: bool,

/// Set to some size to resize the outer window (e.g. glium window) to this size.
#[cfg(not(target_arch = "wasm32"))]
pub window_size: Option<egui::Vec2>,

/// Set to some string to rename the outer window (e.g. glium window) to this title.
#[cfg(not(target_arch = "wasm32"))]
pub window_title: Option<String>,

/// Set to some bool to change window decorations.
#[cfg(not(target_arch = "wasm32"))]
pub decorated: Option<bool>,

/// Set to some bool to change window fullscreen.
#[cfg(not(target_arch = "wasm32"))] // TODO: implement fullscreen on web
pub fullscreen: Option<bool>,

/// Set to true to drag window while primary mouse button is down.
#[cfg(not(target_arch = "wasm32"))]
pub drag_window: bool,

/// Set to some position to move the outer window (e.g. glium window) to this position
#[cfg(not(target_arch = "wasm32"))]
pub window_pos: Option<egui::Pos2>,

/// Set to some bool to change window visibility.
#[cfg(not(target_arch = "wasm32"))]
pub visible: Option<bool>,

/// Set to some bool to tell the window always on top.
#[cfg(not(target_arch = "wasm32"))]
pub always_on_top: Option<bool>,

/// Set to some bool to minimize or unminimize window.
#[cfg(not(target_arch = "wasm32"))]
pub minimized: Option<bool>,

/// Set to some bool to maximize or unmaximize window.
#[cfg(not(target_arch = "wasm32"))]
pub maximized: Option<bool>,

/// Set to some bool to focus window.
#[cfg(not(target_arch = "wasm32"))]
pub focus: Option<bool>,

/// Set to request a user's attention to the native window.
#[cfg(not(target_arch = "wasm32"))]
pub attention: Option<egui::UserAttentionType>,

#[cfg(not(target_arch = "wasm32"))]
pub screenshot_requested: bool,
}
}
Loading
Loading