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

Remove everything that was marked #[deprecated] (#8105)

Simplify. Streamline. Spring cleaning.
This commit is contained in:
Emil Ernerfeldt
2026-04-14 20:19:36 +02:00
committed by GitHub
parent fe5533e450
commit 1cd89b5edc
52 changed files with 78 additions and 2633 deletions

View File

@@ -2,7 +2,7 @@
//!
//! `epi` provides interfaces for window management and serialization.
//!
//! Start by looking at the [`App`] trait, and implement [`App::update`].
//! Start by looking at the [`App`] trait, and implement [`App::ui`].
#![warn(missing_docs)] // Let's keep `epi` well-documented.
@@ -161,22 +161,6 @@ pub trait App {
/// (A "viewport" in egui means an native OS window).
fn ui(&mut self, ui: &mut egui::Ui, frame: &mut Frame);
/// Called each time the UI needs repainting, which may be many times per second.
///
/// Put your widgets into a [`egui::Panel`], [`egui::CentralPanel`], [`egui::Window`] or [`egui::Area`].
///
/// The [`egui::Context`] can be cloned and saved if you like.
///
/// To force a repaint, call [`egui::Context::request_repaint`] at any time (e.g. from another thread).
///
/// This is called for the root viewport ([`egui::ViewportId::ROOT`]).
/// Use [`egui::Context::show_viewport_deferred`] to spawn additional viewports (windows).
/// (A "viewport" in egui means an native OS window).
#[deprecated = "Use Self::ui instead"]
fn update(&mut self, ctx: &egui::Context, frame: &mut Frame) {
_ = (ctx, frame);
}
/// Get a handle to the app.
///
/// Can be used from web to interact or other external context.
@@ -256,7 +240,7 @@ pub trait App {
true
}
/// A hook for manipulating or filtering raw input before it is processed by [`Self::update`].
/// A hook for manipulating or filtering raw input before it is processed by [`Self::ui`].
///
/// This function provides a way to modify or filter input events before they are processed by egui.
///
@@ -780,7 +764,7 @@ impl Frame {
/// * Read the pixel buffer from the previous frame (`glow::Context::read_pixels`).
/// * Render things behind the egui windows.
///
/// Note that all egui painting is deferred to after the call to [`App::update`]
/// Note that all egui painting is deferred to after the call to [`App::ui`]
/// ([`egui`] only collects [`egui::Shape`]s and then eframe paints them all in one go later on).
///
/// To get a [`glow`] context you need to compile with the `glow` feature flag,
@@ -886,7 +870,7 @@ pub struct IntegrationInfo {
/// Seconds of cpu usage (in seconds) on the previous frame.
///
/// This includes [`App::update`] as well as rendering (except for vsync waiting).
/// This includes [`App::ui`] as well as rendering (except for vsync waiting).
///
/// For a more detailed view of cpu usage, connect your preferred profiler by enabling it's feature in [`profiling`](https://crates.io/crates/profiling).
///

View File

@@ -6,7 +6,7 @@
//! To get started, see the [examples](https://github.com/emilk/egui/tree/main/examples).
//! To learn how to set up `eframe` for web and native, go to <https://github.com/emilk/eframe_template/> and follow the instructions there!
//!
//! In short, you implement [`App`] (especially [`App::update`]) and then
//! In short, you implement [`App`] (especially [`App::ui`]) and then
//! call [`crate::run_native`] from your `main.rs`, and/or use `eframe::WebRunner` from your `lib.rs`.
//!
//! ## Compiling for web
@@ -19,7 +19,7 @@
//!
//! ## Simplified usage
//! If your app is only for native, and you don't need advanced features like state persistence,
//! then you can use the simpler function [`run_simple_native`].
//! then you can use the simpler function [`run_ui_native`].
//!
//! ## Usage, native:
//! ``` no_run
@@ -446,67 +446,6 @@ pub fn run_ui_native(
)
}
/// The simplest way to get started when writing a native app.
///
/// This does NOT support persistence of custom user data. For that you need to use [`run_native`].
/// However, it DOES support persistence of egui data (window positions and sizes, how far the user has scrolled in a
/// [`ScrollArea`](egui::ScrollArea), etc.) if the persistence feature is enabled.
///
/// # Example
/// ``` no_run
/// fn main() -> eframe::Result {
/// // Our application state:
/// let mut name = "Arthur".to_owned();
/// let mut age = 42;
///
/// let options = eframe::NativeOptions::default();
/// eframe::run_simple_native("My egui App", options, move |ctx, _frame| {
/// egui::CentralPanel::default().show(ctx, |ui| {
/// ui.heading("My egui Application");
/// ui.horizontal(|ui| {
/// let name_label = ui.label("Your name: ");
/// ui.text_edit_singleline(&mut name)
/// .labelled_by(name_label.id);
/// });
/// ui.add(egui::Slider::new(&mut age, 0..=120).text("age"));
/// if ui.button("Increment").clicked() {
/// age += 1;
/// }
/// ui.label(format!("Hello '{name}', age {age}"));
/// });
/// })
/// }
/// ```
///
/// # Errors
/// This function can fail if we fail to set up a graphics context.
#[deprecated = "Use run_ui_native instead"]
#[cfg(not(target_arch = "wasm32"))]
#[cfg(any(feature = "glow", feature = "wgpu_no_default_features"))]
pub fn run_simple_native(
app_name: &str,
native_options: NativeOptions,
update_fun: impl FnMut(&egui::Context, &mut Frame) + 'static,
) -> Result {
struct SimpleApp<U> {
update_fun: U,
}
impl<U: FnMut(&egui::Context, &mut Frame) + 'static> App for SimpleApp<U> {
fn ui(&mut self, _ui: &mut egui::Ui, _frame: &mut Frame) {}
fn update(&mut self, ctx: &egui::Context, frame: &mut Frame) {
(self.update_fun)(ctx, frame);
}
}
run_native(
app_name,
native_options,
Box::new(|_cc| Ok(Box::new(SimpleApp { update_fun }))),
)
}
// ----------------------------------------------------------------------------
/// The different problems that can occur when trying to run `eframe`.

View File

@@ -259,7 +259,7 @@ impl EpiIntegration {
/// Run user code - this can create immediate viewports, so hold no locks over this!
///
/// If `viewport_ui_cb` is None, we are in the root viewport and will call [`crate::App::update`].
/// If `viewport_ui_cb` is None, we are in the root viewport and will call [`crate::App::ui`].
pub fn update(
&mut self,
app: &mut dyn epi::App,
@@ -287,12 +287,6 @@ impl EpiIntegration {
}
if is_visible {
{
profiling::scope!("App::update");
#[expect(deprecated)]
app.update(ui.ctx(), &mut self.frame);
}
{
profiling::scope!("App::ui");
app.ui(ui, &mut self.frame);

View File

@@ -284,9 +284,6 @@ impl AppRunner {
self.app.logic(ui.ctx(), &mut self.frame);
if is_visible {
#[expect(deprecated)]
self.app.update(ui.ctx(), &mut self.frame);
self.app.ui(ui, &mut self.frame);
}
});

View File

@@ -280,7 +280,7 @@ impl Area {
self
}
/// Constrains this area to [`Context::screen_rect`]?
/// Constrains this area to [`Context::content_rect`]?
///
/// Default: `true`.
#[inline]
@@ -291,7 +291,7 @@ impl Area {
/// Constrain the movement of the window to the given rectangle.
///
/// For instance: `.constrain_to(ctx.screen_rect())`.
/// For instance: `.constrain_to(ctx.content_rect())`.
#[inline]
pub fn constrain_to(mut self, constrain_rect: Rect) -> Self {
self.constrain = true;

View File

@@ -451,15 +451,6 @@ impl CollapsingHeader {
self
}
/// Explicitly set the source of the [`Id`] of this widget, instead of using title label.
/// This is useful if the title label is dynamic or not unique.
#[deprecated = "Renamed id_salt"]
#[inline]
pub fn id_source(mut self, id_salt: impl Hash) -> Self {
self.id_salt = Id::new(id_salt);
self
}
/// If you set this to `false`, the [`CollapsingHeader`] will be grayed out and un-clickable.
///
/// This is a convenience for [`Ui::disable`].

View File

@@ -94,12 +94,6 @@ impl ComboBox {
}
}
/// Without label.
#[deprecated = "Renamed from_id_salt"]
pub fn from_id_source(id_salt: impl std::hash::Hash) -> Self {
Self::from_id_salt(id_salt)
}
/// Set the outer width of the button and menu.
///
/// Default is [`Spacing::combo_width`].

View File

@@ -174,11 +174,6 @@ impl Frame {
Self::NONE
}
#[deprecated = "Use `Frame::NONE` or `Frame::new()` instead."]
pub const fn none() -> Self {
Self::NONE
}
/// For when you want to group a few widgets together within a frame.
pub fn group(style: &Style) -> Self {
Self::new()
@@ -283,16 +278,6 @@ impl Frame {
self
}
/// The rounding of the _outer_ corner of the [`Self::stroke`]
/// (or, if there is no stroke, the outer corner of [`Self::fill`]).
///
/// In other words, this is the corner radius of the _widget rect_.
#[inline]
#[deprecated = "Renamed to `corner_radius`"]
pub fn rounding(self, corner_radius: impl Into<CornerRadius>) -> Self {
self.corner_radius(corner_radius)
}
/// Margin outside the painted frame.
///
/// Similar to what is called `margin` in CSS.

View File

@@ -197,7 +197,7 @@ impl MenuState {
/// Horizontal menu bar where you can add [`MenuButton`]s.
///
/// The menu bar goes well in a [`crate::TopBottomPanel::top`],
/// The menu bar goes well in a [`crate::Panel::top`],
/// but can also be placed in a [`crate::Window`].
/// In the latter case you may want to wrap it in [`Frame`].
///
@@ -219,9 +219,6 @@ pub struct MenuBar {
style: StyleModifier,
}
#[deprecated = "Renamed to `egui::MenuBar`"]
pub type Bar = MenuBar;
impl Default for MenuBar {
fn default() -> Self {
Self {

View File

@@ -9,7 +9,6 @@ mod combo_box;
pub mod frame;
pub mod menu;
pub mod modal;
pub mod old_popup;
pub mod panel;
mod popup;
pub(crate) mod resize;
@@ -26,7 +25,6 @@ pub use {
combo_box::*,
frame::Frame,
modal::{Modal, ModalResponse},
old_popup::*,
panel::*,
popup::*,
resize::Resize,

View File

@@ -1,212 +0,0 @@
//! Old and deprecated API for popups. Use [`Popup`] instead.
#![expect(deprecated)]
use crate::containers::tooltip::Tooltip;
use crate::{
Align, Context, Id, LayerId, Layout, Popup, PopupAnchor, PopupCloseBehavior, Pos2, Rect,
Response, Ui, Widget as _, WidgetText,
};
use emath::RectAlign;
// ----------------------------------------------------------------------------
/// Show a tooltip at the current pointer position (if any).
///
/// Most of the time it is easier to use [`Response::on_hover_ui`].
///
/// See also [`show_tooltip_text`].
///
/// Returns `None` if the tooltip could not be placed.
///
/// ```
/// # egui::__run_test_ui(|ui| {
/// # #[expect(deprecated)]
/// if ui.ui_contains_pointer() {
/// egui::show_tooltip(ui.ctx(), ui.layer_id(), egui::Id::new("my_tooltip"), |ui| {
/// ui.label("Helpful text");
/// });
/// }
/// # });
/// ```
#[deprecated = "Use `egui::Tooltip` instead"]
pub fn show_tooltip<R>(
ctx: &Context,
parent_layer: LayerId,
widget_id: Id,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> Option<R> {
show_tooltip_at_pointer(ctx, parent_layer, widget_id, add_contents)
}
/// Show a tooltip at the current pointer position (if any).
///
/// Most of the time it is easier to use [`Response::on_hover_ui`].
///
/// See also [`show_tooltip_text`].
///
/// Returns `None` if the tooltip could not be placed.
///
/// ```
/// # egui::__run_test_ui(|ui| {
/// if ui.ui_contains_pointer() {
/// egui::show_tooltip_at_pointer(ui.ctx(), ui.layer_id(), egui::Id::new("my_tooltip"), |ui| {
/// ui.label("Helpful text");
/// });
/// }
/// # });
/// ```
#[deprecated = "Use `egui::Tooltip` instead"]
pub fn show_tooltip_at_pointer<R>(
ctx: &Context,
parent_layer: LayerId,
widget_id: Id,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> Option<R> {
Tooltip::always_open(ctx.clone(), parent_layer, widget_id, PopupAnchor::Pointer)
.gap(12.0)
.show(add_contents)
.map(|response| response.inner)
}
/// Show a tooltip under the given area.
///
/// If the tooltip does not fit under the area, it tries to place it above it instead.
#[deprecated = "Use `egui::Tooltip` instead"]
pub fn show_tooltip_for<R>(
ctx: &Context,
parent_layer: LayerId,
widget_id: Id,
widget_rect: &Rect,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> Option<R> {
Tooltip::always_open(ctx.clone(), parent_layer, widget_id, *widget_rect)
.show(add_contents)
.map(|response| response.inner)
}
/// Show a tooltip at the given position.
///
/// Returns `None` if the tooltip could not be placed.
#[deprecated = "Use `egui::Tooltip` instead"]
pub fn show_tooltip_at<R>(
ctx: &Context,
parent_layer: LayerId,
widget_id: Id,
suggested_position: Pos2,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> Option<R> {
Tooltip::always_open(ctx.clone(), parent_layer, widget_id, suggested_position)
.show(add_contents)
.map(|response| response.inner)
}
/// Show some text at the current pointer position (if any).
///
/// Most of the time it is easier to use [`Response::on_hover_text`].
///
/// See also [`show_tooltip`].
///
/// Returns `None` if the tooltip could not be placed.
///
/// ```
/// # egui::__run_test_ui(|ui| {
/// if ui.ui_contains_pointer() {
/// egui::show_tooltip_text(ui.ctx(), ui.layer_id(), egui::Id::new("my_tooltip"), "Helpful text");
/// }
/// # });
/// ```
#[deprecated = "Use `egui::Tooltip` instead"]
pub fn show_tooltip_text(
ctx: &Context,
parent_layer: LayerId,
widget_id: Id,
text: impl Into<WidgetText>,
) -> Option<()> {
show_tooltip(ctx, parent_layer, widget_id, |ui| {
crate::widgets::Label::new(text).ui(ui);
})
}
/// Was this tooltip visible last frame?
#[deprecated = "Use `Tooltip::was_tooltip_open_last_frame` instead"]
pub fn was_tooltip_open_last_frame(ctx: &Context, widget_id: Id) -> bool {
Tooltip::was_tooltip_open_last_frame(ctx, widget_id)
}
/// Indicate whether a popup will be shown above or below the box.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum AboveOrBelow {
Above,
Below,
}
/// Helper for [`popup_above_or_below_widget`].
#[deprecated = "Use `egui::Popup` instead"]
pub fn popup_below_widget<R>(
ui: &Ui,
popup_id: Id,
widget_response: &Response,
close_behavior: PopupCloseBehavior,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> Option<R> {
popup_above_or_below_widget(
ui,
popup_id,
widget_response,
AboveOrBelow::Below,
close_behavior,
add_contents,
)
}
/// Shows a popup above or below another widget.
///
/// Useful for drop-down menus (combo boxes) or suggestion menus under text fields.
///
/// The opened popup will have a minimum width matching its parent.
///
/// You must open the popup with [`crate::Memory::open_popup`] or [`crate::Memory::toggle_popup`].
///
/// Returns `None` if the popup is not open.
///
/// ```
/// # egui::__run_test_ui(|ui| {
/// let response = ui.button("Open popup");
/// let popup_id = ui.make_persistent_id("my_unique_id");
/// if response.clicked() {
/// ui.memory_mut(|mem| mem.toggle_popup(popup_id));
/// }
/// let below = egui::AboveOrBelow::Below;
/// let close_on_click_outside = egui::PopupCloseBehavior::CloseOnClickOutside;
/// # #[expect(deprecated)]
/// egui::popup_above_or_below_widget(ui, popup_id, &response, below, close_on_click_outside, |ui| {
/// ui.set_min_width(200.0); // if you want to control the size
/// ui.label("Some more info, or things you can select:");
/// ui.label("…");
/// });
/// # });
/// ```
#[deprecated = "Use `egui::Popup` instead"]
pub fn popup_above_or_below_widget<R>(
_parent_ui: &Ui,
popup_id: Id,
widget_response: &Response,
above_or_below: AboveOrBelow,
close_behavior: PopupCloseBehavior,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> Option<R> {
let response = Popup::from_response(widget_response)
.layout(Layout::top_down_justified(Align::LEFT))
.open_memory(None)
.close_behavior(close_behavior)
.id(popup_id)
.align(match above_or_below {
AboveOrBelow::Above => RectAlign::TOP_START,
AboveOrBelow::Below => RectAlign::BOTTOM_START,
})
.width(widget_response.rect.width())
.show(|ui| {
ui.set_min_width(ui.available_width());
add_contents(ui)
})?;
Some(response.inner)
}

View File

@@ -18,9 +18,8 @@
use emath::{GuiRounding as _, Pos2};
use crate::{
Align, Context, CursorIcon, Frame, Id, InnerResponse, LayerId, Layout, NumExt as _, Rangef,
Rect, Sense, Stroke, Ui, UiBuilder, UiKind, UiStackInfo, Vec2, WidgetInfo, WidgetType, lerp,
vec2,
Align, Context, CursorIcon, Frame, Id, InnerResponse, Layout, NumExt as _, Rangef, Rect, Sense,
Stroke, Ui, UiBuilder, UiKind, UiStackInfo, Vec2, lerp, vec2,
};
fn animate_expansion(ctx: &Context, id: Id, is_expanded: bool) -> f32 {
@@ -451,59 +450,6 @@ impl Panel {
}
}
// Deprecated
impl Panel {
#[deprecated = "Renamed default_size"]
pub fn default_width(self, default_size: f32) -> Self {
self.default_size(default_size)
}
#[deprecated = "Renamed min_size"]
pub fn min_width(self, min_size: f32) -> Self {
self.min_size(min_size)
}
#[deprecated = "Renamed max_size"]
pub fn max_width(self, max_size: f32) -> Self {
self.max_size(max_size)
}
#[deprecated = "Renamed size_range"]
pub fn width_range(self, size_range: impl Into<Rangef>) -> Self {
self.size_range(size_range)
}
#[deprecated = "Renamed exact_size"]
pub fn exact_width(self, size: f32) -> Self {
self.exact_size(size)
}
#[deprecated = "Renamed default_size"]
pub fn default_height(self, default_size: f32) -> Self {
self.default_size(default_size)
}
#[deprecated = "Renamed min_size"]
pub fn min_height(self, min_size: f32) -> Self {
self.min_size(min_size)
}
#[deprecated = "Renamed max_size"]
pub fn max_height(self, max_size: f32) -> Self {
self.max_size(max_size)
}
#[deprecated = "Renamed size_range"]
pub fn height_range(self, size_range: impl Into<Rangef>) -> Self {
self.size_range(size_range)
}
#[deprecated = "Renamed exact_size"]
pub fn exact_height(self, size: f32) -> Self {
self.exact_size(size)
}
}
// Public showing methods
impl Panel {
/// Show the panel inside a [`Ui`].
@@ -515,41 +461,6 @@ impl Panel {
self.show_inside_dyn(ui, Box::new(add_contents))
}
/// Show the panel at the top level.
#[deprecated = "Use show_inside() instead"]
pub fn show<R>(
self,
ctx: &Context,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> InnerResponse<R> {
self.show_dyn(ctx, Box::new(add_contents))
}
/// Show the panel if `is_expanded` is `true`,
/// otherwise don't show it, but with a nice animation between collapsed and expanded.
#[deprecated = "Use show_animated_inside() instead"]
pub fn show_animated<R>(
self,
ctx: &Context,
is_expanded: bool,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> Option<InnerResponse<R>> {
#![expect(deprecated)]
let how_expanded = animate_expansion(ctx, self.id.with("animation"), is_expanded);
let animated_panel = self.get_animated_panel(ctx, is_expanded)?;
if how_expanded < 1.0 {
// Show a fake panel in this in-between animation state:
animated_panel.show(ctx, |_ui| {});
None
} else {
// Show the real panel:
Some(animated_panel.show(ctx, add_contents))
}
}
/// Show the panel if `is_expanded` is `true`,
/// otherwise don't show it, but with a nice animation between collapsed and expanded.
pub fn show_animated_inside<R>(
@@ -577,34 +488,6 @@ impl Panel {
}
}
/// Show either a collapsed or a expanded panel, with a nice animation between.
#[deprecated = "Use show_animated_between_inside() instead"]
pub fn show_animated_between<R>(
ctx: &Context,
is_expanded: bool,
collapsed_panel: Self,
expanded_panel: Self,
add_contents: impl FnOnce(&mut Ui, f32) -> R,
) -> Option<InnerResponse<R>> {
#![expect(deprecated)]
let how_expanded = animate_expansion(ctx, expanded_panel.id.with("animation"), is_expanded);
// Get either the fake or the real panel to animate
let animated_between_panel =
Self::get_animated_between_panel(ctx, is_expanded, collapsed_panel, expanded_panel);
if 0.0 == how_expanded {
Some(animated_between_panel.show(ctx, |ui| add_contents(ui, how_expanded)))
} else if how_expanded < 1.0 {
// Show animation:
animated_between_panel.show(ctx, |ui| add_contents(ui, how_expanded));
None
} else {
Some(animated_between_panel.show(ctx, |ui| add_contents(ui, how_expanded)))
}
}
/// Show either a collapsed or a expanded panel, with a nice animation between.
pub fn show_animated_between_inside<R>(
ui: &mut Ui,
@@ -756,59 +639,6 @@ impl Panel {
inner_response
}
/// Show the panel at the top level.
fn show_dyn<'c, R>(
self,
ctx: &Context,
add_contents: Box<dyn FnOnce(&mut Ui) -> R + 'c>,
) -> InnerResponse<R> {
#![expect(deprecated)]
let side = self.side;
let available_rect = ctx.available_rect();
let mut panel_ui = Ui::new(
ctx.clone(),
self.id,
UiBuilder::new()
.layer_id(LayerId::background())
.max_rect(available_rect),
);
panel_ui.set_clip_rect(ctx.content_rect());
panel_ui
.response()
.widget_info(|| WidgetInfo::new(WidgetType::Panel));
let inner_response = self.show_inside_dyn(&mut panel_ui, add_contents);
let rect = inner_response.response.rect;
match side {
PanelSide::Vertical(side) => match side {
VerticalSide::Left => ctx.pass_state_mut(|state| {
state.allocate_left_panel(Rect::from_min_max(available_rect.min, rect.max));
}),
VerticalSide::Right => ctx.pass_state_mut(|state| {
state.allocate_right_panel(Rect::from_min_max(rect.min, available_rect.max));
}),
},
PanelSide::Horizontal(side) => match side {
HorizontalSide::Top => {
ctx.pass_state_mut(|state| {
state.allocate_top_panel(Rect::from_min_max(available_rect.min, rect.max));
});
}
HorizontalSide::Bottom => {
ctx.pass_state_mut(|state| {
state.allocate_bottom_panel(Rect::from_min_max(
rect.min,
available_rect.max,
));
});
}
},
}
inner_response
}
fn prepare_resizable_panel(&self, panel_sizer: &mut PanelSizer<'_>, ui: &Ui) {
let resize_id = self.id.with("__resize");
let resize_response = ui.ctx().read_response(resize_id);
@@ -1044,61 +874,9 @@ impl CentralPanel {
response
}
/// Show the panel at the top level.
#[deprecated = "Use show_inside() instead"]
pub fn show<R>(
self,
ctx: &Context,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> InnerResponse<R> {
self.show_dyn(ctx, Box::new(add_contents))
}
/// Show the panel at the top level.
fn show_dyn<'c, R>(
self,
ctx: &Context,
add_contents: Box<dyn FnOnce(&mut Ui) -> R + 'c>,
) -> InnerResponse<R> {
#![expect(deprecated)]
let id = Id::new((ctx.viewport_id(), "central_panel"));
let mut panel_ui = Ui::new(
ctx.clone(),
id,
UiBuilder::new()
.layer_id(LayerId::background())
.max_rect(ctx.available_rect()),
);
panel_ui.set_clip_rect(ctx.content_rect());
if false {
// TODO(emilk): @lucasmerlin shouldn't we enable this?
panel_ui
.response()
.widget_info(|| WidgetInfo::new(WidgetType::Panel));
}
let inner_response = self.show_inside_dyn(&mut panel_ui, add_contents);
// Only inform ctx about what we actually used, so we can shrink the native window to fit.
ctx.pass_state_mut(|state| state.allocate_central_panel(inner_response.response.rect));
inner_response
}
}
fn clamp_to_range(x: f32, range: Rangef) -> f32 {
let range = range.as_positive();
x.clamp(range.min, range.max)
}
// ----------------------------------------------------------------------------
#[deprecated = "Use Panel::left or Panel::right instead"]
pub type SidePanel = super::Panel;
#[deprecated = "Use Panel::top or Panel::bottom instead"]
pub type TopBottomPanel = super::Panel;

View File

@@ -1,5 +1,3 @@
#![expect(deprecated)] // This is a new, safe wrapper around the old `Memory::popup` API.
use std::iter::once;
use emath::{Align, Pos2, Rect, RectAlign, Vec2, vec2};
@@ -87,7 +85,7 @@ pub enum PopupCloseBehavior {
/// but in the popup's body
CloseOnClickOutside,
/// Clicks will be ignored. Popup might be closed manually by calling [`crate::Memory::close_all_popups`]
/// Clicks will be ignored. Popup might be closed manually by calling [`Popup::close_all`]
/// or by pressing the escape button
IgnoreClicks,
}
@@ -666,10 +664,6 @@ impl Popup<'_> {
}
/// Open the given popup and close all others.
///
/// If you are NOT using [`Popup::show`], you must
/// also call [`crate::Memory::keep_popup_open`] as long as
/// you're showing the popup.
pub fn open_id(ctx: &Context, popup_id: Id) {
ctx.memory_mut(|mem| mem.open_popup(popup_id));
}

View File

@@ -69,13 +69,6 @@ impl Resize {
self
}
/// A source for the unique [`Id`], e.g. `.id_source("second_resize_area")` or `.id_source(loop_index)`.
#[inline]
#[deprecated = "Renamed id_salt"]
pub fn id_source(self, id_salt: impl std::hash::Hash) -> Self {
self.id_salt(id_salt)
}
/// A source for the unique [`Id`], e.g. `.id_salt("second_resize_area")` or `.id_salt(loop_index)`.
#[inline]
pub fn id_salt(mut self, id_salt: impl std::hash::Hash) -> Self {

View File

@@ -423,13 +423,6 @@ impl ScrollArea {
self
}
/// A source for the unique [`Id`], e.g. `.id_source("second_scroll_area")` or `.id_source(loop_index)`.
#[inline]
#[deprecated = "Renamed id_salt"]
pub fn id_source(self, id_salt: impl std::hash::Hash) -> Self {
self.id_salt(id_salt)
}
/// A source for the unique [`Id`], e.g. `.id_salt("second_scroll_area")` or `.id_salt(loop_index)`.
#[inline]
pub fn id_salt(mut self, id_salt: impl std::hash::Hash) -> Self {
@@ -530,32 +523,6 @@ impl ScrollArea {
/// This can be used, for example, to optionally freeze scrolling while the user
/// is typing text in a [`crate::TextEdit`] widget contained within the scroll area.
///
/// This controls both scrolling directions.
#[deprecated = "Use `ScrollArea::scroll_source()"]
#[inline]
pub fn enable_scrolling(mut self, enable: bool) -> Self {
self.scroll_source = if enable {
ScrollSource::ALL
} else {
ScrollSource::NONE
};
self
}
/// Can the user drag the scroll area to scroll?
///
/// This is useful for touch screens.
///
/// If `true`, the [`ScrollArea`] will sense drags.
///
/// Default: `true`.
#[deprecated = "Use `ScrollArea::scroll_source()"]
#[inline]
pub fn drag_to_scroll(mut self, drag_to_scroll: bool) -> Self {
self.scroll_source.drag = drag_to_scroll;
self
}
/// What sources does the [`ScrollArea`] use for scrolling the contents.
#[inline]
pub fn scroll_source(mut self, scroll_source: ScrollSource) -> Self {

View File

@@ -16,24 +16,6 @@ pub struct Tooltip<'a> {
}
impl Tooltip<'_> {
/// Show a tooltip that is always open.
#[deprecated = "Use `Tooltip::always_open` instead."]
pub fn new(
parent_widget: Id,
ctx: Context,
anchor: impl Into<PopupAnchor>,
parent_layer: LayerId,
) -> Self {
Self {
popup: Popup::new(parent_widget, ctx, anchor.into(), parent_layer)
.kind(PopupKind::Tooltip)
.gap(4.0)
.sense(Sense::hover()),
parent_layer,
parent_widget,
}
}
/// Show a tooltip that is always open.
pub fn always_open(
ctx: Context,

View File

@@ -262,7 +262,7 @@ impl<'open> Window<'open> {
self
}
/// Constrains this window to [`Context::screen_rect`].
/// Constrains this window to [`Context::content_rect`].
///
/// To change the area to constrain to, use [`Self::constrain_to`].
///
@@ -275,7 +275,7 @@ impl<'open> Window<'open> {
/// Constrain the movement of the window to the given rectangle.
///
/// For instance: `.constrain_to(ctx.screen_rect())`.
/// For instance: `.constrain_to(ctx.content_rect())`.
#[inline]
pub fn constrain_to(mut self, constrain_rect: Rect) -> Self {
self.area = self.area.constrain_to(constrain_rect);
@@ -427,7 +427,7 @@ impl<'open> Window<'open> {
/// Enable/disable scrolling on the window by dragging with the pointer. `true` by default.
///
/// See [`ScrollArea::drag_to_scroll`] for more.
/// See [`ScrollArea::scroll_source`] for more.
#[inline]
pub fn drag_to_scroll(mut self, drag_to_scroll: bool) -> Self {
self.scroll = self.scroll.scroll_source(ScrollSource {

View File

@@ -300,7 +300,7 @@ impl RepaintCause {
struct ViewportRepaintInfo {
/// Monotonically increasing counter.
///
/// Incremented at the end of [`Context::run`].
/// Incremented at the end of [`Context::run_ui`].
/// This can be smaller than [`Self::cumulative_pass_nr`],
/// but never larger.
cumulative_frame_nr: u64,
@@ -463,7 +463,7 @@ impl ContextImpl {
let content_rect = viewport.input.content_rect();
viewport.this_pass.begin_pass(content_rect);
viewport.this_pass.begin_pass();
{
let mut layers: Vec<LayerId> = viewport.prev_pass.widgets.layer_ids().collect();
@@ -697,8 +697,8 @@ impl ContextImpl {
/// // Game loop:
/// loop {
/// let raw_input = egui::RawInput::default();
/// let full_output = ctx.run(raw_input, |ctx| {
/// egui::CentralPanel::default().show(&ctx, |ui| {
/// let full_output = ctx.run_ui(raw_input, |ui| {
/// egui::CentralPanel::default().show_inside(ui, |ui| {
/// ui.label("Hello world!");
/// if ui.button("Click me").clicked() {
/// // take some action here
@@ -780,9 +780,6 @@ impl Context {
/// });
/// // handle full_output
/// ```
///
/// ## See also
/// * [`Self::run`]
#[must_use]
pub fn run_ui(&self, new_input: RawInput, mut run_ui: impl FnMut(&mut Ui)) -> FullOutput {
self.run_ui_dyn(new_input, &mut run_ui)
@@ -791,14 +788,13 @@ impl Context {
#[must_use]
fn run_ui_dyn(&self, new_input: RawInput, run_ui: &mut dyn FnMut(&mut Ui)) -> FullOutput {
let plugins = self.read(|ctx| ctx.plugins.ordered_plugins());
#[expect(deprecated)]
self.run(new_input, |ctx| {
self.run_dyn(new_input, &mut |ctx| {
let mut root_ui = Ui::new(
ctx.clone(),
Id::new((ctx.viewport_id(), "__top_ui")),
UiBuilder::new()
.layer_id(LayerId::background())
.max_rect(ctx.available_rect()),
.max_rect(ctx.viewport_rect()),
);
{
@@ -814,38 +810,6 @@ impl Context {
})
}
/// Run the ui code for one frame.
///
/// At most [`Options::max_passes`] calls will be issued to `run_ui`,
/// and only on the rare occasion that [`Context::request_discard`] is called.
/// Usually, it `run_ui` will only be called once.
///
/// Put your widgets into a [`crate::Panel`], [`crate::CentralPanel`], [`crate::Window`] or [`crate::Area`].
///
/// Instead of calling `run`, you can alternatively use [`Self::begin_pass`] and [`Context::end_pass`].
///
/// ```
/// // One egui context that you keep reusing:
/// let mut ctx = egui::Context::default();
///
/// // Each frame:
/// let input = egui::RawInput::default();
/// let full_output = ctx.run(input, |ctx| {
/// egui::CentralPanel::default().show(&ctx, |ui| {
/// ui.label("Hello egui!");
/// });
/// });
/// // handle full_output
/// ```
///
/// ## See also
/// * [`Self::run_ui`]
#[must_use]
#[deprecated = "Call run_ui instead"]
pub fn run(&self, new_input: RawInput, mut run_ui: impl FnMut(&Self)) -> FullOutput {
self.run_dyn(new_input, &mut run_ui)
}
#[must_use]
fn run_dyn(&self, mut new_input: RawInput, run_ui: &mut dyn FnMut(&Self)) -> FullOutput {
profiling::function_scope!();
@@ -915,10 +879,10 @@ impl Context {
output
}
/// An alternative to calling [`Self::run`].
/// An alternative to calling [`Self::run_ui`].
///
/// It is usually better to use [`Self::run`], because
/// `run` supports multi-pass layout using [`Self::request_discard`].
/// It is usually better to use [`Self::run_ui`], because
/// `run_ui` supports multi-pass layout using [`Self::request_discard`].
///
/// ```
/// // One egui context that you keep reusing:
@@ -928,9 +892,7 @@ impl Context {
/// let input = egui::RawInput::default();
/// ctx.begin_pass(input);
///
/// egui::CentralPanel::default().show(&ctx, |ui| {
/// ui.label("Hello egui!");
/// });
/// // … add panels and windows here …
///
/// let full_output = ctx.end_pass();
/// // handle full_output
@@ -943,12 +905,6 @@ impl Context {
self.write(|ctx| ctx.begin_pass(new_input));
}
/// See [`Self::begin_pass`].
#[deprecated = "Renamed begin_pass"]
pub fn begin_frame(&self, new_input: RawInput) {
self.begin_pass(new_input);
}
}
/// ## Borrows parts of [`Context`]
@@ -1049,7 +1005,7 @@ impl Context {
/// Read-only access to [`PassState`].
///
/// This is only valid during the call to [`Self::run`] (between [`Self::begin_pass`] and [`Self::end_pass`]).
/// This is only valid during the call to [`Self::run_ui`] (between [`Self::begin_pass`] and [`Self::end_pass`]).
#[inline]
pub(crate) fn pass_state<R>(&self, reader: impl FnOnce(&PassState) -> R) -> R {
self.write(move |ctx| reader(&ctx.viewport().this_pass))
@@ -1057,7 +1013,7 @@ impl Context {
/// Read-write access to [`PassState`].
///
/// This is only valid during the call to [`Self::run`] (between [`Self::begin_pass`] and [`Self::end_pass`]).
/// This is only valid during the call to [`Self::run_ui`] (between [`Self::begin_pass`] and [`Self::end_pass`]).
#[inline]
pub(crate) fn pass_state_mut<R>(&self, writer: impl FnOnce(&mut PassState) -> R) -> R {
self.write(move |ctx| writer(&mut ctx.viewport().this_pass))
@@ -1073,7 +1029,7 @@ impl Context {
/// Read-only access to [`Fonts`].
///
/// Not valid until first call to [`Context::run()`].
/// Not valid until first call to [`Context::run_ui()`].
/// That's because since we don't know the proper `pixels_per_point` until then.
#[inline]
pub fn fonts<R>(&self, reader: impl FnOnce(&FontsView<'_>) -> R) -> R {
@@ -1090,7 +1046,7 @@ impl Context {
/// Read-write access to [`Fonts`].
///
/// Not valid until first call to [`Context::run()`].
/// Not valid until first call to [`Context::run_ui()`].
/// That's because since we don't know the proper `pixels_per_point` until then.
#[inline]
pub fn fonts_mut<R>(&self, reader: impl FnOnce(&mut FontsView<'_>) -> R) -> R {
@@ -1666,7 +1622,7 @@ impl Context {
/// The total number of completed frames.
///
/// Starts at zero, and is incremented once at the end of each call to [`Self::run`].
/// Starts at zero, and is incremented once at the end of each call to [`Self::run_ui`].
///
/// This is always smaller or equal to [`Self::cumulative_pass_nr`].
pub fn cumulative_frame_nr(&self) -> u64 {
@@ -1675,7 +1631,7 @@ impl Context {
/// The total number of completed frames.
///
/// Starts at zero, and is incremented once at the end of each call to [`Self::run`].
/// Starts at zero, and is incremented once at the end of each call to [`Self::run_ui`].
///
/// This is always smaller or equal to [`Self::cumulative_pass_nr_for`].
pub fn cumulative_frame_nr_for(&self, id: ViewportId) -> u64 {
@@ -1695,7 +1651,7 @@ impl Context {
/// The total number of completed passes (usually there is one pass per rendered frame).
///
/// Starts at zero, and is incremented for each completed pass inside of [`Self::run`] (usually once).
/// Starts at zero, and is incremented for each completed pass inside of [`Self::run_ui`] (usually once).
///
/// If you instead want to know which pass index this is within the current frame,
/// use [`Self::current_pass_index`].
@@ -1705,7 +1661,7 @@ impl Context {
/// The total number of completed passes (usually there is one pass per rendered frame).
///
/// Starts at zero, and is incremented for each completed pass inside of [`Self::run`] (usually once).
/// Starts at zero, and is incremented for each completed pass inside of [`Self::run_ui`] (usually once).
pub fn cumulative_pass_nr_for(&self, id: ViewportId) -> u64 {
self.read(|ctx| {
ctx.viewports
@@ -2080,7 +2036,7 @@ impl Context {
self.options(|opt| opt.theme())
}
/// The [`Theme`] used to select between dark and light [`Self::style`]
/// The [`Theme`] used to select between dark and light [`Self::global_style`]
/// as the active style used by all subsequent popups, menus, etc.
///
/// Example:
@@ -2097,12 +2053,6 @@ impl Context {
self.options(|opt| Arc::clone(opt.style()))
}
/// The currently active [`Style`] used by all subsequent popups, menus, etc.
#[deprecated = "Renamed to `global_style` to avoid confusion with `ui.style()`"]
pub fn style(&self) -> Arc<Style> {
self.options(|opt| Arc::clone(opt.style()))
}
/// Mutate the currently active [`Style`] used by all subsequent popups, menus, etc.
/// Use [`Self::all_styles_mut`] to mutate both dark and light mode styles.
///
@@ -2117,21 +2067,6 @@ impl Context {
self.options_mut(|opt| mutate_style(Arc::make_mut(opt.style_mut())));
}
/// Mutate the currently active [`Style`] used by all subsequent popups, menus, etc.
/// Use [`Self::all_styles_mut`] to mutate both dark and light mode styles.
///
/// Example:
/// ```
/// # let mut ctx = egui::Context::default();
/// ctx.global_style_mut(|style| {
/// style.spacing.item_spacing = egui::vec2(10.0, 20.0);
/// });
/// ```
#[deprecated = "Renamed to `global_style_mut` to avoid confusion with `ui.style_mut()`"]
pub fn style_mut(&self, mutate_style: impl FnOnce(&mut Style)) {
self.options_mut(|opt| mutate_style(Arc::make_mut(opt.style_mut())));
}
/// The currently active [`Style`] used by all new popups, menus, etc.
///
/// Use [`Self::all_styles_mut`] to mutate both dark and light mode styles.
@@ -2143,18 +2078,6 @@ impl Context {
self.options_mut(|opt| *opt.style_mut() = style.into());
}
/// The currently active [`Style`] used by all new popups, menus, etc.
///
/// Use [`Self::all_styles_mut`] to mutate both dark and light mode styles.
///
/// You can also change this using [`Self::style_mut`].
///
/// You can use [`Ui::style_mut`] to change the style of a single [`Ui`].
#[deprecated = "Renamed to `set_global_style` to avoid confusion with `ui.set_style()`"]
pub fn set_style(&self, style: impl Into<Arc<Style>>) {
self.options_mut(|opt| *opt.style_mut() = style.into());
}
/// Mutate the [`Style`]s used by all subsequent popups, menus, etc. in both dark and light mode.
///
/// Example:
@@ -2418,13 +2341,6 @@ impl Context {
output
}
/// Call at the end of each frame if you called [`Context::begin_pass`].
#[must_use]
#[deprecated = "Renamed end_pass"]
pub fn end_frame(&self) -> FullOutput {
self.end_pass()
}
/// Called at the end of the pass.
#[cfg(debug_assertions)]
fn debug_painting(&self) {
@@ -2849,21 +2765,6 @@ impl Context {
self.input(|i| i.viewport_rect()).round_ui()
}
/// Position and size of the egui area.
#[deprecated(
note = "screen_rect has been split into viewport_rect() and content_rect(). You likely should use content_rect()"
)]
pub fn screen_rect(&self) -> Rect {
self.input(|i| i.content_rect()).round_ui()
}
/// How much space is still available after panels have been added.
#[deprecated = "Use content_rect (or viewport_rect) instead"]
pub fn available_rect(&self) -> Rect {
#[expect(deprecated)] // legacy
self.pass_state(|s| s.available_rect()).round_ui()
}
/// How much space is used by windows and the top-level [`Ui`].
pub fn globally_used_rect(&self) -> Rect {
self.write(|ctx| {
@@ -2871,10 +2772,7 @@ impl Context {
let root_ui_min_rect =
(viewport.this_pass.root_ui_min_rect).or(viewport.prev_pass.root_ui_min_rect);
let mut used = root_ui_min_rect.unwrap_or_else(|| {
#[expect(deprecated)] // legacy
ctx.viewport().this_pass.used_by_panels
});
let mut used = root_ui_min_rect.unwrap_or(Rect::NOTHING);
for (_id, window) in ctx.memory.areas().visible_windows() {
used |= window.rect();
}
@@ -2882,20 +2780,6 @@ impl Context {
})
}
/// How much space is used by windows and the top-level [`Ui`].
#[deprecated = "Renamed to globally_used_rect"]
pub fn used_rect(&self) -> Rect {
self.globally_used_rect()
}
/// How much space is used by windows and the top-level [`Ui`].
///
/// You can shrink your egui area to this size and still fit all egui components.
#[deprecated = "Use globally_used_rect instead"]
pub fn used_size(&self) -> Vec2 {
(self.globally_used_rect().max - Pos2::ZERO).round_ui()
}
// ---------------------------------------------------------------------
/// Is the pointer (mouse/touch) over any egui area?
@@ -2916,21 +2800,13 @@ impl Context {
// Modern `run_ui` code
!root_ui_available_rect.contains(pointer_pos)
} else {
// Legacy code
#[expect(deprecated)]
!self.pass_state(|state| state.unused_rect.contains(pointer_pos))
true // We shouldn't get here, but who knows
}
} else {
true
}
}
/// Is the pointer (mouse/touch) over any egui area?
#[deprecated = "Renamed to is_pointer_over_egui"]
pub fn is_pointer_over_area(&self) -> bool {
self.is_pointer_over_egui()
}
/// True if egui is currently interested in the pointer (mouse or touch).
///
/// Could be the pointer is hovering over a [`crate::Window`] or the user is dragging a widget.
@@ -2942,17 +2818,6 @@ impl Context {
|| (self.is_pointer_over_egui() && !self.input(|i| i.pointer.any_down()))
}
/// True if egui is currently interested in the pointer (mouse or touch).
///
/// Could be the pointer is hovering over a [`crate::Window`] or the user is dragging a widget.
/// If `false`, the pointer is outside of any egui area and so
/// you may be interested in what it is doing (e.g. controlling your game).
/// Returns `false` if a drag started outside of egui and then moved over an egui area.
#[deprecated = "Renamed to egui_wants_pointer_input"]
pub fn wants_pointer_input(&self) -> bool {
self.egui_wants_pointer_input()
}
/// Is egui currently using the pointer position (e.g. dragging a slider)?
///
/// NOTE: this will return `false` if the pointer is just hovering over an egui area.
@@ -2960,25 +2825,11 @@ impl Context {
self.memory(|m| m.interaction().is_using_pointer())
}
/// Is egui currently using the pointer position (e.g. dragging a slider)?
///
/// NOTE: this will return `false` if the pointer is just hovering over an egui area.
#[deprecated = "Renamed to egui_is_using_pointer"]
pub fn is_using_pointer(&self) -> bool {
self.egui_is_using_pointer()
}
/// If `true`, egui is currently listening on text input (e.g. typing text in a [`crate::TextEdit`]).
pub fn egui_wants_keyboard_input(&self) -> bool {
self.memory(|m| m.focused().is_some())
}
/// If `true`, egui is currently listening on text input (e.g. typing text in a [`crate::TextEdit`]).
#[deprecated = "Renamed to egui_wants_keyboard_input"]
pub fn wants_keyboard_input(&self) -> bool {
self.egui_wants_keyboard_input()
}
/// Is the currently focused widget a text edit?
pub fn text_edit_focused(&self) -> bool {
if let Some(id) = self.memory(|mem| mem.focused()) {
@@ -2998,18 +2849,6 @@ impl Context {
self.pass_state_mut(|fs| fs.highlight_next_pass.insert(id));
}
/// Is an egui context menu open?
///
/// This only works with the old, deprecated [`crate::menu`] API.
#[expect(deprecated)]
#[deprecated = "Use `any_popup_open` instead"]
pub fn is_context_menu_open(&self) -> bool {
self.data(|d| {
d.get_temp::<crate::menu::BarState>(crate::menu::CONTEXT_MENU_ID_STR.into())
.is_some_and(|state| state.has_root())
})
}
/// Is a popup or (context) menu open?
///
/// Will return false for [`crate::Tooltip`]s (which are technically popups as well).
@@ -3020,18 +2859,6 @@ impl Context {
.any(|layer| !layer.open_popups.is_empty())
})
}
/// Is a popup or (context) menu open?
///
/// Will return false for [`crate::Tooltip`]s (which are technically popups as well).
#[deprecated = "Renamed to any_popup_open"]
pub fn is_popup_open(&self) -> bool {
self.pass_state_mut(|fs| {
fs.layers
.values()
.any(|layer| !layer.open_popups.is_empty())
})
}
}
// Ergonomic methods to forward some calls often used in 'if let' without holding the borrow
@@ -3646,17 +3473,6 @@ impl Context {
}
});
#[expect(deprecated)]
ui.horizontal(|ui| {
ui.label(format!(
"{} menu bars",
self.data(|d| d.count::<crate::menu::BarState>())
));
if ui.button("Reset").clicked() {
self.data_mut(|d| d.remove_by_type::<crate::menu::BarState>());
}
});
ui.horizontal(|ui| {
ui.label(format!(
"{} scroll areas",
@@ -4009,8 +3825,8 @@ impl Context {
/// When called, the integration needs to:
/// * Check if there already is a window for this viewport id, and if not open one
/// * Set the window attributes (position, size, …) based on [`ImmediateViewport::builder`].
/// * Call [`Context::run`] with [`ImmediateViewport::viewport_ui_cb`].
/// * Handle the output from [`Context::run`], including rendering
/// * Call [`Context::run_ui`] with [`ImmediateViewport::viewport_ui_cb`].
/// * Handle the output from [`Context::run_ui`], including rendering
pub fn set_immediate_viewport_renderer(
callback: impl for<'a> Fn(&Self, ImmediateViewport<'a>) + 'static,
) {

View File

@@ -12,7 +12,7 @@ use crate::{
/// Set the values that make sense, leave the rest at their `Default::default()`.
///
/// You can check if `egui` is using the inputs using
/// [`crate::Context::wants_pointer_input`] and [`crate::Context::wants_keyboard_input`].
/// [`crate::Context::egui_wants_pointer_input`] and [`crate::Context::egui_wants_keyboard_input`].
///
/// All coordinates are in points (logical pixels) with origin (0, 0) in the top left .corner.
///
@@ -64,8 +64,8 @@ pub struct RawInput {
/// In-order events received this frame.
///
/// There is currently no way to know if egui handles a particular event,
/// but you can check if egui is using the keyboard with [`crate::Context::wants_keyboard_input`]
/// and/or the pointer (mouse/touch) with [`crate::Context::is_using_pointer`].
/// but you can check if egui is using the keyboard with [`crate::Context::egui_wants_keyboard_input`]
/// and/or the pointer (mouse/touch) with [`crate::Context::egui_is_using_pointer`].
pub events: Vec<Event>,
/// Dragged files hovering over egui.

View File

@@ -2,7 +2,7 @@
use crate::{OrderedViewportIdMap, RepaintCause, ViewportOutput, WidgetType};
/// What egui emits each frame from [`crate::Context::run`].
/// What egui emits each frame from [`crate::Context::run_ui`].
///
/// The backend should use this.
#[derive(Clone, Default)]

View File

@@ -2,7 +2,7 @@ use ahash::HashMap;
use emath::TSTransform;
use crate::{LayerId, Pos2, Sense, WidgetRect, WidgetRects, ahash, emath, id::IdSet};
use crate::{LayerId, Pos2, Sense, WidgetRect, WidgetRects, emath, id::IdSet};
/// Result of a hit-test against [`WidgetRects`].
///

View File

@@ -209,7 +209,7 @@ impl InputOptions {
/// You can access this with [`crate::Context::input`].
///
/// You can check if `egui` is using the inputs using
/// [`crate::Context::wants_pointer_input`] and [`crate::Context::wants_keyboard_input`].
/// [`crate::Context::egui_wants_pointer_input`] and [`crate::Context::egui_wants_keyboard_input`].
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct InputState {
@@ -522,14 +522,6 @@ impl InputState {
self.viewport_rect
}
/// Position and size of the egui area.
#[deprecated(
note = "screen_rect has been split into viewport_rect() and content_rect(). You likely should use content_rect()"
)]
pub fn screen_rect(&self) -> Rect {
self.content_rect()
}
/// Get the safe area insets.
///
/// This represents the area of the screen covered by status bars, navigation controls, notches,

View File

@@ -1,7 +1,7 @@
//! Handles paint layers, i.e. how things
//! are sometimes painted behind or in front of other things.
use crate::{Id, IdMap, Rect, ahash, epaint};
use crate::{Id, IdMap, Rect, epaint};
use epaint::{ClippedShape, Shape, emath::TSTransform};
/// Different layer categories
@@ -86,12 +86,6 @@ impl LayerId {
}
}
#[inline(always)]
#[deprecated = "Use `Memory::allows_interaction` instead"]
pub fn allow_interaction(&self) -> bool {
self.order.allow_interaction()
}
/// Short and readable summary
pub fn short_debug_format(&self) -> String {
format!(

View File

@@ -112,8 +112,8 @@
//! loop {
//! let raw_input: egui::RawInput = gather_input();
//!
//! let full_output = ctx.run(raw_input, |ctx| {
//! egui::CentralPanel::default().show(&ctx, |ui| {
//! let full_output = ctx.run_ui(raw_input, |ui| {
//! egui::CentralPanel::default().show_inside(ui, |ui| {
//! ui.label("Hello world!");
//! if ui.button("Click me").clicked() {
//! // take some action here
@@ -407,8 +407,6 @@ pub mod layers;
mod layout;
pub mod load;
mod memory;
#[deprecated = "Use `egui::containers::menu` instead"]
pub mod menu;
pub mod os;
mod painter;
mod pass_state;
@@ -434,9 +432,6 @@ mod callstack;
pub use accesskit;
#[deprecated = "Use the ahash crate directly."]
pub use ahash;
pub use epaint;
pub use epaint::ecolor;
pub use epaint::emath;
@@ -499,9 +494,6 @@ pub use self::{
widgets::*,
};
#[deprecated = "Renamed to CornerRadius"]
pub type Rounding = CornerRadius;
// ----------------------------------------------------------------------------
/// Helper function that adds a label when compiling with debug assertions enabled.

View File

@@ -199,7 +199,7 @@ pub struct Options {
#[cfg_attr(feature = "serde", serde(skip))]
pub light_style: std::sync::Arc<Style>,
/// Preference for selection between dark and light [`crate::Context::style`]
/// Preference for selection between dark and light [`crate::Context::global_style`]
/// as the active style used by all subsequent windows, panels, etc.
///
/// Default: `ThemePreference::System`.
@@ -272,7 +272,7 @@ pub struct Options {
///
/// If this is `1`, [`crate::Context::request_discard`] will be ignored.
///
/// Multi-pass is supported by [`crate::Context::run`].
/// Multi-pass is supported by [`crate::Context::run_ui`].
///
/// See [`crate::Context::request_discard`] for more.
pub max_passes: NonZeroUsize,
@@ -820,12 +820,6 @@ impl Memory {
}
}
/// The currently set transform of a layer.
#[deprecated = "Use `Context::layer_transform_to_global` instead"]
pub fn layer_transforms(&self, layer_id: LayerId) -> Option<TSTransform> {
self.to_global.get(&layer_id).copied()
}
/// An iterator over all layers. Back-to-front, top is last.
pub fn layer_ids(&self) -> impl ExactSizeIterator<Item = LayerId> + '_ {
self.areas().order().iter().copied()
@@ -1052,40 +1046,27 @@ impl OpenPopup {
}
}
/// ## Deprecated popup API
/// Use [`crate::Popup`] instead.
/// ## Popup state (internal API)
///
/// Used by [`crate::Popup`].
impl Memory {
/// Is the given popup open?
#[deprecated = "Use Popup::is_id_open instead"]
pub fn is_popup_open(&self, popup_id: Id) -> bool {
pub(crate) fn is_popup_open(&self, popup_id: Id) -> bool {
self.popups
.get(&self.viewport_id)
.is_some_and(|state| state.id == popup_id)
|| self.everything_is_visible()
}
/// Is any popup open?
#[deprecated = "Use Popup::is_any_open instead"]
pub fn any_popup_open(&self) -> bool {
pub(crate) fn any_popup_open(&self) -> bool {
self.popups.contains_key(&self.viewport_id) || self.everything_is_visible()
}
/// Open the given popup and close all others.
///
/// Note that you must call `keep_popup_open` on subsequent frames as long as the popup is open.
#[deprecated = "Use Popup::open_id instead"]
pub fn open_popup(&mut self, popup_id: Id) {
pub(crate) fn open_popup(&mut self, popup_id: Id) {
self.popups
.insert(self.viewport_id, OpenPopup::new(popup_id, None));
}
/// Popups must call this every frame while open.
///
/// This is needed because in some cases popups can go away without `close_popup` being
/// called. For example, when a context menu is open and the underlying widget stops
/// being rendered.
#[deprecated = "Use Popup::show instead"]
pub fn keep_popup_open(&mut self, popup_id: Id) {
pub(crate) fn keep_popup_open(&mut self, popup_id: Id) {
if let Some(state) = self.popups.get_mut(&self.viewport_id)
&& state.id == popup_id
{
@@ -1093,43 +1074,27 @@ impl Memory {
}
}
/// Open the popup and remember its position.
#[deprecated = "Use Popup with PopupAnchor::Position instead"]
pub fn open_popup_at(&mut self, popup_id: Id, pos: impl Into<Option<Pos2>>) {
pub(crate) fn open_popup_at(&mut self, popup_id: Id, pos: impl Into<Option<Pos2>>) {
self.popups
.insert(self.viewport_id, OpenPopup::new(popup_id, pos.into()));
}
/// Get the position for this popup.
#[deprecated = "Use Popup::position_of_id instead"]
pub fn popup_position(&self, id: Id) -> Option<Pos2> {
pub(crate) fn popup_position(&self, id: Id) -> Option<Pos2> {
let state = self.popups.get(&self.viewport_id)?;
if state.id == id { state.pos } else { None }
}
/// Close any currently open popup.
#[deprecated = "Use Popup::close_all instead"]
pub fn close_all_popups(&mut self) {
pub(crate) fn close_all_popups(&mut self) {
self.popups.clear();
}
/// Close the given popup, if it is open.
///
/// See also [`Self::close_all_popups`] if you want to close any / all currently open popups.
#[deprecated = "Use Popup::close_id instead"]
pub fn close_popup(&mut self, popup_id: Id) {
#[expect(deprecated)]
pub(crate) fn close_popup(&mut self, popup_id: Id) {
if self.is_popup_open(popup_id) {
self.popups.remove(&self.viewport_id);
}
}
/// Toggle the given popup between closed and open.
///
/// Note: At most, only one popup can be open at a time.
#[deprecated = "Use Popup::toggle_id instead"]
pub fn toggle_popup(&mut self, popup_id: Id) {
#[expect(deprecated)]
pub(crate) fn toggle_popup(&mut self, popup_id: Id) {
if self.is_popup_open(popup_id) {
self.close_popup(popup_id);
} else {

View File

@@ -1,781 +0,0 @@
#![expect(deprecated)]
//! Deprecated menu API - Use [`crate::containers::menu`] instead.
//!
//! Usage:
//! ```
//! fn show_menu(ui: &mut egui::Ui) {
//! use egui::{menu, Button};
//!
//! menu::bar(ui, |ui| {
//! ui.menu_button("File", |ui| {
//! if ui.button("Open").clicked() {
//! // …
//! }
//! });
//! });
//! }
//! ```
use super::{
Align, Context, Id, InnerResponse, PointerState, Pos2, Rect, Response, Sense, TextStyle, Ui,
Vec2, style::WidgetVisuals,
};
use crate::{
Align2, Area, Color32, Frame, Key, LayerId, Layout, NumExt as _, Order, Stroke, Style,
TextWrapMode, UiKind, WidgetText, epaint, vec2,
widgets::{Button, ImageButton},
};
use epaint::mutex::RwLock;
use std::sync::Arc;
/// What is saved between frames.
#[derive(Clone, Default)]
pub struct BarState {
open_menu: MenuRootManager,
}
impl BarState {
pub fn load(ctx: &Context, bar_id: Id) -> Self {
ctx.data_mut(|d| d.get_temp::<Self>(bar_id).unwrap_or_default())
}
pub fn store(self, ctx: &Context, bar_id: Id) {
ctx.data_mut(|d| d.insert_temp(bar_id, self));
}
/// Show a menu at pointer if primary-clicked response.
///
/// Should be called from [`Context`] on a [`Response`]
pub fn bar_menu<R>(
&mut self,
button: &Response,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> Option<InnerResponse<R>> {
MenuRoot::stationary_click_interaction(button, &mut self.open_menu);
self.open_menu.show(button, add_contents)
}
pub(crate) fn has_root(&self) -> bool {
self.open_menu.inner.is_some()
}
}
impl std::ops::Deref for BarState {
type Target = MenuRootManager;
fn deref(&self) -> &Self::Target {
&self.open_menu
}
}
impl std::ops::DerefMut for BarState {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.open_menu
}
}
fn set_menu_style(style: &mut Style) {
if style.compact_menu_style {
style.spacing.button_padding = vec2(2.0, 0.0);
style.visuals.widgets.active.bg_stroke = Stroke::NONE;
style.visuals.widgets.hovered.bg_stroke = Stroke::NONE;
style.visuals.widgets.inactive.weak_bg_fill = Color32::TRANSPARENT;
style.visuals.widgets.inactive.bg_stroke = Stroke::NONE;
}
}
/// The menu bar goes well in a [`crate::Panel::top`],
/// but can also be placed in a [`crate::Window`].
/// In the latter case you may want to wrap it in [`Frame`].
#[deprecated = "Use `egui::MenuBar::new().ui(` instead"]
pub fn bar<R>(ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) -> InnerResponse<R> {
ui.horizontal(|ui| {
set_menu_style(ui.style_mut());
// Take full width and fixed height:
let height = ui.spacing().interact_size.y;
ui.set_min_size(vec2(ui.available_width(), height));
add_contents(ui)
})
}
/// Construct a top level menu in a menu bar. This would be e.g. "File", "Edit" etc.
///
/// Responds to primary clicks.
///
/// Returns `None` if the menu is not open.
pub fn menu_button<R>(
ui: &mut Ui,
title: impl Into<WidgetText>,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> InnerResponse<Option<R>> {
stationary_menu_impl(ui, title, Box::new(add_contents))
}
/// Construct a top level menu with a custom button in a menu bar.
///
/// Responds to primary clicks.
///
/// Returns `None` if the menu is not open.
pub fn menu_custom_button<R>(
ui: &mut Ui,
button: Button<'_>,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> InnerResponse<Option<R>> {
stationary_menu_button_impl(ui, button, Box::new(add_contents))
}
/// Construct a top level menu with an image in a menu bar. This would be e.g. "File", "Edit" etc.
///
/// Responds to primary clicks.
///
/// Returns `None` if the menu is not open.
#[deprecated = "Use `menu_custom_button` instead"]
pub fn menu_image_button<R>(
ui: &mut Ui,
image_button: ImageButton<'_>,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> InnerResponse<Option<R>> {
stationary_menu_button_impl(
ui,
Button::image(image_button.image),
Box::new(add_contents),
)
}
/// Construct a nested sub menu in another menu.
///
/// Opens on hover.
///
/// Returns `None` if the menu is not open.
pub fn submenu_button<R>(
ui: &mut Ui,
parent_state: Arc<RwLock<MenuState>>,
title: impl Into<WidgetText>,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> InnerResponse<Option<R>> {
SubMenu::new(parent_state, title).show(ui, add_contents)
}
/// wrapper for the contents of every menu.
fn menu_popup<'c, R>(
ctx: &Context,
parent_layer: LayerId,
menu_state_arc: &Arc<RwLock<MenuState>>,
menu_id: Id,
add_contents: impl FnOnce(&mut Ui) -> R + 'c,
) -> InnerResponse<R> {
let pos = {
let mut menu_state = menu_state_arc.write();
menu_state.entry_count = 0;
menu_state.rect.min
};
let area_id = menu_id.with("__menu");
ctx.pass_state_mut(|fs| {
fs.layers
.entry(parent_layer)
.or_default()
.open_popups
.insert(area_id)
});
let area = Area::new(area_id)
.kind(UiKind::Menu)
.order(Order::Foreground)
.fixed_pos(pos)
.default_width(ctx.global_style().spacing.menu_width)
.sense(Sense::hover());
let mut sizing_pass = false;
let area_response = area.show(ctx, |ui| {
sizing_pass = ui.is_sizing_pass();
set_menu_style(ui.style_mut());
Frame::menu(ui.style())
.show(ui, |ui| {
ui.set_menu_state(Some(Arc::clone(menu_state_arc)));
ui.with_layout(Layout::top_down_justified(Align::LEFT), add_contents)
.inner
})
.inner
});
let area_rect = area_response.response.rect;
menu_state_arc.write().rect = if sizing_pass {
// During the sizing pass we didn't know the size yet,
// so we might have just constrained the position unnecessarily.
// Therefore keep the original=desired position until the next frame.
Rect::from_min_size(pos, area_rect.size())
} else {
// We knew the size, and this is where it ended up (potentially constrained to screen).
// Remember it for the future:
area_rect
};
area_response
}
/// Build a top level menu with a button.
///
/// Responds to primary clicks.
fn stationary_menu_impl<'c, R>(
ui: &mut Ui,
title: impl Into<WidgetText>,
add_contents: Box<dyn FnOnce(&mut Ui) -> R + 'c>,
) -> InnerResponse<Option<R>> {
let title = title.into();
let bar_id = ui.id();
let menu_id = bar_id.with(title.text());
let mut bar_state = BarState::load(ui.ctx(), bar_id);
let mut button = Button::new(title);
if bar_state.open_menu.is_menu_open(menu_id) {
button = button.fill(ui.visuals().widgets.open.weak_bg_fill);
button = button.stroke(ui.visuals().widgets.open.bg_stroke);
}
let button_response = ui.add(button);
let inner = bar_state.bar_menu(&button_response, add_contents);
bar_state.store(ui.ctx(), bar_id);
InnerResponse::new(inner.map(|r| r.inner), button_response)
}
/// Build a top level menu with an image button.
///
/// Responds to primary clicks.
fn stationary_menu_button_impl<'c, R>(
ui: &mut Ui,
button: Button<'_>,
add_contents: Box<dyn FnOnce(&mut Ui) -> R + 'c>,
) -> InnerResponse<Option<R>> {
let bar_id = ui.id();
let mut bar_state = BarState::load(ui.ctx(), bar_id);
let button_response = ui.add(button);
let inner = bar_state.bar_menu(&button_response, add_contents);
bar_state.store(ui.ctx(), bar_id);
InnerResponse::new(inner.map(|r| r.inner), button_response)
}
pub(crate) const CONTEXT_MENU_ID_STR: &str = "__egui::context_menu";
/// Response to secondary clicks (right-clicks) by showing the given menu.
pub fn context_menu(
response: &Response,
add_contents: impl FnOnce(&mut Ui),
) -> Option<InnerResponse<()>> {
let menu_id = Id::new(CONTEXT_MENU_ID_STR);
let mut bar_state = BarState::load(&response.ctx, menu_id);
MenuRoot::context_click_interaction(response, &mut bar_state);
let inner_response = bar_state.show(response, add_contents);
bar_state.store(&response.ctx, menu_id);
inner_response
}
/// Returns `true` if the context menu is opened for this widget.
pub fn context_menu_opened(response: &Response) -> bool {
let menu_id = Id::new(CONTEXT_MENU_ID_STR);
let bar_state = BarState::load(&response.ctx, menu_id);
bar_state.is_menu_open(response.id)
}
/// Stores the state for the context menu.
#[derive(Clone, Default)]
pub struct MenuRootManager {
inner: Option<MenuRoot>,
}
impl MenuRootManager {
/// Show a menu at pointer if right-clicked response.
///
/// Should be called from [`Context`] on a [`Response`]
pub fn show<R>(
&mut self,
button: &Response,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> Option<InnerResponse<R>> {
if let Some(root) = self.inner.as_mut() {
let (menu_response, inner_response) = root.show(button, add_contents);
if menu_response.is_close() {
self.inner = None;
}
inner_response
} else {
None
}
}
fn is_menu_open(&self, id: Id) -> bool {
self.inner.as_ref().map(|m| m.id) == Some(id)
}
}
impl std::ops::Deref for MenuRootManager {
type Target = Option<MenuRoot>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl std::ops::DerefMut for MenuRootManager {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
/// Menu root associated with an Id from a Response
#[derive(Clone)]
pub struct MenuRoot {
pub menu_state: Arc<RwLock<MenuState>>,
pub id: Id,
}
impl MenuRoot {
pub fn new(position: Pos2, id: Id) -> Self {
Self {
menu_state: Arc::new(RwLock::new(MenuState::new(position))),
id,
}
}
pub fn show<R>(
&self,
button: &Response,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> (MenuResponse, Option<InnerResponse<R>>) {
if self.id == button.id {
let inner_response = menu_popup(
&button.ctx,
button.layer_id,
&self.menu_state,
self.id,
add_contents,
);
let menu_state = self.menu_state.read();
let escape_pressed = button.ctx.input(|i| i.key_pressed(Key::Escape));
if menu_state.response.is_close()
|| escape_pressed
|| inner_response.response.should_close()
{
return (MenuResponse::Close, Some(inner_response));
}
}
(MenuResponse::Stay, None)
}
/// Interaction with a stationary menu, i.e. fixed in another Ui.
///
/// Responds to primary clicks.
fn stationary_interaction(button: &Response, root: &mut MenuRootManager) -> MenuResponse {
let id = button.id;
if (button.clicked() && root.is_menu_open(id))
|| button.ctx.input(|i| i.key_pressed(Key::Escape))
{
// menu open and button clicked or esc pressed
return MenuResponse::Close;
} else if (button.clicked() && !root.is_menu_open(id))
|| (button.hovered() && root.is_some())
{
// menu not open and button clicked
// or button hovered while other menu is open
let mut pos = button.rect.left_bottom();
let menu_frame = Frame::menu(&button.ctx.global_style());
pos.x -= menu_frame.total_margin().left; // Make fist button in menu align with the parent button
pos.y += button.ctx.global_style().spacing.menu_spacing;
if let Some(root) = root.inner.as_mut() {
let menu_rect = root.menu_state.read().rect;
let content_rect = button.ctx.input(|i| i.content_rect());
if pos.y + menu_rect.height() > content_rect.max.y {
pos.y = content_rect.max.y - menu_rect.height() - button.rect.height();
}
if pos.x + menu_rect.width() > content_rect.max.x {
pos.x = content_rect.max.x - menu_rect.width();
}
}
if let Some(to_global) = button.ctx.layer_transform_to_global(button.layer_id) {
pos = to_global * pos;
}
return MenuResponse::Create(pos, id);
} else if button
.ctx
.input(|i| i.pointer.any_pressed() && i.pointer.primary_down())
&& let Some(pos) = button.ctx.input(|i| i.pointer.interact_pos())
&& let Some(root) = root.inner.as_mut()
&& root.id == id
{
// pressed somewhere while this menu is open
let in_menu = root.menu_state.read().area_contains(pos);
if !in_menu {
return MenuResponse::Close;
}
}
MenuResponse::Stay
}
/// Interaction with a context menu (secondary click).
pub fn context_interaction(response: &Response, root: &mut Option<Self>) -> MenuResponse {
let response = response.interact(Sense::click());
let hovered = response.hovered();
let secondary_clicked = response.secondary_clicked();
response.ctx.input(|input| {
let pointer = &input.pointer;
if let Some(pos) = pointer.interact_pos() {
let (in_old_menu, destroy) = if let Some(root) = root {
let in_old_menu = root.menu_state.read().area_contains(pos);
let destroy = !in_old_menu && pointer.any_pressed() && root.id == response.id;
(in_old_menu, destroy)
} else {
(false, false)
};
if !in_old_menu {
if hovered && secondary_clicked {
return MenuResponse::Create(pos, response.id);
} else if destroy || hovered && pointer.primary_down() {
return MenuResponse::Close;
}
}
}
MenuResponse::Stay
})
}
pub fn handle_menu_response(root: &mut MenuRootManager, menu_response: MenuResponse) {
match menu_response {
MenuResponse::Create(pos, id) => {
root.inner = Some(Self::new(pos, id));
}
MenuResponse::Close => root.inner = None,
MenuResponse::Stay => {}
}
}
/// Respond to secondary (right) clicks.
pub fn context_click_interaction(response: &Response, root: &mut MenuRootManager) {
let menu_response = Self::context_interaction(response, root);
Self::handle_menu_response(root, menu_response);
}
// Responds to primary clicks.
pub fn stationary_click_interaction(button: &Response, root: &mut MenuRootManager) {
let menu_response = Self::stationary_interaction(button, root);
Self::handle_menu_response(root, menu_response);
}
}
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum MenuResponse {
Close,
Stay,
Create(Pos2, Id),
}
impl MenuResponse {
pub fn is_close(&self) -> bool {
*self == Self::Close
}
}
pub struct SubMenuButton {
text: WidgetText,
icon: WidgetText,
index: usize,
}
impl SubMenuButton {
/// The `icon` can be an emoji (e.g. `⏵` right arrow), shown right of the label
fn new(text: impl Into<WidgetText>, icon: impl Into<WidgetText>, index: usize) -> Self {
Self {
text: text.into(),
icon: icon.into(),
index,
}
}
fn visuals<'a>(
ui: &'a Ui,
response: &Response,
menu_state: &MenuState,
sub_id: Id,
) -> &'a WidgetVisuals {
if menu_state.is_open(sub_id) && !response.hovered() {
&ui.style().visuals.widgets.open
} else {
ui.style().interact(response)
}
}
#[inline]
pub fn icon(mut self, icon: impl Into<WidgetText>) -> Self {
self.icon = icon.into();
self
}
pub(crate) fn show(self, ui: &mut Ui, menu_state: &MenuState, sub_id: Id) -> Response {
let Self { text, icon, .. } = self;
let text_style = TextStyle::Button;
let sense = Sense::click();
let text_icon_gap = ui.spacing().item_spacing.x;
let button_padding = ui.spacing().button_padding;
let total_extra = button_padding + button_padding;
let text_available_width = ui.available_width() - total_extra.x;
let text_galley = text.into_galley(
ui,
Some(TextWrapMode::Wrap),
text_available_width,
text_style.clone(),
);
let icon_available_width = text_available_width - text_galley.size().x;
let icon_galley = icon.into_galley(
ui,
Some(TextWrapMode::Wrap),
icon_available_width,
text_style,
);
let text_and_icon_size = Vec2::new(
text_galley.size().x + text_icon_gap + icon_galley.size().x,
text_galley.size().y.max(icon_galley.size().y),
);
let mut desired_size = text_and_icon_size + 2.0 * button_padding;
desired_size.y = desired_size.y.at_least(ui.spacing().interact_size.y);
let (rect, response) = ui.allocate_at_least(desired_size, sense);
response.widget_info(|| {
crate::WidgetInfo::labeled(
crate::WidgetType::Button,
ui.is_enabled(),
text_galley.text(),
)
});
if ui.is_rect_visible(rect) {
let visuals = Self::visuals(ui, &response, menu_state, sub_id);
let text_pos = Align2::LEFT_CENTER
.align_size_within_rect(text_galley.size(), rect.shrink2(button_padding))
.min;
let icon_pos = Align2::RIGHT_CENTER
.align_size_within_rect(icon_galley.size(), rect.shrink2(button_padding))
.min;
if ui.visuals().button_frame {
ui.painter().rect_filled(
rect.expand(visuals.expansion),
visuals.corner_radius,
visuals.weak_bg_fill,
);
}
let text_color = visuals.text_color();
ui.painter().galley(text_pos, text_galley, text_color);
ui.painter().galley(icon_pos, icon_galley, text_color);
}
response
}
}
pub struct SubMenu {
button: SubMenuButton,
parent_state: Arc<RwLock<MenuState>>,
}
impl SubMenu {
fn new(parent_state: Arc<RwLock<MenuState>>, text: impl Into<WidgetText>) -> Self {
let index = parent_state.write().next_entry_index();
Self {
button: SubMenuButton::new(text, "", index),
parent_state,
}
}
pub fn show<R>(
self,
ui: &mut Ui,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> InnerResponse<Option<R>> {
let sub_id = ui.id().with(self.button.index);
let response = self.button.show(ui, &self.parent_state.read(), sub_id);
self.parent_state
.write()
.submenu_button_interaction(ui, sub_id, &response);
let inner =
self.parent_state
.write()
.show_submenu(ui.ctx(), ui.layer_id(), sub_id, add_contents);
InnerResponse::new(inner, response)
}
}
/// Components of menu state, public for advanced usage.
///
/// Usually you don't need to use it directly.
pub struct MenuState {
/// The opened sub-menu and its [`Id`]
sub_menu: Option<(Id, Arc<RwLock<Self>>)>,
/// Bounding box of this menu (without the sub-menu),
/// including the frame and everything.
pub rect: Rect,
/// Used to check if any menu in the tree wants to close
pub response: MenuResponse,
/// Used to hash different [`Id`]s for sub-menus
entry_count: usize,
}
impl MenuState {
pub fn new(position: Pos2) -> Self {
Self {
rect: Rect::from_min_size(position, Vec2::ZERO),
sub_menu: None,
response: MenuResponse::Stay,
entry_count: 0,
}
}
/// Close menu hierarchy.
pub fn close(&mut self) {
self.response = MenuResponse::Close;
}
fn show_submenu<R>(
&mut self,
ctx: &Context,
parent_layer: LayerId,
id: Id,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> Option<R> {
let (sub_response, response) = self.submenu(id).map(|sub| {
let inner_response = menu_popup(ctx, parent_layer, sub, id, add_contents);
if inner_response.response.should_close() {
sub.write().close();
}
(sub.read().response, inner_response.inner)
})?;
self.cascade_close_response(sub_response);
Some(response)
}
/// Check if position is in the menu hierarchy's area.
pub fn area_contains(&self, pos: Pos2) -> bool {
self.rect.contains(pos)
|| self
.sub_menu
.as_ref()
.is_some_and(|(_, sub)| sub.read().area_contains(pos))
}
fn next_entry_index(&mut self) -> usize {
self.entry_count += 1;
self.entry_count - 1
}
/// Sense button interaction opening and closing submenu.
fn submenu_button_interaction(&mut self, ui: &Ui, sub_id: Id, button: &Response) {
let pointer = ui.input(|i| i.pointer.clone());
let open = self.is_open(sub_id);
if self.moving_towards_current_submenu(&pointer) {
// We don't close the submenu if the pointer is on its way to hover it.
// ensure to repaint once even when pointer is not moving
ui.request_repaint();
} else if !open && button.hovered() {
// TODO(emilk): open menu to the left if there isn't enough space to the right
let mut pos = button.rect.right_top();
pos.x = self.rect.right() + ui.spacing().menu_spacing;
pos.y -= Frame::menu(ui.style()).total_margin().top; // align the first button in the submenu with the parent button
self.open_submenu(sub_id, pos);
} else if open
&& ui.response().contains_pointer()
&& !button.hovered()
&& !self.hovering_current_submenu(&pointer)
{
// We are hovering something else in the menu, so close the submenu.
self.close_submenu();
}
}
/// Check if pointer is moving towards current submenu.
fn moving_towards_current_submenu(&self, pointer: &PointerState) -> bool {
if pointer.is_still() {
return false;
}
if let Some(sub_menu) = self.current_submenu()
&& let Some(pos) = pointer.hover_pos()
{
let rect = sub_menu.read().rect;
return rect.intersects_ray(pos, pointer.direction().normalized());
}
false
}
/// Check if pointer is hovering current submenu.
fn hovering_current_submenu(&self, pointer: &PointerState) -> bool {
if let Some(sub_menu) = self.current_submenu()
&& let Some(pos) = pointer.hover_pos()
{
return sub_menu.read().area_contains(pos);
}
false
}
/// Cascade close response to menu root.
fn cascade_close_response(&mut self, response: MenuResponse) {
if response.is_close() {
self.response = response;
}
}
fn is_open(&self, id: Id) -> bool {
self.sub_id() == Some(id)
}
fn sub_id(&self) -> Option<Id> {
self.sub_menu.as_ref().map(|(id, _)| *id)
}
fn current_submenu(&self) -> Option<&Arc<RwLock<Self>>> {
self.sub_menu.as_ref().map(|(_, sub)| sub)
}
fn submenu(&self, id: Id) -> Option<&Arc<RwLock<Self>>> {
let (k, sub) = self.sub_menu.as_ref()?;
if id == *k { Some(sub) } else { None }
}
/// Open submenu at position, if not already open.
fn open_submenu(&mut self, id: Id, pos: Pos2) {
if !self.is_open(id) {
self.sub_menu = Some((id, Arc::new(RwLock::new(Self::new(pos)))));
}
}
fn close_submenu(&mut self) {
self.sub_menu = None;
}
}

View File

@@ -82,12 +82,6 @@ impl Painter {
self.layer_id = layer_id;
}
/// If set, colors will be modified to look like this
#[deprecated = "Use `multiply_opacity` instead"]
pub fn set_fade_to_color(&mut self, fade_to_color: Option<Color32>) {
self.fade_to_color = fade_to_color;
}
/// Set the opacity (alpha multiplier) of everything painted by this painter from this point forward.
///
/// `opacity` must be between 0.0 and 1.0, where 0.0 means fully transparent (i.e., invisible)
@@ -195,41 +189,6 @@ impl Painter {
pub fn round_to_pixel_center(&self, point: f32) -> f32 {
point.round_to_pixel_center(self.pixels_per_point())
}
/// Useful for pixel-perfect rendering of lines that are one pixel wide (or any odd number of pixels).
#[deprecated = "Use `emath::GuiRounding` with `painter.pixels_per_point()` instead"]
#[inline]
pub fn round_pos_to_pixel_center(&self, pos: Pos2) -> Pos2 {
pos.round_to_pixel_center(self.pixels_per_point())
}
/// Useful for pixel-perfect rendering of filled shapes.
#[deprecated = "Use `emath::GuiRounding` with `painter.pixels_per_point()` instead"]
#[inline]
pub fn round_to_pixel(&self, point: f32) -> f32 {
point.round_to_pixels(self.pixels_per_point())
}
/// Useful for pixel-perfect rendering.
#[deprecated = "Use `emath::GuiRounding` with `painter.pixels_per_point()` instead"]
#[inline]
pub fn round_vec_to_pixels(&self, vec: Vec2) -> Vec2 {
vec.round_to_pixels(self.pixels_per_point())
}
/// Useful for pixel-perfect rendering.
#[deprecated = "Use `emath::GuiRounding` with `painter.pixels_per_point()` instead"]
#[inline]
pub fn round_pos_to_pixels(&self, pos: Pos2) -> Pos2 {
pos.round_to_pixels(self.pixels_per_point())
}
/// Useful for pixel-perfect rendering.
#[deprecated = "Use `emath::GuiRounding` with `painter.pixels_per_point()` instead"]
#[inline]
pub fn round_rect_to_pixels(&self, rect: Rect) -> Rect {
rect.round_to_pixels(self.pixels_per_point())
}
}
/// ## Low level

View File

@@ -1,5 +1,3 @@
#![expect(deprecated)] // TODO(emilk): Remove legacy panels
use ahash::HashMap;
use crate::{Align, Id, IdMap, LayerId, Rangef, Rect, Vec2, WidgetRects, id::IdSet, style};
@@ -211,20 +209,6 @@ pub struct PassState {
/// Only set if [`crate::Context::run_ui`] has been called.
pub root_ui_min_rect: Option<Rect>,
/// Starts off as the `screen_rect`, shrinks as panels are added.
/// The [`crate::CentralPanel`] does not change this.
#[deprecated = "Only used by legacy Context-Panels"]
pub available_rect: Rect,
/// Starts off as the `screen_rect`, shrinks as panels are added.
/// The [`crate::CentralPanel`] retracts from this.
#[deprecated = "Only used by legacy Context-Panels"]
pub unused_rect: Rect,
/// How much space is used by panels.
#[deprecated = "Only used by legacy Context-Panels"]
pub used_by_panels: Rect,
/// The current scroll area should scroll to this range (horizontal, vertical).
pub scroll_target: [Option<ScrollTarget>; 2],
@@ -257,9 +241,6 @@ impl Default for PassState {
tooltips: Default::default(),
root_ui_available_rect: None,
root_ui_min_rect: None,
available_rect: Rect::NAN,
unused_rect: Rect::NAN,
used_by_panels: Rect::NAN,
scroll_target: [None, None],
scroll_delta: (Vec2::default(), style::ScrollAnimation::none()),
accesskit_state: None,
@@ -272,7 +253,7 @@ impl Default for PassState {
}
impl PassState {
pub(crate) fn begin_pass(&mut self, content_rect: Rect) {
pub(crate) fn begin_pass(&mut self) {
profiling::function_scope!();
let Self {
used_ids,
@@ -281,9 +262,6 @@ impl PassState {
layers,
root_ui_available_rect,
root_ui_min_rect,
available_rect,
unused_rect,
used_by_panels,
scroll_target,
scroll_delta,
accesskit_state,
@@ -299,9 +277,6 @@ impl PassState {
layers.clear();
*root_ui_available_rect = None;
*root_ui_min_rect = None;
*available_rect = content_rect;
*unused_rect = content_rect;
*used_by_panels = Rect::NOTHING;
*scroll_target = [None, None];
*scroll_delta = Default::default();
@@ -314,70 +289,4 @@ impl PassState {
highlight_next_pass.clear();
}
/// How much space is still available after panels has been added.
#[deprecated = "Only used by legacy Context-Panels"]
pub(crate) fn available_rect(&self) -> Rect {
debug_assert!(
self.available_rect.is_finite(),
"Called `available_rect()` before `Context::run()`"
);
self.available_rect
}
/// Shrink `available_rect`.
#[deprecated = "Only used by legacy Context-Panels"]
pub(crate) fn allocate_left_panel(&mut self, panel_rect: Rect) {
debug_assert!(
panel_rect.min.distance(self.available_rect.min) < 0.1,
"Mismatching left panel. You must not create a panel from within another panel."
);
self.available_rect.min.x = panel_rect.max.x;
self.unused_rect.min.x = panel_rect.max.x;
self.used_by_panels |= panel_rect;
}
/// Shrink `available_rect`.
#[deprecated = "Only used by legacy Context-Panels"]
pub(crate) fn allocate_right_panel(&mut self, panel_rect: Rect) {
debug_assert!(
panel_rect.max.distance(self.available_rect.max) < 0.1,
"Mismatching right panel. You must not create a panel from within another panel."
);
self.available_rect.max.x = panel_rect.min.x;
self.unused_rect.max.x = panel_rect.min.x;
self.used_by_panels |= panel_rect;
}
/// Shrink `available_rect`.
#[deprecated = "Only used by legacy Context-Panels"]
pub(crate) fn allocate_top_panel(&mut self, panel_rect: Rect) {
debug_assert!(
panel_rect.min.distance(self.available_rect.min) < 0.1,
"Mismatching top panel. You must not create a panel from within another panel."
);
self.available_rect.min.y = panel_rect.max.y;
self.unused_rect.min.y = panel_rect.max.y;
self.used_by_panels |= panel_rect;
}
/// Shrink `available_rect`.
#[deprecated = "Only used by legacy Context-Panels"]
pub(crate) fn allocate_bottom_panel(&mut self, panel_rect: Rect) {
debug_assert!(
panel_rect.max.distance(self.available_rect.max) < 0.1,
"Mismatching bottom panel. You must not create a panel from within another panel."
);
self.available_rect.max.y = panel_rect.min.y;
self.unused_rect.max.y = panel_rect.min.y;
self.used_by_panels |= panel_rect;
}
#[deprecated = "Only used by legacy Context-Panels"]
pub(crate) fn allocate_central_panel(&mut self, panel_rect: Rect) {
// Note: we do not shrink `available_rect`, because
// we allow windows to cover the CentralPanel.
self.unused_rect = Rect::NOTHING; // Nothing left unused after this
self.used_by_panels |= panel_rect;
}
}

View File

@@ -297,17 +297,6 @@ pub struct Style {
#[cfg_attr(feature = "serde", serde(skip))]
pub number_formatter: NumberFormatter,
/// If set, labels, buttons, etc. will use this to determine whether to wrap the text at the
/// right edge of the [`Ui`] they are in. By default, this is `None`.
///
/// **Note**: this API is deprecated, use `wrap_mode` instead.
///
/// * `None`: use `wrap_mode` instead
/// * `Some(true)`: wrap mode defaults to [`crate::TextWrapMode::Wrap`]
/// * `Some(false)`: wrap mode defaults to [`crate::TextWrapMode::Extend`]
#[deprecated = "Use wrap_mode instead"]
pub wrap: Option<bool>,
/// If set, labels, buttons, etc. will use this to determine whether to wrap or truncate the
/// text at the right edge of the [`Ui`] they are in, or to extend it. By default, this is
/// `None`.
@@ -1166,13 +1155,6 @@ impl Visuals {
self.window_stroke
}
/// When fading out things, we fade the colors towards this.
#[inline(always)]
#[deprecated = "Use disabled_alpha(). Fading is now handled by modifying the alpha channel."]
pub fn fade_out_to_color(&self) -> Color32 {
self.widgets.noninteractive.weak_bg_fill
}
/// Disabled widgets have their alpha modified by this.
#[inline(always)]
pub fn disabled_alpha(&self) -> f32 {
@@ -1303,11 +1285,6 @@ impl WidgetVisuals {
pub fn text_color(&self) -> Color32 {
self.fg_stroke.color
}
#[deprecated = "Renamed to corner_radius"]
pub fn rounding(&self) -> CornerRadius {
self.corner_radius
}
}
/// Options for help debug egui by adding extra visualization
@@ -1410,7 +1387,6 @@ pub fn default_text_styles() -> BTreeMap<TextStyle, FontId> {
impl Default for Style {
fn default() -> Self {
#[expect(deprecated)]
Self {
override_font_id: None,
override_text_style: None,
@@ -1418,7 +1394,6 @@ impl Default for Style {
text_styles: default_text_styles(),
drag_value_text_style: TextStyle::Button,
number_formatter: NumberFormatter(Arc::new(emath::format_with_decimals_in_range)),
wrap: None,
wrap_mode: None,
spacing: Spacing::default(),
interaction: Interaction::default(),
@@ -1724,7 +1699,6 @@ use crate::{
impl Style {
pub fn ui(&mut self, ui: &mut crate::Ui) {
#[expect(deprecated)]
let Self {
override_font_id,
override_text_style,
@@ -1732,7 +1706,6 @@ impl Style {
text_styles,
drag_value_text_style,
number_formatter: _, // can't change callbacks in the UI
wrap: _,
wrap_mode,
spacing,
interaction,

View File

@@ -97,12 +97,6 @@ impl CCursorRange {
}
}
#[inline]
#[deprecated = "Use `self.sorted_cursors` instead."]
pub fn sorted(&self) -> [CCursor; 2] {
self.sorted_cursors()
}
pub fn slice_str<'s>(&self, text: &'s str) -> &'s str {
let [min, max] = self.sorted_cursors();
slice_char_range(text, min.index..max.index)

View File

@@ -3,11 +3,9 @@
use std::{any::Any, hash::Hash, ops::Deref, sync::Arc};
use emath::GuiRounding as _;
use epaint::mutex::RwLock;
use crate::containers::menu;
use crate::{containers::*, ecolor::*, layout::*, placer::Placer, widgets::*, *};
use emath::GuiRounding as _;
// ----------------------------------------------------------------------------
/// This is what you use to place widgets.
@@ -75,10 +73,6 @@ pub struct Ui {
/// where we size up the contents of the Ui, without actually showing it.
sizing_pass: bool,
/// Indicates whether this Ui belongs to a Menu.
#[expect(deprecated)]
menu_state: Option<Arc<RwLock<crate::menu::MenuState>>>,
/// The [`UiStack`] for this [`Ui`].
stack: Arc<UiStack>,
@@ -157,7 +151,6 @@ impl Ui {
placer,
enabled: true,
sizing_pass,
menu_state: None,
stack: Arc::new(ui_stack),
sense,
min_rect_already_remembered: false,
@@ -198,47 +191,6 @@ impl Ui {
ui
}
/// Create a new [`Ui`] at a specific region.
///
/// Note: calling this function twice from the same [`Ui`] will create a conflict of id. Use
/// [`Self::scope`] if needed.
///
/// When in doubt, use `None` for the `UiStackInfo` argument.
#[deprecated = "Use ui.new_child() instead"]
pub fn child_ui(
&mut self,
max_rect: Rect,
layout: Layout,
ui_stack_info: Option<UiStackInfo>,
) -> Self {
self.new_child(
UiBuilder::new()
.max_rect(max_rect)
.layout(layout)
.ui_stack_info(ui_stack_info.unwrap_or_default()),
)
}
/// Create a new [`Ui`] at a specific region with a specific id.
///
/// When in doubt, use `None` for the `UiStackInfo` argument.
#[deprecated = "Use ui.new_child() instead"]
pub fn child_ui_with_id_source(
&mut self,
max_rect: Rect,
layout: Layout,
id_salt: impl Hash,
ui_stack_info: Option<UiStackInfo>,
) -> Self {
self.new_child(
UiBuilder::new()
.id_salt(id_salt)
.max_rect(max_rect)
.layout(layout)
.ui_stack_info(ui_stack_info.unwrap_or_default()),
)
}
/// Create a child `Ui` with the properties of the given builder.
///
/// This is a very low-level function.
@@ -320,7 +272,6 @@ impl Ui {
placer,
enabled,
sizing_pass,
menu_state: self.menu_state.clone(),
stack: Arc::new(ui_stack),
sense,
min_rect_already_remembered: false,
@@ -362,18 +313,6 @@ impl Ui {
// -------------------------------------------------
/// Set to true in special cases where we do one frame
/// where we size up the contents of the Ui, without actually showing it.
///
/// This will also turn the Ui invisible.
/// Should be called right after [`Self::new`], if at all.
#[inline]
#[deprecated = "Use UiBuilder.sizing_pass().invisible()"]
pub fn set_sizing_pass(&mut self) {
self.sizing_pass = true;
self.set_invisible();
}
/// Set to true in special cases where we do one frame
/// where we size up the contents of the Ui, without actually showing it.
#[inline]
@@ -412,7 +351,7 @@ impl Ui {
/// Style options for this [`Ui`] and its children.
///
/// Note that this may be a different [`Style`] than that of [`Context::style`].
/// Note that this may be a different [`Style`] than that of [`Context::global_style`].
#[inline]
pub fn style(&self) -> &Arc<Style> {
&self.style
@@ -554,33 +493,6 @@ impl Ui {
}
}
/// Calling `set_enabled(false)` will cause the [`Ui`] to deny all future interaction
/// and all the widgets will draw with a gray look.
///
/// Usually it is more convenient to use [`Self::add_enabled_ui`] or [`Self::add_enabled`].
///
/// Calling `set_enabled(true)` has no effect - it will NOT re-enable the [`Ui`] once disabled.
///
/// ### Example
/// ```
/// # egui::__run_test_ui(|ui| {
/// # let mut enabled = true;
/// ui.group(|ui| {
/// ui.checkbox(&mut enabled, "Enable subsection");
/// ui.set_enabled(enabled);
/// if ui.button("Button that is not always clickable").clicked() {
/// /* … */
/// }
/// });
/// # });
/// ```
#[deprecated = "Use disable(), add_enabled_ui(), or add_enabled() instead"]
pub fn set_enabled(&mut self, enabled: bool) {
if !enabled {
self.disable();
}
}
/// If `false`, any widgets added to the [`Ui`] will be invisible and non-interactive.
///
/// This is `false` if any parent had [`UiBuilder::invisible`]
@@ -597,7 +509,7 @@ impl Ui {
///
/// Once invisible, there is no way to make the [`Ui`] visible again.
///
/// Usually it is more convenient to use [`Self::add_visible_ui`] or [`Self::add_visible`].
/// Usually it is more convenient to use [`Self::add_visible`].
///
/// ### Example
/// ```
@@ -619,34 +531,6 @@ impl Ui {
self.disable();
}
/// Calling `set_visible(false)` will cause all further widgets to be invisible,
/// yet still allocate space.
///
/// The widgets will not be interactive (`set_visible(false)` implies `set_enabled(false)`).
///
/// Calling `set_visible(true)` has no effect.
///
/// ### Example
/// ```
/// # egui::__run_test_ui(|ui| {
/// # let mut visible = true;
/// ui.group(|ui| {
/// ui.checkbox(&mut visible, "Show subsection");
/// ui.set_visible(visible);
/// if ui.button("Button that is not always shown").clicked() {
/// /* … */
/// }
/// });
/// # });
/// ```
#[deprecated = "Use set_invisible(), add_visible_ui(), or add_visible() instead"]
pub fn set_visible(&mut self, visible: bool) {
if !visible {
self.painter.set_invisible();
self.disable();
}
}
/// Make the widget in this [`Ui`] semi-transparent.
///
/// `opacity` must be between 0.0 and 1.0, where 0.0 means fully transparent (i.e., invisible)
@@ -694,17 +578,8 @@ impl Ui {
///
/// This is determined first by [`Style::wrap_mode`], and then by the layout of this [`Ui`].
pub fn wrap_mode(&self) -> TextWrapMode {
#[expect(deprecated)]
if let Some(wrap_mode) = self.style.wrap_mode {
wrap_mode
}
// `wrap` handling for backward compatibility
else if let Some(wrap) = self.style.wrap {
if wrap {
TextWrapMode::Wrap
} else {
TextWrapMode::Extend
}
} else if let Some(grid) = self.placer.grid() {
if grid.wrap_text() {
TextWrapMode::Wrap
@@ -721,14 +596,6 @@ impl Ui {
}
}
/// Should text wrap in this [`Ui`]?
///
/// This is determined first by [`Style::wrap_mode`], and then by the layout of this [`Ui`].
#[deprecated = "Use `wrap_mode` instead"]
pub fn wrap_text(&self) -> bool {
self.wrap_mode() == TextWrapMode::Wrap
}
/// How to vertically align text
#[inline]
pub fn text_valign(&self) -> Align {
@@ -1063,18 +930,6 @@ impl Ui {
)
}
/// Deprecated: use [`Self::interact`] instead.
#[deprecated = "The contains_pointer argument is ignored. Use `ui.interact` instead."]
pub fn interact_with_hovered(
&self,
rect: Rect,
_contains_pointer: bool,
id: Id,
sense: Sense,
) -> Response {
self.interact(rect, id, sense)
}
/// Read the [`Ui`]'s background [`Response`].
/// Its [`Sense`] will be based on the [`UiBuilder::sense`] used to create this [`Ui`].
///
@@ -1086,7 +941,7 @@ impl Ui {
pub fn response(&self) -> Response {
// This is the inverse of Context::read_response. We prefer a response
// based on last frame's widget rect since the one from this frame is Rect::NOTHING until
// Ui::interact_bg is called or the Ui is dropped.
// Ui::remember_min_rect is called or the Ui is dropped.
let mut response = self
.ctx()
.viewport(|viewport| {
@@ -1137,16 +992,6 @@ impl Ui {
response
}
/// Interact with the background of this [`Ui`],
/// i.e. behind all the widgets.
///
/// The rectangle of the [`Response`] (and interactive area) will be [`Self::min_rect`].
#[deprecated = "Use UiBuilder::sense with Ui::response instead"]
pub fn interact_bg(&self, sense: Sense) -> Response {
// This will update the WidgetRect that was first created in `Ui::new`.
self.interact(self.min_rect(), self.unique_id, sense)
}
/// Is the pointer (mouse/touch) above this rectangle in this [`Ui`]?
///
/// The `clip_rect` and layer of this [`Ui`] will be respected, so, for instance,
@@ -1499,34 +1344,6 @@ impl Ui {
)
}
/// Allocated the given rectangle and then adds content to that rectangle.
///
/// If the contents overflow, more space will be allocated.
/// When finished, the amount of space actually used (`min_rect`) will be allocated.
/// So you can request a lot of space and then use less.
#[deprecated = "Use `allocate_new_ui` instead"]
pub fn allocate_ui_at_rect<R>(
&mut self,
max_rect: Rect,
add_contents: impl FnOnce(&mut Self) -> R,
) -> InnerResponse<R> {
self.scope_builder(UiBuilder::new().max_rect(max_rect), add_contents)
}
/// Allocated space (`UiBuilder::max_rect`) and then add content to it.
///
/// If the contents overflow, more space will be allocated.
/// When finished, the amount of space actually used (`min_rect`) will be allocated in the parent.
/// So you can request a lot of space and then use less.
#[deprecated = "Use `scope_builder` instead"]
pub fn allocate_new_ui<R>(
&mut self,
ui_builder: UiBuilder,
add_contents: impl FnOnce(&mut Self) -> R,
) -> InnerResponse<R> {
self.scope_dyn(ui_builder, Box::new(add_contents))
}
/// Convenience function to get a region to paint on.
///
/// Note that egui uses screen coordinates for everything.
@@ -1817,7 +1634,7 @@ impl Ui {
/// If you call `add_visible` from within an already invisible [`Ui`],
/// the widget will always be invisible, even if the `visible` argument is true.
///
/// See also [`Self::add_visible_ui`], [`Self::set_visible`] and [`Self::is_visible`].
/// See also [`Self::set_invisible`] and [`Self::is_visible`].
///
/// ```
/// # egui::__run_test_ui(|ui| {
@@ -1842,38 +1659,6 @@ impl Ui {
}
}
/// Add a section that is possibly invisible, i.e. greyed out and non-interactive.
///
/// An invisible ui still takes up the same space as if it were visible.
///
/// If you call `add_visible_ui` from within an already invisible [`Ui`],
/// the result will always be invisible, even if the `visible` argument is true.
///
/// See also [`Self::add_visible`], [`Self::set_visible`] and [`Self::is_visible`].
///
/// ### Example
/// ```
/// # egui::__run_test_ui(|ui| {
/// # let mut visible = true;
/// ui.checkbox(&mut visible, "Show subsection");
/// ui.add_visible_ui(visible, |ui| {
/// ui.label("Maybe you see this, maybe you don't!");
/// });
/// # });
/// ```
#[deprecated = "Use 'ui.scope_builder' instead"]
pub fn add_visible_ui<R>(
&mut self,
visible: bool,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> InnerResponse<R> {
let mut ui_builder = UiBuilder::new();
if !visible {
ui_builder = ui_builder.invisible();
}
self.scope_builder(ui_builder, add_contents)
}
/// Add extra space before the next widget.
///
/// The direction is dependent on the layout.
@@ -2381,21 +2166,6 @@ impl Ui {
self.scope_dyn(UiBuilder::new().id_salt(id_salt), Box::new(add_contents))
}
/// Push another level onto the [`UiStack`].
///
/// You can use this, for instance, to tag a group of widgets.
#[deprecated = "Use 'ui.scope_builder' instead"]
pub fn push_stack_info<R>(
&mut self,
ui_stack_info: UiStackInfo,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> InnerResponse<R> {
self.scope_dyn(
UiBuilder::new().ui_stack_info(ui_stack_info),
Box::new(add_contents),
)
}
/// Create a scoped child ui.
///
/// You can use this to temporarily change the [`Style`] of a sub-region, for instance:
@@ -2436,26 +2206,6 @@ impl Ui {
InnerResponse::new(ret, response)
}
/// Redirect shapes to another paint layer.
///
/// ```
/// # use egui::{LayerId, Order, Id};
/// # egui::__run_test_ui(|ui| {
/// let layer_id = LayerId::new(Order::Tooltip, Id::new("my_floating_ui"));
/// ui.with_layer_id(layer_id, |ui| {
/// ui.label("This is now in a different layer");
/// });
/// # });
/// ```
#[deprecated = "Use ui.scope_builder(UiBuilder::new().layer_id(…), …) instead"]
pub fn with_layer_id<R>(
&mut self,
layer_id: LayerId,
add_contents: impl FnOnce(&mut Self) -> R,
) -> InnerResponse<R> {
self.scope_builder(UiBuilder::new().layer_id(layer_id), add_contents)
}
/// A [`CollapsingHeader`] that starts out collapsed.
///
/// The name must be unique within the current parent,
@@ -3009,22 +2759,6 @@ impl Ui {
/// # Menus
impl Ui {
/// Close the menu we are in (including submenus), if any.
///
/// See also: [`Self::menu_button`] and [`Response::context_menu`].
#[deprecated = "Use `ui.close()` or `ui.close_kind(UiKind::Menu)` instead"]
pub fn close_menu(&self) {
self.close_kind(UiKind::Menu);
}
#[expect(deprecated)]
pub(crate) fn set_menu_state(
&mut self,
menu_state: Option<Arc<RwLock<crate::menu::MenuState>>>,
) {
self.menu_state = menu_state;
}
#[inline]
/// Create a menu button that when clicked will show the given menu.
///

View File

@@ -8,7 +8,3 @@ pub use id_type_map::IdTypeMap;
pub use epaint::emath::History;
pub use epaint::util::{hash, hash_with};
/// Deprecated alias for [`crate::cache`].
#[deprecated = "Use egui::cache instead"]
pub use crate::cache;

View File

@@ -1201,7 +1201,7 @@ impl ViewportCommand {
/// Describes a viewport, i.e. a native window.
///
/// This is returned by [`crate::Context::run`] on each frame, and should be applied
/// This is returned by [`crate::Context::run_ui`] on each frame, and should be applied
/// by the integration.
#[derive(Clone)]
pub struct ViewportOutput {

View File

@@ -156,7 +156,7 @@ impl RichText {
/// Default: 0.0.
///
/// For even text it is recommended you round this to an even number of _pixels_,
/// e.g. using [`crate::Painter::round_to_pixel`].
/// e.g. using [`emath::GuiRounding`].
#[inline]
pub fn extra_letter_spacing(mut self, extra_letter_spacing: f32) -> Self {
self.extra_letter_spacing = extra_letter_spacing;
@@ -170,7 +170,7 @@ impl RichText {
/// If `None` (the default), the line height is determined by the font.
///
/// For even text it is recommended you round this to an even number of _pixels_,
/// e.g. using [`crate::Painter::round_to_pixel`].
/// e.g. using [`emath::GuiRounding`].
#[inline]
pub fn line_height(mut self, line_height: Option<f32>) -> Self {
self.line_height = line_height;

View File

@@ -200,12 +200,6 @@ impl<'a> Button<'a> {
self
}
#[inline]
#[deprecated = "Renamed to `corner_radius`"]
pub fn rounding(self, corner_radius: impl Into<CornerRadius>) -> Self {
self.corner_radius(corner_radius)
}
/// If true, the tint of the image is multiplied by the widget text color.
///
/// This makes sense for images that are white, that should have the same color as the text color.

View File

@@ -91,16 +91,6 @@ impl<'a> DragValue<'a> {
self
}
/// Sets valid range for the value.
///
/// By default all values are clamped to this range, even when not interacted with.
/// You can change this behavior by passing `false` to [`Self::clamp_existing_to_range`].
#[deprecated = "Use `range` instead"]
#[inline]
pub fn clamp_range<Num: emath::Numeric>(self, range: RangeInclusive<Num>) -> Self {
self.range(range)
}
/// Sets valid range for dragging the value.
///
/// By default all values are clamped to this range, even when not interacted with.
@@ -157,12 +147,6 @@ impl<'a> DragValue<'a> {
self
}
#[inline]
#[deprecated = "Renamed clamp_existing_to_range"]
pub fn clamp_to_range(self, clamp_to_range: bool) -> Self {
self.clamp_existing_to_range(clamp_to_range)
}
/// Show a prefix before the number, e.g. "x: "
#[inline]
pub fn prefix(mut self, prefix: impl IntoAtoms<'a>) -> Self {

View File

@@ -256,18 +256,6 @@ impl<'a> Image<'a> {
self
}
/// Round the corners of the image.
///
/// The default is no rounding ([`CornerRadius::ZERO`]).
///
/// Due to limitations in the current implementation,
/// this will turn off any rotation of the image.
#[inline]
#[deprecated = "Renamed to `corner_radius`"]
pub fn rounding(self, corner_radius: impl Into<CornerRadius>) -> Self {
self.corner_radius(corner_radius)
}
/// Show a spinner when the image is loading.
///
/// By default this uses the value of [`crate::Visuals::image_loading_spinners`].

View File

@@ -1,164 +0,0 @@
use crate::{
Color32, CornerRadius, Image, Rect, Response, Sense, Ui, Vec2, Widget, WidgetInfo, WidgetType,
widgets,
};
/// A clickable image within a frame.
#[must_use = "You should put this widget in a ui with `ui.add(widget);`"]
#[derive(Clone, Debug)]
#[deprecated(since = "0.33.0", note = "Use egui::Button::image instead")]
pub struct ImageButton<'a> {
pub(crate) image: Image<'a>,
sense: Sense,
frame: bool,
selected: bool,
alt_text: Option<String>,
}
#[expect(deprecated, reason = "Deprecated in egui 0.33.0")]
impl<'a> ImageButton<'a> {
pub fn new(image: impl Into<Image<'a>>) -> Self {
Self {
image: image.into(),
sense: Sense::click(),
frame: true,
selected: false,
alt_text: None,
}
}
/// Select UV range. Default is (0,0) in top-left, (1,1) bottom right.
#[inline]
pub fn uv(mut self, uv: impl Into<Rect>) -> Self {
self.image = self.image.uv(uv);
self
}
/// Multiply image color with this. Default is WHITE (no tint).
#[inline]
pub fn tint(mut self, tint: impl Into<Color32>) -> Self {
self.image = self.image.tint(tint);
self
}
/// If `true`, mark this button as "selected".
#[inline]
pub fn selected(mut self, selected: bool) -> Self {
self.selected = selected;
self
}
/// Turn off the frame
#[inline]
pub fn frame(mut self, frame: bool) -> Self {
self.frame = frame;
self
}
/// By default, buttons senses clicks.
/// Change this to a drag-button with `Sense::drag()`.
#[inline]
pub fn sense(mut self, sense: Sense) -> Self {
self.sense = sense;
self
}
/// Set rounding for the `ImageButton`.
///
/// If the underlying image already has rounding, this
/// will override that value.
#[inline]
pub fn corner_radius(mut self, corner_radius: impl Into<CornerRadius>) -> Self {
self.image = self.image.corner_radius(corner_radius.into());
self
}
/// Set rounding for the `ImageButton`.
///
/// If the underlying image already has rounding, this
/// will override that value.
#[inline]
#[deprecated = "Renamed to `corner_radius`"]
pub fn rounding(self, corner_radius: impl Into<CornerRadius>) -> Self {
self.corner_radius(corner_radius)
}
}
#[expect(deprecated, reason = "Deprecated in egui 0.33.0")]
impl Widget for ImageButton<'_> {
fn ui(self, ui: &mut Ui) -> Response {
let padding = if self.frame {
// so we can see that it is a button:
Vec2::splat(ui.spacing().button_padding.x)
} else {
Vec2::ZERO
};
let available_size_for_image = ui.available_size() - 2.0 * padding;
let tlr = self.image.load_for_size(ui.ctx(), available_size_for_image);
let image_source_size = tlr.as_ref().ok().and_then(|t| t.size());
let image_size = self
.image
.calc_size(available_size_for_image, image_source_size);
let padded_size = image_size + 2.0 * padding;
let (rect, response) = ui.allocate_exact_size(padded_size, self.sense);
response.widget_info(|| {
let mut info = WidgetInfo::new(WidgetType::Button);
info.label = self.alt_text.clone();
info
});
if ui.is_rect_visible(rect) {
let (expansion, rounding, fill, stroke) = if self.selected {
let selection = ui.visuals().selection;
(
Vec2::ZERO,
self.image.image_options().corner_radius,
selection.bg_fill,
selection.stroke,
)
} else if self.frame {
let visuals = ui.style().interact(&response);
let expansion = Vec2::splat(visuals.expansion);
(
expansion,
self.image.image_options().corner_radius,
visuals.weak_bg_fill,
visuals.bg_stroke,
)
} else {
Default::default()
};
// Draw frame background (for transparent images):
ui.painter()
.rect_filled(rect.expand2(expansion), rounding, fill);
let image_rect = ui
.layout()
.align_size_within_rect(image_size, rect.shrink2(padding));
// let image_rect = image_rect.expand2(expansion); // can make it blurry, so let's not
let image_options = self.image.image_options().clone();
widgets::image::paint_texture_load_result(
ui,
&tlr,
image_rect,
None,
&image_options,
self.alt_text.as_deref(),
);
// Draw frame outline:
ui.painter().rect_stroke(
rect.expand2(expansion),
rounding,
stroke,
epaint::StrokeKind::Inside,
);
}
widgets::image::texture_load_result_response(&self.image.source(ui.ctx()), &tlr, response)
}
}

View File

@@ -4,7 +4,7 @@
//! * `ui.add(Label::new("Text").text_color(color::red));`
//! * `if ui.add(Button::new("Click me")).clicked() { … }`
use crate::{Response, Ui, epaint};
use crate::{Response, Ui};
mod button;
mod checkbox;
@@ -12,19 +12,14 @@ pub mod color_picker;
pub(crate) mod drag_value;
mod hyperlink;
mod image;
mod image_button;
mod label;
mod progress_bar;
mod radio_button;
mod selected_label;
mod separator;
mod slider;
mod spinner;
pub mod text_edit;
#[expect(deprecated)]
pub use self::selected_label::SelectableLabel;
#[expect(deprecated, reason = "Deprecated in egui 0.33.0")]
pub use self::{
button::Button,
checkbox::Checkbox,
@@ -34,7 +29,6 @@ pub use self::{
FrameDurations, Image, ImageFit, ImageOptions, ImageSize, ImageSource,
decode_animated_image_uri, has_gif_magic_header, has_webp_header, paint_texture_at,
},
image_button::ImageButton,
label::Label,
progress_bar::ProgressBar,
radio_button::RadioButton,
@@ -126,14 +120,6 @@ pub fn reset_button_with<T: PartialEq>(ui: &mut Ui, value: &mut T, text: &str, r
// ----------------------------------------------------------------------------
#[deprecated = "Use `ui.add(&mut stroke)` instead"]
pub fn stroke_ui(ui: &mut crate::Ui, stroke: &mut epaint::Stroke, text: &str) {
ui.horizontal(|ui| {
ui.label(text);
ui.add(stroke);
});
}
/// Show a small button to switch to/from dark/light mode (globally).
pub fn global_theme_preference_switch(ui: &mut Ui) {
if let Some(new_theme) = ui.ctx().theme().small_toggle_button(ui) {
@@ -147,15 +133,3 @@ pub fn global_theme_preference_buttons(ui: &mut Ui) {
theme_preference.radio_buttons(ui);
ui.ctx().set_theme(theme_preference);
}
/// Show a small button to switch to/from dark/light mode (globally).
#[deprecated = "Use global_theme_preference_switch instead"]
pub fn global_dark_light_mode_switch(ui: &mut Ui) {
global_theme_preference_switch(ui);
}
/// Show larger buttons for switching between light and dark mode (globally).
#[deprecated = "Use global_theme_preference_buttons instead"]
pub fn global_dark_light_mode_buttons(ui: &mut Ui) {
global_theme_preference_buttons(ui);
}

View File

@@ -94,12 +94,6 @@ impl ProgressBar {
self.corner_radius = Some(corner_radius.into());
self
}
#[inline]
#[deprecated = "Renamed to `corner_radius`"]
pub fn rounding(self, corner_radius: impl Into<CornerRadius>) -> Self {
self.corner_radius(corner_radius)
}
}
impl Widget for ProgressBar {

View File

@@ -1,13 +0,0 @@
#![expect(deprecated, clippy::new_ret_no_self)]
use crate::WidgetText;
#[deprecated = "Use `Button::selectable()` instead"]
pub struct SelectableLabel {}
impl SelectableLabel {
#[deprecated = "Use `Button::selectable()` instead"]
pub fn new(selected: bool, text: impl Into<WidgetText>) -> super::Button<'static> {
crate::Button::selectable(selected, text)
}
}

View File

@@ -79,7 +79,7 @@ pub enum SliderClamping {
///
/// The slider range defines the values you get when pulling the slider to the far edges.
/// By default all values are clamped to this range, even when not interacted with.
/// You can change this behavior by passing `false` to [`Slider::clamp_to_range`].
/// You can change this behavior by passing `false` to [`Slider::clamping`].
///
/// The range can include any numbers, and go from low-to-high or from high-to-low.
///
@@ -288,16 +288,6 @@ impl<'a> Slider<'a> {
self
}
#[inline]
#[deprecated = "Use `slider.clamping(…) instead"]
pub fn clamp_to_range(self, clamp_to_range: bool) -> Self {
self.clamping(if clamp_to_range {
SliderClamping::Always
} else {
SliderClamping::Never
})
}
/// Turn smart aim on/off. Default is ON.
/// There is almost no point in turning this off.
#[inline]

View File

@@ -51,14 +51,6 @@ impl<'a> DatePickerButton<'a> {
self
}
/// Add id source.
/// Must be set if multiple date picker buttons are in the same Ui.
#[inline]
#[deprecated = "Renamed id_salt"]
pub fn id_source(self, id_salt: &'a str) -> Self {
self.id_salt(id_salt)
}
/// Show combo boxes in date picker popup. (Default: true)
#[inline]
pub fn combo_boxes(mut self, combo_boxes: bool) -> Self {

View File

@@ -270,15 +270,6 @@ impl<'a> TableBuilder<'a> {
}
}
/// Give this table a unique id within the parent [`Ui`].
///
/// This is required if you have multiple tables in the same [`Ui`].
#[inline]
#[deprecated = "Renamed id_salt"]
pub fn id_source(self, id_salt: impl std::hash::Hash) -> Self {
self.id_salt(id_salt)
}
/// Give this table a unique id within the parent [`Ui`].
///
/// This is required if you have multiple tables in the same [`Ui`].
@@ -329,7 +320,7 @@ impl<'a> TableBuilder<'a> {
/// Enables scrolling the table's contents using mouse drag (default: `true`).
///
/// See [`ScrollArea::drag_to_scroll`] for more.
/// See [`ScrollArea::scroll_source`] for more.
#[inline]
pub fn drag_to_scroll(mut self, drag_to_scroll: bool) -> Self {
self.scroll_options.drag_to_scroll = drag_to_scroll;

View File

@@ -1,8 +1,6 @@
use egui::Frame;
type AppKindContextState<'a, State> = Box<dyn FnMut(&egui::Context, &mut State) + 'a>;
type AppKindUiState<'a, State> = Box<dyn FnMut(&mut egui::Ui, &mut State) + 'a>;
type AppKindContext<'a> = Box<dyn FnMut(&egui::Context) + 'a>;
type AppKindUi<'a> = Box<dyn FnMut(&mut egui::Ui) + 'a>;
/// In order to access the [`eframe::App`] trait from the generic `State`, we store a function pointer
@@ -13,9 +11,7 @@ type AppKindUi<'a> = Box<dyn FnMut(&mut egui::Ui) + 'a>;
type AppKindEframe<'a, State> = (fn(&mut State) -> &mut dyn eframe::App, eframe::Frame);
pub(crate) enum AppKind<'a, State> {
Context(AppKindContext<'a>),
Ui(AppKindUi<'a>),
ContextState(AppKindContextState<'a, State>),
UiState(AppKindUiState<'a, State>),
#[cfg(feature = "eframe")]
Eframe(AppKindEframe<'a, State>),
@@ -29,25 +25,12 @@ impl<State> AppKind<'_, State> {
sizing_pass: bool,
) -> Option<egui::Response> {
match self {
AppKind::Context(f) => {
debug_assert!(!sizing_pass, "Context closures cannot do a sizing pass");
f(ui);
None
}
AppKind::ContextState(f) => {
debug_assert!(!sizing_pass, "Context closures cannot do a sizing pass");
f(ui, state);
None
}
#[cfg(feature = "eframe")]
AppKind::Eframe((get_app, frame)) => {
let app = get_app(state);
app.logic(ui, frame);
#[expect(deprecated)]
app.update(ui, frame);
app.ui(ui, frame);
None
@@ -74,8 +57,9 @@ impl<State> AppKind<'_, State> {
.show(ui, |ui| match self {
AppKind::Ui(f) => f(ui),
AppKind::UiState(f) => f(ui, state),
_ => unreachable!(
"run_ui should only be called with AppKind::Ui or AppKind UiState"
#[cfg(feature = "eframe")]
AppKind::Eframe(_) => unreachable!(
"run_ui should only be called with AppKind::Ui or AppKind::UiState"
),
});
})

View File

@@ -159,46 +159,10 @@ impl<State> HarnessBuilder<State> {
self.renderer(crate::wgpu::WgpuTestRenderer::from_setup(setup))
}
/// Create a new Harness with the given app closure and a state.
///
/// The app closure will immediately be called once to create the initial ui.
///
/// If you don't need to create Windows / Panels, you can use [`HarnessBuilder::build_ui`] instead.
///
/// # Example
/// ```rust
/// # use egui::CentralPanel;
/// # use egui_kittest::{Harness, kittest::Queryable};
/// let checked = false;
/// let mut harness = Harness::builder()
/// .with_size(egui::Vec2::new(300.0, 200.0))
/// .build_state(|ctx, checked| {
/// CentralPanel::default().show(ctx, |ui| {
/// ui.checkbox(checked, "Check me!");
/// });
/// }, checked);
///
/// harness.get_by_label("Check me!").click();
/// harness.run();
///
/// assert_eq!(*harness.state(), true);
/// ```
#[track_caller]
#[deprecated = "use `build_ui_state` instead"]
pub fn build_state<'a>(
self,
app: impl FnMut(&egui::Context, &mut State) + 'a,
state: State,
) -> Harness<'a, State> {
Harness::from_builder(self, AppKind::ContextState(Box::new(app)), state, None)
}
/// Create a new Harness with the given ui closure and a state.
///
/// The ui closure will immediately be called once to create the initial ui.
///
/// If you need to create Windows / Panels, you can use [`HarnessBuilder::build`] instead.
///
/// # Example
/// ```rust
/// # use egui_kittest::{Harness, kittest::Queryable};
@@ -249,37 +213,10 @@ impl<State> HarnessBuilder<State> {
}
impl HarnessBuilder {
/// Create a new Harness with the given app closure.
///
/// The app closure will immediately be called once to create the initial ui.
///
/// If you don't need to create Windows / Panels, you can use [`HarnessBuilder::build_ui`] instead.
///
/// # Example
/// ```rust
/// # use egui::CentralPanel;
/// # use egui_kittest::{Harness, kittest::Queryable};
/// let mut harness = Harness::builder()
/// .with_size(egui::Vec2::new(300.0, 200.0))
/// .build(|ctx| {
/// CentralPanel::default().show(ctx, |ui| {
/// ui.label("Hello, world!");
/// });
/// });
/// ```
#[must_use]
#[track_caller]
#[deprecated = "use `build_ui` instead"]
pub fn build<'a>(self, app: impl FnMut(&egui::Context) + 'a) -> Harness<'a> {
Harness::from_builder(self, AppKind::Context(Box::new(app)), (), None)
}
/// Create a new Harness with the given ui closure.
///
/// The ui closure will immediately be called once to create the initial ui.
///
/// If you need to create Windows / Panels, you can use [`HarnessBuilder::build`] instead.
///
/// # Example
/// ```rust
/// # use egui_kittest::{Harness, kittest::Queryable};

View File

@@ -60,7 +60,7 @@ impl Display for ExceededMaxStepsError {
/// The test Harness. This contains everything needed to run the test.
///
/// Create a new Harness using [`Harness::new`] or [`Harness::builder`].
/// Create a new Harness using [`Harness::new_ui`] or [`Harness::builder`].
///
/// The [Harness] has a optional generic state that can be used to pass data to the app / ui closure.
/// In _most cases_ it should be fine to just store the state in the closure itself.
@@ -185,43 +185,10 @@ impl<'a, State> Harness<'a, State> {
HarnessBuilder::default()
}
/// Create a new Harness with the given app closure and a state.
///
/// The app closure will immediately be called once to create the initial ui.
///
/// If you don't need to create Windows / Panels, you can use [`Harness::new_ui`] instead.
///
/// If you e.g. want to customize the size of the window, you can use [`Harness::builder`].
///
/// # Example
/// ```rust
/// # use egui::CentralPanel;
/// # use egui_kittest::{Harness, kittest::Queryable};
/// let mut checked = false;
/// let mut harness = Harness::new_state(|ctx, checked| {
/// CentralPanel::default().show(ctx, |ui| {
/// ui.checkbox(checked, "Check me!");
/// });
/// }, checked);
///
/// harness.get_by_label("Check me!").click();
/// harness.run();
///
/// assert_eq!(*harness.state(), true);
/// ```
#[track_caller]
#[deprecated = "use `new_ui_state` instead"]
pub fn new_state(app: impl FnMut(&egui::Context, &mut State) + 'a, state: State) -> Self {
#[expect(deprecated)]
Self::builder().build_state(app, state)
}
/// Create a new Harness with the given ui closure and a state.
///
/// The ui closure will immediately be called once to create the initial ui.
///
/// If you need to create Windows / Panels, you can use [`Harness::new`] instead.
///
/// If you e.g. want to customize the size of the ui, you can use [`Harness::builder`].
///
/// # Example
@@ -714,48 +681,15 @@ impl<'a, State> Harness<'a, State> {
queue: &self.queued_events,
}
}
#[deprecated = "Use `Harness::root` instead."]
pub fn node(&self) -> Node<'_> {
self.root()
}
}
/// Utilities for stateless harnesses.
impl<'a> Harness<'a> {
/// Create a new Harness with the given app closure.
/// Use the [`Harness::run`], [`Harness::step`], etc... methods to run the app.
///
/// The app closure will immediately be called once to create the initial ui.
///
/// If you don't need to create Windows / Panels, you can use [`Harness::new_ui`] instead.
///
/// If you e.g. want to customize the size of the window, you can use [`Harness::builder`].
///
/// # Example
/// ```rust
/// # use egui::CentralPanel;
/// # use egui_kittest::Harness;
/// let mut harness = Harness::new(|ctx| {
/// CentralPanel::default().show(ctx, |ui| {
/// ui.label("Hello, world!");
/// });
/// });
/// ```
#[track_caller]
#[deprecated = "use `new_ui` instead"]
pub fn new(app: impl FnMut(&egui::Context) + 'a) -> Self {
#[expect(deprecated)]
Self::builder().build(app)
}
/// Create a new Harness with the given ui closure.
/// Use the [`Harness::run`], [`Harness::step`], etc... methods to run the app.
///
/// The ui closure will immediately be called once to create the initial ui.
///
/// If you need to create Windows / Panels, you can use [`Harness::new`] instead.
///
/// If you e.g. want to customize the size of the ui, you can use [`Harness::builder`].
///
/// # Example

View File

@@ -54,11 +54,6 @@ impl Node<'_> {
self.click_button(PointerButton::Primary);
}
#[deprecated = "Use `click()` instead."]
pub fn simulate_click(&self) {
self.click();
}
pub fn click_secondary(&self) {
self.click_button(PointerButton::Secondary);
}
@@ -130,28 +125,6 @@ impl Node<'_> {
}));
}
#[deprecated = "Use `Harness::key_down` instead."]
pub fn key_down(&self, key: egui::Key) {
self.event(egui::Event::Key {
key,
pressed: true,
modifiers: Modifiers::default(),
repeat: false,
physical_key: None,
});
}
#[deprecated = "Use `Harness::key_up` instead."]
pub fn key_up(&self, key: egui::Key) {
self.event(egui::Event::Key {
key,
pressed: false,
modifiers: Modifiers::default(),
repeat: false,
physical_key: None,
});
}
pub fn type_text(&self, text: &str) {
self.event(egui::Event::Text(text.to_owned()));
}

View File

@@ -71,15 +71,9 @@ pub use self::{
viewport::ViewportInPixels,
};
#[deprecated = "Renamed to CornerRadius"]
pub type Rounding = CornerRadius;
pub use ecolor::{Color32, Hsva, HsvaGamma, Rgba};
pub use emath::{Pos2, Rect, Vec2, pos2, vec2};
#[deprecated = "Use the ahash crate directly."]
pub use ahash;
pub use ecolor;
pub use emath;

View File

@@ -17,9 +17,6 @@ pub struct MarginF32 {
pub bottom: f32,
}
#[deprecated = "Renamed to MarginF32"]
pub type Marginf = MarginF32;
impl From<Margin> for MarginF32 {
#[inline]
fn from(margin: Margin) -> Self {
@@ -97,18 +94,6 @@ impl MarginF32 {
pub fn is_same(&self) -> bool {
self.left == self.right && self.left == self.top && self.left == self.bottom
}
#[deprecated = "Use `rect + margin` instead"]
#[inline]
pub fn expand_rect(&self, rect: Rect) -> Rect {
Rect::from_min_max(rect.min - self.left_top(), rect.max + self.right_bottom())
}
#[deprecated = "Use `rect - margin` instead"]
#[inline]
pub fn shrink_rect(&self, rect: Rect) -> Rect {
Rect::from_min_max(rect.min + self.left_top(), rect.max - self.right_bottom())
}
}
impl From<f32> for MarginF32 {

View File

@@ -357,12 +357,6 @@ impl Shape {
.into()
}
#[inline]
#[deprecated = "Use `Shape::galley` or `Shape::galley_with_override_text_color` instead"]
pub fn galley_with_color(pos: Pos2, galley: Arc<Galley>, text_color: Color32) -> Self {
Self::galley_with_override_text_color(pos, galley, text_color)
}
#[inline]
pub fn mesh(mesh: impl Into<Arc<Mesh>>) -> Self {
let mesh = mesh.into();

View File

@@ -1703,16 +1703,6 @@ impl Tessellator {
.stroke_open(self.feathering, &stroke.into(), out);
}
#[deprecated = "Use `tessellate_line_segment` instead"]
pub fn tessellate_line(
&mut self,
points: [Pos2; 2],
stroke: impl Into<Stroke>,
out: &mut Mesh,
) {
self.tessellate_line_segment(points, stroke, out);
}
/// Tessellate a single [`PathShape`] into a [`Mesh`].
///
/// * `path_shape`: the path to tessellate.