diff options
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 Binary files differnew file mode 100755 index 0000000..a884ca8 --- /dev/null +++ b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-add-16.png 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 Binary files differnew file mode 100755 index 0000000..e71fdbd --- /dev/null +++ b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-add-16@2x.png 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 Binary files differnew file mode 100755 index 0000000..6751913 --- /dev/null +++ b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-add-16~dark.png 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 Binary files differnew file mode 100755 index 0000000..4f160c7 --- /dev/null +++ b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-add-16~dark@2x.png 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 Binary files differnew file mode 100755 index 0000000..ade63c0 --- /dev/null +++ b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-remove-16.png 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 Binary files differnew file mode 100755 index 0000000..6e2f4d0 --- /dev/null +++ b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-remove-16@2x.png 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 Binary files differnew file mode 100755 index 0000000..f6b4266 --- /dev/null +++ b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-remove-16~dark.png 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 Binary files differnew file mode 100755 index 0000000..3a6d32b --- /dev/null +++ b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-list-remove-16~dark@2x.png 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 Binary files differnew file mode 100755 index 0000000..9055ecd --- /dev/null +++ b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-property-generic-item-16.png 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 Binary files differnew file mode 100755 index 0000000..ba41dc3 --- /dev/null +++ b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-property-generic-item-16@2x.png 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 Binary files differnew file mode 100755 index 0000000..b76d421 --- /dev/null +++ b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-property-generic-item-16~dark.png 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 Binary files differnew file mode 100755 index 0000000..a314f65 --- /dev/null +++ b/Xamarin.PropertyEditing.Mac/PropertyEditingResource/Contents/Resources/pe-property-generic-item-16~dark@2x.png 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 () |