Move layouts definitions to backend and fix Firefox overlay scrollbars (#647)

* Fix two-axis scrollbars in scrollable regions on Firefox

* Move Document Mode dropdown to the backend; and related code cleanup

* Port the Layer Tree options bar layout to the backend

* Port the tool shelf to the backend

* Clean up initialization and wasm wrapper

* Fix crash

* Fix missing document bar

* Remove unused functions in api.rs

* Code review

* Tool initalisation

* Remove some frontend functions

* Initalise -> Init so en-US/GB doesn't have to matter :)

* Remove blend_mode and opacity from LayerPanelEntry

Co-authored-by: 0hypercube <0hypercube@gmail.com>
This commit is contained in:
Keavon Chambers
2022-05-17 13:12:52 -07:00
co-authored by 0hypercube
parent e7d63276ad
commit 29e00e488b
50 changed files with 1034 additions and 978 deletions
+18 -102
View File
@@ -2,17 +2,13 @@
// It serves as a thin wrapper over the editor backend API that relies
// on the dispatcher messaging system and more complex Rust data types.
use crate::helpers::Error;
use crate::type_translators::{translate_blend_mode, translate_key, translate_tool_type};
use crate::helpers::{translate_key, Error};
use crate::{EDITOR_HAS_CRASHED, EDITOR_INSTANCES, JS_EDITOR_HANDLES};
use editor::consts::{FILE_SAVE_SUFFIX, GRAPHITE_DOCUMENT_VERSION};
use editor::input::input_preprocessor::ModifierKeys;
use editor::input::mouse::{EditorMouseState, ScrollDelta, ViewportBounds};
use editor::message_prelude::*;
use editor::misc::EditorError;
use editor::viewport_tools::tool::ToolType;
use editor::viewport_tools::tools;
use editor::Color;
use editor::Editor;
use editor::LayerId;
@@ -96,19 +92,6 @@ impl JsEditorHandle {
self.dispatch(WorkspaceMessage::NodeGraphToggleVisibility);
}
/// Modify the currently selected tool in the document state store
pub fn select_tool(&self, tool: String) -> Result<(), JsValue> {
match translate_tool_type(&tool) {
Some(tool_type) => {
let message = ToolMessage::ActivateTool { tool_type };
self.dispatch(message);
Ok(())
}
None => Err(Error::new(&format!("Couldn't select {} because it was not recognized as a valid tool", tool)).into()),
}
}
/// Update layout of a given UI
pub fn update_layout(&self, layout_target: JsValue, widget_id: u64, value: JsValue) -> Result<(), JsValue> {
match (from_value(layout_target), from_value(value)) {
@@ -121,29 +104,6 @@ impl JsEditorHandle {
}
}
/// Send a message to a given tool
pub fn send_tool_message(&self, tool: String, message: &JsValue) -> Result<(), JsValue> {
let tool_message = match translate_tool_type(&tool) {
Some(tool) => match tool {
ToolType::Select => match serde_wasm_bindgen::from_value::<tools::select_tool::SelectToolMessage>(message.clone()) {
Ok(select_message) => Ok(ToolMessage::Select(select_message)),
Err(err) => Err(Error::new(&format!("Invalid message for {}: {}", tool, err)).into()),
},
_ => Err(Error::new(&format!("Tool message sending not implemented for {}", tool)).into()),
},
None => Err(Error::new(&format!("Couldn't send message for {} because it was not recognized as a valid tool", tool)).into()),
};
match tool_message {
Ok(message) => {
self.dispatch(message);
Ok(())
}
Err(err) => Err(err),
}
}
pub fn select_document(&self, document_id: u64) {
let message = PortfolioMessage::SelectDocument { document_id };
self.dispatch(message);
@@ -442,12 +402,6 @@ impl JsEditorHandle {
self.dispatch(message);
}
/// Delete all selected layers
pub fn delete_selected_layers(&self) {
let message = DocumentMessage::DeleteSelectedLayers;
self.dispatch(message);
}
/// Reorder selected layer
pub fn reorder_selected_layers(&self, relative_index_offset: isize) {
let message = DocumentMessage::ReorderSelectedLayers { relative_index_offset };
@@ -470,25 +424,6 @@ impl JsEditorHandle {
self.dispatch(message);
}
/// Set the blend mode for the selected layers
pub fn set_blend_mode_for_selected_layers(&self, blend_mode_svg_style_name: String) -> Result<(), JsValue> {
if let Some(blend_mode) = translate_blend_mode(blend_mode_svg_style_name.as_str()) {
let message = DocumentMessage::SetBlendModeForSelectedLayers { blend_mode };
self.dispatch(message);
Ok(())
} else {
Err(Error::new(&EditorError::Misc("UnknownBlendMode".to_string()).to_string()).into())
}
}
/// Set the opacity for the selected layers
pub fn set_opacity_for_selected_layers(&self, opacity_percent: f64) {
let opacity = opacity_percent / 100.;
let message = DocumentMessage::SetOpacityForSelectedLayers { opacity };
self.dispatch(message);
}
/// Export the document
pub fn export_document(&self) {
let message = DialogMessage::RequestExportDialog;
@@ -507,13 +442,6 @@ impl JsEditorHandle {
self.dispatch(message);
}
/// Update the list of selected layers. The layer paths have to be stored in one array and are separated by LayerId::MAX
pub fn select_layers(&self, paths: Vec<LayerId>) {
let replacement_selected_layers = paths.split(|id| *id == LayerId::MAX).map(|path| path.to_vec()).collect();
let message = DocumentMessage::SetSelectedLayers { replacement_selected_layers };
self.dispatch(message);
}
/// Sends the blob url generated by js
pub fn set_image_blob_url(&self, path: Vec<LayerId>, blob_url: String, width: f64, height: f64) {
let dimensions = (width, height);
@@ -540,29 +468,14 @@ impl JsEditorHandle {
self.dispatch(message);
}
/// Renames a layer from the layer list
pub fn rename_layer(&self, layer_path: Vec<LayerId>, new_name: String) {
let message = DocumentMessage::RenameLayer { layer_path, new_name };
// TODO: Replace with initialization system, issue #524
pub fn init_app(&self) {
let message = PortfolioMessage::UpdateDocumentWidgets;
self.dispatch(message);
}
/// Deletes a layer from the layer list
pub fn delete_layer(&self, layer_path: Vec<LayerId>) {
let message = DocumentMessage::DeleteLayer { layer_path };
let message = ToolMessage::InitTools;
self.dispatch(message);
}
/// Creates an empty folder at the document root
pub fn create_empty_folder(&self) {
let message = DocumentMessage::CreateEmptyFolder { container_path: vec![] };
self.dispatch(message);
}
// TODO(mfish33): Replace with initialization system Issue:#524
pub fn init_document_bar(&self) {
let message = PortfolioMessage::UpdateDocumentBar;
self.dispatch(message)
}
}
// Needed to make JsEditorHandle functions pub to rust. Do not fully
@@ -579,10 +492,11 @@ impl Drop for JsEditorHandle {
}
}
/// Access a handle to WASM memory
/// Set the random seed used by the editor by calling this from JS upon initialization.
/// This is necessary because WASM doesn't have a random number generator.
#[wasm_bindgen]
pub fn wasm_memory() -> JsValue {
wasm_bindgen::memory()
pub fn set_random_seed(seed: u64) {
editor::communication::set_uuid_seed(seed)
}
/// Intentionally panic for debugging purposes
@@ -591,17 +505,24 @@ pub fn intentional_panic() {
panic!();
}
/// Get the constant FILE_SAVE_SUFFIX
/// Access a handle to WASM memory
#[wasm_bindgen]
pub fn wasm_memory() -> JsValue {
wasm_bindgen::memory()
}
/// Get the constant `FILE_SAVE_SUFFIX`
#[wasm_bindgen]
pub fn file_save_suffix() -> String {
FILE_SAVE_SUFFIX.into()
}
/// Get the constant FILE_SAVE_SUFFIX
/// Get the constant `GRAPHITE_DOCUMENT_VERSION`
#[wasm_bindgen]
pub fn graphite_version() -> String {
GRAPHITE_DOCUMENT_VERSION.to_string()
}
/// Get the constant `i32::MAX`
#[wasm_bindgen]
pub fn i32_max() -> i32 {
@@ -613,8 +534,3 @@ pub fn i32_max() -> i32 {
pub fn i32_min() -> i32 {
i32::MIN
}
#[wasm_bindgen]
pub fn set_random_seed(seed: u64) {
editor::communication::set_uuid_seed(seed)
}