From a8edb951b3b4cf53b89c119a734304e9866e1d4e Mon Sep 17 00:00:00 2001
From: Siegfried Pammer <siegfriedpammer@gmail.com>
Date: Sun, 25 Aug 2013 16:34:25 +0200
Subject: [PATCH] implement GridViewColumnAutoSize

---
 .../Gui/Pads/TaskList/TaskViewResources.xaml  |  2 +-
 .../Pads/TaskList/TaskViewResources.xaml.cs   | 16 +----
 .../GridViewColumnAutoSize.cs                 | 72 +++++++++++++++++++
 .../ICSharpCode.Core.Presentation.csproj      |  1 +
 4 files changed, 75 insertions(+), 16 deletions(-)
 create mode 100644 src/Main/ICSharpCode.Core.Presentation/GridViewColumnAutoSize.cs

diff --git a/src/Main/Base/Project/Src/Gui/Pads/TaskList/TaskViewResources.xaml b/src/Main/Base/Project/Src/Gui/Pads/TaskList/TaskViewResources.xaml
index 29182e56ec..1bbb32aa7a 100644
--- a/src/Main/Base/Project/Src/Gui/Pads/TaskList/TaskViewResources.xaml
+++ b/src/Main/Base/Project/Src/Gui/Pads/TaskList/TaskViewResources.xaml
@@ -5,7 +5,7 @@
 	xmlns:local="clr-namespace:ICSharpCode.SharpDevelop.Gui">
 	<Style TargetType="{x:Type ListView}" x:Key="TaskListView">
 		<Setter Property="core:SortableGridViewColumn.SortMode" Value="Automatic" />
-		<EventSetter Event="SizeChanged" Handler="ListViewSizeChanged" />
+		<Setter Property="core:GridViewColumnAutoSize.AutoWidth" Value="35;50;70%;15%;15%" />
 		<Setter Property="View">
 			<Setter.Value>
 				<GridView AllowsColumnReorder="False">
diff --git a/src/Main/Base/Project/Src/Gui/Pads/TaskList/TaskViewResources.xaml.cs b/src/Main/Base/Project/Src/Gui/Pads/TaskList/TaskViewResources.xaml.cs
index d9cb148759..40a948bd6d 100644
--- a/src/Main/Base/Project/Src/Gui/Pads/TaskList/TaskViewResources.xaml.cs
+++ b/src/Main/Base/Project/Src/Gui/Pads/TaskList/TaskViewResources.xaml.cs
@@ -32,21 +32,7 @@ namespace ICSharpCode.SharpDevelop.Gui
 				target.ToolTip = null;
 			}
 		}
-		
-		void ListViewSizeChanged(object sender, SizeChangedEventArgs e)
-		{
-			ListView target = sender as ListView;
-			if (target == null || target.ActualWidth < 115.0) return;
-			GridView view = target.View as  GridView;
-			if (view == null) return;
-			view.Columns[0].Width = 35;
-			view.Columns[1].Width = 50;
-			double w = target.ActualWidth - view.Columns[0].Width - view.Columns[1].Width;
-			view.Columns[3].Width = w * 15 / 100;
-			view.Columns[4].Width = w * 15 / 100;
-			view.Columns[2].Width = w - view.Columns[3].Width - view.Columns[4].Width - 30;
-		}
-		
+
 		public static void CopySelectionToClipboard(ListView taskView)
 		{
 			StringBuilder b = new StringBuilder();
diff --git a/src/Main/ICSharpCode.Core.Presentation/GridViewColumnAutoSize.cs b/src/Main/ICSharpCode.Core.Presentation/GridViewColumnAutoSize.cs
new file mode 100644
index 0000000000..543d548e6b
--- /dev/null
+++ b/src/Main/ICSharpCode.Core.Presentation/GridViewColumnAutoSize.cs
@@ -0,0 +1,72 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace ICSharpCode.Core.Presentation
+{
+	public class GridViewColumnAutoSize
+	{
+		public static readonly DependencyProperty AutoWidthProperty =
+			DependencyProperty.RegisterAttached("AutoWidth", typeof(string), typeof(GridViewColumnAutoSize),
+			                                    new FrameworkPropertyMetadata(null, AutoWidthPropertyChanged));
+		
+		public static string GetAutoWidth(DependencyObject obj)
+		{
+			return (string)obj.GetValue(AutoWidthProperty);
+		}
+		
+		public static void SetAutoWidth(DependencyObject obj, string value)
+		{
+			obj.SetValue(AutoWidthProperty, value);
+		}
+		
+		static void AutoWidthPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
+		{
+			ListView grid = sender as ListView;
+			if (grid == null) return;
+			grid.SizeChanged += delegate(object listView, SizeChangedEventArgs e) {
+				ListView lv = listView as ListView;
+				if (lv == null) return;
+				GridView v = lv.View as GridView;
+				if (v == null) return;
+				CalculateSizes(v, GetAutoWidth(lv), e.NewSize.Width);
+			};
+			GridView view = grid.View as GridView;
+			if (view == null) return;
+			CalculateSizes(view, args.NewValue as string, grid.ActualWidth);
+		}
+		
+		static void CalculateSizes(GridView view, string sizeValue, double fullWidth)
+		{
+			string[] sizes = (sizeValue ?? "").Split(';');
+			
+			Debug.Assert(sizes.Length == view.Columns.Count);
+			Dictionary<int, Func<double, double>> percentages = new Dictionary<int, Func<double, double>>();
+			double remainingWidth = fullWidth - 30; // 30 is a good offset for the scrollbar
+			
+			for (int i = 0; i < view.Columns.Count; i++) {
+				var column = view.Columns[i];
+				double size;
+				bool isPercentage = !double.TryParse(sizes[i], out size);
+				if (isPercentage) {
+					size = double.Parse(sizes[i].TrimEnd('%', ' '));
+					percentages.Add(i, w => w * size / 100.0);
+				} else {
+					column.Width = size;
+					remainingWidth -= size;
+				}
+			}
+			
+			if (remainingWidth < 0) return;
+			foreach (var p in percentages) {
+				var column = view.Columns[p.Key];
+				column.Width = p.Value(remainingWidth);
+			}
+		}
+	}
+}
diff --git a/src/Main/ICSharpCode.Core.Presentation/ICSharpCode.Core.Presentation.csproj b/src/Main/ICSharpCode.Core.Presentation/ICSharpCode.Core.Presentation.csproj
index b49b89d88b..86e767f4f7 100644
--- a/src/Main/ICSharpCode.Core.Presentation/ICSharpCode.Core.Presentation.csproj
+++ b/src/Main/ICSharpCode.Core.Presentation/ICSharpCode.Core.Presentation.csproj
@@ -72,6 +72,7 @@
       <Link>Properties\GlobalAssemblyInfo.cs</Link>
     </Compile>
     <Compile Include="GlobalStyles.cs" />
+    <Compile Include="GridViewColumnAutoSize.cs" />
     <Compile Include="Menu\MenuCheckBox.cs" />
     <Compile Include="NotBoolConverter.cs" />
     <Compile Include="RestrictDesiredSize.cs" />