1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
23 // Peter Bartok pbartok@novell.com
29 using System.Collections;
30 using System.ComponentModel;
33 namespace System.Windows.Forms {
34 [DesignTimeVisible(false)]
36 public sealed class MdiClient : Control {
37 #region Local Variables
38 private int mdi_created;
40 private HScrollBar hbar;
41 private VScrollBar vbar;
42 private SizeGrip sizegrip;
43 private int hbar_value;
44 private int vbar_value;
45 private bool lock_sizing;
47 #endregion // Local Variables
49 #region Public Classes
50 public new class ControlCollection : Control.ControlCollection {
53 public ControlCollection(MdiClient owner) : base(owner) {
55 controls = new ArrayList ();
58 public override void Add(Control value) {
59 if ((value is Form) == false || !(((Form)value).IsMdiChild)) {
60 throw new ArgumentException("Form must be MdiChild");
63 SetChildIndex (value, 0); // always insert at front
64 // newest member is the active one
65 owner.ActiveMdiChild = (Form) value;
67 value.LocationChanged += new EventHandler (owner.FormLocationChanged);
70 public override void Remove(Control value) {
74 #endregion // Public Classes
76 #region Public Constructors
78 BackColor = SystemColors.AppWorkspace;
79 Dock = DockStyle.Fill;
80 SetStyle (ControlStyles.Selectable, false);
82 #endregion // Public Constructors
84 protected override Control.ControlCollection CreateControlsInstance ()
86 return new MdiClient.ControlCollection (this);
89 protected override void WndProc(ref Message m) {
91 switch ((Msg) m.Msg) {
93 Console.WriteLine ("ignoring paint");
101 protected override void OnResize (EventArgs e)
105 // Should probably make this into one loop
110 protected override void ScaleCore (float dx, float dy)
112 base.ScaleCore (dx, dy);
115 protected override void SetBoundsCore (int x, int y, int width, int height, BoundsSpecified specified)
117 base.SetBoundsCore (x, y, width, height, specified);
120 #region Public Instance Properties
122 public override System.Drawing.Image BackgroundImage {
124 return base.BackgroundImage;
127 base.BackgroundImage = value;
131 public Form[] MdiChildren {
135 children = new Form[Controls.Count];
136 Controls.CopyTo(children, 0);
141 #endregion // Public Instance Properties
143 #region Protected Instance Properties
144 protected override CreateParams CreateParams {
146 return base.CreateParams;
149 #endregion // Protected Instance Properties
151 #region Public Instance Methods
152 public void LayoutMdi(MdiLayout value) {
153 throw new NotImplementedException();
155 #endregion // Public Instance Methods
157 #region Protected Instance Methods
158 #endregion // Protected Instance Methods
160 private void SizeScrollBars ()
165 if (Controls.Count == 0 || ((Form) Controls [0]).WindowState == FormWindowState.Maximized) {
167 hbar.Visible = false;
169 vbar.Visible = false;
173 bool hbar_required = false;
174 bool vbar_required = false;
178 foreach (Form child in Controls) {
181 if (child.Right > right)
183 if (child.Left < left) {
184 hbar_required = true;
191 foreach (Form child in Controls) {
194 if (child.Bottom > bottom)
195 bottom = child.Bottom;
197 vbar_required = true;
202 int right_edge = Right;
203 int bottom_edge = Bottom;
205 int prev_bottom_edge;
207 bool need_hbar = false;
208 bool need_vbar = false;
211 prev_right_edge = right_edge;
212 prev_bottom_edge = bottom_edge;
214 if (hbar_required || right > right_edge) {
216 bottom_edge = Bottom - SystemInformation.HorizontalScrollBarHeight;
219 bottom_edge = Bottom;
222 if (vbar_required || bottom > bottom_edge) {
224 right_edge = Right - SystemInformation.VerticalScrollBarWidth;
230 } while (right_edge != prev_right_edge || bottom_edge != prev_bottom_edge);
234 hbar = new HScrollBar ();
235 Controls.AddImplicit (hbar);
238 CalcHBar (left, right, right_edge, need_vbar);
239 } else if (hbar != null)
240 hbar.Visible = false;
244 vbar = new VScrollBar ();
245 Controls.AddImplicit (vbar);
248 CalcVBar (top, bottom, bottom_edge, need_hbar);
249 } else if (vbar != null)
250 vbar.Visible = false;
252 if (need_hbar && need_vbar) {
253 if (sizegrip == null) {
254 sizegrip = new SizeGrip ();
255 Controls.AddImplicit (sizegrip);
257 sizegrip.Location = new Point (hbar.Right, vbar.Bottom);
258 sizegrip.Width = vbar.Width;
259 sizegrip.Height = hbar.Height;
260 sizegrip.Visible = true;
261 } else if (sizegrip != null) {
262 sizegrip.Visible = false;
266 private void CalcHBar (int left, int right, int right_edge, bool vert_vis)
268 int virtual_left = Math.Min (left, 0);
269 int virtual_right = Math.Max (right, right_edge);
270 int diff = (virtual_right - virtual_left) - right_edge;
272 hbar.Top = Height - hbar.Height;
273 hbar.Width = Width - (vert_vis ? SystemInformation.VerticalScrollBarWidth : 0);
274 hbar.LargeChange = 50;
275 hbar.Maximum = diff + 51;
276 hbar.Value = -virtual_left;
277 hbar.ValueChanged += new EventHandler (HBarValueChanged);
280 private void CalcVBar (int top, int bottom, int bottom_edge, bool horz_vis)
282 int virtual_top = Math.Min (top, 0);
283 int virtual_bottom = Math.Max (bottom, bottom_edge);
284 int diff = (virtual_bottom - virtual_top) - bottom_edge;
286 vbar.Left = Width - vbar.Width;
287 vbar.Height = Height - (horz_vis ? SystemInformation.HorizontalScrollBarHeight : 0);
288 vbar.LargeChange = 50;
289 vbar.Maximum = diff + 51;
290 vbar.Value = -virtual_top;
291 vbar.ValueChanged += new EventHandler (VBarValueChanged);
295 private void HBarValueChanged (object sender, EventArgs e)
297 if (hbar.Value == hbar_value)
303 foreach (Form child in Controls) {
304 child.Left += hbar_value - hbar.Value;
310 hbar_value = hbar.Value;
314 private void VBarValueChanged (object sender, EventArgs e)
316 if (vbar.Value == vbar_value)
322 foreach (Form child in Controls) {
323 child.Top += vbar_value - vbar.Value;
329 vbar_value = vbar.Value;
333 private void SizeMaximized ()
335 foreach (Form child in Controls) {
338 MdiWindowManager wm = (MdiWindowManager) child.WindowManager;
339 if (wm.GetWindowState () == FormWindowState.Maximized)
344 private void FormLocationChanged (object sender, EventArgs e)
349 private int iconic_x = -1;
350 private int iconic_y = -1;
351 internal void ArrangeIconicWindows ()
356 if (iconic_x == -1 && iconic_y == -1) {
358 iconic_y = Bottom - yspacing;
362 foreach (Form form in Controls) {
363 if (form.WindowState != FormWindowState.Minimized)
366 MdiWindowManager wm = (MdiWindowManager) form.WindowManager;
368 if (wm.IconicBounds != Rectangle.Empty) {
369 form.Bounds = wm.IconicBounds;
373 // The extra one pixel is a cheap hack for now until we
374 // handle 0 client sizes properly in the driver
375 int height = wm.TitleBarHeight + (wm.BorderWidth * 2) + 1;
376 Rectangle rect = new Rectangle (iconic_x, iconic_y, xspacing, height);
377 form.Bounds = wm.IconicBounds = rect;
379 iconic_x += xspacing;
380 if (iconic_x >= Right) {
388 internal void ActivateChild (Form form)
390 form.BringToFront ();
393 foreach (Form child in Controls) {
396 // TODO: We need to repaint the decorations here
400 internal int ChildrenCreated {
401 get { return mdi_created; }
402 set { mdi_created = value; }
405 internal Form ActiveMdiChild {
406 get { return active; }
407 set { active = value; }