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:
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
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.
23 // Copyright (c) 2006 Jonathan Pobst
26 // Jonathan Pobst (monkey@jpobst.com)
30 using System.Windows.Forms.Layout;
31 using System.ComponentModel;
32 using System.Runtime.InteropServices;
35 namespace System.Windows.Forms
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
45 private FlowLayoutSettings settings;
47 public FlowLayoutPanel () : base ()
53 [DefaultValue (FlowDirection.LeftToRight)]
54 public FlowDirection FlowDirection {
55 get { return LayoutSettings.FlowDirection; }
56 set { LayoutSettings.FlowDirection = value; }
59 [LocalizableAttribute (true)]
61 public bool WrapContents {
62 get { return LayoutSettings.WrapContents; }
63 set { LayoutSettings.WrapContents = value; }
66 public override LayoutEngine LayoutEngine {
67 get { return this.LayoutSettings.LayoutEngine; }
70 internal FlowLayoutSettings LayoutSettings {
72 if (this.settings == null)
73 this.settings = new FlowLayoutSettings (this);
80 #region Public Methods
81 [DefaultValue (false)]
82 [DisplayName ("FlowBreak")]
83 public bool GetFlowBreak (Control control)
85 return LayoutSettings.GetFlowBreak (control);
88 [DisplayName ("FlowBreak")]
89 public void SetFlowBreak (Control control, bool value)
91 LayoutSettings.SetFlowBreak (control, value);
95 #region IExtenderProvider Members
96 bool IExtenderProvider.CanExtend (object obj)
99 if ((obj as Control).Parent == this)
106 #region Internal Methods
107 internal override void CalculateCanvasSize (bool canOverride)
110 canvas_size = ClientSize;
112 base.CalculateCanvasSize (canOverride);
115 internal override Size GetPreferredSizeCore (Size proposedSize)
119 bool horizontal = FlowDirection == FlowDirection.LeftToRight || FlowDirection == FlowDirection.RightToLeft;
120 if (!WrapContents || (horizontal && proposedSize.Width == 0) || (!horizontal && proposedSize.Height == 0)) {
121 foreach (Control control in Controls) {
122 Size control_preferred_size;
123 if (control.AutoSize)
124 control_preferred_size = control.PreferredSize;
126 control_preferred_size = control.Size;
127 Padding control_margin = control.Margin;
129 width += control_preferred_size.Width + control_margin.Horizontal;
130 height = Math.Max (height, control_preferred_size.Height + control_margin.Vertical);
132 height += control_preferred_size.Height + control_margin.Vertical;
133 width = Math.Max (width, control_preferred_size.Width + control_margin.Horizontal);
137 int size_in_flow_direction = 0;
138 int size_in_other_direction = 0;
140 foreach (Control control in Controls) {
141 Size control_preferred_size;
142 if (control.AutoSize)
143 control_preferred_size = control.PreferredSize;
145 control_preferred_size = control.ExplicitBounds.Size;
146 Padding control_margin = control.Margin;
148 increase = control_preferred_size.Width + control_margin.Horizontal;
149 if (size_in_flow_direction != 0 && size_in_flow_direction + increase >= proposedSize.Width) {
150 width = Math.Max (width, size_in_flow_direction);
151 size_in_flow_direction = 0;
152 height += size_in_other_direction;
153 size_in_other_direction = 0;
155 size_in_flow_direction += increase;
156 size_in_other_direction = Math.Max (size_in_other_direction, control_preferred_size.Height + control_margin.Vertical);
158 increase = control_preferred_size.Height + control_margin.Vertical;
159 if (size_in_flow_direction != 0 && size_in_flow_direction + increase >= proposedSize.Height) {
160 height = Math.Max (height, size_in_flow_direction);
161 size_in_flow_direction = 0;
162 width += size_in_other_direction;
163 size_in_other_direction = 0;
165 size_in_flow_direction += increase;
166 size_in_other_direction = Math.Max (size_in_other_direction, control_preferred_size.Width + control_margin.Horizontal);
170 width = Math.Max (width, size_in_flow_direction);
171 height += size_in_other_direction;
173 height = Math.Max (height, size_in_flow_direction);
174 width += size_in_other_direction;
177 return new Size (width, height);