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

Add ui.data(), ctx.data(), ctx.options() and ctx.tessellation_options() (#1175)

Helpful access deeper into Memory
This commit is contained in:
Emil Ernerfeldt
2022-01-29 17:53:41 +01:00
committed by GitHub
parent 3333d63b91
commit b618636425
19 changed files with 91 additions and 72 deletions

View File

@@ -15,11 +15,11 @@ pub(crate) struct State {
impl State {
pub fn load(ctx: &Context, id: Id) -> Option<Self> {
ctx.memory().data.get_persisted(id)
ctx.data().get_persisted(id)
}
pub fn store(self, ctx: &Context, id: Id) {
ctx.memory().data.insert_persisted(id, self);
ctx.data().insert_persisted(id, self);
}
pub fn from_memory_with_default_open(ctx: &Context, id: Id, default_open: bool) -> Self {

View File

@@ -25,11 +25,11 @@ struct PanelState {
impl PanelState {
fn load(ctx: &Context, bar_id: Id) -> Option<Self> {
ctx.memory().data.get_persisted(bar_id)
ctx.data().get_persisted(bar_id)
}
fn store(self, ctx: &Context, bar_id: Id) {
ctx.memory().data.insert_persisted(bar_id, self);
ctx.data().insert_persisted(bar_id, self);
}
}

View File

@@ -13,11 +13,11 @@ pub(crate) struct MonoState {
impl MonoState {
fn load(ctx: &Context) -> Option<Self> {
ctx.memory().data.get_temp(Id::null())
ctx.data().get_temp(Id::null())
}
fn store(self, ctx: &Context) {
ctx.memory().data.insert_temp(Id::null(), self);
ctx.data().insert_temp(Id::null(), self);
}
fn tooltip_size(&self, id: Id, index: usize) -> Option<Vec2> {

View File

@@ -18,11 +18,11 @@ pub(crate) struct State {
impl State {
pub fn load(ctx: &Context, id: Id) -> Option<Self> {
ctx.memory().data.get_persisted(id)
ctx.data().get_persisted(id)
}
pub fn store(self, ctx: &Context, id: Id) {
ctx.memory().data.insert_persisted(id, self);
ctx.data().insert_persisted(id, self);
}
}

View File

@@ -43,11 +43,11 @@ impl Default for State {
impl State {
pub fn load(ctx: &Context, id: Id) -> Option<Self> {
ctx.memory().data.get_persisted(id)
ctx.data().get_persisted(id)
}
pub fn store(self, ctx: &Context, id: Id) {
ctx.memory().data.insert_persisted(id, self);
ctx.data().insert_persisted(id, self);
}
}

View File

@@ -2,9 +2,9 @@
use crate::{
animation_manager::AnimationManager, data::output::Output, frame_state::FrameState,
input_state::*, layers::GraphicLayers, TextureHandle, *,
input_state::*, layers::GraphicLayers, memory::Options, TextureHandle, *,
};
use epaint::{mutex::*, stats::*, text::Fonts, *};
use epaint::{mutex::*, stats::*, text::Fonts, TessellationOptions, *};
// ----------------------------------------------------------------------------
@@ -444,20 +444,31 @@ impl Context {
/// ## Borrows parts of [`Context`]
impl Context {
/// Stores all the egui state.
///
/// If you want to store/restore egui, serialize this.
#[inline]
pub fn memory(&self) -> RwLockWriteGuard<'_, Memory> {
RwLockWriteGuard::map(self.write(), |c| &mut c.memory)
}
/// Stores superficial widget state.
#[inline]
pub fn data(&self) -> RwLockWriteGuard<'_, crate::util::IdTypeMap> {
RwLockWriteGuard::map(self.write(), |c| &mut c.memory.data)
}
#[inline]
pub(crate) fn graphics(&self) -> RwLockWriteGuard<'_, GraphicLayers> {
RwLockWriteGuard::map(self.write(), |c| &mut c.graphics)
}
/// What egui outputs each frame.
#[inline]
pub fn output(&self) -> RwLockWriteGuard<'_, Output> {
RwLockWriteGuard::map(self.write(), |c| &mut c.output)
}
#[inline]
pub(crate) fn frame_state(&self) -> RwLockWriteGuard<'_, FrameState> {
RwLockWriteGuard::map(self.write(), |c| &mut c.frame_state)
}
@@ -481,17 +492,19 @@ impl Context {
/// // This is fine!
/// }
/// ```
#[inline(always)]
#[inline]
pub fn input(&self) -> RwLockReadGuard<'_, InputState> {
RwLockReadGuard::map(self.read(), |c| &c.input)
}
#[inline]
pub fn input_mut(&self) -> RwLockWriteGuard<'_, InputState> {
RwLockWriteGuard::map(self.write(), |c| &mut c.input)
}
/// Not valid until first call to [`Context::run()`].
/// That's because since we don't know the proper `pixels_per_point` until then.
#[inline]
pub fn fonts(&self) -> RwLockReadGuard<'_, Fonts> {
RwLockReadGuard::map(self.read(), |c| {
c.fonts
@@ -500,9 +513,21 @@ impl Context {
})
}
#[inline]
fn fonts_mut(&self) -> RwLockWriteGuard<'_, Option<Fonts>> {
RwLockWriteGuard::map(self.write(), |c| &mut c.fonts)
}
#[inline]
pub fn options(&self) -> RwLockWriteGuard<'_, Options> {
RwLockWriteGuard::map(self.write(), |c| &mut c.memory.options)
}
/// Change the options used by the tessellator.
#[inline]
pub fn tessellation_options(&self) -> RwLockWriteGuard<'_, TessellationOptions> {
RwLockWriteGuard::map(self.write(), |c| &mut c.memory.options.tessellation_options)
}
}
impl Context {
@@ -533,7 +558,7 @@ impl Context {
/// The [`Style`] used by all subsequent windows, panels etc.
pub fn style(&self) -> Arc<Style> {
self.memory().options.style.clone()
self.options().style.clone()
}
/// The [`Style`] used by all new windows, panels etc.
@@ -548,7 +573,7 @@ impl Context {
/// ctx.set_style(style);
/// ```
pub fn set_style(&self, style: impl Into<Arc<Style>>) {
self.memory().options.style = style.into();
self.options().style = style.into();
}
/// The [`Visuals`] used by all subsequent windows, panels etc.
@@ -561,7 +586,7 @@ impl Context {
/// ctx.set_visuals(egui::Visuals::light()); // Switch to light mode
/// ```
pub fn set_visuals(&self, visuals: crate::Visuals) {
std::sync::Arc::make_mut(&mut self.memory().options.style).visuals = visuals;
std::sync::Arc::make_mut(&mut self.options().style).visuals = visuals;
}
/// The number of physical pixels for each logical point.
@@ -747,7 +772,7 @@ impl Context {
// shapes are the same, but just comparing the shapes takes about 50% of the time
// it takes to tessellate them, so it is not a worth optimization.
let mut tessellation_options = self.memory().options.tessellation_options;
let mut tessellation_options = *self.tessellation_options();
tessellation_options.pixels_per_point = self.pixels_per_point();
tessellation_options.aa_size = 1.0 / self.pixels_per_point();
let paint_stats = PaintStats::from_shapes(&shapes);
@@ -877,12 +902,12 @@ impl Context {
/// Wether or not to debug widget layout on hover.
pub fn debug_on_hover(&self) -> bool {
self.memory().options.style.debug.debug_on_hover
self.options().style.debug.debug_on_hover
}
/// Turn on/off wether or not to debug widget layout on hover.
pub fn set_debug_on_hover(&self, debug_on_hover: bool) {
let mut style = (*self.memory().options.style).clone();
let mut style = (*self.options().style).clone();
style.debug.debug_on_hover = debug_on_hover;
self.set_style(style);
}
@@ -956,10 +981,10 @@ impl Context {
CollapsingHeader::new("✒ Painting")
.default_open(true)
.show(ui, |ui| {
let mut tessellation_options = self.memory().options.tessellation_options;
let mut tessellation_options = self.options().tessellation_options;
tessellation_options.ui(ui);
ui.vertical_centered(|ui| reset_button(ui, &mut tessellation_options));
self.memory().options.tessellation_options = tessellation_options;
*self.tessellation_options() = tessellation_options;
});
}
@@ -1104,8 +1129,8 @@ impl Context {
*self.memory() = Default::default();
}
let num_state = self.memory().data.len();
let num_serialized = self.memory().data.count_serialized();
let num_state = self.data().len();
let num_serialized = self.data().count_serialized();
ui.label(format!(
"{} widget states stored (of which {} are serialized).",
num_state, num_serialized
@@ -1149,13 +1174,10 @@ impl Context {
ui.horizontal(|ui| {
ui.label(format!(
"{} collapsing headers",
self.memory()
.data
.count::<containers::collapsing_header::State>()
self.data().count::<containers::collapsing_header::State>()
));
if ui.button("Reset").clicked() {
self.memory()
.data
self.data()
.remove_by_type::<containers::collapsing_header::State>();
}
});
@@ -1163,30 +1185,30 @@ impl Context {
ui.horizontal(|ui| {
ui.label(format!(
"{} menu bars",
self.memory().data.count::<menu::BarState>()
self.data().count::<menu::BarState>()
));
if ui.button("Reset").clicked() {
self.memory().data.remove_by_type::<menu::BarState>();
self.data().remove_by_type::<menu::BarState>();
}
});
ui.horizontal(|ui| {
ui.label(format!(
"{} scroll areas",
self.memory().data.count::<scroll_area::State>()
self.data().count::<scroll_area::State>()
));
if ui.button("Reset").clicked() {
self.memory().data.remove_by_type::<scroll_area::State>();
self.data().remove_by_type::<scroll_area::State>();
}
});
ui.horizontal(|ui| {
ui.label(format!(
"{} resize areas",
self.memory().data.count::<resize::State>()
self.data().count::<resize::State>()
));
if ui.button("Reset").clicked() {
self.memory().data.remove_by_type::<resize::State>();
self.data().remove_by_type::<resize::State>();
}
});

View File

@@ -9,11 +9,11 @@ pub(crate) struct State {
impl State {
pub fn load(ctx: &Context, id: Id) -> Option<Self> {
ctx.memory().data.get_persisted(id)
ctx.data().get_persisted(id)
}
pub fn store(self, ctx: &Context, id: Id) {
ctx.memory().data.insert_persisted(id, self);
ctx.data().insert_persisted(id, self);
}
fn set_min_col_width(&mut self, col: usize, width: f32) {

View File

@@ -423,7 +423,7 @@ impl Memory {
/// Popups are things like combo-boxes, color pickers, menus etc.
/// Only one can be be open at a time.
impl Memory {
pub fn is_popup_open(&mut self, popup_id: Id) -> bool {
pub fn is_popup_open(&self, popup_id: Id) -> bool {
self.popup == Some(popup_id) || self.everything_is_visible()
}

View File

@@ -30,14 +30,11 @@ pub(crate) struct BarState {
impl BarState {
fn load(ctx: &Context, bar_id: Id) -> Self {
ctx.memory()
.data
.get_temp::<Self>(bar_id)
.unwrap_or_default()
ctx.data().get_temp::<Self>(bar_id).unwrap_or_default()
}
fn store(self, ctx: &Context, bar_id: Id) {
ctx.memory().data.insert_temp(bar_id, self);
ctx.data().insert_temp(bar_id, self);
}
/// Show a menu at pointer if primary-clicked response.

View File

@@ -338,21 +338,27 @@ impl Ui {
self.ctx().input()
}
/// The `Memory` of the `Context` associated with the `Ui`.
/// The [`Memory`] of the [`Context`] associated with this ui.
/// Equivalent to `.ctx().memory()`.
#[inline]
pub fn memory(&self) -> RwLockWriteGuard<'_, Memory> {
self.ctx().memory()
}
/// The `Output` of the `Context` associated with the `Ui`.
/// Stores superficial widget state.
#[inline]
pub fn data(&self) -> RwLockWriteGuard<'_, crate::util::IdTypeMap> {
self.ctx().data()
}
/// The [`Output`] of the [`Context`] associated with this ui.
/// Equivalent to `.ctx().output()`.
#[inline]
pub fn output(&self) -> RwLockWriteGuard<'_, Output> {
self.ctx().output()
}
/// The `Fonts` of the `Context` associated with the `Ui`.
/// The [`Fonts`] of the [`Context`] associated with this ui.
/// Equivalent to `.ctx().fonts()`.
#[inline]
pub fn fonts(&self) -> RwLockReadGuard<'_, Fonts> {

View File

@@ -429,5 +429,5 @@ fn color_cache_set(ctx: &Context, rgba: impl Into<Rgba>, hsva: Hsva) {
// To ensure we keep hue slider when `srgba` is gray we store the full `Hsva` in a cache:
fn use_color_cache<R>(ctx: &Context, f: impl FnOnce(&mut FixedCache<Rgba, Hsva>) -> R) -> R {
f(ctx.memory().data.get_temp_mut_or_default(Id::null()))
f(ctx.data().get_temp_mut_or_default(Id::null()))
}

View File

@@ -39,11 +39,11 @@ struct PlotMemory {
impl PlotMemory {
pub fn load(ctx: &Context, id: Id) -> Option<Self> {
ctx.memory().data.get_persisted(id)
ctx.data().get_persisted(id)
}
pub fn store(self, ctx: &Context, id: Id) {
ctx.memory().data.insert_persisted(id, self);
ctx.data().insert_persisted(id, self);
}
}

View File

@@ -34,11 +34,11 @@ pub struct TextEditState {
impl TextEditState {
pub fn load(ctx: &Context, id: Id) -> Option<Self> {
ctx.memory().data.get_persisted(id)
ctx.data().get_persisted(id)
}
pub fn store(self, ctx: &Context, id: Id) {
ctx.memory().data.insert_persisted(id, self);
ctx.data().insert_persisted(id, self);
}
/// The the currently selected range of characters.