mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-30 21:08:12 +08:00
Refactor the WidgetLayout struct to remove SubLayout and avoid sending LayoutTarget to frontend
This commit is contained in:
@@ -120,7 +120,7 @@ pub(super) fn intercept_frontend_message(dispatcher: &mut DesktopWrapperMessageD
|
|||||||
[
|
[
|
||||||
WidgetDiff {
|
WidgetDiff {
|
||||||
widget_path,
|
widget_path,
|
||||||
new_value: DiffUpdate::SubLayout(layout),
|
new_value: DiffUpdate::WidgetLayout(layout),
|
||||||
},
|
},
|
||||||
] if widget_path.is_empty() => {
|
] if widget_path.is_empty() => {
|
||||||
let entries = crate::utils::menu::convert_menu_bar_layout_to_menu_items(layout);
|
let entries = crate::utils::menu::convert_menu_bar_layout_to_menu_items(layout);
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ pub(crate) mod menu {
|
|||||||
use graphite_editor::messages::input_mapper::utility_types::input_keyboard::{Key, LabeledKey, LabeledShortcut};
|
use graphite_editor::messages::input_mapper::utility_types::input_keyboard::{Key, LabeledKey, LabeledShortcut};
|
||||||
use graphite_editor::messages::input_mapper::utility_types::misc::ActionShortcut;
|
use graphite_editor::messages::input_mapper::utility_types::misc::ActionShortcut;
|
||||||
use graphite_editor::messages::layout::LayoutMessage;
|
use graphite_editor::messages::layout::LayoutMessage;
|
||||||
use graphite_editor::messages::tool::tool_messages::tool_prelude::{LayoutGroup, LayoutTarget, MenuListEntry, SubLayout, Widget, WidgetId};
|
use graphite_editor::messages::tool::tool_messages::tool_prelude::{LayoutGroup, LayoutTarget, MenuListEntry, Widget, WidgetId, WidgetLayout};
|
||||||
|
|
||||||
use crate::messages::{EditorMessage, KeyCode, MenuItem, Modifiers, Shortcut};
|
use crate::messages::{EditorMessage, KeyCode, MenuItem, Modifiers, Shortcut};
|
||||||
|
|
||||||
pub(crate) fn convert_menu_bar_layout_to_menu_items(layout: &SubLayout) -> Vec<MenuItem> {
|
pub(crate) fn convert_menu_bar_layout_to_menu_items(layout: &WidgetLayout) -> Vec<MenuItem> {
|
||||||
let layout_group = match layout.as_slice() {
|
let layout_group = match layout.as_slice() {
|
||||||
[layout_group] => layout_group,
|
[layout_group] => layout_group,
|
||||||
_ => panic!("Menu bar layout is supposed to have exactly one layout group"),
|
_ => panic!("Menu bar layout is supposed to have exactly one layout group"),
|
||||||
|
|||||||
@@ -547,9 +547,9 @@ mod test {
|
|||||||
|
|
||||||
for response in responses {
|
for response in responses {
|
||||||
// Check for the existence of the file format incompatibility warning dialog after opening the test file
|
// Check for the existence of the file format incompatibility warning dialog after opening the test file
|
||||||
if let FrontendMessage::UpdateDialogColumn1 { layout_target: _, diff } = response {
|
if let FrontendMessage::UpdateDialogColumn1 { diff } = response {
|
||||||
if let DiffUpdate::SubLayout(sub_layout) = &diff[0].new_value {
|
if let DiffUpdate::WidgetLayout(sub_layout) = &diff[0].new_value {
|
||||||
if let LayoutGroup::Row { widgets } = &sub_layout[0] {
|
if let LayoutGroup::Row { widgets } = &sub_layout.0[0] {
|
||||||
if let Widget::TextLabel(TextLabel { value, .. }) = &widgets[0].widget {
|
if let Widget::TextLabel(TextLabel { value, .. }) = &widgets[0].widget {
|
||||||
print_problem_to_terminal_on_failure(value);
|
print_problem_to_terminal_on_failure(value);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ impl DialogLayoutHolder for ExportDialogMessageHandler {
|
|||||||
TextButton::new("Cancel").on_update(|_| FrontendMessage::DisplayDialogDismiss.into()).widget_instance(),
|
TextButton::new("Cancel").on_update(|_| FrontendMessage::DisplayDialogDismiss.into()).widget_instance(),
|
||||||
];
|
];
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Row { widgets }]))
|
Layout::WidgetLayout(WidgetLayout(vec![LayoutGroup::Row { widgets }]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,7 +160,7 @@ impl LayoutHolder for ExportDialogMessageHandler {
|
|||||||
.widget_instance(),
|
.widget_instance(),
|
||||||
];
|
];
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![
|
Layout::WidgetLayout(WidgetLayout(vec![
|
||||||
LayoutGroup::Row { widgets: export_type },
|
LayoutGroup::Row { widgets: export_type },
|
||||||
LayoutGroup::Row { widgets: resolution },
|
LayoutGroup::Row { widgets: resolution },
|
||||||
LayoutGroup::Row { widgets: export_area },
|
LayoutGroup::Row { widgets: export_area },
|
||||||
|
|||||||
+2
-2
@@ -66,7 +66,7 @@ impl DialogLayoutHolder for NewDocumentDialogMessageHandler {
|
|||||||
TextButton::new("Cancel").on_update(|_| FrontendMessage::DisplayDialogDismiss.into()).widget_instance(),
|
TextButton::new("Cancel").on_update(|_| FrontendMessage::DisplayDialogDismiss.into()).widget_instance(),
|
||||||
];
|
];
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Row { widgets }]))
|
Layout::WidgetLayout(WidgetLayout(vec![LayoutGroup::Row { widgets }]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ impl LayoutHolder for NewDocumentDialogMessageHandler {
|
|||||||
.widget_instance(),
|
.widget_instance(),
|
||||||
];
|
];
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![
|
Layout::WidgetLayout(WidgetLayout(vec![
|
||||||
LayoutGroup::Row { widgets: name },
|
LayoutGroup::Row { widgets: name },
|
||||||
LayoutGroup::Row { widgets: infinite },
|
LayoutGroup::Row { widgets: infinite },
|
||||||
LayoutGroup::Row { widgets: scale },
|
LayoutGroup::Row { widgets: scale },
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ impl PreferencesDialogMessageHandler {
|
|||||||
.widget_instance(),
|
.widget_instance(),
|
||||||
];
|
];
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![
|
Layout::WidgetLayout(WidgetLayout(vec![
|
||||||
LayoutGroup::Row { widgets: navigation_header },
|
LayoutGroup::Row { widgets: navigation_header },
|
||||||
LayoutGroup::Row { widgets: zoom_rate_label },
|
LayoutGroup::Row { widgets: zoom_rate_label },
|
||||||
LayoutGroup::Row { widgets: zoom_rate },
|
LayoutGroup::Row { widgets: zoom_rate },
|
||||||
@@ -272,7 +272,7 @@ impl PreferencesDialogMessageHandler {
|
|||||||
TextButton::new("Reset to Defaults").on_update(|_| PreferencesMessage::ResetToDefaults.into()).widget_instance(),
|
TextButton::new("Reset to Defaults").on_update(|_| PreferencesMessage::ResetToDefaults.into()).widget_instance(),
|
||||||
];
|
];
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Row { widgets }]))
|
Layout::WidgetLayout(WidgetLayout(vec![LayoutGroup::Row { widgets }]))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_layout_buttons(&self, responses: &mut VecDeque<Message>, layout_target: LayoutTarget) {
|
fn send_layout_buttons(&self, responses: &mut VecDeque<Message>, layout_target: LayoutTarget) {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ impl DialogLayoutHolder for AboutGraphiteDialog {
|
|||||||
fn layout_buttons(&self) -> Layout {
|
fn layout_buttons(&self) -> Layout {
|
||||||
let widgets = vec![TextButton::new("OK").emphasized(true).on_update(|_| FrontendMessage::DisplayDialogDismiss.into()).widget_instance()];
|
let widgets = vec![TextButton::new("OK").emphasized(true).on_update(|_| FrontendMessage::DisplayDialogDismiss.into()).widget_instance()];
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Row { widgets }]))
|
Layout::WidgetLayout(WidgetLayout(vec![LayoutGroup::Row { widgets }]))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layout_column_2(&self) -> Layout {
|
fn layout_column_2(&self) -> Layout {
|
||||||
@@ -51,13 +51,13 @@ impl DialogLayoutHolder for AboutGraphiteDialog {
|
|||||||
.widget_instance(),
|
.widget_instance(),
|
||||||
);
|
);
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Column { widgets }]))
|
Layout::WidgetLayout(WidgetLayout(vec![LayoutGroup::Column { widgets }]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LayoutHolder for AboutGraphiteDialog {
|
impl LayoutHolder for AboutGraphiteDialog {
|
||||||
fn layout(&self) -> Layout {
|
fn layout(&self) -> Layout {
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![
|
Layout::WidgetLayout(WidgetLayout(vec![
|
||||||
LayoutGroup::Row {
|
LayoutGroup::Row {
|
||||||
widgets: vec![TextLabel::new("About this release").bold(true).widget_instance()],
|
widgets: vec![TextLabel::new("About this release").bold(true).widget_instance()],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ impl DialogLayoutHolder for CloseAllDocumentsDialog {
|
|||||||
TextButton::new("Cancel").on_update(|_| FrontendMessage::DisplayDialogDismiss.into()).widget_instance(),
|
TextButton::new("Cancel").on_update(|_| FrontendMessage::DisplayDialogDismiss.into()).widget_instance(),
|
||||||
];
|
];
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Row { widgets }]))
|
Layout::WidgetLayout(WidgetLayout(vec![LayoutGroup::Row { widgets }]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ impl LayoutHolder for CloseAllDocumentsDialog {
|
|||||||
fn layout(&self) -> Layout {
|
fn layout(&self) -> Layout {
|
||||||
let unsaved_list = "• ".to_string() + &self.unsaved_document_names.join("\n• ");
|
let unsaved_list = "• ".to_string() + &self.unsaved_document_names.join("\n• ");
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![
|
Layout::WidgetLayout(WidgetLayout(vec![
|
||||||
LayoutGroup::Row {
|
LayoutGroup::Row {
|
||||||
widgets: vec![TextLabel::new("Save documents before closing them?").bold(true).multiline(true).widget_instance()],
|
widgets: vec![TextLabel::new("Save documents before closing them?").bold(true).multiline(true).widget_instance()],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ impl DialogLayoutHolder for CloseDocumentDialog {
|
|||||||
TextButton::new("Cancel").on_update(|_| FrontendMessage::DisplayDialogDismiss.into()).widget_instance(),
|
TextButton::new("Cancel").on_update(|_| FrontendMessage::DisplayDialogDismiss.into()).widget_instance(),
|
||||||
];
|
];
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Row { widgets }]))
|
Layout::WidgetLayout(WidgetLayout(vec![LayoutGroup::Row { widgets }]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ impl LayoutHolder for CloseDocumentDialog {
|
|||||||
|
|
||||||
let break_lines = if self.document_name.len() > max_one_line_length { '\n' } else { ' ' };
|
let break_lines = if self.document_name.len() > max_one_line_length { '\n' } else { ' ' };
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![
|
Layout::WidgetLayout(WidgetLayout(vec![
|
||||||
LayoutGroup::Row {
|
LayoutGroup::Row {
|
||||||
widgets: vec![TextLabel::new("Save document before closing it?").bold(true).widget_instance()],
|
widgets: vec![TextLabel::new("Save document before closing it?").bold(true).widget_instance()],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ impl DialogLayoutHolder for ComingSoonDialog {
|
|||||||
fn layout_buttons(&self) -> Layout {
|
fn layout_buttons(&self) -> Layout {
|
||||||
let widgets = vec![TextButton::new("OK").emphasized(true).on_update(|_| FrontendMessage::DisplayDialogDismiss.into()).widget_instance()];
|
let widgets = vec![TextButton::new("OK").emphasized(true).on_update(|_| FrontendMessage::DisplayDialogDismiss.into()).widget_instance()];
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Row { widgets }]))
|
Layout::WidgetLayout(WidgetLayout(vec![LayoutGroup::Row { widgets }]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,6 +43,6 @@ impl LayoutHolder for ComingSoonDialog {
|
|||||||
rows.push(LayoutGroup::Row { widgets: row3 });
|
rows.push(LayoutGroup::Row { widgets: row3 });
|
||||||
}
|
}
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(rows))
|
Layout::WidgetLayout(WidgetLayout(rows))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ impl DialogLayoutHolder for DemoArtworkDialog {
|
|||||||
fn layout_buttons(&self) -> Layout {
|
fn layout_buttons(&self) -> Layout {
|
||||||
let widgets = vec![TextButton::new("Close").emphasized(true).on_update(|_| FrontendMessage::DisplayDialogDismiss.into()).widget_instance()];
|
let widgets = vec![TextButton::new("Close").emphasized(true).on_update(|_| FrontendMessage::DisplayDialogDismiss.into()).widget_instance()];
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Row { widgets }]))
|
Layout::WidgetLayout(WidgetLayout(vec![LayoutGroup::Row { widgets }]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,6 +59,6 @@ impl LayoutHolder for DemoArtworkDialog {
|
|||||||
.collect();
|
.collect();
|
||||||
let _ = rows_of_images_with_buttons.pop();
|
let _ = rows_of_images_with_buttons.pop();
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(rows_of_images_with_buttons))
|
Layout::WidgetLayout(WidgetLayout(rows_of_images_with_buttons))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,13 +14,13 @@ impl DialogLayoutHolder for ErrorDialog {
|
|||||||
fn layout_buttons(&self) -> Layout {
|
fn layout_buttons(&self) -> Layout {
|
||||||
let widgets = vec![TextButton::new("OK").emphasized(true).on_update(|_| FrontendMessage::DisplayDialogDismiss.into()).widget_instance()];
|
let widgets = vec![TextButton::new("OK").emphasized(true).on_update(|_| FrontendMessage::DisplayDialogDismiss.into()).widget_instance()];
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Row { widgets }]))
|
Layout::WidgetLayout(WidgetLayout(vec![LayoutGroup::Row { widgets }]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LayoutHolder for ErrorDialog {
|
impl LayoutHolder for ErrorDialog {
|
||||||
fn layout(&self) -> Layout {
|
fn layout(&self) -> Layout {
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![
|
Layout::WidgetLayout(WidgetLayout(vec![
|
||||||
LayoutGroup::Row {
|
LayoutGroup::Row {
|
||||||
widgets: vec![TextLabel::new(&self.title).bold(true).widget_instance()],
|
widgets: vec![TextLabel::new(&self.title).bold(true).widget_instance()],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ impl DialogLayoutHolder for LicensesDialog {
|
|||||||
fn layout_buttons(&self) -> Layout {
|
fn layout_buttons(&self) -> Layout {
|
||||||
let widgets = vec![TextButton::new("OK").emphasized(true).on_update(|_| FrontendMessage::DisplayDialogDismiss.into()).widget_instance()];
|
let widgets = vec![TextButton::new("OK").emphasized(true).on_update(|_| FrontendMessage::DisplayDialogDismiss.into()).widget_instance()];
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Row { widgets }]))
|
Layout::WidgetLayout(WidgetLayout(vec![LayoutGroup::Row { widgets }]))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layout_column_2(&self) -> Layout {
|
fn layout_column_2(&self) -> Layout {
|
||||||
@@ -43,7 +43,7 @@ impl DialogLayoutHolder for LicensesDialog {
|
|||||||
.map(|&(icon, label, message_factory)| TextButton::new(label).icon(Some((icon).into())).flush(true).on_update(move |_| message_factory()).widget_instance())
|
.map(|&(icon, label, message_factory)| TextButton::new(label).icon(Some((icon).into())).flush(true).on_update(move |_| message_factory()).widget_instance())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Column { widgets }]))
|
Layout::WidgetLayout(WidgetLayout(vec![LayoutGroup::Column { widgets }]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ impl LayoutHolder for LicensesDialog {
|
|||||||
);
|
);
|
||||||
let description = description.trim();
|
let description = description.trim();
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![
|
Layout::WidgetLayout(WidgetLayout(vec![
|
||||||
LayoutGroup::Row {
|
LayoutGroup::Row {
|
||||||
widgets: vec![TextLabel::new("Graphite is free, open source software").bold(true).widget_instance()],
|
widgets: vec![TextLabel::new("Graphite is free, open source software").bold(true).widget_instance()],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ impl DialogLayoutHolder for LicensesThirdPartyDialog {
|
|||||||
fn layout_buttons(&self) -> Layout {
|
fn layout_buttons(&self) -> Layout {
|
||||||
let widgets = vec![TextButton::new("OK").emphasized(true).on_update(|_| FrontendMessage::DisplayDialogDismiss.into()).widget_instance()];
|
let widgets = vec![TextButton::new("OK").emphasized(true).on_update(|_| FrontendMessage::DisplayDialogDismiss.into()).widget_instance()];
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Row { widgets }]))
|
Layout::WidgetLayout(WidgetLayout(vec![LayoutGroup::Row { widgets }]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ impl LayoutHolder for LicensesThirdPartyDialog {
|
|||||||
// Two characters (one before, one after) the sequence of underscore characters, plus one additional column to provide a space between the text and the scrollbar
|
// Two characters (one before, one after) the sequence of underscore characters, plus one additional column to provide a space between the text and the scrollbar
|
||||||
let non_wrapping_column_width = license_text.split('\n').map(|line| line.chars().filter(|&c| c == '_').count()).max().unwrap_or(0) + 2 + 1;
|
let non_wrapping_column_width = license_text.split('\n').map(|line| line.chars().filter(|&c| c == '_').count()).max().unwrap_or(0) + 2 + 1;
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Row {
|
Layout::WidgetLayout(WidgetLayout(vec![LayoutGroup::Row {
|
||||||
widgets: vec![
|
widgets: vec![
|
||||||
TextLabel::new(license_text)
|
TextLabel::new(license_text)
|
||||||
.monospace(true)
|
.monospace(true)
|
||||||
|
|||||||
@@ -170,8 +170,6 @@ pub enum FrontendMessage {
|
|||||||
open: bool,
|
open: bool,
|
||||||
},
|
},
|
||||||
UpdateDataPanelLayout {
|
UpdateDataPanelLayout {
|
||||||
#[serde(rename = "layoutTarget")]
|
|
||||||
layout_target: LayoutTarget,
|
|
||||||
diff: Vec<WidgetDiff>,
|
diff: Vec<WidgetDiff>,
|
||||||
},
|
},
|
||||||
UpdateImportReorderIndex {
|
UpdateImportReorderIndex {
|
||||||
@@ -191,18 +189,12 @@ pub enum FrontendMessage {
|
|||||||
has_left_input_wire: HashMap<NodeId, bool>,
|
has_left_input_wire: HashMap<NodeId, bool>,
|
||||||
},
|
},
|
||||||
UpdateDialogButtons {
|
UpdateDialogButtons {
|
||||||
#[serde(rename = "layoutTarget")]
|
|
||||||
layout_target: LayoutTarget,
|
|
||||||
diff: Vec<WidgetDiff>,
|
diff: Vec<WidgetDiff>,
|
||||||
},
|
},
|
||||||
UpdateDialogColumn1 {
|
UpdateDialogColumn1 {
|
||||||
#[serde(rename = "layoutTarget")]
|
|
||||||
layout_target: LayoutTarget,
|
|
||||||
diff: Vec<WidgetDiff>,
|
diff: Vec<WidgetDiff>,
|
||||||
},
|
},
|
||||||
UpdateDialogColumn2 {
|
UpdateDialogColumn2 {
|
||||||
#[serde(rename = "layoutTarget")]
|
|
||||||
layout_target: LayoutTarget,
|
|
||||||
diff: Vec<WidgetDiff>,
|
diff: Vec<WidgetDiff>,
|
||||||
},
|
},
|
||||||
UpdateDocumentArtwork {
|
UpdateDocumentArtwork {
|
||||||
@@ -212,8 +204,6 @@ pub enum FrontendMessage {
|
|||||||
image_data: Vec<(u64, Image<Color>)>,
|
image_data: Vec<(u64, Image<Color>)>,
|
||||||
},
|
},
|
||||||
UpdateDocumentBarLayout {
|
UpdateDocumentBarLayout {
|
||||||
#[serde(rename = "layoutTarget")]
|
|
||||||
layout_target: LayoutTarget,
|
|
||||||
diff: Vec<WidgetDiff>,
|
diff: Vec<WidgetDiff>,
|
||||||
},
|
},
|
||||||
UpdateDocumentLayerDetails {
|
UpdateDocumentLayerDetails {
|
||||||
@@ -228,8 +218,6 @@ pub enum FrontendMessage {
|
|||||||
data_buffer: JsRawBuffer,
|
data_buffer: JsRawBuffer,
|
||||||
},
|
},
|
||||||
UpdateDocumentModeLayout {
|
UpdateDocumentModeLayout {
|
||||||
#[serde(rename = "layoutTarget")]
|
|
||||||
layout_target: LayoutTarget,
|
|
||||||
diff: Vec<WidgetDiff>,
|
diff: Vec<WidgetDiff>,
|
||||||
},
|
},
|
||||||
UpdateDocumentRulers {
|
UpdateDocumentRulers {
|
||||||
@@ -257,23 +245,15 @@ pub enum FrontendMessage {
|
|||||||
percentage: f64,
|
percentage: f64,
|
||||||
},
|
},
|
||||||
UpdateLayersPanelControlBarLeftLayout {
|
UpdateLayersPanelControlBarLeftLayout {
|
||||||
#[serde(rename = "layoutTarget")]
|
|
||||||
layout_target: LayoutTarget,
|
|
||||||
diff: Vec<WidgetDiff>,
|
diff: Vec<WidgetDiff>,
|
||||||
},
|
},
|
||||||
UpdateLayersPanelControlBarRightLayout {
|
UpdateLayersPanelControlBarRightLayout {
|
||||||
#[serde(rename = "layoutTarget")]
|
|
||||||
layout_target: LayoutTarget,
|
|
||||||
diff: Vec<WidgetDiff>,
|
diff: Vec<WidgetDiff>,
|
||||||
},
|
},
|
||||||
UpdateLayersPanelBottomBarLayout {
|
UpdateLayersPanelBottomBarLayout {
|
||||||
#[serde(rename = "layoutTarget")]
|
|
||||||
layout_target: LayoutTarget,
|
|
||||||
diff: Vec<WidgetDiff>,
|
diff: Vec<WidgetDiff>,
|
||||||
},
|
},
|
||||||
UpdateMenuBarLayout {
|
UpdateMenuBarLayout {
|
||||||
#[serde(rename = "layoutTarget")]
|
|
||||||
layout_target: LayoutTarget,
|
|
||||||
diff: Vec<WidgetDiff>,
|
diff: Vec<WidgetDiff>,
|
||||||
},
|
},
|
||||||
UpdateMouseCursor {
|
UpdateMouseCursor {
|
||||||
@@ -293,8 +273,6 @@ pub enum FrontendMessage {
|
|||||||
},
|
},
|
||||||
ClearAllNodeGraphWires,
|
ClearAllNodeGraphWires,
|
||||||
UpdateNodeGraphControlBarLayout {
|
UpdateNodeGraphControlBarLayout {
|
||||||
#[serde(rename = "layoutTarget")]
|
|
||||||
layout_target: LayoutTarget,
|
|
||||||
diff: Vec<WidgetDiff>,
|
diff: Vec<WidgetDiff>,
|
||||||
},
|
},
|
||||||
UpdateNodeGraphSelection {
|
UpdateNodeGraphSelection {
|
||||||
@@ -312,18 +290,12 @@ pub enum FrontendMessage {
|
|||||||
open_documents: Vec<OpenDocument>,
|
open_documents: Vec<OpenDocument>,
|
||||||
},
|
},
|
||||||
UpdatePropertiesPanelLayout {
|
UpdatePropertiesPanelLayout {
|
||||||
#[serde(rename = "layoutTarget")]
|
|
||||||
layout_target: LayoutTarget,
|
|
||||||
diff: Vec<WidgetDiff>,
|
diff: Vec<WidgetDiff>,
|
||||||
},
|
},
|
||||||
UpdateToolOptionsLayout {
|
UpdateToolOptionsLayout {
|
||||||
#[serde(rename = "layoutTarget")]
|
|
||||||
layout_target: LayoutTarget,
|
|
||||||
diff: Vec<WidgetDiff>,
|
diff: Vec<WidgetDiff>,
|
||||||
},
|
},
|
||||||
UpdateToolShelfLayout {
|
UpdateToolShelfLayout {
|
||||||
#[serde(rename = "layoutTarget")]
|
|
||||||
layout_target: LayoutTarget,
|
|
||||||
diff: Vec<WidgetDiff>,
|
diff: Vec<WidgetDiff>,
|
||||||
},
|
},
|
||||||
UpdateWirePathInProgress {
|
UpdateWirePathInProgress {
|
||||||
@@ -331,18 +303,12 @@ pub enum FrontendMessage {
|
|||||||
wire_path: Option<WirePath>,
|
wire_path: Option<WirePath>,
|
||||||
},
|
},
|
||||||
UpdateWelcomeScreenButtonsLayout {
|
UpdateWelcomeScreenButtonsLayout {
|
||||||
#[serde(rename = "layoutTarget")]
|
|
||||||
layout_target: LayoutTarget,
|
|
||||||
diff: Vec<WidgetDiff>,
|
diff: Vec<WidgetDiff>,
|
||||||
},
|
},
|
||||||
UpdateStatusBarHintsLayout {
|
UpdateStatusBarHintsLayout {
|
||||||
#[serde(rename = "layoutTarget")]
|
|
||||||
layout_target: LayoutTarget,
|
|
||||||
diff: Vec<WidgetDiff>,
|
diff: Vec<WidgetDiff>,
|
||||||
},
|
},
|
||||||
UpdateWorkingColorsLayout {
|
UpdateWorkingColorsLayout {
|
||||||
#[serde(rename = "layoutTarget")]
|
|
||||||
layout_target: LayoutTarget,
|
|
||||||
diff: Vec<WidgetDiff>,
|
diff: Vec<WidgetDiff>,
|
||||||
},
|
},
|
||||||
UpdatePlatform {
|
UpdatePlatform {
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ impl MessageHandler<LayoutMessage, LayoutMessageContext<'_>> for LayoutMessageHa
|
|||||||
impl LayoutMessageHandler {
|
impl LayoutMessageHandler {
|
||||||
/// Get the widget path for the widget with the specified id
|
/// Get the widget path for the widget with the specified id
|
||||||
fn get_widget_path(widget_layout: &WidgetLayout, widget_id: WidgetId) -> Option<(&WidgetInstance, Vec<usize>)> {
|
fn get_widget_path(widget_layout: &WidgetLayout, widget_id: WidgetId) -> Option<(&WidgetInstance, Vec<usize>)> {
|
||||||
let mut stack = widget_layout.layout.iter().enumerate().map(|(index, val)| (vec![index], val)).collect::<Vec<_>>();
|
let mut stack = widget_layout.0.iter().enumerate().map(|(index, val)| (vec![index], val)).collect::<Vec<_>>();
|
||||||
while let Some((mut widget_path, layout_group)) = stack.pop() {
|
while let Some((mut widget_path, layout_group)) = stack.pop() {
|
||||||
match layout_group {
|
match layout_group {
|
||||||
// Check if any of the widgets in the current column or row have the correct id
|
// Check if any of the widgets in the current column or row have the correct id
|
||||||
@@ -75,13 +75,20 @@ impl LayoutMessageHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Widget::PopoverButton(popover) = &widget.widget {
|
if let Widget::PopoverButton(popover) = &widget.widget {
|
||||||
stack.extend(popover.popover_layout.iter().enumerate().map(|(child, val)| ([widget_path.as_slice(), &[index, child]].concat(), val)));
|
stack.extend(
|
||||||
|
popover
|
||||||
|
.popover_layout
|
||||||
|
.0
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(child, val)| ([widget_path.as_slice(), &[index, child]].concat(), val)),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// A section contains more LayoutGroups which we add to the stack.
|
// A section contains more LayoutGroups which we add to the stack.
|
||||||
LayoutGroup::Section { layout, .. } => {
|
LayoutGroup::Section { layout, .. } => {
|
||||||
stack.extend(layout.iter().enumerate().map(|(index, val)| ([widget_path.as_slice(), &[index]].concat(), val)));
|
stack.extend(layout.0.iter().enumerate().map(|(index, val)| ([widget_path.as_slice(), &[index]].concat(), val)));
|
||||||
}
|
}
|
||||||
LayoutGroup::Table { rows, .. } => {
|
LayoutGroup::Table { rows, .. } => {
|
||||||
for (row_index, row) in rows.iter().enumerate() {
|
for (row_index, row) in rows.iter().enumerate() {
|
||||||
@@ -97,6 +104,7 @@ impl LayoutMessageHandler {
|
|||||||
stack.extend(
|
stack.extend(
|
||||||
popover
|
popover
|
||||||
.popover_layout
|
.popover_layout
|
||||||
|
.0
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(child, val)| ([widget_path.as_slice(), &[row_index, cell_index, child]].concat(), val)),
|
.map(|(child, val)| ([widget_path.as_slice(), &[row_index, cell_index, child]].concat(), val)),
|
||||||
@@ -489,7 +497,7 @@ impl LayoutMessageHandler {
|
|||||||
if layout_target == LayoutTarget::MenuBar {
|
if layout_target == LayoutTarget::MenuBar {
|
||||||
widget_diffs = vec![WidgetDiff {
|
widget_diffs = vec![WidgetDiff {
|
||||||
widget_path: Vec::new(),
|
widget_path: Vec::new(),
|
||||||
new_value: DiffUpdate::SubLayout(current.layout.clone()),
|
new_value: DiffUpdate::WidgetLayout(current.layout.clone()),
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -503,23 +511,23 @@ impl LayoutMessageHandler {
|
|||||||
diff.iter_mut().for_each(|diff| diff.new_value.apply_keyboard_shortcut(action_input_mapping));
|
diff.iter_mut().for_each(|diff| diff.new_value.apply_keyboard_shortcut(action_input_mapping));
|
||||||
|
|
||||||
let message = match layout_target {
|
let message = match layout_target {
|
||||||
LayoutTarget::DataPanel => FrontendMessage::UpdateDataPanelLayout { layout_target, diff },
|
LayoutTarget::DataPanel => FrontendMessage::UpdateDataPanelLayout { diff },
|
||||||
LayoutTarget::DialogButtons => FrontendMessage::UpdateDialogButtons { layout_target, diff },
|
LayoutTarget::DialogButtons => FrontendMessage::UpdateDialogButtons { diff },
|
||||||
LayoutTarget::DialogColumn1 => FrontendMessage::UpdateDialogColumn1 { layout_target, diff },
|
LayoutTarget::DialogColumn1 => FrontendMessage::UpdateDialogColumn1 { diff },
|
||||||
LayoutTarget::DialogColumn2 => FrontendMessage::UpdateDialogColumn2 { layout_target, diff },
|
LayoutTarget::DialogColumn2 => FrontendMessage::UpdateDialogColumn2 { diff },
|
||||||
LayoutTarget::DocumentBar => FrontendMessage::UpdateDocumentBarLayout { layout_target, diff },
|
LayoutTarget::DocumentBar => FrontendMessage::UpdateDocumentBarLayout { diff },
|
||||||
LayoutTarget::DocumentMode => FrontendMessage::UpdateDocumentModeLayout { layout_target, diff },
|
LayoutTarget::DocumentMode => FrontendMessage::UpdateDocumentModeLayout { diff },
|
||||||
LayoutTarget::LayersPanelBottomBar => FrontendMessage::UpdateLayersPanelBottomBarLayout { layout_target, diff },
|
LayoutTarget::LayersPanelBottomBar => FrontendMessage::UpdateLayersPanelBottomBarLayout { diff },
|
||||||
LayoutTarget::LayersPanelControlLeftBar => FrontendMessage::UpdateLayersPanelControlBarLeftLayout { layout_target, diff },
|
LayoutTarget::LayersPanelControlLeftBar => FrontendMessage::UpdateLayersPanelControlBarLeftLayout { diff },
|
||||||
LayoutTarget::LayersPanelControlRightBar => FrontendMessage::UpdateLayersPanelControlBarRightLayout { layout_target, diff },
|
LayoutTarget::LayersPanelControlRightBar => FrontendMessage::UpdateLayersPanelControlBarRightLayout { diff },
|
||||||
LayoutTarget::MenuBar => FrontendMessage::UpdateMenuBarLayout { layout_target, diff },
|
LayoutTarget::MenuBar => FrontendMessage::UpdateMenuBarLayout { diff },
|
||||||
LayoutTarget::NodeGraphControlBar => FrontendMessage::UpdateNodeGraphControlBarLayout { layout_target, diff },
|
LayoutTarget::NodeGraphControlBar => FrontendMessage::UpdateNodeGraphControlBarLayout { diff },
|
||||||
LayoutTarget::PropertiesPanel => FrontendMessage::UpdatePropertiesPanelLayout { layout_target, diff },
|
LayoutTarget::PropertiesPanel => FrontendMessage::UpdatePropertiesPanelLayout { diff },
|
||||||
LayoutTarget::StatusBarHints => FrontendMessage::UpdateStatusBarHintsLayout { layout_target, diff },
|
LayoutTarget::StatusBarHints => FrontendMessage::UpdateStatusBarHintsLayout { diff },
|
||||||
LayoutTarget::ToolOptions => FrontendMessage::UpdateToolOptionsLayout { layout_target, diff },
|
LayoutTarget::ToolOptions => FrontendMessage::UpdateToolOptionsLayout { diff },
|
||||||
LayoutTarget::ToolShelf => FrontendMessage::UpdateToolShelfLayout { layout_target, diff },
|
LayoutTarget::ToolShelf => FrontendMessage::UpdateToolShelfLayout { diff },
|
||||||
LayoutTarget::WelcomeScreenButtons => FrontendMessage::UpdateWelcomeScreenButtonsLayout { layout_target, diff },
|
LayoutTarget::WelcomeScreenButtons => FrontendMessage::UpdateWelcomeScreenButtonsLayout { diff },
|
||||||
LayoutTarget::WorkingColors => FrontendMessage::UpdateWorkingColorsLayout { layout_target, diff },
|
LayoutTarget::WorkingColors => FrontendMessage::UpdateWorkingColorsLayout { diff },
|
||||||
|
|
||||||
LayoutTarget::LayoutTargetLength => panic!("`LayoutTargetLength` is not a valid Layout Target and is used for array indexing"),
|
LayoutTarget::LayoutTargetLength => panic!("`LayoutTargetLength` is not a valid Layout Target and is used for array indexing"),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -118,25 +118,19 @@ impl Default for Layout {
|
|||||||
|
|
||||||
// TODO: Unwrap this struct
|
// TODO: Unwrap this struct
|
||||||
#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize, PartialEq, specta::Type)]
|
#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize, PartialEq, specta::Type)]
|
||||||
pub struct WidgetLayout {
|
pub struct WidgetLayout(pub Vec<LayoutGroup>);
|
||||||
pub layout: SubLayout,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WidgetLayout {
|
impl WidgetLayout {
|
||||||
pub fn new(layout: SubLayout) -> Self {
|
|
||||||
Self { layout }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn iter(&self) -> WidgetIter<'_> {
|
pub fn iter(&self) -> WidgetIter<'_> {
|
||||||
WidgetIter {
|
WidgetIter {
|
||||||
stack: self.layout.iter().collect(),
|
stack: self.0.iter().collect(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_mut(&mut self) -> WidgetIterMut<'_> {
|
pub fn iter_mut(&mut self) -> WidgetIterMut<'_> {
|
||||||
WidgetIterMut {
|
WidgetIterMut {
|
||||||
stack: self.layout.iter_mut().collect(),
|
stack: self.0.iter_mut().collect(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -145,12 +139,12 @@ impl WidgetLayout {
|
|||||||
pub fn diff(&mut self, new: Self, widget_path: &mut Vec<usize>, widget_diffs: &mut Vec<WidgetDiff>) {
|
pub fn diff(&mut self, new: Self, widget_path: &mut Vec<usize>, widget_diffs: &mut Vec<WidgetDiff>) {
|
||||||
// Check if the length of items is different
|
// Check if the length of items is different
|
||||||
// TODO: Diff insersion and deletion of items
|
// TODO: Diff insersion and deletion of items
|
||||||
if self.layout.len() != new.layout.len() {
|
if self.0.len() != new.0.len() {
|
||||||
// Update the layout to the new layout
|
// Update the layout to the new layout
|
||||||
self.layout.clone_from(&new.layout);
|
self.0.clone_from(&new.0);
|
||||||
|
|
||||||
// Push an update sublayout to the diff
|
// Push an update sublayout to the diff
|
||||||
let new = DiffUpdate::SubLayout(new.layout);
|
let new = DiffUpdate::WidgetLayout(new);
|
||||||
widget_diffs.push(WidgetDiff {
|
widget_diffs.push(WidgetDiff {
|
||||||
widget_path: widget_path.to_vec(),
|
widget_path: widget_path.to_vec(),
|
||||||
new_value: new,
|
new_value: new,
|
||||||
@@ -158,7 +152,7 @@ impl WidgetLayout {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Diff all of the children
|
// Diff all of the children
|
||||||
for (index, (current_child, new_child)) in self.layout.iter_mut().zip(new.layout).enumerate() {
|
for (index, (current_child, new_child)) in self.0.iter_mut().zip(new.0).enumerate() {
|
||||||
widget_path.push(index);
|
widget_path.push(index);
|
||||||
current_child.diff(new_child, widget_path, widget_diffs);
|
current_child.diff(new_child, widget_path, widget_diffs);
|
||||||
widget_path.pop();
|
widget_path.pop();
|
||||||
@@ -185,7 +179,7 @@ impl<'a> Iterator for WidgetIter<'a> {
|
|||||||
|
|
||||||
if let Some(item) = widget {
|
if let Some(item) = widget {
|
||||||
if let WidgetInstance { widget: Widget::PopoverButton(p), .. } = item {
|
if let WidgetInstance { widget: Widget::PopoverButton(p), .. } = item {
|
||||||
self.stack.extend(p.popover_layout.iter());
|
self.stack.extend(p.popover_layout.0.iter());
|
||||||
return self.next();
|
return self.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,7 +200,7 @@ impl<'a> Iterator for WidgetIter<'a> {
|
|||||||
self.next()
|
self.next()
|
||||||
}
|
}
|
||||||
Some(LayoutGroup::Section { layout, .. }) => {
|
Some(LayoutGroup::Section { layout, .. }) => {
|
||||||
for layout_row in layout {
|
for layout_row in &layout.0 {
|
||||||
self.stack.push(layout_row);
|
self.stack.push(layout_row);
|
||||||
}
|
}
|
||||||
self.next()
|
self.next()
|
||||||
@@ -235,7 +229,7 @@ impl<'a> Iterator for WidgetIterMut<'a> {
|
|||||||
|
|
||||||
if let Some(widget) = widget {
|
if let Some(widget) = widget {
|
||||||
if let WidgetInstance { widget: Widget::PopoverButton(p), .. } = widget {
|
if let WidgetInstance { widget: Widget::PopoverButton(p), .. } = widget {
|
||||||
self.stack.extend(p.popover_layout.iter_mut());
|
self.stack.extend(p.popover_layout.0.iter_mut());
|
||||||
return self.next();
|
return self.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,7 +250,7 @@ impl<'a> Iterator for WidgetIterMut<'a> {
|
|||||||
self.next()
|
self.next()
|
||||||
}
|
}
|
||||||
Some(LayoutGroup::Section { layout, .. }) => {
|
Some(LayoutGroup::Section { layout, .. }) => {
|
||||||
for layout_row in layout {
|
for layout_row in &mut layout.0 {
|
||||||
self.stack.push(layout_row);
|
self.stack.push(layout_row);
|
||||||
}
|
}
|
||||||
self.next()
|
self.next()
|
||||||
@@ -266,8 +260,6 @@ impl<'a> Iterator for WidgetIterMut<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type SubLayout = Vec<LayoutGroup>;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, specta::Type)]
|
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||||
pub enum LayoutGroup {
|
pub enum LayoutGroup {
|
||||||
#[serde(rename = "column")]
|
#[serde(rename = "column")]
|
||||||
@@ -293,7 +285,7 @@ pub enum LayoutGroup {
|
|||||||
visible: bool,
|
visible: bool,
|
||||||
pinned: bool,
|
pinned: bool,
|
||||||
id: u64,
|
id: u64,
|
||||||
layout: SubLayout,
|
layout: WidgetLayout,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -425,7 +417,7 @@ impl LayoutGroup {
|
|||||||
) => {
|
) => {
|
||||||
// Resend the entire panel if the lengths, names, visibility, or node IDs are different
|
// Resend the entire panel if the lengths, names, visibility, or node IDs are different
|
||||||
// TODO: Diff insersion and deletion of items
|
// TODO: Diff insersion and deletion of items
|
||||||
if current_layout.len() != new_layout.len()
|
if current_layout.0.len() != new_layout.0.len()
|
||||||
|| *current_name != new_name
|
|| *current_name != new_name
|
||||||
|| *current_description != new_description
|
|| *current_description != new_description
|
||||||
|| *current_visible != new_visible
|
|| *current_visible != new_visible
|
||||||
@@ -454,7 +446,7 @@ impl LayoutGroup {
|
|||||||
}
|
}
|
||||||
// Diff all of the children
|
// Diff all of the children
|
||||||
else {
|
else {
|
||||||
for (index, (current_child, new_child)) in current_layout.iter_mut().zip(new_layout).enumerate() {
|
for (index, (current_child, new_child)) in current_layout.0.iter_mut().zip(new_layout.0).enumerate() {
|
||||||
widget_path.push(index);
|
widget_path.push(index);
|
||||||
current_child.diff(new_child, widget_path, widget_diffs);
|
current_child.diff(new_child, widget_path, widget_diffs);
|
||||||
widget_path.pop();
|
widget_path.pop();
|
||||||
@@ -478,7 +470,6 @@ impl LayoutGroup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Rename to WidgetInstance
|
|
||||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, specta::Type)]
|
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||||
pub struct WidgetInstance {
|
pub struct WidgetInstance {
|
||||||
#[serde(rename = "widgetId")]
|
#[serde(rename = "widgetId")]
|
||||||
@@ -514,7 +505,7 @@ impl WidgetInstance {
|
|||||||
&& button1.popover_min_width == button2.popover_min_width
|
&& button1.popover_min_width == button2.popover_min_width
|
||||||
{
|
{
|
||||||
let mut new_widget_path = widget_path.to_vec();
|
let mut new_widget_path = widget_path.to_vec();
|
||||||
for (i, (a, b)) in button1.popover_layout.iter_mut().zip(button2.popover_layout.iter()).enumerate() {
|
for (i, (a, b)) in button1.popover_layout.0.iter_mut().zip(button2.popover_layout.0.iter()).enumerate() {
|
||||||
new_widget_path.push(i);
|
new_widget_path.push(i);
|
||||||
a.diff(b.clone(), &mut new_widget_path, widget_diffs);
|
a.diff(b.clone(), &mut new_widget_path, widget_diffs);
|
||||||
new_widget_path.pop();
|
new_widget_path.pop();
|
||||||
@@ -598,11 +589,11 @@ pub struct WidgetDiff {
|
|||||||
|
|
||||||
/// The new value of the UI, sent as part of a diff.
|
/// 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.
|
/// An update can represent a single widget or an entire WidgetLayout, or just a single layout group.
|
||||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize, specta::Type)]
|
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||||
pub enum DiffUpdate {
|
pub enum DiffUpdate {
|
||||||
#[serde(rename = "subLayout")]
|
#[serde(rename = "widgetLayout")]
|
||||||
SubLayout(SubLayout),
|
WidgetLayout(WidgetLayout),
|
||||||
#[serde(rename = "layoutGroup")]
|
#[serde(rename = "layoutGroup")]
|
||||||
LayoutGroup(LayoutGroup),
|
LayoutGroup(LayoutGroup),
|
||||||
#[serde(rename = "widget")]
|
#[serde(rename = "widget")]
|
||||||
@@ -684,7 +675,7 @@ impl DiffUpdate {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Self::SubLayout(sub_layout) => sub_layout.iter_mut().flat_map(|layout_group| layout_group.iter_mut()).for_each(|widget_instance| {
|
Self::WidgetLayout(widget_layout) => widget_layout.0.iter_mut().flat_map(|layout_group| layout_group.iter_mut()).for_each(|widget_instance| {
|
||||||
convert_tooltip(widget_instance);
|
convert_tooltip(widget_instance);
|
||||||
convert_menu_lists(widget_instance);
|
convert_menu_lists(widget_instance);
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ pub struct PopoverButton {
|
|||||||
pub tooltip_shortcut: Option<ActionShortcut>,
|
pub tooltip_shortcut: Option<ActionShortcut>,
|
||||||
|
|
||||||
#[serde(rename = "popoverLayout")]
|
#[serde(rename = "popoverLayout")]
|
||||||
pub popover_layout: SubLayout,
|
pub popover_layout: WidgetLayout,
|
||||||
|
|
||||||
#[serde(rename = "popoverMinWidth")]
|
#[serde(rename = "popoverMinWidth")]
|
||||||
pub popover_min_width: Option<u32>,
|
pub popover_min_width: Option<u32>,
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ impl DataPanelMessageHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
responses.add(LayoutMessage::SendLayout {
|
responses.add(LayoutMessage::SendLayout {
|
||||||
layout: Layout::WidgetLayout(WidgetLayout { layout }),
|
layout: Layout::WidgetLayout(WidgetLayout(layout)),
|
||||||
layout_target: LayoutTarget::DataPanel,
|
layout_target: LayoutTarget::DataPanel,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2175,7 +2175,7 @@ impl DocumentMessageHandler {
|
|||||||
pub fn update_document_widgets(&self, responses: &mut VecDeque<Message>, animation_is_playing: bool, time: Duration) {
|
pub fn update_document_widgets(&self, responses: &mut VecDeque<Message>, animation_is_playing: bool, time: Duration) {
|
||||||
// Document mode (dropdown menu at the left of the bar above the viewport, before the tool options)
|
// Document mode (dropdown menu at the left of the bar above the viewport, before the tool options)
|
||||||
|
|
||||||
let document_mode_layout = WidgetLayout::new(vec![LayoutGroup::Row {
|
let document_mode_layout = WidgetLayout(vec![LayoutGroup::Row {
|
||||||
widgets: vec![
|
widgets: vec![
|
||||||
// DropdownInput::new(
|
// DropdownInput::new(
|
||||||
// vec![vec![
|
// vec![vec![
|
||||||
@@ -2235,7 +2235,7 @@ impl DocumentMessageHandler {
|
|||||||
})
|
})
|
||||||
.widget_instance(),
|
.widget_instance(),
|
||||||
PopoverButton::new()
|
PopoverButton::new()
|
||||||
.popover_layout(vec![
|
.popover_layout(WidgetLayout(vec![
|
||||||
LayoutGroup::Row {
|
LayoutGroup::Row {
|
||||||
widgets: vec![TextLabel::new("Overlays").bold(true).widget_instance()],
|
widgets: vec![TextLabel::new("Overlays").bold(true).widget_instance()],
|
||||||
},
|
},
|
||||||
@@ -2468,7 +2468,7 @@ impl DocumentMessageHandler {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
])
|
]))
|
||||||
.widget_instance(),
|
.widget_instance(),
|
||||||
Separator::new(SeparatorType::Related).widget_instance(),
|
Separator::new(SeparatorType::Related).widget_instance(),
|
||||||
CheckboxInput::new(snapping_state.snapping_enabled)
|
CheckboxInput::new(snapping_state.snapping_enabled)
|
||||||
@@ -2484,7 +2484,7 @@ impl DocumentMessageHandler {
|
|||||||
})
|
})
|
||||||
.widget_instance(),
|
.widget_instance(),
|
||||||
PopoverButton::new()
|
PopoverButton::new()
|
||||||
.popover_layout(
|
.popover_layout(WidgetLayout(
|
||||||
[
|
[
|
||||||
LayoutGroup::Row {
|
LayoutGroup::Row {
|
||||||
widgets: vec![TextLabel::new("Snapping").bold(true).widget_instance()],
|
widgets: vec![TextLabel::new("Snapping").bold(true).widget_instance()],
|
||||||
@@ -2538,7 +2538,7 @@ impl DocumentMessageHandler {
|
|||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
.collect(),
|
.collect(),
|
||||||
)
|
))
|
||||||
.widget_instance(),
|
.widget_instance(),
|
||||||
Separator::new(SeparatorType::Related).widget_instance(),
|
Separator::new(SeparatorType::Related).widget_instance(),
|
||||||
CheckboxInput::new(self.snapping_state.grid_snapping)
|
CheckboxInput::new(self.snapping_state.grid_snapping)
|
||||||
@@ -2548,7 +2548,7 @@ impl DocumentMessageHandler {
|
|||||||
.on_update(|optional_input: &CheckboxInput| DocumentMessage::GridVisibility { visible: optional_input.checked }.into())
|
.on_update(|optional_input: &CheckboxInput| DocumentMessage::GridVisibility { visible: optional_input.checked }.into())
|
||||||
.widget_instance(),
|
.widget_instance(),
|
||||||
PopoverButton::new()
|
PopoverButton::new()
|
||||||
.popover_layout(overlay_options(&self.snapping_state.grid))
|
.popover_layout(WidgetLayout(overlay_options(&self.snapping_state.grid)))
|
||||||
.popover_min_width(Some(320))
|
.popover_min_width(Some(320))
|
||||||
.widget_instance(),
|
.widget_instance(),
|
||||||
Separator::new(SeparatorType::Unrelated).widget_instance(),
|
Separator::new(SeparatorType::Unrelated).widget_instance(),
|
||||||
@@ -2573,8 +2573,8 @@ impl DocumentMessageHandler {
|
|||||||
.selected_index(Some(self.render_mode as u32))
|
.selected_index(Some(self.render_mode as u32))
|
||||||
.narrow(true)
|
.narrow(true)
|
||||||
.widget_instance(),
|
.widget_instance(),
|
||||||
// PopoverButton::new()
|
// PopoverButton::new().popover_layout(
|
||||||
// .popover_layout(vec![
|
// WidgetLayout(vec![
|
||||||
// LayoutGroup::Row {
|
// LayoutGroup::Row {
|
||||||
// widgets: vec![TextLabel::new("Render Mode").bold(true).widget_instance()],
|
// widgets: vec![TextLabel::new("Render Mode").bold(true).widget_instance()],
|
||||||
// },
|
// },
|
||||||
@@ -2583,6 +2583,7 @@ impl DocumentMessageHandler {
|
|||||||
// },
|
// },
|
||||||
// ])
|
// ])
|
||||||
// .widget_instance(),
|
// .widget_instance(),
|
||||||
|
// ),
|
||||||
Separator::new(SeparatorType::Unrelated).widget_instance(),
|
Separator::new(SeparatorType::Unrelated).widget_instance(),
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -2631,7 +2632,7 @@ impl DocumentMessageHandler {
|
|||||||
.widget_instance(),
|
.widget_instance(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
let document_bar_layout = WidgetLayout::new(vec![LayoutGroup::Row { widgets }]);
|
let document_bar_layout = WidgetLayout(vec![LayoutGroup::Row { widgets }]);
|
||||||
|
|
||||||
responses.add(LayoutMessage::SendLayout {
|
responses.add(LayoutMessage::SendLayout {
|
||||||
layout: Layout::WidgetLayout(document_bar_layout),
|
layout: Layout::WidgetLayout(document_bar_layout),
|
||||||
@@ -2772,7 +2773,7 @@ impl DocumentMessageHandler {
|
|||||||
.tooltip_label("Fill")
|
.tooltip_label("Fill")
|
||||||
.widget_instance(),
|
.widget_instance(),
|
||||||
];
|
];
|
||||||
let layers_panel_control_bar_left = WidgetLayout::new(vec![LayoutGroup::Row { widgets }]);
|
let layers_panel_control_bar_left = WidgetLayout(vec![LayoutGroup::Row { widgets }]);
|
||||||
|
|
||||||
let widgets = vec![
|
let widgets = vec![
|
||||||
IconButton::new(if selection_all_locked { "PadlockLocked" } else { "PadlockUnlocked" }, 24)
|
IconButton::new(if selection_all_locked { "PadlockLocked" } else { "PadlockUnlocked" }, 24)
|
||||||
@@ -2790,7 +2791,7 @@ impl DocumentMessageHandler {
|
|||||||
.disabled(!has_selection)
|
.disabled(!has_selection)
|
||||||
.widget_instance(),
|
.widget_instance(),
|
||||||
];
|
];
|
||||||
let layers_panel_control_bar_right = WidgetLayout::new(vec![LayoutGroup::Row { widgets }]);
|
let layers_panel_control_bar_right = WidgetLayout(vec![LayoutGroup::Row { widgets }]);
|
||||||
|
|
||||||
responses.add(LayoutMessage::SendLayout {
|
responses.add(LayoutMessage::SendLayout {
|
||||||
layout: Layout::WidgetLayout(layers_panel_control_bar_left),
|
layout: Layout::WidgetLayout(layers_panel_control_bar_left),
|
||||||
@@ -2844,7 +2845,7 @@ impl DocumentMessageHandler {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.widget_instance();
|
.widget_instance();
|
||||||
vec![LayoutGroup::Row { widgets: vec![node_chooser] }]
|
WidgetLayout(vec![LayoutGroup::Row { widgets: vec![node_chooser] }])
|
||||||
})
|
})
|
||||||
.widget_instance(),
|
.widget_instance(),
|
||||||
Separator::new(SeparatorType::Unrelated).widget_instance(),
|
Separator::new(SeparatorType::Unrelated).widget_instance(),
|
||||||
@@ -2869,7 +2870,7 @@ impl DocumentMessageHandler {
|
|||||||
.disabled(!has_selection)
|
.disabled(!has_selection)
|
||||||
.widget_instance(),
|
.widget_instance(),
|
||||||
];
|
];
|
||||||
let layers_panel_bottom_bar = WidgetLayout::new(vec![LayoutGroup::Row { widgets }]);
|
let layers_panel_bottom_bar = WidgetLayout(vec![LayoutGroup::Row { widgets }]);
|
||||||
|
|
||||||
responses.add(LayoutMessage::SendLayout {
|
responses.add(LayoutMessage::SendLayout {
|
||||||
layout: Layout::WidgetLayout(layers_panel_bottom_bar),
|
layout: Layout::WidgetLayout(layers_panel_bottom_bar),
|
||||||
|
|||||||
@@ -2069,7 +2069,7 @@ impl NodeGraphMessageHandler {
|
|||||||
/// Send the cached layout to the frontend for the control bar at the top of the node panel
|
/// Send the cached layout to the frontend for the control bar at the top of the node panel
|
||||||
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(self.widgets.to_vec())),
|
||||||
layout_target: LayoutTarget::NodeGraphControlBar,
|
layout_target: LayoutTarget::NodeGraphControlBar,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -2145,7 +2145,7 @@ impl NodeGraphMessageHandler {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.widget_instance();
|
.widget_instance();
|
||||||
vec![LayoutGroup::Row { widgets: vec![node_chooser] }]
|
WidgetLayout(vec![LayoutGroup::Row { widgets: vec![node_chooser] }])
|
||||||
})
|
})
|
||||||
.widget_instance(),
|
.widget_instance(),
|
||||||
//
|
//
|
||||||
@@ -2443,7 +2443,7 @@ impl NodeGraphMessageHandler {
|
|||||||
.into()
|
.into()
|
||||||
})
|
})
|
||||||
.widget_instance();
|
.widget_instance();
|
||||||
vec![LayoutGroup::Row { widgets: vec![node_chooser] }]
|
WidgetLayout(vec![LayoutGroup::Row { widgets: vec![node_chooser] }])
|
||||||
})
|
})
|
||||||
.widget_instance(),
|
.widget_instance(),
|
||||||
Separator::new(SeparatorType::Related).widget_instance(),
|
Separator::new(SeparatorType::Related).widget_instance(),
|
||||||
|
|||||||
@@ -1699,7 +1699,7 @@ pub(crate) fn generate_node_properties(node_id: NodeId, context: &mut NodeProper
|
|||||||
visible,
|
visible,
|
||||||
pinned,
|
pinned,
|
||||||
id: node_id.0,
|
id: node_id.0,
|
||||||
layout,
|
layout: WidgetLayout(layout),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -35,7 +35,7 @@ impl MessageHandler<PropertiesPanelMessage, PropertiesPanelMessageContext<'_>> f
|
|||||||
match message {
|
match message {
|
||||||
PropertiesPanelMessage::Clear => {
|
PropertiesPanelMessage::Clear => {
|
||||||
responses.add(LayoutMessage::SendLayout {
|
responses.add(LayoutMessage::SendLayout {
|
||||||
layout: Layout::WidgetLayout(WidgetLayout::new(vec![])),
|
layout: Layout::WidgetLayout(WidgetLayout(vec![])),
|
||||||
layout_target: LayoutTarget::PropertiesPanel,
|
layout_target: LayoutTarget::PropertiesPanel,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -56,7 +56,7 @@ impl MessageHandler<PropertiesPanelMessage, PropertiesPanelMessageContext<'_>> f
|
|||||||
let properties_sections = NodeGraphMessageHandler::collate_properties(&mut node_properties_context);
|
let properties_sections = NodeGraphMessageHandler::collate_properties(&mut node_properties_context);
|
||||||
|
|
||||||
node_properties_context.responses.add(LayoutMessage::SendLayout {
|
node_properties_context.responses.add(LayoutMessage::SendLayout {
|
||||||
layout: Layout::WidgetLayout(WidgetLayout::new(properties_sections)),
|
layout: Layout::WidgetLayout(WidgetLayout(properties_sections)),
|
||||||
layout_target: LayoutTarget::PropertiesPanel,
|
layout_target: LayoutTarget::PropertiesPanel,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -736,6 +736,6 @@ impl LayoutHolder for MenuBarMessageHandler {
|
|||||||
.widget_instance(),
|
.widget_instance(),
|
||||||
];
|
];
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Row { widgets: menu_bar_buttons }]))
|
Layout::WidgetLayout(WidgetLayout(vec![LayoutGroup::Row { widgets: menu_bar_buttons }]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -924,7 +924,7 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageContext<'_>> for Portfolio
|
|||||||
layout_target: LayoutTarget::WelcomeScreenButtons,
|
layout_target: LayoutTarget::WelcomeScreenButtons,
|
||||||
});
|
});
|
||||||
responses.add(LayoutMessage::SendLayout {
|
responses.add(LayoutMessage::SendLayout {
|
||||||
layout: Layout::WidgetLayout(WidgetLayout::new(vec![table])),
|
layout: Layout::WidgetLayout(WidgetLayout(vec![table])),
|
||||||
layout_target: LayoutTarget::WelcomeScreenButtons,
|
layout_target: LayoutTarget::WelcomeScreenButtons,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ impl LayoutHolder for BrushTool {
|
|||||||
.widget_instance(),
|
.widget_instance(),
|
||||||
);
|
);
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Row { widgets }]))
|
Layout::WidgetLayout(WidgetLayout(vec![LayoutGroup::Row { widgets }]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ impl LayoutHolder for FreehandTool {
|
|||||||
widgets.push(Separator::new(SeparatorType::Unrelated).widget_instance());
|
widgets.push(Separator::new(SeparatorType::Unrelated).widget_instance());
|
||||||
widgets.push(create_weight_widget(self.options.line_weight));
|
widgets.push(create_weight_widget(self.options.line_weight));
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Row { widgets }]))
|
Layout::WidgetLayout(WidgetLayout(vec![LayoutGroup::Row { widgets }]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ impl LayoutHolder for GradientTool {
|
|||||||
.selected_index(Some((self.selected_gradient().unwrap_or(self.options.gradient_type) == GradientType::Radial) as u32))
|
.selected_index(Some((self.selected_gradient().unwrap_or(self.options.gradient_type) == GradientType::Radial) as u32))
|
||||||
.widget_instance();
|
.widget_instance();
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Row { widgets: vec![gradient_type] }]))
|
Layout::WidgetLayout(WidgetLayout(vec![LayoutGroup::Row { widgets: vec![gradient_type] }]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -342,7 +342,7 @@ impl LayoutHolder for PathTool {
|
|||||||
|
|
||||||
let _pin_pivot = pin_pivot_widget(self.tool_data.pivot_gizmo.pin_active(), false, PivotToolSource::Path);
|
let _pin_pivot = pin_pivot_widget(self.tool_data.pivot_gizmo.pin_active(), false, PivotToolSource::Path);
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Row {
|
Layout::WidgetLayout(WidgetLayout(vec![LayoutGroup::Row {
|
||||||
widgets: vec![
|
widgets: vec![
|
||||||
x_location,
|
x_location,
|
||||||
related_seperator.clone(),
|
related_seperator.clone(),
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ impl LayoutHolder for PenTool {
|
|||||||
.widget_instance(),
|
.widget_instance(),
|
||||||
);
|
);
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Row { widgets }]))
|
Layout::WidgetLayout(WidgetLayout(vec![LayoutGroup::Row { widgets }]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -252,14 +252,14 @@ impl LayoutHolder for SelectTool {
|
|||||||
widgets.extend(self.alignment_widgets(disabled));
|
widgets.extend(self.alignment_widgets(disabled));
|
||||||
// widgets.push(
|
// widgets.push(
|
||||||
// PopoverButton::new()
|
// PopoverButton::new()
|
||||||
// .popover_layout(vec![
|
// .popover_layout(WidgetLayout(vec![
|
||||||
// LayoutGroup::Row {
|
// LayoutGroup::Row {
|
||||||
// widgets: vec![TextLabel::new("Align").bold(true).widget_instance()],
|
// widgets: vec![TextLabel::new("Align").bold(true).widget_instance()],
|
||||||
// },
|
// },
|
||||||
// LayoutGroup::Row {
|
// LayoutGroup::Row {
|
||||||
// widgets: vec![TextLabel::new("Coming soon").widget_instance()],
|
// widgets: vec![TextLabel::new("Coming soon").widget_instance()],
|
||||||
// },
|
// },
|
||||||
// ])
|
// ]))
|
||||||
// .disabled(disabled)
|
// .disabled(disabled)
|
||||||
// .widget_instance(),
|
// .widget_instance(),
|
||||||
// );
|
// );
|
||||||
@@ -277,7 +277,7 @@ impl LayoutHolder for SelectTool {
|
|||||||
widgets.push(Separator::new(SeparatorType::Unrelated).widget_instance());
|
widgets.push(Separator::new(SeparatorType::Unrelated).widget_instance());
|
||||||
widgets.extend(self.boolean_widgets(self.tool_data.selected_layers_count));
|
widgets.extend(self.boolean_widgets(self.tool_data.selected_layers_count));
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Row { widgets }]))
|
Layout::WidgetLayout(WidgetLayout(vec![LayoutGroup::Row { widgets }]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -335,7 +335,7 @@ impl LayoutHolder for ShapeTool {
|
|||||||
widgets.push(Separator::new(SeparatorType::Unrelated).widget_instance());
|
widgets.push(Separator::new(SeparatorType::Unrelated).widget_instance());
|
||||||
widgets.push(create_weight_widget(self.options.line_weight));
|
widgets.push(create_weight_widget(self.options.line_weight));
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Row { widgets }]))
|
Layout::WidgetLayout(WidgetLayout(vec![LayoutGroup::Row { widgets }]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ impl LayoutHolder for SplineTool {
|
|||||||
widgets.push(Separator::new(SeparatorType::Unrelated).widget_instance());
|
widgets.push(Separator::new(SeparatorType::Unrelated).widget_instance());
|
||||||
widgets.push(create_weight_widget(self.options.line_weight));
|
widgets.push(create_weight_widget(self.options.line_weight));
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Row { widgets }]))
|
Layout::WidgetLayout(WidgetLayout(vec![LayoutGroup::Row { widgets }]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ impl LayoutHolder for TextTool {
|
|||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Row { widgets }]))
|
Layout::WidgetLayout(WidgetLayout(vec![LayoutGroup::Row { widgets }]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ pub struct DocumentToolData {
|
|||||||
|
|
||||||
impl DocumentToolData {
|
impl DocumentToolData {
|
||||||
pub fn update_working_colors(&self, responses: &mut VecDeque<Message>) {
|
pub fn update_working_colors(&self, responses: &mut VecDeque<Message>) {
|
||||||
let layout = WidgetLayout::new(vec![
|
let layout = WidgetLayout(vec![
|
||||||
LayoutGroup::Row {
|
LayoutGroup::Row {
|
||||||
widgets: vec![WorkingColorsInput::new(self.primary_color.to_gamma_srgb(), self.secondary_color.to_gamma_srgb()).widget_instance()],
|
widgets: vec![WorkingColorsInput::new(self.primary_color.to_gamma_srgb(), self.secondary_color.to_gamma_srgb()).widget_instance()],
|
||||||
},
|
},
|
||||||
@@ -290,9 +290,7 @@ impl LayoutHolder for ToolData {
|
|||||||
.skip(1)
|
.skip(1)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout {
|
Layout::WidgetLayout(WidgetLayout(vec![LayoutGroup::Row { widgets: tool_groups_layout }]))
|
||||||
layout: vec![LayoutGroup::Row { widgets: tool_groups_layout }],
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -547,7 +545,7 @@ impl HintData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Row { widgets }]))
|
Layout::WidgetLayout(WidgetLayout(vec![LayoutGroup::Row { widgets }]))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_layout(&self, responses: &mut VecDeque<Message>) {
|
pub fn send_layout(&self, responses: &mut VecDeque<Message>) {
|
||||||
@@ -559,7 +557,7 @@ impl HintData {
|
|||||||
|
|
||||||
pub fn clear_layout(responses: &mut VecDeque<Message>) {
|
pub fn clear_layout(responses: &mut VecDeque<Message>) {
|
||||||
responses.add(LayoutMessage::SendLayout {
|
responses.add(LayoutMessage::SendLayout {
|
||||||
layout: Layout::WidgetLayout(WidgetLayout::new(vec![])),
|
layout: Layout::WidgetLayout(WidgetLayout(vec![])),
|
||||||
layout_target: LayoutTarget::StatusBarHints,
|
layout_target: LayoutTarget::StatusBarHints,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,8 +34,8 @@
|
|||||||
</LayoutRow>
|
</LayoutRow>
|
||||||
<LayoutRow class={`content ${$dialog.title === "Demo Artwork" ? "center" : "" /* TODO: Replace this with a less hacky approach that's compatible with localization/translation */}`}>
|
<LayoutRow class={`content ${$dialog.title === "Demo Artwork" ? "center" : "" /* TODO: Replace this with a less hacky approach that's compatible with localization/translation */}`}>
|
||||||
<LayoutCol class="column-1">
|
<LayoutCol class="column-1">
|
||||||
{#if $dialog.column1.layout.length > 0}
|
{#if $dialog.column1.length > 0}
|
||||||
<WidgetLayout layout={$dialog.column1} class="details" />
|
<WidgetLayout layout={$dialog.column1} layoutTarget="DialogColumn1" class="details" />
|
||||||
{/if}
|
{/if}
|
||||||
{#if $dialog.panicDetails}
|
{#if $dialog.panicDetails}
|
||||||
<div class="widget-layout details">
|
<div class="widget-layout details">
|
||||||
@@ -57,15 +57,15 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</LayoutCol>
|
</LayoutCol>
|
||||||
{#if $dialog.column2.layout.length > 0}
|
{#if $dialog.column2.length > 0}
|
||||||
<LayoutCol class="column-2">
|
<LayoutCol class="column-2">
|
||||||
<WidgetLayout layout={$dialog.column2} class="details" />
|
<WidgetLayout layout={$dialog.column2} layoutTarget="DialogColumn2" class="details" />
|
||||||
</LayoutCol>
|
</LayoutCol>
|
||||||
{/if}
|
{/if}
|
||||||
</LayoutRow>
|
</LayoutRow>
|
||||||
<LayoutRow class="footer-area">
|
<LayoutRow class="footer-area">
|
||||||
{#if $dialog.buttons.layout.length > 0}
|
{#if $dialog.buttons.length > 0}
|
||||||
<WidgetLayout layout={$dialog.buttons} class="details" />
|
<WidgetLayout layout={$dialog.buttons} layoutTarget="DialogButtons" class="details" />
|
||||||
{/if}
|
{/if}
|
||||||
{#if $dialog.panicDetails}
|
{#if $dialog.panicDetails}
|
||||||
<TextButton label="Copy Error Log" action={() => navigator.clipboard.writeText($dialog.panicDetails)} />
|
<TextButton label="Copy Error Log" action={() => navigator.clipboard.writeText($dialog.panicDetails)} />
|
||||||
|
|||||||
@@ -2,14 +2,14 @@
|
|||||||
import { getContext, onMount, onDestroy } from "svelte";
|
import { getContext, onMount, onDestroy } from "svelte";
|
||||||
|
|
||||||
import type { Editor } from "@graphite/editor";
|
import type { Editor } from "@graphite/editor";
|
||||||
import { defaultWidgetLayout, patchWidgetLayout, UpdateDataPanelLayout } from "@graphite/messages";
|
import { patchWidgetLayout, UpdateDataPanelLayout, type LayoutGroup } from "@graphite/messages";
|
||||||
|
|
||||||
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
||||||
import WidgetLayout from "@graphite/components/widgets/WidgetLayout.svelte";
|
import WidgetLayout from "@graphite/components/widgets/WidgetLayout.svelte";
|
||||||
|
|
||||||
const editor = getContext<Editor>("editor");
|
const editor = getContext<Editor>("editor");
|
||||||
|
|
||||||
let dataPanelLayout = defaultWidgetLayout();
|
let dataPanelLayout: LayoutGroup[] = [];
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
editor.subscriptions.subscribeJsMessage(UpdateDataPanelLayout, (updateDataPanelLayout) => {
|
editor.subscriptions.subscribeJsMessage(UpdateDataPanelLayout, (updateDataPanelLayout) => {
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
<LayoutCol class="data-panel">
|
<LayoutCol class="data-panel">
|
||||||
<LayoutCol class="body" scrollableY={true}>
|
<LayoutCol class="body" scrollableY={true}>
|
||||||
<WidgetLayout layout={dataPanelLayout} />
|
<WidgetLayout layout={dataPanelLayout} layoutTarget="DataPanel" />
|
||||||
</LayoutCol>
|
</LayoutCol>
|
||||||
</LayoutCol>
|
</LayoutCol>
|
||||||
|
|
||||||
|
|||||||
@@ -126,7 +126,7 @@
|
|||||||
totalToolRowsFor2Columns,
|
totalToolRowsFor2Columns,
|
||||||
totalToolRowsFor3Columns,
|
totalToolRowsFor3Columns,
|
||||||
};
|
};
|
||||||
})($document.toolShelfLayout.layout[0]);
|
})($document.toolShelfLayout[0]);
|
||||||
|
|
||||||
function dropFile(e: DragEvent) {
|
function dropFile(e: DragEvent) {
|
||||||
const { dataTransfer } = e;
|
const { dataTransfer } = e;
|
||||||
@@ -506,12 +506,12 @@
|
|||||||
<LayoutCol class="document" on:dragover={(e) => e.preventDefault()} on:drop={dropFile}>
|
<LayoutCol class="document" on:dragover={(e) => e.preventDefault()} on:drop={dropFile}>
|
||||||
<LayoutRow class="control-bar" classes={{ "for-graph": $document.graphViewOverlayOpen }} scrollableX={true}>
|
<LayoutRow class="control-bar" classes={{ "for-graph": $document.graphViewOverlayOpen }} scrollableX={true}>
|
||||||
{#if !$document.graphViewOverlayOpen}
|
{#if !$document.graphViewOverlayOpen}
|
||||||
<WidgetLayout layout={$document.documentModeLayout} />
|
<WidgetLayout layout={$document.documentModeLayout} layoutTarget="DocumentMode" />
|
||||||
<WidgetLayout layout={$document.toolOptionsLayout} />
|
<WidgetLayout layout={$document.toolOptionsLayout} layoutTarget="ToolOptions" />
|
||||||
<LayoutRow class="spacer" />
|
<LayoutRow class="spacer" />
|
||||||
<WidgetLayout layout={$document.documentBarLayout} />
|
<WidgetLayout layout={$document.documentBarLayout} layoutTarget="DocumentBar" />
|
||||||
{:else}
|
{:else}
|
||||||
<WidgetLayout layout={$document.nodeGraphControlBarLayout} />
|
<WidgetLayout layout={$document.nodeGraphControlBarLayout} layoutTarget="NodeGraphControlBar" />
|
||||||
{/if}
|
{/if}
|
||||||
</LayoutRow>
|
</LayoutRow>
|
||||||
<LayoutRow
|
<LayoutRow
|
||||||
@@ -526,13 +526,13 @@
|
|||||||
<LayoutCol class="tool-shelf">
|
<LayoutCol class="tool-shelf">
|
||||||
{#if !$document.graphViewOverlayOpen}
|
{#if !$document.graphViewOverlayOpen}
|
||||||
<LayoutCol class="tools" scrollableY={true}>
|
<LayoutCol class="tools" scrollableY={true}>
|
||||||
<WidgetLayout layout={$document.toolShelfLayout} />
|
<WidgetLayout layout={$document.toolShelfLayout} layoutTarget="ToolShelf" />
|
||||||
</LayoutCol>
|
</LayoutCol>
|
||||||
{:else}
|
{:else}
|
||||||
<LayoutRow class="spacer" />
|
<LayoutRow class="spacer" />
|
||||||
{/if}
|
{/if}
|
||||||
<LayoutCol class="tool-shelf-bottom-widgets">
|
<LayoutCol class="tool-shelf-bottom-widgets">
|
||||||
<WidgetLayout class="working-colors-input-area" layout={$document.workingColorsLayout} />
|
<WidgetLayout class="working-colors-input-area" layout={$document.workingColorsLayout} layoutTarget="WorkingColors" />
|
||||||
</LayoutCol>
|
</LayoutCol>
|
||||||
</LayoutCol>
|
</LayoutCol>
|
||||||
<LayoutCol class="viewport-container">
|
<LayoutCol class="viewport-container">
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
import { shortcutAltClick } from "@graphite/../wasm/pkg/graphite_wasm";
|
import { shortcutAltClick } from "@graphite/../wasm/pkg/graphite_wasm";
|
||||||
import type { Editor } from "@graphite/editor";
|
import type { Editor } from "@graphite/editor";
|
||||||
import {
|
import {
|
||||||
defaultWidgetLayout,
|
|
||||||
patchWidgetLayout,
|
patchWidgetLayout,
|
||||||
UpdateDocumentLayerDetails,
|
UpdateDocumentLayerDetails,
|
||||||
UpdateDocumentLayerStructureJs,
|
UpdateDocumentLayerStructureJs,
|
||||||
@@ -12,7 +11,7 @@
|
|||||||
UpdateLayersPanelControlBarRightLayout,
|
UpdateLayersPanelControlBarRightLayout,
|
||||||
UpdateLayersPanelBottomBarLayout,
|
UpdateLayersPanelBottomBarLayout,
|
||||||
} from "@graphite/messages";
|
} from "@graphite/messages";
|
||||||
import type { ActionShortcut, DataBuffer, LayerPanelEntry } from "@graphite/messages";
|
import type { ActionShortcut, DataBuffer, LayerPanelEntry, LayoutGroup } from "@graphite/messages";
|
||||||
import type { NodeGraphState } from "@graphite/state-providers/node-graph";
|
import type { NodeGraphState } from "@graphite/state-providers/node-graph";
|
||||||
import { operatingSystem } from "@graphite/utility-functions/platform";
|
import { operatingSystem } from "@graphite/utility-functions/platform";
|
||||||
import { extractPixelData } from "@graphite/utility-functions/rasterization";
|
import { extractPixelData } from "@graphite/utility-functions/rasterization";
|
||||||
@@ -70,9 +69,9 @@
|
|||||||
let layerToClipAltKeyPressed = false;
|
let layerToClipAltKeyPressed = false;
|
||||||
|
|
||||||
// Layouts
|
// Layouts
|
||||||
let layersPanelControlBarLeftLayout = defaultWidgetLayout();
|
let layersPanelControlBarLeftLayout: LayoutGroup[] = [];
|
||||||
let layersPanelControlBarRightLayout = defaultWidgetLayout();
|
let layersPanelControlBarRightLayout: LayoutGroup[] = [];
|
||||||
let layersPanelBottomBarLayout = defaultWidgetLayout();
|
let layersPanelBottomBarLayout: LayoutGroup[] = [];
|
||||||
|
|
||||||
const altClickKeys: ActionShortcut = shortcutAltClick();
|
const altClickKeys: ActionShortcut = shortcutAltClick();
|
||||||
|
|
||||||
@@ -582,11 +581,11 @@
|
|||||||
|
|
||||||
<LayoutCol class="layers" on:dragleave={() => (dragInPanel = false)}>
|
<LayoutCol class="layers" on:dragleave={() => (dragInPanel = false)}>
|
||||||
<LayoutRow class="control-bar" scrollableX={true}>
|
<LayoutRow class="control-bar" scrollableX={true}>
|
||||||
<WidgetLayout layout={layersPanelControlBarLeftLayout} />
|
<WidgetLayout layout={layersPanelControlBarLeftLayout} layoutTarget="LayersPanelControlLeftBar" />
|
||||||
{#if layersPanelControlBarLeftLayout?.layout?.length > 0 && layersPanelControlBarRightLayout?.layout?.length > 0}
|
{#if layersPanelControlBarLeftLayout?.length > 0 && layersPanelControlBarRightLayout?.length > 0}
|
||||||
<Separator />
|
<Separator />
|
||||||
{/if}
|
{/if}
|
||||||
<WidgetLayout layout={layersPanelControlBarRightLayout} />
|
<WidgetLayout layout={layersPanelControlBarRightLayout} layoutTarget="LayersPanelControlRightBar" />
|
||||||
</LayoutRow>
|
</LayoutRow>
|
||||||
<LayoutRow class="list-area" classes={{ "drag-ongoing": Boolean(internalDragState?.active && draggingData) }} scrollableY={true}>
|
<LayoutRow class="list-area" classes={{ "drag-ongoing": Boolean(internalDragState?.active && draggingData) }} scrollableY={true}>
|
||||||
<LayoutCol
|
<LayoutCol
|
||||||
@@ -691,7 +690,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</LayoutRow>
|
</LayoutRow>
|
||||||
<LayoutRow class="bottom-bar" scrollableX={true}>
|
<LayoutRow class="bottom-bar" scrollableX={true}>
|
||||||
<WidgetLayout layout={layersPanelBottomBarLayout} />
|
<WidgetLayout layout={layersPanelBottomBarLayout} layoutTarget="LayersPanelBottomBar" />
|
||||||
</LayoutRow>
|
</LayoutRow>
|
||||||
</LayoutCol>
|
</LayoutCol>
|
||||||
|
|
||||||
|
|||||||
@@ -2,14 +2,14 @@
|
|||||||
import { getContext, onMount, onDestroy } from "svelte";
|
import { getContext, onMount, onDestroy } from "svelte";
|
||||||
|
|
||||||
import type { Editor } from "@graphite/editor";
|
import type { Editor } from "@graphite/editor";
|
||||||
import { defaultWidgetLayout, patchWidgetLayout, UpdatePropertiesPanelLayout } from "@graphite/messages";
|
import { patchWidgetLayout, UpdatePropertiesPanelLayout, type LayoutGroup } from "@graphite/messages";
|
||||||
|
|
||||||
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
||||||
import WidgetLayout from "@graphite/components/widgets/WidgetLayout.svelte";
|
import WidgetLayout from "@graphite/components/widgets/WidgetLayout.svelte";
|
||||||
|
|
||||||
const editor = getContext<Editor>("editor");
|
const editor = getContext<Editor>("editor");
|
||||||
|
|
||||||
let propertiesPanelLayout = defaultWidgetLayout();
|
let propertiesPanelLayout: LayoutGroup[] = [];
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
editor.subscriptions.subscribeJsMessage(UpdatePropertiesPanelLayout, (updatePropertiesPanelLayout) => {
|
editor.subscriptions.subscribeJsMessage(UpdatePropertiesPanelLayout, (updatePropertiesPanelLayout) => {
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
<LayoutCol class="properties">
|
<LayoutCol class="properties">
|
||||||
<LayoutCol class="sections" scrollableY={true}>
|
<LayoutCol class="sections" scrollableY={true}>
|
||||||
<WidgetLayout layout={propertiesPanelLayout} />
|
<WidgetLayout layout={propertiesPanelLayout} layoutTarget="PropertiesPanel" />
|
||||||
</LayoutCol>
|
</LayoutCol>
|
||||||
</LayoutCol>
|
</LayoutCol>
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
import { getContext, onMount, onDestroy } from "svelte";
|
import { getContext, onMount, onDestroy } from "svelte";
|
||||||
|
|
||||||
import type { Editor } from "@graphite/editor";
|
import type { Editor } from "@graphite/editor";
|
||||||
import { defaultWidgetLayout, patchWidgetLayout, UpdateWelcomeScreenButtonsLayout } from "@graphite/messages";
|
import type { LayoutGroup } from "@graphite/messages";
|
||||||
|
import { patchWidgetLayout, UpdateWelcomeScreenButtonsLayout } from "@graphite/messages";
|
||||||
import { extractPixelData } from "@graphite/utility-functions/rasterization";
|
import { extractPixelData } from "@graphite/utility-functions/rasterization";
|
||||||
|
|
||||||
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
||||||
@@ -13,7 +14,7 @@
|
|||||||
|
|
||||||
const editor = getContext<Editor>("editor");
|
const editor = getContext<Editor>("editor");
|
||||||
|
|
||||||
let welcomePanelButtonsLayout = defaultWidgetLayout();
|
let welcomePanelButtonsLayout: LayoutGroup[] = [];
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
editor.subscriptions.subscribeJsMessage(UpdateWelcomeScreenButtonsLayout, (updateWelcomeScreenButtonsLayout) => {
|
editor.subscriptions.subscribeJsMessage(UpdateWelcomeScreenButtonsLayout, (updateWelcomeScreenButtonsLayout) => {
|
||||||
@@ -68,7 +69,7 @@
|
|||||||
<IconLabel icon="GraphiteLogotypeSolid" />
|
<IconLabel icon="GraphiteLogotypeSolid" />
|
||||||
</LayoutRow>
|
</LayoutRow>
|
||||||
<LayoutRow class="actions">
|
<LayoutRow class="actions">
|
||||||
<WidgetLayout layout={welcomePanelButtonsLayout} />
|
<WidgetLayout layout={welcomePanelButtonsLayout} layoutTarget="WelcomeScreenButtons" />
|
||||||
</LayoutRow>
|
</LayoutRow>
|
||||||
</LayoutCol>
|
</LayoutCol>
|
||||||
</LayoutCol>
|
</LayoutCol>
|
||||||
|
|||||||
@@ -1,26 +1,24 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { isWidgetSpanColumn, isWidgetSpanRow, isWidgetSection, type WidgetLayout, isWidgetTable } from "@graphite/messages";
|
import { isWidgetSpanColumn, isWidgetSpanRow, isWidgetSection, type LayoutGroup, isWidgetTable, type LayoutTarget } from "@graphite/messages";
|
||||||
|
|
||||||
import TextLabel from "@graphite/components/widgets/labels/TextLabel.svelte";
|
|
||||||
import WidgetSection from "@graphite/components/widgets/WidgetSection.svelte";
|
import WidgetSection from "@graphite/components/widgets/WidgetSection.svelte";
|
||||||
import WidgetSpan from "@graphite/components/widgets/WidgetSpan.svelte";
|
import WidgetSpan from "@graphite/components/widgets/WidgetSpan.svelte";
|
||||||
import WidgetTable from "@graphite/components/widgets/WidgetTable.svelte";
|
import WidgetTable from "@graphite/components/widgets/WidgetTable.svelte";
|
||||||
|
|
||||||
export let layout: WidgetLayout;
|
export let layout: LayoutGroup[];
|
||||||
|
export let layoutTarget: LayoutTarget;
|
||||||
let className = "";
|
let className = "";
|
||||||
export { className as class };
|
export { className as class };
|
||||||
export let classes: Record<string, boolean> = {};
|
export let classes: Record<string, boolean> = {};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#each layout.layout as layoutGroup}
|
{#each layout as layoutGroup}
|
||||||
{#if isWidgetSpanRow(layoutGroup) || isWidgetSpanColumn(layoutGroup)}
|
{#if isWidgetSpanRow(layoutGroup) || isWidgetSpanColumn(layoutGroup)}
|
||||||
<WidgetSpan widgetData={layoutGroup} layoutTarget={layout.layoutTarget} class={className} {classes} />
|
<WidgetSpan widgetData={layoutGroup} {layoutTarget} class={className} {classes} />
|
||||||
{:else if isWidgetSection(layoutGroup)}
|
{:else if isWidgetSection(layoutGroup)}
|
||||||
<WidgetSection widgetData={layoutGroup} layoutTarget={layout.layoutTarget} class={className} {classes} />
|
<WidgetSection widgetData={layoutGroup} {layoutTarget} class={className} {classes} />
|
||||||
{:else if isWidgetTable(layoutGroup)}
|
{:else if isWidgetTable(layoutGroup)}
|
||||||
<WidgetTable widgetData={layoutGroup} unstyled={layoutGroup.unstyled} layoutTarget={layout.layoutTarget} />
|
<WidgetTable widgetData={layoutGroup} {layoutTarget} unstyled={layoutGroup.unstyled} />
|
||||||
{:else}
|
|
||||||
<TextLabel styles={{ color: "#d6536e" }}>Error: The widget layout that belongs here has an invalid layout group type</TextLabel>
|
|
||||||
{/if}
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import { getContext } from "svelte";
|
import { getContext } from "svelte";
|
||||||
|
|
||||||
import type { Editor } from "@graphite/editor";
|
import type { Editor } from "@graphite/editor";
|
||||||
import { isWidgetSpanRow, isWidgetSpanColumn, isWidgetSection, type WidgetSection as WidgetSectionFromJsMessages } from "@graphite/messages";
|
import { isWidgetSpanRow, isWidgetSection, type WidgetSection as WidgetSectionFromJsMessages, type LayoutTarget } from "@graphite/messages";
|
||||||
|
|
||||||
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
|
||||||
import IconButton from "@graphite/components/widgets/buttons/IconButton.svelte";
|
import IconButton from "@graphite/components/widgets/buttons/IconButton.svelte";
|
||||||
@@ -10,8 +10,7 @@
|
|||||||
import WidgetSpan from "@graphite/components/widgets/WidgetSpan.svelte";
|
import WidgetSpan from "@graphite/components/widgets/WidgetSpan.svelte";
|
||||||
|
|
||||||
export let widgetData: WidgetSectionFromJsMessages;
|
export let widgetData: WidgetSectionFromJsMessages;
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
export let layoutTarget: LayoutTarget;
|
||||||
export let layoutTarget: any; // TODO: Give type
|
|
||||||
|
|
||||||
let className = "";
|
let className = "";
|
||||||
export { className as class };
|
export { className as class };
|
||||||
@@ -64,12 +63,8 @@
|
|||||||
{#each widgetData.layout as layoutGroup}
|
{#each widgetData.layout as layoutGroup}
|
||||||
{#if isWidgetSpanRow(layoutGroup)}
|
{#if isWidgetSpanRow(layoutGroup)}
|
||||||
<WidgetSpan widgetData={layoutGroup} {layoutTarget} />
|
<WidgetSpan widgetData={layoutGroup} {layoutTarget} />
|
||||||
{:else if isWidgetSpanColumn(layoutGroup)}
|
|
||||||
<TextLabel styles={{ color: "#d6536e" }}>Error: The WidgetSpan used here should be a row not a column</TextLabel>
|
|
||||||
{:else if isWidgetSection(layoutGroup)}
|
{:else if isWidgetSection(layoutGroup)}
|
||||||
<svelte:self widgetData={layoutGroup} {layoutTarget} />
|
<svelte:self widgetData={layoutGroup} {layoutTarget} />
|
||||||
{:else}
|
|
||||||
<TextLabel styles={{ color: "#d6536e" }}>Error: The widget that belongs here has an invalid layout group type</TextLabel>
|
|
||||||
{/if}
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
</LayoutCol>
|
</LayoutCol>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import { getContext } from "svelte";
|
import { getContext } from "svelte";
|
||||||
|
|
||||||
import type { Editor } from "@graphite/editor";
|
import type { Editor } from "@graphite/editor";
|
||||||
import type { Widget, WidgetSpanColumn, WidgetSpanRow } from "@graphite/messages";
|
import type { LayoutTarget, Widget, WidgetSpanColumn, WidgetSpanRow } from "@graphite/messages";
|
||||||
import { narrowWidgetProps, isWidgetSpanColumn, isWidgetSpanRow } from "@graphite/messages";
|
import { narrowWidgetProps, isWidgetSpanColumn, isWidgetSpanRow } from "@graphite/messages";
|
||||||
import { debouncer } from "@graphite/utility-functions/debounce";
|
import { debouncer } from "@graphite/utility-functions/debounce";
|
||||||
|
|
||||||
@@ -34,8 +34,7 @@
|
|||||||
const editor = getContext<Editor>("editor");
|
const editor = getContext<Editor>("editor");
|
||||||
|
|
||||||
export let widgetData: WidgetSpanRow | WidgetSpanColumn;
|
export let widgetData: WidgetSpanRow | WidgetSpanColumn;
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
export let layoutTarget: LayoutTarget;
|
||||||
export let layoutTarget: any;
|
|
||||||
|
|
||||||
let className = "";
|
let className = "";
|
||||||
export { className as class };
|
export { className as class };
|
||||||
@@ -162,7 +161,7 @@
|
|||||||
{@const popoverButton = narrowWidgetProps(component.props, "PopoverButton")}
|
{@const popoverButton = narrowWidgetProps(component.props, "PopoverButton")}
|
||||||
{#if popoverButton}
|
{#if popoverButton}
|
||||||
<PopoverButton {...exclude(popoverButton, ["popoverLayout"])}>
|
<PopoverButton {...exclude(popoverButton, ["popoverLayout"])}>
|
||||||
<WidgetLayout layout={{ layout: popoverButton.popoverLayout, layoutTarget: layoutTarget }} />
|
<WidgetLayout layout={popoverButton.popoverLayout} {layoutTarget} />
|
||||||
</PopoverButton>
|
</PopoverButton>
|
||||||
{/if}
|
{/if}
|
||||||
{@const radioInput = narrowWidgetProps(component.props, "RadioInput")}
|
{@const radioInput = narrowWidgetProps(component.props, "RadioInput")}
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { type WidgetTable as WidgetTableFromJsMessages } from "@graphite/messages";
|
import { type LayoutTarget, type WidgetTable as WidgetTableFromJsMessages } from "@graphite/messages";
|
||||||
|
|
||||||
import WidgetSpan from "@graphite/components/widgets/WidgetSpan.svelte";
|
import WidgetSpan from "@graphite/components/widgets/WidgetSpan.svelte";
|
||||||
|
|
||||||
export let widgetData: WidgetTableFromJsMessages;
|
export let widgetData: WidgetTableFromJsMessages;
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
export let layoutTarget: LayoutTarget;
|
||||||
export let layoutTarget: any;
|
|
||||||
export let unstyled = false;
|
export let unstyled = false;
|
||||||
|
|
||||||
$: columns = widgetData.tableWidgets.length > 0 ? widgetData.tableWidgets[0].length : 0;
|
$: columns = widgetData.tableWidgets.length > 0 ? widgetData.tableWidgets[0].length : 0;
|
||||||
|
|||||||
@@ -2,14 +2,15 @@
|
|||||||
import { getContext, onMount } from "svelte";
|
import { getContext, onMount } from "svelte";
|
||||||
|
|
||||||
import type { Editor } from "@graphite/editor";
|
import type { Editor } from "@graphite/editor";
|
||||||
import { defaultWidgetLayout, patchWidgetLayout, UpdateStatusBarHintsLayout } from "@graphite/messages";
|
import type { LayoutGroup } from "@graphite/messages";
|
||||||
|
import { patchWidgetLayout, UpdateStatusBarHintsLayout } from "@graphite/messages";
|
||||||
|
|
||||||
import LayoutRow from "@graphite/components/layout/LayoutRow.svelte";
|
import LayoutRow from "@graphite/components/layout/LayoutRow.svelte";
|
||||||
import WidgetLayout from "@graphite/components/widgets/WidgetLayout.svelte";
|
import WidgetLayout from "@graphite/components/widgets/WidgetLayout.svelte";
|
||||||
|
|
||||||
const editor = getContext<Editor>("editor");
|
const editor = getContext<Editor>("editor");
|
||||||
|
|
||||||
let statusBarHintsLayout = defaultWidgetLayout();
|
let statusBarHintsLayout: LayoutGroup[] = [];
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
editor.subscriptions.subscribeJsMessage(UpdateStatusBarHintsLayout, (updateStatusBarHintsLayout) => {
|
editor.subscriptions.subscribeJsMessage(UpdateStatusBarHintsLayout, (updateStatusBarHintsLayout) => {
|
||||||
@@ -20,7 +21,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<LayoutRow class="status-bar">
|
<LayoutRow class="status-bar">
|
||||||
<WidgetLayout class="hints" layout={statusBarHintsLayout} />
|
<WidgetLayout class="hints" layout={statusBarHintsLayout} layoutTarget="StatusBarHints" />
|
||||||
</LayoutRow>
|
</LayoutRow>
|
||||||
|
|
||||||
<style lang="scss" global>
|
<style lang="scss" global>
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
import { getContext, onMount } from "svelte";
|
import { getContext, onMount } from "svelte";
|
||||||
|
|
||||||
import type { Editor } from "@graphite/editor";
|
import type { Editor } from "@graphite/editor";
|
||||||
import { defaultWidgetLayout, patchWidgetLayout, UpdateMenuBarLayout } from "@graphite/messages";
|
import type { LayoutGroup } from "@graphite/messages";
|
||||||
|
import { patchWidgetLayout, UpdateMenuBarLayout } from "@graphite/messages";
|
||||||
import type { AppWindowState } from "@graphite/state-providers/app-window";
|
import type { AppWindowState } from "@graphite/state-providers/app-window";
|
||||||
|
|
||||||
import LayoutRow from "@graphite/components/layout/LayoutRow.svelte";
|
import LayoutRow from "@graphite/components/layout/LayoutRow.svelte";
|
||||||
@@ -14,7 +15,7 @@
|
|||||||
const appWindow = getContext<AppWindowState>("appWindow");
|
const appWindow = getContext<AppWindowState>("appWindow");
|
||||||
const editor = getContext<Editor>("editor");
|
const editor = getContext<Editor>("editor");
|
||||||
|
|
||||||
let menuBarLayout = defaultWidgetLayout();
|
let menuBarLayout: LayoutGroup[] = [];
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
editor.subscriptions.subscribeJsMessage(UpdateMenuBarLayout, (updateMenuBarLayout) => {
|
editor.subscriptions.subscribeJsMessage(UpdateMenuBarLayout, (updateMenuBarLayout) => {
|
||||||
@@ -28,7 +29,7 @@
|
|||||||
<!-- Menu bar -->
|
<!-- Menu bar -->
|
||||||
<LayoutRow>
|
<LayoutRow>
|
||||||
{#if $appWindow.platform !== "Mac"}
|
{#if $appWindow.platform !== "Mac"}
|
||||||
<WidgetLayout layout={menuBarLayout} />
|
<WidgetLayout layout={menuBarLayout} layoutTarget="MenuBar" />
|
||||||
{/if}
|
{/if}
|
||||||
</LayoutRow>
|
</LayoutRow>
|
||||||
<!-- Spacer -->
|
<!-- Spacer -->
|
||||||
|
|||||||
+23
-20
@@ -1485,33 +1485,36 @@ function hoistWidgetInstances(widgetInstance: any[]): Widget[] {
|
|||||||
|
|
||||||
// WIDGET LAYOUT
|
// WIDGET LAYOUT
|
||||||
|
|
||||||
export type WidgetLayout = {
|
export type LayoutTarget =
|
||||||
layoutTarget: unknown;
|
| "DataPanel"
|
||||||
layout: LayoutGroup[];
|
| "DialogButtons"
|
||||||
};
|
| "DialogColumn1"
|
||||||
|
| "DialogColumn2"
|
||||||
|
| "DocumentBar"
|
||||||
|
| "DocumentMode"
|
||||||
|
| "LayersPanelBottomBar"
|
||||||
|
| "LayersPanelControlLeftBar"
|
||||||
|
| "LayersPanelControlRightBar"
|
||||||
|
| "MenuBar"
|
||||||
|
| "NodeGraphControlBar"
|
||||||
|
| "PropertiesPanel"
|
||||||
|
| "StatusBarHints"
|
||||||
|
| "ToolOptions"
|
||||||
|
| "ToolShelf"
|
||||||
|
| "WelcomeScreenButtons"
|
||||||
|
| "WorkingColors";
|
||||||
|
|
||||||
export class WidgetDiffUpdate extends JsMessage {
|
export class WidgetDiffUpdate extends JsMessage {
|
||||||
layoutTarget!: unknown;
|
|
||||||
|
|
||||||
// TODO: Replace `any` with correct typing
|
// TODO: Replace `any` with correct typing
|
||||||
@Transform(({ value }: { value: any }) => createWidgetDiff(value))
|
@Transform(({ value }: { value: any }) => createWidgetDiff(value))
|
||||||
diff!: WidgetDiff[];
|
diff!: WidgetDiff[];
|
||||||
}
|
}
|
||||||
|
|
||||||
type UIItem = LayoutGroup[] | LayoutGroup | Widget | Widget[];
|
type UIItem = LayoutGroup[] | LayoutGroup | Widget[] | Widget;
|
||||||
type WidgetDiff = { widgetPath: number[]; newValue: UIItem };
|
type WidgetDiff = { widgetPath: number[]; newValue: UIItem };
|
||||||
|
|
||||||
export function defaultWidgetLayout(): WidgetLayout {
|
|
||||||
return {
|
|
||||||
layoutTarget: undefined,
|
|
||||||
layout: [],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Updates a widget layout based on a list of updates, giving the new layout by mutating the `layout` argument
|
// Updates a widget layout based on a list of updates, giving the new layout by mutating the `layout` argument
|
||||||
export function patchWidgetLayout(layout: /* &mut */ WidgetLayout, updates: WidgetDiffUpdate) {
|
export function patchWidgetLayout(layout: /* &mut */ LayoutGroup[], updates: WidgetDiffUpdate) {
|
||||||
layout.layoutTarget = updates.layoutTarget;
|
|
||||||
|
|
||||||
updates.diff.forEach((update) => {
|
updates.diff.forEach((update) => {
|
||||||
// Find the object where the diff applies to
|
// Find the object where the diff applies to
|
||||||
const diffObject = update.widgetPath.reduce((targetLayout: UIItem | undefined, index: number): UIItem | undefined => {
|
const diffObject = update.widgetPath.reduce((targetLayout: UIItem | undefined, index: number): UIItem | undefined => {
|
||||||
@@ -1529,7 +1532,7 @@ export function patchWidgetLayout(layout: /* &mut */ WidgetLayout, updates: Widg
|
|||||||
}
|
}
|
||||||
|
|
||||||
return targetLayout?.[index];
|
return targetLayout?.[index];
|
||||||
}, layout.layout as UIItem);
|
}, layout as UIItem);
|
||||||
|
|
||||||
// Exit if we failed to produce a valid patch for the existing layout.
|
// Exit if we failed to produce a valid patch for the existing layout.
|
||||||
// This means that the backend assumed an existing layout that doesn't exist in the frontend. This can happen, for
|
// This means that the backend assumed an existing layout that doesn't exist in the frontend. This can happen, for
|
||||||
@@ -1581,8 +1584,8 @@ export function isWidgetSection(layoutRow: LayoutGroup): layoutRow is WidgetSect
|
|||||||
function createWidgetDiff(diffs: any[]): WidgetDiff[] {
|
function createWidgetDiff(diffs: any[]): WidgetDiff[] {
|
||||||
return diffs.map((diff) => {
|
return diffs.map((diff) => {
|
||||||
const { widgetPath, newValue } = diff;
|
const { widgetPath, newValue } = diff;
|
||||||
if (newValue.subLayout) {
|
if (newValue.widgetLayout) {
|
||||||
return { widgetPath, newValue: newValue.subLayout.map(createLayoutGroup) };
|
return { widgetPath, newValue: newValue.widgetLayout.map(createLayoutGroup) };
|
||||||
}
|
}
|
||||||
if (newValue.layoutGroup) {
|
if (newValue.layoutGroup) {
|
||||||
return { widgetPath, newValue: createLayoutGroup(newValue.layoutGroup) };
|
return { widgetPath, newValue: createLayoutGroup(newValue.layoutGroup) };
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { writable } from "svelte/store";
|
|||||||
import { type Editor } from "@graphite/editor";
|
import { type Editor } from "@graphite/editor";
|
||||||
import { type IconName } from "@graphite/icons";
|
import { type IconName } from "@graphite/icons";
|
||||||
import {
|
import {
|
||||||
defaultWidgetLayout,
|
|
||||||
DisplayDialog,
|
DisplayDialog,
|
||||||
DisplayDialogDismiss,
|
DisplayDialogDismiss,
|
||||||
UpdateDialogButtons,
|
UpdateDialogButtons,
|
||||||
@@ -11,6 +10,7 @@ import {
|
|||||||
UpdateDialogColumn2,
|
UpdateDialogColumn2,
|
||||||
patchWidgetLayout,
|
patchWidgetLayout,
|
||||||
TriggerDisplayThirdPartyLicensesDialog,
|
TriggerDisplayThirdPartyLicensesDialog,
|
||||||
|
type LayoutGroup,
|
||||||
} from "@graphite/messages";
|
} from "@graphite/messages";
|
||||||
|
|
||||||
export function createDialogState(editor: Editor) {
|
export function createDialogState(editor: Editor) {
|
||||||
@@ -18,9 +18,9 @@ export function createDialogState(editor: Editor) {
|
|||||||
visible: false,
|
visible: false,
|
||||||
title: "",
|
title: "",
|
||||||
icon: "" as IconName,
|
icon: "" as IconName,
|
||||||
buttons: defaultWidgetLayout(),
|
buttons: [] as LayoutGroup[],
|
||||||
column1: defaultWidgetLayout(),
|
column1: [] as LayoutGroup[],
|
||||||
column2: defaultWidgetLayout(),
|
column2: [] as LayoutGroup[],
|
||||||
// Special case for the crash dialog because we cannot handle button widget callbacks from Rust once the editor has panicked
|
// Special case for the crash dialog because we cannot handle button widget callbacks from Rust once the editor has panicked
|
||||||
panicDetails: "",
|
panicDetails: "",
|
||||||
});
|
});
|
||||||
@@ -44,9 +44,9 @@ export function createDialogState(editor: Editor) {
|
|||||||
state.title = "Crash";
|
state.title = "Crash";
|
||||||
state.panicDetails = panicDetails;
|
state.panicDetails = panicDetails;
|
||||||
|
|
||||||
state.column1 = defaultWidgetLayout();
|
state.column1 = [];
|
||||||
state.column2 = defaultWidgetLayout();
|
state.column2 = [];
|
||||||
state.buttons = defaultWidgetLayout();
|
state.buttons = [];
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import { writable } from "svelte/store";
|
|||||||
import { type Editor } from "@graphite/editor";
|
import { type Editor } from "@graphite/editor";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
defaultWidgetLayout,
|
|
||||||
patchWidgetLayout,
|
patchWidgetLayout,
|
||||||
UpdateDocumentBarLayout,
|
UpdateDocumentBarLayout,
|
||||||
UpdateDocumentModeLayout,
|
UpdateDocumentModeLayout,
|
||||||
@@ -14,17 +13,18 @@ import {
|
|||||||
UpdateNodeGraphControlBarLayout,
|
UpdateNodeGraphControlBarLayout,
|
||||||
UpdateGraphViewOverlay,
|
UpdateGraphViewOverlay,
|
||||||
UpdateGraphFadeArtwork,
|
UpdateGraphFadeArtwork,
|
||||||
|
type LayoutGroup,
|
||||||
} from "@graphite/messages";
|
} from "@graphite/messages";
|
||||||
|
|
||||||
export function createDocumentState(editor: Editor) {
|
export function createDocumentState(editor: Editor) {
|
||||||
const state = writable({
|
const state = writable({
|
||||||
// Layouts
|
// Layouts
|
||||||
documentModeLayout: defaultWidgetLayout(),
|
documentModeLayout: [] as LayoutGroup[],
|
||||||
toolOptionsLayout: defaultWidgetLayout(),
|
toolOptionsLayout: [] as LayoutGroup[],
|
||||||
documentBarLayout: defaultWidgetLayout(),
|
documentBarLayout: [] as LayoutGroup[],
|
||||||
toolShelfLayout: defaultWidgetLayout(),
|
toolShelfLayout: [] as LayoutGroup[],
|
||||||
workingColorsLayout: defaultWidgetLayout(),
|
workingColorsLayout: [] as LayoutGroup[],
|
||||||
nodeGraphControlBarLayout: defaultWidgetLayout(),
|
nodeGraphControlBarLayout: [] as LayoutGroup[],
|
||||||
// Graph view overlay
|
// Graph view overlay
|
||||||
graphViewOverlayOpen: false,
|
graphViewOverlayOpen: false,
|
||||||
fadeArtwork: 100,
|
fadeArtwork: 100,
|
||||||
|
|||||||
Reference in New Issue
Block a user