mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-01 08:48: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
@@ -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))?;
|
||||
|
||||
Reference in New Issue
Block a user