Dexter89 пре 11 година
родитељ
комит
950001dcee

+ 32 - 4
tools/gui/crown-tests/GtkExt/BindingEngine.cs

@@ -6,17 +6,36 @@ namespace crown_tests.GtkExt
 	public static class BindingEngine
 	{
 		private static Dictionary<IBindingTarget, Binding> mBindings;
+		private static Dictionary<Gtk.Widget, ViewModelBase> mViewModels;
 
 		static BindingEngine() {
 			mBindings = new Dictionary<IBindingTarget, Binding>();
+			mViewModels = new Dictionary<Gtk.Widget, ViewModelBase>();
 		}
 
-		public static Binding GetOrCreateBinding(Object source, IBindingTarget target, BindingInfo info) {
+		public static void SetViewModel(Gtk.Widget widget, ViewModelBase viewModel)
+		{
+			if (mViewModels.ContainsKey(widget)) {
+				Console.WriteLine("BindingEngine.SetViewModel: ViewModel already set for this widget");
+				return;
+			}
+			mViewModels.Add(widget, viewModel);
+		}
+
+		public static ViewModelBase GetViewModel(Gtk.Widget widget)
+		{
+			ViewModelBase viewModel = null;
+			mViewModels.TryGetValue(widget, out viewModel);
+			return viewModel;
+		}
+
+		public static Binding GetOrCreateBinding(Gtk.Widget widget, Object source, IBindingTarget target, BindingInfo info) 
+		{
 			Binding result = null;
 			if (!mBindings.TryGetValue(target, out result)) {
 				result = new Binding();
 				result.Info = info;
-				result.Connect(source, target);
+				result.Connect(widget, source, target);
 				mBindings[target] = result;
 			}
 			return result;
@@ -41,8 +60,17 @@ namespace crown_tests.GtkExt
 		private Object mSource;
 		private IBindingTarget mTarget;
 
-		public void Connect(Object source, IBindingTarget target) {
-			mSource = source;
+		public void Connect(Gtk.Widget widget, Object source, IBindingTarget target) {
+			if (source == null) {
+				mSource = BindingEngine.GetViewModel(widget);
+				if (mSource == null) {
+					Console.WriteLine("Binding.Connect: ViewModel not set for this widget");
+					return;
+				}
+			} else {
+				mSource = source;
+			}
+
 			mTarget = target;
 
 			var propertyChanged = mSource as IPropertyChanged;

+ 35 - 0
tools/gui/crown-tests/GtkExt/EntryTemplate.cs

@@ -0,0 +1,35 @@
+using System;
+
+namespace crown_tests.GtkExt
+{
+	public class EntryTemplate: ITemplate
+	{
+		private BindingInfo mTextBinding;
+
+		public EntryTemplate()
+		{
+		}
+
+		public EntryTemplate SetTextBinding(String path)
+		{
+			mTextBinding = new BindingInfo() { Path = path };
+			return this;
+		}
+
+		public void Apply(Gtk.Widget widget) 
+		{
+			Gtk.Entry entry = widget as Gtk.Entry;
+			if (entry == null) {
+				Console.WriteLine("EntryTemplate.Apply: Invalid widget type for this template");
+				return;
+			}
+
+			if (mTextBinding != null) {
+				var bindingTarget = new EntryBindingTarget(entry);
+				Binding binding = BindingEngine.GetOrCreateBinding(widget, null, bindingTarget, mTextBinding);
+				bindingTarget.Update(binding, binding.GetSourceValue());
+			}
+		}
+	}
+}
+

+ 1 - 1
tools/gui/crown-tests/GtkExt/TreeViewTemplate.cs

@@ -51,7 +51,7 @@ namespace crown_tests.GtkExt
 						return;
 
 					//The actual binding, on the other hand, is specific to the current (row,column) pair.
-					Binding binding = BindingEngine.GetOrCreateBinding(value, new TreeViewIterBindingTarget(treeView, iter, column), bindingInfo);
+					Binding binding = BindingEngine.GetOrCreateBinding(treeView, value, new TreeViewIterBindingTarget(treeView, iter, column), bindingInfo);
 					var propValue = binding.GetSourceValue();
 					textCell.Text = propValue == null ? String.Empty : propValue.ToString();
 					return;

+ 9 - 0
tools/gui/crown-tests/GtkExt/ViewModelBase.cs

@@ -8,6 +8,15 @@ namespace crown_tests.GtkExt
 		{
 		}
 
+		protected Boolean SetAndNotify<T>(ref T field, T newValue, String propertyName) {
+			if (!object.Equals(field, newValue)) {
+				field = newValue;
+				Notify(propertyName);
+				return true;
+			}
+			return false;
+		}
+
 		#region IPropertyChanged implementation
 
 		public event PropertyChangedEventHandler PropertyChanged;

+ 11 - 7
tools/gui/crown-tests/MainWindow.cs

@@ -3,6 +3,7 @@ using Gtk;
 using crown_tests.tests;
 using Newtonsoft.Json;
 using crown_tests.GtkExt;
+using crown_tests.ViewModels;
 
 namespace crown_tests
 {
@@ -17,6 +18,8 @@ namespace crown_tests
 
 			twTests.AppendColumn("Name", new Gtk.CellRendererText());
 			twTests.AppendColumn("State", new Gtk.CellRendererText());
+
+			var crownTestsViewModel = new CrownTestsViewModel();
 			Templating.ApplyTemplate(twTests,
 				new TreeViewTemplate()
 				  .AddRowTemplate(TreeViewRowTemplate.Create(typeof(TestCategory))
@@ -25,7 +28,14 @@ namespace crown_tests
 																						 .SetBinding("Name", "Name")
 																						 .SetBinding("State", "LastResult")));
 
-			LoadConfigData();
+			BindingEngine.SetViewModel(txtTestFolder, crownTestsViewModel);
+			Templating.ApplyTemplate(txtTestFolder,
+				new EntryTemplate().SetTextBinding("TestFolder"));
+
+			BindingEngine.SetViewModel(txtCrownTestsExe, crownTestsViewModel);
+			Templating.ApplyTemplate(txtCrownTestsExe,
+				new EntryTemplate().SetTextBinding("CrownTestsExe"));
+
 			LoadTestsData();
 		}
 
@@ -49,12 +59,6 @@ namespace crown_tests
 			executor.ExecuteAll();
 		}
 
-		private void LoadConfigData()
-		{
-			txtTestFolder.Text = @"..\..\..\..\..\tests\";
-			txtCrownTestsExe.Text = @"..\..\..\..\..\build\tests\Debug\crown-tests.exe";
-		}
-
 		private void LoadTestsData()
 		{
 			var testsJsonFullfileName = System.IO.Path.Combine(txtTestFolder.Text, "tests.json");

+ 27 - 0
tools/gui/crown-tests/ViewModels/CrownTestsViewModel.cs

@@ -0,0 +1,27 @@
+using System;
+using crown_tests.GtkExt;
+
+namespace crown_tests.ViewModels
+{
+	public class CrownTestsViewModel: ViewModelBase
+	{
+		public CrownTestsViewModel()
+		{
+			TestFolder = @"..\..\..\..\..\tests\";
+			CrownTestsExe = @"..\..\..\..\..\build\tests\Debug\crown-tests.exe";
+		}
+
+		private String mTestFolder;
+		public String TestFolder {
+			get { return mTestFolder; }
+			set { SetAndNotify(ref mTestFolder, value, "TestFolder"); }
+		}
+
+		private String mCrownTestsExe;
+		public String CrownTestsExe {
+			get { return mCrownTestsExe; }
+			set { SetAndNotify(ref mCrownTestsExe, value, "CrownTestsExe"); }
+		}
+	}
+}
+

+ 3 - 0
tools/gui/crown-tests/crown-tests.csproj

@@ -78,6 +78,8 @@
     <Compile Include="GtkExt\BindingTargets\EntryBindingTarget.cs" />
     <Compile Include="GtkExt\Templating.cs" />
     <Compile Include="GtkExt\TreeViewTemplate.cs" />
+    <Compile Include="GtkExt\EntryTemplate.cs" />
+    <Compile Include="ViewModels\CrownTestsViewModel.cs" />
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
@@ -95,5 +97,6 @@
   <ItemGroup>
     <Folder Include="GtkExt\" />
     <Folder Include="GtkExt\BindingTargets\" />
+    <Folder Include="ViewModels\" />
   </ItemGroup>
 </Project>