mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-26 12:08:11 +08:00
Replace responses.push() with responses.add() everywhere (#1186)
This commit is contained in:
@@ -76,7 +76,7 @@ impl Dispatcher {
|
|||||||
} else if self.message_queues.len() > 1 {
|
} else if self.message_queues.len() > 1 {
|
||||||
self.log_deferred_message(&message, &self.message_queues, self.message_handlers.debug_message_handler.message_logging_verbosity);
|
self.log_deferred_message(&message, &self.message_queues, self.message_handlers.debug_message_handler.message_logging_verbosity);
|
||||||
self.cleanup_queues(true);
|
self.cleanup_queues(true);
|
||||||
self.message_queues[0].push_back(message);
|
self.message_queues[0].add(message);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -95,15 +95,15 @@ impl Dispatcher {
|
|||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
Init => {
|
Init => {
|
||||||
// Load persistent data from the browser database
|
// Load persistent data from the browser database
|
||||||
queue.push_back(FrontendMessage::TriggerLoadAutoSaveDocuments.into());
|
queue.add(FrontendMessage::TriggerLoadAutoSaveDocuments);
|
||||||
queue.push_back(FrontendMessage::TriggerLoadPreferences.into());
|
queue.add(FrontendMessage::TriggerLoadPreferences);
|
||||||
|
|
||||||
// Display the menu bar at the top of the window
|
// Display the menu bar at the top of the window
|
||||||
queue.push_back(MenuBarMessage::SendLayout.into());
|
queue.add(MenuBarMessage::SendLayout);
|
||||||
|
|
||||||
// Load the default font
|
// Load the default font
|
||||||
let font = Font::new(DEFAULT_FONT_FAMILY.into(), DEFAULT_FONT_STYLE.into());
|
let font = Font::new(DEFAULT_FONT_FAMILY.into(), DEFAULT_FONT_STYLE.into());
|
||||||
queue.push_back(FrontendMessage::TriggerFontLoad { font, is_default: true }.into());
|
queue.add(FrontendMessage::TriggerFontLoad { font, is_default: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
Broadcast(message) => self.message_handlers.broadcast_message_handler.process_message(message, &mut queue, ()),
|
Broadcast(message) => self.message_handlers.broadcast_message_handler.process_message(message, &mut queue, ()),
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ impl MessageHandler<BroadcastMessage, ()> for BroadcastMessageHandler {
|
|||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
BroadcastMessage::TriggerEvent(event) => {
|
BroadcastMessage::TriggerEvent(event) => {
|
||||||
for message in self.listeners.entry(event).or_default() {
|
for message in self.listeners.entry(event).or_default() {
|
||||||
responses.push_front(message.clone())
|
responses.add_front(message.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,25 +18,25 @@ impl MessageHandler<DebugMessage, ()> for DebugMessageHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Refresh the checkmark beside the menu entry for this
|
// Refresh the checkmark beside the menu entry for this
|
||||||
responses.push_back(MenuBarMessage::SendLayout.into());
|
responses.add(MenuBarMessage::SendLayout);
|
||||||
}
|
}
|
||||||
DebugMessage::MessageOff => {
|
DebugMessage::MessageOff => {
|
||||||
self.message_logging_verbosity = MessageLoggingVerbosity::Off;
|
self.message_logging_verbosity = MessageLoggingVerbosity::Off;
|
||||||
|
|
||||||
// Refresh the checkmark beside the menu entry for this
|
// Refresh the checkmark beside the menu entry for this
|
||||||
responses.push_back(MenuBarMessage::SendLayout.into());
|
responses.add(MenuBarMessage::SendLayout);
|
||||||
}
|
}
|
||||||
DebugMessage::MessageNames => {
|
DebugMessage::MessageNames => {
|
||||||
self.message_logging_verbosity = MessageLoggingVerbosity::Names;
|
self.message_logging_verbosity = MessageLoggingVerbosity::Names;
|
||||||
|
|
||||||
// Refresh the checkmark beside the menu entry for this
|
// Refresh the checkmark beside the menu entry for this
|
||||||
responses.push_back(MenuBarMessage::SendLayout.into());
|
responses.add(MenuBarMessage::SendLayout);
|
||||||
}
|
}
|
||||||
DebugMessage::MessageContents => {
|
DebugMessage::MessageContents => {
|
||||||
self.message_logging_verbosity = MessageLoggingVerbosity::Contents;
|
self.message_logging_verbosity = MessageLoggingVerbosity::Contents;
|
||||||
|
|
||||||
// Refresh the checkmark beside the menu entry for this
|
// Refresh the checkmark beside the menu entry for this
|
||||||
responses.push_back(MenuBarMessage::SendLayout.into());
|
responses.add(MenuBarMessage::SendLayout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,37 +25,34 @@ impl MessageHandler<DialogMessage, (&PortfolioMessageHandler, &PreferencesMessag
|
|||||||
DialogMessage::CloseAllDocumentsWithConfirmation => {
|
DialogMessage::CloseAllDocumentsWithConfirmation => {
|
||||||
let dialog = simple_dialogs::CloseAllDocumentsDialog;
|
let dialog = simple_dialogs::CloseAllDocumentsDialog;
|
||||||
dialog.register_properties(responses, LayoutTarget::DialogDetails);
|
dialog.register_properties(responses, LayoutTarget::DialogDetails);
|
||||||
responses.push_back(FrontendMessage::DisplayDialog { icon: "Copy".to_string() }.into());
|
responses.add(FrontendMessage::DisplayDialog { icon: "Copy".to_string() });
|
||||||
}
|
}
|
||||||
DialogMessage::CloseDialogAndThen { followups } => {
|
DialogMessage::CloseDialogAndThen { followups } => {
|
||||||
responses.push_back(FrontendMessage::DisplayDialogDismiss.into());
|
responses.add(FrontendMessage::DisplayDialogDismiss);
|
||||||
for message in followups.into_iter() {
|
for message in followups.into_iter() {
|
||||||
responses.push_back(message);
|
responses.add(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DialogMessage::DisplayDialogError { title, description } => {
|
DialogMessage::DisplayDialogError { title, description } => {
|
||||||
let dialog = simple_dialogs::ErrorDialog { title, description };
|
let dialog = simple_dialogs::ErrorDialog { title, description };
|
||||||
dialog.register_properties(responses, LayoutTarget::DialogDetails);
|
dialog.register_properties(responses, LayoutTarget::DialogDetails);
|
||||||
responses.push_back(FrontendMessage::DisplayDialog { icon: "Warning".to_string() }.into());
|
responses.add(FrontendMessage::DisplayDialog { icon: "Warning".to_string() });
|
||||||
}
|
}
|
||||||
DialogMessage::RequestAboutGraphiteDialog => {
|
DialogMessage::RequestAboutGraphiteDialog => {
|
||||||
responses.push_back(
|
responses.add(FrontendMessage::TriggerAboutGraphiteLocalizedCommitDate {
|
||||||
FrontendMessage::TriggerAboutGraphiteLocalizedCommitDate {
|
commit_date: env!("GRAPHITE_GIT_COMMIT_DATE").into(),
|
||||||
commit_date: env!("GRAPHITE_GIT_COMMIT_DATE").into(),
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
DialogMessage::RequestAboutGraphiteDialogWithLocalizedCommitDate { localized_commit_date } => {
|
DialogMessage::RequestAboutGraphiteDialogWithLocalizedCommitDate { localized_commit_date } => {
|
||||||
let about_graphite = AboutGraphiteDialog { localized_commit_date };
|
let about_graphite = AboutGraphiteDialog { localized_commit_date };
|
||||||
|
|
||||||
about_graphite.register_properties(responses, LayoutTarget::DialogDetails);
|
about_graphite.register_properties(responses, LayoutTarget::DialogDetails);
|
||||||
responses.push_back(FrontendMessage::DisplayDialog { icon: "GraphiteLogo".to_string() }.into());
|
responses.add(FrontendMessage::DisplayDialog { icon: "GraphiteLogo".to_string() });
|
||||||
}
|
}
|
||||||
DialogMessage::RequestComingSoonDialog { issue } => {
|
DialogMessage::RequestComingSoonDialog { issue } => {
|
||||||
let coming_soon = ComingSoonDialog { issue };
|
let coming_soon = ComingSoonDialog { issue };
|
||||||
coming_soon.register_properties(responses, LayoutTarget::DialogDetails);
|
coming_soon.register_properties(responses, LayoutTarget::DialogDetails);
|
||||||
responses.push_back(FrontendMessage::DisplayDialog { icon: "Warning".to_string() }.into());
|
responses.add(FrontendMessage::DisplayDialog { icon: "Warning".to_string() });
|
||||||
}
|
}
|
||||||
DialogMessage::RequestExportDialog => {
|
DialogMessage::RequestExportDialog => {
|
||||||
if let Some(document) = portfolio.active_document() {
|
if let Some(document) = portfolio.active_document() {
|
||||||
@@ -88,7 +85,7 @@ impl MessageHandler<DialogMessage, (&PortfolioMessageHandler, &PreferencesMessag
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
self.export_dialog.register_properties(responses, LayoutTarget::DialogDetails);
|
self.export_dialog.register_properties(responses, LayoutTarget::DialogDetails);
|
||||||
responses.push_back(FrontendMessage::DisplayDialog { icon: "File".to_string() }.into());
|
responses.add(FrontendMessage::DisplayDialog { icon: "File".to_string() });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DialogMessage::RequestNewDocumentDialog => {
|
DialogMessage::RequestNewDocumentDialog => {
|
||||||
@@ -98,12 +95,12 @@ impl MessageHandler<DialogMessage, (&PortfolioMessageHandler, &PreferencesMessag
|
|||||||
dimensions: glam::UVec2::new(1920, 1080),
|
dimensions: glam::UVec2::new(1920, 1080),
|
||||||
};
|
};
|
||||||
self.new_document_dialog.register_properties(responses, LayoutTarget::DialogDetails);
|
self.new_document_dialog.register_properties(responses, LayoutTarget::DialogDetails);
|
||||||
responses.push_back(FrontendMessage::DisplayDialog { icon: "File".to_string() }.into());
|
responses.add(FrontendMessage::DisplayDialog { icon: "File".to_string() });
|
||||||
}
|
}
|
||||||
DialogMessage::RequestPreferencesDialog => {
|
DialogMessage::RequestPreferencesDialog => {
|
||||||
self.preferences_dialog = PreferencesDialogMessageHandler {};
|
self.preferences_dialog = PreferencesDialogMessageHandler {};
|
||||||
self.preferences_dialog.register_properties(responses, LayoutTarget::DialogDetails, preferences);
|
self.preferences_dialog.register_properties(responses, LayoutTarget::DialogDetails, preferences);
|
||||||
responses.push_back(FrontendMessage::DisplayDialog { icon: "Settings".to_string() }.into());
|
responses.add(FrontendMessage::DisplayDialog { icon: "Settings".to_string() });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,15 +27,12 @@ impl MessageHandler<ExportDialogMessage, ()> for ExportDialogMessageHandler {
|
|||||||
ExportDialogMessage::ScaleFactor(x) => self.scale_factor = x,
|
ExportDialogMessage::ScaleFactor(x) => self.scale_factor = x,
|
||||||
ExportDialogMessage::ExportBounds(export_area) => self.bounds = export_area,
|
ExportDialogMessage::ExportBounds(export_area) => self.bounds = export_area,
|
||||||
|
|
||||||
ExportDialogMessage::Submit => responses.push_front(
|
ExportDialogMessage::Submit => responses.add_front(DocumentMessage::ExportDocument {
|
||||||
DocumentMessage::ExportDocument {
|
file_name: self.file_name.clone(),
|
||||||
file_name: self.file_name.clone(),
|
file_type: self.file_type,
|
||||||
file_type: self.file_type,
|
scale_factor: self.scale_factor,
|
||||||
scale_factor: self.scale_factor,
|
bounds: self.bounds,
|
||||||
bounds: self.bounds,
|
}),
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.register_properties(responses, LayoutTarget::DialogDetails);
|
self.register_properties(responses, LayoutTarget::DialogDetails);
|
||||||
|
|||||||
+7
-10
@@ -24,18 +24,15 @@ impl MessageHandler<NewDocumentDialogMessage, ()> for NewDocumentDialogMessageHa
|
|||||||
NewDocumentDialogMessage::DimensionsY(y) => self.dimensions.y = y as u32,
|
NewDocumentDialogMessage::DimensionsY(y) => self.dimensions.y = y as u32,
|
||||||
|
|
||||||
NewDocumentDialogMessage::Submit => {
|
NewDocumentDialogMessage::Submit => {
|
||||||
responses.push_back(PortfolioMessage::NewDocumentWithName { name: self.name.clone() }.into());
|
responses.add(PortfolioMessage::NewDocumentWithName { name: self.name.clone() });
|
||||||
|
|
||||||
if !self.infinite && self.dimensions.x > 0 && self.dimensions.y > 0 {
|
if !self.infinite && self.dimensions.x > 0 && self.dimensions.y > 0 {
|
||||||
responses.push_back(
|
responses.add(ArtboardMessage::AddArtboard {
|
||||||
ArtboardMessage::AddArtboard {
|
id: None,
|
||||||
id: None,
|
position: (0., 0.),
|
||||||
position: (0., 0.),
|
size: (self.dimensions.x as f64, self.dimensions.y as f64),
|
||||||
size: (self.dimensions.x as f64, self.dimensions.y as f64),
|
});
|
||||||
}
|
responses.add(DocumentMessage::ZoomCanvasToFitAll);
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
responses.push_back(DocumentMessage::ZoomCanvasToFitAll.into());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,13 +23,10 @@ impl MessageHandler<PreferencesDialogMessage, &PreferencesMessageHandler> for Pr
|
|||||||
|
|
||||||
impl PreferencesDialogMessageHandler {
|
impl PreferencesDialogMessageHandler {
|
||||||
pub fn register_properties(&self, responses: &mut VecDeque<Message>, layout_target: LayoutTarget, preferences: &PreferencesMessageHandler) {
|
pub fn register_properties(&self, responses: &mut VecDeque<Message>, layout_target: LayoutTarget, preferences: &PreferencesMessageHandler) {
|
||||||
responses.push_back(
|
responses.add(LayoutMessage::SendLayout {
|
||||||
LayoutMessage::SendLayout {
|
layout: self.properties(preferences),
|
||||||
layout: self.properties(preferences),
|
layout_target,
|
||||||
layout_target,
|
})
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn properties(&self, preferences: &PreferencesMessageHandler) -> Layout {
|
fn properties(&self, preferences: &PreferencesMessageHandler) -> Layout {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ pub struct InputMapperMessageHandler {
|
|||||||
impl MessageHandler<InputMapperMessage, (&InputPreprocessorMessageHandler, ActionList)> for InputMapperMessageHandler {
|
impl MessageHandler<InputMapperMessage, (&InputPreprocessorMessageHandler, ActionList)> for InputMapperMessageHandler {
|
||||||
fn process_message(&mut self, message: InputMapperMessage, responses: &mut VecDeque<Message>, (input, actions): (&InputPreprocessorMessageHandler, ActionList)) {
|
fn process_message(&mut self, message: InputMapperMessage, responses: &mut VecDeque<Message>, (input, actions): (&InputPreprocessorMessageHandler, ActionList)) {
|
||||||
if let Some(message) = self.mapping.match_input_message(message, &input.keyboard, actions) {
|
if let Some(message) = self.mapping.match_input_message(message, &input.keyboard, actions) {
|
||||||
responses.push_back(message);
|
responses.add(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
advertise_actions!();
|
advertise_actions!();
|
||||||
|
|||||||
@@ -92,8 +92,8 @@ impl MouseState {
|
|||||||
|
|
||||||
pub fn finish_transaction(&self, drag_start: DVec2, responses: &mut VecDeque<Message>) {
|
pub fn finish_transaction(&self, drag_start: DVec2, responses: &mut VecDeque<Message>) {
|
||||||
match drag_start.distance(self.position) <= DRAG_THRESHOLD {
|
match drag_start.distance(self.position) <= DRAG_THRESHOLD {
|
||||||
true => responses.push_back(DocumentMessage::AbortTransaction.into()),
|
true => responses.add(DocumentMessage::AbortTransaction),
|
||||||
false => responses.push_back(DocumentMessage::CommitTransaction.into()),
|
false => responses.add(DocumentMessage::CommitTransaction),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,24 +32,18 @@ impl MessageHandler<InputPreprocessorMessage, KeyboardPlatformLayout> for InputP
|
|||||||
// TODO: Extend this to multiple viewports instead of setting it to the value of this last loop iteration
|
// TODO: Extend this to multiple viewports instead of setting it to the value of this last loop iteration
|
||||||
self.viewport_bounds = bounds;
|
self.viewport_bounds = bounds;
|
||||||
|
|
||||||
responses.push_back(
|
responses.add(Operation::TransformLayer {
|
||||||
|
path: vec![],
|
||||||
|
transform: glam::DAffine2::from_translation(translation).to_cols_array(),
|
||||||
|
});
|
||||||
|
responses.add(DocumentMessage::Artboard(
|
||||||
Operation::TransformLayer {
|
Operation::TransformLayer {
|
||||||
path: vec![],
|
path: vec![],
|
||||||
transform: glam::DAffine2::from_translation(translation).to_cols_array(),
|
transform: glam::DAffine2::from_translation(translation).to_cols_array(),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
);
|
));
|
||||||
responses.push_back(
|
responses.add(FrontendMessage::TriggerViewportResize);
|
||||||
DocumentMessage::Artboard(
|
|
||||||
Operation::TransformLayer {
|
|
||||||
path: vec![],
|
|
||||||
transform: glam::DAffine2::from_translation(translation).to_cols_array(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
responses.push_back(FrontendMessage::TriggerViewportResize.into());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InputPreprocessorMessage::DoubleClick { editor_mouse_state, modifier_keys } => {
|
InputPreprocessorMessage::DoubleClick { editor_mouse_state, modifier_keys } => {
|
||||||
@@ -58,17 +52,17 @@ impl MessageHandler<InputPreprocessorMessage, KeyboardPlatformLayout> for InputP
|
|||||||
let mouse_state = editor_mouse_state.to_mouse_state(&self.viewport_bounds);
|
let mouse_state = editor_mouse_state.to_mouse_state(&self.viewport_bounds);
|
||||||
self.mouse.position = mouse_state.position;
|
self.mouse.position = mouse_state.position;
|
||||||
|
|
||||||
responses.push_back(InputMapperMessage::DoubleClick.into());
|
responses.add(InputMapperMessage::DoubleClick);
|
||||||
}
|
}
|
||||||
InputPreprocessorMessage::KeyDown { key, modifier_keys } => {
|
InputPreprocessorMessage::KeyDown { key, modifier_keys } => {
|
||||||
self.update_states_of_modifier_keys(modifier_keys, keyboard_platform, responses);
|
self.update_states_of_modifier_keys(modifier_keys, keyboard_platform, responses);
|
||||||
self.keyboard.set(key as usize);
|
self.keyboard.set(key as usize);
|
||||||
responses.push_back(InputMapperMessage::KeyDown(key).into());
|
responses.add(InputMapperMessage::KeyDown(key));
|
||||||
}
|
}
|
||||||
InputPreprocessorMessage::KeyUp { key, modifier_keys } => {
|
InputPreprocessorMessage::KeyUp { key, modifier_keys } => {
|
||||||
self.update_states_of_modifier_keys(modifier_keys, keyboard_platform, responses);
|
self.update_states_of_modifier_keys(modifier_keys, keyboard_platform, responses);
|
||||||
self.keyboard.unset(key as usize);
|
self.keyboard.unset(key as usize);
|
||||||
responses.push_back(InputMapperMessage::KeyUp(key).into());
|
responses.add(InputMapperMessage::KeyUp(key));
|
||||||
}
|
}
|
||||||
InputPreprocessorMessage::PointerDown { editor_mouse_state, modifier_keys } => {
|
InputPreprocessorMessage::PointerDown { editor_mouse_state, modifier_keys } => {
|
||||||
self.update_states_of_modifier_keys(modifier_keys, keyboard_platform, responses);
|
self.update_states_of_modifier_keys(modifier_keys, keyboard_platform, responses);
|
||||||
@@ -84,7 +78,7 @@ impl MessageHandler<InputPreprocessorMessage, KeyboardPlatformLayout> for InputP
|
|||||||
let mouse_state = editor_mouse_state.to_mouse_state(&self.viewport_bounds);
|
let mouse_state = editor_mouse_state.to_mouse_state(&self.viewport_bounds);
|
||||||
self.mouse.position = mouse_state.position;
|
self.mouse.position = mouse_state.position;
|
||||||
|
|
||||||
responses.push_back(InputMapperMessage::PointerMove.into());
|
responses.add(InputMapperMessage::PointerMove);
|
||||||
|
|
||||||
// While any pointer button is already down, additional button down events are not reported, but they are sent as `pointermove` events
|
// While any pointer button is already down, additional button down events are not reported, but they are sent as `pointermove` events
|
||||||
self.translate_mouse_event(mouse_state, false, responses);
|
self.translate_mouse_event(mouse_state, false, responses);
|
||||||
@@ -104,7 +98,7 @@ impl MessageHandler<InputPreprocessorMessage, KeyboardPlatformLayout> for InputP
|
|||||||
self.mouse.position = mouse_state.position;
|
self.mouse.position = mouse_state.position;
|
||||||
self.mouse.scroll_delta = mouse_state.scroll_delta;
|
self.mouse.scroll_delta = mouse_state.scroll_delta;
|
||||||
|
|
||||||
responses.push_back(InputMapperMessage::WheelScroll.into());
|
responses.add(InputMapperMessage::WheelScroll);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -123,14 +117,14 @@ impl InputPreprocessorMessageHandler {
|
|||||||
let new_down = new_state.mouse_keys & bit_flag == bit_flag;
|
let new_down = new_state.mouse_keys & bit_flag == bit_flag;
|
||||||
if !old_down && new_down {
|
if !old_down && new_down {
|
||||||
if allow_first_button_down || self.mouse.mouse_keys != MouseKeys::NONE {
|
if allow_first_button_down || self.mouse.mouse_keys != MouseKeys::NONE {
|
||||||
responses.push_back(InputMapperMessage::KeyDown(key).into());
|
responses.add(InputMapperMessage::KeyDown(key));
|
||||||
} else {
|
} else {
|
||||||
// Required to stop a keyup being emitted for a keydown outside canvas
|
// Required to stop a keyup being emitted for a keydown outside canvas
|
||||||
new_state.mouse_keys ^= bit_flag;
|
new_state.mouse_keys ^= bit_flag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if old_down && !new_down {
|
if old_down && !new_down {
|
||||||
responses.push_back(InputMapperMessage::KeyUp(key).into());
|
responses.add(InputMapperMessage::KeyUp(key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,10 +159,10 @@ impl InputPreprocessorMessageHandler {
|
|||||||
|
|
||||||
if key_was_down && !key_is_down {
|
if key_was_down && !key_is_down {
|
||||||
self.keyboard.unset(key as usize);
|
self.keyboard.unset(key as usize);
|
||||||
responses.push_back(InputMapperMessage::KeyUp(key).into());
|
responses.add(InputMapperMessage::KeyUp(key));
|
||||||
} else if !key_was_down && key_is_down {
|
} else if !key_was_down && key_is_down {
|
||||||
self.keyboard.set(key as usize);
|
self.keyboard.set(key as usize);
|
||||||
responses.push_back(InputMapperMessage::KeyDown(key).into());
|
responses.add(InputMapperMessage::KeyDown(key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -93,13 +93,13 @@ impl<F: Fn(&MessageDiscriminant) -> Vec<KeysGroup>> MessageHandler<LayoutMessage
|
|||||||
let update_value = value.as_u64().expect("BreadcrumbTrailButtons update was not of type: u64");
|
let update_value = value.as_u64().expect("BreadcrumbTrailButtons update was not of type: u64");
|
||||||
|
|
||||||
let callback_message = (breadcrumb_trail_buttons.on_update.callback)(&update_value);
|
let callback_message = (breadcrumb_trail_buttons.on_update.callback)(&update_value);
|
||||||
responses.push_back(callback_message);
|
responses.add(callback_message);
|
||||||
}
|
}
|
||||||
Widget::CheckboxInput(checkbox_input) => {
|
Widget::CheckboxInput(checkbox_input) => {
|
||||||
let update_value = value.as_bool().expect("CheckboxInput update was not of type: bool");
|
let update_value = value.as_bool().expect("CheckboxInput update was not of type: bool");
|
||||||
checkbox_input.checked = update_value;
|
checkbox_input.checked = update_value;
|
||||||
let callback_message = (checkbox_input.on_update.callback)(checkbox_input);
|
let callback_message = (checkbox_input.on_update.callback)(checkbox_input);
|
||||||
responses.push_back(callback_message);
|
responses.add(callback_message);
|
||||||
}
|
}
|
||||||
Widget::ColorInput(color_input) => {
|
Widget::ColorInput(color_input) => {
|
||||||
let update_value = value.as_object().expect("ColorInput update was not of type: object");
|
let update_value = value.as_object().expect("ColorInput update was not of type: object");
|
||||||
@@ -120,13 +120,13 @@ impl<F: Fn(&MessageDiscriminant) -> Vec<KeysGroup>> MessageHandler<LayoutMessage
|
|||||||
.unwrap_or_else(|| panic!("ColorInput update was not able to be parsed with color data: {color_input:?}"));
|
.unwrap_or_else(|| panic!("ColorInput update was not able to be parsed with color data: {color_input:?}"));
|
||||||
color_input.value = parsed_color;
|
color_input.value = parsed_color;
|
||||||
let callback_message = (color_input.on_update.callback)(color_input);
|
let callback_message = (color_input.on_update.callback)(color_input);
|
||||||
responses.push_back(callback_message);
|
responses.add(callback_message);
|
||||||
}
|
}
|
||||||
Widget::DropdownInput(dropdown_input) => {
|
Widget::DropdownInput(dropdown_input) => {
|
||||||
let update_value = value.as_u64().expect("DropdownInput update was not of type: u64");
|
let update_value = value.as_u64().expect("DropdownInput update was not of type: u64");
|
||||||
dropdown_input.selected_index = Some(update_value as u32);
|
dropdown_input.selected_index = Some(update_value as u32);
|
||||||
let callback_message = (dropdown_input.entries.iter().flatten().nth(update_value as usize).unwrap().on_update.callback)(&());
|
let callback_message = (dropdown_input.entries.iter().flatten().nth(update_value as usize).unwrap().on_update.callback)(&());
|
||||||
responses.push_back(callback_message);
|
responses.add(callback_message);
|
||||||
}
|
}
|
||||||
Widget::FontInput(font_input) => {
|
Widget::FontInput(font_input) => {
|
||||||
let update_value = value.as_object().expect("FontInput update was not of type: object");
|
let update_value = value.as_object().expect("FontInput update was not of type: object");
|
||||||
@@ -139,24 +139,21 @@ impl<F: Fn(&MessageDiscriminant) -> Vec<KeysGroup>> MessageHandler<LayoutMessage
|
|||||||
font_input.font_family = font_family.into();
|
font_input.font_family = font_family.into();
|
||||||
font_input.font_style = font_style.into();
|
font_input.font_style = font_style.into();
|
||||||
|
|
||||||
responses.push_back(
|
responses.add(PortfolioMessage::LoadFont {
|
||||||
PortfolioMessage::LoadFont {
|
font: Font::new(font_family.into(), font_style.into()),
|
||||||
font: Font::new(font_family.into(), font_style.into()),
|
is_default: false,
|
||||||
is_default: false,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
let callback_message = (font_input.on_update.callback)(font_input);
|
let callback_message = (font_input.on_update.callback)(font_input);
|
||||||
responses.push_back(callback_message);
|
responses.add(callback_message);
|
||||||
}
|
}
|
||||||
Widget::IconButton(icon_button) => {
|
Widget::IconButton(icon_button) => {
|
||||||
let callback_message = (icon_button.on_update.callback)(icon_button);
|
let callback_message = (icon_button.on_update.callback)(icon_button);
|
||||||
responses.push_back(callback_message);
|
responses.add(callback_message);
|
||||||
}
|
}
|
||||||
Widget::IconLabel(_) => {}
|
Widget::IconLabel(_) => {}
|
||||||
Widget::InvisibleStandinInput(invisible) => {
|
Widget::InvisibleStandinInput(invisible) => {
|
||||||
let callback_message = (invisible.on_update.callback)(&());
|
let callback_message = (invisible.on_update.callback)(&());
|
||||||
responses.push_back(callback_message);
|
responses.add(callback_message);
|
||||||
}
|
}
|
||||||
Widget::LayerReferenceInput(layer_reference_input) => {
|
Widget::LayerReferenceInput(layer_reference_input) => {
|
||||||
let update_value = value.is_null().not().then(|| {
|
let update_value = value.is_null().not().then(|| {
|
||||||
@@ -169,18 +166,18 @@ impl<F: Fn(&MessageDiscriminant) -> Vec<KeysGroup>> MessageHandler<LayoutMessage
|
|||||||
});
|
});
|
||||||
layer_reference_input.value = update_value;
|
layer_reference_input.value = update_value;
|
||||||
let callback_message = (layer_reference_input.on_update.callback)(layer_reference_input);
|
let callback_message = (layer_reference_input.on_update.callback)(layer_reference_input);
|
||||||
responses.push_back(callback_message);
|
responses.add(callback_message);
|
||||||
}
|
}
|
||||||
Widget::NumberInput(number_input) => match value {
|
Widget::NumberInput(number_input) => match value {
|
||||||
Value::Number(num) => {
|
Value::Number(num) => {
|
||||||
let update_value = num.as_f64().unwrap();
|
let update_value = num.as_f64().unwrap();
|
||||||
number_input.value = Some(update_value);
|
number_input.value = Some(update_value);
|
||||||
let callback_message = (number_input.on_update.callback)(number_input);
|
let callback_message = (number_input.on_update.callback)(number_input);
|
||||||
responses.push_back(callback_message);
|
responses.add(callback_message);
|
||||||
}
|
}
|
||||||
Value::String(str) => match str.as_str() {
|
Value::String(str) => match str.as_str() {
|
||||||
"Increment" => responses.push_back((number_input.increment_callback_increase.callback)(number_input)),
|
"Increment" => responses.add((number_input.increment_callback_increase.callback)(number_input)),
|
||||||
"Decrement" => responses.push_back((number_input.increment_callback_decrease.callback)(number_input)),
|
"Decrement" => responses.add((number_input.increment_callback_decrease.callback)(number_input)),
|
||||||
_ => {
|
_ => {
|
||||||
panic!("Invalid string found when updating `NumberInput`")
|
panic!("Invalid string found when updating `NumberInput`")
|
||||||
}
|
}
|
||||||
@@ -191,24 +188,24 @@ impl<F: Fn(&MessageDiscriminant) -> Vec<KeysGroup>> MessageHandler<LayoutMessage
|
|||||||
let update_value = value.as_bool().expect("OptionalInput update was not of type: bool");
|
let update_value = value.as_bool().expect("OptionalInput update was not of type: bool");
|
||||||
optional_input.checked = update_value;
|
optional_input.checked = update_value;
|
||||||
let callback_message = (optional_input.on_update.callback)(optional_input);
|
let callback_message = (optional_input.on_update.callback)(optional_input);
|
||||||
responses.push_back(callback_message);
|
responses.add(callback_message);
|
||||||
}
|
}
|
||||||
Widget::ParameterExposeButton(parameter_expose_button) => {
|
Widget::ParameterExposeButton(parameter_expose_button) => {
|
||||||
let callback_message = (parameter_expose_button.on_update.callback)(parameter_expose_button);
|
let callback_message = (parameter_expose_button.on_update.callback)(parameter_expose_button);
|
||||||
responses.push_back(callback_message);
|
responses.add(callback_message);
|
||||||
}
|
}
|
||||||
Widget::PivotAssist(pivot_assist) => {
|
Widget::PivotAssist(pivot_assist) => {
|
||||||
let update_value = value.as_str().expect("RadioInput update was not of type: u64");
|
let update_value = value.as_str().expect("RadioInput update was not of type: u64");
|
||||||
pivot_assist.position = update_value.into();
|
pivot_assist.position = update_value.into();
|
||||||
let callback_message = (pivot_assist.on_update.callback)(pivot_assist);
|
let callback_message = (pivot_assist.on_update.callback)(pivot_assist);
|
||||||
responses.push_back(callback_message);
|
responses.add(callback_message);
|
||||||
}
|
}
|
||||||
Widget::PopoverButton(_) => {}
|
Widget::PopoverButton(_) => {}
|
||||||
Widget::RadioInput(radio_input) => {
|
Widget::RadioInput(radio_input) => {
|
||||||
let update_value = value.as_u64().expect("RadioInput update was not of type: u64");
|
let update_value = value.as_u64().expect("RadioInput update was not of type: u64");
|
||||||
radio_input.selected_index = update_value as u32;
|
radio_input.selected_index = update_value as u32;
|
||||||
let callback_message = (radio_input.entries[update_value as usize].on_update.callback)(&());
|
let callback_message = (radio_input.entries[update_value as usize].on_update.callback)(&());
|
||||||
responses.push_back(callback_message);
|
responses.add(callback_message);
|
||||||
}
|
}
|
||||||
Widget::Separator(_) => {}
|
Widget::Separator(_) => {}
|
||||||
Widget::SwatchPairInput(_) => {}
|
Widget::SwatchPairInput(_) => {}
|
||||||
@@ -216,21 +213,21 @@ impl<F: Fn(&MessageDiscriminant) -> Vec<KeysGroup>> MessageHandler<LayoutMessage
|
|||||||
let update_value = value.as_str().expect("TextAreaInput update was not of type: string");
|
let update_value = value.as_str().expect("TextAreaInput update was not of type: string");
|
||||||
text_area_input.value = update_value.into();
|
text_area_input.value = update_value.into();
|
||||||
let callback_message = (text_area_input.on_update.callback)(text_area_input);
|
let callback_message = (text_area_input.on_update.callback)(text_area_input);
|
||||||
responses.push_back(callback_message);
|
responses.add(callback_message);
|
||||||
}
|
}
|
||||||
Widget::TextButton(text_button) => {
|
Widget::TextButton(text_button) => {
|
||||||
let callback_message = (text_button.on_update.callback)(text_button);
|
let callback_message = (text_button.on_update.callback)(text_button);
|
||||||
responses.push_back(callback_message);
|
responses.add(callback_message);
|
||||||
}
|
}
|
||||||
Widget::TextInput(text_input) => {
|
Widget::TextInput(text_input) => {
|
||||||
let update_value = value.as_str().expect("TextInput update was not of type: string");
|
let update_value = value.as_str().expect("TextInput update was not of type: string");
|
||||||
text_input.value = update_value.into();
|
text_input.value = update_value.into();
|
||||||
let callback_message = (text_input.on_update.callback)(text_input);
|
let callback_message = (text_input.on_update.callback)(text_input);
|
||||||
responses.push_back(callback_message);
|
responses.add(callback_message);
|
||||||
}
|
}
|
||||||
Widget::TextLabel(_) => {}
|
Widget::TextLabel(_) => {}
|
||||||
};
|
};
|
||||||
responses.push_back(ResendActiveWidget { layout_target, dirty_id: widget_id }.into());
|
responses.add(ResendActiveWidget { layout_target, dirty_id: widget_id });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -252,13 +249,10 @@ impl LayoutMessageHandler {
|
|||||||
// Update the backend storage
|
// Update the backend storage
|
||||||
self.layouts[layout_target as usize] = new_layout;
|
self.layouts[layout_target as usize] = new_layout;
|
||||||
// Update the UI
|
// Update the UI
|
||||||
responses.push_back(
|
responses.add(FrontendMessage::UpdateMenuBarLayout {
|
||||||
FrontendMessage::UpdateMenuBarLayout {
|
layout_target,
|
||||||
layout_target,
|
layout: self.layouts[layout_target as usize].clone().unwrap_menu_layout(action_input_mapping).layout,
|
||||||
layout: self.layouts[layout_target as usize].clone().unwrap_menu_layout(action_input_mapping).layout,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,6 +290,6 @@ impl LayoutMessageHandler {
|
|||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
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"),
|
||||||
};
|
};
|
||||||
responses.push_back(message.into());
|
responses.add(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,10 @@ pub trait PropertyHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn register_properties(&self, responses: &mut VecDeque<Message>, layout_target: LayoutTarget) {
|
fn register_properties(&self, responses: &mut VecDeque<Message>, layout_target: LayoutTarget) {
|
||||||
responses.push_back(
|
responses.add(LayoutMessage::SendLayout {
|
||||||
LayoutMessage::SendLayout {
|
layout: self.properties(),
|
||||||
layout: self.properties(),
|
layout_target,
|
||||||
layout_target,
|
})
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,12 +34,12 @@ impl MessageHandler<ArtboardMessage, &PersistentData> for ArtboardMessageHandler
|
|||||||
Ok(Some(document_responses)) => {
|
Ok(Some(document_responses)) => {
|
||||||
for response in document_responses {
|
for response in document_responses {
|
||||||
match &response {
|
match &response {
|
||||||
DocumentResponse::LayerChanged { path } => responses.push_back(PropertiesPanelMessage::CheckSelectedWasUpdated { path: path.clone() }.into()),
|
DocumentResponse::LayerChanged { path } => responses.add(PropertiesPanelMessage::CheckSelectedWasUpdated { path: path.clone() }),
|
||||||
DocumentResponse::DeletedLayer { path } => responses.push_back(PropertiesPanelMessage::CheckSelectedWasDeleted { path: path.clone() }.into()),
|
DocumentResponse::DeletedLayer { path } => responses.add(PropertiesPanelMessage::CheckSelectedWasDeleted { path: path.clone() }),
|
||||||
DocumentResponse::DocumentChanged => responses.push_back(ArtboardMessage::RenderArtboards.into()),
|
DocumentResponse::DocumentChanged => responses.add(ArtboardMessage::RenderArtboards),
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(None) => {}
|
Ok(None) => {}
|
||||||
@@ -52,50 +52,41 @@ impl MessageHandler<ArtboardMessage, &PersistentData> for ArtboardMessageHandler
|
|||||||
let artboard_id = id.unwrap_or_else(generate_uuid);
|
let artboard_id = id.unwrap_or_else(generate_uuid);
|
||||||
self.artboard_ids.push(artboard_id);
|
self.artboard_ids.push(artboard_id);
|
||||||
|
|
||||||
responses.push_back(
|
responses.add(ArtboardMessage::DispatchOperation(
|
||||||
ArtboardMessage::DispatchOperation(
|
DocumentOperation::AddRect {
|
||||||
DocumentOperation::AddRect {
|
path: vec![artboard_id],
|
||||||
path: vec![artboard_id],
|
insert_index: -1,
|
||||||
insert_index: -1,
|
transform: DAffine2::from_scale_angle_translation(size.into(), 0., position.into()).to_cols_array(),
|
||||||
transform: DAffine2::from_scale_angle_translation(size.into(), 0., position.into()).to_cols_array(),
|
style: style::PathStyle::new(None, Fill::solid(Color::WHITE)),
|
||||||
style: style::PathStyle::new(None, Fill::solid(Color::WHITE)),
|
}
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
)
|
|
||||||
.into(),
|
.into(),
|
||||||
);
|
));
|
||||||
|
|
||||||
responses.push_back(DocumentMessage::RenderDocument.into());
|
responses.add(DocumentMessage::RenderDocument);
|
||||||
}
|
}
|
||||||
ClearArtboards => {
|
ClearArtboards => {
|
||||||
for &artboard in self.artboard_ids.iter() {
|
for &artboard in self.artboard_ids.iter() {
|
||||||
responses.push_front(ArtboardMessage::DeleteArtboard { artboard }.into());
|
responses.add_front(ArtboardMessage::DeleteArtboard { artboard });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DeleteArtboard { artboard } => {
|
DeleteArtboard { artboard } => {
|
||||||
self.artboard_ids.retain(|&id| id != artboard);
|
self.artboard_ids.retain(|&id| id != artboard);
|
||||||
|
|
||||||
responses.push_back(ArtboardMessage::DispatchOperation(Box::new(DocumentOperation::DeleteLayer { path: vec![artboard] })).into());
|
responses.add(ArtboardMessage::DispatchOperation(Box::new(DocumentOperation::DeleteLayer { path: vec![artboard] })));
|
||||||
|
|
||||||
responses.push_back(DocumentMessage::RenderDocument.into());
|
responses.add(DocumentMessage::RenderDocument);
|
||||||
}
|
}
|
||||||
RenderArtboards => {
|
RenderArtboards => {
|
||||||
// Render an infinite canvas if there are no artboards
|
// Render an infinite canvas if there are no artboards
|
||||||
if self.artboard_ids.is_empty() {
|
if self.artboard_ids.is_empty() {
|
||||||
responses.push_back(
|
responses.add(FrontendMessage::UpdateDocumentArtboards {
|
||||||
FrontendMessage::UpdateDocumentArtboards {
|
svg: r##"<rect width="100%" height="100%" fill="#ffffff" />"##.to_string(),
|
||||||
svg: r##"<rect width="100%" height="100%" fill="#ffffff" />"##.to_string(),
|
})
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
let render_data = RenderData::new(&persistent_data.font_cache, ViewMode::Normal, None);
|
let render_data = RenderData::new(&persistent_data.font_cache, ViewMode::Normal, None);
|
||||||
responses.push_back(
|
responses.add(FrontendMessage::UpdateDocumentArtboards {
|
||||||
FrontendMessage::UpdateDocumentArtboards {
|
svg: self.artboards_document.render_root(&render_data),
|
||||||
svg: self.artboards_document.render_root(&render_data),
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ResizeArtboard { artboard, position, mut size } => {
|
ResizeArtboard { artboard, position, mut size } => {
|
||||||
@@ -106,15 +97,12 @@ impl MessageHandler<ArtboardMessage, &PersistentData> for ArtboardMessageHandler
|
|||||||
size.1 = size.1.signum();
|
size.1 = size.1.signum();
|
||||||
}
|
}
|
||||||
|
|
||||||
responses.push_back(
|
responses.add(ArtboardMessage::DispatchOperation(Box::new(DocumentOperation::SetLayerTransform {
|
||||||
ArtboardMessage::DispatchOperation(Box::new(DocumentOperation::SetLayerTransform {
|
path: vec![artboard],
|
||||||
path: vec![artboard],
|
transform: DAffine2::from_scale_angle_translation(size.into(), 0., position.into()).to_cols_array(),
|
||||||
transform: DAffine2::from_scale_angle_translation(size.into(), 0., position.into()).to_cols_array(),
|
})));
|
||||||
}))
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
|
|
||||||
responses.push_back(DocumentMessage::RenderDocument.into());
|
responses.add(DocumentMessage::RenderDocument);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,56 +124,46 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||||||
Ok(Some(document_responses)) => {
|
Ok(Some(document_responses)) => {
|
||||||
for response in document_responses {
|
for response in document_responses {
|
||||||
match &response {
|
match &response {
|
||||||
DocumentResponse::FolderChanged { path } => responses.push_back(FolderChanged { affected_folder_path: path.clone() }.into()),
|
DocumentResponse::FolderChanged { path } => responses.add(FolderChanged { affected_folder_path: path.clone() }),
|
||||||
DocumentResponse::DeletedLayer { path } => {
|
DocumentResponse::DeletedLayer { path } => {
|
||||||
self.layer_metadata.remove(path);
|
self.layer_metadata.remove(path);
|
||||||
}
|
}
|
||||||
DocumentResponse::LayerChanged { path } => responses.push_back(LayerChanged { affected_layer_path: path.clone() }.into()),
|
DocumentResponse::LayerChanged { path } => responses.add(LayerChanged { affected_layer_path: path.clone() }),
|
||||||
DocumentResponse::CreatedLayer { path } => {
|
DocumentResponse::CreatedLayer { path } => {
|
||||||
if self.layer_metadata.contains_key(path) {
|
if self.layer_metadata.contains_key(path) {
|
||||||
warn!("CreatedLayer overrides existing layer metadata.");
|
warn!("CreatedLayer overrides existing layer metadata.");
|
||||||
}
|
}
|
||||||
self.layer_metadata.insert(path.clone(), LayerMetadata::new(false));
|
self.layer_metadata.insert(path.clone(), LayerMetadata::new(false));
|
||||||
|
|
||||||
responses.push_back(LayerChanged { affected_layer_path: path.clone() }.into());
|
responses.add(LayerChanged { affected_layer_path: path.clone() });
|
||||||
self.layer_range_selection_reference = path.clone();
|
self.layer_range_selection_reference = path.clone();
|
||||||
responses.push_back(
|
responses.add(AddSelectedLayers {
|
||||||
AddSelectedLayers {
|
additional_layers: vec![path.clone()],
|
||||||
additional_layers: vec![path.clone()],
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
DocumentResponse::DocumentChanged => responses.push_back(RenderDocument.into()),
|
DocumentResponse::DocumentChanged => responses.add(RenderDocument),
|
||||||
DocumentResponse::DeletedSelectedManipulatorPoints => {
|
DocumentResponse::DeletedSelectedManipulatorPoints => {
|
||||||
// Clear Properties panel after deleting all points by updating backend widget state.
|
// Clear Properties panel after deleting all points by updating backend widget state.
|
||||||
responses.push_back(
|
responses.add(LayoutMessage::SendLayout {
|
||||||
LayoutMessage::SendLayout {
|
layout: Layout::WidgetLayout(WidgetLayout::new(vec![])),
|
||||||
layout: Layout::WidgetLayout(WidgetLayout::new(vec![])),
|
layout_target: LayoutTarget::PropertiesOptions,
|
||||||
layout_target: LayoutTarget::PropertiesOptions,
|
});
|
||||||
}
|
responses.add(LayoutMessage::SendLayout {
|
||||||
.into(),
|
layout: Layout::WidgetLayout(WidgetLayout::new(vec![])),
|
||||||
);
|
layout_target: LayoutTarget::PropertiesSections,
|
||||||
responses.push_back(
|
});
|
||||||
LayoutMessage::SendLayout {
|
|
||||||
layout: Layout::WidgetLayout(WidgetLayout::new(vec![])),
|
|
||||||
layout_target: LayoutTarget::PropertiesSections,
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Display boolean operation error to the user (except if it is a nothing done error).
|
// Display boolean operation error to the user (except if it is a nothing done error).
|
||||||
Err(DocumentError::BooleanOperationError(boolean_operation_error)) if boolean_operation_error != BooleanOperationError::NothingDone => responses.push_back(
|
Err(DocumentError::BooleanOperationError(boolean_operation_error)) if boolean_operation_error != BooleanOperationError::NothingDone => {
|
||||||
DialogMessage::DisplayDialogError {
|
responses.add(DialogMessage::DisplayDialogError {
|
||||||
title: "Failed to calculate boolean operation".into(),
|
title: "Failed to calculate boolean operation".into(),
|
||||||
description: format!("Unfortunately, this feature not that robust yet.\n\nError: {boolean_operation_error:?}"),
|
description: format!("Unfortunately, this feature not that robust yet.\n\nError: {boolean_operation_error:?}"),
|
||||||
}
|
})
|
||||||
.into(),
|
}
|
||||||
),
|
|
||||||
Err(e) => error!("DocumentError: {:?}", e),
|
Err(e) => error!("DocumentError: {:?}", e),
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
}
|
}
|
||||||
@@ -224,8 +214,8 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Correctly update layer panel in clear_selection instead of here
|
// TODO: Correctly update layer panel in clear_selection instead of here
|
||||||
responses.push_back(FolderChanged { affected_folder_path: vec![] }.into());
|
responses.add(FolderChanged { affected_folder_path: vec![] });
|
||||||
responses.push_back(BroadcastEvent::SelectionChanged.into());
|
responses.add(BroadcastEvent::SelectionChanged);
|
||||||
|
|
||||||
self.update_layer_tree_options_bar_widgets(responses, &render_data);
|
self.update_layer_tree_options_bar_widgets(responses, &render_data);
|
||||||
}
|
}
|
||||||
@@ -262,95 +252,86 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||||||
skip_rerender: false,
|
skip_rerender: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BackupDocument { document, artboard, layer_metadata } => self.backup_with_document(document, *artboard, layer_metadata, responses),
|
BackupDocument { document, artboard, layer_metadata } => self.backup_with_document(document, *artboard, layer_metadata, responses),
|
||||||
BooleanOperation(op) => {
|
BooleanOperation(op) => {
|
||||||
// Convert Vec<&[LayerId]> to Vec<Vec<&LayerId>> because Vec<&[LayerId]> does not implement several traits (Debug, Serialize, Deserialize, ...) required by DocumentOperation enum
|
// Convert Vec<&[LayerId]> to Vec<Vec<&LayerId>> because Vec<&[LayerId]> does not implement several traits (Debug, Serialize, Deserialize, ...) required by DocumentOperation enum
|
||||||
responses.push_back(StartTransaction.into());
|
responses.add(StartTransaction);
|
||||||
responses.push_back(BroadcastEvent::ToolAbort.into());
|
responses.add(BroadcastEvent::ToolAbort);
|
||||||
responses.push_back(
|
responses.add(DocumentOperation::BooleanOperation {
|
||||||
DocumentOperation::BooleanOperation {
|
operation: op,
|
||||||
operation: op,
|
selected: self.selected_layers_sorted().iter().map(|slice| (*slice).into()).collect(),
|
||||||
selected: self.selected_layers_sorted().iter().map(|slice| (*slice).into()).collect(),
|
});
|
||||||
}
|
responses.add(CommitTransaction);
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
responses.push_back(CommitTransaction.into());
|
|
||||||
}
|
}
|
||||||
ClearLayerTree => {
|
ClearLayerTree => {
|
||||||
// Send an empty layer tree
|
// Send an empty layer tree
|
||||||
let data_buffer: RawBuffer = Self::default().serialize_root().as_slice().into();
|
let data_buffer: RawBuffer = Self::default().serialize_root().as_slice().into();
|
||||||
responses.push_back(FrontendMessage::UpdateDocumentLayerTreeStructure { data_buffer }.into());
|
responses.add(FrontendMessage::UpdateDocumentLayerTreeStructure { data_buffer });
|
||||||
|
|
||||||
// Clear the options bar
|
// Clear the options bar
|
||||||
responses.push_back(
|
responses.add(LayoutMessage::SendLayout {
|
||||||
LayoutMessage::SendLayout {
|
layout: Layout::WidgetLayout(Default::default()),
|
||||||
layout: Layout::WidgetLayout(Default::default()),
|
layout_target: LayoutTarget::LayerTreeOptions,
|
||||||
layout_target: LayoutTarget::LayerTreeOptions,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
CommitTransaction => (),
|
CommitTransaction => (),
|
||||||
CreateEmptyFolder { mut container_path } => {
|
CreateEmptyFolder { mut container_path } => {
|
||||||
let id = generate_uuid();
|
let id = generate_uuid();
|
||||||
container_path.push(id);
|
container_path.push(id);
|
||||||
responses.push_back(DocumentMessage::DeselectAllLayers.into());
|
responses.add(DocumentMessage::DeselectAllLayers);
|
||||||
responses.push_back(DocumentOperation::CreateFolder { path: container_path.clone() }.into());
|
responses.add(DocumentOperation::CreateFolder { path: container_path.clone() });
|
||||||
responses.push_back(
|
responses.add(DocumentMessage::SetLayerExpansion {
|
||||||
DocumentMessage::SetLayerExpansion {
|
layer_path: container_path,
|
||||||
layer_path: container_path,
|
set_expanded: true,
|
||||||
set_expanded: true,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
DebugPrintDocument => {
|
DebugPrintDocument => {
|
||||||
info!("{:#?}\n{:#?}", self.document_legacy, self.layer_metadata);
|
info!("{:#?}\n{:#?}", self.document_legacy, self.layer_metadata);
|
||||||
}
|
}
|
||||||
DeleteLayer { layer_path } => {
|
DeleteLayer { layer_path } => {
|
||||||
responses.push_front(DocumentOperation::DeleteLayer { path: layer_path.clone() }.into());
|
responses.add_front(DocumentOperation::DeleteLayer { path: layer_path.clone() });
|
||||||
responses.push_front(BroadcastEvent::ToolAbort.into());
|
responses.add_front(BroadcastEvent::ToolAbort);
|
||||||
responses.push_back(PropertiesPanelMessage::CheckSelectedWasDeleted { path: layer_path }.into());
|
responses.add(PropertiesPanelMessage::CheckSelectedWasDeleted { path: layer_path });
|
||||||
}
|
}
|
||||||
DeleteSelectedLayers => {
|
DeleteSelectedLayers => {
|
||||||
self.backup(responses);
|
self.backup(responses);
|
||||||
|
|
||||||
for path in self.selected_layers_without_children() {
|
for path in self.selected_layers_without_children() {
|
||||||
responses.push_front(DocumentMessage::DeleteLayer { layer_path: path.to_vec() }.into());
|
responses.add_front(DocumentMessage::DeleteLayer { layer_path: path.to_vec() });
|
||||||
}
|
}
|
||||||
|
|
||||||
responses.push_front(BroadcastEvent::SelectionChanged.into());
|
responses.add_front(BroadcastEvent::SelectionChanged);
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
}
|
}
|
||||||
DeselectAllLayers => {
|
DeselectAllLayers => {
|
||||||
responses.push_front(SetSelectedLayers { replacement_selected_layers: vec![] }.into());
|
responses.add_front(SetSelectedLayers { replacement_selected_layers: vec![] });
|
||||||
self.layer_range_selection_reference.clear();
|
self.layer_range_selection_reference.clear();
|
||||||
}
|
}
|
||||||
DirtyRenderDocument => {
|
DirtyRenderDocument => {
|
||||||
// Mark all non-overlay caches as dirty
|
// Mark all non-overlay caches as dirty
|
||||||
DocumentLegacy::mark_children_as_dirty(&mut self.document_legacy.root);
|
DocumentLegacy::mark_children_as_dirty(&mut self.document_legacy.root);
|
||||||
responses.push_back(DocumentMessage::RenderDocument.into());
|
responses.add(DocumentMessage::RenderDocument);
|
||||||
}
|
}
|
||||||
DirtyRenderDocumentInOutlineView => {
|
DirtyRenderDocumentInOutlineView => {
|
||||||
if self.view_mode == ViewMode::Outline {
|
if self.view_mode == ViewMode::Outline {
|
||||||
responses.push_front(DocumentMessage::DirtyRenderDocument.into());
|
responses.add_front(DocumentMessage::DirtyRenderDocument);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DocumentHistoryBackward => self.undo(responses).unwrap_or_else(|e| warn!("{}", e)),
|
DocumentHistoryBackward => self.undo(responses).unwrap_or_else(|e| warn!("{}", e)),
|
||||||
DocumentHistoryForward => self.redo(responses).unwrap_or_else(|e| warn!("{}", e)),
|
DocumentHistoryForward => self.redo(responses).unwrap_or_else(|e| warn!("{}", e)),
|
||||||
DocumentStructureChanged => {
|
DocumentStructureChanged => {
|
||||||
let data_buffer: RawBuffer = self.serialize_root().as_slice().into();
|
let data_buffer: RawBuffer = self.serialize_root().as_slice().into();
|
||||||
responses.push_back(FrontendMessage::UpdateDocumentLayerTreeStructure { data_buffer }.into())
|
responses.add(FrontendMessage::UpdateDocumentLayerTreeStructure { data_buffer })
|
||||||
}
|
}
|
||||||
DuplicateSelectedLayers => {
|
DuplicateSelectedLayers => {
|
||||||
self.backup(responses);
|
self.backup(responses);
|
||||||
responses.push_front(SetSelectedLayers { replacement_selected_layers: vec![] }.into());
|
responses.add_front(SetSelectedLayers { replacement_selected_layers: vec![] });
|
||||||
self.layer_range_selection_reference.clear();
|
self.layer_range_selection_reference.clear();
|
||||||
for path in self.selected_layers_sorted() {
|
for path in self.selected_layers_sorted() {
|
||||||
responses.push_back(DocumentOperation::DuplicateLayer { path: path.to_vec() }.into());
|
responses.add(DocumentOperation::DuplicateLayer { path: path.to_vec() });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExportDocument {
|
ExportDocument {
|
||||||
@@ -381,11 +362,11 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||||||
};
|
};
|
||||||
|
|
||||||
if file_type == FileType::Svg {
|
if file_type == FileType::Svg {
|
||||||
responses.push_back(FrontendMessage::TriggerFileDownload { document, name }.into());
|
responses.add(FrontendMessage::TriggerFileDownload { document, name });
|
||||||
} else {
|
} else {
|
||||||
let mime = file_type.to_mime().to_string();
|
let mime = file_type.to_mime().to_string();
|
||||||
let size = (size * scale_factor).into();
|
let size = (size * scale_factor).into();
|
||||||
responses.push_back(FrontendMessage::TriggerRasterDownload { svg: document, name, mime, size }.into());
|
responses.add(FrontendMessage::TriggerRasterDownload { svg: document, name, mime, size });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FlipSelectedLayers { flip_axis } => {
|
FlipSelectedLayers { flip_axis } => {
|
||||||
@@ -405,7 +386,7 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||||||
skip_rerender: false,
|
skip_rerender: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FolderChanged { affected_folder_path } => {
|
FolderChanged { affected_folder_path } => {
|
||||||
@@ -429,9 +410,9 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some(url) = previous_blob_url {
|
if let Some(url) = previous_blob_url {
|
||||||
responses.push_back(FrontendMessage::TriggerRevokeBlobUrl { url: url.clone() }.into());
|
responses.add(FrontendMessage::TriggerRevokeBlobUrl { url: url.clone() });
|
||||||
}
|
}
|
||||||
responses.push_back(DocumentOperation::ClearBlobURL { path: layer_path.into() }.into());
|
responses.add(DocumentOperation::ClearBlobURL { path: layer_path.into() });
|
||||||
}
|
}
|
||||||
GroupSelectedLayers => {
|
GroupSelectedLayers => {
|
||||||
let mut new_folder_path = self.document_legacy.shallowest_common_folder(self.selected_layers()).unwrap_or(&[]).to_vec();
|
let mut new_folder_path = self.document_legacy.shallowest_common_folder(self.selected_layers()).unwrap_or(&[]).to_vec();
|
||||||
@@ -443,30 +424,24 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||||||
|
|
||||||
new_folder_path.push(generate_uuid());
|
new_folder_path.push(generate_uuid());
|
||||||
|
|
||||||
responses.push_back(PortfolioMessage::Copy { clipboard: Clipboard::Internal }.into());
|
responses.add(PortfolioMessage::Copy { clipboard: Clipboard::Internal });
|
||||||
responses.push_back(DocumentMessage::DeleteSelectedLayers.into());
|
responses.add(DocumentMessage::DeleteSelectedLayers);
|
||||||
responses.push_back(DocumentOperation::CreateFolder { path: new_folder_path.clone() }.into());
|
responses.add(DocumentOperation::CreateFolder { path: new_folder_path.clone() });
|
||||||
responses.push_back(DocumentMessage::ToggleLayerExpansion { layer_path: new_folder_path.clone() }.into());
|
responses.add(DocumentMessage::ToggleLayerExpansion { layer_path: new_folder_path.clone() });
|
||||||
responses.push_back(
|
responses.add(PortfolioMessage::PasteIntoFolder {
|
||||||
PortfolioMessage::PasteIntoFolder {
|
clipboard: Clipboard::Internal,
|
||||||
clipboard: Clipboard::Internal,
|
folder_path: new_folder_path.clone(),
|
||||||
folder_path: new_folder_path.clone(),
|
insert_index: -1,
|
||||||
insert_index: -1,
|
});
|
||||||
}
|
responses.add(DocumentMessage::SetSelectedLayers {
|
||||||
.into(),
|
replacement_selected_layers: vec![new_folder_path],
|
||||||
);
|
});
|
||||||
responses.push_back(
|
|
||||||
DocumentMessage::SetSelectedLayers {
|
|
||||||
replacement_selected_layers: vec![new_folder_path],
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
LayerChanged { affected_layer_path } => {
|
LayerChanged { affected_layer_path } => {
|
||||||
if let Ok(layer_entry) = self.layer_panel_entry(affected_layer_path.clone(), &render_data) {
|
if let Ok(layer_entry) = self.layer_panel_entry(affected_layer_path.clone(), &render_data) {
|
||||||
responses.push_back(FrontendMessage::UpdateDocumentLayerDetails { data: layer_entry }.into());
|
responses.add(FrontendMessage::UpdateDocumentLayerDetails { data: layer_entry });
|
||||||
}
|
}
|
||||||
responses.push_back(PropertiesPanelMessage::CheckSelectedWasUpdated { path: affected_layer_path }.into());
|
responses.add(PropertiesPanelMessage::CheckSelectedWasUpdated { path: affected_layer_path });
|
||||||
self.update_layer_tree_options_bar_widgets(responses, &render_data);
|
self.update_layer_tree_options_bar_widgets(responses, &render_data);
|
||||||
}
|
}
|
||||||
MoveSelectedLayersTo {
|
MoveSelectedLayersTo {
|
||||||
@@ -483,16 +458,13 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||||||
|
|
||||||
let insert_index = self.update_insert_index(&selected_layers, &folder_path, insert_index, reverse_index).unwrap();
|
let insert_index = self.update_insert_index(&selected_layers, &folder_path, insert_index, reverse_index).unwrap();
|
||||||
|
|
||||||
responses.push_back(PortfolioMessage::Copy { clipboard: Clipboard::Internal }.into());
|
responses.add(PortfolioMessage::Copy { clipboard: Clipboard::Internal });
|
||||||
responses.push_back(DocumentMessage::DeleteSelectedLayers.into());
|
responses.add(DocumentMessage::DeleteSelectedLayers);
|
||||||
responses.push_back(
|
responses.add(PortfolioMessage::PasteIntoFolder {
|
||||||
PortfolioMessage::PasteIntoFolder {
|
clipboard: Clipboard::Internal,
|
||||||
clipboard: Clipboard::Internal,
|
folder_path,
|
||||||
folder_path,
|
insert_index,
|
||||||
insert_index,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
NodeGraphFrameClear {
|
NodeGraphFrameClear {
|
||||||
layer_path,
|
layer_path,
|
||||||
@@ -500,17 +472,17 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||||||
cached_index: input_index,
|
cached_index: input_index,
|
||||||
} => {
|
} => {
|
||||||
let value = graph_craft::document::value::TaggedValue::RcImage(None);
|
let value = graph_craft::document::value::TaggedValue::RcImage(None);
|
||||||
responses.push_back(NodeGraphMessage::SetInputValue { node_id, input_index, value }.into());
|
responses.add(NodeGraphMessage::SetInputValue { node_id, input_index, value });
|
||||||
responses.push_back(NodeGraphFrameGenerate { layer_path }.into());
|
responses.add(NodeGraphFrameGenerate { layer_path });
|
||||||
}
|
}
|
||||||
NodeGraphFrameGenerate { layer_path } => {
|
NodeGraphFrameGenerate { layer_path } => {
|
||||||
if let Some(message) = self.call_node_graph_frame(document_id, layer_path, preferences, persistent_data, None) {
|
if let Some(message) = self.call_node_graph_frame(document_id, layer_path, preferences, persistent_data, None) {
|
||||||
responses.push_back(message);
|
responses.add(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NodeGraphFrameImaginate { layer_path, imaginate_node } => {
|
NodeGraphFrameImaginate { layer_path, imaginate_node } => {
|
||||||
if let Some(message) = self.call_node_graph_frame(document_id, layer_path, preferences, persistent_data, Some(imaginate_node)) {
|
if let Some(message) = self.call_node_graph_frame(document_id, layer_path, preferences, persistent_data, Some(imaginate_node)) {
|
||||||
responses.push_back(message);
|
responses.add(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NodeGraphFrameImaginateRandom {
|
NodeGraphFrameImaginateRandom {
|
||||||
@@ -519,31 +491,25 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||||||
then_generate,
|
then_generate,
|
||||||
} => {
|
} => {
|
||||||
// Set a random seed input
|
// Set a random seed input
|
||||||
responses.push_back(
|
responses.add(NodeGraphMessage::SetInputValue {
|
||||||
NodeGraphMessage::SetInputValue {
|
node_id: *imaginate_node.last().unwrap(),
|
||||||
node_id: *imaginate_node.last().unwrap(),
|
// Needs to match the index of the seed parameter in `pub const IMAGINATE_NODE: DocumentNodeType` in `document_node_type.rs`
|
||||||
// Needs to match the index of the seed parameter in `pub const IMAGINATE_NODE: DocumentNodeType` in `document_node_type.rs`
|
input_index: 1,
|
||||||
input_index: 1,
|
value: graph_craft::document::value::TaggedValue::F64((generate_uuid() >> 1) as f64),
|
||||||
value: graph_craft::document::value::TaggedValue::F64((generate_uuid() >> 1) as f64),
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Generate the image
|
// Generate the image
|
||||||
if then_generate {
|
if then_generate {
|
||||||
responses.push_back(DocumentMessage::NodeGraphFrameImaginate { layer_path, imaginate_node }.into());
|
responses.add(DocumentMessage::NodeGraphFrameImaginate { layer_path, imaginate_node });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NodeGraphFrameImaginateTerminate { layer_path, node_path } => {
|
NodeGraphFrameImaginateTerminate { layer_path, node_path } => {
|
||||||
responses.push_back(
|
responses.add(FrontendMessage::TriggerImaginateTerminate {
|
||||||
FrontendMessage::TriggerImaginateTerminate {
|
document_id,
|
||||||
document_id,
|
layer_path,
|
||||||
layer_path,
|
node_path,
|
||||||
node_path,
|
hostname: preferences.imaginate_server_hostname.clone(),
|
||||||
hostname: preferences.imaginate_server_hostname.clone(),
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
NudgeSelectedLayers {
|
NudgeSelectedLayers {
|
||||||
delta_x,
|
delta_x,
|
||||||
@@ -591,7 +557,7 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
}
|
}
|
||||||
PasteImage { image, mouse } => {
|
PasteImage { image, mouse } => {
|
||||||
let image_size = DVec2::new(image.width as f64, image.height as f64);
|
let image_size = DVec2::new(image.width as f64, image.height as f64);
|
||||||
@@ -629,7 +595,7 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||||||
|
|
||||||
let transform = center_in_viewport_layerspace * fit_image_size;
|
let transform = center_in_viewport_layerspace * fit_image_size;
|
||||||
|
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
|
|
||||||
let mut pos = 8;
|
let mut pos = 8;
|
||||||
let mut next_pos = || {
|
let mut next_pos = || {
|
||||||
@@ -656,21 +622,15 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||||||
downres_node_type.to_document_node_default_inputs([Some(graph_craft::document::NodeInput::node(transform_node_id, 0))], next_pos()),
|
downres_node_type.to_document_node_default_inputs([Some(graph_craft::document::NodeInput::node(transform_node_id, 0))], next_pos()),
|
||||||
);
|
);
|
||||||
|
|
||||||
responses.push_back(
|
responses.add(DocumentOperation::AddNodeGraphFrame {
|
||||||
DocumentOperation::AddNodeGraphFrame {
|
path: path.clone(),
|
||||||
path: path.clone(),
|
insert_index: -1,
|
||||||
insert_index: -1,
|
transform: DAffine2::ZERO.to_cols_array(),
|
||||||
transform: DAffine2::ZERO.to_cols_array(),
|
network,
|
||||||
network,
|
});
|
||||||
}
|
responses.add(DocumentMessage::SetSelectedLayers {
|
||||||
.into(),
|
replacement_selected_layers: vec![path.clone()],
|
||||||
);
|
});
|
||||||
responses.push_back(
|
|
||||||
DocumentMessage::SetSelectedLayers {
|
|
||||||
replacement_selected_layers: vec![path.clone()],
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
|
|
||||||
responses.add(GraphOperationMessage::TransformSet {
|
responses.add(GraphOperationMessage::TransformSet {
|
||||||
layer: path.clone(),
|
layer: path.clone(),
|
||||||
@@ -679,27 +639,24 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||||||
skip_rerender: false,
|
skip_rerender: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
responses.push_back(DocumentMessage::NodeGraphFrameGenerate { layer_path: path }.into());
|
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path: path });
|
||||||
|
|
||||||
// Force chosen tool to be Select Tool after importing image.
|
// Force chosen tool to be Select Tool after importing image.
|
||||||
responses.push_back(ToolMessage::ActivateTool { tool_type: ToolType::Select }.into());
|
responses.add(ToolMessage::ActivateTool { tool_type: ToolType::Select });
|
||||||
}
|
}
|
||||||
Redo => {
|
Redo => {
|
||||||
responses.push_back(SelectToolMessage::Abort.into());
|
responses.add(SelectToolMessage::Abort);
|
||||||
responses.push_back(DocumentHistoryForward.into());
|
responses.add(DocumentHistoryForward);
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
responses.push_back(RenderDocument.into());
|
responses.add(RenderDocument);
|
||||||
responses.push_back(FolderChanged { affected_folder_path: vec![] }.into());
|
responses.add(FolderChanged { affected_folder_path: vec![] });
|
||||||
}
|
}
|
||||||
RenameLayer { layer_path, new_name } => responses.push_back(DocumentOperation::RenameLayer { layer_path, new_name }.into()),
|
RenameLayer { layer_path, new_name } => responses.add(DocumentOperation::RenameLayer { layer_path, new_name }),
|
||||||
RenderDocument => {
|
RenderDocument => {
|
||||||
responses.push_back(
|
responses.add(FrontendMessage::UpdateDocumentArtwork {
|
||||||
FrontendMessage::UpdateDocumentArtwork {
|
svg: self.document_legacy.render_root(&render_data),
|
||||||
svg: self.document_legacy.render_root(&render_data),
|
});
|
||||||
}
|
responses.add(ArtboardMessage::RenderArtboards);
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
responses.push_back(ArtboardMessage::RenderArtboards.into());
|
|
||||||
|
|
||||||
let document_transform_scale = self.navigation_handler.snapped_scale();
|
let document_transform_scale = self.navigation_handler.snapped_scale();
|
||||||
let scale = 0.5 + ASYMPTOTIC_EFFECT + document_transform_scale * SCALE_EFFECT;
|
let scale = 0.5 + ASYMPTOTIC_EFFECT + document_transform_scale * SCALE_EFFECT;
|
||||||
@@ -719,23 +676,17 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||||||
|
|
||||||
let ruler_origin = self.document_legacy.root.transform.transform_point2(DVec2::ZERO);
|
let ruler_origin = self.document_legacy.root.transform.transform_point2(DVec2::ZERO);
|
||||||
|
|
||||||
responses.push_back(
|
responses.add(FrontendMessage::UpdateDocumentScrollbars {
|
||||||
FrontendMessage::UpdateDocumentScrollbars {
|
position: scrollbar_position.into(),
|
||||||
position: scrollbar_position.into(),
|
size: scrollbar_size.into(),
|
||||||
size: scrollbar_size.into(),
|
multiplier: scrollbar_multiplier.into(),
|
||||||
multiplier: scrollbar_multiplier.into(),
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
|
|
||||||
responses.push_back(
|
responses.add(FrontendMessage::UpdateDocumentRulers {
|
||||||
FrontendMessage::UpdateDocumentRulers {
|
origin: ruler_origin.into(),
|
||||||
origin: ruler_origin.into(),
|
spacing: ruler_spacing,
|
||||||
spacing: ruler_spacing,
|
interval: ruler_interval,
|
||||||
interval: ruler_interval,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
RollbackTransaction => {
|
RollbackTransaction => {
|
||||||
self.rollback(responses).unwrap_or_else(|e| warn!("{}", e));
|
self.rollback(responses).unwrap_or_else(|e| warn!("{}", e));
|
||||||
@@ -743,37 +694,34 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||||||
}
|
}
|
||||||
SaveDocument => {
|
SaveDocument => {
|
||||||
self.set_save_state(true);
|
self.set_save_state(true);
|
||||||
responses.push_back(PortfolioMessage::AutoSaveActiveDocument.into());
|
responses.add(PortfolioMessage::AutoSaveActiveDocument);
|
||||||
// Update the save status of the just saved document
|
// Update the save status of the just saved document
|
||||||
responses.push_back(PortfolioMessage::UpdateOpenDocumentsList.into());
|
responses.add(PortfolioMessage::UpdateOpenDocumentsList);
|
||||||
|
|
||||||
let name = match self.name.ends_with(FILE_SAVE_SUFFIX) {
|
let name = match self.name.ends_with(FILE_SAVE_SUFFIX) {
|
||||||
true => self.name.clone(),
|
true => self.name.clone(),
|
||||||
false => self.name.clone() + FILE_SAVE_SUFFIX,
|
false => self.name.clone() + FILE_SAVE_SUFFIX,
|
||||||
};
|
};
|
||||||
responses.push_back(
|
responses.add(FrontendMessage::TriggerFileDownload {
|
||||||
FrontendMessage::TriggerFileDownload {
|
document: self.serialize_document(),
|
||||||
document: self.serialize_document(),
|
name,
|
||||||
name,
|
})
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
SelectAllLayers => {
|
SelectAllLayers => {
|
||||||
let all = self.all_layers().map(|path| path.to_vec()).collect();
|
let all = self.all_layers().map(|path| path.to_vec()).collect();
|
||||||
responses.push_front(SetSelectedLayers { replacement_selected_layers: all }.into());
|
responses.add_front(SetSelectedLayers { replacement_selected_layers: all });
|
||||||
}
|
}
|
||||||
SelectedLayersLower => {
|
SelectedLayersLower => {
|
||||||
responses.push_front(DocumentMessage::SelectedLayersReorder { relative_index_offset: -1 }.into());
|
responses.add_front(DocumentMessage::SelectedLayersReorder { relative_index_offset: -1 });
|
||||||
}
|
}
|
||||||
SelectedLayersLowerToBack => {
|
SelectedLayersLowerToBack => {
|
||||||
responses.push_front(DocumentMessage::SelectedLayersReorder { relative_index_offset: isize::MIN }.into());
|
responses.add_front(DocumentMessage::SelectedLayersReorder { relative_index_offset: isize::MIN });
|
||||||
}
|
}
|
||||||
SelectedLayersRaise => {
|
SelectedLayersRaise => {
|
||||||
responses.push_front(DocumentMessage::SelectedLayersReorder { relative_index_offset: 1 }.into());
|
responses.add_front(DocumentMessage::SelectedLayersReorder { relative_index_offset: 1 });
|
||||||
}
|
}
|
||||||
SelectedLayersRaiseToFront => {
|
SelectedLayersRaiseToFront => {
|
||||||
responses.push_front(DocumentMessage::SelectedLayersReorder { relative_index_offset: isize::MAX }.into());
|
responses.add_front(DocumentMessage::SelectedLayersReorder { relative_index_offset: isize::MAX });
|
||||||
}
|
}
|
||||||
SelectedLayersReorder { relative_index_offset } => {
|
SelectedLayersReorder { relative_index_offset } => {
|
||||||
self.selected_layers_reorder(relative_index_offset, responses);
|
self.selected_layers_reorder(relative_index_offset, responses);
|
||||||
@@ -796,13 +744,10 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||||||
// Toggle selection when holding ctrl
|
// Toggle selection when holding ctrl
|
||||||
let layer = self.layer_metadata_mut(&layer_path);
|
let layer = self.layer_metadata_mut(&layer_path);
|
||||||
layer.selected = !layer.selected;
|
layer.selected = !layer.selected;
|
||||||
responses.push_back(
|
responses.add(LayerChanged {
|
||||||
LayerChanged {
|
affected_layer_path: layer_path.clone(),
|
||||||
affected_layer_path: layer_path.clone(),
|
});
|
||||||
}
|
responses.add(BroadcastEvent::SelectionChanged);
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
responses.push_back(BroadcastEvent::SelectionChanged.into());
|
|
||||||
} else {
|
} else {
|
||||||
paths.push(layer_path.clone());
|
paths.push(layer_path.clone());
|
||||||
}
|
}
|
||||||
@@ -815,16 +760,16 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||||||
if !paths.is_empty() {
|
if !paths.is_empty() {
|
||||||
// Add or set our selected layers
|
// Add or set our selected layers
|
||||||
if ctrl {
|
if ctrl {
|
||||||
responses.push_front(AddSelectedLayers { additional_layers: paths }.into());
|
responses.add_front(AddSelectedLayers { additional_layers: paths });
|
||||||
} else {
|
} else {
|
||||||
responses.push_front(SetSelectedLayers { replacement_selected_layers: paths }.into());
|
responses.add_front(SetSelectedLayers { replacement_selected_layers: paths });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SetBlendModeForSelectedLayers { blend_mode } => {
|
SetBlendModeForSelectedLayers { blend_mode } => {
|
||||||
self.backup(responses);
|
self.backup(responses);
|
||||||
for path in self.selected_layers() {
|
for path in self.selected_layers() {
|
||||||
responses.push_back(DocumentOperation::SetLayerBlendMode { path: path.to_vec(), blend_mode }.into());
|
responses.add(DocumentOperation::SetLayerBlendMode { path: path.to_vec(), blend_mode });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SetImageBlobUrl {
|
SetImageBlobUrl {
|
||||||
@@ -842,7 +787,7 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||||||
match &layer.data {
|
match &layer.data {
|
||||||
LayerDataType::NodeGraphFrame(node_graph_frame) => {
|
LayerDataType::NodeGraphFrame(node_graph_frame) => {
|
||||||
if let Some(url) = node_graph_frame.as_blob_url() {
|
if let Some(url) = node_graph_frame.as_blob_url() {
|
||||||
responses.push_back(FrontendMessage::TriggerRevokeBlobUrl { url: url.clone() }.into());
|
responses.add(FrontendMessage::TriggerRevokeBlobUrl { url: url.clone() });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
other => {
|
other => {
|
||||||
@@ -854,25 +799,22 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
responses.push_back(
|
responses.add(PortfolioMessage::DocumentPassMessage {
|
||||||
PortfolioMessage::DocumentPassMessage {
|
document_id,
|
||||||
document_id,
|
message: DocumentOperation::SetLayerBlobUrl { layer_path, blob_url, resolution }.into(),
|
||||||
message: DocumentOperation::SetLayerBlobUrl { layer_path, blob_url, resolution }.into(),
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
SetLayerExpansion { layer_path, set_expanded } => {
|
SetLayerExpansion { layer_path, set_expanded } => {
|
||||||
self.layer_metadata_mut(&layer_path).expanded = set_expanded;
|
self.layer_metadata_mut(&layer_path).expanded = set_expanded;
|
||||||
responses.push_back(DocumentStructureChanged.into());
|
responses.add(DocumentStructureChanged);
|
||||||
responses.push_back(LayerChanged { affected_layer_path: layer_path }.into())
|
responses.add(LayerChanged { affected_layer_path: layer_path })
|
||||||
}
|
}
|
||||||
SetLayerName { layer_path, name } => {
|
SetLayerName { layer_path, name } => {
|
||||||
if let Some(layer) = self.layer_panel_entry_from_path(&layer_path, &render_data) {
|
if let Some(layer) = self.layer_panel_entry_from_path(&layer_path, &render_data) {
|
||||||
// Only save the history state if the name actually changed to something different
|
// Only save the history state if the name actually changed to something different
|
||||||
if layer.name != name {
|
if layer.name != name {
|
||||||
self.backup(responses);
|
self.backup(responses);
|
||||||
responses.push_back(DocumentOperation::SetLayerName { path: layer_path, name }.into());
|
responses.add(DocumentOperation::SetLayerName { path: layer_path, name });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -881,57 +823,57 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||||||
let opacity = opacity.clamp(0., 1.);
|
let opacity = opacity.clamp(0., 1.);
|
||||||
|
|
||||||
for path in self.selected_layers().map(|path| path.to_vec()) {
|
for path in self.selected_layers().map(|path| path.to_vec()) {
|
||||||
responses.push_back(DocumentOperation::SetLayerOpacity { path, opacity }.into());
|
responses.add(DocumentOperation::SetLayerOpacity { path, opacity });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SetOverlaysVisibility { visible } => {
|
SetOverlaysVisibility { visible } => {
|
||||||
self.overlays_visible = visible;
|
self.overlays_visible = visible;
|
||||||
responses.push_back(BroadcastEvent::ToolAbort.into());
|
responses.add(BroadcastEvent::ToolAbort);
|
||||||
responses.push_back(OverlaysMessage::ClearAllOverlays.into());
|
responses.add(OverlaysMessage::ClearAllOverlays);
|
||||||
responses.push_back(OverlaysMessage::Rerender.into());
|
responses.add(OverlaysMessage::Rerender);
|
||||||
}
|
}
|
||||||
SetSelectedLayers { replacement_selected_layers } => {
|
SetSelectedLayers { replacement_selected_layers } => {
|
||||||
let selected = self.layer_metadata.iter_mut().filter(|(_, layer_metadata)| layer_metadata.selected);
|
let selected = self.layer_metadata.iter_mut().filter(|(_, layer_metadata)| layer_metadata.selected);
|
||||||
selected.for_each(|(path, layer_metadata)| {
|
selected.for_each(|(path, layer_metadata)| {
|
||||||
layer_metadata.selected = false;
|
layer_metadata.selected = false;
|
||||||
responses.push_back(LayerChanged { affected_layer_path: path.clone() }.into())
|
responses.add(LayerChanged { affected_layer_path: path.clone() })
|
||||||
});
|
});
|
||||||
|
|
||||||
let additional_layers = replacement_selected_layers;
|
let additional_layers = replacement_selected_layers;
|
||||||
responses.push_front(AddSelectedLayers { additional_layers }.into());
|
responses.add_front(AddSelectedLayers { additional_layers });
|
||||||
}
|
}
|
||||||
SetSnapping { snap } => {
|
SetSnapping { snap } => {
|
||||||
self.snapping_enabled = snap;
|
self.snapping_enabled = snap;
|
||||||
}
|
}
|
||||||
SetViewMode { view_mode } => {
|
SetViewMode { view_mode } => {
|
||||||
self.view_mode = view_mode;
|
self.view_mode = view_mode;
|
||||||
responses.push_front(DocumentMessage::DirtyRenderDocument.into());
|
responses.add_front(DocumentMessage::DirtyRenderDocument);
|
||||||
}
|
}
|
||||||
StartTransaction => self.backup(responses),
|
StartTransaction => self.backup(responses),
|
||||||
ToggleLayerExpansion { layer_path } => {
|
ToggleLayerExpansion { layer_path } => {
|
||||||
self.layer_metadata_mut(&layer_path).expanded ^= true;
|
self.layer_metadata_mut(&layer_path).expanded ^= true;
|
||||||
responses.push_back(DocumentStructureChanged.into());
|
responses.add(DocumentStructureChanged);
|
||||||
responses.push_back(LayerChanged { affected_layer_path: layer_path }.into())
|
responses.add(LayerChanged { affected_layer_path: layer_path })
|
||||||
}
|
}
|
||||||
ToggleLayerVisibility { layer_path } => {
|
ToggleLayerVisibility { layer_path } => {
|
||||||
responses.push_back(DocumentOperation::ToggleLayerVisibility { path: layer_path }.into());
|
responses.add(DocumentOperation::ToggleLayerVisibility { path: layer_path });
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
}
|
}
|
||||||
Undo => {
|
Undo => {
|
||||||
self.undo_in_progress = true;
|
self.undo_in_progress = true;
|
||||||
responses.push_back(BroadcastEvent::ToolAbort.into());
|
responses.add(BroadcastEvent::ToolAbort);
|
||||||
responses.push_back(DocumentHistoryBackward.into());
|
responses.add(DocumentHistoryBackward);
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
responses.push_back(RenderDocument.into());
|
responses.add(RenderDocument);
|
||||||
responses.push_back(FolderChanged { affected_folder_path: vec![] }.into());
|
responses.add(FolderChanged { affected_folder_path: vec![] });
|
||||||
responses.push_back(UndoFinished.into());
|
responses.add(UndoFinished);
|
||||||
}
|
}
|
||||||
UndoFinished => self.undo_in_progress = false,
|
UndoFinished => self.undo_in_progress = false,
|
||||||
UngroupLayers { folder_path } => {
|
UngroupLayers { folder_path } => {
|
||||||
// Select all the children of the folder
|
// Select all the children of the folder
|
||||||
let select = self.document_legacy.folder_children_paths(&folder_path);
|
let select = self.document_legacy.folder_children_paths(&folder_path);
|
||||||
|
|
||||||
let message_buffer = [
|
let message_buffer: [Message; 4] = [
|
||||||
// Select them
|
// Select them
|
||||||
DocumentMessage::SetSelectedLayers { replacement_selected_layers: select }.into(),
|
DocumentMessage::SetSelectedLayers { replacement_selected_layers: select }.into(),
|
||||||
// Copy them
|
// Copy them
|
||||||
@@ -949,36 +891,33 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||||||
|
|
||||||
// Push these messages in reverse due to push_front
|
// Push these messages in reverse due to push_front
|
||||||
for message in message_buffer.into_iter().rev() {
|
for message in message_buffer.into_iter().rev() {
|
||||||
responses.push_front(message);
|
responses.add_front(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UngroupSelectedLayers => {
|
UngroupSelectedLayers => {
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
let folder_paths = self.document_legacy.sorted_folders_by_depth(self.selected_layers());
|
let folder_paths = self.document_legacy.sorted_folders_by_depth(self.selected_layers());
|
||||||
for folder_path in folder_paths {
|
for folder_path in folder_paths {
|
||||||
responses.push_back(DocumentMessage::UngroupLayers { folder_path: folder_path.to_vec() }.into());
|
responses.add(DocumentMessage::UngroupLayers { folder_path: folder_path.to_vec() });
|
||||||
}
|
}
|
||||||
responses.push_back(DocumentMessage::CommitTransaction.into());
|
responses.add(DocumentMessage::CommitTransaction);
|
||||||
}
|
}
|
||||||
UpdateLayerMetadata { layer_path, layer_metadata } => {
|
UpdateLayerMetadata { layer_path, layer_metadata } => {
|
||||||
self.layer_metadata.insert(layer_path, layer_metadata);
|
self.layer_metadata.insert(layer_path, layer_metadata);
|
||||||
}
|
}
|
||||||
ZoomCanvasTo100Percent => {
|
ZoomCanvasTo100Percent => {
|
||||||
responses.push_front(NavigationMessage::SetCanvasZoom { zoom_factor: 1. }.into());
|
responses.add_front(NavigationMessage::SetCanvasZoom { zoom_factor: 1. });
|
||||||
}
|
}
|
||||||
ZoomCanvasTo200Percent => {
|
ZoomCanvasTo200Percent => {
|
||||||
responses.push_front(NavigationMessage::SetCanvasZoom { zoom_factor: 2. }.into());
|
responses.add_front(NavigationMessage::SetCanvasZoom { zoom_factor: 2. });
|
||||||
}
|
}
|
||||||
ZoomCanvasToFitAll => {
|
ZoomCanvasToFitAll => {
|
||||||
if let Some(bounds) = self.document_bounds(&render_data) {
|
if let Some(bounds) = self.document_bounds(&render_data) {
|
||||||
responses.push_back(
|
responses.add(NavigationMessage::FitViewportToBounds {
|
||||||
NavigationMessage::FitViewportToBounds {
|
bounds,
|
||||||
bounds,
|
padding_scale_factor: Some(VIEWPORT_ZOOM_TO_FIT_PADDING_SCALE_FACTOR),
|
||||||
padding_scale_factor: Some(VIEWPORT_ZOOM_TO_FIT_PADDING_SCALE_FACTOR),
|
prevent_zoom_past_100: true,
|
||||||
prevent_zoom_past_100: true,
|
})
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1387,7 +1326,7 @@ impl DocumentMessageHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Push the UpdateOpenDocumentsList message to the bus in order to update the save status of the open documents
|
// Push the UpdateOpenDocumentsList message to the bus in order to update the save status of the open documents
|
||||||
responses.push_back(PortfolioMessage::UpdateOpenDocumentsList.into());
|
responses.add(PortfolioMessage::UpdateOpenDocumentsList);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Copies the entire document into the history system
|
/// Copies the entire document into the history system
|
||||||
@@ -1397,14 +1336,11 @@ impl DocumentMessageHandler {
|
|||||||
|
|
||||||
/// Push a message backing up the document in its current state
|
/// Push a message backing up the document in its current state
|
||||||
pub fn backup_nonmut(&self, responses: &mut VecDeque<Message>) {
|
pub fn backup_nonmut(&self, responses: &mut VecDeque<Message>) {
|
||||||
responses.push_back(
|
responses.add(DocumentMessage::BackupDocument {
|
||||||
DocumentMessage::BackupDocument {
|
document: self.document_legacy.clone(),
|
||||||
document: self.document_legacy.clone(),
|
artboard: Box::new(self.artboard_message_handler.clone()),
|
||||||
artboard: Box::new(self.artboard_message_handler.clone()),
|
layer_metadata: self.layer_metadata.clone(),
|
||||||
layer_metadata: self.layer_metadata.clone(),
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rollback(&mut self, responses: &mut VecDeque<Message>) -> Result<(), EditorError> {
|
pub fn rollback(&mut self, responses: &mut VecDeque<Message>) -> Result<(), EditorError> {
|
||||||
@@ -1432,7 +1368,7 @@ impl DocumentMessageHandler {
|
|||||||
|
|
||||||
pub fn undo(&mut self, responses: &mut VecDeque<Message>) -> Result<(), EditorError> {
|
pub fn undo(&mut self, responses: &mut VecDeque<Message>) -> Result<(), EditorError> {
|
||||||
// Push the UpdateOpenDocumentsList message to the bus in order to update the save status of the open documents
|
// Push the UpdateOpenDocumentsList message to the bus in order to update the save status of the open documents
|
||||||
responses.push_back(PortfolioMessage::UpdateOpenDocumentsList.into());
|
responses.add(PortfolioMessage::UpdateOpenDocumentsList);
|
||||||
|
|
||||||
let selected_paths: Vec<Vec<LayerId>> = self.selected_layers().map(|path| path.to_vec()).collect();
|
let selected_paths: Vec<Vec<LayerId>> = self.selected_layers().map(|path| path.to_vec()).collect();
|
||||||
|
|
||||||
@@ -1443,7 +1379,7 @@ impl DocumentMessageHandler {
|
|||||||
let prev_selected_paths: Vec<Vec<LayerId>> = layer_metadata.iter().filter_map(|(layer_id, metadata)| metadata.selected.then_some(layer_id.clone())).collect();
|
let prev_selected_paths: Vec<Vec<LayerId>> = layer_metadata.iter().filter_map(|(layer_id, metadata)| metadata.selected.then_some(layer_id.clone())).collect();
|
||||||
|
|
||||||
if prev_selected_paths != selected_paths {
|
if prev_selected_paths != selected_paths {
|
||||||
responses.push_back(BroadcastEvent::SelectionChanged.into());
|
responses.add(BroadcastEvent::SelectionChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
let document_save = self.replace_document(DocumentSave { document, artboard, layer_metadata });
|
let document_save = self.replace_document(DocumentSave { document, artboard, layer_metadata });
|
||||||
@@ -1454,10 +1390,10 @@ impl DocumentMessageHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for layer in self.layer_metadata.keys() {
|
for layer in self.layer_metadata.keys() {
|
||||||
responses.push_back(DocumentMessage::LayerChanged { affected_layer_path: layer.clone() }.into())
|
responses.add(DocumentMessage::LayerChanged { affected_layer_path: layer.clone() })
|
||||||
}
|
}
|
||||||
|
|
||||||
responses.push_back(NodeGraphMessage::SendGraph { should_rerender: true }.into());
|
responses.add(NodeGraphMessage::SendGraph { should_rerender: true });
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -1467,7 +1403,7 @@ impl DocumentMessageHandler {
|
|||||||
|
|
||||||
pub fn redo(&mut self, responses: &mut VecDeque<Message>) -> Result<(), EditorError> {
|
pub fn redo(&mut self, responses: &mut VecDeque<Message>) -> Result<(), EditorError> {
|
||||||
// Push the UpdateOpenDocumentsList message to the bus in order to update the save status of the open documents
|
// Push the UpdateOpenDocumentsList message to the bus in order to update the save status of the open documents
|
||||||
responses.push_back(PortfolioMessage::UpdateOpenDocumentsList.into());
|
responses.add(PortfolioMessage::UpdateOpenDocumentsList);
|
||||||
|
|
||||||
let selected_paths: Vec<Vec<LayerId>> = self.selected_layers().map(|path| path.to_vec()).collect();
|
let selected_paths: Vec<Vec<LayerId>> = self.selected_layers().map(|path| path.to_vec()).collect();
|
||||||
|
|
||||||
@@ -1478,7 +1414,7 @@ impl DocumentMessageHandler {
|
|||||||
let next_selected_paths: Vec<Vec<LayerId>> = layer_metadata.iter().filter_map(|(layer_id, metadata)| metadata.selected.then_some(layer_id.clone())).collect();
|
let next_selected_paths: Vec<Vec<LayerId>> = layer_metadata.iter().filter_map(|(layer_id, metadata)| metadata.selected.then_some(layer_id.clone())).collect();
|
||||||
|
|
||||||
if next_selected_paths != selected_paths {
|
if next_selected_paths != selected_paths {
|
||||||
responses.push_back(BroadcastEvent::SelectionChanged.into());
|
responses.add(BroadcastEvent::SelectionChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
let document_save = self.replace_document(DocumentSave { document, artboard, layer_metadata });
|
let document_save = self.replace_document(DocumentSave { document, artboard, layer_metadata });
|
||||||
@@ -1488,10 +1424,10 @@ impl DocumentMessageHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for layer in self.layer_metadata.keys() {
|
for layer in self.layer_metadata.keys() {
|
||||||
responses.push_back(DocumentMessage::LayerChanged { affected_layer_path: layer.clone() }.into())
|
responses.add(DocumentMessage::LayerChanged { affected_layer_path: layer.clone() })
|
||||||
}
|
}
|
||||||
|
|
||||||
responses.push_back(NodeGraphMessage::SendGraph { should_rerender: true }.into());
|
responses.add(NodeGraphMessage::SendGraph { should_rerender: true });
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -1630,7 +1566,7 @@ impl DocumentMessageHandler {
|
|||||||
let mut fonts = HashSet::new();
|
let mut fonts = HashSet::new();
|
||||||
walk_layers(root, &mut path, responses, &mut fonts);
|
walk_layers(root, &mut path, responses, &mut fonts);
|
||||||
for font in fonts {
|
for font in fonts {
|
||||||
responses.push_front(FrontendMessage::TriggerFontLoad { font, is_default: false }.into());
|
responses.add_front(FrontendMessage::TriggerFontLoad { font, is_default: false });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1836,21 +1772,15 @@ impl DocumentMessageHandler {
|
|||||||
],
|
],
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
responses.push_back(
|
responses.add(LayoutMessage::SendLayout {
|
||||||
LayoutMessage::SendLayout {
|
layout: Layout::WidgetLayout(document_bar_layout),
|
||||||
layout: Layout::WidgetLayout(document_bar_layout),
|
layout_target: LayoutTarget::DocumentBar,
|
||||||
layout_target: LayoutTarget::DocumentBar,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
|
|
||||||
responses.push_back(
|
responses.add(LayoutMessage::SendLayout {
|
||||||
LayoutMessage::SendLayout {
|
layout: Layout::WidgetLayout(document_mode_layout),
|
||||||
layout: Layout::WidgetLayout(document_mode_layout),
|
layout_target: LayoutTarget::DocumentMode,
|
||||||
layout_target: LayoutTarget::DocumentMode,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_layer_tree_options_bar_widgets(&self, responses: &mut VecDeque<Message>, render_data: &RenderData) {
|
pub fn update_layer_tree_options_bar_widgets(&self, responses: &mut VecDeque<Message>, render_data: &RenderData) {
|
||||||
@@ -1963,13 +1893,10 @@ impl DocumentMessageHandler {
|
|||||||
],
|
],
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
responses.push_back(
|
responses.add(LayoutMessage::SendLayout {
|
||||||
LayoutMessage::SendLayout {
|
layout: Layout::WidgetLayout(layer_tree_options),
|
||||||
layout: Layout::WidgetLayout(layer_tree_options),
|
layout_target: LayoutTarget::LayerTreeOptions,
|
||||||
layout_target: LayoutTarget::LayerTreeOptions,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn selected_layers_reorder(&mut self, relative_index_offset: isize, responses: &mut VecDeque<Message>) {
|
pub fn selected_layers_reorder(&mut self, relative_index_offset: isize, responses: &mut VecDeque<Message>) {
|
||||||
@@ -2014,14 +1941,11 @@ impl DocumentMessageHandler {
|
|||||||
// If moving down, insert below this layer. If moving up, insert above this layer.
|
// If moving down, insert below this layer. If moving up, insert above this layer.
|
||||||
let insert_index = if relative_index_offset < 0 { neighbor_layer_index } else { neighbor_layer_index + 1 };
|
let insert_index = if relative_index_offset < 0 { neighbor_layer_index } else { neighbor_layer_index + 1 };
|
||||||
|
|
||||||
responses.push_back(
|
responses.add(DocumentMessage::MoveSelectedLayersTo {
|
||||||
DocumentMessage::MoveSelectedLayersTo {
|
folder_path: folder_path.to_vec(),
|
||||||
folder_path: folder_path.to_vec(),
|
insert_index,
|
||||||
insert_index,
|
reverse_index: false,
|
||||||
reverse_index: false,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,9 +61,9 @@ impl MessageHandler<NavigationMessage, (&Document, &InputPreprocessorMessageHand
|
|||||||
DecreaseCanvasZoom { center_on_mouse } => {
|
DecreaseCanvasZoom { center_on_mouse } => {
|
||||||
let new_scale = *VIEWPORT_ZOOM_LEVELS.iter().rev().find(|scale| **scale < self.zoom).unwrap_or(&self.zoom);
|
let new_scale = *VIEWPORT_ZOOM_LEVELS.iter().rev().find(|scale| **scale < self.zoom).unwrap_or(&self.zoom);
|
||||||
if center_on_mouse {
|
if center_on_mouse {
|
||||||
responses.push_back(self.center_zoom(ipp.viewport_bounds.size(), new_scale / self.zoom, ipp.mouse.position));
|
responses.add(self.center_zoom(ipp.viewport_bounds.size(), new_scale / self.zoom, ipp.mouse.position));
|
||||||
}
|
}
|
||||||
responses.push_back(SetCanvasZoom { zoom_factor: new_scale }.into());
|
responses.add(SetCanvasZoom { zoom_factor: new_scale });
|
||||||
}
|
}
|
||||||
FitViewportToBounds {
|
FitViewportToBounds {
|
||||||
bounds: [bounds_corner_a, bounds_corner_b],
|
bounds: [bounds_corner_a, bounds_corner_b],
|
||||||
@@ -89,29 +89,26 @@ impl MessageHandler<NavigationMessage, (&Document, &InputPreprocessorMessageHand
|
|||||||
self.zoom = 1.
|
self.zoom = 1.
|
||||||
}
|
}
|
||||||
|
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
responses.push_back(DocumentMessage::DirtyRenderDocumentInOutlineView.into());
|
responses.add(DocumentMessage::DirtyRenderDocumentInOutlineView);
|
||||||
responses.push_back(PortfolioMessage::UpdateDocumentWidgets.into());
|
responses.add(PortfolioMessage::UpdateDocumentWidgets);
|
||||||
self.create_document_transform(&ipp.viewport_bounds, responses);
|
self.create_document_transform(&ipp.viewport_bounds, responses);
|
||||||
}
|
}
|
||||||
FitViewportToSelection => {
|
FitViewportToSelection => {
|
||||||
if let Some(bounds) = selection_bounds {
|
if let Some(bounds) = selection_bounds {
|
||||||
responses.push_back(
|
responses.add(FitViewportToBounds {
|
||||||
FitViewportToBounds {
|
bounds,
|
||||||
bounds,
|
padding_scale_factor: Some(VIEWPORT_ZOOM_TO_FIT_PADDING_SCALE_FACTOR),
|
||||||
padding_scale_factor: Some(VIEWPORT_ZOOM_TO_FIT_PADDING_SCALE_FACTOR),
|
prevent_zoom_past_100: false,
|
||||||
prevent_zoom_past_100: false,
|
})
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IncreaseCanvasZoom { center_on_mouse } => {
|
IncreaseCanvasZoom { center_on_mouse } => {
|
||||||
let new_scale = *VIEWPORT_ZOOM_LEVELS.iter().find(|scale| **scale > self.zoom).unwrap_or(&self.zoom);
|
let new_scale = *VIEWPORT_ZOOM_LEVELS.iter().find(|scale| **scale > self.zoom).unwrap_or(&self.zoom);
|
||||||
if center_on_mouse {
|
if center_on_mouse {
|
||||||
responses.push_back(self.center_zoom(ipp.viewport_bounds.size(), new_scale / self.zoom, ipp.mouse.position));
|
responses.add(self.center_zoom(ipp.viewport_bounds.size(), new_scale / self.zoom, ipp.mouse.position));
|
||||||
}
|
}
|
||||||
responses.push_back(SetCanvasZoom { zoom_factor: new_scale }.into());
|
responses.add(SetCanvasZoom { zoom_factor: new_scale });
|
||||||
}
|
}
|
||||||
PointerMove {
|
PointerMove {
|
||||||
snap_angle,
|
snap_angle,
|
||||||
@@ -122,7 +119,7 @@ impl MessageHandler<NavigationMessage, (&Document, &InputPreprocessorMessageHand
|
|||||||
if self.panning {
|
if self.panning {
|
||||||
let delta = ipp.mouse.position - self.mouse_position;
|
let delta = ipp.mouse.position - self.mouse_position;
|
||||||
|
|
||||||
responses.push_back(TranslateCanvas { delta }.into());
|
responses.add(TranslateCanvas { delta });
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.tilting {
|
if self.tilting {
|
||||||
@@ -143,7 +140,7 @@ impl MessageHandler<NavigationMessage, (&Document, &InputPreprocessorMessageHand
|
|||||||
start_offset.angle_between(end_offset)
|
start_offset.angle_between(end_offset)
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push_back(SetCanvasRotation { angle_radians: self.tilt + rotation }.into());
|
responses.add(SetCanvasRotation { angle_radians: self.tilt + rotation });
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.zooming {
|
if self.zooming {
|
||||||
@@ -163,29 +160,26 @@ impl MessageHandler<NavigationMessage, (&Document, &InputPreprocessorMessageHand
|
|||||||
if let Some(mouse) = zoom_from_viewport {
|
if let Some(mouse) = zoom_from_viewport {
|
||||||
let zoom_factor = self.snapped_scale() / zoom_start;
|
let zoom_factor = self.snapped_scale() / zoom_start;
|
||||||
|
|
||||||
responses.push_back(SetCanvasZoom { zoom_factor: self.zoom }.into());
|
responses.add(SetCanvasZoom { zoom_factor: self.zoom });
|
||||||
responses.push_back(self.center_zoom(ipp.viewport_bounds.size(), zoom_factor, mouse));
|
responses.add(self.center_zoom(ipp.viewport_bounds.size(), zoom_factor, mouse));
|
||||||
} else {
|
} else {
|
||||||
responses.push_back(SetCanvasZoom { zoom_factor: self.zoom }.into());
|
responses.add(SetCanvasZoom { zoom_factor: self.zoom });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.mouse_position = ipp.mouse.position;
|
self.mouse_position = ipp.mouse.position;
|
||||||
}
|
}
|
||||||
RotateCanvasBegin => {
|
RotateCanvasBegin => {
|
||||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Default }.into());
|
responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Default });
|
||||||
responses.push_back(
|
responses.add(FrontendMessage::UpdateInputHints {
|
||||||
FrontendMessage::UpdateInputHints {
|
hint_data: HintData(vec![HintGroup(vec![HintInfo {
|
||||||
hint_data: HintData(vec![HintGroup(vec![HintInfo {
|
key_groups: vec![KeysGroup(vec![Key::Control]).into()],
|
||||||
key_groups: vec![KeysGroup(vec![Key::Control]).into()],
|
key_groups_mac: None,
|
||||||
key_groups_mac: None,
|
mouse: None,
|
||||||
mouse: None,
|
label: String::from("Snap 15°"),
|
||||||
label: String::from("Snap 15°"),
|
plus: false,
|
||||||
plus: false,
|
}])]),
|
||||||
}])]),
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
|
|
||||||
self.tilting = true;
|
self.tilting = true;
|
||||||
self.mouse_position = ipp.mouse.position;
|
self.mouse_position = ipp.mouse.position;
|
||||||
@@ -193,22 +187,22 @@ impl MessageHandler<NavigationMessage, (&Document, &InputPreprocessorMessageHand
|
|||||||
SetCanvasRotation { angle_radians } => {
|
SetCanvasRotation { angle_radians } => {
|
||||||
self.tilt = angle_radians;
|
self.tilt = angle_radians;
|
||||||
self.create_document_transform(&ipp.viewport_bounds, responses);
|
self.create_document_transform(&ipp.viewport_bounds, responses);
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
responses.push_back(PortfolioMessage::UpdateDocumentWidgets.into());
|
responses.add(PortfolioMessage::UpdateDocumentWidgets);
|
||||||
}
|
}
|
||||||
SetCanvasZoom { zoom_factor } => {
|
SetCanvasZoom { zoom_factor } => {
|
||||||
self.zoom = zoom_factor.clamp(VIEWPORT_ZOOM_SCALE_MIN, VIEWPORT_ZOOM_SCALE_MAX);
|
self.zoom = zoom_factor.clamp(VIEWPORT_ZOOM_SCALE_MIN, VIEWPORT_ZOOM_SCALE_MAX);
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
responses.push_back(DocumentMessage::DirtyRenderDocumentInOutlineView.into());
|
responses.add(DocumentMessage::DirtyRenderDocumentInOutlineView);
|
||||||
responses.push_back(PortfolioMessage::UpdateDocumentWidgets.into());
|
responses.add(PortfolioMessage::UpdateDocumentWidgets);
|
||||||
self.create_document_transform(&ipp.viewport_bounds, responses);
|
self.create_document_transform(&ipp.viewport_bounds, responses);
|
||||||
}
|
}
|
||||||
TransformCanvasEnd => {
|
TransformCanvasEnd => {
|
||||||
self.tilt = self.snapped_angle();
|
self.tilt = self.snapped_angle();
|
||||||
self.zoom = self.snapped_scale();
|
self.zoom = self.snapped_scale();
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
responses.push_back(ToolMessage::UpdateCursor.into());
|
responses.add(ToolMessage::UpdateCursor);
|
||||||
responses.push_back(ToolMessage::UpdateHints.into());
|
responses.add(ToolMessage::UpdateHints);
|
||||||
self.snap_tilt = false;
|
self.snap_tilt = false;
|
||||||
self.snap_tilt_released = false;
|
self.snap_tilt_released = false;
|
||||||
self.snap_zoom = false;
|
self.snap_zoom = false;
|
||||||
@@ -220,12 +214,12 @@ impl MessageHandler<NavigationMessage, (&Document, &InputPreprocessorMessageHand
|
|||||||
let transformed_delta = document.root.transform.inverse().transform_vector2(delta);
|
let transformed_delta = document.root.transform.inverse().transform_vector2(delta);
|
||||||
|
|
||||||
self.pan += transformed_delta;
|
self.pan += transformed_delta;
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
self.create_document_transform(&ipp.viewport_bounds, responses);
|
self.create_document_transform(&ipp.viewport_bounds, responses);
|
||||||
}
|
}
|
||||||
TranslateCanvasBegin => {
|
TranslateCanvasBegin => {
|
||||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Grabbing }.into());
|
responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Grabbing });
|
||||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data: HintData(Vec::new()) }.into());
|
responses.add(FrontendMessage::UpdateInputHints { hint_data: HintData(Vec::new()) });
|
||||||
|
|
||||||
self.panning = true;
|
self.panning = true;
|
||||||
self.mouse_position = ipp.mouse.position;
|
self.mouse_position = ipp.mouse.position;
|
||||||
@@ -234,7 +228,7 @@ impl MessageHandler<NavigationMessage, (&Document, &InputPreprocessorMessageHand
|
|||||||
let transformed_delta = document.root.transform.inverse().transform_vector2(delta * ipp.viewport_bounds.size());
|
let transformed_delta = document.root.transform.inverse().transform_vector2(delta * ipp.viewport_bounds.size());
|
||||||
|
|
||||||
self.pan += transformed_delta;
|
self.pan += transformed_delta;
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
self.create_document_transform(&ipp.viewport_bounds, responses);
|
self.create_document_transform(&ipp.viewport_bounds, responses);
|
||||||
}
|
}
|
||||||
WheelCanvasTranslate { use_y_as_x } => {
|
WheelCanvasTranslate { use_y_as_x } => {
|
||||||
@@ -242,7 +236,7 @@ impl MessageHandler<NavigationMessage, (&Document, &InputPreprocessorMessageHand
|
|||||||
false => -ipp.mouse.scroll_delta.as_dvec2(),
|
false => -ipp.mouse.scroll_delta.as_dvec2(),
|
||||||
true => (-ipp.mouse.scroll_delta.y as f64, 0.).into(),
|
true => (-ipp.mouse.scroll_delta.y as f64, 0.).into(),
|
||||||
} * VIEWPORT_SCROLL_RATE;
|
} * VIEWPORT_SCROLL_RATE;
|
||||||
responses.push_back(TranslateCanvas { delta }.into());
|
responses.add(TranslateCanvas { delta });
|
||||||
}
|
}
|
||||||
WheelCanvasZoom => {
|
WheelCanvasZoom => {
|
||||||
let scroll = ipp.mouse.scroll_delta.scroll_delta();
|
let scroll = ipp.mouse.scroll_delta.scroll_delta();
|
||||||
@@ -251,23 +245,20 @@ impl MessageHandler<NavigationMessage, (&Document, &InputPreprocessorMessageHand
|
|||||||
zoom_factor = 1. / zoom_factor
|
zoom_factor = 1. / zoom_factor
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push_back(self.center_zoom(ipp.viewport_bounds.size(), zoom_factor, ipp.mouse.position));
|
responses.add(self.center_zoom(ipp.viewport_bounds.size(), zoom_factor, ipp.mouse.position));
|
||||||
responses.push_back(SetCanvasZoom { zoom_factor: self.zoom * zoom_factor }.into());
|
responses.add(SetCanvasZoom { zoom_factor: self.zoom * zoom_factor });
|
||||||
}
|
}
|
||||||
ZoomCanvasBegin => {
|
ZoomCanvasBegin => {
|
||||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::ZoomIn }.into());
|
responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::ZoomIn });
|
||||||
responses.push_back(
|
responses.add(FrontendMessage::UpdateInputHints {
|
||||||
FrontendMessage::UpdateInputHints {
|
hint_data: HintData(vec![HintGroup(vec![HintInfo {
|
||||||
hint_data: HintData(vec![HintGroup(vec![HintInfo {
|
key_groups: vec![KeysGroup(vec![Key::Control]).into()],
|
||||||
key_groups: vec![KeysGroup(vec![Key::Control]).into()],
|
key_groups_mac: None,
|
||||||
key_groups_mac: None,
|
mouse: None,
|
||||||
mouse: None,
|
label: String::from("Snap Increments"),
|
||||||
label: String::from("Snap Increments"),
|
plus: false,
|
||||||
plus: false,
|
}])]),
|
||||||
}])]),
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
|
|
||||||
self.zooming = true;
|
self.zooming = true;
|
||||||
self.mouse_position = ipp.mouse.position;
|
self.mouse_position = ipp.mouse.position;
|
||||||
@@ -338,24 +329,18 @@ impl NavigationMessageHandler {
|
|||||||
fn create_document_transform(&self, viewport_bounds: &ViewportBounds, responses: &mut VecDeque<Message>) {
|
fn create_document_transform(&self, viewport_bounds: &ViewportBounds, responses: &mut VecDeque<Message>) {
|
||||||
let half_viewport = viewport_bounds.size() / 2.;
|
let half_viewport = viewport_bounds.size() / 2.;
|
||||||
let scaled_half_viewport = half_viewport / self.snapped_scale();
|
let scaled_half_viewport = half_viewport / self.snapped_scale();
|
||||||
responses.push_back(
|
responses.add(DocumentOperation::SetLayerTransform {
|
||||||
|
path: vec![],
|
||||||
|
transform: self.calculate_offset_transform(scaled_half_viewport).to_cols_array(),
|
||||||
|
});
|
||||||
|
|
||||||
|
responses.add(ArtboardMessage::DispatchOperation(
|
||||||
DocumentOperation::SetLayerTransform {
|
DocumentOperation::SetLayerTransform {
|
||||||
path: vec![],
|
path: vec![],
|
||||||
transform: self.calculate_offset_transform(scaled_half_viewport).to_cols_array(),
|
transform: self.calculate_offset_transform(scaled_half_viewport).to_cols_array(),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
);
|
));
|
||||||
|
|
||||||
responses.push_back(
|
|
||||||
ArtboardMessage::DispatchOperation(
|
|
||||||
DocumentOperation::SetLayerTransform {
|
|
||||||
path: vec![],
|
|
||||||
transform: self.calculate_offset_transform(scaled_half_viewport).to_cols_array(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn center_zoom(&self, viewport_bounds: DVec2, zoom_factor: f64, mouse: DVec2) -> Message {
|
pub fn center_zoom(&self, viewport_bounds: DVec2, zoom_factor: f64, mouse: DVec2) -> Message {
|
||||||
|
|||||||
@@ -137,13 +137,10 @@ impl NodeGraphMessageHandler {
|
|||||||
|
|
||||||
/// Send the cached layout for the bar at the top of the node panel to the frontend
|
/// Send the cached layout for the bar at the top of the node panel to the frontend
|
||||||
fn send_node_bar_layout(&self, responses: &mut VecDeque<Message>) {
|
fn send_node_bar_layout(&self, responses: &mut VecDeque<Message>) {
|
||||||
responses.push_back(
|
responses.add(LayoutMessage::SendLayout {
|
||||||
LayoutMessage::SendLayout {
|
layout: Layout::WidgetLayout(WidgetLayout::new(self.widgets.to_vec())),
|
||||||
layout: Layout::WidgetLayout(WidgetLayout::new(self.widgets.to_vec())),
|
layout_target: crate::messages::layout::utility_types::misc::LayoutTarget::NodeGraphBar,
|
||||||
layout_target: crate::messages::layout::utility_types::misc::LayoutTarget::NodeGraphBar,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Collect the addresses of the currently viewed nested node e.g. Root -> MyFunFilter -> Exposure
|
/// Collect the addresses of the currently viewed nested node e.g. Root -> MyFunFilter -> Exposure
|
||||||
@@ -249,7 +246,7 @@ impl NodeGraphMessageHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn send_graph(network: &NodeNetwork, responses: &mut VecDeque<Message>) {
|
fn send_graph(network: &NodeNetwork, responses: &mut VecDeque<Message>) {
|
||||||
responses.push_back(PropertiesPanelMessage::ResendActiveProperties.into());
|
responses.add(PropertiesPanelMessage::ResendActiveProperties);
|
||||||
|
|
||||||
// List of links in format (link_start, link_end, link_end_input_index)
|
// List of links in format (link_start, link_end, link_end_input_index)
|
||||||
let links = network
|
let links = network
|
||||||
@@ -315,18 +312,15 @@ impl NodeGraphMessageHandler {
|
|||||||
disabled: network.disabled.contains(id),
|
disabled: network.disabled.contains(id),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
responses.push_back(FrontendMessage::UpdateNodeGraph { nodes, links }.into());
|
responses.add(FrontendMessage::UpdateNodeGraph { nodes, links });
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates the frontend's selection state in line with the backend
|
/// Updates the frontend's selection state in line with the backend
|
||||||
fn update_selected(&mut self, document: &mut Document, responses: &mut VecDeque<Message>) {
|
fn update_selected(&mut self, document: &mut Document, responses: &mut VecDeque<Message>) {
|
||||||
self.update_selection_action_buttons(document, responses);
|
self.update_selection_action_buttons(document, responses);
|
||||||
responses.push_back(
|
responses.add(FrontendMessage::UpdateNodeGraphSelection {
|
||||||
FrontendMessage::UpdateNodeGraphSelection {
|
selected: self.selected_nodes.clone(),
|
||||||
selected: self.selected_nodes.clone(),
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_references_from_network(network: &mut NodeNetwork, deleting_node_id: NodeId) -> bool {
|
fn remove_references_from_network(network: &mut NodeNetwork, deleting_node_id: NodeId) -> bool {
|
||||||
@@ -410,7 +404,7 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
|
|||||||
NodeGraphMessage::CloseNodeGraph => {
|
NodeGraphMessage::CloseNodeGraph => {
|
||||||
if let Some(_old_layer_path) = self.layer_path.take() {
|
if let Some(_old_layer_path) = self.layer_path.take() {
|
||||||
Self::clear_graph(responses);
|
Self::clear_graph(responses);
|
||||||
responses.push_back(PropertiesPanelMessage::ResendActiveProperties.into());
|
responses.add(PropertiesPanelMessage::ResendActiveProperties);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NodeGraphMessage::ConnectNodesByLink {
|
NodeGraphMessage::ConnectNodesByLink {
|
||||||
@@ -434,13 +428,13 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
|
|
||||||
let input = NodeInput::node(output_node, output_node_connector_index);
|
let input = NodeInput::node(output_node, output_node_connector_index);
|
||||||
responses.push_back(NodeGraphMessage::SetNodeInput { node_id, input_index, input }.into());
|
responses.add(NodeGraphMessage::SetNodeInput { node_id, input_index, input });
|
||||||
|
|
||||||
let should_rerender = network.connected_to_output(node_id, true);
|
let should_rerender = network.connected_to_output(node_id, true);
|
||||||
responses.push_back(NodeGraphMessage::SendGraph { should_rerender }.into());
|
responses.add(NodeGraphMessage::SendGraph { should_rerender });
|
||||||
}
|
}
|
||||||
NodeGraphMessage::Copy => {
|
NodeGraphMessage::Copy => {
|
||||||
let Some(network) = self.get_active_network(document) else {
|
let Some(network) = self.get_active_network(document) else {
|
||||||
@@ -456,29 +450,29 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
|
|||||||
let mut copy_text = String::from("graphite/nodes: ");
|
let mut copy_text = String::from("graphite/nodes: ");
|
||||||
copy_text += &serde_json::to_string(&copied_nodes).expect("Could not serialize paste");
|
copy_text += &serde_json::to_string(&copied_nodes).expect("Could not serialize paste");
|
||||||
|
|
||||||
responses.push_back(FrontendMessage::TriggerTextCopy { copy_text }.into());
|
responses.add(FrontendMessage::TriggerTextCopy { copy_text });
|
||||||
}
|
}
|
||||||
NodeGraphMessage::CreateNode { node_id, node_type, x, y } => {
|
NodeGraphMessage::CreateNode { node_id, node_type, x, y } => {
|
||||||
let node_id = node_id.unwrap_or_else(crate::application::generate_uuid);
|
let node_id = node_id.unwrap_or_else(crate::application::generate_uuid);
|
||||||
|
|
||||||
let Some(document_node_type) = document_node_types::resolve_document_node_type(&node_type) else {
|
let Some(document_node_type) = document_node_types::resolve_document_node_type(&node_type) else {
|
||||||
responses.push_back(DialogMessage::DisplayDialogError { title: "Cannot insert node".to_string(), description: format!("The document node '{node_type}' does not exist in the document node list") }.into());
|
responses.add(DialogMessage::DisplayDialogError { title: "Cannot insert node".to_string(), description: format!("The document node '{node_type}' does not exist in the document node list") });
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
|
|
||||||
let document_node = document_node_type.to_document_node(
|
let document_node = document_node_type.to_document_node(
|
||||||
document_node_type.inputs.iter().map(|input| input.default.clone()),
|
document_node_type.inputs.iter().map(|input| input.default.clone()),
|
||||||
graph_craft::document::DocumentNodeMetadata::position((x, y)),
|
graph_craft::document::DocumentNodeMetadata::position((x, y)),
|
||||||
);
|
);
|
||||||
responses.push_back(NodeGraphMessage::InsertNode { node_id, document_node }.into());
|
responses.add(NodeGraphMessage::InsertNode { node_id, document_node });
|
||||||
|
|
||||||
responses.push_back(NodeGraphMessage::SendGraph { should_rerender: false }.into());
|
responses.add(NodeGraphMessage::SendGraph { should_rerender: false });
|
||||||
}
|
}
|
||||||
NodeGraphMessage::Cut => {
|
NodeGraphMessage::Cut => {
|
||||||
responses.push_back(NodeGraphMessage::Copy.into());
|
responses.add(NodeGraphMessage::Copy);
|
||||||
responses.push_back(NodeGraphMessage::DeleteSelectedNodes.into());
|
responses.add(NodeGraphMessage::DeleteSelectedNodes);
|
||||||
}
|
}
|
||||||
NodeGraphMessage::DeleteNode { node_id } => {
|
NodeGraphMessage::DeleteNode { node_id } => {
|
||||||
if let Some(network) = self.get_active_network_mut(document) {
|
if let Some(network) = self.get_active_network_mut(document) {
|
||||||
@@ -487,19 +481,19 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
|
|||||||
self.update_selected(document, responses);
|
self.update_selected(document, responses);
|
||||||
}
|
}
|
||||||
NodeGraphMessage::DeleteSelectedNodes => {
|
NodeGraphMessage::DeleteSelectedNodes => {
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
|
|
||||||
for node_id in self.selected_nodes.clone() {
|
for node_id in self.selected_nodes.clone() {
|
||||||
responses.push_back(NodeGraphMessage::DeleteNode { node_id }.into());
|
responses.add(NodeGraphMessage::DeleteNode { node_id });
|
||||||
}
|
}
|
||||||
|
|
||||||
responses.push_back(NodeGraphMessage::SendGraph { should_rerender: false }.into());
|
responses.add(NodeGraphMessage::SendGraph { should_rerender: false });
|
||||||
|
|
||||||
if let Some(network) = self.get_active_network(document) {
|
if let Some(network) = self.get_active_network(document) {
|
||||||
// Only generate node graph if one of the selected nodes is connected to the output
|
// Only generate node graph if one of the selected nodes is connected to the output
|
||||||
if self.selected_nodes.iter().any(|&node_id| network.connected_to_output(node_id, true)) {
|
if self.selected_nodes.iter().any(|&node_id| network.connected_to_output(node_id, true)) {
|
||||||
if let Some(layer_path) = self.layer_path.clone() {
|
if let Some(layer_path) = self.layer_path.clone() {
|
||||||
responses.push_back(DocumentMessage::NodeGraphFrameGenerate { layer_path }.into());
|
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -518,13 +512,13 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
|
|
||||||
let input = node_type.inputs[input_index].default.clone();
|
let input = node_type.inputs[input_index].default.clone();
|
||||||
responses.push_back(NodeGraphMessage::SetNodeInput { node_id, input_index, input }.into());
|
responses.add(NodeGraphMessage::SetNodeInput { node_id, input_index, input });
|
||||||
|
|
||||||
let should_rerender = network.connected_to_output(node_id, true);
|
let should_rerender = network.connected_to_output(node_id, true);
|
||||||
responses.push_back(NodeGraphMessage::SendGraph { should_rerender }.into());
|
responses.add(NodeGraphMessage::SendGraph { should_rerender });
|
||||||
}
|
}
|
||||||
NodeGraphMessage::DoubleClickNode { node } => {
|
NodeGraphMessage::DoubleClickNode { node } => {
|
||||||
if let Some(network) = self.get_active_network(document) {
|
if let Some(network) = self.get_active_network(document) {
|
||||||
@@ -540,7 +534,7 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
|
|||||||
}
|
}
|
||||||
NodeGraphMessage::DuplicateSelectedNodes => {
|
NodeGraphMessage::DuplicateSelectedNodes => {
|
||||||
if let Some(network) = self.get_active_network(document) {
|
if let Some(network) = self.get_active_network(document) {
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
|
|
||||||
let new_ids = &self.selected_nodes.iter().map(|&id| (id, crate::application::generate_uuid())).collect();
|
let new_ids = &self.selected_nodes.iter().map(|&id| (id, crate::application::generate_uuid())).collect();
|
||||||
self.selected_nodes.clear();
|
self.selected_nodes.clear();
|
||||||
@@ -555,7 +549,7 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
|
|||||||
self.selected_nodes.push(node_id);
|
self.selected_nodes.push(node_id);
|
||||||
|
|
||||||
// Insert new node into graph
|
// Insert new node into graph
|
||||||
responses.push_back(NodeGraphMessage::InsertNode { node_id, document_node }.into());
|
responses.add(NodeGraphMessage::InsertNode { node_id, document_node });
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::send_graph(network, responses);
|
Self::send_graph(network, responses);
|
||||||
@@ -584,7 +578,7 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
|
|
||||||
let mut input = node.inputs[input_index].clone();
|
let mut input = node.inputs[input_index].clone();
|
||||||
if let NodeInput::Value { exposed, .. } = &mut input {
|
if let NodeInput::Value { exposed, .. } = &mut input {
|
||||||
@@ -597,11 +591,11 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
responses.push_back(NodeGraphMessage::SetNodeInput { node_id, input_index, input }.into());
|
responses.add(NodeGraphMessage::SetNodeInput { node_id, input_index, input });
|
||||||
|
|
||||||
let should_rerender = network.connected_to_output(node_id, true);
|
let should_rerender = network.connected_to_output(node_id, true);
|
||||||
responses.push_back(NodeGraphMessage::SendGraph { should_rerender }.into());
|
responses.add(NodeGraphMessage::SendGraph { should_rerender });
|
||||||
responses.push_back(PropertiesPanelMessage::ResendActiveProperties.into());
|
responses.add(PropertiesPanelMessage::ResendActiveProperties);
|
||||||
}
|
}
|
||||||
NodeGraphMessage::InsertNode { node_id, document_node } => {
|
NodeGraphMessage::InsertNode { node_id, document_node } => {
|
||||||
if let Some(network) = self.get_active_network_mut(document) {
|
if let Some(network) = self.get_active_network_mut(document) {
|
||||||
@@ -630,7 +624,7 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
|
|||||||
Self::send_graph(network, responses);
|
Self::send_graph(network, responses);
|
||||||
|
|
||||||
let node_types = document_node_types::collect_node_types();
|
let node_types = document_node_types::collect_node_types();
|
||||||
responses.push_back(FrontendMessage::UpdateNodeTypes { node_types }.into());
|
responses.add(FrontendMessage::UpdateNodeTypes { node_types });
|
||||||
}
|
}
|
||||||
self.collect_nested_addresses(document, responses);
|
self.collect_nested_addresses(document, responses);
|
||||||
self.update_selected(document, responses);
|
self.update_selected(document, responses);
|
||||||
@@ -658,7 +652,7 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
|
|||||||
shift += IVec2::splat(2);
|
shift += IVec2::splat(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
|
|
||||||
let new_ids: HashMap<_, _> = data.iter().map(|&(id, _)| (id, crate::application::generate_uuid())).collect();
|
let new_ids: HashMap<_, _> = data.iter().map(|&(id, _)| (id, crate::application::generate_uuid())).collect();
|
||||||
for (old_id, mut document_node) in data {
|
for (old_id, mut document_node) in data {
|
||||||
@@ -670,26 +664,26 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
|
|||||||
document_node = document_node.map_ids(Self::default_node_input, &new_ids);
|
document_node = document_node.map_ids(Self::default_node_input, &new_ids);
|
||||||
|
|
||||||
// Insert node into network
|
// Insert node into network
|
||||||
responses.push_back(NodeGraphMessage::InsertNode { node_id, document_node }.into());
|
responses.add(NodeGraphMessage::InsertNode { node_id, document_node });
|
||||||
}
|
}
|
||||||
|
|
||||||
let nodes = new_ids.values().copied().collect();
|
let nodes = new_ids.values().copied().collect();
|
||||||
responses.push_back(NodeGraphMessage::SelectNodes { nodes }.into());
|
responses.add(NodeGraphMessage::SelectNodes { nodes });
|
||||||
|
|
||||||
responses.push_back(NodeGraphMessage::SendGraph { should_rerender: false }.into());
|
responses.add(NodeGraphMessage::SendGraph { should_rerender: false });
|
||||||
}
|
}
|
||||||
NodeGraphMessage::SelectNodes { nodes } => {
|
NodeGraphMessage::SelectNodes { nodes } => {
|
||||||
self.selected_nodes = nodes;
|
self.selected_nodes = nodes;
|
||||||
self.update_selection_action_buttons(document, responses);
|
self.update_selection_action_buttons(document, responses);
|
||||||
self.update_selected(document, responses);
|
self.update_selected(document, responses);
|
||||||
responses.push_back(PropertiesPanelMessage::ResendActiveProperties.into());
|
responses.add(PropertiesPanelMessage::ResendActiveProperties);
|
||||||
}
|
}
|
||||||
NodeGraphMessage::SendGraph { should_rerender } => {
|
NodeGraphMessage::SendGraph { should_rerender } => {
|
||||||
if let Some(network) = self.get_active_network(document) {
|
if let Some(network) = self.get_active_network(document) {
|
||||||
Self::send_graph(network, responses);
|
Self::send_graph(network, responses);
|
||||||
if should_rerender {
|
if should_rerender {
|
||||||
if let Some(layer_path) = self.layer_path.clone() {
|
if let Some(layer_path) = self.layer_path.clone() {
|
||||||
responses.push_back(DocumentMessage::NodeGraphFrameGenerate { layer_path }.into());
|
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -698,14 +692,14 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
|
|||||||
NodeGraphMessage::SetInputValue { node_id, input_index, value } => {
|
NodeGraphMessage::SetInputValue { node_id, input_index, value } => {
|
||||||
if let Some(network) = self.get_active_network(document) {
|
if let Some(network) = self.get_active_network(document) {
|
||||||
if let Some(node) = network.nodes.get(&node_id) {
|
if let Some(node) = network.nodes.get(&node_id) {
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
|
|
||||||
let input = NodeInput::Value { tagged_value: value, exposed: false };
|
let input = NodeInput::Value { tagged_value: value, exposed: false };
|
||||||
responses.push_back(NodeGraphMessage::SetNodeInput { node_id, input_index, input }.into());
|
responses.add(NodeGraphMessage::SetNodeInput { node_id, input_index, input });
|
||||||
responses.push_back(PropertiesPanelMessage::ResendActiveProperties.into());
|
responses.add(PropertiesPanelMessage::ResendActiveProperties);
|
||||||
if (node.name != "Imaginate" || input_index == 0) && network.connected_to_output(node_id, true) {
|
if (node.name != "Imaginate" || input_index == 0) && network.connected_to_output(node_id, true) {
|
||||||
if let Some(layer_path) = self.layer_path.clone() {
|
if let Some(layer_path) = self.layer_path.clone() {
|
||||||
responses.push_back(DocumentMessage::NodeGraphFrameGenerate { layer_path }.into());
|
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -743,7 +737,7 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
|
|||||||
}
|
}
|
||||||
node.inputs[input_index] = NodeInput::Value { tagged_value: value, exposed: false };
|
node.inputs[input_index] = NodeInput::Value { tagged_value: value, exposed: false };
|
||||||
if network.connected_to_output(*node_id, true) {
|
if network.connected_to_output(*node_id, true) {
|
||||||
responses.push_back(DocumentMessage::NodeGraphFrameGenerate { layer_path }.into());
|
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -793,11 +787,11 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
|
|||||||
stack.extend(outwards_links.get(&id).unwrap_or(&Vec::new()).iter().copied())
|
stack.extend(outwards_links.get(&id).unwrap_or(&Vec::new()).iter().copied())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
responses.push_back(NodeGraphMessage::SendGraph { should_rerender: false }.into());
|
responses.add(NodeGraphMessage::SendGraph { should_rerender: false });
|
||||||
}
|
}
|
||||||
NodeGraphMessage::ToggleHidden => {
|
NodeGraphMessage::ToggleHidden => {
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
responses.push_back(NodeGraphMessage::ToggleHiddenImpl.into());
|
responses.add(NodeGraphMessage::ToggleHiddenImpl);
|
||||||
}
|
}
|
||||||
NodeGraphMessage::ToggleHiddenImpl => {
|
NodeGraphMessage::ToggleHiddenImpl => {
|
||||||
if let Some(network) = self.get_active_network_mut(document) {
|
if let Some(network) = self.get_active_network_mut(document) {
|
||||||
@@ -817,15 +811,15 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
|
|||||||
// Only generate node graph if one of the selected nodes is connected to the output
|
// Only generate node graph if one of the selected nodes is connected to the output
|
||||||
if self.selected_nodes.iter().any(|&node_id| network.connected_to_output(node_id, true)) {
|
if self.selected_nodes.iter().any(|&node_id| network.connected_to_output(node_id, true)) {
|
||||||
if let Some(layer_path) = self.layer_path.clone() {
|
if let Some(layer_path) = self.layer_path.clone() {
|
||||||
responses.push_back(DocumentMessage::NodeGraphFrameGenerate { layer_path }.into());
|
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.update_selection_action_buttons(document, responses);
|
self.update_selection_action_buttons(document, responses);
|
||||||
}
|
}
|
||||||
NodeGraphMessage::TogglePreview { node_id } => {
|
NodeGraphMessage::TogglePreview { node_id } => {
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
responses.push_back(NodeGraphMessage::TogglePreviewImpl { node_id }.into());
|
responses.add(NodeGraphMessage::TogglePreviewImpl { node_id });
|
||||||
}
|
}
|
||||||
NodeGraphMessage::TogglePreviewImpl { node_id } => {
|
NodeGraphMessage::TogglePreviewImpl { node_id } => {
|
||||||
if let Some(network) = self.get_active_network_mut(document) {
|
if let Some(network) = self.get_active_network_mut(document) {
|
||||||
@@ -842,7 +836,7 @@ impl MessageHandler<NodeGraphMessage, (&mut Document, &mut dyn Iterator<Item = &
|
|||||||
}
|
}
|
||||||
self.update_selection_action_buttons(document, responses);
|
self.update_selection_action_buttons(document, responses);
|
||||||
if let Some(layer_path) = self.layer_path.clone() {
|
if let Some(layer_path) = self.layer_path.clone() {
|
||||||
responses.push_back(DocumentMessage::NodeGraphFrameGenerate { layer_path }.into());
|
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -923,7 +923,7 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
|
|||||||
let server_status = {
|
let server_status = {
|
||||||
let status = match &context.persistent_data.imaginate_server_status {
|
let status = match &context.persistent_data.imaginate_server_status {
|
||||||
ImaginateServerStatus::Unknown => {
|
ImaginateServerStatus::Unknown => {
|
||||||
context.responses.push_back(PortfolioMessage::ImaginateCheckServerStatus.into());
|
context.responses.add(PortfolioMessage::ImaginateCheckServerStatus);
|
||||||
"Checking..."
|
"Checking..."
|
||||||
}
|
}
|
||||||
ImaginateServerStatus::Checking => "Checking...",
|
ImaginateServerStatus::Checking => "Checking...",
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ impl MessageHandler<OverlaysMessage, (bool, &PersistentData, &InputPreprocessorM
|
|||||||
let render_data = RenderData::new(&persistent_data.font_cache, ViewMode::Normal, Some(ipp.document_bounds()));
|
let render_data = RenderData::new(&persistent_data.font_cache, ViewMode::Normal, Some(ipp.document_bounds()));
|
||||||
|
|
||||||
match self.overlays_document.handle_operation(*operation, &render_data) {
|
match self.overlays_document.handle_operation(*operation, &render_data) {
|
||||||
Ok(_) => responses.push_back(OverlaysMessage::Rerender.into()),
|
Ok(_) => responses.add(OverlaysMessage::Rerender),
|
||||||
Err(e) => error!("OverlaysError: {:?}", e),
|
Err(e) => error!("OverlaysError: {:?}", e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -34,17 +34,14 @@ impl MessageHandler<OverlaysMessage, (bool, &PersistentData, &InputPreprocessorM
|
|||||||
Rerender =>
|
Rerender =>
|
||||||
// Render overlays
|
// Render overlays
|
||||||
{
|
{
|
||||||
responses.push_back(
|
responses.add(FrontendMessage::UpdateDocumentOverlays {
|
||||||
FrontendMessage::UpdateDocumentOverlays {
|
svg: if overlays_visible {
|
||||||
svg: if overlays_visible {
|
let render_data = RenderData::new(&persistent_data.font_cache, ViewMode::Normal, Some(ipp.document_bounds()));
|
||||||
let render_data = RenderData::new(&persistent_data.font_cache, ViewMode::Normal, Some(ipp.document_bounds()));
|
self.overlays_document.render_root(&render_data)
|
||||||
self.overlays_document.render_root(&render_data)
|
} else {
|
||||||
} else {
|
String::from("")
|
||||||
String::from("")
|
},
|
||||||
},
|
})
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+39
-60
@@ -40,8 +40,8 @@ impl<'a> MessageHandler<PropertiesPanelMessage, (&PersistentData, PropertiesPane
|
|||||||
SetActiveLayers { paths, document } => {
|
SetActiveLayers { paths, document } => {
|
||||||
if paths.len() != 1 {
|
if paths.len() != 1 {
|
||||||
// TODO: Allow for multiple selected layers
|
// TODO: Allow for multiple selected layers
|
||||||
responses.push_back(PropertiesPanelMessage::ClearSelection.into());
|
responses.add(PropertiesPanelMessage::ClearSelection);
|
||||||
responses.push_back(NodeGraphMessage::CloseNodeGraph.into());
|
responses.add(NodeGraphMessage::CloseNodeGraph);
|
||||||
} else {
|
} else {
|
||||||
let path = paths.into_iter().next().unwrap();
|
let path = paths.into_iter().next().unwrap();
|
||||||
if Some((path.clone(), document)) != self.active_selection {
|
if Some((path.clone(), document)) != self.active_selection {
|
||||||
@@ -52,48 +52,36 @@ impl<'a> MessageHandler<PropertiesPanelMessage, (&PersistentData, PropertiesPane
|
|||||||
.filter(|layer| LayerDataTypeDiscriminant::from(&layer.data) == LayerDataTypeDiscriminant::NodeGraphFrame)
|
.filter(|layer| LayerDataTypeDiscriminant::from(&layer.data) == LayerDataTypeDiscriminant::NodeGraphFrame)
|
||||||
.is_some()
|
.is_some()
|
||||||
{
|
{
|
||||||
responses.push_back(NodeGraphMessage::OpenNodeGraph { layer_path: path.clone() }.into());
|
responses.add(NodeGraphMessage::OpenNodeGraph { layer_path: path.clone() });
|
||||||
} else {
|
} else {
|
||||||
responses.push_back(NodeGraphMessage::CloseNodeGraph.into());
|
responses.add(NodeGraphMessage::CloseNodeGraph);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.active_selection = Some((path, document));
|
self.active_selection = Some((path, document));
|
||||||
responses.push_back(PropertiesPanelMessage::ResendActiveProperties.into());
|
responses.add(PropertiesPanelMessage::ResendActiveProperties);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ClearSelection => {
|
ClearSelection => {
|
||||||
responses.push_back(
|
responses.add(LayoutMessage::SendLayout {
|
||||||
LayoutMessage::SendLayout {
|
layout: Layout::WidgetLayout(WidgetLayout::new(vec![])),
|
||||||
layout: Layout::WidgetLayout(WidgetLayout::new(vec![])),
|
layout_target: LayoutTarget::PropertiesOptions,
|
||||||
layout_target: LayoutTarget::PropertiesOptions,
|
});
|
||||||
}
|
responses.add(LayoutMessage::SendLayout {
|
||||||
.into(),
|
layout: Layout::WidgetLayout(WidgetLayout::new(vec![])),
|
||||||
);
|
layout_target: LayoutTarget::PropertiesSections,
|
||||||
responses.push_back(
|
});
|
||||||
LayoutMessage::SendLayout {
|
responses.add(NodeGraphMessage::CloseNodeGraph);
|
||||||
layout: Layout::WidgetLayout(WidgetLayout::new(vec![])),
|
|
||||||
layout_target: LayoutTarget::PropertiesSections,
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
responses.push_back(NodeGraphMessage::CloseNodeGraph.into());
|
|
||||||
self.active_selection = None;
|
self.active_selection = None;
|
||||||
}
|
}
|
||||||
Deactivate => responses.push_back(
|
Deactivate => responses.add(BroadcastMessage::UnsubscribeEvent {
|
||||||
BroadcastMessage::UnsubscribeEvent {
|
on: BroadcastEvent::SelectionChanged,
|
||||||
on: BroadcastEvent::SelectionChanged,
|
message: Box::new(PropertiesPanelMessage::UpdateSelectedDocumentProperties.into()),
|
||||||
message: Box::new(PropertiesPanelMessage::UpdateSelectedDocumentProperties.into()),
|
}),
|
||||||
}
|
Init => responses.add(BroadcastMessage::SubscribeEvent {
|
||||||
.into(),
|
on: BroadcastEvent::SelectionChanged,
|
||||||
),
|
send: Box::new(PropertiesPanelMessage::UpdateSelectedDocumentProperties.into()),
|
||||||
Init => responses.push_back(
|
}),
|
||||||
BroadcastMessage::SubscribeEvent {
|
|
||||||
on: BroadcastEvent::SelectionChanged,
|
|
||||||
send: Box::new(PropertiesPanelMessage::UpdateSelectedDocumentProperties.into()),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
),
|
|
||||||
ModifyTransform { value, transform_op } => {
|
ModifyTransform { value, transform_op } => {
|
||||||
let (path, target_document) = self.active_selection.as_ref().expect("Received update for properties panel with no active layer");
|
let (path, target_document) = self.active_selection.as_ref().expect("Received update for properties panel with no active layer");
|
||||||
let layer = get_document(*target_document).layer(path).unwrap();
|
let layer = get_document(*target_document).layer(path).unwrap();
|
||||||
@@ -128,27 +116,21 @@ impl<'a> MessageHandler<PropertiesPanelMessage, (&PersistentData, PropertiesPane
|
|||||||
}
|
}
|
||||||
CheckSelectedWasUpdated { path } => {
|
CheckSelectedWasUpdated { path } => {
|
||||||
if self.matches_selected(&path) {
|
if self.matches_selected(&path) {
|
||||||
responses.push_back(PropertiesPanelMessage::ResendActiveProperties.into())
|
responses.add(PropertiesPanelMessage::ResendActiveProperties)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CheckSelectedWasDeleted { path } => {
|
CheckSelectedWasDeleted { path } => {
|
||||||
if self.matches_selected(&path) {
|
if self.matches_selected(&path) {
|
||||||
self.active_selection = None;
|
self.active_selection = None;
|
||||||
responses.push_back(
|
responses.add(LayoutMessage::SendLayout {
|
||||||
LayoutMessage::SendLayout {
|
layout_target: LayoutTarget::PropertiesOptions,
|
||||||
layout_target: LayoutTarget::PropertiesOptions,
|
layout: Layout::WidgetLayout(WidgetLayout::default()),
|
||||||
layout: Layout::WidgetLayout(WidgetLayout::default()),
|
});
|
||||||
}
|
responses.add(LayoutMessage::SendLayout {
|
||||||
.into(),
|
layout_target: LayoutTarget::PropertiesSections,
|
||||||
);
|
layout: Layout::WidgetLayout(WidgetLayout::default()),
|
||||||
responses.push_back(
|
});
|
||||||
LayoutMessage::SendLayout {
|
responses.add(NodeGraphMessage::CloseNodeGraph);
|
||||||
layout_target: LayoutTarget::PropertiesSections,
|
|
||||||
layout: Layout::WidgetLayout(WidgetLayout::default()),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
responses.push_back(NodeGraphMessage::CloseNodeGraph.into());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ResendActiveProperties => {
|
ResendActiveProperties => {
|
||||||
@@ -161,13 +143,10 @@ impl<'a> MessageHandler<PropertiesPanelMessage, (&PersistentData, PropertiesPane
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UpdateSelectedDocumentProperties => responses.push_back(
|
UpdateSelectedDocumentProperties => responses.add(PropertiesPanelMessage::SetActiveLayers {
|
||||||
PropertiesPanelMessage::SetActiveLayers {
|
paths: selected_layers.map(|path| path.to_vec()).collect(),
|
||||||
paths: selected_layers.map(|path| path.to_vec()).collect(),
|
document: TargetDocument::Artwork,
|
||||||
document: TargetDocument::Artwork,
|
}),
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,16 +169,16 @@ impl PropertiesPanelMessageHandler {
|
|||||||
// Commit history is not respected as the artboard document is not saved in the history system.
|
// Commit history is not respected as the artboard document is not saved in the history system.
|
||||||
|
|
||||||
// Dispatch the relevant operation to the artboard document
|
// Dispatch the relevant operation to the artboard document
|
||||||
responses.push_back(ArtboardMessage::DispatchOperation(Box::new(operation)).into())
|
responses.add(ArtboardMessage::DispatchOperation(Box::new(operation)))
|
||||||
}
|
}
|
||||||
TargetDocument::Artwork => {
|
TargetDocument::Artwork => {
|
||||||
// Commit to history before the modification
|
// Commit to history before the modification
|
||||||
if commit_history {
|
if commit_history {
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dispatch the relevant operation to the main document
|
// Dispatch the relevant operation to the main document
|
||||||
responses.push_back(DocumentMessage::DispatchOperation(Box::new(operation)).into());
|
responses.add(DocumentMessage::DispatchOperation(Box::new(operation)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -225,20 +225,14 @@ pub fn register_artboard_layer_properties(layer: &Layer, responses: &mut VecDequ
|
|||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push_back(
|
responses.add(LayoutMessage::SendLayout {
|
||||||
LayoutMessage::SendLayout {
|
layout: Layout::WidgetLayout(WidgetLayout::new(options_bar)),
|
||||||
layout: Layout::WidgetLayout(WidgetLayout::new(options_bar)),
|
layout_target: LayoutTarget::PropertiesOptions,
|
||||||
layout_target: LayoutTarget::PropertiesOptions,
|
});
|
||||||
}
|
responses.add(LayoutMessage::SendLayout {
|
||||||
.into(),
|
layout: Layout::WidgetLayout(WidgetLayout::new(properties_body)),
|
||||||
);
|
layout_target: LayoutTarget::PropertiesSections,
|
||||||
responses.push_back(
|
});
|
||||||
LayoutMessage::SendLayout {
|
|
||||||
layout: Layout::WidgetLayout(WidgetLayout::new(properties_body)),
|
|
||||||
layout_target: LayoutTarget::PropertiesSections,
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_artwork_layer_properties(
|
pub fn register_artwork_layer_properties(
|
||||||
@@ -325,20 +319,14 @@ pub fn register_artwork_layer_properties(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push_back(
|
responses.add(LayoutMessage::SendLayout {
|
||||||
LayoutMessage::SendLayout {
|
layout: Layout::WidgetLayout(WidgetLayout::new(options_bar)),
|
||||||
layout: Layout::WidgetLayout(WidgetLayout::new(options_bar)),
|
layout_target: LayoutTarget::PropertiesOptions,
|
||||||
layout_target: LayoutTarget::PropertiesOptions,
|
});
|
||||||
}
|
responses.add(LayoutMessage::SendLayout {
|
||||||
.into(),
|
layout: Layout::WidgetLayout(WidgetLayout::new(properties_body)),
|
||||||
);
|
layout_target: LayoutTarget::PropertiesSections,
|
||||||
responses.push_back(
|
});
|
||||||
LayoutMessage::SendLayout {
|
|
||||||
layout: Layout::WidgetLayout(WidgetLayout::new(properties_body)),
|
|
||||||
layout_target: LayoutTarget::PropertiesSections,
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn node_section_transform(layer: &Layer, persistent_data: &PersistentData) -> LayoutGroup {
|
fn node_section_transform(layer: &Layer, persistent_data: &PersistentData) -> LayoutGroup {
|
||||||
|
|||||||
@@ -423,7 +423,7 @@ impl<'a> Selected<'a> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
self.responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,88 +60,85 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
|||||||
if let Some(document) = self.active_document_mut() {
|
if let Some(document) = self.active_document_mut() {
|
||||||
document.set_auto_save_state(true);
|
document.set_auto_save_state(true);
|
||||||
}
|
}
|
||||||
responses.push_back(PortfolioMessage::AutoSaveDocument { document_id }.into());
|
responses.add(PortfolioMessage::AutoSaveDocument { document_id });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PortfolioMessage::AutoSaveDocument { document_id } => {
|
PortfolioMessage::AutoSaveDocument { document_id } => {
|
||||||
let document = self.documents.get(&document_id).unwrap();
|
let document = self.documents.get(&document_id).unwrap();
|
||||||
responses.push_back(
|
responses.add(FrontendMessage::TriggerIndexedDbWriteDocument {
|
||||||
FrontendMessage::TriggerIndexedDbWriteDocument {
|
document: document.serialize_document(),
|
||||||
document: document.serialize_document(),
|
details: FrontendDocumentDetails {
|
||||||
details: FrontendDocumentDetails {
|
is_auto_saved: document.is_auto_saved(),
|
||||||
is_auto_saved: document.is_auto_saved(),
|
is_saved: document.is_saved(),
|
||||||
is_saved: document.is_saved(),
|
id: document_id,
|
||||||
id: document_id,
|
name: document.name.clone(),
|
||||||
name: document.name.clone(),
|
},
|
||||||
},
|
version: GRAPHITE_DOCUMENT_VERSION.to_string(),
|
||||||
version: GRAPHITE_DOCUMENT_VERSION.to_string(),
|
})
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
PortfolioMessage::CloseActiveDocumentWithConfirmation => {
|
PortfolioMessage::CloseActiveDocumentWithConfirmation => {
|
||||||
if let Some(document_id) = self.active_document_id {
|
if let Some(document_id) = self.active_document_id {
|
||||||
responses.push_back(PortfolioMessage::CloseDocumentWithConfirmation { document_id }.into());
|
responses.add(PortfolioMessage::CloseDocumentWithConfirmation { document_id });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PortfolioMessage::CloseAllDocuments => {
|
PortfolioMessage::CloseAllDocuments => {
|
||||||
if self.active_document_id.is_some() {
|
if self.active_document_id.is_some() {
|
||||||
responses.push_back(PropertiesPanelMessage::Deactivate.into());
|
responses.add(PropertiesPanelMessage::Deactivate);
|
||||||
responses.push_back(BroadcastEvent::ToolAbort.into());
|
responses.add(BroadcastEvent::ToolAbort);
|
||||||
responses.push_back(ToolMessage::DeactivateTools.into());
|
responses.add(ToolMessage::DeactivateTools);
|
||||||
|
|
||||||
// Clear relevant UI layouts if there are no documents
|
// Clear relevant UI layouts if there are no documents
|
||||||
responses.push_back(PropertiesPanelMessage::ClearSelection.into());
|
responses.add(PropertiesPanelMessage::ClearSelection);
|
||||||
responses.push_back(DocumentMessage::ClearLayerTree.into());
|
responses.add(DocumentMessage::ClearLayerTree);
|
||||||
let hint_data = HintData(vec![HintGroup(vec![])]);
|
let hint_data = HintData(vec![HintGroup(vec![])]);
|
||||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
responses.add(FrontendMessage::UpdateInputHints { hint_data });
|
||||||
}
|
}
|
||||||
|
|
||||||
for document_id in &self.document_ids {
|
for document_id in &self.document_ids {
|
||||||
responses.push_back(FrontendMessage::TriggerIndexedDbRemoveDocument { document_id: *document_id }.into());
|
responses.add(FrontendMessage::TriggerIndexedDbRemoveDocument { document_id: *document_id });
|
||||||
}
|
}
|
||||||
|
|
||||||
responses.push_back(PortfolioMessage::DestroyAllDocuments.into());
|
responses.add(PortfolioMessage::DestroyAllDocuments);
|
||||||
responses.push_back(PortfolioMessage::UpdateOpenDocumentsList.into());
|
responses.add(PortfolioMessage::UpdateOpenDocumentsList);
|
||||||
}
|
}
|
||||||
PortfolioMessage::CloseDocument { document_id } => {
|
PortfolioMessage::CloseDocument { document_id } => {
|
||||||
// Is this the last document?
|
// Is this the last document?
|
||||||
if self.documents.len() == 1 && self.document_ids[0] == document_id {
|
if self.documents.len() == 1 && self.document_ids[0] == document_id {
|
||||||
// Clear UI layouts that assume the existence of a document
|
// Clear UI layouts that assume the existence of a document
|
||||||
responses.push_back(PropertiesPanelMessage::ClearSelection.into());
|
responses.add(PropertiesPanelMessage::ClearSelection);
|
||||||
responses.push_back(DocumentMessage::ClearLayerTree.into());
|
responses.add(DocumentMessage::ClearLayerTree);
|
||||||
let hint_data = HintData(vec![HintGroup(vec![])]);
|
let hint_data = HintData(vec![HintGroup(vec![])]);
|
||||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
responses.add(FrontendMessage::UpdateInputHints { hint_data });
|
||||||
}
|
}
|
||||||
// Actually delete the document (delay to delete document is required to let the document and properties panel messages above get processed)
|
// Actually delete the document (delay to delete document is required to let the document and properties panel messages above get processed)
|
||||||
responses.push_back(PortfolioMessage::DeleteDocument { document_id }.into());
|
responses.add(PortfolioMessage::DeleteDocument { document_id });
|
||||||
|
|
||||||
// Send the new list of document tab names
|
// Send the new list of document tab names
|
||||||
responses.push_back(PortfolioMessage::UpdateOpenDocumentsList.into());
|
responses.add(PortfolioMessage::UpdateOpenDocumentsList);
|
||||||
responses.push_back(FrontendMessage::TriggerIndexedDbRemoveDocument { document_id }.into());
|
responses.add(FrontendMessage::TriggerIndexedDbRemoveDocument { document_id });
|
||||||
responses.push_back(DocumentMessage::RenderDocument.into());
|
responses.add(DocumentMessage::RenderDocument);
|
||||||
responses.push_back(DocumentMessage::DocumentStructureChanged.into());
|
responses.add(DocumentMessage::DocumentStructureChanged);
|
||||||
if let Some(document) = self.active_document() {
|
if let Some(document) = self.active_document() {
|
||||||
for layer in document.layer_metadata.keys() {
|
for layer in document.layer_metadata.keys() {
|
||||||
responses.push_back(DocumentMessage::LayerChanged { affected_layer_path: layer.clone() }.into());
|
responses.add(DocumentMessage::LayerChanged { affected_layer_path: layer.clone() });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PortfolioMessage::CloseDocumentWithConfirmation { document_id } => {
|
PortfolioMessage::CloseDocumentWithConfirmation { document_id } => {
|
||||||
let target_document = self.documents.get(&document_id).unwrap();
|
let target_document = self.documents.get(&document_id).unwrap();
|
||||||
if target_document.is_saved() {
|
if target_document.is_saved() {
|
||||||
responses.push_back(BroadcastEvent::ToolAbort.into());
|
responses.add(BroadcastEvent::ToolAbort);
|
||||||
responses.push_back(PortfolioMessage::CloseDocument { document_id }.into());
|
responses.add(PortfolioMessage::CloseDocument { document_id });
|
||||||
} else {
|
} else {
|
||||||
let dialog = simple_dialogs::CloseDocumentDialog {
|
let dialog = simple_dialogs::CloseDocumentDialog {
|
||||||
document_name: target_document.name.clone(),
|
document_name: target_document.name.clone(),
|
||||||
document_id,
|
document_id,
|
||||||
};
|
};
|
||||||
dialog.register_properties(responses, LayoutTarget::DialogDetails);
|
dialog.register_properties(responses, LayoutTarget::DialogDetails);
|
||||||
responses.push_back(FrontendMessage::DisplayDialog { icon: "File".to_string() }.into());
|
responses.add(FrontendMessage::DisplayDialog { icon: "File".to_string() });
|
||||||
|
|
||||||
// Select the document being closed
|
// Select the document being closed
|
||||||
responses.push_back(PortfolioMessage::SelectDocument { document_id }.into());
|
responses.add(PortfolioMessage::SelectDocument { document_id });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PortfolioMessage::Copy { clipboard } => {
|
PortfolioMessage::Copy { clipboard } => {
|
||||||
@@ -164,7 +161,7 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
|||||||
let mut copy_text = String::from("graphite/layer: ");
|
let mut copy_text = String::from("graphite/layer: ");
|
||||||
copy_text += &serde_json::to_string(&buffer).expect("Could not serialize paste");
|
copy_text += &serde_json::to_string(&buffer).expect("Could not serialize paste");
|
||||||
|
|
||||||
responses.push_back(FrontendMessage::TriggerTextCopy { copy_text }.into());
|
responses.add(FrontendMessage::TriggerTextCopy { copy_text });
|
||||||
} else {
|
} else {
|
||||||
let copy_buffer = &mut self.copy_buffer;
|
let copy_buffer = &mut self.copy_buffer;
|
||||||
copy_buffer[clipboard as usize].clear();
|
copy_buffer[clipboard as usize].clear();
|
||||||
@@ -173,8 +170,8 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
PortfolioMessage::Cut { clipboard } => {
|
PortfolioMessage::Cut { clipboard } => {
|
||||||
responses.push_back(PortfolioMessage::Copy { clipboard }.into());
|
responses.add(PortfolioMessage::Copy { clipboard });
|
||||||
responses.push_back(DocumentMessage::DeleteSelectedLayers.into());
|
responses.add(DocumentMessage::DeleteSelectedLayers);
|
||||||
}
|
}
|
||||||
PortfolioMessage::DeleteDocument { document_id } => {
|
PortfolioMessage::DeleteDocument { document_id } => {
|
||||||
let document_index = self.document_index(document_id);
|
let document_index = self.document_index(document_id);
|
||||||
@@ -191,7 +188,7 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
|||||||
// Move to the next tab
|
// Move to the next tab
|
||||||
self.document_ids[document_index]
|
self.document_ids[document_index]
|
||||||
};
|
};
|
||||||
responses.push_back(PortfolioMessage::SelectDocument { document_id }.into());
|
responses.add(PortfolioMessage::SelectDocument { document_id });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PortfolioMessage::DestroyAllDocuments => {
|
PortfolioMessage::DestroyAllDocuments => {
|
||||||
@@ -211,21 +208,18 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
|||||||
|
|
||||||
if let Some(document) = self.active_document_mut() {
|
if let Some(document) = self.active_document_mut() {
|
||||||
Self::uploaded_new_font(document, &font, responses);
|
Self::uploaded_new_font(document, &font, responses);
|
||||||
responses.push_back(DocumentMessage::RenderDocument.into());
|
responses.add(DocumentMessage::RenderDocument);
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.persistent_data.font_cache.insert(font, preview_url, data, is_default);
|
self.persistent_data.font_cache.insert(font, preview_url, data, is_default);
|
||||||
}
|
}
|
||||||
PortfolioMessage::ImaginateCheckServerStatus => {
|
PortfolioMessage::ImaginateCheckServerStatus => {
|
||||||
self.persistent_data.imaginate_server_status = ImaginateServerStatus::Checking;
|
self.persistent_data.imaginate_server_status = ImaginateServerStatus::Checking;
|
||||||
responses.push_back(
|
responses.add(FrontendMessage::TriggerImaginateCheckServerStatus {
|
||||||
FrontendMessage::TriggerImaginateCheckServerStatus {
|
hostname: preferences.imaginate_server_hostname.clone(),
|
||||||
hostname: preferences.imaginate_server_hostname.clone(),
|
});
|
||||||
}
|
responses.add(PropertiesPanelMessage::ResendActiveProperties);
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
responses.push_back(PropertiesPanelMessage::ResendActiveProperties.into());
|
|
||||||
}
|
}
|
||||||
PortfolioMessage::ImaginateSetGeneratingStatus {
|
PortfolioMessage::ImaginateSetGeneratingStatus {
|
||||||
document_id,
|
document_id,
|
||||||
@@ -236,34 +230,28 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
|||||||
} => {
|
} => {
|
||||||
let get = |name: &str| IMAGINATE_NODE.inputs.iter().position(|input| input.name == name).unwrap_or_else(|| panic!("Input {name} not found"));
|
let get = |name: &str| IMAGINATE_NODE.inputs.iter().position(|input| input.name == name).unwrap_or_else(|| panic!("Input {name} not found"));
|
||||||
if let Some(percentage) = percent {
|
if let Some(percentage) = percent {
|
||||||
responses.push_back(
|
responses.add(PortfolioMessage::DocumentPassMessage {
|
||||||
PortfolioMessage::DocumentPassMessage {
|
|
||||||
document_id,
|
|
||||||
message: NodeGraphMessage::SetQualifiedInputValue {
|
|
||||||
layer_path: layer_path.clone(),
|
|
||||||
node_path: node_path.clone(),
|
|
||||||
input_index: get("Percent Complete"),
|
|
||||||
value: TaggedValue::F64(percentage),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
responses.push_back(
|
|
||||||
PortfolioMessage::DocumentPassMessage {
|
|
||||||
document_id,
|
document_id,
|
||||||
message: NodeGraphMessage::SetQualifiedInputValue {
|
message: NodeGraphMessage::SetQualifiedInputValue {
|
||||||
layer_path,
|
layer_path: layer_path.clone(),
|
||||||
node_path,
|
node_path: node_path.clone(),
|
||||||
input_index: get("Status"),
|
input_index: get("Percent Complete"),
|
||||||
value: TaggedValue::ImaginateStatus(status),
|
value: TaggedValue::F64(percentage),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
responses.add(PortfolioMessage::DocumentPassMessage {
|
||||||
|
document_id,
|
||||||
|
message: NodeGraphMessage::SetQualifiedInputValue {
|
||||||
|
layer_path,
|
||||||
|
node_path,
|
||||||
|
input_index: get("Status"),
|
||||||
|
value: TaggedValue::ImaginateStatus(status),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
);
|
});
|
||||||
}
|
}
|
||||||
PortfolioMessage::ImaginateSetImageData {
|
PortfolioMessage::ImaginateSetImageData {
|
||||||
document_id,
|
document_id,
|
||||||
@@ -276,28 +264,25 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
|||||||
let get = |name: &str| IMAGINATE_NODE.inputs.iter().position(|input| input.name == name).unwrap_or_else(|| panic!("Input {name} not found"));
|
let get = |name: &str| IMAGINATE_NODE.inputs.iter().position(|input| input.name == name).unwrap_or_else(|| panic!("Input {name} not found"));
|
||||||
|
|
||||||
let image = Image::from_image_data(&image_data, width, height);
|
let image = Image::from_image_data(&image_data, width, height);
|
||||||
responses.push_back(
|
responses.add(PortfolioMessage::DocumentPassMessage {
|
||||||
PortfolioMessage::DocumentPassMessage {
|
document_id,
|
||||||
document_id,
|
message: NodeGraphMessage::SetQualifiedInputValue {
|
||||||
message: NodeGraphMessage::SetQualifiedInputValue {
|
layer_path,
|
||||||
layer_path,
|
node_path,
|
||||||
node_path,
|
input_index: get("Cached Data"),
|
||||||
input_index: get("Cached Data"),
|
value: TaggedValue::RcImage(Some(std::sync::Arc::new(image))),
|
||||||
value: TaggedValue::RcImage(Some(std::sync::Arc::new(image))),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
);
|
});
|
||||||
}
|
}
|
||||||
PortfolioMessage::ImaginateSetServerStatus { status } => {
|
PortfolioMessage::ImaginateSetServerStatus { status } => {
|
||||||
self.persistent_data.imaginate_server_status = status;
|
self.persistent_data.imaginate_server_status = status;
|
||||||
responses.push_back(PropertiesPanelMessage::ResendActiveProperties.into());
|
responses.add(PropertiesPanelMessage::ResendActiveProperties);
|
||||||
}
|
}
|
||||||
PortfolioMessage::Import => {
|
PortfolioMessage::Import => {
|
||||||
// This portfolio message wraps the frontend message so it can be listed as an action, which isn't possible for frontend messages
|
// This portfolio message wraps the frontend message so it can be listed as an action, which isn't possible for frontend messages
|
||||||
if self.active_document().is_some() {
|
if self.active_document().is_some() {
|
||||||
responses.push_back(FrontendMessage::TriggerImport.into());
|
responses.add(FrontendMessage::TriggerImport);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PortfolioMessage::LoadDocumentResources { document_id } => {
|
PortfolioMessage::LoadDocumentResources { document_id } => {
|
||||||
@@ -307,15 +292,15 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
|||||||
}
|
}
|
||||||
PortfolioMessage::LoadFont { font, is_default } => {
|
PortfolioMessage::LoadFont { font, is_default } => {
|
||||||
if !self.persistent_data.font_cache.loaded_font(&font) {
|
if !self.persistent_data.font_cache.loaded_font(&font) {
|
||||||
responses.push_front(FrontendMessage::TriggerFontLoad { font, is_default }.into());
|
responses.add_front(FrontendMessage::TriggerFontLoad { font, is_default });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PortfolioMessage::NewDocumentWithName { name } => {
|
PortfolioMessage::NewDocumentWithName { name } => {
|
||||||
let new_document = DocumentMessageHandler::with_name(name, ipp);
|
let new_document = DocumentMessageHandler::with_name(name, ipp);
|
||||||
let document_id = generate_uuid();
|
let document_id = generate_uuid();
|
||||||
if self.active_document().is_some() {
|
if self.active_document().is_some() {
|
||||||
responses.push_back(BroadcastEvent::ToolAbort.into());
|
responses.add(BroadcastEvent::ToolAbort);
|
||||||
responses.push_back(NavigationMessage::TranslateCanvas { delta: (0., 0.).into() }.into());
|
responses.add(NavigationMessage::TranslateCanvas { delta: (0., 0.).into() });
|
||||||
}
|
}
|
||||||
|
|
||||||
self.load_document(new_document, document_id, responses);
|
self.load_document(new_document, document_id, responses);
|
||||||
@@ -326,27 +311,24 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
|||||||
let next_index = (current_index + 1) % self.document_ids.len();
|
let next_index = (current_index + 1) % self.document_ids.len();
|
||||||
let next_id = self.document_ids[next_index];
|
let next_id = self.document_ids[next_index];
|
||||||
|
|
||||||
responses.push_back(PortfolioMessage::SelectDocument { document_id: next_id }.into());
|
responses.add(PortfolioMessage::SelectDocument { document_id: next_id });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PortfolioMessage::OpenDocument => {
|
PortfolioMessage::OpenDocument => {
|
||||||
// This portfolio message wraps the frontend message so it can be listed as an action, which isn't possible for frontend messages
|
// This portfolio message wraps the frontend message so it can be listed as an action, which isn't possible for frontend messages
|
||||||
responses.push_back(FrontendMessage::TriggerOpenDocument.into());
|
responses.add(FrontendMessage::TriggerOpenDocument);
|
||||||
}
|
}
|
||||||
PortfolioMessage::OpenDocumentFile {
|
PortfolioMessage::OpenDocumentFile {
|
||||||
document_name,
|
document_name,
|
||||||
document_serialized_content,
|
document_serialized_content,
|
||||||
} => {
|
} => {
|
||||||
responses.push_back(
|
responses.add(PortfolioMessage::OpenDocumentFileWithId {
|
||||||
PortfolioMessage::OpenDocumentFileWithId {
|
document_id: generate_uuid(),
|
||||||
document_id: generate_uuid(),
|
document_name,
|
||||||
document_name,
|
document_is_auto_saved: false,
|
||||||
document_is_auto_saved: false,
|
document_is_saved: true,
|
||||||
document_is_saved: true,
|
document_serialized_content,
|
||||||
document_serialized_content,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
PortfolioMessage::OpenDocumentFileWithId {
|
PortfolioMessage::OpenDocumentFileWithId {
|
||||||
document_id,
|
document_id,
|
||||||
@@ -364,13 +346,10 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
|||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
if !document_is_auto_saved {
|
if !document_is_auto_saved {
|
||||||
responses.push_back(
|
responses.add(DialogMessage::DisplayDialogError {
|
||||||
DialogMessage::DisplayDialogError {
|
title: "Failed to open document".to_string(),
|
||||||
title: "Failed to open document".to_string(),
|
description: e.to_string(),
|
||||||
description: e.to_string(),
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -385,17 +364,14 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
|||||||
});
|
});
|
||||||
|
|
||||||
if let Some(folder) = shallowest_common_folder {
|
if let Some(folder) = shallowest_common_folder {
|
||||||
responses.push_back(DocumentMessage::DeselectAllLayers.into());
|
responses.add(DocumentMessage::DeselectAllLayers);
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
responses.push_back(
|
responses.add(PortfolioMessage::PasteIntoFolder {
|
||||||
PortfolioMessage::PasteIntoFolder {
|
clipboard,
|
||||||
clipboard,
|
folder_path: folder.to_vec(),
|
||||||
folder_path: folder.to_vec(),
|
insert_index: -1,
|
||||||
insert_index: -1,
|
});
|
||||||
}
|
responses.add(DocumentMessage::CommitTransaction);
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
responses.push_back(DocumentMessage::CommitTransaction.into());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PortfolioMessage::PasteIntoFolder {
|
PortfolioMessage::PasteIntoFolder {
|
||||||
@@ -408,22 +384,16 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
|||||||
trace!("Pasting into folder {:?} as index: {}", &path, insert_index);
|
trace!("Pasting into folder {:?} as index: {}", &path, insert_index);
|
||||||
let destination_path = [path.to_vec(), vec![generate_uuid()]].concat();
|
let destination_path = [path.to_vec(), vec![generate_uuid()]].concat();
|
||||||
|
|
||||||
responses.push_front(
|
responses.add_front(DocumentMessage::UpdateLayerMetadata {
|
||||||
DocumentMessage::UpdateLayerMetadata {
|
layer_path: destination_path.clone(),
|
||||||
layer_path: destination_path.clone(),
|
layer_metadata: entry.layer_metadata,
|
||||||
layer_metadata: entry.layer_metadata,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
document.load_layer_resources(responses, &entry.layer.data, destination_path.clone(), self.active_document_id.unwrap());
|
document.load_layer_resources(responses, &entry.layer.data, destination_path.clone(), self.active_document_id.unwrap());
|
||||||
responses.push_front(
|
responses.add_front(DocumentOperation::InsertLayer {
|
||||||
DocumentOperation::InsertLayer {
|
layer: Box::new(entry.layer.clone()),
|
||||||
layer: Box::new(entry.layer.clone()),
|
destination_path,
|
||||||
destination_path,
|
insert_index,
|
||||||
insert_index,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -444,31 +414,25 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
|||||||
.document_legacy
|
.document_legacy
|
||||||
.shallowest_common_folder(document.selected_layers())
|
.shallowest_common_folder(document.selected_layers())
|
||||||
.expect("While pasting from serialized, the selected layers did not exist while attempting to find the appropriate folder path for insertion");
|
.expect("While pasting from serialized, the selected layers did not exist while attempting to find the appropriate folder path for insertion");
|
||||||
responses.push_back(DocumentMessage::DeselectAllLayers.into());
|
responses.add(DocumentMessage::DeselectAllLayers);
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
|
|
||||||
for entry in data.iter().rev() {
|
for entry in data.iter().rev() {
|
||||||
let destination_path = [shallowest_common_folder.to_vec(), vec![generate_uuid()]].concat();
|
let destination_path = [shallowest_common_folder.to_vec(), vec![generate_uuid()]].concat();
|
||||||
|
|
||||||
responses.push_front(
|
responses.add_front(DocumentMessage::UpdateLayerMetadata {
|
||||||
DocumentMessage::UpdateLayerMetadata {
|
layer_path: destination_path.clone(),
|
||||||
layer_path: destination_path.clone(),
|
layer_metadata: entry.layer_metadata,
|
||||||
layer_metadata: entry.layer_metadata,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
document.load_layer_resources(responses, &entry.layer.data, destination_path.clone(), self.active_document_id.unwrap());
|
document.load_layer_resources(responses, &entry.layer.data, destination_path.clone(), self.active_document_id.unwrap());
|
||||||
responses.push_front(
|
responses.add_front(DocumentOperation::InsertLayer {
|
||||||
DocumentOperation::InsertLayer {
|
layer: Box::new(entry.layer.clone()),
|
||||||
layer: Box::new(entry.layer.clone()),
|
destination_path,
|
||||||
destination_path,
|
insert_index: -1,
|
||||||
insert_index: -1,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
responses.push_back(DocumentMessage::CommitTransaction.into());
|
responses.add(DocumentMessage::CommitTransaction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -478,7 +442,7 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
|||||||
let current_index = self.document_index(active_document_id);
|
let current_index = self.document_index(active_document_id);
|
||||||
let prev_index = (current_index + len - 1) % len;
|
let prev_index = (current_index + len - 1) % len;
|
||||||
let prev_id = self.document_ids[prev_index];
|
let prev_id = self.document_ids[prev_index];
|
||||||
responses.push_back(PortfolioMessage::SelectDocument { document_id: prev_id }.into());
|
responses.add(PortfolioMessage::SelectDocument { document_id: prev_id });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PortfolioMessage::ProcessNodeGraphFrame {
|
PortfolioMessage::ProcessNodeGraphFrame {
|
||||||
@@ -498,46 +462,40 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
|||||||
);
|
);
|
||||||
|
|
||||||
if let Err(description) = result {
|
if let Err(description) = result {
|
||||||
responses.push_back(
|
responses.add(DialogMessage::DisplayDialogError {
|
||||||
DialogMessage::DisplayDialogError {
|
title: "Unable to update node graph".to_string(),
|
||||||
title: "Unable to update node graph".to_string(),
|
description,
|
||||||
description,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PortfolioMessage::SelectDocument { document_id } => {
|
PortfolioMessage::SelectDocument { document_id } => {
|
||||||
if let Some(document) = self.active_document() {
|
if let Some(document) = self.active_document() {
|
||||||
if !document.is_auto_saved() {
|
if !document.is_auto_saved() {
|
||||||
responses.push_back(
|
responses.add(PortfolioMessage::AutoSaveDocument {
|
||||||
PortfolioMessage::AutoSaveDocument {
|
// Safe to unwrap since we know that there is an active document
|
||||||
// Safe to unwrap since we know that there is an active document
|
document_id: self.active_document_id.unwrap(),
|
||||||
document_id: self.active_document_id.unwrap(),
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.active_document().is_some() {
|
if self.active_document().is_some() {
|
||||||
responses.push_back(BroadcastEvent::ToolAbort.into());
|
responses.add(BroadcastEvent::ToolAbort);
|
||||||
responses.push_back(OverlaysMessage::ClearAllOverlays.into());
|
responses.add(OverlaysMessage::ClearAllOverlays);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Remove this message in favor of having tools have specific data per document instance
|
// TODO: Remove this message in favor of having tools have specific data per document instance
|
||||||
responses.push_back(PortfolioMessage::SetActiveDocument { document_id }.into());
|
responses.add(PortfolioMessage::SetActiveDocument { document_id });
|
||||||
responses.push_back(PortfolioMessage::UpdateOpenDocumentsList.into());
|
responses.add(PortfolioMessage::UpdateOpenDocumentsList);
|
||||||
responses.push_back(FrontendMessage::UpdateActiveDocument { document_id }.into());
|
responses.add(FrontendMessage::UpdateActiveDocument { document_id });
|
||||||
responses.push_back(DocumentMessage::RenderDocument.into());
|
responses.add(DocumentMessage::RenderDocument);
|
||||||
responses.push_back(DocumentMessage::DocumentStructureChanged.into());
|
responses.add(DocumentMessage::DocumentStructureChanged);
|
||||||
for layer in self.documents.get(&document_id).unwrap().layer_metadata.keys() {
|
for layer in self.documents.get(&document_id).unwrap().layer_metadata.keys() {
|
||||||
responses.push_back(DocumentMessage::LayerChanged { affected_layer_path: layer.clone() }.into());
|
responses.add(DocumentMessage::LayerChanged { affected_layer_path: layer.clone() });
|
||||||
}
|
}
|
||||||
responses.push_back(BroadcastEvent::SelectionChanged.into());
|
responses.add(BroadcastEvent::SelectionChanged);
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
responses.push_back(PortfolioMessage::UpdateDocumentWidgets.into());
|
responses.add(PortfolioMessage::UpdateDocumentWidgets);
|
||||||
responses.push_back(NavigationMessage::TranslateCanvas { delta: (0., 0.).into() }.into());
|
responses.add(NavigationMessage::TranslateCanvas { delta: (0., 0.).into() });
|
||||||
}
|
}
|
||||||
PortfolioMessage::SetActiveDocument { document_id } => self.active_document_id = Some(document_id),
|
PortfolioMessage::SetActiveDocument { document_id } => self.active_document_id = Some(document_id),
|
||||||
PortfolioMessage::SetImageBlobUrl {
|
PortfolioMessage::SetImageBlobUrl {
|
||||||
@@ -552,7 +510,7 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
|||||||
resolution,
|
resolution,
|
||||||
document_id,
|
document_id,
|
||||||
};
|
};
|
||||||
responses.push_back(PortfolioMessage::DocumentPassMessage { document_id, message }.into());
|
responses.add(PortfolioMessage::DocumentPassMessage { document_id, message });
|
||||||
}
|
}
|
||||||
PortfolioMessage::UpdateDocumentWidgets => {
|
PortfolioMessage::UpdateDocumentWidgets => {
|
||||||
if let Some(document) = self.active_document() {
|
if let Some(document) = self.active_document() {
|
||||||
@@ -573,7 +531,7 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
responses.push_back(FrontendMessage::UpdateOpenDocumentsList { open_documents }.into());
|
responses.add(FrontendMessage::UpdateOpenDocumentsList { open_documents });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -670,19 +628,19 @@ impl PortfolioMessageHandler {
|
|||||||
self.documents.insert(document_id, new_document);
|
self.documents.insert(document_id, new_document);
|
||||||
|
|
||||||
if self.active_document().is_some() {
|
if self.active_document().is_some() {
|
||||||
responses.push_back(PropertiesPanelMessage::Deactivate.into());
|
responses.add(PropertiesPanelMessage::Deactivate);
|
||||||
responses.push_back(BroadcastEvent::ToolAbort.into());
|
responses.add(BroadcastEvent::ToolAbort);
|
||||||
responses.push_back(ToolMessage::DeactivateTools.into());
|
responses.add(ToolMessage::DeactivateTools);
|
||||||
}
|
}
|
||||||
|
|
||||||
responses.push_back(PortfolioMessage::UpdateOpenDocumentsList.into());
|
responses.add(PortfolioMessage::UpdateOpenDocumentsList);
|
||||||
responses.push_back(PortfolioMessage::SelectDocument { document_id }.into());
|
responses.add(PortfolioMessage::SelectDocument { document_id });
|
||||||
responses.push_back(PortfolioMessage::LoadDocumentResources { document_id }.into());
|
responses.add(PortfolioMessage::LoadDocumentResources { document_id });
|
||||||
responses.push_back(PortfolioMessage::UpdateDocumentWidgets.into());
|
responses.add(PortfolioMessage::UpdateDocumentWidgets);
|
||||||
responses.push_back(ToolMessage::InitTools.into());
|
responses.add(ToolMessage::InitTools);
|
||||||
responses.push_back(PropertiesPanelMessage::Init.into());
|
responses.add(PropertiesPanelMessage::Init);
|
||||||
responses.push_back(NavigationMessage::TranslateCanvas { delta: (0., 0.).into() }.into());
|
responses.add(NavigationMessage::TranslateCanvas { delta: (0., 0.).into() });
|
||||||
responses.push_back(DocumentMessage::DocumentStructureChanged.into());
|
responses.add(DocumentMessage::DocumentStructureChanged);
|
||||||
responses.add(PropertiesPanelMessage::ClearSelection);
|
responses.add(PropertiesPanelMessage::ClearSelection);
|
||||||
responses.add(PropertiesPanelMessage::UpdateSelectedDocumentProperties);
|
responses.add(PropertiesPanelMessage::UpdateSelectedDocumentProperties);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ impl MessageHandler<PreferencesMessage, ()> for PreferencesMessageHandler {
|
|||||||
*self = deserialized_preferences;
|
*self = deserialized_preferences;
|
||||||
|
|
||||||
if self.imaginate_server_hostname != Self::default().imaginate_server_hostname {
|
if self.imaginate_server_hostname != Self::default().imaginate_server_hostname {
|
||||||
responses.push_back(PortfolioMessage::ImaginateCheckServerStatus.into());
|
responses.add(PortfolioMessage::ImaginateCheckServerStatus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -41,7 +41,7 @@ impl MessageHandler<PreferencesMessage, ()> for PreferencesMessageHandler {
|
|||||||
|
|
||||||
PreferencesMessage::ImaginateRefreshFrequency { seconds } => {
|
PreferencesMessage::ImaginateRefreshFrequency { seconds } => {
|
||||||
self.imaginate_refresh_frequency = seconds;
|
self.imaginate_refresh_frequency = seconds;
|
||||||
responses.push_back(PortfolioMessage::ImaginateCheckServerStatus.into());
|
responses.add(PortfolioMessage::ImaginateCheckServerStatus);
|
||||||
}
|
}
|
||||||
PreferencesMessage::ImaginateServerHostname { hostname } => {
|
PreferencesMessage::ImaginateServerHostname { hostname } => {
|
||||||
let initial = hostname.clone();
|
let initial = hostname.clone();
|
||||||
@@ -54,7 +54,7 @@ impl MessageHandler<PreferencesMessage, ()> for PreferencesMessageHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.imaginate_server_hostname = hostname;
|
self.imaginate_server_hostname = hostname;
|
||||||
responses.push_back(PortfolioMessage::ImaginateCheckServerStatus.into());
|
responses.add(PortfolioMessage::ImaginateCheckServerStatus);
|
||||||
}
|
}
|
||||||
PreferencesMessage::ModifyLayout { zoom_with_scroll } => {
|
PreferencesMessage::ModifyLayout { zoom_with_scroll } => {
|
||||||
self.zoom_with_scroll = zoom_with_scroll;
|
self.zoom_with_scroll = zoom_with_scroll;
|
||||||
@@ -63,12 +63,12 @@ impl MessageHandler<PreferencesMessage, ()> for PreferencesMessageHandler {
|
|||||||
false => MappingVariant::Default,
|
false => MappingVariant::Default,
|
||||||
true => MappingVariant::ZoomWithScroll,
|
true => MappingVariant::ZoomWithScroll,
|
||||||
};
|
};
|
||||||
responses.push_back(KeyMappingMessage::ModifyMapping(variant).into());
|
responses.add(KeyMappingMessage::ModifyMapping(variant));
|
||||||
responses.push_back(FrontendMessage::UpdateZoomWithScroll { zoom_with_scroll }.into());
|
responses.add(FrontendMessage::UpdateZoomWithScroll { zoom_with_scroll });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
responses.push_back(FrontendMessage::TriggerSavePreferences { preferences: self.clone() }.into());
|
responses.add(FrontendMessage::TriggerSavePreferences { preferences: self.clone() });
|
||||||
}
|
}
|
||||||
|
|
||||||
advertise_actions!(PreferencesMessageDiscriminant;
|
advertise_actions!(PreferencesMessageDiscriminant;
|
||||||
@@ -76,10 +76,7 @@ impl MessageHandler<PreferencesMessage, ()> for PreferencesMessageHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn refresh_dialog(responses: &mut VecDeque<Message>) {
|
fn refresh_dialog(responses: &mut VecDeque<Message>) {
|
||||||
responses.push_back(
|
responses.add(DialogMessage::CloseDialogAndThen {
|
||||||
DialogMessage::CloseDialogAndThen {
|
followups: vec![DialogMessage::RequestPreferencesDialog.into()],
|
||||||
followups: vec![DialogMessage::RequestPreferencesDialog.into()],
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,14 +60,22 @@ pub use std::collections::{HashMap, HashSet, VecDeque};
|
|||||||
|
|
||||||
pub trait Responses {
|
pub trait Responses {
|
||||||
fn add(&mut self, message: impl Into<Message>);
|
fn add(&mut self, message: impl Into<Message>);
|
||||||
|
|
||||||
|
fn add_front(&mut self, message: impl Into<Message>);
|
||||||
|
|
||||||
fn try_add(&mut self, message: Option<impl Into<Message>>) {
|
fn try_add(&mut self, message: Option<impl Into<Message>>) {
|
||||||
if let Some(message) = message {
|
if let Some(message) = message {
|
||||||
self.add(message);
|
self.add(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Responses for VecDeque<Message> {
|
impl Responses for VecDeque<Message> {
|
||||||
fn add(&mut self, message: impl Into<Message>) {
|
fn add(&mut self, message: impl Into<Message>) {
|
||||||
self.push_back(message.into());
|
self.push_back(message.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn add_front(&mut self, message: impl Into<Message>) {
|
||||||
|
self.push_front(message.into());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,16 +17,13 @@ pub fn new_vector_layer(subpaths: Vec<Subpath<ManipulatorGroupId>>, layer_path:
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_custom_layer(network: NodeNetwork, layer_path: Vec<LayerId>, responses: &mut VecDeque<Message>) {
|
pub fn new_custom_layer(network: NodeNetwork, layer_path: Vec<LayerId>, responses: &mut VecDeque<Message>) {
|
||||||
responses.push_back(DocumentMessage::DeselectAllLayers.into());
|
responses.add(DocumentMessage::DeselectAllLayers);
|
||||||
responses.push_back(
|
responses.add(Operation::AddNodeGraphFrame {
|
||||||
Operation::AddNodeGraphFrame {
|
path: layer_path.clone(),
|
||||||
path: layer_path.clone(),
|
insert_index: -1,
|
||||||
insert_index: -1,
|
transform: DAffine2::ZERO.to_cols_array(),
|
||||||
transform: DAffine2::ZERO.to_cols_array(),
|
network,
|
||||||
network,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path });
|
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ impl OverlayRenderer {
|
|||||||
insert_index: -1,
|
insert_index: -1,
|
||||||
transform: DAffine2::IDENTITY.to_cols_array(),
|
transform: DAffine2::IDENTITY.to_cols_array(),
|
||||||
};
|
};
|
||||||
responses.push_back(DocumentMessage::Overlays(operation.into()).into());
|
responses.add(DocumentMessage::Overlays(operation.into()));
|
||||||
|
|
||||||
layer_path
|
layer_path
|
||||||
}
|
}
|
||||||
@@ -177,7 +177,7 @@ impl OverlayRenderer {
|
|||||||
style: style::PathStyle::new(Some(Stroke::new(COLOR_ACCENT, 2.0)), Fill::solid(Color::WHITE)),
|
style: style::PathStyle::new(Some(Stroke::new(COLOR_ACCENT, 2.0)), Fill::solid(Color::WHITE)),
|
||||||
insert_index: -1,
|
insert_index: -1,
|
||||||
};
|
};
|
||||||
responses.push_back(DocumentMessage::Overlays(operation.into()).into());
|
responses.add(DocumentMessage::Overlays(operation.into()));
|
||||||
layer_path
|
layer_path
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,7 +190,7 @@ impl OverlayRenderer {
|
|||||||
style: style::PathStyle::new(Some(Stroke::new(COLOR_ACCENT, 2.0)), Fill::solid(Color::WHITE)),
|
style: style::PathStyle::new(Some(Stroke::new(COLOR_ACCENT, 2.0)), Fill::solid(Color::WHITE)),
|
||||||
insert_index: -1,
|
insert_index: -1,
|
||||||
};
|
};
|
||||||
responses.push_back(DocumentMessage::Overlays(operation.into()).into());
|
responses.add(DocumentMessage::Overlays(operation.into()));
|
||||||
layer_path
|
layer_path
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,7 +202,7 @@ impl OverlayRenderer {
|
|||||||
/// Remove an overlay at the specified path
|
/// Remove an overlay at the specified path
|
||||||
fn remove_overlay(path: Option<Vec<LayerId>>, responses: &mut VecDeque<Message>) {
|
fn remove_overlay(path: Option<Vec<LayerId>>, responses: &mut VecDeque<Message>) {
|
||||||
if let Some(path) = path {
|
if let Some(path) = path {
|
||||||
responses.push_back(DocumentMessage::Overlays(Operation::DeleteLayer { path }.into()).into());
|
responses.add(DocumentMessage::Overlays(Operation::DeleteLayer { path }.into()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,7 +215,7 @@ impl OverlayRenderer {
|
|||||||
style: style::PathStyle::new(Some(Stroke::new(COLOR_ACCENT, 1.0)), Fill::None),
|
style: style::PathStyle::new(Some(Stroke::new(COLOR_ACCENT, 1.0)), Fill::None),
|
||||||
insert_index: -1,
|
insert_index: -1,
|
||||||
};
|
};
|
||||||
responses.push_front(DocumentMessage::Overlays(operation.into()).into());
|
responses.add_front(DocumentMessage::Overlays(operation.into()));
|
||||||
layer_path
|
layer_path
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,12 +226,12 @@ impl OverlayRenderer {
|
|||||||
|
|
||||||
fn place_outline_overlays(outline_path: Vec<LayerId>, parent_transform: &DAffine2, responses: &mut VecDeque<Message>) {
|
fn place_outline_overlays(outline_path: Vec<LayerId>, parent_transform: &DAffine2, responses: &mut VecDeque<Message>) {
|
||||||
let transform_message = Self::overlay_transform_message(outline_path, parent_transform.to_cols_array());
|
let transform_message = Self::overlay_transform_message(outline_path, parent_transform.to_cols_array());
|
||||||
responses.push_back(transform_message);
|
responses.add(transform_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn modify_outline_overlays(outline_path: Vec<LayerId>, subpath: graphene_core::vector::Subpath, responses: &mut VecDeque<Message>) {
|
fn modify_outline_overlays(outline_path: Vec<LayerId>, subpath: graphene_core::vector::Subpath, responses: &mut VecDeque<Message>) {
|
||||||
let outline_modify_message = Self::overlay_modify_message(outline_path, subpath);
|
let outline_modify_message = Self::overlay_modify_message(outline_path, subpath);
|
||||||
responses.push_back(outline_modify_message);
|
responses.add(outline_modify_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates the position of the overlays based on the [Subpath] points.
|
/// Updates the position of the overlays based on the [Subpath] points.
|
||||||
@@ -245,7 +245,7 @@ impl OverlayRenderer {
|
|||||||
|
|
||||||
let translation = (parent_transform.transform_point2(handle_position) + VIEWPORT_GRID_ROUNDING_BIAS).round() + DVec2::splat(0.5);
|
let translation = (parent_transform.transform_point2(handle_position) + VIEWPORT_GRID_ROUNDING_BIAS).round() + DVec2::splat(0.5);
|
||||||
let transform = DAffine2::from_scale_angle_translation(scale, angle, translation).to_cols_array();
|
let transform = DAffine2::from_scale_angle_translation(scale, angle, translation).to_cols_array();
|
||||||
responses.push_back(Self::overlay_transform_message(line_overlay.to_vec(), transform));
|
responses.add(Self::overlay_transform_message(line_overlay.to_vec(), transform));
|
||||||
|
|
||||||
let marker_overlay = marker_source.take().unwrap_or_else(|| Self::create_handle_overlay(responses));
|
let marker_overlay = marker_source.take().unwrap_or_else(|| Self::create_handle_overlay(responses));
|
||||||
|
|
||||||
@@ -254,7 +254,7 @@ impl OverlayRenderer {
|
|||||||
let translation = (parent_transform.transform_point2(handle_position) - (scale / 2.) + VIEWPORT_GRID_ROUNDING_BIAS).round();
|
let translation = (parent_transform.transform_point2(handle_position) - (scale / 2.) + VIEWPORT_GRID_ROUNDING_BIAS).round();
|
||||||
let transform = DAffine2::from_scale_angle_translation(scale, angle, translation).to_cols_array();
|
let transform = DAffine2::from_scale_angle_translation(scale, angle, translation).to_cols_array();
|
||||||
|
|
||||||
responses.push_back(Self::overlay_transform_message(marker_overlay.clone(), transform));
|
responses.add(Self::overlay_transform_message(marker_overlay.clone(), transform));
|
||||||
|
|
||||||
*marker_source = Some(marker_overlay);
|
*marker_source = Some(marker_overlay);
|
||||||
};
|
};
|
||||||
@@ -275,7 +275,7 @@ impl OverlayRenderer {
|
|||||||
let transform = DAffine2::from_scale_angle_translation(scale, angle, translation).to_cols_array();
|
let transform = DAffine2::from_scale_angle_translation(scale, angle, translation).to_cols_array();
|
||||||
|
|
||||||
let message = Self::overlay_transform_message(anchor_overlay.clone(), transform);
|
let message = Self::overlay_transform_message(anchor_overlay.clone(), transform);
|
||||||
responses.push_back(message);
|
responses.add(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,23 +283,23 @@ impl OverlayRenderer {
|
|||||||
fn remove_manipulator_group_overlays(overlay_paths: &ManipulatorGroupOverlays, responses: &mut VecDeque<Message>) {
|
fn remove_manipulator_group_overlays(overlay_paths: &ManipulatorGroupOverlays, responses: &mut VecDeque<Message>) {
|
||||||
overlay_paths.iter().flatten().for_each(|layer_id| {
|
overlay_paths.iter().flatten().for_each(|layer_id| {
|
||||||
trace!("Overlay: Sending delete message for: {:?}", layer_id);
|
trace!("Overlay: Sending delete message for: {:?}", layer_id);
|
||||||
responses.push_back(DocumentMessage::Overlays(Operation::DeleteLayer { path: layer_id.clone() }.into()).into());
|
responses.add(DocumentMessage::Overlays(Operation::DeleteLayer { path: layer_id.clone() }.into()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_outline_overlays(overlay_path: Vec<LayerId>, responses: &mut VecDeque<Message>) {
|
fn remove_outline_overlays(overlay_path: Vec<LayerId>, responses: &mut VecDeque<Message>) {
|
||||||
responses.push_back(DocumentMessage::Overlays(Operation::DeleteLayer { path: overlay_path }.into()).into());
|
responses.add(DocumentMessage::Overlays(Operation::DeleteLayer { path: overlay_path }.into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the visibility of the handles overlay.
|
/// Sets the visibility of the handles overlay.
|
||||||
fn set_manipulator_group_overlay_visibility(manipulator_group_overlays: &ManipulatorGroupOverlays, visibility: bool, responses: &mut VecDeque<Message>) {
|
fn set_manipulator_group_overlay_visibility(manipulator_group_overlays: &ManipulatorGroupOverlays, visibility: bool, responses: &mut VecDeque<Message>) {
|
||||||
manipulator_group_overlays.iter().flatten().for_each(|layer_id| {
|
manipulator_group_overlays.iter().flatten().for_each(|layer_id| {
|
||||||
responses.push_back(Self::overlay_visibility_message(layer_id.clone(), visibility));
|
responses.add(Self::overlay_visibility_message(layer_id.clone(), visibility));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_outline_overlay_visibility(overlay_path: Vec<LayerId>, visibility: bool, responses: &mut VecDeque<Message>) {
|
fn set_outline_overlay_visibility(overlay_path: Vec<LayerId>, visibility: bool, responses: &mut VecDeque<Message>) {
|
||||||
responses.push_back(Self::overlay_visibility_message(overlay_path, visibility));
|
responses.add(Self::overlay_visibility_message(overlay_path, visibility));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a visibility message for an overlay.
|
/// Create a visibility message for an overlay.
|
||||||
@@ -340,7 +340,7 @@ impl OverlayRenderer {
|
|||||||
.is_some();
|
.is_some();
|
||||||
|
|
||||||
let style = if selected { selected_style.clone() } else { deselected_style.clone() };
|
let style = if selected { selected_style.clone() } else { deselected_style.clone() };
|
||||||
responses.push_back(DocumentMessage::Overlays(Operation::SetLayerStyle { path: overlay_path.clone(), style }.into()).into());
|
responses.add(DocumentMessage::Overlays(Operation::SetLayerStyle { path: overlay_path.clone(), style }.into()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ impl PathOutline {
|
|||||||
transform: DAffine2::IDENTITY.to_cols_array(),
|
transform: DAffine2::IDENTITY.to_cols_array(),
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push_back(DocumentMessage::Overlays(operation.into()).into());
|
responses.add(DocumentMessage::Overlays(operation.into()));
|
||||||
|
|
||||||
overlay_path
|
overlay_path
|
||||||
}
|
}
|
||||||
@@ -59,14 +59,14 @@ impl PathOutline {
|
|||||||
|
|
||||||
// Update the shape bezpath
|
// Update the shape bezpath
|
||||||
let operation = Operation::SetShapePath { path: overlay.clone(), subpath };
|
let operation = Operation::SetShapePath { path: overlay.clone(), subpath };
|
||||||
responses.push_back(DocumentMessage::Overlays(operation.into()).into());
|
responses.add(DocumentMessage::Overlays(operation.into()));
|
||||||
|
|
||||||
// Update the transform to match the document
|
// Update the transform to match the document
|
||||||
let operation = Operation::SetLayerTransform {
|
let operation = Operation::SetLayerTransform {
|
||||||
path: overlay.clone(),
|
path: overlay.clone(),
|
||||||
transform: document.document_legacy.multiply_transforms(&document_layer_path).unwrap().to_cols_array(),
|
transform: document.document_legacy.multiply_transforms(&document_layer_path).unwrap().to_cols_array(),
|
||||||
};
|
};
|
||||||
responses.push_back(DocumentMessage::Overlays(operation.into()).into());
|
responses.add(DocumentMessage::Overlays(operation.into()));
|
||||||
|
|
||||||
Some(overlay)
|
Some(overlay)
|
||||||
}
|
}
|
||||||
@@ -87,7 +87,7 @@ impl PathOutline {
|
|||||||
// Discard the overlay layer if it exists
|
// Discard the overlay layer if it exists
|
||||||
if let Some(overlay_path) = copied_overlay_path {
|
if let Some(overlay_path) = copied_overlay_path {
|
||||||
let operation = Operation::DeleteLayer { path: overlay_path };
|
let operation = Operation::DeleteLayer { path: overlay_path };
|
||||||
responses.push_back(DocumentMessage::Overlays(operation.into()).into());
|
responses.add(DocumentMessage::Overlays(operation.into()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
@@ -97,7 +97,7 @@ impl PathOutline {
|
|||||||
pub fn clear_hovered(&mut self, responses: &mut VecDeque<Message>) {
|
pub fn clear_hovered(&mut self, responses: &mut VecDeque<Message>) {
|
||||||
if let Some(path) = self.hovered_overlay_path.take() {
|
if let Some(path) = self.hovered_overlay_path.take() {
|
||||||
let operation = Operation::DeleteLayer { path };
|
let operation = Operation::DeleteLayer { path };
|
||||||
responses.push_back(DocumentMessage::Overlays(operation.into()).into());
|
responses.add(DocumentMessage::Overlays(operation.into()));
|
||||||
}
|
}
|
||||||
self.hovered_layer_path = None;
|
self.hovered_layer_path = None;
|
||||||
}
|
}
|
||||||
@@ -131,7 +131,7 @@ impl PathOutline {
|
|||||||
pub fn clear_selected(&mut self, responses: &mut VecDeque<Message>) {
|
pub fn clear_selected(&mut self, responses: &mut VecDeque<Message>) {
|
||||||
while let Some(path) = self.selected_overlay_paths.pop() {
|
while let Some(path) = self.selected_overlay_paths.pop() {
|
||||||
let operation = Operation::DeleteLayer { path };
|
let operation = Operation::DeleteLayer { path };
|
||||||
responses.push_back(DocumentMessage::Overlays(operation.into()).into());
|
responses.add(DocumentMessage::Overlays(operation.into()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ impl PathOutline {
|
|||||||
}
|
}
|
||||||
for path in old_overlay_paths {
|
for path in old_overlay_paths {
|
||||||
let operation = Operation::DeleteLayer { path };
|
let operation = Operation::DeleteLayer { path };
|
||||||
responses.push_back(DocumentMessage::Overlays(operation.into()).into());
|
responses.add(DocumentMessage::Overlays(operation.into()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ impl Pivot {
|
|||||||
pub fn clear_overlays(&mut self, responses: &mut VecDeque<Message>) {
|
pub fn clear_overlays(&mut self, responses: &mut VecDeque<Message>) {
|
||||||
if let Some(overlays) = self.pivot_overlay_circles.take() {
|
if let Some(overlays) = self.pivot_overlay_circles.take() {
|
||||||
for path in overlays {
|
for path in overlays {
|
||||||
responses.push_back(DocumentMessage::Overlays(Operation::DeleteLayer { path }.into()).into());
|
responses.add(DocumentMessage::Overlays(Operation::DeleteLayer { path }.into()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,43 +107,37 @@ impl Pivot {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let layer_paths = [vec![generate_uuid()], vec![generate_uuid()]];
|
let layer_paths = [vec![generate_uuid()], vec![generate_uuid()]];
|
||||||
responses.push_back(
|
responses.add(DocumentMessage::Overlays(
|
||||||
DocumentMessage::Overlays(
|
Operation::AddEllipse {
|
||||||
Operation::AddEllipse {
|
path: layer_paths[0].clone(),
|
||||||
path: layer_paths[0].clone(),
|
transform: DAffine2::IDENTITY.to_cols_array(),
|
||||||
transform: DAffine2::IDENTITY.to_cols_array(),
|
style: style::PathStyle::new(
|
||||||
style: style::PathStyle::new(
|
Some(style::Stroke::new(COLOR_ACCENT, PIVOT_OUTER_OUTLINE_THICKNESS)),
|
||||||
Some(style::Stroke::new(COLOR_ACCENT, PIVOT_OUTER_OUTLINE_THICKNESS)),
|
style::Fill::Solid(graphene_core::raster::color::Color::WHITE),
|
||||||
style::Fill::Solid(graphene_core::raster::color::Color::WHITE),
|
),
|
||||||
),
|
insert_index: -1,
|
||||||
insert_index: -1,
|
}
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
)
|
|
||||||
.into(),
|
.into(),
|
||||||
);
|
));
|
||||||
responses.push_back(
|
responses.add(DocumentMessage::Overlays(
|
||||||
DocumentMessage::Overlays(
|
Operation::AddEllipse {
|
||||||
Operation::AddEllipse {
|
path: layer_paths[1].clone(),
|
||||||
path: layer_paths[1].clone(),
|
transform: DAffine2::IDENTITY.to_cols_array(),
|
||||||
transform: DAffine2::IDENTITY.to_cols_array(),
|
style: style::PathStyle::new(None, style::Fill::Solid(COLOR_ACCENT)),
|
||||||
style: style::PathStyle::new(None, style::Fill::Solid(COLOR_ACCENT)),
|
insert_index: -1,
|
||||||
insert_index: -1,
|
}
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
)
|
|
||||||
.into(),
|
.into(),
|
||||||
);
|
));
|
||||||
|
|
||||||
self.pivot_overlay_circles = Some(layer_paths.clone());
|
self.pivot_overlay_circles = Some(layer_paths.clone());
|
||||||
let [outer, inner] = layer_paths;
|
let [outer, inner] = layer_paths;
|
||||||
|
|
||||||
let pivot_diameter_without_outline = PIVOT_OUTER - PIVOT_OUTER_OUTLINE_THICKNESS;
|
let pivot_diameter_without_outline = PIVOT_OUTER - PIVOT_OUTER_OUTLINE_THICKNESS;
|
||||||
let transform = DAffine2::from_scale_angle_translation(DVec2::splat(pivot_diameter_without_outline), 0., pivot - DVec2::splat(pivot_diameter_without_outline / 2.)).to_cols_array();
|
let transform = DAffine2::from_scale_angle_translation(DVec2::splat(pivot_diameter_without_outline), 0., pivot - DVec2::splat(pivot_diameter_without_outline / 2.)).to_cols_array();
|
||||||
responses.push_back(DocumentMessage::Overlays(Operation::TransformLayerInViewport { path: outer, transform }.into()).into());
|
responses.add(DocumentMessage::Overlays(Operation::TransformLayerInViewport { path: outer, transform }.into()));
|
||||||
|
|
||||||
let transform = DAffine2::from_scale_angle_translation(DVec2::splat(PIVOT_INNER), 0., pivot - DVec2::splat(PIVOT_INNER / 2.)).to_cols_array();
|
let transform = DAffine2::from_scale_angle_translation(DVec2::splat(PIVOT_INNER), 0., pivot - DVec2::splat(PIVOT_INNER / 2.)).to_cols_array();
|
||||||
responses.push_back(DocumentMessage::Overlays(Operation::TransformLayerInViewport { path: inner, transform }.into()).into());
|
responses.add(DocumentMessage::Overlays(Operation::TransformLayerInViewport { path: inner, transform }.into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_pivot(&mut self, document: &DocumentMessageHandler, render_data: &RenderData, responses: &mut VecDeque<Message>) {
|
pub fn update_pivot(&mut self, document: &DocumentMessageHandler, render_data: &RenderData, responses: &mut VecDeque<Message>) {
|
||||||
|
|||||||
@@ -29,40 +29,37 @@ impl SnapOverlays {
|
|||||||
// If there isn't one in the pool to ruse, add a new alignment line to the pool with the intended transform
|
// If there isn't one in the pool to ruse, add a new alignment line to the pool with the intended transform
|
||||||
let layer_path = if index >= overlay_paths.len() {
|
let layer_path = if index >= overlay_paths.len() {
|
||||||
let layer_path = vec![generate_uuid()];
|
let layer_path = vec![generate_uuid()];
|
||||||
responses.push_back(
|
responses.add(DocumentMessage::Overlays(
|
||||||
DocumentMessage::Overlays(
|
if is_axis {
|
||||||
if is_axis {
|
Operation::AddLine {
|
||||||
Operation::AddLine {
|
path: layer_path.clone(),
|
||||||
path: layer_path.clone(),
|
transform,
|
||||||
transform,
|
style: style::PathStyle::new(Some(Stroke::new(COLOR_ACCENT, 1.0)), style::Fill::None),
|
||||||
style: style::PathStyle::new(Some(Stroke::new(COLOR_ACCENT, 1.0)), style::Fill::None),
|
insert_index: -1,
|
||||||
insert_index: -1,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Operation::AddEllipse {
|
|
||||||
path: layer_path.clone(),
|
|
||||||
transform,
|
|
||||||
style: style::PathStyle::new(None, style::Fill::Solid(COLOR_ACCENT)),
|
|
||||||
insert_index: -1,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.into(),
|
} else {
|
||||||
)
|
Operation::AddEllipse {
|
||||||
|
path: layer_path.clone(),
|
||||||
|
transform,
|
||||||
|
style: style::PathStyle::new(None, style::Fill::Solid(COLOR_ACCENT)),
|
||||||
|
insert_index: -1,
|
||||||
|
}
|
||||||
|
}
|
||||||
.into(),
|
.into(),
|
||||||
);
|
));
|
||||||
overlay_paths.push(layer_path.clone());
|
overlay_paths.push(layer_path.clone());
|
||||||
layer_path
|
layer_path
|
||||||
}
|
}
|
||||||
// Otherwise, reuse an overlay from the pool and update its new transform
|
// Otherwise, reuse an overlay from the pool and update its new transform
|
||||||
else {
|
else {
|
||||||
let layer_path = overlay_paths[index].clone();
|
let layer_path = overlay_paths[index].clone();
|
||||||
responses.push_back(DocumentMessage::Overlays(Operation::SetLayerTransform { path: layer_path.clone(), transform }.into()).into());
|
responses.add(DocumentMessage::Overlays(Operation::SetLayerTransform { path: layer_path.clone(), transform }.into()));
|
||||||
layer_path
|
layer_path
|
||||||
};
|
};
|
||||||
|
|
||||||
// Then set its opacity to the fade amount
|
// Then set its opacity to the fade amount
|
||||||
if let Some(opacity) = opacity {
|
if let Some(opacity) = opacity {
|
||||||
responses.push_back(DocumentMessage::Overlays(Operation::SetLayerOpacity { path: layer_path, opacity }.into()).into());
|
responses.add(DocumentMessage::Overlays(Operation::SetLayerOpacity { path: layer_path, opacity }.into()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,7 +144,7 @@ impl SnapOverlays {
|
|||||||
/// Remove overlays from the pool beyond a given index. Pool entries up through that index will be kept.
|
/// Remove overlays from the pool beyond a given index. Pool entries up through that index will be kept.
|
||||||
fn remove_unused_overlays(overlay_paths: &mut Vec<Vec<LayerId>>, responses: &mut VecDeque<Message>, remove_after_index: usize) {
|
fn remove_unused_overlays(overlay_paths: &mut Vec<Vec<LayerId>>, responses: &mut VecDeque<Message>, remove_after_index: usize) {
|
||||||
while overlay_paths.len() > remove_after_index {
|
while overlay_paths.len() > remove_after_index {
|
||||||
responses.push_back(DocumentMessage::Overlays(Operation::DeleteLayer { path: overlay_paths.pop().unwrap() }.into()).into());
|
responses.add(DocumentMessage::Overlays(Operation::DeleteLayer { path: overlay_paths.pop().unwrap() }.into()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ pub fn add_bounding_box(responses: &mut VecDeque<Message>) -> Vec<LayerId> {
|
|||||||
style: style::PathStyle::new(Some(Stroke::new(COLOR_ACCENT, 1.0)), Fill::None),
|
style: style::PathStyle::new(Some(Stroke::new(COLOR_ACCENT, 1.0)), Fill::None),
|
||||||
insert_index: -1,
|
insert_index: -1,
|
||||||
};
|
};
|
||||||
responses.push_back(DocumentMessage::Overlays(operation.into()).into());
|
responses.add(DocumentMessage::Overlays(operation.into()));
|
||||||
|
|
||||||
path
|
path
|
||||||
}
|
}
|
||||||
@@ -178,7 +178,7 @@ fn add_transform_handles(responses: &mut VecDeque<Message>) -> [Vec<LayerId>; 8]
|
|||||||
style: style::PathStyle::new(Some(Stroke::new(COLOR_ACCENT, 2.0)), Fill::solid(Color::WHITE)),
|
style: style::PathStyle::new(Some(Stroke::new(COLOR_ACCENT, 2.0)), Fill::solid(Color::WHITE)),
|
||||||
insert_index: -1,
|
insert_index: -1,
|
||||||
};
|
};
|
||||||
responses.push_back(DocumentMessage::Overlays(operation.into()).into());
|
responses.add(DocumentMessage::Overlays(operation.into()));
|
||||||
|
|
||||||
*item = current_path;
|
*item = current_path;
|
||||||
}
|
}
|
||||||
@@ -253,7 +253,7 @@ impl BoundingBoxOverlays {
|
|||||||
pub fn transform(&mut self, responses: &mut VecDeque<Message>) {
|
pub fn transform(&mut self, responses: &mut VecDeque<Message>) {
|
||||||
let transform = transform_from_box(self.bounds[0], self.bounds[1], self.transform).to_cols_array();
|
let transform = transform_from_box(self.bounds[0], self.bounds[1], self.transform).to_cols_array();
|
||||||
let path = self.bounding_box.clone();
|
let path = self.bounding_box.clone();
|
||||||
responses.push_back(DocumentMessage::Overlays(Operation::SetLayerTransformInViewport { path, transform }.into()).into());
|
responses.add(DocumentMessage::Overlays(Operation::SetLayerTransformInViewport { path, transform }.into()));
|
||||||
|
|
||||||
// Helps push values that end in approximately half, plus or minus some floating point imprecision, towards the same side of the round() function
|
// Helps push values that end in approximately half, plus or minus some floating point imprecision, towards the same side of the round() function
|
||||||
const BIAS: f64 = 0.0001;
|
const BIAS: f64 = 0.0001;
|
||||||
@@ -263,7 +263,7 @@ impl BoundingBoxOverlays {
|
|||||||
let translation = (position - (scale / 2.) - 0.5 + BIAS).round();
|
let translation = (position - (scale / 2.) - 0.5 + BIAS).round();
|
||||||
let transform = DAffine2::from_scale_angle_translation(scale, 0., translation).to_cols_array();
|
let transform = DAffine2::from_scale_angle_translation(scale, 0., translation).to_cols_array();
|
||||||
let path = path.clone();
|
let path = path.clone();
|
||||||
responses.push_back(DocumentMessage::Overlays(Operation::SetLayerTransformInViewport { path, transform }.into()).into());
|
responses.add(DocumentMessage::Overlays(Operation::SetLayerTransformInViewport { path, transform }.into()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -341,7 +341,7 @@ impl BoundingBoxOverlays {
|
|||||||
|
|
||||||
/// Removes the overlays
|
/// Removes the overlays
|
||||||
pub fn delete(self, responses: &mut VecDeque<Message>) {
|
pub fn delete(self, responses: &mut VecDeque<Message>) {
|
||||||
responses.push_back(DocumentMessage::Overlays(Operation::DeleteLayer { path: self.bounding_box }.into()).into());
|
responses.add(DocumentMessage::Overlays(Operation::DeleteLayer { path: self.bounding_box }.into()));
|
||||||
responses.extend(
|
responses.extend(
|
||||||
self.transform_handles
|
self.transform_handles
|
||||||
.iter()
|
.iter()
|
||||||
|
|||||||
@@ -38,41 +38,41 @@ impl MessageHandler<ToolMessage, (&DocumentMessageHandler, u64, &InputPreprocess
|
|||||||
.process_message(message, responses, (document, input, &render_data, &self.tool_state.tool_data, &mut self.shape_editor)),
|
.process_message(message, responses, (document, input, &render_data, &self.tool_state.tool_data, &mut self.shape_editor)),
|
||||||
|
|
||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
ToolMessage::ActivateToolSelect => responses.push_front(ToolMessage::ActivateTool { tool_type: ToolType::Select }.into()),
|
ToolMessage::ActivateToolSelect => responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Select }),
|
||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
ToolMessage::ActivateToolArtboard => responses.push_front(ToolMessage::ActivateTool { tool_type: ToolType::Artboard }.into()),
|
ToolMessage::ActivateToolArtboard => responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Artboard }),
|
||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
ToolMessage::ActivateToolNavigate => responses.push_front(ToolMessage::ActivateTool { tool_type: ToolType::Navigate }.into()),
|
ToolMessage::ActivateToolNavigate => responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Navigate }),
|
||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
ToolMessage::ActivateToolEyedropper => responses.push_front(ToolMessage::ActivateTool { tool_type: ToolType::Eyedropper }.into()),
|
ToolMessage::ActivateToolEyedropper => responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Eyedropper }),
|
||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
ToolMessage::ActivateToolText => responses.push_front(ToolMessage::ActivateTool { tool_type: ToolType::Text }.into()),
|
ToolMessage::ActivateToolText => responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Text }),
|
||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
ToolMessage::ActivateToolFill => responses.push_front(ToolMessage::ActivateTool { tool_type: ToolType::Fill }.into()),
|
ToolMessage::ActivateToolFill => responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Fill }),
|
||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
ToolMessage::ActivateToolGradient => responses.push_front(ToolMessage::ActivateTool { tool_type: ToolType::Gradient }.into()),
|
ToolMessage::ActivateToolGradient => responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Gradient }),
|
||||||
|
|
||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
ToolMessage::ActivateToolPath => responses.push_front(ToolMessage::ActivateTool { tool_type: ToolType::Path }.into()),
|
ToolMessage::ActivateToolPath => responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Path }),
|
||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
ToolMessage::ActivateToolPen => responses.push_front(ToolMessage::ActivateTool { tool_type: ToolType::Pen }.into()),
|
ToolMessage::ActivateToolPen => responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Pen }),
|
||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
ToolMessage::ActivateToolFreehand => responses.push_front(ToolMessage::ActivateTool { tool_type: ToolType::Freehand }.into()),
|
ToolMessage::ActivateToolFreehand => responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Freehand }),
|
||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
ToolMessage::ActivateToolSpline => responses.push_front(ToolMessage::ActivateTool { tool_type: ToolType::Spline }.into()),
|
ToolMessage::ActivateToolSpline => responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Spline }),
|
||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
ToolMessage::ActivateToolLine => responses.push_front(ToolMessage::ActivateTool { tool_type: ToolType::Line }.into()),
|
ToolMessage::ActivateToolLine => responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Line }),
|
||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
ToolMessage::ActivateToolRectangle => responses.push_front(ToolMessage::ActivateTool { tool_type: ToolType::Rectangle }.into()),
|
ToolMessage::ActivateToolRectangle => responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Rectangle }),
|
||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
ToolMessage::ActivateToolEllipse => responses.push_front(ToolMessage::ActivateTool { tool_type: ToolType::Ellipse }.into()),
|
ToolMessage::ActivateToolEllipse => responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Ellipse }),
|
||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
ToolMessage::ActivateToolShape => responses.push_front(ToolMessage::ActivateTool { tool_type: ToolType::Shape }.into()),
|
ToolMessage::ActivateToolShape => responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Shape }),
|
||||||
|
|
||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
ToolMessage::ActivateToolBrush => responses.push_front(ToolMessage::ActivateTool { tool_type: ToolType::Brush }.into()),
|
ToolMessage::ActivateToolBrush => responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Brush }),
|
||||||
#[remain::unsorted]
|
#[remain::unsorted]
|
||||||
ToolMessage::ActivateToolImaginate => responses.push_front(ToolMessage::ActivateTool { tool_type: ToolType::Imaginate }.into()),
|
ToolMessage::ActivateToolImaginate => responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Imaginate }),
|
||||||
|
|
||||||
ToolMessage::ActivateTool { tool_type } => {
|
ToolMessage::ActivateTool { tool_type } => {
|
||||||
let tool_data = &mut self.tool_state.tool_data;
|
let tool_data = &mut self.tool_state.tool_data;
|
||||||
@@ -122,13 +122,13 @@ impl MessageHandler<ToolMessage, (&DocumentMessageHandler, u64, &InputPreprocess
|
|||||||
tool_data.tools.get(&tool_type).unwrap().activate(responses);
|
tool_data.tools.get(&tool_type).unwrap().activate(responses);
|
||||||
|
|
||||||
// Send the SelectionChanged message to the active tool, this will ensure the selection is updated
|
// Send the SelectionChanged message to the active tool, this will ensure the selection is updated
|
||||||
responses.push_back(BroadcastEvent::SelectionChanged.into());
|
responses.add(BroadcastEvent::SelectionChanged);
|
||||||
|
|
||||||
// Send the DocumentIsDirty message to the active tool's sub-tool message handler
|
// Send the DocumentIsDirty message to the active tool's sub-tool message handler
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
|
|
||||||
// Send tool options to the frontend
|
// Send tool options to the frontend
|
||||||
responses.push_back(ToolMessage::RefreshToolOptions.into());
|
responses.add(ToolMessage::RefreshToolOptions);
|
||||||
|
|
||||||
// Notify the frontend about the new active tool to be displayed
|
// Notify the frontend about the new active tool to be displayed
|
||||||
tool_data.register_properties(responses, LayoutTarget::ToolShelf);
|
tool_data.register_properties(responses, LayoutTarget::ToolShelf);
|
||||||
@@ -140,13 +140,13 @@ impl MessageHandler<ToolMessage, (&DocumentMessageHandler, u64, &InputPreprocess
|
|||||||
// Unsubscribe the transform layer to selection change events
|
// Unsubscribe the transform layer to selection change events
|
||||||
let message = Box::new(TransformLayerMessage::SelectionChanged.into());
|
let message = Box::new(TransformLayerMessage::SelectionChanged.into());
|
||||||
let on = BroadcastEvent::SelectionChanged;
|
let on = BroadcastEvent::SelectionChanged;
|
||||||
responses.push_back(BroadcastMessage::UnsubscribeEvent { message, on }.into());
|
responses.add(BroadcastMessage::UnsubscribeEvent { message, on });
|
||||||
}
|
}
|
||||||
ToolMessage::InitTools => {
|
ToolMessage::InitTools => {
|
||||||
// Subscribe the transform layer to selection change events
|
// Subscribe the transform layer to selection change events
|
||||||
let send = Box::new(TransformLayerMessage::SelectionChanged.into());
|
let send = Box::new(TransformLayerMessage::SelectionChanged.into());
|
||||||
let on = BroadcastEvent::SelectionChanged;
|
let on = BroadcastEvent::SelectionChanged;
|
||||||
responses.push_back(BroadcastMessage::SubscribeEvent { send, on }.into());
|
responses.add(BroadcastMessage::SubscribeEvent { send, on });
|
||||||
|
|
||||||
let tool_data = &mut self.tool_state.tool_data;
|
let tool_data = &mut self.tool_state.tool_data;
|
||||||
let document_data = &self.tool_state.document_tool_data;
|
let document_data = &self.tool_state.document_tool_data;
|
||||||
@@ -163,7 +163,7 @@ impl MessageHandler<ToolMessage, (&DocumentMessageHandler, u64, &InputPreprocess
|
|||||||
|
|
||||||
// Notify the frontend about the initial working colors
|
// Notify the frontend about the initial working colors
|
||||||
document_data.update_working_colors(responses);
|
document_data.update_working_colors(responses);
|
||||||
responses.push_back(FrontendMessage::TriggerRefreshBoundsOfViewports.into());
|
responses.add(FrontendMessage::TriggerRefreshBoundsOfViewports);
|
||||||
|
|
||||||
let mut data = ToolActionHandlerData {
|
let mut data = ToolActionHandlerData {
|
||||||
document,
|
document,
|
||||||
|
|||||||
@@ -132,14 +132,11 @@ impl Fsm for ArtboardToolFsmState {
|
|||||||
|
|
||||||
tool_data.bounding_box_overlays = Some(bounding_box_overlays);
|
tool_data.bounding_box_overlays = Some(bounding_box_overlays);
|
||||||
|
|
||||||
responses.push_back(OverlaysMessage::Rerender.into());
|
responses.add(OverlaysMessage::Rerender);
|
||||||
responses.push_back(
|
responses.add(PropertiesPanelMessage::SetActiveLayers {
|
||||||
PropertiesPanelMessage::SetActiveLayers {
|
paths: vec![vec![tool_data.selected_artboard.unwrap()]],
|
||||||
paths: vec![vec![tool_data.selected_artboard.unwrap()]],
|
document: TargetDocument::Artboard,
|
||||||
document: TargetDocument::Artboard,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
@@ -165,7 +162,7 @@ impl Fsm for ArtboardToolFsmState {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some(selected_edges) = dragging_bounds {
|
if let Some(selected_edges) = dragging_bounds {
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
|
|
||||||
let snap_x = selected_edges.2 || selected_edges.3;
|
let snap_x = selected_edges.2 || selected_edges.3;
|
||||||
let snap_y = selected_edges.0 || selected_edges.1;
|
let snap_y = selected_edges.0 || selected_edges.1;
|
||||||
@@ -185,12 +182,12 @@ impl Fsm for ArtboardToolFsmState {
|
|||||||
|
|
||||||
ArtboardToolFsmState::ResizingBounds
|
ArtboardToolFsmState::ResizingBounds
|
||||||
} else {
|
} else {
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
let tolerance = DVec2::splat(SELECTION_TOLERANCE);
|
let tolerance = DVec2::splat(SELECTION_TOLERANCE);
|
||||||
let quad = Quad::from_box([input.mouse.position - tolerance, input.mouse.position + tolerance]);
|
let quad = Quad::from_box([input.mouse.position - tolerance, input.mouse.position + tolerance]);
|
||||||
let intersection = document.artboard_message_handler.artboards_document.intersects_quad_root(quad, render_data);
|
let intersection = document.artboard_message_handler.artboards_document.intersects_quad_root(quad, render_data);
|
||||||
|
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
if let Some(intersection) = intersection.last() {
|
if let Some(intersection) = intersection.last() {
|
||||||
tool_data.selected_artboard = Some(intersection[0]);
|
tool_data.selected_artboard = Some(intersection[0]);
|
||||||
|
|
||||||
@@ -199,19 +196,16 @@ impl Fsm for ArtboardToolFsmState {
|
|||||||
.start_snap(document, input, document.bounding_boxes(None, Some(intersection[0]), render_data), true, true);
|
.start_snap(document, input, document.bounding_boxes(None, Some(intersection[0]), render_data), true, true);
|
||||||
tool_data.snap_manager.add_all_document_handles(document, input, &[], &[], &[]);
|
tool_data.snap_manager.add_all_document_handles(document, input, &[], &[], &[]);
|
||||||
|
|
||||||
responses.push_back(
|
responses.add(PropertiesPanelMessage::SetActiveLayers {
|
||||||
PropertiesPanelMessage::SetActiveLayers {
|
paths: vec![intersection.clone()],
|
||||||
paths: vec![intersection.clone()],
|
document: TargetDocument::Artboard,
|
||||||
document: TargetDocument::Artboard,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
|
|
||||||
ArtboardToolFsmState::Dragging
|
ArtboardToolFsmState::Dragging
|
||||||
} else {
|
} else {
|
||||||
tool_data.selected_artboard = None;
|
tool_data.selected_artboard = None;
|
||||||
|
|
||||||
responses.push_back(PropertiesPanelMessage::ClearSelection.into());
|
responses.add(PropertiesPanelMessage::ClearSelection);
|
||||||
|
|
||||||
ArtboardToolFsmState::Drawing
|
ArtboardToolFsmState::Drawing
|
||||||
}
|
}
|
||||||
@@ -227,16 +221,13 @@ impl Fsm for ArtboardToolFsmState {
|
|||||||
let snapped_mouse_position = tool_data.snap_manager.snap_position(responses, document, mouse_position);
|
let snapped_mouse_position = tool_data.snap_manager.snap_position(responses, document, mouse_position);
|
||||||
|
|
||||||
let (position, size) = movement.new_size(snapped_mouse_position, bounds.transform, from_center, bounds.center_of_transformation, constrain_square);
|
let (position, size) = movement.new_size(snapped_mouse_position, bounds.transform, from_center, bounds.center_of_transformation, constrain_square);
|
||||||
responses.push_back(
|
responses.add(ArtboardMessage::ResizeArtboard {
|
||||||
ArtboardMessage::ResizeArtboard {
|
artboard: tool_data.selected_artboard.unwrap(),
|
||||||
artboard: tool_data.selected_artboard.unwrap(),
|
position: position.round().into(),
|
||||||
position: position.round().into(),
|
size: size.round().into(),
|
||||||
size: size.round().into(),
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
|
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ArtboardToolFsmState::ResizingBounds
|
ArtboardToolFsmState::ResizingBounds
|
||||||
@@ -255,16 +246,13 @@ impl Fsm for ArtboardToolFsmState {
|
|||||||
|
|
||||||
let position = bounds.bounds[0] + bounds.transform.inverse().transform_vector2(mouse_position - tool_data.drag_current + closest_move);
|
let position = bounds.bounds[0] + bounds.transform.inverse().transform_vector2(mouse_position - tool_data.drag_current + closest_move);
|
||||||
|
|
||||||
responses.push_back(
|
responses.add(ArtboardMessage::ResizeArtboard {
|
||||||
ArtboardMessage::ResizeArtboard {
|
artboard: tool_data.selected_artboard.unwrap(),
|
||||||
artboard: tool_data.selected_artboard.unwrap(),
|
position: position.round().into(),
|
||||||
position: position.round().into(),
|
size: size.round().into(),
|
||||||
size: size.round().into(),
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
|
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
|
|
||||||
tool_data.drag_current = mouse_position + closest_move;
|
tool_data.drag_current = mouse_position + closest_move;
|
||||||
}
|
}
|
||||||
@@ -292,14 +280,11 @@ impl Fsm for ArtboardToolFsmState {
|
|||||||
let size = root_transform.transform_vector2(size);
|
let size = root_transform.transform_vector2(size);
|
||||||
|
|
||||||
if let Some(artboard) = tool_data.selected_artboard {
|
if let Some(artboard) = tool_data.selected_artboard {
|
||||||
responses.push_back(
|
responses.add(ArtboardMessage::ResizeArtboard {
|
||||||
ArtboardMessage::ResizeArtboard {
|
artboard,
|
||||||
artboard,
|
position: start.round().into(),
|
||||||
position: start.round().into(),
|
size: size.round().into(),
|
||||||
size: size.round().into(),
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
let id = generate_uuid();
|
let id = generate_uuid();
|
||||||
tool_data.selected_artboard = Some(id);
|
tool_data.selected_artboard = Some(id);
|
||||||
@@ -307,27 +292,21 @@ impl Fsm for ArtboardToolFsmState {
|
|||||||
tool_data.snap_manager.start_snap(document, input, document.bounding_boxes(None, Some(id), render_data), true, true);
|
tool_data.snap_manager.start_snap(document, input, document.bounding_boxes(None, Some(id), render_data), true, true);
|
||||||
tool_data.snap_manager.add_all_document_handles(document, input, &[], &[], &[]);
|
tool_data.snap_manager.add_all_document_handles(document, input, &[], &[], &[]);
|
||||||
|
|
||||||
responses.push_back(
|
responses.add(ArtboardMessage::AddArtboard {
|
||||||
ArtboardMessage::AddArtboard {
|
id: Some(id),
|
||||||
id: Some(id),
|
position: start.round().into(),
|
||||||
position: start.round().into(),
|
size: (1., 1.),
|
||||||
size: (1., 1.),
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Have to put message here instead of when Artboard is created
|
// Have to put message here instead of when Artboard is created
|
||||||
// This might result in a few more calls but it is not reliant on the order of messages
|
// This might result in a few more calls but it is not reliant on the order of messages
|
||||||
responses.push_back(
|
responses.add(PropertiesPanelMessage::SetActiveLayers {
|
||||||
PropertiesPanelMessage::SetActiveLayers {
|
paths: vec![vec![tool_data.selected_artboard.unwrap()]],
|
||||||
paths: vec![vec![tool_data.selected_artboard.unwrap()]],
|
document: TargetDocument::Artboard,
|
||||||
document: TargetDocument::Artboard,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
|
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
|
|
||||||
ArtboardToolFsmState::Drawing
|
ArtboardToolFsmState::Drawing
|
||||||
}
|
}
|
||||||
@@ -336,7 +315,7 @@ impl Fsm for ArtboardToolFsmState {
|
|||||||
|
|
||||||
if tool_data.cursor != cursor {
|
if tool_data.cursor != cursor {
|
||||||
tool_data.cursor = cursor;
|
tool_data.cursor = cursor;
|
||||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor }.into());
|
responses.add(FrontendMessage::UpdateMouseCursor { cursor });
|
||||||
}
|
}
|
||||||
|
|
||||||
ArtboardToolFsmState::Ready
|
ArtboardToolFsmState::Ready
|
||||||
@@ -357,7 +336,7 @@ impl Fsm for ArtboardToolFsmState {
|
|||||||
bounds.original_transforms.clear();
|
bounds.original_transforms.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
|
|
||||||
ArtboardToolFsmState::Ready
|
ArtboardToolFsmState::Ready
|
||||||
}
|
}
|
||||||
@@ -372,21 +351,18 @@ impl Fsm for ArtboardToolFsmState {
|
|||||||
}
|
}
|
||||||
(_, ArtboardToolMessage::DeleteSelected) => {
|
(_, ArtboardToolMessage::DeleteSelected) => {
|
||||||
if let Some(artboard) = tool_data.selected_artboard.take() {
|
if let Some(artboard) = tool_data.selected_artboard.take() {
|
||||||
responses.push_back(ArtboardMessage::DeleteArtboard { artboard }.into());
|
responses.add(ArtboardMessage::DeleteArtboard { artboard });
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
}
|
}
|
||||||
ArtboardToolFsmState::Ready
|
ArtboardToolFsmState::Ready
|
||||||
}
|
}
|
||||||
(_, ArtboardToolMessage::NudgeSelected { delta_x, delta_y }) => {
|
(_, ArtboardToolMessage::NudgeSelected { delta_x, delta_y }) => {
|
||||||
if let Some(bounds) = &mut tool_data.bounding_box_overlays {
|
if let Some(bounds) = &mut tool_data.bounding_box_overlays {
|
||||||
responses.push_back(
|
responses.add(ArtboardMessage::ResizeArtboard {
|
||||||
ArtboardMessage::ResizeArtboard {
|
artboard: tool_data.selected_artboard.unwrap(),
|
||||||
artboard: tool_data.selected_artboard.unwrap(),
|
position: (bounds.bounds[0].x + delta_x, bounds.bounds[0].y + delta_y),
|
||||||
position: (bounds.bounds[0].x + delta_x, bounds.bounds[0].y + delta_y),
|
size: (bounds.bounds[1] - bounds.bounds[0]).round().into(),
|
||||||
size: (bounds.bounds[1] - bounds.bounds[0]).round().into(),
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ArtboardToolFsmState::Ready
|
ArtboardToolFsmState::Ready
|
||||||
@@ -397,13 +373,10 @@ impl Fsm for ArtboardToolFsmState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Register properties when switching back to other tools
|
// Register properties when switching back to other tools
|
||||||
responses.push_back(
|
responses.add(PropertiesPanelMessage::SetActiveLayers {
|
||||||
PropertiesPanelMessage::SetActiveLayers {
|
paths: document.selected_layers().map(|path| path.to_vec()).collect(),
|
||||||
paths: document.selected_layers().map(|path| path.to_vec()).collect(),
|
document: TargetDocument::Artwork,
|
||||||
document: TargetDocument::Artwork,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
|
|
||||||
tool_data.snap_manager.cleanup(responses);
|
tool_data.snap_manager.cleanup(responses);
|
||||||
ArtboardToolFsmState::Ready
|
ArtboardToolFsmState::Ready
|
||||||
@@ -428,10 +401,10 @@ impl Fsm for ArtboardToolFsmState {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
responses.add(FrontendMessage::UpdateInputHints { hint_data });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
||||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Default }.into());
|
responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Default });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -215,14 +215,14 @@ impl Fsm for BrushToolFsmState {
|
|||||||
if let ToolMessage::Brush(event) = event {
|
if let ToolMessage::Brush(event) = event {
|
||||||
match (self, event) {
|
match (self, event) {
|
||||||
(Ready, DragStart) => {
|
(Ready, DragStart) => {
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
let existing_points = load_existing_points(document);
|
let existing_points = load_existing_points(document);
|
||||||
let new_layer = existing_points.is_none();
|
let new_layer = existing_points.is_none();
|
||||||
if let Some((layer_path, points)) = existing_points {
|
if let Some((layer_path, points)) = existing_points {
|
||||||
tool_data.path = Some(layer_path);
|
tool_data.path = Some(layer_path);
|
||||||
tool_data.points = points;
|
tool_data.points = points;
|
||||||
} else {
|
} else {
|
||||||
responses.push_back(DocumentMessage::DeselectAllLayers.into());
|
responses.add(DocumentMessage::DeselectAllLayers);
|
||||||
tool_data.path = Some(document.get_path_for_new_layer());
|
tool_data.path = Some(document.get_path_for_new_layer());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,9 +262,9 @@ impl Fsm for BrushToolFsmState {
|
|||||||
}
|
}
|
||||||
(Drawing, DragStop) | (Drawing, Abort) => {
|
(Drawing, DragStop) | (Drawing, Abort) => {
|
||||||
if !tool_data.points.is_empty() {
|
if !tool_data.points.is_empty() {
|
||||||
responses.push_back(DocumentMessage::CommitTransaction.into());
|
responses.add(DocumentMessage::CommitTransaction);
|
||||||
} else {
|
} else {
|
||||||
responses.push_back(DocumentMessage::AbortTransaction.into());
|
responses.add(DocumentMessage::AbortTransaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
tool_data.path = None;
|
tool_data.path = None;
|
||||||
@@ -285,11 +285,11 @@ impl Fsm for BrushToolFsmState {
|
|||||||
BrushToolFsmState::Drawing => HintData(vec![]),
|
BrushToolFsmState::Drawing => HintData(vec![]),
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
responses.add(FrontendMessage::UpdateInputHints { hint_data });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
||||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Default }.into());
|
responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Default });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ impl Fsm for EllipseToolFsmState {
|
|||||||
match (self, event) {
|
match (self, event) {
|
||||||
(Ready, DragStart) => {
|
(Ready, DragStart) => {
|
||||||
shape_data.start(responses, document, input, render_data);
|
shape_data.start(responses, document, input, render_data);
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
|
|
||||||
// Create a new layer path for this shape
|
// Create a new layer path for this shape
|
||||||
let layer_path = document.get_path_for_new_layer();
|
let layer_path = document.get_path_for_new_layer();
|
||||||
@@ -141,7 +141,7 @@ impl Fsm for EllipseToolFsmState {
|
|||||||
}
|
}
|
||||||
(state, Resize { center, lock_ratio }) => {
|
(state, Resize { center, lock_ratio }) => {
|
||||||
if let Some(message) = shape_data.calculate_transform(responses, document, input, center, lock_ratio, false) {
|
if let Some(message) = shape_data.calculate_transform(responses, document, input, center, lock_ratio, false) {
|
||||||
responses.push_back(message);
|
responses.add(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
state
|
state
|
||||||
@@ -153,7 +153,7 @@ impl Fsm for EllipseToolFsmState {
|
|||||||
Ready
|
Ready
|
||||||
}
|
}
|
||||||
(Drawing, Abort) => {
|
(Drawing, Abort) => {
|
||||||
responses.push_back(DocumentMessage::AbortTransaction.into());
|
responses.add(DocumentMessage::AbortTransaction);
|
||||||
shape_data.cleanup(responses);
|
shape_data.cleanup(responses);
|
||||||
|
|
||||||
Ready
|
Ready
|
||||||
@@ -175,10 +175,10 @@ impl Fsm for EllipseToolFsmState {
|
|||||||
EllipseToolFsmState::Drawing => HintData(vec![HintGroup(vec![HintInfo::keys([Key::Shift], "Constrain Circular"), HintInfo::keys([Key::Alt], "From Center")])]),
|
EllipseToolFsmState::Drawing => HintData(vec![HintGroup(vec![HintInfo::keys([Key::Shift], "Constrain Circular"), HintInfo::keys([Key::Alt], "From Center")])]),
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
responses.add(FrontendMessage::UpdateInputHints { hint_data });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
||||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Crosshair }.into());
|
responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Crosshair });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ impl Fsm for EyedropperToolFsmState {
|
|||||||
EyedropperToolFsmState::SamplingPrimary | EyedropperToolFsmState::SamplingSecondary => HintData(vec![HintGroup(vec![HintInfo::keys([Key::Escape], "Cancel")])]),
|
EyedropperToolFsmState::SamplingPrimary | EyedropperToolFsmState::SamplingSecondary => HintData(vec![HintGroup(vec![HintInfo::keys([Key::Escape], "Cancel")])]),
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
responses.add(FrontendMessage::UpdateInputHints { hint_data });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
||||||
@@ -156,30 +156,24 @@ impl Fsm for EyedropperToolFsmState {
|
|||||||
EyedropperToolFsmState::SamplingPrimary | EyedropperToolFsmState::SamplingSecondary => MouseCursorIcon::None,
|
EyedropperToolFsmState::SamplingPrimary | EyedropperToolFsmState::SamplingSecondary => MouseCursorIcon::None,
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor }.into());
|
responses.add(FrontendMessage::UpdateMouseCursor { cursor });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn disable_cursor_preview(responses: &mut VecDeque<Message>) {
|
fn disable_cursor_preview(responses: &mut VecDeque<Message>) {
|
||||||
responses.push_back(
|
responses.add(FrontendMessage::UpdateEyedropperSamplingState {
|
||||||
FrontendMessage::UpdateEyedropperSamplingState {
|
mouse_position: None,
|
||||||
mouse_position: None,
|
primary_color: "".into(),
|
||||||
primary_color: "".into(),
|
secondary_color: "".into(),
|
||||||
secondary_color: "".into(),
|
set_color_choice: None,
|
||||||
set_color_choice: None,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_cursor_preview(responses: &mut VecDeque<Message>, input: &InputPreprocessorMessageHandler, global_tool_data: &DocumentToolData, set_color_choice: Option<String>) {
|
fn update_cursor_preview(responses: &mut VecDeque<Message>, input: &InputPreprocessorMessageHandler, global_tool_data: &DocumentToolData, set_color_choice: Option<String>) {
|
||||||
responses.push_back(
|
responses.add(FrontendMessage::UpdateEyedropperSamplingState {
|
||||||
FrontendMessage::UpdateEyedropperSamplingState {
|
mouse_position: Some(input.mouse.position.into()),
|
||||||
mouse_position: Some(input.mouse.position.into()),
|
primary_color: "#".to_string() + global_tool_data.primary_color.rgb_hex().as_str(),
|
||||||
primary_color: "#".to_string() + global_tool_data.primary_color.rgb_hex().as_str(),
|
secondary_color: "#".to_string() + global_tool_data.secondary_color.rgb_hex().as_str(),
|
||||||
secondary_color: "#".to_string() + global_tool_data.secondary_color.rgb_hex().as_str(),
|
set_color_choice,
|
||||||
set_color_choice,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -136,10 +136,10 @@ impl Fsm for FillToolFsmState {
|
|||||||
])]),
|
])]),
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
responses.add(FrontendMessage::UpdateInputHints { hint_data });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
||||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Default }.into());
|
responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Default });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,8 +152,8 @@ impl Fsm for FreehandToolFsmState {
|
|||||||
if let ToolMessage::Freehand(event) = event {
|
if let ToolMessage::Freehand(event) = event {
|
||||||
match (self, event) {
|
match (self, event) {
|
||||||
(Ready, DragStart) => {
|
(Ready, DragStart) => {
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
responses.push_back(DocumentMessage::DeselectAllLayers.into());
|
responses.add(DocumentMessage::DeselectAllLayers);
|
||||||
tool_data.path = Some(document.get_path_for_new_layer());
|
tool_data.path = Some(document.get_path_for_new_layer());
|
||||||
|
|
||||||
let pos = transform.inverse().transform_point2(input.mouse.position);
|
let pos = transform.inverse().transform_point2(input.mouse.position);
|
||||||
@@ -179,11 +179,11 @@ impl Fsm for FreehandToolFsmState {
|
|||||||
}
|
}
|
||||||
(Drawing, DragStop) | (Drawing, Abort) => {
|
(Drawing, DragStop) | (Drawing, Abort) => {
|
||||||
if tool_data.points.len() >= 2 {
|
if tool_data.points.len() >= 2 {
|
||||||
responses.push_back(remove_preview(tool_data));
|
responses.add(remove_preview(tool_data));
|
||||||
add_polyline(tool_data, global_tool_data, responses);
|
add_polyline(tool_data, global_tool_data, responses);
|
||||||
responses.push_back(DocumentMessage::CommitTransaction.into());
|
responses.add(DocumentMessage::CommitTransaction);
|
||||||
} else {
|
} else {
|
||||||
responses.push_back(DocumentMessage::AbortTransaction.into());
|
responses.add(DocumentMessage::AbortTransaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
tool_data.path = None;
|
tool_data.path = None;
|
||||||
@@ -204,11 +204,11 @@ impl Fsm for FreehandToolFsmState {
|
|||||||
FreehandToolFsmState::Drawing => HintData(vec![]),
|
FreehandToolFsmState::Drawing => HintData(vec![]),
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
responses.add(FrontendMessage::UpdateInputHints { hint_data });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
||||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Default }.into());
|
responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Default });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ impl GradientOverlay {
|
|||||||
style: PathStyle::new(Some(Stroke::new(COLOR_ACCENT, 1.0)), fill),
|
style: PathStyle::new(Some(Stroke::new(COLOR_ACCENT, 1.0)), fill),
|
||||||
insert_index: -1,
|
insert_index: -1,
|
||||||
};
|
};
|
||||||
responses.push_back(DocumentMessage::Overlays(operation.into()).into());
|
responses.add(DocumentMessage::Overlays(operation.into()));
|
||||||
|
|
||||||
path
|
path
|
||||||
}
|
}
|
||||||
@@ -182,7 +182,7 @@ impl GradientOverlay {
|
|||||||
style: PathStyle::new(Some(Stroke::new(COLOR_ACCENT, 1.0)), Fill::None),
|
style: PathStyle::new(Some(Stroke::new(COLOR_ACCENT, 1.0)), Fill::None),
|
||||||
insert_index: -1,
|
insert_index: -1,
|
||||||
};
|
};
|
||||||
responses.push_back(DocumentMessage::Overlays(operation.into()).into());
|
responses.add(DocumentMessage::Overlays(operation.into()));
|
||||||
|
|
||||||
path
|
path
|
||||||
}
|
}
|
||||||
@@ -224,12 +224,12 @@ impl GradientOverlay {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_overlays(self, responses: &mut VecDeque<Message>) {
|
pub fn delete_overlays(self, responses: &mut VecDeque<Message>) {
|
||||||
responses.push_back(DocumentMessage::Overlays(Operation::DeleteLayer { path: self.line }.into()).into());
|
responses.add(DocumentMessage::Overlays(Operation::DeleteLayer { path: self.line }.into()));
|
||||||
let [start, end] = self.handles;
|
let [start, end] = self.handles;
|
||||||
responses.push_back(DocumentMessage::Overlays(Operation::DeleteLayer { path: start }.into()).into());
|
responses.add(DocumentMessage::Overlays(Operation::DeleteLayer { path: start }.into()));
|
||||||
responses.push_back(DocumentMessage::Overlays(Operation::DeleteLayer { path: end }.into()).into());
|
responses.add(DocumentMessage::Overlays(Operation::DeleteLayer { path: end }.into()));
|
||||||
for step in self.steps {
|
for step in self.steps {
|
||||||
responses.push_back(DocumentMessage::Overlays(Operation::DeleteLayer { path: step }.into()).into());
|
responses.add(DocumentMessage::Overlays(Operation::DeleteLayer { path: step }.into()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,7 +278,7 @@ impl SelectedGradient {
|
|||||||
|
|
||||||
// Clear the gradient if layer deleted
|
// Clear the gradient if layer deleted
|
||||||
let Ok(layer) = document.document_legacy.layer(&inner_gradient.path) else {
|
let Ok(layer) = document.document_legacy.layer(&inner_gradient.path) else {
|
||||||
responses.push_back(ToolMessage::RefreshToolOptions.into());
|
responses.add(ToolMessage::RefreshToolOptions);
|
||||||
*gradient = None;
|
*gradient = None;
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
@@ -288,13 +288,13 @@ impl SelectedGradient {
|
|||||||
|
|
||||||
// Clear if no longer a gradient
|
// Clear if no longer a gradient
|
||||||
let Some(gradient) = layer.style().ok().and_then(|style|style.fill().as_gradient()) else {
|
let Some(gradient) = layer.style().ok().and_then(|style|style.fill().as_gradient()) else {
|
||||||
responses.push_back(ToolMessage::RefreshToolOptions.into());
|
responses.add(ToolMessage::RefreshToolOptions);
|
||||||
*gradient = None;
|
*gradient = None;
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
if gradient.gradient_type != inner_gradient.gradient.gradient_type {
|
if gradient.gradient_type != inner_gradient.gradient.gradient_type {
|
||||||
responses.push_back(ToolMessage::RefreshToolOptions.into());
|
responses.add(ToolMessage::RefreshToolOptions);
|
||||||
}
|
}
|
||||||
inner_gradient.gradient = gradient.clone();
|
inner_gradient.gradient = gradient.clone();
|
||||||
}
|
}
|
||||||
@@ -519,7 +519,7 @@ impl Fsm for GradientToolFsmState {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
(GradientToolFsmState::Ready, GradientToolMessage::PointerDown) => {
|
(GradientToolFsmState::Ready, GradientToolMessage::PointerDown) => {
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
|
|
||||||
let mouse = input.mouse.position;
|
let mouse = input.mouse.position;
|
||||||
tool_data.drag_start = mouse;
|
tool_data.drag_start = mouse;
|
||||||
@@ -570,12 +570,12 @@ impl Fsm for GradientToolFsmState {
|
|||||||
if !document.selected_layers_contains(&intersection) {
|
if !document.selected_layers_contains(&intersection) {
|
||||||
let replacement_selected_layers = vec![intersection.clone()];
|
let replacement_selected_layers = vec![intersection.clone()];
|
||||||
|
|
||||||
responses.push_back(DocumentMessage::SetSelectedLayers { replacement_selected_layers }.into());
|
responses.add(DocumentMessage::SetSelectedLayers { replacement_selected_layers });
|
||||||
}
|
}
|
||||||
|
|
||||||
let layer = document.document_legacy.layer(&intersection).unwrap();
|
let layer = document.document_legacy.layer(&intersection).unwrap();
|
||||||
|
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
|
|
||||||
// Use the already existing gradient if it exists
|
// Use the already existing gradient if it exists
|
||||||
let gradient = if let Some(gradient) = layer.style().ok().map(|style| style.fill()).and_then(|fill| fill.as_gradient()) {
|
let gradient = if let Some(gradient) = layer.style().ok().map(|style| style.fill()).and_then(|fill| fill.as_gradient()) {
|
||||||
@@ -643,10 +643,10 @@ impl Fsm for GradientToolFsmState {
|
|||||||
GradientToolFsmState::Drawing => HintData(vec![HintGroup(vec![HintInfo::keys([Key::Shift], "Snap 15°")])]),
|
GradientToolFsmState::Drawing => HintData(vec![HintGroup(vec![HintInfo::keys([Key::Shift], "Snap 15°")])]),
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
responses.add(FrontendMessage::UpdateInputHints { hint_data });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
||||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Default }.into());
|
responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Default });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ impl PropertyHolder for LineTool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for LineTool {
|
impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for LineTool {
|
||||||
fn process_message(&mut self, message: ToolMessage, messages: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
||||||
if let ToolMessage::Line(LineToolMessage::UpdateOptions(action)) = message {
|
if let ToolMessage::Line(LineToolMessage::UpdateOptions(action)) = message {
|
||||||
match action {
|
match action {
|
||||||
LineOptionsUpdate::LineWeight(line_weight) => self.options.line_weight = line_weight,
|
LineOptionsUpdate::LineWeight(line_weight) => self.options.line_weight = line_weight,
|
||||||
@@ -91,7 +91,7 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for LineToo
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.fsm_state.process_event(message, &mut self.tool_data, tool_data, &self.options, messages, true);
|
self.fsm_state.process_event(message, &mut self.tool_data, tool_data, &self.options, responses, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn actions(&self) -> ActionList {
|
fn actions(&self) -> ActionList {
|
||||||
@@ -159,7 +159,7 @@ impl Fsm for LineToolFsmState {
|
|||||||
|
|
||||||
let subpath = bezier_rs::Subpath::new_line(DVec2::ZERO, DVec2::X);
|
let subpath = bezier_rs::Subpath::new_line(DVec2::ZERO, DVec2::X);
|
||||||
|
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
let layer_path = document.get_path_for_new_layer();
|
let layer_path = document.get_path_for_new_layer();
|
||||||
tool_data.path = Some(layer_path.clone());
|
tool_data.path = Some(layer_path.clone());
|
||||||
graph_modification_utils::new_vector_layer(vec![subpath], layer_path.clone(), responses);
|
graph_modification_utils::new_vector_layer(vec![subpath], layer_path.clone(), responses);
|
||||||
@@ -176,7 +176,7 @@ impl Fsm for LineToolFsmState {
|
|||||||
tool_data.drag_current = tool_data.snap_manager.snap_position(responses, document, input.mouse.position);
|
tool_data.drag_current = tool_data.snap_manager.snap_position(responses, document, input.mouse.position);
|
||||||
|
|
||||||
let keyboard = &input.keyboard;
|
let keyboard = &input.keyboard;
|
||||||
responses.push_back(generate_transform(tool_data, keyboard.key(lock_angle), keyboard.key(snap_angle), keyboard.key(center)));
|
responses.add(generate_transform(tool_data, keyboard.key(lock_angle), keyboard.key(snap_angle), keyboard.key(center)));
|
||||||
|
|
||||||
Drawing
|
Drawing
|
||||||
}
|
}
|
||||||
@@ -189,7 +189,7 @@ impl Fsm for LineToolFsmState {
|
|||||||
}
|
}
|
||||||
(Drawing, Abort) => {
|
(Drawing, Abort) => {
|
||||||
tool_data.snap_manager.cleanup(responses);
|
tool_data.snap_manager.cleanup(responses);
|
||||||
responses.push_back(DocumentMessage::AbortTransaction.into());
|
responses.add(DocumentMessage::AbortTransaction);
|
||||||
tool_data.path = None;
|
tool_data.path = None;
|
||||||
Ready
|
Ready
|
||||||
}
|
}
|
||||||
@@ -215,11 +215,11 @@ impl Fsm for LineToolFsmState {
|
|||||||
])]),
|
])]),
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
responses.add(FrontendMessage::UpdateInputHints { hint_data });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
||||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Crosshair }.into());
|
responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Crosshair });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -107,59 +107,56 @@ impl Fsm for NavigateToolFsmState {
|
|||||||
tool_data: &mut Self::ToolData,
|
tool_data: &mut Self::ToolData,
|
||||||
ToolActionHandlerData { input, .. }: &mut ToolActionHandlerData,
|
ToolActionHandlerData { input, .. }: &mut ToolActionHandlerData,
|
||||||
_tool_options: &Self::ToolOptions,
|
_tool_options: &Self::ToolOptions,
|
||||||
messages: &mut VecDeque<Message>,
|
responses: &mut VecDeque<Message>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
if let ToolMessage::Navigate(navigate) = message {
|
if let ToolMessage::Navigate(navigate) = message {
|
||||||
use NavigateToolMessage::*;
|
use NavigateToolMessage::*;
|
||||||
|
|
||||||
match navigate {
|
match navigate {
|
||||||
ClickZoom { zoom_in } => {
|
ClickZoom { zoom_in } => {
|
||||||
messages.push_front(NavigationMessage::TransformCanvasEnd.into());
|
responses.add_front(NavigationMessage::TransformCanvasEnd);
|
||||||
|
|
||||||
// Mouse has not moved from pointerdown to pointerup
|
// Mouse has not moved from pointerdown to pointerup
|
||||||
if tool_data.drag_start == input.mouse.position {
|
if tool_data.drag_start == input.mouse.position {
|
||||||
messages.push_front(if zoom_in {
|
responses.add_front(if zoom_in {
|
||||||
NavigationMessage::IncreaseCanvasZoom { center_on_mouse: true }.into()
|
NavigationMessage::IncreaseCanvasZoom { center_on_mouse: true }
|
||||||
} else {
|
} else {
|
||||||
NavigationMessage::DecreaseCanvasZoom { center_on_mouse: true }.into()
|
NavigationMessage::DecreaseCanvasZoom { center_on_mouse: true }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
NavigateToolFsmState::Ready
|
NavigateToolFsmState::Ready
|
||||||
}
|
}
|
||||||
PointerMove { snap_angle, snap_zoom } => {
|
PointerMove { snap_angle, snap_zoom } => {
|
||||||
messages.push_front(
|
responses.add_front(NavigationMessage::PointerMove {
|
||||||
NavigationMessage::PointerMove {
|
snap_angle,
|
||||||
snap_angle,
|
wait_for_snap_angle_release: false,
|
||||||
wait_for_snap_angle_release: false,
|
snap_zoom,
|
||||||
snap_zoom,
|
zoom_from_viewport: Some(tool_data.drag_start),
|
||||||
zoom_from_viewport: Some(tool_data.drag_start),
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
TranslateCanvasBegin => {
|
TranslateCanvasBegin => {
|
||||||
tool_data.drag_start = input.mouse.position;
|
tool_data.drag_start = input.mouse.position;
|
||||||
messages.push_front(NavigationMessage::TranslateCanvasBegin.into());
|
responses.add_front(NavigationMessage::TranslateCanvasBegin);
|
||||||
NavigateToolFsmState::Panning
|
NavigateToolFsmState::Panning
|
||||||
}
|
}
|
||||||
RotateCanvasBegin => {
|
RotateCanvasBegin => {
|
||||||
tool_data.drag_start = input.mouse.position;
|
tool_data.drag_start = input.mouse.position;
|
||||||
messages.push_front(NavigationMessage::RotateCanvasBegin.into());
|
responses.add_front(NavigationMessage::RotateCanvasBegin);
|
||||||
NavigateToolFsmState::Tilting
|
NavigateToolFsmState::Tilting
|
||||||
}
|
}
|
||||||
ZoomCanvasBegin => {
|
ZoomCanvasBegin => {
|
||||||
tool_data.drag_start = input.mouse.position;
|
tool_data.drag_start = input.mouse.position;
|
||||||
messages.push_front(NavigationMessage::ZoomCanvasBegin.into());
|
responses.add_front(NavigationMessage::ZoomCanvasBegin);
|
||||||
NavigateToolFsmState::Zooming
|
NavigateToolFsmState::Zooming
|
||||||
}
|
}
|
||||||
TransformCanvasEnd => {
|
TransformCanvasEnd => {
|
||||||
messages.push_front(NavigationMessage::TransformCanvasEnd.into());
|
responses.add_front(NavigationMessage::TransformCanvasEnd);
|
||||||
NavigateToolFsmState::Ready
|
NavigateToolFsmState::Ready
|
||||||
}
|
}
|
||||||
Abort => {
|
Abort => {
|
||||||
messages.push_front(NavigationMessage::TransformCanvasEnd.into());
|
responses.add_front(NavigationMessage::TransformCanvasEnd);
|
||||||
NavigateToolFsmState::Ready
|
NavigateToolFsmState::Ready
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -181,7 +178,7 @@ impl Fsm for NavigateToolFsmState {
|
|||||||
_ => HintData(Vec::new()),
|
_ => HintData(Vec::new()),
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
responses.add(FrontendMessage::UpdateInputHints { hint_data });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
||||||
@@ -192,6 +189,6 @@ impl Fsm for NavigateToolFsmState {
|
|||||||
NavigateToolFsmState::Zooming => MouseCursorIcon::ZoomIn,
|
NavigateToolFsmState::Zooming => MouseCursorIcon::ZoomIn,
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor }.into());
|
responses.add(FrontendMessage::UpdateMouseCursor { cursor });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ impl Fsm for PathToolFsmState {
|
|||||||
|
|
||||||
// Select the first point within the threshold (in pixels)
|
// Select the first point within the threshold (in pixels)
|
||||||
if let Some(mut selected_points) = shape_editor.select_point(&document.document_legacy, input.mouse.position, SELECTION_THRESHOLD, shift_pressed) {
|
if let Some(mut selected_points) = shape_editor.select_point(&document.document_legacy, input.mouse.position, SELECTION_THRESHOLD, shift_pressed) {
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
|
|
||||||
tool_data
|
tool_data
|
||||||
.snap_manager
|
.snap_manager
|
||||||
@@ -224,16 +224,13 @@ impl Fsm for PathToolFsmState {
|
|||||||
.intersects_quad_root(Quad::from_box([input.mouse.position - selection_size, input.mouse.position + selection_size]), render_data);
|
.intersects_quad_root(Quad::from_box([input.mouse.position - selection_size, input.mouse.position + selection_size]), render_data);
|
||||||
if !intersection.is_empty() {
|
if !intersection.is_empty() {
|
||||||
if shift_pressed {
|
if shift_pressed {
|
||||||
responses.push_back(DocumentMessage::AddSelectedLayers { additional_layers: intersection }.into());
|
responses.add(DocumentMessage::AddSelectedLayers { additional_layers: intersection });
|
||||||
} else {
|
} else {
|
||||||
// Selects the topmost layer when selecting intersecting shapes
|
// Selects the topmost layer when selecting intersecting shapes
|
||||||
let top_most_intersection = intersection[intersection.len() - 1].clone();
|
let top_most_intersection = intersection[intersection.len() - 1].clone();
|
||||||
responses.push_back(
|
responses.add(DocumentMessage::SetSelectedLayers {
|
||||||
DocumentMessage::SetSelectedLayers {
|
replacement_selected_layers: vec![top_most_intersection.clone()],
|
||||||
replacement_selected_layers: vec![top_most_intersection.clone()],
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
tool_data.drag_start_pos = input.mouse.position;
|
tool_data.drag_start_pos = input.mouse.position;
|
||||||
tool_data.previous_mouse_position = input.mouse.position;
|
tool_data.previous_mouse_position = input.mouse.position;
|
||||||
// Selects all the anchor points when clicking in a filled area of shape. If two shapes intersect we pick the topmost layer.
|
// Selects all the anchor points when clicking in a filled area of shape. If two shapes intersect we pick the topmost layer.
|
||||||
@@ -243,7 +240,7 @@ impl Fsm for PathToolFsmState {
|
|||||||
} else {
|
} else {
|
||||||
// Clear the previous selection if we didn't find anything
|
// Clear the previous selection if we didn't find anything
|
||||||
if !input.keyboard.get(shift_pressed as usize) {
|
if !input.keyboard.get(shift_pressed as usize) {
|
||||||
responses.push_back(DocumentMessage::DeselectAllLayers.into());
|
responses.add(DocumentMessage::DeselectAllLayers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,9 +309,9 @@ impl Fsm for PathToolFsmState {
|
|||||||
// Delete key
|
// Delete key
|
||||||
(_, PathToolMessage::Delete) => {
|
(_, PathToolMessage::Delete) => {
|
||||||
// Delete the selected points and clean up overlays
|
// Delete the selected points and clean up overlays
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
shape_editor.delete_selected_points(responses);
|
shape_editor.delete_selected_points(responses);
|
||||||
responses.push_back(PathToolMessage::SelectionChanged.into());
|
responses.add(PathToolMessage::SelectionChanged);
|
||||||
for layer_path in document.all_layers() {
|
for layer_path in document.all_layers() {
|
||||||
shape_overlay.clear_subpath_overlays(&document.document_legacy, layer_path.to_vec(), responses);
|
shape_overlay.clear_subpath_overlays(&document.document_legacy, layer_path.to_vec(), responses);
|
||||||
}
|
}
|
||||||
@@ -367,10 +364,10 @@ impl Fsm for PathToolFsmState {
|
|||||||
])]),
|
])]),
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
responses.add(FrontendMessage::UpdateInputHints { hint_data });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
||||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Default }.into());
|
responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Default });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ impl PenToolData {
|
|||||||
modification: VectorDataModification::SetClosed { index: 0, closed: true },
|
modification: VectorDataModification::SetClosed { index: 0, closed: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
responses.push_back(DocumentMessage::CommitTransaction.into());
|
responses.add(DocumentMessage::CommitTransaction);
|
||||||
|
|
||||||
// Clean up overlays
|
// Clean up overlays
|
||||||
for layer_path in document.all_layers() {
|
for layer_path in document.all_layers() {
|
||||||
@@ -329,7 +329,7 @@ impl PenToolData {
|
|||||||
}
|
}
|
||||||
// Add a new manipulator for the next anchor that we will place
|
// Add a new manipulator for the next anchor that we will place
|
||||||
if let Some(out_handle) = outwards_handle.get_position(last_manipulator_group) {
|
if let Some(out_handle) = outwards_handle.get_position(last_manipulator_group) {
|
||||||
responses.push_back(add_manipulator_group(&self.path, self.from_start, bezier_rs::ManipulatorGroup::new_anchor(out_handle)));
|
responses.add(add_manipulator_group(&self.path, self.from_start, bezier_rs::ManipulatorGroup::new_anchor(out_handle)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(PenToolFsmState::PlacingAnchor)
|
Some(PenToolFsmState::PlacingAnchor)
|
||||||
@@ -524,7 +524,7 @@ impl Fsm for PenToolFsmState {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
(PenToolFsmState::Ready, PenToolMessage::DragStart) => {
|
(PenToolFsmState::Ready, PenToolMessage::DragStart) => {
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
|
|
||||||
// Initialize snapping
|
// Initialize snapping
|
||||||
tool_data.snap_manager.start_snap(document, input, document.bounding_boxes(None, None, render_data), true, true);
|
tool_data.snap_manager.start_snap(document, input, document.bounding_boxes(None, None, render_data), true, true);
|
||||||
@@ -608,11 +608,11 @@ impl Fsm for PenToolFsmState {
|
|||||||
]),
|
]),
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
responses.add(FrontendMessage::UpdateInputHints { hint_data });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
||||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Default }.into());
|
responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Default });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ impl Fsm for RectangleToolFsmState {
|
|||||||
let subpath = bezier_rs::Subpath::new_rect(DVec2::ZERO, DVec2::ONE);
|
let subpath = bezier_rs::Subpath::new_rect(DVec2::ZERO, DVec2::ONE);
|
||||||
|
|
||||||
let layer_path = document.get_path_for_new_layer();
|
let layer_path = document.get_path_for_new_layer();
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
shape_data.path = Some(layer_path.clone());
|
shape_data.path = Some(layer_path.clone());
|
||||||
graph_modification_utils::new_vector_layer(vec![subpath], layer_path.clone(), responses);
|
graph_modification_utils::new_vector_layer(vec![subpath], layer_path.clone(), responses);
|
||||||
responses.add(GraphOperationMessage::FillSet {
|
responses.add(GraphOperationMessage::FillSet {
|
||||||
@@ -134,7 +134,7 @@ impl Fsm for RectangleToolFsmState {
|
|||||||
}
|
}
|
||||||
(state, Resize { center, lock_ratio }) => {
|
(state, Resize { center, lock_ratio }) => {
|
||||||
if let Some(message) = shape_data.calculate_transform(responses, document, input, center, lock_ratio, false) {
|
if let Some(message) = shape_data.calculate_transform(responses, document, input, center, lock_ratio, false) {
|
||||||
responses.push_back(message);
|
responses.add(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
state
|
state
|
||||||
@@ -146,7 +146,7 @@ impl Fsm for RectangleToolFsmState {
|
|||||||
Ready
|
Ready
|
||||||
}
|
}
|
||||||
(Drawing, Abort) => {
|
(Drawing, Abort) => {
|
||||||
responses.push_back(DocumentMessage::AbortTransaction.into());
|
responses.add(DocumentMessage::AbortTransaction);
|
||||||
|
|
||||||
shape_data.cleanup(responses);
|
shape_data.cleanup(responses);
|
||||||
|
|
||||||
@@ -169,10 +169,10 @@ impl Fsm for RectangleToolFsmState {
|
|||||||
RectangleToolFsmState::Drawing => HintData(vec![HintGroup(vec![HintInfo::keys([Key::Shift], "Constrain Square"), HintInfo::keys([Key::Alt], "From Center")])]),
|
RectangleToolFsmState::Drawing => HintData(vec![HintGroup(vec![HintInfo::keys([Key::Shift], "Constrain Square"), HintInfo::keys([Key::Alt], "From Center")])]),
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
responses.add(FrontendMessage::UpdateInputHints { hint_data });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
||||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Crosshair }.into());
|
responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Crosshair });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for SelectT
|
|||||||
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
fn process_message(&mut self, message: ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut ToolActionHandlerData<'a>) {
|
||||||
if let ToolMessage::Select(SelectToolMessage::SelectOptions(SelectOptionsUpdate::NestedSelectionBehavior(nested_selection_behavior))) = message {
|
if let ToolMessage::Select(SelectToolMessage::SelectOptions(SelectOptionsUpdate::NestedSelectionBehavior(nested_selection_behavior))) = message {
|
||||||
self.tool_data.nested_selection_behavior = nested_selection_behavior;
|
self.tool_data.nested_selection_behavior = nested_selection_behavior;
|
||||||
responses.push_back(ToolMessage::UpdateHints.into());
|
responses.add(ToolMessage::UpdateHints);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.fsm_state.process_event(message, &mut self.tool_data, tool_data, &(), responses, false);
|
self.fsm_state.process_event(message, &mut self.tool_data, tool_data, &(), responses, false);
|
||||||
@@ -336,7 +336,7 @@ impl SelectToolData {
|
|||||||
|
|
||||||
/// Duplicates the currently dragging layers. Called when Alt is pressed and the layers have not yet been duplicated.
|
/// Duplicates the currently dragging layers. Called when Alt is pressed and the layers have not yet been duplicated.
|
||||||
fn start_duplicates(&mut self, document: &DocumentMessageHandler, responses: &mut VecDeque<Message>) {
|
fn start_duplicates(&mut self, document: &DocumentMessageHandler, responses: &mut VecDeque<Message>) {
|
||||||
responses.push_back(DocumentMessage::DeselectAllLayers.into());
|
responses.add(DocumentMessage::DeselectAllLayers);
|
||||||
|
|
||||||
// Take the selected layers and store them in a separate list.
|
// Take the selected layers and store them in a separate list.
|
||||||
self.not_duplicated_layers = Some(self.layers_dragging.clone());
|
self.not_duplicated_layers = Some(self.layers_dragging.clone());
|
||||||
@@ -344,15 +344,12 @@ impl SelectToolData {
|
|||||||
// Duplicate each previously selected layer and select the new ones.
|
// Duplicate each previously selected layer and select the new ones.
|
||||||
for layer_path in Document::shallowest_unique_layers(self.layers_dragging.iter_mut()) {
|
for layer_path in Document::shallowest_unique_layers(self.layers_dragging.iter_mut()) {
|
||||||
// Moves the original back to its starting position.
|
// Moves the original back to its starting position.
|
||||||
responses.push_front(
|
responses.add_front(GraphOperationMessage::TransformChange {
|
||||||
GraphOperationMessage::TransformChange {
|
layer: layer_path.clone(),
|
||||||
layer: layer_path.clone(),
|
transform: DAffine2::from_translation(self.drag_start - self.drag_current),
|
||||||
transform: DAffine2::from_translation(self.drag_start - self.drag_current),
|
transform_in: TransformIn::Viewport,
|
||||||
transform_in: TransformIn::Viewport,
|
skip_rerender: true,
|
||||||
skip_rerender: true,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Copy the layers.
|
// Copy the layers.
|
||||||
// Not using the Copy message allows us to retrieve the ids of the new layers to initialize the drag.
|
// Not using the Copy message allows us to retrieve the ids of the new layers to initialize the drag.
|
||||||
@@ -391,33 +388,27 @@ impl SelectToolData {
|
|||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push_back(DocumentMessage::DeselectAllLayers.into());
|
responses.add(DocumentMessage::DeselectAllLayers);
|
||||||
|
|
||||||
// Delete the duplicated layers
|
// Delete the duplicated layers
|
||||||
for layer_path in Document::shallowest_unique_layers(self.layers_dragging.iter()) {
|
for layer_path in Document::shallowest_unique_layers(self.layers_dragging.iter()) {
|
||||||
responses.push_back(Operation::DeleteLayer { path: layer_path.clone() }.into());
|
responses.add(Operation::DeleteLayer { path: layer_path.clone() });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move the original to under the mouse
|
// Move the original to under the mouse
|
||||||
for layer_path in Document::shallowest_unique_layers(originals.iter()) {
|
for layer_path in Document::shallowest_unique_layers(originals.iter()) {
|
||||||
responses.push_front(
|
responses.add_front(GraphOperationMessage::TransformChange {
|
||||||
GraphOperationMessage::TransformChange {
|
layer: layer_path.clone(),
|
||||||
layer: layer_path.clone(),
|
transform: DAffine2::from_translation(self.drag_current - self.drag_start),
|
||||||
transform: DAffine2::from_translation(self.drag_current - self.drag_start),
|
transform_in: TransformIn::Viewport,
|
||||||
transform_in: TransformIn::Viewport,
|
skip_rerender: true,
|
||||||
skip_rerender: true,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Select the originals
|
// Select the originals
|
||||||
responses.push_back(
|
responses.add(DocumentMessage::SetSelectedLayers {
|
||||||
DocumentMessage::SetSelectedLayers {
|
replacement_selected_layers: originals.clone(),
|
||||||
replacement_selected_layers: originals.clone(),
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
|
|
||||||
self.layers_dragging = originals;
|
self.layers_dragging = originals;
|
||||||
}
|
}
|
||||||
@@ -514,14 +505,14 @@ impl Fsm for SelectToolFsmState {
|
|||||||
// If the user clicks on new shape, make that layer their new selection.
|
// If the user clicks on new shape, make that layer their new selection.
|
||||||
// Otherwise enter the box select mode
|
// Otherwise enter the box select mode
|
||||||
let state = if tool_data.pivot.is_over(input.mouse.position) {
|
let state = if tool_data.pivot.is_over(input.mouse.position) {
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
|
|
||||||
tool_data.snap_manager.start_snap(document, input, document.bounding_boxes(None, None, render_data), true, true);
|
tool_data.snap_manager.start_snap(document, input, document.bounding_boxes(None, None, render_data), true, true);
|
||||||
tool_data.snap_manager.add_all_document_handles(document, input, &[], &[], &[]);
|
tool_data.snap_manager.add_all_document_handles(document, input, &[], &[], &[]);
|
||||||
|
|
||||||
DraggingPivot
|
DraggingPivot
|
||||||
} else if let Some(selected_edges) = dragging_bounds {
|
} else if let Some(selected_edges) = dragging_bounds {
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
|
|
||||||
let snap_x = selected_edges.2 || selected_edges.3;
|
let snap_x = selected_edges.2 || selected_edges.3;
|
||||||
let snap_y = selected_edges.0 || selected_edges.1;
|
let snap_y = selected_edges.0 || selected_edges.1;
|
||||||
@@ -553,7 +544,7 @@ impl Fsm for SelectToolFsmState {
|
|||||||
|
|
||||||
ResizingBounds
|
ResizingBounds
|
||||||
} else if rotating_bounds {
|
} else if rotating_bounds {
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
|
|
||||||
if let Some(bounds) = &mut tool_data.bounding_box_overlays {
|
if let Some(bounds) = &mut tool_data.bounding_box_overlays {
|
||||||
let selected = selected.iter().collect::<Vec<_>>();
|
let selected = selected.iter().collect::<Vec<_>>();
|
||||||
@@ -574,7 +565,7 @@ impl Fsm for SelectToolFsmState {
|
|||||||
|
|
||||||
RotatingBounds
|
RotatingBounds
|
||||||
} else if intersection.last().map(|last| selected.contains(last)).unwrap_or(false) {
|
} else if intersection.last().map(|last| selected.contains(last)).unwrap_or(false) {
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
|
|
||||||
tool_data.layers_dragging = selected;
|
tool_data.layers_dragging = selected;
|
||||||
|
|
||||||
@@ -584,10 +575,10 @@ impl Fsm for SelectToolFsmState {
|
|||||||
|
|
||||||
Dragging
|
Dragging
|
||||||
} else {
|
} else {
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
|
|
||||||
if !input.keyboard.get(add_to_selection as usize) && tool_data.nested_selection_behavior == NestedSelectionBehavior::Deepest {
|
if !input.keyboard.get(add_to_selection as usize) && tool_data.nested_selection_behavior == NestedSelectionBehavior::Deepest {
|
||||||
responses.push_back(DocumentMessage::DeselectAllLayers.into());
|
responses.add(DocumentMessage::DeselectAllLayers);
|
||||||
tool_data.layers_dragging.clear();
|
tool_data.layers_dragging.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -606,7 +597,7 @@ impl Fsm for SelectToolFsmState {
|
|||||||
// Deselect all layers if using shallowest selection behavior
|
// Deselect all layers if using shallowest selection behavior
|
||||||
// Necessary since for shallowest mode, we need to know the current selected layers to determine the next
|
// Necessary since for shallowest mode, we need to know the current selected layers to determine the next
|
||||||
if tool_data.nested_selection_behavior == NestedSelectionBehavior::Shallowest {
|
if tool_data.nested_selection_behavior == NestedSelectionBehavior::Shallowest {
|
||||||
responses.push_back(DocumentMessage::DeselectAllLayers.into());
|
responses.add(DocumentMessage::DeselectAllLayers);
|
||||||
tool_data.layers_dragging.clear();
|
tool_data.layers_dragging.clear();
|
||||||
}
|
}
|
||||||
tool_data.drag_box_overlay_layer = Some(add_bounding_box(responses));
|
tool_data.drag_box_overlay_layer = Some(add_bounding_box(responses));
|
||||||
@@ -620,7 +611,7 @@ impl Fsm for SelectToolFsmState {
|
|||||||
(Dragging, PointerMove { axis_align, duplicate, .. }) => {
|
(Dragging, PointerMove { axis_align, duplicate, .. }) => {
|
||||||
tool_data.is_dragging = true;
|
tool_data.is_dragging = true;
|
||||||
// TODO: This is a cheat. Break out the relevant functionality from the handler above and call it from there and here.
|
// TODO: This is a cheat. Break out the relevant functionality from the handler above and call it from there and here.
|
||||||
responses.push_front(SelectToolMessage::DocumentIsDirty.into());
|
responses.add_front(SelectToolMessage::DocumentIsDirty);
|
||||||
|
|
||||||
let mouse_position = axis_align_drag(input.keyboard.get(axis_align as usize), input.mouse.position, tool_data.drag_start);
|
let mouse_position = axis_align_drag(input.keyboard.get(axis_align as usize), input.mouse.position, tool_data.drag_start);
|
||||||
|
|
||||||
@@ -636,15 +627,12 @@ impl Fsm for SelectToolFsmState {
|
|||||||
let closest_move = tool_data.snap_manager.snap_layers(responses, document, snap, mouse_delta);
|
let closest_move = tool_data.snap_manager.snap_layers(responses, document, snap, mouse_delta);
|
||||||
// TODO: Cache the result of `shallowest_unique_layers` to avoid this heavy computation every frame of movement, see https://github.com/GraphiteEditor/Graphite/pull/481
|
// TODO: Cache the result of `shallowest_unique_layers` to avoid this heavy computation every frame of movement, see https://github.com/GraphiteEditor/Graphite/pull/481
|
||||||
for path in Document::shallowest_unique_layers(tool_data.layers_dragging.iter()) {
|
for path in Document::shallowest_unique_layers(tool_data.layers_dragging.iter()) {
|
||||||
responses.push_front(
|
responses.add_front(GraphOperationMessage::TransformChange {
|
||||||
GraphOperationMessage::TransformChange {
|
layer: path.to_vec(),
|
||||||
layer: path.to_vec(),
|
transform: DAffine2::from_translation(mouse_delta + closest_move),
|
||||||
transform: DAffine2::from_translation(mouse_delta + closest_move),
|
transform_in: TransformIn::Viewport,
|
||||||
transform_in: TransformIn::Viewport,
|
skip_rerender: true,
|
||||||
skip_rerender: true,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
tool_data.drag_current = mouse_position + closest_move;
|
tool_data.drag_current = mouse_position + closest_move;
|
||||||
|
|
||||||
@@ -720,16 +708,13 @@ impl Fsm for SelectToolFsmState {
|
|||||||
(DrawingBox, PointerMove { .. }) => {
|
(DrawingBox, PointerMove { .. }) => {
|
||||||
tool_data.drag_current = input.mouse.position;
|
tool_data.drag_current = input.mouse.position;
|
||||||
|
|
||||||
responses.push_front(
|
responses.add_front(DocumentMessage::Overlays(
|
||||||
DocumentMessage::Overlays(
|
Operation::SetLayerTransformInViewport {
|
||||||
Operation::SetLayerTransformInViewport {
|
path: tool_data.drag_box_overlay_layer.clone().unwrap(),
|
||||||
path: tool_data.drag_box_overlay_layer.clone().unwrap(),
|
transform: transform_from_box(tool_data.drag_start, tool_data.drag_current, DAffine2::IDENTITY).to_cols_array(),
|
||||||
transform: transform_from_box(tool_data.drag_start, tool_data.drag_current, DAffine2::IDENTITY).to_cols_array(),
|
}
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
)
|
|
||||||
.into(),
|
.into(),
|
||||||
);
|
));
|
||||||
DrawingBox
|
DrawingBox
|
||||||
}
|
}
|
||||||
(Ready, PointerMove { .. }) => {
|
(Ready, PointerMove { .. }) => {
|
||||||
@@ -749,7 +734,7 @@ impl Fsm for SelectToolFsmState {
|
|||||||
|
|
||||||
if tool_data.cursor != cursor {
|
if tool_data.cursor != cursor {
|
||||||
tool_data.cursor = cursor;
|
tool_data.cursor = cursor;
|
||||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor }.into());
|
responses.add(FrontendMessage::UpdateMouseCursor { cursor });
|
||||||
}
|
}
|
||||||
|
|
||||||
Ready
|
Ready
|
||||||
@@ -762,7 +747,7 @@ impl Fsm for SelectToolFsmState {
|
|||||||
false => DocumentMessage::CommitTransaction,
|
false => DocumentMessage::CommitTransaction,
|
||||||
};
|
};
|
||||||
tool_data.snap_manager.cleanup(responses);
|
tool_data.snap_manager.cleanup(responses);
|
||||||
responses.push_front(response.into());
|
responses.add_front(response);
|
||||||
|
|
||||||
Ready
|
Ready
|
||||||
}
|
}
|
||||||
@@ -782,14 +767,14 @@ impl Fsm for SelectToolFsmState {
|
|||||||
tool_data.layers_dragging.clear();
|
tool_data.layers_dragging.clear();
|
||||||
tool_data.layers_dragging.append(replacement_selected_layers.clone().as_mut());
|
tool_data.layers_dragging.append(replacement_selected_layers.clone().as_mut());
|
||||||
|
|
||||||
responses.push_back(DocumentMessage::SetSelectedLayers { replacement_selected_layers }.into());
|
responses.add(DocumentMessage::SetSelectedLayers { replacement_selected_layers });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tool_data.is_dragging = false;
|
tool_data.is_dragging = false;
|
||||||
tool_data.layer_selected_on_start = None;
|
tool_data.layer_selected_on_start = None;
|
||||||
|
|
||||||
responses.push_back(DocumentMessage::CommitTransaction.into());
|
responses.add(DocumentMessage::CommitTransaction);
|
||||||
tool_data.snap_manager.cleanup(responses);
|
tool_data.snap_manager.cleanup(responses);
|
||||||
|
|
||||||
Ready
|
Ready
|
||||||
@@ -801,7 +786,7 @@ impl Fsm for SelectToolFsmState {
|
|||||||
true => DocumentMessage::Undo,
|
true => DocumentMessage::Undo,
|
||||||
false => DocumentMessage::CommitTransaction,
|
false => DocumentMessage::CommitTransaction,
|
||||||
};
|
};
|
||||||
responses.push_back(response.into());
|
responses.add(response);
|
||||||
|
|
||||||
tool_data.snap_manager.cleanup(responses);
|
tool_data.snap_manager.cleanup(responses);
|
||||||
|
|
||||||
@@ -818,7 +803,7 @@ impl Fsm for SelectToolFsmState {
|
|||||||
true => DocumentMessage::Undo,
|
true => DocumentMessage::Undo,
|
||||||
false => DocumentMessage::CommitTransaction,
|
false => DocumentMessage::CommitTransaction,
|
||||||
};
|
};
|
||||||
responses.push_back(response.into());
|
responses.add(response);
|
||||||
|
|
||||||
if let Some(bounds) = &mut tool_data.bounding_box_overlays {
|
if let Some(bounds) = &mut tool_data.bounding_box_overlays {
|
||||||
bounds.original_transforms.clear();
|
bounds.original_transforms.clear();
|
||||||
@@ -831,7 +816,7 @@ impl Fsm for SelectToolFsmState {
|
|||||||
true => DocumentMessage::Undo,
|
true => DocumentMessage::Undo,
|
||||||
false => DocumentMessage::CommitTransaction,
|
false => DocumentMessage::CommitTransaction,
|
||||||
};
|
};
|
||||||
responses.push_back(response.into());
|
responses.add(response);
|
||||||
|
|
||||||
tool_data.snap_manager.cleanup(responses);
|
tool_data.snap_manager.cleanup(responses);
|
||||||
|
|
||||||
@@ -839,21 +824,15 @@ impl Fsm for SelectToolFsmState {
|
|||||||
}
|
}
|
||||||
(DrawingBox, DragStop { .. } | Enter) => {
|
(DrawingBox, DragStop { .. } | Enter) => {
|
||||||
let quad = tool_data.selection_quad();
|
let quad = tool_data.selection_quad();
|
||||||
responses.push_front(
|
responses.add_front(DocumentMessage::AddSelectedLayers {
|
||||||
DocumentMessage::AddSelectedLayers {
|
additional_layers: document.document_legacy.intersects_quad_root(quad, render_data),
|
||||||
additional_layers: document.document_legacy.intersects_quad_root(quad, render_data),
|
});
|
||||||
|
responses.add_front(DocumentMessage::Overlays(
|
||||||
|
Operation::DeleteLayer {
|
||||||
|
path: tool_data.drag_box_overlay_layer.take().unwrap(),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
);
|
));
|
||||||
responses.push_front(
|
|
||||||
DocumentMessage::Overlays(
|
|
||||||
Operation::DeleteLayer {
|
|
||||||
path: tool_data.drag_box_overlay_layer.take().unwrap(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
Ready
|
Ready
|
||||||
}
|
}
|
||||||
(Ready, Enter) => {
|
(Ready, Enter) => {
|
||||||
@@ -865,8 +844,8 @@ impl Fsm for SelectToolFsmState {
|
|||||||
if let Ok(layer) = document.document_legacy.layer(layer_path) {
|
if let Ok(layer) = document.document_legacy.layer(layer_path) {
|
||||||
if let Ok(network) = layer.as_node_graph() {
|
if let Ok(network) = layer.as_node_graph() {
|
||||||
if network.nodes.values().any(|node| node.name == "Text") {
|
if network.nodes.values().any(|node| node.name == "Text") {
|
||||||
responses.push_front(ToolMessage::ActivateTool { tool_type: ToolType::Text }.into());
|
responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Text });
|
||||||
responses.push_back(TextToolMessage::EditSelected.into());
|
responses.add(TextToolMessage::EditSelected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -879,7 +858,7 @@ impl Fsm for SelectToolFsmState {
|
|||||||
rerender_selected_layers(tool_data, responses);
|
rerender_selected_layers(tool_data, responses);
|
||||||
|
|
||||||
tool_data.snap_manager.cleanup(responses);
|
tool_data.snap_manager.cleanup(responses);
|
||||||
responses.push_back(DocumentMessage::Undo.into());
|
responses.add(DocumentMessage::Undo);
|
||||||
|
|
||||||
tool_data.path_outlines.clear_selected(responses);
|
tool_data.path_outlines.clear_selected(responses);
|
||||||
tool_data.pivot.clear_overlays(responses);
|
tool_data.pivot.clear_overlays(responses);
|
||||||
@@ -888,7 +867,7 @@ impl Fsm for SelectToolFsmState {
|
|||||||
}
|
}
|
||||||
(_, Abort) => {
|
(_, Abort) => {
|
||||||
if let Some(path) = tool_data.drag_box_overlay_layer.take() {
|
if let Some(path) = tool_data.drag_box_overlay_layer.take() {
|
||||||
responses.push_front(DocumentMessage::Overlays(Operation::DeleteLayer { path }.into()).into())
|
responses.add_front(DocumentMessage::Overlays(Operation::DeleteLayer { path }.into()))
|
||||||
};
|
};
|
||||||
if let Some(mut bounding_box_overlays) = tool_data.bounding_box_overlays.take() {
|
if let Some(mut bounding_box_overlays) = tool_data.bounding_box_overlays.take() {
|
||||||
let selected = tool_data.layers_dragging.iter().collect::<Vec<_>>();
|
let selected = tool_data.layers_dragging.iter().collect::<Vec<_>>();
|
||||||
@@ -915,22 +894,22 @@ impl Fsm for SelectToolFsmState {
|
|||||||
Ready
|
Ready
|
||||||
}
|
}
|
||||||
(_, Align { axis, aggregate }) => {
|
(_, Align { axis, aggregate }) => {
|
||||||
responses.push_back(DocumentMessage::AlignSelectedLayers { axis, aggregate }.into());
|
responses.add(DocumentMessage::AlignSelectedLayers { axis, aggregate });
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
(_, FlipHorizontal) => {
|
(_, FlipHorizontal) => {
|
||||||
responses.push_back(DocumentMessage::FlipSelectedLayers { flip_axis: FlipAxis::X }.into());
|
responses.add(DocumentMessage::FlipSelectedLayers { flip_axis: FlipAxis::X });
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
(_, FlipVertical) => {
|
(_, FlipVertical) => {
|
||||||
responses.push_back(DocumentMessage::FlipSelectedLayers { flip_axis: FlipAxis::Y }.into());
|
responses.add(DocumentMessage::FlipSelectedLayers { flip_axis: FlipAxis::Y });
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
(_, SetPivot { position }) => {
|
(_, SetPivot { position }) => {
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
|
|
||||||
let pos: Option<DVec2> = position.into();
|
let pos: Option<DVec2> = position.into();
|
||||||
tool_data.pivot.set_normalized_position(pos.unwrap(), document, render_data, responses);
|
tool_data.pivot.set_normalized_position(pos.unwrap(), document, render_data, responses);
|
||||||
@@ -944,7 +923,7 @@ impl Fsm for SelectToolFsmState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn standard_tool_messages(&self, message: &ToolMessage, messages: &mut VecDeque<Message>, tool_data: &mut Self::ToolData) -> bool {
|
fn standard_tool_messages(&self, message: &ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut Self::ToolData) -> bool {
|
||||||
// Check for standard hits or cursor events
|
// Check for standard hits or cursor events
|
||||||
match message {
|
match message {
|
||||||
ToolMessage::UpdateHints => {
|
ToolMessage::UpdateHints => {
|
||||||
@@ -974,12 +953,12 @@ impl Fsm for SelectToolFsmState {
|
|||||||
]),
|
]),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
messages.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
responses.add(FrontendMessage::UpdateInputHints { hint_data });
|
||||||
self.update_hints(messages);
|
self.update_hints(responses);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
ToolMessage::UpdateCursor => {
|
ToolMessage::UpdateCursor => {
|
||||||
self.update_cursor(messages);
|
self.update_cursor(responses);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
@@ -989,7 +968,7 @@ impl Fsm for SelectToolFsmState {
|
|||||||
fn update_hints(&self, _responses: &mut VecDeque<Message>) {}
|
fn update_hints(&self, _responses: &mut VecDeque<Message>) {}
|
||||||
|
|
||||||
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
||||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Default }.into());
|
responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Default });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1023,13 +1002,13 @@ fn drag_shallowest_manipulation(
|
|||||||
if layers.contains(&&[incoming_parent].as_slice()) {
|
if layers.contains(&&[incoming_parent].as_slice()) {
|
||||||
// Add incoming layer
|
// Add incoming layer
|
||||||
tool_data.layers_dragging.clear();
|
tool_data.layers_dragging.clear();
|
||||||
responses.push_back(DocumentMessage::DeselectAllLayers.into());
|
responses.add(DocumentMessage::DeselectAllLayers);
|
||||||
layers_without_incoming_parent.append(selected.clone().as_mut());
|
layers_without_incoming_parent.append(selected.clone().as_mut());
|
||||||
*selected = layers_without_incoming_parent;
|
*selected = layers_without_incoming_parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
tool_data.layers_dragging.append(selected.clone().as_mut());
|
tool_data.layers_dragging.append(selected.clone().as_mut());
|
||||||
responses.push_back(DocumentMessage::AddSelectedLayers { additional_layers: selected.clone() }.into());
|
responses.add(DocumentMessage::AddSelectedLayers { additional_layers: selected.clone() });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1037,12 +1016,9 @@ fn drag_shallowest_manipulation(
|
|||||||
if input.keyboard.get(select_deepest as usize) {
|
if input.keyboard.get(select_deepest as usize) {
|
||||||
tool_data.layers_dragging.clear();
|
tool_data.layers_dragging.clear();
|
||||||
tool_data.layers_dragging.append(selected.clone().as_mut());
|
tool_data.layers_dragging.append(selected.clone().as_mut());
|
||||||
responses.push_back(
|
responses.add(DocumentMessage::SetSelectedLayers {
|
||||||
DocumentMessage::SetSelectedLayers {
|
replacement_selected_layers: selected.clone(),
|
||||||
replacement_selected_layers: selected.clone(),
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1094,23 +1070,17 @@ fn drag_shallowest_manipulation(
|
|||||||
if selected_layers_count <= 1 {
|
if selected_layers_count <= 1 {
|
||||||
if input.keyboard.get(add_to_selection as usize) {
|
if input.keyboard.get(add_to_selection as usize) {
|
||||||
if !already_selected {
|
if !already_selected {
|
||||||
responses.push_back(
|
responses.add(DocumentMessage::AddSelectedLayers {
|
||||||
DocumentMessage::AddSelectedLayers {
|
additional_layers: vec![search.clone()],
|
||||||
additional_layers: vec![search.clone()],
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
tool_data.layer_selected_on_start = None;
|
tool_data.layer_selected_on_start = None;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tool_data.layers_dragging.clear();
|
tool_data.layers_dragging.clear();
|
||||||
responses.push_back(
|
responses.add(DocumentMessage::SetSelectedLayers {
|
||||||
DocumentMessage::SetSelectedLayers {
|
replacement_selected_layers: vec![search.clone()],
|
||||||
replacement_selected_layers: vec![search.clone()],
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
tool_data.layers_dragging.push(search);
|
tool_data.layers_dragging.push(search);
|
||||||
} else {
|
} else {
|
||||||
@@ -1131,23 +1101,17 @@ fn drag_shallowest_manipulation(
|
|||||||
if input.keyboard.get(add_to_selection as usize) {
|
if input.keyboard.get(add_to_selection as usize) {
|
||||||
if !already_selected {
|
if !already_selected {
|
||||||
tool_data.layers_dragging.push(direct_child.clone());
|
tool_data.layers_dragging.push(direct_child.clone());
|
||||||
responses.push_back(
|
responses.add(DocumentMessage::AddSelectedLayers {
|
||||||
DocumentMessage::AddSelectedLayers {
|
additional_layers: vec![direct_child.clone()],
|
||||||
additional_layers: vec![direct_child.clone()],
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
tool_data.layer_selected_on_start = None;
|
tool_data.layer_selected_on_start = None;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tool_data.layers_dragging.push(direct_child.clone());
|
tool_data.layers_dragging.push(direct_child.clone());
|
||||||
responses.push_back(
|
responses.add(DocumentMessage::SetSelectedLayers {
|
||||||
DocumentMessage::SetSelectedLayers {
|
replacement_selected_layers: vec![direct_child.clone()],
|
||||||
replacement_selected_layers: vec![direct_child.clone()],
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1155,20 +1119,14 @@ fn drag_shallowest_manipulation(
|
|||||||
else {
|
else {
|
||||||
let parent_folder_id = selected.first().unwrap().first().unwrap();
|
let parent_folder_id = selected.first().unwrap().first().unwrap();
|
||||||
if input.keyboard.get(add_to_selection as usize) {
|
if input.keyboard.get(add_to_selection as usize) {
|
||||||
responses.push_back(
|
responses.add(DocumentMessage::AddSelectedLayers {
|
||||||
DocumentMessage::AddSelectedLayers {
|
additional_layers: vec![vec![*parent_folder_id]],
|
||||||
additional_layers: vec![vec![*parent_folder_id]],
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
tool_data.layers_dragging.clear();
|
tool_data.layers_dragging.clear();
|
||||||
responses.push_back(
|
responses.add(DocumentMessage::SetSelectedLayers {
|
||||||
DocumentMessage::SetSelectedLayers {
|
replacement_selected_layers: vec![vec![*parent_folder_id]],
|
||||||
replacement_selected_layers: vec![vec![*parent_folder_id]],
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
tool_data.layers_dragging.push(vec![*parent_folder_id]);
|
tool_data.layers_dragging.push(vec![*parent_folder_id]);
|
||||||
}
|
}
|
||||||
@@ -1176,12 +1134,9 @@ fn drag_shallowest_manipulation(
|
|||||||
// Check if new layer is already selected
|
// Check if new layer is already selected
|
||||||
let parent_folder_id = selected.first().unwrap().first().unwrap();
|
let parent_folder_id = selected.first().unwrap().first().unwrap();
|
||||||
tool_data.layers_dragging.push(vec![*parent_folder_id]);
|
tool_data.layers_dragging.push(vec![*parent_folder_id]);
|
||||||
responses.push_back(
|
responses.add(DocumentMessage::AddSelectedLayers {
|
||||||
DocumentMessage::AddSelectedLayers {
|
additional_layers: vec![vec![*parent_folder_id]],
|
||||||
additional_layers: vec![vec![*parent_folder_id]],
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1193,7 +1148,7 @@ fn drag_deepest_manipulation(
|
|||||||
input: &InputPreprocessorMessageHandler,
|
input: &InputPreprocessorMessageHandler,
|
||||||
render_data: &document_legacy::layers::RenderData,
|
render_data: &document_legacy::layers::RenderData,
|
||||||
) {
|
) {
|
||||||
responses.push_back(DocumentMessage::AddSelectedLayers { additional_layers: selected.clone() }.into());
|
responses.add(DocumentMessage::AddSelectedLayers { additional_layers: selected.clone() });
|
||||||
tool_data.layers_dragging.append(selected.as_mut());
|
tool_data.layers_dragging.append(selected.as_mut());
|
||||||
tool_data
|
tool_data
|
||||||
.snap_manager
|
.snap_manager
|
||||||
@@ -1237,14 +1192,11 @@ fn edit_layer_shallowest_manipulation(document: &DocumentMessageHandler, interse
|
|||||||
if !selected_layers.contains(&new_layer_path.as_slice()) {
|
if !selected_layers.contains(&new_layer_path.as_slice()) {
|
||||||
tool_data.layers_dragging.clear();
|
tool_data.layers_dragging.clear();
|
||||||
tool_data.layers_dragging.push(new_layer_path.clone());
|
tool_data.layers_dragging.push(new_layer_path.clone());
|
||||||
responses.push_back(
|
responses.add(DocumentMessage::SetSelectedLayers {
|
||||||
DocumentMessage::SetSelectedLayers {
|
replacement_selected_layers: vec![new_layer_path],
|
||||||
replacement_selected_layers: vec![new_layer_path],
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
responses.push_front(ToolMessage::ActivateTool { tool_type: ToolType::Path }.into());
|
responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Path });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1252,14 +1204,14 @@ fn edit_layer_shallowest_manipulation(document: &DocumentMessageHandler, interse
|
|||||||
fn edit_layer_deepest_manipulation(intersect: &Layer, responses: &mut VecDeque<Message>) {
|
fn edit_layer_deepest_manipulation(intersect: &Layer, responses: &mut VecDeque<Message>) {
|
||||||
match &intersect.data {
|
match &intersect.data {
|
||||||
LayerDataType::Shape(_) => {
|
LayerDataType::Shape(_) => {
|
||||||
responses.push_front(ToolMessage::ActivateTool { tool_type: ToolType::Path }.into());
|
responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Path });
|
||||||
}
|
}
|
||||||
LayerDataType::NodeGraphFrame(graph_frame) if graph_frame.as_vector_data().is_some() => {
|
LayerDataType::NodeGraphFrame(graph_frame) if graph_frame.as_vector_data().is_some() => {
|
||||||
if graph_frame.network.nodes.values().any(|node| node.name == "Text") {
|
if graph_frame.network.nodes.values().any(|node| node.name == "Text") {
|
||||||
responses.push_front(ToolMessage::ActivateTool { tool_type: ToolType::Text }.into());
|
responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Text });
|
||||||
responses.push_back(TextToolMessage::EditSelected.into());
|
responses.add(TextToolMessage::EditSelected);
|
||||||
} else {
|
} else {
|
||||||
responses.push_front(ToolMessage::ActivateTool { tool_type: ToolType::Path }.into());
|
responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Path });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ impl Fsm for ShapeToolFsmState {
|
|||||||
match (self, event) {
|
match (self, event) {
|
||||||
(Ready, DragStart) => {
|
(Ready, DragStart) => {
|
||||||
shape_data.start(responses, document, input, render_data);
|
shape_data.start(responses, document, input, render_data);
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
let layer_path = document.get_path_for_new_layer();
|
let layer_path = document.get_path_for_new_layer();
|
||||||
shape_data.path = Some(layer_path.clone());
|
shape_data.path = Some(layer_path.clone());
|
||||||
tool_data.sides = tool_options.vertices;
|
tool_data.sides = tool_options.vertices;
|
||||||
@@ -173,7 +173,7 @@ impl Fsm for ShapeToolFsmState {
|
|||||||
}
|
}
|
||||||
(state, Resize { center, lock_ratio }) => {
|
(state, Resize { center, lock_ratio }) => {
|
||||||
if let Some(message) = shape_data.calculate_transform(responses, document, input, center, lock_ratio, false) {
|
if let Some(message) = shape_data.calculate_transform(responses, document, input, center, lock_ratio, false) {
|
||||||
responses.push_back(message);
|
responses.add(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
state
|
state
|
||||||
@@ -185,7 +185,7 @@ impl Fsm for ShapeToolFsmState {
|
|||||||
Ready
|
Ready
|
||||||
}
|
}
|
||||||
(Drawing, Abort) => {
|
(Drawing, Abort) => {
|
||||||
responses.push_back(DocumentMessage::AbortTransaction.into());
|
responses.add(DocumentMessage::AbortTransaction);
|
||||||
|
|
||||||
shape_data.cleanup(responses);
|
shape_data.cleanup(responses);
|
||||||
|
|
||||||
@@ -208,10 +208,10 @@ impl Fsm for ShapeToolFsmState {
|
|||||||
ShapeToolFsmState::Drawing => HintData(vec![HintGroup(vec![HintInfo::keys([Key::Shift], "Constrain 1:1 Aspect"), HintInfo::keys([Key::Alt], "From Center")])]),
|
ShapeToolFsmState::Drawing => HintData(vec![HintGroup(vec![HintInfo::keys([Key::Shift], "Constrain 1:1 Aspect"), HintInfo::keys([Key::Alt], "From Center")])]),
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
responses.add(FrontendMessage::UpdateInputHints { hint_data });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
||||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Crosshair }.into());
|
responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Crosshair });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -164,8 +164,8 @@ impl Fsm for SplineToolFsmState {
|
|||||||
if let ToolMessage::Spline(event) = event {
|
if let ToolMessage::Spline(event) = event {
|
||||||
match (self, event) {
|
match (self, event) {
|
||||||
(Ready, DragStart) => {
|
(Ready, DragStart) => {
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
responses.push_back(DocumentMessage::DeselectAllLayers.into());
|
responses.add(DocumentMessage::DeselectAllLayers);
|
||||||
tool_data.path = Some(document.get_path_for_new_layer());
|
tool_data.path = Some(document.get_path_for_new_layer());
|
||||||
|
|
||||||
tool_data.snap_manager.start_snap(document, input, document.bounding_boxes(None, None, render_data), true, true);
|
tool_data.snap_manager.start_snap(document, input, document.bounding_boxes(None, None, render_data), true, true);
|
||||||
@@ -194,7 +194,7 @@ impl Fsm for SplineToolFsmState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
responses.push_back(remove_preview(tool_data));
|
responses.add(remove_preview(tool_data));
|
||||||
add_spline(tool_data, global_tool_data, true, responses);
|
add_spline(tool_data, global_tool_data, true, responses);
|
||||||
|
|
||||||
Drawing
|
Drawing
|
||||||
@@ -204,18 +204,18 @@ impl Fsm for SplineToolFsmState {
|
|||||||
let pos = transform.inverse().transform_point2(snapped_position);
|
let pos = transform.inverse().transform_point2(snapped_position);
|
||||||
tool_data.next_point = pos;
|
tool_data.next_point = pos;
|
||||||
|
|
||||||
responses.push_back(remove_preview(tool_data));
|
responses.add(remove_preview(tool_data));
|
||||||
add_spline(tool_data, global_tool_data, true, responses);
|
add_spline(tool_data, global_tool_data, true, responses);
|
||||||
|
|
||||||
Drawing
|
Drawing
|
||||||
}
|
}
|
||||||
(Drawing, Confirm) | (Drawing, Abort) => {
|
(Drawing, Confirm) | (Drawing, Abort) => {
|
||||||
if tool_data.points.len() >= 2 {
|
if tool_data.points.len() >= 2 {
|
||||||
responses.push_back(remove_preview(tool_data));
|
responses.add(remove_preview(tool_data));
|
||||||
add_spline(tool_data, global_tool_data, false, responses);
|
add_spline(tool_data, global_tool_data, false, responses);
|
||||||
responses.push_back(DocumentMessage::CommitTransaction.into());
|
responses.add(DocumentMessage::CommitTransaction);
|
||||||
} else {
|
} else {
|
||||||
responses.push_back(DocumentMessage::AbortTransaction.into());
|
responses.add(DocumentMessage::AbortTransaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
tool_data.path = None;
|
tool_data.path = None;
|
||||||
@@ -240,11 +240,11 @@ impl Fsm for SplineToolFsmState {
|
|||||||
]),
|
]),
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
responses.add(FrontendMessage::UpdateInputHints { hint_data });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
||||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Default }.into());
|
responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Default });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ impl<'a> MessageHandler<TransformLayerMessage, TransformData<'a>> for TransformL
|
|||||||
self.transform_operation = TransformOperation::Grabbing(Default::default());
|
self.transform_operation = TransformOperation::Grabbing(Default::default());
|
||||||
|
|
||||||
selected.original_transforms.clear();
|
selected.original_transforms.clear();
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
}
|
}
|
||||||
BeginRotate => {
|
BeginRotate => {
|
||||||
if let TransformOperation::Rotating(_) = self.transform_operation {
|
if let TransformOperation::Rotating(_) = self.transform_operation {
|
||||||
@@ -142,7 +142,7 @@ impl<'a> MessageHandler<TransformLayerMessage, TransformData<'a>> for TransformL
|
|||||||
self.transform_operation = TransformOperation::Rotating(Default::default());
|
self.transform_operation = TransformOperation::Rotating(Default::default());
|
||||||
|
|
||||||
selected.original_transforms.clear();
|
selected.original_transforms.clear();
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
}
|
}
|
||||||
BeginScale => {
|
BeginScale => {
|
||||||
if let TransformOperation::Scaling(_) = self.transform_operation {
|
if let TransformOperation::Scaling(_) = self.transform_operation {
|
||||||
@@ -159,7 +159,7 @@ impl<'a> MessageHandler<TransformLayerMessage, TransformData<'a>> for TransformL
|
|||||||
self.transform_operation = TransformOperation::Scaling(Default::default());
|
self.transform_operation = TransformOperation::Scaling(Default::default());
|
||||||
|
|
||||||
selected.original_transforms.clear();
|
selected.original_transforms.clear();
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
}
|
}
|
||||||
CancelTransformOperation => {
|
CancelTransformOperation => {
|
||||||
selected.revert_operation();
|
selected.revert_operation();
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ pub trait Fsm {
|
|||||||
/// For example, if the tool's FSM is in a `Ready` state and receives a `DragStart` message as its event, it may decide to send some messages,
|
/// For example, if the tool's FSM is in a `Ready` state and receives a `DragStart` message as its event, it may decide to send some messages,
|
||||||
/// update some internal tool variables, and end by transitioning to a `Drawing` state.
|
/// update some internal tool variables, and end by transitioning to a `Drawing` state.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
fn transition(self, message: ToolMessage, tool_data: &mut Self::ToolData, transition_data: &mut ToolActionHandlerData, options: &Self::ToolOptions, messages: &mut VecDeque<Message>) -> Self;
|
fn transition(self, message: ToolMessage, tool_data: &mut Self::ToolData, transition_data: &mut ToolActionHandlerData, options: &Self::ToolOptions, responses: &mut VecDeque<Message>) -> Self;
|
||||||
|
|
||||||
/// Implementing this trait function lets a specific tool provide a list of hints (user input actions presently available) to draw in the footer bar.
|
/// Implementing this trait function lets a specific tool provide a list of hints (user input actions presently available) to draw in the footer bar.
|
||||||
fn update_hints(&self, responses: &mut VecDeque<Message>);
|
fn update_hints(&self, responses: &mut VecDeque<Message>);
|
||||||
@@ -80,15 +80,15 @@ pub trait Fsm {
|
|||||||
fn update_cursor(&self, responses: &mut VecDeque<Message>);
|
fn update_cursor(&self, responses: &mut VecDeque<Message>);
|
||||||
|
|
||||||
/// If this message is a standard tool message, process it and return true. Standard tool messages are those which are common across every tool.
|
/// If this message is a standard tool message, process it and return true. Standard tool messages are those which are common across every tool.
|
||||||
fn standard_tool_messages(&self, message: &ToolMessage, messages: &mut VecDeque<Message>, _tool_data: &mut Self::ToolData) -> bool {
|
fn standard_tool_messages(&self, message: &ToolMessage, responses: &mut VecDeque<Message>, _tool_data: &mut Self::ToolData) -> bool {
|
||||||
// Check for standard hits or cursor events
|
// Check for standard hits or cursor events
|
||||||
match message {
|
match message {
|
||||||
ToolMessage::UpdateHints => {
|
ToolMessage::UpdateHints => {
|
||||||
self.update_hints(messages);
|
self.update_hints(responses);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
ToolMessage::UpdateCursor => {
|
ToolMessage::UpdateCursor => {
|
||||||
self.update_cursor(messages);
|
self.update_cursor(responses);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
@@ -103,25 +103,25 @@ pub trait Fsm {
|
|||||||
tool_data: &mut Self::ToolData,
|
tool_data: &mut Self::ToolData,
|
||||||
transition_data: &mut ToolActionHandlerData,
|
transition_data: &mut ToolActionHandlerData,
|
||||||
options: &Self::ToolOptions,
|
options: &Self::ToolOptions,
|
||||||
messages: &mut VecDeque<Message>,
|
responses: &mut VecDeque<Message>,
|
||||||
update_cursor_on_transition: bool,
|
update_cursor_on_transition: bool,
|
||||||
) where
|
) where
|
||||||
Self: PartialEq + Sized + Copy,
|
Self: PartialEq + Sized + Copy,
|
||||||
{
|
{
|
||||||
// If this message is one of the standard tool messages, process it and exit early
|
// If this message is one of the standard tool messages, process it and exit early
|
||||||
if self.standard_tool_messages(&message, messages, tool_data) {
|
if self.standard_tool_messages(&message, responses, tool_data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transition the tool
|
// Transition the tool
|
||||||
let new_state = self.transition(message, tool_data, transition_data, options, messages);
|
let new_state = self.transition(message, tool_data, transition_data, options, responses);
|
||||||
|
|
||||||
// Update state
|
// Update state
|
||||||
if *self != new_state {
|
if *self != new_state {
|
||||||
*self = new_state;
|
*self = new_state;
|
||||||
self.update_hints(messages);
|
self.update_hints(responses);
|
||||||
if update_cursor_on_transition {
|
if update_cursor_on_transition {
|
||||||
self.update_cursor(messages);
|
self.update_cursor(responses);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -164,15 +164,12 @@ impl DocumentToolData {
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
responses.push_back(
|
responses.add(LayoutMessage::SendLayout {
|
||||||
LayoutMessage::SendLayout {
|
layout: Layout::WidgetLayout(layout),
|
||||||
layout: Layout::WidgetLayout(layout),
|
layout_target: LayoutTarget::WorkingColors,
|
||||||
layout_target: LayoutTarget::WorkingColors,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
|
|
||||||
responses.push_back(EyedropperToolMessage::PointerMove.into());
|
responses.add(EyedropperToolMessage::PointerMove);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,13 +186,10 @@ pub trait ToolTransition {
|
|||||||
fn activate(&self, responses: &mut VecDeque<Message>) {
|
fn activate(&self, responses: &mut VecDeque<Message>) {
|
||||||
let mut subscribe_message = |broadcast_to_tool_mapping: Option<ToolMessage>, event: BroadcastEvent| {
|
let mut subscribe_message = |broadcast_to_tool_mapping: Option<ToolMessage>, event: BroadcastEvent| {
|
||||||
if let Some(mapping) = broadcast_to_tool_mapping {
|
if let Some(mapping) = broadcast_to_tool_mapping {
|
||||||
responses.push_back(
|
responses.add(BroadcastMessage::SubscribeEvent {
|
||||||
BroadcastMessage::SubscribeEvent {
|
on: event,
|
||||||
on: event,
|
send: Box::new(mapping.into()),
|
||||||
send: Box::new(mapping.into()),
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -208,13 +202,10 @@ pub trait ToolTransition {
|
|||||||
fn deactivate(&self, responses: &mut VecDeque<Message>) {
|
fn deactivate(&self, responses: &mut VecDeque<Message>) {
|
||||||
let mut unsubscribe_message = |broadcast_to_tool_mapping: Option<ToolMessage>, event: BroadcastEvent| {
|
let mut unsubscribe_message = |broadcast_to_tool_mapping: Option<ToolMessage>, event: BroadcastEvent| {
|
||||||
if let Some(mapping) = broadcast_to_tool_mapping {
|
if let Some(mapping) = broadcast_to_tool_mapping {
|
||||||
responses.push_back(
|
responses.add(BroadcastMessage::UnsubscribeEvent {
|
||||||
BroadcastMessage::UnsubscribeEvent {
|
on: event,
|
||||||
on: event,
|
message: Box::new(mapping.into()),
|
||||||
message: Box::new(mapping.into()),
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -261,7 +261,7 @@ impl NodeGraphExecutor {
|
|||||||
|
|
||||||
// Special execution path for generating Imaginate (as generation requires IO from outside node graph)
|
// Special execution path for generating Imaginate (as generation requires IO from outside node graph)
|
||||||
if let Some(imaginate_node) = imaginate_node {
|
if let Some(imaginate_node) = imaginate_node {
|
||||||
responses.push_back(self.generate_imaginate(network, imaginate_node, (document, document_id), layer_path, editor_api, persistent_data)?);
|
responses.add(self.generate_imaginate(network, imaginate_node, (document, document_id), layer_path, editor_api, persistent_data)?);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
// Execute the node graph
|
// Execute the node graph
|
||||||
@@ -272,8 +272,8 @@ impl NodeGraphExecutor {
|
|||||||
// Update the cached vector data on the layer
|
// Update the cached vector data on the layer
|
||||||
let vector_data: VectorData = dyn_any::downcast(boxed_node_graph_output).map(|v| *v)?;
|
let vector_data: VectorData = dyn_any::downcast(boxed_node_graph_output).map(|v| *v)?;
|
||||||
let transform = vector_data.transform.to_cols_array();
|
let transform = vector_data.transform.to_cols_array();
|
||||||
responses.push_back(Operation::SetLayerTransform { path: layer_path.clone(), transform }.into());
|
responses.add(Operation::SetLayerTransform { path: layer_path.clone(), transform });
|
||||||
responses.push_back(Operation::SetVectorData { path: layer_path, vector_data }.into());
|
responses.add(Operation::SetVectorData { path: layer_path, vector_data });
|
||||||
} else {
|
} else {
|
||||||
// Attempt to downcast to an image frame
|
// Attempt to downcast to an image frame
|
||||||
let ImageFrame { image, transform } = dyn_any::downcast(boxed_node_graph_output).map(|image_frame| *image_frame)?;
|
let ImageFrame { image, transform } = dyn_any::downcast(boxed_node_graph_output).map(|image_frame| *image_frame)?;
|
||||||
@@ -283,11 +283,11 @@ impl NodeGraphExecutor {
|
|||||||
|
|
||||||
// If no image was generated, clear the frame
|
// If no image was generated, clear the frame
|
||||||
if image.width == 0 || image.height == 0 {
|
if image.width == 0 || image.height == 0 {
|
||||||
responses.push_back(DocumentMessage::FrameClear.into());
|
responses.add(DocumentMessage::FrameClear);
|
||||||
|
|
||||||
// Update the transform based on the graph output
|
// Update the transform based on the graph output
|
||||||
if let Some(transform) = transform {
|
if let Some(transform) = transform {
|
||||||
responses.push_back(Operation::SetLayerTransform { path: layer_path.clone(), transform }.into());
|
responses.add(Operation::SetLayerTransform { path: layer_path.clone(), transform });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Update the image data
|
// Update the image data
|
||||||
@@ -301,7 +301,7 @@ impl NodeGraphExecutor {
|
|||||||
mime,
|
mime,
|
||||||
transform,
|
transform,
|
||||||
}];
|
}];
|
||||||
responses.push_back(FrontendMessage::UpdateImageData { document_id, image_data }.into());
|
responses.add(FrontendMessage::UpdateImageData { document_id, image_data });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user