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-01-15 19:11:58 +0300
committerEric Maupin <ermaup@microsoft.com>2019-02-15 21:00:44 +0300
commit6a6761eb9b3d8624ee6901fcde1c94db47250357 (patch)
tree37c37ab590f23724f85c6b1b38dd470bcee9f7de /Xamarin.PropertyEditing.Mac
parent00594887a77ac1f3382dc4a59a1f01d42bf04b8e (diff)
[mac] Add ObjectEditor
Diffstat (limited to 'Xamarin.PropertyEditing.Mac')
-rw-r--r--Xamarin.PropertyEditing.Mac/Controls/ObjectEditorControl.cs184
-rw-r--r--Xamarin.PropertyEditing.Mac/Controls/TypeSelectorWindow.cs75
-rw-r--r--Xamarin.PropertyEditing.Mac/PropertyEditorPanel.cs2
-rw-r--r--Xamarin.PropertyEditing.Mac/PropertyEditorSelector.cs2
-rw-r--r--Xamarin.PropertyEditing.Mac/PropertyTableDataSource.cs30
-rw-r--r--Xamarin.PropertyEditing.Mac/Xamarin.PropertyEditing.Mac.csproj2
6 files changed, 290 insertions, 5 deletions
diff --git a/Xamarin.PropertyEditing.Mac/Controls/ObjectEditorControl.cs b/Xamarin.PropertyEditing.Mac/Controls/ObjectEditorControl.cs
new file mode 100644
index 0000000..ab9749b
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac/Controls/ObjectEditorControl.cs
@@ -0,0 +1,184 @@
+using System;
+using System.Collections;
+using System.ComponentModel;
+using System.Threading.Tasks;
+using AppKit;
+using Foundation;
+using Xamarin.PropertyEditing.ViewModels;
+
+namespace Xamarin.PropertyEditing.Mac
+{
+ internal class ObjectEditorControl
+ : PropertyEditorControl<ObjectPropertyViewModel>
+ {
+ public ObjectEditorControl (IHostResourceProvider hostResources)
+ : base (hostResources)
+ {
+ this.typeLabel = new UnfocusableTextField {
+ TranslatesAutoresizingMaskIntoConstraints = false
+ };
+ AddSubview (this.typeLabel);
+
+ this.createObject = new NSButton {
+ Title = Properties.Resources.New,
+ TranslatesAutoresizingMaskIntoConstraints = false,
+ BezelStyle = NSBezelStyle.Rounded
+ };
+ this.createObject.Activated += OnNewPressed;
+ AddSubview (this.createObject);
+
+ this.buttonConstraint = NSLayoutConstraint.Create (this.createObject, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, this.typeLabel, NSLayoutAttribute.Trailing, 1f, 12);
+
+ AddConstraints (new[] {
+ NSLayoutConstraint.Create (this.typeLabel, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, this, NSLayoutAttribute.Leading, 1f, 0f),
+ NSLayoutConstraint.Create (this.typeLabel, NSLayoutAttribute.CenterY, NSLayoutRelation.Equal, this, NSLayoutAttribute.CenterY, 1f, 0f),
+ NSLayoutConstraint.Create (this.typeLabel, NSLayoutAttribute.Height, NSLayoutRelation.Equal, this, NSLayoutAttribute.Height, 1, 0),
+ this.buttonConstraint,
+ NSLayoutConstraint.Create (this.createObject, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, this, NSLayoutAttribute.Leading, 1, 0).WithPriority (NSLayoutPriority.DefaultLow),
+ NSLayoutConstraint.Create (this.createObject, NSLayoutAttribute.CenterY, NSLayoutRelation.Equal, this, NSLayoutAttribute.CenterY, 1f, 0f),
+ NSLayoutConstraint.Create (this.createObject, NSLayoutAttribute.Width, NSLayoutRelation.GreaterThanOrEqual, 1f, 70f),
+ });
+ }
+
+ public override NSView FirstKeyView => this.createObject;
+
+ public override NSView LastKeyView => this.createObject;
+
+ protected override void UpdateValue ()
+ {
+ }
+
+ protected override void UpdateErrorsDisplayed (IEnumerable errors)
+ {
+ }
+
+ protected override void HandleErrorsChanged (object sender, DataErrorsChangedEventArgs e)
+ {
+ }
+
+ protected override void SetEnabled ()
+ {
+ this.createObject.Enabled = ViewModel.Property.CanWrite;
+ }
+
+ protected override void UpdateAccessibilityValues ()
+ {
+ this.createObject.AccessibilityTitle = String.Format (Properties.Resources.NewInstanceForProperty, ViewModel.Property.Name);
+ }
+
+ protected override void OnViewModelChanged (PropertyViewModel oldModel)
+ {
+ base.OnViewModelChanged (oldModel);
+
+ if (oldModel is ObjectPropertyViewModel ovm) {
+ ovm.TypeRequested -= OnTypeRequested;
+ ovm.CreateInstanceCommand.CanExecuteChanged -= OnCreateInstanceExecutableChanged;
+ }
+
+ if (ViewModel != null) {
+ ViewModel.TypeRequested += OnTypeRequested;
+ ViewModel.CreateInstanceCommand.CanExecuteChanged += OnCreateInstanceExecutableChanged;
+
+ OnPropertyChanged (ViewModel, new PropertyChangedEventArgs (null));
+ }
+ }
+
+ protected override void OnPropertyChanged (object sender, PropertyChangedEventArgs e)
+ {
+ switch (e.PropertyName) {
+ case nameof (ObjectPropertyViewModel.ValueType):
+ UpdateTypeLabel ();
+ break;
+ case null:
+ case "":
+ UpdateTypeLabel ();
+ UpdateCreateInstanceCommand ();
+ break;
+ }
+
+ base.OnPropertyChanged (sender, e);
+ }
+
+ private readonly UnfocusableTextField typeLabel;
+ private readonly NSButton createObject;
+ private readonly NSLayoutConstraint buttonConstraint;
+
+ private void OnCreateInstanceExecutableChanged (object sender, EventArgs e)
+ {
+ UpdateCreateInstanceCommand ();
+ }
+
+ private void OnTypeRequested (object sender, TypeRequestedEventArgs e)
+ {
+ var tcs = new TaskCompletionSource<ITypeInfo> ();
+ e.SelectedType = tcs.Task;
+
+ var vm = new TypeSelectorViewModel (ViewModel.AssignableTypes);
+ var selector = new TypeSelectorControl {
+ ViewModel = vm,
+ Appearance = EffectiveAppearance
+ };
+
+ vm.PropertyChanged += (vms, ve) => {
+ if (ve.PropertyName == nameof (TypeSelectorViewModel.SelectedType)) {
+ tcs.TrySetResult (vm.SelectedType);
+ }
+ };
+
+ var popover = new NSPopover {
+ Behavior = NSPopoverBehavior.Transient,
+ Delegate = new PopoverDelegate<ITypeInfo> (tcs),
+ ContentViewController = new NSViewController {
+ View = selector,
+ PreferredContentSize = new CoreGraphics.CGSize (360, 335)
+ },
+ };
+
+ popover.SetAppearance (HostResources.GetVibrantAppearance (EffectiveAppearance));
+
+ tcs.Task.ContinueWith (t => {
+ popover.PerformClose (popover);
+ popover.Dispose ();
+ }, TaskScheduler.FromCurrentSynchronizationContext());
+
+ popover.Show (this.createObject.Frame, this, NSRectEdge.MinYEdge);
+ }
+
+ private void UpdateTypeLabel ()
+ {
+ if (ViewModel.ValueType == null) {
+ this.typeLabel.StringValue = String.Empty;
+ this.buttonConstraint.Active = false;
+ } else {
+ this.typeLabel.StringValue = $"({ViewModel.ValueType.Name})";
+ this.buttonConstraint.Active = true;
+ }
+ }
+
+ private void UpdateCreateInstanceCommand()
+ {
+ this.createObject.Enabled = ViewModel.CreateInstanceCommand.CanExecute (null);
+ }
+
+ private void OnNewPressed (object sender, EventArgs e)
+ {
+ ViewModel.CreateInstanceCommand.Execute (null);
+ }
+
+ private class PopoverDelegate<T>
+ : NSPopoverDelegate
+ {
+ public PopoverDelegate (TaskCompletionSource<T> tcs)
+ {
+ this.tcs = tcs;
+ }
+
+ public override void WillClose (NSNotification notification)
+ {
+ this.tcs.TrySetCanceled ();
+ }
+
+ private readonly TaskCompletionSource<T> tcs;
+ }
+ }
+}
diff --git a/Xamarin.PropertyEditing.Mac/Controls/TypeSelectorWindow.cs b/Xamarin.PropertyEditing.Mac/Controls/TypeSelectorWindow.cs
new file mode 100644
index 0000000..de4da3c
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac/Controls/TypeSelectorWindow.cs
@@ -0,0 +1,75 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+using AppKit;
+using CoreGraphics;
+
+using Xamarin.PropertyEditing.ViewModels;
+
+namespace Xamarin.PropertyEditing.Mac
+{
+ internal class TypeSelectorWindow
+ : NSWindow
+ {
+ public TypeSelectorWindow (TypeSelectorViewModel viewModel)
+ : base (new CGRect (0, 0, 300, 300), NSWindowStyle.Titled | NSWindowStyle.Closable | NSWindowStyle.Resizable, NSBackingStore.Buffered, true)
+ {
+ Title = Properties.Resources.SelectObjectTitle;
+
+ this.selector = new TypeSelectorControl {
+ ViewModel = viewModel,
+ TranslatesAutoresizingMaskIntoConstraints = false
+ };
+
+ ContentView.AddSubview (this.selector);
+
+ this.ok = NSButton.CreateButton (Properties.Resources.OK, OnOked);
+ this.ok.TranslatesAutoresizingMaskIntoConstraints = false;
+ 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.selector, NSLayoutAttribute.Width, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Width, 1, -20),
+ NSLayoutConstraint.Create (this.selector, NSLayoutAttribute.Top, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Top, 1, 0),
+ NSLayoutConstraint.Create (this.selector, NSLayoutAttribute.CenterX, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.CenterX, 1, 0),
+ NSLayoutConstraint.Create (this.selector, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, this.ok, NSLayoutAttribute.Top, 1, -10),
+
+ NSLayoutConstraint.Create (this.ok, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Bottom, 1, -10),
+ NSLayoutConstraint.Create (this.ok, NSLayoutAttribute.Right, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Right, 1, -10),
+
+ NSLayoutConstraint.Create (this.cancel, NSLayoutAttribute.Right, NSLayoutRelation.Equal, this.ok, NSLayoutAttribute.Left, 1, -10),
+ NSLayoutConstraint.Create (this.cancel, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Bottom, 1, -10),
+ });
+ }
+
+ private TypeSelectorControl selector;
+ private NSButton ok, cancel;
+
+ private void OnOked ()
+ {
+ NSApplication.SharedApplication.StopModalWithCode ((int)NSModalResponse.OK);
+ Close ();
+ }
+
+ private void OnCanceled ()
+ {
+ NSApplication.SharedApplication.StopModalWithCode ((int)NSModalResponse.Cancel);
+ Close ();
+ }
+
+ public static ITypeInfo RequestType (AsyncValue<IReadOnlyDictionary<IAssemblyInfo, ILookup<string, ITypeInfo>>> assignableTypes)
+ {
+ var w = new TypeSelectorWindow (new TypeSelectorViewModel (assignableTypes));
+
+ var result = (NSModalResponse)(int)NSApplication.SharedApplication.RunModalForWindow (w);
+ if (result != NSModalResponse.OK)
+ return null;
+
+ return w.selector.ViewModel.SelectedType;
+ }
+ }
+}
diff --git a/Xamarin.PropertyEditing.Mac/PropertyEditorPanel.cs b/Xamarin.PropertyEditing.Mac/PropertyEditorPanel.cs
index 566ca5b..51051be 100644
--- a/Xamarin.PropertyEditing.Mac/PropertyEditorPanel.cs
+++ b/Xamarin.PropertyEditing.Mac/PropertyEditorPanel.cs
@@ -183,7 +183,7 @@ namespace Xamarin.PropertyEditing.Mac
var propertyEditors = new NSTableColumn (PropertyEditorColId);
this.propertyTable.AddColumn (propertyEditors);
- // Set OutlineTableColumn or the arrows showing children/expansion will not be drawn
+ // Set OutlineTableColumn or the arrows showing children/expansion or they will not be drawn
this.propertyTable.OutlineTableColumn = propertyEditors;
var tableContainer = new NSScrollView {
diff --git a/Xamarin.PropertyEditing.Mac/PropertyEditorSelector.cs b/Xamarin.PropertyEditing.Mac/PropertyEditorSelector.cs
index d3a7398..cb96191 100644
--- a/Xamarin.PropertyEditing.Mac/PropertyEditorSelector.cs
+++ b/Xamarin.PropertyEditing.Mac/PropertyEditorSelector.cs
@@ -54,6 +54,8 @@ namespace Xamarin.PropertyEditing.Mac
{typeof (RatioViewModel), typeof (RatioEditorControl<CommonRatio>)},
{typeof (ThicknessPropertyViewModel), typeof (CommonThicknessEditorControl) },
{typeof (PropertyGroupViewModel), typeof (GroupEditorControl)},
+ {typeof (ObjectPropertyViewModel), typeof (ObjectEditorControl)},
+
};
}
}
diff --git a/Xamarin.PropertyEditing.Mac/PropertyTableDataSource.cs b/Xamarin.PropertyEditing.Mac/PropertyTableDataSource.cs
index da40034..2c0e403 100644
--- a/Xamarin.PropertyEditing.Mac/PropertyTableDataSource.cs
+++ b/Xamarin.PropertyEditing.Mac/PropertyTableDataSource.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.ComponentModel;
using System.Linq;
using AppKit;
using Foundation;
@@ -27,8 +28,11 @@ namespace Xamarin.PropertyEditing.Mac
if (this.vm.ArrangedEditors.Count == 0)
return 0;
- var childCount = 0;
+ var facade = (NSObjectFacade)item;
+ if (facade?.Target is ObjectPropertyViewModel ovm)
+ return ovm.ValueModel.Properties.Count;
+ var childCount = 0;
if (this.vm.ArrangeMode == PropertyArrangeMode.Name)
childCount = Filtering ? this.vm.ArrangedEditors[0].Editors.Count : this.vm.ArrangedEditors[0].Editors.Count + 1;
else {
@@ -47,17 +51,20 @@ namespace Xamarin.PropertyEditing.Mac
{
object element;
+ var f = ((NSObjectFacade)item);
// We only want the Header to appear at the top of both Category and Name Modes, which means item is null in both.
if (childIndex == 0 && item == null && !Filtering)
element = null;
- else {
+ else if (f?.Target is ObjectPropertyViewModel ovm) {
+ element = ovm.ValueModel.Properties[(int)childIndex];
+ } else {
if (this.vm.ArrangeMode == PropertyArrangeMode.Name)
element = Filtering ? this.vm.ArrangedEditors[0].Editors[(int)childIndex] : this.vm.ArrangedEditors[0].Editors[(int)childIndex - 1];
else {
if (item == null)
element = Filtering ? this.vm.ArrangedEditors[(int)childIndex] : this.vm.ArrangedEditors[(int)childIndex - 1];
else {
- var group = (PanelGroupViewModel)((NSObjectFacade)item).Target;
+ var group = (PanelGroupViewModel)f.Target;
var list = group.Editors;
if (childIndex >= list.Count) {
childIndex -= list.Count;
@@ -74,10 +81,25 @@ namespace Xamarin.PropertyEditing.Mac
public override bool ItemExpandable (NSOutlineView outlineView, NSObject item)
{
+ var f = (NSObjectFacade)item;
+ if (f.Target is ObjectPropertyViewModel ovm) {
+ PropertyChangedEventHandler changed = null;
+ changed = (o, e) => {
+ if (e.PropertyName != nameof (ObjectPropertyViewModel.CanDelve))
+ return;
+
+ ovm.PropertyChanged -= changed;
+ outlineView.ReloadItem (item);
+ };
+ ovm.PropertyChanged += changed;
+
+ return ovm.CanDelve;
+ }
+
if (this.vm.ArrangeMode == PropertyArrangeMode.Name)
return false;
- return ((NSObjectFacade)item).Target is PanelGroupViewModel;
+ return f.Target is PanelGroupViewModel;
}
public NSObject GetFacade (object element)
diff --git a/Xamarin.PropertyEditing.Mac/Xamarin.PropertyEditing.Mac.csproj b/Xamarin.PropertyEditing.Mac/Xamarin.PropertyEditing.Mac.csproj
index ce10228..708bcdd 100644
--- a/Xamarin.PropertyEditing.Mac/Xamarin.PropertyEditing.Mac.csproj
+++ b/Xamarin.PropertyEditing.Mac/Xamarin.PropertyEditing.Mac.csproj
@@ -145,7 +145,9 @@
<Compile Include="Controls\Custom\DynamicFillBox.cs" />
<Compile Include="Controls\Custom\TabButton.cs" />
<Compile Include="Controls\Custom\FocusableComboBox.cs" />
+ <Compile Include="Controls\ObjectEditorControl.cs" />
<Compile Include="Controls\TypeSelectorControl.cs" />
+ <Compile Include="Controls\TypeSelectorWindow.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="Controls\" />