File: AnimatingViewsWindowController.cs

package info (click to toggle)
monodevelop 3.0.3.2%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 153,256 kB
  • sloc: cs: 1,020,242; xml: 751,053; makefile: 9,596; sh: 1,529; objc: 302; sql: 129; ansic: 96
file content (186 lines) | stat: -rw-r--r-- 4,919 bytes parent folder | download
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186

using System;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using MonoMac.Foundation;
using MonoMac.AppKit;
using MonoMac.CoreAnimation;

namespace AnimatingViews
{
	public partial class AnimatingViewsWindowController : MonoMac.AppKit.NSWindowController
	{
		private enum Layout {
			ColumnLayout,
			RowLayout,
			GridLayout
		}
		
		private Layout layoutStyle = Layout.ColumnLayout;
		
		/* Default separation between items, and default size of added subviews. */
		private const float SEPARATION = 10.0f;
		private const float BOX_WIDTH = 80.0f;
		private const float BOX_HEIGHT = 80.0f;
		
		// Called when created from unmanaged code
		public AnimatingViewsWindowController (IntPtr handle) : base(handle)
		{
		}

		// Called when created directly from a XIB file
		[Export("initWithCoder:")]
		public AnimatingViewsWindowController (NSCoder coder) : base(coder)
		{
		}

		// Call to load from the XIB/NIB file
		public AnimatingViewsWindowController () : base("AnimatingViewsWindow")
		{
		}
		
		private Layout LayoutStyle {
			get {
				return layoutStyle;
			}
			
			set {
				if (layoutStyle != value) {
					layoutStyle = value;
					layout ();
				}
			}
		}
		
		//strongly typed window accessor
		public new AnimatingViewsWindow Window {
			get { return (AnimatingViewsWindow)base.Window; }
		}
		
		// Action for change layout Matrix
		partial void changeLayout (NSMatrix sender)
		{
			LayoutStyle = (Layout)sender.SelectedTag;
			layout ();
			
		} 
		
		// Action for Add pushbutton
		partial void addABox (NSButton sender)
		{
			simpleView.AddSubview (viewToBeAdded ());
			layout ();
		}
		
		// Action for Remove pushbutton
		partial void removeLastBox (NSButton sender)
		{
			if (simpleView.Subviews.Length == 0)
				return;
			
			simpleView.Subviews.Last ().RemoveFromSuperview ();
			layout ();
		}
		
		private NSView viewToBeAdded() 
		{
			return new NSBox (new RectangleF (0.0f, 0.0f, BOX_WIDTH, BOX_HEIGHT)){
				BoxType = NSBoxType.NSBoxCustom,
				BorderType = NSBorderType.LineBorder,
				TitlePosition = NSTitlePosition.NoTitle,
				FillColor = colorWell.Color
			};
		}
		
		/* This method returns a rect that is integral in base coordinates. */
		private RectangleF integralRect (RectangleF rect) 
		{
			// missing NSIntegralRect
			//return simpleView.ConvertRectFromBase(NSIntegralRect(simpleView.ConvertRectToBase(rect)));
			return simpleView.ConvertRectFromBase(simpleView.ConvertRectToBase(rect));	
		}
		
		// Layout the sub views
		private void layout ()
		{
			NSView[] subviews = simpleView.Subviews;
			PointF curPoint;
				
			switch (LayoutStyle){
			case Layout.ColumnLayout:
				curPoint = new PointF(simpleView.Bounds.Size.Width / 2.0f, 0.0f);
				foreach (NSView subview in subviews) {
					RectangleF frame = new RectangleF(curPoint.X - BOX_WIDTH /2.0f, curPoint.Y, BOX_WIDTH, BOX_HEIGHT);
					animateView(subview, frame);
					curPoint.Y += frame.Size.Height + SEPARATION;
				}
				break;

			case Layout.RowLayout:
				curPoint = new PointF(0.0f , simpleView.Bounds.Size.Height / 2.0f);
				foreach (NSView subview in subviews) {
					RectangleF frame = new RectangleF(curPoint.X, curPoint.Y - BOX_HEIGHT /2.0f, BOX_WIDTH, BOX_HEIGHT);
					animateView(subview, frame);
					curPoint.X += frame.Size.Width + SEPARATION;
				}
				break;

			case Layout.GridLayout:
				int viewsPerSide = (int)Math.Ceiling( Math.Sqrt(subviews.Count()) ); 
				
				int idx = 0;
				foreach (NSView subview in subviews) {
					RectangleF frame = new RectangleF(curPoint.X, curPoint.Y, BOX_WIDTH, BOX_HEIGHT);
					
					animateView(subview, frame);
					curPoint.X += frame.Size.Width + SEPARATION;
					
					if (++idx % viewsPerSide == 0) {
						curPoint.X = 0;
						curPoint.Y += BOX_HEIGHT + SEPARATION;
					}
				}
				break;
				
			}
		}
		
		// Helper method to animate the sub view
		private void animateView(NSView subView, RectangleF toFrame) 
		{
#if true
			// Simple animation: assign the new value, and let CoreAnimation
			// take it from here
			
			((NSView) subView.Animator).Frame = toFrame;
#else
			//
			// Performing the animation by hand, every step of the way
			//
			var animationY = CABasicAnimation.FromKeyPath("position.y");
			animationY.To = NSNumber.FromFloat(toFrame.Y);
			animationY.AnimationStopped += delegate {
				//Console.WriteLine("animation stopped");
				subView.Layer.Frame = toFrame;
			};
			
			var animationX = CABasicAnimation.FromKeyPath("position.x");
			animationX.To = NSNumber.FromFloat(toFrame.X);
			
			animationY.AutoReverses = false;
			animationX.AutoReverses = false;
			
			animationY.RemovedOnCompletion = false;
			animationX.RemovedOnCompletion = false;
			
			animationY.FillMode = CAFillMode.Forwards;
			animationX.FillMode = CAFillMode.Forwards;
			
			subView.Layer.AddAnimation(animationX,"moveX");
			subView.Layer.AddAnimation(animationY,"moveY");
#endif
		}
	}
}