port from perforce
This commit is contained in:
10
intromat/Intromat/Views/CodeGenConnectionView.xaml
Normal file
10
intromat/Intromat/Views/CodeGenConnectionView.xaml
Normal file
@@ -0,0 +1,10 @@
|
||||
<UserControl x:Class="Intromat.Views.CodeGenConnectionView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:views="clr-namespace:NodeNetwork.Views;assembly=NodeNetwork"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300" d:DesignWidth="300">
|
||||
<views:ConnectionView x:Name="ConnectionView" />
|
||||
</UserControl>
|
||||
36
intromat/Intromat/Views/CodeGenConnectionView.xaml.cs
Normal file
36
intromat/Intromat/Views/CodeGenConnectionView.xaml.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using Intromat.ViewModels;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Intromat.Views
|
||||
{
|
||||
public partial class CodeGenConnectionView : IViewFor<CodeGenConnectionViewModel>
|
||||
{
|
||||
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel),
|
||||
typeof(CodeGenConnectionViewModel), typeof(CodeGenConnectionView), new PropertyMetadata(null));
|
||||
|
||||
public CodeGenConnectionView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
ConnectionView.ViewModel = ViewModel;
|
||||
d(Disposable.Create(() => ConnectionView.ViewModel = null));
|
||||
});
|
||||
}
|
||||
|
||||
public CodeGenConnectionViewModel? ViewModel
|
||||
{
|
||||
get => (CodeGenConnectionViewModel?)GetValue(ViewModelProperty);
|
||||
set => SetValue(ViewModelProperty, value);
|
||||
}
|
||||
|
||||
object? IViewFor.ViewModel
|
||||
{
|
||||
get => ViewModel;
|
||||
set => ViewModel = (CodeGenConnectionViewModel?)value;
|
||||
}
|
||||
}
|
||||
}
|
||||
41
intromat/Intromat/Views/CodeGenNetworkView.xaml
Normal file
41
intromat/Intromat/Views/CodeGenNetworkView.xaml
Normal file
@@ -0,0 +1,41 @@
|
||||
<UserControl x:Class="Intromat.Views.CodeGenNetworkView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Intromat.Views"
|
||||
xmlns:views="clr-namespace:NodeNetwork.Views;assembly=NodeNetwork"
|
||||
xmlns:converters="clr-namespace:Intromat.Views.Converters"
|
||||
xmlns:nodes="clr-namespace:Intromat.ViewModels.Nodes"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<UserControl.Resources>
|
||||
<converters:TypeVisibilityCheck x:Key="TypeCheckToVisibility" />
|
||||
<ContextMenu x:Key="nodeMenu" x:Shared="True">
|
||||
<MenuItem x:Name="_groupNodesButton" Header="Group nodes" />
|
||||
<MenuItem x:Name="_ungroupNodesButton" Header="Ungroup nodes"
|
||||
Visibility="{Binding Converter={StaticResource TypeCheckToVisibility}, ConverterParameter={x:Type nodes:GroupNodeViewModel}}" />
|
||||
<MenuItem x:Name="_openGroupButton" Header="Open group"
|
||||
Visibility="{Binding Converter={StaticResource TypeCheckToVisibility}, ConverterParameter={x:Type nodes:GroupNodeViewModel}}" />
|
||||
</ContextMenu>
|
||||
</UserControl.Resources>
|
||||
<views:NetworkView x:Name="_network">
|
||||
<views:NetworkView.Resources>
|
||||
<Style TargetType="local:CodeGenNodeView" BasedOn="{StaticResource {x:Type local:CodeGenNodeView}}">
|
||||
<Setter Property="ContextMenu" Value="{StaticResource nodeMenu}" />
|
||||
</Style>
|
||||
</views:NetworkView.Resources>
|
||||
<views:NetworkView.NetworkBackground>
|
||||
<DrawingBrush TileMode="Tile" Viewport="0,0,96,96" ViewportUnits="Absolute" Viewbox="0,0,96,96"
|
||||
ViewboxUnits="Absolute">
|
||||
<DrawingBrush.Drawing>
|
||||
<GeometryDrawing Brush="Black">
|
||||
<GeometryDrawing.Geometry>
|
||||
<Geometry>M 77.000,37.000 L 59.000,37.000 L 59.000,19.000 L 77.000,19.000 L 77.000,37.000 Z M 77.000,57.000 L 59.000,57.000 L 59.000,38.000 L 77.000,38.000 L 77.000,57.000 Z M 77.000,76.000 L 59.000,76.000 L 59.000,58.000 L 77.000,58.000 L 77.000,76.000 Z M 77.000,94.000 L 59.000,94.000 L 59.000,77.000 L 77.000,77.000 L 77.000,94.000 Z M 39.000,94.000 L 39.000,77.000 L 58.000,77.000 L 58.000,94.000 L 39.000,94.000 Z M 20.000,94.000 L 20.000,77.000 L 38.000,77.000 L 38.000,94.000 L 20.000,94.000 Z M 2.000,94.000 L 2.000,77.000 L 19.000,77.000 L 19.000,94.000 L 2.000,94.000 Z M 2.000,58.000 L 19.000,58.000 L 19.000,76.000 L 2.000,76.000 L 2.000,58.000 Z M 2.000,38.000 L 19.000,38.000 L 19.000,57.000 L 2.000,57.000 L 2.000,38.000 Z M 2.000,19.000 L 19.000,19.000 L 19.000,37.000 L 2.000,37.000 L 2.000,19.000 Z M 38.000,19.000 L 38.000,37.000 L 20.000,37.000 L 20.000,19.000 L 38.000,19.000 Z M 39.000,57.000 L 39.000,38.000 L 58.000,38.000 L 58.000,57.000 L 39.000,57.000 Z M 39.000,58.000 L 58.000,58.000 L 58.000,76.000 L 39.000,76.000 L 39.000,58.000 Z M 20.000,57.000 L 20.000,38.000 L 38.000,38.000 L 38.000,57.000 L 20.000,57.000 Z M 38.000,58.000 L 38.000,76.000 L 20.000,76.000 L 20.000,58.000 L 38.000,58.000 Z M 58.000,19.000 L 58.000,37.000 L 39.000,37.000 L 39.000,19.000 L 58.000,19.000 Z M 96.000,19.000 L 96.000,18.000 L 78.000,18.000 L 78.000,0.000 L 77.000,0.000 L 77.000,18.000 L 59.000,18.000 L 59.000,0.000 L 58.000,0.000 L 58.000,18.000 L 39.000,18.000 L 39.000,0.000 L 38.000,0.000 L 38.000,18.000 L 20.000,18.000 L 20.000,0.000 L 19.000,0.000 L 19.000,18.000 L 2.000,18.000 L 2.000,0.000 L 0.000,0.000 L 0.000,18.000 L 0.000,19.000 L 0.000,37.000 L 0.000,38.000 L 0.000,57.000 L 0.000,58.000 L 0.000,76.000 L 0.000,77.000 L 0.000,94.000 L 0.000,96.000 L 2.000,96.000 L 19.000,96.000 L 20.000,96.000 L 38.000,96.000 L 39.000,96.000 L 58.000,96.000 L 59.000,96.000 L 77.000,96.000 L 78.000,96.000 L 96.000,96.000 L 96.000,94.000 L 78.000,94.000 L 78.000,77.000 L 96.000,77.000 L 96.000,76.000 L 78.000,76.000 L 78.000,58.000 L 96.000,58.000 L 96.000,57.000 L 78.000,57.000 L 78.000,38.000 L 96.000,38.000 L 96.000,37.000 L 78.000,37.000 L 78.000,19.000 L 96.000,19.000 Z</Geometry>
|
||||
</GeometryDrawing.Geometry>
|
||||
</GeometryDrawing>
|
||||
</DrawingBrush.Drawing>
|
||||
</DrawingBrush>
|
||||
</views:NetworkView.NetworkBackground>
|
||||
</views:NetworkView>
|
||||
</UserControl>
|
||||
67
intromat/Intromat/Views/CodeGenNetworkView.xaml.cs
Normal file
67
intromat/Intromat/Views/CodeGenNetworkView.xaml.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Reactive.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Intromat.ViewModels;
|
||||
using NodeNetwork.ViewModels;
|
||||
using NodeNetwork.Views;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Intromat.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for CodeGenNetworkView.xaml
|
||||
/// </summary>
|
||||
public partial class CodeGenNetworkView : IViewFor<CodeGenNetworkViewModel>
|
||||
{
|
||||
private readonly MenuItem _groupNodesButton;
|
||||
private readonly MenuItem _openGroupButton;
|
||||
private readonly MenuItem _ungroupNodesButton;
|
||||
|
||||
public CodeGenNetworkView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
var nodeMenu = ((ContextMenu)Resources["nodeMenu"]).Items.OfType<MenuItem>().ToList();
|
||||
_groupNodesButton = nodeMenu.First(c => c.Name == nameof(_groupNodesButton));
|
||||
_ungroupNodesButton = nodeMenu.First(c => c.Name == nameof(_ungroupNodesButton));
|
||||
_openGroupButton = nodeMenu.First(c => c.Name == nameof(_openGroupButton));
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
Observable.FromEventPattern<NetworkView.NodeMoveStartDelegate, NetworkView.NodeMoveStartEventArgs>(handler => _network.NodeMoveStart += handler, handler => _network.NodeMoveStart -= handler)
|
||||
.Select(e => e.EventArgs.Nodes.ToDictionary(node => node, node => node.Position))
|
||||
.Zip(Observable.FromEventPattern<NetworkView.NodeMoveEndDelegate, NetworkView.NodeMoveEndEventArgs>(handler => _network.NodeMoveEnd += handler, handler => _network.NodeMoveEnd -= handler))
|
||||
.Select(pair => pair.Second.EventArgs.Nodes.ToDictionary(node => node, node => (pair.First[node], node.Position)))
|
||||
.Subscribe(RecordNodeDragAction)
|
||||
.DisposeWith(d);
|
||||
|
||||
var networkViewModel = ViewModel!;
|
||||
_network.ViewModel = networkViewModel;
|
||||
this.BindCommand(networkViewModel, vm => vm.GroupNodes, v => v._groupNodesButton).DisposeWith(d);
|
||||
this.BindCommand(networkViewModel, vm => vm.UngroupNodes, v => v._ungroupNodesButton).DisposeWith(d);
|
||||
this.BindCommand(networkViewModel, vm => vm.OpenGroup, v => v._openGroupButton).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
private void RecordNodeDragAction(IDictionary<NodeViewModel, (Point, Point)> nodePositions)
|
||||
{
|
||||
var undoRedo = ViewModel!.Document.MainViewModel.UndoRedo;
|
||||
undoRedo.PushGroup(ViewModel.Document);
|
||||
foreach (var (node, (before, after)) in nodePositions)
|
||||
undoRedo.Record(new UndoItem<NodeViewModel, Point>(ViewModel.Document, node, v => v.Position, before, after));
|
||||
undoRedo.PopGroup();
|
||||
}
|
||||
|
||||
object? IViewFor.ViewModel
|
||||
{
|
||||
get => ViewModel;
|
||||
set => ViewModel = (CodeGenNetworkViewModel?)value;
|
||||
}
|
||||
|
||||
public CodeGenNetworkViewModel? ViewModel { get; set; }
|
||||
}
|
||||
}
|
||||
270
intromat/Intromat/Views/CodeGenNodeView.cs
Normal file
270
intromat/Intromat/Views/CodeGenNodeView.cs
Normal file
@@ -0,0 +1,270 @@
|
||||
using System;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using Intromat.ViewModels;
|
||||
using NodeNetwork.Utilities;
|
||||
using NodeNetwork.ViewModels;
|
||||
using NodeNetwork.Views;
|
||||
using ReactiveUI;
|
||||
using Splat;
|
||||
|
||||
namespace Intromat.Views
|
||||
{
|
||||
[TemplatePart(Name = nameof(NameLabel), Type = typeof(TextBlock))]
|
||||
[TemplatePart(Name = nameof(HeaderIcon), Type = typeof(Image))]
|
||||
[TemplatePart(Name = nameof(LeftList), Type = typeof(ItemsControl))]
|
||||
[TemplatePart(Name = nameof(RightList), Type = typeof(ItemsControl))]
|
||||
[TemplatePart(Name = nameof(ResizeVerticalThumb), Type = typeof(Thumb))]
|
||||
[TemplatePart(Name = nameof(ResizeHorizontalThumb), Type = typeof(Thumb))]
|
||||
[TemplatePart(Name = nameof(ResizeDiagonalThumb), Type = typeof(Thumb))]
|
||||
[TemplatePart(Name = nameof(Preview), Type = typeof(ViewModelViewHost))]
|
||||
[TemplateVisualState(Name = SelectedState, GroupName = SelectedVisualStatesGroup)]
|
||||
[TemplateVisualState(Name = UnselectedState, GroupName = SelectedVisualStatesGroup)]
|
||||
[TemplateVisualState(Name = CollapsedState, GroupName = CollapsedVisualStatesGroup)]
|
||||
[TemplateVisualState(Name = ExpandedState, GroupName = CollapsedVisualStatesGroup)]
|
||||
public class CodeGenNodeView : NodeViewBase, IViewFor<CodeGenNodeViewModel>
|
||||
{
|
||||
private Size _previousSize;
|
||||
|
||||
public CodeGenNodeView()
|
||||
{
|
||||
DefaultStyleKey = typeof(CodeGenNodeView);
|
||||
|
||||
SetupBindings();
|
||||
SetupEvents();
|
||||
SetupVisualStateBindings();
|
||||
}
|
||||
|
||||
private TextBlock NameLabel { get; set; } = null!;
|
||||
private Image HeaderIcon { get; set; } = null!;
|
||||
private ItemsControl LeftList { get; set; } = null!;
|
||||
private ItemsControl RightList { get; set; } = null!;
|
||||
private Thumb ResizeVerticalThumb { get; set; } = null!;
|
||||
private Thumb ResizeHorizontalThumb { get; set; } = null!;
|
||||
private Thumb ResizeDiagonalThumb { get; set; } = null!;
|
||||
private ViewModelViewHost Preview { get; set; } = null!;
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
ResizeHorizontalThumb = (Thumb)GetTemplateChild(nameof(ResizeHorizontalThumb))!;
|
||||
ResizeVerticalThumb = (Thumb)GetTemplateChild(nameof(ResizeVerticalThumb))!;
|
||||
LeftList = (ItemsControl)GetTemplateChild(nameof(LeftList))!;
|
||||
RightList = (ItemsControl)GetTemplateChild(nameof(RightList))!;
|
||||
HeaderIcon = (Image)GetTemplateChild(nameof(HeaderIcon))!;
|
||||
NameLabel = (TextBlock)GetTemplateChild(nameof(NameLabel))!;
|
||||
ResizeDiagonalThumb = (Thumb)GetTemplateChild(nameof(ResizeDiagonalThumb))!;
|
||||
Preview = (ViewModelViewHost)GetTemplateChild(nameof(Preview))!;
|
||||
|
||||
ResizeVerticalThumb.DragStarted += BeginResize;
|
||||
ResizeHorizontalThumb.DragStarted += BeginResize;
|
||||
ResizeDiagonalThumb.DragStarted += BeginResize;
|
||||
|
||||
ResizeVerticalThumb.DragCompleted += EndResize;
|
||||
ResizeHorizontalThumb.DragCompleted += EndResize;
|
||||
ResizeDiagonalThumb.DragCompleted += EndResize;
|
||||
|
||||
ResizeVerticalThumb.DragDelta += (_, e) => ApplyResize(e, false, true);
|
||||
ResizeHorizontalThumb.DragDelta += (_, e) => ApplyResize(e, true, false);
|
||||
ResizeDiagonalThumb.DragDelta += (_, e) => ApplyResize(e, true, true);
|
||||
|
||||
VisualStateManager.GoToState(this, ExpandedState, false);
|
||||
VisualStateManager.GoToState(this, UnselectedState, false);
|
||||
}
|
||||
|
||||
private void BeginResize(object sender, DragStartedEventArgs e)
|
||||
{
|
||||
_previousSize = ViewModel!.Size;
|
||||
}
|
||||
|
||||
private void EndResize(object sender, DragCompletedEventArgs e)
|
||||
{
|
||||
var document = ((CodeGenNetworkViewModel)ViewModel!.Parent).Document;
|
||||
var undoRedo = document.MainViewModel.UndoRedo;
|
||||
undoRedo.Record(new UndoItem<NodeViewModel, Size>(document, ViewModel, vm => vm.Size, _previousSize, ViewModel.Size));
|
||||
}
|
||||
|
||||
private void ApplyResize(DragDeltaEventArgs e, bool horizontal, bool vertical)
|
||||
{
|
||||
if (horizontal)
|
||||
MinWidth = Math.Max(20, MinWidth + e.HorizontalChange);
|
||||
if (vertical)
|
||||
MinHeight = Math.Max(20, MinHeight + e.VerticalChange);
|
||||
}
|
||||
|
||||
private void SetupBindings()
|
||||
{
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
var viewModel = ViewModel!;
|
||||
this.Events()
|
||||
.MouseEnter.Subscribe(_ => { viewModel.IsMouseOver = true; })
|
||||
.DisposeWith(d);
|
||||
this.Events()
|
||||
.MouseLeave.Subscribe(_ => { viewModel.IsMouseOver = false; })
|
||||
.DisposeWith(d);
|
||||
|
||||
this.OneWayBind(viewModel, vm => vm.Name, v => v.NameLabel.Text)
|
||||
.DisposeWith(d);
|
||||
|
||||
this.BindList(viewModel, vm => vm.LeftEndpoints, v => v.LeftList.ItemsSource)
|
||||
.DisposeWith(d);
|
||||
this.BindList(viewModel, vm => vm.RightEndpoints, v => v.RightList.ItemsSource)
|
||||
.DisposeWith(d);
|
||||
|
||||
this.WhenAnyValue(v => v.ActualWidth, v => v.ActualHeight, (width, height) => new Size(width, height))
|
||||
.BindTo(this, v => v.ViewModel!.Size)
|
||||
.DisposeWith(d);
|
||||
this.WhenAnyValue(v => v.ViewModel!.Size)
|
||||
.Subscribe(size =>
|
||||
{
|
||||
MinWidth = size.Width;
|
||||
MinHeight = size.Height;
|
||||
})
|
||||
.DisposeWith(d);
|
||||
|
||||
this.OneWayBind(viewModel, vm => vm.HeaderIcon, v => v.HeaderIcon.Source, img => img?.ToNative())
|
||||
.DisposeWith(d);
|
||||
this.OneWayBind(viewModel, vm => vm.NodeType, v => v.Background, ConvertNodeTypeToBrush)
|
||||
.DisposeWith(d);
|
||||
|
||||
this.OneWayBind(viewModel, vm => vm.Preview, v => v.Preview.ViewModel)
|
||||
.DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
private void SetupEvents()
|
||||
{
|
||||
MouseLeftButtonDown += (_, _) =>
|
||||
{
|
||||
Focus();
|
||||
|
||||
if (ViewModel == null)
|
||||
return;
|
||||
|
||||
if (ViewModel.IsSelected)
|
||||
return;
|
||||
|
||||
if (ViewModel.Parent != null && !Keyboard.IsKeyDown(Key.LeftCtrl) && !Keyboard.IsKeyDown(Key.RightCtrl))
|
||||
ViewModel.Parent.ClearSelection();
|
||||
|
||||
ViewModel.IsSelected = true;
|
||||
};
|
||||
}
|
||||
|
||||
private void SetupVisualStateBindings()
|
||||
{
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
this.WhenAnyValue(v => v.ViewModel!.IsCollapsed)
|
||||
.Subscribe(isCollapsed => { VisualStateManager.GoToState(this, isCollapsed ? CollapsedState : ExpandedState, true); })
|
||||
.DisposeWith(d);
|
||||
|
||||
this.WhenAnyValue(v => v.ViewModel!.IsSelected)
|
||||
.Subscribe(isSelected => { VisualStateManager.GoToState(this, isSelected ? SelectedState : UnselectedState, true); })
|
||||
.DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
public static Brush ConvertNodeTypeToBrush(NodeType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
NodeType.Special => new SolidColorBrush(Color.FromRgb(0x9b, 0x00, 0x00)),
|
||||
NodeType.Literal => new SolidColorBrush(Color.FromRgb(0x49, 0x49, 0x49)),
|
||||
NodeType.Code => new SolidColorBrush(Color.FromRgb(0x00, 0x60, 0x0f)),
|
||||
NodeType.Group => new SolidColorBrush(Color.FromRgb(0x7B, 0x1F, 0xA2)),
|
||||
_ => throw new Exception("Unsupported node type")
|
||||
};
|
||||
}
|
||||
|
||||
#region SelectedStates
|
||||
|
||||
public const string SelectedVisualStatesGroup = "SelectedStates";
|
||||
public const string SelectedState = "Selected";
|
||||
public const string UnselectedState = "Unselected";
|
||||
|
||||
#endregion
|
||||
|
||||
#region CollapsedStates
|
||||
|
||||
public const string CollapsedVisualStatesGroup = "CollapsedStates";
|
||||
public const string CollapsedState = "Collapsed";
|
||||
public const string ExpandedState = "Expanded";
|
||||
|
||||
#endregion
|
||||
|
||||
#region ViewModel
|
||||
|
||||
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel), typeof(CodeGenNodeViewModel), typeof(CodeGenNodeView), new PropertyMetadata(null));
|
||||
|
||||
public CodeGenNodeViewModel? ViewModel
|
||||
{
|
||||
get => (CodeGenNodeViewModel)GetValue(ViewModelProperty);
|
||||
set => SetValue(ViewModelProperty, value);
|
||||
}
|
||||
|
||||
object? IViewFor.ViewModel
|
||||
{
|
||||
get => ViewModel;
|
||||
set => ViewModel = (CodeGenNodeViewModel?)value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register(nameof(CornerRadius), typeof(CornerRadius), typeof(CodeGenNodeView));
|
||||
|
||||
public CornerRadius CornerRadius
|
||||
{
|
||||
get => (CornerRadius)GetValue(CornerRadiusProperty);
|
||||
set => SetValue(CornerRadiusProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty ArrowSizeProperty = DependencyProperty.Register(nameof(ArrowSize), typeof(double), typeof(CodeGenNodeView));
|
||||
|
||||
public double ArrowSize
|
||||
{
|
||||
get => (double)GetValue(ArrowSizeProperty);
|
||||
set => SetValue(ArrowSizeProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty TitleFontFamilyProperty = DependencyProperty.Register(nameof(TitleFontFamily), typeof(FontFamily), typeof(CodeGenNodeView));
|
||||
|
||||
public FontFamily TitleFontFamily
|
||||
{
|
||||
get => (FontFamily)GetValue(TitleFontFamilyProperty);
|
||||
set => SetValue(TitleFontFamilyProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty TitleFontSizeProperty = DependencyProperty.Register(nameof(TitleFontSize), typeof(double), typeof(CodeGenNodeView));
|
||||
|
||||
public double TitleFontSize
|
||||
{
|
||||
get => (double)GetValue(TitleFontSizeProperty);
|
||||
set => SetValue(TitleFontSizeProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty EndpointsStackingOrientationProperty = DependencyProperty.Register(nameof(EndpointsStackingOrientation), typeof(Orientation), typeof(CodeGenNodeView));
|
||||
|
||||
public Orientation EndpointsStackingOrientation
|
||||
{
|
||||
get => (Orientation)GetValue(EndpointsStackingOrientationProperty);
|
||||
set => SetValue(EndpointsStackingOrientationProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty TrailingControlPresenterStyleProperty = DependencyProperty.Register(nameof(TrailingControlPresenterStyle), typeof(Style), typeof(CodeGenNodeView));
|
||||
|
||||
public Style TrailingControlPresenterStyle
|
||||
{
|
||||
get => (Style)GetValue(TrailingControlPresenterStyleProperty);
|
||||
set => SetValue(TrailingControlPresenterStyleProperty, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
10
intromat/Intromat/Views/CodeGenPendingConnectionView.xaml
Normal file
10
intromat/Intromat/Views/CodeGenPendingConnectionView.xaml
Normal file
@@ -0,0 +1,10 @@
|
||||
<UserControl x:Class="Intromat.Views.CodeGenPendingConnectionView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:views="clr-namespace:NodeNetwork.Views;assembly=NodeNetwork"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300" d:DesignWidth="300">
|
||||
<views:PendingConnectionView x:Name="PendingConnectionView" />
|
||||
</UserControl>
|
||||
36
intromat/Intromat/Views/CodeGenPendingConnectionView.xaml.cs
Normal file
36
intromat/Intromat/Views/CodeGenPendingConnectionView.xaml.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using Intromat.ViewModels;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Intromat.Views
|
||||
{
|
||||
public partial class CodeGenPendingConnectionView : IViewFor<CodeGenPendingConnectionViewModel>
|
||||
{
|
||||
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel),
|
||||
typeof(CodeGenPendingConnectionViewModel), typeof(CodeGenPendingConnectionView), new PropertyMetadata(null));
|
||||
|
||||
public CodeGenPendingConnectionView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
PendingConnectionView.ViewModel = ViewModel;
|
||||
d(Disposable.Create(() => PendingConnectionView.ViewModel = null));
|
||||
});
|
||||
}
|
||||
|
||||
public CodeGenPendingConnectionViewModel? ViewModel
|
||||
{
|
||||
get => (CodeGenPendingConnectionViewModel?)GetValue(ViewModelProperty);
|
||||
set => SetValue(ViewModelProperty, value);
|
||||
}
|
||||
|
||||
object? IViewFor.ViewModel
|
||||
{
|
||||
get => ViewModel;
|
||||
set => ViewModel = (CodeGenPendingConnectionViewModel?)value;
|
||||
}
|
||||
}
|
||||
}
|
||||
76
intromat/Intromat/Views/CodeGenPortView.xaml
Normal file
76
intromat/Intromat/Views/CodeGenPortView.xaml
Normal file
@@ -0,0 +1,76 @@
|
||||
<UserControl x:Class="Intromat.Views.CodeGenPortView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:views="clr-namespace:NodeNetwork.Views;assembly=NodeNetwork"
|
||||
xmlns:local1="clr-namespace:Intromat.Views"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="100" d:DesignWidth="100">
|
||||
<UserControl.Resources>
|
||||
<!-- ReSharper disable Xaml.RedundantResource -->
|
||||
<ControlTemplate x:Key="{x:Static local1:CodeGenPortView.ExecutionPortTemplateKey}" TargetType="views:PortView">
|
||||
<Viewbox StretchDirection="Both" Stretch="Uniform">
|
||||
<Grid Width="20" Height="20">
|
||||
<Path Fill="White" Data="M 0 0 L 8 0 L 18 10 L 8 20 L 0 20 Z" HorizontalAlignment="Center"/>
|
||||
</Grid>
|
||||
</Viewbox>
|
||||
</ControlTemplate>
|
||||
|
||||
<ControlTemplate x:Key="{x:Static local1:CodeGenPortView.IntegerPortTemplateKey}" TargetType="views:PortView">
|
||||
<Viewbox StretchDirection="Both" Stretch="Uniform">
|
||||
<Grid Width="20" Height="20">
|
||||
<Ellipse Fill="#7cb342" HorizontalAlignment="Left" VerticalAlignment="Center" Height="15" Width="15"/>
|
||||
<Path Fill="#7cb342" Data="M 0 0 L 4 4 L 0 8 Z" HorizontalAlignment="Right" VerticalAlignment="Center" Height="8" Width="4"/>
|
||||
</Grid>
|
||||
</Viewbox>
|
||||
</ControlTemplate>
|
||||
|
||||
<ControlTemplate x:Key="{x:Static local1:CodeGenPortView.FloatPortTemplateKey}" TargetType="views:PortView">
|
||||
<Viewbox StretchDirection="Both" Stretch="Uniform">
|
||||
<Grid Width="20" Height="20">
|
||||
<Ellipse Fill="#68c8ba" HorizontalAlignment="Left" VerticalAlignment="Center" Height="15" Width="15"/>
|
||||
<Path Fill="#68c8ba" Data="M 0 0 L 4 4 L 0 8 Z" HorizontalAlignment="Right" VerticalAlignment="Center" Height="8" Width="4"/>
|
||||
</Grid>
|
||||
</Viewbox>
|
||||
</ControlTemplate>
|
||||
|
||||
<ControlTemplate x:Key="{x:Static local1:CodeGenPortView.StringPortTemplateKey}" TargetType="views:PortView">
|
||||
<Viewbox StretchDirection="Both" Stretch="Uniform">
|
||||
<Grid Width="20" Height="20">
|
||||
<Ellipse Fill="#ba68c8" HorizontalAlignment="Left" VerticalAlignment="Center" Height="15" Width="15"/>
|
||||
<Path Fill="#ba68c8" Data="M 0 0 L 4 4 L 0 8 Z" HorizontalAlignment="Right" VerticalAlignment="Center" Height="8" Width="4"/>
|
||||
</Grid>
|
||||
</Viewbox>
|
||||
</ControlTemplate>
|
||||
|
||||
<ControlTemplate x:Key="{x:Static local1:CodeGenPortView.BooleanPortTemplateKey}" TargetType="views:PortView">
|
||||
<Viewbox StretchDirection="Both" Stretch="Uniform">
|
||||
<Grid Width="20" Height="20">
|
||||
<Path Fill="#808080" Data="M 0 0 L 15 0 L 15 15 L 0 15 Z" HorizontalAlignment="Left" VerticalAlignment="Center" Height="15" Width="15"/>
|
||||
<Path Fill="#808080" Data="M 0 0 L 4 4 L 0 8 Z" HorizontalAlignment="Right" VerticalAlignment="Center" Height="8" Width="4"/>
|
||||
</Grid>
|
||||
</Viewbox>
|
||||
</ControlTemplate>
|
||||
|
||||
<ControlTemplate x:Key="{x:Static local1:CodeGenPortView.TexturePortTemplateKey}" TargetType="views:PortView">
|
||||
<Viewbox StretchDirection="Both" Stretch="Uniform">
|
||||
<Grid Width="20" Height="20">
|
||||
<Ellipse Fill="#F0A040" HorizontalAlignment="Left" VerticalAlignment="Center" Height="15" Width="15"/>
|
||||
<Path Fill="#F0A040" Data="M 0 0 L 4 4 L 0 8 Z" HorizontalAlignment="Right" VerticalAlignment="Center" Height="8" Width="4"/>
|
||||
</Grid>
|
||||
</Viewbox>
|
||||
</ControlTemplate>
|
||||
|
||||
<ControlTemplate x:Key="{x:Static local1:CodeGenPortView.MeshPortTemplateKey}" TargetType="views:PortView">
|
||||
<Viewbox StretchDirection="Both" Stretch="Uniform">
|
||||
<Grid Width="20" Height="20">
|
||||
<Ellipse Fill="#40A0F0" HorizontalAlignment="Left" VerticalAlignment="Center" Height="15" Width="15"/>
|
||||
<Path Fill="#40A0F0" Data="M 0 0 L 4 4 L 0 8 Z" HorizontalAlignment="Right" VerticalAlignment="Center" Height="8" Width="4"/>
|
||||
</Grid>
|
||||
</Viewbox>
|
||||
</ControlTemplate>
|
||||
<!-- ReSharper enable Xaml.RedundantResource -->
|
||||
</UserControl.Resources>
|
||||
<views:PortView x:Name="PortView" RenderTransformOrigin="0.5,0.5" />
|
||||
</UserControl>
|
||||
68
intromat/Intromat/Views/CodeGenPortView.xaml.cs
Normal file
68
intromat/Intromat/Views/CodeGenPortView.xaml.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using Intromat.ViewModels;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Intromat.Views
|
||||
{
|
||||
public partial class CodeGenPortView : IViewFor<CodeGenPortViewModel>
|
||||
{
|
||||
public const string ExecutionPortTemplateKey = "ExecutionPortTemplate";
|
||||
public const string IntegerPortTemplateKey = "IntegerPortTemplate";
|
||||
public const string StringPortTemplateKey = "StringPortTemplate";
|
||||
public const string BooleanPortTemplateKey = "BooleanPortTemplate";
|
||||
public const string FloatPortTemplateKey = "FloatPortTemplate";
|
||||
public const string TexturePortTemplateKey = "TexturePortTemplate";
|
||||
public const string MeshPortTemplateKey = "MeshPortTemplate";
|
||||
|
||||
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel), typeof(CodeGenPortViewModel), typeof(CodeGenPortView), new PropertyMetadata(null));
|
||||
|
||||
public CodeGenPortView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
this.WhenAnyValue(v => v.ViewModel)
|
||||
.BindTo(this, v => v.PortView.ViewModel)
|
||||
.DisposeWith(d);
|
||||
|
||||
this.OneWayBind(ViewModel, vm => vm.PortType, v => v.PortView.Template, GetTemplateFromPortType)
|
||||
.DisposeWith(d);
|
||||
|
||||
this.OneWayBind(ViewModel, vm => vm.IsMirrored, v => v.PortView.RenderTransform, isMirrored => new ScaleTransform(isMirrored ? -1.0 : 1.0, 1.0))
|
||||
.DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
public CodeGenPortViewModel? ViewModel
|
||||
{
|
||||
get => (CodeGenPortViewModel?)GetValue(ViewModelProperty);
|
||||
set => SetValue(ViewModelProperty, value);
|
||||
}
|
||||
|
||||
object? IViewFor.ViewModel
|
||||
{
|
||||
get => ViewModel;
|
||||
set => ViewModel = (CodeGenPortViewModel?)value;
|
||||
}
|
||||
|
||||
public ControlTemplate GetTemplateFromPortType(EPortType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
EPortType.Execution => (ControlTemplate)Resources[ExecutionPortTemplateKey],
|
||||
EPortType.Integer => (ControlTemplate)Resources[IntegerPortTemplateKey],
|
||||
EPortType.String => (ControlTemplate)Resources[StringPortTemplateKey],
|
||||
EPortType.Boolean => (ControlTemplate)Resources[BooleanPortTemplateKey],
|
||||
EPortType.Float => (ControlTemplate)Resources[FloatPortTemplateKey],
|
||||
EPortType.Texture => (ControlTemplate)Resources[TexturePortTemplateKey],
|
||||
EPortType.Mesh => (ControlTemplate)Resources[MeshPortTemplateKey],
|
||||
_ => throw new Exception("Unsupported port type")
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
26
intromat/Intromat/Views/CodePreviewView.xaml
Normal file
26
intromat/Intromat/Views/CodePreviewView.xaml
Normal file
@@ -0,0 +1,26 @@
|
||||
<UserControl x:Class="Intromat.Views.CodePreviewView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300" d:DesignWidth="300">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Label Content="Code" HorizontalAlignment="Left" Margin="10,10,0,10" VerticalAlignment="Top" FontSize="18"
|
||||
FontFamily="Segoe UI Semilight" />
|
||||
|
||||
<Grid Grid.Row="1" Margin="10,0,10,0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
|
||||
<TextBlock x:Name="errorTextBlock" Foreground="Red" HorizontalAlignment="Left" VerticalAlignment="Top"
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
|
||||
<Grid Grid.Row="2" Margin="10,0,10,0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
|
||||
<TextBlock x:Name="codeTextBlock" HorizontalAlignment="Left" VerticalAlignment="Top" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
36
intromat/Intromat/Views/CodePreviewView.xaml.cs
Normal file
36
intromat/Intromat/Views/CodePreviewView.xaml.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using Intromat.ViewModels;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Intromat.Views
|
||||
{
|
||||
public partial class CodePreviewView : IViewFor<CodePreviewViewModel>
|
||||
{
|
||||
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel),
|
||||
typeof(CodePreviewViewModel), typeof(CodePreviewView), new PropertyMetadata(null));
|
||||
|
||||
public CodePreviewView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
this.OneWayBind(ViewModel, vm => vm.CompiledCode, v => v.codeTextBlock.Text).DisposeWith(d);
|
||||
this.OneWayBind(ViewModel, vm => vm.CompilerError, v => v.errorTextBlock.Text).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
public CodePreviewViewModel? ViewModel
|
||||
{
|
||||
get => (CodePreviewViewModel?)GetValue(ViewModelProperty);
|
||||
set => SetValue(ViewModelProperty, value);
|
||||
}
|
||||
|
||||
object? IViewFor.ViewModel
|
||||
{
|
||||
get => ViewModel;
|
||||
set => ViewModel = (CodePreviewViewModel?)value;
|
||||
}
|
||||
}
|
||||
}
|
||||
23
intromat/Intromat/Views/Converters/TypeVisibilityCheck.cs
Normal file
23
intromat/Intromat/Views/Converters/TypeVisibilityCheck.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace Intromat.Views.Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// Given an object o and a type t, return Visible if o is of type t, else return Collapsed.
|
||||
/// </summary>
|
||||
public class TypeVisibilityCheck : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return ((Type)parameter).IsInstanceOfType(value) ? Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
18
intromat/Intromat/Views/DocumentView.xaml
Normal file
18
intromat/Intromat/Views/DocumentView.xaml
Normal file
@@ -0,0 +1,18 @@
|
||||
<UserControl x:Class="Intromat.Views.DocumentView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:breadcrumbBar="clr-namespace:NodeNetwork.Toolkit.BreadcrumbBar;assembly=NodeNetworkToolkit"
|
||||
xmlns:reactiveUi="http://reactiveui.net"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<breadcrumbBar:BreadcrumbBarView Grid.Row="0" x:Name="_breadcrumbBar" Margin="-2,-2,-1,-1" />
|
||||
<reactiveUi:ViewModelViewHost Grid.Row="1" x:Name="_content" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" VerticalAlignment="Stretch" VerticalContentAlignment="Stretch" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
41
intromat/Intromat/Views/DocumentView.xaml.cs
Normal file
41
intromat/Intromat/Views/DocumentView.xaml.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Reactive.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Intromat.ViewModels;
|
||||
using NodeNetwork.ViewModels;
|
||||
using NodeNetwork.Views;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Intromat.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for DocumentView.xaml
|
||||
/// </summary>
|
||||
public partial class DocumentView : IViewFor<DocumentViewModel>
|
||||
{
|
||||
|
||||
public DocumentView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
var documentViewModel = ViewModel!;
|
||||
this.OneWayBind(documentViewModel, vm => vm.CurrentViewModel, v => v._content.ViewModel).DisposeWith(d);
|
||||
this.OneWayBind(documentViewModel, vm => vm.NetworkBreadcrumbBar, v => v._breadcrumbBar.ViewModel).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
object? IViewFor.ViewModel
|
||||
{
|
||||
get => ViewModel;
|
||||
set => ViewModel = (DocumentViewModel?)value;
|
||||
}
|
||||
|
||||
public DocumentViewModel? ViewModel { get; set; }
|
||||
}
|
||||
}
|
||||
11
intromat/Intromat/Views/DxView.xaml
Normal file
11
intromat/Intromat/Views/DxView.xaml
Normal file
@@ -0,0 +1,11 @@
|
||||
<Grid x:Class="Intromat.Views.DxView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Canvas MinWidth="64" MinHeight="64">
|
||||
<Image x:Name="_swapChainImage" Opacity="1.0" />
|
||||
</Canvas>
|
||||
</Grid>
|
||||
314
intromat/Intromat/Views/DxView.xaml.cs
Normal file
314
intromat/Intromat/Views/DxView.xaml.cs
Normal file
@@ -0,0 +1,314 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using Intromat.Graphics;
|
||||
using SharpDX.DXGI;
|
||||
using Splat;
|
||||
using D3D9 = SharpDX.Direct3D9;
|
||||
using D3D11 = SharpDX.Direct3D11;
|
||||
|
||||
namespace Intromat.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for DxView.xaml
|
||||
/// </summary>
|
||||
public partial class DxView
|
||||
{
|
||||
private readonly D3DImage _d3dImage;
|
||||
private readonly DxHost _dxHost;
|
||||
private int _backBufferHeight = -1;
|
||||
private bool _backBufferMultiSample;
|
||||
|
||||
private D3D11.Texture2D? _backBufferTexture;
|
||||
private D3D11.RenderTargetView? _backBufferView;
|
||||
private int _backBufferWidth = -1;
|
||||
private D3D9.Surface? _d3d9Surface;
|
||||
private D3D9.Texture? _d3d9Texture;
|
||||
private D3D11.Texture2D? _depthBufferTexture;
|
||||
private D3D11.DepthStencilView? _depthBufferView;
|
||||
private TimeSpan _lastRender;
|
||||
private volatile IntPtr _nextFrame = IntPtr.Zero;
|
||||
private bool _supportRemoteDesktop;
|
||||
private D3D11.Texture2D? _transferBuffer;
|
||||
private D3D11.Texture2D? _transferBuffer2;
|
||||
private D3D11.Query? _transferCompleteQuery;
|
||||
private DxHost.RenderDelegate? _updateHandler;
|
||||
|
||||
public DxView()
|
||||
{
|
||||
InitializeComponent();
|
||||
_dxHost = Locator.Current.GetService<DxHost>()!;
|
||||
_d3dImage = new D3DImage();
|
||||
_swapChainImage.Source = _d3dImage;
|
||||
|
||||
SizeChanged += HostSizeChanged;
|
||||
Loaded += OnLoaded;
|
||||
Unloaded += OnUnloaded;
|
||||
Dispatcher.ShutdownStarted += OnUnloaded;
|
||||
}
|
||||
|
||||
public int ViewHeight { get; private set; }
|
||||
|
||||
public int ViewWidth { get; private set; }
|
||||
|
||||
private void OnLoaded(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
CompositionTarget.Rendering += CompositionTargetRendering;
|
||||
CheckHostSize();
|
||||
}
|
||||
|
||||
private void OnUnloaded(object? sender, EventArgs e)
|
||||
{
|
||||
CompositionTarget.Rendering -= CompositionTargetRendering;
|
||||
}
|
||||
|
||||
public void SetUpdateHandler(DxHost.RenderDelegate? handler)
|
||||
{
|
||||
_updateHandler = handler;
|
||||
}
|
||||
|
||||
private void CompositionTargetRendering(object? sender, EventArgs e)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
var args = (RenderingEventArgs)e;
|
||||
|
||||
if (_lastRender == args.RenderingTime)
|
||||
return;
|
||||
|
||||
_lastRender = args.RenderingTime;
|
||||
|
||||
var nextFrame = _nextFrame;
|
||||
if (nextFrame != IntPtr.Zero)
|
||||
{
|
||||
_nextFrame = IntPtr.Zero;
|
||||
|
||||
var image = _d3dImage;
|
||||
var hasFrontBuffer = image.IsFrontBufferAvailable;
|
||||
if (_supportRemoteDesktop || hasFrontBuffer)
|
||||
{
|
||||
image.Lock();
|
||||
image.SetBackBuffer(D3DResourceType.IDirect3DSurface9, nextFrame, _supportRemoteDesktop);
|
||||
|
||||
var targetWidth = image.PixelWidth;
|
||||
var targetHeight = image.PixelHeight;
|
||||
|
||||
image.AddDirtyRect(new Int32Rect(0, 0, targetWidth, targetHeight));
|
||||
image.Unlock();
|
||||
|
||||
if (hasFrontBuffer)
|
||||
_supportRemoteDesktop = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_supportRemoteDesktop = SystemInformation.TerminalServerSession;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Render()
|
||||
{
|
||||
_dxHost.EnqueueAction(Render);
|
||||
}
|
||||
|
||||
public void Render(D3D11.Device device, D3D11.DeviceContext context)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
EnsureBuffers();
|
||||
|
||||
if (_backBufferTexture == null || _transferBuffer == null || _updateHandler == null)
|
||||
return;
|
||||
|
||||
context.OutputMerger.SetTargets(_depthBufferView, _backBufferView);
|
||||
context.Rasterizer.SetViewport(0, 0, ViewWidth, ViewHeight);
|
||||
|
||||
try
|
||||
{
|
||||
_updateHandler(device, context);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e.ToString());
|
||||
}
|
||||
|
||||
if (_backBufferMultiSample)
|
||||
{
|
||||
context.ResolveSubresource(_backBufferTexture, 0, _transferBuffer2, 0, Format.B8G8R8A8_UNorm_SRgb);
|
||||
context.CopyResource(_transferBuffer2, _transferBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.CopyResource(_backBufferTexture, _transferBuffer);
|
||||
}
|
||||
|
||||
context.End(_transferCompleteQuery);
|
||||
|
||||
while (!context.GetData(_transferCompleteQuery, out int completed) || completed == 0)
|
||||
Thread.Yield();
|
||||
|
||||
_nextFrame = _d3d9Surface!.NativePointer;
|
||||
}
|
||||
}
|
||||
|
||||
private void HostSizeChanged(object sender, SizeChangedEventArgs e)
|
||||
{
|
||||
CheckHostSize();
|
||||
}
|
||||
|
||||
private void CheckHostSize()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
double scaleX = 1.0f;
|
||||
double scaleY = 1.0f;
|
||||
|
||||
if (PresentationSource.FromVisual(this)?.CompositionTarget is HwndTarget hwndTarget)
|
||||
{
|
||||
scaleX = hwndTarget.TransformToDevice.M11;
|
||||
scaleY = hwndTarget.TransformToDevice.M22;
|
||||
}
|
||||
|
||||
var width = (int)Math.Ceiling(ActualWidth);
|
||||
var height = (int)Math.Ceiling(ActualHeight);
|
||||
|
||||
width = width > 1 ? width : 1;
|
||||
height = height > 1 ? height : 1;
|
||||
|
||||
if (ViewWidth == width && ViewHeight == height)
|
||||
return;
|
||||
|
||||
ViewWidth = width;
|
||||
ViewHeight = height;
|
||||
Render();
|
||||
}
|
||||
}
|
||||
|
||||
private void EnsureBuffers()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (_backBufferHeight != ViewHeight || _backBufferWidth != ViewWidth)
|
||||
{
|
||||
_backBufferHeight = ViewHeight;
|
||||
_backBufferWidth = ViewWidth;
|
||||
|
||||
if (_d3d9Surface != null)
|
||||
{
|
||||
_d3d9Surface.Dispose();
|
||||
_d3d9Surface = null;
|
||||
}
|
||||
|
||||
if (_d3d9Texture != null)
|
||||
{
|
||||
_d3d9Texture.Dispose();
|
||||
_d3d9Texture = null;
|
||||
}
|
||||
|
||||
if (_transferBuffer != null)
|
||||
{
|
||||
_transferBuffer.Dispose();
|
||||
_transferBuffer = null;
|
||||
}
|
||||
|
||||
if (_transferBuffer2 != null)
|
||||
{
|
||||
_transferBuffer2.Dispose();
|
||||
_transferBuffer2 = null;
|
||||
}
|
||||
|
||||
if (_backBufferTexture != null) // TODO: test
|
||||
{
|
||||
_backBufferTexture.Dispose();
|
||||
_backBufferTexture = null;
|
||||
}
|
||||
|
||||
if (_backBufferView != null)
|
||||
{
|
||||
_backBufferView.Dispose();
|
||||
_backBufferView = null;
|
||||
}
|
||||
|
||||
if (_depthBufferTexture != null) // TODO: test
|
||||
{
|
||||
_depthBufferTexture.Dispose();
|
||||
_depthBufferTexture = null;
|
||||
}
|
||||
|
||||
if (_depthBufferView != null)
|
||||
{
|
||||
_depthBufferView.Dispose();
|
||||
_depthBufferView = null;
|
||||
}
|
||||
|
||||
if (_transferCompleteQuery != null)
|
||||
{
|
||||
_transferCompleteQuery.Dispose();
|
||||
_transferCompleteQuery = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (_transferBuffer == null && _dxHost.D3D9Device != null)
|
||||
{
|
||||
var device = _dxHost.Device;
|
||||
|
||||
var textureDesc = new D3D11.Texture2DDescription
|
||||
{
|
||||
ArraySize = 1,
|
||||
MipLevels = 1,
|
||||
Width = _backBufferWidth,
|
||||
Height = _backBufferHeight,
|
||||
SampleDescription = new SampleDescription(1, 0), // TAM
|
||||
Usage = D3D11.ResourceUsage.Default,
|
||||
CpuAccessFlags = D3D11.CpuAccessFlags.None,
|
||||
OptionFlags = D3D11.ResourceOptionFlags.Shared,
|
||||
BindFlags = D3D11.BindFlags.RenderTarget | D3D11.BindFlags.ShaderResource,
|
||||
Format = Format.B8G8R8A8_UNorm
|
||||
};
|
||||
|
||||
_transferBuffer = new D3D11.Texture2D(device, textureDesc);
|
||||
|
||||
textureDesc.Format = Format.B8G8R8A8_UNorm_SRgb;
|
||||
textureDesc.OptionFlags = D3D11.ResourceOptionFlags.None;
|
||||
_transferBuffer2 = new D3D11.Texture2D(device, textureDesc);
|
||||
|
||||
_backBufferMultiSample = true;
|
||||
textureDesc.SampleDescription = new SampleDescription(4, 0);
|
||||
|
||||
textureDesc.BindFlags = D3D11.BindFlags.RenderTarget;
|
||||
|
||||
_backBufferTexture = new D3D11.Texture2D(device, textureDesc);
|
||||
_backBufferView = new D3D11.RenderTargetView(device, _backBufferTexture);
|
||||
|
||||
textureDesc.Format = Format.R32_Typeless;
|
||||
textureDesc.BindFlags = D3D11.BindFlags.DepthStencil;
|
||||
textureDesc.OptionFlags = D3D11.ResourceOptionFlags.None;
|
||||
|
||||
var depthDesc = new D3D11.DepthStencilViewDescription
|
||||
{
|
||||
Format = Format.D32_Float,
|
||||
Flags = D3D11.DepthStencilViewFlags.None,
|
||||
Dimension = D3D11.DepthStencilViewDimension.Texture2DMultisampled,
|
||||
Texture2DMS = new D3D11.DepthStencilViewDescription.Texture2DMultisampledResource()
|
||||
};
|
||||
|
||||
_depthBufferTexture = new D3D11.Texture2D(device, textureDesc);
|
||||
_depthBufferView = new D3D11.DepthStencilView(device, _depthBufferTexture, depthDesc);
|
||||
|
||||
var dxgiRes = _transferBuffer.QueryInterface<Resource>();
|
||||
var handle = dxgiRes.SharedHandle;
|
||||
|
||||
_d3d9Texture = new D3D9.Texture(_dxHost.D3D9Device, _backBufferWidth, _backBufferHeight, 1, D3D9.Usage.RenderTarget, D3D9.Format.A8R8G8B8, D3D9.Pool.Default, ref handle);
|
||||
_d3d9Surface = _d3d9Texture.GetSurfaceLevel(0);
|
||||
|
||||
var queryDesc = new D3D11.QueryDescription { Type = D3D11.QueryType.Event };
|
||||
_transferCompleteQuery = new D3D11.Query(device, queryDesc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Intromat.Interfaces;
|
||||
using Intromat.ViewModels.Editors;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Intromat.Views.Editors
|
||||
{
|
||||
[TemplatePart(Name = nameof(_checkBoxValue), Type = typeof(CheckBox))]
|
||||
[TemplatePart(Name = nameof(_textBlockValue), Type = typeof(TextBlock))]
|
||||
public class BooleanExpressionEditorView : EditorViewBase<BooleanExpressionEditorViewModel>
|
||||
{
|
||||
private CheckBox _checkBoxValue = null!;
|
||||
private TextBlock _textBlockValue = null!;
|
||||
|
||||
public BooleanExpressionEditorView()
|
||||
{
|
||||
DefaultStyleKey = typeof(BooleanExpressionEditorView);
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
this.OneWayBind(ViewModel, vm => vm.CustomValue, v => v._textBlockValue.Text, b => b.ToString()).DisposeWith(d);
|
||||
this.Bind(ViewModel, vm => vm.CustomValue, v => v._checkBoxValue.IsChecked).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
_checkBoxValue = (CheckBox)GetTemplateChild(nameof(_checkBoxValue))!;
|
||||
_textBlockValue = (TextBlock)GetTemplateChild(nameof(_textBlockValue))!;
|
||||
}
|
||||
}
|
||||
}
|
||||
35
intromat/Intromat/Views/Editors/BooleanValueEditorView.cs
Normal file
35
intromat/Intromat/Views/Editors/BooleanValueEditorView.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Intromat.Interfaces;
|
||||
using Intromat.ViewModels.Editors;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Intromat.Views.Editors
|
||||
{
|
||||
[TemplatePart(Name = nameof(_checkBoxValue), Type = typeof(CheckBox))]
|
||||
[TemplatePart(Name = nameof(_textBlockValue), Type = typeof(TextBlock))]
|
||||
public class BooleanValueEditorView : EditorViewBase<BooleanValueEditorViewModel>
|
||||
{
|
||||
private CheckBox _checkBoxValue = null!;
|
||||
private TextBlock _textBlockValue = null!;
|
||||
|
||||
public BooleanValueEditorView()
|
||||
{
|
||||
DefaultStyleKey = typeof(BooleanValueEditorView);
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
this.OneWayBind(ViewModel, vm => vm.Value, v => v._textBlockValue.Text, b => b.ToString()).DisposeWith(d);
|
||||
this.Bind(ViewModel, vm => vm.Value, v => v._checkBoxValue.IsChecked).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
_checkBoxValue = (CheckBox)GetTemplateChild(nameof(_checkBoxValue))!;
|
||||
_textBlockValue = (TextBlock)GetTemplateChild(nameof(_textBlockValue))!;
|
||||
}
|
||||
}
|
||||
}
|
||||
38
intromat/Intromat/Views/Editors/DimensionEditorView.cs
Normal file
38
intromat/Intromat/Views/Editors/DimensionEditorView.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Intromat.Interfaces;
|
||||
using Intromat.Nodes.Code;
|
||||
using Intromat.ViewModels.Editors;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Intromat.Views.Editors
|
||||
{
|
||||
[TemplatePart(Name = nameof(_sliderValue), Type = typeof(Slider))]
|
||||
[TemplatePart(Name = nameof(_textBlockValue), Type = typeof(TextBlock))]
|
||||
public class DimensionEditorView : EditorViewBase<DimensionEditorViewModel>
|
||||
{
|
||||
private Slider _sliderValue = null!;
|
||||
private TextBlock _textBlockValue = null!;
|
||||
|
||||
public DimensionEditorView()
|
||||
{
|
||||
DefaultStyleKey = typeof(DimensionEditorView);
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
this.OneWayBind(ViewModel, vm => vm.Value, v => v._textBlockValue.Text, v => ((IntLiteralValue?)v)?.EvaluateDimension().ToString() ?? "0").DisposeWith(d);
|
||||
this.Bind(ViewModel, vm => vm.CustomValue, v => v._sliderValue.Value, i => i, v => (int)v).DisposeWith(d);
|
||||
this.Bind(ViewModel, vm => vm.MinValue, v => v._sliderValue.Minimum, i => i, v => (int)v).DisposeWith(d);
|
||||
this.Bind(ViewModel, vm => vm.MaxValue, v => v._sliderValue.Maximum, i => i, v => (int)v).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
_sliderValue = (Slider)GetTemplateChild(nameof(_sliderValue))!;
|
||||
_textBlockValue = (TextBlock)GetTemplateChild(nameof(_textBlockValue))!;
|
||||
}
|
||||
}
|
||||
}
|
||||
59
intromat/Intromat/Views/Editors/EditorHeader.xaml
Normal file
59
intromat/Intromat/Views/Editors/EditorHeader.xaml
Normal file
@@ -0,0 +1,59 @@
|
||||
<UserControl x:Class="Intromat.Views.Editors.EditorHeader"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="30" d:DesignWidth="800">
|
||||
<Grid Margin="0,0,0,5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" x:Name="_textBlockName" Foreground="{DynamicResource ControlDefaultForeground}" HorizontalAlignment="Stretch" VerticalAlignment="Center" TextTrimming="CharacterEllipsis" />
|
||||
<ComboBox Grid.Column="1" x:Name="_comboBoxRelativeSource" VerticalAlignment="Center" />
|
||||
<ToggleButton Grid.Column="2" x:Name="_checkBoxPortVisible" VerticalAlignment="Center">
|
||||
<Viewbox StretchDirection="Both" Stretch="Uniform" Width="16" Height="16">
|
||||
<Grid Width="20" Height="20">
|
||||
<Ellipse x:Name="_ellipse" HorizontalAlignment="Left" VerticalAlignment="Center" Height="15" Width="15">
|
||||
<Ellipse.Fill>
|
||||
<SolidColorBrush Color="#505050" />
|
||||
</Ellipse.Fill>
|
||||
</Ellipse>
|
||||
<Path x:Name="_path" Data="M 0 0 L 4 4 L 0 8 Z" HorizontalAlignment="Right" VerticalAlignment="Center" Height="8" Width="4">
|
||||
<Path.Fill>
|
||||
<SolidColorBrush Color="#505050" />
|
||||
</Path.Fill>
|
||||
</Path>
|
||||
</Grid>
|
||||
</Viewbox>
|
||||
<ToggleButton.Triggers>
|
||||
<EventTrigger RoutedEvent="ToggleButton.Checked">
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<ColorAnimation Storyboard.TargetName="_ellipse"
|
||||
Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)"
|
||||
Duration="0:0:0.2" From="#505050" To="White" />
|
||||
<ColorAnimation Storyboard.TargetName="_path"
|
||||
Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)"
|
||||
Duration="0:0:0.2" From="#505050" To="White" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</EventTrigger>
|
||||
<EventTrigger RoutedEvent="ToggleButton.Unchecked">
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<ColorAnimation Storyboard.TargetName="_ellipse"
|
||||
Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)"
|
||||
Duration="0:0:0.2" From="White" To="#505050" />
|
||||
<ColorAnimation Storyboard.TargetName="_path"
|
||||
Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)"
|
||||
Duration="0:0:0.2" From="White" To="#505050" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</EventTrigger>
|
||||
</ToggleButton.Triggers>
|
||||
</ToggleButton>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
16
intromat/Intromat/Views/Editors/EditorHeader.xaml.cs
Normal file
16
intromat/Intromat/Views/Editors/EditorHeader.xaml.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Intromat.Views.Editors
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for EditorHeader.xaml
|
||||
/// </summary>
|
||||
public partial class EditorHeader : UserControl
|
||||
{
|
||||
public EditorHeader()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
88
intromat/Intromat/Views/Editors/EditorViewBase.cs
Normal file
88
intromat/Intromat/Views/Editors/EditorViewBase.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Forms.VisualStyles;
|
||||
using Intromat.Interfaces;
|
||||
using Intromat.Nodes.Code;
|
||||
using Intromat.ViewModels;
|
||||
using NodeNetwork.ViewModels;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Intromat.Views.Editors
|
||||
{
|
||||
[TemplatePart(Name = nameof(_header), Type = typeof(EditorHeader))]
|
||||
[TemplatePart(Name = nameof(_content), Type = typeof(Panel))]
|
||||
public abstract class EditorViewBase<T> : ContentControl, IViewFor<T> where T : NodeEndpointEditorViewModel
|
||||
{
|
||||
protected EditorHeader _header = null!;
|
||||
protected Panel _content = null!;
|
||||
|
||||
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel),
|
||||
typeof(T), typeof(EditorViewBase<T>), new PropertyMetadata(null));
|
||||
|
||||
protected EditorViewBase()
|
||||
{
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
this.Bind(ViewModel, vm => vm.Parent.Name, v => v._header._textBlockName.Text)
|
||||
.DisposeWith(d);
|
||||
|
||||
if (ViewModel is IExpressionEditor expressionEditor)
|
||||
{
|
||||
if (expressionEditor.HasParentSource)
|
||||
_header._comboBoxRelativeSource.Items.Add(ERelativeSource.Parent);
|
||||
if (expressionEditor.HasInputSource)
|
||||
_header._comboBoxRelativeSource.Items.Add(ERelativeSource.Input);
|
||||
|
||||
if (_header._comboBoxRelativeSource.Items.Count > 0)
|
||||
_header._comboBoxRelativeSource.Items.Add(ERelativeSource.Custom);
|
||||
else
|
||||
_header._comboBoxRelativeSource.Visibility = Visibility.Collapsed;
|
||||
|
||||
this.Bind(expressionEditor, vm => vm.RelativeSource, v => v._header._comboBoxRelativeSource.SelectedItem)
|
||||
.DisposeWith(d);
|
||||
|
||||
if (expressionEditor.CodeGenPort.PortType == EPortType.None)
|
||||
{
|
||||
_header._checkBoxPortVisible.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Bind(expressionEditor, vm => vm.CodeGenPort.IsPortVisible, v => v._header._checkBoxPortVisible.IsChecked)
|
||||
.DisposeWith(d);
|
||||
this.OneWayBind(expressionEditor, vm => vm.CodeGenPort.IsPortVisible, v => v._content.Visibility, portVisible => portVisible ? Visibility.Collapsed : Visibility.Visible)
|
||||
.DisposeWith(d);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_header._comboBoxRelativeSource.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
_header = (EditorHeader)GetTemplateChild(nameof(_header))!;
|
||||
_content = (Panel)GetTemplateChild(nameof(_content))!;
|
||||
}
|
||||
|
||||
public T? ViewModel
|
||||
{
|
||||
get => (T?)GetValue(ViewModelProperty);
|
||||
set => SetValue(ViewModelProperty, value);
|
||||
}
|
||||
|
||||
object? IViewFor.ViewModel
|
||||
{
|
||||
get => ViewModel;
|
||||
set => ViewModel = (T?)value;
|
||||
}
|
||||
}
|
||||
}
|
||||
34
intromat/Intromat/Views/Editors/EnumEditorView.cs
Normal file
34
intromat/Intromat/Views/Editors/EnumEditorView.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Intromat.ViewModels.Editors;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Intromat.Views.Editors
|
||||
{
|
||||
[TemplatePart(Name = nameof(_comboBoxValue), Type = typeof(ComboBox))]
|
||||
public class EnumEditorView : EditorViewBase<EnumEditorViewModel>
|
||||
{
|
||||
private ComboBox _comboBoxValue = null!;
|
||||
|
||||
public EnumEditorView()
|
||||
{
|
||||
DefaultStyleKey = typeof(EnumEditorView);
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
foreach (var name in Enum.GetNames(ViewModel!.EnumType))
|
||||
_comboBoxValue.Items.Add(name);
|
||||
|
||||
this.OneWayBind(ViewModel, vm => vm.Value, v => v._comboBoxValue.SelectedIndex).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
_comboBoxValue = (ComboBox)GetTemplateChild(nameof(_comboBoxValue))!;
|
||||
}
|
||||
}
|
||||
}
|
||||
37
intromat/Intromat/Views/Editors/FloatExpressionEditorView.cs
Normal file
37
intromat/Intromat/Views/Editors/FloatExpressionEditorView.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Intromat.Interfaces;
|
||||
using Intromat.ViewModels.Editors;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Intromat.Views.Editors
|
||||
{
|
||||
[TemplatePart(Name = nameof(_sliderValue), Type = typeof(Slider))]
|
||||
[TemplatePart(Name = nameof(_textBoxValue), Type = typeof(TextBox))]
|
||||
public class FloatExpressionEditorView : EditorViewBase<FloatExpressionEditorViewModel>
|
||||
{
|
||||
private Slider _sliderValue = null!;
|
||||
private TextBox _textBoxValue = null!;
|
||||
|
||||
public FloatExpressionEditorView()
|
||||
{
|
||||
DefaultStyleKey = typeof(FloatExpressionEditorView);
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
this.Bind(ViewModel, vm => vm.CustomValue, v => v._textBoxValue.Text).DisposeWith(d);
|
||||
this.Bind(ViewModel, vm => vm.CustomValue, v => v._sliderValue.Value, i => i, v => (float)v).DisposeWith(d);
|
||||
this.Bind(ViewModel, vm => vm.MinValue, v => v._sliderValue.Minimum, i => i, v => (float)v).DisposeWith(d);
|
||||
this.Bind(ViewModel, vm => vm.MaxValue, v => v._sliderValue.Maximum, i => i, v => (float)v).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
_sliderValue = (Slider)GetTemplateChild(nameof(_sliderValue))!;
|
||||
_textBoxValue = (TextBox)GetTemplateChild(nameof(_textBoxValue))!;
|
||||
}
|
||||
}
|
||||
}
|
||||
37
intromat/Intromat/Views/Editors/FloatValueEditorView.cs
Normal file
37
intromat/Intromat/Views/Editors/FloatValueEditorView.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Intromat.Interfaces;
|
||||
using Intromat.ViewModels.Editors;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Intromat.Views.Editors
|
||||
{
|
||||
[TemplatePart(Name = nameof(_sliderValue), Type = typeof(Slider))]
|
||||
[TemplatePart(Name = nameof(_textBoxValue), Type = typeof(TextBox))]
|
||||
public class FloatValueEditorView : EditorViewBase<FloatValueEditorViewModel>
|
||||
{
|
||||
private Slider _sliderValue = null!;
|
||||
private TextBox _textBoxValue = null!;
|
||||
|
||||
public FloatValueEditorView()
|
||||
{
|
||||
DefaultStyleKey = typeof(FloatValueEditorView);
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
this.Bind(ViewModel, vm => vm.Value, v => v._textBoxValue.Text).DisposeWith(d);
|
||||
this.Bind(ViewModel, vm => vm.Value, v => v._sliderValue.Value, i => i, v => (float)v).DisposeWith(d);
|
||||
this.Bind(ViewModel, vm => vm.MinValue, v => v._sliderValue.Minimum, i => i, v => (float)v).DisposeWith(d);
|
||||
this.Bind(ViewModel, vm => vm.MaxValue, v => v._sliderValue.Maximum, i => i, v => (float)v).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
_sliderValue = (Slider)GetTemplateChild(nameof(_sliderValue))!;
|
||||
_textBoxValue = (TextBox)GetTemplateChild(nameof(_textBoxValue))!;
|
||||
}
|
||||
}
|
||||
}
|
||||
15
intromat/Intromat/Views/Editors/GroupEndpointEditorView.xaml
Normal file
15
intromat/Intromat/Views/Editors/GroupEndpointEditorView.xaml
Normal file
@@ -0,0 +1,15 @@
|
||||
<UserControl x:Class="Intromat.Views.Editors.GroupEndpointEditorView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="25" d:DesignWidth="800">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBox x:Name="nameTextBox" Width="125" />
|
||||
<ToggleButton x:Name="editNameButton" Margin="5,0,0,0">Edit name</ToggleButton>
|
||||
<Button x:Name="upButton" Margin="5,0,0,0">▲</Button>
|
||||
<Button x:Name="downButton" Margin="5,0,0,0">▼</Button>
|
||||
<Button x:Name="deleteButton" Margin="5,0,0,0">Delete</Button>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,45 @@
|
||||
using System.Diagnostics;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Reactive.Linq;
|
||||
using System.Windows;
|
||||
using Intromat.ViewModels.Nodes;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Intromat.Views.Editors
|
||||
{
|
||||
public partial class GroupEndpointEditorView : IViewFor<IGroupEndpointEditorViewModel>
|
||||
{
|
||||
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel),
|
||||
typeof(IGroupEndpointEditorViewModel), typeof(GroupEndpointEditorView), new PropertyMetadata(null));
|
||||
|
||||
public GroupEndpointEditorView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.WhenAnyValue(v => v.editNameButton.IsChecked)
|
||||
.Select(isChecked => isChecked ?? false ? Visibility.Visible : Visibility.Collapsed)
|
||||
.BindTo(this, v => v.nameTextBox.Visibility);
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
Debug.Assert(ViewModel != null, nameof(ViewModel) + " != null");
|
||||
this.Bind(ViewModel, vm => vm.Endpoint.Name, v => v.nameTextBox.Text).DisposeWith(d);
|
||||
this.BindCommand(ViewModel, vm => vm.MoveUp, v => v.upButton).DisposeWith(d);
|
||||
this.BindCommand(ViewModel, vm => vm.MoveDown, v => v.downButton).DisposeWith(d);
|
||||
this.BindCommand(ViewModel, vm => vm.Delete, v => v.deleteButton).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
public IGroupEndpointEditorViewModel? ViewModel
|
||||
{
|
||||
get => (IGroupEndpointEditorViewModel?)GetValue(ViewModelProperty);
|
||||
set => SetValue(ViewModelProperty, value);
|
||||
}
|
||||
|
||||
object? IViewFor.ViewModel
|
||||
{
|
||||
get => ViewModel;
|
||||
set => ViewModel = (IGroupEndpointEditorViewModel?)value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Intromat.Interfaces;
|
||||
using Intromat.ViewModels.Editors;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Intromat.Views.Editors
|
||||
{
|
||||
[TemplatePart(Name = nameof(_sliderValue), Type = typeof(Slider))]
|
||||
[TemplatePart(Name = nameof(_textBoxValue), Type = typeof(TextBox))]
|
||||
public class IntegerExpressionEditorView : EditorViewBase<IntegerExpressionEditorViewModel>
|
||||
{
|
||||
private Slider _sliderValue = null!;
|
||||
private TextBox _textBoxValue = null!;
|
||||
|
||||
public IntegerExpressionEditorView()
|
||||
{
|
||||
DefaultStyleKey = typeof(IntegerExpressionEditorView);
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
this.Bind(ViewModel, vm => vm.CustomValue, v => v._textBoxValue.Text).DisposeWith(d);
|
||||
this.Bind(ViewModel, vm => vm.CustomValue, v => v._sliderValue.Value, i => i, v => (int)v).DisposeWith(d);
|
||||
this.Bind(ViewModel, vm => vm.MinValue, v => v._sliderValue.Minimum, i => i, v => (int)v).DisposeWith(d);
|
||||
this.Bind(ViewModel, vm => vm.MaxValue, v => v._sliderValue.Maximum, i => i, v => (int)v).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
_sliderValue = (Slider)GetTemplateChild(nameof(_sliderValue))!;
|
||||
_textBoxValue = (TextBox)GetTemplateChild(nameof(_textBoxValue))!;
|
||||
}
|
||||
}
|
||||
}
|
||||
37
intromat/Intromat/Views/Editors/IntegerValueEditorView.cs
Normal file
37
intromat/Intromat/Views/Editors/IntegerValueEditorView.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Intromat.Interfaces;
|
||||
using Intromat.ViewModels.Editors;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Intromat.Views.Editors
|
||||
{
|
||||
[TemplatePart(Name = nameof(_sliderValue), Type = typeof(Slider))]
|
||||
[TemplatePart(Name = nameof(_textBoxValue), Type = typeof(TextBox))]
|
||||
public class IntegerValueEditorView : EditorViewBase<IntegerValueEditorViewModel>
|
||||
{
|
||||
private Slider _sliderValue = null!;
|
||||
private TextBox _textBoxValue = null!;
|
||||
|
||||
public IntegerValueEditorView()
|
||||
{
|
||||
DefaultStyleKey = typeof(IntegerValueEditorView);
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
this.Bind(ViewModel, vm => vm.Value, v => v._textBoxValue.Text).DisposeWith(d);
|
||||
this.Bind(ViewModel, vm => vm.Value, v => v._sliderValue.Value, i => i, v => (int)v).DisposeWith(d);
|
||||
this.Bind(ViewModel, vm => vm.MinValue, v => v._sliderValue.Minimum, i => i, v => (int)v).DisposeWith(d);
|
||||
this.Bind(ViewModel, vm => vm.MaxValue, v => v._sliderValue.Maximum, i => i, v => (int)v).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
_sliderValue = (Slider)GetTemplateChild(nameof(_sliderValue))!;
|
||||
_textBoxValue = (TextBox)GetTemplateChild(nameof(_textBoxValue))!;
|
||||
}
|
||||
}
|
||||
}
|
||||
44
intromat/Intromat/Views/Editors/SamplerEditorView.cs
Normal file
44
intromat/Intromat/Views/Editors/SamplerEditorView.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Intromat.Interfaces;
|
||||
using Intromat.ViewModels.Editors;
|
||||
using ReactiveUI;
|
||||
using SharpDX.Direct3D11;
|
||||
|
||||
namespace Intromat.Views.Editors
|
||||
{
|
||||
[TemplatePart(Name = nameof(_comboBoxFilter), Type = typeof(ComboBox))]
|
||||
[TemplatePart(Name = nameof(_comboBoxAddress), Type = typeof(ComboBox))]
|
||||
public class SamplerEditorView : EditorViewBase<SamplerEditorViewModel>
|
||||
{
|
||||
private ComboBox _comboBoxFilter = null!;
|
||||
private ComboBox _comboBoxAddress = null!;
|
||||
|
||||
public SamplerEditorView()
|
||||
{
|
||||
DefaultStyleKey = typeof(SamplerEditorView);
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
var addressNames = Enum.GetValues(typeof(TextureAddressMode)).Cast<TextureAddressMode>().ToArray();
|
||||
_comboBoxAddress.ItemsSource = addressNames;
|
||||
|
||||
var filterNames = Enum.GetValues(typeof(Filter)).Cast<Filter>();
|
||||
_comboBoxFilter.ItemsSource = filterNames;
|
||||
|
||||
this.Bind(ViewModel, vm => vm.Address, v => v._comboBoxAddress.SelectedItem).DisposeWith(d);
|
||||
this.Bind(ViewModel, vm => vm.Filter, v => v._comboBoxFilter.SelectedItem).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
_comboBoxFilter = (ComboBox)GetTemplateChild(nameof(_comboBoxFilter))!;
|
||||
_comboBoxAddress = (ComboBox)GetTemplateChild(nameof(_comboBoxAddress))!;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Intromat.ViewModels.Editors;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Intromat.Views.Editors
|
||||
{
|
||||
[TemplatePart(Name = nameof(_textBoxValue), Type = typeof(TextBox))]
|
||||
public class StringExpressionEditorView : EditorViewBase<StringExpressionEditorViewModel>
|
||||
{
|
||||
private TextBox _textBoxValue = null!;
|
||||
|
||||
public StringExpressionEditorView()
|
||||
{
|
||||
DefaultStyleKey = typeof(StringExpressionEditorView);
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
this.Bind(ViewModel, vm => vm.CustomValue, v => v._textBoxValue.Text).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
_textBoxValue = (TextBox)GetTemplateChild(nameof(_textBoxValue))!;
|
||||
}
|
||||
}
|
||||
}
|
||||
30
intromat/Intromat/Views/Editors/StringValueEditorView.cs
Normal file
30
intromat/Intromat/Views/Editors/StringValueEditorView.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Intromat.ViewModels.Editors;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Intromat.Views.Editors
|
||||
{
|
||||
[TemplatePart(Name = nameof(_textBoxValue), Type = typeof(TextBox))]
|
||||
public class StringValueEditorView : EditorViewBase<StringValueEditorViewModel>
|
||||
{
|
||||
private TextBox _textBoxValue = null!;
|
||||
|
||||
public StringValueEditorView()
|
||||
{
|
||||
DefaultStyleKey = typeof(StringValueEditorView);
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
this.Bind(ViewModel, vm => vm.Value, v => v._textBoxValue.Text).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
_textBoxValue = (TextBox)GetTemplateChild(nameof(_textBoxValue))!;
|
||||
}
|
||||
}
|
||||
}
|
||||
78
intromat/Intromat/Views/ExplorerView.xaml
Normal file
78
intromat/Intromat/Views/ExplorerView.xaml
Normal file
@@ -0,0 +1,78 @@
|
||||
<UserControl x:Class="Intromat.Views.ExplorerView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:viewModels="clr-namespace:Intromat.ViewModels"
|
||||
mc:Ignorable="d"
|
||||
d:DataContext="{d:DesignInstance {x:Type viewModels:ExplorerViewModel}}"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<UserControl.Resources>
|
||||
<Style x:Key="TreeViewIcon" TargetType="Image">
|
||||
<Setter Property="Width" Value="16" />
|
||||
<Setter Property="Height" Value="16" />
|
||||
<Setter Property="Stretch" Value="Uniform" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="UseLayoutRounding" Value="True" />
|
||||
<Setter Property="SnapsToDevicePixels" Value="True" />
|
||||
<Setter Property="Margin" Value="2,0,5,0" />
|
||||
</Style>
|
||||
<ContextMenu x:Key="projectMenu" x:Shared="True">
|
||||
<MenuItem x:Name="_newModuleButton" Header="New module..." Icon="{StaticResource ModuleImage}" />
|
||||
</ContextMenu>
|
||||
<ContextMenu x:Key="moduleMenu" x:Shared="True">
|
||||
<MenuItem x:Name="_renameModuleButton" Header="Rename module..." Icon="{StaticResource RenameImage}" />
|
||||
<MenuItem x:Name="_deleteModuleButton" Header="Delete module" Icon="{StaticResource DeleteImage}" />
|
||||
<MenuItem x:Name="_createModuleFolderButton" Header="Create folder..." Icon="{StaticResource FolderOpenImage}" />
|
||||
<MenuItem x:Name="_createModuleFileButton" Header="Create file..." Icon="{StaticResource GraphImage}" />
|
||||
</ContextMenu>
|
||||
<ContextMenu x:Key="folderMenu" x:Shared="True">
|
||||
<MenuItem x:Name="_renameFolderButton" Header="Rename folder..." Icon="{StaticResource RenameImage}" />
|
||||
<MenuItem x:Name="_deleteFolderButton" Header="Delete folder" Icon="{StaticResource DeleteImage}" />
|
||||
<MenuItem x:Name="_createSubFolderButton" Header="Create folder..." Icon="{StaticResource FolderOpenImage}" />
|
||||
<MenuItem x:Name="_createSubFileButton" Header="Create file..." Icon="{StaticResource GraphImage}" />
|
||||
</ContextMenu>
|
||||
<ContextMenu x:Key="documentMenu" x:Shared="True">
|
||||
<MenuItem x:Name="_renameFileButton" Header="Rename file..." Icon="{StaticResource RenameImage}" />
|
||||
<MenuItem x:Name="_deleteFileButton" Header="Delete file" Icon="{StaticResource DeleteImage}" />
|
||||
</ContextMenu>
|
||||
</UserControl.Resources>
|
||||
<TreeView x:Name="_treeView">
|
||||
<TreeView.Resources>
|
||||
<Style TargetType="TreeViewItem" BasedOn="{StaticResource {x:Type TreeViewItem}}">
|
||||
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
|
||||
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
|
||||
</Style>
|
||||
<HierarchicalDataTemplate DataType="{x:Type viewModels:ProjectViewModel}" ItemsSource="{Binding Modules}">
|
||||
<StackPanel Orientation="Horizontal" Height="20" ContextMenu="{StaticResource projectMenu}">
|
||||
<Image Style="{StaticResource TreeViewIcon}" Source="{StaticResource ProjectImageSource}" />
|
||||
<TextBlock Text="{Binding Name}" VerticalAlignment="Center" Margin="0,0,2,0" />
|
||||
</StackPanel>
|
||||
</HierarchicalDataTemplate>
|
||||
<HierarchicalDataTemplate DataType="{x:Type viewModels:ModuleViewModel}" ItemsSource="{Binding TreeChildren}">
|
||||
<StackPanel Orientation="Horizontal" Height="20" ContextMenu="{StaticResource moduleMenu}">
|
||||
<Image Style="{StaticResource TreeViewIcon}" Source="{StaticResource ModuleImageSource}" />
|
||||
<TextBlock Text="{Binding Name}" VerticalAlignment="Center" Margin="0,0,2,0" />
|
||||
</StackPanel>
|
||||
</HierarchicalDataTemplate>
|
||||
<HierarchicalDataTemplate DataType="{x:Type viewModels:FolderViewModel}" ItemsSource="{Binding TreeChildren}">
|
||||
<StackPanel Orientation="Horizontal" Height="20" ContextMenu="{StaticResource folderMenu}">
|
||||
<Image Style="{StaticResource TreeViewIcon}" Source="{StaticResource FolderClosedImageSource}" />
|
||||
<TextBlock Text="{Binding Name}" VerticalAlignment="Center" Margin="0,0,2,0" />
|
||||
</StackPanel>
|
||||
</HierarchicalDataTemplate>
|
||||
<DataTemplate DataType="{x:Type viewModels:DocumentViewModel}">
|
||||
<StackPanel Orientation="Horizontal" Height="20" ContextMenu="{StaticResource documentMenu}">
|
||||
<Image Style="{StaticResource TreeViewIcon}" Source="{StaticResource GraphImageSource}" />
|
||||
<TextBlock Text="{Binding Name}" VerticalAlignment="Center" Margin="0,0,2,0" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
<DataTemplate DataType="{x:Type viewModels:ShaderFileViewModel}">
|
||||
<StackPanel Orientation="Horizontal" Height="20" ContextMenu="{StaticResource documentMenu}">
|
||||
<Image Style="{StaticResource TreeViewIcon}" Source="{StaticResource GraphImageSource}" />
|
||||
<TextBlock Text="{Binding Name}" VerticalAlignment="Center" Margin="0,0,2,0" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</TreeView.Resources>
|
||||
</TreeView>
|
||||
</UserControl>
|
||||
105
intromat/Intromat/Views/ExplorerView.xaml.cs
Normal file
105
intromat/Intromat/Views/ExplorerView.xaml.cs
Normal file
@@ -0,0 +1,105 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using Intromat.ViewModels;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Intromat.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ExplorerView.xaml
|
||||
/// </summary>
|
||||
public partial class ExplorerView : IViewFor<ExplorerViewModel>
|
||||
{
|
||||
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel), typeof(ExplorerViewModel), typeof(ExplorerView), new PropertyMetadata(null));
|
||||
private readonly MenuItem _newModuleButton;
|
||||
private readonly MenuItem _renameModuleButton;
|
||||
private readonly MenuItem _deleteModuleButton;
|
||||
private readonly MenuItem _createModuleFolderButton;
|
||||
private readonly MenuItem _renameFolderButton;
|
||||
private readonly MenuItem _deleteFolderButton;
|
||||
private readonly MenuItem _createSubFolderButton;
|
||||
private readonly MenuItem _createModuleFileButton;
|
||||
private readonly MenuItem _createSubFileButton;
|
||||
private readonly MenuItem _renameFileButton;
|
||||
private readonly MenuItem _deleteFileButton;
|
||||
|
||||
public ExplorerView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
var projectMenu = (ContextMenu)Resources["projectMenu"];
|
||||
var projectMenuItems = projectMenu.Items.OfType<MenuItem>().ToList();
|
||||
_newModuleButton = projectMenuItems.First(c => c.Name == nameof(_newModuleButton));
|
||||
|
||||
var moduleMenu = (ContextMenu)Resources["moduleMenu"];
|
||||
var moduleMenuItems = moduleMenu.Items.OfType<MenuItem>().ToList();
|
||||
_renameModuleButton = moduleMenuItems.First(c => c.Name == nameof(_renameModuleButton));
|
||||
_deleteModuleButton = moduleMenuItems.First(c => c.Name == nameof(_deleteModuleButton));
|
||||
_createModuleFolderButton = moduleMenuItems.First(c => c.Name == nameof(_createModuleFolderButton));
|
||||
_createModuleFileButton = moduleMenuItems.First(c => c.Name == nameof(_createModuleFileButton));
|
||||
|
||||
var folderMenu = (ContextMenu)Resources["folderMenu"];
|
||||
var folderMenuItems = folderMenu.Items.OfType<MenuItem>().ToList();
|
||||
_renameFolderButton = folderMenuItems.First(c => c.Name == nameof(_renameFolderButton));
|
||||
_deleteFolderButton = folderMenuItems.First(c => c.Name == nameof(_deleteFolderButton));
|
||||
_createSubFolderButton = folderMenuItems.First(c => c.Name == nameof(_createSubFolderButton));
|
||||
_createSubFileButton = folderMenuItems.First(c => c.Name == nameof(_createSubFileButton));
|
||||
|
||||
var documentMenu = (ContextMenu)Resources["documentMenu"];
|
||||
var documentMenuItems = documentMenu.Items.OfType<MenuItem>().ToList();
|
||||
_renameFileButton = documentMenuItems.First(c => c.Name == nameof(_renameFileButton));
|
||||
_deleteFileButton = documentMenuItems.First(c => c.Name == nameof(_deleteFileButton));
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
_treeView.ItemsSource = ViewModel!.TreeRoot;
|
||||
_treeView.Events().MouseDoubleClick.Subscribe(OnTreeViewDoubleClicked);
|
||||
projectMenu.Events().DataContextChanged.Subscribe(args => ViewModel.CurrentProject = (ProjectViewModel)args.NewValue);
|
||||
moduleMenu.Events().DataContextChanged.Subscribe(args => ViewModel.CurrentModule = (ModuleViewModel)args.NewValue);
|
||||
folderMenu.Events().DataContextChanged.Subscribe(args => ViewModel.CurrentFolder = (FolderViewModel)args.NewValue);
|
||||
documentMenu.Events().DataContextChanged.Subscribe(args => ViewModel.CurrentFile = (FileViewModel)args.NewValue);
|
||||
|
||||
this.BindCommand(ViewModel, vm => vm.NewModule, v => v._newModuleButton).DisposeWith(d);
|
||||
this.BindCommand(ViewModel, vm => vm.RenameModule, v => v._renameModuleButton).DisposeWith(d);
|
||||
this.BindCommand(ViewModel, vm => vm.DeleteModule, v => v._deleteModuleButton).DisposeWith(d);
|
||||
this.BindCommand(ViewModel, vm => vm.NewModuleFolder, v => v._createModuleFolderButton).DisposeWith(d);
|
||||
this.BindCommand(ViewModel, vm => vm.NewSubFolder, v => v._createSubFolderButton).DisposeWith(d);
|
||||
this.BindCommand(ViewModel, vm => vm.RenameFolder, v => v._renameFolderButton).DisposeWith(d);
|
||||
this.BindCommand(ViewModel, vm => vm.DeleteFolder, v => v._deleteFolderButton).DisposeWith(d);
|
||||
this.BindCommand(ViewModel, vm => vm.NewFile, v => v._createModuleFileButton).DisposeWith(d);
|
||||
this.BindCommand(ViewModel, vm => vm.NewFile, v => v._createSubFileButton).DisposeWith(d);
|
||||
this.BindCommand(ViewModel, vm => vm.RenameFile, v => v._renameFileButton).DisposeWith(d);
|
||||
this.BindCommand(ViewModel, vm => vm.DeleteFile, v => v._deleteFileButton).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
object? IViewFor.ViewModel
|
||||
{
|
||||
get => ViewModel;
|
||||
set => ViewModel = (ExplorerViewModel?)value;
|
||||
}
|
||||
|
||||
public ExplorerViewModel? ViewModel
|
||||
{
|
||||
get => (ExplorerViewModel?)GetValue(ViewModelProperty);
|
||||
set => SetValue(ViewModelProperty, value);
|
||||
}
|
||||
|
||||
private void OnTreeViewDoubleClicked(MouseButtonEventArgs args)
|
||||
{
|
||||
var vm = ((FrameworkElement)args.OriginalSource).DataContext;
|
||||
if (vm is FileViewModel fileVm)
|
||||
{
|
||||
var mainVm = ViewModel!.MainViewModel;
|
||||
if (mainVm.Files.All(d => d != fileVm))
|
||||
mainVm.Files.Add(fileVm);
|
||||
|
||||
mainVm.ActiveFile = fileVm;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
intromat/Intromat/Views/GroupNodeView.xaml
Normal file
24
intromat/Intromat/Views/GroupNodeView.xaml
Normal file
@@ -0,0 +1,24 @@
|
||||
<UserControl x:Class="Intromat.Views.GroupNodeView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:views="clr-namespace:Intromat.Views"
|
||||
xmlns:newEndpointDropPanel="clr-namespace:NodeNetwork.Toolkit.Group.AddEndpointDropPanel;assembly=NodeNetworkToolkit"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300" d:DesignWidth="300">
|
||||
<views:CodeGenNodeView x:Name="NodeView">
|
||||
<views:CodeGenNodeView.TrailingControlPresenterStyle>
|
||||
<Style TargetType="ContentPresenter">
|
||||
<Setter Property="Content" Value="{Binding AddEndpointDropPanelVM}" />
|
||||
<Setter Property="ContentTemplate">
|
||||
<Setter.Value>
|
||||
<DataTemplate>
|
||||
<newEndpointDropPanel:AddEndpointDropPanelView ViewModel="{Binding }" Margin="0,5,0,0" />
|
||||
</DataTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</views:CodeGenNodeView.TrailingControlPresenterStyle>
|
||||
</views:CodeGenNodeView>
|
||||
</UserControl>
|
||||
38
intromat/Intromat/Views/GroupNodeView.xaml.cs
Normal file
38
intromat/Intromat/Views/GroupNodeView.xaml.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using Intromat.ViewModels.Nodes;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Intromat.Views
|
||||
{
|
||||
public partial class GroupNodeView : IViewFor<GroupNodeViewModel>
|
||||
{
|
||||
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel),
|
||||
typeof(GroupNodeViewModel), typeof(GroupNodeView), new PropertyMetadata(null));
|
||||
|
||||
public GroupNodeView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
NodeView.ViewModel = ViewModel;
|
||||
Disposable.Create(() => NodeView.ViewModel = null).DisposeWith(d);
|
||||
|
||||
this.OneWayBind(ViewModel, vm => vm.NodeType, v => v.NodeView.Background, CodeGenNodeView.ConvertNodeTypeToBrush).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
public GroupNodeViewModel? ViewModel
|
||||
{
|
||||
get => (GroupNodeViewModel?)GetValue(ViewModelProperty);
|
||||
set => SetValue(ViewModelProperty, value);
|
||||
}
|
||||
|
||||
object? IViewFor.ViewModel
|
||||
{
|
||||
get => ViewModel;
|
||||
set => ViewModel = (GroupNodeViewModel?)value;
|
||||
}
|
||||
}
|
||||
}
|
||||
24
intromat/Intromat/Views/GroupSubnetIONodeView.xaml
Normal file
24
intromat/Intromat/Views/GroupSubnetIONodeView.xaml
Normal file
@@ -0,0 +1,24 @@
|
||||
<UserControl x:Class="Intromat.Views.GroupSubnetIONodeView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:views="clr-namespace:Intromat.Views"
|
||||
xmlns:addEndpointDropPanel="clr-namespace:NodeNetwork.Toolkit.Group.AddEndpointDropPanel;assembly=NodeNetworkToolkit"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<views:CodeGenNodeView x:Name="NodeView">
|
||||
<views:CodeGenNodeView.TrailingControlPresenterStyle>
|
||||
<Style TargetType="ContentPresenter">
|
||||
<Setter Property="Content" Value="{Binding AddEndpointDropPanelVM}" />
|
||||
<Setter Property="ContentTemplate">
|
||||
<Setter.Value>
|
||||
<DataTemplate>
|
||||
<addEndpointDropPanel:AddEndpointDropPanelView ViewModel="{Binding }" Margin="0,5,0,0" />
|
||||
</DataTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</views:CodeGenNodeView.TrailingControlPresenterStyle>
|
||||
</views:CodeGenNodeView>
|
||||
</UserControl>
|
||||
38
intromat/Intromat/Views/GroupSubnetIONodeView.xaml.cs
Normal file
38
intromat/Intromat/Views/GroupSubnetIONodeView.xaml.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using Intromat.ViewModels.Nodes;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Intromat.Views
|
||||
{
|
||||
public partial class GroupSubnetIONodeView : IViewFor<GroupSubnetIONodeViewModel>
|
||||
{
|
||||
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel),
|
||||
typeof(GroupSubnetIONodeViewModel), typeof(GroupSubnetIONodeView), new PropertyMetadata(null));
|
||||
|
||||
public GroupSubnetIONodeView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
NodeView.ViewModel = ViewModel;
|
||||
Disposable.Create(() => NodeView.ViewModel = null).DisposeWith(d);
|
||||
|
||||
this.OneWayBind(ViewModel, vm => vm.NodeType, v => v.NodeView.Background, CodeGenNodeView.ConvertNodeTypeToBrush).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
public GroupSubnetIONodeViewModel? ViewModel
|
||||
{
|
||||
get => (GroupSubnetIONodeViewModel?)GetValue(ViewModelProperty);
|
||||
set => SetValue(ViewModelProperty, value);
|
||||
}
|
||||
|
||||
object? IViewFor.ViewModel
|
||||
{
|
||||
get => ViewModel;
|
||||
set => ViewModel = (GroupSubnetIONodeViewModel?)value;
|
||||
}
|
||||
}
|
||||
}
|
||||
110
intromat/Intromat/Views/MainWindow.xaml
Normal file
110
intromat/Intromat/Views/MainWindow.xaml
Normal file
@@ -0,0 +1,110 @@
|
||||
<Window x:Class="Intromat.Views.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:nodeList="clr-namespace:NodeNetwork.Toolkit.NodeList;assembly=NodeNetworkToolkit"
|
||||
xmlns:views="clr-namespace:Intromat.Views"
|
||||
xmlns:viewModels="clr-namespace:Intromat.ViewModels"
|
||||
xmlns:reactiveUi="http://reactiveui.net"
|
||||
mc:Ignorable="d"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Style="{DynamicResource CustomWindowStyle}"
|
||||
Icon="{StaticResource LogoImageSource}"
|
||||
Height="960" Width="1280">
|
||||
<Grid Margin="0,-30,0,0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="30" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="120" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Menu Grid.Row="0" Margin="35,2,2,2" VerticalAlignment="Center" HorizontalAlignment="Left" WindowChrome.IsHitTestVisibleInChrome="True">
|
||||
<MenuItem Header="_File">
|
||||
<MenuItem Header="E_xit" />
|
||||
</MenuItem>
|
||||
<MenuItem Header="_Edit">
|
||||
<MenuItem Header="_Preferences..." />
|
||||
</MenuItem>
|
||||
<MenuItem Header="_Windows">
|
||||
<MenuItem x:Name="_menuExplorer" IsCheckable="True" IsChecked="{Binding IsVisible, ElementName=_explorerAnchorable, Mode=TwoWay}" Header="_Explorer" />
|
||||
<MenuItem x:Name="_menuLibrary" IsCheckable="True" IsChecked="{Binding IsVisible, ElementName=_libraryAnchorable, Mode=TwoWay}" Header="_Library" />
|
||||
<MenuItem x:Name="_menu3dView" IsCheckable="True" IsChecked="{Binding IsVisible, ElementName=_3dViewAnchorable, Mode=TwoWay}" Header="_3D View" />
|
||||
<MenuItem x:Name="_menu2dView" IsCheckable="True" IsChecked="{Binding IsVisible, ElementName=_2dViewAnchorable, Mode=TwoWay}" Header="_2D View" />
|
||||
<MenuItem x:Name="_menuParameters" IsCheckable="True" IsChecked="{Binding IsVisible, ElementName=_parametersAnchorable, Mode=TwoWay}" Header="_Parameters" />
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
<Border Grid.Row="0" Grid.Column="1" Margin="20,0,0,0" Background="{DynamicResource BackgroundColor}" HorizontalAlignment="Left" VerticalAlignment="Center">
|
||||
<TextBlock Text="Intromat" Margin="8,3" />
|
||||
</Border>
|
||||
</Grid>
|
||||
<ToolBarTray Grid.Row="1">
|
||||
<ToolBar>
|
||||
<Button Name="_openButton" Style="{StaticResource IconToolButton}" ToolTip="Open" Foreground="#C0A020" Content="" />
|
||||
<Button Name="_saveButton" Style="{StaticResource IconToolButton}" ToolTip="Save" Content="" />
|
||||
<Separator Style="{StaticResource VerticalSeparator}" />
|
||||
<views:UndoRedoView x:Name="_undoRedoView" VerticalAlignment="Stretch" />
|
||||
</ToolBar>
|
||||
</ToolBarTray>
|
||||
<DockingManager Grid.Row="2" x:Name="_dockingManager">
|
||||
<DockingManager.Resources>
|
||||
<DataTemplate DataType="{x:Type viewModels:DocumentViewModel}">
|
||||
<reactiveUi:ViewModelViewHost ViewModel="{Binding}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" />
|
||||
</DataTemplate>
|
||||
<DataTemplate DataType="{x:Type viewModels:ShaderFileViewModel}">
|
||||
<reactiveUi:ViewModelViewHost ViewModel="{Binding}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" />
|
||||
</DataTemplate>
|
||||
</DockingManager.Resources>
|
||||
<DockingManager.DocumentHeaderTemplate>
|
||||
<DataTemplate DataType="{x:Type LayoutDocument}">
|
||||
<TextBlock Text="{Binding Content.Name}" />
|
||||
</DataTemplate>
|
||||
</DockingManager.DocumentHeaderTemplate>
|
||||
<DockingManager.Theme>
|
||||
<Vs2013DarkTheme />
|
||||
</DockingManager.Theme>
|
||||
<LayoutRoot>
|
||||
<LayoutPanel>
|
||||
<LayoutAnchorablePaneGroup Orientation="Vertical" DockWidth="200">
|
||||
<LayoutAnchorablePane>
|
||||
<LayoutAnchorable x:Name="_explorerAnchorable" Title="EXPLORER">
|
||||
<views:ExplorerView x:Name="_explorerView" />
|
||||
</LayoutAnchorable>
|
||||
</LayoutAnchorablePane>
|
||||
<LayoutAnchorablePane>
|
||||
<LayoutAnchorable x:Name="_libraryAnchorable" Title="LIBRARY">
|
||||
<nodeList:NodeListView x:Name="_nodeList" />
|
||||
</LayoutAnchorable>
|
||||
</LayoutAnchorablePane>
|
||||
</LayoutAnchorablePaneGroup>
|
||||
<LayoutPanel Orientation="Vertical">
|
||||
<LayoutDocumentPane x:Name="_documentPane" />
|
||||
<LayoutAnchorablePaneGroup DockHeight="300">
|
||||
<LayoutAnchorablePane>
|
||||
<LayoutAnchorable x:Name="_3dViewAnchorable" Title="3D VIEW">
|
||||
<views:Preview3DView x:Name="_preview3dView" />
|
||||
</LayoutAnchorable>
|
||||
</LayoutAnchorablePane>
|
||||
<LayoutAnchorablePane>
|
||||
<LayoutAnchorable x:Name="_2dViewAnchorable" Title="2D VIEW">
|
||||
<views:Preview2DView x:Name="_preview2dView" />
|
||||
</LayoutAnchorable>
|
||||
</LayoutAnchorablePane>
|
||||
</LayoutAnchorablePaneGroup>
|
||||
</LayoutPanel>
|
||||
<LayoutAnchorablePane DockWidth="200">
|
||||
<LayoutAnchorable x:Name="_parametersAnchorable" Title="PARAMETERS">
|
||||
<views:PropertiesView x:Name="_propertiesView"/>
|
||||
</LayoutAnchorable>
|
||||
</LayoutAnchorablePane>
|
||||
</LayoutPanel>
|
||||
</LayoutRoot>
|
||||
</DockingManager>
|
||||
</Grid>
|
||||
</Window>
|
||||
84
intromat/Intromat/Views/MainWindow.xaml.cs
Normal file
84
intromat/Intromat/Views/MainWindow.xaml.cs
Normal file
@@ -0,0 +1,84 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using Intromat.Graphics;
|
||||
using Intromat.ViewModels;
|
||||
using Microsoft.Win32;
|
||||
using ReactiveUI;
|
||||
using Splat;
|
||||
|
||||
namespace Intromat.Views
|
||||
{
|
||||
public partial class MainWindow : IViewFor<MainViewModel>
|
||||
{
|
||||
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel),
|
||||
typeof(MainViewModel), typeof(MainWindow), new PropertyMetadata(null));
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
var dxHost = Locator.Current.GetService<DxHost>()!;
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
dxHost.Load(this);
|
||||
this.Events().Unloaded.Subscribe(_ => dxHost.Unload());
|
||||
|
||||
this.OneWayBind(ViewModel, vm => vm.PropertiesContext, v => v._propertiesView.ViewModel).DisposeWith(d);
|
||||
this.OneWayBind(ViewModel, vm => vm.Preview2dContext, v => v._preview2dView.ViewModel).DisposeWith(d);
|
||||
this.OneWayBind(ViewModel, vm => vm.Preview3dContext, v => v._preview3dView.ViewModel).DisposeWith(d);
|
||||
//this.OneWayBind(ViewModel, vm => vm.CodePreview, v => v._codePreviewView.ViewModel).DisposeWith(d);
|
||||
|
||||
Debug.Assert(ViewModel != null, nameof(ViewModel) + " != null");
|
||||
ViewModel.OpenProjectFile.RegisterHandler(interaction =>
|
||||
{
|
||||
FileDialog dialog;
|
||||
if (interaction.Input)
|
||||
dialog = new OpenFileDialog();
|
||||
else
|
||||
dialog = new SaveFileDialog();
|
||||
|
||||
dialog.FileName = "network.xml";
|
||||
dialog.AddExtension = true;
|
||||
dialog.DereferenceLinks = true;
|
||||
dialog.DefaultExt = "json";
|
||||
|
||||
interaction.SetOutput(dialog.ShowDialog() ?? false ? dialog.FileName : null);
|
||||
});
|
||||
|
||||
ViewModel.SelectName.RegisterHandler(interaction =>
|
||||
{
|
||||
interaction.SetOutput(UserInputWindow.Show(this, interaction.Input));
|
||||
});
|
||||
|
||||
ViewModel.SelectTypeAndFileName.RegisterHandler(interaction =>
|
||||
{
|
||||
interaction.SetOutput(NewFileWindow.Show(this, ViewModel));
|
||||
});
|
||||
|
||||
_dockingManager.DocumentsSource = ViewModel.Files;
|
||||
this.OneWayBind(ViewModel, vm => vm.Explorer, v => v._explorerView.ViewModel).DisposeWith(d);
|
||||
this.Bind(ViewModel, vm => vm.ActiveFile, v => v._dockingManager.ActiveContent).DisposeWith(d);
|
||||
this.OneWayBind(ViewModel, vm => vm.NodeList, v => v._nodeList.ViewModel).DisposeWith(d);
|
||||
this.OneWayBind(ViewModel, vm => vm.UndoRedo, v => v._undoRedoView.ViewModel).DisposeWith(d);
|
||||
this.OneWayBind(ViewModel, vm => vm.LoadProject, v => v._openButton.Command).DisposeWith(d);
|
||||
this.OneWayBind(ViewModel, vm => vm.SaveProject, v => v._saveButton.Command).DisposeWith(d);
|
||||
});
|
||||
|
||||
ViewModel = new MainViewModel();
|
||||
}
|
||||
|
||||
public MainViewModel? ViewModel
|
||||
{
|
||||
get => (MainViewModel?)GetValue(ViewModelProperty);
|
||||
set => SetValue(ViewModelProperty, value);
|
||||
}
|
||||
|
||||
object? IViewFor.ViewModel
|
||||
{
|
||||
get => ViewModel;
|
||||
set => ViewModel = (MainViewModel?)value;
|
||||
}
|
||||
}
|
||||
}
|
||||
43
intromat/Intromat/Views/NewFileWindow.xaml
Normal file
43
intromat/Intromat/Views/NewFileWindow.xaml
Normal file
@@ -0,0 +1,43 @@
|
||||
<Window x:Class="Intromat.Views.NewFileWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:System="clr-namespace:System;assembly=System.Runtime"
|
||||
xmlns:views="clr-namespace:Intromat.Views"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
ShowInTaskbar="False"
|
||||
ResizeMode="NoResize"
|
||||
Style="{DynamicResource CustomWindowStyle}"
|
||||
mc:Ignorable="d" SizeToContent="Height"
|
||||
Closing="NewFileWindow_OnClosing"
|
||||
Title="Intromat" MinHeight="50" Width="300">
|
||||
<Window.Resources>
|
||||
<ObjectDataProvider x:Key="supportedFileTypes" MethodName="GetValues" ObjectType="{x:Type System:Enum}">
|
||||
<ObjectDataProvider.MethodParameters>
|
||||
<x:Type TypeName="views:ESupportedFileTypes"/>
|
||||
</ObjectDataProvider.MethodParameters>
|
||||
</ObjectDataProvider>
|
||||
</Window.Resources>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Grid.Column="0" x:Name="Header" Grid.Row="0" Text="Enter details to create new file:" Margin="5" Grid.ColumnSpan="2" />
|
||||
<TextBlock Grid.Column="0" Grid.Row="1" Text="Type:" Margin="5" HorizontalAlignment="Right" />
|
||||
<ComboBox Grid.Column="1" x:Name="Type" Grid.Row="1" Text="" Margin="5,0" ItemsSource="{Binding Source={StaticResource supportedFileTypes}}" SelectionChanged="Type_OnSelectionChanged" />
|
||||
<TextBlock Grid.Column="0" Grid.Row="2" Text="Name:" Margin="5" HorizontalAlignment="Right" />
|
||||
<TextBox Grid.Column="1" x:Name="FileName" Grid.Row="2" Text="" Margin="5,0" TextChanged="Name_OnTextChanged" />
|
||||
<StackPanel Grid.Column="1" Grid.Row="3" Orientation="Horizontal" HorizontalAlignment="Right" Margin="5">
|
||||
<Button x:Name="ButtonOK" IsDefault="True" Width="60" Margin="0,0,2,0" Click="ButtonOK_OnClick">OK</Button>
|
||||
<Button x:Name="ButtonCancel" IsCancel="True" Width="60" Click="ButtonCancel_OnClick">Cancel</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
89
intromat/Intromat/Views/NewFileWindow.xaml.cs
Normal file
89
intromat/Intromat/Views/NewFileWindow.xaml.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Intromat.ViewModels;
|
||||
|
||||
namespace Intromat.Views
|
||||
{
|
||||
public enum ESupportedFileTypes
|
||||
{
|
||||
Network,
|
||||
Shader
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for NewFileWindow.xaml
|
||||
/// </summary>
|
||||
public partial class NewFileWindow
|
||||
{
|
||||
public NewFileWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
Type.SelectedItem = ESupportedFileTypes.Network;
|
||||
}
|
||||
|
||||
public Func<FileViewModel>? Result { get; set; }
|
||||
|
||||
public static Func<FileViewModel>? Show(Window? owner, MainViewModel mainVm, string? defaultValue = null)
|
||||
{
|
||||
var window = new NewFileWindow
|
||||
{
|
||||
MainViewModel = mainVm,
|
||||
Owner = owner
|
||||
};
|
||||
if (defaultValue != null)
|
||||
window.FileName.Text = defaultValue;
|
||||
window.FileName.SelectAll();
|
||||
window.FileName.Focus();
|
||||
window.UpdateResult();
|
||||
return window.ShowDialog() == true ? window.Result : null;
|
||||
}
|
||||
|
||||
public MainViewModel? MainViewModel { get; set; }
|
||||
|
||||
private void Type_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
UpdateResult();
|
||||
}
|
||||
|
||||
private void Name_OnTextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
UpdateResult();
|
||||
}
|
||||
|
||||
private void UpdateResult()
|
||||
{
|
||||
if (MainViewModel == null)
|
||||
return;
|
||||
|
||||
var module = MainViewModel.Explorer.CurrentModule!;
|
||||
var parent = MainViewModel.Explorer.CurrentFolder!;
|
||||
Result = (ESupportedFileTypes)Type.SelectedItem switch
|
||||
{
|
||||
ESupportedFileTypes.Network => () => new DocumentViewModel(MainViewModel, module, parent, FileName.Text),
|
||||
ESupportedFileTypes.Shader => () => new ShaderFileViewModel(MainViewModel, module, parent, FileName.Text),
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
}
|
||||
|
||||
private void ButtonOK_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DialogResult = true;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void ButtonCancel_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DialogResult = false;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void NewFileWindow_OnClosing(object sender, CancelEventArgs e)
|
||||
{
|
||||
if (DialogResult != true)
|
||||
Result = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
16
intromat/Intromat/Views/Preview2DView.xaml
Normal file
16
intromat/Intromat/Views/Preview2DView.xaml
Normal file
@@ -0,0 +1,16 @@
|
||||
<UserControl x:Class="Intromat.Views.Preview2DView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Intromat.Views"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid>
|
||||
<local:DxView x:Name="_dxView" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MouseWheel="OnDxViewMouseWheel">
|
||||
<local:DxView.RenderTransform>
|
||||
<MatrixTransform />
|
||||
</local:DxView.RenderTransform>
|
||||
</local:DxView>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
77
intromat/Intromat/Views/Preview2DView.xaml.cs
Normal file
77
intromat/Intromat/Views/Preview2DView.xaml.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using Intromat.Graphics;
|
||||
using Intromat.Pipelines;
|
||||
using Intromat.ViewModels.Previews;
|
||||
using ReactiveUI;
|
||||
using SharpDX.Direct3D11;
|
||||
using Splat;
|
||||
|
||||
namespace Intromat.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for Preview2DView.xaml
|
||||
/// </summary>
|
||||
public partial class Preview2DView : IViewFor<DxTexturePreviewViewModel>
|
||||
{
|
||||
private DisplayTexturePipeline? _pipeline;
|
||||
|
||||
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel),
|
||||
typeof(DxTexturePreviewViewModel), typeof(Preview2DView), new PropertyMetadata(null));
|
||||
|
||||
public Preview2DView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
_pipeline = Locator.Current.GetService<DisplayTexturePipeline>()!;
|
||||
this.WhenAnyObservable(v => v.ViewModel!.TextureValue).Subscribe(textureValue =>
|
||||
{
|
||||
var srv = textureValue?.ShaderResourceView;
|
||||
if (srv != null)
|
||||
{
|
||||
_pipeline.ShaderResourceView = srv;
|
||||
_dxView.Render();
|
||||
}
|
||||
}).DisposeWith(d);
|
||||
_dxView.SetUpdateHandler(UpdateFrameAction);
|
||||
});
|
||||
}
|
||||
|
||||
private void UpdateFrameAction(Device device, DeviceContext context)
|
||||
{
|
||||
var graphicsAnalysis = Locator.Current.GetService<DxHost>()?._graphicsAnalysis;
|
||||
graphicsAnalysis?.BeginCapture();
|
||||
_pipeline?.Apply();
|
||||
graphicsAnalysis?.EndCapture();
|
||||
}
|
||||
|
||||
private void OnDxViewMouseWheel(object sender, MouseWheelEventArgs e)
|
||||
{
|
||||
var element = (UIElement)sender;
|
||||
var position = e.GetPosition(element);
|
||||
var transform = (MatrixTransform)element.RenderTransform;
|
||||
var matrix = transform.Matrix;
|
||||
var scale = e.Delta >= 0 ? 1.1 : (1.0 / 1.1); // choose appropriate scaling factor
|
||||
|
||||
matrix.ScaleAtPrepend(scale, scale, position.X, position.Y);
|
||||
transform.Matrix = matrix;
|
||||
}
|
||||
|
||||
object? IViewFor.ViewModel
|
||||
{
|
||||
get => ViewModel;
|
||||
set => ViewModel = (DxTexturePreviewViewModel?)value;
|
||||
}
|
||||
|
||||
public DxTexturePreviewViewModel? ViewModel
|
||||
{
|
||||
get => (DxTexturePreviewViewModel?)GetValue(ViewModelProperty);
|
||||
set => SetValue(ViewModelProperty, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
16
intromat/Intromat/Views/Preview3DView.xaml
Normal file
16
intromat/Intromat/Views/Preview3DView.xaml
Normal file
@@ -0,0 +1,16 @@
|
||||
<UserControl x:Class="Intromat.Views.Preview3DView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Intromat.Views"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid>
|
||||
<local:DxView x:Name="_dxView" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MouseWheel="OnDxViewMouseWheel">
|
||||
<local:DxView.RenderTransform>
|
||||
<MatrixTransform />
|
||||
</local:DxView.RenderTransform>
|
||||
</local:DxView>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
77
intromat/Intromat/Views/Preview3DView.xaml.cs
Normal file
77
intromat/Intromat/Views/Preview3DView.xaml.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using Intromat.Graphics;
|
||||
using Intromat.Pipelines;
|
||||
using Intromat.ViewModels.Previews;
|
||||
using ReactiveUI;
|
||||
using SharpDX.Direct3D11;
|
||||
using Splat;
|
||||
|
||||
namespace Intromat.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for Preview3DView.xaml
|
||||
/// </summary>
|
||||
public partial class Preview3DView : IViewFor<DxMeshPreviewViewModel>
|
||||
{
|
||||
private DisplayMeshPipeline? _pipeline;
|
||||
|
||||
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel),
|
||||
typeof(DxMeshPreviewViewModel), typeof(Preview3DView), new PropertyMetadata(null));
|
||||
|
||||
public Preview3DView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
_pipeline = Locator.Current.GetService<DisplayMeshPipeline>()!;
|
||||
this.WhenAnyObservable(v => v.ViewModel!.MeshValue).Subscribe(textureValue =>
|
||||
{
|
||||
//var srv = textureValue?.ShaderResourceView;
|
||||
//if (srv != null)
|
||||
//{
|
||||
// _pipeline.ShaderResourceView = srv;
|
||||
// _dxView.Render();
|
||||
//}
|
||||
}).DisposeWith(d);
|
||||
_dxView.SetUpdateHandler(UpdateFrameAction);
|
||||
});
|
||||
}
|
||||
|
||||
private void UpdateFrameAction(Device device, DeviceContext context)
|
||||
{
|
||||
var graphicsAnalysis = Locator.Current.GetService<DxHost>()?._graphicsAnalysis;
|
||||
graphicsAnalysis?.BeginCapture();
|
||||
_pipeline?.Apply();
|
||||
graphicsAnalysis?.EndCapture();
|
||||
}
|
||||
|
||||
private void OnDxViewMouseWheel(object sender, MouseWheelEventArgs e)
|
||||
{
|
||||
var element = (UIElement)sender;
|
||||
var position = e.GetPosition(element);
|
||||
var transform = (MatrixTransform)element.RenderTransform;
|
||||
var matrix = transform.Matrix;
|
||||
var scale = e.Delta >= 0 ? 1.1 : (1.0 / 1.1); // choose appropriate scaling factor
|
||||
|
||||
matrix.ScaleAtPrepend(scale, scale, position.X, position.Y);
|
||||
transform.Matrix = matrix;
|
||||
}
|
||||
|
||||
object? IViewFor.ViewModel
|
||||
{
|
||||
get => ViewModel;
|
||||
set => ViewModel = (DxMeshPreviewViewModel?)value;
|
||||
}
|
||||
|
||||
public DxMeshPreviewViewModel? ViewModel
|
||||
{
|
||||
get => (DxMeshPreviewViewModel?)GetValue(ViewModelProperty);
|
||||
set => SetValue(ViewModelProperty, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
12
intromat/Intromat/Views/Previews/DxMeshPreview.xaml
Normal file
12
intromat/Intromat/Views/Previews/DxMeshPreview.xaml
Normal file
@@ -0,0 +1,12 @@
|
||||
<UserControl x:Class="Intromat.Views.Previews.DxMeshPreview"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:views="clr-namespace:Intromat.Views"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid Margin="5">
|
||||
<views:DxView x:Name="_dxView" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
63
intromat/Intromat/Views/Previews/DxMeshPreview.xaml.cs
Normal file
63
intromat/Intromat/Views/Previews/DxMeshPreview.xaml.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Reactive.Disposables;
|
||||
using Intromat.Graphics;
|
||||
using Intromat.Pipelines;
|
||||
using Intromat.ViewModels;
|
||||
using Intromat.ViewModels.Previews;
|
||||
using ReactiveUI;
|
||||
using SharpDX.Direct3D11;
|
||||
using Splat;
|
||||
|
||||
namespace Intromat.Views.Previews
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for DxMeshPreview.xaml
|
||||
/// </summary>
|
||||
public partial class DxMeshPreview : IViewFor<DxMeshPreviewViewModel>
|
||||
{
|
||||
private DisplayMeshPipeline? _pipeline;
|
||||
|
||||
public DxMeshPreview()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
MouseDoubleClick += (_, _) =>
|
||||
{
|
||||
if (ViewModel == null)
|
||||
return;
|
||||
|
||||
var network = (CodeGenNetworkViewModel)ViewModel.Parent.Parent;
|
||||
var main = network.Document.MainViewModel;
|
||||
main.Preview3dContext = ViewModel;
|
||||
};
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
_pipeline = Locator.Current.GetService<DisplayMeshPipeline>()!;
|
||||
this.WhenAnyObservable(v => v.ViewModel!.MeshValue).Subscribe(meshValue =>
|
||||
{
|
||||
//var srv = meshValue?.ShaderResourceView;
|
||||
//if (srv != null)
|
||||
//{
|
||||
// _pipeline.ShaderResourceView = srv;
|
||||
// _dxView.Render();
|
||||
//}
|
||||
}).DisposeWith(d);
|
||||
_dxView.SetUpdateHandler(UpdateFrameAction);
|
||||
});
|
||||
}
|
||||
|
||||
private void UpdateFrameAction(Device device, DeviceContext context)
|
||||
{
|
||||
_pipeline?.Apply();
|
||||
}
|
||||
|
||||
object? IViewFor.ViewModel
|
||||
{
|
||||
get => ViewModel;
|
||||
set => ViewModel = (DxMeshPreviewViewModel?)value;
|
||||
}
|
||||
|
||||
public DxMeshPreviewViewModel? ViewModel { get; set; }
|
||||
}
|
||||
}
|
||||
12
intromat/Intromat/Views/Previews/DxTexturePreview.xaml
Normal file
12
intromat/Intromat/Views/Previews/DxTexturePreview.xaml
Normal file
@@ -0,0 +1,12 @@
|
||||
<UserControl x:Class="Intromat.Views.Previews.DxTexturePreview"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:views="clr-namespace:Intromat.Views"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid Margin="5">
|
||||
<views:DxView x:Name="_dxView" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
63
intromat/Intromat/Views/Previews/DxTexturePreview.xaml.cs
Normal file
63
intromat/Intromat/Views/Previews/DxTexturePreview.xaml.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Reactive.Disposables;
|
||||
using Intromat.Graphics;
|
||||
using Intromat.Pipelines;
|
||||
using Intromat.ViewModels;
|
||||
using Intromat.ViewModels.Previews;
|
||||
using ReactiveUI;
|
||||
using SharpDX.Direct3D11;
|
||||
using Splat;
|
||||
|
||||
namespace Intromat.Views.Previews
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for DxTexturePreview.xaml
|
||||
/// </summary>
|
||||
public partial class DxTexturePreview : IViewFor<DxTexturePreviewViewModel>
|
||||
{
|
||||
private DisplayTexturePipeline? _pipeline;
|
||||
|
||||
public DxTexturePreview()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
MouseDoubleClick += (_, _) =>
|
||||
{
|
||||
if (ViewModel == null)
|
||||
return;
|
||||
|
||||
var network = (CodeGenNetworkViewModel)ViewModel.Parent.Parent;
|
||||
var main = network.Document.MainViewModel;
|
||||
main.Preview2dContext = ViewModel;
|
||||
};
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
_pipeline = Locator.Current.GetService<DisplayTexturePipeline>()!;
|
||||
this.WhenAnyObservable(v => v.ViewModel!.TextureValue).Subscribe(textureValue =>
|
||||
{
|
||||
var srv = textureValue?.ShaderResourceView;
|
||||
if (srv != null)
|
||||
{
|
||||
_pipeline.ShaderResourceView = srv;
|
||||
_dxView.Render();
|
||||
}
|
||||
}).DisposeWith(d);
|
||||
_dxView.SetUpdateHandler(UpdateFrameAction);
|
||||
});
|
||||
}
|
||||
|
||||
private void UpdateFrameAction(Device device, DeviceContext context)
|
||||
{
|
||||
_pipeline?.Apply();
|
||||
}
|
||||
|
||||
object? IViewFor.ViewModel
|
||||
{
|
||||
get => ViewModel;
|
||||
set => ViewModel = (DxTexturePreviewViewModel?)value;
|
||||
}
|
||||
|
||||
public DxTexturePreviewViewModel? ViewModel { get; set; }
|
||||
}
|
||||
}
|
||||
12
intromat/Intromat/Views/Previews/StringPreview.xaml
Normal file
12
intromat/Intromat/Views/Previews/StringPreview.xaml
Normal file
@@ -0,0 +1,12 @@
|
||||
<UserControl x:Class="Intromat.Views.Previews.StringPreview"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Intromat.Views.Previews"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid>
|
||||
<TextBlock x:Name="_textBlock" TextTrimming="WordEllipsis" VerticalAlignment="Center" HorizontalAlignment="Stretch" TextAlignment="Center" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
30
intromat/Intromat/Views/Previews/StringPreview.xaml.cs
Normal file
30
intromat/Intromat/Views/Previews/StringPreview.xaml.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System.Reactive.Disposables;
|
||||
using Intromat.ViewModels.Previews;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Intromat.Views.Previews
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for StringPreview.xaml
|
||||
/// </summary>
|
||||
public partial class StringPreview : IViewFor<StringPreviewViewModel>
|
||||
{
|
||||
public StringPreview()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
this.Bind(ViewModel, vm => vm.Value, v => v._textBlock.Text).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
object? IViewFor.ViewModel
|
||||
{
|
||||
get => ViewModel;
|
||||
set => ViewModel = (StringPreviewViewModel?)value;
|
||||
}
|
||||
|
||||
public StringPreviewViewModel? ViewModel { get; set; }
|
||||
}
|
||||
}
|
||||
12
intromat/Intromat/Views/PropertiesView.xaml
Normal file
12
intromat/Intromat/Views/PropertiesView.xaml
Normal file
@@ -0,0 +1,12 @@
|
||||
<UserControl x:Class="Intromat.Views.PropertiesView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid>
|
||||
<xctk:PropertyGrid x:Name="PropertyGrid" ShowSortOptions="False" AutoGenerateProperties="False" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
71
intromat/Intromat/Views/PropertiesView.xaml.cs
Normal file
71
intromat/Intromat/Views/PropertiesView.xaml.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Reactive.Linq;
|
||||
using System.Windows;
|
||||
using DynamicData;
|
||||
using Intromat.ViewModels;
|
||||
using ReactiveUI;
|
||||
using Xceed.Wpf.Toolkit.PropertyGrid;
|
||||
|
||||
namespace Intromat.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for PropertiesView.xaml
|
||||
/// </summary>
|
||||
public partial class PropertiesView : IViewFor<CodeGenNetworkViewModel>
|
||||
{
|
||||
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel),
|
||||
typeof(CodeGenNetworkViewModel), typeof(PropertiesView), new PropertyMetadata(null));
|
||||
|
||||
public PropertiesView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
this.WhenAnyValue(v => v.ViewModel!.SelectedObject!.PropertyDescriptors)
|
||||
.Where(l => l != null)
|
||||
.Select(l => l!.Connect())
|
||||
.Switch()
|
||||
.Subscribe(_ => PropertyGrid.PropertyDefinitions = CreatePropertyDefinitions(ViewModel!.SelectedObject!.PropertyDescriptors))
|
||||
.DisposeWith(d);
|
||||
|
||||
this.OneWayBind(ViewModel, vm => vm.SelectedObject, v => v.PropertyGrid.SelectedObject).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
private PropertyDefinitionCollection CreatePropertyDefinitions(IObservableList<PropertyDescriptor>? propertyDescriptors)
|
||||
{
|
||||
var result = new PropertyDefinitionCollection();
|
||||
if (propertyDescriptors != null)
|
||||
result.AddRange(propertyDescriptors.Items.Select(PropertySelector));
|
||||
return result;
|
||||
}
|
||||
|
||||
private PropertyDefinition PropertySelector(PropertyDescriptor descriptor)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Category = descriptor.Category,
|
||||
Description = descriptor.Description,
|
||||
IsBrowsable = descriptor.IsBrowsable,
|
||||
DisplayName = descriptor.DisplayName,
|
||||
TargetProperties = new [] { descriptor.Name }
|
||||
};
|
||||
}
|
||||
|
||||
object? IViewFor.ViewModel
|
||||
{
|
||||
get => ViewModel;
|
||||
set => ViewModel = (CodeGenNetworkViewModel?)value;
|
||||
}
|
||||
|
||||
public CodeGenNetworkViewModel? ViewModel
|
||||
{
|
||||
get => (CodeGenNetworkViewModel?)GetValue(ViewModelProperty);
|
||||
set => SetValue(ViewModelProperty, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
14
intromat/Intromat/Views/ShaderFileView.xaml
Normal file
14
intromat/Intromat/Views/ShaderFileView.xaml
Normal file
@@ -0,0 +1,14 @@
|
||||
<UserControl x:Class="Intromat.Views.ShaderFileView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Intromat.Views"
|
||||
xmlns:avalonedit="http://icsharpcode.net/sharpdevelop/avalonedit"
|
||||
xmlns:controls="clr-namespace:Intromat.Controls"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid>
|
||||
<controls:SourceEditor x:Name="_textEditor" ShowLineNumbers="True" SyntaxHighlighting="HLSL" Background="{DynamicResource BackgroundColor}" FontFamily="Consolas" FontSize="14" Foreground="{DynamicResource ControlDefaultForeground}" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
44
intromat/Intromat/Views/ShaderFileView.xaml.cs
Normal file
44
intromat/Intromat/Views/ShaderFileView.xaml.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using System.Xml;
|
||||
using ICSharpCode.AvalonEdit.Highlighting;
|
||||
using ICSharpCode.AvalonEdit.Highlighting.Xshd;
|
||||
using Intromat.ViewModels;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Intromat.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ShaderFileView.xaml
|
||||
/// </summary>
|
||||
public partial class ShaderFileView : IViewFor<ShaderFileViewModel>
|
||||
{
|
||||
static ShaderFileView()
|
||||
{
|
||||
using var s = Application.GetResourceStream(new Uri("Resources/HLSL-Mode.xshd", UriKind.Relative))!.Stream;
|
||||
using var reader = new XmlTextReader(s);
|
||||
HighlightingManager.Instance.RegisterHighlighting("HLSL", new string[0], HighlightingLoader.Load(reader, HighlightingManager.Instance));
|
||||
}
|
||||
|
||||
public ShaderFileView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
var documentViewModel = ViewModel!;
|
||||
this.Bind(documentViewModel, vm => vm.Source, v => v._textEditor.Text).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
object? IViewFor.ViewModel
|
||||
{
|
||||
get => ViewModel;
|
||||
set => ViewModel = (ShaderFileViewModel?)value;
|
||||
}
|
||||
|
||||
public ShaderFileViewModel? ViewModel { get; set; }
|
||||
}
|
||||
}
|
||||
19
intromat/Intromat/Views/SplashScreenWindow.xaml
Normal file
19
intromat/Intromat/Views/SplashScreenWindow.xaml
Normal file
@@ -0,0 +1,19 @@
|
||||
<Window x:Class="Intromat.Views.SplashScreenWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
WindowStyle="None"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
AllowsTransparency="True"
|
||||
Background="Transparent"
|
||||
mc:Ignorable="d"
|
||||
SizeToContent="WidthAndHeight"
|
||||
Title="SplashScreenWindow">
|
||||
<Border Background="#C0242424" CornerRadius="5" BorderBrush="#a0a0a0" BorderThickness="1" Padding="10">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<Image Source="{StaticResource LogoImageSource}" Width="400" Height="400" />
|
||||
<TextBlock Text="Intromat" VerticalAlignment="Bottom" HorizontalAlignment="Center" FontSize="96" Margin="0,-30,0,0"></TextBlock>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Window>
|
||||
15
intromat/Intromat/Views/SplashScreenWindow.xaml.cs
Normal file
15
intromat/Intromat/Views/SplashScreenWindow.xaml.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System.Windows;
|
||||
|
||||
namespace Intromat.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for SplashScreenWindow.xaml
|
||||
/// </summary>
|
||||
public partial class SplashScreenWindow : Window
|
||||
{
|
||||
public SplashScreenWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
12
intromat/Intromat/Views/UndoRedoView.xaml
Normal file
12
intromat/Intromat/Views/UndoRedoView.xaml
Normal file
@@ -0,0 +1,12 @@
|
||||
<UserControl x:Class="Intromat.Views.UndoRedoView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="30" d:DesignWidth="800">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Name="undoButton" Style="{StaticResource IconToolButton}" ToolTip="Undo" Content="" />
|
||||
<Button Name="redoButton" Style="{StaticResource IconToolButton}" ToolTip="Redo" Content="" />
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
41
intromat/Intromat/Views/UndoRedoView.xaml.cs
Normal file
41
intromat/Intromat/Views/UndoRedoView.xaml.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System.Diagnostics;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows;
|
||||
using Intromat.ViewModels;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace Intromat.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for UndoRedoView.xaml
|
||||
/// </summary>
|
||||
public partial class UndoRedoView : IViewFor<UndoRedoViewModel>
|
||||
{
|
||||
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel),
|
||||
typeof(UndoRedoViewModel), typeof(UndoRedoView), new PropertyMetadata(null));
|
||||
|
||||
public UndoRedoView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
Debug.Assert(ViewModel != null, nameof(ViewModel) + " != null");
|
||||
this.BindCommand(ViewModel, vm => vm.UndoCommand, v => v.undoButton).DisposeWith(d);
|
||||
this.BindCommand(ViewModel, vm => vm.RedoCommand, v => v.redoButton).DisposeWith(d);
|
||||
});
|
||||
}
|
||||
|
||||
public UndoRedoViewModel? ViewModel
|
||||
{
|
||||
get => (UndoRedoViewModel?)GetValue(ViewModelProperty);
|
||||
set => SetValue(ViewModelProperty, value);
|
||||
}
|
||||
|
||||
object? IViewFor.ViewModel
|
||||
{
|
||||
get => ViewModel;
|
||||
set => ViewModel = (UndoRedoViewModel?)value;
|
||||
}
|
||||
}
|
||||
}
|
||||
26
intromat/Intromat/Views/UserInputWindow.xaml
Normal file
26
intromat/Intromat/Views/UserInputWindow.xaml
Normal file
@@ -0,0 +1,26 @@
|
||||
<Window x:Class="Intromat.Views.UserInputWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
ShowInTaskbar="False"
|
||||
ResizeMode="NoResize"
|
||||
Style="{DynamicResource CustomWindowStyle}"
|
||||
mc:Ignorable="d" SizeToContent="Height"
|
||||
Closing="UserInputWindow_OnClosing"
|
||||
Title="Intromat" MinHeight="50" Width="300">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock x:Name="Header" Grid.Row="0" Text="Enter data:" Margin="5" />
|
||||
<TextBox x:Name="Input" Grid.Row="1" Text="" Margin="5,0" TextChanged="Input_OnTextChanged" />
|
||||
<StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right" Margin="5">
|
||||
<Button x:Name="ButtonOK" IsDefault="True" Width="60" Margin="0,0,2,0" Click="ButtonOK_OnClick">OK</Button>
|
||||
<Button x:Name="ButtonCancel" IsCancel="True" Width="60" Click="ButtonCancel_OnClick">Cancel</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
57
intromat/Intromat/Views/UserInputWindow.xaml.cs
Normal file
57
intromat/Intromat/Views/UserInputWindow.xaml.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Intromat.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for UserInputWindow.xaml
|
||||
/// </summary>
|
||||
public partial class UserInputWindow
|
||||
{
|
||||
public UserInputWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public string? Result { get; set; }
|
||||
|
||||
public static string? Show(Window? owner, string? header, string? title = null, string? defaultValue = null)
|
||||
{
|
||||
var window = new UserInputWindow
|
||||
{
|
||||
Owner = owner,
|
||||
Title = title ?? "Intromat",
|
||||
Header = { Text = header ?? "Enter value:" }
|
||||
};
|
||||
if (defaultValue != null)
|
||||
window.Input.Text = window.Result = defaultValue;
|
||||
window.Input.SelectAll();
|
||||
window.Input.Focus();
|
||||
return window.ShowDialog() == true ? window.Result : null;
|
||||
}
|
||||
|
||||
private void Input_OnTextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
Result = Input.Text;
|
||||
}
|
||||
|
||||
private void ButtonOK_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DialogResult = true;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void ButtonCancel_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DialogResult = false;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void UserInputWindow_OnClosing(object sender, CancelEventArgs e)
|
||||
{
|
||||
if (DialogResult != true)
|
||||
Result = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user