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

Put everything in Context behind the same Mutex #1050

Merged
merged 13 commits into from Jan 10, 2022
9 changes: 9 additions & 0 deletions CHANGELOG.md
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`.

### Fixed 🐛
* Context menu now respects the theme ([#1043](https://github.com/emilk/egui/pull/1043))
* Immovable windows can no longer incorrectly move ([#1049](https://github.com/emilk/egui/pull/1049))

### 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
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
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
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
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
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
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
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
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
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
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
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
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 @@ -763,7 +763,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