فهرست منبع

行为树编辑器增加折叠节点功能

tanghai 11 سال پیش
والد
کامیت
f15c24f7d4

+ 3 - 3
CSharp/App/Editor/Shell.xaml

@@ -5,12 +5,12 @@
 	<Grid>
 		<!--<ContentControl Name="login" prism:RegionManager.RegionName="LoginRegion" HorizontalAlignment="Center" VerticalAlignment="Center" />-->
 		<TabControl>
-			<TabItem Height="25" Width="80" Header="机器人">
-				<ContentControl Name="robot" prism:RegionManager.RegionName="RobotRegion" />
-			</TabItem>
 			<TabItem Height="25" Width="80" Header="行为树">
 				<ContentControl Name="behaviorTree" prism:RegionManager.RegionName="BehaviorTreeRegion" />
 			</TabItem>
+			<TabItem Height="25" Width="80" Header="机器人">
+				<ContentControl Name="robot" prism:RegionManager.RegionName="RobotRegion" />
+			</TabItem>
 			<TabItem Height="25" Width="80" Header="WCFClient">
 				<ContentControl Name="wcfClient" prism:RegionManager.RegionName="WCFClientRegion" />
 			</TabItem>

+ 6 - 6
CSharp/App/Modules/Tree/BehaviorTreeLayout.cs

@@ -88,12 +88,12 @@ namespace Tree
 		}
 
 		private static void CalculatePrelimAndModify(TreeNodeViewModel treeNode)
-		{
-			foreach (TreeNodeViewModel node in treeNode.Children)
-			{
-				CalculatePrelimAndModify(node);
-			}
-
+		{
+			foreach (TreeNodeViewModel node in treeNode.Children)
+			{
+				CalculatePrelimAndModify(node);
+			}
+
 			double prelim = 0;
 			double modify = 0;
 

+ 5 - 5
CSharp/App/Modules/Tree/BehaviorTreeView.xaml

@@ -23,9 +23,9 @@
 
 	<UserControl.ContextMenu>
 		<ContextMenu>
-			<MenuItem Header="New" Command="ApplicationCommands.New"
+			<MenuItem Header="新建" Command="ApplicationCommands.New"
 					CommandTarget="{Binding Path=PlacementTarget, RelativeSource={RelativeSource AncestorType=ContextMenu}}" />
-			<MenuItem Header="Delete" Command="ApplicationCommands.Delete"
+			<MenuItem Header="删除" Command="ApplicationCommands.Delete"
 					CommandTarget="{Binding Path=PlacementTarget, RelativeSource={RelativeSource AncestorType=ContextMenu}}" />
 		</ContextMenu>
 	</UserControl.ContextMenu>
@@ -45,10 +45,10 @@
 			<ListBox.ItemTemplate>
 				<DataTemplate DataType="BehaviorTree:TreeNodeViewModel">
 					<Canvas MouseDown="ListBoxItem_MouseDown" MouseUp="ListBoxItem_MouseUp" MouseMove="ListBoxItem_MouseMove" >
-						<Rectangle Name="rectNode" Width="{Binding Width}" Height="{Binding Height}" Cursor="Hand" StrokeThickness="4"
-								RadiusX="4" RadiusY="4" Stroke="{StaticResource treeNodeBorderBrush}" Fill="{StaticResource treeNodeFillBrush}"/>
+						<Rectangle Name="rectNode" Width="{Binding Width}" Height="{Binding Height}" Cursor="Hand" StrokeThickness="2"
+								RadiusX="40" RadiusY="40" Stroke="{StaticResource treeNodeBorderBrush}" Fill="{StaticResource treeNodeFillBrush}"/>
 						<Line X1="{Binding ConnectorX1}" Y1="{Binding ConnectorY1}" X2="{Binding ConnectorX2}" Y2="{Binding ConnectorY2}"
-								Stroke="Black" StrokeThickness="2" />
+								Stroke="Black" StrokeThickness="2"  />
 					</Canvas>
 					<DataTemplate.Triggers>
 						<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}, Path=IsSelected}" Value="True">

+ 60 - 30
CSharp/App/Modules/Tree/BehaviorTreeView.xaml.cs

@@ -67,47 +67,77 @@ namespace Tree
 			this.ViewModel.Remove(treeNodeViewModel);
 			this.listBox.SelectedItem = null;
 			e.Handled = true;
-		}
-
-		private void ListBoxItem_MouseDown(object sender, MouseButtonEventArgs e)
+		}
+
+		private void MenuDeleteNode_Close(object sender, ExecutedRoutedEventArgs e)
 		{
-			if (e.ChangedButton != MouseButton.Left)
+			if (this.listBox.SelectedItem == null)
 			{
 				return;
 			}
-			this.isLeftButtonDown = true;
-
-			var item = (FrameworkElement) sender;
-			var treeNodeViewModel = item.DataContext as TreeNodeViewModel;
-
-			this.listBox.SelectedItem = treeNodeViewModel;
-
-			this.origMouseDownPoint = e.GetPosition(this);
-
-			item.CaptureMouse();
+			var treeNodeViewModel = this.listBox.SelectedItem as TreeNodeViewModel;
+			this.ViewModel.Remove(treeNodeViewModel);
+			this.listBox.SelectedItem = null;
 			e.Handled = true;
 		}
 
-		private void ListBoxItem_MouseUp(object sender, MouseButtonEventArgs e)
+		private void ListBoxItem_MouseDown(object sender, MouseButtonEventArgs e)
 		{
-			if (!this.isLeftButtonDown)
+			if (e.ChangedButton != MouseButton.Left)
 			{
-				this.isDragging = false;
 				return;
-			}
-
-			var item = (FrameworkElement) sender;
-			var treeNodeViewModel = item.DataContext as TreeNodeViewModel;
-
-			if (!this.isDragging)
-			{
-				this.listBox.SelectedItem = treeNodeViewModel;
-			}
-
-			this.isLeftButtonDown = false;
-			this.isDragging = false;
+			}
+
+			// 双击鼠标
+			if (e.ClickCount == 2 && e.ChangedButton == MouseButton.Left)
+			{
+				var item = (FrameworkElement) sender;
+				var treeNodeViewModel = item.DataContext as TreeNodeViewModel;
+				if (treeNodeViewModel.IsFolder)
+				{
+					this.ViewModel.UnFold(treeNodeViewModel);
+				}
+				else
+				{
+					this.ViewModel.Fold(treeNodeViewModel);	
+				}
+			}
+			else
+			{
+				this.isLeftButtonDown = true;
+
+				var item = (FrameworkElement) sender;
+				var treeNodeViewModel = item.DataContext as TreeNodeViewModel;
+
+				this.listBox.SelectedItem = treeNodeViewModel;
+
+				this.origMouseDownPoint = e.GetPosition(this);
+
+				item.CaptureMouse();
+			}
+			e.Handled = true;
+		}
 
-			item.ReleaseMouseCapture();
+		private void ListBoxItem_MouseUp(object sender, MouseButtonEventArgs e)
+		{
+			if (!this.isLeftButtonDown)
+			{
+				this.isDragging = false;
+				return;
+			}
+
+			var item = (FrameworkElement) sender;
+			var treeNodeViewModel = item.DataContext as TreeNodeViewModel;
+
+			if (!this.isDragging)
+			{
+				this.listBox.SelectedItem = treeNodeViewModel;
+			}
+
+			this.isLeftButtonDown = false;
+			this.isDragging = false;
+
+			item.ReleaseMouseCapture();
 			e.Handled = true;
 		}
 

+ 54 - 4
CSharp/App/Modules/Tree/BehaviorTreeViewModel.cs

@@ -1,4 +1,5 @@
-using System.Collections.ObjectModel;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.ComponentModel.Composition;
 
 namespace Tree
@@ -10,6 +11,10 @@ namespace Tree
 		private readonly ObservableCollection<TreeNodeViewModel> treeNodes =
 			new ObservableCollection<TreeNodeViewModel>();
 
+		// 保存折叠节点的孩子节点
+		private readonly Dictionary<TreeNodeViewModel, ObservableCollection<TreeNodeViewModel>>
+			folderNodeChildren = new Dictionary<TreeNodeViewModel, ObservableCollection<TreeNodeViewModel>>();
+
 		public ObservableCollection<TreeNodeViewModel> TreeNodes
 		{
 			get
@@ -27,7 +32,12 @@ namespace Tree
 		}
 
 		public void Add(TreeNode treeNode, TreeNodeViewModel parent)
-		{
+		{
+			// 如果父节点是折叠的,需要先展开父节点
+			if (parent != null && parent.IsFolder)
+			{
+				UnFold(parent);
+			}
 			var treeNodeViewModel = new TreeNodeViewModel(treeNode, parent);
 			this.treeNodes.Add(treeNodeViewModel);
 			if (parent != null)
@@ -43,13 +53,13 @@ namespace Tree
 			{
 				this.RecursionRemove(treeNodeViewModel.Children[i]);
 			}
-			treeNodeViewModel.Parent.Children.Remove(treeNodeViewModel);
 			this.treeNodes.Remove(treeNodeViewModel);
 		}
 
 		public void Remove(TreeNodeViewModel treeNodeViewModel)
 		{
-			this.RecursionRemove(treeNodeViewModel);
+			this.RecursionRemove(treeNodeViewModel);
+			treeNodeViewModel.Parent.Children.Remove(treeNodeViewModel);
 			BehaviorTreeLayout.ExcuteLayout(this.Root);
 		}
 
@@ -66,6 +76,46 @@ namespace Tree
 		public void Move(double offsetX, double offsetY)
 		{
 			this.RecursionMove(this.Root, offsetX, offsetY);
+		}
+
+		/// <summary>
+		/// 折叠节点
+		/// </summary>
+		/// <param name="treeNodeViewModel"></param>
+		public void Fold(TreeNodeViewModel treeNodeViewModel)
+		{
+			this.folderNodeChildren[treeNodeViewModel] = treeNodeViewModel.Children;
+			foreach (var node in treeNodeViewModel.Children)
+			{
+				this.RecursionRemove(node);
+			}
+			treeNodeViewModel.IsFolder = true;
+			BehaviorTreeLayout.ExcuteLayout(this.Root);
+		}
+
+		/// <summary>
+		/// 展开节点
+		/// </summary>
+		/// <param name="treeNodeViewModel"></param>
+		public void UnFold(TreeNodeViewModel treeNodeViewModel)
+		{
+			ObservableCollection<TreeNodeViewModel> children = this.folderNodeChildren[treeNodeViewModel];
+			foreach (var tn in children)
+			{
+				this.RecursionAdd(tn);
+			}
+			treeNodeViewModel.IsFolder = false;
+			BehaviorTreeLayout.ExcuteLayout(this.Root);
+		}
+
+		private void RecursionAdd(TreeNodeViewModel treeNodeViewModel)
+		{
+			this.treeNodes.Add(treeNodeViewModel);
+			ObservableCollection<TreeNodeViewModel> children = treeNodeViewModel.Children;
+			foreach (var tn in children)
+			{
+				this.RecursionAdd(tn);
+			}
 		}
 	}
 }

+ 3 - 1
CSharp/App/Modules/Tree/TreeNode.cs

@@ -12,7 +12,9 @@ namespace Tree
 
 		public int Type { get; set; }
 
-		public int Id { get; set; }
+		public int Id { get; set; }
+
+		public bool IsFold { get; set; }
 
 		public int ParentId { get; set; }
 

+ 21 - 8
CSharp/App/Modules/Tree/TreeNodeViewModel.cs

@@ -1,9 +1,8 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using Microsoft.Practices.Prism.Mvvm;
-using Microsoft.Practices.Prism.ViewModel;
-
+using System;
+using System.Collections.ObjectModel;
+using System.Windows;
+using Microsoft.Practices.Prism.Mvvm;
+
 namespace Tree
 {
 	public class TreeNodeViewModel : BindableBase
@@ -20,8 +19,7 @@ namespace Tree
 		private double ancestorModify;
 		private TreeNodeViewModel parent;
 
-		private ObservableCollection<TreeNodeViewModel> children =
-			new ObservableCollection<TreeNodeViewModel>();
+		private ObservableCollection<TreeNodeViewModel> children = new ObservableCollection<TreeNodeViewModel>();
 
 		public TreeNodeViewModel(TreeNode treeNode, TreeNodeViewModel parent)
 		{
@@ -221,6 +219,21 @@ namespace Tree
 			{
 				this.parent = value;
 			}
+		}
+
+		/// <summary>
+		/// 节点是否折叠
+		/// </summary>
+		public bool IsFolder
+		{
+			get
+			{
+				return treeNode.IsFold;
+			}
+			set
+			{
+				treeNode.IsFold = value;
+			}
 		}
 
 		public ObservableCollection<TreeNodeViewModel> Children

+ 2 - 2
CSharp/CSharp.sln.DotSettings

@@ -1,6 +1,6 @@
 <wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
 	<s:Boolean x:Key="/Default/CodeEditing/Intellisense/CodeCompletion/AutoCompleteBasicCompletion/@EntryValue">True</s:Boolean>
-	<s:Boolean x:Key="/Default/CodeEditing/Intellisense/LookupWindow/ShowSummary/@EntryValue">True</s:Boolean>
+	
 	<s:Boolean x:Key="/Default/CodeEditing/Localization/CSharpLocalizationOptions/DontAnalyseVerbatimStrings/@EntryValue">False</s:Boolean>
 	<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CheckNamespace/@EntryIndexedValue">DO_NOT_SHOW</s:String>
 	<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertIfStatementToReturnStatement/@EntryIndexedValue">DO_NOT_SHOW</s:String>
@@ -288,7 +288,7 @@ II.2.12 &lt;HandlesEvent /&gt;&#xD;
 	<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
 	<s:String x:Key="/Default/CodeStyle/Naming/VBNaming/EventHandlerPatternLong/@EntryValue">$object$_On$event$</s:String>
 	<s:String x:Key="/Default/CodeStyle/Naming/XamlNaming/UserRules/=XAML_005FFIELD/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
-	<s:Boolean x:Key="/Default/Environment/Editor/UseCamelHumps/@EntryValue">False</s:Boolean>
+	
 	<s:String x:Key="/Default/Environment/Editor/MatchingBraceHighlighting/Position/@EntryValue">BOTH_SIDES</s:String>
 	<s:Boolean x:Key="/Default/Environment/OpenDocument/OpenDocumentAfterModification/@EntryValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/Environment/SearchAndNavigation/MergeOccurences/@EntryValue">True</s:Boolean>