1
0
mirror of https://github.com/emilk/egui.git synced 2026-09-02 06:40:06 -04:00

Simplify ViewportBuilder: Defaults is chosen by eframe

This commit is contained in:
Emil Ernerfeldt
2023-11-15 18:18:07 +01:00
parent 6f98994a7c
commit d21458d166
6 changed files with 67 additions and 115 deletions

View File

@@ -85,7 +85,7 @@ pub fn window_builder<E>(
.. ..
} = native_options; } = native_options;
let mut viewport_builder = egui::ViewportBuilder::DEFAULTS let mut viewport_builder = egui::ViewportBuilder::default()
.with_title(title) .with_title(title)
.with_decorations(*decorated) .with_decorations(*decorated)
.with_fullscreen(*fullscreen) .with_fullscreen(*fullscreen)

View File

@@ -1005,8 +1005,9 @@ pub fn process_viewport_commands(
egui::ViewportCommand::StartDrag => { egui::ViewportCommand::StartDrag => {
// if this is not checked on x11 the input will be permanently taken until the app is killed! // if this is not checked on x11 the input will be permanently taken until the app is killed!
if is_viewport_focused { if is_viewport_focused {
// TODO possible return the error to `egui::Context` if let Err(err) = window.drag_window() {
let _ = window.drag_window(); log::warn!("{command:?}: {err}");
}
} }
} }
egui::ViewportCommand::InnerSize(size) => { egui::ViewportCommand::InnerSize(size) => {
@@ -1014,23 +1015,18 @@ pub fn process_viewport_commands(
let height = size.y.max(1.0); let height = size.y.max(1.0);
window.set_inner_size(LogicalSize::new(width, height)); window.set_inner_size(LogicalSize::new(width, height));
} }
egui::ViewportCommand::BeginResize { egui::ViewportCommand::BeginResize(direction) => {
top, if let Err(err) = window.drag_resize_window(match direction {
bottom, egui::viewport::ResizeDirection::North => ResizeDirection::North,
right, egui::viewport::ResizeDirection::South => ResizeDirection::South,
left, egui::viewport::ResizeDirection::West => ResizeDirection::West,
} => { egui::viewport::ResizeDirection::NorthEast => ResizeDirection::NorthEast,
// TODO posibile return the error to `egui::Context` egui::viewport::ResizeDirection::SouthEast => ResizeDirection::SouthEast,
let _ = window.drag_resize_window(match (top, bottom, right, left) { egui::viewport::ResizeDirection::NorthWest => ResizeDirection::NorthWest,
(true, false, false, false) => ResizeDirection::North, egui::viewport::ResizeDirection::SouthWest => ResizeDirection::SouthWest,
(false, true, false, false) => ResizeDirection::South, }) {
(false, false, false, true) => ResizeDirection::West, log::warn!("{command:?}: {err}");
(true, false, true, false) => ResizeDirection::NorthEast, }
(false, true, true, false) => ResizeDirection::SouthEast,
(true, false, false, true) => ResizeDirection::NorthWest,
(false, true, false, true) => ResizeDirection::SouthWest,
_ => ResizeDirection::East,
});
} }
ViewportCommand::Title(title) => window.set_title(&title), ViewportCommand::Title(title) => window.set_title(&title),
ViewportCommand::Transparent(v) => window.set_transparent(v), ViewportCommand::Transparent(v) => window.set_transparent(v),
@@ -1115,7 +1111,7 @@ pub fn process_viewport_commands(
ViewportCommand::ContentProtected(v) => window.set_content_protected(v), ViewportCommand::ContentProtected(v) => window.set_content_protected(v),
ViewportCommand::CursorPosition(pos) => { ViewportCommand::CursorPosition(pos) => {
if let Err(err) = window.set_cursor_position(LogicalPosition::new(pos.x, pos.y)) { if let Err(err) = window.set_cursor_position(LogicalPosition::new(pos.x, pos.y)) {
log::error!("{err}"); log::warn!("{command:?}: {err}");
} }
} }
ViewportCommand::CursorGrab(o) => { ViewportCommand::CursorGrab(o) => {
@@ -1124,13 +1120,13 @@ pub fn process_viewport_commands(
egui::viewport::CursorGrab::Confined => CursorGrabMode::Confined, egui::viewport::CursorGrab::Confined => CursorGrabMode::Confined,
egui::viewport::CursorGrab::Locked => CursorGrabMode::Locked, egui::viewport::CursorGrab::Locked => CursorGrabMode::Locked,
}) { }) {
log::error!("{err}"); log::warn!("{command:?}: {err}");
} }
} }
ViewportCommand::CursorVisible(v) => window.set_cursor_visible(v), ViewportCommand::CursorVisible(v) => window.set_cursor_visible(v),
ViewportCommand::CursorHitTest(v) => { ViewportCommand::CursorHitTest(v) => {
if let Err(err) = window.set_cursor_hittest(v) { if let Err(err) = window.set_cursor_hittest(v) {
log::error!("Setting viewport CursorHitTest: {err}"); log::warn!("{command:?}: {err}");
} }
} }
} }
@@ -1157,21 +1153,20 @@ pub fn create_winit_window_builder(builder: &ViewportBuilder) -> winit::window::
.fullscreen .fullscreen
.and_then(|e| e.then_some(winit::window::Fullscreen::Borderless(None))), .and_then(|e| e.then_some(winit::window::Fullscreen::Borderless(None))),
) )
.with_enabled_buttons( .with_enabled_buttons({
builder let mut buttons = WindowButtons::empty();
.minimize_button if builder.minimize_button.unwrap_or(true) {
.and_then(|v| v.then_some(WindowButtons::MINIMIZE)) buttons |= WindowButtons::MINIMIZE;
.unwrap_or(WindowButtons::empty()) }
| builder if builder.maximize_button.unwrap_or(true) {
.maximize_button buttons |= WindowButtons::MAXIMIZE;
.and_then(|v| v.then_some(WindowButtons::MAXIMIZE)) }
.unwrap_or(WindowButtons::empty()) if builder.close_button.unwrap_or(true) {
| builder buttons |= WindowButtons::CLOSE;
.close_button }
.and_then(|v| v.then_some(WindowButtons::CLOSE)) buttons
.unwrap_or(WindowButtons::empty()), })
) .with_active(builder.active.unwrap_or(true));
.with_active(builder.active.map_or(false, |e| e));
if let Some(Some(inner_size)) = builder.inner_size { if let Some(Some(inner_size)) = builder.inner_size {
window_builder = window_builder window_builder = window_builder
@@ -1222,7 +1217,7 @@ pub fn create_winit_window_builder(builder: &ViewportBuilder) -> winit::window::
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
{ {
use winit::platform::macos::WindowBuilderExtMacOS; use winit::platform::macos::WindowBuilderExtMacOS as _;
window_builder = window_builder window_builder = window_builder
.with_title_hidden(builder.title_hidden.unwrap_or(false)) .with_title_hidden(builder.title_hidden.unwrap_or(false))
.with_titlebar_transparent(builder.titlebar_transparent.unwrap_or(false)) .with_titlebar_transparent(builder.titlebar_transparent.unwrap_or(false))

View File

@@ -157,7 +157,8 @@ pub struct ViewportInfo {
/// unit = physical pixels /// unit = physical pixels
pub outer_rect_px: Option<Rect>, pub outer_rect_px: Option<Rect>,
/// Viewport should close? /// The user requested the viewport should close,
/// e.g. by pressing the close button in the window decoration.
pub close_requested: bool, pub close_requested: bool,
} }

View File

@@ -99,6 +99,9 @@ pub type ImmediateViewportRendererCallback = dyn for<'a> Fn(&Context, ImmediateV
/// Since egui is immediate mode, `ViewportBuilder` is accumulative in nature. /// Since egui is immediate mode, `ViewportBuilder` is accumulative in nature.
/// Setting any option to `None` means "keep the current value", /// Setting any option to `None` means "keep the current value",
/// or "Use the default" if it is the first call. /// or "Use the default" if it is the first call.
///
/// The default values are implementation defined, so you may want to explicitly
/// configure the size of the window, and what buttons are shown.
#[derive(Clone, Debug, Default, Eq, PartialEq)] #[derive(Clone, Debug, Default, Eq, PartialEq)]
#[allow(clippy::option_option)] #[allow(clippy::option_option)]
pub struct ViewportBuilder { pub struct ViewportBuilder {
@@ -134,63 +137,6 @@ pub struct ViewportBuilder {
} }
impl ViewportBuilder { impl ViewportBuilder {
/// Default settings for the root viewport.
pub const DEFAULTS: Self = Self {
title: None,
name: None,
position: None,
inner_size: Some(Some(Vec2::new(300.0, 200.0))),
fullscreen: None,
maximized: None,
resizable: Some(true),
transparent: Some(true),
decorations: Some(true),
icon: None,
active: Some(true),
visible: Some(true),
title_hidden: None,
titlebar_transparent: None,
fullsize_content_view: None,
min_inner_size: None,
max_inner_size: None,
drag_and_drop: Some(true),
close_button: Some(true),
minimize_button: Some(true),
maximize_button: Some(true),
hittest: Some(true),
};
/// Empty settings for everything.
///
/// If used the first frame, backend-specific defaults will be used.
/// When used on subsequent frames, the current settings will be kept.
///
/// The given id must be unique for each viewport.
pub const EMPTY: Self = Self {
title: None,
name: None,
position: None,
inner_size: None,
fullscreen: None,
maximized: None,
resizable: None,
transparent: None,
decorations: None,
icon: None,
active: None,
visible: None,
title_hidden: None,
titlebar_transparent: None,
fullsize_content_view: None,
min_inner_size: None,
max_inner_size: None,
drag_and_drop: None,
close_button: None,
minimize_button: None,
maximize_button: None,
hittest: None,
};
/// Sets the initial title of the window in the title bar. /// Sets the initial title of the window in the title bar.
/// ///
/// Look at winit for more details /// Look at winit for more details
@@ -294,24 +240,27 @@ impl ViewportBuilder {
self self
} }
/// Mac Os only
/// Hides the window title. /// Hides the window title.
///
/// Mac Os only.
#[inline] #[inline]
pub fn with_title_hidden(mut self, title_hidden: bool) -> Self { pub fn with_title_hidden(mut self, title_hidden: bool) -> Self {
self.title_hidden = Some(title_hidden); self.title_hidden = Some(title_hidden);
self self
} }
/// Mac Os only
/// Makes the titlebar transparent and allows the content to appear behind it. /// Makes the titlebar transparent and allows the content to appear behind it.
///
/// Mac Os only.
#[inline] #[inline]
pub fn with_titlebar_transparent(mut self, value: bool) -> Self { pub fn with_titlebar_transparent(mut self, value: bool) -> Self {
self.titlebar_transparent = Some(value); self.titlebar_transparent = Some(value);
self self
} }
/// Mac Os only
/// Makes the window content appear behind the titlebar. /// Makes the window content appear behind the titlebar.
///
/// Mac Os only.
#[inline] #[inline]
pub fn with_fullsize_content_view(mut self, value: bool) -> Self { pub fn with_fullsize_content_view(mut self, value: bool) -> Self {
self.fullsize_content_view = Some(value); self.fullsize_content_view = Some(value);
@@ -584,7 +533,7 @@ impl ViewportBuilder {
} }
} }
#[derive(Clone, Copy, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum WindowLevel { pub enum WindowLevel {
Normal, Normal,
@@ -592,7 +541,7 @@ pub enum WindowLevel {
AlwaysOnTop, AlwaysOnTop,
} }
#[derive(Clone, Copy, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum IMEPurpose { pub enum IMEPurpose {
Normal, Normal,
@@ -600,7 +549,7 @@ pub enum IMEPurpose {
Terminal, Terminal,
} }
#[derive(Clone, Copy, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum SystemTheme { pub enum SystemTheme {
Light, Light,
@@ -608,7 +557,7 @@ pub enum SystemTheme {
SystemDefault, SystemDefault,
} }
#[derive(Clone, Copy, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum CursorGrab { pub enum CursorGrab {
None, None,
@@ -616,17 +565,29 @@ pub enum CursorGrab {
Locked, Locked,
} }
#[derive(Clone, Copy, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum UserAttentionType { pub enum UserAttentionType {
Informational, Informational,
Critical, Critical,
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum ResizeDirection {
North,
South,
West,
NorthEast,
SouthEast,
NorthWest,
SouthWest,
}
/// You can send a [`ViewportCommand`] to the viewport with [`Context::viewport_command`]. /// You can send a [`ViewportCommand`] to the viewport with [`Context::viewport_command`].
/// ///
/// All coordinates are in logical points. /// All coordinates are in logical points.
#[derive(Clone, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum ViewportCommand { pub enum ViewportCommand {
/// Set the title /// Set the title
@@ -663,12 +624,7 @@ pub enum ViewportCommand {
/// ///
/// There's no guarantee that this will work unless the left mouse button was pressed /// There's no guarantee that this will work unless the left mouse button was pressed
/// immediately before this function is called. /// immediately before this function is called.
BeginResize { BeginResize(ResizeDirection),
top: bool,
bottom: bool,
right: bool,
left: bool,
},
/// Can the window be resized? /// Can the window be resized?
Resizable(bool), Resizable(bool),

View File

@@ -52,7 +52,7 @@ impl eframe::App for MyApp {
if self.show_immediate_viewport { if self.show_immediate_viewport {
ctx.show_viewport_immediate( ctx.show_viewport_immediate(
egui::ViewportId::from_hash_of("immediate_viewport"), egui::ViewportId::from_hash_of("immediate_viewport"),
egui::ViewportBuilder::DEFAULTS.with_title("Immediate Viewport"), egui::ViewportBuilder::default().with_title("Immediate Viewport"),
|ctx| { |ctx| {
egui::CentralPanel::default().show(ctx, |ui| { egui::CentralPanel::default().show(ctx, |ui| {
ui.label("Hello from immediate viewport"); ui.label("Hello from immediate viewport");
@@ -70,7 +70,7 @@ impl eframe::App for MyApp {
let show_deferred_viewport = self.show_deferred_viewport.clone(); let show_deferred_viewport = self.show_deferred_viewport.clone();
ctx.show_viewport_immediate( ctx.show_viewport_immediate(
egui::ViewportId::from_hash_of("deferred_viewport"), egui::ViewportId::from_hash_of("deferred_viewport"),
egui::ViewportBuilder::DEFAULTS.with_title("Deferred Viewport"), egui::ViewportBuilder::default().with_title("Deferred Viewport"),
|ctx| { |ctx| {
egui::CentralPanel::default().show(ctx, |ui| { egui::CentralPanel::default().show(ctx, |ui| {
ui.label("Hello from deferred viewport"); ui.label("Hello from deferred viewport");

View File

@@ -65,7 +65,7 @@ impl ViewportState {
let immediate = vp_state.read().immediate; let immediate = vp_state.read().immediate;
let title = vp_state.read().title.clone(); let title = vp_state.read().title.clone();
let viewport = ViewportBuilder::DEFAULTS let viewport = ViewportBuilder::default()
.with_title(&title) .with_title(&title)
.with_inner_size(Some(egui::vec2(450.0, 400.0))); .with_inner_size(Some(egui::vec2(450.0, 400.0)));