eframe: Add center
to NativeOptions
and monitor_size
to WindowInfo
(#2035)
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
This commit is contained in:
parent
c4117066cf
commit
bc6a823103
4 changed files with 96 additions and 5 deletions
|
@ -10,8 +10,8 @@ NOTE: [`egui-winit`](../egui-winit/CHANGELOG.md), [`egui_glium`](../egui_glium/C
|
||||||
* Enabled deferred render state initialization to support Android ([#1952](https://github.com/emilk/egui/pull/1952)).
|
* Enabled deferred render state initialization to support Android ([#1952](https://github.com/emilk/egui/pull/1952)).
|
||||||
* Allow empty textures with the glow renderer.
|
* Allow empty textures with the glow renderer.
|
||||||
* Added `shader_version` to `NativeOptions` for cross compiling support on different target OpenGL | ES versions (on native `glow` renderer only) ([#1993](https://github.com/emilk/egui/pull/1993)).
|
* Added `shader_version` to `NativeOptions` for cross compiling support on different target OpenGL | ES versions (on native `glow` renderer only) ([#1993](https://github.com/emilk/egui/pull/1993)).
|
||||||
* Fix: app state is now saved when user presses Cmd-Q on Mac ([#1993](https://github.com/emilk/egui/pull/1993)).
|
* Fix: app state is now saved when user presses Cmd-Q on Mac ([#2013](https://github.com/emilk/egui/pull/2013)).
|
||||||
|
* Added `center` to `NativeOptions` and `monitor_size` to `WindowInfo` on desktop ([#2035](https://github.com/emilk/egui/pull/2035)).
|
||||||
|
|
||||||
## 0.19.0 - 2022-08-20
|
## 0.19.0 - 2022-08-20
|
||||||
* MSRV (Minimum Supported Rust Version) is now `1.61.0` ([#1846](https://github.com/emilk/egui/pull/1846)).
|
* MSRV (Minimum Supported Rust Version) is now `1.61.0` ([#1846](https://github.com/emilk/egui/pull/1846)).
|
||||||
|
|
|
@ -208,7 +208,7 @@ pub enum HardwareAcceleration {
|
||||||
/// Only a single native window is currently supported.
|
/// Only a single native window is currently supported.
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
pub struct NativeOptions {
|
pub struct NativeOptions {
|
||||||
/// Sets whether or not the window will always be on top of other windows.
|
/// Sets whether or not the window will always be on top of other windows at initialization.
|
||||||
pub always_on_top: bool,
|
pub always_on_top: bool,
|
||||||
|
|
||||||
/// Show window in maximized mode
|
/// Show window in maximized mode
|
||||||
|
@ -347,6 +347,13 @@ pub struct NativeOptions {
|
||||||
///
|
///
|
||||||
/// For OpenGL ES 2.0: set this to [`egui_glow::ShaderVersion::Es100`] to solve blank texture problem (by using the "fallback shader").
|
/// For OpenGL ES 2.0: set this to [`egui_glow::ShaderVersion::Es100`] to solve blank texture problem (by using the "fallback shader").
|
||||||
pub shader_version: Option<egui_glow::ShaderVersion>,
|
pub shader_version: Option<egui_glow::ShaderVersion>,
|
||||||
|
|
||||||
|
/// On desktop: make the window position to be centered at initialization.
|
||||||
|
///
|
||||||
|
/// Platform specific:
|
||||||
|
///
|
||||||
|
/// Wayland desktop currently not supported.
|
||||||
|
pub centered: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
@ -389,6 +396,7 @@ impl Default for NativeOptions {
|
||||||
event_loop_builder: None,
|
event_loop_builder: None,
|
||||||
#[cfg(feature = "glow")]
|
#[cfg(feature = "glow")]
|
||||||
shader_version: None,
|
shader_version: None,
|
||||||
|
centered: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -712,6 +720,29 @@ impl Frame {
|
||||||
self.output.visible = Some(visible);
|
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
|
/// for integrations only: call once per frame
|
||||||
pub(crate) fn take_app_output(&mut self) -> backend::AppOutput {
|
pub(crate) fn take_app_output(&mut self) -> backend::AppOutput {
|
||||||
std::mem::take(&mut self.output)
|
std::mem::take(&mut self.output)
|
||||||
|
@ -742,6 +773,9 @@ pub struct WindowInfo {
|
||||||
|
|
||||||
/// Window inner size in egui points (logical pixels).
|
/// Window inner size in egui points (logical pixels).
|
||||||
pub size: egui::Vec2,
|
pub size: egui::Vec2,
|
||||||
|
|
||||||
|
/// Current monitor size in egui points (logical pixels)
|
||||||
|
pub monitor_size: Option<egui::Vec2>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Information about the URL.
|
/// Information about the URL.
|
||||||
|
@ -915,5 +949,9 @@ pub(crate) mod backend {
|
||||||
/// Set to some bool to change window visibility.
|
/// Set to some bool to change window visibility.
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
pub visible: Option<bool>,
|
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>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,14 @@ pub fn read_window_info(window: &winit::window::Window, pixels_per_point: f32) -
|
||||||
.map(|pos| pos.to_logical::<f32>(pixels_per_point.into()))
|
.map(|pos| pos.to_logical::<f32>(pixels_per_point.into()))
|
||||||
.map(|pos| egui::Pos2 { x: pos.x, y: pos.y });
|
.map(|pos| egui::Pos2 { x: pos.x, y: pos.y });
|
||||||
|
|
||||||
|
let monitor = window.current_monitor().is_some();
|
||||||
|
let monitor_size = if monitor {
|
||||||
|
let size = window.current_monitor().unwrap().size();
|
||||||
|
Some(egui::vec2(size.width as _, size.height as _))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
let size = window
|
let size = window
|
||||||
.inner_size()
|
.inner_size()
|
||||||
.to_logical::<f32>(pixels_per_point.into());
|
.to_logical::<f32>(pixels_per_point.into());
|
||||||
|
@ -32,6 +40,7 @@ pub fn read_window_info(window: &winit::window::Window, pixels_per_point: f32) -
|
||||||
x: size.width,
|
x: size.width,
|
||||||
y: size.height,
|
y: size.height,
|
||||||
},
|
},
|
||||||
|
monitor_size,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,6 +147,7 @@ pub fn handle_app_output(
|
||||||
drag_window,
|
drag_window,
|
||||||
window_pos,
|
window_pos,
|
||||||
visible,
|
visible,
|
||||||
|
always_on_top,
|
||||||
} = app_output;
|
} = app_output;
|
||||||
|
|
||||||
if let Some(decorated) = decorated {
|
if let Some(decorated) = decorated {
|
||||||
|
@ -176,6 +186,10 @@ pub fn handle_app_output(
|
||||||
if let Some(visible) = visible {
|
if let Some(visible) = visible {
|
||||||
window.set_visible(visible);
|
window.set_visible(visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(always_on_top) = always_on_top {
|
||||||
|
window.set_always_on_top(always_on_top);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
|
@ -223,6 +223,27 @@ fn run_and_exit(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn centere_window_pos(
|
||||||
|
monitor: Option<winit::monitor::MonitorHandle>,
|
||||||
|
native_options: &mut epi::NativeOptions,
|
||||||
|
) {
|
||||||
|
// Get the current_monitor.
|
||||||
|
if let Some(monitor) = monitor {
|
||||||
|
let monitor_size = monitor.size();
|
||||||
|
let inner_size = native_options
|
||||||
|
.initial_window_size
|
||||||
|
.unwrap_or(egui::Vec2 { x: 800.0, y: 600.0 });
|
||||||
|
if monitor_size.width > 0 && monitor_size.height > 0 {
|
||||||
|
let x = (monitor_size.width - inner_size.x as u32) / 2;
|
||||||
|
let y = (monitor_size.height - inner_size.y as u32) / 2;
|
||||||
|
native_options.initial_window_pos = Some(egui::Pos2 {
|
||||||
|
x: x as _,
|
||||||
|
y: y as _,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/// Run an egui app
|
/// Run an egui app
|
||||||
#[cfg(feature = "glow")]
|
#[cfg(feature = "glow")]
|
||||||
|
@ -588,13 +609,22 @@ mod glow_integration {
|
||||||
app_creator: epi::AppCreator,
|
app_creator: epi::AppCreator,
|
||||||
) {
|
) {
|
||||||
if native_options.run_and_return {
|
if native_options.run_and_return {
|
||||||
with_event_loop(native_options, |event_loop, native_options| {
|
with_event_loop(native_options, |event_loop, mut native_options| {
|
||||||
|
if native_options.centered {
|
||||||
|
centere_window_pos(event_loop.available_monitors().next(), &mut native_options);
|
||||||
|
}
|
||||||
|
|
||||||
let glow_eframe =
|
let glow_eframe =
|
||||||
GlowWinitApp::new(event_loop, app_name, native_options, app_creator);
|
GlowWinitApp::new(event_loop, app_name, native_options, app_creator);
|
||||||
run_and_return(event_loop, glow_eframe);
|
run_and_return(event_loop, glow_eframe);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
let event_loop = create_event_loop_builder(&mut native_options).build();
|
let event_loop = create_event_loop_builder(&mut native_options).build();
|
||||||
|
|
||||||
|
if native_options.centered {
|
||||||
|
centere_window_pos(event_loop.available_monitors().next(), &mut native_options);
|
||||||
|
}
|
||||||
|
|
||||||
let glow_eframe = GlowWinitApp::new(&event_loop, app_name, native_options, app_creator);
|
let glow_eframe = GlowWinitApp::new(&event_loop, app_name, native_options, app_creator);
|
||||||
run_and_exit(event_loop, glow_eframe);
|
run_and_exit(event_loop, glow_eframe);
|
||||||
}
|
}
|
||||||
|
@ -959,13 +989,22 @@ mod wgpu_integration {
|
||||||
app_creator: epi::AppCreator,
|
app_creator: epi::AppCreator,
|
||||||
) {
|
) {
|
||||||
if native_options.run_and_return {
|
if native_options.run_and_return {
|
||||||
with_event_loop(native_options, |event_loop, native_options| {
|
with_event_loop(native_options, |event_loop, mut native_options| {
|
||||||
|
if native_options.centered {
|
||||||
|
centere_window_pos(event_loop.available_monitors().next(), &mut native_options);
|
||||||
|
}
|
||||||
|
|
||||||
let wgpu_eframe =
|
let wgpu_eframe =
|
||||||
WgpuWinitApp::new(event_loop, app_name, native_options, app_creator);
|
WgpuWinitApp::new(event_loop, app_name, native_options, app_creator);
|
||||||
run_and_return(event_loop, wgpu_eframe);
|
run_and_return(event_loop, wgpu_eframe);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
let event_loop = create_event_loop_builder(&mut native_options).build();
|
let event_loop = create_event_loop_builder(&mut native_options).build();
|
||||||
|
|
||||||
|
if native_options.centered {
|
||||||
|
centere_window_pos(event_loop.available_monitors().next(), &mut native_options);
|
||||||
|
}
|
||||||
|
|
||||||
let wgpu_eframe = WgpuWinitApp::new(&event_loop, app_name, native_options, app_creator);
|
let wgpu_eframe = WgpuWinitApp::new(&event_loop, app_name, native_options, app_creator);
|
||||||
run_and_exit(event_loop, wgpu_eframe);
|
run_and_exit(event_loop, wgpu_eframe);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue