1
0
mirror of https://github.com/emilk/egui.git synced 2026-09-03 07:10:04 -04:00

* Implement changes_between_builders

* Now process_viewport_commands was renamed to process_viewports_commands
* Added process_viewport_commands
* eframe glutin backend uses changes_between_builders
This commit is contained in:
Konkitoman
2023-08-11 17:39:14 +03:00
parent 88a7071e74
commit d33075388c
3 changed files with 300 additions and 133 deletions

View File

@@ -414,7 +414,10 @@ mod glow_integration {
use egui::{
epaint::ahash::HashMap, mutex::RwLock, NumExt as _, ViewportBuilder, ViewportRender,
};
use egui_winit::{create_winit_window_builder, EventResponse};
use egui_winit::{
changes_between_builders, create_winit_window_builder, process_viewport_commands,
process_viewports_commands, EventResponse,
};
use glutin::{
display::GetGlDisplay,
prelude::{GlDisplay, NotCurrentGlContextSurfaceAccessor, PossiblyCurrentGlContext},
@@ -1060,7 +1063,7 @@ mod glow_integration {
}
}
Self::process_viewport_builders(&glutin, output.viewports);
egui_winit::process_viewport_commands(
egui_winit::process_viewports_commands(
output.viewport_commands,
*focused.read(),
|id| {
@@ -1103,13 +1106,17 @@ mod glow_integration {
viewports.retain_mut(|(id, _, builder, render)| {
if let Some(w) = glutin_ctx.read().windows.get(id) {
let mut w = w.write();
if w.builder != *builder {
let (commands, recreate) = changes_between_builders(builder, &mut w.builder);
if recreate {
w.window = None;
w.gl_surface = None;
w.render = render.clone();
w.builder = builder.clone();
w.parent_id = *id;
}
if let Some(w) = w.window.clone() {
process_viewport_commands(commands, *id, None, w);
}
active_viewports_ids.push(*id);
false
} else {
@@ -1438,7 +1445,7 @@ mod glow_integration {
Self::process_viewport_builders(&glutin_ctx, viewports);
egui_winit::process_viewport_commands(
egui_winit::process_viewports_commands(
viewport_commands,
*self.is_focused.read(),
|viewport_id| {
@@ -2030,7 +2037,7 @@ mod wgpu_integration {
active_viewports_ids.push(id);
}
egui_winit::process_viewport_commands(
egui_winit::process_viewports_commands(
output.viewport_commands,
*focused.read(),
|id| _windows.read().get(&id).and_then(|w| w.0.clone()),
@@ -2223,7 +2230,7 @@ mod wgpu_integration {
active_viewports_ids.push(id);
}
egui_winit::process_viewport_commands(
egui_winit::process_viewports_commands(
viewport_commands,
*self.is_focused.read(),
|viewport_id| windows.read().get(&viewport_id).and_then(|w| w.0.clone()),

View File

@@ -908,16 +908,16 @@ fn translate_cursor(cursor_icon: egui::CursorIcon) -> Option<winit::window::Curs
// ---------------------------------------------------------------------------
pub fn process_viewport_commands(
commands: Vec<(ViewportId, ViewportCommand)>,
commands: Vec<ViewportCommand>,
viewport_id: ViewportId,
focused: Option<ViewportId>,
get_window: impl Fn(ViewportId) -> Option<Arc<RwLock<winit::window::Window>>>,
window: Arc<RwLock<winit::window::Window>>,
) {
use winit::dpi::PhysicalSize;
use winit::window::ResizeDirection;
for (viewport_id, command) in commands {
if let Some(window) = get_window(viewport_id) {
let win = window.read();
for command in commands {
match command {
egui::ViewportCommand::Drag => {
// if this is not checked on x11 the input will be permanently taken until the app is killed!
@@ -995,24 +995,20 @@ pub fn process_viewport_commands(
.expect("Invalid ICON data!")
}))
}
ViewportCommand::IMEPossition(x, y) => {
win.set_ime_position(LogicalPosition::new(x, y))
}
ViewportCommand::IMEPossition(x, y) => win.set_ime_position(LogicalPosition::new(x, y)),
ViewportCommand::IMEAllowed(v) => win.set_ime_allowed(v),
ViewportCommand::IMEPurpose(o) => win.set_ime_purpose(match o {
1 => winit::window::ImePurpose::Password,
2 => winit::window::ImePurpose::Terminal,
_ => winit::window::ImePurpose::Normal,
}),
ViewportCommand::RequestUserAttention(o) => {
win.request_user_attention(o.map(|o| {
ViewportCommand::RequestUserAttention(o) => win.request_user_attention(o.map(|o| {
if o == 1 {
winit::window::UserAttentionType::Critical
} else {
winit::window::UserAttentionType::Informational
}
}))
}
})),
ViewportCommand::SetTheme(o) => win.set_theme(o.map(|o| {
if o == 1 {
winit::window::Theme::Dark
@@ -1038,6 +1034,17 @@ pub fn process_viewport_commands(
}
}
}
pub fn process_viewports_commands(
commands: Vec<(ViewportId, ViewportCommand)>,
focused: Option<ViewportId>,
get_window: impl Fn(ViewportId) -> Option<Arc<RwLock<winit::window::Window>>>,
) {
for (viewport_id, command) in commands {
if let Some(window) = get_window(viewport_id) {
process_viewport_commands(vec![command], viewport_id, focused, window)
}
}
}
pub fn create_winit_window_builder(builder: &ViewportBuilder) -> winit::window::WindowBuilder {
@@ -1094,11 +1101,156 @@ pub fn create_winit_window_builder(builder: &ViewportBuilder) -> winit::window::
window_builder
}
pub fn changes_betwen_builders(
now: &ViewportBuilder,
last: &ViewportBuilder,
) -> Vec<ViewportCommand> {
vec![]
pub fn changes_between_builders(
new: &ViewportBuilder,
last: &mut ViewportBuilder,
) -> (Vec<ViewportCommand>, bool) {
let mut commands = Vec::new();
// Title is not compared because if has a new title will create a new window
// The title of a avalibile window can only be changed with ViewportCommand::Title
if let Some(position) = new.position {
if Some(position) != last.position {
last.position = Some(position);
if let Some(position) = position {
commands.push(ViewportCommand::OuterPosition(position.0, position.1));
}
}
}
if let Some(inner_size) = new.inner_size {
if Some(inner_size) != last.inner_size {
last.inner_size = Some(inner_size);
if let Some(inner_size) = inner_size {
commands.push(ViewportCommand::InnerSize(inner_size.0, inner_size.1));
}
}
}
if let Some(min_inner_size) = new.min_inner_size {
if Some(min_inner_size) != last.min_inner_size {
last.min_inner_size = Some(min_inner_size);
commands.push(ViewportCommand::MinInnerSize(min_inner_size));
}
}
if let Some(max_inner_size) = new.max_inner_size {
if Some(max_inner_size) != last.max_inner_size {
last.max_inner_size = Some(max_inner_size);
commands.push(ViewportCommand::MaxInnerSize(max_inner_size));
}
}
if let Some(fullscreen) = new.fullscreen {
if Some(fullscreen) != last.fullscreen {
last.fullscreen = Some(fullscreen);
commands.push(ViewportCommand::Fullscreen(fullscreen));
}
}
if let Some(minimized) = new.minimized {
if Some(minimized) != last.minimized {
last.minimized = Some(minimized);
commands.push(ViewportCommand::Minimized(minimized));
}
}
if let Some(maximized) = new.maximized {
if Some(maximized) != last.maximized {
last.maximized = Some(maximized);
commands.push(ViewportCommand::Maximized(maximized));
}
}
if let Some(resizable) = new.resizable {
if Some(resizable) != last.resizable {
last.resizable = Some(resizable);
commands.push(ViewportCommand::Resizable(resizable));
}
}
if let Some(transparent) = new.transparent {
if Some(transparent) != last.transparent {
last.transparent = Some(transparent);
commands.push(ViewportCommand::Transparent(transparent));
}
}
if let Some(decorations) = new.decorations {
if Some(decorations) != last.decorations {
last.decorations = Some(decorations);
commands.push(ViewportCommand::Decorations(decorations));
}
}
if let Some(icon) = new.icon.clone() {
let eq = match &icon {
Some(icon) => {
if let Some(last_icon) = &last.icon {
matches!(last_icon, Some(last_icon) if Arc::ptr_eq(icon, last_icon))
} else {
false
}
}
None => last.icon == Some(None),
};
if !eq {
commands.push(ViewportCommand::WindowIcon(
icon.as_ref().map(|i| (i.2.clone(), i.0, i.1)),
));
last.icon = Some(icon);
}
}
if let Some(visible) = new.visible {
if Some(visible) != last.active {
last.visible = Some(visible);
commands.push(ViewportCommand::Visible(visible));
}
}
// TODO: Implement compare for windows buttons
let mut recreate_window = false;
if let Some(active) = new.active {
if Some(active) != last.active {
last.active = Some(active);
recreate_window = true;
}
}
if let Some(close_button) = new.close_button {
if Some(close_button) != last.close_button {
last.close_button = Some(close_button);
recreate_window = true;
}
}
if let Some(title_hidden) = new.title_hidden {
if Some(title_hidden) != last.title_hidden {
last.title_hidden = Some(title_hidden);
recreate_window = true;
}
}
if let Some(titlebar_transparent) = new.titlebar_transparent {
if Some(titlebar_transparent) != last.titlebar_transparent {
last.titlebar_transparent = Some(titlebar_transparent);
recreate_window = true;
}
}
if let Some(value) = new.fullsize_content_view {
if Some(value) != last.fullsize_content_view {
last.fullsize_content_view = Some(value);
recreate_window = true;
}
}
(commands, recreate_window)
}
// ---------------------------------------------------------------------------

View File

@@ -32,6 +32,7 @@ pub struct ViewportBuilder {
pub inner_size: Option<Option<(u32, u32)>>,
pub fullscreen: Option<bool>,
pub maximized: Option<bool>,
pub minimized: Option<bool>,
pub resizable: Option<bool>,
pub transparent: Option<bool>,
pub decorations: Option<bool>,
@@ -70,6 +71,7 @@ impl Default for ViewportBuilder {
max_inner_size: None,
drag_and_drop: None,
close_button: None,
minimized: Some(false),
}
}
}
@@ -96,6 +98,7 @@ impl ViewportBuilder {
max_inner_size: None,
drag_and_drop: None,
close_button: None,
minimized: None,
}
}
pub fn with_title(mut self, title: impl Into<String>) -> Self {
@@ -118,6 +121,11 @@ impl ViewportBuilder {
self
}
pub fn with_mimimized(mut self, minimized: bool) -> Self {
self.minimized = Some(minimized);
self
}
pub fn with_resizable(mut self, resizable: bool) -> Self {
self.resizable = Some(resizable);
self