Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 1 commit into from Jan 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 4 additions & 3 deletions CHANGELOG.md
Expand Up @@ -15,8 +15,9 @@ NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui_w
* Added `TextStyle::resolve`.
* `Context::load_texture` to convert an image into a texture which can be displayed using e.g. `ui.image(texture, size)` ([#1110](https://github.com/emilk/egui/pull/1110)).
* Added `Ui::add_visible` and `Ui::add_visible_ui`.
* Added `CollapsingHeader::icon` to override the default open/close icon using a custom function. ([1147](https://github.com/emilk/egui/pull/1147))
* Added `Plot::x_axis_formatter` and `Plot::y_axis_formatter` for custom axis labels ([#1130](https://github.com/emilk/egui/pull/1130))
* Added `CollapsingHeader::icon` to override the default open/close icon using a custom function. ([1147](https://github.com/emilk/egui/pull/1147)).
* Added `Plot::x_axis_formatter` and `Plot::y_axis_formatter` for custom axis labels ([#1130](https://github.com/emilk/egui/pull/1130)).
* Added `ui.data()`, `ctx.data()`, `ctx.options()` and `ctx.tessellation_options()` ([#1175](https://github.com/emilk/egui/pull/1175)).

### Changed 🔧
* ⚠️ `Context::input` and `Ui::input` now locks a mutex. This can lead to a dead-lock is used in an `if let` binding!
Expand All @@ -42,9 +43,9 @@ NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui_w
* Fixed `enable_drag` for Windows ([#1108](https://github.com/emilk/egui/pull/1108)).

### Contributors 🙏
* [AlexxxRu](https://github.com/alexxxru): [#1108](https://github.com/emilk/egui/pull/1108).
* [danielkeller](https://github.com/danielkeller): [#1050](https://github.com/emilk/egui/pull/1050).
* [juancampa](https://github.com/juancampa): [#1147](https://github.com/emilk/egui/pull/1147).
* [AlexxxRu](https://github.com/alexxxru): [#1108](https://github.com/emilk/egui/pull/1108).


## 0.16.1 - 2021-12-31 - Add back `CtxRef::begin_frame,end_frame`
Expand Down
2 changes: 1 addition & 1 deletion egui-winit/src/lib.rs
Expand Up @@ -520,7 +520,7 @@ impl State {
egui_ctx: &egui::Context,
output: egui::Output,
) -> egui::TexturesDelta {
if egui_ctx.memory().options.screen_reader {
if egui_ctx.options().screen_reader {
self.screen_reader.speak(&output.events_description());
}

Expand Down
4 changes: 2 additions & 2 deletions egui/src/containers/collapsing_header.rs
Expand Up @@ -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 {
Expand Down
4 changes: 2 additions & 2 deletions egui/src/containers/panel.rs
Expand Up @@ -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);
}
}

Expand Down
4 changes: 2 additions & 2 deletions egui/src/containers/popup.rs
Expand Up @@ -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> {
Expand Down
4 changes: 2 additions & 2 deletions egui/src/containers/resize.rs
Expand Up @@ -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);
}
}

Expand Down
4 changes: 2 additions & 2 deletions egui/src/containers/scroll_area.rs
Expand Up @@ -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);
}
}

Expand Down
70 changes: 46 additions & 24 deletions egui/src/context.rs
Expand Up @@ -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, *};

// ----------------------------------------------------------------------------

Expand Down Expand Up @@ -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)
}
Expand All @@ -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
Expand All @@ -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 {
Expand Down Expand Up @@ -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.
Expand All @@ -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.
Expand All @@ -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.
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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;
});
}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -1149,44 +1174,41 @@ 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>();
}
});

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>();
}
});

Expand Down
4 changes: 2 additions & 2 deletions egui/src/grid.rs
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion egui/src/memory.rs
Expand Up @@ -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()
}

Expand Down
7 changes: 2 additions & 5 deletions egui/src/menu.rs
Expand Up @@ -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.
Expand Down
12 changes: 9 additions & 3 deletions egui/src/ui.rs
Expand Up @@ -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> {
Expand Down
2 changes: 1 addition & 1 deletion egui/src/widgets/color_picker.rs
Expand Up @@ -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()))
}