Ejemplo n.º 1
0
        /// <summary>
        /// Perform final steps now that the button spec has been created.
        /// </summary>
        /// <param name="buttonSpec">ButtonSpec instance.</param>
        /// <param name="buttonView">Associated ButtonSpecView instance.</param>
        /// <param name="viewDockerIndex">Index of view docker button is placed onto.</param>
        protected override void ButtonSpecCreated(ButtonSpec buttonSpec,
                                                  ButtonSpecView buttonView,
                                                  int viewDockerIndex)
        {
            // Cast the remapping palette to the correct type
            ButtonSpecRemapByContentCache remapPalette = (ButtonSpecRemapByContentCache)buttonView.RemapPalette;

            // Update button with the foreground used for color mapping
            remapPalette.SetPaletteContent(_paletteContent);
            remapPalette.SetPaletteState(_paletteState);
        }
        /// <summary>
        /// Gets the ButtonSpec associated with the provided view element.
        /// </summary>
        /// <param name="element">Element to search against.</param>
        /// <returns>Reference to ButtonSpec; otherwise null.</returns>
        public override ButtonSpec ButtonSpecFromView(ViewBase element)
        {
            // Check base class for page specific button specs
            ButtonSpec bs = base.ButtonSpecFromView(element);

            // Delegate lookup to the viewlet that has the button spec manager
            if (bs == null)
            {
                bs = _headerGroup.ButtonSpecFromView(element);
            }

            return(bs);
        }
        /// <summary>
        /// Get the display rectangle of the provided button.
        /// </summary>
        /// <param name="buttonSpec">Button specification.</param>
        /// <returns>Display rectangle.</returns>
        public Rectangle GetButtonRectangle(ButtonSpec buttonSpec)
        {
            // Find all the buttons on this view docker
            foreach (ButtonSpecView buttonView in _specLookup.Values)
            {
                if (buttonView.ButtonSpec == buttonSpec)
                {
                    return(buttonView.ViewButton.ClientRectangle);
                }
            }

            return(Rectangle.Empty);
        }
        /// <summary>
        /// Gets the ButtonSpec associated with the provided view element.
        /// </summary>
        /// <param name="element">Element to search against.</param>
        /// <returns>Reference to ButtonSpec; otherwise null.</returns>
        public override ButtonSpec ButtonSpecFromView(ViewBase element)
        {
            // Always check base class first
            ButtonSpec bs = base.ButtonSpecFromView(element);

            // Call onto the contained header group implementation
            if (bs == null)
            {
                bs = _headerGroup.ButtonSpecFromView(element);
            }

            return(bs);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Gets the ButtonSpec associated with the provided view element.
        /// </summary>
        /// <param name="element">Element to search against.</param>
        /// <returns>Reference to ButtonSpec; otherwise null.</returns>
        public override ButtonSpec ButtonSpecFromView(ViewBase element)
        {
            // Check each page level button spec
            if (_pageLookup != null)
            {
                foreach (KeyValuePair <KryptonPage, ViewDrawNavCheckButtonBase> pair in _pageLookup)
                {
                    ButtonSpec bs = pair.Value.ButtonSpecFromView(element);
                    if (bs != null)
                    {
                        return(bs);
                    }
                }
            }

            return(null);
        }
        /// <summary>
        /// Gets the ButtonSpec associated with the provided view element.
        /// </summary>
        /// <param name="element">Element to search against.</param>
        /// <returns>Reference to ButtonSpec; otherwise null.</returns>
        public override ButtonSpec ButtonSpecFromView(ViewBase element)
        {
            // Check each page level button spec
            if (_pageLookup != null)
            {
                foreach (var pair in _pageLookup)
                {
                    ButtonSpec bs = pair.Value.ButtonSpecFromView(element);
                    if (bs != null)
                    {
                        return(bs);
                    }
                }
            }

            return(null);
        }
Ejemplo n.º 7
0
        private void OnCellCloseAction(object sender, EventArgs e)
        {
            if (ApplyDockingCloseAction)
            {
                // Find the page associated with the cell that fired this button spec
                ButtonSpec buttonSpec = (ButtonSpec)sender;
                foreach (CachedCellState cellState in _lookupCellState.Values)
                {
                    if (cellState.CloseButtonSpec == buttonSpec)
                    {
                        if (cellState.Cell.SelectedPage != null)
                        {
                            OnPageCloseClicked(new UniqueNameEventArgs(cellState.Cell.SelectedPage.UniqueName));
                        }

                        break;
                    }
                }
            }
        }
        private void OnComponentRemoving(object sender, ComponentEventArgs e)
        {
            // If our control is being removed
            if (e.Component == _ribbon)
            {
                // Need access to host in order to delete a component
                IDesignerHost host = (IDesignerHost)GetService(typeof(IDesignerHost));

                // We need to remove all the button spec instances
                for (int i = _ribbon.ButtonSpecs.Count - 1; i >= 0; i--)
                {
                    ButtonSpec spec = _ribbon.ButtonSpecs[i];
                    _ribbon.ButtonSpecs.Remove(spec);
                    host.DestroyComponent(spec);
                }

                // We need to remove all the QAT button specifications
                for (int i = _ribbon.QATButtons.Count - 1; i >= 0; i--)
                {
                    Component button = _ribbon.QATButtons[i];
                    _ribbon.QATButtons.Remove(button);
                    host.DestroyComponent(button);
                }

                // We need to remove all the ribbon context instances
                for (int i = _ribbon.RibbonContexts.Count - 1; i >= 0; i--)
                {
                    KryptonRibbonContext context = _ribbon.RibbonContexts[i];
                    _ribbon.RibbonContexts.Remove(context);
                    host.DestroyComponent(context);
                }

                // We need to remove all the ribbon tab instances
                for (int i = _ribbon.RibbonTabs.Count - 1; i >= 0; i--)
                {
                    KryptonRibbonTab tab = _ribbon.RibbonTabs[i];
                    _ribbon.RibbonTabs.Remove(tab);
                    host.DestroyComponent(tab);
                }
            }
        }
Ejemplo n.º 9
0
        private void OnShowToolTip(object sender, ToolTipEventArgs e)
        {
            if (!_ribbon.IsDisposed)
            {
                // Do not show tooltips when the form we are in does not have focus
                Form topForm = _ribbon.FindForm();
                if ((topForm != null) && !topForm.ContainsFocus)
                {
                    return;
                }

                // Never show tooltips are design time
                if (!_ribbon.InDesignMode)
                {
                    IContentValues sourceContent = null;
                    LabelStyle     toolTipStyle  = LabelStyle.SuperTip;
                    Rectangle      screenRect    = new Rectangle(e.ScreenPt, new Size(1, 1));

                    // If the target is the application button
                    if ((e.Target is ViewLayoutRibbonAppButton) || (e.Target is ViewLayoutRibbonAppTab))
                    {
                        // Create a content that recovers values from a the ribbon for the app button/tab
                        AppButtonToolTipToContent appButtonContent = new AppButtonToolTipToContent(_ribbon);

                        // Is there actually anything to show for the tooltip
                        if (appButtonContent.HasContent)
                        {
                            sourceContent = appButtonContent;

                            // Grab the style from the app button settings
                            toolTipStyle = _ribbon.RibbonAppButton.AppButtonToolTipStyle;

                            // Display below the mouse cursor
                            screenRect.Height += SystemInformation.CursorSize.Height / 3 * 2;
                        }
                    }
                    else
                    {
                        // If the target is a QAT button
                        if (e.Target is ViewDrawRibbonQATButton)
                        {
                            // Cast to correct type
                            ViewDrawRibbonQATButton viewElement = (ViewDrawRibbonQATButton)e.Target;

                            // Create a content that recovers values from a IQuickAccessToolbarButton
                            QATButtonToolTipToContent qatButtonContent = new QATButtonToolTipToContent(viewElement.QATButton);

                            // Is there actually anything to show for the tooltip
                            if (qatButtonContent.HasContent)
                            {
                                sourceContent = qatButtonContent;

                                // Grab the style from the QAT button settings
                                toolTipStyle = viewElement.QATButton.GetToolTipStyle();

                                // Display below the mouse cursor
                                screenRect.Height += SystemInformation.CursorSize.Height / 3 * 2;
                            }
                        }
                        else
                        {
                            // If the target is a label
                            if ((e.Target.Parent != null) && (e.Target.Parent is ViewDrawRibbonGroupLabel))
                            {
                                // Cast to correct type
                                ViewDrawRibbonGroupLabel viewElement = (ViewDrawRibbonGroupLabel)e.Target.Parent;

                                // Create a content that recovers values from a KryptonRibbonGroupItem
                                GroupItemToolTipToContent groupItemContent = new GroupItemToolTipToContent(viewElement.GroupLabel);

                                // Is there actually anything to show for the tooltip
                                if (groupItemContent.HasContent)
                                {
                                    sourceContent = groupItemContent;

                                    // Grab the style from the group label settings
                                    toolTipStyle = viewElement.GroupLabel.ToolTipStyle;

                                    // Display below the bottom of the ribbon control
                                    Rectangle ribbonScreenRect = _ribbon.ToolTipScreenRectangle;
                                    screenRect.Y      = ribbonScreenRect.Y;
                                    screenRect.Height = ribbonScreenRect.Height;
                                    screenRect.X      = ribbonScreenRect.X + viewElement.ClientLocation.X;
                                    screenRect.Width  = viewElement.ClientWidth;
                                }
                            }
                            else
                            {
                                // Is the target is a button or cluster button
                                if (e.Target is ViewDrawRibbonGroupButtonBackBorder)
                                {
                                    // Cast to correct type
                                    ViewDrawRibbonGroupButtonBackBorder viewElement = (ViewDrawRibbonGroupButtonBackBorder)e.Target;

                                    // Create a content that recovers values from a KryptonRibbonGroupItem
                                    GroupItemToolTipToContent groupItemContent = new GroupItemToolTipToContent(viewElement.GroupItem);

                                    // Is there actually anything to show for the tooltip
                                    if (groupItemContent.HasContent)
                                    {
                                        sourceContent = groupItemContent;

                                        // Grab the style from the group button/group cluster button settings
                                        toolTipStyle = viewElement.GroupItem.InternalToolTipStyle;

                                        // Display below the bottom of the ribbon control
                                        Rectangle ribbonScreenRect = _ribbon.ToolTipScreenRectangle;
                                        screenRect.Y      = ribbonScreenRect.Y;
                                        screenRect.Height = ribbonScreenRect.Height;
                                        screenRect.X      = ribbonScreenRect.X + viewElement.ClientLocation.X;
                                        screenRect.Width  = viewElement.ClientWidth;
                                    }
                                }
                                else
                                {
                                    if (e.Target is ViewLayoutRibbonCheckBox)
                                    {
                                        // Cast to correct type
                                        ViewDrawRibbonGroupCheckBox viewElement = (ViewDrawRibbonGroupCheckBox)e.Target.Parent;

                                        // Create a content that recovers values from a KryptonRibbonGroupItem
                                        GroupItemToolTipToContent groupItemContent = new GroupItemToolTipToContent(viewElement.GroupCheckBox);

                                        // Is there actually anything to show for the tooltip
                                        if (groupItemContent.HasContent)
                                        {
                                            sourceContent = groupItemContent;

                                            // Grab the style from the group check box cluster button settings
                                            toolTipStyle = viewElement.GroupCheckBox.InternalToolTipStyle;

                                            // Display below the bottom of the ribbon control
                                            Rectangle ribbonScreenRect = _ribbon.ToolTipScreenRectangle;
                                            screenRect.Y      = ribbonScreenRect.Y;
                                            screenRect.Height = ribbonScreenRect.Height;
                                            screenRect.X      = ribbonScreenRect.X + viewElement.ClientLocation.X;
                                            screenRect.Width  = viewElement.ClientWidth;
                                        }
                                    }
                                    else
                                    {
                                        if (e.Target is ViewLayoutRibbonRadioButton)
                                        {
                                            // Cast to correct type
                                            ViewDrawRibbonGroupRadioButton viewElement = (ViewDrawRibbonGroupRadioButton)e.Target.Parent;

                                            // Create a content that recovers values from a KryptonRibbonGroupItem
                                            GroupItemToolTipToContent groupItemContent = new GroupItemToolTipToContent(viewElement.GroupRadioButton);

                                            // Is there actually anything to show for the tooltip
                                            if (groupItemContent.HasContent)
                                            {
                                                sourceContent = groupItemContent;

                                                // Grab the style from the group radio button button settings
                                                toolTipStyle = viewElement.GroupRadioButton.InternalToolTipStyle;

                                                // Display below the bottom of the ribbon control
                                                Rectangle ribbonScreenRect = _ribbon.ToolTipScreenRectangle;
                                                screenRect.Y      = ribbonScreenRect.Y;
                                                screenRect.Height = ribbonScreenRect.Height;
                                                screenRect.X      = ribbonScreenRect.X + viewElement.ClientLocation.X;
                                                screenRect.Width  = viewElement.ClientWidth;
                                            }
                                        }
                                        else
                                        {
                                            // Find the button spec associated with the tooltip request
                                            ButtonSpec buttonSpec = _buttonManager.ButtonSpecFromView(e.Target);

                                            // If the tooltip is for a button spec
                                            if (buttonSpec != null)
                                            {
                                                // Are we allowed to show page related tooltips
                                                if (_ribbon.AllowButtonSpecToolTips)
                                                {
                                                    // Create a helper object to provide tooltip values
                                                    ButtonSpecToContent buttonSpecMapping = new ButtonSpecToContent(_ribbon.GetRedirector(), buttonSpec);

                                                    // Is there actually anything to show for the tooltip
                                                    if (buttonSpecMapping.HasContent)
                                                    {
                                                        sourceContent = buttonSpecMapping;

                                                        // Grab the style from the button spec settings
                                                        toolTipStyle = buttonSpec.ToolTipStyle;

                                                        // Display below the mouse cursor
                                                        screenRect.Height += SystemInformation.CursorSize.Height / 3 * 2;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }

                    if (sourceContent != null)
                    {
                        // Remove any currently showing tooltip
                        _visualPopupToolTip?.Dispose();

                        // Create the actual tooltip popup object
                        _visualPopupToolTip = new VisualPopupToolTip(_ribbon.GetRedirector(),
                                                                     sourceContent,
                                                                     _ribbon.Renderer,
                                                                     PaletteBackStyle.ControlToolTip,
                                                                     PaletteBorderStyle.ControlToolTip,
                                                                     CommonHelper.ContentStyleFromLabelStyle(toolTipStyle));

                        _visualPopupToolTip.Disposed += new EventHandler(OnVisualPopupToolTipDisposed);

                        // The popup tooltip control always adds on a border above/below so we negate that here.
                        screenRect.Height -= 20;

                        // Show relative to the provided screen rectangle
                        _visualPopupToolTip.ShowCalculatingSize(screenRect);
                    }
                }
            }
        }
        /// <summary>
        /// Initialize a new instance of the ButtonSpecView class.
        /// </summary>
        /// <param name="redirector">Palette redirector.</param>
        /// <param name="paletteMetric">Source for metric values.</param>
        /// <param name="metricPadding">Padding metric for border padding.</param>
        /// <param name="manager">Reference to owning manager.</param>
        /// <param name="buttonSpec">Access</param>
        public ButtonSpecView(PaletteRedirect redirector,
                              IPaletteMetric paletteMetric,
                              PaletteMetricPadding metricPadding,
                              ButtonSpecManagerBase manager,
                              ButtonSpec buttonSpec)
        {
            Debug.Assert(redirector != null);
            Debug.Assert(manager != null);
            Debug.Assert(buttonSpec != null);

            // Remember references
            _redirector     = redirector;
            Manager         = manager;
            ButtonSpec      = buttonSpec;
            _finishDelegate = OnFinishDelegate;

            // Create delegate for paint notifications
            NeedPaintHandler needPaint = OnNeedPaint;

            // Intercept calls from the button for color remapping and instead use
            // the button spec defined map and the container foreground color
            RemapPalette = Manager.CreateButtonSpecRemap(redirector, buttonSpec);

            // Use a redirector to get button values directly from palette
            _palette = new PaletteTripleRedirect(RemapPalette,
                                                 PaletteBackStyle.ButtonButtonSpec,
                                                 PaletteBorderStyle.ButtonButtonSpec,
                                                 PaletteContentStyle.ButtonButtonSpec,
                                                 needPaint);


            // Create the view for displaying a button
            ViewButton = new ViewDrawButton(_palette, _palette, _palette, _palette,
                                            paletteMetric, this, VisualOrientation.Top, false);

            // Associate the view with the source component (for design time support)
            if (buttonSpec.AllowComponent)
            {
                ViewButton.Component = buttonSpec;
            }

            // Use a view center to place button in centre of given space
            ViewCenter = new ViewLayoutCenter(paletteMetric, metricPadding, VisualOrientation.Top)
            {
                ViewButton
            };

            // Create a controller for managing button behavior
            ButtonSpecViewControllers controllers = CreateController(ViewButton, needPaint, OnClick);

            ViewButton.MouseController  = controllers.MouseController;
            ViewButton.SourceController = controllers.SourceController;
            ViewButton.KeyController    = controllers.KeyController;

            // We need notifying whenever a button specification property changes
            ButtonSpec.ButtonSpecPropertyChanged += OnPropertyChanged;

            // Associate the button spec with the view that is drawing it
            ButtonSpec.SetView(ViewButton);

            // Finally update view with current button spec settings
            UpdateButtonStyle();
            UpdateVisible();
            UpdateEnabled();
            UpdateChecked();
        }
 /// <summary>
 /// Create a palette redirector for remapping button spec colors.
 /// </summary>
 /// <param name="redirector">Base palette class.</param>
 /// <param name="buttonSpec">ButtonSpec instance.</param>
 /// <returns>Palette redirector for the button spec instance.</returns>
 public override PaletteRedirect CreateButtonSpecRemap(PaletteRedirect redirector,
                                                       ButtonSpec buttonSpec)
 {
     return(new ButtonSpecRemapByContentCache(redirector, buttonSpec));
 }
 /// <summary>
 /// Create a palette redirector for remapping button spec colors.
 /// </summary>
 /// <param name="redirector">Base palette class.</param>
 /// <param name="buttonSpec">ButtonSpec instance.</param>
 /// <returns>Palette redirector for the button spec instance.</returns>
 public virtual PaletteRedirect CreateButtonSpecRemap(PaletteRedirect redirector,
                                                      ButtonSpec buttonSpec) =>
 new ButtonSpecRemapByContentView(redirector, buttonSpec);
Ejemplo n.º 13
0
 public void addButton(ButtonSpec bs)
 {
     this.buttons.Add(bs.buttonLabel, bs);
 }
 /// <summary>
 /// Create the button spec view appropriate for the button spec.
 /// </summary>
 /// <param name="redirector">Redirector for acquiring palette values.</param>
 /// <param name="viewPaletteMetric">Target metric providers.</param>
 /// <param name="viewMetricPadding">Target metric padding.</param>
 /// <param name="buttonSpec">ButtonSpec instance.</param>
 /// <returns>ButtonSpecView derived class.</returns>
 protected virtual ButtonSpecView CreateButtonSpecView(PaletteRedirect redirector,
                                                       IPaletteMetric viewPaletteMetric,
                                                       PaletteMetricPadding viewMetricPadding,
                                                       ButtonSpec buttonSpec) =>
 /// <summary>
 /// Initialize a new instance of the ButtonSpecRemapByContentView class.
 /// </summary>
 /// <param name="target">Initial palette target for redirection.</param>
 /// <param name="buttonSpec">Reference to button specification.</param>
 public ButtonSpecRemapByContentView(IPalette target,
                                     ButtonSpec buttonSpec)
     : base(target, buttonSpec)
 {
 }
 /// <summary>
 /// Perform final steps now that the button spec has been created.
 /// </summary>
 /// <param name="buttonSpec">ButtonSpec instance.</param>
 /// <param name="buttonView">Associated ButtonSpecView instance.</param>
 /// <param name="viewDockerIndex">Index of view docker button is placed onto.</param>
 protected override void ButtonSpecCreated(ButtonSpec buttonSpec,
                                           ButtonSpecView buttonView,
                                           int viewDockerIndex)
 {
     // Nothing extra to do
 }
 /// <summary>
 /// Create a palette redirector for remapping button spec colors.
 /// </summary>
 /// <param name="redirector">Base palette class.</param>
 /// <param name="buttonSpec">ButtonSpec instance.</param>
 /// <returns>Palette redirector for the button spec instance.</returns>
 public override PaletteRedirect CreateButtonSpecRemap(PaletteRedirect redirector,
                                                       ButtonSpec buttonSpec)
 {
     return(new ButtonSpecNavRemap(redirector, buttonSpec, RemapTarget));
 }
 /// <summary>
 /// Create the button spec view appropriate for the button spec.
 /// </summary>
 /// <param name="redirector">Redirector for acquiring palette values.</param>
 /// <param name="viewPaletteMetric">Target metric providers.</param>
 /// <param name="viewMetricPadding">Target metric padding.</param>
 /// <param name="buttonSpec">ButtonSpec instance.</param>
 /// <returns>ButtonSpecView derived class.</returns>
 protected override ButtonSpecView CreateButtonSpecView(PaletteRedirect redirector,
                                                        IPaletteMetric viewPaletteMetric,
                                                        PaletteMetricPadding viewMetricPadding,
                                                        ButtonSpec buttonSpec) =>
 new ButtonSpecViewRibbon(redirector, viewPaletteMetric,
                          viewMetricPadding, this, buttonSpec);
        /// <summary>
        /// Key has been pressed down.
        /// </summary>
        /// <param name="c">Reference to the source control instance.</param>
        /// <param name="e">A KeyEventArgs that contains the event data.</param>
        public override void KeyDown(Control c, KeyEventArgs e)
        {
            ViewBase      newView = null;
            KryptonRibbon ribbon  = (KryptonRibbon)c;

            // Get the button spec associated with this controller
            ViewDrawButton viewButton = (ViewDrawButton)Target;
            ButtonSpec     buttonSpec = ribbon.TabsArea.ButtonSpecManager.GetButtonSpecFromView(viewButton);

            // Note if we are on the near edge
            bool isNear = (buttonSpec.Edge == PaletteRelativeEdgeAlign.Near);

            switch (e.KeyData)
            {
            case Keys.Tab:
            case Keys.Right:
                // Logic depends on the edge this button is on
                if (isNear)
                {
                    // Try getting the previous near edge button (previous on near gets the next right hand side!)
                    newView = ribbon.TabsArea.ButtonSpecManager.GetPreviousVisibleViewButton(PaletteRelativeEdgeAlign.Near, viewButton);

                    if (newView == null)
                    {
                        if ((e.KeyData == Keys.Tab) && (ribbon.SelectedTab != null))
                        {
                            // Get the currently selected tab page
                            newView = ribbon.TabsArea.LayoutTabs.GetViewForRibbonTab(ribbon.SelectedTab);
                        }
                        else
                        {
                            // Get the first visible tab page
                            newView = ribbon.TabsArea.LayoutTabs.GetViewForFirstRibbonTab();
                        }
                    }

                    // Get the first far edge button
                    if (newView == null)
                    {
                        newView = ribbon.TabsArea.ButtonSpecManager.GetFirstVisibleViewButton(PaletteRelativeEdgeAlign.Far);
                    }

                    // Get the first inherit edge button
                    if (newView == null)
                    {
                        newView = ribbon.TabsArea.ButtonSpecManager.GetFirstVisibleViewButton(PaletteRelativeEdgeAlign.Inherit);
                    }

                    // Rotate around to application button
                    if (newView == null)
                    {
                        if (ribbon.TabsArea.LayoutAppButton.Visible)
                        {
                            newView = ribbon.TabsArea.LayoutAppButton.AppButton;
                        }
                        else if (ribbon.TabsArea.LayoutAppTab.Visible)
                        {
                            newView = ribbon.TabsArea.LayoutAppTab.AppTab;
                        }
                    }
                }
                else
                {
                    // Try using the next far edge button
                    newView = ribbon.TabsArea.ButtonSpecManager.GetNextVisibleViewButton(PaletteRelativeEdgeAlign.Far, viewButton);

                    // Try using the next inherit edge button
                    if (newView == null)
                    {
                        newView = ribbon.TabsArea.ButtonSpecManager.GetNextVisibleViewButton(PaletteRelativeEdgeAlign.Inherit, viewButton);
                    }

                    // Rotate around to application button
                    if (newView == null)
                    {
                        if (ribbon.TabsArea.LayoutAppButton.Visible)
                        {
                            newView = ribbon.TabsArea.LayoutAppButton.AppButton;
                        }
                        else if (ribbon.TabsArea.LayoutAppTab.Visible)
                        {
                            newView = ribbon.TabsArea.LayoutAppTab.AppTab;
                        }
                    }
                }
                break;

            case Keys.Tab | Keys.Shift:
            case Keys.Left:
                // Logic depends on the edge this button is on
                if (isNear)
                {
                    // Try using the previous near edge button (next for a near edge is the left hand side!)
                    newView = ribbon.TabsArea.ButtonSpecManager.GetNextVisibleViewButton(PaletteRelativeEdgeAlign.Near, viewButton);

                    // Get the last qat button
                    if (newView == null)
                    {
                        newView = ribbon.GetLastQATView();
                    }

                    // Rotate around to application button
                    if (newView == null)
                    {
                        if (ribbon.TabsArea.LayoutAppButton.Visible)
                        {
                            newView = ribbon.TabsArea.LayoutAppButton.AppButton;
                        }
                        else if (ribbon.TabsArea.LayoutAppTab.Visible)
                        {
                            newView = ribbon.TabsArea.LayoutAppTab.AppTab;
                        }
                    }
                }
                else
                {
                    // Try getting the previous far edge button
                    newView = ribbon.TabsArea.ButtonSpecManager.GetPreviousVisibleViewButton(PaletteRelativeEdgeAlign.Far, viewButton);

                    // Try getting the previous inherit edge button
                    if (newView == null)
                    {
                        newView = ribbon.TabsArea.ButtonSpecManager.GetPreviousVisibleViewButton(PaletteRelativeEdgeAlign.Inherit, viewButton);
                    }

                    if (newView == null)
                    {
                        if (e.KeyData != Keys.Left)
                        {
                            // Get the last control on the selected tab
                            newView = ribbon.GroupsArea.ViewGroups.GetLastFocusItem();

                            // Get the currently selected tab page
                            if (newView == null)
                            {
                                if (ribbon.SelectedTab != null)
                                {
                                    newView = ribbon.TabsArea.LayoutTabs.GetViewForRibbonTab(ribbon.SelectedTab);
                                }
                                else
                                {
                                    newView = ribbon.TabsArea.LayoutTabs.GetViewForLastRibbonTab();
                                }
                            }
                        }
                        else
                        {
                            // Get the last visible tab page
                            newView = ribbon.TabsArea.LayoutTabs.GetViewForLastRibbonTab();
                        }
                    }

                    // Get the last near edge button
                    if (newView == null)
                    {
                        newView = ribbon.TabsArea.ButtonSpecManager.GetFirstVisibleViewButton(PaletteRelativeEdgeAlign.Near);
                    }

                    // Get the last qat button
                    if (newView == null)
                    {
                        newView = ribbon.GetLastQATView();
                    }

                    // Rotate around to application button
                    if (newView == null)
                    {
                        if (ribbon.TabsArea.LayoutAppButton.Visible)
                        {
                            newView = ribbon.TabsArea.LayoutAppButton.AppButton;
                        }
                        else if (ribbon.TabsArea.LayoutAppTab.Visible)
                        {
                            newView = ribbon.TabsArea.LayoutAppTab.AppTab;
                        }
                    }
                }
                break;

            case Keys.Space:
            case Keys.Enter:
                // Exit keyboard mode when you click the button spec
                ribbon.KillKeyboardMode();

                // Generate a click event
                OnClick(new MouseEventArgs(MouseButtons.Left, 1, 0, 0, 0));
                break;
            }

            // If we have a new view to focus and it is not ourself...
            if ((newView != null) && (newView != Target))
            {
                // If the new view is a tab then select that tab unless in minimized mode
                if (!ribbon.RealMinimizedMode && (newView is ViewDrawRibbonTab tab))
                {
                    ribbon.SelectedTab = tab.RibbonTab;
                }

                // Finally we switch focus to new view
                ribbon.FocusView = newView;
            }
        }