Skip to content

Commit

Permalink
Put everything in Context behind the same Mutex (#1050)
Browse files Browse the repository at this point in the history
* Move all interior mutability from Context to CtxRef and make it a handle
* Rename `CtxRef` to `Context`
* The old `Context` is now `ContextImpl` and is non-pub
* Add benchmark Painter::rect

Co-authored-by: Daniel Keller <dklr433@gmail.com>
  • Loading branch information
emilk and danielkeller committed Jan 10, 2022
1 parent 225d2b5 commit d567341
Show file tree
Hide file tree
Showing 75 changed files with 549 additions and 494 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,21 @@ NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui_w
* Added `Ui::add_visible` and `Ui::add_visible_ui`.

### Changed 🔧
* ⚠️ `Context::input` and `Ui::input` now locks a mutex. This can lead to a dead-lock is used in an `if let` binding!
* `if let Some(pos) = ui.input().pointer.latest_pos()` and similar must now be rewritten on two lines, or with added `{}` around the righ-hand-side.
* Search for this problem in your code using the regex `if let .*input`.
* Renamed `CtxRef` to `Context` ([#1050](https://github.com/emilk/egui/pull/1050)).
* `Context` can now be cloned and stored between frames ([#1050](https://github.com/emilk/egui/pull/1050)).
* Renamed `Ui::visible` to `Ui::is_visible`.
* Split `Event::Text` into `Event::Text` and `Event::Paste` ([#1058](https://github.com/emilk/egui/pull/1058)).

### Fixed 🐛
* Context menu now respects the theme ([#1043](https://github.com/emilk/egui/pull/1043))

### Contributors 🙏
* [danielkeller](https://github.com/danielkeller): [#1050](https://github.com/emilk/egui/pull/1050).


## 0.16.1 - 2021-12-31 - Add back `CtxRef::begin_frame,end_frame`

### Added ⭐
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ Notable contributions by:
* [@AlexApps99](https://github.com/AlexApps99): [`egui_glow`](https://github.com/emilk/egui/pull/685).
* [@mankinskin](https://github.com/mankinskin): [Context menus](https://github.com/emilk/egui/pull/543).
* [@t18b219k](https://github.com/t18b219k): [Port glow painter to web](https://github.com/emilk/egui/pull/868).
* [@danielkeller](https://github.com/danielkeller): [`Context` refactor](https://github.com/emilk/egui/pull/1050).
* And [many more](https://github.com/emilk/egui/graphs/contributors?type=a).

egui is licensed under [MIT](LICENSE-MIT) OR [Apache-2.0](LICENSE-APACHE).
Expand Down
4 changes: 2 additions & 2 deletions eframe/examples/custom_font.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ impl epi::App for MyApp {

fn setup(
&mut self,
ctx: &egui::CtxRef,
ctx: &egui::Context,
_frame: &epi::Frame,
_storage: Option<&dyn epi::Storage>,
) {
Expand Down Expand Up @@ -51,7 +51,7 @@ impl epi::App for MyApp {
ctx.set_fonts(fonts);
}

fn update(&mut self, ctx: &egui::CtxRef, _frame: &epi::Frame) {
fn update(&mut self, ctx: &egui::Context, _frame: &epi::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
ui.heading("egui using custom fonts");
ui.text_edit_multiline(&mut self.text);
Expand Down
4 changes: 2 additions & 2 deletions eframe/examples/file_dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ impl epi::App for MyApp {
"Native file dialogs and drag-and-drop files"
}

fn update(&mut self, ctx: &egui::CtxRef, _frame: &epi::Frame) {
fn update(&mut self, ctx: &egui::Context, _frame: &epi::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
ui.label("Drag-and-drop files onto the window!");

Expand Down Expand Up @@ -57,7 +57,7 @@ impl epi::App for MyApp {
}

impl MyApp {
fn detect_files_being_dropped(&mut self, ctx: &egui::CtxRef) {
fn detect_files_being_dropped(&mut self, ctx: &egui::Context) {
use egui::*;

// Preview hovering files:
Expand Down
2 changes: 1 addition & 1 deletion eframe/examples/hello_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ impl epi::App for MyApp {
"My egui App"
}

fn update(&mut self, ctx: &egui::CtxRef, frame: &epi::Frame) {
fn update(&mut self, ctx: &egui::Context, frame: &epi::Frame) {
let Self { name, age } = self;

egui::CentralPanel::default().show(ctx, |ui| {
Expand Down
2 changes: 1 addition & 1 deletion eframe/examples/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ impl epi::App for MyApp {
"Show an image with eframe/egui"
}

fn update(&mut self, ctx: &egui::CtxRef, frame: &epi::Frame) {
fn update(&mut self, ctx: &egui::Context, frame: &epi::Frame) {
if self.texture.is_none() {
// Load the image:
let image_data = include_bytes!("rust-logo-256x256.png");
Expand Down
6 changes: 3 additions & 3 deletions eframe/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
//! "My egui App"
//! }
//!
//! fn update(&mut self, ctx: &egui::CtxRef, frame: &epi::Frame) {
//! fn update(&mut self, ctx: &egui::Context, frame: &epi::Frame) {
//! egui::CentralPanel::default().show(ctx, |ui| {
//! ui.heading("Hello World!");
//! });
Expand Down Expand Up @@ -129,7 +129,7 @@ pub fn start_web(canvas_id: &str, app: Box<dyn epi::App>) -> Result<(), wasm_bin
/// "My egui App"
/// }
///
/// fn update(&mut self, ctx: &egui::CtxRef, frame: &epi::Frame) {
/// fn update(&mut self, ctx: &egui::Context, frame: &epi::Frame) {
/// egui::CentralPanel::default().show(ctx, |ui| {
/// ui.heading("Hello World!");
/// });
Expand Down Expand Up @@ -160,7 +160,7 @@ pub fn run_native(app: Box<dyn epi::App>, native_options: epi::NativeOptions) ->
/// "My egui App"
/// }
///
/// fn update(&mut self, ctx: &egui::CtxRef, frame: &epi::Frame) {
/// fn update(&mut self, ctx: &egui::Context, frame: &epi::Frame) {
/// egui::CentralPanel::default().show(ctx, |ui| {
/// ui.heading("Hello World!");
/// });
Expand Down
6 changes: 3 additions & 3 deletions egui-winit/src/epi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ impl Persistence {
pub struct EpiIntegration {
frame: epi::Frame,
persistence: crate::epi::Persistence,
pub egui_ctx: egui::CtxRef,
pub egui_ctx: egui::Context,
egui_winit: crate::State,
pub app: Box<dyn epi::App>,
/// When set, it is time to quit
Expand All @@ -206,7 +206,7 @@ impl EpiIntegration {
persistence: crate::epi::Persistence,
app: Box<dyn epi::App>,
) -> Self {
let egui_ctx = egui::CtxRef::default();
let egui_ctx = egui::Context::default();

*egui_ctx.memory() = persistence.load_memory().unwrap_or_default();

Expand Down Expand Up @@ -250,7 +250,7 @@ impl EpiIntegration {
}

fn warm_up(&mut self, window: &winit::window::Window) {
let saved_memory = self.egui_ctx.memory().clone();
let saved_memory: egui::Memory = self.egui_ctx.memory().clone();
self.egui_ctx.memory().set_everything_is_visible(true);
let (_, tex_alloc_data, _) = self.update(window);
self.frame.lock().output.tex_allocation_data = tex_alloc_data; // handle it next frame
Expand Down
15 changes: 8 additions & 7 deletions egui/src/containers/area.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ pub(crate) struct Prepared {
impl Area {
pub fn show<R>(
self,
ctx: &CtxRef,
ctx: &Context,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> InnerResponse<R> {
let prepared = self.begin(ctx);
Expand All @@ -186,7 +186,7 @@ impl Area {
InnerResponse { inner, response }
}

pub(crate) fn begin(self, ctx: &CtxRef) -> Prepared {
pub(crate) fn begin(self, ctx: &Context) -> Prepared {
let Area {
id,
movable,
Expand Down Expand Up @@ -234,7 +234,7 @@ impl Area {
}
}

pub fn show_open_close_animation(&self, ctx: &CtxRef, frame: &Frame, is_open: bool) {
pub fn show_open_close_animation(&self, ctx: &Context, frame: &Frame, is_open: bool) {
// must be called first so animation managers know the latest state
let visibility_factor = ctx.animate_bool(self.id.with("close_animation"), is_open);

Expand Down Expand Up @@ -276,7 +276,7 @@ impl Prepared {
self.drag_bounds
}

pub(crate) fn content_ui(&self, ctx: &CtxRef) -> Ui {
pub(crate) fn content_ui(&self, ctx: &Context) -> Ui {
let screen_rect = ctx.input().screen_rect();

let bounds = if let Some(bounds) = self.drag_bounds {
Expand Down Expand Up @@ -317,7 +317,7 @@ impl Prepared {
}

#[allow(clippy::needless_pass_by_value)] // intentional to swallow up `content_ui`.
pub(crate) fn end(self, ctx: &CtxRef, content_ui: Ui) -> Response {
pub(crate) fn end(self, ctx: &Context, content_ui: Ui) -> Response {
let Prepared {
layer_id,
mut state,
Expand Down Expand Up @@ -370,8 +370,9 @@ impl Prepared {
}

fn pointer_pressed_on_area(ctx: &Context, layer_id: LayerId) -> bool {
if let Some(pointer_pos) = ctx.input().pointer.interact_pos() {
ctx.input().pointer.any_pressed() && ctx.layer_id_at(pointer_pos) == Some(layer_id)
if let Some(pointer_pos) = ctx.pointer_interact_pos() {
let any_pressed = ctx.input().pointer.any_pressed();
any_pressed && ctx.layer_id_at(pointer_pos) == Some(layer_id)
} else {
false
}
Expand Down
17 changes: 9 additions & 8 deletions egui/src/containers/panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ impl SidePanel {
let mut is_resizing = false;
if resizable {
let resize_id = id.with("__resize");
if let Some(pointer) = ui.input().pointer.latest_pos() {
if let Some(pointer) = ui.ctx().latest_pointer_pos() {
let we_are_on_top = ui
.ctx()
.layer_id_at(pointer)
Expand Down Expand Up @@ -284,7 +284,7 @@ impl SidePanel {
/// Show the panel at the top level.
pub fn show<R>(
self,
ctx: &CtxRef,
ctx: &Context,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> InnerResponse<R> {
self.show_dyn(ctx, Box::new(add_contents))
Expand All @@ -293,7 +293,7 @@ impl SidePanel {
/// Show the panel at the top level.
fn show_dyn<'c, R>(
self,
ctx: &CtxRef,
ctx: &Context,
add_contents: Box<dyn FnOnce(&mut Ui) -> R + 'c>,
) -> InnerResponse<R> {
let layer_id = LayerId::background();
Expand Down Expand Up @@ -485,7 +485,8 @@ impl TopBottomPanel {
let mut is_resizing = false;
if resizable {
let resize_id = id.with("__resize");
if let Some(pointer) = ui.input().pointer.latest_pos() {
let latest_pos = ui.input().pointer.latest_pos();
if let Some(pointer) = latest_pos {
let we_are_on_top = ui
.ctx()
.layer_id_at(pointer)
Expand Down Expand Up @@ -570,7 +571,7 @@ impl TopBottomPanel {
/// Show the panel at the top level.
pub fn show<R>(
self,
ctx: &CtxRef,
ctx: &Context,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> InnerResponse<R> {
self.show_dyn(ctx, Box::new(add_contents))
Expand All @@ -579,7 +580,7 @@ impl TopBottomPanel {
/// Show the panel at the top level.
fn show_dyn<'c, R>(
self,
ctx: &CtxRef,
ctx: &Context,
add_contents: Box<dyn FnOnce(&mut Ui) -> R + 'c>,
) -> InnerResponse<R> {
let layer_id = LayerId::background();
Expand Down Expand Up @@ -670,7 +671,7 @@ impl CentralPanel {
/// Show the panel at the top level.
pub fn show<R>(
self,
ctx: &CtxRef,
ctx: &Context,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> InnerResponse<R> {
self.show_dyn(ctx, Box::new(add_contents))
Expand All @@ -679,7 +680,7 @@ impl CentralPanel {
/// Show the panel at the top level.
fn show_dyn<'c, R>(
self,
ctx: &CtxRef,
ctx: &Context,
add_contents: Box<dyn FnOnce(&mut Ui) -> R + 'c>,
) -> InnerResponse<R> {
let available_rect = ctx.available_rect();
Expand Down
18 changes: 11 additions & 7 deletions egui/src/containers/popup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,11 @@ impl MonoState {
/// }
/// # });
/// ```
pub fn show_tooltip<R>(ctx: &CtxRef, id: Id, add_contents: impl FnOnce(&mut Ui) -> R) -> Option<R> {
pub fn show_tooltip<R>(
ctx: &Context,
id: Id,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> Option<R> {
show_tooltip_at_pointer(ctx, id, add_contents)
}

Expand All @@ -88,7 +92,7 @@ pub fn show_tooltip<R>(ctx: &CtxRef, id: Id, add_contents: impl FnOnce(&mut Ui)
/// # });
/// ```
pub fn show_tooltip_at_pointer<R>(
ctx: &CtxRef,
ctx: &Context,
id: Id,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> Option<R> {
Expand All @@ -104,7 +108,7 @@ pub fn show_tooltip_at_pointer<R>(
///
/// If the tooltip does not fit under the area, it tries to place it above it instead.
pub fn show_tooltip_for<R>(
ctx: &CtxRef,
ctx: &Context,
id: Id,
rect: &Rect,
add_contents: impl FnOnce(&mut Ui) -> R,
Expand All @@ -129,7 +133,7 @@ pub fn show_tooltip_for<R>(
///
/// Returns `None` if the tooltip could not be placed.
pub fn show_tooltip_at<R>(
ctx: &CtxRef,
ctx: &Context,
id: Id,
suggested_position: Option<Pos2>,
add_contents: impl FnOnce(&mut Ui) -> R,
Expand All @@ -146,7 +150,7 @@ pub fn show_tooltip_at<R>(
}

fn show_tooltip_at_avoid_dyn<'c, R>(
ctx: &CtxRef,
ctx: &Context,
mut id: Id,
suggested_position: Option<Pos2>,
above: bool,
Expand Down Expand Up @@ -229,15 +233,15 @@ fn show_tooltip_at_avoid_dyn<'c, R>(
/// }
/// # });
/// ```
pub fn show_tooltip_text(ctx: &CtxRef, id: Id, text: impl Into<WidgetText>) -> Option<()> {
pub fn show_tooltip_text(ctx: &Context, id: Id, text: impl Into<WidgetText>) -> Option<()> {
show_tooltip(ctx, id, |ui| {
crate::widgets::Label::new(text).ui(ui);
})
}

/// Show a pop-over window.
fn show_tooltip_area_dyn<'c, R>(
ctx: &CtxRef,
ctx: &Context,
id: Id,
window_pos: Pos2,
add_contents: Box<dyn FnOnce(&mut Ui) -> R + 'c>,
Expand Down
7 changes: 3 additions & 4 deletions egui/src/containers/scroll_area.rs
Original file line number Diff line number Diff line change
Expand Up @@ -523,12 +523,11 @@ impl Prepared {
};
let content_response = ui.interact(inner_rect, id.with("area"), sense);

let input = ui.input();
if content_response.dragged() {
for d in 0..2 {
if has_bar[d] {
state.offset[d] -= input.pointer.delta()[d];
state.vel[d] = input.pointer.velocity()[d];
state.offset[d] -= ui.input().pointer.delta()[d];
state.vel[d] = ui.input().pointer.velocity()[d];
state.scroll_stuck_to_end[d] = false;
} else {
state.vel[d] = 0.0;
Expand All @@ -537,7 +536,7 @@ impl Prepared {
} else {
let stop_speed = 20.0; // Pixels per second.
let friction_coeff = 1000.0; // Pixels per second squared.
let dt = input.unstable_dt;
let dt = ui.input().unstable_dt;

let friction = friction_coeff * dt;
if friction > state.vel.length() || state.vel.length() < stop_speed {
Expand Down
8 changes: 4 additions & 4 deletions egui/src/containers/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,15 +235,15 @@ impl<'open> Window<'open> {
#[inline]
pub fn show<R>(
self,
ctx: &CtxRef,
ctx: &Context,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> Option<InnerResponse<Option<R>>> {
self.show_dyn(ctx, Box::new(add_contents))
}

fn show_dyn<'c, R>(
self,
ctx: &CtxRef,
ctx: &Context,
add_contents: Box<dyn FnOnce(&mut Ui) -> R + 'c>,
) -> Option<InnerResponse<Option<R>>> {
let Window {
Expand Down Expand Up @@ -296,7 +296,7 @@ impl<'open> Window<'open> {
.and_then(|window_interaction| {
// Calculate roughly how much larger the window size is compared to the inner rect
let title_bar_height = if with_title_bar {
title.font_height(ctx.fonts(), &ctx.style()) + title_content_spacing
title.font_height(ctx) + title_content_spacing
} else {
0.0
};
Expand Down Expand Up @@ -757,7 +757,7 @@ fn show_title_bar(
) -> TitleBar {
let inner_response = ui.horizontal(|ui| {
let height = title
.font_height(ui.fonts(), ui.style())
.font_height(ui.ctx())
.max(ui.spacing().interact_size.y);
ui.set_min_height(height);

Expand Down
Loading

0 comments on commit d567341

Please sign in to comment.