Transform API (#301)

* Enforce cache dirtification

* Turn all shapes into one struct

* Remove working folder

* Remove old shapes

* Major restructuring

* Refactor Ellipse, Rectangle and ShapeTool

* Simplify bounding box calculation for folder

* Fix panic in select tool

*  Refactorselect tool

* Refactor Align

* Refactor flipping layers

* Zoom to fit all

* Refactor tools to avoid state keeping

* Refactor more tools to use state that is passed along

* Fix whitespace + change selection box style

* Set viewbox of svg export based on the contents
This commit is contained in:
TrueDoctor
2021-08-06 12:34:30 +02:00
committed by GitHub
parent 63a4ed64c8
commit f79e6e378d
55 changed files with 2059 additions and 2251 deletions

View File

@@ -117,7 +117,7 @@
<script lang="ts">
import { defineComponent } from "vue";
import { ResponseType, registerResponseHandler, Response, BlendMode, ExpandFolder, LayerPanelEntry } from "@/utilities/response-handler";
import { ResponseType, registerResponseHandler, Response, BlendMode, ExpandFolder, UpdateLayer, LayerPanelEntry } from "@/utilities/response-handler";
import { SeparatorType } from "@/components/widgets/widgets";
import LayoutRow from "@/components/layout/LayoutRow.vue";
@@ -324,6 +324,22 @@ export default defineComponent({
registerResponseHandler(ResponseType.CollapseFolder, (responseData) => {
console.log("CollapseFolder: ", responseData);
});
registerResponseHandler(ResponseType.UpdateLayer, (responseData) => {
const updateData = responseData as UpdateLayer;
if (updateData) {
const responsePath = updateData.path;
const responseLayer = updateData.data;
const index = this.layers.findIndex((layer: LayerPanelEntry) => {
const pathLengthsEqual = responsePath.length === layer.path.length;
return pathLengthsEqual && responsePath.every((layer_id, i) => layer_id === layer.path[i]);
});
if (index >= 0) this.layers[index] = responseLayer;
this.setBlendModeForSelectedLayers();
this.setOpacityForSelectedLayers();
}
});
},
data() {
return {

View File

@@ -20,6 +20,7 @@ export enum ResponseType {
SetActiveDocument = "SetActiveDocument",
UpdateOpenDocumentsList = "UpdateOpenDocumentsList",
UpdateWorkingColors = "UpdateWorkingColors",
UpdateLayer = "UpdateLayer",
SetCanvasZoom = "SetCanvasZoom",
SetCanvasRotation = "SetCanvasRotation",
DisplayConfirmationToCloseDocument = "DisplayConfirmationToCloseDocument",
@@ -61,6 +62,8 @@ function parseResponse(responseType: string, data: any): Response {
return newUpdateOpenDocumentsList(data.UpdateOpenDocumentsList);
case "UpdateCanvas":
return newUpdateCanvas(data.UpdateCanvas);
case "UpdateLayer":
return newUpdateLayer(data.UpdateLayer);
case "SetCanvasZoom":
return newSetCanvasZoom(data.SetCanvasZoom);
case "SetCanvasRotation":
@@ -168,7 +171,18 @@ export interface CollapseFolder {
}
function newCollapseFolder(input: any): CollapseFolder {
return {
path: new BigUint64Array(input.path.map((n: number) => BigInt(n))),
path: newPath(input.path),
};
}
export interface UpdateLayer {
path: BigUint64Array;
data: LayerPanelEntry;
}
function newUpdateLayer(input: any): UpdateLayer {
return {
path: newPath(input.data.path),
data: newLayerPanelEntry(input.data),
};
}
@@ -178,7 +192,7 @@ export interface ExpandFolder {
}
function newExpandFolder(input: any): ExpandFolder {
return {
path: new BigUint64Array(input.path.map((n: number) => BigInt(n))),
path: newPath(input.path),
children: input.children.map((child: any) => newLayerPanelEntry(child)),
};
}
@@ -201,6 +215,12 @@ function newSetCanvasRotation(input: any): SetCanvasRotation {
};
}
function newPath(input: any): BigUint64Array {
// eslint-disable-next-line
const u32CombinedPairs = input.map((n: Array<bigint>) => BigInt((BigInt(n[0]) << BigInt(32)) | BigInt(n[1])));
return new BigUint64Array(u32CombinedPairs);
}
export enum BlendMode {
Normal = "normal",
Multiply = "multiply",
@@ -266,7 +286,7 @@ function newLayerPanelEntry(input: any): LayerPanelEntry {
opacity: newOpacity(input.opacity),
layer_type: newLayerType(input.layer_type),
layer_data: newLayerData(input.layer_data),
path: new BigUint64Array(input.path.map((n: number) => BigInt(n))),
path: newPath(input.path),
thumbnail: input.thumbnail,
};
}

View File

@@ -7,10 +7,7 @@ use editor_core::input::mouse::ScrollDelta;
use editor_core::message_prelude::*;
use editor_core::misc::EditorError;
use editor_core::tool::{tool_options::ToolOptions, tools, ToolType};
use editor_core::{
input::mouse::{MouseState, ViewportPosition},
LayerId,
};
use editor_core::{input::mouse::MouseState, LayerId};
use wasm_bindgen::prelude::*;
fn convert_error(err: editor_core::EditorError) -> JsValue {
@@ -59,44 +56,44 @@ pub fn send_tool_message(tool: String, message: &JsValue) -> Result<(), JsValue>
#[wasm_bindgen]
pub fn select_document(document: usize) -> Result<(), JsValue> {
EDITOR_STATE.with(|editor| editor.borrow_mut().handle_message(DocumentMessage::SelectDocument(document)).map_err(convert_error))
EDITOR_STATE.with(|editor| editor.borrow_mut().handle_message(DocumentsMessage::SelectDocument(document)).map_err(convert_error))
}
#[wasm_bindgen]
pub fn get_open_documents_list() -> Result<(), JsValue> {
EDITOR_STATE.with(|editor| editor.borrow_mut().handle_message(DocumentMessage::GetOpenDocumentsList).map_err(convert_error))
EDITOR_STATE.with(|editor| editor.borrow_mut().handle_message(DocumentsMessage::GetOpenDocumentsList).map_err(convert_error))
}
#[wasm_bindgen]
pub fn new_document() -> Result<(), JsValue> {
EDITOR_STATE.with(|editor| editor.borrow_mut().handle_message(DocumentMessage::NewDocument).map_err(convert_error))
EDITOR_STATE.with(|editor| editor.borrow_mut().handle_message(DocumentsMessage::NewDocument).map_err(convert_error))
}
#[wasm_bindgen]
pub fn close_document(document: usize) -> Result<(), JsValue> {
EDITOR_STATE.with(|editor| editor.borrow_mut().handle_message(DocumentMessage::CloseDocument(document)).map_err(convert_error))
EDITOR_STATE.with(|editor| editor.borrow_mut().handle_message(DocumentsMessage::CloseDocument(document)).map_err(convert_error))
}
#[wasm_bindgen]
pub fn close_all_documents() -> Result<(), JsValue> {
EDITOR_STATE.with(|editor| editor.borrow_mut().handle_message(DocumentMessage::CloseAllDocuments).map_err(convert_error))
EDITOR_STATE.with(|editor| editor.borrow_mut().handle_message(DocumentsMessage::CloseAllDocuments).map_err(convert_error))
}
#[wasm_bindgen]
pub fn close_active_document_with_confirmation() -> Result<(), JsValue> {
EDITOR_STATE.with(|editor| editor.borrow_mut().handle_message(DocumentMessage::CloseActiveDocumentWithConfirmation).map_err(convert_error))
EDITOR_STATE.with(|editor| editor.borrow_mut().handle_message(DocumentsMessage::CloseActiveDocumentWithConfirmation).map_err(convert_error))
}
#[wasm_bindgen]
pub fn close_all_documents_with_confirmation() -> Result<(), JsValue> {
EDITOR_STATE.with(|editor| editor.borrow_mut().handle_message(DocumentMessage::CloseAllDocumentsWithConfirmation).map_err(convert_error))
EDITOR_STATE.with(|editor| editor.borrow_mut().handle_message(DocumentsMessage::CloseAllDocumentsWithConfirmation).map_err(convert_error))
}
// TODO: Call event when the panels are resized
/// Viewport resized
#[wasm_bindgen]
pub fn viewport_resize(new_width: u32, new_height: u32) -> Result<(), JsValue> {
let ev = InputPreprocessorMessage::ViewportResize(ViewportPosition { x: new_width, y: new_height });
let ev = InputPreprocessorMessage::ViewportResize((new_width, new_height).into());
EDITOR_STATE.with(|editor| editor.borrow_mut().handle_message(ev)).map_err(convert_error)
}
@@ -106,7 +103,7 @@ pub fn viewport_resize(new_width: u32, new_height: u32) -> Result<(), JsValue> {
pub fn on_mouse_move(x: u32, y: u32, modifiers: u8) -> Result<(), JsValue> {
let mods = ModifierKeys::from_bits(modifiers).expect("invalid modifier keys");
// TODO: Convert these screenspace viewport coordinates to canvas coordinates based on the current zoom and pan
let ev = InputPreprocessorMessage::MouseMove(ViewportPosition { x, y }, mods);
let ev = InputPreprocessorMessage::MouseMove((x, y).into(), mods);
EDITOR_STATE.with(|editor| editor.borrow_mut().handle_message(ev)).map_err(convert_error)
}
@@ -122,18 +119,16 @@ pub fn on_mouse_scroll(delta_x: i32, delta_y: i32, delta_z: i32, modifiers: u8)
/// A mouse button depressed within screenspace the bounds of the viewport
#[wasm_bindgen]
pub fn on_mouse_down(x: u32, y: u32, mouse_keys: u8, modifiers: u8) -> Result<(), JsValue> {
let pos = ViewportPosition { x, y };
let mods = ModifierKeys::from_bits(modifiers).expect("invalid modifier keys");
let ev = InputPreprocessorMessage::MouseDown(MouseState::from_u8_pos(mouse_keys, pos), mods);
let ev = InputPreprocessorMessage::MouseDown(MouseState::from_u8_pos(mouse_keys, (x, y).into()), mods);
EDITOR_STATE.with(|editor| editor.borrow_mut().handle_message(ev)).map_err(convert_error)
}
/// A mouse button released
#[wasm_bindgen]
pub fn on_mouse_up(x: u32, y: u32, mouse_keys: u8, modifiers: u8) -> Result<(), JsValue> {
let pos = ViewportPosition { x, y };
let mods = ModifierKeys::from_bits(modifiers).expect("invalid modifier keys");
let ev = InputPreprocessorMessage::MouseUp(MouseState::from_u8_pos(mouse_keys, pos), mods);
let ev = InputPreprocessorMessage::MouseUp(MouseState::from_u8_pos(mouse_keys, (x, y).into()), mods);
EDITOR_STATE.with(|editor| editor.borrow_mut().handle_message(ev)).map_err(convert_error)
}
@@ -259,14 +254,14 @@ pub fn export_document() -> Result<(), JsValue> {
/// Sets the zoom to the value
#[wasm_bindgen]
pub fn set_zoom(new_zoom: f64) -> Result<(), JsValue> {
let ev = DocumentMessage::SetCanvasZoom(new_zoom);
let ev = MovementMessage::SetCanvasZoom(new_zoom);
EDITOR_STATE.with(|editor| editor.borrow_mut().handle_message(ev)).map_err(convert_error)
}
/// Sets the rotation to the new value (in radians)
#[wasm_bindgen]
pub fn set_rotation(new_radians: f64) -> Result<(), JsValue> {
let ev = DocumentMessage::SetCanvasRotation(new_radians);
let ev = MovementMessage::SetCanvasRotation(new_radians);
EDITOR_STATE.with(|editor| editor.borrow_mut().handle_message(ev)).map_err(convert_error)
}