Replace Context::begin_frame/end_frame
with fn run
taking a closure (#872)
* Replace Context begin_frame/end_frame with `fn run` taking a closure * Create `egui::__run_test_ui` to replace `Ui::__test` * Add helper `egui::__run_test_ctx` for doctests
This commit is contained in:
parent
e54106e950
commit
49e43885ff
32 changed files with 294 additions and 199 deletions
|
@ -15,6 +15,8 @@ NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui_w
|
|||
### Changed 🔧
|
||||
* Unifiy the four `Memory` data buckets (`data`, `data_temp`, `id_data` and `id_data_temp`) into a single `Memory::data`, with a new interface ([#836](https://github.com/emilk/egui/pull/836)).
|
||||
* `ui.add(Button::new("…").text_color(…))` is now `ui.button(RichText::new("…").color(…))` (same for `Label` )([#855](https://github.com/emilk/egui/pull/855)).
|
||||
* Replace `CtxRef::begin_frame` and `end_frame` with `CtxRef::run` ([#872](https://github.com/emilk/egui/pull/872)).
|
||||
* Replace `Ui::__test` with `egui::__run_test_ui` ([#872](https://github.com/emilk/egui/pull/872)).
|
||||
|
||||
### Contributors 🙏
|
||||
* [mankinskin](https://github.com/mankinskin) ([#543](https://github.com/emilk/egui/pull/543))
|
||||
|
|
|
@ -198,14 +198,14 @@ Missing an integration for the thing you're working on? Create one, it is easy!
|
|||
You need to collect [`egui::RawInput`](https://docs.rs/egui/latest/egui/struct.RawInput.html), paint [`egui::ClippedMesh`](https://docs.rs/epaint/):es and handle [`egui::Output`](https://docs.rs/egui/latest/egui/struct.Output.html). The basic structure is this:
|
||||
|
||||
``` rust
|
||||
let mut egui_ctx = egui::Context::new();
|
||||
let mut egui_ctx = egui::CtxRef::default();
|
||||
|
||||
// Game loop:
|
||||
loop {
|
||||
let raw_input: egui::RawInput = my_integration.gather_input();
|
||||
egui_ctx.begin_frame(raw_input);
|
||||
my_app.ui(&mut egui_ctx); // add panels, windows and widgets to `egui_ctx` here
|
||||
let (output, shapes) = egui_ctx.end_frame();
|
||||
let (output, shapes) = egui_ctx.run(raw_input, |egui_ctx| {
|
||||
my_app.ui(egui_ctx); // add panels, windows and widgets to `egui_ctx` here
|
||||
});
|
||||
let clipped_meshes = egui_ctx.tessellate(shapes); // create triangles to paint
|
||||
my_integration.paint(clipped_meshes);
|
||||
my_integration.set_cursor_icon(output.cursor_icon);
|
||||
|
|
|
@ -282,8 +282,6 @@ impl EpiIntegration {
|
|||
|
||||
let raw_input = self.egui_winit.take_egui_input(window);
|
||||
|
||||
self.egui_ctx.begin_frame(raw_input);
|
||||
|
||||
let mut app_output = epi::backend::AppOutput::default();
|
||||
let mut frame = epi::backend::FrameBuilder {
|
||||
info: integration_info(self.integration_name, window, self.latest_frame_time),
|
||||
|
@ -293,9 +291,11 @@ impl EpiIntegration {
|
|||
}
|
||||
.build();
|
||||
|
||||
self.app.update(&self.egui_ctx, &mut frame);
|
||||
let app = &mut self.app; // TODO: remove when we update MSVR to 1.56
|
||||
let (egui_output, shapes) = self.egui_ctx.run(raw_input, |egui_ctx| {
|
||||
app.update(egui_ctx, &mut frame);
|
||||
});
|
||||
|
||||
let (egui_output, shapes) = self.egui_ctx.end_frame();
|
||||
let needs_repaint = egui_output.needs_repaint;
|
||||
self.egui_winit
|
||||
.handle_output(window, &self.egui_ctx, egui_output);
|
||||
|
|
|
@ -33,14 +33,13 @@ impl State {
|
|||
/// This forms the base of the [`Window`] container.
|
||||
///
|
||||
/// ```
|
||||
/// # let mut ctx = egui::CtxRef::default();
|
||||
/// # ctx.begin_frame(Default::default());
|
||||
/// # let ctx = &ctx;
|
||||
/// # egui::__run_test_ctx(|ctx| {
|
||||
/// egui::Area::new("my_area")
|
||||
/// .fixed_pos(egui::pos2(32.0, 32.0))
|
||||
/// .show(ctx, |ui| {
|
||||
/// ui.label("Floating text!");
|
||||
/// });
|
||||
/// # });
|
||||
#[must_use = "You should call .show()"]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct Area {
|
||||
|
|
|
@ -130,7 +130,7 @@ pub(crate) fn paint_icon(ui: &mut Ui, openness: f32, response: &Response) {
|
|||
///
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// egui::CollapsingHeader::new("Heading")
|
||||
/// .show(ui, |ui| {
|
||||
/// ui.label("Contents");
|
||||
|
@ -138,6 +138,7 @@ pub(crate) fn paint_icon(ui: &mut Ui, openness: f32, response: &Response) {
|
|||
///
|
||||
/// // Short version:
|
||||
/// ui.collapsing("Heading", |ui| { ui.label("Contents"); });
|
||||
/// # });
|
||||
/// ```
|
||||
#[must_use = "You should call .show()"]
|
||||
pub struct CollapsingHeader {
|
||||
|
@ -210,7 +211,7 @@ impl CollapsingHeader {
|
|||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// let mut selected = false;
|
||||
/// let response = egui::CollapsingHeader::new("Select and open me")
|
||||
/// .selectable(true)
|
||||
|
@ -219,6 +220,7 @@ impl CollapsingHeader {
|
|||
/// if response.header_response.clicked() {
|
||||
/// selected = true;
|
||||
/// }
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn selected(mut self, selected: bool) -> Self {
|
||||
self.selected = selected;
|
||||
|
@ -229,8 +231,9 @@ impl CollapsingHeader {
|
|||
///
|
||||
/// To show it behind all `CollapsingHeader` you can just use:
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// ui.visuals_mut().collapsing_header_frame = true;
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn show_background(mut self, show_background: bool) -> Self {
|
||||
self.show_background = show_background;
|
||||
|
|
|
@ -7,7 +7,7 @@ use epaint::Shape;
|
|||
/// # #[derive(Debug, PartialEq)]
|
||||
/// # enum Enum { First, Second, Third }
|
||||
/// # let mut selected = Enum::First;
|
||||
/// # let mut ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// egui::ComboBox::from_label("Select one!")
|
||||
/// .selected_text(format!("{:?}", selected))
|
||||
/// .show_ui(ui, |ui| {
|
||||
|
@ -16,6 +16,7 @@ use epaint::Shape;
|
|||
/// ui.selectable_value(&mut selected, Enum::Third, "Third");
|
||||
/// }
|
||||
/// );
|
||||
/// # });
|
||||
/// ```
|
||||
#[must_use = "You should call .show*"]
|
||||
pub struct ComboBox {
|
||||
|
@ -109,7 +110,7 @@ impl ComboBox {
|
|||
/// # #[derive(Debug, PartialEq)]
|
||||
/// # enum Enum { First, Second, Third }
|
||||
/// # let mut selected = Enum::First;
|
||||
/// # let mut ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// let alternatives = ["a", "b", "c", "d"];
|
||||
/// let mut selected = 2;
|
||||
/// egui::ComboBox::from_label("Select one!").show_index(
|
||||
|
@ -118,6 +119,7 @@ impl ComboBox {
|
|||
/// alternatives.len(),
|
||||
/// |i| alternatives[i].to_owned()
|
||||
/// );
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn show_index(
|
||||
self,
|
||||
|
|
|
@ -73,12 +73,11 @@ impl Side {
|
|||
/// See the [module level docs](crate::containers::panel) for more details.
|
||||
///
|
||||
/// ```
|
||||
/// # let mut ctx = egui::CtxRef::default();
|
||||
/// # ctx.begin_frame(Default::default());
|
||||
/// # let ctx = &ctx;
|
||||
/// # egui::__run_test_ctx(|ctx| {
|
||||
/// egui::SidePanel::left("my_left_panel").show(ctx, |ui| {
|
||||
/// ui.label("Hello World!");
|
||||
/// });
|
||||
/// # });
|
||||
/// ```
|
||||
///
|
||||
/// See also [`TopBottomPanel`].
|
||||
|
@ -350,12 +349,11 @@ impl TopBottomSide {
|
|||
/// See the [module level docs](crate::containers::panel) for more details.
|
||||
///
|
||||
/// ```
|
||||
/// # let mut ctx = egui::CtxRef::default();
|
||||
/// # ctx.begin_frame(Default::default());
|
||||
/// # let ctx = &ctx;
|
||||
/// # egui::__run_test_ctx(|ctx| {
|
||||
/// egui::TopBottomPanel::top("my_panel").show(ctx, |ui| {
|
||||
/// ui.label("Hello World!");
|
||||
/// });
|
||||
/// # });
|
||||
/// ```
|
||||
///
|
||||
/// See also [`SidePanel`].
|
||||
|
@ -605,12 +603,11 @@ impl TopBottomPanel {
|
|||
/// See the [module level docs](crate::containers::panel) for more details.
|
||||
///
|
||||
/// ```
|
||||
/// # let mut ctx = egui::CtxRef::default();
|
||||
/// # ctx.begin_frame(Default::default());
|
||||
/// # let ctx = &ctx;
|
||||
/// # egui::__run_test_ctx(|ctx| {
|
||||
/// egui::CentralPanel::default().show(ctx, |ui| {
|
||||
/// ui.label("Hello World!");
|
||||
/// });
|
||||
/// # });
|
||||
/// ```
|
||||
#[must_use = "You should call .show()"]
|
||||
#[derive(Default)]
|
||||
|
|
|
@ -58,12 +58,13 @@ impl MonoState {
|
|||
/// Returns `None` if the tooltip could not be placed.
|
||||
///
|
||||
/// ```
|
||||
/// # let mut ui = egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// if ui.ui_contains_pointer() {
|
||||
/// egui::show_tooltip(ui.ctx(), egui::Id::new("my_tooltip"), |ui| {
|
||||
/// ui.label("Helpful text");
|
||||
/// });
|
||||
/// }
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn show_tooltip<R>(ctx: &CtxRef, id: Id, add_contents: impl FnOnce(&mut Ui) -> R) -> Option<R> {
|
||||
show_tooltip_at_pointer(ctx, id, add_contents)
|
||||
|
@ -78,12 +79,13 @@ pub fn show_tooltip<R>(ctx: &CtxRef, id: Id, add_contents: impl FnOnce(&mut Ui)
|
|||
/// Returns `None` if the tooltip could not be placed.
|
||||
///
|
||||
/// ```
|
||||
/// # let mut ui = egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// if ui.ui_contains_pointer() {
|
||||
/// egui::show_tooltip_at_pointer(ui.ctx(), egui::Id::new("my_tooltip"), |ui| {
|
||||
/// ui.label("Helpful text");
|
||||
/// });
|
||||
/// }
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn show_tooltip_at_pointer<R>(
|
||||
ctx: &CtxRef,
|
||||
|
@ -221,10 +223,11 @@ fn show_tooltip_at_avoid_dyn<'c, R>(
|
|||
/// Returns `None` if the tooltip could not be placed.
|
||||
///
|
||||
/// ```
|
||||
/// # let mut ui = egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// if ui.ui_contains_pointer() {
|
||||
/// egui::show_tooltip_text(ui.ctx(), egui::Id::new("my_tooltip"), "Helpful text");
|
||||
/// }
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn show_tooltip_text(ctx: &CtxRef, id: Id, text: impl Into<WidgetText>) -> Option<()> {
|
||||
show_tooltip(ctx, id, |ui| {
|
||||
|
@ -264,7 +267,7 @@ fn show_tooltip_area_dyn<'c, R>(
|
|||
/// Returns `None` if the popup is not open.
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// let response = ui.button("Open popup");
|
||||
/// let popup_id = ui.make_persistent_id("my_unique_id");
|
||||
/// if response.clicked() {
|
||||
|
@ -275,6 +278,7 @@ fn show_tooltip_area_dyn<'c, R>(
|
|||
/// ui.label("Some more info, or things you can select:");
|
||||
/// ui.label("…");
|
||||
/// });
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn popup_below_widget<R>(
|
||||
ui: &Ui,
|
||||
|
|
|
@ -54,10 +54,12 @@ impl State {
|
|||
/// Add vertical and/or horizontal scrolling to a contained [`Ui`].
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// egui::ScrollArea::vertical().show(ui, |ui| {
|
||||
/// // Add a lot of widgets here.
|
||||
/// });
|
||||
/// # });
|
||||
/// ```
|
||||
#[derive(Clone, Debug)]
|
||||
#[must_use = "You should call .show()"]
|
||||
pub struct ScrollArea {
|
||||
|
@ -370,7 +372,7 @@ impl ScrollArea {
|
|||
/// Efficiently show only the visible part of a large number of rows.
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// let text_style = egui::TextStyle::Body;
|
||||
/// let row_height = ui.fonts()[text_style].row_height();
|
||||
/// // let row_height = ui.spacing().interact_size.y; // if you are adding buttons instead of labels.
|
||||
|
@ -381,6 +383,8 @@ impl ScrollArea {
|
|||
/// ui.label(text);
|
||||
/// }
|
||||
/// });
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn show_rows<R>(
|
||||
self,
|
||||
ui: &mut Ui,
|
||||
|
|
|
@ -15,12 +15,11 @@ use super::*;
|
|||
/// * if there should be a close button (none by default)
|
||||
///
|
||||
/// ```
|
||||
/// # let mut ctx = egui::CtxRef::default();
|
||||
/// # ctx.begin_frame(Default::default());
|
||||
/// # let ctx = &ctx;
|
||||
/// # egui::__run_test_ctx(|ctx| {
|
||||
/// egui::Window::new("My Window").show(ctx, |ui| {
|
||||
/// ui.label("Hello World!");
|
||||
/// });
|
||||
/// # });
|
||||
#[must_use = "You should call .show()"]
|
||||
pub struct Window<'open> {
|
||||
title: WidgetText,
|
||||
|
|
|
@ -36,16 +36,14 @@ use epaint::{stats::*, text::Fonts, *};
|
|||
/// // Game loop:
|
||||
/// loop {
|
||||
/// let raw_input = egui::RawInput::default();
|
||||
/// ctx.begin_frame(raw_input);
|
||||
///
|
||||
/// let (output, shapes) = ctx.run(raw_input, |ctx| {
|
||||
/// egui::CentralPanel::default().show(&ctx, |ui| {
|
||||
/// ui.label("Hello world!");
|
||||
/// if ui.button("Click me").clicked() {
|
||||
/// /* take some action here */
|
||||
/// // take some action here
|
||||
/// }
|
||||
/// });
|
||||
///
|
||||
/// let (output, shapes) = ctx.end_frame();
|
||||
/// });
|
||||
/// let clipped_meshes = ctx.tessellate(shapes); // create triangles to paint
|
||||
/// handle_output(output);
|
||||
/// paint(clipped_meshes);
|
||||
|
@ -93,13 +91,34 @@ impl Default for CtxRef {
|
|||
}
|
||||
|
||||
impl CtxRef {
|
||||
/// Run the ui code for one frame.
|
||||
///
|
||||
/// Put your widgets into a [`SidePanel`], [`TopBottomPanel`], [`CentralPanel`], [`Window`] or [`Area`].
|
||||
///
|
||||
/// This will modify the internal reference to point to a new generation of [`Context`].
|
||||
/// Any old clones of this [`CtxRef`] will refer to the old [`Context`], which will not get new input.
|
||||
///
|
||||
/// This is a convenience for calling [`Self::begin_frame`] and [`Context::end_frame`]
|
||||
#[must_use]
|
||||
pub fn run(
|
||||
&mut self,
|
||||
new_input: RawInput,
|
||||
run_ui: impl FnOnce(&CtxRef),
|
||||
) -> (Output, Vec<ClippedShape>) {
|
||||
self.begin_frame(new_input);
|
||||
run_ui(self);
|
||||
self.end_frame()
|
||||
}
|
||||
|
||||
/// Alternative to [`Self::run`].
|
||||
///
|
||||
/// Call at the start of every frame. Match with a call to [`Context::end_frame`].
|
||||
///
|
||||
/// This will modify the internal reference to point to a new generation of [`Context`].
|
||||
/// Any old clones of this [`CtxRef`] will refer to the old [`Context`], which will not get new input.
|
||||
///
|
||||
/// Put your widgets into a [`SidePanel`], [`TopBottomPanel`], [`CentralPanel`], [`Window`] or [`Area`].
|
||||
pub fn begin_frame(&mut self, new_input: RawInput) {
|
||||
fn begin_frame(&mut self, new_input: RawInput) {
|
||||
let mut self_: Context = (*self.0).clone();
|
||||
self_.begin_frame_mut(new_input);
|
||||
*self = Self(Arc::new(self_));
|
||||
|
@ -577,10 +596,23 @@ impl Context {
|
|||
self.input = input.begin_frame(new_raw_input);
|
||||
self.frame_state.lock().begin_frame(&self.input);
|
||||
|
||||
{
|
||||
// Load new fonts if required:
|
||||
self.update_fonts(self.input.pixels_per_point());
|
||||
|
||||
// Ensure we register the background area so panels and background ui can catch clicks:
|
||||
let screen_rect = self.input.screen_rect();
|
||||
self.memory().areas.set_state(
|
||||
LayerId::background(),
|
||||
containers::area::State {
|
||||
pos: screen_rect.min,
|
||||
size: screen_rect.size(),
|
||||
interactable: true,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// Load fonts unless already loaded.
|
||||
fn update_fonts(&mut self, pixels_per_point: f32) {
|
||||
let new_font_definitions = self.memory().new_font_definitions.take();
|
||||
let pixels_per_point = self.input.pixels_per_point();
|
||||
|
||||
let pixels_per_point_changed = match &self.fonts {
|
||||
None => true,
|
||||
|
@ -602,23 +634,11 @@ impl Context {
|
|||
}
|
||||
}
|
||||
|
||||
// Ensure we register the background area so panels and background ui can catch clicks:
|
||||
let screen_rect = self.input.screen_rect();
|
||||
self.memory().areas.set_state(
|
||||
LayerId::background(),
|
||||
containers::area::State {
|
||||
pos: screen_rect.min,
|
||||
size: screen_rect.size(),
|
||||
interactable: true,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// Call at the end of each frame.
|
||||
/// Returns what has happened this frame [`crate::Output`] as well as what you need to paint.
|
||||
/// You can transform the returned shapes into triangles with a call to [`Context::tessellate`].
|
||||
#[must_use]
|
||||
pub fn end_frame(&self) -> (Output, Vec<ClippedShape>) {
|
||||
fn end_frame(&self) -> (Output, Vec<ClippedShape>) {
|
||||
if self.input.wants_repaint() {
|
||||
self.request_repaint();
|
||||
}
|
||||
|
|
|
@ -238,7 +238,7 @@ impl GridLayout {
|
|||
/// [`Ui::horizontal`], [`Ui::vertical`] etc.
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// egui::Grid::new("some_unique_id").show(ui, |ui| {
|
||||
/// ui.label("First row, first column");
|
||||
/// ui.label("First row, second column");
|
||||
|
@ -253,6 +253,7 @@ impl GridLayout {
|
|||
/// ui.label("Third row, second column");
|
||||
/// ui.end_row();
|
||||
/// });
|
||||
/// # });
|
||||
/// ```
|
||||
#[must_use = "You should call .show()"]
|
||||
pub struct Grid {
|
||||
|
|
|
@ -237,7 +237,7 @@ impl InputState {
|
|||
///
|
||||
/// ```
|
||||
/// # use egui::emath::Rot2;
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// let mut zoom = 1.0; // no zoom
|
||||
/// let mut rotation = 0.0; // no rotation
|
||||
/// if let Some(multi_touch) = ui.input().multi_touch() {
|
||||
|
@ -245,6 +245,7 @@ impl InputState {
|
|||
/// rotation += multi_touch.rotation_delta;
|
||||
/// }
|
||||
/// let transform = zoom * Rot2::from_angle(rotation);
|
||||
/// # });
|
||||
/// ```
|
||||
///
|
||||
/// By far not all touch devices are supported, and the details depend on the `egui`
|
||||
|
|
|
@ -108,11 +108,12 @@ impl Direction {
|
|||
/// The layout of a [`Ui`][`crate::Ui`], e.g. "vertical & centered".
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// ui.with_layout(egui::Layout::right_to_left(), |ui| {
|
||||
/// ui.label("world!");
|
||||
/// ui.label("Hello");
|
||||
/// });
|
||||
/// # });
|
||||
/// ```
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
// #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||
|
|
|
@ -45,21 +45,21 @@
|
|||
//! get access to an [`Ui`] where you can put widgets. For example:
|
||||
//!
|
||||
//! ```
|
||||
//! # let mut ctx = egui::CtxRef::default();
|
||||
//! # ctx.begin_frame(Default::default());
|
||||
//! # egui::__run_test_ctx(|ctx| {
|
||||
//! egui::CentralPanel::default().show(&ctx, |ui| {
|
||||
//! ui.add(egui::Label::new("Hello World!"));
|
||||
//! ui.label("A shorter and more convenient way to add a label.");
|
||||
//! if ui.button("Click me").clicked() {
|
||||
//! /* take some action here */
|
||||
//! // take some action here
|
||||
//! }
|
||||
//! });
|
||||
//! # });
|
||||
//! ```
|
||||
//!
|
||||
//! ### Quick start
|
||||
//!
|
||||
//! ``` rust
|
||||
//! # let ui = &mut egui::Ui::__test();
|
||||
//! # egui::__run_test_ui(|ui| {
|
||||
//! # let mut my_string = String::new();
|
||||
//! # let mut my_boolean = true;
|
||||
//! # let mut my_f32 = 42.0;
|
||||
|
@ -89,6 +89,7 @@
|
|||
//! ui.collapsing("Click to see what is hidden!", |ui| {
|
||||
//! ui.label("Not much, as it turns out");
|
||||
//! });
|
||||
//! # });
|
||||
//! ```
|
||||
//!
|
||||
//! ## Conventions
|
||||
|
@ -117,16 +118,16 @@
|
|||
//! // Game loop:
|
||||
//! loop {
|
||||
//! let raw_input: egui::RawInput = gather_input();
|
||||
//! ctx.begin_frame(raw_input);
|
||||
//!
|
||||
//! let (output, shapes) = ctx.run(raw_input, |ctx| {
|
||||
//! egui::CentralPanel::default().show(&ctx, |ui| {
|
||||
//! ui.label("Hello world!");
|
||||
//! if ui.button("Click me").clicked() {
|
||||
//! /* take some action here */
|
||||
//! // take some action here
|
||||
//! }
|
||||
//! });
|
||||
//! });
|
||||
//!
|
||||
//! let (output, shapes) = ctx.end_frame();
|
||||
//! let clipped_meshes = ctx.tessellate(shapes); // create triangles to paint
|
||||
//! handle_output(output);
|
||||
//! paint(clipped_meshes);
|
||||
|
@ -141,10 +142,11 @@
|
|||
//! Here is an example to illustrate it:
|
||||
//!
|
||||
//! ```
|
||||
//! # let ui = &mut egui::Ui::__test();
|
||||
//! # egui::__run_test_ui(|ui| {
|
||||
//! if ui.button("click me").clicked() {
|
||||
//! take_action()
|
||||
//! }
|
||||
//! # });
|
||||
//! # fn take_action() {}
|
||||
//! ```
|
||||
//!
|
||||
|
@ -166,17 +168,19 @@
|
|||
//! ## How widgets works
|
||||
//!
|
||||
//! ```
|
||||
//! # let ui = &mut egui::Ui::__test();
|
||||
//! # egui::__run_test_ui(|ui| {
|
||||
//! if ui.button("click me").clicked() { take_action() }
|
||||
//! # });
|
||||
//! # fn take_action() {}
|
||||
//! ```
|
||||
//!
|
||||
//! is short for
|
||||
//!
|
||||
//! ```
|
||||
//! # let ui = &mut egui::Ui::__test();
|
||||
//! # egui::__run_test_ui(|ui| {
|
||||
//! let button = egui::Button::new("click me");
|
||||
//! if ui.add(button).clicked() { take_action() }
|
||||
//! # });
|
||||
//! # fn take_action() {}
|
||||
//! ```
|
||||
//!
|
||||
|
@ -184,10 +188,11 @@
|
|||
//!
|
||||
//! ```
|
||||
//! # use egui::Widget;
|
||||
//! # let ui = &mut egui::Ui::__test();
|
||||
//! # egui::__run_test_ui(|ui| {
|
||||
//! let button = egui::Button::new("click me");
|
||||
//! let response = button.ui(ui);
|
||||
//! if response.clicked() { take_action() }
|
||||
//! # });
|
||||
//! # fn take_action() {}
|
||||
//! ```
|
||||
//!
|
||||
|
@ -214,32 +219,35 @@
|
|||
//! 3. Use a justified layout:
|
||||
//!
|
||||
//! ``` rust
|
||||
//! # let ui = &mut egui::Ui::__test();
|
||||
//! # egui::__run_test_ui(|ui| {
|
||||
//! ui.with_layout(egui::Layout::top_down_justified(egui::Align::Center), |ui| {
|
||||
//! ui.button("I am becoming wider as needed");
|
||||
//! });
|
||||
//! # });
|
||||
//! ```
|
||||
//!
|
||||
//! 4. Fill in extra space with emptiness:
|
||||
//!
|
||||
//! ``` rust
|
||||
//! # let ui = &mut egui::Ui::__test();
|
||||
//! # egui::__run_test_ui(|ui| {
|
||||
//! ui.allocate_space(ui.available_size()); // put this LAST in your panel/window code
|
||||
//! # });
|
||||
//! ```
|
||||
//!
|
||||
//! ## Sizes
|
||||
//! You can control the size of widgets using [`Ui::add_sized`].
|
||||
//!
|
||||
//! ```
|
||||
//! # let ui = &mut egui::Ui::__test();
|
||||
//! # egui::__run_test_ui(|ui| {
|
||||
//! # let mut my_value = 0.0_f32;
|
||||
//! ui.add_sized([40.0, 20.0], egui::DragValue::new(&mut my_value));
|
||||
//! # });
|
||||
//! ```
|
||||
//!
|
||||
//! ## Code snippets
|
||||
//!
|
||||
//! ```
|
||||
//! # let ui = &mut egui::Ui::__test();
|
||||
//! # egui::__run_test_ui(|ui| {
|
||||
//! # let mut some_bool = true;
|
||||
//! // Miscellaneous tips and tricks
|
||||
//!
|
||||
|
@ -263,6 +271,7 @@
|
|||
//!
|
||||
//! ui.label("This text will be red, monospace, and won't wrap to a new line");
|
||||
//! }); // the temporary settings are reverted here
|
||||
//! # });
|
||||
//! ```
|
||||
|
||||
// Forbid warnings in release builds:
|
||||
|
@ -432,8 +441,9 @@ pub fn warn_if_debug_build(ui: &mut crate::Ui) {
|
|||
/// Create a [`Hyperlink`](crate::Hyperlink) to the current [`file!()`] (and line) on Github
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// ui.add(egui::github_link_file_line!("https://github.com/YOUR/PROJECT/blob/master/", "(source code)"));
|
||||
/// # });
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! github_link_file_line {
|
||||
|
@ -446,8 +456,9 @@ macro_rules! github_link_file_line {
|
|||
/// Create a [`Hyperlink`](crate::Hyperlink) to the current [`file!()`] on github.
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// ui.add(egui::github_link_file!("https://github.com/YOUR/PROJECT/blob/master/", "(source code)"));
|
||||
/// # });
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! github_link_file {
|
||||
|
@ -462,7 +473,7 @@ macro_rules! github_link_file {
|
|||
/// Show debug info on hover when [`Context::set_debug_on_hover`] has been turned on.
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// // Turn on tracing of widgets
|
||||
/// ui.ctx().set_debug_on_hover(true);
|
||||
///
|
||||
|
@ -471,6 +482,7 @@ macro_rules! github_link_file {
|
|||
///
|
||||
/// /// Show [`std::file`] and [`std::line`] on hover
|
||||
/// egui::trace!(ui);
|
||||
/// # });
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! trace {
|
||||
|
@ -561,3 +573,23 @@ pub enum WidgetType {
|
|||
/// If this is something you think should be added, file an issue.
|
||||
Other,
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/// For use in tests; especially doctests.
|
||||
pub fn __run_test_ctx(mut run_ui: impl FnMut(&CtxRef)) {
|
||||
let mut ctx = CtxRef::default();
|
||||
let _ = ctx.run(Default::default(), |ctx| {
|
||||
run_ui(ctx);
|
||||
});
|
||||
}
|
||||
|
||||
/// For use in tests; especially doctests.
|
||||
pub fn __run_test_ui(mut add_contents: impl FnMut(&mut Ui)) {
|
||||
let mut ctx = CtxRef::default();
|
||||
let _ = ctx.run(Default::default(), |ctx| {
|
||||
crate::CentralPanel::default().show(ctx, |ui| {
|
||||
add_contents(ui);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -200,13 +200,14 @@ impl Response {
|
|||
/// or (in case of a [`crate::TextEdit`]) because the user pressed enter.
|
||||
///
|
||||
/// ```
|
||||
/// # let mut ui = egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// # let mut my_text = String::new();
|
||||
/// # fn do_request(_: &str) {}
|
||||
/// let response = ui.text_edit_singleline(&mut my_text);
|
||||
/// if response.lost_focus() && ui.input().key_pressed(egui::Key::Enter) {
|
||||
/// do_request(&my_text);
|
||||
/// }
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn lost_focus(&self) -> bool {
|
||||
self.ctx.memory().lost_focus(self.id)
|
||||
|
@ -415,11 +416,12 @@ impl Response {
|
|||
/// it is better to give the widget a `Sense` instead, e.g. using [`crate::Label::sense`].
|
||||
///
|
||||
/// ```
|
||||
/// # let mut ui = egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// let response = ui.label("hello");
|
||||
/// assert!(!response.clicked()); // labels don't sense clicks by default
|
||||
/// let response = response.interact(egui::Sense::click());
|
||||
/// if response.clicked() { /* … */ }
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn interact(&self, sense: Sense) -> Self {
|
||||
self.ctx.interact_with_hovered(
|
||||
|
@ -436,7 +438,7 @@ impl Response {
|
|||
///
|
||||
/// ```
|
||||
/// # use egui::Align;
|
||||
/// # let mut ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// egui::ScrollArea::vertical().show(ui, |ui| {
|
||||
/// for i in 0..1000 {
|
||||
/// let response = ui.button(format!("Button {}", i));
|
||||
|
@ -445,6 +447,7 @@ impl Response {
|
|||
/// }
|
||||
/// }
|
||||
/// });
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn scroll_to_me(&self, align: Align) {
|
||||
let scroll_target = lerp(self.rect.x_range(), align.to_factor());
|
||||
|
@ -478,13 +481,14 @@ impl Response {
|
|||
/// Response to secondary clicks (right-clicks) by showing the given menu.
|
||||
///
|
||||
/// ``` rust
|
||||
/// # let mut ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// let response = ui.label("Right-click me!");
|
||||
/// response.context_menu(|ui|{
|
||||
/// response.context_menu(|ui| {
|
||||
/// if ui.button("Close the menu").clicked() {
|
||||
/// ui.close_menu();
|
||||
/// }
|
||||
/// });
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn context_menu(self, add_contents: impl FnOnce(&mut Ui)) -> Self {
|
||||
self.ctx.show_context_menu(&self, add_contents);
|
||||
|
@ -549,12 +553,13 @@ impl std::ops::BitOr for Response {
|
|||
/// To summarize the response from many widgets you can use this pattern:
|
||||
///
|
||||
/// ```
|
||||
/// # let mut ui = egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// # let (widget_a, widget_b, widget_c) = (egui::Label::new("a"), egui::Label::new("b"), egui::Label::new("c"));
|
||||
/// let mut response = ui.add(widget_a);
|
||||
/// response |= ui.add(widget_b);
|
||||
/// response |= ui.add(widget_c);
|
||||
/// if response.hovered() { ui.label("You hovered at least one of the widgets"); }
|
||||
/// # });
|
||||
/// ```
|
||||
impl std::ops::BitOrAssign for Response {
|
||||
fn bitor_assign(&mut self, rhs: Self) {
|
||||
|
@ -568,13 +573,14 @@ impl std::ops::BitOrAssign for Response {
|
|||
/// the results of the inner function and the ui as a whole, e.g.:
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// let inner_resp = ui.horizontal(|ui| {
|
||||
/// ui.label("Blah blah");
|
||||
/// 42
|
||||
/// });
|
||||
/// inner_resp.response.on_hover_text("You hovered the horizontal layout");
|
||||
/// assert_eq!(inner_resp.inner, 42);
|
||||
/// # });
|
||||
/// ```
|
||||
#[derive(Debug)]
|
||||
pub struct InnerResponse<R> {
|
||||
|
|
|
@ -16,7 +16,7 @@ use crate::{
|
|||
/// Represents a region of the screen with a type of layout (horizontal or vertical).
|
||||
///
|
||||
/// ```
|
||||
/// # let mut ui = egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// ui.add(egui::Label::new("Hello World!"));
|
||||
/// ui.label("A shorter and more convenient way to add a label.");
|
||||
/// ui.horizontal(|ui| {
|
||||
|
@ -25,6 +25,7 @@ use crate::{
|
|||
/// /* … */
|
||||
/// }
|
||||
/// });
|
||||
/// # });
|
||||
/// ```
|
||||
pub struct Ui {
|
||||
/// ID of this ui.
|
||||
|
@ -109,16 +110,6 @@ impl Ui {
|
|||
}
|
||||
}
|
||||
|
||||
/// Empty `Ui` for use in tests.
|
||||
pub fn __test() -> Self {
|
||||
let mut ctx = CtxRef::default();
|
||||
ctx.begin_frame(Default::default());
|
||||
let id = Id::new("__test");
|
||||
let layer_id = LayerId::new(Order::Middle, id);
|
||||
let rect = Rect::from_min_size(Pos2::new(0.0, 0.0), vec2(1000.0, 1000.0));
|
||||
Self::new(ctx, layer_id, id, rect, rect)
|
||||
}
|
||||
|
||||
// -------------------------------------------------
|
||||
|
||||
/// A unique identity of this `Ui`.
|
||||
|
@ -140,8 +131,9 @@ impl Ui {
|
|||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// ui.style_mut().body_text_style = egui::TextStyle::Heading;
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn style_mut(&mut self) -> &mut Style {
|
||||
std::sync::Arc::make_mut(&mut self.style) // clone-on-write
|
||||
|
@ -171,8 +163,9 @@ impl Ui {
|
|||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// ui.spacing_mut().item_spacing = egui::vec2(10.0, 2.0);
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn spacing_mut(&mut self) -> &mut crate::style::Spacing {
|
||||
&mut self.style_mut().spacing
|
||||
|
@ -192,8 +185,9 @@ impl Ui {
|
|||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// ui.visuals_mut().override_text_color = Some(egui::Color32::RED);
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn visuals_mut(&mut self) -> &mut crate::Visuals {
|
||||
&mut self.style_mut().visuals
|
||||
|
@ -227,7 +221,7 @@ impl Ui {
|
|||
///
|
||||
/// ### Example
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// # let mut enabled = true;
|
||||
/// ui.group(|ui| {
|
||||
/// ui.checkbox(&mut enabled, "Enable subsection");
|
||||
|
@ -236,6 +230,7 @@ impl Ui {
|
|||
/// /* … */
|
||||
/// }
|
||||
/// });
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn set_enabled(&mut self, enabled: bool) {
|
||||
self.enabled &= enabled;
|
||||
|
@ -260,7 +255,7 @@ impl Ui {
|
|||
///
|
||||
/// ### Example
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// # let mut visible = true;
|
||||
/// ui.group(|ui| {
|
||||
/// ui.checkbox(&mut visible, "Show subsection");
|
||||
|
@ -269,6 +264,7 @@ impl Ui {
|
|||
/// /* … */
|
||||
/// }
|
||||
/// });
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn set_visible(&mut self, visible: bool) {
|
||||
self.set_enabled(visible);
|
||||
|
@ -593,10 +589,11 @@ impl Ui {
|
|||
/// You will never get a rectangle that is smaller than the amount of space you asked for.
|
||||
///
|
||||
/// ```
|
||||
/// # let mut ui = egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// let response = ui.allocate_response(egui::vec2(100.0, 200.0), egui::Sense::click());
|
||||
/// if response.clicked() { /* … */ }
|
||||
/// ui.painter().rect_stroke(response.rect, 0.0, (1.0, egui::Color32::WHITE));
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn allocate_response(&mut self, desired_size: Vec2, sense: Sense) -> Response {
|
||||
let (id, rect) = self.allocate_space(desired_size);
|
||||
|
@ -640,9 +637,10 @@ impl Ui {
|
|||
/// Returns an automatic `Id` (which you can use for interaction) and the `Rect` of where to put your widget.
|
||||
///
|
||||
/// ```
|
||||
/// # let mut ui = egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// let (id, rect) = ui.allocate_space(egui::vec2(100.0, 200.0));
|
||||
/// let response = ui.interact(rect, id, egui::Sense::click());
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn allocate_space(&mut self, desired_size: Vec2) -> (Id, Rect) {
|
||||
// For debug rendering
|
||||
|
@ -833,8 +831,8 @@ impl Ui {
|
|||
///
|
||||
/// ```
|
||||
/// # use egui::*;
|
||||
/// # let mut ui = &mut egui::Ui::__test();
|
||||
/// # use std::f32::consts::TAU;
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// let size = Vec2::splat(16.0);
|
||||
/// let (response, painter) = ui.allocate_painter(size, Sense::hover());
|
||||
/// let rect = response.rect;
|
||||
|
@ -846,6 +844,7 @@ impl Ui {
|
|||
/// painter.line_segment([c - vec2(0.0, r), c + vec2(0.0, r)], stroke);
|
||||
/// painter.line_segment([c, c + r * Vec2::angled(TAU * 1.0 / 8.0)], stroke);
|
||||
/// painter.line_segment([c, c + r * Vec2::angled(TAU * 3.0 / 8.0)], stroke);
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn allocate_painter(&mut self, desired_size: Vec2, sense: Sense) -> (Response, Painter) {
|
||||
let response = self.allocate_response(desired_size, sense);
|
||||
|
@ -858,7 +857,7 @@ impl Ui {
|
|||
///
|
||||
/// ```
|
||||
/// # use egui::Align;
|
||||
/// # let mut ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// egui::ScrollArea::vertical().show(ui, |ui| {
|
||||
/// let scroll_bottom = ui.button("Scroll to bottom.").clicked();
|
||||
/// for i in 0..1000 {
|
||||
|
@ -869,6 +868,7 @@ impl Ui {
|
|||
/// ui.scroll_to_cursor(Align::BOTTOM);
|
||||
/// }
|
||||
/// });
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn scroll_to_cursor(&mut self, align: Align) {
|
||||
let target = self.next_widget_position();
|
||||
|
@ -888,10 +888,11 @@ impl Ui {
|
|||
/// See also [`Self::add_sized`] and [`Self::put`].
|
||||
///
|
||||
/// ```
|
||||
/// # let mut ui = egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// # let mut my_value = 42;
|
||||
/// let response = ui.add(egui::Slider::new(&mut my_value, 0..=100));
|
||||
/// response.on_hover_text("Drag me!");
|
||||
/// # });
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn add(&mut self, widget: impl Widget) -> Response {
|
||||
|
@ -906,9 +907,10 @@ impl Ui {
|
|||
/// See also [`Self::add`] and [`Self::put`].
|
||||
///
|
||||
/// ```
|
||||
/// # let mut ui = egui::Ui::__test();
|
||||
/// # let mut my_value = 42;
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// ui.add_sized([40.0, 20.0], egui::DragValue::new(&mut my_value));
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn add_sized(&mut self, max_size: impl Into<Vec2>, widget: impl Widget) -> Response {
|
||||
// TODO: configure to overflow to main_dir instead of centered overflow
|
||||
|
@ -939,8 +941,9 @@ impl Ui {
|
|||
/// See also [`Self::add_enabled_ui`] and [`Self::is_enabled`].
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// ui.add_enabled(false, egui::Button::new("Can't click this"));
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn add_enabled(&mut self, enabled: bool, widget: impl Widget) -> Response {
|
||||
if enabled || !self.is_enabled() {
|
||||
|
@ -964,7 +967,7 @@ impl Ui {
|
|||
///
|
||||
/// ### Example
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// # let mut enabled = true;
|
||||
/// ui.checkbox(&mut enabled, "Enable subsection");
|
||||
/// ui.add_enabled_ui(enabled, |ui| {
|
||||
|
@ -972,6 +975,7 @@ impl Ui {
|
|||
/// /* … */
|
||||
/// }
|
||||
/// });
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn add_enabled_ui<R>(
|
||||
&mut self,
|
||||
|
@ -1061,8 +1065,9 @@ impl Ui {
|
|||
/// Shortcut for `add(Hyperlink::new(url).text(label))`
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// ui.hyperlink_to("egui on GitHub", "https://www.github.com/emilk/egui/");
|
||||
/// # });
|
||||
/// ```
|
||||
///
|
||||
/// See also [`Hyperlink`].
|
||||
|
@ -1106,7 +1111,7 @@ impl Ui {
|
|||
/// See also [`Button`].
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// if ui.button("Click me!").clicked() {
|
||||
/// // …
|
||||
/// }
|
||||
|
@ -1115,6 +1120,7 @@ impl Ui {
|
|||
/// if ui.button(RichText::new("delete").color(Color32::RED)).clicked() {
|
||||
/// // …
|
||||
/// }
|
||||
/// # });
|
||||
/// ```
|
||||
#[must_use = "You should check if the user clicked this with `if ui.button(…).clicked() { … } "]
|
||||
#[inline]
|
||||
|
@ -1150,7 +1156,7 @@ impl Ui {
|
|||
/// If clicked, `selected_value` is assigned to `*current_value`.
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
///
|
||||
/// #[derive(PartialEq)]
|
||||
/// enum Enum { First, Second, Third }
|
||||
|
@ -1163,6 +1169,7 @@ impl Ui {
|
|||
/// if ui.add(egui::RadioButton::new(my_enum == Enum::First, "First")).clicked() {
|
||||
/// my_enum = Enum::First
|
||||
/// }
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn radio_value<Value: PartialEq>(
|
||||
&mut self,
|
||||
|
@ -1349,10 +1356,11 @@ impl Ui {
|
|||
/// Put into a [`Frame::group`], visually grouping the contents together
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// ui.group(|ui| {
|
||||
/// ui.label("Within a frame");
|
||||
/// });
|
||||
/// # });
|
||||
/// ```
|
||||
///
|
||||
/// Se also [`Self::scope`].
|
||||
|
@ -1365,11 +1373,12 @@ impl Ui {
|
|||
/// You can use this to temporarily change the [`Style`] of a sub-region, for instance:
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// ui.scope(|ui| {
|
||||
/// ui.spacing_mut().slider_width = 200.0; // Temporary change
|
||||
/// // …
|
||||
/// });
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn scope<R>(&mut self, add_contents: impl FnOnce(&mut Ui) -> R) -> InnerResponse<R> {
|
||||
self.scope_dyn(Box::new(add_contents))
|
||||
|
@ -1483,11 +1492,12 @@ impl Ui {
|
|||
/// It also contains the `Rect` used by the horizontal layout.
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// ui.horizontal(|ui| {
|
||||
/// ui.label("Same");
|
||||
/// ui.label("row");
|
||||
/// });
|
||||
/// # });
|
||||
/// ```
|
||||
///
|
||||
/// See also [`Self::with_layout`] for more options.
|
||||
|
@ -1557,11 +1567,12 @@ impl Ui {
|
|||
/// Widgets will be left-justified.
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// ui.vertical(|ui| {
|
||||
/// ui.label("over");
|
||||
/// ui.label("under");
|
||||
/// });
|
||||
/// # });
|
||||
/// ```
|
||||
///
|
||||
/// See also [`Self::with_layout`] for more options.
|
||||
|
@ -1574,11 +1585,12 @@ impl Ui {
|
|||
/// Widgets will be horizontally centered.
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// ui.vertical_centered(|ui| {
|
||||
/// ui.label("over");
|
||||
/// ui.label("under");
|
||||
/// });
|
||||
/// # });
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn vertical_centered<R>(
|
||||
|
@ -1592,11 +1604,12 @@ impl Ui {
|
|||
/// Widgets will be horizontally centered and justified (fill full width).
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// ui.vertical_centered_justified(|ui| {
|
||||
/// ui.label("over");
|
||||
/// ui.label("under");
|
||||
/// });
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn vertical_centered_justified<R>(
|
||||
&mut self,
|
||||
|
@ -1611,11 +1624,12 @@ impl Ui {
|
|||
/// The new layout will take up all available space.
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// ui.with_layout(egui::Layout::right_to_left(), |ui| {
|
||||
/// ui.label("world!");
|
||||
/// ui.label("Hello");
|
||||
/// });
|
||||
/// # });
|
||||
/// ```
|
||||
///
|
||||
/// See also [`Self::allocate_ui_with_layout`],
|
||||
|
@ -1687,11 +1701,12 @@ impl Ui {
|
|||
/// Temporarily split split an Ui into several columns.
|
||||
///
|
||||
/// ```
|
||||
/// # let mut ui = egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// ui.columns(2, |columns| {
|
||||
/// columns[0].label("First column");
|
||||
/// columns[1].label("Second column");
|
||||
/// });
|
||||
/// # });
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn columns<R>(
|
||||
|
@ -1764,7 +1779,7 @@ impl Ui {
|
|||
/// Create a menu button. Creates a button for a sub-menu when the `Ui` is inside a menu.
|
||||
///
|
||||
/// ```
|
||||
/// # let mut ui = egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// ui.menu_button("My menu", |ui| {
|
||||
/// ui.menu_button("My sub-menu", |ui| {
|
||||
/// if ui.button("Close the menu").clicked() {
|
||||
|
@ -1772,6 +1787,7 @@ impl Ui {
|
|||
/// }
|
||||
/// });
|
||||
/// });
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn menu_button<R>(
|
||||
&mut self,
|
||||
|
|
|
@ -5,7 +5,7 @@ use crate::*;
|
|||
/// See also [`Ui::button`].
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// # fn do_stuff() {}
|
||||
///
|
||||
/// if ui.add(egui::Button::new("Click me")).clicked() {
|
||||
|
@ -16,6 +16,7 @@ use crate::*;
|
|||
/// if ui.add_enabled(false, egui::Button::new("Can't click this")).clicked() {
|
||||
/// unreachable!();
|
||||
/// }
|
||||
/// # });
|
||||
/// ```
|
||||
#[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
|
||||
pub struct Button {
|
||||
|
@ -177,11 +178,12 @@ impl Widget for Button {
|
|||
/// Usually you'd use [`Ui::checkbox`] instead.
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// # let mut my_bool = true;
|
||||
/// // These are equivalent:
|
||||
/// ui.checkbox(&mut my_bool, "Checked");
|
||||
/// ui.add(egui::Checkbox::new(&mut my_bool, "Checked"));
|
||||
/// # });
|
||||
/// ```
|
||||
#[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
|
||||
pub struct Checkbox<'a> {
|
||||
|
@ -275,7 +277,7 @@ impl<'a> Widget for Checkbox<'a> {
|
|||
/// Usually you'd use [`Ui::radio_value`] or [`Ui::radio`] instead.
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// #[derive(PartialEq)]
|
||||
/// enum Enum { First, Second, Third }
|
||||
/// let mut my_enum = Enum::First;
|
||||
|
@ -287,6 +289,7 @@ impl<'a> Widget for Checkbox<'a> {
|
|||
/// if ui.add(egui::RadioButton::new(my_enum == Enum::First, "First")).clicked() {
|
||||
/// my_enum = Enum::First
|
||||
/// }
|
||||
/// # });
|
||||
/// ```
|
||||
#[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
|
||||
pub struct RadioButton {
|
||||
|
|
|
@ -42,9 +42,10 @@ fn set(get_set_value: &mut GetSetValue<'_>, value: f64) {
|
|||
/// A numeric value that you can change by dragging the number. More compact than a [`Slider`].
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// # let mut my_f32: f32 = 0.0;
|
||||
/// ui.add(egui::DragValue::new(&mut my_f32).speed(0.1));
|
||||
/// # });
|
||||
/// ```
|
||||
#[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
|
||||
pub struct DragValue<'a> {
|
||||
|
|
|
@ -5,9 +5,10 @@ use crate::*;
|
|||
/// See also [`Ui::hyperlink`] and [`Ui::hyperlink_to`].
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// ui.hyperlink("https://github.com/emilk/egui");
|
||||
/// ui.add(egui::Hyperlink::new("https://github.com/emilk/egui").text("My favorite repo").small());
|
||||
/// # });
|
||||
/// ```
|
||||
#[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
|
||||
pub struct Hyperlink {
|
||||
|
|
|
@ -3,12 +3,13 @@ use crate::*;
|
|||
/// An widget to show an image of a given size.
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// # let my_texture_id = egui::TextureId::User(0);
|
||||
/// ui.add(egui::Image::new(my_texture_id, [640.0, 480.0]));
|
||||
///
|
||||
/// // Shorter version:
|
||||
/// ui.image(my_texture_id, [640.0, 480.0]);
|
||||
/// # });
|
||||
/// ```
|
||||
///
|
||||
/// Se also [`crate::ImageButton`].
|
||||
|
|
|
@ -3,11 +3,12 @@ use crate::{widget_text::WidgetTextGalley, *};
|
|||
/// Static text.
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// ui.label("Equivalent");
|
||||
/// ui.add(egui::Label::new("Equivalent"));
|
||||
/// ui.add(egui::Label::new("With Options").wrap(false));
|
||||
/// ui.label(egui::RichText::new("With formatting").underline());
|
||||
/// # });
|
||||
/// ```
|
||||
#[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
|
||||
pub struct Label {
|
||||
|
@ -134,10 +135,11 @@ impl Label {
|
|||
///
|
||||
/// ``` rust
|
||||
/// # use egui::{Label, Sense};
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// if ui.add(Label::new("click me").sense(Sense::click())).clicked() {
|
||||
/// /* … */
|
||||
/// }
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn sense(mut self, sense: Sense) -> Self {
|
||||
self.sense = sense;
|
||||
|
|
|
@ -47,7 +47,7 @@ impl PlotMemory {
|
|||
/// `Plot` supports multiple lines and points.
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// use egui::plot::{Line, Plot, Value, Values};
|
||||
/// let sin = (0..1000).map(|i| {
|
||||
/// let x = i as f64 * 0.01;
|
||||
|
@ -57,6 +57,7 @@ impl PlotMemory {
|
|||
/// ui.add(
|
||||
/// Plot::new("my_plot").line(line).view_aspect(2.0)
|
||||
/// );
|
||||
/// # });
|
||||
/// ```
|
||||
pub struct Plot {
|
||||
id_source: Id,
|
||||
|
|
|
@ -7,7 +7,7 @@ use crate::*;
|
|||
/// Usually you'd use [`Ui::selectable_value`] or [`Ui::selectable_label`] instead.
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// #[derive(PartialEq)]
|
||||
/// enum Enum { First, Second, Third }
|
||||
/// let mut my_enum = Enum::First;
|
||||
|
@ -19,6 +19,7 @@ use crate::*;
|
|||
/// if ui.add(egui::SelectableLabel::new(my_enum == Enum::First, "First")).clicked() {
|
||||
/// my_enum = Enum::First
|
||||
/// }
|
||||
/// # });
|
||||
/// ```
|
||||
#[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
|
||||
pub struct SelectableLabel {
|
||||
|
|
|
@ -5,10 +5,11 @@ use crate::*;
|
|||
/// Usually you'd use the shorter version [`Ui::separator`].
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// // These are equivalent:
|
||||
/// ui.separator();
|
||||
/// ui.add(egui::Separator::default());
|
||||
/// # });
|
||||
/// ```
|
||||
#[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
|
||||
pub struct Separator {
|
||||
|
|
|
@ -45,9 +45,10 @@ struct SliderSpec {
|
|||
/// The user can click the value display to edit its value. It can be turned off with `.show_value(false)`.
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// # let mut my_f32: f32 = 0.0;
|
||||
/// ui.add(egui::Slider::new(&mut my_f32, 0.0..=100.0).text("My value"));
|
||||
/// # });
|
||||
/// ```
|
||||
///
|
||||
/// The default `Slider` size is set by [`crate::style::Spacing::slider_width`].
|
||||
|
|
|
@ -13,7 +13,7 @@ use super::{CCursorRange, CursorRange, TextEditOutput, TextEditState};
|
|||
/// Example:
|
||||
///
|
||||
/// ```
|
||||
/// # let mut ui = egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// # let mut my_string = String::new();
|
||||
/// let response = ui.add(egui::TextEdit::singleline(&mut my_string));
|
||||
/// if response.changed() {
|
||||
|
@ -22,14 +22,16 @@ use super::{CCursorRange, CursorRange, TextEditOutput, TextEditState};
|
|||
/// if response.lost_focus() && ui.input().key_pressed(egui::Key::Enter) {
|
||||
/// // …
|
||||
/// }
|
||||
/// # });
|
||||
/// ```
|
||||
///
|
||||
/// To fill an [`Ui`] with a [`TextEdit`] use [`Ui::add_sized`]:
|
||||
///
|
||||
/// ```
|
||||
/// # let mut ui = egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// # let mut my_string = String::new();
|
||||
/// ui.add_sized(ui.available_size(), egui::TextEdit::multiline(&mut my_string));
|
||||
/// # });
|
||||
/// ```
|
||||
///
|
||||
///
|
||||
|
@ -165,7 +167,7 @@ impl<'t> TextEdit<'t> {
|
|||
/// the text and the wrap width.
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// # egui::__run_test_ui(|ui| {
|
||||
/// # let mut my_code = String::new();
|
||||
/// # fn my_memoized_highlighter(s: &str) -> egui::text::LayoutJob { Default::default() }
|
||||
/// let mut layouter = |ui: &egui::Ui, string: &str, wrap_width: f32| {
|
||||
|
@ -174,6 +176,7 @@ impl<'t> TextEdit<'t> {
|
|||
/// ui.fonts().layout_job(layout_job)
|
||||
/// };
|
||||
/// ui.add(egui::TextEdit::multiline(&mut my_code).layouter(&mut layouter));
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn layouter(mut self, layouter: &'t mut dyn FnMut(&Ui, &str, f32) -> Arc<Galley>) -> Self {
|
||||
self.layouter = Some(layouter);
|
||||
|
|
|
@ -13,24 +13,24 @@ pub fn criterion_benchmark(c: &mut Criterion) {
|
|||
// The most end-to-end benchmark.
|
||||
c.bench_function("demo_with_tessellate__realistic", |b| {
|
||||
b.iter(|| {
|
||||
ctx.begin_frame(raw_input.clone());
|
||||
demo_windows.ui(&ctx);
|
||||
let (_, shapes) = ctx.end_frame();
|
||||
let (_output, shapes) = ctx.run(raw_input.clone(), |ctx| {
|
||||
demo_windows.ui(ctx);
|
||||
});
|
||||
ctx.tessellate(shapes)
|
||||
})
|
||||
});
|
||||
|
||||
c.bench_function("demo_no_tessellate", |b| {
|
||||
b.iter(|| {
|
||||
ctx.begin_frame(raw_input.clone());
|
||||
demo_windows.ui(&ctx);
|
||||
ctx.end_frame()
|
||||
ctx.run(raw_input.clone(), |ctx| {
|
||||
demo_windows.ui(ctx);
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
ctx.begin_frame(raw_input.clone());
|
||||
demo_windows.ui(&ctx);
|
||||
let (_, shapes) = ctx.end_frame();
|
||||
let (_output, shapes) = ctx.run(raw_input.clone(), |ctx| {
|
||||
demo_windows.ui(ctx);
|
||||
});
|
||||
c.bench_function("demo_only_tessellate", |b| {
|
||||
b.iter(|| ctx.tessellate(shapes.clone()))
|
||||
});
|
||||
|
@ -42,17 +42,17 @@ pub fn criterion_benchmark(c: &mut Criterion) {
|
|||
let mut demo_windows = egui_demo_lib::DemoWindows::default();
|
||||
c.bench_function("demo_full_no_tessellate", |b| {
|
||||
b.iter(|| {
|
||||
ctx.begin_frame(raw_input.clone());
|
||||
demo_windows.ui(&ctx);
|
||||
ctx.end_frame()
|
||||
ctx.run(raw_input.clone(), |ctx| {
|
||||
demo_windows.ui(ctx);
|
||||
})
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
let mut ctx = egui::CtxRef::default();
|
||||
ctx.begin_frame(raw_input);
|
||||
let mut ui = egui::Ui::__test();
|
||||
let _ = ctx.run(raw_input, |ctx| {
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
c.bench_function("label &str", |b| {
|
||||
b.iter(|| {
|
||||
ui.label("the quick brown fox jumps over the lazy dog");
|
||||
|
@ -63,6 +63,8 @@ pub fn criterion_benchmark(c: &mut Criterion) {
|
|||
ui.label("the quick brown fox jumps over the lazy dog".to_owned());
|
||||
})
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -145,9 +145,9 @@ fn test_egui_e2e() {
|
|||
|
||||
const NUM_FRAMES: usize = 5;
|
||||
for _ in 0..NUM_FRAMES {
|
||||
ctx.begin_frame(raw_input.clone());
|
||||
demo_windows.ui(&ctx);
|
||||
let (_output, shapes) = ctx.end_frame();
|
||||
let (_output, shapes) = ctx.run(raw_input.clone(), |ctx| {
|
||||
demo_windows.ui(ctx);
|
||||
});
|
||||
let clipped_meshes = ctx.tessellate(shapes);
|
||||
assert!(!clipped_meshes.is_empty());
|
||||
}
|
||||
|
@ -164,9 +164,9 @@ fn test_egui_zero_window_size() {
|
|||
|
||||
const NUM_FRAMES: usize = 5;
|
||||
for _ in 0..NUM_FRAMES {
|
||||
ctx.begin_frame(raw_input.clone());
|
||||
demo_windows.ui(&ctx);
|
||||
let (_output, shapes) = ctx.end_frame();
|
||||
let (_output, shapes) = ctx.run(raw_input.clone(), |ctx| {
|
||||
demo_windows.ui(ctx);
|
||||
});
|
||||
let clipped_meshes = ctx.tessellate(shapes);
|
||||
assert!(clipped_meshes.is_empty(), "There should be nothing to show");
|
||||
}
|
||||
|
|
|
@ -101,7 +101,7 @@ use glium::glutin;
|
|||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/// Use [`egui`] from a [`glium`] app.
|
||||
/// Convenience wrapper for using [`egui`] from a [`glium`] app.
|
||||
pub struct EguiGlium {
|
||||
pub egui_ctx: egui::CtxRef,
|
||||
pub egui_winit: egui_winit::State,
|
||||
|
@ -136,16 +136,12 @@ impl EguiGlium {
|
|||
pub fn run(
|
||||
&mut self,
|
||||
display: &glium::Display,
|
||||
mut run_ui: impl FnMut(&egui::CtxRef),
|
||||
run_ui: impl FnMut(&egui::CtxRef),
|
||||
) -> (bool, Vec<egui::epaint::ClippedShape>) {
|
||||
let raw_input = self
|
||||
.egui_winit
|
||||
.take_egui_input(display.gl_window().window());
|
||||
self.egui_ctx.begin_frame(raw_input);
|
||||
|
||||
run_ui(&self.egui_ctx);
|
||||
|
||||
let (egui_output, shapes) = self.egui_ctx.end_frame();
|
||||
let (egui_output, shapes) = self.egui_ctx.run(raw_input, run_ui);
|
||||
let needs_repaint = egui_output.needs_repaint;
|
||||
self.egui_winit
|
||||
.handle_output(display.gl_window().window(), &self.egui_ctx, egui_output);
|
||||
|
|
|
@ -150,14 +150,10 @@ impl EguiGlow {
|
|||
pub fn run(
|
||||
&mut self,
|
||||
window: &glutin::window::Window,
|
||||
mut run_ui: impl FnMut(&egui::CtxRef),
|
||||
run_ui: impl FnMut(&egui::CtxRef),
|
||||
) -> (bool, Vec<egui::epaint::ClippedShape>) {
|
||||
let raw_input = self.egui_winit.take_egui_input(window);
|
||||
self.egui_ctx.begin_frame(raw_input);
|
||||
|
||||
run_ui(&self.egui_ctx);
|
||||
|
||||
let (egui_output, shapes) = self.egui_ctx.end_frame();
|
||||
let (egui_output, shapes) = self.egui_ctx.run(raw_input, run_ui);
|
||||
let needs_repaint = egui_output.needs_repaint;
|
||||
self.egui_winit
|
||||
.handle_output(window, &self.egui_ctx, egui_output);
|
||||
|
|
|
@ -189,8 +189,6 @@ impl AppRunner {
|
|||
let canvas_size = canvas_size_in_points(self.canvas_id());
|
||||
let raw_input = self.input.new_frame(canvas_size);
|
||||
|
||||
self.egui_ctx.begin_frame(raw_input);
|
||||
|
||||
let mut app_output = epi::backend::AppOutput::default();
|
||||
let mut frame = epi::backend::FrameBuilder {
|
||||
info: self.integration_info(),
|
||||
|
@ -200,9 +198,10 @@ impl AppRunner {
|
|||
}
|
||||
.build();
|
||||
|
||||
self.app.update(&self.egui_ctx, &mut frame);
|
||||
|
||||
let (egui_output, shapes) = self.egui_ctx.end_frame();
|
||||
let app = &mut self.app; // TODO: remove when we bump MSRV to 1.56
|
||||
let (egui_output, shapes) = self.egui_ctx.run(raw_input, |egui_ctx| {
|
||||
app.update(egui_ctx, &mut frame);
|
||||
});
|
||||
let clipped_meshes = self.egui_ctx.tessellate(shapes);
|
||||
|
||||
self.handle_egui_output(&egui_output);
|
||||
|
|
Loading…
Reference in a new issue