From d8b9121ac2557cff937a3541e01d1fcd5ac91d8d Mon Sep 17 00:00:00 2001 From: jkuehner Date: Mon, 29 Jul 2013 18:32:37 +0200 Subject: [PATCH] Add a ThumbnailView control (show a Miniature View of the workspace) --- samples/XamlDesigner/MainWindow.xaml | 7 +- .../Project/Configuration/AssemblyInfo.cs | 1 + .../Project/ThumbnailView/ThumbnailView.cs | 155 ++++++++++++++++++ .../Project/ThumbnailView/ThumbnailView.xaml | 43 +++++ .../Project/WpfDesign.Designer.csproj | 8 +- .../Project/themes/generic.xaml | 1 + 6 files changed, 212 insertions(+), 3 deletions(-) create mode 100644 src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/ThumbnailView/ThumbnailView.cs create mode 100644 src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/ThumbnailView/ThumbnailView.xaml diff --git a/samples/XamlDesigner/MainWindow.xaml b/samples/XamlDesigner/MainWindow.xaml index 7efb54aefb..b3cd9e3b43 100644 --- a/samples/XamlDesigner/MainWindow.xaml +++ b/samples/XamlDesigner/MainWindow.xaml @@ -1,4 +1,4 @@ - + + + + + diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Configuration/AssemblyInfo.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Configuration/AssemblyInfo.cs index 5d9156ab3c..cb9a82e02b 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Configuration/AssemblyInfo.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Configuration/AssemblyInfo.cs @@ -50,3 +50,4 @@ using System.Windows.Markup; [assembly: XmlnsDefinition("http://sharpdevelop.net", "ICSharpCode.WpfDesign.Designer.Controls")] [assembly: XmlnsDefinition("http://sharpdevelop.net", "ICSharpCode.WpfDesign.Designer.PropertyGrid")] [assembly: XmlnsDefinition("http://sharpdevelop.net", "ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors")] +[assembly: XmlnsDefinition("http://sharpdevelop.net", "ICSharpCode.WpfDesign.Designer.ThumbnailView")] \ No newline at end of file diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/ThumbnailView/ThumbnailView.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/ThumbnailView/ThumbnailView.cs new file mode 100644 index 0000000000..07aabdc1af --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/ThumbnailView/ThumbnailView.cs @@ -0,0 +1,155 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Controls.Primitives; +using System.Windows.Media; +using System.Diagnostics; +using ICSharpCode.WpfDesign.Designer.Controls; + +namespace ICSharpCode.WpfDesign.Designer.ThumbnailView +{ + public class ThumbnailView : Control, INotifyPropertyChanged + { + public DesignSurface DesignSurface + { + get { return (DesignSurface)GetValue(DesignSurfaceProperty); } + set { SetValue(DesignSurfaceProperty, value); } + } + + public static readonly DependencyProperty DesignSurfaceProperty = + DependencyProperty.Register("DesignSurface", typeof(DesignSurface), typeof(ThumbnailView), new PropertyMetadata(OnDesignSurfaceChanged)); + + private static void OnDesignSurfaceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var ctl = d as ThumbnailView; + + + if (ctl.oldSurface != null) + ctl.oldSurface.LayoutUpdated -= ctl.DesignSurface_LayoutUpdated; + + ctl.oldSurface = ctl.DesignSurface; + ctl.scrollViewer = null; + + if (ctl.DesignSurface != null) + { + ctl.DesignSurface.LayoutUpdated += ctl.DesignSurface_LayoutUpdated; + } + + ctl.OnPropertyChanged("ScrollViewer"); + } + + static ThumbnailView() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(ThumbnailView), new FrameworkPropertyMetadata(typeof(ThumbnailView))); + } + + public ScrollViewer ScrollViewer + { + get + { + if (DesignSurface != null && scrollViewer == null) + scrollViewer = DesignSurface.TryFindChild(); + + return scrollViewer; + } + } + + + void DesignSurface_LayoutUpdated(object sender, EventArgs e) + { + if (this.scrollViewer == null) + OnPropertyChanged("ScrollViewer"); + + if (this.scrollViewer != null) + { + double scale, xOffset, yOffset; + this.InvalidateScale(out scale, out xOffset, out yOffset); + + this.zoomThumb.Width = scrollViewer.ViewportWidth * scale; + this.zoomThumb.Height = scrollViewer.ViewportHeight * scale; + + Canvas.SetLeft(this.zoomThumb, xOffset + this.ScrollViewer.HorizontalOffset*scale); + Canvas.SetTop(this.zoomThumb, yOffset + this.ScrollViewer.VerticalOffset*scale); + } + } + + private DesignSurface oldSurface; + private ZoomControl scrollViewer; + private Canvas zoomCanvas; + private Thumb zoomThumb; + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + this.zoomThumb = Template.FindName("PART_ZoomThumb", this) as Thumb; + this.zoomCanvas = Template.FindName("PART_ZoomCanvas", this) as Canvas; + + this.zoomThumb.DragDelta += this.Thumb_DragDelta; + + + } + + private void Thumb_DragDelta(object sender, DragDeltaEventArgs e) + { + if (DesignSurface != null) + { + if (scrollViewer != null) + { + double scale, xOffset, yOffset; + this.InvalidateScale(out scale, out xOffset, out yOffset); + + scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset + e.HorizontalChange / scale); + scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset + e.VerticalChange / scale); + } + } + } + + private void InvalidateScale(out double scale, out double xOffset, out double yOffset) + { + var designedElement = this.DesignSurface.DesignContext.RootItem.Component as FrameworkElement; + + var fac1 = designedElement.ActualWidth / zoomCanvas.ActualWidth; + var fac2 = designedElement.ActualHeight / zoomCanvas.ActualHeight; + + // zoom canvas size + double x = this.zoomCanvas.ActualWidth; + double y = this.zoomCanvas.ActualHeight; + + if (fac1 < fac2) + { + x = designedElement.ActualWidth / fac2; + xOffset = (zoomCanvas.ActualWidth - x) / 2; + yOffset = 0; + } + else + { + y = designedElement.ActualHeight / fac1; + xOffset = 0; + yOffset = (zoomCanvas.ActualHeight - y) / 2; + } + + double w = designedElement.ActualWidth; + double h = designedElement.ActualHeight; + + double scaleX = x / w; + double scaleY = y / h; + + scale = (scaleX < scaleY) ? scaleX : scaleY; + + xOffset += (x - scale * w) / 2; + yOffset += (y - scale * h) / 2; + } + + public event PropertyChangedEventHandler PropertyChanged; + protected virtual void OnPropertyChanged(string propertyName) + { + PropertyChangedEventHandler handler = PropertyChanged; + if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); + } + } +} diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/ThumbnailView/ThumbnailView.xaml b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/ThumbnailView/ThumbnailView.xaml new file mode 100644 index 0000000000..6192747665 --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/ThumbnailView/ThumbnailView.xaml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj index 01ca5daf7a..1cca268adb 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj @@ -220,6 +220,7 @@ + @@ -231,6 +232,7 @@ + {8035765F-D51F-4A0C-A746-2FD100E19419} ICSharpCode.SharpDevelop.Widgets @@ -346,5 +348,7 @@ - - + + + + \ No newline at end of file diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/themes/generic.xaml b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/themes/generic.xaml index a2529325ca..7de9ea3759 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/themes/generic.xaml +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/themes/generic.xaml @@ -5,5 +5,6 @@ +