Пример #1
0
        /// <summary>Constructor that initializes the various resources that we use in rendering.</summary>
        /// <param name="parentWindow">Parent window that this renderer belongs to.</param>
        public chrome_tab_renderer(TitleBarTabs parentWindow)
            : base(parentWindow)
        {
            // Initialize the various images to use during rendering
            _activeLeftSideImage    = Resources.tabLeft;
            _activeRightSideImage   = Resources.tabRight;
            _activeCenterImage      = Resources.tabCenter;
            _inactiveLeftSideImage  = Resources.tabInactiveLeft;
            _inactiveRightSideImage = Resources.tabInactiveRight;
            _inactiveCenterImage    = Resources.tabInactiveCenter;
            _closeButtonImage       = Resources.tabClose;
            _closeButtonHoverImage  = Resources.tabCloseHover;
            _background             = Resources.tabBackground;
            _addButtonImage         = new Bitmap(Resources.tabAdd);
            _addButtonHoverImage    = new Bitmap(Resources.tabAddHover);

            // Set the various positioning properties
            CloseButtonMarginTop  = 6;
            CloseButtonMarginLeft = 2;
            AddButtonMarginTop    = 5;
            AddButtonMarginLeft   = -3;
            CaptionMarginTop      = 5;
            IconMarginTop         = 6;
            IconMarginRight       = 5;
            AddButtonMarginRight  = 5;
        }
Пример #2
0
        /// <summary>
        /// Retrieves or creates the overlay for <paramref name="parentForm" />.
        /// </summary>
        /// <param name="parentForm">Parent form that we are to create the overlay for.</param>
        /// <returns>
        /// Newly-created or previously existing overlay for <paramref name="parentForm" />.
        /// </returns>
        public static TitleBarTabsOverlay GetInstance(TitleBarTabs parentForm)
        {
            if (!_parents.ContainsKey(parentForm))
            {
                _parents.Add(parentForm, new TitleBarTabsOverlay(parentForm));
            }

            return(_parents[parentForm]);
        }
		/// <summary>
		/// Adds <paramref name="window" /> to <see cref="_openWindows" /> and attaches event handlers to its <see cref="Form.FormClosed" /> event to keep track
		/// of it.
		/// </summary>
		/// <param name="window">Window that we're opening.</param>
		public void OpenWindow(TitleBarTabs window)
		{
			if (!_openWindows.Contains(window))
			{
				window.ApplicationContext = this;

				_openWindows.Add(window);
				window.FormClosed += window_FormClosed;
			}
		}
		/// <summary>Constructor; takes the initial window to display and, if it's not closing, opens it and shows it.</summary>
		/// <param name="initialFormInstance">Initial window to display.</param>
		public void Start(TitleBarTabs initialFormInstance)
		{
			if (initialFormInstance.IsClosing)
				ExitThread();

			else
			{
				OpenWindow(initialFormInstance);
				initialFormInstance.Show();
			}
		}
Пример #5
0
        /// <summary>
        /// Creates the overlay window and attaches it to <paramref name="parentForm" />.
        /// </summary>
        /// <param name="parentForm">Parent form that the overlay should be rendered on top of.</param>
        protected TitleBarTabsOverlay(TitleBarTabs parentForm)
        {
            _parentForm = parentForm;

            // We don't want this window visible in the taskbar
            ShowInTaskbar   = false;
            FormBorderStyle = FormBorderStyle.Sizable;
            MinimizeBox     = false;
            MaximizeBox     = false;
            _aeroEnabled    = _parentForm.IsCompositionEnabled;

            Show(_parentForm);
            AttachHandlers();
        }
Пример #6
0
        /// <summary>Default constructor that initializes the <see cref="_parentWindow" /> and <see cref="ShowAddButton" /> properties.</summary>
        /// <param name="parentWindow">The parent window that this renderer instance belongs to.</param>
        protected base_tab_renderer(TitleBarTabs parentWindow)
        {
            _parentWindow             = parentWindow;
            ShowAddButton             = true;
            TabRepositionDragDistance = 10;
            TabTearDragDistance       = 10;

            parentWindow.Tabs.CollectionModified += Tabs_CollectionModified;

            if (parentWindow._overlay != null)
            {
                parentWindow._overlay.MouseMove += Overlay_MouseMove;
                parentWindow._overlay.MouseUp   += Overlay_MouseUp;
                parentWindow._overlay.MouseDown += Overlay_MouseDown;
            }
        }
Пример #7
0
        /// <summary>
        /// Event handler that is called when <see cref="_parentForm" /> is in the process of closing.  This uninstalls <see cref="_hookproc" /> from the low-
        /// level hooks list and stops the consumer thread that processes those events.
        /// </summary>
        /// <param name="sender">
        /// Object from which this event originated, <see cref="_parentForm" /> in this case.
        /// </param>
        /// <param name="e">Arguments associated with this event.</param>
        private void _parentForm_Closing(object sender, CancelEventArgs e)
        {
            TitleBarTabs form = (TitleBarTabs)sender;

            if (form == null)
            {
                return;
            }

            if (_parents.ContainsKey(form))
            {
                _parents.Remove(form);
            }

            // Uninstall the mouse hook
            User32.UnhookWindowsHookEx(_hookId);

            // Kill the mouse events processing thread
            _mouseEvents.CompleteAdding();
            _mouseEventsThread.Abort();
        }
Пример #8
0
 /// <summary>Default constructor that initializes the various properties.</summary>
 /// <param name="parent">Parent window that contains this tab.</param>
 public TitleBarTab(TitleBarTabs parent)
 {
     ShowCloseButton = true;
     Parent          = parent;
 }
Пример #9
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)
                {
// ReSharper disable PossibleInvalidOperationException
                    Point cursorPosition = new Point(hookStruct.Value.pt.x, hookStruct.Value.pt.y);
// ReSharper restore PossibleInvalidOperationException
                    bool reRender = false;

                    if (_tornTab != 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)
                    {
                        // 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))));
                }
            }
        }