Exemplo n.º 1
0
        /// <summary>Consumer method that processes mouse events in <see cref="_mouseEvents" /> that are recorded by <see cref="MouseHookCallback" />.</summary>
        protected void InterpretMouseEvents()
        {
            foreach (MouseEvent mouseEvent in _mouseEvents.GetConsumingEnumerable())
            {
                int            nCode      = mouseEvent.nCode;
                IntPtr         wParam     = mouseEvent.wParam;
                MSLLHOOKSTRUCT?hookStruct = mouseEvent.MouseData;

                if (nCode >= 0 && (int)WM.WM_MOUSEMOVE == (int)wParam)
                {
                    HideTooltip();

                    // ReSharper disable PossibleInvalidOperationException
                    Point cursorPosition = new Point(hookStruct.Value.pt.x, hookStruct.Value.pt.y);
                    // ReSharper restore PossibleInvalidOperationException
                    bool reRender = false;

                    if (_tornTab != null && _dropAreas != null)
                    {
                        // ReSharper disable ForCanBeConvertedToForeach
                        for (int i = 0; i < _dropAreas.Length; i++)
                        // ReSharper restore ForCanBeConvertedToForeach
                        {
                            // If the cursor is within the drop area, combine the tab for the window that belongs to that drop area
                            if (_dropAreas[i].Item2.Contains(cursorPosition))
                            {
                                TitleBarTab tabToCombine = null;

                                lock (_tornTabLock)
                                {
                                    if (_tornTab != null)
                                    {
                                        tabToCombine = _tornTab;
                                        _tornTab     = null;
                                    }
                                }

                                if (tabToCombine != null)
                                {
                                    int i1 = i;

                                    // In all cases where we need to affect the UI, we call Invoke so that those changes are made on the main UI thread since
                                    // we are on a separate processing thread in this case
                                    Invoke(
                                        new Action(
                                            () =>
                                    {
                                        _dropAreas[i1].Item1.TabRenderer.CombineTab(tabToCombine, cursorPosition);

                                        tabToCombine = null;
                                        _tornTabForm.Close();
                                        _tornTabForm = null;

                                        if (_parentForm.Tabs.Count == 0)
                                        {
                                            _parentForm.Close();
                                        }
                                    }));
                                }
                            }
                        }
                    }

                    else if (!_parentForm.TabRenderer.IsTabRepositioning)
                    {
                        StartTooltipTimer();

                        // If we were over a close button previously, check to see if the cursor is still over that tab's
                        // close button; if not, re-render
                        if (_isOverCloseButtonForTab != -1 &&
                            (_isOverCloseButtonForTab >= _parentForm.Tabs.Count ||
                             !_parentForm.TabRenderer.IsOverCloseButton(_parentForm.Tabs[_isOverCloseButtonForTab], GetRelativeCursorPosition(cursorPosition))))
                        {
                            reRender = true;
                            _isOverCloseButtonForTab = -1;
                        }

                        // Otherwise, see if any tabs' close button is being hovered over
                        else
                        {
                            // ReSharper disable ForCanBeConvertedToForeach
                            for (int i = 0; i < _parentForm.Tabs.Count; i++)
                            // ReSharper restore ForCanBeConvertedToForeach
                            {
                                if (_parentForm.TabRenderer.IsOverCloseButton(_parentForm.Tabs[i], GetRelativeCursorPosition(cursorPosition)))
                                {
                                    _isOverCloseButtonForTab = i;
                                    reRender = true;

                                    break;
                                }
                            }
                        }
                    }

                    else
                    {
                        Invoke(
                            new Action(
                                () =>
                        {
                            _wasDragging = true;

                            // When determining if a tab has been torn from the window while dragging, we take the drop area for this window and inflate it by the
                            // TabTearDragDistance setting
                            Rectangle dragArea = TabDropArea;
                            dragArea.Inflate(_parentForm.TabRenderer.TabTearDragDistance, _parentForm.TabRenderer.TabTearDragDistance);

                            // If the cursor is outside the tear area, tear it away from the current window
                            if (!dragArea.Contains(cursorPosition) && _tornTab == null)
                            {
                                lock (_tornTabLock)
                                {
                                    if (_tornTab == null)
                                    {
                                        _parentForm.TabRenderer.IsTabRepositioning = false;

                                        // Clear the event handler subscriptions from the tab and then create a thumbnail representation of it to use when dragging
                                        _tornTab = _parentForm.SelectedTab;
                                        _tornTab.ClearSubscriptions();
                                        _tornTabForm = new TornTabForm(_tornTab, _parentForm.TabRenderer);
                                    }
                                }

                                if (_tornTab != null)
                                {
                                    _parentForm.SelectedTabIndex = (_parentForm.SelectedTabIndex == _parentForm.Tabs.Count - 1
                                                                                                ? _parentForm.SelectedTabIndex - 1
                                                                                                : _parentForm.SelectedTabIndex + 1);
                                    _parentForm.Tabs.Remove(_tornTab);

                                    // If this tab was the only tab in the window, hide the parent window
                                    if (_parentForm.Tabs.Count == 0)
                                    {
                                        _parentForm.Hide();
                                    }

                                    _tornTabForm.Show();
                                    _dropAreas = (from window in _parentForm.ApplicationContext.OpenWindows.Where(w => w.Tabs.Count > 0)
                                                  select new Tuple <TitleBarTabs, Rectangle>(window, window.TabDropArea)).ToArray();
                                }
                            }
                        }));
                    }

                    Invoke(new Action(() => OnMouseMove(new MouseEventArgs(MouseButtons.None, 0, cursorPosition.X, cursorPosition.Y, 0))));

                    if (_parentForm.TabRenderer.IsTabRepositioning)
                    {
                        reRender = true;
                    }

                    if (reRender)
                    {
                        Invoke(new Action(() => Render(cursorPosition, true)));
                    }
                }

                else if (nCode >= 0 && (int)WM.WM_LBUTTONDOWN == (int)wParam)
                {
                    _wasDragging = false;
                }

                else if (nCode >= 0 && (int)WM.WM_LBUTTONUP == (int)wParam)
                {
                    // If we released the mouse button while we were dragging a torn tab, put that tab into a new window
                    if (_tornTab != null)
                    {
                        TitleBarTab tabToRelease = null;

                        lock (_tornTabLock)
                        {
                            if (_tornTab != null)
                            {
                                tabToRelease = _tornTab;
                                _tornTab     = null;
                            }
                        }

                        if (tabToRelease != null)
                        {
                            Invoke(
                                new Action(
                                    () =>
                            {
                                TitleBarTabs newWindow = (TitleBarTabs)Activator.CreateInstance(_parentForm.GetType());

                                // Set the initial window position and state properly
                                if (newWindow.WindowState == FormWindowState.Maximized)
                                {
                                    Screen screen = Screen.AllScreens.First(s => s.WorkingArea.Contains(Cursor.Position));

                                    newWindow.StartPosition = FormStartPosition.Manual;
                                    newWindow.WindowState   = FormWindowState.Normal;
                                    newWindow.Left          = screen.WorkingArea.Left;
                                    newWindow.Top           = screen.WorkingArea.Top;
                                    newWindow.Width         = screen.WorkingArea.Width;
                                    newWindow.Height        = screen.WorkingArea.Height;
                                }

                                else
                                {
                                    newWindow.Left = Cursor.Position.X;
                                    newWindow.Top  = Cursor.Position.Y;
                                }

                                tabToRelease.Parent = newWindow;
                                _parentForm.ApplicationContext.OpenWindow(newWindow);

                                newWindow.Show();
                                newWindow.Tabs.Add(tabToRelease);
                                newWindow.SelectedTabIndex = 0;
                                newWindow.ResizeTabContents();

                                _tornTabForm.Close();
                                _tornTabForm = null;

                                if (_parentForm.Tabs.Count == 0)
                                {
                                    _parentForm.Close();
                                }
                            }));
                        }
                    }

                    Invoke(new Action(() => OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, Cursor.Position.X, Cursor.Position.Y, 0))));
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Consumer method that processes mouse events in <see cref="MouseEvents" /> that are recorded by <see cref="MouseHookCallback" />
        /// </summary>
        protected void InterpretMouseEvents()
        {
            foreach (MouseEvent mouseEvent in MouseEvents.GetConsumingEnumerable())
            {
                int            nCode      = mouseEvent.nCode;
                IntPtr         wParam     = mouseEvent.wParam;
                MSLLHOOKSTRUCT?hookStruct = mouseEvent.MouseData;
                if (nCode >= 0 && (int)WM.WM_MOUSEMOVE == (int)wParam)
                {
                    Point cursorPosition = new Point(hookStruct.Value.pt.x, hookStruct.Value.pt.y);
                    bool  reRender       = false;
                    if (s_tornTab != null && DropAreas != null)
                    {
                        for (int i = 0; i < DropAreas.Length; i++)
                        {
                            if (DropAreas[i].Item2.Contains(cursorPosition)) // If the cursor is within the drop area, combine the tab for the window that belongs to that drop area
                            {
                                TitleBarTab tabToCombine = null;
                                lock (s_tornTabLock)
                                {
                                    if (s_tornTab != null)
                                    {
                                        tabToCombine = s_tornTab;
                                        s_tornTab    = null;
                                    }
                                }

                                if (tabToCombine != null)
                                {
                                    int i1 = i;
                                    Invoke(new Action(() =>
                                    {
                                        DropAreas[i1].Item1.TabRenderer.CombineTab(tabToCombine, cursorPosition);
                                        tabToCombine = null;
                                        s_tornTabForm.Close();
                                        s_tornTabForm = null;
                                        if (ParentForm.Tabs.Count == 0)
                                        {
                                            ParentForm.Close();
                                        }
                                    }));
                                }
                            }
                        }
                    }
                    else if (!ParentForm.TabRenderer.IsTabRepositioning)
                    {
                        // If we were over a close button previously, check to see if the cursor is still over that tab's close button; if not, re-render
                        if (IsOverCLoseButtonForTab != -1 && (IsOverCLoseButtonForTab >= ParentForm.Tabs.Count || !ParentForm.TabRenderer.IsOverCloseButton(ParentForm.Tabs[IsOverCLoseButtonForTab], GetRelativeCursorPosition(cursorPosition))))
                        {
                            reRender = true;
                            IsOverCLoseButtonForTab = -1;
                        }
                        else // Otherwise, see if any tabs' close button is being hovered over
                        {
                            for (int i = 0; i < ParentForm.Tabs.Count; i++)
                            {
                                if (ParentForm.TabRenderer.IsOverCloseButton(ParentForm.Tabs[i], GetRelativeCursorPosition(cursorPosition)))
                                {
                                    IsOverCLoseButtonForTab = i;
                                    reRender = true;
                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        Invoke(new Action(() =>
                        {
                            s_wasDragging      = true;
                            Rectangle dragArea = TabDropArea;
                            dragArea.Inflate(ParentForm.TabRenderer.TabTearDragDistance, ParentForm.TabRenderer.TabTearDragDistance);
                            if (!dragArea.Contains(cursorPosition) && s_tornTab == null)
                            {
                                lock (s_tornTabLock)
                                {
                                    if (s_tornTab == null)
                                    {
                                        ParentForm.TabRenderer.IsTabRepositioning = false;
                                        s_tornTab = ParentForm.SelectedTab;
                                        s_tornTab.ClearEventSubscriptions();
                                        s_tornTabForm = new TornTabForm(s_tornTab, ParentForm.TabRenderer);
                                    }
                                }

                                if (s_tornTab != null)
                                {
                                    ParentForm.SelectedTabIndex = ParentForm.SelectedTabIndex == ParentForm.Tabs.Count - 1 ? ParentForm.SelectedTabIndex - 1 : ParentForm.SelectedTabIndex + 1;
                                    ParentForm.Tabs.Remove(s_tornTab);
                                    if (ParentForm.Tabs.Count == 0)
                                    {
                                        ParentForm.Hide();
                                    }
                                    s_tornTabForm.Show();
                                    DropAreas = (from window in ParentForm.ApplicationContext.OpenWindows.Where(w => w.Tabs.Count > 0) select new Tuple <TitleBarTabs, Rectangle>(window, window.TabDropArea)).ToArray();
                                }
                            }
                        }));
                    }
                    Invoke(new Action(() => OnMouseMove(new MouseEventArgs(MouseButtons.None, 0, cursorPosition.X, cursorPosition.Y, 0))));
                    if (ParentForm.TabRenderer.IsTabRepositioning)
                    {
                        reRender = true;
                    }
                    if (reRender)
                    {
                        Invoke(new Action(() => Render(cursorPosition, true)));
                    }
                }
                else if (nCode >= 0 && (int)WM.WM_LBUTTONDOWN == (int)wParam)
                {
                    s_wasDragging = false;
                }
                else if (nCode >= 0 && (int)WM.WM_LBUTTONUP == (int)wParam)
                {
                    if (s_tornTab != null)
                    {
                        TitleBarTab tabToRelease = null;
                        lock (s_tornTabLock)
                        {
                            if (s_tornTab != null)
                            {
                                tabToRelease = s_tornTab;
                                s_tornTab    = null;
                            }
                        }

                        if (tabToRelease != null)
                        {
                            Invoke(new Action(() =>
                            {
                                TitleBarTabs newWindow = (TitleBarTabs)Activator.CreateInstance(ParentForm.GetType());
                                if (newWindow.WindowState == FormWindowState.Maximized)
                                {
                                    Screen screen           = Screen.AllScreens.First(s => s.WorkingArea.Contains(Cursor.Position));
                                    newWindow.StartPosition = FormStartPosition.Manual;
                                    newWindow.WindowState   = FormWindowState.Normal;
                                    newWindow.Left          = screen.WorkingArea.Left;
                                    newWindow.Top           = screen.WorkingArea.Top;
                                    newWindow.Width         = screen.WorkingArea.Width;
                                    newWindow.Height        = screen.WorkingArea.Height;
                                }
                                else
                                {
                                    newWindow.Left = Cursor.Position.X;
                                    newWindow.Top  = Cursor.Position.Y;
                                }
                                tabToRelease.Parent = newWindow;
                                ParentForm.ApplicationContext.OpenWindow(newWindow);
                                newWindow.Show();
                                newWindow.Tabs.Add(tabToRelease);
                                newWindow.SelectedTabIndex = 0;
                                newWindow.ResizeTabContents();
                                s_tornTabForm.Close();
                                s_tornTabForm = null;
                                if (ParentForm.Tabs.Count == 0)
                                {
                                    ParentForm.Close();
                                }
                            }));
                        }
                    }
                    Invoke(new Action(() => OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, Cursor.Position.X, Cursor.Position.Y, 0))));
                }
            }
        }