mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-05 22:18:12 +08:00
Box the widget: Widget field of WidgetInstance (#3506)
Box the `pub widget: Box<Widget>` field of `WidgetInstance`
This commit is contained in:
@@ -594,7 +594,7 @@ mod test {
|
|||||||
if let FrontendMessage::UpdateDialogColumn1 { diff } = response {
|
if let FrontendMessage::UpdateDialogColumn1 { diff } = response {
|
||||||
if let DiffUpdate::Layout(sub_layout) = &diff[0].new_value {
|
if let DiffUpdate::Layout(sub_layout) = &diff[0].new_value {
|
||||||
if let LayoutGroup::Row { widgets } = &sub_layout.0[0] {
|
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);
|
print_problem_to_terminal_on_failure(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ impl LayoutMessageHandler {
|
|||||||
return Some((widget, widget_path));
|
return Some((widget, widget_path));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Widget::PopoverButton(popover) = &widget.widget {
|
if let Widget::PopoverButton(popover) = &*widget.widget {
|
||||||
stack.extend(
|
stack.extend(
|
||||||
popover
|
popover
|
||||||
.popover_layout
|
.popover_layout
|
||||||
@@ -97,7 +97,7 @@ impl LayoutMessageHandler {
|
|||||||
return Some((cell, widget_path));
|
return Some((cell, widget_path));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Widget::PopoverButton(popover) = &cell.widget {
|
if let Widget::PopoverButton(popover) = &*cell.widget {
|
||||||
stack.extend(
|
stack.extend(
|
||||||
popover
|
popover
|
||||||
.popover_layout
|
.popover_layout
|
||||||
@@ -126,7 +126,7 @@ impl LayoutMessageHandler {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
match &mut widget_instance.widget {
|
match &mut *widget_instance.widget {
|
||||||
Widget::BreadcrumbTrailButtons(breadcrumb_trail_buttons) => {
|
Widget::BreadcrumbTrailButtons(breadcrumb_trail_buttons) => {
|
||||||
let callback_message = match action {
|
let callback_message = match action {
|
||||||
WidgetValueAction::Commit => (breadcrumb_trail_buttons.on_commit.callback)(&()),
|
WidgetValueAction::Commit => (breadcrumb_trail_buttons.on_commit.callback)(&()),
|
||||||
|
|||||||
@@ -229,13 +229,13 @@ impl<'a> Iterator for WidgetIter<'a> {
|
|||||||
Some(first)
|
Some(first)
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(item) = widget {
|
if let Some(instance) = widget {
|
||||||
if let WidgetInstance { widget: Widget::PopoverButton(p), .. } = item {
|
if let Widget::PopoverButton(popover_button) = &*instance.widget {
|
||||||
self.stack.extend(p.popover_layout.0.iter());
|
self.stack.extend(popover_button.popover_layout.0.iter());
|
||||||
return self.next();
|
return self.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Some(item);
|
return Some(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.stack.pop() {
|
match self.stack.pop() {
|
||||||
@@ -279,13 +279,15 @@ impl<'a> Iterator for WidgetIterMut<'a> {
|
|||||||
Some(first)
|
Some(first)
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(widget) = widget {
|
if let Some(instance) = widget {
|
||||||
if let WidgetInstance { widget: Widget::PopoverButton(p), .. } = 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.
|
||||||
self.stack.extend(p.popover_layout.0.iter_mut());
|
// After Rust's Polonius is stable, we can reverse that order of steps to avoid the redundancy and unreachable statement.
|
||||||
return self.next();
|
if !matches!(*instance.widget, Widget::PopoverButton(_)) {
|
||||||
|
return Some(instance);
|
||||||
}
|
}
|
||||||
|
let Widget::PopoverButton(popover_button) = &mut *instance.widget else { unreachable!() };
|
||||||
return Some(widget);
|
self.stack.extend(popover_button.popover_layout.0.iter_mut());
|
||||||
|
return self.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.stack.pop() {
|
match self.stack.pop() {
|
||||||
@@ -362,7 +364,7 @@ impl LayoutGroup {
|
|||||||
};
|
};
|
||||||
let description = description.into();
|
let description = description.into();
|
||||||
for widget in &mut widgets {
|
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::CheckboxInput(x) => &mut x.tooltip_description,
|
||||||
Widget::ColorInput(x) => &mut x.tooltip_description,
|
Widget::ColorInput(x) => &mut x.tooltip_description,
|
||||||
Widget::CurveInput(x) => &mut x.tooltip_description,
|
Widget::CurveInput(x) => &mut x.tooltip_description,
|
||||||
@@ -552,7 +554,7 @@ impl Diffable for LayoutGroup {
|
|||||||
pub struct WidgetInstance {
|
pub struct WidgetInstance {
|
||||||
#[serde(rename = "widgetId")]
|
#[serde(rename = "widgetId")]
|
||||||
pub widget_id: WidgetId,
|
pub widget_id: WidgetId,
|
||||||
pub widget: Widget,
|
pub widget: Box<Widget>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for WidgetInstance {
|
impl PartialEq for WidgetInstance {
|
||||||
@@ -566,7 +568,7 @@ impl WidgetInstance {
|
|||||||
pub fn new(widget: Widget) -> Self {
|
pub fn new(widget: Widget) -> Self {
|
||||||
Self {
|
Self {
|
||||||
widget_id: WidgetId(generate_uuid()),
|
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
|
// 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)
|
// Check if only the popover layout changed (all other fields are the same)
|
||||||
if self.widget_id == new.widget_id
|
if self.widget_id == new.widget_id
|
||||||
&& button1.disabled == button2.disabled
|
&& 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>) {
|
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) => {
|
Widget::CheckboxInput(checkbox) => {
|
||||||
// Compute stable ID based on position and insert mapping
|
// Compute stable ID based on position and insert mapping
|
||||||
let checkbox_id = checkbox.for_label;
|
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);
|
self.widget_id = compute_widget_id(layout_target, widget_path, &self.widget);
|
||||||
|
|
||||||
// 2. Replace CheckboxIds if present
|
// 2. Replace CheckboxIds if present
|
||||||
match &mut self.widget {
|
match &mut *self.widget {
|
||||||
Widget::CheckboxInput(checkbox) => {
|
Widget::CheckboxInput(checkbox) => {
|
||||||
let old_id = checkbox.for_label;
|
let old_id = checkbox.for_label;
|
||||||
if let Some(&new_id) = checkbox_map.get(&old_id) {
|
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
|
// 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| {
|
let convert_tooltip = |widget_instance: &mut WidgetInstance| {
|
||||||
// Handle all the widgets that have tooltips
|
// 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::BreadcrumbTrailButtons(widget) => widget.tooltip_shortcut.as_mut(),
|
||||||
Widget::CheckboxInput(widget) => widget.tooltip_shortcut.as_mut(),
|
Widget::CheckboxInput(widget) => widget.tooltip_shortcut.as_mut(),
|
||||||
Widget::ColorInput(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
|
// 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 {
|
for radio_entry_data in &mut radio_input.entries {
|
||||||
// Convert `ActionShortcut::Action` to `ActionShortcut::Shortcut`
|
// Convert `ActionShortcut::Action` to `ActionShortcut::Shortcut`
|
||||||
if let Some(tooltip_shortcut) = radio_entry_data.tooltip_shortcut.as_mut() {
|
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
|
// 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) => {
|
Widget::DropdownInput(dropdown_input) => {
|
||||||
apply_action_shortcut_to_menu_lists(&mut dropdown_input.entries);
|
apply_action_shortcut_to_menu_lists(&mut dropdown_input.entries);
|
||||||
dropdown_input.entries_hash = hash_menu_list_entry_sections(&dropdown_input.entries);
|
dropdown_input.entries_hash = hash_menu_list_entry_sections(&dropdown_input.entries);
|
||||||
|
|||||||
Reference in New Issue
Block a user