2006-09-15 Jonathan Pobst <monkey@jpobst.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms.Layout / DefaultLayout.cs
1 //\r
2 // DefaultLayout.cs\r
3 //\r
4 // Permission is hereby granted, free of charge, to any person obtaining\r
5 // a copy of this software and associated documentation files (the\r
6 // "Software"), to deal in the Software without restriction, including\r
7 // without limitation the rights to use, copy, modify, merge, publish,\r
8 // distribute, sublicense, and/or sell copies of the Software, and to\r
9 // permit persons to whom the Software is furnished to do so, subject to\r
10 // the following conditions:\r
11 // \r
12 // The above copyright notice and this permission notice shall be\r
13 // included in all copies or substantial portions of the Software.\r
14 // \r
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
22 //\r
23 // Copyright (c) 2006 Jonathan Pobst\r
24 //\r
25 // Authors:\r
26 //      Jonathan Pobst (monkey@jpobst.com)\r
27 //\r
28 \r
29 #if NET_2_0\r
30 using System;\r
31 using System.Drawing;\r
32 \r
33 namespace System.Windows.Forms.Layout\r
34 {\r
35         class DefaultLayout : LayoutEngine\r
36         {\r
37                 public override bool Layout (object container, LayoutEventArgs args)\r
38                 {\r
39                         // Copied from 1.1's Control.PerformLayout\r
40                         Control parent = container as Control;\r
41 \r
42                         Control child;\r
43                         AnchorStyles anchor;\r
44                         Rectangle space;\r
45 \r
46                         space = parent.DisplayRectangle;\r
47 \r
48                         // Deal with docking; go through in reverse, MS docs say that lowest Z-order is closest to edge\r
49                         Control[] controls = parent.child_controls.GetAllControls ();\r
50                         for (int i = controls.Length - 1; i >= 0; i--) {\r
51                                 child = controls[i];\r
52 \r
53                                 if (!child.Visible) {\r
54                                         continue;\r
55                                 }\r
56 \r
57                                 switch (child.Dock) {\r
58                                         case DockStyle.None: {\r
59                                                         // Do nothing\r
60                                                         break;\r
61                                                 }\r
62 \r
63                                         case DockStyle.Left: {\r
64                                                         child.SetBounds (space.Left, space.Y, child.Width, space.Height);\r
65                                                         space.X += child.Width;\r
66                                                         space.Width -= child.Width;\r
67                                                         break;\r
68                                                 }\r
69 \r
70                                         case DockStyle.Top: {\r
71                                                         child.SetBounds (space.Left, space.Y, space.Width, child.Height);\r
72                                                         space.Y += child.Height;\r
73                                                         space.Height -= child.Height;\r
74                                                         break;\r
75                                                 }\r
76 \r
77                                         case DockStyle.Right: {\r
78                                                         child.SetBounds (space.Right - child.Width, space.Y, child.Width, space.Height);\r
79                                                         space.Width -= child.Width;\r
80                                                         break;\r
81                                                 }\r
82 \r
83                                         case DockStyle.Bottom: {\r
84                                                         child.SetBounds (space.Left, space.Bottom - child.Height, space.Width, child.Height);\r
85                                                         space.Height -= child.Height;\r
86                                                         break;\r
87                                                 }\r
88                                 }\r
89                         }\r
90 \r
91                         for (int i = controls.Length - 1; i >= 0; i--) {\r
92                                 child = controls[i];\r
93 \r
94                                 if (child.Visible && (child.Dock == DockStyle.Fill)) {\r
95                                         child.SetBounds (space.Left, space.Top, space.Width, space.Height);\r
96                                 }\r
97                         }\r
98 \r
99                         space = parent.DisplayRectangle;\r
100 \r
101                         for (int i = 0; i < controls.Length; i++) {\r
102                                 int left;\r
103                                 int top;\r
104                                 int width;\r
105                                 int height;\r
106 \r
107                                 child = controls[i];\r
108 \r
109                                 // If the control is docked we don't need to do anything\r
110                                 if (child.Dock != DockStyle.None) {\r
111                                         continue;\r
112                                 }\r
113 \r
114                                 anchor = child.Anchor;\r
115 \r
116                                 left = child.Left;\r
117                                 top = child.Top;\r
118                                 width = child.Width;\r
119                                 height = child.Height;\r
120 \r
121                                 if ((anchor & AnchorStyles.Left) != 0) {\r
122                                         if ((anchor & AnchorStyles.Right) != 0) {\r
123                                                 width = space.Width - child.dist_right - left;\r
124                                         }\r
125                                         else {\r
126                                                 ; // Left anchored only, nothing to be done\r
127                                         }\r
128                                 }\r
129                                 else if ((anchor & AnchorStyles.Right) != 0) {\r
130                                         left = space.Width - child.dist_right - width;\r
131                                 }\r
132                                 else {\r
133                                         // left+=diff_width/2 will introduce rounding errors (diff_width removed from svn after r51780)\r
134                                         // This calculates from scratch every time:\r
135                                         left = child.dist_left + (space.Width - (child.dist_left + width + child.dist_right)) / 2;\r
136                                 }\r
137 \r
138                                 if ((anchor & AnchorStyles.Top) != 0) {\r
139                                         if ((anchor & AnchorStyles.Bottom) != 0) {\r
140                                                 height = space.Height - child.dist_bottom - top;\r
141                                         }\r
142                                         else {\r
143                                                 ; // Top anchored only, nothing to be done\r
144                                         }\r
145                                 }\r
146                                 else if ((anchor & AnchorStyles.Bottom) != 0) {\r
147                                         top = space.Height - child.dist_bottom - height;\r
148                                 }\r
149                                 else {\r
150                                         // top += diff_height/2 will introduce rounding errors (diff_height removed from after r51780)\r
151                                         // This calculates from scratch every time:\r
152                                         top = child.dist_top + (space.Height - (child.dist_top + height + child.dist_bottom)) / 2;\r
153                                 }\r
154 \r
155                                 // Sanity\r
156                                 if (width < 0) {\r
157                                         width = 0;\r
158                                 }\r
159 \r
160                                 if (height < 0) {\r
161                                         height = 0;\r
162                                 }\r
163 \r
164                                 child.SetBounds (left, top, width, height);\r
165                         }\r
166 \r
167                         return false;\r
168                 }\r
169         }\r
170 }\r
171 #endif