/// <summary> /// Initialize a new instance of the ViewLayoutRibbonScrollPort class. /// </summary> /// <param name="ribbon">Reference to owning ribbon control.</param> /// <param name="orientation">Viewport orientation.</param> /// <param name="viewFiller">View to size and position.</param> /// <param name="insetForTabs">Should scoller be inset for use in tabs area.</param> /// <param name="scrollSpeed">Scrolling speed.</param> /// <param name="needPaintDelegate">Delegate for notifying paint/layout requests.</param> public ViewLayoutRibbonScrollPort(KryptonRibbon ribbon, Orientation orientation, ViewBase viewFiller, bool insetForTabs, int scrollSpeed, NeedPaintHandler needPaintDelegate) { Debug.Assert(ribbon != null); Debug.Assert(viewFiller != null); Debug.Assert(needPaintDelegate != null); // Remember initial settings _ribbon = ribbon; _orientation = orientation; _viewFiller = viewFiller; _needPaintDelegate = needPaintDelegate; _scrollSpeed = scrollSpeed; _ribbonTabs = viewFiller as ViewLayoutRibbonTabs; // Default to left hand scroll position _scrollOffset = 0; // Place the child view inside a actual control, so that the contents of the // filler are clipped to the control size. This is needed if the child view // contains controls and need clipping inside this area and so prevent them // from drawing over the end scrollers. _viewControlContent = new RibbonViewControl(ribbon); _viewControlContent.PaintBackground += new PaintEventHandler(OnViewControlPaintBackground); _viewControl = new ViewLayoutControl(_viewControlContent, ribbon, _viewFiller); // For ribbon tabs we want to monitor and intercept the WM_NCHITTEST so that the remainder of the // tabs area acts like the application title bar and can be used to manipulate the application if (_ribbonTabs != null) { _viewControl.ChildControl.WndProcHitTest += new EventHandler <ViewControlHitTestArgs>(OnChildWndProcHitTest); } // Create the two scrollers used when not enough space for filler _nearScroller = new ViewLayoutRibbonScroller(ribbon, NearOrientation, insetForTabs, needPaintDelegate); _farScroller = new ViewLayoutRibbonScroller(ribbon, FarOrientation, insetForTabs, needPaintDelegate); // Hook into scroller events _nearScroller.Click += new EventHandler(OnNearClick); _farScroller.Click += new EventHandler(OnFarClick); // Add elements in correct order Add(_viewControl); Add(_nearScroller); Add(_farScroller); }
/// <summary> /// Initialize a new instance of the ViewDrawRibbonTab class. /// </summary> /// <param name="ribbon">Reference to owning ribbon control.</param> /// <param name="layoutTabs">Reference to view used for layout out tabs.</param> /// <param name="needPaint">Delegate for notifying paint requests.</param> public ViewDrawRibbonTab(KryptonRibbon ribbon, ViewLayoutRibbonTabs layoutTabs, NeedPaintHandler needPaint) { Debug.Assert(ribbon != null); Debug.Assert(layoutTabs != null); Debug.Assert(needPaint != null); // Cache incoming values _ribbon = ribbon; _layoutTabs = layoutTabs; _needPaint = needPaint; // Create overrides for handling a focus state _paletteGeneral = ribbon.StateCommon.RibbonGeneral; _overrideStateNormal = new PaletteRibbonDoubleInheritOverride(_ribbon.OverrideFocus.RibbonTab, _ribbon.OverrideFocus.RibbonTab, _ribbon.StateNormal.RibbonTab, _ribbon.StateNormal.RibbonTab, PaletteState.FocusOverride); _overrideStateTracking = new PaletteRibbonDoubleInheritOverride(_ribbon.OverrideFocus.RibbonTab, _ribbon.OverrideFocus.RibbonTab, _ribbon.StateTracking.RibbonTab, _ribbon.StateTracking.RibbonTab, PaletteState.FocusOverride); _overrideStateCheckedNormal = new PaletteRibbonDoubleInheritOverride(_ribbon.OverrideFocus.RibbonTab, _ribbon.OverrideFocus.RibbonTab, _ribbon.StateCheckedNormal.RibbonTab, _ribbon.StateCheckedNormal.RibbonTab, PaletteState.FocusOverride); _overrideStateCheckedTracking = new PaletteRibbonDoubleInheritOverride(_ribbon.OverrideFocus.RibbonTab, _ribbon.OverrideFocus.RibbonTab, _ribbon.StateCheckedTracking.RibbonTab, _ribbon.StateCheckedTracking.RibbonTab, PaletteState.FocusOverride); _overrideStateContextTracking = new PaletteRibbonDoubleInheritOverride(_ribbon.OverrideFocus.RibbonTab, _ribbon.OverrideFocus.RibbonTab, _ribbon.StateContextTracking.RibbonTab, _ribbon.StateContextTracking.RibbonTab, PaletteState.FocusOverride); _overrideStateContextCheckedNormal = new PaletteRibbonDoubleInheritOverride(_ribbon.OverrideFocus.RibbonTab, _ribbon.OverrideFocus.RibbonTab, _ribbon.StateContextCheckedNormal.RibbonTab, _ribbon.StateContextCheckedNormal.RibbonTab, PaletteState.FocusOverride); _overrideStateContextCheckedTracking = new PaletteRibbonDoubleInheritOverride(_ribbon.OverrideFocus.RibbonTab, _ribbon.OverrideFocus.RibbonTab, _ribbon.StateContextCheckedTracking.RibbonTab, _ribbon.StateContextCheckedTracking.RibbonTab, PaletteState.FocusOverride); _overrideCurrent = _overrideStateNormal; // Create and default the setup of the context colors provider _paletteContextCurrent = new PaletteRibbonContextDouble(_ribbon); _paletteContextCurrent.SetInherit(_overrideCurrent); // Use a class to convert from ribbon tab to content interface _contentProvider = new RibbonTabToContent(_paletteGeneral, _paletteContextCurrent); // Use a controller to change state because of mouse movement RibbonTabController controller = new RibbonTabController(_ribbon, this, _needPaint); controller.Click += new MouseEventHandler(OnTabClicked); controller.ContextClick += new MouseEventHandler(OnTabContextClicked); MouseController = controller; SourceController = controller; KeyController = controller; // Associate this view with the source component (required for design time selection) Component = _ribbonTab; // Create and add the draw content for display inside the tab Add(new ViewDrawContent(_contentProvider, this, VisualOrientation.Top)); // Create the state specific memento array _mementos = new IDisposable[Enum.GetValues(typeof(PaletteState)).Length]; }
/// <summary> /// Perform a layout of the elements. /// </summary> /// <param name="context">Layout context.</param> public override void Layout(ViewLayoutContext context) { Debug.Assert(context != null); // Out enabled state is the same as that of the ribbon itself Enabled = _ribbon.Enabled; // We take on all the available display area ClientRectangle = context.DisplayRectangle; Rectangle layoutRect = ClientRectangle; Rectangle controlRect = new Rectangle(Point.Empty, ClientSize); // Reset the the view control layout offset to be zero again _viewControl.LayoutOffset = Point.Empty; // Ask the view control the size it would like to be, this is the requested filler // size of the control. If it wants more than we can give then scroll buttons are // needed, otherwise we can give it the requested size and any extra available. _ribbon.GetViewManager().DoNotLayoutControls = true; _viewControl.GetPreferredSize(context); // Ensure context has the correct control if ((_viewControl.ChildControl != null) && !_viewControl.ChildControl.IsDisposed) { using (CorrectContextControl ccc = new CorrectContextControl(context, _viewControl.ChildControl)) _viewFiller.Layout(context); } _ribbon.GetViewManager().DoNotLayoutControls = false; Size fillerSize = _viewFiller.ClientSize; // Limit check the scroll offset _scrollOffset = Math.Max(_scrollOffset, 0); // Did it fit fully into our space? if (((Orientation == Orientation.Horizontal) && (fillerSize.Width <= ClientWidth)) || ((Orientation == Orientation.Vertical) && (fillerSize.Height <= ClientHeight))) { // Filler rectangle is used for clipping _viewClipRect = controlRect; // Default back to left hand scroll position _scrollOffset = 0; // Then make the scrollers invisible and nothing more to do _nearScroller.Visible = false; _farScroller.Visible = false; // We need to layout again but this time we do layout the actual children _viewControl.Layout(context); } else { // We only need the near scroller if we are not at the left scroll position if (_scrollOffset > 0) { _nearScroller.Visible = true; // Find size requirements of the near scroller Size nearSize = _nearScroller.GetPreferredSize(context); // Find layout position of the near scroller if (Orientation == Orientation.Horizontal) { context.DisplayRectangle = new Rectangle(layoutRect.X, layoutRect.Y, nearSize.Width, layoutRect.Height); layoutRect.Width -= nearSize.Width; layoutRect.X += nearSize.Width; controlRect.Width -= nearSize.Width; controlRect.X += nearSize.Width; } else { context.DisplayRectangle = new Rectangle(layoutRect.X, layoutRect.Y, layoutRect.Width, nearSize.Height); layoutRect.Height -= nearSize.Height; layoutRect.Y += nearSize.Height; controlRect.Height -= nearSize.Height; controlRect.Y += nearSize.Height; } _nearScroller.Layout(context); } else { _nearScroller.Visible = false; } int maxOffset = 0; // Work out the maximum scroll offset needed to show all of the filler if (Orientation == Orientation.Horizontal) { maxOffset = fillerSize.Width - layoutRect.Width; } else { maxOffset = fillerSize.Height - layoutRect.Height; } // We only need the far scroller if we are not at the right scroll position if (_scrollOffset < maxOffset) { _farScroller.Visible = true; // Find size requirements of the near scroller Size farSize = _nearScroller.GetPreferredSize(context); // Find layout position of the far scroller if (Orientation == Orientation.Horizontal) { context.DisplayRectangle = new Rectangle(layoutRect.Right - farSize.Width, layoutRect.Y, farSize.Width, layoutRect.Height); layoutRect.Width -= farSize.Width; controlRect.Width -= farSize.Width; } else { context.DisplayRectangle = new Rectangle(layoutRect.X, layoutRect.Bottom - farSize.Height, layoutRect.Width, farSize.Height); layoutRect.Height -= farSize.Height; controlRect.Height -= farSize.Height; } _farScroller.Layout(context); } else { _farScroller.Visible = false; } // Calculate the maximum offset again with all scrollers positioned if (Orientation == Orientation.Horizontal) { maxOffset = fillerSize.Width - layoutRect.Width; } else { maxOffset = fillerSize.Height - layoutRect.Height; } // Limit check the current offset _scrollOffset = Math.Min(_scrollOffset, maxOffset); // Filler rectangle is used for clipping _viewClipRect = controlRect; // Apply the offset to the display of the view filler if (Orientation == Orientation.Horizontal) { _viewControl.LayoutOffset = new Point(-_scrollOffset, 0); } else { _viewControl.LayoutOffset = new Point(0, -_scrollOffset); } // Position the filler in the remaining space context.DisplayRectangle = layoutRect; _viewControl.GetPreferredSize(context); _viewControl.Layout(context); } // Put back the original display value now we have finished context.DisplayRectangle = ClientRectangle; // If we are the scroller for the tab headers if (_ribbon.InKeyboardMode && (_viewFiller is ViewLayoutRibbonTabs)) { // Cast to correct type ViewLayoutRibbonTabs layoutTabs = (ViewLayoutRibbonTabs)_viewFiller; // If we have a selected tab, then ensure it is visible if (_ribbon.SelectedTab != null) { // Cast to correct type ViewBase viewTab = layoutTabs.GetViewForRibbonTab(_ribbon.SelectedTab); // If a scroll change is required to bring it into view if (ScrollIntoView(viewTab.ClientRectangle, false)) { // Call ourself again to take change into account Layout(context); } } } }
private void CreateViewElements(PaletteRedirect redirect) { // Layout for individual tabs inside the header _layoutRibbonTabs = new ViewLayoutRibbonTabs(_ribbon, NeedPaintDelegate); // Put inside a viewport so scrollers are used when tabs cannot be shrunk to fill space _tabsViewport = new ViewLayoutRibbonScrollPort(_ribbon, System.Windows.Forms.Orientation.Horizontal, _layoutRibbonTabs, true, SCROLL_SPEED, NeedPaintDelegate); _tabsViewport.TransparentBackground = true; _tabsViewport.PaintBackground += new PaintEventHandler(OnTabsPaintBackground); _layoutRibbonTabs.ParentControl = _tabsViewport.ViewLayoutControl.ChildControl; _layoutRibbonTabs.NeedPaintDelegate = _tabsViewport.ViewControlPaintDelegate; // We use a layout docker as a child to prevent buttons going to the left of the app button ViewLayoutDocker tabsDocker = new ViewLayoutDocker(); // Place the tabs viewport as the fill inside ourself, the button specs will be placed // to the left and right of this fill element automatically by the button manager below tabsDocker.Add(_tabsViewport, ViewDockStyle.Fill); // We need to draw the bottom half of the application button or a full app tab _layoutAppButton = new ViewLayoutRibbonAppButton(_ribbon, true); _layoutAppTab = new ViewLayoutRibbonAppTab(_ribbon); // Connect up the application button controller to the app button element _appButtonController.Target3 = _layoutAppButton.AppButton; _appButtonController.Click += new EventHandler(OnAppButtonClicked); _appButtonController.MouseReleased += new EventHandler(OnAppButtonReleased); _layoutAppButton.MouseController = _appButtonController; _layoutAppButton.SourceController = _appButtonController; _layoutAppButton.KeyController = _appButtonController; _appTabController.Target1 = _layoutAppTab.AppTab; _appTabController.Click += new EventHandler(OnAppButtonClicked); _appTabController.MouseReleased += new EventHandler(OnAppButtonReleased); _layoutAppTab.MouseController = _appTabController; _layoutAppTab.SourceController = _appTabController; _layoutAppTab.KeyController = _appTabController; // When the app button is not visible we need separator instead before start of first tab _layoutAppButtonSep = new ViewLayoutSeparator(5, 0); _layoutAppButtonSep.Visible = false; // Used separators around the tabs and the edge elements _rightSeparator = new ViewLayoutRibbonSeparator(FAR_TAB_GAP, true); _leftSeparator = new ViewLayoutRibbonSeparator(BUTTON_TAB_GAP_2007, true); // Place application button on left and tabs as the filler (with some separators for neatness) Add(_rightSeparator, ViewDockStyle.Left); Add(_leftSeparator, ViewDockStyle.Left); Add(_layoutAppButton, ViewDockStyle.Left); Add(_layoutAppButtonSep, ViewDockStyle.Left); Add(_layoutAppTab, ViewDockStyle.Left); Add(tabsDocker, ViewDockStyle.Fill); // Create button specification collection manager PaletteRedirect aeroOverrideText = new PaletteRedirectRibbonAeroOverride(_ribbon, redirect); _buttonManager = new ButtonSpecManagerLayoutRibbon(_ribbon, aeroOverrideText, _ribbon.ButtonSpecs, _buttonSpecsFixed, new ViewLayoutDocker[] { tabsDocker }, new IPaletteMetric[] { _ribbon.StateCommon }, new PaletteMetricInt[] { PaletteMetricInt.HeaderButtonEdgeInsetPrimary }, new PaletteMetricPadding[] { PaletteMetricPadding.RibbonButtonPadding }, new GetToolStripRenderer(_ribbon.CreateToolStripRenderer), NeedPaintDelegate); // Create the manager for handling tooltips _toolTipManager = new ToolTipManager(); _toolTipManager.ShowToolTip += new EventHandler <ToolTipEventArgs>(OnShowToolTip); _toolTipManager.CancelToolTip += new EventHandler(OnCancelToolTip); _buttonManager.ToolTipManager = _toolTipManager; }