Improve automatic Id generation to make Id clashes less likely
This commit is contained in:
parent
ee3f269d93
commit
03eb9151c4
4 changed files with 28 additions and 15 deletions
|
@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
|
||||
* Pressing enter in a single-line `TextEdit` will now surrender keyboard focus for it.
|
||||
* You must now be explicit when creating a `TextEdit` if you want it to be singeline or multiline.
|
||||
* Improved automatic `Id` generation, making `Id` clashes less likely.
|
||||
|
||||
### Fixed 🐛
|
||||
|
||||
|
|
|
@ -58,6 +58,10 @@ impl Id {
|
|||
pub(crate) fn short_debug_format(&self) -> String {
|
||||
format!("{:04X}", self.0 as u16)
|
||||
}
|
||||
|
||||
pub(crate) fn value(&self) -> u64 {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for Id {
|
||||
|
|
|
@ -11,9 +11,17 @@ pub struct Ui {
|
|||
/// Generated based on id of parent ui together with
|
||||
/// another source of child identity (e.g. window title).
|
||||
/// Acts like a namespace for child uis.
|
||||
/// Hopefully unique.
|
||||
/// Should be unique and persist predictably from one frame to next
|
||||
/// so it can be used as a source for storing state (e.g. window position, or if a collapsing header is open).
|
||||
id: Id,
|
||||
|
||||
/// This is used to create a unique interact ID for some widgets.
|
||||
/// This value is based on where in the hierarchy of widgets this Ui is in,
|
||||
/// 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: u64,
|
||||
|
||||
painter: Painter,
|
||||
|
||||
/// This is the minimal size of the `Ui`.
|
||||
|
@ -49,11 +57,6 @@ pub struct Ui {
|
|||
/// If something has already been added, this will point ot style.spacing.item_spacing beyond the latest child.
|
||||
/// The cursor can thus be style.spacing.item_spacing pixels outside of the min_rect.
|
||||
cursor: Pos2, // TODO: move into Layout?
|
||||
|
||||
/// How many children has been added to us?
|
||||
/// This is only used to create a unique interact ID for some widgets
|
||||
/// that work as long as no other widgets are added/removed while interacting.
|
||||
child_count: usize,
|
||||
}
|
||||
|
||||
impl Ui {
|
||||
|
@ -74,33 +77,31 @@ impl Ui {
|
|||
let min_rect = layout.rect_from_cursor_size(cursor, min_size);
|
||||
Ui {
|
||||
id,
|
||||
next_auto_id: id.with("auto").value(),
|
||||
painter: Painter::new(ctx, layer_id, clip_rect),
|
||||
min_rect,
|
||||
max_rect,
|
||||
style,
|
||||
layout,
|
||||
cursor,
|
||||
child_count: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn child_ui(&mut self, max_rect: Rect, layout: Layout) -> Self {
|
||||
self.child_count += 1;
|
||||
let id = self.make_position_id(); // TODO: ui.id should be persistent and not position based.
|
||||
|
||||
self.next_auto_id = self.next_auto_id.wrapping_add(1);
|
||||
let cursor = layout.initial_cursor(max_rect);
|
||||
let min_size = Vec2::zero(); // TODO: From Style
|
||||
let min_rect = layout.rect_from_cursor_size(cursor, min_size);
|
||||
|
||||
Ui {
|
||||
id,
|
||||
id: self.id,
|
||||
next_auto_id: Id::new(self.next_auto_id).with("child").value(),
|
||||
painter: self.painter.clone(),
|
||||
min_rect,
|
||||
max_rect,
|
||||
style: self.style.clone(),
|
||||
layout,
|
||||
cursor,
|
||||
child_count: 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -379,7 +380,7 @@ impl Ui {
|
|||
/// Call AFTER allocating new space for your widget.
|
||||
// TODO: return from `allocate_space` ?
|
||||
pub fn make_position_id(&self) -> Id {
|
||||
self.id.with(self.child_count)
|
||||
Id::new(self.next_auto_id)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -472,7 +473,7 @@ impl Ui {
|
|||
let item_spacing = self.style().spacing.item_spacing;
|
||||
self.layout.advance_cursor2(&mut self.cursor, item_spacing);
|
||||
self.expand_to_include_rect(child_rect);
|
||||
self.child_count += 1;
|
||||
self.next_auto_id = self.next_auto_id.wrapping_add(1);
|
||||
child_rect
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,7 +129,14 @@ impl<'t> Widget for TextEdit<'t> {
|
|||
desired_height_rows,
|
||||
} = self;
|
||||
|
||||
let id = id.unwrap_or_else(|| ui.make_persistent_id(id_source));
|
||||
let id = id.unwrap_or_else(|| {
|
||||
if let Some(id_source) = id_source {
|
||||
ui.make_persistent_id(id_source)
|
||||
} else {
|
||||
// Since we are only storing cursor, perfect persistence Id not super important
|
||||
ui.make_position_id()
|
||||
}
|
||||
});
|
||||
|
||||
let mut state = ui.memory().text_edit.get(&id).cloned().unwrap_or_default();
|
||||
|
||||
|
|
Loading…
Reference in a new issue