diff --git a/crates/egui/src/context.rs b/crates/egui/src/context.rs index f4e520cea..f78101ff2 100644 --- a/crates/egui/src/context.rs +++ b/crates/egui/src/context.rs @@ -551,10 +551,6 @@ impl Context { ) -> R { self.write(move |ctx| writer(&mut ctx.memory.options.tessellation_options)) } -} - -impl Context { - // --------------------------------------------------------------------- /// If the given [`Id`] has been used previously the same frame at at different position, /// then an error will be printed on screen. @@ -919,6 +915,31 @@ impl Context { self.output_mut(|o| o.cursor_icon = cursor_icon); } + /// Open an URL in a browser. + /// + /// Equivalent to: + /// ``` + /// # let ctx = egui::Context::default(); + /// # let open_url = egui::OpenUrl::same_tab("http://www.example.com"); + /// ctx.output_mut(|o| o.open_url = Some(open_url)); + /// ``` + pub fn open_url(&self, open_url: crate::OpenUrl) { + self.output_mut(|o| o.open_url = Some(open_url)); + } + + /// Copy the given text to the system clipboard. + /// + /// Empty strings are ignored. + /// + /// Equivalent to: + /// ``` + /// # let ctx = egui::Context::default(); + /// ctx.output_mut(|o| o.copied_text = "Copy this".to_owned()); + /// ``` + pub fn copy_text(&self, text: String) { + self.output_mut(|o| o.copied_text = text); + } + /// Format the given shortcut in a human-readable way (e.g. `Ctrl+Shift+X`). /// /// Can be used to get the text for [`Button::shortcut_text`]. diff --git a/crates/egui/src/data/output.rs b/crates/egui/src/data/output.rs index 156a34928..ddb9b2864 100644 --- a/crates/egui/src/data/output.rs +++ b/crates/egui/src/data/output.rs @@ -92,7 +92,9 @@ pub struct PlatformOutput { impl PlatformOutput { /// Open the given url in a web browser. + /// /// If egui is running in a browser, the same tab will be reused. + #[deprecated = "Use Context::open_url instead"] pub fn open_url(&mut self, url: impl ToString) { self.open_url = Some(OpenUrl::same_tab(url)); } @@ -156,6 +158,8 @@ impl PlatformOutput { } /// What URL to open, and how. +/// +/// Use with [`crate::Context::open_url`]. #[derive(Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub struct OpenUrl { diff --git a/crates/egui/src/lib.rs b/crates/egui/src/lib.rs index 68d798075..15020c333 100644 --- a/crates/egui/src/lib.rs +++ b/crates/egui/src/lib.rs @@ -389,7 +389,9 @@ pub use { context::{Context, RequestRepaintInfo}, data::{ input::*, - output::{self, CursorIcon, FullOutput, PlatformOutput, UserAttentionType, WidgetInfo}, + output::{ + self, CursorIcon, FullOutput, OpenUrl, PlatformOutput, UserAttentionType, WidgetInfo, + }, }, grid::Grid, id::{Id, IdMap}, diff --git a/crates/egui/src/widgets/color_picker.rs b/crates/egui/src/widgets/color_picker.rs index fcb701f47..aed954793 100644 --- a/crates/egui/src/widgets/color_picker.rs +++ b/crates/egui/src/widgets/color_picker.rs @@ -234,9 +234,9 @@ fn color_text_ui(ui: &mut Ui, color: impl Into, alpha: Alpha) { if ui.button("📋").on_hover_text("Click to copy").clicked() { if alpha == Alpha::Opaque { - ui.output_mut(|o| o.copied_text = format!("{r}, {g}, {b}")); + ui.ctx().copy_text(format!("{r}, {g}, {b}")); } else { - ui.output_mut(|o| o.copied_text = format!("{r}, {g}, {b}, {a}")); + ui.ctx().copy_text(format!("{r}, {g}, {b}, {a}")); } } diff --git a/crates/egui/src/widgets/hyperlink.rs b/crates/egui/src/widgets/hyperlink.rs index 0ef0ee488..7017d7463 100644 --- a/crates/egui/src/widgets/hyperlink.rs +++ b/crates/egui/src/widgets/hyperlink.rs @@ -118,21 +118,18 @@ impl Widget for Hyperlink { let Self { url, text, new_tab } = self; let response = ui.add(Link::new(text)); + if response.clicked() { let modifiers = ui.ctx().input(|i| i.modifiers); - ui.ctx().output_mut(|o| { - o.open_url = Some(crate::output::OpenUrl { - url: url.clone(), - new_tab: new_tab || modifiers.any(), - }); + ui.ctx().open_url(crate::OpenUrl { + url: url.clone(), + new_tab: new_tab || modifiers.any(), }); } if response.middle_clicked() { - ui.ctx().output_mut(|o| { - o.open_url = Some(crate::output::OpenUrl { - url: url.clone(), - new_tab: true, - }); + ui.ctx().open_url(crate::OpenUrl { + url: url.clone(), + new_tab: true, }); } response.on_hover_text(url) diff --git a/crates/egui/src/widgets/text_edit/builder.rs b/crates/egui/src/widgets/text_edit/builder.rs index e19698977..f07beedea 100644 --- a/crates/egui/src/widgets/text_edit/builder.rs +++ b/crates/egui/src/widgets/text_edit/builder.rs @@ -900,7 +900,7 @@ fn events( let copy_if_not_password = |ui: &Ui, text: String| { if !password { - ui.ctx().output_mut(|o| o.copied_text = text); + ui.ctx().copy_text(text); } }; diff --git a/crates/egui_demo_app/src/apps/http_app.rs b/crates/egui_demo_app/src/apps/http_app.rs index ef5c2987a..90be24dd2 100644 --- a/crates/egui_demo_app/src/apps/http_app.rs +++ b/crates/egui_demo_app/src/apps/http_app.rs @@ -195,7 +195,7 @@ fn ui_resource(ui: &mut egui::Ui, resource: &Resource) { if let Some(text) = &text { let tooltip = "Click to copy the response body"; if ui.button("📋").on_hover_text(tooltip).clicked() { - ui.output_mut(|o| o.copied_text = text.clone()); + ui.ctx().copy_text(text.clone()); } ui.separator(); } diff --git a/crates/egui_demo_app/src/wrap_app.rs b/crates/egui_demo_app/src/wrap_app.rs index d2a0e9102..619e70ad8 100644 --- a/crates/egui_demo_app/src/wrap_app.rs +++ b/crates/egui_demo_app/src/wrap_app.rs @@ -396,7 +396,8 @@ impl WrapApp { { selected_anchor = anchor; if frame.is_web() { - ui.output_mut(|o| o.open_url(format!("#{anchor}"))); + ui.ctx() + .open_url(egui::OpenUrl::same_tab(format!("#{anchor}"))); } } } @@ -408,7 +409,7 @@ impl WrapApp { if clock_button(ui, crate::seconds_since_midnight()).clicked() { self.state.selected_anchor = Anchor::Clock; if frame.is_web() { - ui.output_mut(|o| o.open_url("#clock")); + ui.ctx().open_url(egui::OpenUrl::same_tab("#clock")); } } } diff --git a/crates/egui_demo_lib/src/demo/font_book.rs b/crates/egui_demo_lib/src/demo/font_book.rs index 2b4eebae0..4dda2d87b 100644 --- a/crates/egui_demo_lib/src/demo/font_book.rs +++ b/crates/egui_demo_lib/src/demo/font_book.rs @@ -93,7 +93,7 @@ impl super::View for FontBook { }; if ui.add(button).on_hover_ui(tooltip_ui).clicked() { - ui.output_mut(|o| o.copied_text = chr.to_string()); + ui.ctx().copy_text(chr.to_string()); } } } diff --git a/examples/puffin_profiler/src/main.rs b/examples/puffin_profiler/src/main.rs index ab0007156..18b7f6e16 100644 --- a/examples/puffin_profiler/src/main.rs +++ b/examples/puffin_profiler/src/main.rs @@ -28,7 +28,7 @@ impl eframe::App for MyApp { ui.horizontal(|ui| { ui.monospace(cmd); if ui.small_button("📋").clicked() { - ui.output_mut(|o| o.copied_text = cmd.into()); + ui.ctx().copy_text(cmd.into()); } });