Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.WinFormsUI/2.3.1/WinFormsUI-2.3.1/Docking/FloatWindow.cs @ 4068

Last change on this file since 4068 was 4068, checked in by swagner, 14 years ago

Sorted usings and removed unused usings in entire solution (#1094)

File size: 13.2 KB
Line 
1using System;
2using System.Diagnostics.CodeAnalysis;
3using System.Drawing;
4using System.Security.Permissions;
5using System.Windows.Forms;
6
7namespace WeifenLuo.WinFormsUI.Docking {
8  public class FloatWindow : Form, INestedPanesContainer, IDockDragSource {
9    private NestedPaneCollection m_nestedPanes;
10    internal const int WM_CHECKDISPOSE = (int)(Win32.Msgs.WM_USER + 1);
11
12    internal protected FloatWindow(DockPanel dockPanel, DockPane pane) {
13      InternalConstruct(dockPanel, pane, false, Rectangle.Empty);
14    }
15
16    internal protected FloatWindow(DockPanel dockPanel, DockPane pane, Rectangle bounds) {
17      InternalConstruct(dockPanel, pane, true, bounds);
18    }
19
20    private void InternalConstruct(DockPanel dockPanel, DockPane pane, bool boundsSpecified, Rectangle bounds) {
21      if (dockPanel == null)
22        throw (new ArgumentNullException(Strings.FloatWindow_Constructor_NullDockPanel));
23
24      m_nestedPanes = new NestedPaneCollection(this);
25
26      FormBorderStyle = FormBorderStyle.SizableToolWindow;
27      ShowInTaskbar = false;
28      if (dockPanel.RightToLeft != RightToLeft)
29        RightToLeft = dockPanel.RightToLeft;
30      if (RightToLeftLayout != dockPanel.RightToLeftLayout)
31        RightToLeftLayout = dockPanel.RightToLeftLayout;
32
33      SuspendLayout();
34      if (boundsSpecified) {
35        Bounds = bounds;
36        StartPosition = FormStartPosition.Manual;
37      } else {
38        StartPosition = FormStartPosition.WindowsDefaultLocation;
39        Size = dockPanel.DefaultFloatWindowSize;
40      }
41
42      m_dockPanel = dockPanel;
43      Owner = DockPanel.FindForm();
44      DockPanel.AddFloatWindow(this);
45      if (pane != null)
46        pane.FloatWindow = this;
47
48      ResumeLayout();
49    }
50
51    protected override void Dispose(bool disposing) {
52      if (disposing) {
53        if (DockPanel != null)
54          DockPanel.RemoveFloatWindow(this);
55        m_dockPanel = null;
56      }
57      base.Dispose(disposing);
58    }
59
60    private bool m_allowEndUserDocking = true;
61    public bool AllowEndUserDocking {
62      get { return m_allowEndUserDocking; }
63      set { m_allowEndUserDocking = value; }
64    }
65
66    public NestedPaneCollection NestedPanes {
67      get { return m_nestedPanes; }
68    }
69
70    public VisibleNestedPaneCollection VisibleNestedPanes {
71      get { return NestedPanes.VisibleNestedPanes; }
72    }
73
74    private DockPanel m_dockPanel;
75    public DockPanel DockPanel {
76      get { return m_dockPanel; }
77    }
78
79    public DockState DockState {
80      get { return DockState.Float; }
81    }
82
83    public bool IsFloat {
84      get { return DockState == DockState.Float; }
85    }
86
87    internal bool IsDockStateValid(DockState dockState) {
88      foreach (DockPane pane in NestedPanes)
89        foreach (IDockContent content in pane.Contents)
90          if (!DockHelper.IsDockStateValid(dockState, content.DockHandler.DockAreas))
91            return false;
92
93      return true;
94    }
95
96    protected override void OnActivated(EventArgs e) {
97      DockPanel.FloatWindows.BringWindowToFront(this);
98      base.OnActivated(e);
99      // Propagate the Activated event to the visible panes content objects
100      foreach (DockPane pane in VisibleNestedPanes)
101        foreach (IDockContent content in pane.Contents)
102          content.OnActivated(e);
103    }
104
105    protected override void OnDeactivate(EventArgs e) {
106      base.OnDeactivate(e);
107      // Propagate the Deactivate event to the visible panes content objects
108      foreach (DockPane pane in VisibleNestedPanes)
109        foreach (IDockContent content in pane.Contents)
110          content.OnDeactivate(e);
111    }
112
113    protected override void OnLayout(LayoutEventArgs levent) {
114      VisibleNestedPanes.Refresh();
115      RefreshChanges();
116      Visible = (VisibleNestedPanes.Count > 0);
117      SetText();
118
119      base.OnLayout(levent);
120    }
121
122
123    [SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", MessageId = "System.Windows.Forms.Control.set_Text(System.String)")]
124    internal void SetText() {
125      DockPane theOnlyPane = (VisibleNestedPanes.Count == 1) ? VisibleNestedPanes[0] : null;
126
127      if (theOnlyPane == null)
128        Text = " "; // use " " instead of string.Empty because the whole title bar will disappear when ControlBox is set to false.
129      else if (theOnlyPane.ActiveContent == null)
130        Text = " ";
131      else
132        Text = theOnlyPane.ActiveContent.DockHandler.TabText;
133    }
134
135    protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) {
136      Rectangle rectWorkArea = SystemInformation.VirtualScreen;
137
138      if (y + height > rectWorkArea.Bottom)
139        y -= (y + height) - rectWorkArea.Bottom;
140
141      if (y < rectWorkArea.Top)
142        y += rectWorkArea.Top - y;
143
144      base.SetBoundsCore(x, y, width, height, specified);
145    }
146
147    [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
148    protected override void WndProc(ref Message m) {
149      if (m.Msg == (int)Win32.Msgs.WM_NCLBUTTONDOWN) {
150        if (IsDisposed)
151          return;
152
153        uint result = NativeMethods.SendMessage(this.Handle, (int)Win32.Msgs.WM_NCHITTEST, 0, (uint)m.LParam);
154        if (result == 2 && DockPanel.AllowEndUserDocking && this.AllowEndUserDocking) // HITTEST_CAPTION
155        {
156          Activate();
157          m_dockPanel.BeginDrag(this);
158        } else
159          base.WndProc(ref m);
160
161        return;
162      } else if (m.Msg == (int)Win32.Msgs.WM_NCRBUTTONDOWN) {
163        uint result = NativeMethods.SendMessage(this.Handle, (int)Win32.Msgs.WM_NCHITTEST, 0, (uint)m.LParam);
164        if (result == 2)  // HITTEST_CAPTION
165                {
166          DockPane theOnlyPane = (VisibleNestedPanes.Count == 1) ? VisibleNestedPanes[0] : null;
167          if (theOnlyPane != null && theOnlyPane.ActiveContent != null) {
168            theOnlyPane.ShowTabPageContextMenu(this, PointToClient(Control.MousePosition));
169            return;
170          }
171        }
172
173        base.WndProc(ref m);
174        return;
175      } else if (m.Msg == (int)Win32.Msgs.WM_CLOSE) {
176        if (NestedPanes.Count == 0) {
177          base.WndProc(ref m);
178          return;
179        }
180
181        for (int i = NestedPanes.Count - 1; i >= 0; i--) {
182          DockContentCollection contents = NestedPanes[i].Contents;
183          for (int j = contents.Count - 1; j >= 0; j--) {
184            IDockContent content = contents[j];
185            if (content.DockHandler.DockState != DockState.Float)
186              continue;
187
188            if (!content.DockHandler.CloseButton)
189              continue;
190
191            if (content.DockHandler.HideOnClose)
192              content.DockHandler.Hide();
193            else
194              content.DockHandler.Close();
195          }
196        }
197
198        return;
199      } else if (m.Msg == (int)Win32.Msgs.WM_NCLBUTTONDBLCLK) {
200        uint result = NativeMethods.SendMessage(this.Handle, (int)Win32.Msgs.WM_NCHITTEST, 0, (uint)m.LParam);
201        if (result != 2)  // HITTEST_CAPTION
202                {
203          base.WndProc(ref m);
204          return;
205        }
206
207        DockPanel.SuspendLayout(true);
208
209        // Restore to panel
210        foreach (DockPane pane in NestedPanes) {
211          if (pane.DockState != DockState.Float)
212            continue;
213          pane.RestoreToPanel();
214        }
215
216
217        DockPanel.ResumeLayout(true, true);
218        return;
219      } else if (m.Msg == WM_CHECKDISPOSE) {
220        if (NestedPanes.Count == 0)
221          Dispose();
222
223        return;
224      }
225
226      base.WndProc(ref m);
227    }
228
229    internal void RefreshChanges() {
230      if (IsDisposed)
231        return;
232
233      if (VisibleNestedPanes.Count == 0) {
234        ControlBox = true;
235        return;
236      }
237
238      for (int i = VisibleNestedPanes.Count - 1; i >= 0; i--) {
239        DockContentCollection contents = VisibleNestedPanes[i].Contents;
240        for (int j = contents.Count - 1; j >= 0; j--) {
241          IDockContent content = contents[j];
242          if (content.DockHandler.DockState != DockState.Float)
243            continue;
244
245          if (content.DockHandler.CloseButton && content.DockHandler.CloseButtonVisible) {
246            ControlBox = true;
247            return;
248          }
249        }
250      }
251      //Only if there is a ControlBox do we turn it off
252      //old code caused a flash of the window.
253      if (ControlBox)
254        ControlBox = false;
255    }
256
257    public virtual Rectangle DisplayingRectangle {
258      get { return ClientRectangle; }
259    }
260
261    internal void TestDrop(IDockDragSource dragSource, DockOutlineBase dockOutline) {
262      if (VisibleNestedPanes.Count == 1) {
263        DockPane pane = VisibleNestedPanes[0];
264        if (!dragSource.CanDockTo(pane))
265          return;
266
267        Point ptMouse = Control.MousePosition;
268        uint lParam = Win32Helper.MakeLong(ptMouse.X, ptMouse.Y);
269        if (NativeMethods.SendMessage(Handle, (int)Win32.Msgs.WM_NCHITTEST, 0, lParam) == (uint)Win32.HitTest.HTCAPTION)
270          dockOutline.Show(VisibleNestedPanes[0], -1);
271      }
272    }
273
274    #region IDockDragSource Members
275
276    #region IDragSource Members
277
278    Control IDragSource.DragControl {
279      get { return this; }
280    }
281
282    #endregion
283
284    bool IDockDragSource.IsDockStateValid(DockState dockState) {
285      return IsDockStateValid(dockState);
286    }
287
288    bool IDockDragSource.CanDockTo(DockPane pane) {
289      if (!IsDockStateValid(pane.DockState))
290        return false;
291
292      if (pane.FloatWindow == this)
293        return false;
294
295      return true;
296    }
297
298    Rectangle IDockDragSource.BeginDrag(Point ptMouse) {
299      return Bounds;
300    }
301
302    public void FloatAt(Rectangle floatWindowBounds) {
303      Bounds = floatWindowBounds;
304    }
305
306    public void DockTo(DockPane pane, DockStyle dockStyle, int contentIndex) {
307      if (dockStyle == DockStyle.Fill) {
308        for (int i = NestedPanes.Count - 1; i >= 0; i--) {
309          DockPane paneFrom = NestedPanes[i];
310          for (int j = paneFrom.Contents.Count - 1; j >= 0; j--) {
311            IDockContent c = paneFrom.Contents[j];
312            c.DockHandler.Pane = pane;
313            if (contentIndex != -1)
314              pane.SetContentIndex(c, contentIndex);
315            c.DockHandler.Activate();
316          }
317        }
318      } else {
319        DockAlignment alignment = DockAlignment.Left;
320        if (dockStyle == DockStyle.Left)
321          alignment = DockAlignment.Left;
322        else if (dockStyle == DockStyle.Right)
323          alignment = DockAlignment.Right;
324        else if (dockStyle == DockStyle.Top)
325          alignment = DockAlignment.Top;
326        else if (dockStyle == DockStyle.Bottom)
327          alignment = DockAlignment.Bottom;
328
329        MergeNestedPanes(VisibleNestedPanes, pane.NestedPanesContainer.NestedPanes, pane, alignment, 0.5);
330      }
331    }
332
333    public void DockTo(DockPanel panel, DockStyle dockStyle) {
334      if (panel != DockPanel)
335        throw new ArgumentException(Strings.IDockDragSource_DockTo_InvalidPanel, "panel");
336
337      NestedPaneCollection nestedPanesTo = null;
338
339      if (dockStyle == DockStyle.Top)
340        nestedPanesTo = DockPanel.DockWindows[DockState.DockTop].NestedPanes;
341      else if (dockStyle == DockStyle.Bottom)
342        nestedPanesTo = DockPanel.DockWindows[DockState.DockBottom].NestedPanes;
343      else if (dockStyle == DockStyle.Left)
344        nestedPanesTo = DockPanel.DockWindows[DockState.DockLeft].NestedPanes;
345      else if (dockStyle == DockStyle.Right)
346        nestedPanesTo = DockPanel.DockWindows[DockState.DockRight].NestedPanes;
347      else if (dockStyle == DockStyle.Fill)
348        nestedPanesTo = DockPanel.DockWindows[DockState.Document].NestedPanes;
349
350      DockPane prevPane = null;
351      for (int i = nestedPanesTo.Count - 1; i >= 0; i--)
352        if (nestedPanesTo[i] != VisibleNestedPanes[0])
353          prevPane = nestedPanesTo[i];
354      MergeNestedPanes(VisibleNestedPanes, nestedPanesTo, prevPane, DockAlignment.Left, 0.5);
355    }
356
357    private static void MergeNestedPanes(VisibleNestedPaneCollection nestedPanesFrom, NestedPaneCollection nestedPanesTo, DockPane prevPane, DockAlignment alignment, double proportion) {
358      if (nestedPanesFrom.Count == 0)
359        return;
360
361      int count = nestedPanesFrom.Count;
362      DockPane[] panes = new DockPane[count];
363      DockPane[] prevPanes = new DockPane[count];
364      DockAlignment[] alignments = new DockAlignment[count];
365      double[] proportions = new double[count];
366
367      for (int i = 0; i < count; i++) {
368        panes[i] = nestedPanesFrom[i];
369        prevPanes[i] = nestedPanesFrom[i].NestedDockingStatus.PreviousPane;
370        alignments[i] = nestedPanesFrom[i].NestedDockingStatus.Alignment;
371        proportions[i] = nestedPanesFrom[i].NestedDockingStatus.Proportion;
372      }
373
374      DockPane pane = panes[0].DockTo(nestedPanesTo.Container, prevPane, alignment, proportion);
375      panes[0].DockState = nestedPanesTo.DockState;
376
377      for (int i = 1; i < count; i++) {
378        for (int j = i; j < count; j++) {
379          if (prevPanes[j] == panes[i - 1])
380            prevPanes[j] = pane;
381        }
382        pane = panes[i].DockTo(nestedPanesTo.Container, prevPanes[i], alignments[i], proportions[i]);
383        panes[i].DockState = nestedPanesTo.DockState;
384      }
385    }
386
387    #endregion
388  }
389}
Note: See TracBrowser for help on using the repository browser.