1
0
mirror of https://github.com/emilk/egui.git synced 2026-06-26 14:49:06 -04:00

Add Deref<Target = Context> for Ui (#7770)

* Closes https://github.com/emilk/egui/issues/4033
* Closes https://github.com/emilk/egui/pull/4072

This means you don't have to type `ui.ctx().foo` but just `ui.foo`

---------

Co-authored-by: obellish <obellish@mpilabels.com>
Co-authored-by: obellish <125279760+obellish@users.noreply.github.com>
This commit is contained in:
Emil Ernerfeldt
2025-12-14 16:25:28 +01:00
committed by GitHub
parent ce17f6c518
commit 5ea94dd0d7
2 changed files with 16 additions and 114 deletions

View File

@@ -1,34 +1,13 @@
#![warn(missing_docs)] // Let's keep `Ui` well-documented.
#![allow(clippy::use_self)]
use std::{any::Any, hash::Hash, ops::Deref, sync::Arc};
use emath::GuiRounding as _;
use epaint::mutex::RwLock;
use epaint::text::FontsView;
use std::{any::Any, hash::Hash, sync::Arc};
use crate::ClosableTag;
#[cfg(debug_assertions)]
use crate::Stroke;
use crate::containers::menu;
use crate::{
Align, Color32, Context, CursorIcon, DragAndDrop, Id, InnerResponse, InputState, IntoAtoms,
LayerId, Memory, Order, Painter, PlatformOutput, Pos2, Rangef, Rect, Response, Rgba, RichText,
Sense, Style, TextStyle, TextWrapMode, UiBuilder, UiKind, UiStack, UiStackInfo, Vec2,
WidgetRect, WidgetText,
containers::{CollapsingHeader, CollapsingResponse, Frame},
ecolor::Hsva,
emath, epaint, grid,
layout::{Direction, Layout},
pass_state,
placer::Placer,
pos2, style,
util::IdTypeMap,
vec2, widgets,
widgets::{
Button, Checkbox, DragValue, Hyperlink, Image, ImageSource, Label, Link, RadioButton,
Separator, Spinner, TextEdit, Widget, color_picker,
},
};
use crate::{containers::*, ecolor::*, layout::*, placer::Placer, widgets::*, *};
// ----------------------------------------------------------------------------
/// This is what you use to place widgets.
@@ -112,6 +91,16 @@ pub struct Ui {
min_rect_already_remembered: bool,
}
/// Allow using [`Ui`] like a [`Context`].
impl Deref for Ui {
type Target = Context;
#[inline]
fn deref(&self) -> &Self::Target {
self.ctx()
}
}
impl Ui {
// ------------------------------------------------------------------------
// Creation:
@@ -459,7 +448,7 @@ impl Ui {
&self.style.spacing
}
/// Mutably borrow internal [`Spacing`](crate::style::Spacing).
/// Mutably borrow internal [`Spacing`].
/// Changes apply to this [`Ui`] and its subsequent children.
///
/// Example:
@@ -794,93 +783,6 @@ impl Ui {
}
}
/// # Helpers for accessing the underlying [`Context`].
/// These functions all lock the [`Context`] owned by this [`Ui`].
/// Please see the documentation of [`Context`] for how locking works!
impl Ui {
/// Read-only access to the shared [`InputState`].
///
/// ```
/// # egui::__run_test_ui(|ui| {
/// if ui.input(|i| i.key_pressed(egui::Key::A)) {
/// // …
/// }
/// # });
/// ```
#[inline]
pub fn input<R>(&self, reader: impl FnOnce(&InputState) -> R) -> R {
self.ctx().input(reader)
}
/// Read-write access to the shared [`InputState`].
#[inline]
pub fn input_mut<R>(&self, writer: impl FnOnce(&mut InputState) -> R) -> R {
self.ctx().input_mut(writer)
}
/// Read-only access to the shared [`Memory`].
#[inline]
pub fn memory<R>(&self, reader: impl FnOnce(&Memory) -> R) -> R {
self.ctx().memory(reader)
}
/// Read-write access to the shared [`Memory`].
#[inline]
pub fn memory_mut<R>(&self, writer: impl FnOnce(&mut Memory) -> R) -> R {
self.ctx().memory_mut(writer)
}
/// Read-only access to the shared [`IdTypeMap`], which stores superficial widget state.
#[inline]
pub fn data<R>(&self, reader: impl FnOnce(&IdTypeMap) -> R) -> R {
self.ctx().data(reader)
}
/// Read-write access to the shared [`IdTypeMap`], which stores superficial widget state.
#[inline]
pub fn data_mut<R>(&self, writer: impl FnOnce(&mut IdTypeMap) -> R) -> R {
self.ctx().data_mut(writer)
}
/// Read-only access to the shared [`PlatformOutput`].
///
/// This is what egui outputs each frame.
///
/// ```
/// # let mut ctx = egui::Context::default();
/// ctx.output_mut(|o| o.cursor_icon = egui::CursorIcon::Progress);
/// ```
#[inline]
pub fn output<R>(&self, reader: impl FnOnce(&PlatformOutput) -> R) -> R {
self.ctx().output(reader)
}
/// Read-write access to the shared [`PlatformOutput`].
///
/// This is what egui outputs each frame.
///
/// ```
/// # let mut ctx = egui::Context::default();
/// ctx.output_mut(|o| o.cursor_icon = egui::CursorIcon::Progress);
/// ```
#[inline]
pub fn output_mut<R>(&self, writer: impl FnOnce(&mut PlatformOutput) -> R) -> R {
self.ctx().output_mut(writer)
}
/// Read-only access to [`FontsView`].
#[inline]
pub fn fonts<R>(&self, reader: impl FnOnce(&FontsView<'_>) -> R) -> R {
self.ctx().fonts(reader)
}
/// Read-write access to [`FontsView`].
#[inline]
pub fn fonts_mut<R>(&self, reader: impl FnOnce(&mut FontsView<'_>) -> R) -> R {
self.ctx().fonts_mut(reader)
}
}
// ------------------------------------------------------------------------
/// # Sizes etc
@@ -1432,7 +1334,7 @@ impl Ui {
crate::StrokeKind::Inside,
);
let stroke = Stroke::new(2.5, Color32::from_rgb(200, 0, 0));
let stroke = crate::Stroke::new(2.5, Color32::from_rgb(200, 0, 0));
let paint_line_seg = |a, b| self.painter().line_segment([a, b], stroke);
if debug_expand_width && too_wide {

View File

@@ -256,7 +256,7 @@ impl<'t> TextEdit<'t> {
/// so it is strongly suggested that you cache the results of any syntax highlighter
/// so as not to waste CPU highlighting the same string every frame.
///
/// The arguments is the enclosing [`Ui`] (so you can access e.g. [`Ui::fonts`]),
/// The arguments is the enclosing [`Ui`] (so you can access e.g. [`Context::fonts`]),
/// the text and the wrap width.
///
/// ```