Box the widget: Widget field of WidgetInstance (#3506)
Some checks are pending
Editor: Dev & CI / build (push) Waiting to run
Editor: Dev & CI / cargo-deny (push) Waiting to run

Box the `pub widget: Box<Widget>` field of `WidgetInstance`
This commit is contained in:
Keavon Chambers 2025-12-22 04:18:33 -08:00 committed by GitHub
parent 20bbe6cdcc
commit 9d26c040e9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 25 additions and 23 deletions

View file

@ -594,7 +594,7 @@ mod test {
if let FrontendMessage::UpdateDialogColumn1 { diff } = response {
if let DiffUpdate::Layout(sub_layout) = &diff[0].new_value {
if let LayoutGroup::Row { widgets } = &sub_layout.0[0] {
if let Widget::TextLabel(TextLabel { value, .. }) = &widgets[0].widget {
if let Widget::TextLabel(TextLabel { value, .. }) = &*widgets[0].widget {
print_problem_to_terminal_on_failure(value);
}
}

View file

@ -71,7 +71,7 @@ impl LayoutMessageHandler {
return Some((widget, widget_path));
}
if let Widget::PopoverButton(popover) = &widget.widget {
if let Widget::PopoverButton(popover) = &*widget.widget {
stack.extend(
popover
.popover_layout
@ -97,7 +97,7 @@ impl LayoutMessageHandler {
return Some((cell, widget_path));
}
if let Widget::PopoverButton(popover) = &cell.widget {
if let Widget::PopoverButton(popover) = &*cell.widget {
stack.extend(
popover
.popover_layout
@ -126,7 +126,7 @@ impl LayoutMessageHandler {
return;
};
match &mut widget_instance.widget {
match &mut *widget_instance.widget {
Widget::BreadcrumbTrailButtons(breadcrumb_trail_buttons) => {
let callback_message = match action {
WidgetValueAction::Commit => (breadcrumb_trail_buttons.on_commit.callback)(&()),

View file

@ -229,13 +229,13 @@ impl<'a> Iterator for WidgetIter<'a> {
Some(first)
});
if let Some(item) = widget {
if let WidgetInstance { widget: Widget::PopoverButton(p), .. } = item {
self.stack.extend(p.popover_layout.0.iter());
if let Some(instance) = widget {
if let Widget::PopoverButton(popover_button) = &*instance.widget {
self.stack.extend(popover_button.popover_layout.0.iter());
return self.next();
}
return Some(item);
return Some(instance);
}
match self.stack.pop() {
@ -279,13 +279,15 @@ impl<'a> Iterator for WidgetIterMut<'a> {
Some(first)
});
if let Some(widget) = widget {
if let WidgetInstance { widget: Widget::PopoverButton(p), .. } = widget {
self.stack.extend(p.popover_layout.0.iter_mut());
return self.next();
if let Some(instance) = widget {
// We have to check that we're not a popover and return first, then extract the popover with an unreachable else condition second, to satisfy the borrow checker.
// After Rust's Polonius is stable, we can reverse that order of steps to avoid the redundancy and unreachable statement.
if !matches!(*instance.widget, Widget::PopoverButton(_)) {
return Some(instance);
}
return Some(widget);
let Widget::PopoverButton(popover_button) = &mut *instance.widget else { unreachable!() };
self.stack.extend(popover_button.popover_layout.0.iter_mut());
return self.next();
}
match self.stack.pop() {
@ -362,7 +364,7 @@ impl LayoutGroup {
};
let description = description.into();
for widget in &mut widgets {
let val = match &mut widget.widget {
let val = match &mut *widget.widget {
Widget::CheckboxInput(x) => &mut x.tooltip_description,
Widget::ColorInput(x) => &mut x.tooltip_description,
Widget::CurveInput(x) => &mut x.tooltip_description,
@ -552,7 +554,7 @@ impl Diffable for LayoutGroup {
pub struct WidgetInstance {
#[serde(rename = "widgetId")]
pub widget_id: WidgetId,
pub widget: Widget,
pub widget: Box<Widget>,
}
impl PartialEq for WidgetInstance {
@ -566,7 +568,7 @@ impl WidgetInstance {
pub fn new(widget: Widget) -> Self {
Self {
widget_id: WidgetId(generate_uuid()),
widget,
widget: Box::new(widget),
}
}
}
@ -584,7 +586,7 @@ impl Diffable for WidgetInstance {
}
// Special handling for PopoverButton: recursively diff nested layout if only the layout changed
if let (Widget::PopoverButton(button1), Widget::PopoverButton(button2)) = (&mut self.widget, &new.widget) {
if let (Widget::PopoverButton(button1), Widget::PopoverButton(button2)) = (&mut *self.widget, &*new.widget) {
// Check if only the popover layout changed (all other fields are the same)
if self.widget_id == new.widget_id
&& button1.disabled == button2.disabled
@ -614,7 +616,7 @@ impl Diffable for WidgetInstance {
}
fn collect_checkbox_ids(&self, layout_target: LayoutTarget, widget_path: &mut Vec<usize>, checkbox_map: &mut HashMap<CheckboxId, CheckboxId>) {
match &self.widget {
match &*self.widget {
Widget::CheckboxInput(checkbox) => {
// Compute stable ID based on position and insert mapping
let checkbox_id = checkbox.for_label;
@ -644,7 +646,7 @@ impl Diffable for WidgetInstance {
self.widget_id = compute_widget_id(layout_target, widget_path, &self.widget);
// 2. Replace CheckboxIds if present
match &mut self.widget {
match &mut *self.widget {
Widget::CheckboxInput(checkbox) => {
let old_id = checkbox.for_label;
if let Some(&new_id) = checkbox_map.get(&old_id) {
@ -744,7 +746,7 @@ impl DiffUpdate {
// Go through each widget to convert `ActionShortcut::Action` to `ActionShortcut::Shortcut` and append the key combination to the widget tooltip
let convert_tooltip = |widget_instance: &mut WidgetInstance| {
// Handle all the widgets that have tooltips
let tooltip_shortcut = match &mut widget_instance.widget {
let tooltip_shortcut = match &mut *widget_instance.widget {
Widget::BreadcrumbTrailButtons(widget) => widget.tooltip_shortcut.as_mut(),
Widget::CheckboxInput(widget) => widget.tooltip_shortcut.as_mut(),
Widget::ColorInput(widget) => widget.tooltip_shortcut.as_mut(),
@ -775,7 +777,7 @@ impl DiffUpdate {
}
// Handle RadioInput separately because its tooltips are children of the widget
if let Widget::RadioInput(radio_input) = &mut widget_instance.widget {
if let Widget::RadioInput(radio_input) = &mut *widget_instance.widget {
for radio_entry_data in &mut radio_input.entries {
// Convert `ActionShortcut::Action` to `ActionShortcut::Shortcut`
if let Some(tooltip_shortcut) = radio_entry_data.tooltip_shortcut.as_mut() {
@ -827,7 +829,7 @@ impl DiffUpdate {
};
// Apply shortcut conversions to all widgets that have menu lists
let convert_menu_lists = |widget_instance: &mut WidgetInstance| match &mut widget_instance.widget {
let convert_menu_lists = |widget_instance: &mut WidgetInstance| match &mut *widget_instance.widget {
Widget::DropdownInput(dropdown_input) => {
apply_action_shortcut_to_menu_lists(&mut dropdown_input.entries);
dropdown_input.entries_hash = hash_menu_list_entry_sections(&dropdown_input.entries);