Rename PropertyHolder to LayoutHolder

This commit is contained in:
Keavon Chambers
2023-08-01 00:46:30 -07:00
parent 8e87e42f3e
commit b9e49623a3
51 changed files with 280 additions and 284 deletions
+2 -3
View File
@@ -255,7 +255,7 @@ impl Dispatcher {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use crate::application::Editor; use crate::application::Editor;
use crate::messages::layout::utility_types::layout_widget::DiffUpdate; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::portfolio::document::utility_types::clipboards::Clipboard; use crate::messages::portfolio::document::utility_types::clipboards::Clipboard;
use crate::messages::prelude::*; use crate::messages::prelude::*;
use crate::test_utils::EditorTestUtils; use crate::test_utils::EditorTestUtils;
@@ -549,8 +549,7 @@ mod test {
/// If this test is failing take a look at `GRAPHITE_DOCUMENT_VERSION` in `editor/src/consts.rs`, it may need to be updated. /// If this test is failing take a look at `GRAPHITE_DOCUMENT_VERSION` in `editor/src/consts.rs`, it may need to be updated.
/// This test will fail when you make changes to the underlying serialization format for a document. /// This test will fail when you make changes to the underlying serialization format for a document.
fn check_if_graphite_file_version_upgrade_is_needed() { fn check_if_graphite_file_version_upgrade_is_needed() {
use crate::messages::layout::utility_types::layout_widget::{LayoutGroup, Widget}; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::layout::utility_types::widgets::label_widgets::TextLabel;
let print_problem_to_terminal_on_failure = |value: &String| { let print_problem_to_terminal_on_failure = |value: &String| {
println!(); println!();
@@ -1,6 +1,5 @@
use super::simple_dialogs::{self, AboutGraphiteDialog, ComingSoonDialog}; use super::simple_dialogs::{self, AboutGraphiteDialog, ComingSoonDialog};
use crate::messages::layout::utility_types::layout_widget::PropertyHolder; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::prelude::*; use crate::messages::prelude::*;
#[derive(Debug, Default, Clone)] #[derive(Debug, Default, Clone)]
@@ -24,7 +23,7 @@ impl MessageHandler<DialogMessage, (&PortfolioMessageHandler, &PreferencesMessag
DialogMessage::CloseAllDocumentsWithConfirmation => { DialogMessage::CloseAllDocumentsWithConfirmation => {
let dialog = simple_dialogs::CloseAllDocumentsDialog; let dialog = simple_dialogs::CloseAllDocumentsDialog;
dialog.register_properties(responses, LayoutTarget::DialogDetails); dialog.send_layout(responses, LayoutTarget::DialogDetails);
responses.add(FrontendMessage::DisplayDialog { icon: "Copy".to_string() }); responses.add(FrontendMessage::DisplayDialog { icon: "Copy".to_string() });
} }
DialogMessage::CloseDialogAndThen { followups } => { DialogMessage::CloseDialogAndThen { followups } => {
@@ -35,7 +34,7 @@ impl MessageHandler<DialogMessage, (&PortfolioMessageHandler, &PreferencesMessag
} }
DialogMessage::DisplayDialogError { title, description } => { DialogMessage::DisplayDialogError { title, description } => {
let dialog = simple_dialogs::ErrorDialog { title, description }; let dialog = simple_dialogs::ErrorDialog { title, description };
dialog.register_properties(responses, LayoutTarget::DialogDetails); dialog.send_layout(responses, LayoutTarget::DialogDetails);
responses.add(FrontendMessage::DisplayDialog { icon: "Warning".to_string() }); responses.add(FrontendMessage::DisplayDialog { icon: "Warning".to_string() });
} }
DialogMessage::RequestAboutGraphiteDialog => { DialogMessage::RequestAboutGraphiteDialog => {
@@ -46,12 +45,12 @@ impl MessageHandler<DialogMessage, (&PortfolioMessageHandler, &PreferencesMessag
DialogMessage::RequestAboutGraphiteDialogWithLocalizedCommitDate { localized_commit_date } => { DialogMessage::RequestAboutGraphiteDialogWithLocalizedCommitDate { localized_commit_date } => {
let about_graphite = AboutGraphiteDialog { localized_commit_date }; let about_graphite = AboutGraphiteDialog { localized_commit_date };
about_graphite.register_properties(responses, LayoutTarget::DialogDetails); about_graphite.send_layout(responses, LayoutTarget::DialogDetails);
responses.add(FrontendMessage::DisplayDialog { icon: "GraphiteLogo".to_string() }); responses.add(FrontendMessage::DisplayDialog { icon: "GraphiteLogo".to_string() });
} }
DialogMessage::RequestComingSoonDialog { issue } => { DialogMessage::RequestComingSoonDialog { issue } => {
let coming_soon = ComingSoonDialog { issue }; let coming_soon = ComingSoonDialog { issue };
coming_soon.register_properties(responses, LayoutTarget::DialogDetails); coming_soon.send_layout(responses, LayoutTarget::DialogDetails);
responses.add(FrontendMessage::DisplayDialog { icon: "Warning".to_string() }); responses.add(FrontendMessage::DisplayDialog { icon: "Warning".to_string() });
} }
DialogMessage::RequestExportDialog => { DialogMessage::RequestExportDialog => {
@@ -84,7 +83,7 @@ impl MessageHandler<DialogMessage, (&PortfolioMessageHandler, &PreferencesMessag
has_selection: document.selected_layers().next().is_some(), has_selection: document.selected_layers().next().is_some(),
..Default::default() ..Default::default()
}; };
self.export_dialog.register_properties(responses, LayoutTarget::DialogDetails); self.export_dialog.send_layout(responses, LayoutTarget::DialogDetails);
responses.add(FrontendMessage::DisplayDialog { icon: "File".to_string() }); responses.add(FrontendMessage::DisplayDialog { icon: "File".to_string() });
} }
} }
@@ -94,12 +93,12 @@ impl MessageHandler<DialogMessage, (&PortfolioMessageHandler, &PreferencesMessag
infinite: false, infinite: false,
dimensions: glam::UVec2::new(1920, 1080), dimensions: glam::UVec2::new(1920, 1080),
}; };
self.new_document_dialog.register_properties(responses, LayoutTarget::DialogDetails); self.new_document_dialog.send_layout(responses, LayoutTarget::DialogDetails);
responses.add(FrontendMessage::DisplayDialog { icon: "File".to_string() }); responses.add(FrontendMessage::DisplayDialog { icon: "File".to_string() });
} }
DialogMessage::RequestPreferencesDialog => { DialogMessage::RequestPreferencesDialog => {
self.preferences_dialog = PreferencesDialogMessageHandler {}; self.preferences_dialog = PreferencesDialogMessageHandler {};
self.preferences_dialog.register_properties(responses, LayoutTarget::DialogDetails, preferences); self.preferences_dialog.send_layout(responses, LayoutTarget::DialogDetails, preferences);
responses.add(FrontendMessage::DisplayDialog { icon: "Settings".to_string() }); responses.add(FrontendMessage::DisplayDialog { icon: "Settings".to_string() });
} }
} }
@@ -1,5 +1,4 @@
use crate::messages::frontend::utility_types::{ExportBounds, FileType}; use crate::messages::frontend::utility_types::{ExportBounds, FileType};
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::widget_prelude::*; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::prelude::*; use crate::messages::prelude::*;
@@ -35,14 +34,14 @@ impl MessageHandler<ExportDialogMessage, ()> for ExportDialogMessageHandler {
}), }),
} }
self.register_properties(responses, LayoutTarget::DialogDetails); self.send_layout(responses, LayoutTarget::DialogDetails);
} }
advertise_actions! {ExportDialogUpdate;} advertise_actions! {ExportDialogUpdate;}
} }
impl PropertyHolder for ExportDialogMessageHandler { impl LayoutHolder for ExportDialogMessageHandler {
fn properties(&self) -> Layout { fn layout(&self) -> Layout {
let file_name = vec![ let file_name = vec![
TextLabel::new("File Name").table_align(true).widget_holder(), TextLabel::new("File Name").table_align(true).widget_holder(),
Separator::new(SeparatorType::Unrelated).widget_holder(), Separator::new(SeparatorType::Unrelated).widget_holder(),
+1 -1
View File
@@ -1,6 +1,6 @@
//! Handles modal dialogs that appear as floating menus in the center of the editor window. //! Handles modal dialogs that appear as floating menus in the center of the editor window.
//! //!
//! Dialogs are represented as structs that implement the `PropertyHolder` trait. //! Dialogs are represented as structs that implement the `LayoutHolder` trait.
//! //!
//! To open a dialog, call the function `register_properties` on the dialog struct with `responses` and the `LayoutTarget::DialogDetails` enum variant. //! To open a dialog, call the function `register_properties` on the dialog struct with `responses` and the `LayoutTarget::DialogDetails` enum variant.
//! Then dialog can be opened by sending the `FrontendMessage::DisplayDialog` message; //! Then dialog can be opened by sending the `FrontendMessage::DisplayDialog` message;
@@ -1,4 +1,3 @@
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::widget_prelude::*; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::prelude::*; use crate::messages::prelude::*;
@@ -43,14 +42,14 @@ impl MessageHandler<NewDocumentDialogMessage, ()> for NewDocumentDialogMessageHa
} }
} }
self.register_properties(responses, LayoutTarget::DialogDetails); self.send_layout(responses, LayoutTarget::DialogDetails);
} }
advertise_actions! {NewDocumentDialogUpdate;} advertise_actions! {NewDocumentDialogUpdate;}
} }
impl PropertyHolder for NewDocumentDialogMessageHandler { impl LayoutHolder for NewDocumentDialogMessageHandler {
fn properties(&self) -> Layout { fn layout(&self) -> Layout {
let title = vec![TextLabel::new("New document").bold(true).widget_holder()]; let title = vec![TextLabel::new("New document").bold(true).widget_holder()];
let name = vec![ let name = vec![
@@ -1,4 +1,3 @@
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::widget_prelude::*; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::prelude::*; use crate::messages::prelude::*;
@@ -12,21 +11,21 @@ impl MessageHandler<PreferencesDialogMessage, &PreferencesMessageHandler> for Pr
PreferencesDialogMessage::Confirm => {} PreferencesDialogMessage::Confirm => {}
} }
self.register_properties(responses, LayoutTarget::DialogDetails, preferences); self.send_layout(responses, LayoutTarget::DialogDetails, preferences);
} }
advertise_actions! {PreferencesDialogUpdate;} advertise_actions! {PreferencesDialogUpdate;}
} }
impl PreferencesDialogMessageHandler { impl PreferencesDialogMessageHandler {
pub fn register_properties(&self, responses: &mut VecDeque<Message>, layout_target: LayoutTarget, preferences: &PreferencesMessageHandler) { pub fn send_layout(&self, responses: &mut VecDeque<Message>, layout_target: LayoutTarget, preferences: &PreferencesMessageHandler) {
responses.add(LayoutMessage::SendLayout { responses.add(LayoutMessage::SendLayout {
layout: self.properties(preferences), layout: self.layout(preferences),
layout_target, layout_target,
}) })
} }
fn properties(&self, preferences: &PreferencesMessageHandler) -> Layout { fn layout(&self, preferences: &PreferencesMessageHandler) -> Layout {
let zoom_with_scroll = vec![ let zoom_with_scroll = vec![
TextLabel::new("Input").min_width(60).italic(true).widget_holder(), TextLabel::new("Input").min_width(60).italic(true).widget_holder(),
TextLabel::new("Zoom with Scroll").table_align(true).widget_holder(), TextLabel::new("Zoom with Scroll").table_align(true).widget_holder(),
@@ -7,8 +7,8 @@ pub struct AboutGraphiteDialog {
pub localized_commit_date: String, pub localized_commit_date: String,
} }
impl PropertyHolder for AboutGraphiteDialog { impl LayoutHolder for AboutGraphiteDialog {
fn properties(&self) -> Layout { fn layout(&self) -> Layout {
let links = [ let links = [
("Website", "https://graphite.rs"), ("Website", "https://graphite.rs"),
("Credits", "https://github.com/GraphiteEditor/Graphite/graphs/contributors"), ("Credits", "https://github.com/GraphiteEditor/Graphite/graphs/contributors"),
@@ -4,8 +4,8 @@ use crate::messages::prelude::*;
/// A dialog for confirming the closing of all documents viewable via `file -> close all` in the menu bar. /// A dialog for confirming the closing of all documents viewable via `file -> close all` in the menu bar.
pub struct CloseAllDocumentsDialog; pub struct CloseAllDocumentsDialog;
impl PropertyHolder for CloseAllDocumentsDialog { impl LayoutHolder for CloseAllDocumentsDialog {
fn properties(&self) -> Layout { fn layout(&self) -> Layout {
let discard = TextButton::new("Discard All") let discard = TextButton::new("Discard All")
.min_width(96) .min_width(96)
.on_update(|_| { .on_update(|_| {
@@ -8,8 +8,8 @@ pub struct CloseDocumentDialog {
pub document_id: u64, pub document_id: u64,
} }
impl PropertyHolder for CloseDocumentDialog { impl LayoutHolder for CloseDocumentDialog {
fn properties(&self) -> Layout { fn layout(&self) -> Layout {
let document_id = self.document_id; let document_id = self.document_id;
let button_widgets = vec![ let button_widgets = vec![
@@ -8,8 +8,8 @@ pub struct ComingSoonDialog {
pub issue: Option<i32>, pub issue: Option<i32>,
} }
impl PropertyHolder for ComingSoonDialog { impl LayoutHolder for ComingSoonDialog {
fn properties(&self) -> Layout { fn layout(&self) -> Layout {
let mut details = "This feature is not implemented yet".to_string(); let mut details = "This feature is not implemented yet".to_string();
let mut buttons = vec![TextButton::new("OK") let mut buttons = vec![TextButton::new("OK")
@@ -7,8 +7,8 @@ pub struct ErrorDialog {
pub description: String, pub description: String,
} }
impl PropertyHolder for ErrorDialog { impl LayoutHolder for ErrorDialog {
fn properties(&self) -> Layout { fn layout(&self) -> Layout {
Layout::WidgetLayout(WidgetLayout::new(vec![ Layout::WidgetLayout(WidgetLayout::new(vec![
LayoutGroup::Row { LayoutGroup::Row {
widgets: vec![TextLabel::new(&self.title).bold(true).widget_holder()], widgets: vec![TextLabel::new(&self.title).bold(true).widget_holder()],
@@ -1,7 +1,5 @@
use super::utility_types::{FrontendDocumentDetails, FrontendImageData, MouseCursorIcon}; use super::utility_types::{FrontendDocumentDetails, FrontendImageData, MouseCursorIcon};
use crate::messages::layout::utility_types::layout_widget::WidgetDiff; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::widgets::menu_widgets::MenuBarEntry;
use crate::messages::portfolio::document::node_graph::{FrontendNode, FrontendNodeLink, FrontendNodeType}; use crate::messages::portfolio::document::node_graph::{FrontendNode, FrontendNodeLink, FrontendNodeType};
use crate::messages::portfolio::document::utility_types::layer_panel::{JsRawBuffer, LayerPanelEntry, RawBuffer}; use crate::messages::portfolio::document::utility_types::layer_panel::{JsRawBuffer, LayerPanelEntry, RawBuffer};
use crate::messages::prelude::*; use crate::messages::prelude::*;
+1 -2
View File
@@ -1,5 +1,4 @@
use super::utility_types::misc::LayoutTarget; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::layout::utility_types::layout_widget::Layout;
use crate::messages::prelude::*; use crate::messages::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@@ -1,8 +1,5 @@
use super::utility_types::layout_widget::{LayoutGroup, WidgetDiff, WidgetHolder};
use super::utility_types::misc::LayoutTarget;
use crate::messages::input_mapper::utility_types::input_keyboard::KeysGroup; use crate::messages::input_mapper::utility_types::input_keyboard::KeysGroup;
use crate::messages::layout::utility_types::layout_widget::{DiffUpdate, Widget}; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::layout::utility_types::layout_widget::{Layout, WidgetLayout};
use crate::messages::prelude::*; use crate::messages::prelude::*;
use document_legacy::LayerId; use document_legacy::LayerId;
@@ -68,7 +65,7 @@ impl<F: Fn(&MessageDiscriminant) -> Vec<KeysGroup>> MessageHandler<LayoutMessage
// Resend that diff // Resend that diff
self.send_diff(vec![diff], layout_target, responses, &action_input_mapping); self.send_diff(vec![diff], layout_target, responses, &action_input_mapping);
} }
SendLayout { layout, layout_target } => self.send_layout(layout_target, layout, responses, &action_input_mapping), SendLayout { layout, layout_target } => self.diff_and_send_layout_to_frontend(layout_target, layout, responses, &action_input_mapping),
UpdateLayout { layout_target, widget_id, value } => { UpdateLayout { layout_target, widget_id, value } => {
// Look up the layout // Look up the layout
let layout = if let Some(layout) = self.layouts.get_mut(layout_target as usize) { let layout = if let Some(layout) = self.layouts.get_mut(layout_target as usize) {
@@ -243,7 +240,13 @@ impl<F: Fn(&MessageDiscriminant) -> Vec<KeysGroup>> MessageHandler<LayoutMessage
impl LayoutMessageHandler { impl LayoutMessageHandler {
/// Diff the update and send to the frontend where necessary /// Diff the update and send to the frontend where necessary
fn send_layout(&mut self, layout_target: LayoutTarget, new_layout: Layout, responses: &mut VecDeque<Message>, action_input_mapping: &impl Fn(&MessageDiscriminant) -> Vec<KeysGroup>) { fn diff_and_send_layout_to_frontend(
&mut self,
layout_target: LayoutTarget,
new_layout: Layout,
responses: &mut VecDeque<Message>,
action_input_mapping: &impl Fn(&MessageDiscriminant) -> Vec<KeysGroup>,
) {
// We don't diff the menu bar layout yet. // We don't diff the menu bar layout yet.
if matches!(new_layout, Layout::MenuLayout(_)) { if matches!(new_layout, Layout::MenuLayout(_)) {
// Skip update if the same // Skip update if the same
@@ -6,129 +6,61 @@ use super::widgets::menu_widgets::MenuLayout;
use crate::application::generate_uuid; use crate::application::generate_uuid;
use crate::messages::input_mapper::utility_types::input_keyboard::KeysGroup; use crate::messages::input_mapper::utility_types::input_keyboard::KeysGroup;
use crate::messages::input_mapper::utility_types::misc::ActionKeys; use crate::messages::input_mapper::utility_types::misc::ActionKeys;
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::prelude::*; use crate::messages::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::sync::Arc; use std::sync::Arc;
pub trait PropertyHolder { #[remain::sorted]
fn properties(&self) -> Layout { #[derive(PartialEq, Clone, Debug, Hash, Eq, Copy, Serialize, Deserialize, specta::Type)]
Layout::WidgetLayout(WidgetLayout::default()) #[repr(u8)]
} pub enum LayoutTarget {
/// Contains the contents of the dialog, including the title and action buttons. Must be shown with the `FrontendMessage::DisplayDialog` message.
DialogDetails,
/// Contains the widgets located directly above the canvas to the right, for example the zoom in and out buttons.
DocumentBar,
/// Contains the dropdown for design / select / guide mode found on the top left of the canvas.
DocumentMode,
/// Options for opacity seen at the top of the Layers panel.
LayerTreeOptions,
/// The dropdown menu at the very top of the application: File, Edit, etc.
MenuBar,
/// Bar at the top of the node graph containing the location and the 'preview' and 'hide' buttons.
NodeGraphBar,
/// The bar at the top of the Properties panel containing the layer name and icon.
PropertiesOptions,
/// The body of the Properties panel containing many collapsable sections.
PropertiesSections,
/// The bar directly above the canvas, left-aligned and to the right of the document mode dropdown.
ToolOptions,
/// The vertical buttons for all of the tools on the left of the canvas.
ToolShelf,
/// The color swatch for the working colors and a flip and reset button found at the bottom of the tool shelf.
WorkingColors,
fn register_properties(&self, responses: &mut VecDeque<Message>, layout_target: LayoutTarget) { // KEEP THIS ENUM LAST
responses.add(LayoutMessage::SendLayout { // This is a marker that is used to define an array that is used to hold widgets
layout: self.properties(), #[remain::unsorted]
layout_target, LayoutTargetLength,
}) }
/// For use by structs that define a UI widget layout by implementing the layout() function belonging to this trait.
/// The send_layout() function can then be called by other code which is a part of the same struct so as to send the layout to the frontend.
pub trait LayoutHolder {
fn layout(&self) -> Layout;
fn send_layout(&self, responses: &mut VecDeque<Message>, layout_target: LayoutTarget) {
responses.add(LayoutMessage::SendLayout { layout: self.layout(), layout_target });
} }
} }
/// Wraps a choice of layout type. The chosen layout contains an arrangement of widgets mounted somewhere specific in the frontend.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, specta::Type)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, specta::Type)]
pub enum Layout { pub enum Layout {
WidgetLayout(WidgetLayout), WidgetLayout(WidgetLayout),
MenuLayout(MenuLayout), MenuLayout(MenuLayout),
} }
/// The new value of the UI, sent as part of a diff.
///
/// An update can represent a single widget or an entire SubLayout, or just a single layout group.
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize, specta::Type)]
pub enum DiffUpdate {
#[serde(rename = "subLayout")]
SubLayout(SubLayout),
#[serde(rename = "layoutGroup")]
LayoutGroup(LayoutGroup),
#[serde(rename = "widget")]
Widget(WidgetHolder),
}
/// A single change to part of the UI, containing the location of the change and the new value.
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize, specta::Type)]
pub struct WidgetDiff {
/// A path to the change
/// e.g. [0, 1, 2] in the properties panel is the first section, second row and third widget.
/// An empty path [] shows that the entire panel has changed and is sent when the UI is first created.
#[serde(rename = "widgetPath")]
pub widget_path: Vec<usize>,
/// What the specified part of the UI has changed to.
#[serde(rename = "newValue")]
pub new_value: DiffUpdate,
}
impl DiffUpdate {
/// Append the shortcut to the tooltip where applicable
pub fn apply_shortcut(&mut self, action_input_mapping: &impl Fn(&MessageDiscriminant) -> Vec<KeysGroup>) {
// Function used multiple times later in this code block to convert `ActionKeys::Action` to `ActionKeys::Keys` and append its shortcut to the tooltip
let apply_shortcut_to_tooltip = |tooltip_shortcut: &mut ActionKeys, tooltip: &mut String| {
let shortcut_text = tooltip_shortcut.to_keys(action_input_mapping);
if let ActionKeys::Keys(_keys) = tooltip_shortcut {
if !shortcut_text.is_empty() {
if !tooltip.is_empty() {
tooltip.push(' ');
}
tooltip.push('(');
tooltip.push_str(&shortcut_text);
tooltip.push(')');
}
}
};
// Go through each widget to convert `ActionKeys::Action` to `ActionKeys::Keys` and append the key combination to the widget tooltip
let convert_tooltip = |widget_holder: &mut WidgetHolder| {
// Handle all the widgets that have tooltips
let mut tooltip_shortcut = match &mut widget_holder.widget {
Widget::BreadcrumbTrailButtons(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)),
Widget::CheckboxInput(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)),
Widget::ColorInput(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)),
Widget::DropdownInput(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)),
Widget::FontInput(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)),
Widget::IconButton(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)),
Widget::LayerReferenceInput(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)),
Widget::NumberInput(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)),
Widget::OptionalInput(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)),
Widget::ParameterExposeButton(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)),
Widget::PopoverButton(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)),
Widget::TextButton(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)),
Widget::IconLabel(_)
| Widget::InvisibleStandinInput(_)
| Widget::PivotAssist(_)
| Widget::RadioInput(_)
| Widget::Separator(_)
| Widget::SwatchPairInput(_)
| Widget::TextAreaInput(_)
| Widget::TextInput(_)
| Widget::TextLabel(_) => None,
};
if let Some((tooltip, Some(tooltip_shortcut))) = &mut tooltip_shortcut {
apply_shortcut_to_tooltip(tooltip_shortcut, tooltip);
}
// Handle RadioInput separately because its tooltips are children of the widget
if let Widget::RadioInput(radio_input) = &mut widget_holder.widget {
for radio_entry_data in &mut radio_input.entries {
if let RadioEntryData {
tooltip,
tooltip_shortcut: Some(tooltip_shortcut),
..
} = radio_entry_data
{
apply_shortcut_to_tooltip(tooltip_shortcut, tooltip);
}
}
}
};
match self {
Self::SubLayout(sub_layout) => sub_layout.iter_mut().flat_map(|group| group.iter_mut()).for_each(convert_tooltip),
Self::LayoutGroup(layout_group) => layout_group.iter_mut().for_each(convert_tooltip),
Self::Widget(widget_holder) => convert_tooltip(widget_holder),
}
}
}
impl Layout { impl Layout {
pub fn unwrap_menu_layout(self, action_input_mapping: &impl Fn(&MessageDiscriminant) -> Vec<KeysGroup>) -> MenuLayout { pub fn unwrap_menu_layout(self, action_input_mapping: &impl Fn(&MessageDiscriminant) -> Vec<KeysGroup>) -> MenuLayout {
if let Self::MenuLayout(mut menu) = self { if let Self::MenuLayout(mut menu) = self {
@@ -517,3 +449,101 @@ pub enum Widget {
TextInput(TextInput), TextInput(TextInput),
TextLabel(TextLabel), TextLabel(TextLabel),
} }
/// A single change to part of the UI, containing the location of the change and the new value.
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize, specta::Type)]
pub struct WidgetDiff {
/// A path to the change
/// e.g. [0, 1, 2] in the properties panel is the first section, second row and third widget.
/// An empty path [] shows that the entire panel has changed and is sent when the UI is first created.
#[serde(rename = "widgetPath")]
pub widget_path: Vec<usize>,
/// What the specified part of the UI has changed to.
#[serde(rename = "newValue")]
pub new_value: DiffUpdate,
}
/// The new value of the UI, sent as part of a diff.
///
/// An update can represent a single widget or an entire SubLayout, or just a single layout group.
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize, specta::Type)]
pub enum DiffUpdate {
#[serde(rename = "subLayout")]
SubLayout(SubLayout),
#[serde(rename = "layoutGroup")]
LayoutGroup(LayoutGroup),
#[serde(rename = "widget")]
Widget(WidgetHolder),
}
impl DiffUpdate {
/// Append the shortcut to the tooltip where applicable
pub fn apply_shortcut(&mut self, action_input_mapping: &impl Fn(&MessageDiscriminant) -> Vec<KeysGroup>) {
// Function used multiple times later in this code block to convert `ActionKeys::Action` to `ActionKeys::Keys` and append its shortcut to the tooltip
let apply_shortcut_to_tooltip = |tooltip_shortcut: &mut ActionKeys, tooltip: &mut String| {
let shortcut_text = tooltip_shortcut.to_keys(action_input_mapping);
if let ActionKeys::Keys(_keys) = tooltip_shortcut {
if !shortcut_text.is_empty() {
if !tooltip.is_empty() {
tooltip.push(' ');
}
tooltip.push('(');
tooltip.push_str(&shortcut_text);
tooltip.push(')');
}
}
};
// Go through each widget to convert `ActionKeys::Action` to `ActionKeys::Keys` and append the key combination to the widget tooltip
let convert_tooltip = |widget_holder: &mut WidgetHolder| {
// Handle all the widgets that have tooltips
let mut tooltip_shortcut = match &mut widget_holder.widget {
Widget::BreadcrumbTrailButtons(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)),
Widget::CheckboxInput(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)),
Widget::ColorInput(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)),
Widget::DropdownInput(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)),
Widget::FontInput(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)),
Widget::IconButton(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)),
Widget::LayerReferenceInput(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)),
Widget::NumberInput(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)),
Widget::OptionalInput(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)),
Widget::ParameterExposeButton(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)),
Widget::PopoverButton(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)),
Widget::TextButton(widget) => Some((&mut widget.tooltip, &mut widget.tooltip_shortcut)),
Widget::IconLabel(_)
| Widget::InvisibleStandinInput(_)
| Widget::PivotAssist(_)
| Widget::RadioInput(_)
| Widget::Separator(_)
| Widget::SwatchPairInput(_)
| Widget::TextAreaInput(_)
| Widget::TextInput(_)
| Widget::TextLabel(_) => None,
};
if let Some((tooltip, Some(tooltip_shortcut))) = &mut tooltip_shortcut {
apply_shortcut_to_tooltip(tooltip_shortcut, tooltip);
}
// Handle RadioInput separately because its tooltips are children of the widget
if let Widget::RadioInput(radio_input) = &mut widget_holder.widget {
for radio_entry_data in &mut radio_input.entries {
if let RadioEntryData {
tooltip,
tooltip_shortcut: Some(tooltip_shortcut),
..
} = radio_entry_data
{
apply_shortcut_to_tooltip(tooltip_shortcut, tooltip);
}
}
}
};
match self {
Self::SubLayout(sub_layout) => sub_layout.iter_mut().flat_map(|group| group.iter_mut()).for_each(convert_tooltip),
Self::LayoutGroup(layout_group) => layout_group.iter_mut().for_each(convert_tooltip),
Self::Widget(widget_holder) => convert_tooltip(widget_holder),
}
}
}
@@ -1,34 +0,0 @@
use serde::{Deserialize, Serialize};
#[remain::sorted]
#[derive(PartialEq, Clone, Debug, Hash, Eq, Copy, Serialize, Deserialize, specta::Type)]
#[repr(u8)]
pub enum LayoutTarget {
/// Contains the contents of the dialog, including the title and action buttons. Must be shown with the `FrontendMessage::DisplayDialog` message.
DialogDetails,
/// Contains the widgets located directly above the canvas to the right, for example the zoom in and out buttons.
DocumentBar,
/// Contains the dropdown for design / select / guide mode found on the top left of the canvas.
DocumentMode,
/// Options for opacity seen at the top of the Layers panel.
LayerTreeOptions,
/// The dropdown menu at the very top of the application: File, Edit, etc.
MenuBar,
/// Bar at the top of the node graph containing the location and the 'preview' and 'hide' buttons.
NodeGraphBar,
/// The bar at the top of the Properties panel containing the layer name and icon.
PropertiesOptions,
/// The body of the Properties panel containing many collapsable sections.
PropertiesSections,
/// The bar directly above the canvas, left-aligned and to the right of the document mode dropdown.
ToolOptions,
/// The vertical buttons for all of the tools on the left of the canvas.
ToolShelf,
/// The color swatch for the working colors and a flip and reset button found at the bottom of the tool shelf.
WorkingColors,
// KEEP THIS ENUM LAST
// This is a marker that is used to define an array that is used to hold widgets
#[remain::unsorted]
LayoutTargetLength,
}
@@ -1,5 +1,4 @@
pub mod layout_widget; pub mod layout_widget;
pub mod misc;
pub mod widgets; pub mod widgets;
pub mod widget_prelude { pub mod widget_prelude {
@@ -1,4 +1,4 @@
use crate::messages::layout::utility_types::layout_widget::WidgetCallback; use crate::messages::layout::utility_types::widget_prelude::*;
use graphite_proc_macros::WidgetBuilder; use graphite_proc_macros::WidgetBuilder;
use derivative::*; use derivative::*;
@@ -1,6 +1,5 @@
use crate::messages::input_mapper::utility_types::misc::ActionKeys; use crate::messages::input_mapper::utility_types::misc::ActionKeys;
use crate::messages::layout::utility_types::layout_widget::WidgetCallback; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::layout::utility_types::widget_prelude::SubLayout;
use crate::messages::portfolio::document::node_graph::FrontendGraphDataType; use crate::messages::portfolio::document::node_graph::FrontendGraphDataType;
use graphite_proc_macros::WidgetBuilder; use graphite_proc_macros::WidgetBuilder;
@@ -1,5 +1,5 @@
use crate::messages::input_mapper::utility_types::misc::ActionKeys; use crate::messages::input_mapper::utility_types::misc::ActionKeys;
use crate::messages::layout::utility_types::layout_widget::WidgetCallback; use crate::messages::layout::utility_types::widget_prelude::*;
use document_legacy::layers::layer_info::LayerDataTypeDiscriminant; use document_legacy::layers::layer_info::LayerDataTypeDiscriminant;
use document_legacy::LayerId; use document_legacy::LayerId;
@@ -5,7 +5,6 @@ use crate::consts::{ASYMPTOTIC_EFFECT, DEFAULT_DOCUMENT_NAME, FILE_SAVE_SUFFIX,
use crate::messages::frontend::utility_types::ExportBounds; use crate::messages::frontend::utility_types::ExportBounds;
use crate::messages::frontend::utility_types::FileType; use crate::messages::frontend::utility_types::FileType;
use crate::messages::input_mapper::utility_types::macros::action_keys; use crate::messages::input_mapper::utility_types::macros::action_keys;
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::widget_prelude::*; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::portfolio::document::properties_panel::utility_types::PropertiesPanelMessageHandlerData; use crate::messages::portfolio::document::properties_panel::utility_types::PropertiesPanelMessageHandlerData;
use crate::messages::portfolio::document::utility_types::clipboards::Clipboard; use crate::messages::portfolio::document::utility_types::clipboards::Clipboard;
@@ -160,7 +160,7 @@ impl NodeGraphMessageHandler {
fn send_node_bar_layout(&self, responses: &mut VecDeque<Message>) { fn send_node_bar_layout(&self, responses: &mut VecDeque<Message>) {
responses.add(LayoutMessage::SendLayout { responses.add(LayoutMessage::SendLayout {
layout: Layout::WidgetLayout(WidgetLayout::new(self.widgets.to_vec())), layout: Layout::WidgetLayout(WidgetLayout::new(self.widgets.to_vec())),
layout_target: crate::messages::layout::utility_types::misc::LayoutTarget::NodeGraphBar, layout_target: LayoutTarget::NodeGraphBar,
}); });
} }
@@ -1,6 +1,6 @@
use super::{node_properties, FrontendGraphDataType, FrontendNodeType}; use super::{node_properties, FrontendGraphDataType, FrontendNodeType};
use crate::consts::{DEFAULT_FONT_FAMILY, DEFAULT_FONT_STYLE}; use crate::consts::{DEFAULT_FONT_FAMILY, DEFAULT_FONT_STYLE};
use crate::messages::layout::utility_types::layout_widget::LayoutGroup; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::node_graph_executor::NodeGraphExecutor; use crate::node_graph_executor::NodeGraphExecutor;
use graph_craft::concrete; use graph_craft::concrete;
@@ -1,5 +1,5 @@
use super::utility_types::TransformOp; use super::utility_types::TransformOp;
use crate::messages::layout::utility_types::widgets::assist_widgets::PivotPosition; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::portfolio::document::utility_types::misc::TargetDocument; use crate::messages::portfolio::document::utility_types::misc::TargetDocument;
use crate::messages::prelude::*; use crate::messages::prelude::*;
@@ -1,7 +1,6 @@
use super::utility_functions::{register_artboard_layer_properties, register_artwork_layer_properties, register_document_graph_properties}; use super::utility_functions::{register_artboard_layer_properties, register_artwork_layer_properties, register_document_graph_properties};
use super::utility_types::PropertiesPanelMessageHandlerData; use super::utility_types::PropertiesPanelMessageHandlerData;
use crate::messages::layout::utility_types::layout_widget::{Layout, WidgetLayout}; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::portfolio::document::properties_panel::utility_functions::apply_transform_operation; use crate::messages::portfolio::document::properties_panel::utility_functions::apply_transform_operation;
use crate::messages::portfolio::document::utility_types::misc::TargetDocument; use crate::messages::portfolio::document::utility_types::misc::TargetDocument;
use crate::messages::portfolio::utility_types::PersistentData; use crate::messages::portfolio::utility_types::PersistentData;
@@ -1,6 +1,5 @@
use super::utility_types::TransformOp; use super::utility_types::TransformOp;
use crate::application::generate_uuid; use crate::application::generate_uuid;
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::widget_prelude::*; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::portfolio::document::node_graph::NodePropertiesContext; use crate::messages::portfolio::document::node_graph::NodePropertiesContext;
use crate::messages::portfolio::utility_types::PersistentData; use crate::messages::portfolio::utility_types::PersistentData;
@@ -1,7 +1,5 @@
use crate::messages::input_mapper::utility_types::macros::action_keys; use crate::messages::input_mapper::utility_types::macros::action_keys;
use crate::messages::layout::utility_types::layout_widget::{Layout, PropertyHolder}; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::widgets::menu_widgets::{MenuBarEntry, MenuBarEntryChildren, MenuLayout};
use crate::messages::portfolio::document::utility_types::clipboards::Clipboard; use crate::messages::portfolio::document::utility_types::clipboards::Clipboard;
use crate::messages::prelude::*; use crate::messages::prelude::*;
@@ -18,7 +16,7 @@ impl MessageHandler<MenuBarMessage, bool> for MenuBarMessageHandler {
#[remain::sorted] #[remain::sorted]
match message { match message {
SendLayout => self.register_properties(responses, LayoutTarget::MenuBar), SendLayout => self.send_layout(responses, LayoutTarget::MenuBar),
} }
} }
@@ -27,8 +25,8 @@ impl MessageHandler<MenuBarMessage, bool> for MenuBarMessageHandler {
} }
} }
impl PropertyHolder for MenuBarMessageHandler { impl LayoutHolder for MenuBarMessageHandler {
fn properties(&self) -> Layout { fn layout(&self) -> Layout {
let no_active_document = self.no_active_document; let no_active_document = self.no_active_document;
let menu_bar_entries = vec![ let menu_bar_entries = vec![
MenuBarEntry { MenuBarEntry {
@@ -3,8 +3,7 @@ use crate::application::generate_uuid;
use crate::consts::{DEFAULT_DOCUMENT_NAME, GRAPHITE_DOCUMENT_VERSION}; use crate::consts::{DEFAULT_DOCUMENT_NAME, GRAPHITE_DOCUMENT_VERSION};
use crate::messages::dialog::simple_dialogs; use crate::messages::dialog::simple_dialogs;
use crate::messages::frontend::utility_types::FrontendDocumentDetails; use crate::messages::frontend::utility_types::FrontendDocumentDetails;
use crate::messages::layout::utility_types::layout_widget::PropertyHolder; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::portfolio::document::utility_types::clipboards::{Clipboard, CopyBufferEntry, INTERNAL_CLIPBOARD_COUNT}; use crate::messages::portfolio::document::utility_types::clipboards::{Clipboard, CopyBufferEntry, INTERNAL_CLIPBOARD_COUNT};
use crate::messages::prelude::*; use crate::messages::prelude::*;
use crate::messages::tool::utility_types::{HintData, HintGroup}; use crate::messages::tool::utility_types::{HintData, HintGroup};
@@ -138,7 +137,7 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
document_name: target_document.name.clone(), document_name: target_document.name.clone(),
document_id, document_id,
}; };
dialog.register_properties(responses, LayoutTarget::DialogDetails); dialog.send_layout(responses, LayoutTarget::DialogDetails);
responses.add(FrontendMessage::DisplayDialog { icon: "File".to_string() }); responses.add(FrontendMessage::DisplayDialog { icon: "File".to_string() });
// Select the document being closed // Select the document being closed
@@ -1,4 +1,3 @@
use crate::messages::layout::utility_types::layout_widget::WidgetCallback;
use crate::messages::layout::utility_types::widget_prelude::*; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::prelude::Message; use crate::messages::prelude::Message;
@@ -2,7 +2,7 @@
use crate::application::generate_uuid; use crate::application::generate_uuid;
use crate::consts::{COLOR_ACCENT, PIVOT_INNER, PIVOT_OUTER, PIVOT_OUTER_OUTLINE_THICKNESS}; use crate::consts::{COLOR_ACCENT, PIVOT_INNER, PIVOT_OUTER, PIVOT_OUTER_OUTLINE_THICKNESS};
use crate::messages::layout::utility_types::widgets::assist_widgets::PivotPosition; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::prelude::*; use crate::messages::prelude::*;
use document_legacy::layers::style::{self, RenderData}; use document_legacy::layers::style::{self, RenderData};
@@ -2,8 +2,7 @@ use super::common_functionality::overlay_renderer::OverlayRenderer;
use super::common_functionality::shape_editor::ShapeState; use super::common_functionality::shape_editor::ShapeState;
use super::utility_types::{tool_message_to_tool_type, ToolActionHandlerData, ToolFsmState}; use super::utility_types::{tool_message_to_tool_type, ToolActionHandlerData, ToolFsmState};
use crate::application::generate_uuid; use crate::application::generate_uuid;
use crate::messages::layout::utility_types::layout_widget::PropertyHolder; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::portfolio::utility_types::PersistentData; use crate::messages::portfolio::utility_types::PersistentData;
use crate::messages::prelude::*; use crate::messages::prelude::*;
use crate::messages::tool::utility_types::ToolType; use crate::messages::tool::utility_types::ToolType;
@@ -136,7 +135,7 @@ impl MessageHandler<ToolMessage, (&DocumentMessageHandler, u64, &InputPreprocess
responses.add(ToolMessage::RefreshToolOptions); responses.add(ToolMessage::RefreshToolOptions);
// Notify the frontend about the new active tool to be displayed // Notify the frontend about the new active tool to be displayed
tool_data.register_properties(responses, LayoutTarget::ToolShelf); tool_data.send_layout(responses, LayoutTarget::ToolShelf);
} }
ToolMessage::DeactivateTools => { ToolMessage::DeactivateTools => {
let tool_data = &mut self.tool_state.tool_data; let tool_data = &mut self.tool_state.tool_data;
@@ -161,10 +160,10 @@ impl MessageHandler<ToolMessage, (&DocumentMessageHandler, u64, &InputPreprocess
tool_data.tools.get(active_tool).unwrap().activate(responses); tool_data.tools.get(active_tool).unwrap().activate(responses);
// Register initial properties // Register initial properties
tool_data.tools.get(active_tool).unwrap().register_properties(responses, LayoutTarget::ToolOptions); tool_data.tools.get(active_tool).unwrap().send_layout(responses, LayoutTarget::ToolOptions);
// Notify the frontend about the initial active tool // Notify the frontend about the initial active tool
tool_data.register_properties(responses, LayoutTarget::ToolShelf); tool_data.send_layout(responses, LayoutTarget::ToolShelf);
// Notify the frontend about the initial working colors // Notify the frontend about the initial working colors
document_data.update_working_colors(responses); document_data.update_working_colors(responses);
@@ -187,7 +186,7 @@ impl MessageHandler<ToolMessage, (&DocumentMessageHandler, u64, &InputPreprocess
} }
ToolMessage::RefreshToolOptions => { ToolMessage::RefreshToolOptions => {
let tool_data = &mut self.tool_state.tool_data; let tool_data = &mut self.tool_state.tool_data;
tool_data.tools.get(&tool_data.active_tool_type).unwrap().register_properties(responses, LayoutTarget::ToolOptions); tool_data.tools.get(&tool_data.active_tool_type).unwrap().send_layout(responses, LayoutTarget::ToolOptions);
} }
ToolMessage::ResetColors => { ToolMessage::ResetColors => {
let document_data = &mut self.tool_state.document_tool_data; let document_data = &mut self.tool_state.document_tool_data;
@@ -2,7 +2,7 @@ use crate::application::generate_uuid;
use crate::consts::SELECTION_TOLERANCE; use crate::consts::SELECTION_TOLERANCE;
use crate::messages::frontend::utility_types::MouseCursorIcon; use crate::messages::frontend::utility_types::MouseCursorIcon;
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion}; use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion};
use crate::messages::layout::utility_types::layout_widget::PropertyHolder; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::portfolio::document::utility_types::misc::TargetDocument; use crate::messages::portfolio::document::utility_types::misc::TargetDocument;
use crate::messages::prelude::*; use crate::messages::prelude::*;
use crate::messages::tool::common_functionality::snapping::SnapManager; use crate::messages::tool::common_functionality::snapping::SnapManager;
@@ -73,7 +73,11 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for Artboar
); );
} }
impl PropertyHolder for ArtboardTool {} impl LayoutHolder for ArtboardTool {
fn layout(&self) -> Layout {
Layout::WidgetLayout(WidgetLayout::default())
}
}
impl ToolTransition for ArtboardTool { impl ToolTransition for ArtboardTool {
fn event_to_message_map(&self) -> EventToMessageMap { fn event_to_message_map(&self) -> EventToMessageMap {
@@ -1,7 +1,5 @@
use crate::messages::frontend::utility_types::MouseCursorIcon; use crate::messages::frontend::utility_types::MouseCursorIcon;
use crate::messages::input_mapper::utility_types::input_keyboard::MouseMotion; use crate::messages::input_mapper::utility_types::input_keyboard::MouseMotion;
use crate::messages::layout::utility_types::layout_widget::{Layout, LayoutGroup, PropertyHolder, WidgetCallback, WidgetLayout};
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::widget_prelude::*; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::portfolio::document::node_graph::transform_utils::get_current_transform; use crate::messages::portfolio::document::node_graph::transform_utils::get_current_transform;
use crate::messages::prelude::*; use crate::messages::prelude::*;
@@ -141,8 +139,8 @@ impl ToolMetadata for BrushTool {
} }
} }
impl PropertyHolder for BrushTool { impl LayoutHolder for BrushTool {
fn properties(&self) -> Layout { fn layout(&self) -> Layout {
let mut widgets = vec![ let mut widgets = vec![
NumberInput::new(Some(self.options.diameter)) NumberInput::new(Some(self.options.diameter))
.label("Diameter") .label("Diameter")
@@ -236,7 +234,7 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for BrushTo
self.options.diameter = (self.options.diameter / change.abs()).round() * change.abs() + change; self.options.diameter = (self.options.diameter / change.abs()).round() * change.abs() + change;
} }
self.options.diameter = self.options.diameter.max(1.); self.options.diameter = self.options.diameter.max(1.);
self.register_properties(responses, LayoutTarget::ToolOptions); self.send_layout(responses, LayoutTarget::ToolOptions);
} }
BrushToolMessageOptionsUpdate::Diameter(diameter) => self.options.diameter = diameter, BrushToolMessageOptionsUpdate::Diameter(diameter) => self.options.diameter = diameter,
BrushToolMessageOptionsUpdate::DrawMode(draw_mode) => self.options.draw_mode = draw_mode, BrushToolMessageOptionsUpdate::DrawMode(draw_mode) => self.options.draw_mode = draw_mode,
@@ -254,7 +252,7 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for BrushTo
} }
} }
self.register_properties(responses, LayoutTarget::ToolOptions); self.send_layout(responses, LayoutTarget::ToolOptions);
return; return;
} }
@@ -1,7 +1,5 @@
use crate::messages::frontend::utility_types::MouseCursorIcon; use crate::messages::frontend::utility_types::MouseCursorIcon;
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion}; use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion};
use crate::messages::layout::utility_types::layout_widget::{Layout, LayoutGroup, PropertyHolder, WidgetCallback, WidgetLayout};
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::widget_prelude::*; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::prelude::*; use crate::messages::prelude::*;
use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType}; use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType};
@@ -91,8 +89,8 @@ fn create_weight_widget(line_weight: f64) -> WidgetHolder {
.widget_holder() .widget_holder()
} }
impl PropertyHolder for EllipseTool { impl LayoutHolder for EllipseTool {
fn properties(&self) -> Layout { fn layout(&self) -> Layout {
let mut widgets = self.options.fill.create_widgets( let mut widgets = self.options.fill.create_widgets(
"Fill", "Fill",
true, true,
@@ -140,7 +138,7 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for Ellipse
} }
} }
self.register_properties(responses, LayoutTarget::ToolOptions); self.send_layout(responses, LayoutTarget::ToolOptions);
return; return;
} }
@@ -1,6 +1,6 @@
use crate::messages::frontend::utility_types::MouseCursorIcon; use crate::messages::frontend::utility_types::MouseCursorIcon;
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion}; use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion};
use crate::messages::layout::utility_types::layout_widget::PropertyHolder; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::prelude::*; use crate::messages::prelude::*;
use crate::messages::tool::utility_types::{DocumentToolData, EventToMessageMap, Fsm, ToolActionHandlerData, ToolMetadata, ToolTransition, ToolType}; use crate::messages::tool::utility_types::{DocumentToolData, EventToMessageMap, Fsm, ToolActionHandlerData, ToolMetadata, ToolTransition, ToolType};
use crate::messages::tool::utility_types::{HintData, HintGroup, HintInfo}; use crate::messages::tool::utility_types::{HintData, HintGroup, HintInfo};
@@ -41,7 +41,11 @@ impl ToolMetadata for EyedropperTool {
} }
} }
impl PropertyHolder for EyedropperTool {} impl LayoutHolder for EyedropperTool {
fn layout(&self) -> Layout {
Layout::WidgetLayout(WidgetLayout::default())
}
}
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for EyedropperTool { impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for EyedropperTool {
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) { fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
@@ -1,7 +1,7 @@
use crate::consts::SELECTION_TOLERANCE; use crate::consts::SELECTION_TOLERANCE;
use crate::messages::frontend::utility_types::MouseCursorIcon; use crate::messages::frontend::utility_types::MouseCursorIcon;
use crate::messages::input_mapper::utility_types::input_keyboard::MouseMotion; use crate::messages::input_mapper::utility_types::input_keyboard::MouseMotion;
use crate::messages::layout::utility_types::layout_widget::PropertyHolder; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::prelude::*; use crate::messages::prelude::*;
use crate::messages::tool::utility_types::{EventToMessageMap, Fsm, ToolActionHandlerData, ToolMetadata, ToolTransition, ToolType}; use crate::messages::tool::utility_types::{EventToMessageMap, Fsm, ToolActionHandlerData, ToolMetadata, ToolTransition, ToolType};
use crate::messages::tool::utility_types::{HintData, HintGroup, HintInfo}; use crate::messages::tool::utility_types::{HintData, HintGroup, HintInfo};
@@ -44,7 +44,11 @@ impl ToolMetadata for FillTool {
} }
} }
impl PropertyHolder for FillTool {} impl LayoutHolder for FillTool {
fn layout(&self) -> Layout {
Layout::WidgetLayout(WidgetLayout::default())
}
}
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for FillTool { impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for FillTool {
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) { fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
@@ -1,6 +1,6 @@
use crate::messages::frontend::utility_types::MouseCursorIcon; use crate::messages::frontend::utility_types::MouseCursorIcon;
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion}; use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion};
use crate::messages::layout::utility_types::layout_widget::PropertyHolder; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::portfolio::document::node_graph; use crate::messages::portfolio::document::node_graph;
use crate::messages::prelude::*; use crate::messages::prelude::*;
use crate::messages::tool::common_functionality::path_outline::PathOutline; use crate::messages::tool::common_functionality::path_outline::PathOutline;
@@ -40,7 +40,11 @@ pub enum FrameToolMessage {
}, },
} }
impl PropertyHolder for FrameTool {} impl LayoutHolder for FrameTool {
fn layout(&self) -> Layout {
Layout::WidgetLayout(WidgetLayout::default())
}
}
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for FrameTool { impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for FrameTool {
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) { fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
@@ -1,6 +1,5 @@
use crate::messages::frontend::utility_types::MouseCursorIcon; use crate::messages::frontend::utility_types::MouseCursorIcon;
use crate::messages::input_mapper::utility_types::input_keyboard::MouseMotion; use crate::messages::input_mapper::utility_types::input_keyboard::MouseMotion;
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::widget_prelude::*; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::prelude::*; use crate::messages::prelude::*;
use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType}; use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType};
@@ -95,8 +94,8 @@ fn create_weight_widget(line_weight: f64) -> WidgetHolder {
.widget_holder() .widget_holder()
} }
impl PropertyHolder for FreehandTool { impl LayoutHolder for FreehandTool {
fn properties(&self) -> Layout { fn layout(&self) -> Layout {
let mut widgets = self.options.fill.create_widgets( let mut widgets = self.options.fill.create_widgets(
"Fill", "Fill",
true, true,
@@ -144,7 +143,7 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for Freehan
} }
} }
self.register_properties(responses, LayoutTarget::ToolOptions); self.send_layout(responses, LayoutTarget::ToolOptions);
return; return;
} }
@@ -103,8 +103,8 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for Gradien
); );
} }
impl PropertyHolder for GradientTool { impl LayoutHolder for GradientTool {
fn properties(&self) -> Layout { fn layout(&self) -> Layout {
let gradient_type = RadioInput::new(vec![ let gradient_type = RadioInput::new(vec![
RadioEntryData::new("Linear") RadioEntryData::new("Linear")
.value("linear") .value("linear")
@@ -1,6 +1,6 @@
use crate::messages::frontend::utility_types::MouseCursorIcon; use crate::messages::frontend::utility_types::MouseCursorIcon;
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion}; use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion};
use crate::messages::layout::utility_types::layout_widget::PropertyHolder; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::portfolio::document::node_graph::{self, IMAGINATE_NODE}; use crate::messages::portfolio::document::node_graph::{self, IMAGINATE_NODE};
use crate::messages::prelude::*; use crate::messages::prelude::*;
use crate::messages::tool::common_functionality::path_outline::PathOutline; use crate::messages::tool::common_functionality::path_outline::PathOutline;
@@ -40,7 +40,11 @@ pub enum ImaginateToolMessage {
}, },
} }
impl PropertyHolder for ImaginateTool {} impl LayoutHolder for ImaginateTool {
fn layout(&self) -> Layout {
Layout::WidgetLayout(WidgetLayout::default())
}
}
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for ImaginateTool { impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for ImaginateTool {
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) { fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
@@ -2,7 +2,6 @@ use crate::consts::LINE_ROTATE_SNAP_ANGLE;
use crate::messages::frontend::utility_types::MouseCursorIcon; use crate::messages::frontend::utility_types::MouseCursorIcon;
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion}; use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion};
use crate::messages::input_mapper::utility_types::input_mouse::ViewportPosition; use crate::messages::input_mapper::utility_types::input_mouse::ViewportPosition;
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::widget_prelude::*; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::prelude::*; use crate::messages::prelude::*;
use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType}; use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType};
@@ -90,8 +89,8 @@ fn create_weight_widget(line_weight: f64) -> WidgetHolder {
.widget_holder() .widget_holder()
} }
impl PropertyHolder for LineTool { impl LayoutHolder for LineTool {
fn properties(&self) -> Layout { fn layout(&self) -> Layout {
let mut widgets = self.options.stroke.create_widgets( let mut widgets = self.options.stroke.create_widgets(
"Stroke", "Stroke",
true, true,
@@ -122,7 +121,7 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for LineToo
} }
} }
self.register_properties(responses, LayoutTarget::ToolOptions); self.send_layout(responses, LayoutTarget::ToolOptions);
return; return;
} }
@@ -1,6 +1,6 @@
use crate::messages::frontend::utility_types::MouseCursorIcon; use crate::messages::frontend::utility_types::MouseCursorIcon;
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion}; use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion};
use crate::messages::layout::utility_types::layout_widget::PropertyHolder; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::prelude::*; use crate::messages::prelude::*;
use crate::messages::tool::utility_types::{EventToMessageMap, Fsm, ToolActionHandlerData, ToolMetadata, ToolTransition, ToolType}; use crate::messages::tool::utility_types::{EventToMessageMap, Fsm, ToolActionHandlerData, ToolMetadata, ToolTransition, ToolType};
use crate::messages::tool::utility_types::{HintData, HintGroup, HintInfo}; use crate::messages::tool::utility_types::{HintData, HintGroup, HintInfo};
@@ -48,7 +48,11 @@ impl ToolMetadata for NavigateTool {
} }
} }
impl PropertyHolder for NavigateTool {} impl LayoutHolder for NavigateTool {
fn layout(&self) -> Layout {
Layout::WidgetLayout(WidgetLayout::default())
}
}
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for NavigateTool { impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for NavigateTool {
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) { fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
@@ -70,7 +70,11 @@ impl ToolMetadata for PathTool {
} }
} }
impl PropertyHolder for PathTool {} impl LayoutHolder for PathTool {
fn layout(&self) -> Layout {
Layout::WidgetLayout(WidgetLayout::default())
}
}
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for PathTool { impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for PathTool {
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) { fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
@@ -1,7 +1,6 @@
use crate::consts::LINE_ROTATE_SNAP_ANGLE; use crate::consts::LINE_ROTATE_SNAP_ANGLE;
use crate::messages::frontend::utility_types::MouseCursorIcon; use crate::messages::frontend::utility_types::MouseCursorIcon;
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion}; use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion};
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::widget_prelude::*; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::portfolio::document::node_graph::VectorDataModification; use crate::messages::portfolio::document::node_graph::VectorDataModification;
use crate::messages::prelude::*; use crate::messages::prelude::*;
@@ -114,8 +113,8 @@ fn create_weight_widget(line_weight: f64) -> WidgetHolder {
.widget_holder() .widget_holder()
} }
impl PropertyHolder for PenTool { impl LayoutHolder for PenTool {
fn properties(&self) -> Layout { fn layout(&self) -> Layout {
let mut widgets = self.options.fill.create_widgets( let mut widgets = self.options.fill.create_widgets(
"Fill", "Fill",
true, true,
@@ -163,7 +162,7 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for PenTool
} }
} }
self.register_properties(responses, LayoutTarget::ToolOptions); self.send_layout(responses, LayoutTarget::ToolOptions);
return; return;
} }
@@ -1,6 +1,5 @@
use crate::messages::frontend::utility_types::MouseCursorIcon; use crate::messages::frontend::utility_types::MouseCursorIcon;
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion}; use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion};
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::widget_prelude::*; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::prelude::*; use crate::messages::prelude::*;
use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType}; use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType};
@@ -77,8 +76,8 @@ fn create_weight_widget(line_weight: f64) -> WidgetHolder {
.widget_holder() .widget_holder()
} }
impl PropertyHolder for RectangleTool { impl LayoutHolder for RectangleTool {
fn properties(&self) -> Layout { fn layout(&self) -> Layout {
let mut widgets = self.options.fill.create_widgets( let mut widgets = self.options.fill.create_widgets(
"Fill", "Fill",
true, true,
@@ -126,7 +125,7 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for Rectang
} }
} }
self.register_properties(responses, LayoutTarget::ToolOptions); self.send_layout(responses, LayoutTarget::ToolOptions);
return; return;
} }
@@ -4,7 +4,6 @@ use crate::consts::{ROTATE_SNAP_ANGLE, SELECTION_TOLERANCE};
use crate::messages::frontend::utility_types::MouseCursorIcon; use crate::messages::frontend::utility_types::MouseCursorIcon;
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion}; use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion};
use crate::messages::input_mapper::utility_types::input_mouse::ViewportPosition; use crate::messages::input_mapper::utility_types::input_mouse::ViewportPosition;
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::widget_prelude::*; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::portfolio::document::utility_types::misc::{AlignAggregate, AlignAxis, FlipAxis}; use crate::messages::portfolio::document::utility_types::misc::{AlignAggregate, AlignAxis, FlipAxis};
use crate::messages::portfolio::document::utility_types::transformation::Selected; use crate::messages::portfolio::document::utility_types::transformation::Selected;
@@ -112,8 +111,8 @@ impl ToolMetadata for SelectTool {
} }
} }
impl PropertyHolder for SelectTool { impl LayoutHolder for SelectTool {
fn properties(&self) -> Layout { fn layout(&self) -> Layout {
let layer_selection_behavior_entries = [NestedSelectionBehavior::Deepest, NestedSelectionBehavior::Shallowest] let layer_selection_behavior_entries = [NestedSelectionBehavior::Deepest, NestedSelectionBehavior::Shallowest]
.iter() .iter()
.map(|mode| { .map(|mode| {
@@ -259,7 +258,7 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for SelectT
if self.tool_data.pivot.should_refresh_pivot_position() || self.tool_data.selected_layers_changed { if self.tool_data.pivot.should_refresh_pivot_position() || self.tool_data.selected_layers_changed {
// Notify the frontend about the updated pivot position (a bit ugly to do it here not in the fsm but that doesn't have SelectTool) // Notify the frontend about the updated pivot position (a bit ugly to do it here not in the fsm but that doesn't have SelectTool)
self.register_properties(responses, LayoutTarget::ToolOptions); self.send_layout(responses, LayoutTarget::ToolOptions);
self.tool_data.selected_layers_changed = false; self.tool_data.selected_layers_changed = false;
} }
} }
@@ -1,6 +1,5 @@
use crate::messages::frontend::utility_types::MouseCursorIcon; use crate::messages::frontend::utility_types::MouseCursorIcon;
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion}; use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion};
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::widget_prelude::*; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::prelude::*; use crate::messages::prelude::*;
use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType}; use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType};
@@ -99,7 +98,7 @@ fn create_sides_widget(vertices: u32) -> WidgetHolder {
.int() .int()
.min(3.) .min(3.)
.max(1000.) .max(1000.)
.mode(crate::messages::layout::utility_types::widget_prelude::NumberInputMode::Increment) .mode(NumberInputMode::Increment)
.on_update(|number_input: &NumberInput| ShapeToolMessage::UpdateOptions(ShapeOptionsUpdate::Vertices(number_input.value.unwrap() as u32)).into()) .on_update(|number_input: &NumberInput| ShapeToolMessage::UpdateOptions(ShapeOptionsUpdate::Vertices(number_input.value.unwrap() as u32)).into())
.widget_holder() .widget_holder()
} }
@@ -121,8 +120,8 @@ fn create_weight_widget(line_weight: f64) -> WidgetHolder {
.widget_holder() .widget_holder()
} }
impl PropertyHolder for ShapeTool { impl LayoutHolder for ShapeTool {
fn properties(&self) -> Layout { fn layout(&self) -> Layout {
let mut widgets = vec![ let mut widgets = vec![
create_star_option_widget(self.options.primitive_shape_type), create_star_option_widget(self.options.primitive_shape_type),
Separator::new(SeparatorType::Related).widget_holder(), Separator::new(SeparatorType::Related).widget_holder(),
@@ -179,7 +178,7 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for ShapeTo
} }
} }
self.register_properties(responses, LayoutTarget::ToolOptions); self.send_layout(responses, LayoutTarget::ToolOptions);
return; return;
} }
@@ -1,7 +1,6 @@
use crate::consts::DRAG_THRESHOLD; use crate::consts::DRAG_THRESHOLD;
use crate::messages::frontend::utility_types::MouseCursorIcon; use crate::messages::frontend::utility_types::MouseCursorIcon;
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion}; use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion};
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::widget_prelude::*; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::prelude::*; use crate::messages::prelude::*;
use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType}; use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType};
@@ -98,8 +97,8 @@ fn create_weight_widget(line_weight: f64) -> WidgetHolder {
.widget_holder() .widget_holder()
} }
impl PropertyHolder for SplineTool { impl LayoutHolder for SplineTool {
fn properties(&self) -> Layout { fn layout(&self) -> Layout {
let mut widgets = self.options.fill.create_widgets( let mut widgets = self.options.fill.create_widgets(
"Fill", "Fill",
true, true,
@@ -147,7 +146,7 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for SplineT
} }
} }
self.register_properties(responses, LayoutTarget::ToolOptions); self.send_layout(responses, LayoutTarget::ToolOptions);
return; return;
} }
@@ -4,7 +4,6 @@ use crate::application::generate_uuid;
use crate::consts::{COLOR_ACCENT, SELECTION_TOLERANCE}; use crate::consts::{COLOR_ACCENT, SELECTION_TOLERANCE};
use crate::messages::frontend::utility_types::MouseCursorIcon; use crate::messages::frontend::utility_types::MouseCursorIcon;
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion}; use crate::messages::input_mapper::utility_types::input_keyboard::{Key, MouseMotion};
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::widget_prelude::*; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::portfolio::document::node_graph::new_text_network; use crate::messages::portfolio::document::node_graph::new_text_network;
use crate::messages::prelude::*; use crate::messages::prelude::*;
@@ -134,8 +133,8 @@ fn create_text_widgets(tool: &TextTool) -> Vec<WidgetHolder> {
] ]
} }
impl PropertyHolder for TextTool { impl LayoutHolder for TextTool {
fn properties(&self) -> Layout { fn layout(&self) -> Layout {
let mut widgets = create_text_widgets(self); let mut widgets = create_text_widgets(self);
widgets.push(Separator::new(SeparatorType::Section).widget_holder()); widgets.push(Separator::new(SeparatorType::Section).widget_holder());
@@ -160,7 +159,7 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for TextToo
self.options.font_name = family; self.options.font_name = family;
self.options.font_style = style; self.options.font_style = style;
self.register_properties(responses, LayoutTarget::ToolOptions); self.send_layout(responses, LayoutTarget::ToolOptions);
} }
TextOptionsUpdate::FontSize(font_size) => self.options.font_size = font_size, TextOptionsUpdate::FontSize(font_size) => self.options.font_size = font_size,
TextOptionsUpdate::FillColor(color) => { TextOptionsUpdate::FillColor(color) => {
@@ -174,7 +173,7 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for TextToo
} }
} }
self.register_properties(responses, LayoutTarget::ToolOptions); self.send_layout(responses, LayoutTarget::ToolOptions);
return; return;
} }
+4 -5
View File
@@ -7,7 +7,6 @@ use crate::messages::broadcast::BroadcastMessage;
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, KeysGroup, LayoutKeysGroup, MouseMotion}; use crate::messages::input_mapper::utility_types::input_keyboard::{Key, KeysGroup, LayoutKeysGroup, MouseMotion};
use crate::messages::input_mapper::utility_types::macros::action_keys; use crate::messages::input_mapper::utility_types::macros::action_keys;
use crate::messages::input_mapper::utility_types::misc::ActionKeys; use crate::messages::input_mapper::utility_types::misc::ActionKeys;
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::widget_prelude::*; use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::prelude::*; use crate::messages::prelude::*;
use crate::node_graph_executor::NodeGraphExecutor; use crate::node_graph_executor::NodeGraphExecutor;
@@ -52,8 +51,8 @@ impl<'a> ToolActionHandlerData<'a> {
} }
} }
pub trait ToolCommon: for<'a, 'b> MessageHandler<ToolMessage, &'b mut ToolActionHandlerData<'a>> + PropertyHolder + ToolTransition + ToolMetadata {} pub trait ToolCommon: for<'a, 'b> MessageHandler<ToolMessage, &'b mut ToolActionHandlerData<'a>> + LayoutHolder + ToolTransition + ToolMetadata {}
impl<T> ToolCommon for T where T: for<'a, 'b> MessageHandler<ToolMessage, &'b mut ToolActionHandlerData<'a>> + PropertyHolder + ToolTransition + ToolMetadata {} impl<T> ToolCommon for T where T: for<'a, 'b> MessageHandler<ToolMessage, &'b mut ToolActionHandlerData<'a>> + LayoutHolder + ToolTransition + ToolMetadata {}
type Tool = dyn ToolCommon + Send + Sync; type Tool = dyn ToolCommon + Send + Sync;
@@ -241,8 +240,8 @@ impl ToolData {
} }
} }
impl PropertyHolder for ToolData { impl LayoutHolder for ToolData {
fn properties(&self) -> Layout { fn layout(&self) -> Layout {
let tool_groups_layout = list_tools_in_groups() let tool_groups_layout = list_tools_in_groups()
.iter() .iter()
.map(|tool_group| tool_group.iter().map(|tool_availability| { .map(|tool_group| tool_group.iter().map(|tool_availability| {
+1 -1
View File
@@ -40,7 +40,7 @@ fn extract_ident(field: &Field) -> syn::Result<&Ident> {
/// Find the type passed into the builder and the right hand side of the assignment. /// Find the type passed into the builder and the right hand side of the assignment.
/// ///
/// Applies special behaviour for easier String and WidgetCallback assignment. /// Applies special behavior for easier String and WidgetCallback assignment.
fn find_type_and_assignment(field: &Field) -> syn::Result<(TokenStream2, TokenStream2)> { fn find_type_and_assignment(field: &Field) -> syn::Result<(TokenStream2, TokenStream2)> {
let field_ty = &field.ty; let field_ty = &field.ty;
let field_ident = extract_ident(field)?; let field_ident = extract_ident(field)?;