diff --git a/crates/egui/src/containers/collapsing_header.rs b/crates/egui/src/containers/collapsing_header.rs index 70fd3736bc0..298cdb47698 100644 --- a/crates/egui/src/containers/collapsing_header.rs +++ b/crates/egui/src/containers/collapsing_header.rs @@ -372,7 +372,7 @@ pub struct CollapsingHeader { text: WidgetText, default_open: bool, open: Option, - id_source: Id, + id_salt: Id, enabled: bool, selectable: bool, selected: bool, @@ -386,15 +386,15 @@ impl CollapsingHeader { /// The label is used as an [`Id`] source. /// If the label is unique and static this is fine, /// but if it changes or there are several [`CollapsingHeader`] with the same title - /// you need to provide a unique id source with [`Self::id_source`]. + /// you need to provide a unique id source with [`Self::id_salt`]. pub fn new(text: impl Into) -> Self { let text = text.into(); - let id_source = Id::new(text.text()); + let id_salt = Id::new(text.text()); Self { text, default_open: false, open: None, - id_source, + id_salt, enabled: true, selectable: false, selected: false, @@ -425,8 +425,17 @@ impl CollapsingHeader { /// 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. #[inline] - pub fn id_source(mut self, id_source: impl Hash) -> Self { - self.id_source = Id::new(id_source); + pub fn id_salt(mut self, id_salt: impl Hash) -> Self { + self.id_salt = Id::new(id_salt); + 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 } @@ -494,7 +503,7 @@ impl CollapsingHeader { text, default_open, open, - id_source, + id_salt, enabled: _, selectable, selected, @@ -503,7 +512,7 @@ impl CollapsingHeader { // TODO(emilk): horizontal layout, with icon and text as labels. Insert background behind using Frame. - let id = ui.make_persistent_id(id_source); + let id = ui.make_persistent_id(id_salt); let button_padding = ui.spacing().button_padding; let available = ui.available_rect_before_wrap(); diff --git a/crates/egui/src/containers/combo_box.rs b/crates/egui/src/containers/combo_box.rs index 75305425e42..9883e2c755a 100644 --- a/crates/egui/src/containers/combo_box.rs +++ b/crates/egui/src/containers/combo_box.rs @@ -38,7 +38,7 @@ pub type IconPainter = Box, selected_text: WidgetText, width: Option, @@ -49,9 +49,9 @@ pub struct ComboBox { impl ComboBox { /// Create new [`ComboBox`] with id and label - pub fn new(id_source: impl std::hash::Hash, label: impl Into) -> Self { + pub fn new(id_salt: impl std::hash::Hash, label: impl Into) -> Self { Self { - id_source: Id::new(id_source), + id_salt: Id::new(id_salt), label: Some(label.into()), selected_text: Default::default(), width: None, @@ -65,7 +65,7 @@ impl ComboBox { pub fn from_label(label: impl Into) -> Self { let label = label.into(); Self { - id_source: Id::new(label.text()), + id_salt: Id::new(label.text()), label: Some(label), selected_text: Default::default(), width: None, @@ -76,9 +76,9 @@ impl ComboBox { } /// Without label. - pub fn from_id_source(id_source: impl std::hash::Hash) -> Self { + pub fn from_id_salt(id_salt: impl std::hash::Hash) -> Self { Self { - id_source: Id::new(id_source), + id_salt: Id::new(id_salt), label: Default::default(), selected_text: Default::default(), width: None, @@ -88,6 +88,12 @@ impl ComboBox { } } + /// Without label. + #[deprecated = "Renamed 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`]. @@ -138,7 +144,7 @@ impl ComboBox { /// )); /// } /// - /// egui::ComboBox::from_id_source("my-combobox") + /// egui::ComboBox::from_id_salt("my-combobox") /// .selected_text(text) /// .icon(filled_triangle) /// .show_ui(ui, |_ui| {}); @@ -195,7 +201,7 @@ impl ComboBox { menu_contents: Box R + 'c>, ) -> InnerResponse> { let Self { - id_source, + id_salt, label, selected_text, width, @@ -204,7 +210,7 @@ impl ComboBox { wrap_mode, } = self; - let button_id = ui.make_persistent_id(id_source); + let button_id = ui.make_persistent_id(id_salt); ui.horizontal(|ui| { let mut ir = combo_box_dyn( diff --git a/crates/egui/src/containers/panel.rs b/crates/egui/src/containers/panel.rs index d6c0321f110..652a6755686 100644 --- a/crates/egui/src/containers/panel.rs +++ b/crates/egui/src/containers/panel.rs @@ -266,7 +266,7 @@ impl SidePanel { let mut panel_ui = ui.new_child( UiBuilder::new() - .id_source(id) + .id_salt(id) .ui_stack_info(UiStackInfo::new(match side { Side::Left => UiKind::LeftPanel, Side::Right => UiKind::RightPanel, @@ -761,7 +761,7 @@ impl TopBottomPanel { let mut panel_ui = ui.new_child( UiBuilder::new() - .id_source(id) + .id_salt(id) .ui_stack_info(UiStackInfo::new(match side { TopBottomSide::Top => UiKind::TopPanel, TopBottomSide::Bottom => UiKind::BottomPanel, diff --git a/crates/egui/src/containers/resize.rs b/crates/egui/src/containers/resize.rs index 98518bcef11..458bf11229d 100644 --- a/crates/egui/src/containers/resize.rs +++ b/crates/egui/src/containers/resize.rs @@ -34,7 +34,7 @@ impl State { #[must_use = "You should call .show()"] pub struct Resize { id: Option, - id_source: Option, + id_salt: Option, /// If false, we are no enabled resizable: Vec2b, @@ -51,7 +51,7 @@ impl Default for Resize { fn default() -> Self { Self { id: None, - id_source: None, + id_salt: None, resizable: Vec2b::TRUE, min_size: Vec2::splat(16.0), max_size: Vec2::splat(f32::INFINITY), @@ -71,8 +71,15 @@ impl Resize { /// A source for the unique [`Id`], e.g. `.id_source("second_resize_area")` or `.id_source(loop_index)`. #[inline] - pub fn id_source(mut self, id_source: impl std::hash::Hash) -> Self { - self.id_source = Some(Id::new(id_source)); + #[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 { + self.id_salt = Some(Id::new(id_salt)); self } @@ -201,8 +208,8 @@ impl Resize { fn begin(&mut self, ui: &mut Ui) -> Prepared { let position = ui.available_rect_before_wrap().min; let id = self.id.unwrap_or_else(|| { - let id_source = self.id_source.unwrap_or_else(|| Id::new("resize")); - ui.make_persistent_id(id_source) + let id_salt = self.id_salt.unwrap_or_else(|| Id::new("resize")); + ui.make_persistent_id(id_salt) }); let mut state = State::load(ui.ctx(), id).unwrap_or_else(|| { diff --git a/crates/egui/src/containers/scroll_area.rs b/crates/egui/src/containers/scroll_area.rs index 0cac8181e10..d8252e113e2 100644 --- a/crates/egui/src/containers/scroll_area.rs +++ b/crates/egui/src/containers/scroll_area.rs @@ -171,7 +171,7 @@ pub struct ScrollArea { max_size: Vec2, min_scrolled_size: Vec2, scroll_bar_visibility: ScrollBarVisibility, - id_source: Option, + id_salt: Option, offset_x: Option, offset_y: Option, @@ -223,7 +223,7 @@ impl ScrollArea { max_size: Vec2::INFINITY, min_scrolled_size: Vec2::splat(64.0), scroll_bar_visibility: Default::default(), - id_source: None, + id_salt: None, offset_x: None, offset_y: None, scrolling_enabled: true, @@ -290,8 +290,15 @@ impl ScrollArea { /// A source for the unique [`Id`], e.g. `.id_source("second_scroll_area")` or `.id_source(loop_index)`. #[inline] - pub fn id_source(mut self, id_source: impl std::hash::Hash) -> Self { - self.id_source = Some(Id::new(id_source)); + #[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 { + self.id_salt = Some(Id::new(id_salt)); self } @@ -490,7 +497,7 @@ impl ScrollArea { max_size, min_scrolled_size, scroll_bar_visibility, - id_source, + id_salt, offset_x, offset_y, scrolling_enabled, @@ -502,8 +509,8 @@ impl ScrollArea { let ctx = ui.ctx().clone(); let scrolling_enabled = scrolling_enabled && ui.is_enabled(); - let id_source = id_source.unwrap_or_else(|| Id::new("scroll_area")); - let id = ui.make_persistent_id(id_source); + let id_salt = id_salt.unwrap_or_else(|| Id::new("scroll_area")); + let id = ui.make_persistent_id(id_salt); ctx.check_for_id_clash( id, Rect::from_min_size(ui.available_rect_before_wrap().min, Vec2::ZERO), diff --git a/crates/egui/src/context.rs b/crates/egui/src/context.rs index 7225af6d1ca..162ff4a739e 100644 --- a/crates/egui/src/context.rs +++ b/crates/egui/src/context.rs @@ -1022,7 +1022,7 @@ impl Context { tooltip_pos, format!("Widget is {} this text.\n\n\ ID clashes happens when things like Windows or CollapsingHeaders share names,\n\ - or when things like Plot and Grid:s aren't given unique id_source:s.\n\n\ + or when things like Plot and Grid:s aren't given unique id_salt:s.\n\n\ Sometimes the solution is to use ui.push_id.", if below { "above" } else { "below" }) ); diff --git a/crates/egui/src/grid.rs b/crates/egui/src/grid.rs index 3b25ca226b8..415cfd87177 100644 --- a/crates/egui/src/grid.rs +++ b/crates/egui/src/grid.rs @@ -299,7 +299,7 @@ impl GridLayout { /// ``` #[must_use = "You should call .show()"] pub struct Grid { - id_source: Id, + id_salt: Id, num_columns: Option, min_col_width: Option, min_row_height: Option, @@ -311,9 +311,9 @@ pub struct Grid { impl Grid { /// Create a new [`Grid`] with a locally unique identifier. - pub fn new(id_source: impl std::hash::Hash) -> Self { + pub fn new(id_salt: impl std::hash::Hash) -> Self { Self { - id_source: Id::new(id_source), + id_salt: Id::new(id_salt), num_columns: None, min_col_width: None, min_row_height: None, @@ -407,7 +407,7 @@ impl Grid { add_contents: Box R + 'c>, ) -> InnerResponse { let Self { - id_source, + id_salt, num_columns, min_col_width, min_row_height, @@ -423,7 +423,7 @@ impl Grid { color_picker = Some(Box::new(striped_row_color)); } - let id = ui.make_persistent_id(id_source); + let id = ui.make_persistent_id(id_salt); let prev_state = State::load(ui.ctx(), id); // Each grid cell is aligned LEFT_CENTER. diff --git a/crates/egui/src/style.rs b/crates/egui/src/style.rs index 0097f53521f..f1787fda212 100644 --- a/crates/egui/src/style.rs +++ b/crates/egui/src/style.rs @@ -1537,7 +1537,7 @@ impl Style { ui.end_row(); ui.label("Override text style"); - crate::ComboBox::from_id_source("Override text style") + crate::ComboBox::from_id_salt("Override text style") .selected_text(match override_text_style { None => "None".to_owned(), Some(override_text_style) => override_text_style.to_string(), @@ -1554,7 +1554,7 @@ impl Style { ui.end_row(); ui.label("Text style of DragValue"); - crate::ComboBox::from_id_source("drag_value_text_style") + crate::ComboBox::from_id_salt("drag_value_text_style") .selected_text(drag_value_text_style.to_string()) .show_ui(ui, |ui| { let all_text_styles = ui.style().text_styles(); @@ -1567,7 +1567,7 @@ impl Style { ui.end_row(); ui.label("Text Wrap Mode"); - crate::ComboBox::from_id_source("text_wrap_mode") + crate::ComboBox::from_id_salt("text_wrap_mode") .selected_text(format!("{wrap_mode:?}")) .show_ui(ui, |ui| { let all_wrap_mode: Vec> = vec![ diff --git a/crates/egui/src/ui.rs b/crates/egui/src/ui.rs index e502f11e148..1db33052d24 100644 --- a/crates/egui/src/ui.rs +++ b/crates/egui/src/ui.rs @@ -63,7 +63,7 @@ pub struct Ui { /// and the value is increment with each added child widget. /// This works as an Id source only as long as new widgets aren't added or removed. /// They are therefore only good for Id:s that has no state. - next_auto_id_source: u64, + next_auto_id_salt: u64, /// Specifies paint layer, clip rectangle and a reference to [`Context`]. painter: Painter, @@ -101,7 +101,7 @@ impl Ui { /// [`crate::SidePanel`], [`crate::TopBottomPanel`], [`crate::CentralPanel`], [`crate::Window`] or [`crate::Area`]. pub fn new(ctx: Context, layer_id: LayerId, id: Id, ui_builder: UiBuilder) -> Self { let UiBuilder { - id_source, + id_salt, ui_stack_info, max_rect, layout, @@ -112,8 +112,8 @@ impl Ui { } = ui_builder; debug_assert!( - id_source.is_none(), - "Top-level Ui:s should not have an id_source" + id_salt.is_none(), + "Top-level Ui:s should not have an id_salt" ); let max_rect = max_rect.unwrap_or_else(|| ctx.screen_rect()); @@ -134,7 +134,7 @@ impl Ui { }; let mut ui = Ui { id, - next_auto_id_source: id.with("auto").value(), + next_auto_id_salt: id.with("auto").value(), painter: Painter::new(ctx, layer_id, clip_rect), style, placer, @@ -197,12 +197,12 @@ impl Ui { &mut self, max_rect: Rect, layout: Layout, - id_source: impl Hash, + id_salt: impl Hash, ui_stack_info: Option, ) -> Self { self.new_child( UiBuilder::new() - .id_source(id_source) + .id_salt(id_salt) .max_rect(max_rect) .layout(layout) .ui_stack_info(ui_stack_info.unwrap_or_default()), @@ -212,7 +212,7 @@ impl Ui { /// Create a child `Ui` with the properties of the given builder. pub fn new_child(&mut self, ui_builder: UiBuilder) -> Self { let UiBuilder { - id_source, + id_salt, ui_stack_info, max_rect, layout, @@ -224,7 +224,7 @@ impl Ui { let mut painter = self.painter.clone(); - let id_source = id_source.unwrap_or_else(|| Id::from("child")); + let id_salt = id_salt.unwrap_or_else(|| Id::from("child")); let max_rect = max_rect.unwrap_or_else(|| self.available_rect_before_wrap()); let mut layout = layout.unwrap_or(*self.layout()); let invisible = invisible || sizing_pass; @@ -245,10 +245,10 @@ impl Ui { } debug_assert!(!max_rect.any_nan()); - let new_id = self.id.with(id_source); - let next_auto_id_source = new_id.with(self.next_auto_id_source).value(); + let new_id = self.id.with(id_salt); + let next_auto_id_salt = new_id.with(self.next_auto_id_salt).value(); - self.next_auto_id_source = self.next_auto_id_source.wrapping_add(1); + self.next_auto_id_salt = self.next_auto_id_salt.wrapping_add(1); let placer = Placer::new(max_rect, layout); let ui_stack = UiStack { @@ -261,7 +261,7 @@ impl Ui { }; let child_ui = Ui { id: new_id, - next_auto_id_source, + next_auto_id_salt, painter, style, placer, @@ -918,29 +918,29 @@ impl Ui { /// # [`Id`] creation impl Ui { /// Use this to generate widget ids for widgets that have persistent state in [`Memory`]. - pub fn make_persistent_id(&self, id_source: IdSource) -> Id + pub fn make_persistent_id(&self, id_salt: IdSource) -> Id where IdSource: Hash, { - self.id.with(&id_source) + self.id.with(&id_salt) } /// This is the `Id` that will be assigned to the next widget added to this `Ui`. pub fn next_auto_id(&self) -> Id { - Id::new(self.next_auto_id_source) + Id::new(self.next_auto_id_salt) } - /// Same as `ui.next_auto_id().with(id_source)` - pub fn auto_id_with(&self, id_source: IdSource) -> Id + /// Same as `ui.next_auto_id().with(id_salt)` + pub fn auto_id_with(&self, id_salt: IdSource) -> Id where IdSource: Hash, { - Id::new(self.next_auto_id_source).with(id_source) + Id::new(self.next_auto_id_salt).with(id_salt) } /// Pretend like `count` widgets have been allocated. pub fn skip_ahead_auto_ids(&mut self, count: usize) { - self.next_auto_id_source = self.next_auto_id_source.wrapping_add(count as u64); + self.next_auto_id_salt = self.next_auto_id_salt.wrapping_add(count as u64); } } @@ -1110,8 +1110,8 @@ impl Ui { } } - let id = Id::new(self.next_auto_id_source); - self.next_auto_id_source = self.next_auto_id_source.wrapping_add(1); + let id = Id::new(self.next_auto_id_salt); + self.next_auto_id_salt = self.next_auto_id_salt.wrapping_add(1); (id, rect) } @@ -1148,8 +1148,8 @@ impl Ui { let item_spacing = self.spacing().item_spacing; self.placer.advance_after_rects(rect, rect, item_spacing); - let id = Id::new(self.next_auto_id_source); - self.next_auto_id_source = self.next_auto_id_source.wrapping_add(1); + let id = Id::new(self.next_auto_id_salt); + self.next_auto_id_salt = self.next_auto_id_salt.wrapping_add(1); id } @@ -2086,13 +2086,10 @@ impl Ui { /// ``` pub fn push_id( &mut self, - id_source: impl Hash, + id_salt: impl Hash, add_contents: impl FnOnce(&mut Ui) -> R, ) -> InnerResponse { - self.scope_dyn( - UiBuilder::new().id_source(id_source), - Box::new(add_contents), - ) + self.scope_dyn(UiBuilder::new().id_salt(id_salt), Box::new(add_contents)) } /// Push another level onto the [`UiStack`]. @@ -2141,9 +2138,9 @@ impl Ui { ui_builder: UiBuilder, add_contents: Box R + 'c>, ) -> InnerResponse { - let next_auto_id_source = self.next_auto_id_source; + let next_auto_id_salt = self.next_auto_id_salt; let mut child_ui = self.new_child(ui_builder); - self.next_auto_id_source = next_auto_id_source; // HACK: we want `scope` to only increment this once, so that `ui.scope` is equivalent to `ui.allocate_space`. + self.next_auto_id_salt = next_auto_id_salt; // HACK: we want `scope` to only increment this once, so that `ui.scope` is equivalent to `ui.allocate_space`. let ret = add_contents(&mut child_ui); let response = self.allocate_rect(child_ui.min_rect(), Sense::hover()); InnerResponse::new(ret, response) @@ -2164,7 +2161,7 @@ impl Ui { /// A [`CollapsingHeader`] that starts out collapsed. /// /// The name must be unique within the current parent, - /// or you need to use [`CollapsingHeader::id_source`]. + /// or you need to use [`CollapsingHeader::id_salt`]. pub fn collapsing( &mut self, heading: impl Into, @@ -2175,20 +2172,20 @@ impl Ui { /// Create a child ui which is indented to the right. /// - /// The `id_source` here be anything at all. - // TODO(emilk): remove `id_source` argument? + /// The `id_salt` here be anything at all. + // TODO(emilk): remove `id_salt` argument? #[inline] pub fn indent( &mut self, - id_source: impl Hash, + id_salt: impl Hash, add_contents: impl FnOnce(&mut Ui) -> R, ) -> InnerResponse { - self.indent_dyn(id_source, Box::new(add_contents)) + self.indent_dyn(id_salt, Box::new(add_contents)) } fn indent_dyn<'c, R>( &mut self, - id_source: impl Hash, + id_salt: impl Hash, add_contents: Box R + 'c>, ) -> InnerResponse { assert!( @@ -2201,8 +2198,7 @@ impl Ui { let mut child_rect = self.placer.available_rect_before_wrap(); child_rect.min.x += indent; - let mut child_ui = - self.new_child(UiBuilder::new().id_source(id_source).max_rect(child_rect)); + let mut child_ui = self.new_child(UiBuilder::new().id_salt(id_salt).max_rect(child_rect)); let ret = add_contents(&mut child_ui); let left_vline = self.visuals().indent_has_left_vline; diff --git a/crates/egui/src/ui_builder.rs b/crates/egui/src/ui_builder.rs index 166210b9ab2..34d4acbb4ab 100644 --- a/crates/egui/src/ui_builder.rs +++ b/crates/egui/src/ui_builder.rs @@ -13,7 +13,7 @@ use crate::Ui; #[must_use] #[derive(Clone, Default)] pub struct UiBuilder { - pub id_source: Option, + pub id_salt: Option, pub ui_stack_info: UiStackInfo, pub max_rect: Option, pub layout: Option, @@ -29,14 +29,14 @@ impl UiBuilder { Self::default() } - /// Seed the child `Ui` with this `id_source`, which will be mixed + /// Seed the child `Ui` with this `id_salt`, which will be mixed /// with the [`Ui::id`] of the parent. /// - /// You should give each [`Ui`] an `id_source` that is unique + /// You should give each [`Ui`] an `id_salt` that is unique /// within the parent, or give it none at all. #[inline] - pub fn id_source(mut self, id_source: impl Hash) -> Self { - self.id_source = Some(Id::new(id_source)); + pub fn id_salt(mut self, id_salt: impl Hash) -> Self { + self.id_salt = Some(Id::new(id_salt)); self } diff --git a/crates/egui/src/widgets/text_edit/builder.rs b/crates/egui/src/widgets/text_edit/builder.rs index 4758ad962c3..991ab01c551 100644 --- a/crates/egui/src/widgets/text_edit/builder.rs +++ b/crates/egui/src/widgets/text_edit/builder.rs @@ -66,7 +66,7 @@ pub struct TextEdit<'t> { hint_text: WidgetText, hint_text_font: Option, id: Option, - id_source: Option, + id_salt: Option, font_selection: FontSelection, text_color: Option, layouter: Option<&'t mut dyn FnMut(&Ui, &str, f32) -> Arc>, @@ -118,7 +118,7 @@ impl<'t> TextEdit<'t> { hint_text: Default::default(), hint_text_font: None, id: None, - id_source: None, + id_salt: None, font_selection: Default::default(), text_color: None, layouter: None, @@ -162,8 +162,14 @@ impl<'t> TextEdit<'t> { /// A source for the unique [`Id`], e.g. `.id_source("second_text_edit_field")` or `.id_source(loop_index)`. #[inline] - pub fn id_source(mut self, id_source: impl std::hash::Hash) -> Self { - self.id_source = Some(Id::new(id_source)); + 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_text_edit_field")` or `.id_salt(loop_index)`. + #[inline] + pub fn id_salt(mut self, id_salt: impl std::hash::Hash) -> Self { + self.id_salt = Some(Id::new(id_salt)); self } @@ -453,7 +459,7 @@ impl<'t> TextEdit<'t> { hint_text, hint_text_font, id, - id_source, + id_salt, font_selection, text_color, layouter, @@ -518,8 +524,8 @@ impl<'t> TextEdit<'t> { let rect = outer_rect - margin; // inner rect (excluding frame/margin). let id = id.unwrap_or_else(|| { - if let Some(id_source) = id_source { - ui.make_persistent_id(id_source) + if let Some(id_salt) = id_salt { + ui.make_persistent_id(id_salt) } else { auto_id // Since we are only storing the cursor a persistent Id is not super important } diff --git a/crates/egui_demo_app/src/backend_panel.rs b/crates/egui_demo_app/src/backend_panel.rs index e50c6b29db1..e6cc0903058 100644 --- a/crates/egui_demo_app/src/backend_panel.rs +++ b/crates/egui_demo_app/src/backend_panel.rs @@ -297,7 +297,7 @@ fn integration_ui(ui: &mut egui::Ui, _frame: &mut eframe::Frame) { } let mut size = None; - egui::ComboBox::from_id_source("viewport-size-combo") + egui::ComboBox::from_id_salt("viewport-size-combo") .selected_text("Resize to…") .show_ui(ui, |ui| { ui.selectable_value( diff --git a/crates/egui_demo_lib/src/easy_mark/easy_mark_editor.rs b/crates/egui_demo_lib/src/easy_mark/easy_mark_editor.rs index 7920b97858b..524beaf69de 100644 --- a/crates/egui_demo_lib/src/easy_mark/easy_mark_editor.rs +++ b/crates/egui_demo_lib/src/easy_mark/easy_mark_editor.rs @@ -58,10 +58,10 @@ impl EasyMarkEditor { if self.show_rendered { ui.columns(2, |columns| { ScrollArea::vertical() - .id_source("source") + .id_salt("source") .show(&mut columns[0], |ui| self.editor_ui(ui)); ScrollArea::vertical() - .id_source("rendered") + .id_salt("rendered") .show(&mut columns[1], |ui| { // TODO(emilk): we can save some more CPU by caching the rendered output. crate::easy_mark::easy_mark(ui, &self.code); @@ -69,7 +69,7 @@ impl EasyMarkEditor { }); } else { ScrollArea::vertical() - .id_source("source") + .id_salt("source") .show(ui, |ui| self.editor_ui(ui)); } } diff --git a/crates/egui_extras/src/datepicker/button.rs b/crates/egui_extras/src/datepicker/button.rs index 469a571daa0..53993512638 100644 --- a/crates/egui_extras/src/datepicker/button.rs +++ b/crates/egui_extras/src/datepicker/button.rs @@ -11,7 +11,7 @@ pub(crate) struct DatePickerButtonState { /// Shows a date, and will open a date picker popup when clicked. pub struct DatePickerButton<'a> { selection: &'a mut NaiveDate, - id_source: Option<&'a str>, + id_salt: Option<&'a str>, combo_boxes: bool, arrows: bool, calendar: bool, @@ -25,7 +25,7 @@ impl<'a> DatePickerButton<'a> { pub fn new(selection: &'a mut NaiveDate) -> Self { Self { selection, - id_source: None, + id_salt: None, combo_boxes: true, arrows: true, calendar: true, @@ -39,11 +39,19 @@ impl<'a> DatePickerButton<'a> { /// Add id source. /// Must be set if multiple date picker buttons are in the same Ui. #[inline] - pub fn id_source(mut self, id_source: &'a str) -> Self { - self.id_source = Some(id_source); + pub fn id_salt(mut self, id_salt: &'a str) -> Self { + self.id_salt = Some(id_salt); 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 { @@ -97,7 +105,7 @@ impl<'a> DatePickerButton<'a> { impl<'a> Widget for DatePickerButton<'a> { fn ui(self, ui: &mut Ui) -> egui::Response { - let id = ui.make_persistent_id(self.id_source); + let id = ui.make_persistent_id(self.id_salt); let mut button_state = ui .data_mut(|data| data.get_persisted::(id)) .unwrap_or_default(); @@ -140,7 +148,7 @@ impl<'a> Widget for DatePickerButton<'a> { let InnerResponse { inner: saved, response: area_response, - } = Area::new(ui.make_persistent_id(self.id_source)) + } = Area::new(ui.make_persistent_id(self.id_salt)) .kind(egui::UiKind::Picker) .order(Order::Foreground) .fixed_pos(pos) diff --git a/crates/egui_extras/src/datepicker/popup.rs b/crates/egui_extras/src/datepicker/popup.rs index 1252f209776..230b6e0b331 100644 --- a/crates/egui_extras/src/datepicker/popup.rs +++ b/crates/egui_extras/src/datepicker/popup.rs @@ -81,7 +81,7 @@ impl<'a> DatePickerPopup<'a> { strip.strip(|builder| { builder.sizes(Size::remainder(), 3).horizontal(|mut strip| { strip.cell(|ui| { - ComboBox::from_id_source("date_picker_year") + ComboBox::from_id_salt("date_picker_year") .selected_text(popup_state.year.to_string()) .show_ui(ui, |ui| { for year in today.year() - 100..today.year() + 10 { @@ -105,7 +105,7 @@ impl<'a> DatePickerPopup<'a> { }); }); strip.cell(|ui| { - ComboBox::from_id_source("date_picker_month") + ComboBox::from_id_salt("date_picker_month") .selected_text(month_name(popup_state.month)) .show_ui(ui, |ui| { for month in 1..=12 { @@ -129,7 +129,7 @@ impl<'a> DatePickerPopup<'a> { }); }); strip.cell(|ui| { - ComboBox::from_id_source("date_picker_day") + ComboBox::from_id_salt("date_picker_day") .selected_text(popup_state.day.to_string()) .show_ui(ui, |ui| { for day in 1..=popup_state.last_day_of_month() { diff --git a/crates/egui_extras/src/layout.rs b/crates/egui_extras/src/layout.rs index 6d2b10c3092..c0bfdcd6b13 100644 --- a/crates/egui_extras/src/layout.rs +++ b/crates/egui_extras/src/layout.rs @@ -116,7 +116,7 @@ impl<'l> StripLayout<'l> { flags: StripLayoutFlags, width: CellSize, height: CellSize, - child_ui_id_source: Id, + child_ui_id_salt: Id, add_cell_contents: impl FnOnce(&mut Ui), ) -> (Rect, Response) { let max_rect = self.cell_rect(&width, &height); @@ -149,7 +149,7 @@ impl<'l> StripLayout<'l> { ); } - let child_ui = self.cell(flags, max_rect, child_ui_id_source, add_cell_contents); + let child_ui = self.cell(flags, max_rect, child_ui_id_salt, add_cell_contents); let used_rect = child_ui.min_rect(); @@ -197,11 +197,11 @@ impl<'l> StripLayout<'l> { &mut self, flags: StripLayoutFlags, max_rect: Rect, - child_ui_id_source: egui::Id, + child_ui_id_salt: egui::Id, add_cell_contents: impl FnOnce(&mut Ui), ) -> Ui { let mut ui_builder = UiBuilder::new() - .id_source(child_ui_id_source) + .id_salt(child_ui_id_salt) .ui_stack_info(egui::UiStackInfo::new(egui::UiKind::TableCell)) .max_rect(max_rect) .layout(self.cell_layout); diff --git a/crates/egui_extras/src/table.rs b/crates/egui_extras/src/table.rs index f2b2dfe48ac..d5cf5dfb1a1 100644 --- a/crates/egui_extras/src/table.rs +++ b/crates/egui_extras/src/table.rs @@ -213,7 +213,7 @@ impl Default for TableScrollOptions { /// You must pre-allocate all columns with [`Self::column`]/[`Self::columns`]. /// /// If you have multiple [`Table`]:s in the same [`Ui`] -/// you will need to give them unique id:s by with [`Self::id_source`]. +/// you will need to give them unique id:s by with [`Self::id_salt`]. /// /// ### Example /// ``` @@ -244,7 +244,7 @@ impl Default for TableScrollOptions { /// ``` pub struct TableBuilder<'a> { ui: &'a mut Ui, - id_source: Id, + id_salt: Id, columns: Vec, striped: Option, resizable: bool, @@ -258,7 +258,7 @@ impl<'a> TableBuilder<'a> { let cell_layout = *ui.layout(); Self { ui, - id_source: Id::new("__table_state"), + id_salt: Id::new("__table_state"), columns: Default::default(), striped: None, resizable: false, @@ -272,8 +272,17 @@ impl<'a> TableBuilder<'a> { /// /// This is required if you have multiple tables in the same [`Ui`]. #[inline] - pub fn id_source(mut self, id_source: impl std::hash::Hash) -> Self { - self.id_source = Id::new(id_source); + #[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`]. + #[inline] + pub fn id_salt(mut self, id_salt: impl std::hash::Hash) -> Self { + self.id_salt = Id::new(id_salt); self } @@ -431,7 +440,7 @@ impl<'a> TableBuilder<'a> { /// Reset all column widths. pub fn reset(&mut self) { - let state_id = self.ui.id().with(self.id_source); + let state_id = self.ui.id().with(self.id_salt); TableState::reset(self.ui, state_id); } @@ -441,7 +450,7 @@ impl<'a> TableBuilder<'a> { let Self { ui, - id_source, + id_salt, columns, striped, resizable, @@ -452,7 +461,7 @@ impl<'a> TableBuilder<'a> { let striped = striped.unwrap_or(ui.visuals().striped); - let state_id = ui.id().with(id_source); + let state_id = ui.id().with(id_salt); let (is_sizing_pass, state) = TableState::load(ui, state_id, resizable, &columns, available_width); @@ -509,7 +518,7 @@ impl<'a> TableBuilder<'a> { let Self { ui, - id_source, + id_salt, columns, striped, resizable, @@ -520,7 +529,7 @@ impl<'a> TableBuilder<'a> { let striped = striped.unwrap_or(ui.visuals().striped); - let state_id = ui.id().with(id_source); + let state_id = ui.id().with(id_salt); let (is_sizing_pass, state) = TableState::load(ui, state_id, resizable, &columns, available_width); diff --git a/tests/test_size_pass/src/main.rs b/tests/test_size_pass/src/main.rs index 0376868b279..daecf7758fa 100644 --- a/tests/test_size_pass/src/main.rs +++ b/tests/test_size_pass/src/main.rs @@ -91,7 +91,7 @@ fn main() -> eframe::Result { |i| alternatives[i], ); - egui::ComboBox::from_id_source("combo") + egui::ComboBox::from_id_salt("combo") .selected_text("ComboBox") .width(100.0) .show_ui(ui, |ui| { diff --git a/tests/test_ui_stack/src/main.rs b/tests/test_ui_stack/src/main.rs index 91d76844f8c..fa46b83e172 100644 --- a/tests/test_ui_stack/src/main.rs +++ b/tests/test_ui_stack/src/main.rs @@ -115,7 +115,7 @@ impl eframe::App for MyApp { // combobox test ui.add_space(20.0); - egui::ComboBox::from_id_source("combo_box") + egui::ComboBox::from_id_salt("combo_box") .selected_text("click me") .show_ui(ui, |ui| { full_span_widget(ui, true);