1
0
mirror of https://github.com/emilk/egui.git synced 2026-09-02 23:00:04 -04:00

Refactor and update docs

This commit is contained in:
Konkitoman
2023-10-25 13:30:35 +03:00
parent d6c2f3e8f3
commit 9b32dd7fb5
2 changed files with 39 additions and 37 deletions

View File

@@ -61,7 +61,7 @@ struct Repaint {
/// Incremented at the end of each frame. /// Incremented at the end of each frame.
viewports_frame_nr: HashMap<ViewportId, u64>, viewports_frame_nr: HashMap<ViewportId, u64>,
/// While positive, keep requesting repaints. Decrement at the end of each frame. /// While positive, keep requesting repaints. Decrement at the start of each frame.
repaint_request: HashMap<ViewportId, u8>, repaint_request: HashMap<ViewportId, u8>,
request_repaint_callback: Option<Box<dyn Fn(RequestRepaintInfo) + Send + Sync>>, request_repaint_callback: Option<Box<dyn Fn(RequestRepaintInfo) + Send + Sync>>,
@@ -85,7 +85,10 @@ impl Repaint {
}; };
(callback)(info); (callback)(info);
} else { } else {
eprint!("request_repaint_callback is not implemented by egui integration!\nIf is your integration you need to call `Context::set_request_repaint_callback`"); eprint!(
"request_repaint_callback is not implemented by egui integration!
If is your integration you need to call `Context::set_request_repaint_callback`"
);
} }
} }
@@ -537,13 +540,7 @@ impl Context {
/// ``` /// ```
#[inline] #[inline]
pub fn input<R>(&self, reader: impl FnOnce(&InputState) -> R) -> R { pub fn input<R>(&self, reader: impl FnOnce(&InputState) -> R) -> R {
self.read(move |ctx| { self.input_for(self.viewport_id(), reader)
reader(
ctx.input
.get(&ctx.viewport_id())
.unwrap_or(&Default::default()),
)
})
} }
/// This will create a `InputState::default()` if there is no input state for that viewport /// This will create a `InputState::default()` if there is no input state for that viewport
@@ -555,7 +552,7 @@ impl Context {
/// Read-write access to [`InputState`]. /// Read-write access to [`InputState`].
#[inline] #[inline]
pub fn input_mut<R>(&self, writer: impl FnOnce(&mut InputState) -> R) -> R { pub fn input_mut<R>(&self, writer: impl FnOnce(&mut InputState) -> R) -> R {
self.write(move |ctx| writer(ctx.input.entry(ctx.viewport_id()).or_default())) self.input_mut_for(self.viewport_id(), writer)
} }
/// This will create a `InputState::default()` if there is no input state for that viewport /// This will create a `InputState::default()` if there is no input state for that viewport
@@ -1144,8 +1141,7 @@ impl Context {
/// ///
/// This will repaint the current viewport /// This will repaint the current viewport
pub fn request_repaint(&self) { pub fn request_repaint(&self) {
// request two frames of repaint, just to cover some corner cases (frame delays): self.request_repaint_for(self.viewport_id())
self.write(|ctx| ctx.repaint.request_repaint(ctx.viewport_id()));
} }
/// Call this if there is need to repaint the UI, i.e. if you are showing an animation. /// Call this if there is need to repaint the UI, i.e. if you are showing an animation.
@@ -1181,9 +1177,6 @@ impl Context {
/// and call this function, to make sure that you are displaying the latest updated time, but /// and call this function, to make sure that you are displaying the latest updated time, but
/// not wasting resources on needless repaints within the same second. /// not wasting resources on needless repaints within the same second.
/// ///
/// NOTE: only works if called before `Context::end_frame()`. to force egui to update,
/// use `Context::request_repaint()` instead.
///
/// ### Quirk: /// ### Quirk:
/// Duration begins at the next frame. lets say for example that its a very inefficient app /// Duration begins at the next frame. lets say for example that its a very inefficient app
/// and takes 500 milliseconds per frame at 2 fps. The widget / user might want a repaint in /// and takes 500 milliseconds per frame at 2 fps. The widget / user might want a repaint in
@@ -1194,11 +1187,7 @@ impl Context {
/// ///
/// This repaints the current viewport /// This repaints the current viewport
pub fn request_repaint_after(&self, duration: std::time::Duration) { pub fn request_repaint_after(&self, duration: std::time::Duration) {
// Maybe we can check if duration is ZERO, and call self.request_repaint()? self.request_repaint_after_for(duration, self.viewport_id())
self.write(|ctx| {
ctx.repaint
.request_repaint_after(duration, ctx.viewport_id());
});
} }
/// Request repaint after at most the specified duration elapses. /// Request repaint after at most the specified duration elapses.
@@ -1220,9 +1209,6 @@ impl Context {
/// and call this function, to make sure that you are displaying the latest updated time, but /// and call this function, to make sure that you are displaying the latest updated time, but
/// not wasting resources on needless repaints within the same second. /// not wasting resources on needless repaints within the same second.
/// ///
/// NOTE: only works if called before `Context::end_frame()`. to force egui to update,
/// use `Context::request_repaint()` instead.
///
/// ### Quirk: /// ### Quirk:
/// Duration begins at the next frame. lets say for example that its a very inefficient app /// Duration begins at the next frame. lets say for example that its a very inefficient app
/// and takes 500 milliseconds per frame at 2 fps. The widget / user might want a repaint in /// and takes 500 milliseconds per frame at 2 fps. The widget / user might want a repaint in
@@ -1256,7 +1242,7 @@ impl Context {
self.read(|ctx| ctx.repaint.requested_repaint(viewport_id)) self.read(|ctx| ctx.repaint.requested_repaint(viewport_id))
} }
/// For integrations: this callback will be called when an egui user calls [`Self::request_repaint`]. /// For integrations: this callback will be called when an egui user calls [`Self::request_repaint`] or [`Self::request_repaint_after`].
/// ///
/// This lets you wake up a sleeping UI thread. /// This lets you wake up a sleeping UI thread.
/// ///
@@ -2531,12 +2517,14 @@ impl Context {
impl Context { impl Context {
/// Return the `ViewportId` of the current viewport /// Return the `ViewportId` of the current viewport
/// In the case of this viewport is the main viewport will be `ViewportId::MAIN` /// In the case of this viewport is the main viewport will be `ViewportId::MAIN`
/// Don't use this outside of `Self::run`, or after `Self::end_frame`
pub fn viewport_id(&self) -> ViewportId { pub fn viewport_id(&self) -> ViewportId {
self.read(|ctx| ctx.viewport_id()) self.read(|ctx| ctx.viewport_id())
} }
/// Return the `ViewportId` of his parent /// Return the `ViewportId` of his parent
/// In the case of this viewport is the main viewport will be `ViewportId::MAIN` /// In the case of this viewport is the main viewport will be `ViewportId::MAIN`
/// Don't use this outside of `Self::run`, or after `Self::end_frame`
pub fn parent_viewport_id(&self) -> ViewportId { pub fn parent_viewport_id(&self) -> ViewportId {
self.read(|ctx| ctx.parent_viewport_id()) self.read(|ctx| ctx.parent_viewport_id())
} }
@@ -2546,11 +2534,14 @@ impl Context {
self.read(|ctx| ctx.viewports.get(&id.into()).map(|v| v.pair)) self.read(|ctx| ctx.viewports.get(&id.into()).map(|v| v.pair))
} }
/// This should only be used by the backend! /// For integrations: Is used to render a sync viewport!
///
/// This will only be set for the current thread!
/// Can be set only one callback per thread!
/// ///
/// When a viewport sync is created will be rendered by this function /// When a viewport sync is created will be rendered by this function
/// ///
/// Look in `crates/eframe/native/run.rs` and search for ``set_render_sync_callback`` to see for what is used! /// Look in `crates/eframe/native/run.rs` and search for `set_render_sync_callback` to see for what is used!
#[allow(clippy::unused_self)] #[allow(clippy::unused_self)]
pub fn set_render_sync_callback( pub fn set_render_sync_callback(
&self, &self,
@@ -2568,13 +2559,13 @@ impl Context {
self.read(|ctx| ctx.is_desktop) self.read(|ctx| ctx.is_desktop)
} }
/// If this is true no other native windows will be created /// If this is true no other native window will be created, when a viewport is created!
pub fn force_embedding(&self) -> bool { pub fn force_embedding(&self) -> bool {
self.read(|ctx| ctx.force_embedding) self.read(|ctx| ctx.force_embedding)
} }
/// If this is true no other native windows, will not be created for a ```egui::Window``` or Viewport /// If this is true no other native window will be created, when a viewport is created!
/// You will always be able to set to false /// You will always be able to set to true
pub fn set_force_embedding(&self, value: bool) { pub fn set_force_embedding(&self, value: bool) {
self.write(|ctx| ctx.force_embedding = value || !ctx.is_desktop); self.write(|ctx| ctx.force_embedding = value || !ctx.is_desktop);
} }
@@ -2590,14 +2581,14 @@ impl Context {
} }
/// This will be a native window if is possible! /// This will be a native window if is possible!
/// You will need to wrap your viewport state in an ```Arc<RwLock<T>>``` or ```Arc<Mutex<T>>```! /// You will need to wrap your viewport state in an `Arc<RwLock<T>>` or `Arc<Mutex<T>>`!
/// When this is called again with the same title in `ViewportBuilder` the render function for that viewport will be updated! /// When this is called again with the same id in `ViewportBuilder` the render function for that viewport will be updated!
/// * `render`: will be called when the viewport receives a event or is requested to be rendered /// * `render`: will be called when the viewport receives a event or is requested to be rendered
/// ///
/// If this is no more called that viewport will be destroyed! /// If this is no more called that viewport will be destroyed!
/// ///
/// If you use a ```egui::CentralPanel``` you need to check if the viewport is a new window like: ```ctx.get_viewport_id() != ViewportId::MAIN``` /// If you use a `egui::CentralPanel` you need to check if the viewport is a new window like:
/// If the viewport id is ```ViewportId::MAIN``` you should create ```egui::Area``` then inside the area ```egui::Frame::popup(ctx.style())``` /// `ctx.viewport_id() != ctx.parent_viewport_id` if false you should create a `egui::Window`
pub fn create_viewport( pub fn create_viewport(
&self, &self,
viewport_builder: ViewportBuilder, viewport_builder: ViewportBuilder,
@@ -2633,13 +2624,18 @@ impl Context {
} }
} }
/// This can only be called in the main thread, you can use ```Context::create_viewport_async``` /// This can only be called in the main thread!
/// When this is called the current viewport will be paused /// When this is called the current viewport will be paused
/// This will render in a native window if he can! /// This will render in a native window if is possible!
/// When this finishes then the last viewport will continue drawing /// When this finishes then the last viewport will continue drawing
/// This is bad for performance but easy to use! /// This is bad for performance but easy to use!
/// ///
/// For better performance use `Context::create_viewport` /// For better performance use `Self::create_viewport`
///
/// If this is no more called that viewport will be destroyed!
///
/// If you use a `egui::CentralPanel` you need to check if the viewport is a new window like:
/// `ctx.viewport_id() != ctx.parent_viewport_id` if false you should create a `egui::Window`
pub fn create_viewport_sync<T>( pub fn create_viewport_sync<T>(
&self, &self,
viewport_builder: ViewportBuilder, viewport_builder: ViewportBuilder,

View File

@@ -55,7 +55,7 @@ pub type ViewportRenderSyncCallback =
dyn for<'a> Fn(&Context, ViewportBuilder, ViewportIdPair, Box<dyn FnOnce(&Context) + 'a>); dyn for<'a> Fn(&Context, ViewportBuilder, ViewportIdPair, Box<dyn FnOnce(&Context) + 'a>);
/// The filds in this struct should not be change directly, but is not problem tho! /// The filds in this struct should not be change directly, but is not problem tho!
/// Every thing is wrapped in ``Option<T>`` indicates that nothing changed from the last ``ViewportBuilder``! /// Every thing is wrapped in `Option<T>` indicates that nothing changed from the last `ViewportBuilder`!
#[derive(PartialEq, Eq, Clone)] #[derive(PartialEq, Eq, Clone)]
#[allow(clippy::option_option)] #[allow(clippy::option_option)]
pub struct ViewportBuilder { pub struct ViewportBuilder {
@@ -321,6 +321,7 @@ impl ViewportBuilder {
self self
} }
/// This will probably not work as expected!
pub fn with_position(mut self, value: Option<Pos2>) -> Self { pub fn with_position(mut self, value: Option<Pos2>) -> Self {
self.position = Some(value); self.position = Some(value);
self self
@@ -356,6 +357,8 @@ pub enum ViewportCommand {
Transparent(bool), Transparent(bool),
Visible(bool), Visible(bool),
Drag, Drag,
/// Will probably not work as expected!
OuterPosition(Pos2), OuterPosition(Pos2),
/// Should be bigger then 0 /// Should be bigger then 0
@@ -366,6 +369,8 @@ pub enum ViewportCommand {
/// Should be bigger then 0 /// Should be bigger then 0
MaxInnerSize(Option<Vec2>), MaxInnerSize(Option<Vec2>),
/// Should be bigger then 0
ResizeIncrements(Option<Vec2>), ResizeIncrements(Option<Vec2>),
/// Top, Bottom, Right, Left /// Top, Bottom, Right, Left
@@ -398,6 +403,7 @@ pub enum ViewportCommand {
ContentProtected(bool), ContentProtected(bool),
/// Will probably not work as expected!
CursorPosition(Pos2), CursorPosition(Pos2),
/// 0 = None, 1 = Confined, 2 = Locked /// 0 = None, 1 = Confined, 2 = Locked