Free cookie consent management tool by TermsFeed Policy Generator

source: stable/HeuristicLab.ExtLibs/HeuristicLab.WinFormsUI/2.7.0/WinFormsUI-2.7.0/Docking/DockPanel.AutoHideWindow.cs

Last change on this file was 8616, checked in by mkommend, 12 years ago

#1939: Added DockPanelSuite 2.7.0 to ExtLibs.

File size: 23.4 KB
Line 
1using System;
2using System.Windows.Forms;
3using System.Drawing;
4using System.Runtime.InteropServices;
5
6namespace WeifenLuo.WinFormsUI.Docking
7{
8    partial class DockPanel
9    {
10        private class AutoHideWindowControl : Panel, ISplitterDragSource
11        {
12            private class SplitterControl : SplitterBase
13            {
14                public SplitterControl(AutoHideWindowControl autoHideWindow)
15                {
16                    m_autoHideWindow = autoHideWindow;
17                }
18
19                private AutoHideWindowControl m_autoHideWindow;
20                private AutoHideWindowControl AutoHideWindow
21                {
22                    get { return m_autoHideWindow; }
23                }
24
25                protected override int SplitterSize
26                {
27                    get { return Measures.SplitterSize; }
28                }
29
30                protected override void StartDrag()
31                {
32              AutoHideWindow.DockPanel.BeginDrag(AutoHideWindow, AutoHideWindow.RectangleToScreen(Bounds));
33                }
34            }
35
36            #region consts
37            private const int ANIMATE_TIME = 100; // in mini-seconds
38            #endregion
39
40            private Timer m_timerMouseTrack;
41            private SplitterControl m_splitter;
42
43            public AutoHideWindowControl(DockPanel dockPanel)
44            {
45                m_dockPanel = dockPanel;
46
47                m_timerMouseTrack = new Timer();
48                m_timerMouseTrack.Tick += new EventHandler(TimerMouseTrack_Tick);
49
50                Visible = false;
51                m_splitter = new SplitterControl(this);
52                Controls.Add(m_splitter);
53            }
54
55            protected override void Dispose(bool disposing)
56            {
57                if (disposing)
58                {
59                    m_timerMouseTrack.Dispose();
60                }
61                base.Dispose(disposing);
62            }
63
64            private DockPanel m_dockPanel = null;
65            public DockPanel DockPanel
66            {
67                get { return m_dockPanel; }
68            }
69
70            private DockPane m_activePane = null;
71            public DockPane ActivePane
72            {
73                get { return m_activePane; }
74            }
75            private void SetActivePane()
76            {
77                DockPane value = (ActiveContent == null ? null : ActiveContent.DockHandler.Pane);
78
79                if (value == m_activePane)
80                    return;
81
82                m_activePane = value;
83            }
84
85            private IDockContent m_activeContent = null;
86            public IDockContent ActiveContent
87            {
88                get { return m_activeContent; }
89                set
90                {
91                    if (value == m_activeContent)
92                        return;
93
94                    if (value != null)
95                    {
96                        if (!DockHelper.IsDockStateAutoHide(value.DockHandler.DockState) || value.DockHandler.DockPanel != DockPanel)
97                            throw (new InvalidOperationException(Strings.DockPanel_ActiveAutoHideContent_InvalidValue));
98                    }
99
100                    DockPanel.SuspendLayout();
101
102                    if (m_activeContent != null)
103                    {
104                        if (m_activeContent.DockHandler.Form.ContainsFocus)
105                            if (!Win32Helper.IsRunningOnMono)
106                                DockPanel.ContentFocusManager.GiveUpFocus(m_activeContent);
107                        AnimateWindow(false);
108                    }
109
110                    m_activeContent = value;
111                    SetActivePane();
112                    if (ActivePane != null)
113                        ActivePane.ActiveContent = m_activeContent;
114
115                    if (m_activeContent != null)
116                        AnimateWindow(true);
117
118                    DockPanel.ResumeLayout();
119                    DockPanel.RefreshAutoHideStrip();
120
121                    SetTimerMouseTrack();
122                }
123            }
124
125            public DockState DockState
126            {
127                get { return ActiveContent == null ? DockState.Unknown : ActiveContent.DockHandler.DockState; }
128            }
129
130            private bool m_flagAnimate = true;
131            private bool FlagAnimate
132            {
133                get { return m_flagAnimate; }
134                set { m_flagAnimate = value; }
135            }
136
137            private bool m_flagDragging = false;
138            internal bool FlagDragging
139            {
140                get { return m_flagDragging; }
141                set
142                {
143                    if (m_flagDragging == value)
144                        return;
145
146                    m_flagDragging = value;
147                    SetTimerMouseTrack();
148                }
149            }
150
151            private void AnimateWindow(bool show)
152            {
153                if (!FlagAnimate && Visible != show)
154                {
155                    Visible = show;
156                    return;
157                }
158
159                Parent.SuspendLayout();
160
161                Rectangle rectSource = GetRectangle(!show);
162                Rectangle rectTarget = GetRectangle(show);
163                int dxLoc, dyLoc;
164                int dWidth, dHeight;
165                dxLoc = dyLoc = dWidth = dHeight = 0;
166                if (DockState == DockState.DockTopAutoHide)
167                    dHeight = show ? 1 : -1;
168                else if (DockState == DockState.DockLeftAutoHide)
169                    dWidth = show ? 1 : -1;
170                else if (DockState == DockState.DockRightAutoHide)
171                {
172                    dxLoc = show ? -1 : 1;
173                    dWidth = show ? 1 : -1;
174                }
175                else if (DockState == DockState.DockBottomAutoHide)
176                {
177                    dyLoc = (show ? -1 : 1);
178                    dHeight = (show ? 1 : -1);
179                }
180
181                if (show)
182                {
183                    Bounds = DockPanel.GetAutoHideWindowBounds(new Rectangle(-rectTarget.Width, -rectTarget.Height, rectTarget.Width, rectTarget.Height));
184                    if (Visible == false)
185                        Visible = true;
186                    PerformLayout();
187                }
188
189                SuspendLayout();
190
191                LayoutAnimateWindow(rectSource);
192                if (Visible == false)
193                    Visible = true;
194
195                int speedFactor = 1;
196                int totalPixels = (rectSource.Width != rectTarget.Width) ?
197                    Math.Abs(rectSource.Width - rectTarget.Width) :
198                    Math.Abs(rectSource.Height - rectTarget.Height);
199                int remainPixels = totalPixels;
200                DateTime startingTime = DateTime.Now;
201                while (rectSource != rectTarget)
202                {
203                    DateTime startPerMove = DateTime.Now;
204
205                    rectSource.X += dxLoc * speedFactor;
206                    rectSource.Y += dyLoc * speedFactor;
207                    rectSource.Width += dWidth * speedFactor;
208                    rectSource.Height += dHeight * speedFactor;
209                    if (Math.Sign(rectTarget.X - rectSource.X) != Math.Sign(dxLoc))
210                        rectSource.X = rectTarget.X;
211                    if (Math.Sign(rectTarget.Y - rectSource.Y) != Math.Sign(dyLoc))
212                        rectSource.Y = rectTarget.Y;
213                    if (Math.Sign(rectTarget.Width - rectSource.Width) != Math.Sign(dWidth))
214                        rectSource.Width = rectTarget.Width;
215                    if (Math.Sign(rectTarget.Height - rectSource.Height) != Math.Sign(dHeight))
216                        rectSource.Height = rectTarget.Height;
217
218                    LayoutAnimateWindow(rectSource);
219                    if (Parent != null)
220                        Parent.Update();
221
222                    remainPixels -= speedFactor;
223
224                    while (true)
225                    {
226                        TimeSpan time = new TimeSpan(0, 0, 0, 0, ANIMATE_TIME);
227                        TimeSpan elapsedPerMove = DateTime.Now - startPerMove;
228                        TimeSpan elapsedTime = DateTime.Now - startingTime;
229                        if (((int)((time - elapsedTime).TotalMilliseconds)) <= 0)
230                        {
231                            speedFactor = remainPixels;
232                            break;
233                        }
234                        else
235                            speedFactor = remainPixels * (int)elapsedPerMove.TotalMilliseconds / (int)((time - elapsedTime).TotalMilliseconds);
236                        if (speedFactor >= 1)
237                            break;
238                    }
239                }
240                ResumeLayout();
241                Parent.ResumeLayout();
242            }
243
244            private void LayoutAnimateWindow(Rectangle rect)
245            {
246                Bounds = DockPanel.GetAutoHideWindowBounds(rect);
247
248                Rectangle rectClient = ClientRectangle;
249
250                if (DockState == DockState.DockLeftAutoHide)
251                    ActivePane.Location = new Point(rectClient.Right - 2 - Measures.SplitterSize - ActivePane.Width, ActivePane.Location.Y);
252                else if (DockState == DockState.DockTopAutoHide)
253                    ActivePane.Location = new Point(ActivePane.Location.X, rectClient.Bottom - 2 - Measures.SplitterSize - ActivePane.Height);
254            }
255
256            private Rectangle GetRectangle(bool show)
257            {
258                if (DockState == DockState.Unknown)
259                    return Rectangle.Empty;
260
261                Rectangle rect = DockPanel.AutoHideWindowRectangle;
262
263                if (show)
264                    return rect;
265
266                if (DockState == DockState.DockLeftAutoHide)
267                    rect.Width = 0;
268                else if (DockState == DockState.DockRightAutoHide)
269                {
270                    rect.X += rect.Width;
271                    rect.Width = 0;
272                }
273                else if (DockState == DockState.DockTopAutoHide)
274                    rect.Height = 0;
275                else
276                {
277                    rect.Y += rect.Height;
278                    rect.Height = 0;
279                }
280
281                return rect;
282            }
283
284            private void SetTimerMouseTrack()
285            {
286                if (ActivePane == null || ActivePane.IsActivated || FlagDragging)
287                {
288                    m_timerMouseTrack.Enabled = false;
289                    return;
290                }
291
292                // start the timer
293                int hovertime = SystemInformation.MouseHoverTime ;
294
295                // assign a default value 400 in case of setting Timer.Interval invalid value exception
296                if (hovertime <= 0)
297                    hovertime = 400;
298
299                m_timerMouseTrack.Interval = 2 * (int)hovertime;
300                m_timerMouseTrack.Enabled = true;
301            }
302
303            protected virtual Rectangle DisplayingRectangle
304            {
305                get
306                {
307                    Rectangle rect = ClientRectangle;
308
309                    // exclude the border and the splitter
310                    if (DockState == DockState.DockBottomAutoHide)
311                    {
312                        rect.Y += 2 + Measures.SplitterSize;
313                        rect.Height -= 2 + Measures.SplitterSize;
314                    }
315                    else if (DockState == DockState.DockRightAutoHide)
316                    {
317                        rect.X += 2 + Measures.SplitterSize;
318                        rect.Width -= 2 + Measures.SplitterSize;
319                    }
320                    else if (DockState == DockState.DockTopAutoHide)
321                        rect.Height -= 2 + Measures.SplitterSize;
322                    else if (DockState == DockState.DockLeftAutoHide)
323                        rect.Width -= 2 + Measures.SplitterSize;
324
325                    return rect;
326                }
327            }
328
329            protected override void OnLayout(LayoutEventArgs levent)
330            {
331                DockPadding.All = 0;
332                if (DockState == DockState.DockLeftAutoHide)
333                {
334                    DockPadding.Right = 2;
335                    m_splitter.Dock = DockStyle.Right;
336                }
337                else if (DockState == DockState.DockRightAutoHide)
338                {
339                    DockPadding.Left = 2;
340                    m_splitter.Dock = DockStyle.Left;
341                }
342                else if (DockState == DockState.DockTopAutoHide)
343                {
344                    DockPadding.Bottom = 2;
345                    m_splitter.Dock = DockStyle.Bottom;
346                }
347                else if (DockState == DockState.DockBottomAutoHide)
348                {
349                    DockPadding.Top = 2;
350                    m_splitter.Dock = DockStyle.Top;
351                }
352
353                Rectangle rectDisplaying = DisplayingRectangle;
354                Rectangle rectHidden = new Rectangle(-rectDisplaying.Width, rectDisplaying.Y, rectDisplaying.Width, rectDisplaying.Height);
355                foreach (Control c in Controls)
356                {
357                    DockPane pane = c as DockPane;
358                    if (pane == null)
359                        continue;
360                   
361                   
362                    if (pane == ActivePane)
363                        pane.Bounds = rectDisplaying;
364                    else
365                        pane.Bounds = rectHidden;
366                }
367
368                base.OnLayout(levent);
369            }
370
371            protected override void OnPaint(PaintEventArgs e)
372            {
373                // Draw the border
374                Graphics g = e.Graphics;
375
376                if (DockState == DockState.DockBottomAutoHide)
377                    g.DrawLine(SystemPens.ControlLightLight, 0, 1, ClientRectangle.Right, 1);
378                else if (DockState == DockState.DockRightAutoHide)
379                    g.DrawLine(SystemPens.ControlLightLight, 1, 0, 1, ClientRectangle.Bottom);
380                else if (DockState == DockState.DockTopAutoHide)
381                {
382                    g.DrawLine(SystemPens.ControlDark, 0, ClientRectangle.Height - 2, ClientRectangle.Right, ClientRectangle.Height - 2);
383                    g.DrawLine(SystemPens.ControlDarkDark, 0, ClientRectangle.Height - 1, ClientRectangle.Right, ClientRectangle.Height - 1);
384                }
385                else if (DockState == DockState.DockLeftAutoHide)
386                {
387                    g.DrawLine(SystemPens.ControlDark, ClientRectangle.Width - 2, 0, ClientRectangle.Width - 2, ClientRectangle.Bottom);
388                    g.DrawLine(SystemPens.ControlDarkDark, ClientRectangle.Width - 1, 0, ClientRectangle.Width - 1, ClientRectangle.Bottom);
389                }
390
391                base.OnPaint(e);
392            }
393
394            public void RefreshActiveContent()
395            {
396                if (ActiveContent == null)
397                    return;
398
399                if (!DockHelper.IsDockStateAutoHide(ActiveContent.DockHandler.DockState))
400                {
401                    FlagAnimate = false;
402                    ActiveContent = null;
403                    FlagAnimate = true;
404                }
405            }
406
407            public void RefreshActivePane()
408            {
409                SetTimerMouseTrack();
410            }
411
412            private void TimerMouseTrack_Tick(object sender, EventArgs e)
413            {
414                if (IsDisposed)
415                    return;
416
417                if (ActivePane == null || ActivePane.IsActivated)
418                {
419                    m_timerMouseTrack.Enabled = false;
420                    return;
421                }
422
423                DockPane pane = ActivePane;
424                Point ptMouseInAutoHideWindow = PointToClient(Control.MousePosition);
425                Point ptMouseInDockPanel = DockPanel.PointToClient(Control.MousePosition);
426
427                Rectangle rectTabStrip = DockPanel.GetTabStripRectangle(pane.DockState);
428
429                if (!ClientRectangle.Contains(ptMouseInAutoHideWindow) && !rectTabStrip.Contains(ptMouseInDockPanel))
430                {
431                    ActiveContent = null;
432                    m_timerMouseTrack.Enabled = false;
433                }
434            }
435
436            #region ISplitterDragSource Members
437
438            void ISplitterDragSource.BeginDrag(Rectangle rectSplitter)
439            {
440                FlagDragging = true;
441            }
442
443            void ISplitterDragSource.EndDrag()
444            {
445                FlagDragging = false;
446            }
447
448            bool ISplitterDragSource.IsVertical
449            {
450                get { return (DockState == DockState.DockLeftAutoHide || DockState == DockState.DockRightAutoHide); }
451            }
452
453            Rectangle ISplitterDragSource.DragLimitBounds
454            {
455                get
456                {
457                    Rectangle rectLimit = DockPanel.DockArea;
458
459                    if ((this as ISplitterDragSource).IsVertical)
460                    {
461                        rectLimit.X += MeasurePane.MinSize;
462                        rectLimit.Width -= 2 * MeasurePane.MinSize;
463                    }
464                    else
465                    {
466                        rectLimit.Y += MeasurePane.MinSize;
467                        rectLimit.Height -= 2 * MeasurePane.MinSize;
468                    }
469
470                    return DockPanel.RectangleToScreen(rectLimit);
471                }
472            }
473
474            void ISplitterDragSource.MoveSplitter(int offset)
475            {
476                Rectangle rectDockArea = DockPanel.DockArea;
477                IDockContent content = ActiveContent;
478                if (DockState == DockState.DockLeftAutoHide && rectDockArea.Width > 0)
479                {
480                    if (content.DockHandler.AutoHidePortion < 1)
481                        content.DockHandler.AutoHidePortion += ((double)offset) / (double)rectDockArea.Width;
482                    else
483                        content.DockHandler.AutoHidePortion = Width + offset;
484                }
485                else if (DockState == DockState.DockRightAutoHide && rectDockArea.Width > 0)
486                {
487                    if (content.DockHandler.AutoHidePortion < 1)
488                        content.DockHandler.AutoHidePortion -= ((double)offset) / (double)rectDockArea.Width;
489                    else
490                        content.DockHandler.AutoHidePortion = Width - offset;
491                }
492                else if (DockState == DockState.DockBottomAutoHide && rectDockArea.Height > 0)
493                {
494                    if (content.DockHandler.AutoHidePortion < 1)
495                        content.DockHandler.AutoHidePortion -= ((double)offset) / (double)rectDockArea.Height;
496                    else
497                        content.DockHandler.AutoHidePortion = Height - offset;
498                }
499                else if (DockState == DockState.DockTopAutoHide && rectDockArea.Height > 0)
500                {
501                    if (content.DockHandler.AutoHidePortion < 1)
502                        content.DockHandler.AutoHidePortion += ((double)offset) / (double)rectDockArea.Height;
503                    else
504                        content.DockHandler.AutoHidePortion = Height + offset;
505                }
506            }
507
508            #region IDragSource Members
509
510            Control IDragSource.DragControl
511            {
512                get { return this; }
513            }
514
515            #endregion
516
517            #endregion
518        }
519
520        private AutoHideWindowControl AutoHideWindow
521        {
522            get { return m_autoHideWindow; }
523        }
524
525        internal Control AutoHideControl
526        {
527            get { return m_autoHideWindow; }
528        }
529
530        internal void RefreshActiveAutoHideContent()
531        {
532            AutoHideWindow.RefreshActiveContent();
533        }
534
535        internal Rectangle AutoHideWindowRectangle
536        {
537            get
538            {
539                DockState state = AutoHideWindow.DockState;
540                Rectangle rectDockArea = DockArea;
541                if (ActiveAutoHideContent == null)
542                    return Rectangle.Empty;
543
544                if (Parent == null)
545                    return Rectangle.Empty;
546
547                Rectangle rect = Rectangle.Empty;
548                double autoHideSize = ActiveAutoHideContent.DockHandler.AutoHidePortion;
549                if (state == DockState.DockLeftAutoHide)
550                {
551                    if (autoHideSize < 1)
552                        autoHideSize = rectDockArea.Width * autoHideSize;
553                    if (autoHideSize > rectDockArea.Width - MeasurePane.MinSize)
554                        autoHideSize = rectDockArea.Width - MeasurePane.MinSize;
555                    rect.X = rectDockArea.X;
556                    rect.Y = rectDockArea.Y;
557                    rect.Width = (int)autoHideSize;
558                    rect.Height = rectDockArea.Height;
559                }
560                else if (state == DockState.DockRightAutoHide)
561                {
562                    if (autoHideSize < 1)
563                        autoHideSize = rectDockArea.Width * autoHideSize;
564                    if (autoHideSize > rectDockArea.Width - MeasurePane.MinSize)
565                        autoHideSize = rectDockArea.Width - MeasurePane.MinSize;
566                    rect.X = rectDockArea.X + rectDockArea.Width - (int)autoHideSize;
567                    rect.Y = rectDockArea.Y;
568                    rect.Width = (int)autoHideSize;
569                    rect.Height = rectDockArea.Height;
570                }
571                else if (state == DockState.DockTopAutoHide)
572                {
573                    if (autoHideSize < 1)
574                        autoHideSize = rectDockArea.Height * autoHideSize;
575                    if (autoHideSize > rectDockArea.Height - MeasurePane.MinSize)
576                        autoHideSize = rectDockArea.Height - MeasurePane.MinSize;
577                    rect.X = rectDockArea.X;
578                    rect.Y = rectDockArea.Y;
579                    rect.Width = rectDockArea.Width;
580                    rect.Height = (int)autoHideSize;
581                }
582                else if (state == DockState.DockBottomAutoHide)
583                {
584                    if (autoHideSize < 1)
585                        autoHideSize = rectDockArea.Height * autoHideSize;
586                    if (autoHideSize > rectDockArea.Height - MeasurePane.MinSize)
587                        autoHideSize = rectDockArea.Height - MeasurePane.MinSize;
588                    rect.X = rectDockArea.X;
589                    rect.Y = rectDockArea.Y + rectDockArea.Height - (int)autoHideSize;
590                    rect.Width = rectDockArea.Width;
591                    rect.Height = (int)autoHideSize;
592                }
593
594                return rect;
595            }
596        }
597
598        internal Rectangle GetAutoHideWindowBounds(Rectangle rectAutoHideWindow)
599        {
600            if (DocumentStyle == DocumentStyle.SystemMdi ||
601                DocumentStyle == DocumentStyle.DockingMdi)
602                return (Parent == null) ? Rectangle.Empty : Parent.RectangleToClient(RectangleToScreen(rectAutoHideWindow));
603            else
604                return rectAutoHideWindow;
605        }
606
607        internal void RefreshAutoHideStrip()
608        {
609            AutoHideStripControl.RefreshChanges();
610        }
611
612    }
613}
Note: See TracBrowser for help on using the repository browser.