Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added drag and drop example in Calculator app #82

Merged
merged 1 commit into from
Jan 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
> - Breaking Changes:
> - Features:
> - Added ItemContainer.SelectedBorderThickness dependency property
- Added NodifyEditor.GetLocationInsideEditor
> - Bugfixes:
> - Fixed PendingConnection.PreviewTarget not being set to null when there is no actual target
> - Fixed PendingConnection.PreviewTarget not being set on Connector.PendingConnectionStartedEvent
Expand Down
51 changes: 48 additions & 3 deletions Examples/Nodify.Calculator/EditorView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
xmlns:local="clr-namespace:Nodify.Calculator"
xmlns:nodify="https://miroiu.github.io/nodify"
xmlns:shared="clr-namespace:Nodify;assembly=Nodify.Shared"
xmlns:sys="clr-namespace:System;assembly=System.Runtime"
d:DataContext="{d:DesignInstance Type=local:EditorViewModel}"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
Expand Down Expand Up @@ -98,7 +99,7 @@
<Setter Property="BorderThickness" Value="2" />
</Style>
</UserControl.Resources>

<Grid>
<nodify:NodifyEditor DataContext="{Binding Calculator}"
ItemsSource="{Binding Operations}"
Expand All @@ -111,6 +112,8 @@
Background="{StaticResource SmallGridLinesDrawingBrush}"
ItemContainerStyle="{StaticResource ItemContainerStyle}"
GridCellSize="15"
AllowDrop="True"
Drop="OnDropNode"
x:Name="Editor">
<nodify:NodifyEditor.Resources>
<Style TargetType="{x:Type nodify:NodeInput}"
Expand Down Expand Up @@ -287,7 +290,9 @@
ConnectionTemplate="{StaticResource ConnectionTemplate}"
ItemContainerStyle="{StaticResource ItemContainerStyle}"
Background="Transparent"
GridCellSize="15"
GridCellSize="15"
AllowDrop="True"
Drop="OnDropNode"
Visibility="{Binding DataContext.IsExpanded, RelativeSource={RelativeSource AncestorType=nodify:GroupingNode}, Converter={shared:BooleanToVisibilityConverter}}">

<nodify:NodifyEditor.InputBindings>
Expand Down Expand Up @@ -350,8 +355,48 @@
</nodify:DecoratorContainer>
</CompositeCollection>
</nodify:NodifyEditor>

<Grid Background="{StaticResource LargeGridLinesDrawingBrush}"
Panel.ZIndex="-2" />

<Border HorizontalAlignment="Right"
MinWidth="200"
MaxWidth="300"
Padding="7"
Margin="10"
CornerRadius="3"
BorderThickness="2">
<Border.Background>
<SolidColorBrush Color="{DynamicResource BackgroundColor}"
Opacity="0.7" />
</Border.Background>
<ScrollViewer>
<ItemsControl ItemsSource="{Binding Calculator.OperationsMenu.AvailableOperations}">
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="FrameworkElement.Margin" Value="5"/>
<Setter Property="FrameworkElement.HorizontalAlignment" Value="Left"/>
<Setter Property="FrameworkElement.Cursor" Value="Hand"/>
<Setter Property="FrameworkElement.ToolTip" Value="Drag and drop into the editor"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type local:OperationViewModel}">
<nodify:Node Content="{Binding Title}"
Input="{Binding Input}"
BorderBrush="{StaticResource AnimatedBrush}"
BorderThickness="2"
MouseMove="OnNodeDrag">
<nodify:Node.Output>
<CompositeCollection>
<sys:String>Output</sys:String>
</CompositeCollection>
</nodify:Node.Output>
</nodify:Node>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Border>
</Grid>
</UserControl>
22 changes: 22 additions & 0 deletions Examples/Nodify.Calculator/EditorView.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,27 @@ private void CloseOperationsMenu(object sender, RoutedEventArgs e)
calculator.OperationsMenu.Close();
}
}

private void OnDropNode(object sender, DragEventArgs e)
{
if(e.Source is NodifyEditor editor && editor.DataContext is CalculatorViewModel calculator
&& e.Data.GetData(typeof(OperationInfoViewModel)) is OperationInfoViewModel operation)
{
OperationViewModel op = OperationFactory.GetOperation(operation);
op.Location = editor.GetLocationInsideEditor(e);
calculator.Operations.Add(op);

e.Handled = true;
}
}

private void OnNodeDrag(object sender, MouseEventArgs e)
{
if(e.LeftButton == MouseButtonState.Pressed && ((FrameworkElement)sender).DataContext is OperationInfoViewModel operation)
{
var data = new DataObject(typeof(OperationInfoViewModel), operation);
DragDrop.DoDragDrop(this, data, DragDropEffects.Copy);
}
}
}
}
119 changes: 61 additions & 58 deletions Examples/Nodify.Calculator/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,77 +54,80 @@
</Style>
</shared:TabControlEx.ItemContainerStyle>
</shared:TabControlEx>

<Expander Header="Click to hide/show"
IsExpanded="True"
Margin="10"
HorizontalAlignment="Left"
VerticalAlignment="Bottom">
<Border MaxWidth="325"
MaxHeight="300"
CornerRadius="3">
<Border.Background>
<SolidColorBrush Color="{DynamicResource BackgroundColor}"
Opacity="0.7" />
</Border.Background>
<StackPanel Margin="10"
IsHitTestVisible="False">
<StackPanel.Resources>
<Style TargetType="{x:Type TextBlock}"
BasedOn="{StaticResource {x:Type TextBlock}}">
<Setter Property="Margin"
Value="0 0 0 5" />
</Style>
</StackPanel.Resources>
<ScrollViewer HorizontalScrollBarVisibility="Disabled">
<StackPanel Margin="10"
IsHitTestVisible="False">
<StackPanel.Resources>
<Style TargetType="{x:Type TextBlock}"
BasedOn="{StaticResource {x:Type TextBlock}}">
<Setter Property="Margin"
Value="0 0 0 5" />
</Style>
</StackPanel.Resources>

<StackPanel Margin="0 0 0 20">
<TextBlock Text="(New) Drag a connection and drop it on the editor"
TextWrapping="Wrap"
Foreground="{DynamicResource NodeInput.BorderBrush}"
FontWeight="Bold"/>
<TextBlock Text="(New) CTRL + N : open new editor"
TextWrapping="Wrap"
Foreground="{DynamicResource NodeInput.BorderBrush}"
FontWeight="Bold"/>
<TextBlock Text="(New) CTRL + W : close current editor"
TextWrapping="Wrap"
Foreground="{DynamicResource NodeInput.BorderBrush}"
FontWeight="Bold"/>
<StackPanel Margin="0 0 0 20">
<TextBlock Text="(New) Drag and drop nodes from the toolbox"
TextWrapping="Wrap"
Foreground="{DynamicResource NodeInput.BorderBrush}"
FontWeight="Bold"/>
</StackPanel>
<TextBlock TextWrapping="Wrap">
<Run Foreground="Red"
FontWeight="Bold">CTRL + N/W</Run>
<Run>: open/close editor</Run>
</TextBlock>
<TextBlock TextWrapping="Wrap">
<Run Foreground="Red"
FontWeight="Bold">ALT + Click</Run>
<Run>: disconnect connector</Run>
</TextBlock>
<TextBlock TextWrapping="Wrap">
<Run Foreground="Red"
FontWeight="Bold">Right Click</Run>
<Run>: show operations menu (create nodes)</Run>
</TextBlock>
<TextBlock TextWrapping="Wrap">
<Run Foreground="Red"
FontWeight="Bold">Delete</Run>
<Run>: delete selection</Run>
</TextBlock>
<TextBlock TextWrapping="Wrap">
<Run Foreground="Red"
FontWeight="Bold">CTRL + T</Run>
<Run>: change theme</Run>
</TextBlock>
<TextBlock TextWrapping="Wrap">
<Run Foreground="Red"
FontWeight="Bold">C</Run>
<Run>: group selection (hold SHIFT and mouse drag the header to move the group node alone)</Run>
</TextBlock>
<TextBlock Text="Drag a connection and drop it on the editor"
TextWrapping="Wrap"
FontWeight="Bold" />
<TextBlock Text="Hover over a connector to see its value"
TextWrapping="Wrap"
FontWeight="Bold" />
<TextBlock Text="Create a Calculator node and double click it to open"
TextWrapping="Wrap"
FontWeight="Bold" />
<TextBlock Text="Create an Operation Graph and add operations to it"
TextWrapping="Wrap"
FontWeight="Bold" />
</StackPanel>
<TextBlock TextWrapping="Wrap">
<Run Foreground="Red"
FontWeight="Bold">ALT + Click</Run>
<Run>: disconnect connector</Run>
</TextBlock>
<TextBlock TextWrapping="Wrap">
<Run Foreground="Red"
FontWeight="Bold">Right Click</Run>
<Run>: show operations menu (create nodes)</Run>
</TextBlock>
<TextBlock TextWrapping="Wrap">
<Run Foreground="Red"
FontWeight="Bold">Delete</Run>
<Run>: delete selection</Run>
</TextBlock>
<TextBlock TextWrapping="Wrap">
<Run Foreground="Red"
FontWeight="Bold">CTRL + T</Run>
<Run>: change theme</Run>
</TextBlock>
<TextBlock TextWrapping="Wrap">
<Run Foreground="Red"
FontWeight="Bold">C</Run>
<Run>: group selection (hold SHIFT and mouse drag the header to move the group node alone)</Run>
</TextBlock>
<TextBlock Text="Hover over a connector to see its value"
TextWrapping="Wrap"
FontWeight="Bold" />
<TextBlock Text="Create a Calculator node and double click it to open"
TextWrapping="Wrap"
FontWeight="Bold" />
<TextBlock Text="Create an Operation Graph and add operations to it"
TextWrapping="Wrap"
FontWeight="Bold" />
</StackPanel>
</ScrollViewer>
</Border>
</Expander>
</Grid>
Expand Down
11 changes: 8 additions & 3 deletions Nodify.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30406.217
# Visual Studio Version 17
VisualStudioVersion = 17.8.34330.188
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nodify", "Nodify\Nodify.csproj", "{A4349FD1-2774-42F2-90FD-7D8F4CA8BB71}"
EndProject
Expand All @@ -13,7 +13,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nodify.StateMachine", "Exam
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nodify.Shared", "Examples\Nodify.Shared\Nodify.Shared.csproj", "{499C8539-9973-4102-B976-57DB3F3C7DF3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nodify.Calculator", "Examples\Nodify.Calculator\Nodify.Calculator.csproj", "{7ADD1DAF-B589-4742-8E72-872D2842E73D}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nodify.Calculator", "Examples\Nodify.Calculator\Nodify.Calculator.csproj", "{7ADD1DAF-B589-4742-8E72-872D2842E73D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{88D231A7-D09F-492F-887F-DDBC46398284}"
ProjectSection(SolutionItems) = preProject
CHANGELOG.md = CHANGELOG.md
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down
29 changes: 29 additions & 0 deletions Nodify/NodifyEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,7 @@
/// <summary>
/// Initializes a new instance of the <see cref="NodifyEditor"/> class.
/// </summary>
public NodifyEditor()

Check warning on line 708 in Nodify/NodifyEditor.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'ItemsHost' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

Check warning on line 708 in Nodify/NodifyEditor.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'ItemsHost' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
{
AddHandler(Connector.DisconnectEvent, new ConnectorEventHandler(OnConnectorDisconnected));
AddHandler(Connector.PendingConnectionStartedEvent, new PendingConnectionEventHandler(OnConnectionStarted));
Expand Down Expand Up @@ -1359,5 +1359,34 @@

OnViewportUpdated();
}

#region Utilities

/// <summary>
/// Translates the specified location to graph space coordinates (relative to the <see cref="ItemsHost" />).
/// </summary>
/// <param name="location">The location coordinates relative to <paramref name="relativeTo"/></param>
/// <param name="relativeTo">The element where the <paramref name="location"/> was calculated from.</param>
/// <returns>A location inside the graph.</returns>
public Point GetLocationInsideEditor(Point location, UIElement relativeTo)
=> relativeTo.TranslatePoint(location, ItemsHost);

/// <summary>
/// Translates the event location to graph space coordinates (relative to the <see cref="ItemsHost" />).
/// </summary>
/// <param name="args">The drag event.</param>
/// <returns>A location inside the graph</returns>
public Point GetLocationInsideEditor(DragEventArgs args)
=> args.GetPosition(ItemsHost);

/// <summary>
/// Translates the event location to graph space coordinates (relative to the <see cref="ItemsHost" />).
/// </summary>
/// <param name="args">The mouse event.</param>
/// <returns>A location inside the graph</returns>
public Point GetLocationInsideEditor(MouseEventArgs args)
=> args.GetPosition(ItemsHost);

#endregion
}
}
Loading