/// <summary> /// Initialize a new instance of the ViewLayoutCenter class. /// </summary> /// <param name="childElement">Optional element to add as child.</param> public ViewLayoutCenter(ViewBase childElement) : this(null, PaletteMetricPadding.None, VisualOrientation.Top, childElement) { }
/// <summary> /// Initialize a new instance of the ViewLayoutPadding class. /// </summary> /// <param name="displayPadding">Padding to use around area.</param> /// <param name="child">Child to add into view hierarchy.</param> public ViewLayoutPadding(Padding displayPadding, ViewBase child) { _displayPadding = displayPadding; Add(child); }
/// <summary> /// Removes first occurance of specified view. /// </summary> /// <param name="item">ViewBase reference.</param> /// <returns>True if removed; otherwise false.</returns> public override bool Remove(ViewBase item) { // Can never remove with success return(false); }
/// <summary> /// Inserts a view to the collection at the specified index. /// </summary> /// <param name="index">Insert index.</param> /// <param name="item">ViewBase reference.</param> public override void Insert(int index, ViewBase item) { // Can never insert a view to a leaf view throw new NotSupportedException("Cannot insert to a leaf view."); }
/// <summary> /// Use the setting from the Positioning to display the tooltip /// </summary> /// <param name="target"></param> /// <param name="controlMousePosition"></param> public void ShowRelativeTo(ViewBase target, Point controlMousePosition) { PopupPositionValues position; if (_contentValues is ToolTipValues toolTipValues) { position = toolTipValues.ToolTipPosition; } else { position = new PopupPositionValues(); } Point currentCursorHotSpot = CommonHelper.CaptureCursor(); Rectangle positionPlacementRectangle = position.PlacementRectangle; switch (position.PlacementMode) { case PlacementMode.Absolute: case PlacementMode.AbsolutePoint: // The screen, or PlacementRectangle if it is set. // So do nothing ! break; case PlacementMode.Mouse: case PlacementMode.MousePoint: // The bounds of the mouse pointer. PlacementRectangle is ignored positionPlacementRectangle = new Rectangle(controlMousePosition.X, controlMousePosition.Y, currentCursorHotSpot.X + 2, currentCursorHotSpot.Y + 2); break; default: // The screen, or PlacementRectangle if it is set. The PlacementRectangle is relative to the screen. if (positionPlacementRectangle.IsEmpty) { // PlacementTarget or parent. positionPlacementRectangle = position.PlacementTarget?.ClientRectangle ?? target.ClientRectangle; positionPlacementRectangle = (position.PlacementTarget?.OwningControl ?? target.OwningControl).RectangleToScreen(positionPlacementRectangle); } else { positionPlacementRectangle = Screen.GetWorkingArea(controlMousePosition); } break; } // Get the size the popup would like to be Size popupSize = ViewManager.GetPreferredSize(Renderer, Size.Empty); Point popupLocation; switch (position.PlacementMode) { case PlacementMode.Absolute: case PlacementMode.AbsolutePoint: case PlacementMode.MousePoint: case PlacementMode.Relative: case PlacementMode.RelativePoint: // The top-left corner of the target area. The top-left corner of the Popup. popupLocation = positionPlacementRectangle.Location; if (positionPlacementRectangle.IntersectsWith(new Rectangle(controlMousePosition, (Size)currentCursorHotSpot))) { // TODO: SKC: Should really get the HotSpot from the Icon and use that ! popupLocation.X = controlMousePosition.X + 4; // Still might "Bounce back" due to offscreen location } break; case PlacementMode.Bottom: case PlacementMode.Mouse: // The bottom-left corner of the target area. The top-left corner of the Popup. popupLocation = new Point(positionPlacementRectangle.Left, positionPlacementRectangle.Bottom); break; case PlacementMode.Center: // The center of the target area. The center of the Popup. popupLocation = positionPlacementRectangle.Location; popupLocation.Offset(popupSize.Width / 2, -popupSize.Height / 2); if (positionPlacementRectangle.IntersectsWith(new Rectangle(controlMousePosition, (Size)currentCursorHotSpot))) { // TODO: SKC: Should really get the HotSpot from the Icon and use that ! popupLocation.X = controlMousePosition.X + 4; // Still might "Bounce back" due to offscreen location } break; case PlacementMode.Left: // The top-left corner of the target area. The top-right corner of the Popup. popupLocation = new Point(positionPlacementRectangle.Left - popupSize.Width, positionPlacementRectangle.Top); break; case PlacementMode.Right: // The top-right corner of the target area. The top-left corner of the Popup. popupLocation = new Point(positionPlacementRectangle.Right, positionPlacementRectangle.Top); break; case PlacementMode.Top: // The top-left corner of the target area. The bottom-left corner of the Popup. popupLocation = new Point(positionPlacementRectangle.Left, positionPlacementRectangle.Top - popupSize.Height); break; default: throw new ArgumentOutOfRangeException(); } // Show it now! Show(popupLocation, popupSize); }
/// <summary> /// Determines whether the collection contains the view. /// </summary> /// <param name="item">ViewBase reference.</param> /// <returns>True if view found; otherwise false.</returns> public override bool Contains(ViewBase item) { // Leaf never contains view return(false); }
/// <summary> /// Removes first occurance of specified view. /// </summary> /// <param name="item">ViewBase reference.</param> /// <returns>True if removed; otherwise false.</returns> public override bool Remove(ViewBase item) { return(_child.Remove(item)); }
/// <summary> /// Mouse has left the view. /// </summary> /// <param name="c">Reference to the source control instance.</param> /// <param name="next">Reference to view that is next to have the mouse.</param> public void MouseLeave(Control c, ViewBase next) { _manager.MouseLeave(_targetElement, c, next); _targetController?.MouseLeave(c, next); }
/// <summary> /// Append a view to the collection. /// </summary> /// <param name="item">ViewBase reference.</param> public override void Add(ViewBase item) { _child.Add(item); }
/// <summary> /// Determines whether any part of the view hierarchy is the specified view. /// </summary> /// <param name="item">ViewBase reference.</param> /// <returns>True if view found; otherwise false.</returns> public override bool ContainsRecurse(ViewBase item) { return(_child.ContainsRecurse(item)); }
/// <summary> /// Left mouse button double click. /// </summary> /// <param name="targetElement">Target element for the mouse message.</param> /// <param name="pt">Mouse position relative to control.</param> public void DoubleClick(ViewBase targetElement, Point pt) { }
/// <summary> /// Mouse button has been released in the view. /// </summary> /// <param name="targetElement">Target element for the mouse message.</param> /// <param name="c">Reference to the source control instance.</param> /// <param name="pt">Mouse position relative to control.</param> /// <param name="button">Mouse button released.</param> public void MouseUp(ViewBase targetElement, Control c, Point pt, MouseButtons button) { }
/// <summary> /// Mouse has moved inside the view. /// </summary> /// <param name="targetElement">Target element for the mouse message.</param> /// <param name="c">Reference to the source control instance.</param> /// <param name="pt">Mouse position relative to control.</param> public void MouseMove(ViewBase targetElement, Control c, Point pt) { }
/// <summary> /// Initialize a new instance of the ViewBase class. /// </summary> public ViewDecoratorFixedSize(ViewBase child, Size fixedSize) : base(child) { FixedSize = fixedSize; }
/// <summary> /// Determines the index of the specified view in the collection. /// </summary> /// <param name="item">ViewBase reference.</param> /// <returns>-1 if not found; otherwise index position.</returns> public override int IndexOf(ViewBase item) { return(_child.IndexOf(item)); }
/// <summary> /// Initialize a new instance of the ViewLayoutControl class. /// </summary> /// <param name="rootControl">Top level visual control.</param> /// <param name="viewChild">View used to size and position the child control.</param> public ViewLayoutControl(VisualControl rootControl, ViewBase viewChild) : this(new ViewControl(rootControl), rootControl, viewChild) { }
/// <summary> /// Inserts a view to the collection at the specified index. /// </summary> /// <param name="index">Insert index.</param> /// <param name="item">ViewBase reference.</param> public override void Insert(int index, ViewBase item) { _child.Insert(index, item); }
/// <summary> /// Discovers if the provided view is part of the button. /// </summary> /// <param name="next">View to investigate.</param> /// <returns>True is part of button; otherwise false.</returns> protected virtual bool ViewIsPartOfButton(ViewBase next) { return(_target.ContainsRecurse(next)); }
/// <summary> /// Initialize a new instance of the ViewBase class. /// </summary> protected ViewDecorator(ViewBase child) { Debug.Assert(child != null); _child = child; _child.Parent = this; }
/// <summary> /// Mouse has left the view. /// </summary> /// <param name="c">Reference to the source control instance.</param> /// <param name="next">Reference to view that is next to have the mouse.</param> public virtual void MouseLeave(Control c, ViewBase next) { _mouseOver = false; _lastMovePt = Point.Empty; UpdateTargetState(); }
/// <summary> /// Gets the index of the provided docker. /// </summary> /// <param name="viewDocker">View docker reference.</param> /// <returns>Index of docker; otherwise -1.</returns> protected abstract int DockerIndex(ViewBase viewDocker);
/// <summary> /// Determines whether any part of the view hierarchy is the specified view. /// </summary> /// <param name="item">ViewBase reference.</param> /// <returns>True if view found; otherwise false.</returns> public override bool ContainsRecurse(ViewBase item) { // Only need to check against ourself return(this == item); }
/// <summary> /// Add a view element to a docker. /// </summary> /// <param name="i">Index of view docker.</param> /// <param name="dockStyle">Dock style for placement.</param> /// <param name="view">Actual view to add.</param> /// <param name="usingSpacers">Are view spacers being used.</param> protected abstract void AddViewToDocker(int i, ViewDockStyle dockStyle, ViewBase view, bool usingSpacers);
/// <summary> /// Determines the index of the specified view in the collection. /// </summary> /// <param name="item">ViewBase reference.</param> /// <returns>-1 if not found; otherwise index position.</returns> public override int IndexOf(ViewBase item) { // Can never find the item return(-1); }
/// <summary> /// Perform a layout of the elements. /// </summary> /// <param name="context">Layout context.</param> public override void Layout(ViewLayoutContext context) { Debug.Assert(context != null); // We take on all the available display area ClientRectangle = context.DisplayRectangle; // Maximum space available for the next child Rectangle childRectangle = ClientRectangle; // Find the last visible child ViewBase lastVisible = null; foreach (ViewBase child in Reverse()) { if (child.Visible) { lastVisible = child; break; } } // Position each entry, with last entry filling remaining of space foreach (ViewBase child in this) { if (child.Visible) { // Provide the total space currently available context.DisplayRectangle = childRectangle; // Get the preferred size of the child Size childSize = child.GetPreferredSize(context); if (Horizontal) { // Ask child to fill the available height childSize.Height = childRectangle.Height; if ((child == lastVisible) && FillLastChild) { // This child takes all remainder width childSize.Width = childRectangle.Width; } else { // Reduce remainder space to exclude this child childRectangle.X += childSize.Width; childRectangle.Width -= childSize.Width; } } else { // Ask child to fill the available width childSize.Width = childRectangle.Width; if ((child == lastVisible) && FillLastChild) { // This child takes all remainder height childSize.Height = childRectangle.Height; } else { // Reduce remainder space to exclude this child childRectangle.Y += childSize.Height; childRectangle.Height -= childSize.Height; } } // Use the update child size as the actual space for layout context.DisplayRectangle = new Rectangle(context.DisplayRectangle.Location, childSize); // Layout child in the provided space child.Layout(context); } } // Put back the original display value now we have finished context.DisplayRectangle = ClientRectangle; }
/// <summary> /// Append a view to the collection. /// </summary> /// <param name="item">ViewBase reference.</param> public override void Add(ViewBase item) { // Can never add a view to a leaf view throw new NotSupportedException("Cannot add to a leaf view."); }
/// <summary> /// Initialize a new instance of the ViewLayoutScrollViewport class. /// </summary> /// <param name="rootControl">Top level visual control.</param> /// <param name="viewportFiller">View element to place inside viewport.</param> /// <param name="paletteBorderEdge">Palette for use with the border edge.</param> /// <param name="paletteMetrics">Palette source for metrics.</param> /// <param name="metricPadding">Metric used to get view padding.</param> /// <param name="metricOvers">Metric used to get overposition.</param> /// <param name="orientation">Orientation for the viewport children.</param> /// <param name="alignment">Alignment of the children within the viewport.</param> /// <param name="animateChange">Animate changes in the viewport.</param> /// <param name="vertical">Is the viewport vertical.</param> /// <param name="needPaintDelegate">Delegate for notifying paint requests.</param> public ViewLayoutScrollViewport(VisualControl rootControl, ViewBase viewportFiller, PaletteBorderEdge paletteBorderEdge, IPaletteMetric paletteMetrics, PaletteMetricPadding metricPadding, PaletteMetricInt metricOvers, VisualOrientation orientation, RelativePositionAlign alignment, bool animateChange, bool vertical, NeedPaintHandler needPaintDelegate) { Debug.Assert(rootControl != null); Debug.Assert(viewportFiller != null); Debug.Assert(needPaintDelegate != null); // We need a way to notify changes in layout _needPaintDelegate = needPaintDelegate; // By default we are showing the contained viewport in vertical scrolling _viewportVertical = vertical; // Our initial visual orientation should match the parameter Orientation = orientation; // Create the child viewport Viewport = new ViewLayoutViewport(paletteMetrics, metricPadding, metricOvers, ViewportOrientation(_viewportVertical), alignment, animateChange) { // Default to same alignment for both directions CounterAlignment = alignment, // We always want the viewport to fill any remainder space FillSpace = true }; // Put the provided element inside the viewport Viewport.Add(viewportFiller); // Hook into animation step events Viewport.AnimateStep += OnAnimateStep; // To prevent the contents of the viewport from being able to draw outside // the viewport (such as having child controls) we use a ViewLayoutControl // that uses a child control to restrict the drawing region. ViewControl = new ViewLayoutControl(rootControl, Viewport) { InDesignMode = rootControl.InDesignMode }; // Create the scrollbar and matching border edge ScrollbarV = new ViewDrawScrollBar(true); ScrollbarH = new ViewDrawScrollBar(false); BorderEdgeV = new ViewDrawBorderEdge(paletteBorderEdge, System.Windows.Forms.Orientation.Vertical); BorderEdgeH = new ViewDrawBorderEdge(paletteBorderEdge, System.Windows.Forms.Orientation.Horizontal); // Hook into scroll position changes ScrollbarV.ScrollChanged += OnScrollVChanged; ScrollbarH.ScrollChanged += OnScrollHChanged; // Add with appropriate docking style Add(ViewControl, ViewDockStyle.Fill); Add(BorderEdgeV, ViewDockStyle.Right); Add(BorderEdgeH, ViewDockStyle.Bottom); Add(ScrollbarV, ViewDockStyle.Right); Add(ScrollbarH, ViewDockStyle.Bottom); }
private void UpdateChildBorders(ViewBase child, ViewLayoutContext context, ref PaletteDrawBorders leftEdges, ref PaletteDrawBorders rightEdges, ref PaletteDrawBorders topEdges, ref PaletteDrawBorders bottomEdges, ref PaletteDrawBorders fillEdges) { // Do we need to calculate if the child should remove any borders? if (RemoveChildBorders) { // Check if the view is a canvas ViewDrawCanvas childCanvas = child as ViewDrawCanvas; // Docking edge determines calculation switch (CalculateDock(GetDock(child), context.Control)) { case ViewDockStyle.Top: if (childCanvas != null) { childCanvas.MaxBorderEdges = CommonHelper.ReverseOrientateDrawBorders(topEdges, childCanvas.Orientation); } // Remove top edges from subsequent children leftEdges &= PaletteDrawBorders.BottomLeftRight; rightEdges &= PaletteDrawBorders.BottomLeftRight; topEdges &= PaletteDrawBorders.BottomLeftRight; break; case ViewDockStyle.Bottom: if (childCanvas != null) { childCanvas.MaxBorderEdges = CommonHelper.ReverseOrientateDrawBorders(bottomEdges, childCanvas.Orientation); } // Remove bottom edges from subsequent children leftEdges &= PaletteDrawBorders.TopLeftRight; rightEdges &= PaletteDrawBorders.TopLeftRight; bottomEdges &= PaletteDrawBorders.TopLeftRight; break; case ViewDockStyle.Left: if (childCanvas != null) { childCanvas.MaxBorderEdges = CommonHelper.ReverseOrientateDrawBorders(leftEdges, childCanvas.Orientation); } // Remove left edges from subsequent children topEdges &= PaletteDrawBorders.TopBottomRight; bottomEdges &= PaletteDrawBorders.TopBottomRight; leftEdges &= PaletteDrawBorders.TopBottomRight; break; case ViewDockStyle.Right: if (childCanvas != null) { childCanvas.MaxBorderEdges = CommonHelper.ReverseOrientateDrawBorders(rightEdges, childCanvas.Orientation); } // Remove right edges from subsequent children topEdges &= PaletteDrawBorders.TopBottomLeft; bottomEdges &= PaletteDrawBorders.TopBottomLeft; rightEdges &= PaletteDrawBorders.TopBottomLeft; break; } } }
/// <summary> /// Perform a layout of the elements. /// </summary> /// <param name="context">Layout context.</param> public override void Layout(ViewLayoutContext context) { Debug.Assert(context != null); // Validate incoming reference if (context == null) { throw new ArgumentNullException(nameof(context)); } // We take on all the available display area Rectangle original = context.DisplayRectangle; ClientRectangle = original; // Layout each child int offset = 0; int space = (_orientation == Orientation.Vertical ? ClientHeight : ClientWidth); for (int i = 0; i < Count; i++) { ViewBase child = this[i]; // Find length of this item int length; // If this is the last item then it takes the remaining space if (i == (Count - 1)) { length = space; } else { // Give this item an equal portion of the remainder length = space / (Count - i); } // Ask child for it's own preferred size Size childPreferred = child.GetPreferredSize(context); // Size child to our relevant dimension if (_orientation == Orientation.Vertical) { context.DisplayRectangle = new Rectangle(ClientRectangle.X, ClientRectangle.Y + offset, childPreferred.Width, length); } else { context.DisplayRectangle = new Rectangle(ClientRectangle.X + offset, ClientRectangle.Y, length, ClientRectangle.Height); } // Ask the child to layout child.Layout(context); // Adjust running values offset += length; space -= length; } // Put back the original display value now we have finished context.DisplayRectangle = original; }