* TabControl.cs: Show the tooltip depending on the value
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / FlowLayoutPanel.cs
1 //
2 // FlowLayoutPanel.cs
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
11 // 
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
14 // 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 //
23 // Copyright (c) 2006 Jonathan Pobst
24 //
25 // Authors:
26 //      Jonathan Pobst (monkey@jpobst.com)
27 //
28
29 #if NET_2_0
30 using System.Windows.Forms.Layout;
31 using System.ComponentModel;
32 using System.Runtime.InteropServices;
33 using System.Drawing;
34
35 namespace System.Windows.Forms
36 {
37         [ComVisibleAttribute (true)]
38         [ClassInterfaceAttribute (ClassInterfaceType.AutoDispatch)]
39         [ProvideProperty ("FlowBreak", typeof (Control))]
40         [DefaultProperty ("FlowDirection")]
41         [Docking (DockingBehavior.Ask)]
42         [Designer ("System.Windows.Forms.Design.FlowLayoutPanelDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
43         public class FlowLayoutPanel : Panel, IExtenderProvider
44         {
45                 private FlowLayoutSettings settings;
46
47                 public FlowLayoutPanel () : base ()
48                 {
49                         CreateDockPadding ();
50                 }
51
52                 #region Properties
53                 [Localizable (true)]
54                 [DefaultValue (FlowDirection.LeftToRight)]
55                 public FlowDirection FlowDirection {
56                         get { return LayoutSettings.FlowDirection; }
57                         set { LayoutSettings.FlowDirection = value; }
58                 }
59
60                 [LocalizableAttribute (true)]
61                 [DefaultValue (true)]
62                 public bool WrapContents {
63                         get { return LayoutSettings.WrapContents; }
64                         set { LayoutSettings.WrapContents = value; }
65                 }
66
67                 public override LayoutEngine LayoutEngine {
68                         get { return this.LayoutSettings.LayoutEngine; }
69                 }
70
71                 internal FlowLayoutSettings LayoutSettings {
72                         get { 
73                                 if (this.settings == null)
74                                         this.settings = new FlowLayoutSettings (this);
75                                         
76                                 return this.settings;
77                         }
78                 }
79                 #endregion
80
81                 #region Public Methods
82                 [DefaultValue (false)]
83                 [DisplayName ("FlowBreak")]
84                 public bool GetFlowBreak (Control control)
85                 {
86                         return LayoutSettings.GetFlowBreak (control);
87                 }
88
89                 [DisplayName ("FlowBreak")]
90                 public void SetFlowBreak (Control control, bool value)
91                 {
92                         LayoutSettings.SetFlowBreak (control, value);
93                 }               
94                 #endregion
95                 
96                 #region IExtenderProvider Members
97                 bool IExtenderProvider.CanExtend (object obj)
98                 {
99                         if (obj is Control)
100                                 if ((obj as Control).Parent == this)
101                                         return true;
102
103                         return false;
104                 }
105                 #endregion
106
107                 #region Internal Methods
108                 internal override void CalculateCanvasSize (bool canOverride)
109                 {
110                         if (canOverride)
111                                 canvas_size = ClientSize;
112                         else
113                                 base.CalculateCanvasSize (canOverride);
114                 }
115                 
116                 internal override Size GetPreferredSizeCore (Size proposedSize)
117                 {
118                         int width = 0;
119                         int height = 0;
120                         bool horizontal = FlowDirection == FlowDirection.LeftToRight || FlowDirection == FlowDirection.RightToLeft;
121                         if (!WrapContents || (horizontal && proposedSize.Width == 0) || (!horizontal && proposedSize.Height == 0)) {
122                                 foreach (Control control in Controls) {
123                                         Size control_preferred_size;
124                                         if (control.AutoSize)
125                                                 control_preferred_size = control.PreferredSize;
126                                         else
127                                                 control_preferred_size = control.Size;
128                                         Padding control_margin = control.Margin;
129                                         if (horizontal) {
130                                                 width += control_preferred_size.Width + control_margin.Horizontal;
131                                                 height = Math.Max (height, control_preferred_size.Height + control_margin.Vertical);
132                                         } else {
133                                                 height += control_preferred_size.Height + control_margin.Vertical;
134                                                 width = Math.Max (width, control_preferred_size.Width + control_margin.Horizontal);
135                                         }
136                                 }
137                         } else {
138                                 int size_in_flow_direction = 0;
139                                 int size_in_other_direction = 0;
140                                 int increase;
141                                 foreach (Control control in Controls) {
142                                         Size control_preferred_size;
143                                         if (control.AutoSize)
144                                                 control_preferred_size = control.PreferredSize;
145                                         else
146                                                 control_preferred_size = control.ExplicitBounds.Size;
147                                         Padding control_margin = control.Margin;
148                                         if (horizontal) {
149                                                 increase = control_preferred_size.Width + control_margin.Horizontal;
150                                                 if (size_in_flow_direction != 0 && size_in_flow_direction + increase >= proposedSize.Width) {
151                                                         width = Math.Max (width, size_in_flow_direction);
152                                                         size_in_flow_direction = 0;
153                                                         height += size_in_other_direction;
154                                                         size_in_other_direction = 0;
155                                                 }
156                                                 size_in_flow_direction += increase;
157                                                 size_in_other_direction = Math.Max (size_in_other_direction, control_preferred_size.Height + control_margin.Vertical);
158                                         } else {
159                                                 increase = control_preferred_size.Height + control_margin.Vertical;
160                                                 if (size_in_flow_direction != 0 && size_in_flow_direction + increase >= proposedSize.Height) {
161                                                         height = Math.Max (height, size_in_flow_direction);
162                                                         size_in_flow_direction = 0;
163                                                         width += size_in_other_direction;
164                                                         size_in_other_direction = 0;
165                                                 }
166                                                 size_in_flow_direction += increase;
167                                                 size_in_other_direction = Math.Max (size_in_other_direction, control_preferred_size.Width + control_margin.Horizontal);
168                                         }
169                                 }
170                                 if (horizontal) {
171                                         width = Math.Max (width, size_in_flow_direction);
172                                         height += size_in_other_direction;
173                                 } else {
174                                         height = Math.Max (height, size_in_flow_direction);
175                                         width += size_in_other_direction;
176                                 }
177                         }
178                         return new Size (width, height);
179                 }
180                 #endregion
181         }
182 }
183 #endif