Rename PropertyHolder to LayoutHolder

This commit is contained in:
Keavon Chambers 2023-07-31 23:42:22 -07:00
parent 8e87e42f3e
commit b9e49623a3
51 changed files with 280 additions and 284 deletions

View file

@ -255,7 +255,7 @@ impl Dispatcher {
#[cfg(test)]
mod test {
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::prelude::*;
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.
/// 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() {
use crate::messages::layout::utility_types::layout_widget::{LayoutGroup, Widget};
use crate::messages::layout::utility_types::widgets::label_widgets::TextLabel;
use crate::messages::layout::utility_types::widget_prelude::*;
let print_problem_to_terminal_on_failure = |value: &String| {
println!();

View file

@ -1,6 +1,5 @@
use super::simple_dialogs::{self, AboutGraphiteDialog, ComingSoonDialog};
use crate::messages::layout::utility_types::layout_widget::PropertyHolder;
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::prelude::*;
#[derive(Debug, Default, Clone)]
@ -24,7 +23,7 @@ impl MessageHandler<DialogMessage, (&PortfolioMessageHandler, &PreferencesMessag
DialogMessage::CloseAllDocumentsWithConfirmation => {
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() });
}
DialogMessage::CloseDialogAndThen { followups } => {
@ -35,7 +34,7 @@ impl MessageHandler<DialogMessage, (&PortfolioMessageHandler, &PreferencesMessag
}
DialogMessage::DisplayDialogError { 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() });
}
DialogMessage::RequestAboutGraphiteDialog => {
@ -46,12 +45,12 @@ impl MessageHandler<DialogMessage, (&PortfolioMessageHandler, &PreferencesMessag
DialogMessage::RequestAboutGraphiteDialogWithLocalizedCommitDate { 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() });
}
DialogMessage::RequestComingSoonDialog { 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() });
}
DialogMessage::RequestExportDialog => {
@ -84,7 +83,7 @@ impl MessageHandler<DialogMessage, (&PortfolioMessageHandler, &PreferencesMessag
has_selection: document.selected_layers().next().is_some(),
..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() });
}
}
@ -94,12 +93,12 @@ impl MessageHandler<DialogMessage, (&PortfolioMessageHandler, &PreferencesMessag
infinite: false,
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() });
}
DialogMessage::RequestPreferencesDialog => {
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() });
}
}

View file

@ -1,5 +1,4 @@
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::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;}
}
impl PropertyHolder for ExportDialogMessageHandler {
fn properties(&self) -> Layout {
impl LayoutHolder for ExportDialogMessageHandler {
fn layout(&self) -> Layout {
let file_name = vec![
TextLabel::new("File Name").table_align(true).widget_holder(),
Separator::new(SeparatorType::Unrelated).widget_holder(),

View file

@ -1,6 +1,6 @@
//! 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.
//! Then dialog can be opened by sending the `FrontendMessage::DisplayDialog` message;

View file

@ -1,4 +1,3 @@
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::widget_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;}
}
impl PropertyHolder for NewDocumentDialogMessageHandler {
fn properties(&self) -> Layout {
impl LayoutHolder for NewDocumentDialogMessageHandler {
fn layout(&self) -> Layout {
let title = vec![TextLabel::new("New document").bold(true).widget_holder()];
let name = vec![

View file

@ -1,4 +1,3 @@
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::prelude::*;
@ -12,21 +11,21 @@ impl MessageHandler<PreferencesDialogMessage, &PreferencesMessageHandler> for Pr
PreferencesDialogMessage::Confirm => {}
}
self.register_properties(responses, LayoutTarget::DialogDetails, preferences);
self.send_layout(responses, LayoutTarget::DialogDetails, preferences);
}
advertise_actions! {PreferencesDialogUpdate;}
}
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 {
layout: self.properties(preferences),
layout: self.layout(preferences),
layout_target,
})
}
fn properties(&self, preferences: &PreferencesMessageHandler) -> Layout {
fn layout(&self, preferences: &PreferencesMessageHandler) -> Layout {
let zoom_with_scroll = vec![
TextLabel::new("Input").min_width(60).italic(true).widget_holder(),
TextLabel::new("Zoom with Scroll").table_align(true).widget_holder(),

View file

@ -7,8 +7,8 @@ pub struct AboutGraphiteDialog {
pub localized_commit_date: String,
}
impl PropertyHolder for AboutGraphiteDialog {
fn properties(&self) -> Layout {
impl LayoutHolder for AboutGraphiteDialog {
fn layout(&self) -> Layout {
let links = [
("Website", "https://graphite.rs"),
("Credits", "https://github.com/GraphiteEditor/Graphite/graphs/contributors"),

View file

@ -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.
pub struct CloseAllDocumentsDialog;
impl PropertyHolder for CloseAllDocumentsDialog {
fn properties(&self) -> Layout {
impl LayoutHolder for CloseAllDocumentsDialog {
fn layout(&self) -> Layout {
let discard = TextButton::new("Discard All")
.min_width(96)
.on_update(|_| {

View file

@ -8,8 +8,8 @@ pub struct CloseDocumentDialog {
pub document_id: u64,
}
impl PropertyHolder for CloseDocumentDialog {
fn properties(&self) -> Layout {
impl LayoutHolder for CloseDocumentDialog {
fn layout(&self) -> Layout {
let document_id = self.document_id;
let button_widgets = vec![

View file

@ -8,8 +8,8 @@ pub struct ComingSoonDialog {
pub issue: Option<i32>,
}
impl PropertyHolder for ComingSoonDialog {
fn properties(&self) -> Layout {
impl LayoutHolder for ComingSoonDialog {
fn layout(&self) -> Layout {
let mut details = "This feature is not implemented yet".to_string();
let mut buttons = vec![TextButton::new("OK")

View file

@ -7,8 +7,8 @@ pub struct ErrorDialog {
pub description: String,
}
impl PropertyHolder for ErrorDialog {
fn properties(&self) -> Layout {
impl LayoutHolder for ErrorDialog {
fn layout(&self) -> Layout {
Layout::WidgetLayout(WidgetLayout::new(vec![
LayoutGroup::Row {
widgets: vec![TextLabel::new(&self.title).bold(true).widget_holder()],

View file

@ -1,7 +1,5 @@
use super::utility_types::{FrontendDocumentDetails, FrontendImageData, MouseCursorIcon};
use crate::messages::layout::utility_types::layout_widget::WidgetDiff;
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::widgets::menu_widgets::MenuBarEntry;
use crate::messages::layout::utility_types::widget_prelude::*;
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::prelude::*;

View file

@ -1,5 +1,4 @@
use super::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::layout_widget::Layout;
use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::prelude::*;
use serde::{Deserialize, Serialize};

View file

@ -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::layout::utility_types::layout_widget::{DiffUpdate, Widget};
use crate::messages::layout::utility_types::layout_widget::{Layout, WidgetLayout};
use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::prelude::*;
use document_legacy::LayerId;
@ -68,7 +65,7 @@ impl<F: Fn(&MessageDiscriminant) -> Vec<KeysGroup>> MessageHandler<LayoutMessage
// Resend that diff
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 } => {
// Look up the layout
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 {
/// 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.
if matches!(new_layout, Layout::MenuLayout(_)) {
// Skip update if the same

View file

@ -6,129 +6,61 @@ use super::widgets::menu_widgets::MenuLayout;
use crate::application::generate_uuid;
use crate::messages::input_mapper::utility_types::input_keyboard::KeysGroup;
use crate::messages::input_mapper::utility_types::misc::ActionKeys;
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::prelude::*;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
pub trait PropertyHolder {
fn properties(&self) -> Layout {
Layout::WidgetLayout(WidgetLayout::default())
}
#[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,
fn register_properties(&self, responses: &mut VecDeque<Message>, layout_target: LayoutTarget) {
responses.add(LayoutMessage::SendLayout {
layout: self.properties(),
layout_target,
})
// KEEP THIS ENUM LAST
// This is a marker that is used to define an array that is used to hold widgets
#[remain::unsorted]
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)]
pub enum Layout {
WidgetLayout(WidgetLayout),
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 {
pub fn unwrap_menu_layout(self, action_input_mapping: &impl Fn(&MessageDiscriminant) -> Vec<KeysGroup>) -> MenuLayout {
if let Self::MenuLayout(mut menu) = self {
@ -517,3 +449,101 @@ pub enum Widget {
TextInput(TextInput),
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),
}
}
}

View file

@ -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,
}

View file

@ -1,5 +1,4 @@
pub mod layout_widget;
pub mod misc;
pub mod widgets;
pub mod widget_prelude {

View file

@ -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 derivative::*;

View file

@ -1,6 +1,5 @@
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::SubLayout;
use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::portfolio::document::node_graph::FrontendGraphDataType;
use graphite_proc_macros::WidgetBuilder;

View file

@ -1,5 +1,5 @@
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::LayerId;

View file

@ -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::FileType;
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::portfolio::document::properties_panel::utility_types::PropertiesPanelMessageHandlerData;
use crate::messages::portfolio::document::utility_types::clipboards::Clipboard;

View file

@ -160,7 +160,7 @@ impl NodeGraphMessageHandler {
fn send_node_bar_layout(&self, responses: &mut VecDeque<Message>) {
responses.add(LayoutMessage::SendLayout {
layout: Layout::WidgetLayout(WidgetLayout::new(self.widgets.to_vec())),
layout_target: crate::messages::layout::utility_types::misc::LayoutTarget::NodeGraphBar,
layout_target: LayoutTarget::NodeGraphBar,
});
}

View file

@ -1,6 +1,6 @@
use super::{node_properties, FrontendGraphDataType, FrontendNodeType};
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 graph_craft::concrete;

View file

@ -1,5 +1,5 @@
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::prelude::*;

View file

@ -1,7 +1,6 @@
use super::utility_functions::{register_artboard_layer_properties, register_artwork_layer_properties, register_document_graph_properties};
use super::utility_types::PropertiesPanelMessageHandlerData;
use crate::messages::layout::utility_types::layout_widget::{Layout, WidgetLayout};
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::widget_prelude::*;
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::utility_types::PersistentData;

View file

@ -1,6 +1,5 @@
use super::utility_types::TransformOp;
use crate::application::generate_uuid;
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::portfolio::document::node_graph::NodePropertiesContext;
use crate::messages::portfolio::utility_types::PersistentData;

View file

@ -1,7 +1,5 @@
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::misc::LayoutTarget;
use crate::messages::layout::utility_types::widgets::menu_widgets::{MenuBarEntry, MenuBarEntryChildren, MenuLayout};
use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::portfolio::document::utility_types::clipboards::Clipboard;
use crate::messages::prelude::*;
@ -18,7 +16,7 @@ impl MessageHandler<MenuBarMessage, bool> for MenuBarMessageHandler {
#[remain::sorted]
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 {
fn properties(&self) -> Layout {
impl LayoutHolder for MenuBarMessageHandler {
fn layout(&self) -> Layout {
let no_active_document = self.no_active_document;
let menu_bar_entries = vec![
MenuBarEntry {

View file

@ -3,8 +3,7 @@ use crate::application::generate_uuid;
use crate::consts::{DEFAULT_DOCUMENT_NAME, GRAPHITE_DOCUMENT_VERSION};
use crate::messages::dialog::simple_dialogs;
use crate::messages::frontend::utility_types::FrontendDocumentDetails;
use crate::messages::layout::utility_types::layout_widget::PropertyHolder;
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::portfolio::document::utility_types::clipboards::{Clipboard, CopyBufferEntry, INTERNAL_CLIPBOARD_COUNT};
use crate::messages::prelude::*;
use crate::messages::tool::utility_types::{HintData, HintGroup};
@ -138,7 +137,7 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
document_name: target_document.name.clone(),
document_id,
};
dialog.register_properties(responses, LayoutTarget::DialogDetails);
dialog.send_layout(responses, LayoutTarget::DialogDetails);
responses.add(FrontendMessage::DisplayDialog { icon: "File".to_string() });
// Select the document being closed

View file

@ -1,4 +1,3 @@
use crate::messages::layout::utility_types::layout_widget::WidgetCallback;
use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::prelude::Message;

View file

@ -2,7 +2,7 @@
use crate::application::generate_uuid;
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 document_legacy::layers::style::{self, RenderData};

View file

@ -2,8 +2,7 @@ use super::common_functionality::overlay_renderer::OverlayRenderer;
use super::common_functionality::shape_editor::ShapeState;
use super::utility_types::{tool_message_to_tool_type, ToolActionHandlerData, ToolFsmState};
use crate::application::generate_uuid;
use crate::messages::layout::utility_types::layout_widget::PropertyHolder;
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::portfolio::utility_types::PersistentData;
use crate::messages::prelude::*;
use crate::messages::tool::utility_types::ToolType;
@ -136,7 +135,7 @@ impl MessageHandler<ToolMessage, (&DocumentMessageHandler, u64, &InputPreprocess
responses.add(ToolMessage::RefreshToolOptions);
// 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 => {
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);
// 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
tool_data.register_properties(responses, LayoutTarget::ToolShelf);
tool_data.send_layout(responses, LayoutTarget::ToolShelf);
// Notify the frontend about the initial working colors
document_data.update_working_colors(responses);
@ -187,7 +186,7 @@ impl MessageHandler<ToolMessage, (&DocumentMessageHandler, u64, &InputPreprocess
}
ToolMessage::RefreshToolOptions => {
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 => {
let document_data = &mut self.tool_state.document_tool_data;

View file

@ -2,7 +2,7 @@ use crate::application::generate_uuid;
use crate::consts::SELECTION_TOLERANCE;
use crate::messages::frontend::utility_types::MouseCursorIcon;
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::prelude::*;
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 {
fn event_to_message_map(&self) -> EventToMessageMap {

View file

@ -1,7 +1,5 @@
use crate::messages::frontend::utility_types::MouseCursorIcon;
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::portfolio::document::node_graph::transform_utils::get_current_transform;
use crate::messages::prelude::*;
@ -141,8 +139,8 @@ impl ToolMetadata for BrushTool {
}
}
impl PropertyHolder for BrushTool {
fn properties(&self) -> Layout {
impl LayoutHolder for BrushTool {
fn layout(&self) -> Layout {
let mut widgets = vec![
NumberInput::new(Some(self.options.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.max(1.);
self.register_properties(responses, LayoutTarget::ToolOptions);
self.send_layout(responses, LayoutTarget::ToolOptions);
}
BrushToolMessageOptionsUpdate::Diameter(diameter) => self.options.diameter = diameter,
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;
}

View file

@ -1,7 +1,5 @@
use crate::messages::frontend::utility_types::MouseCursorIcon;
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::prelude::*;
use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType};
@ -91,8 +89,8 @@ fn create_weight_widget(line_weight: f64) -> WidgetHolder {
.widget_holder()
}
impl PropertyHolder for EllipseTool {
fn properties(&self) -> Layout {
impl LayoutHolder for EllipseTool {
fn layout(&self) -> Layout {
let mut widgets = self.options.fill.create_widgets(
"Fill",
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;
}

View file

@ -1,6 +1,6 @@
use crate::messages::frontend::utility_types::MouseCursorIcon;
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::tool::utility_types::{DocumentToolData, EventToMessageMap, Fsm, ToolActionHandlerData, ToolMetadata, ToolTransition, ToolType};
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 {
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {

View file

@ -1,7 +1,7 @@
use crate::consts::SELECTION_TOLERANCE;
use crate::messages::frontend::utility_types::MouseCursorIcon;
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::tool::utility_types::{EventToMessageMap, Fsm, ToolActionHandlerData, ToolMetadata, ToolTransition, ToolType};
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 {
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {

View file

@ -1,6 +1,6 @@
use crate::messages::frontend::utility_types::MouseCursorIcon;
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::prelude::*;
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 {
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {

View file

@ -1,6 +1,5 @@
use crate::messages::frontend::utility_types::MouseCursorIcon;
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::prelude::*;
use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType};
@ -95,8 +94,8 @@ fn create_weight_widget(line_weight: f64) -> WidgetHolder {
.widget_holder()
}
impl PropertyHolder for FreehandTool {
fn properties(&self) -> Layout {
impl LayoutHolder for FreehandTool {
fn layout(&self) -> Layout {
let mut widgets = self.options.fill.create_widgets(
"Fill",
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;
}

View file

@ -103,8 +103,8 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for Gradien
);
}
impl PropertyHolder for GradientTool {
fn properties(&self) -> Layout {
impl LayoutHolder for GradientTool {
fn layout(&self) -> Layout {
let gradient_type = RadioInput::new(vec![
RadioEntryData::new("Linear")
.value("linear")

View file

@ -1,6 +1,6 @@
use crate::messages::frontend::utility_types::MouseCursorIcon;
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::prelude::*;
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 {
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {

View file

@ -2,7 +2,6 @@ use crate::consts::LINE_ROTATE_SNAP_ANGLE;
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_mouse::ViewportPosition;
use crate::messages::layout::utility_types::misc::LayoutTarget;
use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::prelude::*;
use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType};
@ -90,8 +89,8 @@ fn create_weight_widget(line_weight: f64) -> WidgetHolder {
.widget_holder()
}
impl PropertyHolder for LineTool {
fn properties(&self) -> Layout {
impl LayoutHolder for LineTool {
fn layout(&self) -> Layout {
let mut widgets = self.options.stroke.create_widgets(
"Stroke",
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;
}

View file

@ -1,6 +1,6 @@
use crate::messages::frontend::utility_types::MouseCursorIcon;
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::tool::utility_types::{EventToMessageMap, Fsm, ToolActionHandlerData, ToolMetadata, ToolTransition, ToolType};
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 {
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {

View file

@ -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 {
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {

View file

@ -1,7 +1,6 @@
use crate::consts::LINE_ROTATE_SNAP_ANGLE;
use crate::messages::frontend::utility_types::MouseCursorIcon;
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::portfolio::document::node_graph::VectorDataModification;
use crate::messages::prelude::*;
@ -114,8 +113,8 @@ fn create_weight_widget(line_weight: f64) -> WidgetHolder {
.widget_holder()
}
impl PropertyHolder for PenTool {
fn properties(&self) -> Layout {
impl LayoutHolder for PenTool {
fn layout(&self) -> Layout {
let mut widgets = self.options.fill.create_widgets(
"Fill",
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;
}

View file

@ -1,6 +1,5 @@
use crate::messages::frontend::utility_types::MouseCursorIcon;
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::prelude::*;
use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType};
@ -77,8 +76,8 @@ fn create_weight_widget(line_weight: f64) -> WidgetHolder {
.widget_holder()
}
impl PropertyHolder for RectangleTool {
fn properties(&self) -> Layout {
impl LayoutHolder for RectangleTool {
fn layout(&self) -> Layout {
let mut widgets = self.options.fill.create_widgets(
"Fill",
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;
}

View file

@ -4,7 +4,6 @@ use crate::consts::{ROTATE_SNAP_ANGLE, SELECTION_TOLERANCE};
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_mouse::ViewportPosition;
use crate::messages::layout::utility_types::misc::LayoutTarget;
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::transformation::Selected;
@ -112,8 +111,8 @@ impl ToolMetadata for SelectTool {
}
}
impl PropertyHolder for SelectTool {
fn properties(&self) -> Layout {
impl LayoutHolder for SelectTool {
fn layout(&self) -> Layout {
let layer_selection_behavior_entries = [NestedSelectionBehavior::Deepest, NestedSelectionBehavior::Shallowest]
.iter()
.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 {
// 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;
}
}

View file

@ -1,6 +1,5 @@
use crate::messages::frontend::utility_types::MouseCursorIcon;
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::prelude::*;
use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType};
@ -99,7 +98,7 @@ fn create_sides_widget(vertices: u32) -> WidgetHolder {
.int()
.min(3.)
.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())
.widget_holder()
}
@ -121,8 +120,8 @@ fn create_weight_widget(line_weight: f64) -> WidgetHolder {
.widget_holder()
}
impl PropertyHolder for ShapeTool {
fn properties(&self) -> Layout {
impl LayoutHolder for ShapeTool {
fn layout(&self) -> Layout {
let mut widgets = vec![
create_star_option_widget(self.options.primitive_shape_type),
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;
}

View file

@ -1,7 +1,6 @@
use crate::consts::DRAG_THRESHOLD;
use crate::messages::frontend::utility_types::MouseCursorIcon;
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::prelude::*;
use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType};
@ -98,8 +97,8 @@ fn create_weight_widget(line_weight: f64) -> WidgetHolder {
.widget_holder()
}
impl PropertyHolder for SplineTool {
fn properties(&self) -> Layout {
impl LayoutHolder for SplineTool {
fn layout(&self) -> Layout {
let mut widgets = self.options.fill.create_widgets(
"Fill",
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;
}

View file

@ -4,7 +4,6 @@ use crate::application::generate_uuid;
use crate::consts::{COLOR_ACCENT, SELECTION_TOLERANCE};
use crate::messages::frontend::utility_types::MouseCursorIcon;
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::portfolio::document::node_graph::new_text_network;
use crate::messages::prelude::*;
@ -134,8 +133,8 @@ fn create_text_widgets(tool: &TextTool) -> Vec<WidgetHolder> {
]
}
impl PropertyHolder for TextTool {
fn properties(&self) -> Layout {
impl LayoutHolder for TextTool {
fn layout(&self) -> Layout {
let mut widgets = create_text_widgets(self);
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_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::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;
}

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::macros::action_keys;
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::prelude::*;
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 {}
impl<T> ToolCommon for T where T: 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>> + LayoutHolder + ToolTransition + ToolMetadata {}
type Tool = dyn ToolCommon + Send + Sync;
@ -241,8 +240,8 @@ impl ToolData {
}
}
impl PropertyHolder for ToolData {
fn properties(&self) -> Layout {
impl LayoutHolder for ToolData {
fn layout(&self) -> Layout {
let tool_groups_layout = list_tools_in_groups()
.iter()
.map(|tool_group| tool_group.iter().map(|tool_availability| {

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.
///
/// 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)> {
let field_ty = &field.ty;
let field_ident = extract_ident(field)?;