1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-31 05:40:03 -04:00

Rename every thing that i was implemented for multiples windows to Viewport

This commit is contained in:
Konkitoman
2023-07-23 12:47:36 +03:00
parent cf01eff8d1
commit ea2dcd8cb5
10 changed files with 82 additions and 76 deletions

View File

@@ -9,7 +9,7 @@ use raw_window_handle::{HasRawDisplayHandle as _, HasRawWindowHandle as _};
#[cfg(feature = "accesskit")] #[cfg(feature = "accesskit")]
use egui::accesskit; use egui::accesskit;
use egui::{epaint::ahash::HashMap, window::WindowBuilder, NumExt as _}; use egui::{epaint::ahash::HashMap, window::ViewportBuilder, NumExt as _};
#[cfg(feature = "accesskit")] #[cfg(feature = "accesskit")]
use egui_winit::accesskit_winit; use egui_winit::accesskit_winit;
use egui_winit::{native_pixels_per_point, EventResponse, WindowSettings}; use egui_winit::{native_pixels_per_point, EventResponse, WindowSettings};
@@ -79,7 +79,7 @@ pub fn window_builder<E>(
title: &str, title: &str,
native_options: &epi::NativeOptions, native_options: &epi::NativeOptions,
window_settings: Option<WindowSettings>, window_settings: Option<WindowSettings>,
) -> WindowBuilder { ) -> ViewportBuilder {
let epi::NativeOptions { let epi::NativeOptions {
maximized, maximized,
decorated, decorated,
@@ -99,7 +99,7 @@ pub fn window_builder<E>(
.. ..
} = native_options; } = native_options;
let mut window_builder = WindowBuilder::default() let mut window_builder = ViewportBuilder::default()
.with_title(title) .with_title(title)
.with_decorations(*decorated) .with_decorations(*decorated)
.with_fullscreen(*fullscreen) .with_fullscreen(*fullscreen)

View File

@@ -3,7 +3,7 @@
use std::time::Instant; use std::time::Instant;
use egui::{epaint::ahash::HashMap, window::WindowBuilder}; use egui::{epaint::ahash::HashMap, window::ViewportBuilder};
use raw_window_handle::{HasRawDisplayHandle as _, HasRawWindowHandle as _}; use raw_window_handle::{HasRawDisplayHandle as _, HasRawWindowHandle as _};
use winit::event_loop::{ use winit::event_loop::{
ControlFlow, EventLoop, EventLoopBuilder, EventLoopProxy, EventLoopWindowTarget, ControlFlow, EventLoop, EventLoopBuilder, EventLoopProxy, EventLoopWindowTarget,
@@ -411,7 +411,7 @@ fn run_and_exit(event_loop: EventLoop<UserEvent>, mut winit_app: impl WinitApp +
mod glow_integration { mod glow_integration {
use std::sync::Arc; use std::sync::Arc;
use egui::{epaint::ahash::HashMap, window::WindowBuilder, NumExt as _}; use egui::{epaint::ahash::HashMap, window::ViewportBuilder, NumExt as _};
use egui_winit::EventResponse; use egui_winit::EventResponse;
use glow::HasContext; use glow::HasContext;
use glutin::{ use glutin::{
@@ -450,7 +450,7 @@ mod glow_integration {
} }
struct Window { struct Window {
builder: WindowBuilder, builder: ViewportBuilder,
gl_surface: Option<glutin::surface::Surface<glutin::surface::WindowSurface>>, gl_surface: Option<glutin::surface::Surface<glutin::surface::WindowSurface>>,
window: Option<winit::window::Window>, window: Option<winit::window::Window>,
window_id: u64, window_id: u64,
@@ -483,7 +483,7 @@ mod glow_integration {
/// ///
#[allow(unsafe_code)] #[allow(unsafe_code)]
unsafe fn new( unsafe fn new(
window_builder: WindowBuilder, window_builder: ViewportBuilder,
native_options: &epi::NativeOptions, native_options: &epi::NativeOptions,
event_loop: &EventLoopWindowTarget<UserEvent>, event_loop: &EventLoopWindowTarget<UserEvent>,
) -> Result<Self> { ) -> Result<Self> {
@@ -1010,7 +1010,7 @@ mod glow_integration {
repaint_after, repaint_after,
textures_delta, textures_delta,
shapes, shapes,
mut windows, mut viewports,
}; };
let control_flow; let control_flow;
@@ -1038,13 +1038,13 @@ mod glow_integration {
app.clear_color(&integration.egui_ctx.style().visuals), app.clear_color(&integration.egui_ctx.style().visuals),
); );
integration.egui_ctx.set_current_window_id(win.window_id); integration.egui_ctx.set_current_viewport_id(win.window_id);
egui::FullOutput { egui::FullOutput {
platform_output, platform_output,
repaint_after, repaint_after,
textures_delta, textures_delta,
shapes, shapes,
windows, viewports,
} = integration.update( } = integration.update(
app.as_mut(), app.as_mut(),
win.window.as_ref().unwrap(), win.window.as_ref().unwrap(),
@@ -1150,9 +1150,10 @@ mod glow_integration {
} }
} }
let mut wins = vec![0]; // 0 is the main viewport/window that will not be known by the egui_ctx
let mut active_viewports_ids = vec![0];
windows.retain_mut(|(id, builder)| { viewports.retain_mut(|(id, builder)| {
for w in gl_window.windows.iter_mut() { for w in gl_window.windows.iter_mut() {
if w.window_id == *id { if w.window_id == *id {
if w.builder != *builder { if w.builder != *builder {
@@ -1166,14 +1167,14 @@ mod glow_integration {
w.builder = builder.clone(); w.builder = builder.clone();
} }
wins.push(*id); active_viewports_ids.push(*id);
return false; return false;
} }
} }
true true
}); });
for (id, builder) in windows { for (id, builder) in viewports {
gl_window.windows.push(Window { gl_window.windows.push(Window {
builder, builder,
gl_surface: None, gl_surface: None,
@@ -1181,19 +1182,19 @@ mod glow_integration {
window_id: id, window_id: id,
egui_winit: None, egui_winit: None,
}); });
wins.push(id); active_viewports_ids.push(id);
} }
gl_window.windows.retain(|w| wins.contains(&w.window_id)); gl_window
gl_window.window_maps.retain(|_, id| wins.contains(id)); .windows
.retain(|w| active_viewports_ids.contains(&w.window_id));
gl_window
.window_maps
.retain(|_, id| active_viewports_ids.contains(id));
control_flow control_flow
}; };
// !! TODO !!
// Re do this is a really way to implement this
// We need to change the output of this function to `Vec<EventResult>`
windows_indexes windows_indexes
.into_iter() .into_iter()
.map(|window_index| inner(window_index)) .map(|window_index| inner(window_index))
@@ -1855,7 +1856,7 @@ fn extremely_far_future() -> std::time::Instant {
std::time::Instant::now() + std::time::Duration::from_secs(10_000_000_000) std::time::Instant::now() + std::time::Duration::from_secs(10_000_000_000)
} }
fn create_winit_window_builder(builder: &WindowBuilder) -> winit::window::WindowBuilder { fn create_winit_window_builder(builder: &ViewportBuilder) -> winit::window::WindowBuilder {
let mut window_builder = winit::window::WindowBuilder::new() let mut window_builder = winit::window::WindowBuilder::new()
.with_title(builder.title.clone()) .with_title(builder.title.clone())
.with_transparent(builder.transparent) .with_transparent(builder.transparent)

View File

@@ -1,4 +1,4 @@
use egui::window::WindowBuilder; use egui::window::ViewportBuilder;
/// Can be used to store native window settings (position and size). /// Can be used to store native window settings (position and size).
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
@@ -48,7 +48,7 @@ impl WindowSettings {
self.inner_size_points self.inner_size_points
} }
pub fn initialize_window(&self, mut window: WindowBuilder) -> WindowBuilder { pub fn initialize_window(&self, mut window: ViewportBuilder) -> ViewportBuilder {
// If the app last ran on two monitors and only one is now connected, then // If the app last ran on two monitors and only one is now connected, then
// the given position is invalid. // the given position is invalid.
// If this happens on Mac, the window is clamped into valid area. // If this happens on Mac, the window is clamped into valid area.

View File

@@ -7,7 +7,7 @@ use epaint::*;
use super::*; use super::*;
#[derive(Hash, PartialEq, Clone)] #[derive(Hash, PartialEq, Clone)]
pub struct WindowBuilder { pub struct ViewportBuilder {
pub title: String, pub title: String,
pub name: Option<String>, pub name: Option<String>,
pub position: Option<(i32, i32)>, pub position: Option<(i32, i32)>,
@@ -28,7 +28,7 @@ pub struct WindowBuilder {
pub drag_and_drop: bool, pub drag_and_drop: bool,
} }
impl Default for WindowBuilder { impl Default for ViewportBuilder {
fn default() -> Self { fn default() -> Self {
Self { Self {
title: "Dummy EGUI Window".into(), title: "Dummy EGUI Window".into(),
@@ -53,7 +53,7 @@ impl Default for WindowBuilder {
} }
} }
impl WindowBuilder { impl ViewportBuilder {
pub fn with_title(mut self, title: impl Into<String>) -> Self { pub fn with_title(mut self, title: impl Into<String>) -> Self {
self.title = title.into(); self.title = title.into();
self self
@@ -167,7 +167,7 @@ pub struct Window<'open> {
default_open: bool, default_open: bool,
with_title_bar: bool, with_title_bar: bool,
embedded: bool, embedded: bool,
window_builder: WindowBuilder, window_builder: ViewportBuilder,
} }
impl<'open> Window<'open> { impl<'open> Window<'open> {
@@ -178,7 +178,7 @@ impl<'open> Window<'open> {
let title = title.into().fallback_text_style(TextStyle::Heading); let title = title.into().fallback_text_style(TextStyle::Heading);
let area = Area::new(Id::new(title.text())); let area = Area::new(Id::new(title.text()));
Self { Self {
window_builder: WindowBuilder::default().with_title(title.text()), window_builder: ViewportBuilder::default().with_title(title.text()),
title, title,
open: None, open: None,
area, area,
@@ -451,14 +451,14 @@ impl<'open> Window<'open> {
window_builder.with_inner_size((size.x as u32 + 1, size.y as u32 + 1)); window_builder.with_inner_size((size.x as u32 + 1, size.y as u32 + 1));
} }
ctx.create_window(window_builder, move |_window_id| { ctx.create_viewport(window_builder, move |_window_id| {
let mut frame = frame.unwrap_or(Frame::window(&ctx.style())).rounding(0.0); let mut frame = frame.unwrap_or(Frame::window(&ctx.style())).rounding(0.0);
CentralPanel::default() CentralPanel::default()
.frame(frame) .frame(frame)
.show(ctx, |ui| Some(add_contents(ui))) .show(ctx, |ui| Some(add_contents(ui)))
}) })
} else { } else {
if ctx.current_window() != ctx.current_rendering_window() { if ctx.current_viewport() != ctx.current_rendering_viewport() {
return None; return None;
} }
let frame = frame.unwrap_or_else(|| Frame::window(&ctx.style())); let frame = frame.unwrap_or_else(|| Frame::window(&ctx.style()));

View File

@@ -160,10 +160,10 @@ struct ContextImpl {
repaint: Repaint, repaint: Repaint,
windows: HashMap<String, (WindowBuilder, u64, u64, bool)>, viewports: HashMap<String, (ViewportBuilder, u64, u64, bool)>,
window_counter: u64, viewport_counter: u64,
current_rendering_window: u64, current_rendering_viewport: u64,
windows_stack: Vec<u64>, viewport_stack: Vec<u64>,
is_desktop: bool, is_desktop: bool,
/// Written to during the frame. /// Written to during the frame.
@@ -969,7 +969,7 @@ impl Context {
// request two frames of repaint, just to cover some corner cases (frame delays): // request two frames of repaint, just to cover some corner cases (frame delays):
self.write(|ctx| { self.write(|ctx| {
ctx.repaint ctx.repaint
.request_repaint(ctx.windows_stack.last().cloned().unwrap_or(0)) .request_repaint(ctx.viewport_stack.last().cloned().unwrap_or(0))
}); });
} }
@@ -1274,15 +1274,17 @@ impl Context {
let repaint_after = self.write(|ctx| ctx.repaint.end_frame()); let repaint_after = self.write(|ctx| ctx.repaint.end_frame());
let shapes = self.drain_paint_lists(); let shapes = self.drain_paint_lists();
let mut windows = Vec::new(); let mut viewports = Vec::new();
self.write(|ctx| { self.write(|ctx| {
ctx.windows.retain(|_, (builder, id, parent, used)| { ctx.viewports.retain(|_, (builder, id, parent, used)| {
let out = *used; let out = *used;
if ctx.current_rendering_window == *parent || ctx.current_rendering_window == *id { if ctx.current_rendering_viewport == *parent
|| ctx.current_rendering_viewport == *id
{
*used = false; *used = false;
} else { } else {
} }
windows.push((*id, builder.clone())); viewports.push((*id, builder.clone()));
out out
}) })
}); });
@@ -1292,7 +1294,7 @@ impl Context {
repaint_after, repaint_after,
textures_delta, textures_delta,
shapes, shapes,
windows, viewports,
} }
} }
@@ -1476,7 +1478,7 @@ impl Context {
} }
pub(crate) fn rect_contains_pointer(&self, layer_id: LayerId, rect: Rect) -> bool { pub(crate) fn rect_contains_pointer(&self, layer_id: LayerId, rect: Rect) -> bool {
rect.is_positive() && self.current_window() == self.current_rendering_window() && { rect.is_positive() && self.current_viewport() == self.current_rendering_viewport() && {
let pointer_pos = self.input(|i| i.pointer.interact_pos()); let pointer_pos = self.input(|i| i.pointer.interact_pos());
if let Some(pointer_pos) = pointer_pos { if let Some(pointer_pos) = pointer_pos {
rect.contains(pointer_pos) && self.layer_id_at(pointer_pos) == Some(layer_id) rect.contains(pointer_pos) && self.layer_id_at(pointer_pos) == Some(layer_id)
@@ -1897,18 +1899,18 @@ impl Context {
} }
} }
use containers::window::WindowBuilder; use containers::window::ViewportBuilder;
/// # Windows /// # Windows
impl Context { impl Context {
pub fn set_current_window_id(&self, window_id: u64) { pub fn set_current_viewport_id(&self, viewport_id: u64) {
self.write(|ctx| ctx.current_rendering_window = window_id); self.write(|ctx| ctx.current_rendering_viewport = viewport_id);
} }
pub fn current_rendering_window(&self) -> u64 { pub fn current_rendering_viewport(&self) -> u64 {
self.read(|ctx| ctx.current_rendering_window) self.read(|ctx| ctx.current_rendering_viewport)
} }
pub fn current_window(&self) -> u64 { pub fn current_viewport(&self) -> u64 {
self.read(|ctx| ctx.windows_stack.last().cloned().unwrap_or(0)) self.read(|ctx| ctx.viewport_stack.last().cloned().unwrap_or(0))
} }
pub fn is_desktop(&self) -> bool { pub fn is_desktop(&self) -> bool {
@@ -1919,26 +1921,26 @@ impl Context {
self.write(|ctx| ctx.is_desktop = value) self.write(|ctx| ctx.is_desktop = value)
} }
pub fn create_window<T>( pub fn create_viewport<T>(
&self, &self,
window_builder: WindowBuilder, window_builder: ViewportBuilder,
func: impl FnOnce(u64) -> T, func: impl FnOnce(u64) -> T,
) -> Option<T> { ) -> Option<T> {
let id = self.write(|ctx| { let id = self.write(|ctx| {
if ctx.is_desktop { if ctx.is_desktop {
if let Some(window) = ctx.windows.get_mut(&window_builder.title) { if let Some(window) = ctx.viewports.get_mut(&window_builder.title) {
window.2 = *ctx.windows_stack.last().unwrap_or(&0); window.2 = *ctx.viewport_stack.last().unwrap_or(&0);
window.3 = true; window.3 = true;
window.1 window.1
} else { } else {
let id = ctx.window_counter + 1; let id = ctx.viewport_counter + 1;
ctx.window_counter = id; ctx.viewport_counter = id;
ctx.windows.insert( ctx.viewports.insert(
window_builder.title.clone(), window_builder.title.clone(),
( (
window_builder, window_builder,
id, id,
*ctx.windows_stack.last().unwrap_or(&0), *ctx.viewport_stack.last().unwrap_or(&0),
true, true,
), ),
); );
@@ -1949,12 +1951,12 @@ impl Context {
} }
}); });
let should_render = self.write(|ctx| { let should_render = self.write(|ctx| {
ctx.windows_stack.push(id); ctx.viewport_stack.push(id);
ctx.windows_stack.last().cloned().unwrap_or(0) == ctx.current_rendering_window ctx.viewport_stack.last().cloned().unwrap_or(0) == ctx.current_rendering_viewport
}); });
let out = if should_render { Some(func(id)) } else { None }; let out = if should_render { Some(func(id)) } else { None };
self.write(|ctx| { self.write(|ctx| {
ctx.windows_stack.pop(); ctx.viewport_stack.pop();
}); });
out out
} }

View File

@@ -1,6 +1,6 @@
//! All the data egui returns to the backend at the end of each frame. //! All the data egui returns to the backend at the end of each frame.
use crate::{window::WindowBuilder, WidgetType}; use crate::{window::ViewportBuilder, WidgetType};
/// What egui emits each frame from [`crate::Context::run`]. /// What egui emits each frame from [`crate::Context::run`].
/// ///
@@ -31,7 +31,7 @@ pub struct FullOutput {
/// You can use [`crate::Context::tessellate`] to turn this into triangles. /// You can use [`crate::Context::tessellate`] to turn this into triangles.
pub shapes: Vec<epaint::ClippedShape>, pub shapes: Vec<epaint::ClippedShape>,
pub windows: Vec<(u64, WindowBuilder)>, pub viewports: Vec<(u64, ViewportBuilder)>,
} }
impl FullOutput { impl FullOutput {
@@ -42,14 +42,14 @@ impl FullOutput {
repaint_after, repaint_after,
textures_delta, textures_delta,
shapes, shapes,
mut windows, viewports: mut windows,
} = newer; } = newer;
self.platform_output.append(platform_output); self.platform_output.append(platform_output);
self.repaint_after = repaint_after; // if the last frame doesn't need a repaint, then we don't need to repaint self.repaint_after = repaint_after; // if the last frame doesn't need a repaint, then we don't need to repaint
self.textures_delta.append(textures_delta); self.textures_delta.append(textures_delta);
self.shapes = shapes; // Only paint the latest self.shapes = shapes; // Only paint the latest
self.windows.append(&mut windows); self.viewports.append(&mut windows);
} }
} }

View File

@@ -168,7 +168,7 @@ impl Painter {
/// Can be used for free painting. /// Can be used for free painting.
/// NOTE: all coordinates are screen coordinates! /// NOTE: all coordinates are screen coordinates!
pub fn add(&self, shape: impl Into<Shape>) -> ShapeIdx { pub fn add(&self, shape: impl Into<Shape>) -> ShapeIdx {
if self.ctx.current_window() != self.ctx.current_rendering_window() { if self.ctx.current_viewport() != self.ctx.current_rendering_viewport() {
return self return self
.paint_list(|l| l.add(Rect::from_min_size(Pos2::ZERO, Vec2::ZERO), Shape::Noop)); .paint_list(|l| l.add(Rect::from_min_size(Pos2::ZERO, Vec2::ZERO), Shape::Noop));
} }
@@ -186,7 +186,7 @@ impl Painter {
/// Calling this once is generally faster than calling [`Self::add`] multiple times. /// Calling this once is generally faster than calling [`Self::add`] multiple times.
pub fn extend<I: IntoIterator<Item = Shape>>(&self, shapes: I) { pub fn extend<I: IntoIterator<Item = Shape>>(&self, shapes: I) {
if self.fade_to_color == Some(Color32::TRANSPARENT) if self.fade_to_color == Some(Color32::TRANSPARENT)
|| self.ctx.current_window() != self.ctx.current_rendering_window() || self.ctx.current_viewport() != self.ctx.current_rendering_viewport()
{ {
return; return;
} }
@@ -204,7 +204,7 @@ impl Painter {
/// Modify an existing [`Shape`]. /// Modify an existing [`Shape`].
pub fn set(&self, idx: ShapeIdx, shape: impl Into<Shape>) { pub fn set(&self, idx: ShapeIdx, shape: impl Into<Shape>) {
if self.fade_to_color == Some(Color32::TRANSPARENT) if self.fade_to_color == Some(Color32::TRANSPARENT)
|| self.ctx.current_window() != self.ctx.current_rendering_window() || self.ctx.current_viewport() != self.ctx.current_rendering_viewport()
{ {
return; return;
} }
@@ -398,7 +398,7 @@ impl Painter {
font_id: FontId, font_id: FontId,
text_color: Color32, text_color: Color32,
) -> Rect { ) -> Rect {
if self.ctx.current_window() != self.ctx.current_rendering_window() { if self.ctx.current_viewport() != self.ctx.current_rendering_viewport() {
return Rect::from_min_size(Pos2::ZERO, Vec2::ZERO); return Rect::from_min_size(Pos2::ZERO, Vec2::ZERO);
} }
let galley = self.layout_no_wrap(text.to_string(), font_id, text_color); let galley = self.layout_no_wrap(text.to_string(), font_id, text_color);

View File

@@ -283,7 +283,7 @@ impl BackendPanel {
log::info!("Request a repaint in 3s..."); log::info!("Request a repaint in 3s...");
ctx.request_repaint_after( ctx.request_repaint_after(
std::time::Duration::from_secs(3), std::time::Duration::from_secs(3),
ctx.current_rendering_window(), ctx.current_rendering_viewport(),
); );
}); });
} }

View File

@@ -21,8 +21,8 @@ fn main() -> Result<(), eframe::Error> {
egui::CentralPanel::default().show(ctx, |ui| { egui::CentralPanel::default().show(ctx, |ui| {
ui.label(format!( ui.label(format!(
"Current window: {}, Current rendering window: {}", "Current window: {}, Current rendering window: {}",
ctx.current_window(), ctx.current_viewport(),
ctx.current_rendering_window() ctx.current_rendering_viewport()
)); ));
ui.heading("My egui Application"); ui.heading("My egui Application");
ui.horizontal(|ui| { ui.horizontal(|ui| {
@@ -42,8 +42,8 @@ fn main() -> Result<(), eframe::Error> {
ui.checkbox(&mut window1_embedded, "Should embedd?"); ui.checkbox(&mut window1_embedded, "Should embedd?");
ui.label(format!( ui.label(format!(
"Current window: {}, Current rendering window: {}", "Current window: {}, Current rendering window: {}",
ctx.current_window(), ctx.current_viewport(),
ctx.current_rendering_window() ctx.current_rendering_viewport()
)); ));
}); });
}); });
@@ -54,8 +54,8 @@ fn main() -> Result<(), eframe::Error> {
ui.checkbox(&mut window2_embedded, "Should embedd?"); ui.checkbox(&mut window2_embedded, "Should embedd?");
ui.label(format!( ui.label(format!(
"Current window: {}, Current rendering window: {}", "Current window: {}, Current rendering window: {}",
ctx.current_window(), ctx.current_viewport(),
ctx.current_rendering_window() ctx.current_rendering_viewport()
)); ));
}); });
}); });

View File

@@ -128,6 +128,9 @@ impl eframe::App for Application {
}); });
}); });
ctx.request_repaint_after(Self::repaint_max_timeout(), ctx.current_rendering_window()); ctx.request_repaint_after(
Self::repaint_max_timeout(),
ctx.current_rendering_viewport(),
);
} }
} }