Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/WinFormsUI/Docking/DockPanel.AutoHideWindow.cs @ 2410

Last change on this file since 2410 was 2134, checked in by gkronber, 15 years ago

Added up to date source of Weifen Luo dock panel suit in a separate project (and added strong name key). Removed binary versions of Weifen Luo dock panel suite and references to it. #687 (Update AdvancedOptimizationFrontend to use more recent version of Weifen Luo Docking library)

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