mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-16 23:08:05 +08:00
Add the style of right-angle grid-aligned wires in the graph (#2182)
* Verticle and horizontal lines achieved(#2170) * vertical lines alligned with grid dots * fixed vertical lines positioning * Deals with cases 5 and 6 * Fixed case 5 and other problematic zones * edge cases solved * edge cases fixed: HorizontalOut & HorizontalIn * added comments * Changed midX and midY * Clean up if/else statements * Consolidate code * Consolidate further * Add preference for wire style --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
use crate::messages::layout::utility_types::widget_prelude::*;
|
||||
use crate::messages::portfolio::document::node_graph::utility_types::GraphWireStyle;
|
||||
use crate::messages::preferences::SelectionMode;
|
||||
use crate::messages::prelude::*;
|
||||
|
||||
@@ -32,6 +33,29 @@ impl PreferencesDialogMessageHandler {
|
||||
const TITLE: &'static str = "Editor Preferences";
|
||||
|
||||
fn layout(&self, preferences: &PreferencesMessageHandler) -> Layout {
|
||||
// =====
|
||||
// INPUT
|
||||
// =====
|
||||
|
||||
let zoom_with_scroll_tooltip = "Use the scroll wheel for zooming instead of vertically panning (not recommended for trackpads)";
|
||||
let input_section = vec![TextLabel::new("Input").italic(true).widget_holder()];
|
||||
let zoom_with_scroll = vec![
|
||||
CheckboxInput::new(preferences.zoom_with_scroll)
|
||||
.tooltip(zoom_with_scroll_tooltip)
|
||||
.on_update(|checkbox_input: &CheckboxInput| {
|
||||
PreferencesMessage::ModifyLayout {
|
||||
zoom_with_scroll: checkbox_input.checked,
|
||||
}
|
||||
.into()
|
||||
})
|
||||
.widget_holder(),
|
||||
TextLabel::new("Zoom with Scroll").table_align(true).tooltip(zoom_with_scroll_tooltip).widget_holder(),
|
||||
];
|
||||
|
||||
// =========
|
||||
// SELECTION
|
||||
// =========
|
||||
|
||||
let selection_section = vec![TextLabel::new("Selection").italic(true).widget_holder()];
|
||||
let selection_mode = RadioInput::new(vec![
|
||||
RadioEntryData::new(SelectionMode::Touched.to_string())
|
||||
@@ -65,20 +89,28 @@ impl PreferencesDialogMessageHandler {
|
||||
.selected_index(Some(preferences.selection_mode as u32))
|
||||
.widget_holder();
|
||||
|
||||
let zoom_with_scroll_tooltip = "Use the scroll wheel for zooming instead of vertically panning (not recommended for trackpads)";
|
||||
let input_section = vec![TextLabel::new("Input").italic(true).widget_holder()];
|
||||
let zoom_with_scroll = vec![
|
||||
CheckboxInput::new(preferences.zoom_with_scroll)
|
||||
.tooltip(zoom_with_scroll_tooltip)
|
||||
.on_update(|checkbox_input: &CheckboxInput| {
|
||||
PreferencesMessage::ModifyLayout {
|
||||
zoom_with_scroll: checkbox_input.checked,
|
||||
}
|
||||
.into()
|
||||
})
|
||||
.widget_holder(),
|
||||
TextLabel::new("Zoom with Scroll").table_align(true).tooltip(zoom_with_scroll_tooltip).widget_holder(),
|
||||
];
|
||||
// ================
|
||||
// NODE GRAPH WIRES
|
||||
// ================
|
||||
|
||||
let node_graph_section_tooltip = "Appearance of the wires running between node connections in the graph";
|
||||
let node_graph_section = vec![TextLabel::new("Node Graph Wires").tooltip(node_graph_section_tooltip).italic(true).widget_holder()];
|
||||
let graph_wire_style = RadioInput::new(vec![
|
||||
RadioEntryData::new(GraphWireStyle::GridAligned.to_string())
|
||||
.label(GraphWireStyle::GridAligned.to_string())
|
||||
.tooltip(GraphWireStyle::GridAligned.tooltip_description())
|
||||
.on_update(move |_| PreferencesMessage::GraphWireStyle { style: GraphWireStyle::GridAligned }.into()),
|
||||
RadioEntryData::new(GraphWireStyle::Direct.to_string())
|
||||
.label(GraphWireStyle::Direct.to_string())
|
||||
.tooltip(GraphWireStyle::Direct.tooltip_description())
|
||||
.on_update(move |_| PreferencesMessage::GraphWireStyle { style: GraphWireStyle::Direct }.into()),
|
||||
])
|
||||
.selected_index(Some(preferences.graph_wire_style as u32))
|
||||
.widget_holder();
|
||||
|
||||
// ============
|
||||
// EXPERIMENTAL
|
||||
// ============
|
||||
|
||||
let vello_tooltip = "Use the experimental Vello renderer (your browser must support WebGPU)";
|
||||
let renderer_section = vec![TextLabel::new("Experimental").italic(true).widget_holder()];
|
||||
@@ -126,10 +158,12 @@ impl PreferencesDialogMessageHandler {
|
||||
// ];
|
||||
|
||||
Layout::WidgetLayout(WidgetLayout::new(vec![
|
||||
LayoutGroup::Row { widgets: selection_section },
|
||||
LayoutGroup::Row { widgets: vec![selection_mode] },
|
||||
LayoutGroup::Row { widgets: input_section },
|
||||
LayoutGroup::Row { widgets: zoom_with_scroll },
|
||||
LayoutGroup::Row { widgets: selection_section },
|
||||
LayoutGroup::Row { widgets: vec![selection_mode] },
|
||||
LayoutGroup::Row { widgets: node_graph_section },
|
||||
LayoutGroup::Row { widgets: vec![graph_wire_style] },
|
||||
LayoutGroup::Row { widgets: renderer_section },
|
||||
LayoutGroup::Row { widgets: use_vello },
|
||||
LayoutGroup::Row { widgets: vector_meshes },
|
||||
|
||||
@@ -250,6 +250,8 @@ pub enum FrontendMessage {
|
||||
UpdateNodeGraph {
|
||||
nodes: Vec<FrontendNode>,
|
||||
wires: Vec<FrontendNodeWire>,
|
||||
#[serde(rename = "wiresDirectNotGridAligned")]
|
||||
wires_direct_not_grid_aligned: bool,
|
||||
},
|
||||
UpdateNodeGraphControlBarLayout {
|
||||
#[serde(rename = "layoutTarget")]
|
||||
|
||||
@@ -42,6 +42,7 @@ pub struct DocumentMessageData<'a> {
|
||||
pub persistent_data: &'a PersistentData,
|
||||
pub executor: &'a mut NodeGraphExecutor,
|
||||
pub current_tool: &'a ToolType,
|
||||
pub preferences: &'a PreferencesMessageHandler,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
@@ -172,6 +173,7 @@ impl MessageHandler<DocumentMessage, DocumentMessageData<'_>> for DocumentMessag
|
||||
persistent_data,
|
||||
executor,
|
||||
current_tool,
|
||||
preferences,
|
||||
} = data;
|
||||
|
||||
let selected_nodes_bounding_box_viewport = self.network_interface.selected_nodes_bounding_box_viewport(&self.breadcrumb_network_path);
|
||||
@@ -222,6 +224,7 @@ impl MessageHandler<DocumentMessage, DocumentMessageData<'_>> for DocumentMessag
|
||||
graph_view_overlay_open: self.graph_view_overlay_open,
|
||||
graph_fade_artwork_percentage: self.graph_fade_artwork_percentage,
|
||||
navigation_handler: &self.navigation_handler,
|
||||
preferences,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ pub struct NodeGraphHandlerData<'a> {
|
||||
pub graph_view_overlay_open: bool,
|
||||
pub graph_fade_artwork_percentage: f64,
|
||||
pub navigation_handler: &'a NavigationMessageHandler,
|
||||
pub preferences: &'a PreferencesMessageHandler,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -93,6 +94,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
||||
graph_view_overlay_open,
|
||||
graph_fade_artwork_percentage,
|
||||
navigation_handler,
|
||||
preferences,
|
||||
} = data;
|
||||
|
||||
match message {
|
||||
@@ -1293,8 +1295,14 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
||||
let wires = Self::collect_wires(network_interface, breadcrumb_network_path);
|
||||
let nodes = self.collect_nodes(network_interface, breadcrumb_network_path);
|
||||
let (layer_widths, chain_widths, has_left_input_wire) = network_interface.collect_layer_widths(breadcrumb_network_path);
|
||||
let wires_direct_not_grid_aligned = preferences.graph_wire_style.is_direct();
|
||||
|
||||
responses.add(NodeGraphMessage::UpdateImportsExports);
|
||||
responses.add(FrontendMessage::UpdateNodeGraph { nodes, wires });
|
||||
responses.add(FrontendMessage::UpdateNodeGraph {
|
||||
nodes,
|
||||
wires,
|
||||
wires_direct_not_grid_aligned,
|
||||
});
|
||||
responses.add(FrontendMessage::UpdateLayerWidths {
|
||||
layer_widths,
|
||||
chain_widths,
|
||||
|
||||
@@ -200,3 +200,32 @@ pub enum Direction {
|
||||
Left,
|
||||
Right,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Default, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
pub enum GraphWireStyle {
|
||||
#[default]
|
||||
GridAligned = 0,
|
||||
Direct = 1,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for GraphWireStyle {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
GraphWireStyle::GridAligned => write!(f, "Grid-Aligned"),
|
||||
GraphWireStyle::Direct => write!(f, "Direct"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl GraphWireStyle {
|
||||
pub fn tooltip_description(&self) -> &'static str {
|
||||
match self {
|
||||
GraphWireStyle::GridAligned => "Wires follow the grid, running in straight lines between nodes",
|
||||
GraphWireStyle::Direct => "Wires bend to run at an angle directly between nodes",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_direct(&self) -> bool {
|
||||
*self == GraphWireStyle::Direct
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,6 +106,7 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMes
|
||||
persistent_data: &self.persistent_data,
|
||||
executor: &mut self.executor,
|
||||
current_tool,
|
||||
preferences,
|
||||
};
|
||||
document.process_message(message, responses, document_inputs)
|
||||
}
|
||||
@@ -121,6 +122,7 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMes
|
||||
persistent_data: &self.persistent_data,
|
||||
executor: &mut self.executor,
|
||||
current_tool,
|
||||
preferences,
|
||||
};
|
||||
document.process_message(message, responses, document_inputs)
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use crate::messages::portfolio::document::node_graph::utility_types::GraphWireStyle;
|
||||
use crate::messages::preferences::SelectionMode;
|
||||
use crate::messages::prelude::*;
|
||||
|
||||
@@ -13,6 +14,7 @@ pub enum PreferencesMessage {
|
||||
SelectionMode { selection_mode: SelectionMode },
|
||||
VectorMeshes { enabled: bool },
|
||||
ModifyLayout { zoom_with_scroll: bool },
|
||||
GraphWireStyle { style: GraphWireStyle },
|
||||
// ImaginateRefreshFrequency { seconds: f64 },
|
||||
// ImaginateServerHostname { hostname: String },
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use crate::messages::input_mapper::key_mapping::MappingVariant;
|
||||
use crate::messages::portfolio::document::node_graph::utility_types::GraphWireStyle;
|
||||
use crate::messages::preferences::SelectionMode;
|
||||
use crate::messages::prelude::*;
|
||||
|
||||
@@ -12,6 +13,7 @@ pub struct PreferencesMessageHandler {
|
||||
pub zoom_with_scroll: bool,
|
||||
pub use_vello: bool,
|
||||
pub vector_meshes: bool,
|
||||
pub graph_wire_style: GraphWireStyle,
|
||||
}
|
||||
|
||||
impl PreferencesMessageHandler {
|
||||
@@ -37,6 +39,7 @@ impl Default for PreferencesMessageHandler {
|
||||
imaginate_hostname: host_name,
|
||||
use_vello,
|
||||
} = Default::default();
|
||||
|
||||
Self {
|
||||
imaginate_server_hostname: host_name,
|
||||
imaginate_refresh_frequency: 1.,
|
||||
@@ -44,6 +47,7 @@ impl Default for PreferencesMessageHandler {
|
||||
zoom_with_scroll: matches!(MappingVariant::default(), MappingVariant::ZoomWithScroll),
|
||||
use_vello,
|
||||
vector_meshes: false,
|
||||
graph_wire_style: GraphWireStyle::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -95,6 +99,10 @@ impl MessageHandler<PreferencesMessage, ()> for PreferencesMessageHandler {
|
||||
PreferencesMessage::SelectionMode { selection_mode } => {
|
||||
self.selection_mode = selection_mode;
|
||||
}
|
||||
PreferencesMessage::GraphWireStyle { style } => {
|
||||
self.graph_wire_style = style;
|
||||
responses.add(NodeGraphMessage::SendGraph);
|
||||
}
|
||||
}
|
||||
// TODO: Reenable when Imaginate is restored (and move back up one line since the auto-formatter doesn't like it in that block)
|
||||
// PreferencesMessage::ImaginateRefreshFrequency { seconds } => {
|
||||
|
||||
Reference in New Issue
Block a user