From 094bcbc4c761f56abebe3232f9a9d8004522bb23 Mon Sep 17 00:00:00 2001 From: Jose Medrano Date: Tue, 30 Jul 2019 13:25:50 +0200 Subject: [PATCH 01/21] Enables by default property native panel --- .../MonoDevelop.DesignerSupport/PropertyPad.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/PropertyPad.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/PropertyPad.cs index e7fc1f147a0..6fe8d7a321c 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/PropertyPad.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/PropertyPad.cs @@ -70,7 +70,7 @@ public PropertyPad () frame = new InvisibleFrame (); #if MAC - isNative = FeatureSwitchService.IsFeatureEnabled ("NativePropertyPanel") ?? false; + isNative = true; if (isNative) { From 6c9521c8f681007591b48527e2fdca8bc69458f3 Mon Sep 17 00:00:00 2001 From: Jose Medrano Date: Tue, 30 Jul 2019 13:30:33 +0200 Subject: [PATCH 02/21] Changes NSViewToGtkWidget to use GtkNSViewHost --- .../PropertyPad.cs | 24 +++---------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/PropertyPad.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/PropertyPad.cs index 6fe8d7a321c..1f66e4ed649 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/PropertyPad.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/PropertyPad.cs @@ -77,12 +77,8 @@ public PropertyPad () nativeGrid = new MacPropertyGrid (); propertyGrid = nativeGrid; - gtkWidget = Components.Mac.GtkMacInterop.NSViewToGtkWidget (nativeGrid); - gtkWidget.CanFocus = true; - gtkWidget.Sensitive = true; - gtkWidget.Focused += Widget_Focused; + gtkWidget = new GtkNSViewHost (nativeGrid); - nativeGrid.Focused += PropertyGrid_Focused; frame.Add (gtkWidget); } else { #endif @@ -100,12 +96,7 @@ void Grid_Changed (object sender, EventArgs e) { PropertyGridChanged?.Invoke (this, e); } -#if MAC - void Widget_Focused (object o, Gtk.FocusedArgs args) - { - nativeGrid.Window.MakeFirstResponder (nativeGrid); - } -#endif + protected override void Initialize (IPadWindow container) { base.Initialize (container); @@ -136,8 +127,6 @@ public override void Dispose() #if MAC if (isNative) { container.PadContentShown -= Window_PadContentShown; - nativeGrid.Focused -= PropertyGrid_Focused; - gtkWidget.Focused -= Widget_Focused; } else { #endif grid.Changed -= Grid_Changed; @@ -195,14 +184,7 @@ void Window_PadContentShown (object sender, EventArgs e) { propertyGrid.OnPadContentShown (); } -#if MAC - void PropertyGrid_Focused (object sender, EventArgs e) - { - if (!gtkWidget.HasFocus) { - gtkWidget.HasFocus = true; - } - } -#endif + void AttachToolbarIfCustomWidget () { if (customWidget) { From 29acba3c0a41ba4aae176611e0b1521e340f8a63 Mon Sep 17 00:00:00 2001 From: Jose Medrano Date: Tue, 30 Jul 2019 14:12:12 +0200 Subject: [PATCH 03/21] [PropertyPanel] Hides by default current header propably we should allow change this selecting an element --- .../MonoDevelop.DesignerSupport/MacPropertyGrid.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/MacPropertyGrid.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/MacPropertyGrid.cs index 3232c62145e..a73846485cd 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/MacPropertyGrid.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/MacPropertyGrid.cs @@ -67,8 +67,9 @@ public MacPropertyGrid () Spacing = 10; Distribution = NSStackViewDistribution.Fill; - propertyEditorPanel = new MacPropertyEditorPanel (new MonoDevelopHostResourceProvider ()); - + propertyEditorPanel = new MacPropertyEditorPanel (new MonoDevelopHostResourceProvider ()) { + ShowHeader = false + }; scrollView = new NSScrollView () { HasVerticalScroller = true, HasHorizontalScroller = false, From e5880baeb8c9d5b47fc5edaaea1e18364bbeec41 Mon Sep 17 00:00:00 2001 From: Jose Medrano Date: Tue, 30 Jul 2019 14:17:56 +0200 Subject: [PATCH 04/21] =?UTF-8?q?[PropertyPanel]=C2=A0Removes=20old=20hack?= =?UTF-8?q?s=20not=20necessary=20anymore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MacPropertyGrid.cs | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/MacPropertyGrid.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/MacPropertyGrid.cs index a73846485cd..91b71c44cea 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/MacPropertyGrid.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/MacPropertyGrid.cs @@ -49,7 +49,6 @@ namespace MonoDevelop.DesignerSupport class MacPropertyGrid : NSStackView, IPropertyGrid { MacPropertyEditorPanel propertyEditorPanel; - PropertyPadEditorProvider editorProvider; NSScrollView scrollView; @@ -80,18 +79,9 @@ public MacPropertyGrid () AddArrangedSubview (scrollView); - propertyEditorPanel.Focused += PropertyEditorPanel_Focused; - //propertyEditorPanel.PropertiesChanged += PropertyEditorPanel_PropertiesChanged; } - void Widget_Focused (object o, Gtk.FocusedArgs args) - { - propertyEditorPanel.Window.MakeFirstResponder (propertyEditorPanel); - } - - void PropertyEditorPanel_Focused (object sender, EventArgs e) => Focused?.Invoke (this, EventArgs.Empty); - public override void SetFrameSize (CGSize newSize) { scrollView.SetFrameSize (newSize); @@ -111,7 +101,7 @@ public void OnPadContentShown () if (editorProvider == null) { editorProvider = new PropertyPadEditorProvider (); propertyEditorPanel.TargetPlatform = new TargetPlatform (editorProvider) { - AutoExpandGroups = new string [] { "Build", "Misc", "NuGet", "Reference" } + AutoExpandAll = true }; propertyEditorPanel.ArrangeMode = PropertyArrangeMode.Category; } @@ -133,9 +123,6 @@ public void SetCurrentObject (object lastComponent, object [] propertyProviders) protected override void Dispose (bool disposing) { - if (propertyEditorPanel != null) { - propertyEditorPanel.Focused -= PropertyEditorPanel_Focused; - } base.Dispose (disposing); } From af29c5e67cd5a878421d04c596b7cefba7a5460a Mon Sep 17 00:00:00 2001 From: Jose Medrano Date: Wed, 2 Oct 2019 12:58:10 +0200 Subject: [PATCH 05/21] =?UTF-8?q?[ProppertyPanel]=C2=A0Sets=20property=20p?= =?UTF-8?q?ad=20as=20main=20content=20in=20MacPropertyGrid=20abstraction?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MacPropertyGrid.cs | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/MacPropertyGrid.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/MacPropertyGrid.cs index 91b71c44cea..c64eda5698f 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/MacPropertyGrid.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/MacPropertyGrid.cs @@ -36,13 +36,8 @@ using MonoDevelop.Components; using Xamarin.PropertyEditing; using Xamarin.PropertyEditing.Mac; -using MonoDevelop.Components.Mac; -using MonoDevelop.Ide; -using MonoDevelop.Ide.Commands; -using MonoDevelop.Components.Theming; using AppKit; using CoreGraphics; -using Foundation; namespace MonoDevelop.DesignerSupport { @@ -51,7 +46,6 @@ class MacPropertyGrid : NSStackView, IPropertyGrid MacPropertyEditorPanel propertyEditorPanel; PropertyPadEditorProvider editorProvider; - NSScrollView scrollView; public event EventHandler Focused; @@ -69,22 +63,13 @@ public MacPropertyGrid () propertyEditorPanel = new MacPropertyEditorPanel (new MonoDevelopHostResourceProvider ()) { ShowHeader = false }; - scrollView = new NSScrollView () { - HasVerticalScroller = true, - HasHorizontalScroller = false, - }; - scrollView.WantsLayer = true; - scrollView.BackgroundColor = Styles.HeaderBackgroundColor; - scrollView.DocumentView = propertyEditorPanel; - - AddArrangedSubview (scrollView); - + AddArrangedSubview (propertyEditorPanel); //propertyEditorPanel.PropertiesChanged += PropertyEditorPanel_PropertiesChanged; } public override void SetFrameSize (CGSize newSize) { - scrollView.SetFrameSize (newSize); + propertyEditorPanel.SetFrameSize (newSize); base.SetFrameSize (newSize); } From ce260fc53de51dcff4add68e132558265e08df17 Mon Sep 17 00:00:00 2001 From: Jose Medrano Date: Wed, 2 Oct 2019 13:35:13 +0200 Subject: [PATCH 06/21] Some minor changes in the current layout --- .../MacPropertyGrid.cs | 47 ++++++------------- 1 file changed, 15 insertions(+), 32 deletions(-) diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/MacPropertyGrid.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/MacPropertyGrid.cs index c64eda5698f..adbf7140815 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/MacPropertyGrid.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/MacPropertyGrid.cs @@ -30,8 +30,6 @@ #if MAC -using MonoDevelop.Ide.Gui; -using MonoDevelop.Components.Commands; using System; using MonoDevelop.Components; using Xamarin.PropertyEditing; @@ -41,11 +39,11 @@ namespace MonoDevelop.DesignerSupport { - class MacPropertyGrid : NSStackView, IPropertyGrid + class MacPropertyGrid : NSView, IPropertyGrid { - MacPropertyEditorPanel propertyEditorPanel; + readonly MacPropertyEditorPanel propertyEditorPanel; PropertyPadEditorProvider editorProvider; - + PropertyPadItem currentSelectedObject; public event EventHandler Focused; @@ -55,45 +53,30 @@ class MacPropertyGrid : NSStackView, IPropertyGrid public MacPropertyGrid () { - Orientation = NSUserInterfaceLayoutOrientation.Vertical; - Alignment = NSLayoutAttribute.Leading; - Spacing = 10; - Distribution = NSStackViewDistribution.Fill; - propertyEditorPanel = new MacPropertyEditorPanel (new MonoDevelopHostResourceProvider ()) { ShowHeader = false }; - AddArrangedSubview (propertyEditorPanel); - //propertyEditorPanel.PropertiesChanged += PropertyEditorPanel_PropertiesChanged; + AddSubview (propertyEditorPanel); + + editorProvider = new PropertyPadEditorProvider (); + propertyEditorPanel.TargetPlatform = new TargetPlatform (editorProvider) { + AutoExpandAll = true + }; + propertyEditorPanel.ArrangeMode = PropertyArrangeMode.Category; } public override void SetFrameSize (CGSize newSize) { - propertyEditorPanel.SetFrameSize (newSize); base.SetFrameSize (newSize); + propertyEditorPanel.SetFrameSize (newSize); } - void PropertyEditorPanel_PropertiesChanged (object sender, EventArgs e) => PropertyGridChanged?.Invoke (this, e); - public void BlankPad () { propertyEditorPanel.SelectedItems.Clear (); currentSelectedObject = null; } - public void OnPadContentShown () - { - if (editorProvider == null) { - editorProvider = new PropertyPadEditorProvider (); - propertyEditorPanel.TargetPlatform = new TargetPlatform (editorProvider) { - AutoExpandAll = true - }; - propertyEditorPanel.ArrangeMode = PropertyArrangeMode.Category; - } - } - - PropertyPadItem currentSelectedObject; - public void SetCurrentObject (object lastComponent, object [] propertyProviders) { if (lastComponent != null) { @@ -106,17 +89,17 @@ public void SetCurrentObject (object lastComponent, object [] propertyProviders) } } - protected override void Dispose (bool disposing) + public void Populate (bool saveEditSession) { - base.Dispose (disposing); + //not implemented } - public void Populate (bool saveEditSession) + public void SetToolbarProvider (Components.PropertyGrid.PropertyGrid.IToolbarProvider toolbarProvider) { //not implemented } - public void SetToolbarProvider (Components.PropertyGrid.PropertyGrid.IToolbarProvider toolbarProvider) + public void OnPadContentShown () { //not implemented } From 35cb9469e80c20ebcba2e2ab4cbfa0368c8696a6 Mon Sep 17 00:00:00 2001 From: Jose Medrano Date: Wed, 2 Oct 2019 19:19:30 +0200 Subject: [PATCH 07/21] Refactoring to match to handle logic from EditorProvider + better filenames --- .../MonoDevelop.DesignerSupport.csproj | 21 +- .../MacPropertyGrid.cs | 8 +- .../ComponentModelEditorProvider.cs | 136 +++++++++++ .../ComponentModelObjectEditor.cs | 142 ++++++++++++ .../PropertyDescriptorEventInfo.cs | 0 .../PropertyInfo/DescriptorPropertyInfo.cs | 56 +++-- .../PropertyInfo/DirectoryPathPropertyInfo.cs | 0 .../EnumDescriptorPropertyInfo.cs | 43 ++-- .../PropertyInfo/FilePathPropertyInfo.cs | 23 +- .../FlagDescriptorPropertyInfo.cs | 19 +- .../StringStandardValuesPropertyInfo.cs | 41 +++- .../PropertyPadItem.cs} | 24 +- .../PropertyPadEditorProvider.cs | 75 ------- .../NativePropertyEditors/PropertyPadItem.cs | 69 ------ .../PropertyPadObjectEditor.cs | 212 ------------------ 15 files changed, 422 insertions(+), 447 deletions(-) create mode 100644 main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelEditorProvider.cs create mode 100644 main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelObjectEditor.cs rename main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/{NativePropertyEditors => NativePropertyEditor}/PropertyDescriptorEventInfo.cs (100%) rename main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/{NativePropertyEditors => NativePropertyEditor}/PropertyInfo/DescriptorPropertyInfo.cs (75%) rename main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/{NativePropertyEditors => NativePropertyEditor}/PropertyInfo/DirectoryPathPropertyInfo.cs (100%) rename main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/{NativePropertyEditors => NativePropertyEditor}/PropertyInfo/EnumDescriptorPropertyInfo.cs (73%) rename main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/{NativePropertyEditors => NativePropertyEditor}/PropertyInfo/FilePathPropertyInfo.cs (70%) rename main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/{NativePropertyEditors => NativePropertyEditor}/PropertyInfo/FlagDescriptorPropertyInfo.cs (83%) rename main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/{NativePropertyEditors => NativePropertyEditor}/PropertyInfo/StringStandardValuesPropertyInfo.cs (61%) rename main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/{NativePropertyEditors/PropertyProviderTypeInfo.cs => NativePropertyEditor/PropertyPadItem.cs} (70%) delete mode 100644 main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyPadEditorProvider.cs delete mode 100644 main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyPadItem.cs delete mode 100644 main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyPadObjectEditor.cs diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.csproj b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.csproj index 55d7a153a52..21d6114487e 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.csproj +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.csproj @@ -135,18 +135,17 @@ - - - - - - - - - + + + + + + + + - - + + diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/MacPropertyGrid.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/MacPropertyGrid.cs index adbf7140815..3bdf974d952 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/MacPropertyGrid.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/MacPropertyGrid.cs @@ -42,8 +42,8 @@ namespace MonoDevelop.DesignerSupport class MacPropertyGrid : NSView, IPropertyGrid { readonly MacPropertyEditorPanel propertyEditorPanel; - PropertyPadEditorProvider editorProvider; - PropertyPadItem currentSelectedObject; + ComponentModelEditorProvider editorProvider; + ComponentModelTarget currentSelectedObject; public event EventHandler Focused; @@ -58,7 +58,7 @@ public MacPropertyGrid () }; AddSubview (propertyEditorPanel); - editorProvider = new PropertyPadEditorProvider (); + editorProvider = new ComponentModelEditorProvider (); propertyEditorPanel.TargetPlatform = new TargetPlatform (editorProvider) { AutoExpandAll = true }; @@ -80,7 +80,7 @@ public void BlankPad () public void SetCurrentObject (object lastComponent, object [] propertyProviders) { if (lastComponent != null) { - var selection = new PropertyPadItem (lastComponent, propertyProviders); + var selection = new ComponentModelTarget (lastComponent, propertyProviders); if (currentSelectedObject != selection) { propertyEditorPanel.SelectedItems.Clear (); propertyEditorPanel.SelectedItems.Add (selection); diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelEditorProvider.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelEditorProvider.cs new file mode 100644 index 00000000000..61c8831dc31 --- /dev/null +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelEditorProvider.cs @@ -0,0 +1,136 @@ +// +// PropertyPadEditorProvider.cs +// +// Author: +// jmedrano +// +// Copyright (c) 2018 +// +// 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. + +#if MAC + +using System.Linq; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Xamarin.PropertyEditing; +using MonoDevelop.Core; + +namespace MonoDevelop.DesignerSupport +{ + class ComponentModelEditorProvider + : IEditorProvider + { + public IReadOnlyDictionary KnownTypes { + get; + } = new Dictionary (); + + object [] providers; + + public Task GetObjectEditorAsync (object item) + { + if (item is ComponentModelTarget propertyPadItem) { + //on each editor we store current used providers + providers = propertyPadItem.Providers ?? Array.Empty (); + return Task.FromResult (new ComponentModelObjectEditor (propertyPadItem)); + } + throw new ArgumentException (string.Format ("Cannot get editor for type {0} only ComponentModelObjectEditor types are allowed", item.GetType ().Name)); + } + + public Task CreateObjectAsync (ITypeInfo type) + { + var realType = Type.GetType ($"{type.NameSpace}.{type.Name}, {type.Assembly.Name}"); + if (realType == null) + return Task.FromResult (null); + return Task.FromResult (Activator.CreateInstance (realType)); + } + + public Task> GetPropertiesForTypeAsync (ITypeInfo type) + => Task.Run (() => (IReadOnlyCollection)GetPropertiesForProviders (providers)); + + public static IReadOnlyList GetPropertiesForProviders (object[] providers) + { + var collection = new List (); + + foreach (object propertyProvider in providers) { + //get the current properties for this provider + var currentType = propertyProvider.GetType (); + + //we want all property descriptors for this propertyProvider type + var propertyDescriptors = System.ComponentModel.TypeDescriptor.GetProperties (currentType); + + foreach (System.ComponentModel.PropertyDescriptor propertyDescriptor in propertyDescriptors) { + if (propertyDescriptor.IsBrowsable) { + collection.Add (CreatePropertyInfo (propertyDescriptor, propertyProvider)); + } + } + } + return collection.AsReadOnly (); + } + + protected static DescriptorPropertyInfo CreatePropertyInfo (System.ComponentModel.PropertyDescriptor propertyDescriptor, object PropertyProvider) + { + var valueSources = ValueSources.Local | ValueSources.Default; + if (propertyDescriptor.PropertyType.IsEnum) { + if (propertyDescriptor.PropertyType.IsDefined (typeof (FlagsAttribute), true)) + return new FlagDescriptorPropertyInfo (propertyDescriptor, PropertyProvider, valueSources); + return new EnumDescriptorPropertyInfo (propertyDescriptor, PropertyProvider, valueSources); + } + + if (propertyDescriptor.PropertyType.IsAssignableFrom (typeof (Core.FilePath))) { + //var isDirectoryPropertyDescriptor = GetPropertyDescriptor (propertyDescriptor.GetChildProperties (), nameof (Core.FilePath.IsDirectory)); + //if (isDirectoryPropertyDescriptor != null && (bool)isDirectoryPropertyDescriptor.GetValue (propertyItem)) { + // return new DirectoryPathPropertyInfo (propertyDescriptor, PropertyProvider, valueSources); + //} + return new FilePathPropertyInfo (propertyDescriptor, PropertyProvider, valueSources); + } + + if (HasStandardValues (propertyDescriptor)) { + return new StringStandardValuesPropertyInfo (propertyDescriptor, PropertyProvider, valueSources); + } + + return new DescriptorPropertyInfo (propertyDescriptor, PropertyProvider, valueSources); + } + + static bool HasStandardValues (System.ComponentModel.PropertyDescriptor propertyDescriptor) + { + if (propertyDescriptor.Converter.GetStandardValuesSupported ()) { + if (!propertyDescriptor.Converter.GetStandardValuesExclusive () && propertyDescriptor.Converter.CanConvertFrom (typeof (string))) { + return true; + } + } + return false; + } + + public ITypeInfo GetRealType (T item) + => DescriptorPropertyInfo.ToTypeInfo(item.GetType ()); + + public static Type GetRealType (ITypeInfo type) + => Type.GetType ($"{type.NameSpace}.{type.Name}, {type.Assembly.Name}"); + + public Task GetAssignableTypesAsync (ITypeInfo type, bool childTypes) + => ComponentModelObjectEditor.GetAssignableTypes (); + + public Task> GetChildrenAsync (object item) + => Task.FromResult> (Array.Empty ()); + } +} + +#endif \ No newline at end of file diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelObjectEditor.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelObjectEditor.cs new file mode 100644 index 00000000000..445488a0880 --- /dev/null +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelObjectEditor.cs @@ -0,0 +1,142 @@ +// +// PropertyPadObjectEditor.cs +// +// Author: +// jmedrano +// +// Copyright (c) 2018 +// +// 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. + +#if MAC + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using MonoDevelop.Core; +using Xamarin.PropertyEditing; + +namespace MonoDevelop.DesignerSupport +{ + class ComponentModelObjectEditor + : IObjectEditor, INameableObject + { + private readonly ComponentModelTarget propertyItem; + public string Name { get; private set; } + + static IReadOnlyList defaultHandlerList = new List ().AsReadOnly (); + static AssignableTypesResult defaultAssignableTypeResult = new AssignableTypesResult (new List ().AsReadOnly ()); + private static readonly IObjectEditor [] EmptyDirectChildren = Array.Empty (); + + private readonly List properties = new List (); + private readonly List events = new List (); + + public object Target => this.propertyItem; + + public ITypeInfo TargetType => ToTypeInfo (Target.GetType ()); + + public static ITypeInfo ToTypeInfo (Type type, bool isRelevant = true) + { + var asm = type.Assembly.GetName ().Name; + return new TypeInfo (new AssemblyInfo (asm, isRelevant), type.Namespace, type.Name); + } + + public IReadOnlyCollection Properties => this.properties; + + public IReadOnlyDictionary KnownProperties => null; + + public IObjectEditor Parent => null; + + public IReadOnlyList DirectChildren => EmptyDirectChildren; + public IReadOnlyCollection Events => this.events; + + internal static Task GetAssignableTypes () + => Task.FromResult (defaultAssignableTypeResult); + + public event EventHandler PropertyChanged; + + public ComponentModelObjectEditor (ComponentModelTarget propertyItem) + { + this.propertyItem = propertyItem; + this.properties.AddRange (ComponentModelEditorProvider.GetPropertiesForProviders (propertyItem.Providers)); + } + + public async Task GetAssignableTypesAsync (IPropertyInfo property, bool childTypes) + { + return new AssignableTypesResult (Array.Empty ()); + } + + public Task> GetHandlersAsync (IEventInfo ev) => Task.FromResult(defaultHandlerList); + + public Task GetNameAsync () => Task.FromResult (Name); + + public Task> GetPropertyVariantsAsync (IPropertyInfo property) + => Task.FromResult> (Array.Empty ()); + + public async Task> GetValueAsync (IPropertyInfo property, PropertyVariation variations = null) + { + if (property == null) + throw new ArgumentNullException (nameof (property)); + + if (!(property is DescriptorPropertyInfo propertyInfo)) + throw new ArgumentException ("Property should be a DescriptorPropertyInfo", nameof (property)); + + T value = await propertyInfo.GetValueAsync (this); + return new ValueInfo { + Value = value, + Source = ValueSource.Local, + }; + } + + public Task RemovePropertyVariantAsync (IPropertyInfo property, PropertyVariation variant) => Task.CompletedTask; + + public Task SetNameAsync (string name) + { + Name = name; + return Task.FromResult (true); + } + + public Task SetValueAsync (IPropertyInfo propertyInfo, ValueInfo value, PropertyVariation variations = null) + { + try { + if (propertyInfo == null) + throw new ArgumentNullException (nameof (propertyInfo)); + + if (propertyInfo is DescriptorPropertyInfo info && info.CanWrite) { + + info.SetValue (this, value.Value); + OnPropertyChanged (info); + + } else { + throw new ArgumentException ($"Property should be a writeable {nameof (DescriptorPropertyInfo)}.", nameof (propertyInfo)); + } + } catch (Exception ex) { + LoggingService.LogError ("Error setting the value", ex); + } + return Task.CompletedTask; + } + + protected virtual void OnPropertyChanged (IPropertyInfo property) + { + PropertyChanged?.Invoke (this, new EditorPropertyChangedEventArgs (property)); + } + } +} + +#endif \ No newline at end of file diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyDescriptorEventInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyDescriptorEventInfo.cs similarity index 100% rename from main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyDescriptorEventInfo.cs rename to main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyDescriptorEventInfo.cs diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyInfo/DescriptorPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/DescriptorPropertyInfo.cs similarity index 75% rename from main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyInfo/DescriptorPropertyInfo.cs rename to main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/DescriptorPropertyInfo.cs index 033470859b3..9ada3a72fcb 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyInfo/DescriptorPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/DescriptorPropertyInfo.cs @@ -44,15 +44,15 @@ class DescriptorPropertyInfo { public PropertyDescriptor PropertyDescriptor { get; private set; } public object PropertyProvider { get; private set; } - readonly ValueSources valueSources; - static readonly IAvailabilityConstraint [] EmptyConstraints = new IAvailabilityConstraint [0]; - static readonly PropertyVariationOption [] EmptyVariationOptions = new PropertyVariationOption [0]; + + static readonly IAvailabilityConstraint [] EmptyConstraints = Array.Empty (); + static readonly PropertyVariationOption [] EmptyVariationOptions = Array.Empty (); public DescriptorPropertyInfo (PropertyDescriptor propertyInfo, object propertyProvider, ValueSources valueSources) { this.PropertyDescriptor = propertyInfo; this.PropertyProvider = propertyProvider; - this.valueSources = valueSources; + this.ValueSources = valueSources; } public string Name => PropertyDescriptor.DisplayName; @@ -61,13 +61,13 @@ public DescriptorPropertyInfo (PropertyDescriptor propertyInfo, object propertyP public virtual Type Type => PropertyDescriptor.PropertyType; - public ITypeInfo RealType => ToTypeInfo (PropertyDescriptor, PropertyProvider, Type); + public ITypeInfo RealType => ToTypeInfo (Type); public string Category => PropertyDescriptor.Category; public bool CanWrite => !PropertyDescriptor.IsReadOnly; - public ValueSources ValueSources => valueSources; + public ValueSources ValueSources { get; } public IReadOnlyList Variations => EmptyVariationOptions; @@ -105,50 +105,44 @@ public static Type GetCollectionItemType (Type colType) return null; } - public static ITypeInfo ToTypeInfo (PropertyDescriptor propertyDescriptor, object propertyProvider, Type type, bool isRelevant = true) + public static ITypeInfo ToTypeInfo (Type type, bool isRelevant = true) { var asm = type.Assembly.GetName ().Name; - return new PropertyProviderTypeInfo (propertyDescriptor, propertyProvider, new AssemblyInfo (asm, isRelevant), type.Namespace, type.Name); + return new Xamarin.PropertyEditing.TypeInfo (new AssemblyInfo (asm, isRelevant), type.Namespace, type.Name); } - const string ErrorOnGetValueMessage = "Error in GetValueAsync using property descriptor converter"; - protected void LogGetValueAsyncError (Exception ex) => LoggingService.LogError (ErrorOnGetValueMessage, ex); - internal virtual Task GetValueAsync (object target) { + T converted = default; object value = null; - + bool canConvert = false; try { value = PropertyDescriptor.GetValue (PropertyProvider); - TypeConverter tc = PropertyDescriptor.Converter; + var tc = PropertyDescriptor.Converter; + canConvert = tc.CanConvertTo (typeof (T)); if (tc.CanConvertTo (typeof (T))) { - value = tc.ConvertTo (value, typeof (T)); + converted = (T)tc.ConvertTo (value, typeof (T)); + } else { + converted = (T)value; } - return Task.FromResult ((T)value); } catch (Exception ex) { - LogGetValueAsyncError (ex); - } - - T converted = default; - try { - if (value != null && !(value is T)) { - if (typeof (T) == typeof (string)) { - value = value.ToString (); - } else { - value = Convert.ChangeType (value, typeof (T)); - } - } - return Task.FromResult ((T)value); - } catch (Exception ex) { - LogGetValueAsyncError (ex); + LogInternalError ($"Error trying to get and convert value:'{value}' canconvert: {canConvert} T:{typeof (T).FullName} ", ex); } return Task.FromResult (converted); } internal virtual void SetValue (object target, T value) { - PropertyDescriptor.SetValue (PropertyProvider, value); + try { + PropertyDescriptor.SetValue (PropertyProvider, value); + } catch (Exception ex) { + LogInternalError ($"Error trying to set and convert value:'{value}' T:{typeof (T).FullName} ", ex); + } } + + protected void LogInternalError (string message, Exception ex = null) => + LoggingService.LogInternalError (string.Format ("[{0}][{1}] {2}", Name, GetType ().Name, message), ex); + } } diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyInfo/DirectoryPathPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/DirectoryPathPropertyInfo.cs similarity index 100% rename from main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyInfo/DirectoryPathPropertyInfo.cs rename to main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/DirectoryPathPropertyInfo.cs diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyInfo/EnumDescriptorPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/EnumDescriptorPropertyInfo.cs similarity index 73% rename from main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyInfo/EnumDescriptorPropertyInfo.cs rename to main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/EnumDescriptorPropertyInfo.cs index dc5a6c03f38..2aca4c28477 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyInfo/EnumDescriptorPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/EnumDescriptorPropertyInfo.cs @@ -33,11 +33,12 @@ using System.Collections; using System.Threading.Tasks; using MonoDevelop.Core; +using System.Linq; namespace MonoDevelop.DesignerSupport { class EnumDescriptorPropertyInfo - : DescriptorPropertyInfo, IHavePredefinedValues //, IValidator>, ICoerce> + : DescriptorPropertyInfo, IHavePredefinedValues { Hashtable names = new Hashtable (); Array values; @@ -45,6 +46,7 @@ public EnumDescriptorPropertyInfo (PropertyDescriptor propertyDescriptor, object : base (propertyDescriptor, propertyProvider, valueSources) { values = Enum.GetValues (PropertyDescriptor.PropertyType); + var fields = PropertyDescriptor.PropertyType.GetFields (); names = new Hashtable (); @@ -70,34 +72,47 @@ internal override void SetValue (object target, T value) { var tc = PropertyDescriptor.Converter; if (tc.CanConvertFrom (typeof (T))) { - if (int.TryParse ((string)(object)value, out var index)) { - PropertyDescriptor.SetValue (PropertyProvider, values.GetValue (index)); - } else { - throw new Exception (string.Format ("Error in SetValue parsing {0} as integer in {1} (enum descriptor)", value, PropertyDescriptor.DisplayName)); + try { + var item = tc.ConvertFrom (value); + PropertyDescriptor.SetValue (PropertyProvider, item); + } catch (Exception ex) { + LogInternalError ($"Error trying to set and convert a value: {value} T:{typeof (T).FullName}", ex); + } + } else { + base.SetValue (target, value); + } + } + + static int GetIndexOfValue (Array values, string value) + { + for (int i = 0; i < values.Length; i++) { + if (values.GetValue (i).ToString ().Equals (value)) { + return i; } } + return -1; } - internal override Task GetValueAsync (object target) + internal async override Task GetValueAsync (object target) { //we need set the index of the selected item T result = default; try { - TypeConverter tc = PropertyDescriptor.Converter; - object cob = PropertyDescriptor.GetValue (PropertyProvider); - var index = Array.IndexOf (values, cob); + result = await base.GetValueAsync (target); + string cob = result as string; + var index = GetIndexOfValue (values, cob); if (index > -1) { - result = (T)(object) index.ToString (); + result = (T)(object)index.ToString (); } else { - LoggingService.LogError ("Error in GetValueAsync parsing {0} as integer in {1} (enum descriptor)", index, PropertyDescriptor.DisplayName); + throw new InvalidCastException ($"Error in GetValueAsync parsing {index} as integer"); } } catch (Exception ex) { - LogGetValueAsyncError (ex); + LogInternalError ($"Error trying to get and convert a value T:{typeof (T).FullName}", ex); } - return Task.FromResult (result); + return result; } - public bool IsConstrainedToPredefined => false; + public bool IsConstrainedToPredefined => true; public bool IsValueCombinable { get; diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyInfo/FilePathPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FilePathPropertyInfo.cs similarity index 70% rename from main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyInfo/FilePathPropertyInfo.cs rename to main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FilePathPropertyInfo.cs index 393416929af..a57f45d4eed 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyInfo/FilePathPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FilePathPropertyInfo.cs @@ -44,20 +44,27 @@ public FilePathPropertyInfo (PropertyDescriptor propertyInfo, object propertyPro internal override void SetValue (object target, T value) { - if (value is Xamarin.PropertyEditing.Common.FilePath filePath) { - PropertyDescriptor.SetValue (PropertyProvider, new MonoDevelop.Core.FilePath (filePath.Source)); - } else { - throw new Exception (string.Format ("Value: {0} of type {1} is not a DirectoryPath", value, value.GetType ())); + try { + if (value is Xamarin.PropertyEditing.Common.FilePath filePath) { + PropertyDescriptor.SetValue (PropertyProvider, new MonoDevelop.Core.FilePath (filePath.Source)); + } else { + throw new Exception (string.Format ("Value: {0} of type {1} is not a DirectoryPath", value, value.GetType ())); + } + } catch (Exception ex) { + LogInternalError ($"Error trying to get and convert value:'{value}' T:{typeof (T).FullName} ", ex); } } internal override Task GetValueAsync (object target) { - if (target is MonoDevelop.Core.FilePath directoryPath) { - T result = (T)(object)new Xamarin.PropertyEditing.Common.FilePath (directoryPath.FullPath); - return Task.FromResult (result); + try { + if (target is Core.FilePath directoryPath) { + T result = (T)(object)new Xamarin.PropertyEditing.Common.FilePath (directoryPath.FullPath); + return Task.FromResult (result); + } + } catch (Exception ex) { + LogInternalError ($"Error trying to get and convert value:'{target}' T:{typeof (T).FullName} ", ex); } - Core.LoggingService.LogWarning ("Value: {0} of type {1} is not a DirectoryPath", target, target.GetType ()); return base.GetValueAsync (target); } } diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyInfo/FlagDescriptorPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FlagDescriptorPropertyInfo.cs similarity index 83% rename from main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyInfo/FlagDescriptorPropertyInfo.cs rename to main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FlagDescriptorPropertyInfo.cs index d485704ca87..8265b039e7f 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyInfo/FlagDescriptorPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FlagDescriptorPropertyInfo.cs @@ -32,6 +32,7 @@ using System; using System.Collections; using System.Collections.Generic; +using MonoDevelop.Core; namespace MonoDevelop.DesignerSupport { @@ -49,12 +50,16 @@ public FlagDescriptorPropertyInfo (PropertyDescriptor propertyDescriptor, object internal override void SetValue (object target, T value) { - var selectedValues = (System.String []) (object)value; - ulong result = default; - foreach (var selectedValue in selectedValues) { - result += Convert.ToUInt64 (selectedValue); + try { + var selectedValues = (System.String []) (object)value; + ulong result = default; + foreach (var selectedValue in selectedValues) { + result += Convert.ToUInt64 (selectedValue); + } + PropertyDescriptor.SetValue (PropertyProvider, Enum.ToObject (PropertyDescriptor.PropertyType, result)); + } catch (Exception ex) { + LogInternalError ($"Error trying to set value: {value}", ex); } - PropertyDescriptor.SetValue (PropertyProvider, Enum.ToObject (PropertyDescriptor.PropertyType, result)); } internal override Task GetValueAsync (object target) @@ -70,9 +75,9 @@ internal override Task GetValueAsync (object target) result.Add (uintVal.ToString ()); } } - return Task.FromResult ((T)(object)result); + return Task.FromResult ((T)(object)result); } catch (Exception ex) { - LogGetValueAsyncError (ex); + LogInternalError ($"Error trying to get values from a Enum", ex); } return Task.FromResult (default); } diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyInfo/StringStandardValuesPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs similarity index 61% rename from main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyInfo/StringStandardValuesPropertyInfo.cs rename to main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs index 6f1eb5d7247..c21866b4f35 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyInfo/StringStandardValuesPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs @@ -29,6 +29,10 @@ using Xamarin.PropertyEditing; using System.ComponentModel; using System.Collections.Generic; +using System.Threading.Tasks; +using System; +using MonoDevelop.Core; +using System.Linq; namespace MonoDevelop.DesignerSupport { @@ -43,14 +47,43 @@ public StringStandardValuesPropertyInfo (PropertyDescriptor propertyDescriptor, } } - public bool IsConstrainedToPredefined => false; + public bool IsConstrainedToPredefined => true; - public bool IsValueCombinable { - get; - } + public bool IsValueCombinable { get; } protected Dictionary predefinedValues = new Dictionary (); public IReadOnlyDictionary PredefinedValues => predefinedValues; + + internal override void SetValue (object target, T value) + { + var tc = PropertyDescriptor.Converter; + if (tc.CanConvertFrom (typeof (T))) { + try { + PropertyDescriptor.SetValue (PropertyProvider, tc.ConvertTo (value, PropertyDescriptor.ComponentType)); + } catch (Exception ex) { + LogInternalError ($"Error trying to set and convert a value: {value} T:{typeof (T).FullName}", ex); + } + } else { + base.SetValue (target, value); + } + } + + internal async override Task GetValueAsync (object target) + { + TValue result = default; + result = await base.GetValueAsync (target); + + if (typeof (TValue) == typeof (IReadOnlyList) && !result.Equals (default (TValue))) { + string value; + try { + value = predefinedValues.FirstOrDefault ().Key ?? string.Empty; + result = (TValue)(object)value; + } catch (Exception ex) { + LoggingService.LogError (string.Format ("[{0}] Error trying to convert the default value of a StandardValue to default type ({1}) ", Name, typeof(TValue).FullName), ex); + } + } + return result; + } } } diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyProviderTypeInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyPadItem.cs similarity index 70% rename from main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyProviderTypeInfo.cs rename to main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyPadItem.cs index 2ac8c97afea..7614cb468df 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyProviderTypeInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyPadItem.cs @@ -1,5 +1,5 @@ -// -// DescriptorPropertyInfo.cs +// +// PropertyPadItem.cs // // Author: // jmedrano @@ -26,21 +26,21 @@ #if MAC -using Xamarin.PropertyEditing; -using System.ComponentModel; - namespace MonoDevelop.DesignerSupport { - class PropertyProviderTypeInfo : TypeInfo + /// + /// This component model target allows include additional providers to handle properties + /// + class ComponentModelTarget { - public object PropertyProvider { get; } - public PropertyDescriptor PropertyDescriptor { get; } - - public PropertyProviderTypeInfo (PropertyDescriptor propertyDescriptor, object propertyProvider, IAssemblyInfo assembly, string nameSpace, string name) : base (assembly, nameSpace, name) + public ComponentModelTarget (object target, object [] providers) { - PropertyDescriptor = propertyDescriptor; - PropertyProvider = propertyProvider; + Target = target; + Providers = providers; } + + public object Target { get; } + public object[] Providers { get; } } } diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyPadEditorProvider.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyPadEditorProvider.cs deleted file mode 100644 index 8752869230a..00000000000 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyPadEditorProvider.cs +++ /dev/null @@ -1,75 +0,0 @@ -// -// PropertyPadEditorProvider.cs -// -// Author: -// jmedrano -// -// Copyright (c) 2018 -// -// 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. - -#if MAC - -using System.Linq; -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Xamarin.PropertyEditing; -using Xamarin.PropertyEditing.Common; -using Xamarin.PropertyEditing.Reflection; -using System.Reflection; -using System.ComponentModel; - -namespace MonoDevelop.DesignerSupport -{ - class PropertyPadEditorProvider - : IEditorProvider - { - public IReadOnlyDictionary KnownTypes { - get; - } = new Dictionary (); - - public Task GetObjectEditorAsync (object item) - { - if (item is PropertyPadItem propertyPadItem) { - return Task.FromResult (new PropertyPadObjectEditor (propertyPadItem)); - } - return Task.FromResult (null); - } - - public Task CreateObjectAsync (ITypeInfo type) - { - var realType = Type.GetType ($"{type.NameSpace}.{type.Name}, {type.Assembly.Name}"); - if (realType == null) - return Task.FromResult (null); - return Task.FromResult (Activator.CreateInstance (realType)); - } - - public Task> GetPropertiesForTypeAsync (ITypeInfo type) - => Task.FromResult> (new List ()); - - public Task GetAssignableTypesAsync (ITypeInfo type, bool childTypes) - => Task.FromResult (new AssignableTypesResult (new List ())); - - public Task> GetChildrenAsync (object item) - => Task.FromResult> (Array.Empty ()); - } -} - -#endif \ No newline at end of file diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyPadItem.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyPadItem.cs deleted file mode 100644 index ecd5235fd8f..00000000000 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyPadItem.cs +++ /dev/null @@ -1,69 +0,0 @@ -// -// PropertyPadItem.cs -// -// Author: -// jmedrano -// -// Copyright (c) 2018 -// -// 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. - -#if MAC - -using System; -using System.Threading.Tasks; -using MonoDevelop.Core; -using Xamarin.PropertyEditing; - -namespace MonoDevelop.DesignerSupport -{ - class PropertyPadItem - { - public PropertyPadItem (object target, object [] providers) - { - Target = target; - Providers = providers; - } - - public object Target { get; } - public object[] Providers { get; } - - public async Task> GetPropertyValueInfoAsProppyType (DescriptorPropertyInfo propertyInfo) - { - T value = await propertyInfo.GetValueAsync (this); - return new ValueInfo { - Value = value, - Source = ValueSource.Local, - //ValueDescriptor = valueInfoString.ValueDescriptor, - //CustomExpression = valueString - }; - } - - public void SetPropertyValueInfoAsProppyType (DescriptorPropertyInfo info, ValueInfo value, PropertyVariation variations) - { - try { - info.SetValue (this, value.Value); - } catch (Exception ex) { - LoggingService.LogError ("Error setting the value", ex); - } - } - } -} - -#endif \ No newline at end of file diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyPadObjectEditor.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyPadObjectEditor.cs deleted file mode 100644 index c272b78a4a4..00000000000 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditors/PropertyPadObjectEditor.cs +++ /dev/null @@ -1,212 +0,0 @@ -// -// PropertyPadObjectEditor.cs -// -// Author: -// jmedrano -// -// Copyright (c) 2018 -// -// 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. - -#if MAC - -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Xamarin.PropertyEditing; -using Xamarin.PropertyEditing.Reflection; -using System.Linq; -using System.ComponentModel; -using System.Collections; -using MonoDevelop.Core; - -namespace MonoDevelop.DesignerSupport -{ - class PropertyPadObjectEditor - : IObjectEditor, INameableObject - { - private readonly PropertyPadItem propertyItem; - public string Name { - get; - private set; - } - - private readonly List properties = new List (); - private static readonly IObjectEditor [] EmptyDirectChildren = new IObjectEditor [0]; - private readonly List events = new List (); - - public object Target => this.propertyItem; - - public ITypeInfo TargetType => ToTypeInfo (Target.GetType ()); - - public static ITypeInfo ToTypeInfo (Type type, bool isRelevant = true) - { - var asm = type.Assembly.GetName ().Name; - return new TypeInfo (new AssemblyInfo (asm, isRelevant), type.Namespace, type.Name); - } - - public IReadOnlyCollection Properties => this.properties; - - public IReadOnlyDictionary KnownProperties => null; - - public IObjectEditor Parent => null; - - public IReadOnlyList DirectChildren => EmptyDirectChildren; - - public IReadOnlyCollection Events => this.events; - - public event EventHandler PropertyChanged; - - public PropertyPadObjectEditor (PropertyPadItem propertyItem) - { - this.propertyItem = propertyItem; - foreach (object propertyProvider in propertyItem.Providers) { - var props = GetProperties (propertyProvider, null); - - for (int i = 0; i < props.Count; i++) { - var prop = props [i] as PropertyDescriptor; - if (prop.IsBrowsable) { - properties.Add (CreatePropertyInfo (prop, propertyProvider)); - } - } - } - } - - bool HasStandardValues (PropertyDescriptor propertyDescriptor) - { - if (propertyDescriptor.Converter.GetStandardValuesSupported ()) { - if (!propertyDescriptor.Converter.GetStandardValuesExclusive () && propertyDescriptor.Converter.CanConvertFrom (typeof (string))) { - return true; - } - } - return false; - } - - PropertyDescriptor GetPropertyDescriptor (PropertyDescriptorCollection collection, string name) - { - for (int i = 0; i < collection.Count; i++) { - if (collection[i].Name == name) { - return collection [i]; - } - } - return null; - } - - protected IPropertyInfo CreatePropertyInfo (PropertyDescriptor propertyDescriptor, object PropertyProvider) - { - var valueSources = ValueSources.Local | ValueSources.Default; - if (propertyDescriptor.PropertyType.IsEnum) { - if (propertyDescriptor.PropertyType.IsDefined (typeof (FlagsAttribute), true)) - return new FlagDescriptorPropertyInfo (propertyDescriptor, PropertyProvider, valueSources); - return new EnumDescriptorPropertyInfo (propertyDescriptor, PropertyProvider, valueSources); - } - - if (propertyDescriptor.PropertyType.IsAssignableFrom (typeof (Core.FilePath))) { - //var isDirectoryPropertyDescriptor = GetPropertyDescriptor (propertyDescriptor.GetChildProperties (), nameof (Core.FilePath.IsDirectory)); - //if (isDirectoryPropertyDescriptor != null && (bool)isDirectoryPropertyDescriptor.GetValue (propertyItem)) { - // return new DirectoryPathPropertyInfo (propertyDescriptor, PropertyProvider, valueSources); - //} - return new FilePathPropertyInfo (propertyDescriptor, PropertyProvider, valueSources); - } - - if (HasStandardValues (propertyDescriptor)) { - return new StringStandardValuesPropertyInfo (propertyDescriptor, PropertyProvider, valueSources); - } - - return new DescriptorPropertyInfo (propertyDescriptor, PropertyProvider, valueSources); - } - - public static PropertyDescriptorCollection GetProperties (object component, Attribute [] attributes) - { - if (component == null) - return new PropertyDescriptorCollection (new PropertyDescriptor [] { }); - return TypeDescriptor.GetProperties (component); - } - - public async Task GetAssignableTypesAsync (IPropertyInfo property, bool childTypes) - { - return new AssignableTypesResult (Array.Empty ()); - } - - public Task> GetHandlersAsync (IEventInfo ev) - { - if (ev == null) - throw new ArgumentNullException (nameof (ev)); - - if (!(ev is Xamarin.PropertyEditing.Reflection.ReflectionEventInfo info)) - throw new ArgumentException (); - - return Task.FromResult (info.GetHandlers (this.propertyItem)); - } - - public Task GetNameAsync () - { - return Task.FromResult (Name); - } - - public Task> GetPropertyVariantsAsync (IPropertyInfo property) - { - return Task.FromResult> (new PropertyVariation [0]); - } - - public async Task> GetValueAsync (IPropertyInfo property, PropertyVariation variations = null) - { - if (property == null) - throw new ArgumentNullException (nameof (property)); - - if (!(property is DescriptorPropertyInfo propertyInfo)) - throw new ArgumentException ("Property should be a DescriptorPropertyInfo", nameof (property)); - - return await propertyItem.GetPropertyValueInfoAsProppyType (propertyInfo); - } - - public Task RemovePropertyVariantAsync (IPropertyInfo property, PropertyVariation variant) - { - return Task.CompletedTask; - } - - public Task SetNameAsync (string name) - { - Name = name; - return Task.FromResult (true); - } - - public Task SetValueAsync (IPropertyInfo propertyInfo, ValueInfo value, PropertyVariation variations = null) - { - if (propertyInfo == null) - throw new ArgumentNullException (nameof (propertyInfo)); - - if (propertyInfo is DescriptorPropertyInfo info && info.CanWrite) { - - propertyItem.SetPropertyValueInfoAsProppyType (info, value, variations); - - OnPropertyChanged (info); - return Task.CompletedTask; - } - throw new ArgumentException ($"Property should be a writeable {nameof (DescriptorPropertyInfo)}.", nameof (propertyInfo)); - } - - protected virtual void OnPropertyChanged (IPropertyInfo property) - { - PropertyChanged?.Invoke (this, new EditorPropertyChangedEventArgs (property)); - } - } -} - -#endif \ No newline at end of file From dd953bbc02e276ce4e149249d70d22afacfe8f18 Mon Sep 17 00:00:00 2001 From: Jose Medrano Date: Thu, 3 Oct 2019 13:01:56 +0200 Subject: [PATCH 08/21] Removes wrong behaviour when no item is selected --- .../PropertyInfo/StringStandardValuesPropertyInfo.cs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs index c21866b4f35..18d3ed54740 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs @@ -73,15 +73,6 @@ internal async override Task GetValueAsync (object target) TValue result = default; result = await base.GetValueAsync (target); - if (typeof (TValue) == typeof (IReadOnlyList) && !result.Equals (default (TValue))) { - string value; - try { - value = predefinedValues.FirstOrDefault ().Key ?? string.Empty; - result = (TValue)(object)value; - } catch (Exception ex) { - LoggingService.LogError (string.Format ("[{0}] Error trying to convert the default value of a StandardValue to default type ({1}) ", Name, typeof(TValue).FullName), ex); - } - } return result; } } From f3126723ba10beadbb32028eae8c82ef8a4a453b Mon Sep 17 00:00:00 2001 From: Jose Medrano Date: Thu, 3 Oct 2019 13:03:33 +0200 Subject: [PATCH 09/21] [PropertyPanel] Generates a ITypeDescriptorContext to get correct StringStandardValues --- .../ComponentModelEditorProvider.cs | 42 ++++++++++++------- .../PropertyInfo/DescriptorPropertyInfo.cs | 42 ++++++++++++++++--- .../EnumDescriptorPropertyInfo.cs | 4 +- .../PropertyInfo/FilePathPropertyInfo.cs | 2 +- .../FlagDescriptorPropertyInfo.cs | 4 +- .../StringStandardValuesPropertyInfo.cs | 11 +++-- 6 files changed, 77 insertions(+), 28 deletions(-) diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelEditorProvider.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelEditorProvider.cs index 61c8831dc31..18b48a1b902 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelEditorProvider.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelEditorProvider.cs @@ -42,16 +42,17 @@ public IReadOnlyDictionary KnownTypes { get; } = new Dictionary (); - object [] providers; + ComponentModelTarget target; - public Task GetObjectEditorAsync (object item) + Task IEditorProvider.GetObjectEditorAsync(object item) { - if (item is ComponentModelTarget propertyPadItem) { - //on each editor we store current used providers - providers = propertyPadItem.Providers ?? Array.Empty (); - return Task.FromResult (new ComponentModelObjectEditor (propertyPadItem)); + target = item as ComponentModelTarget; + if (target == null) { + throw new ArgumentException (string.Format ("Cannot get editor for type {0} only ComponentModelObjectEditor types are allowed", item.GetType ().Name)); } - throw new ArgumentException (string.Format ("Cannot get editor for type {0} only ComponentModelObjectEditor types are allowed", item.GetType ().Name)); + + //on each editor we store current used providers + return Task.FromResult(new ComponentModelObjectEditor(target)); } public Task CreateObjectAsync (ITypeInfo type) @@ -63,7 +64,12 @@ public Task CreateObjectAsync (ITypeInfo type) } public Task> GetPropertiesForTypeAsync (ITypeInfo type) - => Task.Run (() => (IReadOnlyCollection)GetPropertiesForProviders (providers)); + { + return Task.Run (() => { + var prov = target?.Providers ?? Array.Empty (); + return (IReadOnlyCollection)GetPropertiesForProviders (prov); + }); + } public static IReadOnlyList GetPropertiesForProviders (object[] providers) { @@ -78,20 +84,23 @@ public static IReadOnlyList GetPropertiesForProviders (o foreach (System.ComponentModel.PropertyDescriptor propertyDescriptor in propertyDescriptors) { if (propertyDescriptor.IsBrowsable) { - collection.Add (CreatePropertyInfo (propertyDescriptor, propertyProvider)); + var propertyInfo = CreatePropertyInfo (propertyDescriptor, propertyProvider); + collection.Add (propertyInfo); } } } return collection.AsReadOnly (); } - protected static DescriptorPropertyInfo CreatePropertyInfo (System.ComponentModel.PropertyDescriptor propertyDescriptor, object PropertyProvider) + protected static DescriptorPropertyInfo CreatePropertyInfo (System.ComponentModel.PropertyDescriptor propertyDescriptor, object propertyProvider) { + var typeDescriptorContext = new TypeDescriptorContext (propertyProvider, propertyDescriptor); + var valueSources = ValueSources.Local | ValueSources.Default; if (propertyDescriptor.PropertyType.IsEnum) { if (propertyDescriptor.PropertyType.IsDefined (typeof (FlagsAttribute), true)) - return new FlagDescriptorPropertyInfo (propertyDescriptor, PropertyProvider, valueSources); - return new EnumDescriptorPropertyInfo (propertyDescriptor, PropertyProvider, valueSources); + return new FlagDescriptorPropertyInfo (typeDescriptorContext, valueSources); + return new EnumDescriptorPropertyInfo (typeDescriptorContext, valueSources); } if (propertyDescriptor.PropertyType.IsAssignableFrom (typeof (Core.FilePath))) { @@ -99,14 +108,17 @@ protected static DescriptorPropertyInfo CreatePropertyInfo (System.ComponentMode //if (isDirectoryPropertyDescriptor != null && (bool)isDirectoryPropertyDescriptor.GetValue (propertyItem)) { // return new DirectoryPathPropertyInfo (propertyDescriptor, PropertyProvider, valueSources); //} - return new FilePathPropertyInfo (propertyDescriptor, PropertyProvider, valueSources); + return new FilePathPropertyInfo (typeDescriptorContext, valueSources); } if (HasStandardValues (propertyDescriptor)) { - return new StringStandardValuesPropertyInfo (propertyDescriptor, PropertyProvider, valueSources); + var standardValues = propertyDescriptor.Converter.GetStandardValues (typeDescriptorContext); + if (standardValues.Count > 0) { + return new StringStandardValuesPropertyInfo (standardValues, typeDescriptorContext, valueSources); + } } - return new DescriptorPropertyInfo (propertyDescriptor, PropertyProvider, valueSources); + return new DescriptorPropertyInfo (typeDescriptorContext, valueSources); } static bool HasStandardValues (System.ComponentModel.PropertyDescriptor propertyDescriptor) diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/DescriptorPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/DescriptorPropertyInfo.cs index 9ada3a72fcb..139d124d300 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/DescriptorPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/DescriptorPropertyInfo.cs @@ -39,19 +39,51 @@ namespace MonoDevelop.DesignerSupport { + class TypeDescriptorContext : ITypeDescriptorContext + { + public TypeDescriptorContext (object propertyProvider, PropertyDescriptor propertyDescriptor) + { + Instance = propertyProvider; + PropertyDescriptor = propertyDescriptor; + } + + public IContainer Container => null; + + public object Instance { get; } + + public PropertyDescriptor PropertyDescriptor { get; private set; } + + public object GetService (Type serviceType) + { + return null; + } + + public void OnComponentChanged () + { + //TODO ITypeDescriptorContext.OnComponentChanging + } + + public bool OnComponentChanging () + { + //TODO ITypeDescriptorContext.OnComponentChanging + return true; + } + } + class DescriptorPropertyInfo : IPropertyInfo, IEquatable { - public PropertyDescriptor PropertyDescriptor { get; private set; } - public object PropertyProvider { get; private set; } + public object PropertyProvider => typeDescriptorContext.Instance; + readonly TypeDescriptorContext typeDescriptorContext; + + public PropertyDescriptor PropertyDescriptor => typeDescriptorContext.PropertyDescriptor; static readonly IAvailabilityConstraint [] EmptyConstraints = Array.Empty (); static readonly PropertyVariationOption [] EmptyVariationOptions = Array.Empty (); - public DescriptorPropertyInfo (PropertyDescriptor propertyInfo, object propertyProvider, ValueSources valueSources) + public DescriptorPropertyInfo (TypeDescriptorContext typeDescriptorContext, ValueSources valueSources) { - this.PropertyDescriptor = propertyInfo; - this.PropertyProvider = propertyProvider; + this.typeDescriptorContext = typeDescriptorContext; this.ValueSources = valueSources; } diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/EnumDescriptorPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/EnumDescriptorPropertyInfo.cs index 2aca4c28477..6e7a3ca8021 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/EnumDescriptorPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/EnumDescriptorPropertyInfo.cs @@ -42,8 +42,8 @@ class EnumDescriptorPropertyInfo { Hashtable names = new Hashtable (); Array values; - public EnumDescriptorPropertyInfo (PropertyDescriptor propertyDescriptor, object propertyProvider, ValueSources valueSources) - : base (propertyDescriptor, propertyProvider, valueSources) + public EnumDescriptorPropertyInfo (TypeDescriptorContext typeDescriptorContext, ValueSources valueSources) + : base (typeDescriptorContext, valueSources) { values = Enum.GetValues (PropertyDescriptor.PropertyType); diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FilePathPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FilePathPropertyInfo.cs index a57f45d4eed..75382e6717a 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FilePathPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FilePathPropertyInfo.cs @@ -36,7 +36,7 @@ namespace MonoDevelop.DesignerSupport class FilePathPropertyInfo : DescriptorPropertyInfo, IEquatable { - public FilePathPropertyInfo (PropertyDescriptor propertyInfo, object propertyProvider, ValueSources valueSources) : base (propertyInfo, propertyProvider, valueSources) + public FilePathPropertyInfo (TypeDescriptorContext typeDescriptorContext, ValueSources valueSources) : base (typeDescriptorContext, valueSources) { } diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FlagDescriptorPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FlagDescriptorPropertyInfo.cs index 8265b039e7f..92720c3e118 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FlagDescriptorPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FlagDescriptorPropertyInfo.cs @@ -39,10 +39,10 @@ namespace MonoDevelop.DesignerSupport class FlagDescriptorPropertyInfo : DescriptorPropertyInfo, IHavePredefinedValues { - public FlagDescriptorPropertyInfo (PropertyDescriptor propertyDescriptor, object propertyProvider, ValueSources valueSources) : base (propertyDescriptor, propertyProvider, valueSources) + public FlagDescriptorPropertyInfo (TypeDescriptorContext typeDescriptorContext, ValueSources valueSources) : base (typeDescriptorContext, valueSources) { IsValueCombinable = true; - foreach (object value in System.Enum.GetValues (propertyDescriptor.PropertyType)) { + foreach (object value in System.Enum.GetValues (typeDescriptorContext.PropertyDescriptor.PropertyType)) { ulong uintVal = Convert.ToUInt64 (value); predefinedValues.Add (value.ToString (), uintVal.ToString ()); } diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs index 18d3ed54740..47121d2a0a0 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs @@ -39,10 +39,15 @@ namespace MonoDevelop.DesignerSupport class StringStandardValuesPropertyInfo : DescriptorPropertyInfo, IHavePredefinedValues { - public StringStandardValuesPropertyInfo (PropertyDescriptor propertyDescriptor, object propertyProvider, ValueSources valueSources) : base (propertyDescriptor, propertyProvider, valueSources) + readonly List standardValues = new List (); + + //const string splitCharacter = "--"; + + public StringStandardValuesPropertyInfo (TypeConverter.StandardValuesCollection standardValuesCollection, TypeDescriptorContext typeDescriptorContext, ValueSources valueSources) : base (typeDescriptorContext, valueSources) { - foreach (object stdValue in PropertyDescriptor.Converter.GetStandardValues ()) { + foreach (object stdValue in standardValuesCollection) { var value = PropertyDescriptor.Converter.ConvertToString (stdValue); + standardValues.Add (value); predefinedValues.Add (value, value); } } @@ -64,7 +69,7 @@ internal override void SetValue (object target, T value) LogInternalError ($"Error trying to set and convert a value: {value} T:{typeof (T).FullName}", ex); } } else { - base.SetValue (target, value); + base.SetValue (target, value); } } From 9de84d76ed30df532e26cf1404d84f62fb62ff9c Mon Sep 17 00:00:00 2001 From: Jose Medrano Date: Thu, 3 Oct 2019 16:06:25 +0200 Subject: [PATCH 10/21] Adds a separator string based in System.ComponentModel separator identifiers --- .../NativePropertyEditor/ComponentModelObjectEditor.cs | 2 ++ .../PropertyInfo/EnumDescriptorPropertyInfo.cs | 2 ++ .../PropertyInfo/FlagDescriptorPropertyInfo.cs | 2 ++ .../PropertyInfo/StringStandardValuesPropertyInfo.cs | 2 +- 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelObjectEditor.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelObjectEditor.cs index 445488a0880..55e636bdba7 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelObjectEditor.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelObjectEditor.cs @@ -37,6 +37,8 @@ namespace MonoDevelop.DesignerSupport class ComponentModelObjectEditor : IObjectEditor, INameableObject { + internal const string ComboSeparatorString = "--"; + private readonly ComponentModelTarget propertyItem; public string Name { get; private set; } diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/EnumDescriptorPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/EnumDescriptorPropertyInfo.cs index 6e7a3ca8021..7506699a33d 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/EnumDescriptorPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/EnumDescriptorPropertyInfo.cs @@ -40,6 +40,8 @@ namespace MonoDevelop.DesignerSupport class EnumDescriptorPropertyInfo : DescriptorPropertyInfo, IHavePredefinedValues { + public string SeparatorString => ComponentModelObjectEditor.ComboSeparatorString; + Hashtable names = new Hashtable (); Array values; public EnumDescriptorPropertyInfo (TypeDescriptorContext typeDescriptorContext, ValueSources valueSources) diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FlagDescriptorPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FlagDescriptorPropertyInfo.cs index 92720c3e118..717abc85307 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FlagDescriptorPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FlagDescriptorPropertyInfo.cs @@ -90,6 +90,8 @@ public bool IsValueCombinable { readonly protected Dictionary predefinedValues = new Dictionary (); public IReadOnlyDictionary PredefinedValues => predefinedValues; + + public string SeparatorString => ComponentModelObjectEditor.ComboSeparatorString; } } diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs index 47121d2a0a0..3bf37013981 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs @@ -41,7 +41,7 @@ class StringStandardValuesPropertyInfo { readonly List standardValues = new List (); - //const string splitCharacter = "--"; + public string SeparatorString => ComponentModelObjectEditor.ComboSeparatorString; public StringStandardValuesPropertyInfo (TypeConverter.StandardValuesCollection standardValuesCollection, TypeDescriptorContext typeDescriptorContext, ValueSources valueSources) : base (typeDescriptorContext, valueSources) { From ec19db6e7182b24586e266cbfab222ba7726960e Mon Sep 17 00:00:00 2001 From: Jose Medrano Date: Thu, 3 Oct 2019 21:34:05 +0200 Subject: [PATCH 11/21] Some changes to run update in main thread --- .../ComponentModelObjectEditor.cs | 11 +++---- .../PropertyInfo/DescriptorPropertyInfo.cs | 22 +++++++++++-- .../EnumDescriptorPropertyInfo.cs | 33 ++++++++++--------- .../StringStandardValuesPropertyInfo.cs | 28 ++++++++-------- 4 files changed, 56 insertions(+), 38 deletions(-) diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelObjectEditor.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelObjectEditor.cs index 55e636bdba7..4f4f07c8bd4 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelObjectEditor.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelObjectEditor.cs @@ -114,24 +114,23 @@ public Task SetNameAsync (string name) return Task.FromResult (true); } - public Task SetValueAsync (IPropertyInfo propertyInfo, ValueInfo value, PropertyVariation variations = null) + public async Task SetValueAsync (IPropertyInfo propertyInfo, ValueInfo value, PropertyVariation variations = null) { try { if (propertyInfo == null) throw new ArgumentNullException (nameof (propertyInfo)); if (propertyInfo is DescriptorPropertyInfo info && info.CanWrite) { - - info.SetValue (this, value.Value); - OnPropertyChanged (info); - + await Runtime.RunInMainThread (() => { + info.SetValue (this, value.Value); + OnPropertyChanged (info); + }); } else { throw new ArgumentException ($"Property should be a writeable {nameof (DescriptorPropertyInfo)}.", nameof (propertyInfo)); } } catch (Exception ex) { LoggingService.LogError ("Error setting the value", ex); } - return Task.CompletedTask; } protected virtual void OnPropertyChanged (IPropertyInfo property) diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/DescriptorPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/DescriptorPropertyInfo.cs index 139d124d300..d4d6428399b 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/DescriptorPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/DescriptorPropertyInfo.cs @@ -74,7 +74,7 @@ class DescriptorPropertyInfo : IPropertyInfo, IEquatable { public object PropertyProvider => typeDescriptorContext.Instance; - readonly TypeDescriptorContext typeDescriptorContext; + protected readonly TypeDescriptorContext typeDescriptorContext; public PropertyDescriptor PropertyDescriptor => typeDescriptorContext.PropertyDescriptor; @@ -163,12 +163,28 @@ internal virtual Task GetValueAsync (object target) return Task.FromResult (converted); } + bool IsNullable (Type type) => Nullable.GetUnderlyingType (type) != null; + internal virtual void SetValue (object target, T value) { try { - PropertyDescriptor.SetValue (PropertyProvider, value); + + var currentType = typeof (T) ; + + //TODO: we don't support nulleable types in editors yet + currentType = Nullable.GetUnderlyingType (currentType) ?? currentType; + object notNulleableValue = Convert.ChangeType (value, currentType); + + var tc = PropertyDescriptor.Converter; + if (tc.CanConvertFrom (currentType)) { + var result = tc.ConvertFrom (notNulleableValue); + PropertyDescriptor.SetValue (PropertyProvider, result); + } else { + notNulleableValue = Convert.ChangeType (value, this.Type); + PropertyDescriptor.SetValue (PropertyProvider, notNulleableValue); + } } catch (Exception ex) { - LogInternalError ($"Error trying to set and convert value:'{value}' T:{typeof (T).FullName} ", ex); + LogInternalError ($"Error trying to set and convert a value: {value} T:{typeof (T).FullName}", ex); } } diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/EnumDescriptorPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/EnumDescriptorPropertyInfo.cs index 7506699a33d..bf3c979152b 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/EnumDescriptorPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/EnumDescriptorPropertyInfo.cs @@ -70,21 +70,6 @@ public EnumDescriptorPropertyInfo (TypeDescriptorContext typeDescriptorContext, } } - internal override void SetValue (object target, T value) - { - var tc = PropertyDescriptor.Converter; - if (tc.CanConvertFrom (typeof (T))) { - try { - var item = tc.ConvertFrom (value); - PropertyDescriptor.SetValue (PropertyProvider, item); - } catch (Exception ex) { - LogInternalError ($"Error trying to set and convert a value: {value} T:{typeof (T).FullName}", ex); - } - } else { - base.SetValue (target, value); - } - } - static int GetIndexOfValue (Array values, string value) { for (int i = 0; i < values.Length; i++) { @@ -114,6 +99,24 @@ internal async override Task GetValueAsync (object target) return result; } + internal override void SetValue (object target, T value) + { + try { + var intValue = (int)Convert.ChangeType (value, typeof (int)); + var objValue = values.GetValue (intValue); + var tc = PropertyDescriptor.Converter; + if (tc.CanConvertFrom (objValue.GetType ())) { + var result = tc.ConvertFrom (objValue); + PropertyDescriptor.SetValue (PropertyProvider, result); + } else { + PropertyDescriptor.SetValue (PropertyProvider, objValue); + } + } catch (Exception ex) { + LogInternalError ($"Error trying to set and convert a value: {value} T:{typeof (T).FullName}... trying to use base converter...", ex); + base.SetValue (target, value); + } + } + public bool IsConstrainedToPredefined => true; public bool IsValueCombinable { diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs index 3bf37013981..3c5dcca7220 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs @@ -39,7 +39,7 @@ namespace MonoDevelop.DesignerSupport class StringStandardValuesPropertyInfo : DescriptorPropertyInfo, IHavePredefinedValues { - readonly List standardValues = new List (); + readonly Dictionary standardValues = new Dictionary (); public string SeparatorString => ComponentModelObjectEditor.ComboSeparatorString; @@ -47,24 +47,32 @@ public StringStandardValuesPropertyInfo (TypeConverter.StandardValuesCollection { foreach (object stdValue in standardValuesCollection) { var value = PropertyDescriptor.Converter.ConvertToString (stdValue); - standardValues.Add (value); + standardValues.Add (value, stdValue); predefinedValues.Add (value, value); } } public bool IsConstrainedToPredefined => true; - public bool IsValueCombinable { get; } protected Dictionary predefinedValues = new Dictionary (); public IReadOnlyDictionary PredefinedValues => predefinedValues; + internal override Task GetValueAsync (object target) + { + return base.GetValueAsync (target); + } + internal override void SetValue (object target, T value) { - var tc = PropertyDescriptor.Converter; - if (tc.CanConvertFrom (typeof (T))) { + if (value is string textValue) { try { - PropertyDescriptor.SetValue (PropertyProvider, tc.ConvertTo (value, PropertyDescriptor.ComponentType)); + object objValue; + if (standardValues.TryGetValue (textValue,out objValue)) { + PropertyDescriptor.SetValue (PropertyProvider, objValue); + } else { + throw new Exception ("Value selected doesn't exists in the current standardValuesCollection"); + } } catch (Exception ex) { LogInternalError ($"Error trying to set and convert a value: {value} T:{typeof (T).FullName}", ex); } @@ -72,14 +80,6 @@ internal override void SetValue (object target, T value) base.SetValue (target, value); } } - - internal async override Task GetValueAsync (object target) - { - TValue result = default; - result = await base.GetValueAsync (target); - - return result; - } } } From bff4d7f74a9cb09a94392fdd8dc33f07a8c64aad Mon Sep 17 00:00:00 2001 From: Jose Medrano Date: Fri, 4 Oct 2019 11:27:17 +0200 Subject: [PATCH 12/21] Rename PropertyPadItem to ComponentModelTarget --- .../MonoDevelop.DesignerSupport.csproj | 2 +- .../{PropertyPadItem.cs => ComponentModelTarget.cs} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/{PropertyPadItem.cs => ComponentModelTarget.cs} (100%) diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.csproj b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.csproj index 21d6114487e..24a02a42a4b 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.csproj +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.csproj @@ -145,7 +145,7 @@ - + diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyPadItem.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelTarget.cs similarity index 100% rename from main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyPadItem.cs rename to main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelTarget.cs From 6557a629b1f3a0d83173036efab3cb9ca7703da9 Mon Sep 17 00:00:00 2001 From: Jose Medrano Date: Fri, 4 Oct 2019 13:09:44 +0200 Subject: [PATCH 13/21] Removes unnecessary async GetValue --- .../NativePropertyEditor/ComponentModelObjectEditor.cs | 7 ++++--- .../PropertyInfo/DescriptorPropertyInfo.cs | 4 ++-- .../PropertyInfo/EnumDescriptorPropertyInfo.cs | 4 ++-- .../PropertyInfo/FilePathPropertyInfo.cs | 6 +++--- .../PropertyInfo/FlagDescriptorPropertyInfo.cs | 6 +++--- .../PropertyInfo/StringStandardValuesPropertyInfo.cs | 4 ++-- 6 files changed, 16 insertions(+), 15 deletions(-) diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelObjectEditor.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelObjectEditor.cs index 4f4f07c8bd4..f35a6e4dd6d 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelObjectEditor.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelObjectEditor.cs @@ -91,7 +91,7 @@ public async Task GetAssignableTypesAsync (IPropertyInfo public Task> GetPropertyVariantsAsync (IPropertyInfo property) => Task.FromResult> (Array.Empty ()); - public async Task> GetValueAsync (IPropertyInfo property, PropertyVariation variations = null) + public Task> GetValueAsync (IPropertyInfo property, PropertyVariation variations = null) { if (property == null) throw new ArgumentNullException (nameof (property)); @@ -99,11 +99,12 @@ public async Task> GetValueAsync (IPropertyInfo property, Proper if (!(property is DescriptorPropertyInfo propertyInfo)) throw new ArgumentException ("Property should be a DescriptorPropertyInfo", nameof (property)); - T value = await propertyInfo.GetValueAsync (this); - return new ValueInfo { + T value = propertyInfo.GetValue (this); + var valueInfo = new ValueInfo { Value = value, Source = ValueSource.Local, }; + return Task.FromResult (valueInfo); } public Task RemovePropertyVariantAsync (IPropertyInfo property, PropertyVariation variant) => Task.CompletedTask; diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/DescriptorPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/DescriptorPropertyInfo.cs index d4d6428399b..95f4c7df27d 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/DescriptorPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/DescriptorPropertyInfo.cs @@ -143,7 +143,7 @@ public static ITypeInfo ToTypeInfo (Type type, bool isRelevant = true) return new Xamarin.PropertyEditing.TypeInfo (new AssemblyInfo (asm, isRelevant), type.Namespace, type.Name); } - internal virtual Task GetValueAsync (object target) + internal virtual T GetValue (object target) { T converted = default; object value = null; @@ -160,7 +160,7 @@ internal virtual Task GetValueAsync (object target) } catch (Exception ex) { LogInternalError ($"Error trying to get and convert value:'{value}' canconvert: {canConvert} T:{typeof (T).FullName} ", ex); } - return Task.FromResult (converted); + return converted; } bool IsNullable (Type type) => Nullable.GetUnderlyingType (type) != null; diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/EnumDescriptorPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/EnumDescriptorPropertyInfo.cs index bf3c979152b..c461c390ae3 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/EnumDescriptorPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/EnumDescriptorPropertyInfo.cs @@ -80,12 +80,12 @@ static int GetIndexOfValue (Array values, string value) return -1; } - internal async override Task GetValueAsync (object target) + internal override T GetValue (object target) { //we need set the index of the selected item T result = default; try { - result = await base.GetValueAsync (target); + result = base.GetValue (target); string cob = result as string; var index = GetIndexOfValue (values, cob); if (index > -1) { diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FilePathPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FilePathPropertyInfo.cs index 75382e6717a..8be1cbd2dea 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FilePathPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FilePathPropertyInfo.cs @@ -55,17 +55,17 @@ internal override void SetValue (object target, T value) } } - internal override Task GetValueAsync (object target) + internal override T GetValue (object target) { try { if (target is Core.FilePath directoryPath) { T result = (T)(object)new Xamarin.PropertyEditing.Common.FilePath (directoryPath.FullPath); - return Task.FromResult (result); + return result; } } catch (Exception ex) { LogInternalError ($"Error trying to get and convert value:'{target}' T:{typeof (T).FullName} ", ex); } - return base.GetValueAsync (target); + return base.GetValue (target); } } } diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FlagDescriptorPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FlagDescriptorPropertyInfo.cs index 717abc85307..f8cdac258c3 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FlagDescriptorPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FlagDescriptorPropertyInfo.cs @@ -62,7 +62,7 @@ internal override void SetValue (object target, T value) } } - internal override Task GetValueAsync (object target) + internal override T GetValue (object target) { //we need set the index of the selected item try { @@ -75,11 +75,11 @@ internal override Task GetValueAsync (object target) result.Add (uintVal.ToString ()); } } - return Task.FromResult ((T)(object)result); + return (T)(object)result; } catch (Exception ex) { LogInternalError ($"Error trying to get values from a Enum", ex); } - return Task.FromResult (default); + return default; } public bool IsConstrainedToPredefined => true; diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs index 3c5dcca7220..60936434bb5 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs @@ -58,9 +58,9 @@ public StringStandardValuesPropertyInfo (TypeConverter.StandardValuesCollection protected Dictionary predefinedValues = new Dictionary (); public IReadOnlyDictionary PredefinedValues => predefinedValues; - internal override Task GetValueAsync (object target) + internal override TValue GetValue (object target) { - return base.GetValueAsync (target); + return base.GetValue (target); } internal override void SetValue (object target, T value) From eda776f92c00e22166ddbe3d87e678f596104ca7 Mon Sep 17 00:00:00 2001 From: Jose Medrano Date: Fri, 4 Oct 2019 14:04:49 +0200 Subject: [PATCH 14/21] Fixes FlagDescriptorPropertyInfo get info behaviour --- .../FlagDescriptorPropertyInfo.cs | 39 ++++++++++++------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FlagDescriptorPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FlagDescriptorPropertyInfo.cs index f8cdac258c3..596eb0cba01 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FlagDescriptorPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FlagDescriptorPropertyInfo.cs @@ -39,10 +39,16 @@ namespace MonoDevelop.DesignerSupport class FlagDescriptorPropertyInfo : DescriptorPropertyInfo, IHavePredefinedValues { + + Array elements; + public FlagDescriptorPropertyInfo (TypeDescriptorContext typeDescriptorContext, ValueSources valueSources) : base (typeDescriptorContext, valueSources) { IsValueCombinable = true; - foreach (object value in System.Enum.GetValues (typeDescriptorContext.PropertyDescriptor.PropertyType)) { + + elements = System.Enum.GetValues (typeDescriptorContext.PropertyDescriptor.PropertyType); + + foreach (object value in elements) { ulong uintVal = Convert.ToUInt64 (value); predefinedValues.Add (value.ToString (), uintVal.ToString ()); } @@ -64,22 +70,27 @@ internal override void SetValue (object target, T value) internal override T GetValue (object target) { - //we need set the index of the selected item - try { - var myValue = (Enum)target; - var result = new List (); - foreach (Enum item in Enum.GetValues (target.GetType ())) - { - if (myValue.HasFlag (item)) { - ulong uintVal = Convert.ToUInt64 (item); - result.Add (uintVal.ToString ()); + if (typeof (T) == typeof (IReadOnlyList)) { + //we need set the index of the selected item + try { + var currentObject = PropertyDescriptor.GetValue (PropertyProvider); + var currentEnum = (Enum)currentObject; + var result = new List (); + foreach (Enum item in elements) { + if (currentEnum.HasFlag (item)) { + ulong uintVal = Convert.ToUInt64 (item); + result.Add (uintVal.ToString ()); + } } + + return (T)(object)result.AsReadOnly (); + } catch (Exception ex) { + LogInternalError ($"Error trying to get values from a Enum", ex); } - return (T)(object)result; - } catch (Exception ex) { - LogInternalError ($"Error trying to get values from a Enum", ex); } - return default; + + var baseValue = base.GetValue (target); + return baseValue; } public bool IsConstrainedToPredefined => true; From 2e1a59663fa9eb6b21981dde707139e987b2b786 Mon Sep 17 00:00:00 2001 From: Jose Medrano Date: Fri, 4 Oct 2019 16:33:04 +0200 Subject: [PATCH 15/21] Fixes current FilePath property to get the correct value from property provider --- .../PropertyInfo/FilePathPropertyInfo.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FilePathPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FilePathPropertyInfo.cs index 8be1cbd2dea..c77542789c2 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FilePathPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FilePathPropertyInfo.cs @@ -58,8 +58,9 @@ internal override void SetValue (object target, T value) internal override T GetValue (object target) { try { - if (target is Core.FilePath directoryPath) { - T result = (T)(object)new Xamarin.PropertyEditing.Common.FilePath (directoryPath.FullPath); + var currentObject = PropertyDescriptor.GetValue (PropertyProvider); + if (currentObject is Core.FilePath filePath) { + T result = (T)(object)new Xamarin.PropertyEditing.Common.FilePath (filePath.FullPath); return result; } } catch (Exception ex) { From 060e607fec008634d352cf9ced5dad623e490fc2 Mon Sep 17 00:00:00 2001 From: Jose Medrano Date: Fri, 4 Oct 2019 18:46:37 +0200 Subject: [PATCH 16/21] PropertyChanged event is not correctly tunneled to DesignerService --- .../MacPropertyGrid.cs | 17 ++++++++++++ .../ComponentModelEditorProvider.cs | 26 ++++++++++++++++--- .../ComponentModelObjectEditor.cs | 7 ++--- .../PropertyPad.cs | 3 ++- 4 files changed, 43 insertions(+), 10 deletions(-) diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/MacPropertyGrid.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/MacPropertyGrid.cs index 3bdf974d952..488d513d117 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/MacPropertyGrid.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/MacPropertyGrid.cs @@ -59,12 +59,17 @@ public MacPropertyGrid () AddSubview (propertyEditorPanel); editorProvider = new ComponentModelEditorProvider (); + editorProvider.PropertyChanged += EditorProvider_PropertyChanged; + propertyEditorPanel.TargetPlatform = new TargetPlatform (editorProvider) { AutoExpandAll = true }; propertyEditorPanel.ArrangeMode = PropertyArrangeMode.Category; } + private void EditorProvider_PropertyChanged (object sender, EventArgs e) => + PropertyGridChanged?.Invoke (this, EventArgs.Empty); + public override void SetFrameSize (CGSize newSize) { base.SetFrameSize (newSize); @@ -103,6 +108,18 @@ public void OnPadContentShown () { //not implemented } + + protected override void Dispose (bool disposing) + { + if (disposing) { + if (editorProvider != null) { + editorProvider.PropertyChanged -= EditorProvider_PropertyChanged; + editorProvider.Dispose (); + editorProvider = null; + } + } + base.Dispose (disposing); + } } class MacPropertyEditorPanel : PropertyEditorPanel diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelEditorProvider.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelEditorProvider.cs index 18b48a1b902..7904fda0a8e 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelEditorProvider.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelEditorProvider.cs @@ -26,23 +26,24 @@ #if MAC -using System.Linq; using System; using System.Collections.Generic; using System.Threading.Tasks; using Xamarin.PropertyEditing; -using MonoDevelop.Core; namespace MonoDevelop.DesignerSupport { class ComponentModelEditorProvider - : IEditorProvider + : IEditorProvider, IDisposable { + public event EventHandler PropertyChanged; + public IReadOnlyDictionary KnownTypes { get; } = new Dictionary (); ComponentModelTarget target; + ComponentModelObjectEditor currentEditor; Task IEditorProvider.GetObjectEditorAsync(object item) { @@ -51,10 +52,20 @@ Task IEditorProvider.GetObjectEditorAsync(object item) throw new ArgumentException (string.Format ("Cannot get editor for type {0} only ComponentModelObjectEditor types are allowed", item.GetType ().Name)); } + if (currentEditor != null) { + currentEditor.PropertyChanged -= CurrentEditor_PropertyChanged; + } + + currentEditor = new ComponentModelObjectEditor (target); + currentEditor.PropertyChanged += CurrentEditor_PropertyChanged; + //on each editor we store current used providers - return Task.FromResult(new ComponentModelObjectEditor(target)); + return Task.FromResult(currentEditor); } + void CurrentEditor_PropertyChanged (object sender, EventArgs e) + => PropertyChanged?.Invoke (this, e); + public Task CreateObjectAsync (ITypeInfo type) { var realType = Type.GetType ($"{type.NameSpace}.{type.Name}, {type.Assembly.Name}"); @@ -142,6 +153,13 @@ public Task GetAssignableTypesAsync (ITypeInfo type, bool public Task> GetChildrenAsync (object item) => Task.FromResult> (Array.Empty ()); + + public void Dispose () + { + if (currentEditor != null) { + currentEditor.PropertyChanged -= CurrentEditor_PropertyChanged; + } + } } } diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelObjectEditor.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelObjectEditor.cs index f35a6e4dd6d..3674c3fc93d 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelObjectEditor.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelObjectEditor.cs @@ -124,7 +124,7 @@ public async Task SetValueAsync (IPropertyInfo propertyInfo, ValueInfo val if (propertyInfo is DescriptorPropertyInfo info && info.CanWrite) { await Runtime.RunInMainThread (() => { info.SetValue (this, value.Value); - OnPropertyChanged (info); + RaisePropertyChanged (info); }); } else { throw new ArgumentException ($"Property should be a writeable {nameof (DescriptorPropertyInfo)}.", nameof (propertyInfo)); @@ -134,10 +134,7 @@ await Runtime.RunInMainThread (() => { } } - protected virtual void OnPropertyChanged (IPropertyInfo property) - { - PropertyChanged?.Invoke (this, new EditorPropertyChangedEventArgs (property)); - } + protected void RaisePropertyChanged (IPropertyInfo property) => PropertyChanged?.Invoke (this, new EditorPropertyChangedEventArgs (property)); } } diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/PropertyPad.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/PropertyPad.cs index 1f66e4ed649..c666f5ad9ad 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/PropertyPad.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/PropertyPad.cs @@ -76,7 +76,7 @@ public PropertyPad () nativeGrid = new MacPropertyGrid (); propertyGrid = nativeGrid; - + nativeGrid.PropertyGridChanged += Grid_Changed; gtkWidget = new GtkNSViewHost (nativeGrid); frame.Add (gtkWidget); @@ -127,6 +127,7 @@ public override void Dispose() #if MAC if (isNative) { container.PadContentShown -= Window_PadContentShown; + nativeGrid.PropertyGridChanged -= Grid_Changed; } else { #endif grid.Changed -= Grid_Changed; From adab1a4aeeb6e362ddd6e7ef520b1242862faf26 Mon Sep 17 00:00:00 2001 From: Jose Medrano Date: Fri, 4 Oct 2019 19:15:00 +0200 Subject: [PATCH 17/21] Fixes get default values in enumeration values --- .../PropertyInfo/EnumDescriptorPropertyInfo.cs | 6 ++++++ .../PropertyInfo/FlagDescriptorPropertyInfo.cs | 6 ++++++ .../PropertyInfo/StringStandardValuesPropertyInfo.cs | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/EnumDescriptorPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/EnumDescriptorPropertyInfo.cs index c461c390ae3..33d6fb6523a 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/EnumDescriptorPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/EnumDescriptorPropertyInfo.cs @@ -101,6 +101,12 @@ internal override T GetValue (object target) internal override void SetValue (object target, T value) { + if (EqualityComparer.Default.Equals (value, default)) { + var defaultValue = PropertyDescriptor.GetValue (PropertyProvider); + PropertyDescriptor.SetValue (PropertyProvider, defaultValue); + return; + } + try { var intValue = (int)Convert.ChangeType (value, typeof (int)); var objValue = values.GetValue (intValue); diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FlagDescriptorPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FlagDescriptorPropertyInfo.cs index 596eb0cba01..c944292b167 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FlagDescriptorPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FlagDescriptorPropertyInfo.cs @@ -56,6 +56,12 @@ public FlagDescriptorPropertyInfo (TypeDescriptorContext typeDescriptorContext, internal override void SetValue (object target, T value) { + if (EqualityComparer.Default.Equals (value, default)) { + var defaultValue = PropertyDescriptor.GetValue (PropertyProvider); + PropertyDescriptor.SetValue (PropertyProvider, defaultValue); + return; + } + try { var selectedValues = (System.String []) (object)value; ulong result = default; diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs index 60936434bb5..10818a2e096 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs @@ -65,6 +65,12 @@ internal override TValue GetValue (object target) internal override void SetValue (object target, T value) { + if (EqualityComparer.Default.Equals (value, default)) { + var defaultValue = PropertyDescriptor.GetValue (PropertyProvider); + PropertyDescriptor.SetValue (PropertyProvider, defaultValue); + return; + } + if (value is string textValue) { try { object objValue; From 0beeb0615a9da299a0c35ad4876f8d89a353d697 Mon Sep 17 00:00:00 2001 From: Jose Medrano Date: Fri, 4 Oct 2019 20:29:43 +0200 Subject: [PATCH 18/21] Some code fixes --- .../ComponentModelEditorProvider.cs | 4 +-- .../ComponentModelObjectEditor.cs | 28 +++++++++---------- .../PropertyInfo/DescriptorPropertyInfo.cs | 7 ++--- .../EnumDescriptorPropertyInfo.cs | 2 -- .../FlagDescriptorPropertyInfo.cs | 9 +----- .../StringStandardValuesPropertyInfo.cs | 6 ++-- 6 files changed, 23 insertions(+), 33 deletions(-) diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelEditorProvider.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelEditorProvider.cs index 7904fda0a8e..b246ffb5a27 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelEditorProvider.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelEditorProvider.cs @@ -68,7 +68,7 @@ void CurrentEditor_PropertyChanged (object sender, EventArgs e) public Task CreateObjectAsync (ITypeInfo type) { - var realType = Type.GetType ($"{type.NameSpace}.{type.Name}, {type.Assembly.Name}"); + var realType = GetRealType (type); if (realType == null) return Task.FromResult (null); return Task.FromResult (Activator.CreateInstance (realType)); @@ -109,7 +109,7 @@ protected static DescriptorPropertyInfo CreatePropertyInfo (System.ComponentMode var valueSources = ValueSources.Local | ValueSources.Default; if (propertyDescriptor.PropertyType.IsEnum) { - if (propertyDescriptor.PropertyType.IsDefined (typeof (FlagsAttribute), true)) + if (propertyDescriptor.PropertyType.IsDefined (typeof (FlagsAttribute), inherit: false)) return new FlagDescriptorPropertyInfo (typeDescriptorContext, valueSources); return new EnumDescriptorPropertyInfo (typeDescriptorContext, valueSources); } diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelObjectEditor.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelObjectEditor.cs index 3674c3fc93d..3d19d28abb6 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelObjectEditor.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelObjectEditor.cs @@ -79,25 +79,24 @@ public ComponentModelObjectEditor (ComponentModelTarget propertyItem) this.properties.AddRange (ComponentModelEditorProvider.GetPropertiesForProviders (propertyItem.Providers)); } - public async Task GetAssignableTypesAsync (IPropertyInfo property, bool childTypes) - { - return new AssignableTypesResult (Array.Empty ()); - } + public Task GetAssignableTypesAsync (IPropertyInfo property, bool childTypes) + => Task.FromResult(new AssignableTypesResult (Array.Empty ())); public Task> GetHandlersAsync (IEventInfo ev) => Task.FromResult(defaultHandlerList); public Task GetNameAsync () => Task.FromResult (Name); public Task> GetPropertyVariantsAsync (IPropertyInfo property) - => Task.FromResult> (Array.Empty ()); + => Task.FromResult> (Array.Empty ()); public Task> GetValueAsync (IPropertyInfo property, PropertyVariation variations = null) { if (property == null) throw new ArgumentNullException (nameof (property)); - if (!(property is DescriptorPropertyInfo propertyInfo)) - throw new ArgumentException ("Property should be a DescriptorPropertyInfo", nameof (property)); + if (!(property is DescriptorPropertyInfo propertyInfo)) { + return Task.FromException> (new ArgumentException ($"Property should be a {nameof (DescriptorPropertyInfo)}", nameof (property))); + } T value = propertyInfo.GetValue (this); var valueInfo = new ValueInfo { @@ -112,26 +111,25 @@ public Task> GetValueAsync (IPropertyInfo property, PropertyVari public Task SetNameAsync (string name) { Name = name; - return Task.FromResult (true); + return Task.CompletedTask; } - public async Task SetValueAsync (IPropertyInfo propertyInfo, ValueInfo value, PropertyVariation variations = null) + public Task SetValueAsync (IPropertyInfo propertyInfo, ValueInfo value, PropertyVariation variations = null) { try { if (propertyInfo == null) - throw new ArgumentNullException (nameof (propertyInfo)); + return Task.FromException (new ArgumentNullException (nameof (propertyInfo))); if (propertyInfo is DescriptorPropertyInfo info && info.CanWrite) { - await Runtime.RunInMainThread (() => { - info.SetValue (this, value.Value); - RaisePropertyChanged (info); - }); + info.SetValue (this, value.Value); + RaisePropertyChanged (info); } else { - throw new ArgumentException ($"Property should be a writeable {nameof (DescriptorPropertyInfo)}.", nameof (propertyInfo)); + return Task.FromException (new ArgumentException ($"Property should be a writeable {nameof (DescriptorPropertyInfo)}.", nameof (propertyInfo))); } } catch (Exception ex) { LoggingService.LogError ("Error setting the value", ex); } + return Task.CompletedTask; } protected void RaisePropertyChanged (IPropertyInfo property) => PropertyChanged?.Invoke (this, new EditorPropertyChangedEventArgs (property)); diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/DescriptorPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/DescriptorPropertyInfo.cs index 95f4c7df27d..be7ead2146c 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/DescriptorPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/DescriptorPropertyInfo.cs @@ -152,7 +152,7 @@ internal virtual T GetValue (object target) value = PropertyDescriptor.GetValue (PropertyProvider); var tc = PropertyDescriptor.Converter; canConvert = tc.CanConvertTo (typeof (T)); - if (tc.CanConvertTo (typeof (T))) { + if (canConvert) { converted = (T)tc.ConvertTo (value, typeof (T)); } else { converted = (T)value; @@ -163,15 +163,14 @@ internal virtual T GetValue (object target) return converted; } - bool IsNullable (Type type) => Nullable.GetUnderlyingType (type) != null; - internal virtual void SetValue (object target, T value) { try { var currentType = typeof (T) ; - //TODO: we don't support nulleable types in editors yet + //TODO: Proppy in Boolean types uses bool? to handle it, but this will fail using converters + //thats because we need ensure take the underlying type currentType = Nullable.GetUnderlyingType (currentType) ?? currentType; object notNulleableValue = Convert.ChangeType (value, currentType); diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/EnumDescriptorPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/EnumDescriptorPropertyInfo.cs index 33d6fb6523a..f1140494dfa 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/EnumDescriptorPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/EnumDescriptorPropertyInfo.cs @@ -40,8 +40,6 @@ namespace MonoDevelop.DesignerSupport class EnumDescriptorPropertyInfo : DescriptorPropertyInfo, IHavePredefinedValues { - public string SeparatorString => ComponentModelObjectEditor.ComboSeparatorString; - Hashtable names = new Hashtable (); Array values; public EnumDescriptorPropertyInfo (TypeDescriptorContext typeDescriptorContext, ValueSources valueSources) diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FlagDescriptorPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FlagDescriptorPropertyInfo.cs index c944292b167..3bfad421846 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FlagDescriptorPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/FlagDescriptorPropertyInfo.cs @@ -28,25 +28,20 @@ using Xamarin.PropertyEditing; using System.ComponentModel; -using System.Threading.Tasks; using System; -using System.Collections; using System.Collections.Generic; -using MonoDevelop.Core; namespace MonoDevelop.DesignerSupport { class FlagDescriptorPropertyInfo : DescriptorPropertyInfo, IHavePredefinedValues { - Array elements; - public FlagDescriptorPropertyInfo (TypeDescriptorContext typeDescriptorContext, ValueSources valueSources) : base (typeDescriptorContext, valueSources) { IsValueCombinable = true; - elements = System.Enum.GetValues (typeDescriptorContext.PropertyDescriptor.PropertyType); + elements = Enum.GetValues (typeDescriptorContext.PropertyDescriptor.PropertyType); foreach (object value in elements) { ulong uintVal = Convert.ToUInt64 (value); @@ -107,8 +102,6 @@ public bool IsValueCombinable { readonly protected Dictionary predefinedValues = new Dictionary (); public IReadOnlyDictionary PredefinedValues => predefinedValues; - - public string SeparatorString => ComponentModelObjectEditor.ComboSeparatorString; } } diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs index 10818a2e096..bbc092153d0 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/PropertyInfo/StringStandardValuesPropertyInfo.cs @@ -41,12 +41,14 @@ class StringStandardValuesPropertyInfo { readonly Dictionary standardValues = new Dictionary (); - public string SeparatorString => ComponentModelObjectEditor.ComboSeparatorString; - public StringStandardValuesPropertyInfo (TypeConverter.StandardValuesCollection standardValuesCollection, TypeDescriptorContext typeDescriptorContext, ValueSources valueSources) : base (typeDescriptorContext, valueSources) { foreach (object stdValue in standardValuesCollection) { var value = PropertyDescriptor.Converter.ConvertToString (stdValue); + if (value == ComponentModelObjectEditor.ComboSeparatorString) { + //TODO: we need implement in proppy a way to allow separators + continue; + } standardValues.Add (value, stdValue); predefinedValues.Add (value, value); } From f93084c726c868e7a2a092c9ecca4d24e3b8a533 Mon Sep 17 00:00:00 2001 From: Jose Medrano Date: Fri, 4 Oct 2019 20:54:16 +0200 Subject: [PATCH 19/21] Fixes throw to use Task.FromException --- .../NativePropertyEditor/ComponentModelObjectEditor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelObjectEditor.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelObjectEditor.cs index 3d19d28abb6..a12c908d117 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelObjectEditor.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelObjectEditor.cs @@ -92,7 +92,7 @@ public Task> GetPropertyVariantsAsync (IP public Task> GetValueAsync (IPropertyInfo property, PropertyVariation variations = null) { if (property == null) - throw new ArgumentNullException (nameof (property)); + return Task.FromException> (new ArgumentNullException (nameof (property))); if (!(property is DescriptorPropertyInfo propertyInfo)) { return Task.FromException> (new ArgumentException ($"Property should be a {nameof (DescriptorPropertyInfo)}", nameof (property))); From 4cf919e57ce950036052ae5e85318535318a2669 Mon Sep 17 00:00:00 2001 From: Jose Medrano Date: Tue, 8 Oct 2019 11:17:39 +0200 Subject: [PATCH 20/21] Includes FrameBoxButtonBackgroundColor to the HostResourceProvider --- .../MonoDevelop.DesignerSupport.Toolbox/Styles.cs | 14 +++++++++----- .../MonoDevelopHostResourceProvider.cs | 4 +++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.Toolbox/Styles.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.Toolbox/Styles.cs index 3cdff448bce..2f745c851ff 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.Toolbox/Styles.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport.Toolbox/Styles.cs @@ -29,6 +29,7 @@ public class PropertyPadStyle public NSColor Checkerboard0 { get; internal set; } public NSColor Checkerboard1 { get; internal set; } public NSColor ValueBlockBackgroundColor { get; internal set; } + public NSColor FrameBoxButtonBackgroundColor { get; internal set; } public NSColor TabBorderColor { get; internal set; } public NSColor PanelTabBackground { get; internal set; } } @@ -48,14 +49,16 @@ public static void LoadStyles () ToolbarBackgroundColor = NSColor.White; CellBackgroundSelectedColor = NSColor.FromRgb (0.36f, 0.54f, 0.90f); + PropertyPad = new PropertyPadStyle { Checkerboard0 = NSColor.FromRgb (255, 255, 255), Checkerboard1 = NSColor.FromRgb (217, 217, 217), PanelTabBackground = NSColor.FromRgb (248, 247, 248), TabBorderColor = NSColor.FromRgba (0, 0, 0, 25), - ValueBlockBackgroundColor = NSColor.FromRgba (0, 0, 0, 20) - }; - } else { + ValueBlockBackgroundColor = NSColor.FromRgba (0, 0, 0, 20), + FrameBoxButtonBackgroundColor = NSColor.FromRgb (0.36f, 0.54f, 0.90f) + }; + } else { CellBackgroundSelectedColor = NSColor.FromRgb (0.38f, 0.55f, 0.91f); HeaderBackgroundColor = NSColor.FromRgb (0.29f, 0.29f, 0.29f); HeaderBorderBackgroundColor = NSColor.FromRgb (0.29f, 0.29f, 0.29f); @@ -67,8 +70,9 @@ public static void LoadStyles () Checkerboard1 = NSColor.FromRgb (0, 0, 0), PanelTabBackground = NSColor.FromRgb (85, 85, 85), TabBorderColor = NSColor.FromRgba (255, 255, 255, 0), - ValueBlockBackgroundColor = NSColor.FromRgba (255, 255, 255, 25) - }; + ValueBlockBackgroundColor = NSColor.FromRgba (255, 255, 255, 25), + FrameBoxButtonBackgroundColor = NSColor.FromRgb (0.38f, 0.55f, 0.91f) + }; } } } diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/MonoDevelopHostResourceProvider.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/MonoDevelopHostResourceProvider.cs index e730dacf417..0e67f77c01f 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/MonoDevelopHostResourceProvider.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/MonoDevelopHostResourceProvider.cs @@ -60,8 +60,10 @@ public override NSColor GetNamedColor (string name) return Styles.PropertyPad.TabBorderColor; case ValueBlockBackgroundColor: return Styles.PropertyPad.ValueBlockBackgroundColor; + case FrameBoxButtonBackgroundColor: + return Styles.PropertyPad.FrameBoxButtonBackgroundColor; } - return base.GetNamedColor (name); + return NSColor.FromName (name); } } } From 0c656acb877926ed02865e1af8cab46370bd0e89 Mon Sep 17 00:00:00 2001 From: Jose Medrano Date: Tue, 8 Oct 2019 11:18:23 +0200 Subject: [PATCH 21/21] Don't use task if not necessary in GetPropertiesForTypeAsync --- .../NativePropertyEditor/ComponentModelEditorProvider.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelEditorProvider.cs b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelEditorProvider.cs index b246ffb5a27..c9422c765fb 100644 --- a/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelEditorProvider.cs +++ b/main/src/addins/MonoDevelop.DesignerSupport/MonoDevelop.DesignerSupport/NativePropertyEditor/ComponentModelEditorProvider.cs @@ -76,10 +76,9 @@ public Task CreateObjectAsync (ITypeInfo type) public Task> GetPropertiesForTypeAsync (ITypeInfo type) { - return Task.Run (() => { - var prov = target?.Providers ?? Array.Empty (); - return (IReadOnlyCollection)GetPropertiesForProviders (prov); - }); + var prov = target?.Providers ?? Array.Empty (); + var providers = (IReadOnlyCollection)GetPropertiesForProviders (prov); + return Task.FromResult (providers); } public static IReadOnlyList GetPropertiesForProviders (object[] providers)