Skip to content

Commit

Permalink
Add ViewportCommand::RequestCut, ViewportCommand::RequestCopy and…
Browse files Browse the repository at this point in the history
… `ViewportCommand::RequestPaste` to allow application to request these events
  • Loading branch information
bu5hm4nn committed Feb 12, 2024
1 parent d22ee81 commit a743f6c
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 37 deletions.
58 changes: 40 additions & 18 deletions crates/eframe/src/native/glow_integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

use std::{cell::RefCell, rc::Rc, sync::Arc, time::Instant};

use egui_winit::ActionRequested;
use glutin::{
config::GlConfig,
context::NotCurrentGlContext,
Expand All @@ -22,9 +23,9 @@ use winit::{
};

use egui::{
epaint::ahash::HashMap, DeferredViewportUiCallback, ImmediateViewport, NumExt as _,
ViewportBuilder, ViewportClass, ViewportId, ViewportIdMap, ViewportIdPair, ViewportIdSet,
ViewportInfo, ViewportOutput,
ahash::{HashMap, HashSet, HashSetExt},
DeferredViewportUiCallback, ImmediateViewport, NumExt as _, ViewportBuilder, ViewportClass,
ViewportId, ViewportIdMap, ViewportIdPair, ViewportIdSet, ViewportInfo, ViewportOutput,
};
#[cfg(feature = "accesskit")]
use egui_winit::accesskit_winit;
Expand Down Expand Up @@ -104,7 +105,7 @@ struct Viewport {
class: ViewportClass,
builder: ViewportBuilder,
info: ViewportInfo,
screenshot_requested: bool,
actions_requested: HashSet<egui_winit::ActionRequested>,

/// The user-callback that shows the ui.
/// None for immediate viewports.
Expand Down Expand Up @@ -636,17 +637,38 @@ impl GlowWinitRunning {
);

{
let screenshot_requested = std::mem::take(&mut viewport.screenshot_requested);
if screenshot_requested {
let screenshot = painter.read_screen_rgba(screen_size_in_pixels);
egui_winit
.egui_input_mut()
.events
.push(egui::Event::Screenshot {
viewport_id,
image: screenshot.into(),
});
for action in viewport.actions_requested.drain() {
match action {
ActionRequested::Screenshot => {
let screenshot = painter.read_screen_rgba(screen_size_in_pixels);
egui_winit
.egui_input_mut()
.events
.push(egui::Event::Screenshot {
viewport_id,
image: screenshot.into(),
});
}
ActionRequested::Cut => {
egui_winit.egui_input_mut().events.push(egui::Event::Cut);
}
ActionRequested::Copy => {
egui_winit.egui_input_mut().events.push(egui::Event::Copy);
}
ActionRequested::Paste => {
if let Some(contents) = egui_winit.clipboard_text() {
let contents = contents.replace("\r\n", "\n");
if !contents.is_empty() {
egui_winit
.egui_input_mut()
.events
.push(egui::Event::Paste(contents));
}
}
}
}
}

integration.post_rendering(&window);
}

Expand Down Expand Up @@ -959,7 +981,7 @@ impl GlutinWindowContext {
class: ViewportClass::Root,
builder: viewport_builder,
info,
screenshot_requested: false,
actions_requested: HashSetExt::new(),
viewport_ui_cb: None,
gl_surface: None,
window: window.map(Arc::new),
Expand Down Expand Up @@ -1211,7 +1233,7 @@ impl GlutinWindowContext {
commands,
window,
is_viewport_focused,
&mut viewport.screenshot_requested,
&mut viewport.actions_requested,
);
}
}
Expand Down Expand Up @@ -1256,7 +1278,7 @@ fn initialize_or_update_viewport<'vp>(
class,
builder,
info: Default::default(),
screenshot_requested: false,
actions_requested: HashSet::new(),
viewport_ui_cb,
window: None,
egui_winit: None,
Expand Down Expand Up @@ -1290,7 +1312,7 @@ fn initialize_or_update_viewport<'vp>(
delta_commands,
window,
is_viewport_focused,
&mut viewport.screenshot_requested,
&mut viewport.actions_requested,
);
}

Expand Down
47 changes: 38 additions & 9 deletions crates/eframe/src/native/wgpu_integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use std::{cell::RefCell, rc::Rc, sync::Arc, time::Instant};

use egui_winit::ActionRequested;
use parking_lot::Mutex;
use raw_window_handle::{HasDisplayHandle as _, HasWindowHandle as _};
use winit::{
Expand All @@ -15,9 +16,9 @@ use winit::{
};

use egui::{
ahash::HashMap, DeferredViewportUiCallback, FullOutput, ImmediateViewport, ViewportBuilder,
ViewportClass, ViewportId, ViewportIdMap, ViewportIdPair, ViewportIdSet, ViewportInfo,
ViewportOutput,
ahash::{HashMap, HashSet, HashSetExt},
DeferredViewportUiCallback, FullOutput, ImmediateViewport, ViewportBuilder, ViewportClass,
ViewportId, ViewportIdMap, ViewportIdPair, ViewportIdSet, ViewportInfo, ViewportOutput,
};
#[cfg(feature = "accesskit")]
use egui_winit::accesskit_winit;
Expand Down Expand Up @@ -77,7 +78,7 @@ pub struct Viewport {
class: ViewportClass,
builder: ViewportBuilder,
info: ViewportInfo,
screenshot_requested: bool,
actions_requested: HashSet<ActionRequested>,

/// `None` for sync viewports.
viewport_ui_cb: Option<Arc<DeferredViewportUiCallback>>,
Expand Down Expand Up @@ -286,7 +287,7 @@ impl WgpuWinitApp {
maximized: Some(window.is_maximized()),
..Default::default()
},
screenshot_requested: false,
actions_requested: HashSetExt::new(),
viewport_ui_cb: None,
window: Some(window),
egui_winit: Some(egui_winit),
Expand Down Expand Up @@ -643,7 +644,10 @@ impl WgpuWinitRunning {

let clipped_primitives = egui_ctx.tessellate(shapes, pixels_per_point);

let screenshot_requested = std::mem::take(&mut viewport.screenshot_requested);
let screenshot_requested = viewport
.actions_requested
.take(&ActionRequested::Screenshot)
.is_some();
let (vsync_secs, screenshot) = painter.paint_and_update_textures(
viewport_id,
pixels_per_point,
Expand All @@ -662,6 +666,31 @@ impl WgpuWinitRunning {
});
}

for action in viewport.actions_requested.drain() {
match action {
ActionRequested::Screenshot => {
// already handled above
}
ActionRequested::Cut => {
egui_winit.egui_input_mut().events.push(egui::Event::Cut);
}
ActionRequested::Copy => {
egui_winit.egui_input_mut().events.push(egui::Event::Copy);
}
ActionRequested::Paste => {
if let Some(contents) = egui_winit.clipboard_text() {
let contents = contents.replace("\r\n", "\n");
if !contents.is_empty() {
egui_winit
.egui_input_mut()
.events
.push(egui::Event::Paste(contents));
}
}
}
}
}

integration.post_rendering(window);

let active_viewports_ids: ViewportIdSet = viewport_output.keys().copied().collect();
Expand Down Expand Up @@ -1027,7 +1056,7 @@ fn handle_viewport_output(
commands,
window,
is_viewport_focused,
&mut viewport.screenshot_requested,
&mut viewport.actions_requested,
);
}
}
Expand Down Expand Up @@ -1060,7 +1089,7 @@ fn initialize_or_update_viewport<'vp>(
class,
builder,
info: Default::default(),
screenshot_requested: false,
actions_requested: HashSet::new(),
viewport_ui_cb,
window: None,
egui_winit: None,
Expand Down Expand Up @@ -1093,7 +1122,7 @@ fn initialize_or_update_viewport<'vp>(
delta_commands,
window,
is_viewport_focused,
&mut viewport.screenshot_requested,
&mut viewport.actions_requested,
);
}

Expand Down
28 changes: 23 additions & 5 deletions crates/egui-winit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ pub use accesskit_winit;
pub use egui;
#[cfg(feature = "accesskit")]
use egui::accesskit;
use egui::{Pos2, Rect, Vec2, ViewportBuilder, ViewportCommand, ViewportId, ViewportInfo};
use egui::{
ahash::HashSet, Pos2, Rect, Vec2, ViewportBuilder, ViewportCommand, ViewportId, ViewportInfo,
};
pub use winit;

pub mod clipboard;
Expand Down Expand Up @@ -1244,14 +1246,21 @@ fn translate_cursor(cursor_icon: egui::CursorIcon) -> Option<winit::window::Curs

// Helpers for egui Viewports
// ---------------------------------------------------------------------------
#[derive(PartialEq, Eq, Hash, Debug)]
pub enum ActionRequested {
Screenshot,
Cut,
Copy,
Paste,
}

pub fn process_viewport_commands(
egui_ctx: &egui::Context,
info: &mut ViewportInfo,
commands: impl IntoIterator<Item = ViewportCommand>,
window: &Window,
is_viewport_focused: bool,
screenshot_requested: &mut bool,
actions_requested: &mut HashSet<ActionRequested>,
) {
for command in commands {
process_viewport_command(
Expand All @@ -1260,7 +1269,7 @@ pub fn process_viewport_commands(
command,
info,
is_viewport_focused,
screenshot_requested,
actions_requested,
);
}
}
Expand All @@ -1271,7 +1280,7 @@ fn process_viewport_command(
command: ViewportCommand,
info: &mut ViewportInfo,
is_viewport_focused: bool,
screenshot_requested: &mut bool,
actions_requested: &mut HashSet<ActionRequested>,
) {
crate::profile_function!();

Expand Down Expand Up @@ -1452,7 +1461,16 @@ fn process_viewport_command(
}
}
ViewportCommand::Screenshot => {
*screenshot_requested = true;
actions_requested.insert(ActionRequested::Screenshot);
}
ViewportCommand::RequestCut => {
actions_requested.insert(ActionRequested::Cut);
}
ViewportCommand::RequestCopy => {
actions_requested.insert(ActionRequested::Copy);
}
ViewportCommand::RequestPaste => {
actions_requested.insert(ActionRequested::Paste);
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions crates/egui/src/viewport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,15 @@ pub enum ViewportCommand {
///
/// The results are returned in `crate::Event::Screenshot`.
Screenshot,

/// Request a cut from the clipboard
RequestCut,

/// Request a copy from the clipboard
RequestCopy,

/// Request a paste from the clipboard
RequestPaste,
}

impl ViewportCommand {
Expand Down
13 changes: 8 additions & 5 deletions crates/egui_glow/src/winit.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
pub use egui_winit;
pub use egui_winit::EventResponse;

use egui::{ViewportId, ViewportOutput};
use egui::{
ahash::{HashSet, HashSetExt},
ViewportId, ViewportOutput,
};
use egui_winit::winit;

use crate::shader_version::ShaderVersion;
Expand Down Expand Up @@ -79,17 +82,17 @@ impl EguiGlow {
log::warn!("Multiple viewports not yet supported by EguiGlow");
}
for (_, ViewportOutput { commands, .. }) in viewport_output {
let mut screenshot_requested = false;
let mut actions_requested: HashSet<egui_winit::ActionRequested> = HashSetExt::new();
egui_winit::process_viewport_commands(
&self.egui_ctx,
&mut self.viewport_info,
commands,
window,
true,
&mut screenshot_requested,
&mut actions_requested,
);
if screenshot_requested {
log::warn!("Screenshot not yet supported by EguiGlow");
for action in actions_requested {
log::warn!("{:?} not yet supported by EguiGlow", action);
}
}

Expand Down

0 comments on commit a743f6c

Please sign in to comment.