Browse Source

Merge branch 'master' of github.com:icsharpcode/SharpDevelop

pull/716/head
Peter Forstmeier 10 years ago
parent
commit
ea71545bd5
  1. 3
      .editorconfig
  2. 2
      samples/XamlDesigner/Toolbox.cs
  3. 6
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlConst.cs
  4. 198
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/CollapsiblePanel.cs
  5. 110
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ColorHelper.cs
  6. 232
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ColorPicker.xaml
  7. 191
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ColorPicker.xaml.cs
  8. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ControlStyles.xaml
  9. 323
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/NumericUpDown.cs
  10. 140
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/NumericUpDown.xaml
  11. 5
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PanelMoveAdorner.cs
  12. 151
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/Picker.cs
  13. 118
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/RelayCommand.cs
  14. 30
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/Thumbs/UserControlPointsObjectThumb.cs
  15. 66
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ZoomButtons.cs
  16. 5
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ZoomControl.cs
  17. 184
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ZoomScrollViewer.cs
  18. 94
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ZoomScrollViewer.xaml
  19. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignPanel.cs
  20. 7
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignSurface.cs
  21. 3
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignSurface.xaml
  22. 5
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/CanvasPlacementSupport.cs
  23. 7
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/DefaultPlacementBehavior.cs
  24. 20
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/GridPlacementSupport.cs
  25. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/LineExtensionBase.cs
  26. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/LineHandlerExtension.cs
  27. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PolyLineHandlerExtension.cs
  28. 3
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/QuickOperationMenuExtension.cs
  29. 32
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RotateThumbExtension.cs
  30. 245
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/UserControlPointsObjectExtension.cs
  31. 5
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/FocusNavigator.cs
  32. 69
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/MarkupExtensions/DesignItemBinding.cs
  33. 89
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/ModelTools.cs
  34. 4
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/PropertyGrid/Editors/BrushEditor/BrushEditorView.xaml
  35. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/PropertyGrid/Editors/BrushEditor/SolidBrushEditor.xaml
  36. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/PropertyGrid/Editors/NumberEditor.xaml
  37. 31
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj
  38. 13
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlComponentService.cs
  39. 4
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlDesignItem.cs
  40. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlEditOperations.cs
  41. 38
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelCollectionElementsCollection.cs
  42. 7
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelPropertyCollection.cs
  43. 4
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/themes/generic.xaml
  44. 9
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/EditOperationTests.cs
  45. 62
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/ModelTests.cs
  46. 13
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObject.cs
  47. 12
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs
  48. 5
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignItem.cs
  49. 5
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementOperation.cs
  50. 3
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Services.cs

3
.editorconfig

@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
root = true
[*]
indent_style = tab

2
samples/XamlDesigner/Toolbox.cs

@ -70,7 +70,7 @@ namespace ICSharpCode.XamlDesigner @@ -70,7 +70,7 @@ namespace ICSharpCode.XamlDesigner
{
AddAssembly(Environment.ExpandEnvironmentVariables(path), false);
}
catch (Exception ex)
catch (Exception)
{ }
}
}

6
src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlConst.cs

@ -94,14 +94,16 @@ namespace ICSharpCode.XamlBinding @@ -94,14 +94,16 @@ namespace ICSharpCode.XamlBinding
switch (context.Description) {
case XamlContextDescription.AtTag:
if (context.ParentElement != null && string.Equals(context.ParentElement.Name, xKey + "Members", StringComparison.OrdinalIgnoreCase)) {
if (context.ParentElement == null || context.RootElement == null)
yield break;
if (string.Equals(context.ParentElement.Name, xKey + "Members", StringComparison.OrdinalIgnoreCase)) {
yield return xKey + "Member";
yield return xKey + "Property";
} else if (context.ParentElement == context.RootElement && context.RootElement.Attributes.Any(attr => string.Equals(attr.Name, xKey + "Class", StringComparison.OrdinalIgnoreCase))) {
yield return xKey + "Code";
yield return xKey + "Members";
} else {
if (context.ParentElement != null && string.Equals(context.ParentElement.Name, xKey + "Code", StringComparison.OrdinalIgnoreCase))
if (string.Equals(context.ParentElement.Name, xKey + "Code", StringComparison.OrdinalIgnoreCase))
yield break;
yield return xKey + "Array";
yield return xKey + "Boolean";

198
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/CollapsiblePanel.cs

@ -0,0 +1,198 @@ @@ -0,0 +1,198 @@
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media.Animation;
namespace ICSharpCode.WpfDesign.Designer.Controls
{
/// <summary>
/// Allows animated collapsing of the content of this panel.
/// </summary>
public class CollapsiblePanel : ContentControl
{
static CollapsiblePanel()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CollapsiblePanel),
new FrameworkPropertyMetadata(typeof(CollapsiblePanel)));
FocusableProperty.OverrideMetadata(typeof(CollapsiblePanel),
new FrameworkPropertyMetadata(false));
}
public static readonly DependencyProperty IsCollapsedProperty = DependencyProperty.Register(
"IsCollapsed", typeof(bool), typeof(CollapsiblePanel),
new UIPropertyMetadata(false, new PropertyChangedCallback(OnIsCollapsedChanged)));
public bool IsCollapsed {
get { return (bool)GetValue(IsCollapsedProperty); }
set { SetValue(IsCollapsedProperty, value); }
}
public static readonly DependencyProperty CollapseOrientationProperty =
DependencyProperty.Register("CollapseOrientation", typeof(Orientation), typeof(CollapsiblePanel),
new FrameworkPropertyMetadata(Orientation.Vertical));
public Orientation CollapseOrientation {
get { return (Orientation)GetValue(CollapseOrientationProperty); }
set { SetValue(CollapseOrientationProperty, value); }
}
public static readonly DependencyProperty DurationProperty = DependencyProperty.Register(
"Duration", typeof(TimeSpan), typeof(CollapsiblePanel),
new UIPropertyMetadata(TimeSpan.FromMilliseconds(250)));
/// <summary>
/// The duration in milliseconds of the animation.
/// </summary>
public TimeSpan Duration {
get { return (TimeSpan)GetValue(DurationProperty); }
set { SetValue(DurationProperty, value); }
}
protected internal static readonly DependencyProperty AnimationProgressProperty = DependencyProperty.Register(
"AnimationProgress", typeof(double), typeof(CollapsiblePanel),
new FrameworkPropertyMetadata(1.0));
/// <summary>
/// Value between 0 and 1 specifying how far the animation currently is.
/// </summary>
protected internal double AnimationProgress {
get { return (double)GetValue(AnimationProgressProperty); }
set { SetValue(AnimationProgressProperty, value); }
}
protected internal static readonly DependencyProperty AnimationProgressXProperty = DependencyProperty.Register(
"AnimationProgressX", typeof(double), typeof(CollapsiblePanel),
new FrameworkPropertyMetadata(1.0));
/// <summary>
/// Value between 0 and 1 specifying how far the animation currently is.
/// </summary>
protected internal double AnimationProgressX {
get { return (double)GetValue(AnimationProgressXProperty); }
set { SetValue(AnimationProgressXProperty, value); }
}
protected internal static readonly DependencyProperty AnimationProgressYProperty = DependencyProperty.Register(
"AnimationProgressY", typeof(double), typeof(CollapsiblePanel),
new FrameworkPropertyMetadata(1.0));
/// <summary>
/// Value between 0 and 1 specifying how far the animation currently is.
/// </summary>
protected internal double AnimationProgressY {
get { return (double)GetValue(AnimationProgressYProperty); }
set { SetValue(AnimationProgressYProperty, value); }
}
static void OnIsCollapsedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((CollapsiblePanel)d).SetupAnimation((bool)e.NewValue);
}
void SetupAnimation(bool isCollapsed)
{
if (this.IsLoaded) {
// If the animation is already running, calculate remaining portion of the time
double currentProgress = AnimationProgress;
if (!isCollapsed) {
currentProgress = 1.0 - currentProgress;
}
DoubleAnimation animation = new DoubleAnimation();
animation.To = isCollapsed ? 0.0 : 1.0;
animation.Duration = TimeSpan.FromSeconds(Duration.TotalSeconds * currentProgress);
animation.FillBehavior = FillBehavior.HoldEnd;
this.BeginAnimation(AnimationProgressProperty, animation);
if (CollapseOrientation == Orientation.Horizontal) {
this.BeginAnimation(AnimationProgressXProperty, animation);
this.AnimationProgressY = 1.0;
} else {
this.AnimationProgressX = 1.0;
this.BeginAnimation(AnimationProgressYProperty, animation);
}
} else {
this.AnimationProgress = isCollapsed ? 0.0 : 1.0;
this.AnimationProgressX = (CollapseOrientation == Orientation.Horizontal) ? this.AnimationProgress : 1.0;
this.AnimationProgressY = (CollapseOrientation == Orientation.Vertical) ? this.AnimationProgress : 1.0;
}
}
}
sealed class CollapsiblePanelProgressToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is double)
return (double)value > 0 ? Visibility.Visible : Visibility.Collapsed;
else
return Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class SelfCollapsingPanel : CollapsiblePanel
{
public static readonly DependencyProperty CanCollapseProperty =
DependencyProperty.Register("CanCollapse", typeof(bool), typeof(SelfCollapsingPanel),
new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnCanCollapseChanged)));
public bool CanCollapse {
get { return (bool)GetValue(CanCollapseProperty); }
set { SetValue(CanCollapseProperty, value); }
}
static void OnCanCollapseChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
SelfCollapsingPanel panel = (SelfCollapsingPanel)d;
if ((bool)e.NewValue) {
if (!panel.HeldOpenByMouse)
panel.IsCollapsed = true;
} else {
panel.IsCollapsed = false;
}
}
bool HeldOpenByMouse {
get { return IsMouseOver || IsMouseCaptureWithin; }
}
protected override void OnMouseLeave(MouseEventArgs e)
{
base.OnMouseLeave(e);
if (CanCollapse && !HeldOpenByMouse)
IsCollapsed = true;
}
protected override void OnLostMouseCapture(MouseEventArgs e)
{
base.OnLostMouseCapture(e);
if (CanCollapse && !HeldOpenByMouse)
IsCollapsed = true;
}
}
}

110
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ColorHelper.cs

@ -0,0 +1,110 @@ @@ -0,0 +1,110 @@
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Windows.Media;
namespace ICSharpCode.WpfDesign.Designer.Controls
{
public static class ColorHelper
{
public static Color ColorFromString(string s)
{
if (string.IsNullOrEmpty(s)) {
return Colors.White;
}
if (s[0] != '#') s = "#" + s;
try {
return (Color)ColorConverter.ConvertFromString(s);
}
catch {
return Colors.White;
}
}
public static string StringFromColor(Color c)
{
return c.ToString().Substring(1);
}
public static Color ColorFromHsv(double h, double s, double v)
{
double r, g, b;
RgbFromHsv(h, s, v, out r, out g, out b);
return Color.FromRgb((byte)(r * 255), (byte)(g * 255), (byte)(b * 255));
}
public static void HsvFromColor(Color c, out double h, out double s, out double v)
{
HsvFromRgb(c.R / 255.0, c.G / 255.0, c.B / 255.0, out h, out s, out v);
}
// http://en.wikipedia.org/wiki/HSV_color_space
public static void HsvFromRgb(double r, double g, double b, out double h, out double s, out double v)
{
var max = Math.Max(r, Math.Max(g, b));
var min = Math.Min(r, Math.Min(g, b));
if (max == min) {
h = 0;
}
else if (max == r) {
h = (60 * (g - b) / (max - min)) % 360;
}
else if (max == g) {
h = 60 * (b - r) / (max - min) + 120;
}
else {
h = 60 * (r - g) / (max - min) + 240;
}
if (h < 0) h += 360; // C# '%' can return negative values, use real modulus instead
if (max == 0) {
s = 0;
}
else {
s = 1 - min / max;
}
v = max;
}
// http://en.wikipedia.org/wiki/HSV_color_space
public static void RgbFromHsv(double h, double s, double v, out double r, out double g, out double b)
{
h = h % 360;
if (h < 0) h += 360; // C# '%' can return negative values, use real modulus instead
int hi = (int)(h / 60) % 6;
var f = h / 60 - (int)(h / 60);
var p = v * (1 - s);
var q = v * (1 - f * s);
var t = v * (1 - (1 - f) * s);
switch (hi) {
case 0: r = v; g = t; b = p; break;
case 1: r = q; g = v; b = p; break;
case 2: r = p; g = v; b = t; break;
case 3: r = p; g = q; b = v; break;
case 4: r = t; g = p; b = v; break;
default: r = v; g = p; b = q; break;
}
}
}
}

232
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ColorPicker.xaml

@ -0,0 +1,232 @@ @@ -0,0 +1,232 @@
<UserControl x:Class="ICSharpCode.WpfDesign.Designer.Controls.ColorPicker"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:widgets="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls"
x:Name="this"
Padding="5"
Width="373">
<UserControl.Resources>
<DrawingBrush x:Key="ChessBrush"
TileMode="Tile"
ViewportUnits="Absolute"
Viewport="0 0 9 9">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="White">
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0 0 2 2" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="Gray">
<GeometryDrawing.Geometry>
<GeometryGroup>
<RectangleGeometry Rect="0 0 1 1" />
<RectangleGeometry Rect="1 1 1 1" />
</GeometryGroup>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</UserControl.Resources>
<DockPanel>
<StackPanel VerticalAlignment="Top"
DockPanel.Dock="Right"
Margin="10 0 0 0">
<Border Background="{StaticResource ChessBrush}"
HorizontalAlignment="Right"
BorderBrush="Black"
BorderThickness="1"
Height="50"
Width="70">
<Rectangle>
<Rectangle.Fill>
<SolidColorBrush Color="{Binding Color, ElementName=this}" />
</Rectangle.Fill>
</Rectangle>
</Border>
<DockPanel Margin="0 3 0 0">
<widgets:HexTextBox Text="{Binding Hex, ElementName=this, UpdateSourceTrigger=PropertyChanged}"
Width="70"
Margin="5 0 0 0"
DockPanel.Dock="Right" />
<TextBlock Text="#"
VerticalAlignment="Center"
HorizontalAlignment="Right" />
</DockPanel>
<DockPanel Margin="0 3 0 0">
<widgets:NumericUpDown Value="{Binding H, ElementName=this}"
Maximum="360"
Width="70"
Margin="5 0 0 0"
DockPanel.Dock="Right" />
<TextBlock Text="H"
VerticalAlignment="Center"
HorizontalAlignment="Right" />
</DockPanel>
<DockPanel Margin="0 3 0 0">
<widgets:NumericUpDown Value="{Binding S, ElementName=this}"
Width="70"
Margin="5 0 0 0"
DockPanel.Dock="Right" />
<TextBlock Text="S"
VerticalAlignment="Center"
HorizontalAlignment="Right" />
</DockPanel>
<DockPanel Margin="0 3 0 0">
<widgets:NumericUpDown Value="{Binding V, ElementName=this}"
Width="70"
Margin="5 0 0 0"
DockPanel.Dock="Right" />
<TextBlock Text="V"
VerticalAlignment="Center"
HorizontalAlignment="Right" />
</DockPanel>
<DockPanel Margin="0 3 0 0">
<widgets:NumericUpDown Value="{Binding R, ElementName=this}"
Maximum="255"
Width="70"
Margin="5 0 0 0"
DockPanel.Dock="Right" />
<TextBlock Text="R"
VerticalAlignment="Center"
HorizontalAlignment="Right" />
</DockPanel>
<DockPanel Margin="0 3 0 0">
<widgets:NumericUpDown Value="{Binding G, ElementName=this}"
Maximum="255"
Width="70"
Margin="5 0 0 0"
DockPanel.Dock="Right" />
<TextBlock Text="G"
VerticalAlignment="Center"
HorizontalAlignment="Right" />
</DockPanel>
<DockPanel Margin="0 3 0 0">
<widgets:NumericUpDown Value="{Binding B, ElementName=this}"
Maximum="255"
Width="70"
Margin="5 0 0 0"
DockPanel.Dock="Right" />
<TextBlock Text="B"
VerticalAlignment="Center"
HorizontalAlignment="Right" />
</DockPanel>
<DockPanel Margin="0 3 0 0">
<widgets:NumericUpDown Value="{Binding A, ElementName=this}"
Maximum="255"
Width="70"
Margin="5 0 0 0"
DockPanel.Dock="Right" />
<TextBlock Text="A"
VerticalAlignment="Center"
HorizontalAlignment="Right" />
</DockPanel>
</StackPanel>
<Border Margin="10 0 0 0"
DockPanel.Dock="Right">
<widgets:Picker Orientation="Vertical"
Value="{Binding H, ElementName=this}"
Minimum="360"
Maximum="0"
Marker="{Binding ElementName=arrows}"
Width="20">
<Border Margin="0 -1">
<Border.Background>
<LinearGradientBrush EndPoint="0 1">
<GradientStop Offset="0"
Color="#F00" />
<GradientStop Offset="0.16"
Color="#F0F" />
<GradientStop Offset="0.33"
Color="#00F" />
<GradientStop Offset="0.5"
Color="#0FF" />
<GradientStop Offset="0.76"
Color="#0F0" />
<GradientStop Offset="0.85"
Color="#FF0" />
<GradientStop Offset="1"
Color="#F00" />
</LinearGradientBrush>
</Border.Background>
</Border>
<Grid x:Name="arrows"
IsHitTestVisible="False"
VerticalAlignment="Top"
Margin="-5">
<Path HorizontalAlignment="Left"
Data="M 0 0 L 5 5 L 0 10 Z"
Fill="Black" />
<Path HorizontalAlignment="Right"
Data="M 0 0 L -5 5 L 0 10 Z"
Fill="Black" />
</Grid>
</widgets:Picker>
</Border>
<Border BorderBrush="Black"
BorderThickness="1">
<widgets:Picker Value="{Binding S, ElementName=this}"
Marker="{Binding ElementName=point}"
ClipToBounds="True">
<widgets:Picker Orientation="Vertical"
Value="{Binding V, ElementName=this}"
Minimum="100"
Maximum="0"
Marker="{Binding ElementName=point}">
<Rectangle>
<Rectangle.Fill>
<LinearGradientBrush EndPoint="1 0">
<GradientStop Offset="0"
Color="White" />
<GradientStop Offset="1"
Color="{Binding HueColor, ElementName=this}" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle>
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0 1">
<GradientStop Offset="0"
Color="#0000" />
<GradientStop Offset="1"
Color="#F000" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Grid x:Name="point"
VerticalAlignment="Top"
HorizontalAlignment="Left"
Width="12"
Height="12"
Margin="-6 -6 0 0">
<Ellipse Stroke="Black"
IsHitTestVisible="False" />
<Ellipse Stroke="White"
Margin="1"
IsHitTestVisible="False" />
</Grid>
</widgets:Picker>
</widgets:Picker>
</Border>
</DockPanel>
</UserControl>

191
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ColorPicker.xaml.cs

@ -0,0 +1,191 @@ @@ -0,0 +1,191 @@
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
namespace ICSharpCode.WpfDesign.Designer.Controls
{
public partial class ColorPicker
{
public ColorPicker()
{
InitializeComponent();
}
public static readonly DependencyProperty ColorProperty =
DependencyProperty.Register("Color", typeof(Color), typeof(ColorPicker),
new FrameworkPropertyMetadata(new Color(), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public Color Color {
get { return (Color)GetValue(ColorProperty); }
set { SetValue(ColorProperty, value); }
}
public static readonly DependencyProperty HProperty =
DependencyProperty.Register("H", typeof(int), typeof(ColorPicker));
public int H {
get { return (int)GetValue(HProperty); }
set { SetValue(HProperty, value); }
}
public static readonly DependencyProperty SProperty =
DependencyProperty.Register("S", typeof(int), typeof(ColorPicker));
public int S {
get { return (int)GetValue(SProperty); }
set { SetValue(SProperty, value); }
}
public static readonly DependencyProperty VProperty =
DependencyProperty.Register("V", typeof(int), typeof(ColorPicker));
public int V {
get { return (int)GetValue(VProperty); }
set { SetValue(VProperty, value); }
}
public static readonly DependencyProperty RProperty =
DependencyProperty.Register("R", typeof(byte), typeof(ColorPicker));
public byte R {
get { return (byte)GetValue(RProperty); }
set { SetValue(RProperty, value); }
}
public static readonly DependencyProperty GProperty =
DependencyProperty.Register("G", typeof(byte), typeof(ColorPicker));
public byte G {
get { return (byte)GetValue(GProperty); }
set { SetValue(GProperty, value); }
}
public static readonly DependencyProperty BProperty =
DependencyProperty.Register("B", typeof(byte), typeof(ColorPicker));
public byte B {
get { return (byte)GetValue(BProperty); }
set { SetValue(BProperty, value); }
}
public static readonly DependencyProperty AProperty =
DependencyProperty.Register("A", typeof(byte), typeof(ColorPicker));
public byte A {
get { return (byte)GetValue(AProperty); }
set { SetValue(AProperty, value); }
}
public static readonly DependencyProperty HexProperty =
DependencyProperty.Register("Hex", typeof(string), typeof(ColorPicker));
public string Hex {
get { return (string)GetValue(HexProperty); }
set { SetValue(HexProperty, value); }
}
public static readonly DependencyProperty HueColorProperty =
DependencyProperty.Register("HueColor", typeof(Color), typeof(ColorPicker));
public Color HueColor {
get { return (Color)GetValue(HueColorProperty); }
set { SetValue(HueColorProperty, value); }
}
bool updating;
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
if (updating) return;
updating = true;
try {
if (e.Property == ColorProperty) {
UpdateSource(ColorSource.Hsv);
UpdateRest(ColorSource.Hsv);
} else if (e.Property == HProperty || e.Property == SProperty || e.Property == VProperty) {
var c = ColorHelper.ColorFromHsv(H, S / 100.0, V / 100.0);
c.A = A;
Color = c;
UpdateRest(ColorSource.Hsv);
} else if (e.Property == RProperty || e.Property == GProperty || e.Property == BProperty || e.Property == AProperty) {
Color = Color.FromArgb(A, R, G, B);
UpdateRest(ColorSource.Rgba);
} else if (e.Property == HexProperty) {
Color = ColorHelper.ColorFromString(Hex);
UpdateRest(ColorSource.Hex);
}
} finally {
updating = false;
}
}
void UpdateRest(ColorSource source)
{
HueColor = ColorHelper.ColorFromHsv(H, 1, 1);
UpdateSource((ColorSource)(((int)source + 1) % 3));
UpdateSource((ColorSource)(((int)source + 2) % 3));
}
void UpdateSource(ColorSource source)
{
if (source == ColorSource.Hsv) {
double h, s, v;
ColorHelper.HsvFromColor(Color, out h, out s, out v);
H = (int)h;
S = (int)(s * 100);
V = (int)(v * 100);
}
else if (source == ColorSource.Rgba) {
R = Color.R;
G = Color.G;
B = Color.B;
A = Color.A;
}
else {
Hex = ColorHelper.StringFromColor(Color);
}
}
enum ColorSource
{
Hsv, Rgba, Hex
}
}
class HexTextBox : TextBox
{
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.Key == Key.Enter) {
var b = BindingOperations.GetBindingExpressionBase(this, TextProperty);
if (b != null) {
b.UpdateTarget();
}
SelectAll();
}
}
}
}

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ControlStyles.xaml

@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
xmlns:Controls="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls"
xmlns:ControlConvertors="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls.Converters"
xmlns:Converters="clr-namespace:ICSharpCode.WpfDesign.Designer.Converters"
xmlns:Widgets="http://icsharpcode.net/sharpdevelop/widgets">
xmlns:Widgets="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls">
<!--
This file contains the default styles used by the Controls in ICSharpCode.WpfDesign.Designer.Controls
-->

323
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/NumericUpDown.cs

@ -0,0 +1,323 @@ @@ -0,0 +1,323 @@
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Controls.Primitives;
namespace ICSharpCode.WpfDesign.Designer.Controls
{
public class NumericUpDown : Control
{
static NumericUpDown()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(NumericUpDown),
new FrameworkPropertyMetadata(typeof(NumericUpDown)));
}
TextBox textBox;
DragRepeatButton upButton;
DragRepeatButton downButton;
public static readonly DependencyProperty DecimalPlacesProperty =
DependencyProperty.Register("DecimalPlaces", typeof(int), typeof(NumericUpDown));
public int DecimalPlaces {
get { return (int)GetValue(DecimalPlacesProperty); }
set { SetValue(DecimalPlacesProperty, value); }
}
public static readonly DependencyProperty MinimumProperty =
DependencyProperty.Register("Minimum", typeof(double), typeof(NumericUpDown));
public double Minimum {
get { return (double)GetValue(MinimumProperty); }
set { SetValue(MinimumProperty, value); }
}
public static readonly DependencyProperty MaximumProperty =
DependencyProperty.Register("Maximum", typeof(double), typeof(NumericUpDown),
new FrameworkPropertyMetadata(100.0));
public double Maximum {
get { return (double)GetValue(MaximumProperty); }
set { SetValue(MaximumProperty, value); }
}
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(double), typeof(NumericUpDown),
new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public double Value {
get { return (double)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public static readonly DependencyProperty SmallChangeProperty =
DependencyProperty.Register("SmallChange", typeof(double), typeof(NumericUpDown),
new FrameworkPropertyMetadata(1.0));
public double SmallChange {
get { return (double)GetValue(SmallChangeProperty); }
set { SetValue(SmallChangeProperty, value); }
}
public static readonly DependencyProperty LargeChangeProperty =
DependencyProperty.Register("LargeChange", typeof(double), typeof(NumericUpDown),
new FrameworkPropertyMetadata(10.0));
public double LargeChange {
get { return (double)GetValue(LargeChangeProperty); }
set { SetValue(LargeChangeProperty, value); }
}
bool IsDragging {
get {
return upButton.IsDragging;
}
set {
upButton.IsDragging = value; downButton.IsDragging = value;
}
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
upButton = (DragRepeatButton)Template.FindName("PART_UpButton", this);
downButton = (DragRepeatButton)Template.FindName("PART_DownButton", this);
textBox = (TextBox)Template.FindName("PART_TextBox", this);
upButton.Click += upButton_Click;
downButton.Click += downButton_Click;
textBox.LostFocus += (sender, e) => OnLostFocus(e);
var upDrag = new DragListener(upButton);
var downDrag = new DragListener(downButton);
upDrag.Started += drag_Started;
upDrag.Changed += drag_Changed;
upDrag.Completed += drag_Completed;
downDrag.Started += drag_Started;
downDrag.Changed += drag_Changed;
downDrag.Completed += drag_Completed;
Print();
}
void drag_Started(DragListener drag)
{
OnDragStarted();
}
void drag_Changed(DragListener drag)
{
IsDragging = true;
MoveValue(-drag.DeltaDelta.Y * SmallChange);
}
void drag_Completed(DragListener drag)
{
IsDragging = false;
OnDragCompleted();
}
void downButton_Click(object sender, RoutedEventArgs e)
{
if (!IsDragging) SmallDown();
}
void upButton_Click(object sender, RoutedEventArgs e)
{
if (!IsDragging) SmallUp();
}
protected virtual void OnDragStarted()
{
}
protected virtual void OnDragCompleted()
{
}
public void SmallUp()
{
MoveValue(SmallChange);
}
public void SmallDown()
{
MoveValue(-SmallChange);
}
public void LargeUp()
{
MoveValue(LargeChange);
}
public void LargeDown()
{
MoveValue(-LargeChange);
}
void MoveValue(double delta)
{
double result;
if (double.IsNaN(Value) || double.IsInfinity(Value)) {
SetValue(delta);
}
else if (double.TryParse(textBox.Text, out result)) {
SetValue(result + delta);
}
else {
SetValue(Value + delta);
}
}
void Print()
{
if (textBox != null) {
textBox.Text = Value.ToString("F" + DecimalPlaces);
textBox.CaretIndex = int.MaxValue;
}
}
//wpf bug?: Value = -1 updates bindings without coercing, workaround
//update: not derived from RangeBase - no problem
void SetValue(double newValue)
{
newValue = CoerceValue(newValue);
if (Value != newValue) {
Value = newValue;
}
}
double CoerceValue(double newValue)
{
return Math.Max(Minimum, Math.Min(newValue, Maximum));
}
protected override void OnPreviewKeyDown(KeyEventArgs e)
{
base.OnPreviewKeyDown(e);
switch (e.Key) {
case Key.Enter:
SetInputValue();
textBox.SelectAll();
e.Handled = true;
break;
case Key.Up:
SmallUp();
e.Handled = true;
break;
case Key.Down:
SmallDown();
e.Handled = true;
break;
case Key.PageUp:
LargeUp();
e.Handled = true;
break;
case Key.PageDown:
LargeDown();
e.Handled = true;
break;
// case Key.Home:
// Maximize();
// e.Handled = true;
// break;
// case Key.End:
// Minimize();
// e.Handled = true;
// break;
}
}
void SetInputValue()
{
double result;
if (double.TryParse(textBox.Text, out result)) {
SetValue(result);
} else {
Print();
}
}
protected override void OnLostFocus(RoutedEventArgs e)
{
base.OnLostFocus(e);
SetInputValue();
}
//protected override void OnMouseWheel(MouseWheelEventArgs e)
//{
// if (e.Delta > 0)
// {
// if (Keyboard.IsKeyDown(Key.LeftShift))
// {
// LargeUp();
// }
// else
// {
// SmallUp();
// }
// }
// else
// {
// if (Keyboard.IsKeyDown(Key.LeftShift))
// {
// LargeDown();
// }
// else
// {
// SmallDown();
// }
// }
// e.Handled = true;
//}
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
if (e.Property == ValueProperty) {
Value = CoerceValue((double)e.NewValue);
Print();
}
else if (e.Property == SmallChangeProperty &&
ReadLocalValue(LargeChangeProperty) == DependencyProperty.UnsetValue) {
LargeChange = SmallChange * 10;
}
}
}
public class DragRepeatButton : RepeatButton
{
public static readonly DependencyProperty IsDraggingProperty =
DependencyProperty.Register("IsDragging", typeof(bool), typeof(DragRepeatButton));
public bool IsDragging {
get { return (bool)GetValue(IsDraggingProperty); }
set { SetValue(IsDraggingProperty, value); }
}
}
}

140
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/NumericUpDown.xaml

@ -0,0 +1,140 @@ @@ -0,0 +1,140 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls">
<Brush x:Key="ButtonNormal">#DADFEA</Brush>
<Brush x:Key="ButtonHover">#E6EBEF</Brush>
<Brush x:Key="ButtonPressed">#B6BDD3</Brush>
<Brush x:Key="BorderBrush">#7F9DB9</Brush>
<Brush x:Key="ArrowBrush">Black</Brush>
<Brush x:Key="ArrowsBorderBrush">#B6BDD3</Brush>
<Style x:Key="UpButton"
TargetType="RepeatButton">
<Setter Property="Focusable"
Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Controls:DragRepeatButton}">
<Border x:Name="bg"
Background="{StaticResource ButtonNormal}"
CornerRadius="2 2 0 0">
<Path Fill="{StaticResource ArrowBrush}"
Data="M 0 3 L 3.5 0 L 7 3"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="bg"
Property="Background"
Value="{StaticResource ButtonHover}" />
</Trigger>
<Trigger Property="IsMouseCaptured"
Value="True">
<Setter TargetName="bg"
Property="Background"
Value="{StaticResource ButtonPressed}" />
</Trigger>
<Trigger Property="IsDragging"
Value="True">
<Setter TargetName="bg"
Property="Background"
Value="{StaticResource ButtonPressed}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="DownButton"
TargetType="RepeatButton">
<Setter Property="Focusable"
Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Controls:DragRepeatButton}">
<Border x:Name="bg"
Background="{StaticResource ButtonNormal}"
CornerRadius="0 0 2 2">
<Path Fill="{StaticResource ArrowBrush}"
Data="M 0 0 L 3.5 3 L 7 0"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="bg"
Property="Background"
Value="{StaticResource ButtonHover}" />
</Trigger>
<Trigger Property="IsMouseCaptured"
Value="True">
<Setter TargetName="bg"
Property="Background"
Value="{StaticResource ButtonPressed}" />
</Trigger>
<Trigger Property="IsDragging"
Value="True">
<Setter TargetName="bg"
Property="Background"
Value="{StaticResource ButtonPressed}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type Controls:NumericUpDown}">
<Setter Property="Background"
Value="White" />
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="BorderBrush"
Value="{StaticResource BorderBrush}" />
<Setter Property="Focusable"
Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Controls:NumericUpDown}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="15" />
</Grid.ColumnDefinitions>
<TextBox x:Name="PART_TextBox"
BorderThickness="0"
Background="{x:Null}"
Foreground="{TemplateBinding Foreground}"
Grid.RowSpan="2" />
<Controls:DragRepeatButton x:Name="PART_UpButton"
Style="{StaticResource UpButton}"
Grid.Column="1" />
<Controls:DragRepeatButton x:Name="PART_DownButton"
Style="{StaticResource DownButton}"
Grid.Column="1"
Grid.Row="1" />
<Border Grid.Column="1"
Grid.RowSpan="2"
BorderBrush="{StaticResource ArrowsBorderBrush}"
BorderThickness="1"
CornerRadius="2" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

5
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PanelMoveAdorner.cs

@ -16,17 +16,12 @@ @@ -16,17 +16,12 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Input;
using ICSharpCode.WpfDesign.Designer.Services;
using System.Windows.Media;
using ICSharpCode.WpfDesign.Designer.Converters;
using System.Globalization;
using System.Windows.Data;
using ICSharpCode.WpfDesign.UIExtensions;

151
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/Picker.cs

@ -0,0 +1,151 @@ @@ -0,0 +1,151 @@
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Data;
namespace ICSharpCode.WpfDesign.Designer.Controls
{
public class Picker : Grid
{
public Picker()
{
SizeChanged += delegate { UpdateValueOffset(); };
}
public static readonly DependencyProperty MarkerProperty =
DependencyProperty.Register("Marker", typeof(UIElement), typeof(Picker));
public UIElement Marker {
get { return (UIElement)GetValue(MarkerProperty); }
set { SetValue(MarkerProperty, value); }
}
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(double), typeof(Picker),
new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public double Value {
get { return (double)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public static readonly DependencyProperty ValueOffsetProperty =
DependencyProperty.Register("ValueOffset", typeof(double), typeof(Picker));
public double ValueOffset {
get { return (double)GetValue(ValueOffsetProperty); }
set { SetValue(ValueOffsetProperty, value); }
}
public static readonly DependencyProperty OrientationProperty =
DependencyProperty.Register("Orientation", typeof(Orientation), typeof(Picker));
public Orientation Orientation {
get { return (Orientation)GetValue(OrientationProperty); }
set { SetValue(OrientationProperty, value); }
}
public static readonly DependencyProperty MinimumProperty =
DependencyProperty.Register("Minimum", typeof(double), typeof(Picker));
public double Minimum {
get { return (double)GetValue(MinimumProperty); }
set { SetValue(MinimumProperty, value); }
}
public static readonly DependencyProperty MaximumProperty =
DependencyProperty.Register("Maximum", typeof(double), typeof(Picker),
new FrameworkPropertyMetadata(100.0));
public double Maximum {
get { return (double)GetValue(MaximumProperty); }
set { SetValue(MaximumProperty, value); }
}
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
if (e.Property == MarkerProperty) {
TranslateTransform t = Marker.RenderTransform as TranslateTransform;
if (t == null) {
t = new TranslateTransform();
Marker.RenderTransform = t;
}
var property = Orientation == Orientation.Horizontal ? TranslateTransform.XProperty : TranslateTransform.YProperty;
BindingOperations.SetBinding(t, property, new Binding("ValueOffset") {
Source = this
});
}
else if (e.Property == ValueProperty) {
UpdateValueOffset();
}
}
bool isMouseDown;
protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
{
isMouseDown = true;
CaptureMouse();
UpdateValue();
}
protected override void OnPreviewMouseMove(MouseEventArgs e)
{
if (isMouseDown) {
UpdateValue();
}
}
protected override void OnPreviewMouseUp(MouseButtonEventArgs e)
{
isMouseDown = false;
ReleaseMouseCapture();
}
void UpdateValue()
{
Point p = Mouse.GetPosition(this);
double length = 0, pos = 0;
if (Orientation == Orientation.Horizontal) {
length = ActualWidth;
pos = p.X;
}
else {
length = ActualHeight;
pos = p.Y;
}
pos = Math.Max(0, Math.Min(length, pos));
Value = Minimum + (Maximum - Minimum) * pos / length;
}
void UpdateValueOffset()
{
var length = Orientation == Orientation.Horizontal ? ActualWidth : ActualHeight;
ValueOffset = length * (Value - Minimum) / (Maximum - Minimum);
}
}
}

118
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/RelayCommand.cs

@ -0,0 +1,118 @@ @@ -0,0 +1,118 @@
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Windows.Input;
namespace ICSharpCode.WpfDesign.Designer.Controls
{
/// <summary>
/// A command that invokes a delegate.
/// The command parameter must be of type T.
/// </summary>
public class RelayCommand<T> : ICommand
{
readonly Predicate<T> canExecute;
readonly Action<T> execute;
public RelayCommand(Action<T> execute)
{
if (execute == null)
throw new ArgumentNullException("execute");
this.execute = execute;
}
public RelayCommand(Action<T> execute, Predicate<T> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
this.execute = execute;
this.canExecute = canExecute;
}
public event EventHandler CanExecuteChanged {
add {
if (canExecute != null)
CommandManager.RequerySuggested += value;
}
remove {
if (canExecute != null)
CommandManager.RequerySuggested -= value;
}
}
public bool CanExecute(object parameter)
{
if (parameter != null && !(parameter is T))
return false;
return canExecute == null ? true : canExecute((T)parameter);
}
public void Execute(object parameter)
{
execute((T)parameter);
}
}
/// <summary>
/// A command that invokes a delegate.
/// This class does not provide the command parameter to the delegate -
/// if you need that, use the generic version of this class instead.
/// </summary>
public class RelayCommand : ICommand
{
readonly Func<bool> canExecute;
readonly Action execute;
public RelayCommand(Action execute)
{
if (execute == null)
throw new ArgumentNullException("execute");
this.execute = execute;
}
public RelayCommand(Action execute, Func<bool> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
this.execute = execute;
this.canExecute = canExecute;
}
public event EventHandler CanExecuteChanged {
add {
if (canExecute != null)
CommandManager.RequerySuggested += value;
}
remove {
if (canExecute != null)
CommandManager.RequerySuggested -= value;
}
}
public bool CanExecute(object parameter)
{
return canExecute == null ? true : canExecute();
}
public void Execute(object parameter)
{
execute();
}
}
}

30
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/Thumbs/UserControlPointsObjectThumb.cs

@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using ICSharpCode.WpfDesign.UIExtensions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
namespace ICSharpCode.WpfDesign.Designer.Controls
{
public class UserControlPointsObjectThumb : DesignerThumb
{
public DependencyProperty DependencyProperty { get; set; }
}
}

66
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ZoomButtons.cs

@ -0,0 +1,66 @@ @@ -0,0 +1,66 @@
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Windows;
using System.Windows.Controls.Primitives;
namespace ICSharpCode.WpfDesign.Designer.Controls
{
public class ZoomButtons : RangeBase
{
static ZoomButtons()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ZoomButtons),
new FrameworkPropertyMetadata(typeof(ZoomButtons)));
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
var uxPlus = (ButtonBase)Template.FindName("uxPlus", this);
var uxMinus = (ButtonBase)Template.FindName("uxMinus", this);
var uxReset = (ButtonBase)Template.FindName("uxReset", this);
if (uxPlus != null)
uxPlus.Click += OnZoomInClick;
if (uxMinus != null)
uxMinus.Click += OnZoomOutClick;
if (uxReset != null)
uxReset.Click += OnResetClick;
}
const double ZoomFactor = 1.1;
void OnZoomInClick(object sender, EventArgs e)
{
SetCurrentValue(ValueProperty, ZoomScrollViewer.RoundToOneIfClose(this.Value * ZoomFactor));
}
void OnZoomOutClick(object sender, EventArgs e)
{
SetCurrentValue(ValueProperty, ZoomScrollViewer.RoundToOneIfClose(this.Value / ZoomFactor));
}
void OnResetClick(object sender, EventArgs e)
{
SetCurrentValue(ValueProperty, 1.0);
}
}
}

5
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ZoomControl.cs

@ -15,16 +15,13 @@ @@ -15,16 +15,13 @@
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Windows;
using System.Windows.Input;
using ICSharpCode.SharpDevelop.Widgets;
namespace ICSharpCode.WpfDesign.Designer.Controls
{
public class ZoomControl : ZoomScrollViewer

184
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ZoomScrollViewer.cs

@ -0,0 +1,184 @@ @@ -0,0 +1,184 @@
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
namespace ICSharpCode.WpfDesign.Designer.Controls
{
public class ZoomScrollViewer : ScrollViewer
{
static ZoomScrollViewer()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ZoomScrollViewer),
new FrameworkPropertyMetadata(typeof(ZoomScrollViewer)));
}
public static readonly DependencyProperty CurrentZoomProperty =
DependencyProperty.Register("CurrentZoom", typeof(double), typeof(ZoomScrollViewer),
new FrameworkPropertyMetadata(1.0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, CalculateZoomButtonCollapsed, CoerceZoom));
public double CurrentZoom {
get { return (double)GetValue(CurrentZoomProperty); }
set { SetValue(CurrentZoomProperty, value); }
}
static object CoerceZoom(DependencyObject d, object baseValue)
{
var zoom = (double)baseValue;
ZoomScrollViewer sv = (ZoomScrollViewer)d;
return Math.Max(sv.MinimumZoom, Math.Min(sv.MaximumZoom, zoom));
}
public static readonly DependencyProperty MinimumZoomProperty =
DependencyProperty.Register("MinimumZoom", typeof(double), typeof(ZoomScrollViewer),
new FrameworkPropertyMetadata(0.2));
public double MinimumZoom {
get { return (double)GetValue(MinimumZoomProperty); }
set { SetValue(MinimumZoomProperty, value); }
}
public static readonly DependencyProperty MaximumZoomProperty =
DependencyProperty.Register("MaximumZoom", typeof(double), typeof(ZoomScrollViewer),
new FrameworkPropertyMetadata(5.0));
public double MaximumZoom {
get { return (double)GetValue(MaximumZoomProperty); }
set { SetValue(MaximumZoomProperty, value); }
}
public static readonly DependencyProperty MouseWheelZoomProperty =
DependencyProperty.Register("MouseWheelZoom", typeof(bool), typeof(ZoomScrollViewer),
new FrameworkPropertyMetadata(true));
public bool MouseWheelZoom {
get { return (bool)GetValue(MouseWheelZoomProperty); }
set { SetValue(MouseWheelZoomProperty, value); }
}
public static readonly DependencyProperty AlwaysShowZoomButtonsProperty =
DependencyProperty.Register("AlwaysShowZoomButtons", typeof(bool), typeof(ZoomScrollViewer),
new FrameworkPropertyMetadata(false, CalculateZoomButtonCollapsed));
public bool AlwaysShowZoomButtons {
get { return (bool)GetValue(AlwaysShowZoomButtonsProperty); }
set { SetValue(AlwaysShowZoomButtonsProperty, value); }
}
static readonly DependencyPropertyKey ComputedZoomButtonCollapsedPropertyKey =
DependencyProperty.RegisterReadOnly("ComputedZoomButtonCollapsed", typeof(bool), typeof(ZoomScrollViewer),
new FrameworkPropertyMetadata(true));
public static readonly DependencyProperty ComputedZoomButtonCollapsedProperty = ComputedZoomButtonCollapsedPropertyKey.DependencyProperty;
public bool ComputedZoomButtonCollapsed {
get { return (bool)GetValue(ComputedZoomButtonCollapsedProperty); }
private set { SetValue(ComputedZoomButtonCollapsedPropertyKey, value); }
}
static void CalculateZoomButtonCollapsed(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ZoomScrollViewer z = d as ZoomScrollViewer;
if (z != null)
z.ComputedZoomButtonCollapsed = (z.AlwaysShowZoomButtons == false) && (z.CurrentZoom == 1.0);
}
protected override void OnMouseWheel(MouseWheelEventArgs e)
{
if (!e.Handled && Keyboard.Modifiers == ModifierKeys.Control && MouseWheelZoom) {
double oldZoom = CurrentZoom;
double newZoom = RoundToOneIfClose(CurrentZoom * Math.Pow(1.001, e.Delta));
newZoom = Math.Max(this.MinimumZoom, Math.Min(this.MaximumZoom, newZoom));
// adjust scroll position so that mouse stays over the same virtual coordinate
ContentPresenter presenter = Template.FindName("PART_Presenter", this) as ContentPresenter;
Vector relMousePos;
if (presenter != null) {
Point mousePos = e.GetPosition(presenter);
relMousePos = new Vector(mousePos.X / presenter.ActualWidth, mousePos.Y / presenter.ActualHeight);
} else {
relMousePos = new Vector(0.5, 0.5);
}
Point scrollOffset = new Point(this.HorizontalOffset, this.VerticalOffset);
Vector oldHalfViewport = new Vector(this.ViewportWidth / 2, this.ViewportHeight / 2);
Vector newHalfViewport = oldHalfViewport / newZoom * oldZoom;
Point oldCenter = scrollOffset + oldHalfViewport;
Point virtualMousePos = scrollOffset + new Vector(relMousePos.X * this.ViewportWidth, relMousePos.Y * this.ViewportHeight);
// As newCenter, we want to choose a point between oldCenter and virtualMousePos. The more we zoom in, the closer
// to virtualMousePos. We'll create the line x = oldCenter + lambda * (virtualMousePos-oldCenter).
// On this line, we need to choose lambda between -1 and 1:
// -1 = zoomed out completely
// 0 = zoom unchanged
// +1 = zoomed in completely
// But the zoom factor (newZoom/oldZoom) we have is in the range [0,+Infinity].
// Basically, I just played around until I found a function that maps this to [-1,1] and works well.
// "f" is squared because otherwise the mouse simply stays over virtualMousePos, but I wanted virtualMousePos
// to move towards the middle -> squaring f causes lambda to be closer to 1, giving virtualMousePos more weight
// then oldCenter.
double f = Math.Min(newZoom, oldZoom) / Math.Max(newZoom, oldZoom);
double lambda = 1 - f*f;
if (oldZoom > newZoom)
lambda = -lambda;
Point newCenter = oldCenter + lambda * (virtualMousePos - oldCenter);
scrollOffset = newCenter - newHalfViewport;
SetCurrentValue(CurrentZoomProperty, newZoom);
this.ScrollToHorizontalOffset(scrollOffset.X);
this.ScrollToVerticalOffset(scrollOffset.Y);
e.Handled = true;
}
base.OnMouseWheel(e);
}
internal static double RoundToOneIfClose(double val)
{
if (Math.Abs(val - 1.0) < 0.001)
return 1.0;
else
return val;
}
}
sealed class IsNormalZoomConverter : IValueConverter
{
public static readonly IsNormalZoomConverter Instance = new IsNormalZoomConverter();
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (parameter is bool && (bool)parameter)
return true;
return ((double)value) == 1.0;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

94
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ZoomScrollViewer.xaml

@ -0,0 +1,94 @@ @@ -0,0 +1,94 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls">
<Style TargetType="{x:Type Controls:ZoomScrollViewer}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Controls:ZoomScrollViewer}">
<Grid Background="{TemplateBinding Panel.Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Controls:SelfCollapsingPanel Grid.Column="0" Grid.Row="1" CollapseOrientation="Horizontal" CanCollapse="{Binding Path=ComputedZoomButtonCollapsed, Mode=OneWay, RelativeSource={RelativeSource Mode=TemplatedParent}}">
<Controls:ZoomButtons x:Name="zoomButtons" Value="{Binding Path=CurrentZoom, RelativeSource={RelativeSource Mode=TemplatedParent}}" Minimum="{TemplateBinding MinimumZoom}" Maximum="{TemplateBinding MaximumZoom}" />
</Controls:SelfCollapsingPanel>
<Rectangle Grid.Column="2" Grid.Row="1" Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
<ScrollContentPresenter Name="PART_Presenter" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Margin="{TemplateBinding Control.Padding}" Content="{TemplateBinding ContentControl.Content}" ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" CanContentScroll="{TemplateBinding ScrollViewer.CanContentScroll}">
<ScrollContentPresenter.LayoutTransform>
<ScaleTransform ScaleX="{Binding Path=CurrentZoom, RelativeSource={RelativeSource Mode=TemplatedParent}}" ScaleY="{Binding Path=CurrentZoom, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
</ScrollContentPresenter.LayoutTransform>
</ScrollContentPresenter>
<ScrollBar Name="PART_VerticalScrollBar" Grid.Column="2" Grid.Row="0" Minimum="0" Maximum="{TemplateBinding ScrollableHeight}" ViewportSize="{TemplateBinding ViewportHeight}" Value="{TemplateBinding VerticalOffset}" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" />
<ScrollBar Name="PART_HorizontalScrollBar" Orientation="Horizontal" Grid.Column="1" Grid.Row="1" Minimum="0" Maximum="{TemplateBinding ScrollableWidth}" ViewportSize="{TemplateBinding ViewportWidth}" Value="{TemplateBinding HorizontalOffset}" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ZoomButtonStyle"
TargetType="RepeatButton">
<Setter Property="Delay" Value="0" />
<Setter Property="Focusable" Value="False" />
<Setter Property="Opacity" Value="0.5" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RepeatButton">
<ContentPresenter />
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value="1" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type Controls:ZoomButtons}">
<Setter Property="Minimum" Value="0.2"/>
<Setter Property="Maximum" Value="10"/>
<Setter Property="Value" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Controls:ZoomButtons}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<StackPanel Orientation="Horizontal"
Background="#3000">
<RepeatButton x:Name="uxPlus"
Width="16" Height="16" Padding="0" BorderThickness="0"
Style="{StaticResource ZoomButtonStyle}">
<Image Source="Images/ZoomIn.png"
Stretch="Uniform"/>
</RepeatButton>
<RepeatButton x:Name="uxMinus"
Width="16" Height="16" Padding="0" BorderThickness="0"
Style="{StaticResource ZoomButtonStyle}">
<Image Source="Images/ZoomOut.png"
Stretch="Uniform" />
</RepeatButton>
<RepeatButton x:Name="uxReset"
Width="16" Height="16" Padding="0" BorderThickness="0"
Style="{StaticResource ZoomButtonStyle}">
<Border Background="#5000">
<TextBlock Foreground="White"
HorizontalAlignment="Center"
VerticalAlignment="Center">1</TextBlock>
</Border>
</RepeatButton>
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignPanel.cs

@ -219,6 +219,8 @@ namespace ICSharpCode.WpfDesign.Designer @@ -219,6 +219,8 @@ namespace ICSharpCode.WpfDesign.Designer
#region Properties
public DesignSurface DesignSurface { get; internal set; }
//Set custom HitTestFilterCallbak
public HitTestFilterCallback CustomHitTestFilterBehavior { get; set; }

7
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignSurface.cs

@ -76,14 +76,13 @@ namespace ICSharpCode.WpfDesign.Designer @@ -76,14 +76,13 @@ namespace ICSharpCode.WpfDesign.Designer
this.AddCommandHandler(Commands.AlignCenterCommand, () => ModelTools.ArrangeItems(this.DesignContext.Services.Selection.SelectedItems, ArrangeDirection.HorizontalMiddle), () => this.DesignContext.Services.Selection.SelectedItems.Count() > 1);
this.AddCommandHandler(Commands.AlignRightCommand, () => ModelTools.ArrangeItems(this.DesignContext.Services.Selection.SelectedItems, ArrangeDirection.Right), () => this.DesignContext.Services.Selection.SelectedItems.Count() > 1);
//Todo
//this.AddCommandHandler(Commands.RotateLeftCommand, () => , () => this.DesignContext.Services.Selection.SelectedItems.Count() > 1);
//this.AddCommandHandler(Commands.RotateRightCommand, () => , () => this.DesignContext.Services.Selection.SelectedItems.Count() > 1);
this.AddCommandHandler(Commands.RotateLeftCommand, () => ModelTools.ApplyTransform(this.DesignContext.Services.Selection.PrimarySelection, new RotateTransform(-90)), () => this.DesignContext.Services.Selection.PrimarySelection != null);
this.AddCommandHandler(Commands.RotateRightCommand, () => ModelTools.ApplyTransform(this.DesignContext.Services.Selection.PrimarySelection, new RotateTransform(90)), () => this.DesignContext.Services.Selection.PrimarySelection != null);
_sceneContainer = new Border() { AllowDrop = false, UseLayoutRounding = true };
_sceneContainer.SetValue(TextOptions.TextFormattingModeProperty, TextFormattingMode.Ideal);
_designPanel = new DesignPanel() {Child = _sceneContainer};
_designPanel = new DesignPanel() {Child = _sceneContainer, DesignSurface = this};
}
internal DesignPanel _designPanel;

3
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignSurface.xaml

@ -1,10 +1,9 @@ @@ -1,10 +1,9 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/netfx/2007/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Default="clr-namespace:ICSharpCode.WpfDesign.Designer"
xmlns:Controls="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls"
xmlns:Designer="clr-namespace:ICSharpCode.WpfDesign.Designer"
xmlns:Widgets="http://icsharpcode.net/sharpdevelop/widgets">
xmlns:Widgets="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls">
<Style TargetType="{x:Type Designer:DesignSurface}">
<Setter Property="Template">
<Setter.Value>

5
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/CanvasPlacementSupport.cs

@ -147,6 +147,11 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions @@ -147,6 +147,11 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
info.Item.Properties[FrameworkElement.HorizontalAlignmentProperty].Reset();
info.Item.Properties[FrameworkElement.VerticalAlignmentProperty].Reset();
info.Item.Properties[FrameworkElement.MarginProperty].Reset();
if (operation.Type == PlacementType.PasteItem) {
info.Item.Properties.GetAttachedProperty(Canvas.LeftProperty).SetValue(((double)info.Item.Properties.GetAttachedProperty(Canvas.LeftProperty).ValueOnInstance) + PlacementOperation.PasteOffset);
info.Item.Properties.GetAttachedProperty(Canvas.TopProperty).SetValue(((double)info.Item.Properties.GetAttachedProperty(Canvas.TopProperty).ValueOnInstance) + PlacementOperation.PasteOffset);
}
}
}

7
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/DefaultPlacementBehavior.cs

@ -63,8 +63,11 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions @@ -63,8 +63,11 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
{
InfoTextEnterArea.Stop(ref infoTextEnterArea);
this.ExtendedItem.Services.Selection.SetSelectedComponents(null);
this.ExtendedItem.Services.Selection.SetSelectedComponents(operation.PlacedItems.Select(x => x.Item).ToList());
if (operation.Type != PlacementType.Delete)
{
this.ExtendedItem.Services.Selection.SetSelectedComponents(null);
this.ExtendedItem.Services.Selection.SetSelectedComponents(operation.PlacedItems.Select(x => x.Item).ToList());
}
}
public virtual Rect GetPosition(PlacementOperation operation, DesignItem item)

20
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/GridPlacementSupport.cs

@ -162,6 +162,26 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions @@ -162,6 +162,26 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
enteredIntoNewContainer=true;
grid.UpdateLayout();
base.EnterContainer(operation);
if (operation.Type == PlacementType.PasteItem) {
foreach (PlacementInformation info in operation.PlacedItems) {
var margin = (Thickness)info.Item.Properties.GetProperty(FrameworkElement.MarginProperty).ValueOnInstance;
var horizontalAlignment = (HorizontalAlignment)info.Item.Properties.GetProperty(FrameworkElement.HorizontalAlignmentProperty).ValueOnInstance;
var verticalAlignment = (VerticalAlignment)info.Item.Properties.GetProperty(FrameworkElement.VerticalAlignmentProperty).ValueOnInstance;
if (horizontalAlignment == HorizontalAlignment.Left)
margin.Left += PlacementOperation.PasteOffset;
else if (horizontalAlignment == HorizontalAlignment.Right)
margin.Right -= PlacementOperation.PasteOffset;
if (verticalAlignment == VerticalAlignment.Top)
margin.Top += PlacementOperation.PasteOffset;
else if (verticalAlignment == VerticalAlignment.Bottom)
margin.Bottom -= PlacementOperation.PasteOffset;
info.Item.Properties.GetProperty(FrameworkElement.MarginProperty).SetValue(margin);
}
}
}
GrayOutDesignerExceptActiveArea grayOut;

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/LineExtensionBase.cs

@ -107,7 +107,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions @@ -107,7 +107,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
/// <param name="alignment"></param>
/// <param name="index">if using a polygon or multipoint adorner this is the index of the point in the Points array</param>
/// <returns></returns>
protected PointTrackerPlacementSupport Place(ref DesignerThumb designerThumb, PlacementAlignment alignment, int index = -1)
protected PointTrackerPlacementSupport Place(DesignerThumb designerThumb, PlacementAlignment alignment, int index = -1)
{
PointTrackerPlacementSupport placement = new PointTrackerPlacementSupport(ExtendedItem.View as Shape, alignment, index);
return placement;

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/LineHandlerExtension.cs

@ -56,7 +56,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions @@ -56,7 +56,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
protected DesignerThumb CreateThumb(PlacementAlignment alignment, Cursor cursor)
{
DesignerThumb designerThumb = new DesignerThumb { Alignment = alignment, Cursor = cursor, IsPrimarySelection = true};
AdornerPanel.SetPlacement(designerThumb, Place(ref designerThumb, alignment));
AdornerPanel.SetPlacement(designerThumb, Place(designerThumb, alignment));
adornerPanel.Children.Add(designerThumb);

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PolyLineHandlerExtension.cs

@ -49,7 +49,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions @@ -49,7 +49,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
protected DesignerThumb CreateThumb(PlacementAlignment alignment, Cursor cursor, int index)
{
DesignerThumb designerThumb = new MultiPointThumb { Index = index, Alignment = alignment, Cursor = cursor, IsPrimarySelection = true };
AdornerPlacement ap = Place(ref designerThumb, alignment, index);
AdornerPlacement ap = Place(designerThumb, alignment, index);
(designerThumb as MultiPointThumb).AdornerPlacement = ap;
AdornerPanel.SetPlacement(designerThumb, ap);

3
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/QuickOperationMenuExtension.cs

@ -20,8 +20,7 @@ using System; @@ -20,8 +20,7 @@ using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using ICSharpCode.SharpDevelop.Widgets;
using System.Windows.Media;
using ICSharpCode.WpfDesign.Designer.Controls;
using ICSharpCode.WpfDesign.Extensions;
using ICSharpCode.WpfDesign.Adorners;

32
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/RotateThumbExtension.cs

@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
using System;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
@ -116,29 +117,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions @@ -116,29 +117,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
if (!Keyboard.IsKeyDown(Key.LeftCtrl))
destAngle = ((int)destAngle / 15) * 15;
if (destAngle == 0)
{
this.ExtendedItem.Properties.GetProperty(FrameworkElement.RenderTransformProperty).Reset();
rtTransform = null;
rotateTransform = null;
}
else
{
if ((rtTransform == null) || !(rtTransform.Component is RotateTransform))
{
if (!this.ExtendedItem.Properties.GetProperty(FrameworkElement.RenderTransformOriginProperty).IsSet) {
this.ExtendedItem.Properties.GetProperty(FrameworkElement.RenderTransformOriginProperty).SetValue(new Point(0.5,0.5));
}
if (this.rotateTransform == null)
this.rotateTransform = new RotateTransform(0);
this.ExtendedItem.Properties.GetProperty(FrameworkElement.RenderTransformProperty).SetValue(rotateTransform);
rtTransform = this.ExtendedItem.Properties[FrameworkElement.RenderTransformProperty].Value;
}
rtTransform.Properties["Angle"].SetValue(destAngle);
((DesignPanel) this.ExtendedItem.Services.DesignPanel).AdornerLayer.UpdateAdornersForElement(this.ExtendedItem.View, true);
}
ModelTools.ApplyTransform(this.ExtendedItem, new RotateTransform() { Angle = destAngle });
}
void drag_Rotate_Completed(ICSharpCode.WpfDesign.Designer.Controls.DragListener drag)
@ -161,6 +140,13 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions @@ -161,6 +140,13 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
var designerItem = this.ExtendedItem.Component as FrameworkElement;
this.rotateTransform = designerItem.RenderTransform as RotateTransform;
if (this.rotateTransform == null) {
var tg = designerItem.RenderTransform as TransformGroup;
if (tg != null) {
this.rotateTransform = tg.Children.FirstOrDefault(x => x is RotateTransform) as RotateTransform;
}
}
}
void OnPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)

245
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/UserControlPointsObjectExtension.cs

@ -0,0 +1,245 @@ @@ -0,0 +1,245 @@
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Windows;
using ICSharpCode.WpfDesign.Extensions;
using ICSharpCode.WpfDesign.Adorners;
using ICSharpCode.WpfDesign.Designer.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Controls;
using ICSharpCode.WpfDesign.UIExtensions;
namespace ICSharpCode.WpfDesign.Designer.Extensions
{
/// <summary>
/// Description of UserControlPointsObjectExtension.
/// </summary>
//[ExtensionFor(typeof(Line), OverrideExtensions = new Type[] { typeof(ResizeThumbExtension), typeof(SelectedElementRectangleExtension), typeof(CanvasPositionExtension), typeof(QuickOperationMenuExtension), typeof(RotateThumbExtension), typeof(RenderTransformOriginExtension), typeof(InPlaceEditorExtension), typeof(SkewThumbExtension) })]
public abstract class UserControlPointsObjectExtension : LineExtensionBase
{
/// <summary>
/// Used instead of Rect to allow negative values on "Width" and "Height" (here called X and Y).
/// </summary>
class Bounds
{
public double X, Y, Left, Top;
}
//
private double CurrentX2;
private double CurrentY2;
private double CurrentLeft;
private double CurrentTop;
private IEnumerable<DependencyProperty> _thumbProperties;
//Size oldSize;
ZoomControl zoom;
public DragListener DragListener {get; private set;}
protected UserControlPointsObjectThumb CreateThumb(PlacementAlignment alignment, Cursor cursor, DependencyProperty property)
{
var designerThumb = new UserControlPointsObjectThumb { Alignment = alignment, Cursor = cursor, IsPrimarySelection = true, DependencyProperty = property};
AdornerPanel.SetPlacement(designerThumb, Place(designerThumb, alignment));
adornerPanel.Children.Add(designerThumb);
DragListener = new DragListener(designerThumb);
DragListener.Started += drag_Started;
DragListener.Changed += drag_Changed;
DragListener.Completed += drag_Completed;
return designerThumb;
}
Bounds CalculateDrawing(double x, double y, double left, double top, double xleft, double xtop)
{
Double theta = (180 / Math.PI) * Math.Atan2(y, x);
double verticaloffset = Math.Abs(90 - Math.Abs(theta));
if (Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt))
{
if (Math.Abs(theta) < 45 || Math.Abs(theta) > 135)
{
y = 0;
top = xtop;
}
else if (verticaloffset < 45)
{
x = 0;
left = xleft;
}
}
else if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
{
if (verticaloffset < 10)
{
x = 0;
left = xleft;
}
else if (Math.Abs(theta) < 10 || Math.Abs(theta) > 170)
{
y = 0;
top = xtop;
}
}
SetSurfaceInfo(0, 3, Math.Round((180 / Math.PI) * Math.Atan2(y, x), 0).ToString());
return new Bounds { X = Math.Round(x, 1), Y = Math.Round(y, 1), Left = Math.Round(left, 1), Top = Math.Round(top, 1) };
}
#region eventhandlers
protected virtual void drag_Started(DragListener drag)
{
Line al = ExtendedItem.View as Line;
CurrentX2 = al.X2;
CurrentY2 = al.Y2;
CurrentLeft = (double)al.GetValue(Canvas.LeftProperty);
CurrentTop = (double)al.GetValue(Canvas.TopProperty);
var designPanel = ExtendedItem.Services.DesignPanel as DesignPanel;
zoom = designPanel.TryFindParent<ZoomControl>();
if (resizeBehavior != null)
operation = PlacementOperation.Start(extendedItemArray, PlacementType.Resize);
else
{
changeGroup = this.ExtendedItem.Context.OpenGroup("Resize", extendedItemArray);
}
_isResizing = true;
(drag.Target as UserControlPointsObjectThumb).IsPrimarySelection = false;
}
protected virtual void drag_Changed(DragListener drag)
{
Line al = ExtendedItem.View as Line;
var alignment = (drag.Target as UserControlPointsObjectThumb).Alignment;
var info = operation.PlacedItems[0];
double dx = 0;
double dy = 0;
if (zoom != null) {
dx = drag.Delta.X * (1 / zoom.CurrentZoom);
dy = drag.Delta.Y * (1 / zoom.CurrentZoom);
}
double top, left, x, y, xtop, xleft;
if (alignment == PlacementAlignment.TopLeft) {
//normal values
x = CurrentX2 - dx;
y = CurrentY2 - dy;
top = CurrentTop + dy;
left = CurrentLeft + dx;
//values to use when keys are pressed
xtop = CurrentTop + CurrentY2;
xleft = CurrentLeft + CurrentX2;
} else {
x = CurrentX2 + dx;
y = CurrentY2 + dy;
top = xtop = CurrentTop;
left = xleft = CurrentLeft;
}
Bounds position = CalculateDrawing(x, y, left, top, xleft, xtop);
ExtendedItem.Properties.GetProperty(Line.X1Property).SetValue(0);
ExtendedItem.Properties.GetProperty(Line.Y1Property).SetValue(0);
ExtendedItem.Properties.GetProperty(Line.X2Property).SetValue(position.X);
ExtendedItem.Properties.GetProperty(Line.Y2Property).SetValue(position.Y);
if (operation != null) {
var result = info.OriginalBounds;
result.X = position.Left;
result.Y = position.Top;
result.Width = Math.Abs(position.X);
result.Height = Math.Abs(position.Y);
info.Bounds = result.Round();
operation.CurrentContainerBehavior.BeforeSetPosition(operation);
operation.CurrentContainerBehavior.SetPosition(info);
}
(drag.Target as UserControlPointsObjectThumb).InvalidateArrange();
ResetWidthHeightProperties();
}
protected virtual void drag_Completed(DragListener drag)
{
if (operation != null)
{
if (drag.IsCanceled) operation.Abort();
else
{
ResetWidthHeightProperties();
operation.Commit();
}
operation = null;
}
else
{
if (drag.IsCanceled)
changeGroup.Abort();
else
changeGroup.Commit();
changeGroup = null;
}
_isResizing = false;
(drag.Target as UserControlPointsObjectThumb).IsPrimarySelection = true;
HideSizeAndShowHandles();
}
#endregion
/// <summary>
/// is invoked whenever a line is selected on the canvas, remember that the adorners are created for each line object and never destroyed
/// </summary>
protected override void OnInitialized()
{
base.OnInitialized();
FillThumbProperties();
foreach (var prp in _thumbProperties) {
CreateThumb(PlacementAlignment.Center, Cursors.Cross, prp);
}
extendedItemArray[0] = this.ExtendedItem;
Invalidate();
this.ExtendedItem.PropertyChanged += OnPropertyChanged;
resizeBehavior = PlacementOperation.GetPlacementBehavior(extendedItemArray);
UpdateAdornerVisibility();
}
protected abstract IEnumerable<DependencyProperty> FillThumbProperties();
}
}

5
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/FocusNavigator.cs

@ -15,11 +15,10 @@ @@ -15,11 +15,10 @@
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Linq;
using System.Windows.Input;
using ICSharpCode.SharpDevelop.Widgets;
using ICSharpCode.WpfDesign.Designer.Controls;
namespace ICSharpCode.WpfDesign.Designer
{

69
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/MarkupExtensions/DesignItemBinding.cs

@ -43,6 +43,12 @@ namespace ICSharpCode.WpfDesign.Designer.MarkupExtensions @@ -43,6 +43,12 @@ namespace ICSharpCode.WpfDesign.Designer.MarkupExtensions
public bool SingleItemProperty { get; set; }
public bool AskWhenMultipleItemsSelected { get; set; }
public IValueConverter Converter { get; set; }
public object ConverterParameter { get; set; }
public UpdateSourceTrigger UpdateSourceTrigger { get; set; }
public DesignItemBinding(string path)
@ -50,6 +56,7 @@ namespace ICSharpCode.WpfDesign.Designer.MarkupExtensions @@ -50,6 +56,7 @@ namespace ICSharpCode.WpfDesign.Designer.MarkupExtensions
this._propertyName = path;
UpdateSourceTrigger = UpdateSourceTrigger.Default;
AskWhenMultipleItemsSelected = true;
}
public override object ProvideValue(IServiceProvider serviceProvider)
@ -63,22 +70,44 @@ namespace ICSharpCode.WpfDesign.Designer.MarkupExtensions @@ -63,22 +70,44 @@ namespace ICSharpCode.WpfDesign.Designer.MarkupExtensions
return null;
}
public void CreateBindingOnProperty(DependencyProperty targetProperty, FrameworkElement targetObject)
{
_targetProperty = targetProperty;
_targetObject = targetObject;
_targetObject.DataContextChanged += targetObject_DataContextChanged;
targetObject_DataContextChanged(_targetObject, new DependencyPropertyChangedEventArgs());
}
void targetObject_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
var ctx = ((FrameworkElement) sender).DataContext as FrameworkElement;
var surface = ctx.TryFindParent<DesignSurface>();
var dcontext = ((FrameworkElement) sender).DataContext;
DesignContext context = null;
FrameworkElement fe = null;
DesignItem designItem = null;
if (dcontext is DesignItem) {
designItem = (DesignItem)dcontext;
context = designItem.Context;
fe = designItem.View as FrameworkElement;
} else if (dcontext is FrameworkElement) {
fe = ((FrameworkElement)dcontext);
var srv = fe.TryFindParent<DesignSurface>();
if (srv != null) {
context = srv.DesignContext;
designItem = context.Services.Component.GetDesignItem(fe);
}
}
if (surface != null)
if (context != null)
{
_binding = new Binding(_propertyName);
_binding.Source = ctx;
_binding.Source = fe;
_binding.UpdateSourceTrigger = UpdateSourceTrigger;
_binding.Mode = BindingMode.TwoWay;
_binding.ConverterParameter = ConverterParameter;
var designItem = surface.DesignContext.Services.Component.GetDesignItem(ctx);
_converter = new DesignItemSetConverter(designItem, _propertyName, SingleItemProperty);
_converter = new DesignItemSetConverter(designItem, _propertyName, SingleItemProperty, AskWhenMultipleItemsSelected, Converter);
_binding.Converter = _converter;
_targetObject.SetBinding(_targetProperty, _binding);
@ -94,33 +123,47 @@ namespace ICSharpCode.WpfDesign.Designer.MarkupExtensions @@ -94,33 +123,47 @@ namespace ICSharpCode.WpfDesign.Designer.MarkupExtensions
private DesignItem _designItem;
private string _property;
private bool _singleItemProperty;
private bool _askWhenMultipleItemsSelected;
private IValueConverter _converter;
public DesignItemSetConverter(DesignItem desigItem, string property, bool singleItemProperty)
public DesignItemSetConverter(DesignItem desigItem, string property, bool singleItemProperty, bool askWhenMultipleItemsSelected, IValueConverter converter)
{
this._designItem = desigItem;
this._property = property;
this._singleItemProperty = singleItemProperty;
this._converter = converter;
this._askWhenMultipleItemsSelected = askWhenMultipleItemsSelected;
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (_converter != null)
return _converter.Convert(value, targetType, parameter, culture);
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
var val = value;
if (_converter != null)
val = _converter.ConvertBack(value, targetType, parameter, culture);
var changeGroup = _designItem.OpenGroup("Property: " + _property);
try
{
var property = _designItem.Properties.GetProperty(_property);
property.SetValue(value);
property.SetValue(val);
if (!_singleItemProperty && _designItem.Services.Selection.SelectedItems.Count > 1)
{
var msg = MessageBox.Show("Apply changes to all selected Items","", MessageBoxButton.YesNo);
var msg = MessageBoxResult.Yes;
if (_askWhenMultipleItemsSelected) {
msg = MessageBox.Show("Apply changes to all selected Items","", MessageBoxButton.YesNo);
}
if (msg == MessageBoxResult.Yes)
{
foreach (var item in _designItem.Services.Selection.SelectedItems)
@ -132,7 +175,7 @@ namespace ICSharpCode.WpfDesign.Designer.MarkupExtensions @@ -132,7 +175,7 @@ namespace ICSharpCode.WpfDesign.Designer.MarkupExtensions
catch(Exception)
{ }
if (property != null)
property.SetValue(value);
property.SetValue(val);
}
}
}
@ -144,7 +187,7 @@ namespace ICSharpCode.WpfDesign.Designer.MarkupExtensions @@ -144,7 +187,7 @@ namespace ICSharpCode.WpfDesign.Designer.MarkupExtensions
changeGroup.Abort();
}
return value;
return val;
}
}
}

89
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/ModelTools.cs

@ -113,6 +113,12 @@ namespace ICSharpCode.WpfDesign.Designer @@ -113,6 +113,12 @@ namespace ICSharpCode.WpfDesign.Designer
foreach (var designItem in items) {
designItem.Name = null;
}
var service = parent.Services.Component as XamlComponentService;
foreach (var item in items) {
service.RaiseComponentRemoved(item);
}
operation.DeleteItemsAndCommit();
} catch {
operation.Abort();
@ -344,6 +350,89 @@ namespace ICSharpCode.WpfDesign.Designer @@ -344,6 +350,89 @@ namespace ICSharpCode.WpfDesign.Designer
return new Tuple<DesignItem, Rect>(newPanel, new Rect(xmin, ymin, xmax - xmin, ymax - ymin).Round());
}
public static void ApplyTransform(DesignItem designItem, Transform transform, bool relative = true)
{
var changeGroup = designItem.OpenGroup("Apply Transform");
Transform oldTransform = null;
if (designItem.Properties.GetProperty(FrameworkElement.RenderTransformProperty).IsSet) {
oldTransform = designItem.Properties.GetProperty(FrameworkElement.RenderTransformProperty).ValueOnInstance as Transform;
}
if (oldTransform is MatrixTransform) {
var mt = oldTransform as MatrixTransform;
var tg = new TransformGroup();
if (mt.Matrix.OffsetX != 0 && mt.Matrix.OffsetY != 0)
tg.Children.Add(new TranslateTransform(){ X = mt.Matrix.OffsetX, Y = mt.Matrix.OffsetY });
if (mt.Matrix.M11 != 0 && mt.Matrix.M22 != 0)
tg.Children.Add(new ScaleTransform(){ ScaleX = mt.Matrix.M11, ScaleY = mt.Matrix.M22 });
var angle = Math.Atan2(mt.Matrix.M21, mt.Matrix.M11) * 180 / Math.PI;
if (angle != 0)
tg.Children.Add(new RotateTransform(){ Angle = angle });
//if (mt.Matrix.M11 != 0 && mt.Matrix.M22 != 0)
// tg.Children.Add(new SkewTransform(){ ScaleX = mt.Matrix.M11, ScaleY = mt.Matrix.M22 });
} else if (oldTransform != null && oldTransform.GetType() != transform.GetType()) {
var tg = new TransformGroup();
var tgDes = designItem.Services.Component.RegisterComponentForDesigner(tg);
tgDes.ContentProperty.CollectionElements.Add(designItem.Services.Component.GetDesignItem(oldTransform));
designItem.Properties.GetProperty(FrameworkElement.RenderTransformProperty).SetValue(tg);
oldTransform = tg;
}
if (transform is RotateTransform) {
var rotateTransform = transform as RotateTransform;
if (oldTransform is RotateTransform || oldTransform == null) {
if (rotateTransform.Angle != 0) {
designItem.Properties.GetProperty(FrameworkElement.RenderTransformProperty).SetValue(transform);
var angle = rotateTransform.Angle;
if (relative && oldTransform != null) {
angle = rotateTransform.Angle + ((RotateTransform)oldTransform).Angle;
}
designItem.Properties.GetProperty(FrameworkElement.RenderTransformProperty).Value.Properties.GetProperty(RotateTransform.AngleProperty).SetValue(angle);
if (rotateTransform.CenterX != 0.0)
designItem.Properties.GetProperty(FrameworkElement.RenderTransformProperty).Value.Properties.GetProperty(RotateTransform.CenterXProperty).SetValue(rotateTransform.CenterX);
if (rotateTransform.CenterY != 0.0)
designItem.Properties.GetProperty(FrameworkElement.RenderTransformProperty).Value.Properties.GetProperty(RotateTransform.CenterYProperty).SetValue(rotateTransform.CenterY);
if (oldTransform == null)
designItem.Properties.GetProperty(FrameworkElement.RenderTransformOriginProperty).SetValue(new Point(0.5, 0.5));
}
else {
designItem.Properties.GetProperty(FrameworkElement.RenderTransformProperty).Reset();
designItem.Properties.GetProperty(FrameworkElement.RenderTransformOriginProperty).Reset();
}
} else if (oldTransform is TransformGroup) {
var tg = oldTransform as TransformGroup;
var rot = tg.Children.FirstOrDefault(x=> x is RotateTransform);
if (rot != null) {
designItem.Services.Component.GetDesignItem(tg).ContentProperty.CollectionElements.Remove(designItem.Services.Component.GetDesignItem(rot));
}
if (rotateTransform.Angle != 0) {
var des = designItem.Services.Component.GetDesignItem(transform);
if (des == null)
des = designItem.Services.Component.RegisterComponentForDesigner(transform);
designItem.Services.Component.GetDesignItem(tg).ContentProperty.CollectionElements.Add(des);
if (oldTransform == null)
designItem.Properties.GetProperty(FrameworkElement.RenderTransformOriginProperty).SetValue(new Point(0.5, 0.5));
}
} else {
if (rotateTransform.Angle != 0) {
designItem.Properties.GetProperty(FrameworkElement.RenderTransformProperty).SetValue(transform);
if (oldTransform == null)
designItem.Properties.GetProperty(FrameworkElement.RenderTransformOriginProperty).SetValue(new Point(0.5, 0.5));
}
}
}
((DesignPanel) designItem.Services.DesignPanel).AdornerLayer.UpdateAdornersForElement(designItem.View, true);
changeGroup.Commit();
}
public static void ArrangeItems(IEnumerable<DesignItem> items, ArrangeDirection arrangeDirection)
{

4
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/PropertyGrid/Editors/BrushEditor/BrushEditorView.xaml

@ -2,11 +2,9 @@ @@ -2,11 +2,9 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Designer="clr-namespace:ICSharpCode.WpfDesign.Designer"
xmlns:Controls="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls"
xmlns:BrushEditor="clr-namespace:ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.BrushEditor"
xmlns:Converters="clr-namespace:ICSharpCode.WpfDesign.Designer.Converters"
xmlns:PropertyGrid="clr-namespace:ICSharpCode.WpfDesign.Designer.PropertyGrid"
xmlns:widgets="http://icsharpcode.net/sharpdevelop/widgets"
xmlns:widgets="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls"
Width="395" MinHeight="320">
<UserControl.Resources>

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/PropertyGrid/Editors/BrushEditor/SolidBrushEditor.xaml

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
<UserControl x:Class="ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.BrushEditor.SolidBrushEditor"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:widgets="http://icsharpcode.net/sharpdevelop/widgets"
xmlns:widgets="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls"
x:Name="this"
Height="320">
<TabControl>

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/PropertyGrid/Editors/NumberEditor.xaml

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
<widgets:NumericUpDown x:Class="ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors.NumberEditor"
xmlns="http://schemas.microsoft.com/netfx/2007/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:widgets="http://icsharpcode.net/sharpdevelop/widgets"
xmlns:widgets="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls"
xmlns:Converters="clr-namespace:ICSharpCode.WpfDesign.Designer.Converters"
BorderThickness="0"
Background="{x:Null}"

31
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj

@ -88,6 +88,8 @@ @@ -88,6 +88,8 @@
</Compile>
<Compile Include="ArrangeDirection.cs" />
<Compile Include="Commands.cs" />
<Compile Include="Controls\Picker.cs" />
<Compile Include="Controls\Thumbs\UserControlPointsObjectThumb.cs" />
<Compile Include="Controls\NullableComboBox.cs" />
<Compile Include="Controls\RenderTransformOriginThumb.cs" />
<Compile Include="Controls\Thumbs\PointThumb.cs" />
@ -131,6 +133,7 @@ @@ -131,6 +133,7 @@
<Compile Include="Extensions\ArrangeItemsContextMenu.xaml.cs">
<DependentUpon>ArrangeItemsContextMenu.xaml</DependentUpon>
</Compile>
<Compile Include="Extensions\UserControlPointsObjectExtension.cs" />
<Compile Include="Extensions\WrapItemContextMenu.xaml.cs">
<DependentUpon>WrapItemContextMenu.xaml</DependentUpon>
</Compile>
@ -312,6 +315,13 @@ @@ -312,6 +315,13 @@
<Compile Include="Services\XamlErrorService.cs" />
<Compile Include="SharedInstances.cs" />
<Compile Include="ThumbnailView\ThumbnailView.cs" />
<Compile Include="Controls\CollapsiblePanel.cs" />
<Compile Include="Controls\ColorHelper.cs" />
<Compile Include="Controls\ColorPicker.xaml.cs" />
<Compile Include="Controls\NumericUpDown.cs" />
<Compile Include="Controls\RelayCommand.cs" />
<Compile Include="Controls\ZoomButtons.cs" />
<Compile Include="Controls\ZoomScrollViewer.cs" />
<Compile Include="Xaml\XamlEditOperations.cs" />
<Compile Include="Xaml\XamlLoadSettings.cs" />
<Compile Include="Xaml\XamlModelCollectionElementsCollection.cs" />
@ -359,11 +369,18 @@ @@ -359,11 +369,18 @@
</Page>
<Page Include="PropertyGrid\Editors\TimeSpanEditor.xaml" />
<Page Include="ThumbnailView\ThumbnailView.xaml" />
<ProjectReference Include="..\..\..\..\..\Main\ICSharpCode.SharpDevelop.Widgets\Project\ICSharpCode.SharpDevelop.Widgets.csproj">
<Project>{8035765F-D51F-4A0C-A746-2FD100E19419}</Project>
<Name>ICSharpCode.SharpDevelop.Widgets</Name>
<Private>False</Private>
</ProjectReference>
<Page Include="Controls\ColorPicker.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Controls\NumericUpDown.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Controls\ZoomScrollViewer.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<ProjectReference Include="..\..\WpfDesign.XamlDom\Project\WpfDesign.XamlDom.csproj">
<Project>{88DA149F-21B2-48AB-82C4-28FB6BDFD783}</Project>
<Name>WpfDesign.XamlDom</Name>
@ -521,7 +538,5 @@ @@ -521,7 +538,5 @@
<Resource Include="Images\Icons.16x16.RedoIcon.png" />
<Resource Include="Images\Icons.16x16.UndoIcon.png" />
</ItemGroup>
<ItemGroup>
<Folder Include="MarkupExtensions" />
</ItemGroup>
<ItemGroup />
</Project>

13
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlComponentService.cs

@ -56,6 +56,8 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml @@ -56,6 +56,8 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
public event EventHandler<DesignItemEventArgs> ComponentRegistered;
public event EventHandler<DesignItemEventArgs> ComponentRemoved;
// TODO: this must not be a dictionary because there's no way to unregister components
// however, this isn't critical because our design items will stay alive for the lifetime of the
// designer anyway if we don't limit the Undo stack.
@ -164,5 +166,16 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml @@ -164,5 +166,16 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
ev(this, new DesignItemPropertyChangedEventArgs(property.DesignItem, property));
}
}
/// <summary>
/// raises the RaiseComponentRemoved Event
/// </summary>
internal void RaiseComponentRemoved(DesignItem item)
{
var ev = this.ComponentRemoved;
if (ev != null) {
ev(this, new DesignItemEventArgs(item));
}
}
}
}

4
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlDesignItem.cs

@ -260,6 +260,10 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml @@ -260,6 +260,10 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
get { return _properties; }
}
public override IEnumerable<DesignItemProperty> AllSetProperties {
get { return _xamlObject.Properties.Select(x => new XamlModelProperty(this, x)); }
}
internal void NotifyPropertyChanged(XamlModelProperty property)
{
Debug.Assert(property != null);

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlEditOperations.cs

@ -179,7 +179,7 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml @@ -179,7 +179,7 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
var operation = PlacementOperation.TryStartInsertNewComponents(parent, pastedItems, rects.ToList(), PlacementType.PasteItem);
ISelectionService selection = _context.Services.Selection;
selection.SetSelectedComponents(pastedItems);
if(operation!=null)
if(operation != null)
operation.Commit();
}
}

38
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelCollectionElementsCollection.cs

@ -180,7 +180,7 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml @@ -180,7 +180,7 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
void RemoveInternal(int index, XamlDesignItem item)
{
NameScopeHelper.NameChanged(item.XamlObject, item.Name, null);
RemoveFromNamescopeRecursive(item);
Debug.Assert(property.CollectionElements[index] == item.XamlObject);
property.CollectionElements.RemoveAt(index);
@ -196,7 +196,41 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml @@ -196,7 +196,41 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
if (CollectionChanged != null)
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index));
NameScopeHelper.NameChanged(item.XamlObject, null, item.Name);
AddToNamescopeRecursive(item);
}
private static void RemoveFromNamescopeRecursive(XamlDesignItem designItem)
{
NameScopeHelper.NameChanged(designItem.XamlObject, designItem.Name, null);
foreach (var p in designItem.Properties)
{
if (p.Value != null) {
RemoveFromNamescopeRecursive((XamlDesignItem)p.Value);
}
else if (p.IsCollection && p.CollectionElements != null) {
foreach (var c in p.CollectionElements) {
RemoveFromNamescopeRecursive((XamlDesignItem)c);
}
}
}
}
private static void AddToNamescopeRecursive(XamlDesignItem designItem)
{
NameScopeHelper.NameChanged(designItem.XamlObject, null, designItem.Name);
foreach (var p in designItem.Properties)
{
if (p.Value != null) {
AddToNamescopeRecursive((XamlDesignItem)p.Value);
}
else if (p.IsCollection && p.CollectionElements != null) {
foreach (var c in p.CollectionElements) {
AddToNamescopeRecursive((XamlDesignItem)c);
}
}
}
}
sealed class InsertAction : ITransactionItem

7
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelPropertyCollection.cs

@ -24,6 +24,8 @@ using System.Collections.Generic; @@ -24,6 +24,8 @@ using System.Collections.Generic;
namespace ICSharpCode.WpfDesign.Designer.Xaml
{
using System.Linq;
sealed class XamlModelPropertyCollection : DesignItemPropertyCollection
{
XamlDesignItem _item;
@ -51,7 +53,10 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml @@ -51,7 +53,10 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
public override System.Collections.Generic.IEnumerator<DesignItemProperty> GetEnumerator()
{
yield break;
foreach (var value in propertiesDictionary.Values)
{
yield return value;
}
}
}
}

4
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/themes/generic.xaml

@ -10,5 +10,7 @@ @@ -10,5 +10,7 @@
<v:VersionedAssemblyResourceDictionary RelativePath="DesignSurface.xaml" />
<v:VersionedAssemblyResourceDictionary RelativePath="PropertyGrid/PropertyGridView.xaml" />
<v:VersionedAssemblyResourceDictionary RelativePath="ThumbnailView/ThumbnailView.xaml" />
</ResourceDictionary.MergedDictionaries>
<v:VersionedAssemblyResourceDictionary RelativePath="Controls/ZoomScrollViewer.xaml" />
<v:VersionedAssemblyResourceDictionary RelativePath="Controls/NumericUpDown.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

9
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/EditOperationTests.cs

@ -254,7 +254,7 @@ namespace ICSharpCode.WpfDesign.Tests.Designer @@ -254,7 +254,7 @@ namespace ICSharpCode.WpfDesign.Tests.Designer
xamlContext.XamlEditAction.Paste();
string expectedXaml = "<Button />\n" +
"<sdtcontrols:CustomButton>\n" +
"<sdtcontrols:CustomButton Margin=\"0,0,0,0\">\n" +
" <sdtcontrols:CustomButton.Tag>\n" +
" <Controls0:MyExtension>\n" +
" <Controls0:MyExtension.MyProperty1>\n" +
@ -315,6 +315,13 @@ namespace ICSharpCode.WpfDesign.Tests.Designer @@ -315,6 +315,13 @@ namespace ICSharpCode.WpfDesign.Tests.Designer
selection.SetSelectedComponents(new[] {grid});
xamlContext.XamlEditAction.Paste();
// Verify xaml document to be copied
expectedXaml = "<Grid.Resources>\n" +
" <Controls0:ExampleClass x:Key=\"res1\" />\n" +
"</Grid.Resources>\n" +
"<Button />\n" +
"<sdtcontrols:CustomButton Tag=\"{StaticResource res1}\" Margin=\"0,0,0,0\" />\n";
AssertGridDesignerOutput(expectedXaml, grid.Context,
"xmlns:Controls0=\"clr-namespace:ICSharpCode.WpfDesign.Tests.Designer;assembly=ICSharpCode.WpfDesign.Tests\"",
"xmlns:sdtcontrols=\"http://sharpdevelop.net/WpfDesign/Tests/Controls\"");

62
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/ModelTests.cs

@ -895,6 +895,52 @@ namespace ICSharpCode.WpfDesign.Tests.Designer @@ -895,6 +895,52 @@ namespace ICSharpCode.WpfDesign.Tests.Designer
AssertLog("");
}
[Test]
public void AddBindingWithStaticResourceToMultiBinding()
{
DesignItem textBox = CreateCanvasContext("<TextBox/>");
DesignItem canvasItem = textBox.Parent;
DesignItemProperty canvasResources = canvasItem.Properties.GetProperty("Resources");
DesignItem exampleClassItem = textBox.Services.Component.RegisterComponentForDesigner(new ICSharpCode.WpfDesign.Tests.XamlDom.ExampleClass());
exampleClassItem.Key = "testKey";
exampleClassItem.Properties["StringProp"].SetValue("String value");
canvasResources.CollectionElements.Add(exampleClassItem);
DesignItem multiBindingItem = textBox.Context.Services.Component.RegisterComponentForDesigner(new MultiBinding());
multiBindingItem.Properties["Converter"].SetValue(new ReturnFirstValueMultiConverter());
DesignItemProperty bindingsProp = multiBindingItem.ContentProperty;
DesignItem myBindingExtension = textBox.Context.Services.Component.RegisterComponentForDesigner(new Binding());
myBindingExtension.Properties["Path"].SetValue("StringProp");
myBindingExtension.Properties["Source"].SetValue(new StaticResourceExtension());
myBindingExtension.Properties["Source"].Value.Properties["ResourceKey"].SetValue("testKey");
// Adding it to MultiBinding "Bindings" collection.
bindingsProp.CollectionElements.Add(myBindingExtension);
textBox.ContentProperty.SetValue(multiBindingItem);
// Verify that the text have the expected value, proving that the StaticResource have been resolved.
Assert.AreEqual("String value", ((TextBox)textBox.Component).Text);
const string expectedXaml = "<Canvas.Resources>\n" +
" <Controls0:ExampleClass x:Key=\"testKey\" StringProp=\"String value\" />\n" +
"</Canvas.Resources>\n" +
"<TextBox>\n" +
" <MultiBinding>\n" +
" <MultiBinding.Converter>\n" +
" <t:ReturnFirstValueMultiConverter />\n" +
" </MultiBinding.Converter>\n" +
" <Binding Path=\"StringProp\" Source=\"{StaticResource testKey}\" />\n" +
" </MultiBinding>\n" +
"</TextBox>";
AssertCanvasDesignerOutput(expectedXaml, textBox.Context, "xmlns:Controls0=\"" + ICSharpCode.WpfDesign.Tests.XamlDom.XamlTypeFinderTests.XamlDomTestsNamespace + "\"");
AssertLog("");
}
[Test]
public void AddBrushAsResource()
{
@ -1024,6 +1070,22 @@ namespace ICSharpCode.WpfDesign.Tests.Designer @@ -1024,6 +1070,22 @@ namespace ICSharpCode.WpfDesign.Tests.Designer
}
}
public class ReturnFirstValueMultiConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if(values != null && values.Length > 0) {
return values[0];
} else {
return System.Windows.DependencyProperty.UnsetValue;
}
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class ExampleClass
{
string stringProp;

13
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObject.cs

@ -283,8 +283,17 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -283,8 +283,17 @@ namespace ICSharpCode.WpfDesign.XamlDom
void UpdateChildMarkupExtensions(XamlObject obj)
{
foreach (XamlObject propXamlObject in obj.Properties.Where((prop) => prop.IsSet).Select((prop) => prop.PropertyValue).OfType<XamlObject>()) {
UpdateChildMarkupExtensions(propXamlObject);
foreach (var prop in obj.Properties) {
if (prop.IsSet) {
var propXamlObject = prop.PropertyValue as XamlObject;
if (propXamlObject != null) {
UpdateChildMarkupExtensions(propXamlObject);
}
} else if (prop.IsCollection) {
foreach (var propXamlObject in prop.CollectionElements.OfType<XamlObject>()) {
UpdateChildMarkupExtensions(propXamlObject);
}
}
}
if (obj.IsMarkupExtension && obj.ParentProperty != null) {

12
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs

@ -248,8 +248,9 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -248,8 +248,9 @@ namespace ICSharpCode.WpfDesign.XamlDom
try {
ValueOnInstance = PropertyValue.GetValueFor(propertyInfo);
if (this.parentObject.XamlSetTypeConverter != null)
if (this.parentObject.XamlSetTypeConverter != null && propertyValue is XamlTextValue) {
this.ParentObject.XamlSetTypeConverter(this.parentObject.Instance, new XamlSetTypeConverterEventArgs(this.SystemXamlMemberForProperty, null, ((XamlTextValue) propertyValue).Text, this.parentObject.OwnerDocument.GetTypeDescriptorContext(this.parentObject), null));
}
if (propertyInfo.DependencyProperty == DesignTimeProperties.DesignWidthProperty) {
var widthProperty = this.ParentObject.Properties.FirstOrDefault(x => x.DependencyProperty == FrameworkElement.WidthProperty);
@ -266,6 +267,15 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -266,6 +267,15 @@ namespace ICSharpCode.WpfDesign.XamlDom
catch (Exception ex) {
Debug.WriteLine("UpdateValueOnInstance() failed - Exception:" + ex.Message);
}
} else if (IsCollection) {
var list = ValueOnInstance as System.Collections.IList;
if (list != null) {
list.Clear();
foreach (var item in CollectionElements) {
var newValue = item.GetValueFor(propertyInfo);
list.Add(newValue);
}
}
}
}

5
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignItem.cs

@ -78,6 +78,11 @@ namespace ICSharpCode.WpfDesign @@ -78,6 +78,11 @@ namespace ICSharpCode.WpfDesign
/// </summary>
public abstract DesignItemPropertyCollection Properties { get; }
/// <summary>
/// Gets properties set on the design item.
/// </summary>
public abstract IEnumerable<DesignItemProperty> AllSetProperties { get; }
/// <summary>
/// Gets/Sets the name of the design item.
/// </summary>

5
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PlacementOperation.cs

@ -38,6 +38,8 @@ namespace ICSharpCode.WpfDesign @@ -38,6 +38,8 @@ namespace ICSharpCode.WpfDesign
IPlacementBehavior currentContainerBehavior;
bool isAborted, isCommitted;
public const double PasteOffset = 10;
#region Properties
/// <summary>
/// The items being placed.
@ -294,6 +296,7 @@ namespace ICSharpCode.WpfDesign @@ -294,6 +296,7 @@ namespace ICSharpCode.WpfDesign
#endregion
#region ChangeGroup handling
/// <summary>
/// Gets/Sets the description of the underlying change group.
/// </summary>
@ -301,7 +304,7 @@ namespace ICSharpCode.WpfDesign @@ -301,7 +304,7 @@ namespace ICSharpCode.WpfDesign
get { return changeGroup.Title; }
set { changeGroup.Title = value; }
}
/// <summary>
/// Aborts the operation.
/// This aborts the underlying change group, reverting all changes done while the operation was running.

3
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Services.cs

@ -127,6 +127,9 @@ namespace ICSharpCode.WpfDesign @@ -127,6 +127,9 @@ namespace ICSharpCode.WpfDesign
/// <summary>Event raised whenever a component is registered</summary>
event EventHandler<DesignItemEventArgs> ComponentRegistered;
/// <summary>Event raised whenever a component is removed</summary>
event EventHandler<DesignItemEventArgs> ComponentRemoved;
/// <summary>Property Changed</summary>
event EventHandler<DesignItemPropertyChangedEventArgs> PropertyChanged;

Loading…
Cancel
Save