mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-22 22:58:12 +08:00
Bundle Graphite using Tauri (#873)
* Setup tauri component for graphite editor Integrate graphite into tauri app Split interpreted-executor out of graph-craft * Add gpu execution node * General Cleanup
This commit is contained in:
committed by
Keavon Chambers
parent
52cc770a1e
commit
7d8f94462a
@@ -3,7 +3,7 @@ use crate::messages::layout::utility_types::layout_widget::SubLayout;
|
||||
use crate::messages::layout::utility_types::misc::LayoutTarget;
|
||||
use crate::messages::layout::utility_types::widgets::menu_widgets::MenuBarEntry;
|
||||
use crate::messages::portfolio::document::node_graph::{FrontendNode, FrontendNodeLink, FrontendNodeType};
|
||||
use crate::messages::portfolio::document::utility_types::layer_panel::{LayerPanelEntry, RawBuffer};
|
||||
use crate::messages::portfolio::document::utility_types::layer_panel::{JsRawBuffer, LayerPanelEntry, RawBuffer};
|
||||
use crate::messages::prelude::*;
|
||||
use crate::messages::tool::utility_types::HintData;
|
||||
|
||||
@@ -156,6 +156,10 @@ pub enum FrontendMessage {
|
||||
#[serde(rename = "dataBuffer")]
|
||||
data_buffer: RawBuffer,
|
||||
},
|
||||
UpdateDocumentLayerTreeStructureJs {
|
||||
#[serde(rename = "dataBuffer")]
|
||||
data_buffer: JsRawBuffer,
|
||||
},
|
||||
UpdateDocumentModeLayout {
|
||||
#[serde(rename = "layoutTarget")]
|
||||
layout_target: LayoutTarget,
|
||||
|
||||
@@ -16,7 +16,7 @@ pub struct FrontendImageData {
|
||||
pub path: Vec<LayerId>,
|
||||
pub mime: String,
|
||||
#[serde(skip)]
|
||||
pub image_data: std::rc::Rc<Vec<u8>>,
|
||||
pub image_data: std::sync::Arc<Vec<u8>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
|
||||
|
||||
@@ -4,7 +4,6 @@ use crate::messages::prelude::*;
|
||||
pub use graphene::DocumentResponse;
|
||||
|
||||
use bitflags::bitflags;
|
||||
use serde::ser::SerializeStruct;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign};
|
||||
@@ -51,7 +50,7 @@ bitflags! {
|
||||
// (although we ignore the shift key, so the user doesn't have to press `Ctrl Shift +` on a US keyboard), even if the keyboard layout
|
||||
// is for a different locale where the `+` key is somewhere entirely different, shifted or not. This would then also work for numpad `+`.
|
||||
#[impl_message(Message, InputMapperMessage, KeyDown)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Deserialize)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Deserialize, Serialize)]
|
||||
pub enum Key {
|
||||
// Writing system keys
|
||||
Digit0,
|
||||
@@ -210,18 +209,6 @@ pub enum Key {
|
||||
NumKeys,
|
||||
}
|
||||
|
||||
impl Serialize for Key {
|
||||
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
let key = format!("{:?}", self);
|
||||
let label = self.to_string();
|
||||
|
||||
let mut state = serializer.serialize_struct("KeyWithLabel", 2)?;
|
||||
state.serialize_field("key", &key)?;
|
||||
state.serialize_field("label", &label)?;
|
||||
state.end()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Key {
|
||||
// TODO: Relevant key labels should be localized when we get around to implementing localization/internationalization
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result {
|
||||
@@ -308,6 +295,35 @@ impl fmt::Display for Key {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Key> for LayoutKey {
|
||||
fn from(key: Key) -> Self {
|
||||
Self {
|
||||
key: format!("{:?}", key),
|
||||
label: key.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
struct LayoutKey {
|
||||
key: String,
|
||||
label: String,
|
||||
}
|
||||
/*
|
||||
impl Serialize for Key {
|
||||
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
let key = format!("{:?}", self.0);
|
||||
let label = self.0.to_string();
|
||||
|
||||
assert_eq!(serde_json::to_string(Key::KeyEscape), {"key": KeyEscape, "label": "Esc"});
|
||||
|
||||
let mut state = serializer.serialize_struct("KeyWithLabel", 2)?;
|
||||
state.serialize_field("key", &key)?;
|
||||
state.serialize_field("label", &label)?;
|
||||
state.end()
|
||||
}
|
||||
}*/
|
||||
|
||||
pub const NUMBER_OF_KEYS: usize = Key::NumKeys as usize;
|
||||
|
||||
/// Only `Key`s that exist on a physical keyboard should be used.
|
||||
@@ -342,6 +358,22 @@ impl fmt::Display for KeysGroup {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<KeysGroup> for String {
|
||||
fn from(keys: KeysGroup) -> Self {
|
||||
let layout_keys: LayoutKeysGroup = keys.into();
|
||||
serde_json::to_string(&layout_keys).expect("Failed to serialize KeysGroup")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct LayoutKeysGroup(Vec<LayoutKey>);
|
||||
|
||||
impl From<KeysGroup> for LayoutKeysGroup {
|
||||
fn from(keys_group: KeysGroup) -> Self {
|
||||
Self(keys_group.0.into_iter().map(|key| key.into()).collect())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum MouseMotion {
|
||||
None,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use super::input_keyboard::{all_required_modifiers_pressed, KeysGroup};
|
||||
use super::input_keyboard::{all_required_modifiers_pressed, KeysGroup, LayoutKeysGroup};
|
||||
use crate::messages::input_mapper::default_mapping::default_mapping;
|
||||
use crate::messages::input_mapper::utility_types::input_keyboard::{KeyStates, NUMBER_OF_KEYS};
|
||||
use crate::messages::prelude::*;
|
||||
@@ -81,24 +81,27 @@ pub struct MappingEntry {
|
||||
pub enum ActionKeys {
|
||||
Action(MessageDiscriminant),
|
||||
#[serde(rename = "keys")]
|
||||
Keys(KeysGroup),
|
||||
Keys(LayoutKeysGroup),
|
||||
}
|
||||
|
||||
impl ActionKeys {
|
||||
pub fn to_keys(&mut self, action_input_mapping: &impl Fn(&MessageDiscriminant) -> Vec<KeysGroup>) {
|
||||
pub fn to_keys(&mut self, action_input_mapping: &impl Fn(&MessageDiscriminant) -> Vec<KeysGroup>) -> String {
|
||||
match self {
|
||||
ActionKeys::Action(action) => {
|
||||
if let Some(keys) = action_input_mapping(action).get_mut(0) {
|
||||
let mut taken_keys = KeysGroup::default();
|
||||
std::mem::swap(keys, &mut taken_keys);
|
||||
|
||||
*self = ActionKeys::Keys(taken_keys);
|
||||
let description = taken_keys.to_string();
|
||||
*self = ActionKeys::Keys(taken_keys.into());
|
||||
description
|
||||
} else {
|
||||
*self = ActionKeys::Keys(KeysGroup::default());
|
||||
*self = ActionKeys::Keys(KeysGroup::default().into());
|
||||
String::new()
|
||||
}
|
||||
}
|
||||
ActionKeys::Keys(keys) => {
|
||||
warn!("Calling `.to_keys()` on a `ActionKeys::Keys` is a mistake/bug. Keys are: {:?}.", keys);
|
||||
String::new()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ use crate::messages::layout::utility_types::misc::LayoutTarget;
|
||||
use crate::messages::prelude::*;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub trait PropertyHolder {
|
||||
fn properties(&self) -> Layout {
|
||||
@@ -39,11 +39,9 @@ impl Layout {
|
||||
if let Layout::WidgetLayout(mut widget_layout) = self {
|
||||
// Function used multiple times later in this code block to convert `ActionKeys::Action` to `ActionKeys::Keys` and append its shortcut to the tooltip
|
||||
let apply_shortcut_to_tooltip = |tooltip_shortcut: &mut ActionKeys, tooltip: &mut String| {
|
||||
tooltip_shortcut.to_keys(action_input_mapping);
|
||||
|
||||
if let ActionKeys::Keys(keys) = tooltip_shortcut {
|
||||
let shortcut_text = keys.to_string();
|
||||
let shortcut_text = tooltip_shortcut.to_keys(action_input_mapping);
|
||||
|
||||
if let ActionKeys::Keys(_keys) = tooltip_shortcut {
|
||||
if !shortcut_text.is_empty() {
|
||||
if !tooltip.is_empty() {
|
||||
tooltip.push(' ');
|
||||
@@ -279,12 +277,12 @@ impl WidgetHolder {
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct WidgetCallback<T> {
|
||||
pub callback: Rc<dyn Fn(&T) -> Message + 'static>,
|
||||
pub callback: Arc<dyn Fn(&T) -> Message + 'static + Send + Sync>,
|
||||
}
|
||||
|
||||
impl<T> WidgetCallback<T> {
|
||||
pub fn new(callback: impl Fn(&T) -> Message + 'static) -> Self {
|
||||
Self { callback: Rc::new(callback) }
|
||||
pub fn new(callback: impl Fn(&T) -> Message + 'static + Send + Sync) -> Self {
|
||||
Self { callback: Arc::new(callback) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ impl MenuBarEntry {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_action(callback: impl Fn(&()) -> Message + 'static) -> WidgetHolder {
|
||||
pub fn create_action(callback: impl Fn(&()) -> Message + 'static + Send + Sync) -> WidgetHolder {
|
||||
WidgetHolder::new(Widget::InvisibleStandinInput(InvisibleStandinInput {
|
||||
on_update: WidgetCallback::new(callback),
|
||||
}))
|
||||
|
||||
@@ -548,7 +548,7 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
let image_data = std::rc::Rc::new(image_data);
|
||||
let image_data = std::sync::Arc::new(image_data);
|
||||
responses.push_back(
|
||||
FrontendMessage::UpdateImageData {
|
||||
document_id,
|
||||
|
||||
@@ -162,7 +162,7 @@ impl MessageHandler<NavigationMessage, (&Document, &InputPreprocessorMessageHand
|
||||
responses.push_back(
|
||||
FrontendMessage::UpdateInputHints {
|
||||
hint_data: HintData(vec![HintGroup(vec![HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Control])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Control]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Snap 15°"),
|
||||
@@ -244,7 +244,7 @@ impl MessageHandler<NavigationMessage, (&Document, &InputPreprocessorMessageHand
|
||||
responses.push_back(
|
||||
FrontendMessage::UpdateInputHints {
|
||||
hint_data: HintData(vec![HintGroup(vec![HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Control])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Control]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Snap Increments"),
|
||||
|
||||
@@ -18,6 +18,8 @@ pub enum FrontendGraphDataType {
|
||||
Raster,
|
||||
#[serde(rename = "color")]
|
||||
Color,
|
||||
#[serde(rename = "text")]
|
||||
Text,
|
||||
#[serde(rename = "vector")]
|
||||
Subpath,
|
||||
#[serde(rename = "number")]
|
||||
|
||||
+28
-16
@@ -2,14 +2,11 @@ use super::{node_properties, FrontendGraphDataType, FrontendNodeType};
|
||||
use crate::messages::layout::utility_types::layout_widget::{LayoutGroup, Widget, WidgetHolder};
|
||||
use crate::messages::layout::utility_types::widgets::label_widgets::TextLabel;
|
||||
|
||||
use glam::DVec2;
|
||||
use graph_craft::concrete;
|
||||
use graph_craft::document::value::TaggedValue;
|
||||
use graph_craft::document::{DocumentNode, NodeId, NodeInput};
|
||||
use graph_craft::proto::{NodeIdentifier, Type};
|
||||
use graphene_std::raster::Image;
|
||||
use graphene_std::vector::subpath::Subpath;
|
||||
|
||||
use std::borrow::Cow;
|
||||
use graphene_core::raster::Image;
|
||||
|
||||
pub struct DocumentInputType {
|
||||
pub name: &'static str,
|
||||
@@ -39,7 +36,7 @@ static DOCUMENT_NODE_TYPES: &[DocumentNodeType] = &[
|
||||
DocumentNodeType {
|
||||
name: "Identity",
|
||||
category: "General",
|
||||
identifier: NodeIdentifier::new("graphene_core::ops::IdNode", &[Type::Concrete(Cow::Borrowed("Any<'_>"))]),
|
||||
identifier: NodeIdentifier::new("graphene_core::ops::IdNode", &[concrete!("Any<'_>")]),
|
||||
inputs: &[DocumentInputType {
|
||||
name: "In",
|
||||
data_type: FrontendGraphDataType::General,
|
||||
@@ -58,7 +55,7 @@ static DOCUMENT_NODE_TYPES: &[DocumentNodeType] = &[
|
||||
DocumentNodeType {
|
||||
name: "Input",
|
||||
category: "Meta",
|
||||
identifier: NodeIdentifier::new("graphene_core::ops::IdNode", &[Type::Concrete(Cow::Borrowed("Any<'_>"))]),
|
||||
identifier: NodeIdentifier::new("graphene_core::ops::IdNode", &[concrete!("Any<'_>")]),
|
||||
inputs: &[DocumentInputType {
|
||||
name: "In",
|
||||
data_type: FrontendGraphDataType::Raster,
|
||||
@@ -70,7 +67,7 @@ static DOCUMENT_NODE_TYPES: &[DocumentNodeType] = &[
|
||||
DocumentNodeType {
|
||||
name: "Output",
|
||||
category: "Meta",
|
||||
identifier: NodeIdentifier::new("graphene_core::ops::IdNode", &[Type::Concrete(Cow::Borrowed("Any<'_>"))]),
|
||||
identifier: NodeIdentifier::new("graphene_core::ops::IdNode", &[concrete!("Any<'_>")]),
|
||||
inputs: &[DocumentInputType {
|
||||
name: "In",
|
||||
data_type: FrontendGraphDataType::Raster,
|
||||
@@ -87,6 +84,21 @@ static DOCUMENT_NODE_TYPES: &[DocumentNodeType] = &[
|
||||
outputs: &[FrontendGraphDataType::Raster],
|
||||
properties: node_properties::no_properties,
|
||||
},
|
||||
DocumentNodeType {
|
||||
name: "GpuImage",
|
||||
category: "Image Adjustments",
|
||||
identifier: NodeIdentifier::new("graphene_std::executor::MapGpuSingleImageNode", &[concrete!("&TypeErasedNode")]),
|
||||
inputs: &[
|
||||
DocumentInputType::new("Image", TaggedValue::Image(Image::empty()), true),
|
||||
DocumentInputType {
|
||||
name: "Path",
|
||||
data_type: FrontendGraphDataType::Text,
|
||||
default: NodeInput::value(TaggedValue::String(String::new()), true),
|
||||
},
|
||||
],
|
||||
outputs: &[FrontendGraphDataType::Raster],
|
||||
properties: node_properties::gpu_map_properties,
|
||||
},
|
||||
DocumentNodeType {
|
||||
name: "Invert RGB",
|
||||
category: "Image Adjustments",
|
||||
@@ -98,7 +110,7 @@ static DOCUMENT_NODE_TYPES: &[DocumentNodeType] = &[
|
||||
DocumentNodeType {
|
||||
name: "Hue/Saturation",
|
||||
category: "Image Adjustments",
|
||||
identifier: NodeIdentifier::new("graphene_std::raster::HueSaturationNode", &[Type::Concrete(Cow::Borrowed("&TypeErasedNode"))]),
|
||||
identifier: NodeIdentifier::new("graphene_std::raster::HueSaturationNode", &[concrete!("&TypeErasedNode")]),
|
||||
inputs: &[
|
||||
DocumentInputType::new("Image", TaggedValue::Image(Image::empty()), true),
|
||||
DocumentInputType::new("Hue Shift", TaggedValue::F64(0.), false),
|
||||
@@ -111,7 +123,7 @@ static DOCUMENT_NODE_TYPES: &[DocumentNodeType] = &[
|
||||
DocumentNodeType {
|
||||
name: "Brightness/Contrast",
|
||||
category: "Image Adjustments",
|
||||
identifier: NodeIdentifier::new("graphene_std::raster::BrightnessContrastNode", &[Type::Concrete(Cow::Borrowed("&TypeErasedNode"))]),
|
||||
identifier: NodeIdentifier::new("graphene_std::raster::BrightnessContrastNode", &[concrete!("&TypeErasedNode")]),
|
||||
inputs: &[
|
||||
DocumentInputType::new("Image", TaggedValue::Image(Image::empty()), true),
|
||||
DocumentInputType::new("Brightness", TaggedValue::F64(0.), false),
|
||||
@@ -123,7 +135,7 @@ static DOCUMENT_NODE_TYPES: &[DocumentNodeType] = &[
|
||||
DocumentNodeType {
|
||||
name: "Gamma",
|
||||
category: "Image Adjustments",
|
||||
identifier: NodeIdentifier::new("graphene_std::raster::GammaNode", &[Type::Concrete(Cow::Borrowed("&TypeErasedNode"))]),
|
||||
identifier: NodeIdentifier::new("graphene_std::raster::GammaNode", &[concrete!("&TypeErasedNode")]),
|
||||
inputs: &[
|
||||
DocumentInputType::new("Image", TaggedValue::Image(Image::empty()), true),
|
||||
DocumentInputType::new("Gamma", TaggedValue::F64(1.), false),
|
||||
@@ -134,7 +146,7 @@ static DOCUMENT_NODE_TYPES: &[DocumentNodeType] = &[
|
||||
DocumentNodeType {
|
||||
name: "Opacity",
|
||||
category: "Image Adjustments",
|
||||
identifier: NodeIdentifier::new("graphene_std::raster::OpacityNode", &[Type::Concrete(Cow::Borrowed("&TypeErasedNode"))]),
|
||||
identifier: NodeIdentifier::new("graphene_std::raster::OpacityNode", &[concrete!("&TypeErasedNode")]),
|
||||
inputs: &[
|
||||
DocumentInputType::new("Image", TaggedValue::Image(Image::empty()), true),
|
||||
DocumentInputType::new("Factor", TaggedValue::F64(1.), false),
|
||||
@@ -145,7 +157,7 @@ static DOCUMENT_NODE_TYPES: &[DocumentNodeType] = &[
|
||||
DocumentNodeType {
|
||||
name: "Posterize",
|
||||
category: "Image Adjustments",
|
||||
identifier: NodeIdentifier::new("graphene_std::raster::PosterizeNode", &[Type::Concrete(Cow::Borrowed("&TypeErasedNode"))]),
|
||||
identifier: NodeIdentifier::new("graphene_std::raster::PosterizeNode", &[concrete!("&TypeErasedNode")]),
|
||||
inputs: &[
|
||||
DocumentInputType::new("Image", TaggedValue::Image(Image::empty()), true),
|
||||
DocumentInputType::new("Value", TaggedValue::F64(5.), false),
|
||||
@@ -156,7 +168,7 @@ static DOCUMENT_NODE_TYPES: &[DocumentNodeType] = &[
|
||||
DocumentNodeType {
|
||||
name: "Exposure",
|
||||
category: "Image Adjustments",
|
||||
identifier: NodeIdentifier::new("graphene_std::raster::ExposureNode", &[Type::Concrete(Cow::Borrowed("&TypeErasedNode"))]),
|
||||
identifier: NodeIdentifier::new("graphene_std::raster::ExposureNode", &[concrete!("&TypeErasedNode")]),
|
||||
inputs: &[
|
||||
DocumentInputType::new("Image", TaggedValue::Image(Image::empty()), true),
|
||||
DocumentInputType::new("Value", TaggedValue::F64(0.), false),
|
||||
@@ -167,7 +179,7 @@ static DOCUMENT_NODE_TYPES: &[DocumentNodeType] = &[
|
||||
DocumentNodeType {
|
||||
name: "Add",
|
||||
category: "Math",
|
||||
identifier: NodeIdentifier::new("graphene_core::ops::AddNode", &[Type::Concrete(Cow::Borrowed("&TypeErasedNode"))]),
|
||||
identifier: NodeIdentifier::new("graphene_core::ops::AddNode", &[concrete!("&TypeErasedNode")]),
|
||||
inputs: &[
|
||||
DocumentInputType::new("Input", TaggedValue::F64(0.), true),
|
||||
DocumentInputType::new("Addend", TaggedValue::F64(0.), true),
|
||||
@@ -194,7 +206,7 @@ static DOCUMENT_NODE_TYPES: &[DocumentNodeType] = &[
|
||||
DocumentNodeType {
|
||||
name: "Path Generator",
|
||||
category: "Vector",
|
||||
identifier: NodeIdentifier::new("graphene_core::ops::IdNode", &[Type::Concrete(Cow::Borrowed("Any<'_>"))]),
|
||||
identifier: NodeIdentifier::new("graphene_core::ops::IdNode", &[concrete!("Any<'_>")]),
|
||||
inputs: &[DocumentInputType {
|
||||
name: "Path Data",
|
||||
data_type: FrontendGraphDataType::Subpath,
|
||||
|
||||
+34
-2
@@ -1,6 +1,6 @@
|
||||
use crate::messages::layout::utility_types::layout_widget::{LayoutGroup, Widget, WidgetCallback, WidgetHolder};
|
||||
use crate::messages::layout::utility_types::widgets::button_widgets::ParameterExposeButton;
|
||||
use crate::messages::layout::utility_types::widgets::input_widgets::{NumberInput, NumberInputMode};
|
||||
use crate::messages::layout::utility_types::widgets::input_widgets::{NumberInput, NumberInputMode, TextInput};
|
||||
use crate::messages::prelude::NodeGraphMessage;
|
||||
|
||||
use glam::DVec2;
|
||||
@@ -14,7 +14,7 @@ pub fn string_properties(text: impl Into<String>) -> Vec<LayoutGroup> {
|
||||
vec![LayoutGroup::Row { widgets: vec![widget] }]
|
||||
}
|
||||
|
||||
fn update_value<T, F: Fn(&T) -> TaggedValue + 'static>(value: F, node_id: NodeId, input_index: usize) -> WidgetCallback<T> {
|
||||
fn update_value<T, F: Fn(&T) -> TaggedValue + 'static + Send + Sync>(value: F, node_id: NodeId, input_index: usize) -> WidgetCallback<T> {
|
||||
WidgetCallback::new(move |number_input: &T| {
|
||||
NodeGraphMessage::SetInputValue {
|
||||
node: node_id,
|
||||
@@ -42,6 +42,32 @@ fn expose_widget(node_id: NodeId, index: usize, data_type: FrontendGraphDataType
|
||||
}))
|
||||
}
|
||||
|
||||
fn text_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str) -> Vec<WidgetHolder> {
|
||||
let input: &NodeInput = document_node.inputs.get(index).unwrap();
|
||||
|
||||
let mut widgets = vec![
|
||||
expose_widget(node_id, index, FrontendGraphDataType::Number, input.is_exposed()),
|
||||
WidgetHolder::unrelated_seperator(),
|
||||
WidgetHolder::text_widget(name),
|
||||
];
|
||||
|
||||
if let NodeInput::Value {
|
||||
tagged_value: TaggedValue::String(x),
|
||||
exposed: false,
|
||||
} = &document_node.inputs[index]
|
||||
{
|
||||
widgets.extend_from_slice(&[
|
||||
WidgetHolder::unrelated_seperator(),
|
||||
WidgetHolder::new(Widget::TextInput(TextInput {
|
||||
value: x.clone(),
|
||||
on_update: update_value(|x: &TextInput| TaggedValue::String(x.value.clone()), node_id, index),
|
||||
..TextInput::default()
|
||||
})),
|
||||
])
|
||||
}
|
||||
widgets
|
||||
}
|
||||
|
||||
fn number_range_widget(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, range_min: Option<f64>, range_max: Option<f64>, unit: String, is_integer: bool) -> Vec<WidgetHolder> {
|
||||
let input: &NodeInput = document_node.inputs.get(index).unwrap();
|
||||
|
||||
@@ -98,6 +124,12 @@ pub fn adjust_gamma_properties(document_node: &DocumentNode, node_id: NodeId) ->
|
||||
vec![LayoutGroup::Row { widgets: gamma }]
|
||||
}
|
||||
|
||||
pub fn gpu_map_properties(document_node: &DocumentNode, node_id: NodeId) -> Vec<LayoutGroup> {
|
||||
let map = text_widget(document_node, node_id, 1, "Map");
|
||||
|
||||
vec![LayoutGroup::Row { widgets: map }]
|
||||
}
|
||||
|
||||
pub fn multiply_opacity(document_node: &DocumentNode, node_id: NodeId) -> Vec<LayoutGroup> {
|
||||
let gamma = number_range_widget(document_node, node_id, 1, "Factor", Some(0.), Some(1.), "".into(), false);
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ use graphene::layers::text_layer::{FontCache, TextLayer};
|
||||
|
||||
use glam::{DAffine2, DVec2};
|
||||
use std::f64::consts::PI;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub fn apply_transform_operation(layer: &Layer, transform_op: TransformOp, value: f64, font_cache: &FontCache) -> [f64; 6] {
|
||||
let transformation = match transform_op {
|
||||
@@ -1457,7 +1457,7 @@ fn node_gradient_type(gradient: &Gradient) -> LayoutGroup {
|
||||
}
|
||||
|
||||
fn node_gradient_color(gradient: &Gradient, position: usize) -> LayoutGroup {
|
||||
let gradient_clone = Rc::new(gradient.clone());
|
||||
let gradient_clone = Arc::new(gradient.clone());
|
||||
let gradient_2 = gradient_clone.clone();
|
||||
let gradient_3 = gradient_clone.clone();
|
||||
let send_fill_message = move |new_gradient: Gradient| PropertiesPanelMessage::ModifyFill { fill: Fill::Gradient(new_gradient) }.into();
|
||||
|
||||
@@ -7,7 +7,7 @@ use glam::{DAffine2, DVec2};
|
||||
use serde::ser::SerializeStruct;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct RawBuffer(Vec<u8>);
|
||||
|
||||
impl From<Vec<u64>> for RawBuffer {
|
||||
@@ -22,8 +22,15 @@ impl From<Vec<u64>> for RawBuffer {
|
||||
Self(v_from_raw)
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Clone, Deserialize, PartialEq, Eq)]
|
||||
pub struct JsRawBuffer(Vec<u8>);
|
||||
|
||||
impl Serialize for RawBuffer {
|
||||
impl From<RawBuffer> for JsRawBuffer {
|
||||
fn from(buffer: RawBuffer) -> Self {
|
||||
Self(buffer.0)
|
||||
}
|
||||
}
|
||||
impl Serialize for JsRawBuffer {
|
||||
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
let mut buffer = serializer.serialize_struct("Buffer", 2)?;
|
||||
buffer.serialize_field("pointer", &(self.0.as_ptr() as usize))?;
|
||||
|
||||
@@ -420,12 +420,12 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
||||
size,
|
||||
} => {
|
||||
fn read_image(document: Option<&DocumentMessageHandler>, layer_path: &[LayerId], image_data: Vec<u8>, (width, height): (u32, u32)) -> Result<Vec<u8>, String> {
|
||||
use graphene_std::raster::Image;
|
||||
use graphene_core::raster::Image;
|
||||
use image::{ImageBuffer, Rgba};
|
||||
use std::io::Cursor;
|
||||
|
||||
let data = image_data.chunks_exact(4).map(|v| graphene_core::raster::color::Color::from_rgba8(v[0], v[1], v[2], v[3])).collect();
|
||||
let image = graphene_std::raster::Image { width, height, data };
|
||||
let image = graphene_core::raster::Image { width, height, data };
|
||||
|
||||
let document = document.ok_or_else(|| "Invalid document".to_string())?;
|
||||
let layer = document.graphene_document.layer(layer_path).map_err(|e| format!("No layer: {e:?}"))?;
|
||||
@@ -452,7 +452,7 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
||||
assert_ne!(proto_network.nodes.len(), 0, "No protonodes exist?");
|
||||
for (_id, node) in proto_network.nodes {
|
||||
info!("Inserting proto node {:?}", node);
|
||||
graph_craft::node_registry::push_node(node, &stack);
|
||||
interpreted_executor::node_registry::push_node(node, &stack);
|
||||
}
|
||||
|
||||
use borrow_stack::BorrowStack;
|
||||
@@ -484,7 +484,7 @@ impl MessageHandler<PortfolioMessage, (&InputPreprocessorMessageHandler, &Prefer
|
||||
.into(),
|
||||
);
|
||||
let mime = "image/bmp".to_string();
|
||||
let image_data = std::rc::Rc::new(image_data);
|
||||
let image_data = std::sync::Arc::new(image_data);
|
||||
responses.push_back(
|
||||
FrontendMessage::UpdateImageData {
|
||||
document_id,
|
||||
|
||||
@@ -453,7 +453,7 @@ impl Fsm for ArtboardToolFsmState {
|
||||
plus: false,
|
||||
}]),
|
||||
HintGroup(vec![HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Backspace])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Backspace]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Delete Artboard"),
|
||||
@@ -461,7 +461,7 @@ impl Fsm for ArtboardToolFsmState {
|
||||
}]),
|
||||
]),
|
||||
ArtboardToolFsmState::Dragging => HintData(vec![HintGroup(vec![HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Constrain to Axis"),
|
||||
@@ -469,14 +469,14 @@ impl Fsm for ArtboardToolFsmState {
|
||||
}])]),
|
||||
ArtboardToolFsmState::Drawing | ArtboardToolFsmState::ResizingBounds => HintData(vec![HintGroup(vec![
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Constrain Square"),
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("From Center"),
|
||||
|
||||
@@ -191,14 +191,14 @@ impl Fsm for EllipseToolFsmState {
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Constrain Circular"),
|
||||
plus: true,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("From Center"),
|
||||
@@ -207,14 +207,14 @@ impl Fsm for EllipseToolFsmState {
|
||||
])]),
|
||||
EllipseToolFsmState::Drawing => HintData(vec![HintGroup(vec![
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Constrain Circular"),
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("From Center"),
|
||||
|
||||
@@ -178,7 +178,7 @@ impl Fsm for EyedropperToolFsmState {
|
||||
},
|
||||
])]),
|
||||
EyedropperToolFsmState::SamplingPrimary | EyedropperToolFsmState::SamplingSecondary => HintData(vec![HintGroup(vec![HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Escape])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Escape]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Cancel"),
|
||||
|
||||
@@ -518,7 +518,7 @@ impl Fsm for GradientToolFsmState {
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Snap 15°"),
|
||||
@@ -526,7 +526,7 @@ impl Fsm for GradientToolFsmState {
|
||||
},
|
||||
])]),
|
||||
GradientToolFsmState::Drawing => HintData(vec![HintGroup(vec![HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Snap 15°"),
|
||||
|
||||
@@ -190,14 +190,14 @@ impl Fsm for ImaginateToolFsmState {
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Constrain Square"),
|
||||
plus: true,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("From Center"),
|
||||
@@ -206,14 +206,14 @@ impl Fsm for ImaginateToolFsmState {
|
||||
])]),
|
||||
ImaginateToolFsmState::Drawing => HintData(vec![HintGroup(vec![
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Constrain Square"),
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("From Center"),
|
||||
|
||||
@@ -247,21 +247,21 @@ impl Fsm for LineToolFsmState {
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Snap 15°"),
|
||||
plus: true,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("From Center"),
|
||||
plus: true,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Control])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Control]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Lock Angle"),
|
||||
@@ -270,21 +270,21 @@ impl Fsm for LineToolFsmState {
|
||||
])]),
|
||||
LineToolFsmState::Drawing => HintData(vec![HintGroup(vec![
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Snap 15°"),
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("From Center"),
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Control])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Control]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Lock Angle"),
|
||||
|
||||
@@ -201,7 +201,7 @@ impl Fsm for NavigateToolFsmState {
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Zoom Out"),
|
||||
@@ -217,7 +217,7 @@ impl Fsm for NavigateToolFsmState {
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Control])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Control]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Snap Increments"),
|
||||
@@ -240,7 +240,7 @@ impl Fsm for NavigateToolFsmState {
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Control])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Control]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Snap 15°"),
|
||||
@@ -249,14 +249,14 @@ impl Fsm for NavigateToolFsmState {
|
||||
]),
|
||||
]),
|
||||
NavigateToolFsmState::Tilting => HintData(vec![HintGroup(vec![HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Control])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Control]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Snap 15°"),
|
||||
plus: false,
|
||||
}])]),
|
||||
NavigateToolFsmState::Zooming => HintData(vec![HintGroup(vec![HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Control])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Control]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Snap Increments"),
|
||||
|
||||
@@ -190,14 +190,14 @@ impl Fsm for NodeGraphToolFsmState {
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Constrain Square"),
|
||||
plus: true,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("From Center"),
|
||||
@@ -206,14 +206,14 @@ impl Fsm for NodeGraphToolFsmState {
|
||||
])]),
|
||||
NodeGraphToolFsmState::Drawing => HintData(vec![HintGroup(vec![
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Constrain Square"),
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("From Center"),
|
||||
|
||||
@@ -322,7 +322,7 @@ impl Fsm for PathToolFsmState {
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Grow/Shrink Selection"),
|
||||
@@ -339,10 +339,10 @@ impl Fsm for PathToolFsmState {
|
||||
HintGroup(vec![
|
||||
HintInfo {
|
||||
key_groups: vec![
|
||||
KeysGroup(vec![Key::ArrowUp]),
|
||||
KeysGroup(vec![Key::ArrowRight]),
|
||||
KeysGroup(vec![Key::ArrowDown]),
|
||||
KeysGroup(vec![Key::ArrowLeft]),
|
||||
KeysGroup(vec![Key::ArrowUp]).into(),
|
||||
KeysGroup(vec![Key::ArrowRight]).into(),
|
||||
KeysGroup(vec![Key::ArrowDown]).into(),
|
||||
KeysGroup(vec![Key::ArrowLeft]).into(),
|
||||
],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
@@ -350,7 +350,7 @@ impl Fsm for PathToolFsmState {
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Big Increment Nudge"),
|
||||
@@ -359,21 +359,21 @@ impl Fsm for PathToolFsmState {
|
||||
]),
|
||||
HintGroup(vec![
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::KeyG])],
|
||||
key_groups: vec![KeysGroup(vec![Key::KeyG]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Grab Selected (coming soon)"),
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::KeyR])],
|
||||
key_groups: vec![KeysGroup(vec![Key::KeyR]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Rotate Selected (coming soon)"),
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::KeyS])],
|
||||
key_groups: vec![KeysGroup(vec![Key::KeyS]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Scale Selected (coming soon)"),
|
||||
@@ -383,14 +383,14 @@ impl Fsm for PathToolFsmState {
|
||||
]),
|
||||
PathToolFsmState::Dragging => HintData(vec![HintGroup(vec![
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Split/Align Handles (Toggle)"),
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Share Lengths of Aligned Handles"),
|
||||
|
||||
@@ -636,21 +636,21 @@ impl Fsm for PenToolFsmState {
|
||||
plus: false,
|
||||
}]),
|
||||
HintGroup(vec![HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Control])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Control]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Snap 15°"),
|
||||
plus: false,
|
||||
}]),
|
||||
HintGroup(vec![HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Break Handle"),
|
||||
plus: false,
|
||||
}]),
|
||||
HintGroup(vec![HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Enter])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Enter]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("End Path"),
|
||||
|
||||
@@ -192,14 +192,14 @@ impl Fsm for RectangleToolFsmState {
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Constrain Square"),
|
||||
plus: true,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("From Center"),
|
||||
@@ -208,14 +208,14 @@ impl Fsm for RectangleToolFsmState {
|
||||
])]),
|
||||
RectangleToolFsmState::Drawing => HintData(vec![HintGroup(vec![
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Constrain Square"),
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("From Center"),
|
||||
|
||||
@@ -793,21 +793,21 @@ impl Fsm for SelectToolFsmState {
|
||||
}]),
|
||||
HintGroup(vec![
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::KeyG])],
|
||||
key_groups: vec![KeysGroup(vec![Key::KeyG]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Grab Selected"),
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::KeyR])],
|
||||
key_groups: vec![KeysGroup(vec![Key::KeyR]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Rotate Selected"),
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::KeyS])],
|
||||
key_groups: vec![KeysGroup(vec![Key::KeyS]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Scale Selected"),
|
||||
@@ -823,14 +823,14 @@ impl Fsm for SelectToolFsmState {
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Control])],
|
||||
key_groups_mac: Some(vec![KeysGroup(vec![Key::Command])]),
|
||||
key_groups: vec![KeysGroup(vec![Key::Control]).into()],
|
||||
key_groups_mac: Some(vec![KeysGroup(vec![Key::Command]).into()]),
|
||||
mouse: None,
|
||||
label: String::from("Innermost"),
|
||||
plus: true,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Grow/Shrink Selection"),
|
||||
@@ -846,7 +846,7 @@ impl Fsm for SelectToolFsmState {
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Grow/Shrink Selection"),
|
||||
@@ -856,10 +856,10 @@ impl Fsm for SelectToolFsmState {
|
||||
HintGroup(vec![
|
||||
HintInfo {
|
||||
key_groups: vec![
|
||||
KeysGroup(vec![Key::ArrowUp]),
|
||||
KeysGroup(vec![Key::ArrowRight]),
|
||||
KeysGroup(vec![Key::ArrowDown]),
|
||||
KeysGroup(vec![Key::ArrowLeft]),
|
||||
KeysGroup(vec![Key::ArrowUp]).into(),
|
||||
KeysGroup(vec![Key::ArrowRight]).into(),
|
||||
KeysGroup(vec![Key::ArrowDown]).into(),
|
||||
KeysGroup(vec![Key::ArrowLeft]).into(),
|
||||
],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
@@ -867,7 +867,7 @@ impl Fsm for SelectToolFsmState {
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Big Increment Nudge"),
|
||||
@@ -876,15 +876,15 @@ impl Fsm for SelectToolFsmState {
|
||||
]),
|
||||
HintGroup(vec![
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: Some(MouseMotion::LmbDrag),
|
||||
label: String::from("Move Duplicate"),
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Control, Key::KeyD])],
|
||||
key_groups_mac: Some(vec![KeysGroup(vec![Key::Command, Key::KeyD])]),
|
||||
key_groups: vec![KeysGroup(vec![Key::Control, Key::KeyD]).into()],
|
||||
key_groups_mac: Some(vec![KeysGroup(vec![Key::Command, Key::KeyD]).into()]),
|
||||
mouse: None,
|
||||
label: String::from("Duplicate"),
|
||||
plus: false,
|
||||
@@ -893,14 +893,14 @@ impl Fsm for SelectToolFsmState {
|
||||
]),
|
||||
SelectToolFsmState::Dragging => HintData(vec![HintGroup(vec![
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Constrain to Axis"),
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Control])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Control]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Snap to Points (coming soon)"),
|
||||
@@ -910,7 +910,7 @@ impl Fsm for SelectToolFsmState {
|
||||
SelectToolFsmState::DrawingBox => HintData(vec![]),
|
||||
SelectToolFsmState::ResizingBounds => HintData(vec![]),
|
||||
SelectToolFsmState::RotatingBounds => HintData(vec![HintGroup(vec![HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Control])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Control]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Snap 15°"),
|
||||
|
||||
@@ -235,14 +235,14 @@ impl Fsm for ShapeToolFsmState {
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Constrain 1:1 Aspect"),
|
||||
plus: true,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("From Center"),
|
||||
@@ -251,14 +251,14 @@ impl Fsm for ShapeToolFsmState {
|
||||
])]),
|
||||
ShapeToolFsmState::Drawing => HintData(vec![HintGroup(vec![
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Shift]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Constrain 1:1 Aspect"),
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Alt]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("From Center"),
|
||||
|
||||
@@ -267,7 +267,7 @@ impl Fsm for SplineToolFsmState {
|
||||
plus: false,
|
||||
}]),
|
||||
HintGroup(vec![HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Enter])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Enter]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("End Spline"),
|
||||
|
||||
@@ -474,14 +474,14 @@ impl Fsm for TextToolFsmState {
|
||||
])]),
|
||||
TextToolFsmState::Editing => HintData(vec![HintGroup(vec![
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Control, Key::Enter])],
|
||||
key_groups_mac: Some(vec![KeysGroup(vec![Key::Command, Key::Enter])]),
|
||||
key_groups: vec![KeysGroup(vec![Key::Control, Key::Enter]).into()],
|
||||
key_groups_mac: Some(vec![KeysGroup(vec![Key::Command, Key::Enter]).into()]),
|
||||
mouse: None,
|
||||
label: String::from("Commit Edit"),
|
||||
plus: false,
|
||||
},
|
||||
HintInfo {
|
||||
key_groups: vec![KeysGroup(vec![Key::Escape])],
|
||||
key_groups: vec![KeysGroup(vec![Key::Escape]).into()],
|
||||
key_groups_mac: None,
|
||||
mouse: None,
|
||||
label: String::from("Discard Edit"),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use super::tool_messages::*;
|
||||
use crate::messages::input_mapper::utility_types::input_keyboard::KeysGroup;
|
||||
use crate::messages::input_mapper::utility_types::input_keyboard::LayoutKeysGroup;
|
||||
use crate::messages::input_mapper::utility_types::input_keyboard::MouseMotion;
|
||||
use crate::messages::input_mapper::utility_types::macros::action_keys;
|
||||
use crate::messages::input_mapper::utility_types::misc::ActionKeys;
|
||||
@@ -21,7 +21,7 @@ pub type ToolActionHandlerData<'a> = (&'a DocumentMessageHandler, u64, &'a Docum
|
||||
pub trait ToolCommon: for<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> + PropertyHolder + ToolTransition + ToolMetadata {}
|
||||
impl<T> ToolCommon for T where T: for<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> + PropertyHolder + ToolTransition + ToolMetadata {}
|
||||
|
||||
type Tool = dyn ToolCommon;
|
||||
type Tool = dyn ToolCommon + Send + Sync;
|
||||
|
||||
pub trait Fsm {
|
||||
type ToolData;
|
||||
@@ -442,10 +442,10 @@ pub struct HintInfo {
|
||||
/// A `KeysGroup` specifies all the keys pressed simultaneously to perform an action (like "Ctrl C" to copy).
|
||||
/// Usually at most one is given, but less commonly, multiple can be used to describe additional hotkeys not used simultaneously (like the four different arrow keys to nudge a layer).
|
||||
#[serde(rename = "keyGroups")]
|
||||
pub key_groups: Vec<KeysGroup>,
|
||||
pub key_groups: Vec<LayoutKeysGroup>,
|
||||
/// `None` means that the regular `key_groups` should be used for all platforms, `Some` is an override for a Mac-only input hint.
|
||||
#[serde(rename = "keyGroupsMac")]
|
||||
pub key_groups_mac: Option<Vec<KeysGroup>>,
|
||||
pub key_groups_mac: Option<Vec<LayoutKeysGroup>>,
|
||||
/// An optional `MouseMotion` that can indicate the mouse action, like which mouse button is used and whether a drag occurs.
|
||||
/// No such icon is shown if `None` is given, and it can be combined with `key_groups` if desired.
|
||||
pub mouse: Option<MouseMotion>,
|
||||
|
||||
Reference in New Issue
Block a user