Skip to content

Commit 69e2036

Browse files
Setup popover menu for frontend controls
1 parent e917781 commit 69e2036

1 file changed

Lines changed: 101 additions & 68 deletions

File tree

editor/src/messages/tool/tool_messages/path_tool.rs

Lines changed: 101 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,93 @@ impl ToolMetadata for PathTool {
162162
ToolType::Path
163163
}
164164
}
165+
pub fn proportional_edit_options(options: &PathToolOptions) -> Vec<LayoutGroup> {
166+
let mut widgets = Vec::new();
167+
168+
// Header row with title
169+
widgets.push(LayoutGroup::Row {
170+
widgets: vec![TextLabel::new("Proportional Edit").bold(true).widget_holder()],
171+
});
172+
173+
// Enabled row
174+
widgets.push(LayoutGroup::Row {
175+
widgets: vec![
176+
TextLabel::new("Enabled").center_align(true).widget_holder(),
177+
Separator::new(SeparatorType::Unrelated).widget_holder(),
178+
CheckboxInput::new(options.proportional_editing_enabled)
179+
.tooltip("Enable proportional editing (Alt+P)")
180+
.on_update(|checkbox| PathToolMessage::UpdateOptions(PathOptionsUpdate::ProportionalEditingEnabled(checkbox.checked)).into())
181+
.widget_holder(),
182+
],
183+
});
184+
185+
// Falloff type row
186+
widgets.push(LayoutGroup::Row {
187+
widgets: vec![
188+
TextLabel::new("Falloff Type").center_align(true).multiline(true).widget_holder(),
189+
Separator::new(SeparatorType::Unrelated).widget_holder(),
190+
DropdownInput::new(vec![vec![
191+
MenuListEntry::new("Smooth")
192+
.label("Smooth")
193+
.on_commit(|_| PathToolMessage::UpdateOptions(PathOptionsUpdate::ProportionalFalloffType(ProportionalFalloffType::Smooth)).into()),
194+
MenuListEntry::new("Sphere")
195+
.label("Sphere")
196+
.on_commit(|_| PathToolMessage::UpdateOptions(PathOptionsUpdate::ProportionalFalloffType(ProportionalFalloffType::Sphere)).into()),
197+
MenuListEntry::new("Root")
198+
.label("Root")
199+
.on_commit(|_| PathToolMessage::UpdateOptions(PathOptionsUpdate::ProportionalFalloffType(ProportionalFalloffType::Root)).into()),
200+
MenuListEntry::new("Inverse Square")
201+
.label("Inverse Square")
202+
.on_commit(|_| PathToolMessage::UpdateOptions(PathOptionsUpdate::ProportionalFalloffType(ProportionalFalloffType::InverseSquare)).into()),
203+
MenuListEntry::new("Sharp")
204+
.label("Sharp")
205+
.on_commit(|_| PathToolMessage::UpdateOptions(PathOptionsUpdate::ProportionalFalloffType(ProportionalFalloffType::Sharp)).into()),
206+
MenuListEntry::new("Linear")
207+
.label("Linear")
208+
.on_commit(|_| PathToolMessage::UpdateOptions(PathOptionsUpdate::ProportionalFalloffType(ProportionalFalloffType::Linear)).into()),
209+
MenuListEntry::new("Constant")
210+
.label("Constant")
211+
.on_commit(|_| PathToolMessage::UpdateOptions(PathOptionsUpdate::ProportionalFalloffType(ProportionalFalloffType::Constant)).into()),
212+
MenuListEntry::new("Random")
213+
.label("Random")
214+
.on_commit(|_| PathToolMessage::UpdateOptions(PathOptionsUpdate::ProportionalFalloffType(ProportionalFalloffType::Random)).into()),
215+
]])
216+
.selected_index(Some(options.proportional_falloff_type as u32))
217+
.disabled(!options.proportional_editing_enabled)
218+
.widget_holder(),
219+
],
220+
});
221+
222+
// Radius row
223+
widgets.push(LayoutGroup::Row {
224+
widgets: vec![
225+
TextLabel::new("Radius").center_align(true).widget_holder(),
226+
Separator::new(SeparatorType::Unrelated).widget_holder(),
227+
NumberInput::new(Some(options.proportional_radius as f64))
228+
.unit(" px")
229+
.min(1.0)
230+
.disabled(!options.proportional_editing_enabled)
231+
.on_update(|number_input| PathToolMessage::UpdateOptions(PathOptionsUpdate::ProportionalRadius(number_input.value.unwrap_or(0.) as i32)).into())
232+
.widget_holder(),
233+
],
234+
});
235+
236+
// Strength row
237+
widgets.push(LayoutGroup::Row {
238+
widgets: vec![
239+
TextLabel::new("Strength").center_align(true).widget_holder(),
240+
Separator::new(SeparatorType::Unrelated).widget_holder(),
241+
NumberInput::new(Some(options.proportional_falloff_strength as f64))
242+
.min(1.0)
243+
.step(1.0)
244+
.disabled(!options.proportional_editing_enabled)
245+
.on_update(|number_input| PathToolMessage::UpdateOptions(PathOptionsUpdate::ProportionalFalloffStrength(number_input.value.unwrap_or(1.0) as i32)).into())
246+
.widget_holder(),
247+
],
248+
});
249+
250+
widgets
251+
}
165252

166253
impl LayoutHolder for PathTool {
167254
fn layout(&self) -> Layout {
@@ -247,59 +334,19 @@ impl LayoutHolder for PathTool {
247334
.selected_index(Some(self.options.path_overlay_mode as u32))
248335
.widget_holder();
249336

250-
let proportional_editing_label = TextLabel::new("Proportional Edit").disabled(!self.options.proportional_editing_enabled).widget_holder();
251-
let proportional_checkbox = CheckboxInput::new(self.options.proportional_editing_enabled)
252-
.on_update(|checkbox| PathToolMessage::UpdateOptions(PathOptionsUpdate::ProportionalEditingEnabled(checkbox.checked)).into())
337+
// Create the proportional edit dropdown trigger (checkbox icon)
338+
// TODO: use this when icon is available?
339+
// let proportional_edit_trigger = CheckboxInput::new(self.options.proportional_editing_enabled)
340+
// .icon("ProportionalEdit")
341+
// .tooltip("Proportional Editing (Alt+P)")
342+
// .on_update(|checkbox| PathToolMessage::UpdateOptions(
343+
// PathOptionsUpdate::ProportionalEditingEnabled(checkbox.checked)).into())
344+
// .widget_holder();
345+
let proportional_edit_trigger = CheckboxInput::new(self.options.proportional_editing_enabled)
253346
.tooltip("Proportional Editing (Alt+P)")
347+
.on_update(|checkbox| PathToolMessage::UpdateOptions(PathOptionsUpdate::ProportionalEditingEnabled(checkbox.checked)).into())
254348
.widget_holder();
255-
256-
let falloff_label = TextLabel::new("Falloff").disabled(!self.options.proportional_editing_enabled).widget_holder();
257-
258-
let falloff_entries = vec![
259-
MenuListEntry::new("Smooth")
260-
.label("Smooth")
261-
.on_commit(|_| PathToolMessage::UpdateOptions(PathOptionsUpdate::ProportionalFalloffType(ProportionalFalloffType::Smooth)).into()),
262-
MenuListEntry::new("Sphere")
263-
.label("Sphere")
264-
.on_commit(|_| PathToolMessage::UpdateOptions(PathOptionsUpdate::ProportionalFalloffType(ProportionalFalloffType::Sphere)).into()),
265-
MenuListEntry::new("Root")
266-
.label("Root")
267-
.on_commit(|_| PathToolMessage::UpdateOptions(PathOptionsUpdate::ProportionalFalloffType(ProportionalFalloffType::Root)).into()),
268-
MenuListEntry::new("Inverse Square")
269-
.label("Inverse Square")
270-
.on_commit(|_| PathToolMessage::UpdateOptions(PathOptionsUpdate::ProportionalFalloffType(ProportionalFalloffType::InverseSquare)).into()),
271-
MenuListEntry::new("Sharp")
272-
.label("Sharp")
273-
.on_commit(|_| PathToolMessage::UpdateOptions(PathOptionsUpdate::ProportionalFalloffType(ProportionalFalloffType::Sharp)).into()),
274-
MenuListEntry::new("Linear")
275-
.label("Linear")
276-
.on_commit(|_| PathToolMessage::UpdateOptions(PathOptionsUpdate::ProportionalFalloffType(ProportionalFalloffType::Linear)).into()),
277-
MenuListEntry::new("Constant")
278-
.label("Constant")
279-
.on_commit(|_| PathToolMessage::UpdateOptions(PathOptionsUpdate::ProportionalFalloffType(ProportionalFalloffType::Constant)).into()),
280-
MenuListEntry::new("Random")
281-
.label("Random")
282-
.on_commit(|_| PathToolMessage::UpdateOptions(PathOptionsUpdate::ProportionalFalloffType(ProportionalFalloffType::Random)).into()),
283-
];
284-
285-
let falloff_dropdown = DropdownInput::new(vec![falloff_entries])
286-
.selected_index(Some(self.options.proportional_falloff_type as u32))
287-
.disabled(!self.options.proportional_editing_enabled)
288-
.widget_holder();
289-
let radius_label = TextLabel::new("Radius").disabled(!self.options.proportional_editing_enabled).widget_holder();
290-
let radius_input = NumberInput::new(Some(self.options.proportional_radius as f64))
291-
.unit(" px")
292-
.min(1.0)
293-
.disabled(!self.options.proportional_editing_enabled)
294-
.on_update(|number_input| PathToolMessage::UpdateOptions(PathOptionsUpdate::ProportionalRadius(number_input.value.unwrap_or(0.) as i32)).into())
295-
.widget_holder();
296-
let strength_label = TextLabel::new("Strength").disabled(!self.options.proportional_editing_enabled).widget_holder();
297-
let strength_input = NumberInput::new(Some(self.options.proportional_falloff_strength as f64))
298-
.min(1 as f64)
299-
.step(1 as f64)
300-
.disabled(!self.options.proportional_editing_enabled)
301-
.on_update(|number_input| PathToolMessage::UpdateOptions(PathOptionsUpdate::ProportionalFalloffStrength(number_input.value.unwrap_or(1.0) as i32)).into())
302-
.widget_holder();
349+
let proportional_edit_dropdown = PopoverButton::new().popover_layout(proportional_edit_options(&self.options)).widget_holder();
303350

304351
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Row {
305352
widgets: vec![
@@ -308,27 +355,13 @@ impl LayoutHolder for PathTool {
308355
y_location,
309356
unrelated_seperator.clone(),
310357
colinear_handle_checkbox,
311-
related_seperator.clone(),
358+
related_seperator,
312359
colinear_handles_label,
313360
unrelated_seperator.clone(),
314361
path_overlay_mode_widget,
315-
unrelated_seperator.clone(),
316-
proportional_editing_label,
317-
related_seperator.clone(),
318-
proportional_checkbox,
319-
unrelated_seperator.clone(),
320-
falloff_label,
321-
related_seperator.clone(),
322-
falloff_dropdown,
323-
unrelated_seperator.clone(),
324-
radius_label,
325-
related_seperator.clone(),
326-
radius_input,
327-
unrelated_seperator.clone(),
328-
strength_label,
329-
related_seperator,
330-
strength_input,
331362
unrelated_seperator,
363+
proportional_edit_trigger,
364+
proportional_edit_dropdown,
332365
],
333366
}]))
334367
}

0 commit comments

Comments
 (0)