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

ConstraintExtensions.cs « Controls « Xamarin.PropertyEditing.Mac - github.com/xamarin/Xamarin.PropertyEditing.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: f2816a4cfadfafd1fec4a7a62d6a59e372e087fa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
using System;
using System.Linq;
using System.Linq.Expressions;
using AppKit;

namespace Xamarin.PropertyEditing.Mac
{
	public struct ConstraintProxy
	{
		public int Left, Top, Right, Bottom, Leading, Trailing, CenterX, CenterY, Baseline, Height, Width;
	}

	public static class ConstraintExtensions
	{
		public static NSLayoutConstraint[] ConstraintFill (this NSView child, NSView container, int padding = 0)
		{
			return new NSLayoutConstraint[] {
				NSLayoutConstraint.Create (child, NSLayoutAttribute.Left, NSLayoutRelation.Equal, container, NSLayoutAttribute.Left, 1, padding),
				NSLayoutConstraint.Create (child, NSLayoutAttribute.Right, NSLayoutRelation.Equal, container, NSLayoutAttribute.Right, 1, -padding),
				NSLayoutConstraint.Create (child, NSLayoutAttribute.Top, NSLayoutRelation.Equal, container, NSLayoutAttribute.Top, 1, container.IsFlipped ? padding : -padding),
				NSLayoutConstraint.Create (child, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, container, NSLayoutAttribute.Bottom, 1, container.IsFlipped ? -padding : padding),
			};
		}

		public static NSLayoutConstraint ConstraintTo (this NSView view1, NSView view2, Expression<Func<ConstraintProxy, ConstraintProxy, bool>> expression)
		{
			var mainExpression = expression.Body as BinaryExpression;
			NSLayoutRelation relation = NSLayoutRelation.Equal;
			switch (mainExpression.NodeType) {
				case ExpressionType.Equal:
					relation = NSLayoutRelation.Equal;
					break;
				case ExpressionType.LessThanOrEqual:
					relation = NSLayoutRelation.LessThanOrEqual;
					break;
				case ExpressionType.GreaterThanOrEqual:
					relation = NSLayoutRelation.GreaterThanOrEqual;
					break;
				default:
					throw new ArgumentException ("Relation " + mainExpression.NodeType.ToString () + " not valid");
			}

			var propLeft = (NSLayoutAttribute)Enum.Parse (typeof (NSLayoutAttribute), ((MemberExpression)mainExpression.Left).Member.Name);
			var propRight = propLeft;

			if (mainExpression.Right.NodeType == ExpressionType.Constant) {
				var c = Convert.ToSingle (((ConstantExpression)mainExpression.Right).Value);
				// Console.WriteLine ("NSLayoutConstraint.Create ({0}, NSLayoutAttribute.{1}, NSLayoutRelation.{2}, {3},  NSLayoutAttribute.{4}, {5}f, {6}f),", view1, propLeft, relation, null, propRight, 1, c);
				return NSLayoutConstraint.Create (view1, propLeft, relation, null, NSLayoutAttribute.NoAttribute, 1, c);
			}
			else if (mainExpression.Right is MemberExpression) {
				propRight = (NSLayoutAttribute)Enum.Parse (typeof (NSLayoutAttribute), ((MemberExpression)mainExpression.Right).Member.Name);
				// Console.WriteLine ("NSLayoutConstraint.Create ({0}, NSLayoutAttribute.{1}, NSLayoutRelation.{2}, {3},  NSLayoutAttribute.{4}, {5}f, {6}f),", view1, propLeft, relation, view2, propRight, 1, 0);
				return NSLayoutConstraint.Create (view1, propLeft, relation, view2, propRight, 1, 0);
			}

			var addNode = mainExpression.Right as BinaryExpression;

			var mulNode = addNode;
			var constant = 0f;
			var multiplier = 1f;

			if (addNode.Left.NodeType == ExpressionType.Constant) {
				mulNode = addNode.Right as BinaryExpression;
				constant = Convert.ToSingle (((ConstantExpression)addNode.Left).Value);
			}
			else {
				mulNode = addNode.Left as BinaryExpression;
				constant = Convert.ToSingle (((ConstantExpression)addNode.Right).Value);
			}
			constant *= addNode.NodeType == ExpressionType.Subtract ? -1 : 1;

			if (mulNode != null) {
				if (mulNode.Left.NodeType == ExpressionType.Constant) {
					multiplier = Convert.ToSingle (((ConstantExpression)mulNode.Left).Value);
					propRight = (NSLayoutAttribute)Enum.Parse (typeof (NSLayoutAttribute), ((MemberExpression)mulNode.Right).Member.Name);
				}
				else {
					multiplier = Convert.ToSingle (((ConstantExpression)mulNode.Right).Value);
					propRight = (NSLayoutAttribute)Enum.Parse (typeof (NSLayoutAttribute), ((MemberExpression)mulNode.Left).Member.Name);
				}
				if (mulNode.NodeType == ExpressionType.Divide)
					multiplier = 1.0f / multiplier;
			}
			else {
				var member = (MemberExpression)(addNode.Right is MemberExpression ? addNode.Right : addNode.Left);
				propRight = (NSLayoutAttribute)Enum.Parse (typeof (NSLayoutAttribute), member.Member.Name);
			}
		
			// Console.WriteLine ("NSLayoutConstraint.Create ({0}, NSLayoutAttribute.{1}, NSLayoutRelation.{2}, {3},  NSLayoutAttribute.{4}, {5}f, {6}f),", view1, propLeft, relation, view2, propRight, multiplier, constant);

			return NSLayoutConstraint.Create (view1, propLeft, relation, view2, propRight, multiplier, constant);
		}

		public static void DoConstraints (this NSView view, params NSLayoutConstraint[] constraints)
		{
			view.AddConstraints (constraints);
		}

		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 static NSLayoutConstraint SticksTo (this NSView child, NSView container, NSLayoutAttribute attribute, int padding = 0)
		{
			return NSLayoutConstraint.Create (child, attribute, NSLayoutRelation.Equal, container, attribute, 1, padding);
		}

		public static NSLayoutConstraint[] SticksTo (this NSView child, NSView container, params NSLayoutAttribute[] attributes)
		{
			return attributes
					.Select (a => NSLayoutConstraint.Create (child, a, NSLayoutRelation.Equal, container, a, 1, 0))
					.ToArray ();
		}

		public static NSLayoutConstraint WithPriority (this NSLayoutConstraint constraint, NSLayoutPriority priority)
		{
			return constraint.WithPriority ((float)priority);
		}

		public static NSLayoutConstraint WithPriority (this NSLayoutConstraint constraint, float priority)
		{
			constraint.Priority = priority;
			return constraint;
		}
	}
}