Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/xamarin/Xamarin.PropertyEditing.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Maupin <ermaup@microsoft.com>2019-02-19 23:35:15 +0300
committerEric Maupin <ermaup@microsoft.com>2019-03-13 01:32:59 +0300
commitf21098848ccae7890012106d51f70ef8476744a4 (patch)
tree9e4683fec081d1f39faaa329ad98ce900e846567
parente61f6717dd084a4dc88feedf0a96f0ac6fabf6fe (diff)
[mac] Collection property editor
-rw-r--r--Xamarin.PropertyEditing.Mac.Standalone/Assets.xcassets/ControlBackground.colorset/Contents.json14
-rw-r--r--Xamarin.PropertyEditing.Mac.Standalone/Assets.xcassets/FrameBoxBackgroundColor.colorset/Contents.json38
-rw-r--r--Xamarin.PropertyEditing.Mac.Standalone/Assets.xcassets/FrameBoxBorderColor.colorset/Contents.json38
-rw-r--r--Xamarin.PropertyEditing.Mac.Standalone/Assets.xcassets/FrameBoxButtonBackgroundColor.colorset/Contents.json38
-rw-r--r--Xamarin.PropertyEditing.Mac.Standalone/Assets.xcassets/FrameBoxButtonBorderColor.colorset/Contents.json38
-rw-r--r--Xamarin.PropertyEditing.Mac.Standalone/Assets.xcassets/ListHeaderSeparatorColor.colorset/Contents.json38
-rw-r--r--Xamarin.PropertyEditing.Mac.Standalone/Xamarin.PropertyEditing.Mac.Standalone.csproj6
-rw-r--r--Xamarin.PropertyEditing.Mac/Controls/CollectionEditorControl.cs465
-rw-r--r--Xamarin.PropertyEditing.Mac/Controls/CollectionEditorWindow.cs102
-rw-r--r--Xamarin.PropertyEditing.Mac/Controls/CollectionInlineEditorControl.cs71
-rw-r--r--Xamarin.PropertyEditing.Mac/Controls/Custom/DynamicBox.cs87
-rw-r--r--Xamarin.PropertyEditing.Mac/Controls/Custom/DynamicFillBox.cs62
-rw-r--r--Xamarin.PropertyEditing.Mac/Controls/Custom/UnderlinedTabViewController.cs6
-rw-r--r--Xamarin.PropertyEditing.Mac/HostResourceProvider.cs6
-rwxr-xr-xXamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-add-16.pngbin0 -> 166 bytes
-rwxr-xr-xXamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-add-16@2x.pngbin0 -> 179 bytes
-rwxr-xr-xXamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-add-16~dark.pngbin0 -> 166 bytes
-rwxr-xr-xXamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-add-16~dark@2x.pngbin0 -> 179 bytes
-rwxr-xr-xXamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-remove-16.pngbin0 -> 149 bytes
-rwxr-xr-xXamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-remove-16@2x.pngbin0 -> 154 bytes
-rwxr-xr-xXamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-remove-16~dark.pngbin0 -> 149 bytes
-rwxr-xr-xXamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-remove-16~dark@2x.pngbin0 -> 154 bytes
-rwxr-xr-xXamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-property-generic-item-16.pngbin0 -> 168 bytes
-rwxr-xr-xXamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-property-generic-item-16@2x.pngbin0 -> 211 bytes
-rwxr-xr-xXamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-property-generic-item-16~dark.pngbin0 -> 168 bytes
-rwxr-xr-xXamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-property-generic-item-16~dark@2x.pngbin0 -> 195 bytes
-rw-r--r--Xamarin.PropertyEditing.Mac/PropertyEditorPanel.cs6
-rw-r--r--Xamarin.PropertyEditing.Mac/PropertyEditorSelector.cs1
-rw-r--r--Xamarin.PropertyEditing.Mac/PropertyList.cs6
-rw-r--r--Xamarin.PropertyEditing.Mac/Resources/LocalizationResources.Designer.cs48
-rw-r--r--Xamarin.PropertyEditing.Mac/Resources/LocalizationResources.resx26
-rw-r--r--Xamarin.PropertyEditing.Mac/Xamarin.PropertyEditing.Mac.csproj6
-rw-r--r--Xamarin.PropertyEditing/ViewModels/CollectionPropertyViewModel.cs17
33 files changed, 1039 insertions, 80 deletions
diff --git a/Xamarin.PropertyEditing.Mac.Standalone/Assets.xcassets/ControlBackground.colorset/Contents.json b/Xamarin.PropertyEditing.Mac.Standalone/Assets.xcassets/ControlBackground.colorset/Contents.json
new file mode 100644
index 0000000..56dcb9a
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac.Standalone/Assets.xcassets/ControlBackground.colorset/Contents.json
@@ -0,0 +1,14 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "colors" : [
+ {
+ "idiom" : "universal",
+ "color" : {
+ "reference" : "controlBackgroundColor"
+ }
+ }
+ ]
+} \ No newline at end of file
diff --git a/Xamarin.PropertyEditing.Mac.Standalone/Assets.xcassets/FrameBoxBackgroundColor.colorset/Contents.json b/Xamarin.PropertyEditing.Mac.Standalone/Assets.xcassets/FrameBoxBackgroundColor.colorset/Contents.json
new file mode 100644
index 0000000..51145f2
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac.Standalone/Assets.xcassets/FrameBoxBackgroundColor.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "colors" : [
+ {
+ "idiom" : "universal",
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "red" : "0xF1",
+ "alpha" : "1.000",
+ "blue" : "0xF1",
+ "green" : "0xF1"
+ }
+ }
+ },
+ {
+ "idiom" : "universal",
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "red" : "0x33",
+ "alpha" : "1.000",
+ "blue" : "0x33",
+ "green" : "0x33"
+ }
+ }
+ }
+ ]
+} \ No newline at end of file
diff --git a/Xamarin.PropertyEditing.Mac.Standalone/Assets.xcassets/FrameBoxBorderColor.colorset/Contents.json b/Xamarin.PropertyEditing.Mac.Standalone/Assets.xcassets/FrameBoxBorderColor.colorset/Contents.json
new file mode 100644
index 0000000..38f2db1
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac.Standalone/Assets.xcassets/FrameBoxBorderColor.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "colors" : [
+ {
+ "idiom" : "universal",
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "red" : "0xC5",
+ "alpha" : "1.000",
+ "blue" : "0xC5",
+ "green" : "0xC5"
+ }
+ }
+ },
+ {
+ "idiom" : "universal",
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "red" : "0x3B",
+ "alpha" : "1.000",
+ "blue" : "0x3B",
+ "green" : "0x3B"
+ }
+ }
+ }
+ ]
+} \ No newline at end of file
diff --git a/Xamarin.PropertyEditing.Mac.Standalone/Assets.xcassets/FrameBoxButtonBackgroundColor.colorset/Contents.json b/Xamarin.PropertyEditing.Mac.Standalone/Assets.xcassets/FrameBoxButtonBackgroundColor.colorset/Contents.json
new file mode 100644
index 0000000..3015558
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac.Standalone/Assets.xcassets/FrameBoxButtonBackgroundColor.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "colors" : [
+ {
+ "idiom" : "universal",
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "red" : "0xFA",
+ "alpha" : "1.000",
+ "blue" : "0xFA",
+ "green" : "0xFA"
+ }
+ }
+ },
+ {
+ "idiom" : "universal",
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "red" : "0x3B",
+ "alpha" : "1.000",
+ "blue" : "0x3B",
+ "green" : "0x3B"
+ }
+ }
+ }
+ ]
+} \ No newline at end of file
diff --git a/Xamarin.PropertyEditing.Mac.Standalone/Assets.xcassets/FrameBoxButtonBorderColor.colorset/Contents.json b/Xamarin.PropertyEditing.Mac.Standalone/Assets.xcassets/FrameBoxButtonBorderColor.colorset/Contents.json
new file mode 100644
index 0000000..ed1e9c8
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac.Standalone/Assets.xcassets/FrameBoxButtonBorderColor.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "colors" : [
+ {
+ "idiom" : "universal",
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "red" : "0xBA",
+ "alpha" : "1.000",
+ "blue" : "0xBA",
+ "green" : "0xBA"
+ }
+ }
+ },
+ {
+ "idiom" : "universal",
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "red" : "0x3B",
+ "alpha" : "1.000",
+ "blue" : "0x3B",
+ "green" : "0x3B"
+ }
+ }
+ }
+ ]
+} \ No newline at end of file
diff --git a/Xamarin.PropertyEditing.Mac.Standalone/Assets.xcassets/ListHeaderSeparatorColor.colorset/Contents.json b/Xamarin.PropertyEditing.Mac.Standalone/Assets.xcassets/ListHeaderSeparatorColor.colorset/Contents.json
new file mode 100644
index 0000000..f04c7d6
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac.Standalone/Assets.xcassets/ListHeaderSeparatorColor.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "colors" : [
+ {
+ "idiom" : "universal",
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "red" : "0xF2",
+ "alpha" : "1.000",
+ "blue" : "0xF2",
+ "green" : "0xF2"
+ }
+ }
+ },
+ {
+ "idiom" : "universal",
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "red" : "0x35",
+ "alpha" : "1.000",
+ "blue" : "0x35",
+ "green" : "0x35"
+ }
+ }
+ }
+ ]
+} \ No newline at end of file
diff --git a/Xamarin.PropertyEditing.Mac.Standalone/Xamarin.PropertyEditing.Mac.Standalone.csproj b/Xamarin.PropertyEditing.Mac.Standalone/Xamarin.PropertyEditing.Mac.Standalone.csproj
index c036d74..b936acb 100644
--- a/Xamarin.PropertyEditing.Mac.Standalone/Xamarin.PropertyEditing.Mac.Standalone.csproj
+++ b/Xamarin.PropertyEditing.Mac.Standalone/Xamarin.PropertyEditing.Mac.Standalone.csproj
@@ -76,6 +76,12 @@
<ImageAsset Include="Assets.xcassets\DescriptionLabelColor.colorset\Contents.json" />
<ImageAsset Include="Assets.xcassets\TabBorderColor.colorset\Contents.json" />
<ImageAsset Include="Assets.xcassets\PanelTabBackground.colorset\Contents.json" />
+ <ImageAsset Include="Assets.xcassets\FrameBoxBorderColor.colorset\Contents.json" />
+ <ImageAsset Include="Assets.xcassets\FrameBoxBackgroundColor.colorset\Contents.json" />
+ <ImageAsset Include="Assets.xcassets\FrameBoxButtonBorderColor.colorset\Contents.json" />
+ <ImageAsset Include="Assets.xcassets\FrameBoxButtonBackgroundColor.colorset\Contents.json" />
+ <ImageAsset Include="Assets.xcassets\ListHeaderSeparatorColor.colorset\Contents.json" />
+ <ImageAsset Include="Assets.xcassets\ControlBackground.colorset\Contents.json" />
</ItemGroup>
<ItemGroup>
<Folder Include="Resources\" />
diff --git a/Xamarin.PropertyEditing.Mac/Controls/CollectionEditorControl.cs b/Xamarin.PropertyEditing.Mac/Controls/CollectionEditorControl.cs
new file mode 100644
index 0000000..3cf807d
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac/Controls/CollectionEditorControl.cs
@@ -0,0 +1,465 @@
+using System;
+using System.Collections.Specialized;
+using System.ComponentModel;
+using AppKit;
+using CoreGraphics;
+using Foundation;
+using Xamarin.PropertyEditing.ViewModels;
+
+namespace Xamarin.PropertyEditing.Mac
+{
+ internal class CollectionEditorControl
+ : NotifyingView<CollectionPropertyViewModel>
+ {
+ public CollectionEditorControl (IHostResourceProvider hostResources)
+ {
+ if (hostResources == null)
+ throw new ArgumentNullException (nameof (hostResources));
+
+ this.hostResources = hostResources;
+
+ this.collectionView = new NSTableView {
+ HeaderView = null,
+ RowHeight = 24
+ };
+
+ this.collectionView.RegisterForDraggedTypes (new[] { "public.data" });
+ this.collectionView.AddColumn (new NSTableColumn ());
+
+ var scroll = new NSScrollView {
+ DocumentView = this.collectionView,
+ HasHorizontalScroller = false,
+ };
+
+ var header = new DynamicBox (hostResources, NamedResources.ControlBackground, NamedResources.FrameBoxBorderColor) {
+ BoxType = NSBoxType.NSBoxCustom,
+ BorderWidth = 1,
+ ContentView = new UnfocusableTextField { StringValue = Resources.LocalizationResources.CollectionTargetsHeader },
+ TranslatesAutoresizingMaskIntoConstraints = false,
+ ContentViewMargins = new CGSize (8, 0),
+ };
+ AddSubview (header);
+
+ var headerBorder = new DynamicBox (hostResources, borderName: NamedResources.ListHeaderSeparatorColor) {
+ BoxType = NSBoxType.NSBoxCustom,
+ BorderWidth = 1,
+ TranslatesAutoresizingMaskIntoConstraints = false,
+ ContentViewMargins = new CGSize (0, 0)
+ };
+ AddSubview (headerBorder);
+
+ var scrollBorder = new DynamicBox (hostResources, borderName: NamedResources.FrameBoxBorderColor) {
+ BoxType = NSBoxType.NSBoxCustom,
+ BorderWidth = 1,
+ ContentView = scroll,
+ TranslatesAutoresizingMaskIntoConstraints = false,
+ ContentViewMargins = new CGSize (0, 0)
+ };
+
+ AddSubview (scrollBorder);
+
+ this.typeSelector = new NSComboBox {
+ TranslatesAutoresizingMaskIntoConstraints = false,
+ ControlSize = NSControlSize.Mini,
+ Font = NSFont.SystemFontOfSize (NSFont.SystemFontSizeForControlSize (NSControlSize.Mini)),
+ AccessibilityTitle = Resources.LocalizationResources.AccessibilityCollectionTypeSelector
+ };
+ this.typeSelector.SelectionChanged += OnSelectedTypeChanged;
+
+ this.add = new NSButton {
+ BezelStyle = NSBezelStyle.SmallSquare,
+ AccessibilityTitle = Resources.LocalizationResources.AccessibilityCollectionAddButton,
+ Bordered = false,
+ };
+ this.add.Activated += OnAddChild;
+
+ var addBorder = new DynamicBox (hostResources, borderName: NamedResources.FrameBoxButtonBorderColor) {
+ ContentView = this.add,
+ TranslatesAutoresizingMaskIntoConstraints = false,
+ BoxType = NSBoxType.NSBoxCustom,
+ BorderWidth = 1,
+ ContentViewMargins = new CGSize (0, 0)
+ };
+
+ this.remove = new NSButton {
+ BezelStyle = NSBezelStyle.SmallSquare,
+ AccessibilityTitle = Resources.LocalizationResources.AccessibilityCollectionRemoveButton,
+ Bordered = false
+ };
+ this.remove.Activated += OnRemoveChild;
+
+ var removeBorder = new DynamicBox (hostResources, borderName: NamedResources.FrameBoxButtonBorderColor) {
+ ContentView = this.remove,
+ TranslatesAutoresizingMaskIntoConstraints = false,
+ BoxType = NSBoxType.NSBoxCustom,
+ BorderWidth = 1,
+ ContentViewMargins = new CGSize (0, 0)
+ };
+
+ var controlsBorder = new DynamicBox (hostResources, NamedResources.FrameBoxBackgroundColor, NamedResources.FrameBoxBorderColor) {
+ BoxType = NSBoxType.NSBoxCustom,
+ BorderWidth = 1,
+ TranslatesAutoresizingMaskIntoConstraints = false,
+ ContentViewMargins = new CoreGraphics.CGSize (2.5, 0)
+ };
+ AddSubview (controlsBorder);
+
+ controlsBorder.AddSubview (this.typeSelector);
+ controlsBorder.AddSubview (addBorder);
+ controlsBorder.AddSubview (removeBorder);
+
+ this.propertyList = new PropertyList {
+ HostResourceProvider = hostResources,
+ ShowHeader = false,
+ };
+
+ var listBorder = new DynamicBox (hostResources, borderName: NamedResources.FrameBoxBorderColor) {
+ BoxType = NSBoxType.NSBoxCustom,
+ BorderWidth = 1,
+ ContentView = propertyList,
+ TranslatesAutoresizingMaskIntoConstraints = false,
+ ContentViewMargins = new CoreGraphics.CGSize (0, 0)
+ };
+
+ AddSubview (listBorder);
+
+ AddConstraints (new[] {
+ NSLayoutConstraint.Create (header, NSLayoutAttribute.Left, NSLayoutRelation.Equal, this, NSLayoutAttribute.Left, 1, 0),
+ NSLayoutConstraint.Create (header, NSLayoutAttribute.Top, NSLayoutRelation.Equal, this, NSLayoutAttribute.Top, 1, 0),
+ NSLayoutConstraint.Create (header, NSLayoutAttribute.Width, NSLayoutRelation.Equal, this, NSLayoutAttribute.Width, Mac.Layout.GoldenRatioLeft, 0),
+ NSLayoutConstraint.Create (header, NSLayoutAttribute.Height, NSLayoutRelation.Equal, 1, 21),
+
+ NSLayoutConstraint.Create (headerBorder, NSLayoutAttribute.Top, NSLayoutRelation.Equal, header, NSLayoutAttribute.Bottom, 1, -1),
+ NSLayoutConstraint.Create (headerBorder, NSLayoutAttribute.Width, NSLayoutRelation.Equal, header, NSLayoutAttribute.Width, 1, 0),
+ NSLayoutConstraint.Create (headerBorder, NSLayoutAttribute.Height, NSLayoutRelation.Equal, 1, 1),
+
+ NSLayoutConstraint.Create (scrollBorder, NSLayoutAttribute.Left, NSLayoutRelation.Equal, this, NSLayoutAttribute.Left, 1, 0),
+ NSLayoutConstraint.Create (scrollBorder, NSLayoutAttribute.Top, NSLayoutRelation.Equal, header, NSLayoutAttribute.Bottom, 1, -1),
+ NSLayoutConstraint.Create (scrollBorder, NSLayoutAttribute.Width, NSLayoutRelation.Equal, this, NSLayoutAttribute.Width, Mac.Layout.GoldenRatioLeft, 0),
+ NSLayoutConstraint.Create (scrollBorder, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, controlsBorder, NSLayoutAttribute.Top, 1, 1),
+
+ NSLayoutConstraint.Create (controlsBorder, NSLayoutAttribute.Width, NSLayoutRelation.Equal, scrollBorder, NSLayoutAttribute.Width, 1, 0),
+ NSLayoutConstraint.Create (controlsBorder, NSLayoutAttribute.Height, NSLayoutRelation.Equal, 1, 21),
+ NSLayoutConstraint.Create (controlsBorder, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, this, NSLayoutAttribute.Bottom, 1, 0),
+
+ NSLayoutConstraint.Create (listBorder, NSLayoutAttribute.Left, NSLayoutRelation.Equal, scrollBorder, NSLayoutAttribute.Right, 1, 8),
+ NSLayoutConstraint.Create (listBorder, NSLayoutAttribute.Top, NSLayoutRelation.Equal, this, NSLayoutAttribute.Top, 1, 0),
+ NSLayoutConstraint.Create (listBorder, NSLayoutAttribute.Right, NSLayoutRelation.Equal, this, NSLayoutAttribute.Right, 1, 0),
+ NSLayoutConstraint.Create (listBorder, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, controlsBorder, NSLayoutAttribute.Bottom, 1, 0),
+
+ NSLayoutConstraint.Create (this.typeSelector, NSLayoutAttribute.Height, NSLayoutRelation.Equal, controlsBorder, NSLayoutAttribute.Height, 1, -7),
+ NSLayoutConstraint.Create (this.typeSelector, NSLayoutAttribute.CenterY, NSLayoutRelation.Equal, controlsBorder, NSLayoutAttribute.CenterY, 1, 0),
+ NSLayoutConstraint.Create (this.typeSelector, NSLayoutAttribute.Width, NSLayoutRelation.LessThanOrEqual, 1, 110),
+
+ NSLayoutConstraint.Create (addBorder, NSLayoutAttribute.Height, NSLayoutRelation.Equal, controlsBorder, NSLayoutAttribute.Height, 1, 2),
+ NSLayoutConstraint.Create (addBorder, NSLayoutAttribute.Width, NSLayoutRelation.Equal, 1, 22),
+ NSLayoutConstraint.Create (addBorder, NSLayoutAttribute.CenterY, NSLayoutRelation.Equal, controlsBorder, NSLayoutAttribute.CenterY, 1, 0),
+ NSLayoutConstraint.Create (addBorder, NSLayoutAttribute.Left, NSLayoutRelation.Equal, this.typeSelector, NSLayoutAttribute.Right, 1, 1.5f),
+
+ NSLayoutConstraint.Create (removeBorder, NSLayoutAttribute.Left, NSLayoutRelation.Equal, addBorder, NSLayoutAttribute.Right, 1, -1),
+ NSLayoutConstraint.Create (removeBorder, NSLayoutAttribute.Height, NSLayoutRelation.Equal, controlsBorder, NSLayoutAttribute.Height, 1, 2),
+ NSLayoutConstraint.Create (removeBorder, NSLayoutAttribute.CenterY, NSLayoutRelation.Equal, controlsBorder, NSLayoutAttribute.CenterY, 1, 0),
+ NSLayoutConstraint.Create (removeBorder, NSLayoutAttribute.Width, NSLayoutRelation.Equal, 1, 22),
+ });
+
+ ViewDidChangeEffectiveAppearance ();
+ }
+
+ public override void OnViewModelChanged (CollectionPropertyViewModel oldModel)
+ {
+ base.OnViewModelChanged (oldModel);
+
+ if (oldModel != null) {
+ oldModel.TypeRequested -= OnTypeRequested;
+ oldModel.AddTargetCommand.CanExecuteChanged -= OnCanAddTargetChanged;
+ oldModel.RemoveTargetCommand.CanExecuteChanged -= OnCanRemoveTargetChanged;
+
+ if (this.suggestedTypes != null) {
+ this.suggestedTypes.CollectionChanged -= OnSuggestedTypesChanged;
+ this.suggestedTypes = null;
+ }
+
+ if (this.targets != null) {
+ this.targets.CollectionChanged -= OnTargetsChanged;
+ this.targets = null;
+ }
+
+ this.collectionView.Source = null;
+ this.propertyList.ViewModel = null;
+ }
+
+ if (ViewModel != null) {
+ ViewModel.TypeRequested += OnTypeRequested;
+ ViewModel.AddTargetCommand.CanExecuteChanged += OnCanAddTargetChanged;
+ ViewModel.RemoveTargetCommand.CanExecuteChanged += OnCanRemoveTargetChanged;
+
+ this.collectionView.Source = new CollectionTableSource (this.hostResources, ViewModel);
+ this.propertyList.ViewModel = ViewModel.Panel;
+
+ OnPropertyChanged (ViewModel, new PropertyChangedEventArgs (null));
+ OnCanAddTargetChanged (this, EventArgs.Empty);
+ OnCanRemoveTargetChanged (this, EventArgs.Empty);
+ }
+ }
+
+ public override void OnPropertyChanged (object sender, PropertyChangedEventArgs e)
+ {
+ base.OnPropertyChanged (sender, e);
+
+ if (e.PropertyName == nameof(CollectionPropertyViewModel.SuggestedTypes) || String.IsNullOrEmpty (e.PropertyName)) {
+ if (this.suggestedTypes != null) {
+ this.suggestedTypes.CollectionChanged -= OnSuggestedTypesChanged;
+ }
+
+ this.suggestedTypes = ViewModel.SuggestedTypes as INotifyCollectionChanged;
+ if (this.suggestedTypes != null)
+ this.suggestedTypes.CollectionChanged += OnSuggestedTypesChanged;
+
+ OnSuggestedTypesChanged (ViewModel, new NotifyCollectionChangedEventArgs (NotifyCollectionChangedAction.Reset));
+ }
+
+ if (e.PropertyName == nameof(CollectionPropertyViewModel.SelectedType) || String.IsNullOrEmpty (e.PropertyName)) {
+ if (ViewModel.SelectedType != null)
+ this.typeSelector.SelectItem (ViewModel.SuggestedTypes.IndexOf (ViewModel.SelectedType));
+ else if (this.typeSelector.SelectedIndex >= 0)
+ this.typeSelector.DeselectItem (this.typeSelector.SelectedIndex);
+ }
+
+ if (e.PropertyName == nameof (CollectionPropertyViewModel.Targets) || String.IsNullOrEmpty (e.PropertyName)) {
+ if (this.targets != null)
+ this.targets.CollectionChanged -= OnTargetsChanged;
+
+ this.targets = ViewModel.Targets as INotifyCollectionChanged;
+ if (this.targets != null)
+ this.targets.CollectionChanged += OnTargetsChanged;
+
+ OnTargetsChanged (ViewModel, new NotifyCollectionChangedEventArgs (NotifyCollectionChangedAction.Reset));
+ }
+
+ if (e.PropertyName == nameof (CollectionPropertyViewModel.SelectedTarget) || String.IsNullOrEmpty (e.PropertyName)) {
+ if (ViewModel.SelectedTarget == null)
+ this.collectionView.DeselectAll (this);
+ else
+ this.collectionView.SelectRow (ViewModel.Targets.IndexOf (ViewModel.SelectedTarget), byExtendingSelection: false);
+ }
+ }
+
+ public override void ViewDidChangeEffectiveAppearance ()
+ {
+ base.ViewDidChangeEffectiveAppearance ();
+
+ this.add.Image = this.hostResources.GetNamedImage ("pe-list-add-16");
+ this.remove.Image = this.hostResources.GetNamedImage ("pe-list-remove-16");
+ this.add.Cell.BackgroundColor = this.hostResources.GetNamedColor (NamedResources.FrameBoxButtonBackgroundColor);
+ this.remove.Cell.BackgroundColor = this.hostResources.GetNamedColor (NamedResources.FrameBoxButtonBackgroundColor);
+ }
+
+ private readonly IHostResourceProvider hostResources;
+ private readonly NSTableView collectionView;
+ private readonly NSComboBox typeSelector;
+ private readonly NSButton add, remove;
+ private readonly PropertyList propertyList;
+ private INotifyCollectionChanged suggestedTypes, targets;
+
+ private class CollectionTableSource
+ : NSTableViewSource
+ {
+ public CollectionTableSource (IHostResourceProvider hostResources, CollectionPropertyViewModel vm)
+ {
+ this.viewModel = vm;
+ this.hostResources = hostResources;
+ }
+
+ public override NSView GetViewForItem (NSTableView tableView, NSTableColumn tableColumn, nint row)
+ {
+ var view = (CollectionItemView)tableView.MakeView (CollectionItemId, tableView);
+ if (view == null)
+ view = new CollectionItemView (this.viewModel.TargetPlatform.IconProvider, this.hostResources);
+
+ view.ViewModel = this.viewModel.Targets[(int)row];
+ return view;
+ }
+
+ public override nint GetRowCount (NSTableView tableView)
+ {
+ return this.viewModel.Targets.Count;
+ }
+
+ public override void SelectionDidChange (NSNotification notification)
+ {
+ NSTableView table = (NSTableView)notification.Object;
+ this.viewModel.SelectedTarget = (table.SelectedRow != -1) ? this.viewModel.Targets[(int)table.SelectedRow] : null;
+ }
+
+ public override bool WriteRows (NSTableView tableView, NSIndexSet rowIndexes, NSPasteboard pboard)
+ {
+ var item = new NSPasteboardItem ();
+ item.SetDataForType (NSKeyedArchiver.ArchivedDataWithRootObject (rowIndexes), DataTypeName);
+ pboard.WriteObjects (new[] { item });
+ return true;
+ }
+
+ public override NSDragOperation ValidateDrop (NSTableView tableView, NSDraggingInfo info, nint row, NSTableViewDropOperation dropOperation)
+ {
+ if (info.DraggingPasteboard.GetDataForType (DataTypeName) != null)
+ return NSDragOperation.Move;
+
+ return NSDragOperation.None;
+ }
+
+ public override bool AcceptDrop (NSTableView tableView, NSDraggingInfo info, nint row, NSTableViewDropOperation dropOperation)
+ {
+ NSData data = info.DraggingPasteboard.GetDataForType (DataTypeName);
+ NSIndexSet indexes = NSKeyedUnarchiver.UnarchiveObject (data) as NSIndexSet;
+ if (indexes == null)
+ return false;
+
+ // Dropping at the bottom gives a row at the count, but we shift indexes first
+ if (row >= this.viewModel.Targets.Count)
+ row = this.viewModel.Targets.Count - 1;
+
+ this.viewModel.MoveTarget ((int)indexes.FirstIndex, (int)row);
+ return true;
+ }
+
+ private const string DataTypeName = "public.data";
+
+ private class CollectionItemView
+ : NSView
+ {
+ public CollectionItemView (IIconProvider iconProvider, IHostResourceProvider hostResources)
+ {
+ Identifier = CollectionItemId;
+ this.iconProvider = iconProvider;
+ this.hostResources = hostResources;
+
+ AddSubview (this.label);
+ if (iconProvider != null) {
+ AddSubview (this.iconView);
+ AddConstraints (new[]{
+ NSLayoutConstraint.Create (this.iconView, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, this, NSLayoutAttribute.Leading, 1, 7),
+ NSLayoutConstraint.Create (this.iconView, NSLayoutAttribute.CenterY, NSLayoutRelation.Equal, this, NSLayoutAttribute.CenterY, 1, 0),
+ NSLayoutConstraint.Create (this.iconView, NSLayoutAttribute.Height, NSLayoutRelation.Equal, 1, 16),
+ NSLayoutConstraint.Create (this.iconView, NSLayoutAttribute.Width, NSLayoutRelation.Equal, 1, 16),
+
+ NSLayoutConstraint.Create (this.label, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, this.iconView, NSLayoutAttribute.Trailing, 1, 0),
+ });
+ } else {
+ AddConstraint (NSLayoutConstraint.Create (this.label, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, this, NSLayoutAttribute.Leading, 1, 7));
+ }
+
+ AddConstraints (new[] {
+ NSLayoutConstraint.Create (this.label, NSLayoutAttribute.CenterY, NSLayoutRelation.Equal, this, NSLayoutAttribute.CenterY, 1, 0),
+ NSLayoutConstraint.Create (this.label, NSLayoutAttribute.Height, NSLayoutRelation.Equal, this, NSLayoutAttribute.Height, 1, 0)
+ });
+
+ ViewDidChangeEffectiveAppearance ();
+ }
+
+ public CollectionPropertyItemViewModel ViewModel
+ {
+ get { return this.vm; }
+ set
+ {
+ this.vm = value;
+
+ if (value != null) {
+ this.label.StringValue = value.TypeName;
+ UpdateIcon ();
+ }
+ }
+ }
+
+ public override void ViewDidChangeEffectiveAppearance ()
+ {
+ UpdateIcon ();
+ base.ViewDidChangeEffectiveAppearance ();
+ }
+
+ private readonly IIconProvider iconProvider;
+ private readonly IHostResourceProvider hostResources;
+ private readonly NSImageView iconView = new NSImageView {
+ ImageScaling = NSImageScale.ProportionallyDown,
+ TranslatesAutoresizingMaskIntoConstraints = false
+ };
+
+ private readonly UnfocusableTextField label = new UnfocusableTextField {
+ TranslatesAutoresizingMaskIntoConstraints = false
+ };
+
+ private CollectionPropertyItemViewModel vm;
+
+ private void UpdateIcon()
+ {
+ if (this.iconProvider == null)
+ return;
+
+ var image = this.hostResources.GetNamedImage ("property-generic-item-16");
+ image.Template = true;
+ this.iconView.Image = image;
+
+ if (this.vm == null)
+ return;
+ }
+ }
+
+ private const string CollectionItemId = "CollectionItem";
+ private readonly CollectionPropertyViewModel viewModel;
+ private readonly IHostResourceProvider hostResources;
+ }
+
+ private void OnSelectedTypeChanged (object sender, EventArgs e)
+ {
+ ITypeInfo type = null;
+ int index = (int)this.typeSelector.SelectedIndex;
+ if (index >= 0)
+ type = ViewModel.SuggestedTypes[index];
+
+ ViewModel.SelectedType = type;
+ }
+
+ private void OnTypeRequested (object sender, TypeRequestedEventArgs e)
+ {
+ e.SelectedType = e.RequestAt (this.hostResources, this.typeSelector, ViewModel.AssignableTypes);
+ }
+
+ private void OnAddChild (object sender, EventArgs e)
+ {
+ ViewModel.AddTargetCommand.Execute (null);
+ }
+
+ private void OnRemoveChild (object sender, EventArgs e)
+ {
+ ViewModel.RemoveTargetCommand.Execute (null);
+ }
+
+ private void OnCanAddTargetChanged (object sender, EventArgs e)
+ {
+ this.add.Enabled = ViewModel.AddTargetCommand.CanExecute (null);
+ }
+
+ private void OnCanRemoveTargetChanged (object sender, EventArgs e)
+ {
+ this.remove.Enabled = ViewModel.RemoveTargetCommand.CanExecute (null);
+ }
+
+ private void OnTargetsChanged (object sender, NotifyCollectionChangedEventArgs e)
+ {
+ switch (e.Action) {
+ case NotifyCollectionChangedAction.Reset:
+ default:
+ this.collectionView.ReloadData ();
+ break;
+ }
+ }
+
+ private void OnSuggestedTypesChanged (object sender, NotifyCollectionChangedEventArgs e)
+ {
+ this.typeSelector.RemoveAll ();
+
+ foreach (ITypeInfo type in ViewModel.SuggestedTypes) {
+ this.typeSelector.Add (new NSString (type.Name));
+ }
+ }
+ }
+}
diff --git a/Xamarin.PropertyEditing.Mac/Controls/CollectionEditorWindow.cs b/Xamarin.PropertyEditing.Mac/Controls/CollectionEditorWindow.cs
new file mode 100644
index 0000000..23d9db0
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac/Controls/CollectionEditorWindow.cs
@@ -0,0 +1,102 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+using AppKit;
+using CoreGraphics;
+using Foundation;
+
+using Xamarin.PropertyEditing.ViewModels;
+
+namespace Xamarin.PropertyEditing.Mac
+{
+ internal class CollectionEditorWindow
+ : NSWindow
+ {
+ public CollectionEditorWindow (IHostResourceProvider hostResources, CollectionPropertyViewModel viewModel)
+ : base (new CGRect (0, 0, 500, 400), NSWindowStyle.Titled | NSWindowStyle.Closable | NSWindowStyle.Resizable, NSBackingStore.Buffered, true)
+ {
+ Delegate = new ModalDialogDelegate ();
+ Title = String.Format (Resources.LocalizationResources.CollectionEditorTitle, viewModel.Property.Name);
+
+ this.collectionEditor = new CollectionEditorControl (hostResources) {
+ ViewModel = viewModel,
+ TranslatesAutoresizingMaskIntoConstraints = false
+ };
+
+ ContentView.AddSubview (this.collectionEditor);
+
+ this.ok = NSButton.CreateButton (Properties.Resources.OK, OnOked);
+ this.ok.TranslatesAutoresizingMaskIntoConstraints = false;
+ //this.ok.KeyEquivalent = "\r"; // FIXME: The type selector popup doesn't eat this key, so it ends up closing both.
+ ContentView.AddSubview (this.ok);
+
+ this.cancel = NSButton.CreateButton (Properties.Resources.Cancel, OnCanceled);
+ this.cancel.TranslatesAutoresizingMaskIntoConstraints = false;
+ ContentView.AddSubview (this.cancel);
+
+ ContentView.AddConstraints (new[] {
+ NSLayoutConstraint.Create (this.collectionEditor, NSLayoutAttribute.Width, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Width, 1, -40),
+ NSLayoutConstraint.Create (this.collectionEditor, NSLayoutAttribute.Top, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Top, 1, 20),
+ NSLayoutConstraint.Create (this.collectionEditor, NSLayoutAttribute.CenterX, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.CenterX, 1, 0),
+ NSLayoutConstraint.Create (this.collectionEditor, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, this.ok, NSLayoutAttribute.Top, 1, -20),
+
+ NSLayoutConstraint.Create (this.ok, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Bottom, 1, -20),
+ NSLayoutConstraint.Create (this.ok, NSLayoutAttribute.Right, NSLayoutRelation.Equal, this.collectionEditor, NSLayoutAttribute.Right, 1, 0),
+ NSLayoutConstraint.Create (this.ok, NSLayoutAttribute.Width, NSLayoutRelation.Equal, this.cancel, NSLayoutAttribute.Width, 1, 0),
+
+ NSLayoutConstraint.Create (this.cancel, NSLayoutAttribute.Right, NSLayoutRelation.Equal, this.ok, NSLayoutAttribute.Left, 1, -10),
+ NSLayoutConstraint.Create (this.cancel, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, this.ok, NSLayoutAttribute.Bottom, 1, 0),
+ NSLayoutConstraint.Create (this.cancel, NSLayoutAttribute.Width, NSLayoutRelation.GreaterThanOrEqual, 1, 80)
+ });
+ }
+
+ public NSModalResponse ModalResponse
+ {
+ get;
+ private set;
+ } = NSModalResponse.Cancel;
+
+ private CollectionEditorControl collectionEditor;
+ private NSButton ok, cancel;
+
+ private void OnOked ()
+ {
+ ModalResponse = NSModalResponse.OK;
+ this.collectionEditor.ViewModel = null;
+ Close ();
+ }
+
+ private void OnCanceled ()
+ {
+ ModalResponse = NSModalResponse.Cancel;
+ this.collectionEditor.ViewModel = null;
+ Close ();
+ }
+
+ public static void EditCollection (NSAppearance appearance, IHostResourceProvider hostResources, CollectionPropertyViewModel collectionVm)
+ {
+ var w = new CollectionEditorWindow (hostResources, collectionVm) {
+ Appearance = appearance
+ };
+
+ var result = (NSModalResponse)(int)NSApplication.SharedApplication.RunModalForWindow (w);
+ if (result != NSModalResponse.OK) {
+ collectionVm.CancelCommand.Execute (null);
+ return;
+ }
+
+ collectionVm.CommitCommand.Execute (null);
+ }
+
+ private class ModalDialogDelegate
+ : NSWindowDelegate
+ {
+ public override void WillClose (NSNotification notification)
+ {
+ NSModalResponse response = ((CollectionEditorWindow)notification.Object).ModalResponse;
+ NSApplication.SharedApplication.StopModalWithCode ((int)response);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.PropertyEditing.Mac/Controls/CollectionInlineEditorControl.cs b/Xamarin.PropertyEditing.Mac/Controls/CollectionInlineEditorControl.cs
new file mode 100644
index 0000000..a499c06
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac/Controls/CollectionInlineEditorControl.cs
@@ -0,0 +1,71 @@
+using System;
+using AppKit;
+using Xamarin.PropertyEditing.ViewModels;
+
+namespace Xamarin.PropertyEditing.Mac
+{
+ internal class CollectionInlineEditorControl
+ : PropertyEditorControl<CollectionPropertyViewModel>
+ {
+ public CollectionInlineEditorControl (IHostResourceProvider hostResources)
+ : base (hostResources)
+ {
+ this.label = new UnfocusableTextField {
+ TranslatesAutoresizingMaskIntoConstraints = false,
+ StringValue = Properties.Resources.CollectionValue,
+ };
+
+ AddSubview (this.label);
+
+ this.openCollection = new FocusableButton {
+ Title = Resources.LocalizationResources.CollectionEditButton,
+ BezelStyle = NSBezelStyle.Rounded,
+ AccessibilityEnabled = true,
+ AccessibilityHelp = Resources.LocalizationResources.AccessibilityCollectionHelp
+ };
+
+ this.openCollection.Activated += (o, e) => {
+ CollectionEditorWindow.EditCollection (EffectiveAppearance, HostResources, ViewModel);
+ };
+
+ AddSubview (this.openCollection);
+
+ AddConstraints (new[] {
+ NSLayoutConstraint.Create (this.label, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, this, NSLayoutAttribute.Leading, 1, 0),
+ NSLayoutConstraint.Create (this.label, NSLayoutAttribute.CenterY, NSLayoutRelation.Equal, this, NSLayoutAttribute.CenterY, 1, 0),
+ NSLayoutConstraint.Create (this.label, NSLayoutAttribute.Height, NSLayoutRelation.Equal, this, NSLayoutAttribute.Height, 1, 0),
+ NSLayoutConstraint.Create (this.openCollection, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, this.label, NSLayoutAttribute.Trailing, 1, 12),
+ NSLayoutConstraint.Create (this.openCollection, NSLayoutAttribute.CenterY, NSLayoutRelation.Equal, this, NSLayoutAttribute.CenterY, 1, 0),
+ NSLayoutConstraint.Create (this.openCollection, NSLayoutAttribute.Width, NSLayoutRelation.GreaterThanOrEqual, 1, 70),
+ NSLayoutConstraint.Create (this.openCollection, NSLayoutAttribute.Height, NSLayoutRelation.Equal, this, NSLayoutAttribute.Height, 1, -6)
+ });
+
+ ViewDidChangeEffectiveAppearance ();
+ }
+
+ public override NSView FirstKeyView => this.openCollection;
+ public override NSView LastKeyView => this.openCollection;
+
+ protected override void SetEnabled ()
+ {
+ base.SetEnabled ();
+ this.openCollection.Enabled = ViewModel?.Property.CanWrite ?? false;
+ }
+
+ public override void ViewDidChangeEffectiveAppearance ()
+ {
+ base.ViewDidChangeEffectiveAppearance ();
+ this.label.TextColor = HostResources.GetNamedColor (NamedResources.DescriptionLabelColor);
+ }
+
+ protected override void UpdateAccessibilityValues ()
+ {
+ base.UpdateAccessibilityValues ();
+
+ this.openCollection.AccessibilityTitle = (ViewModel != null) ? String.Format (Resources.LocalizationResources.AccessibilityCollection, ViewModel.Property.Name) : null;
+ }
+
+ private readonly UnfocusableTextField label;
+ private readonly NSButton openCollection;
+ }
+}
diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/DynamicBox.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/DynamicBox.cs
new file mode 100644
index 0000000..a3483a1
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/DynamicBox.cs
@@ -0,0 +1,87 @@
+using System;
+using AppKit;
+
+namespace Xamarin.PropertyEditing.Mac
+{
+ internal class DynamicBox
+ : NSBox
+ {
+ public DynamicBox (IHostResourceProvider hostResources, string fillName = null, string borderName = null)
+ {
+ if (hostResources == null)
+ throw new ArgumentNullException (nameof (hostResources));
+
+ BorderWidth = 0;
+ BoxType = NSBoxType.NSBoxCustom;
+ TranslatesAutoresizingMaskIntoConstraints = false;
+
+ this.fillColor = fillName;
+ if (fillName == null)
+ FillColor = NSColor.Clear;
+
+ this.borderColor = borderName;
+ if (borderName == null)
+ BorderColor = NSColor.Clear;
+
+ HostResourceProvider = hostResources;
+ }
+
+ public IHostResourceProvider HostResourceProvider
+ {
+ get { return this.hostResources; }
+ set
+ {
+ this.hostResources = value;
+ ViewDidChangeEffectiveAppearance ();
+ }
+ }
+
+ public string FillColorName
+ {
+ get => this.fillColor;
+ set
+ {
+ this.fillColor = value;
+ if (value == null)
+ FillColor = NSColor.Clear;
+
+ ViewDidChangeEffectiveAppearance ();
+ }
+ }
+
+ public string BorderColorName
+ {
+ get => this.borderColor;
+ set
+ {
+ this.borderColor = value;
+ if (value == null)
+ BorderColor = NSColor.Clear;
+
+ ViewDidChangeEffectiveAppearance ();
+ }
+ }
+
+ public override void ViewDidChangeEffectiveAppearance ()
+ {
+ if (this.fillColor != null) {
+ NSColor color = this.hostResources.GetNamedColor (this.fillColor);
+ if (color == null)
+ return;
+
+ FillColor = color;
+ }
+
+ if (this.borderColor != null) {
+ NSColor color = this.hostResources.GetNamedColor (this.borderColor);
+ if (color == null)
+ return;
+
+ BorderColor = color;
+ }
+ }
+
+ private IHostResourceProvider hostResources;
+ private string fillColor, borderColor;
+ }
+}
diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/DynamicFillBox.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/DynamicFillBox.cs
deleted file mode 100644
index a542b5d..0000000
--- a/Xamarin.PropertyEditing.Mac/Controls/Custom/DynamicFillBox.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-using System;
-using AppKit;
-
-namespace Xamarin.PropertyEditing.Mac
-{
- internal class DynamicFillBox
- : NSBox
- {
- public DynamicFillBox (IHostResourceProvider hostResources, string colorName)
- {
- if (hostResources == null)
- throw new ArgumentNullException (nameof (hostResources));
-
- BorderWidth = 0;
- BoxType = NSBoxType.NSBoxCustom;
- TranslatesAutoresizingMaskIntoConstraints = false;
- this.colorName = colorName;
- if (colorName == null)
- FillColor = NSColor.Clear;
-
- HostResourceProvider = hostResources;
- }
-
- public IHostResourceProvider HostResourceProvider
- {
- get { return this.hostResources; }
- set
- {
- this.hostResources = value;
- ViewDidChangeEffectiveAppearance ();
- }
- }
-
- public string FillColorName
- {
- get => this.colorName;
- set
- {
- this.colorName = value;
- if (value == null)
- FillColor = NSColor.Clear;
-
- ViewDidChangeEffectiveAppearance ();
- }
- }
-
- public override void ViewDidChangeEffectiveAppearance ()
- {
- if (this.colorName == null)
- return;
-
- NSColor color = this.hostResources.GetNamedColor (this.colorName);
- if (color == null)
- return;
-
- FillColor = color;
- }
-
- private IHostResourceProvider hostResources;
- private string colorName;
- }
-}
diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/UnderlinedTabViewController.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/UnderlinedTabViewController.cs
index fa2e4d9..4911171 100644
--- a/Xamarin.PropertyEditing.Mac/Controls/Custom/UnderlinedTabViewController.cs
+++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/UnderlinedTabViewController.cs
@@ -104,7 +104,7 @@ namespace Xamarin.PropertyEditing.Mac
NSView tabs = this.tabStack;
if (TabBackgroundColor != null) {
- this.tabContainer = new DynamicFillBox (HostResources, TabBackgroundColor) {
+ this.tabContainer = new DynamicBox (HostResources, TabBackgroundColor) {
ContentView = this.tabStack
};
@@ -114,7 +114,7 @@ namespace Xamarin.PropertyEditing.Mac
this.innerStack.AddView (tabs, NSStackViewGravity.Top);
if (TabBorderColor != null) {
- this.border = new DynamicFillBox (HostResources, TabBorderColor) {
+ this.border = new DynamicBox (HostResources, TabBorderColor) {
Frame = new CGRect (0, 0, 1, 1),
AutoresizingMask = NSViewResizingMask.WidthSizable
};
@@ -144,7 +144,7 @@ namespace Xamarin.PropertyEditing.Mac
private string tabBackground, tabBorder;
private IUnderliningTabView selected;
- private DynamicFillBox tabContainer, border;
+ private DynamicBox tabContainer, border;
private NSStackView innerStack;
private readonly NSStackView tabStack = new NSStackView () {
Spacing = 1f,
diff --git a/Xamarin.PropertyEditing.Mac/HostResourceProvider.cs b/Xamarin.PropertyEditing.Mac/HostResourceProvider.cs
index 87c02a8..4d42f06 100644
--- a/Xamarin.PropertyEditing.Mac/HostResourceProvider.cs
+++ b/Xamarin.PropertyEditing.Mac/HostResourceProvider.cs
@@ -70,6 +70,12 @@ namespace Xamarin.PropertyEditing.Mac
public const string DescriptionLabelColor = "DescriptionLabelColor";
public const string ValueBlockBackgroundColor = "ValueBlockBackgroundColor";
public const string TabBorderColor = "TabBorderColor";
+ public const string FrameBoxBorderColor = "FrameBoxBorderColor";
+ public const string FrameBoxBackgroundColor = "FrameBoxBackgroundColor";
+ public const string FrameBoxButtonBorderColor = "FrameBoxButtonBorderColor";
+ public const string FrameBoxButtonBackgroundColor = "FrameBoxButtonBackgroundColor";
+ public const string ListHeaderSeparatorColor = "ListHeaderSeparatorColor";
public const string PanelTabBackground = "PanelTabBackground";
+ public const string ControlBackground = "ControlBackground";
}
}
diff --git a/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-add-16.png b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-add-16.png
new file mode 100755
index 0000000..a884ca8
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-add-16.png
Binary files differ
diff --git a/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-add-16@2x.png b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-add-16@2x.png
new file mode 100755
index 0000000..e71fdbd
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-add-16@2x.png
Binary files differ
diff --git a/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-add-16~dark.png b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-add-16~dark.png
new file mode 100755
index 0000000..6751913
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-add-16~dark.png
Binary files differ
diff --git a/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-add-16~dark@2x.png b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-add-16~dark@2x.png
new file mode 100755
index 0000000..4f160c7
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-add-16~dark@2x.png
Binary files differ
diff --git a/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-remove-16.png b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-remove-16.png
new file mode 100755
index 0000000..ade63c0
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-remove-16.png
Binary files differ
diff --git a/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-remove-16@2x.png b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-remove-16@2x.png
new file mode 100755
index 0000000..6e2f4d0
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-remove-16@2x.png
Binary files differ
diff --git a/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-remove-16~dark.png b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-remove-16~dark.png
new file mode 100755
index 0000000..f6b4266
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-remove-16~dark.png
Binary files differ
diff --git a/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-remove-16~dark@2x.png b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-remove-16~dark@2x.png
new file mode 100755
index 0000000..3a6d32b
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-remove-16~dark@2x.png
Binary files differ
diff --git a/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-property-generic-item-16.png b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-property-generic-item-16.png
new file mode 100755
index 0000000..9055ecd
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-property-generic-item-16.png
Binary files differ
diff --git a/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-property-generic-item-16@2x.png b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-property-generic-item-16@2x.png
new file mode 100755
index 0000000..ba41dc3
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-property-generic-item-16@2x.png
Binary files differ
diff --git a/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-property-generic-item-16~dark.png b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-property-generic-item-16~dark.png
new file mode 100755
index 0000000..b76d421
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-property-generic-item-16~dark.png
Binary files differ
diff --git a/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-property-generic-item-16~dark@2x.png b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-property-generic-item-16~dark@2x.png
new file mode 100755
index 0000000..a314f65
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-property-generic-item-16~dark@2x.png
Binary files differ
diff --git a/Xamarin.PropertyEditing.Mac/PropertyEditorPanel.cs b/Xamarin.PropertyEditing.Mac/PropertyEditorPanel.cs
index fe89664..e2d88ac 100644
--- a/Xamarin.PropertyEditing.Mac/PropertyEditorPanel.cs
+++ b/Xamarin.PropertyEditing.Mac/PropertyEditorPanel.cs
@@ -132,19 +132,19 @@ namespace Xamarin.PropertyEditing.Mac
private NSSearchField propertyFilter;
private NSStackView tabStack;
- private DynamicFillBox header, border;
+ private DynamicBox header, border;
private void Initialize ()
{
AutoresizingMask = NSViewResizingMask.WidthSizable | NSViewResizingMask.HeightSizable;
- this.header = new DynamicFillBox (HostResourceProvider, NamedResources.PanelTabBackground) {
+ this.header = new DynamicBox (HostResourceProvider, NamedResources.PanelTabBackground) {
ContentViewMargins = new CGSize (0, 0),
ContentView = new NSView ()
};
AddSubview (this.header);
- this.border = new DynamicFillBox (HostResourceProvider, NamedResources.TabBorderColor) {
+ this.border = new DynamicBox (HostResourceProvider, NamedResources.TabBorderColor) {
Frame = new CGRect (0, 0, 1, 1)
};
header.AddSubview (this.border);
diff --git a/Xamarin.PropertyEditing.Mac/PropertyEditorSelector.cs b/Xamarin.PropertyEditing.Mac/PropertyEditorSelector.cs
index 29bc5b2..634728b 100644
--- a/Xamarin.PropertyEditing.Mac/PropertyEditorSelector.cs
+++ b/Xamarin.PropertyEditing.Mac/PropertyEditorSelector.cs
@@ -56,6 +56,7 @@ namespace Xamarin.PropertyEditing.Mac
{typeof (PropertyGroupViewModel), typeof (GroupEditorControl)},
{typeof (ObjectPropertyViewModel), typeof (ObjectEditorControl)},
{typeof (TypePropertyViewModel), typeof (TypeEditorControl)},
+ {typeof (CollectionPropertyViewModel), typeof (CollectionInlineEditorControl)},
};
}
diff --git a/Xamarin.PropertyEditing.Mac/PropertyList.cs b/Xamarin.PropertyEditing.Mac/PropertyList.cs
index 753c8f6..b803cc8 100644
--- a/Xamarin.PropertyEditing.Mac/PropertyList.cs
+++ b/Xamarin.PropertyEditing.Mac/PropertyList.cs
@@ -35,12 +35,6 @@ namespace Xamarin.PropertyEditing.Mac
AddSubview (this.scrollView);
}
- public bool ShowBorder
- {
- get { return this.scrollView.BorderType != NSBorderType.NoBorder; }
- set { this.scrollView.BorderType = (value) ? NSBorderType.LineBorder : NSBorderType.NoBorder; }
- }
-
public bool ShowHeader
{
get { return this.showHeader; }
diff --git a/Xamarin.PropertyEditing.Mac/Resources/LocalizationResources.Designer.cs b/Xamarin.PropertyEditing.Mac/Resources/LocalizationResources.Designer.cs
index 7b87969..bcf4a99 100644
--- a/Xamarin.PropertyEditing.Mac/Resources/LocalizationResources.Designer.cs
+++ b/Xamarin.PropertyEditing.Mac/Resources/LocalizationResources.Designer.cs
@@ -83,6 +83,36 @@ namespace Xamarin.PropertyEditing.Mac.Resources {
}
}
+ internal static string AccessibilityCollection {
+ get {
+ return ResourceManager.GetString("AccessibilityCollection", resourceCulture);
+ }
+ }
+
+ internal static string AccessibilityCollectionHelp {
+ get {
+ return ResourceManager.GetString("AccessibilityCollectionHelp", resourceCulture);
+ }
+ }
+
+ internal static string AccessibilityCollectionTypeSelector {
+ get {
+ return ResourceManager.GetString("AccessibilityCollectionTypeSelector", resourceCulture);
+ }
+ }
+
+ internal static string AccessibilityCollectionAddButton {
+ get {
+ return ResourceManager.GetString("AccessibilityCollectionAddButton", resourceCulture);
+ }
+ }
+
+ internal static string AccessibilityCollectionRemoveButton {
+ get {
+ return ResourceManager.GetString("AccessibilityCollectionRemoveButton", resourceCulture);
+ }
+ }
+
internal static string AccessibilityString {
get {
return ResourceManager.GetString("AccessibilityString", resourceCulture);
@@ -143,6 +173,24 @@ namespace Xamarin.PropertyEditing.Mac.Resources {
}
}
+ internal static string CollectionTargetsHeader {
+ get {
+ return ResourceManager.GetString("CollectionTargetsHeader", resourceCulture);
+ }
+ }
+
+ internal static string CollectionEditButton {
+ get {
+ return ResourceManager.GetString("CollectionEditButton", resourceCulture);
+ }
+ }
+
+ internal static string CollectionEditorTitle {
+ get {
+ return ResourceManager.GetString("CollectionEditorTitle", resourceCulture);
+ }
+ }
+
internal static string ColumnResourceName {
get {
return ResourceManager.GetString("ColumnResourceName", resourceCulture);
diff --git a/Xamarin.PropertyEditing.Mac/Resources/LocalizationResources.resx b/Xamarin.PropertyEditing.Mac/Resources/LocalizationResources.resx
index 4fdefc4..7e78b73 100644
--- a/Xamarin.PropertyEditing.Mac/Resources/LocalizationResources.resx
+++ b/Xamarin.PropertyEditing.Mac/Resources/LocalizationResources.resx
@@ -36,6 +36,22 @@
<value>{0} Combobox Editor</value>
<comment>Editor for Combobox Value</comment>
</data>
+ <data name="AccessibilityCollection" xml:space="preserve">
+ <value>{0} property, edit collection</value>
+ <comment></comment>
+ </data>
+ <data name="AccessibilityCollectionHelp" xml:space="preserve">
+ <value>Opens a window to edit the collection</value>
+ </data>
+ <data name="AccessibilityCollectionTypeSelector" xml:space="preserve">
+ <value>Type list</value>
+ </data>
+ <data name="AccessibilityCollectionAddButton" xml:space="preserve">
+ <value>Add instance of type</value>
+ </data>
+ <data name="AccessibilityCollectionRemoveButton" xml:space="preserve">
+ <value>Remove instance</value>
+ </data>
<data name="AccessibilityString" xml:space="preserve">
<value>{0} String Editor</value>
<comment>Editor for String Value</comment>
@@ -71,6 +87,16 @@
<data name="AccessibilityActionButtonDescription" xml:space="preserve">
<value>Display warnings.</value>>
</data>
+ <data name="CollectionTargetsHeader" xml:space="preserve">
+ <value>Collection Items</value>
+ </data>
+ <data name="CollectionEditButton" xml:space="preserve">
+ <value>Edit</value>
+ </data>
+ <data name="CollectionEditorTitle" xml:space="preserve">
+ <value>Edit Collection – {0}</value>
+ <comment>Edit Collection - {PropertyName}</comment>
+ </data>
<data name="ColumnResourceName" xml:space="preserve">
<value>Name</value>>
</data>
diff --git a/Xamarin.PropertyEditing.Mac/Xamarin.PropertyEditing.Mac.csproj b/Xamarin.PropertyEditing.Mac/Xamarin.PropertyEditing.Mac.csproj
index 224329d..f7dedae 100644
--- a/Xamarin.PropertyEditing.Mac/Xamarin.PropertyEditing.Mac.csproj
+++ b/Xamarin.PropertyEditing.Mac/Xamarin.PropertyEditing.Mac.csproj
@@ -142,7 +142,7 @@
<Compile Include="Controls\Layout.cs" />
<Compile Include="IHostResourceProvider.cs" />
<Compile Include="HostResourceProvider.cs" />
- <Compile Include="Controls\Custom\DynamicFillBox.cs" />
+ <Compile Include="Controls\Custom\DynamicBox.cs" />
<Compile Include="Controls\Custom\TabButton.cs" />
<Compile Include="Controls\Custom\FocusableComboBox.cs" />
<Compile Include="Controls\ObjectEditorControl.cs" />
@@ -155,7 +155,9 @@
<Compile Include="Controls\Custom\FocusableBooleanButton.cs" />
<Compile Include="Controls\Custom\FocusableButton.cs" />
<Compile Include="Controls\PropertyContainer.cs" />
- <Compile Include="Controls\ControlExtensions.cs" />
+ <Compile Include="Controls\CollectionInlineEditorControl.cs" />
+ <Compile Include="Controls\CollectionEditorWindow.cs" />
+ <Compile Include="Controls\CollectionEditorControl.cs" />
<Compile Include="PropertyList.cs" />
</ItemGroup>
<ItemGroup>
diff --git a/Xamarin.PropertyEditing/ViewModels/CollectionPropertyViewModel.cs b/Xamarin.PropertyEditing/ViewModels/CollectionPropertyViewModel.cs
index c833a6f..8f1bdd0 100644
--- a/Xamarin.PropertyEditing/ViewModels/CollectionPropertyViewModel.cs
+++ b/Xamarin.PropertyEditing/ViewModels/CollectionPropertyViewModel.cs
@@ -188,6 +188,12 @@ namespace Xamarin.PropertyEditing.ViewModels
get;
}
+ public void MoveTarget (int index, int target)
+ {
+ this.collectionView.Move (index, target);
+ ReIndex ();
+ }
+
protected override async Task UpdateCurrentValueAsync ()
{
await base.UpdateCurrentValueAsync ();
@@ -372,7 +378,12 @@ namespace Xamarin.PropertyEditing.ViewModels
var args = new TypeRequestedEventArgs();
TypeRequested?.Invoke (this, args);
- ITypeInfo st = await args.SelectedType;
+ ITypeInfo st = null;
+ try {
+ st = await args.SelectedType;
+ } catch (OperationCanceledException) {
+ }
+
if (st != null) {
if (!this.suggestedTypes.Contains (st))
this.suggestedTypes.Insert (0, st);
@@ -414,9 +425,7 @@ namespace Xamarin.PropertyEditing.ViewModels
private void MoveTarget (bool up)
{
int index = this.collectionView.IndexOf (SelectedTarget);
- this.collectionView.Move (index, index + ((up) ? -1 : 1));
-
- ReIndex();
+ MoveTarget (index, index + ((up) ? -1 : 1));
}
private bool CanAddTarget ()