void ConstrainSubviewToSuperview(NSView subview, NSView superview) { subview.TranslatesAutoresizingMaskIntoConstraints = false; NSLayoutConstraint[] constraints; if (ownedConstraints.TryGetValue(superview, out constraints)) { superview.RemoveConstraints(constraints); } ownedConstraints.Add(superview, constraints = new [] { NSLayoutConstraint.Create( subview, NSLayoutAttribute.Width, NSLayoutRelation.Equal, superview, NSLayoutAttribute.Width, 1, 0), NSLayoutConstraint.Create( subview, NSLayoutAttribute.Height, NSLayoutRelation.Equal, superview, NSLayoutAttribute.Height, 1, 0) }); superview.AddConstraints(constraints); }
public static void SwapSubView(this NSView containerView, NSView targetView) { // we could add spacing to this while (containerView.Subviews.Any()) { containerView.Subviews[0].RemoveFromSuperview(); } containerView.RemoveConstraints(containerView.Constraints); targetView.TranslatesAutoresizingMaskIntoConstraints = false; containerView.AddSubview(targetView); NSDictionary views = NSDictionary.FromObjectAndKey(targetView, new NSString("target")); containerView.AddConstraints(NSLayoutConstraint.FromVisualFormat( "H:|[target]|", NSLayoutFormatOptions.None, null, views)); containerView.AddConstraints(NSLayoutConstraint.FromVisualFormat( "V:|[target]|", NSLayoutFormatOptions.None, null, views)); }
internal static void PackViews( NSView parent, string[] constraints, NSDictionary views) { foreach (NSView view in views.Values) { view.TranslatesAutoresizingMaskIntoConstraints = false; parent.AddSubview(view); } parent.AddConstraints(BuildConstraints(constraints, views)); }
internal static void AddControls(NSView parent, string[] constraints, NSDictionary controls) { foreach (NSView control in controls.Values) { control.TranslatesAutoresizingMaskIntoConstraints = false; parent.AddSubview(control); } parent.AddConstraints(BuildConstraints(constraints, controls)); }
public static void DoMergedConstraints(this NSView view, params object[] constraints) { foreach (var o in constraints) { var singleConstraint = o as NSLayoutConstraint; var multipleConstraint = o as NSLayoutConstraint[]; if (singleConstraint != null) { view.AddConstraint(singleConstraint); } else if (multipleConstraint != null) { view.AddConstraints(multipleConstraint); } else { throw new ArgumentException("Unexpected constraint type: " + o.GetType()); } } }
public MainWindow(CGRect contentRect, NSWindowStyle aStyle, NSBackingStore bufferingType, bool deferCreation) : base(contentRect, aStyle, bufferingType, deferCreation) { // Define the User Interface of the Window here Title = "Window From Code"; // Create the content view for the window and make it fill the window ContentView = new NSView(Frame); // Add UI Elements to window ClickMeButton = NSButton.CreateButton("Click Me!", ButtonClicked); ClickMeButton.TranslatesAutoresizingMaskIntoConstraints = false; ContentView.AddSubview(ClickMeButton); ClickMeLabel = NSTextField.CreateLabel("Button has not been clicked yet."); ClickMeLabel.TranslatesAutoresizingMaskIntoConstraints = false; ContentView.AddSubview(ClickMeLabel); // Add constraints to window ContentView.AddConstraints(NSLayoutConstraint.FromVisualFormat( "V:|-[button]-[label]", NSLayoutFormatOptions.AlignAllLeading, "button", ClickMeButton, "label", ClickMeLabel)); ContentView.AddConstraints(NSLayoutConstraint.FromVisualFormat( "H:|-[button]", NSLayoutFormatOptions.AlignAllFirstBaseline, "button", ClickMeButton)); ContentView.AddConstraints(NSLayoutConstraint.FromVisualFormat( "H:|-[label]", NSLayoutFormatOptions.AlignAllFirstBaseline, "label", ClickMeLabel)); var constraints = NSLayoutConstraint.FromVisualFormat( "H:[label]-|", NSLayoutFormatOptions.AlignAllFirstBaseline, "label", ClickMeLabel); ContentView.AddConstraints(NSLayoutConstraint.FromVisualFormat( "H:[button]-(>=std)-|", NSLayoutFormatOptions.AlignAllFirstBaseline, "button", ClickMeButton, "std", constraints[0].Constant)); ContentView.AddConstraints(NSLayoutConstraint.FromVisualFormat( "H:[label]-(>=std)-|", NSLayoutFormatOptions.AlignAllFirstBaseline, "label", ClickMeLabel, "std", constraints[0].Constant)); constraints = NSLayoutConstraint.FromVisualFormat( "V:[label]-|", NSLayoutFormatOptions.AlignAllLeft, "label", ClickMeLabel); ContentView.AddConstraints(NSLayoutConstraint.FromVisualFormat( "V:[label]-(>=std)-|", NSLayoutFormatOptions.AlignAllFirstBaseline, "label", ClickMeLabel, "std", constraints[0].Constant)); }
public static void DoConstraints(this NSView view, params NSLayoutConstraint[] constraints) { view.AddConstraints(constraints); }
public MainWindow(CGRect contentRect, NSWindowStyle aStyle, NSBackingStore bufferingType, bool deferCreation) : base(contentRect, aStyle, bufferingType, deferCreation) { var windowSize = new CGSize(640, 480); var windowLocation = new CGPoint(NSScreen.MainScreen.Frame.Width / 2 - windowSize.Width / 2, NSScreen.MainScreen.Frame.Height / 2 - windowSize.Height / 2); var centerRect = new CGRect(windowLocation, windowSize); Title = "Programmatic window"; ContentView = new NSView(centerRect); var title = new NSTextField { StringValue = "Title your problem", Editable = true, UsesSingleLineMode = true, PlaceholderString = "Title your problem" }; title.AccessibilityLabel = title.PlaceholderString; title.TranslatesAutoresizingMaskIntoConstraints = false; ContentView.AddSubview(title); // There are three ways to set auto layout constraints programmatically. The first is by setting layout anchors // https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/ProgrammaticallyCreatingConstraints.html#//apple_ref/doc/uid/TP40010853-CH16-SW5 // Don't forget to set .Active = true on the constraint or it won't show up title.LeadingAnchor.ConstraintEqualToAnchor(ContentView.LeadingAnchor, PADDING).Active = true; title.TrailingAnchor.ConstraintEqualToAnchor(ContentView.TrailingAnchor, -PADDING).Active = true; title.TopAnchor.ConstraintEqualToAnchor(ContentView.TopAnchor, PADDING).Active = true; var scroll = new NSScrollView(new CGRect(0, 0, ContentView.Frame.Width - PADDING - PADDING, 100)); scroll.BorderType = NSBorderType.BezelBorder; scroll.HasHorizontalScroller = false; scroll.HasVerticalScroller = true; var scrollSize = scroll.ContentSize; var description = new NSTextView(new CGRect(0, 0, scrollSize.Width, scrollSize.Height)); description.MinSize = new CGSize(0, scrollSize.Height); description.MaxSize = new CGSize(float.MaxValue, float.MaxValue); description.Editable = true; description.Font = title.Font; description.VerticallyResizable = true; description.HorizontallyResizable = false; description.AutoresizingMask = NSViewResizingMask.WidthSizable; description.TextContainer.Size = new CGSize(scrollSize.Width, float.MaxValue); description.TextContainer.WidthTracksTextView = true; scroll.DocumentView = description; scroll.TranslatesAutoresizingMaskIntoConstraints = false; ContentView.AddSubview(scroll); // The second option is to create NSLayoutConstraints // https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/ProgrammaticallyCreatingConstraints.html#//apple_ref/doc/uid/TP40010853-CH16-SW8 ContentView.AddConstraints(new [] { NSLayoutConstraint.Create(scroll, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Leading, 1, PADDING), NSLayoutConstraint.Create(scroll, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Trailing, 1, -PADDING) }); // Alternatively, you can create the constraints as shown here and set .Active = true, same as with the anchor method above NSLayoutConstraint.Create(scroll, NSLayoutAttribute.Top, NSLayoutRelation.Equal, title, NSLayoutAttribute.Bottom, 1, PADDING).Active = true; title.Activated += (sender, e) => MakeFirstResponder(description); var labelFont = NSFont.LabelFontOfSize(10); var publicLabel = new NSTextField { StringValue = "Your title and description will be public", Editable = false, Bezeled = false, DrawsBackground = false, Selectable = false, Font = labelFont, TranslatesAutoresizingMaskIntoConstraints = false }; ContentView.AddSubview(publicLabel); // You can also use different types of constraints for the same view ContentView.AddConstraints(new [] { NSLayoutConstraint.Create(publicLabel, NSLayoutAttribute.Leading, NSLayoutRelation.GreaterThanOrEqual, ContentView, NSLayoutAttribute.Leading, 1, 40), NSLayoutConstraint.Create(publicLabel, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Trailing, 1, -PADDING) }); publicLabel.TopAnchor.ConstraintEqualToAnchor(scroll.BottomAnchor, 5).Active = true; var email = new NSTextField { Editable = true, PlaceholderString = "Optional email address" }; email.AccessibilityLabel = email.PlaceholderString; email.TranslatesAutoresizingMaskIntoConstraints = false; ContentView.AddSubview(email); ContentView.AddConstraints(new [] { NSLayoutConstraint.Create(email, NSLayoutAttribute.Top, NSLayoutRelation.Equal, publicLabel, NSLayoutAttribute.Bottom, 1, PADDING) }); // The third option for setting layout constraints is to use Visual Format Language // https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/ProgrammaticallyCreatingConstraints.html#//apple_ref/doc/uid/TP40010853-CH16-SW9 string emailFormat = "|-10-[email]-10-|"; var emailViews = NSDictionary.FromObjectAndKey(email, (NSString)"email"); var emailConstraints = NSLayoutConstraint.FromVisualFormat(emailFormat, NSLayoutFormatOptions.None, null, emailViews); NSLayoutConstraint.ActivateConstraints(emailConstraints); var sendButton = new NSButton { Title = "OK" }; sendButton.Activated += (sender, e) => { var alert = new NSAlert { MessageText = "Button pressed" }; alert.AddButton("Okay"); alert.RunModal(); Dispose(); }; sendButton.TranslatesAutoresizingMaskIntoConstraints = false; ContentView.AddSubview(sendButton); ContentView.AddConstraints(new [] { NSLayoutConstraint.Create(sendButton, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, ContentView, NSLayoutAttribute.Trailing, 1, -PADDING), NSLayoutConstraint.Create(sendButton, NSLayoutAttribute.Leading, NSLayoutRelation.GreaterThanOrEqual, ContentView, NSLayoutAttribute.Leading, 1, 40) }); //To do vertical constraints with visual format language, start the format string with V:" string sendButtonFormat = "V:[email]-10-[sendButton]-10-|"; var sendButtonViews = NSDictionary.FromObjectsAndKeys(new NSObject [] { email, sendButton }, new NSObject [] { (NSString)"email", (NSString)"sendButton" }); var sendButtonConstraints = NSLayoutConstraint.FromVisualFormat(sendButtonFormat, NSLayoutFormatOptions.None, null, sendButtonViews); NSLayoutConstraint.ActivateConstraints(sendButtonConstraints); email.Activated += (sender, e) => { if (sendButton.Enabled) { MakeFirstResponder(sendButton); } }; bool hasTitle = false; bool hasDescription = false; title.Changed += (sender, e) => { var titleStr = title.StringValue; hasTitle = !string.IsNullOrWhiteSpace(titleStr) && titleStr.Length > 5; sendButton.Enabled = hasTitle && hasDescription; }; description.TextStorage.DidProcessEditing += (sender, e) => { hasDescription = description.TextStorage.Length > 10; sendButton.Enabled = hasTitle && hasDescription; }; }
public override NSView GetView(NSOutlineView outlineView, NSTableColumn tableColumn, NSObject item) { GetVMGroupCellItendifiterFromFacade(item, out EditorViewModel evm, out PanelGroupViewModel group, out var cellIdentifier); if (group != null) { var labelContainer = (NSView)outlineView.MakeView(CategoryIdentifier, this); if (labelContainer == null) { labelContainer = new NSView { Identifier = CategoryIdentifier, }; var disclosure = outlineView.MakeView("NSOutlineViewDisclosureButtonKey", outlineView); disclosure.TranslatesAutoresizingMaskIntoConstraints = false; labelContainer.AddSubview(disclosure); var label = new UnfocusableTextField { TranslatesAutoresizingMaskIntoConstraints = false }; labelContainer.AddSubview(label); labelContainer.AddConstraints(new[] { NSLayoutConstraint.Create(disclosure, NSLayoutAttribute.CenterY, NSLayoutRelation.Equal, labelContainer, NSLayoutAttribute.CenterY, 1, 0), NSLayoutConstraint.Create(disclosure, NSLayoutAttribute.Left, NSLayoutRelation.Equal, labelContainer, NSLayoutAttribute.Left, 1, 4), NSLayoutConstraint.Create(label, NSLayoutAttribute.Left, NSLayoutRelation.Equal, disclosure, NSLayoutAttribute.Right, 1, 0), NSLayoutConstraint.Create(label, NSLayoutAttribute.Height, NSLayoutRelation.Equal, labelContainer, NSLayoutAttribute.Height, 1, 0), }); } ((UnfocusableTextField)labelContainer.Subviews[1]).StringValue = group.Category; if (this.dataSource.DataContext.GetIsExpanded(group.Category)) { SynchronizationContext.Current.Post(s => { outlineView.ExpandItem(item); }, null); } return(labelContainer); } NSView editorOrContainer = null; if (this.firstCache.TryGetValue(cellIdentifier, out IEditorView editor)) { this.firstCache.Remove(cellIdentifier); editorOrContainer = (editor.NativeView is PropertyEditorControl) ? new EditorContainer(this.hostResources, editor) { Identifier = cellIdentifier } : editor.NativeView; } else { editorOrContainer = GetEditor(cellIdentifier, evm, outlineView); editor = ((editorOrContainer as EditorContainer)?.EditorView) ?? editorOrContainer as IEditorView; } if (editorOrContainer is EditorContainer ec) { ec.ViewModel = evm; ec.Label = evm.Name; #if DEBUG // Currently only used to highlight which controls haven't been implemented if (editor == null) { ec.LabelTextColor = NSColor.Red; } #endif } if (editor != null) { var ovm = evm as ObjectPropertyViewModel; if (ovm != null && editorOrContainer is EditorContainer container) { if (container.LeftEdgeView == null) { if (ovm.CanDelve) { container.LeftEdgeView = outlineView.MakeView("NSOutlineViewDisclosureButtonKey", outlineView); } } else if (!ovm.CanDelve) { container.LeftEdgeView = null; } } else if (!(editorOrContainer is EditorContainer)) { editor.ViewModel = evm; } bool openObjectRow = ovm != null && outlineView.IsItemExpanded(item); if (!openObjectRow) { var parent = outlineView.GetParent(item); openObjectRow = (parent != null && ((NSObjectFacade)parent).Target is ObjectPropertyViewModel); } SetRowValueBackground(editorOrContainer, openObjectRow); // Force a row update due to new height, but only when we are non-default if (editor.IsDynamicallySized) { nint index = outlineView.RowForItem(item); outlineView.NoteHeightOfRowsWithIndexesChanged(new NSIndexSet(index)); } } else if (editorOrContainer is PanelHeaderEditorControl header) { header.ViewModel = this.dataSource.DataContext; } return(editorOrContainer); }