Rename `id_source` to `id_salt` (#5025)

* Closes <https://github.com/emilk/egui/issues/5020 >
* [x] I have followed the instructions in the PR template
This commit is contained in:
Nicolas 2024-09-02 09:29:01 +02:00 committed by GitHub
parent edea5a40b9
commit be944f0915
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 169 additions and 121 deletions

View File

@ -372,7 +372,7 @@ pub struct CollapsingHeader {
text: WidgetText,
default_open: bool,
open: Option<bool>,
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<WidgetText>) -> 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();

View File

@ -38,7 +38,7 @@ pub type IconPainter = Box<dyn FnOnce(&Ui, Rect, &WidgetVisuals, bool, AboveOrBe
/// ```
#[must_use = "You should call .show*"]
pub struct ComboBox {
id_source: Id,
id_salt: Id,
label: Option<WidgetText>,
selected_text: WidgetText,
width: Option<f32>,
@ -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<WidgetText>) -> Self {
pub fn new(id_salt: impl std::hash::Hash, label: impl Into<WidgetText>) -> 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<WidgetText>) -> 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<dyn FnOnce(&mut Ui) -> R + 'c>,
) -> InnerResponse<Option<R>> {
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(

View File

@ -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,

View File

@ -34,7 +34,7 @@ impl State {
#[must_use = "You should call .show()"]
pub struct Resize {
id: Option<Id>,
id_source: Option<Id>,
id_salt: Option<Id>,
/// 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(|| {

View File

@ -171,7 +171,7 @@ pub struct ScrollArea {
max_size: Vec2,
min_scrolled_size: Vec2,
scroll_bar_visibility: ScrollBarVisibility,
id_source: Option<Id>,
id_salt: Option<Id>,
offset_x: Option<f32>,
offset_y: Option<f32>,
@ -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),

View File

@ -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" })
);

View File

@ -299,7 +299,7 @@ impl GridLayout {
/// ```
#[must_use = "You should call .show()"]
pub struct Grid {
id_source: Id,
id_salt: Id,
num_columns: Option<usize>,
min_col_width: Option<f32>,
min_row_height: Option<f32>,
@ -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<dyn FnOnce(&mut Ui) -> R + 'c>,
) -> InnerResponse<R> {
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.

View File

@ -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<Option<TextWrapMode>> = vec![

View File

@ -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<UiStackInfo>,
) -> 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<IdSource>(&self, id_source: IdSource) -> Id
pub fn make_persistent_id<IdSource>(&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<IdSource>(&self, id_source: IdSource) -> Id
/// Same as `ui.next_auto_id().with(id_salt)`
pub fn auto_id_with<IdSource>(&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<R>(
&mut self,
id_source: impl Hash,
id_salt: impl Hash,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> InnerResponse<R> {
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<dyn FnOnce(&mut Ui) -> R + 'c>,
) -> InnerResponse<R> {
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<R>(
&mut self,
heading: impl Into<WidgetText>,
@ -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<R>(
&mut self,
id_source: impl Hash,
id_salt: impl Hash,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> InnerResponse<R> {
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<dyn FnOnce(&mut Ui) -> R + 'c>,
) -> InnerResponse<R> {
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;

View File

@ -13,7 +13,7 @@ use crate::Ui;
#[must_use]
#[derive(Clone, Default)]
pub struct UiBuilder {
pub id_source: Option<Id>,
pub id_salt: Option<Id>,
pub ui_stack_info: UiStackInfo,
pub max_rect: Option<Rect>,
pub layout: Option<Layout>,
@ -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
}

View File

@ -66,7 +66,7 @@ pub struct TextEdit<'t> {
hint_text: WidgetText,
hint_text_font: Option<FontSelection>,
id: Option<Id>,
id_source: Option<Id>,
id_salt: Option<Id>,
font_selection: FontSelection,
text_color: Option<Color32>,
layouter: Option<&'t mut dyn FnMut(&Ui, &str, f32) -> Arc<Galley>>,
@ -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
}

View File

@ -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(

View File

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

View File

@ -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::<DatePickerButtonState>(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)

View File

@ -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() {

View File

@ -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);

View File

@ -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<Column>,
striped: Option<bool>,
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);

View File

@ -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| {

View File

@ -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);