internal static Rect GetLocation(PopupStyles style, Size desiredSize, Rect spanRectInScreenCoordinates, Rect reservedRect, Rect screenRect) { if ((style & PopupStyles.PositionLeftOrRight) != 0) { //Position left or right double xPosition = ((style & PopupStyles.PreferLeftOrTopPosition) != 0) ? (reservedRect.Left - desiredSize.Width) //To the left : reservedRect.Right; //To the right double yPosition = ((style & PopupStyles.RightOrBottomJustify) != 0) ? (spanRectInScreenCoordinates.Bottom - desiredSize.Height) //Bottom justified : spanRectInScreenCoordinates.Top; //Top justified return(ShiftVerticallyToFitScreen(xPosition, yPosition, desiredSize, screenRect)); } else { //Position above or below. double xPosition = ((style & PopupStyles.RightOrBottomJustify) != 0) ? (spanRectInScreenCoordinates.Right - desiredSize.Width) //Right justified : spanRectInScreenCoordinates.Left; //Left justified double yPosition = ((style & PopupStyles.PreferLeftOrTopPosition) != 0) ? (reservedRect.Top - desiredSize.Height) //Above : reservedRect.Bottom; //Below return(ShiftHorizontallyToFitScreen(xPosition, yPosition, desiredSize, screenRect)); } }
public SimpleBox(double coreWidth, double coreHeight) { Color = new Color(0.5, 0.5, 1); this.coreSize = new Size(coreWidth, coreHeight); MinWidth = coreSize.Width + margin * 2; MinHeight = coreSize.Height + margin * 2; }
protected override Size OnGetPreferredSize (SizeConstraint widthConstraint, SizeConstraint heightConstraint) { FrameBox parent = (FrameBox)Parent; Size s = new Size (parent.Padding.HorizontalSpacing + parent.BorderWidth.HorizontalSpacing, parent.Padding.VerticalSpacing + parent.BorderWidth.VerticalSpacing); if (child != null) s += child.Surface.GetPreferredSize (widthConstraint - s.Width, heightConstraint - s.Height, true); return s; }
protected override Size OnGetPreferredSize (SizeConstraint widthConstraint, SizeConstraint heightConstraint) { var parent = (RoundedFrameBox)Parent; var s = new Size (Math.Max (parent.Padding.HorizontalSpacing, Math.Max (parent.BorderSpacing.HorizontalSpacing, parent.CornerRadius.Spacing.HorizontalSpacing)), Math.Max (parent.Padding.VerticalSpacing, Math.Max (parent.BorderSpacing.VerticalSpacing, parent.CornerRadius.Spacing.VerticalSpacing))); if (child != null) s += child.Surface.GetPreferredSize (widthConstraint - s.Width, heightConstraint - s.Height, true); return s; }
void Reallocate (Size size) { TablePlacement[] visibleChildren = VisibleChildren (); var childrenSizes = GetPreferredChildrenSizes (visibleChildren, false, false); var w = CalcPreferredCellSizes (visibleChildren, childrenSizes, Orientation.Horizontal); CalcCellSizes (w, size.Width, true); childrenSizes = GetPreferredChildrenSizes (visibleChildren, true, false); var h = CalcPreferredCellSizes (visibleChildren, childrenSizes, Orientation.Vertical); CalcCellSizes (h, size.Height, true); }
/// <summary> /// Default constructor /// </summary> public OverlayCanvas() : base() { CanGetFocus = true; if (Bounds.Size == Size.Zero) return; cacheSize = Bounds.Size; ib = new ImageBuilder (Bounds.Width, Bounds.Height); cache = ib.ToBitmap (); }
internal static Rect ShiftVerticallyToFitScreen(double x, double y, Size desiredSize, Rect screenRect) { if ((y + desiredSize.Height) > screenRect.Bottom) { y = screenRect.Bottom - desiredSize.Height; } if (y < screenRect.Top) { y = screenRect.Top; } return(new Rect(x, y, desiredSize.Width, desiredSize.Height)); }
internal static Rect ShiftHorizontallyToFitScreen(double x, double y, Size desiredSize, Rect screenRect) { if ((x + desiredSize.Width) > screenRect.Right) { x = screenRect.Right - desiredSize.Width; } if (x < screenRect.Left) { x = screenRect.Left; } return(new Rect(x, y, desiredSize.Width, desiredSize.Height)); }
public Geometry PositionAndDisplay(Geometry reservedSpace) { //This method should only be called from the popup manager (which should never call it when the containing //view is hidden or in the middle of a layout). //This method does not support virtual whitespace positioning. An attempt to support it by using caret position was introduced, but //regressed the behavior that popup should stay in place as the caret moves. If in the future we need to support virtual whitespace, //consider using virtual span instead. //Update the visual span to the current snapshot. SnapshotSpan visualSpan = _visualSpan.GetSpan(_textView.TextSnapshot); // If the style indicates that we should dismiss when the mouse leaves the span of the text, then we should make an // initial check to make sure the mouse starts-off in the span. If not, we should fail to position. if ((_style & (PopupStyles.DismissOnMouseLeaveText | PopupStyles.DismissOnMouseLeaveTextOrContent)) != 0) { _textView.VisualElement.GetPointer(out int x, out int y); if (this.ShouldClearToolTipOnMouseMove(new Point(x, y))) { return(null); } } Rect?spanRectangle = null; if (visualSpan.Length > 0) { double left = double.MaxValue; double top = double.MaxValue; double right = double.MinValue; double bottom = double.MinValue; var bounds = _textView.TextViewLines.GetNormalizedTextBounds(visualSpan); foreach (var bound in bounds) { left = Math.Min(left, bound.Left); top = Math.Min(top, bound.TextTop); right = Math.Max(right, bound.Right); bottom = Math.Max(bottom, bound.TextBottom); } // If the start of the span lies within the view, use that instead of the left-bound of the span as a whole. // This will cause popups to be left-aligned with the start of their span, if at all possible. var startLine = _textView.TextViewLines.GetTextViewLineContainingBufferPosition(visualSpan.Start); if (startLine != null) { var startPointBounds = startLine.GetExtendedCharacterBounds(visualSpan.Start); if ((startPointBounds.Left < right) && (startPointBounds.Left >= _textView.ViewportLeft) && (startPointBounds.Left < _textView.ViewportRight)) { left = startPointBounds.Left; } } //Special case handling for when the end of the span is at the start of a line. ITextViewLine line = _textView.TextViewLines.GetTextViewLineContainingBufferPosition(visualSpan.End); if ((line != null) && (line.Start == visualSpan.End)) { bottom = Math.Max(bottom, line.TextBottom); } if (left < right) { spanRectangle = new Rect(left, top, right - left, bottom - top); } } else { //visualSpan is zero length so the default MarkerGeometry will be null. Create a custom marker geometry based on the location. ITextViewLine line = _textView.TextViewLines.GetTextViewLineContainingBufferPosition(visualSpan.Start); if (line != null) { TextBounds bounds = line.GetCharacterBounds(visualSpan.Start); spanRectangle = new Rect(bounds.Left, bounds.TextTop, 0.0, bounds.TextHeight); } } if (spanRectangle.HasValue) { //Get the portion of the span geometry that is inside the view. Rect viewRect = new Rect(_textView.ViewportLeft, _textView.ViewportTop, _textView.ViewportWidth, _textView.ViewportHeight); Rect spanRect = spanRectangle.Value; spanRect = spanRect.Intersect(viewRect); if (spanRect != default(Rect)) { // Determine two different rectangles for the span. One is the span in its raw form. The other is a "guess" at // what the already-reserved space around the span will be. We have a very-prevalent space reservation agent (the // current line agent) that reserves the current line plus a 3-pixel buffer below the line. We'll optimistically // guess that this agent might be in-play and attempt to avoid it. Rect spanRectWithBuffer = new Rect(spanRect.Left, spanRect.Top, spanRect.Right - spanRect.Left, spanRect.Bottom - spanRect.Top + BelowTheLineBufferHint); //Some of the text associated with the popup is visible, show the popup. Rect spanRectInScreenCoordinates = new Rect(this.GetScreenPointFromTextXY(spanRect.Left, spanRect.Top), this.GetScreenPointFromTextXY(spanRect.Right, spanRect.Bottom)); Rect spanRectWithBufferInScreenCoordinates = new Rect(this.GetScreenPointFromTextXY(spanRectWithBuffer.Left, spanRectWithBuffer.Top), this.GetScreenPointFromTextXY(spanRectWithBuffer.Right, spanRectWithBuffer.Bottom)); Rect screenRect = Xwt.Desktop.GetScreenAtLocation(spanRectInScreenCoordinates.TopLeft).Bounds;//TODO: Check if we should use VisualBounds Size desiredSize = _popup.Size; //The popup size specified in deivice pixels. Convert these to logical //pixels for purposes of calculating the actual size of the popup. //TODO desiredSize = new Size (desiredSize.Width / WpfHelper.DeviceScaleX, desiredSize.Height / WpfHelper.DeviceScaleY); desiredSize = new Size(desiredSize.Width, desiredSize.Height); PopupStyles alternateStyle = _style ^ PopupStyles.PreferLeftOrTopPosition; var tr = reservedSpace.Bounds; Point topLeft = new Point(Math.Min(spanRectInScreenCoordinates.Left, tr.Left), Math.Min(spanRectInScreenCoordinates.Top, tr.Top)); Point bottomRight = new Point(Math.Max(spanRectInScreenCoordinates.Right, tr.Right), Math.Max(spanRectInScreenCoordinates.Bottom, tr.Bottom)); var reservedRect = new Rect(topLeft.X, topLeft.Y, bottomRight.X - topLeft.X, bottomRight.Y - topLeft.Y); //There are 6 possible locations for the popup. The order of preference is determined by the presence of the //'PositionClosest' PopupStyle. // // Without 'PositionClosest': // 1 .. On the desired side of the span. // 2 .. On the desired side of the span with a bit of buffer. // 3 .. on the desired side of the reserved rectangle. // 4 .. On the alternate side of the span. // 5 .. On the alternate side of the span with a bit of buffer. // 6 .. on the alternate side of the reserved rectangle. // // With 'PositionClosest': // 1 .. On the desired side of the span. // 2 .. On the desired side of the span with a bit of buffer. // 3 .. On the alternate side of the span. // 4 .. On the alternate side of the span with a bit of buffer. // 5 .. on the desired side of the reserved rectangle. // 6 .. on the alternate side of the reserved rectangle. // //Try each location till we get a winner. // A location is a winner if it is disjoint from the original reserved rect and // the edges of the screen. Tuple <PopupStyles, Rect>[] positionChoices; if (reservedRect != default(Rect)) { if ((_style & PopupStyles.PositionClosest) == 0) { positionChoices = new Tuple <PopupStyles, Rect>[] { new Tuple <PopupStyles, Rect>(_style, spanRectInScreenCoordinates), new Tuple <PopupStyles, Rect>(_style, spanRectWithBufferInScreenCoordinates), new Tuple <PopupStyles, Rect>(_style, reservedRect), new Tuple <PopupStyles, Rect>(alternateStyle, spanRectInScreenCoordinates), new Tuple <PopupStyles, Rect>(alternateStyle, spanRectWithBufferInScreenCoordinates), new Tuple <PopupStyles, Rect>(alternateStyle, reservedRect), }; } else { positionChoices = new Tuple <PopupStyles, Rect>[] { new Tuple <PopupStyles, Rect>(_style, spanRectInScreenCoordinates), new Tuple <PopupStyles, Rect>(_style, spanRectWithBufferInScreenCoordinates), new Tuple <PopupStyles, Rect>(alternateStyle, spanRectInScreenCoordinates), new Tuple <PopupStyles, Rect>(alternateStyle, spanRectWithBufferInScreenCoordinates), new Tuple <PopupStyles, Rect>(_style, reservedRect), new Tuple <PopupStyles, Rect>(alternateStyle, reservedRect), }; } } else { positionChoices = new Tuple <PopupStyles, Rect>[] { new Tuple <PopupStyles, Rect>(_style, spanRectInScreenCoordinates), new Tuple <PopupStyles, Rect>(_style, spanRectWithBufferInScreenCoordinates), new Tuple <PopupStyles, Rect>(alternateStyle, spanRectInScreenCoordinates), new Tuple <PopupStyles, Rect>(alternateStyle, spanRectWithBufferInScreenCoordinates), }; } Rect location = default; foreach (var choice in positionChoices) { Rect locationToTry = GetLocation(choice.Item1, desiredSize, spanRectInScreenCoordinates, choice.Item2, screenRect); if (DisjointWithPadding(reservedSpace, locationToTry) && ContainsWithPadding(screenRect, locationToTry)) { location = locationToTry; _style = choice.Item1; break; } } // If we couldn't locate a place to live, tell the manager we want to go away. if (location == default) { return(null); } if (!_popup.IsVisible) { this.RegisterForEvents(); } _popup.DisplayAt(location.TopLeft); GeometryGroup requestedSpace = new GeometryGroup(); requestedSpace.Children.Add(new RectangleGeometry(FromXwtRect(spanRectInScreenCoordinates))); requestedSpace.Children.Add(new RectangleGeometry(FromXwtRect(location))); return(requestedSpace); } } //The text associated with the popup visualSpan is not visible: tell the manager we want to go away. return(null); }
void DrawPopover(Context ctx) { lock (trackerLock) { if (actualTrackerHitResult != null) { var trackerSettings = DefaultTrackerSettings; if (actualTrackerHitResult.Series != null && !string.IsNullOrEmpty(actualTrackerHitResult.Series.TrackerKey)) trackerSettings = trackerDefinitions[actualTrackerHitResult.Series.TrackerKey]; if (trackerSettings.Enabled) { var extents = actualTrackerHitResult.LineExtents; if (Math.Abs(extents.Width) < double.Epsilon) { extents = new OxyRect(actualTrackerHitResult.XAxis.ScreenMin.X, extents.Top, actualTrackerHitResult.XAxis.ScreenMax.X - actualTrackerHitResult.XAxis.ScreenMin.X, extents.Height); } if (Math.Abs(extents.Height) < double.Epsilon) { extents = new OxyRect(extents.Left, actualTrackerHitResult.YAxis.ScreenMin.Y, extents.Width, actualTrackerHitResult.YAxis.ScreenMax.Y - actualTrackerHitResult.YAxis.ScreenMin.Y); } var pos = actualTrackerHitResult.Position; if (trackerSettings.HorizontalLineVisible) { renderContext.DrawLine( new[] { new ScreenPoint(extents.Left, pos.Y), new ScreenPoint(extents.Right, pos.Y) }, trackerSettings.HorizontalLineColor, trackerSettings.HorizontalLineWidth, trackerSettings.HorizontalLineActualDashArray, LineJoin.Miter, true); } if (trackerSettings.VerticalLineVisible) { renderContext.DrawLine( new[] { new ScreenPoint(pos.X, extents.Top), new ScreenPoint(pos.X, extents.Bottom) }, trackerSettings.VerticalLineColor, trackerSettings.VerticalLineWidth, trackerSettings.VerticalLineActualDashArray, LineJoin.Miter, true); } TextLayout text = new TextLayout(); text.Font = trackerSettings.Font; text.Text = actualTrackerHitResult.Text; var arrowTop = actualTrackerHitResult.Position.Y <= Bounds.Height / 2; const int arrowPadding = 10; var textSize = text.GetSize(); var outerSize = new Size(textSize.Width + (trackerSettings.Padding * 2), textSize.Height + (trackerSettings.Padding * 2) + arrowPadding); var trackerBounds = new Rectangle(pos.X - (outerSize.Width / 2), 0, outerSize.Width, outerSize.Height - arrowPadding); if (arrowTop) trackerBounds.Y = pos.Y + arrowPadding + trackerSettings.BorderWidth; else trackerBounds.Y = pos.Y - outerSize.Height - trackerSettings.BorderWidth; var borderColor = trackerSettings.BorderColor.ToXwtColor(); ctx.RoundRectangle(trackerBounds, 6); ctx.SetLineWidth(trackerSettings.BorderWidth); ctx.SetColor(borderColor); ctx.StrokePreserve(); ctx.SetColor(trackerSettings.Background.ToXwtColor()); ctx.Fill(); ctx.Save(); var arrowX = trackerBounds.Center.X; var arrowY = arrowTop ? trackerBounds.Top : trackerBounds.Bottom; ctx.NewPath(); ctx.MoveTo(arrowX, arrowY); var triangleSide = 2 * arrowPadding / Math.Sqrt(3); var halfSide = triangleSide / 2; var verticalModifier = arrowTop ? -1 : 1; ctx.RelMoveTo(-halfSide, 0); ctx.RelLineTo(halfSide, verticalModifier * arrowPadding); ctx.RelLineTo(halfSide, verticalModifier * -arrowPadding); ctx.SetColor(borderColor); ctx.StrokePreserve(); ctx.ClosePath(); ctx.SetColor(trackerSettings.Background.ToXwtColor()); ctx.Fill(); ctx.Restore(); ctx.SetColor(trackerSettings.TextColor.ToXwtColor()); ctx.DrawTextLayout(text, trackerBounds.Left + trackerSettings.Padding, trackerBounds.Top + trackerSettings.Padding); } } } }
/// <summary> /// Update the cache contents, reallocating the cache if necessary /// </summary> void UpdateCache() { if (Bounds.Size == Size.Zero) return; // reallocate cache if Bounds have changed if (cacheSize != Bounds.Size) { //if (cache != null) // cache.Dispose (); //if (ib != null) // ib.Dispose (); cacheSize = Bounds.Size; ib = new ImageBuilder (Bounds.Width, Bounds.Height); } // Clear cache to Canvas Background colour ib.Context.SetColor (BackgroundColor); ib.Context.Rectangle (Bounds); ib.Context.Fill (); // Draw into cache OnDrawCache (ib.Context, Bounds); cache = ib.ToBitmap (); }
/// <summary> /// Calculates the preferred size of each cell (either height or width, depending on the provided orientation) /// </summary> /// <param name="mode">Mode.</param> /// <param name="orientation">Wether we are calculating the vertical size or the horizontal size</param> /// <param name="visibleChildren">List of children that are visible, and for which the size is being calculated.</param> /// <param name="fixedSizesByCell">Cells which have a fixed size</param> /// <param name="cellsWithExpand">Cells which are expandable.</param> /// <param name="sizes">Calculated size of each cell</param> /// <param name="spacing">Spacing to use for each cell</param> CellSizeVector CalcPreferredCellSizes(TablePlacement[] visibleChildren, Size[] childrenSizes, Orientation orientation) { Dictionary<int,double> fixedSizesByCell; HashSet<int> cellsWithExpand; double[] sizes; double spacing; int lastCell = 0; fixedSizesByCell = new Dictionary<int, double> (); cellsWithExpand = new HashSet<int> (); HashSet<int> cellsWithWidget = new HashSet<int> (); sizes = new double [visibleChildren.Length]; // Get the size of each widget and store the fixed sizes for widgets which don't span more than one cell for (int n=0; n<visibleChildren.Length; n++) { var bp = visibleChildren[n]; int start = GetStartAttach (bp, orientation); int end = GetEndAttach (bp, orientation); if (end > lastCell) lastCell = end; // Check if the cell is expandable and store the value bool expand = bp.GetExpandsForOrientation (orientation); for (int i=start; i < end; i++) { cellsWithWidget.Add (i); if (expand) cellsWithExpand.Add (i); } double s = orientation == Orientation.Vertical ? childrenSizes[n].Height : childrenSizes[n].Width; sizes [n] = s; if (end == start + 1) { // The widget only takes one cell. Store its size if it is the biggest bool changed = false; double fs; if (!fixedSizesByCell.TryGetValue (start, out fs)) changed = true; if (s > fs) { fs = s; changed = true; } if (changed) fixedSizesByCell [start] = fs; } } // For widgets that span more than one cell, calculate the floating size, that is, the size // which is not taken by other fixed size widgets List<TablePlacement> widgetsToAdjust = new List<TablePlacement> (); Dictionary<TablePlacement,double[]> growSizes = new Dictionary<TablePlacement, double[]> (); for (int n=0; n<visibleChildren.Length; n++) { var bp = visibleChildren[n]; int start = GetStartAttach (bp, orientation); int end = GetEndAttach (bp, orientation); if (end == start + 1) continue; widgetsToAdjust.Add (bp); double fixedSize = 0; // We are going to calculate the spacing included in the widget's span of cells // (there is spacing between each cell) double spanSpacing = 0; for (int c = start; c < end; c++) { double fs; fixedSizesByCell.TryGetValue (c, out fs); fixedSize += fs; if (c != start && c != end) spanSpacing += GetSpacing (c, orientation); } // sizeToGrow is the size that the whole cell span has to grow in order to fit // this widget. We substract the spacing between cells because that space will // be used by the widget, so we don't need to allocate more size for it double sizeToGrow = sizes [n] - fixedSize - spanSpacing; double sizeToGrowPart = sizeToGrow / (end - start); // Split the size to grow between the cells of the widget. We need to know how much size the widget // requires for each cell it covers. double[] widgetGrowSizes = new double [end - start]; for (int i=0; i<widgetGrowSizes.Length; i++) widgetGrowSizes [i] = sizeToGrowPart; growSizes[bp] = widgetGrowSizes; } // Now size-to-grow values have to be adjusted. For example, let's say widget A requires 100px for column 1 and 100px for column 2, and widget B requires // 60px for column 2 and 60px for column 3. So the widgets are overlapping at column 2. Since A requires at least 100px in column 2, it means that B can assume // that it will have 100px available in column 2, which means 40px more than it requested. Those extra 40px can then be substracted from the 60px that // it required for column 3. foreach (var n in cellsWithWidget) { double maxv = 0; TablePlacement maxtNatural = null; // Find the widget that requires the maximum size for this cell foreach (var bp in widgetsToAdjust) { // could be expressed as where clause, but this is faster and performance matters here if (GetStartAttach (bp, orientation) <= n && GetEndAttach (bp, orientation) > n) { double cv = growSizes[bp][n - GetStartAttach (bp, orientation)]; if (cv > maxv) { maxv = cv; maxtNatural = bp; } } } // Adjust the required size of all widgets of the cell (excluding the widget with the max size) foreach (var bp in widgetsToAdjust) { if (GetStartAttach (bp, orientation) <= n && GetEndAttach (bp, orientation) > n) { double[] widgetGrows = growSizes[bp]; int cellIndex = n - GetStartAttach (bp, orientation); if (bp != maxtNatural) { double cv = widgetGrows[cellIndex]; double splitExtraSpace = (maxv - cv) / (widgetGrows.Length - 1); for (int i=0; i<widgetGrows.Length; i++) widgetGrows[i] -= splitExtraSpace; } } } } // Find the maximum size-to-grow for each cell Dictionary<int,double> finalGrowTable = new Dictionary<int, double> (); foreach (var bp in widgetsToAdjust) { int start = GetStartAttach (bp, orientation); int end = GetEndAttach (bp, orientation); double[] widgetGrows = growSizes[bp]; for (int n=start; n<end; n++) { double curGrow; finalGrowTable.TryGetValue (n, out curGrow); var val = widgetGrows [n - start]; if (val > curGrow) curGrow = val; finalGrowTable [n] = curGrow; } } // Add the final size-to-grow to the fixed sizes calculated at the begining foreach (var it in finalGrowTable) { double ws; fixedSizesByCell.TryGetValue (it.Key, out ws); fixedSizesByCell [it.Key] = it.Value + ws; } spacing = 0; for (int n=1; n<lastCell; n++) { if (cellsWithWidget.Contains (n)) spacing += GetSpacing (n, orientation); } return new CellSizeVector () { visibleChildren = visibleChildren, fixedSizesByCell = fixedSizesByCell, cellsWithExpand = cellsWithExpand, sizes = sizes, spacing = spacing, orientation = orientation }; }
/// <summary> /// Draws the arrow on a plot surface. /// </summary> /// <param name="ctx">the Drawing Context with which to draw</param> /// <param name="xAxis">The X-Axis to draw against.</param> /// <param name="yAxis">The Y-Axis to draw against.</param> public void Draw(Context ctx, PhysicalAxis xAxis, PhysicalAxis yAxis ) { if (To.X > xAxis.Axis.WorldMax || To.X < xAxis.Axis.WorldMin) { return; } if (To.Y > yAxis.Axis.WorldMax || To.Y < yAxis.Axis.WorldMin) { return; } ctx.Save (); TextLayout layout = new TextLayout (); layout.Font = textFont_; layout.Text = text_; double angle = angle_; if (angle_ < 0.0) { int mul = -(int)(angle_ / 360.0) + 2; angle = angle_ + 360.0 * (double)mul; } double normAngle = (double)angle % 360.0; // angle in range 0 -> 360. Point toPoint = new Point ( xAxis.WorldToPhysical (to_.X, true).X, yAxis.WorldToPhysical (to_.Y, true).Y); double xDir = Math.Cos (normAngle * 2.0 * Math.PI / 360.0); double yDir = Math.Sin (normAngle * 2.0 * Math.PI / 360.0); toPoint.X += xDir*headOffset_; toPoint.Y += yDir*headOffset_; double xOff = physicalLength_ * xDir; double yOff = physicalLength_ * yDir; Point fromPoint = new Point( (int)(toPoint.X + xOff), (int)(toPoint.Y + yOff) ); ctx.SetLineWidth (1); ctx.SetColor (arrowColor_); ctx.MoveTo (fromPoint); ctx.LineTo (toPoint); ctx.Stroke (); xOff = headSize_ * Math.Cos ((normAngle-headAngle_/2) * 2.0 * Math.PI / 360.0); yOff = headSize_ * Math.Sin ((normAngle-headAngle_/2) * 2.0 * Math.PI / 360.0); ctx.LineTo (toPoint.X + xOff, toPoint.Y + yOff); double xOff2 = headSize_ * Math.Cos ((normAngle+headAngle_/2) * 2.0 * Math.PI / 360.0); double yOff2 = headSize_ * Math.Sin ((normAngle+headAngle_/2) * 2.0 * Math.PI / 360.0); ctx.LineTo (toPoint.X + xOff2, toPoint.Y + yOff2); ctx.LineTo (toPoint); ctx.ClosePath (); ctx.SetColor (arrowColor_); ctx.Fill (); Size textSize = layout.GetSize (); Size halfSize = new Size (textSize.Width/2, textSize.Height/2); double quadrantSlideLength = halfSize.Width + halfSize.Height; double quadrantD = normAngle / 90.0; // integer part gives quadrant. int quadrant = (int)quadrantD; // quadrant in. double prop = quadrantD - (double)quadrant; // proportion of way through this qadrant. double dist = prop * quadrantSlideLength; // distance along quarter of bounds rectangle. // now find the offset from the middle of the text box that the // rear end of the arrow should end at (reverse this to get position // of text box with respect to rear end of arrow). // // There is almost certainly an elgant way of doing this involving // trig functions to get all the signs right, but I'm about ready to // drop off to sleep at the moment, so this blatent method will have // to do. Point offsetFromMiddle = new Point (0, 0); switch (quadrant) { case 0: if (dist > halfSize.Height) { dist -= halfSize.Height; offsetFromMiddle = new Point ( -halfSize.Width + dist, halfSize.Height ); } else { offsetFromMiddle = new Point ( -halfSize.Width, - dist ); } break; case 1: if (dist > halfSize.Width) { dist -= halfSize.Width; offsetFromMiddle = new Point ( halfSize.Width, halfSize.Height - dist ); } else { offsetFromMiddle = new Point ( dist, halfSize.Height ); } break; case 2: if (dist > halfSize.Height) { dist -= halfSize.Height; offsetFromMiddle = new Point ( halfSize.Width - dist, -halfSize.Height ); } else { offsetFromMiddle = new Point ( halfSize.Width, -dist ); } break; case 3: if (dist > halfSize.Width) { dist -= halfSize.Width; offsetFromMiddle = new Point ( -halfSize.Width, -halfSize.Height + dist ); } else { offsetFromMiddle = new Point ( -dist, -halfSize.Height ); } break; default: throw new XwPlotException( "Programmer error." ); } ctx.SetColor (textColor_); double x = fromPoint.X - halfSize.Width - offsetFromMiddle.X; double y = fromPoint.Y - halfSize.Height + offsetFromMiddle.Y; ctx.DrawTextLayout (layout, x, y); ctx.Restore (); }
public Point(Size sz) : this() { this.X = sz.Width; this.Y = sz.Height; }
/// <summary> /// Change the shown image to a size that fits in the provided size limits /// </summary> /// <param name="s">Max width and height</param> public void WithBoxSize(Size s) { if (image != null) { image = image.WithBoxSize(s); if (!IsThumbnail) { scan.RequestedBitmapSize = image.Size; } if (mask != null) { MaskImage = mask.WithBoxSize(s); } QueueDraw(); } }
public TScan(float[] data, Xwt.Size size, bool multipleUsage = false) { rawData = data; explicitSize = size; this.multipleUsage = multipleUsage; }
public SimpleBox(double coreSize) { Color = new Color (0.5, 0.5, 1); this.coreSize = new Size (coreSize, coreSize); MinWidth = MinHeight = coreSize + margin * 2; }
/// <summary> /// Get the in/out-marker at a given position. /// </summary> /// <returns>The marker description and their position.</returns> /// <param name="position">Position.</param> /// <param name="inflate">Inflate search region.</param> MarkerNode GetInOutMarkerAt(Point position, Size? inflate = null) { foreach (PipelineNode pNode in nodes) { foreach (MarkerNode mNode in pNode.mNodes) { if (mNode.Bounds.Inflate(inflate ?? Size.Zero).Contains(position)) { return mNode; } } } return null; }
public SimpleBox(double coreSize) { Color = new Color (0.5, 0.5, 1); this.coreSize = new Size (coreSize, coreSize); MinSize = new Size (coreSize + margin * 2, coreSize + margin * 2); }
void DrawGradientButton(Xwt.Drawing.Context G, GradientButton B) { DrawingPath P = new DrawingPath(); P.Rectangle(new Xwt.Rectangle(B.Position, B.Size)); LinearGradient gr; G.AppendPath(P); Pattern pat = gr = new LinearGradient(B.Position.X, B.Position.Y, B.Position.X + B.Size.Width, B.Position.Y + B.Size.Height); gr.AddColorStop(0, B.Color.BlendWith(Colors.White, 0.8)); gr.AddColorStop(0.5, B.Color); gr.AddColorStop(1, B.Color.BlendWith(Colors.White, 0.8)); G.Pattern = pat; G.Fill(); G.AppendPath(P); G.SetColor(Xwt.Drawing.Colors.Black); G.SetLineWidth(1); G.Stroke(); TextLayout L = new TextLayout() { Font = B.Font, Text = B.Text }; Size TextSize = new Size(0.6 * L.Font.Size * L.Text.Count(), L.Font.Size); G.DrawTextLayout(L, new Xwt.Point(B.Position.X + B.Size.Width / 2 - TextSize.Width / 2, B.Position.Y + B.Size.Height / 2 - TextSize.Height / 2)); }
public CustomCell () { Size = new Size (200, 10); }
/// <summary> /// Initializes the user inferface /// </summary> private void InitializeUI() { // restore last window size and location Location = new Point( Settings.Default.WindowLocationX, Settings.Default.WindowLocationY ); Size = new Size( Settings.Default.WindowSizeWidth, Settings.Default.WindowSizeHeight ); // set window preference Title = "BAIMP"; // file menu var fileMenu = new MenuItem("_File"); fileMenu.SubMenu = new Menu(); MenuItem menuNew = new MenuItem("_New..."); menuNew.Clicked += (object sender, EventArgs e) => project.NewDialog(); fileMenu.SubMenu.Items.Add(menuNew); MenuItem menuOpen = new MenuItem("_Open..."); menuOpen.Clicked += delegate { if (!project.OpenDialog() && !string.IsNullOrEmpty(project.ErrorMessage)) { MessageDialog.ShowMessage ("Error while opening the file", project.ErrorMessage); project.ErrorMessage = null; } }; fileMenu.SubMenu.Items.Add(menuOpen); if (Settings.Default.LastOpenedProjects != null) { MenuItem menuLastOpened = new MenuItem("Recently opened"); menuLastOpened.SubMenu = new Menu(); fileMenu.SubMenu.Items.Add(menuLastOpened); for (int i = Settings.Default.LastOpenedProjects.Count-1; i >= 0; i--) { string path = Settings.Default.LastOpenedProjects[i]; MenuItem menuLastOpenedi = new MenuItem(path); menuLastOpenedi.Clicked += delegate(object sender, EventArgs e) { if (!project.Open(path) && !string.IsNullOrEmpty(project.ErrorMessage)) { MessageDialog.ShowMessage ("Error while opening the file", project.ErrorMessage); project.ErrorMessage = null; } }; menuLastOpened.SubMenu.Items.Add(menuLastOpenedi); } } fileMenu.SubMenu.Items.Add(new SeparatorMenuItem()); MenuItem menuImport = new MenuItem("_Import..."); menuImport.Clicked += (object sender, EventArgs e) => project.ImportDialog(); fileMenu.SubMenu.Items.Add(menuImport); MenuItem menuSave = new MenuItem("_Save"); menuSave.Clicked += (object sender, EventArgs e) => SaveAll(); fileMenu.SubMenu.Items.Add(menuSave); fileMenu.SubMenu.Items.Add(new SeparatorMenuItem()); MenuItem menuClose = new MenuItem("_Exit"); menuClose.Clicked += (object sender, EventArgs e) => Close(); fileMenu.SubMenu.Items.Add(menuClose); // View menu MenuItem viewMenu = new MenuItem("_View"); viewMenu.SubMenu = new Menu(); RadioButtonMenuItemGroup viewRadioGroup = new RadioButtonMenuItemGroup(); RadioButtonMenuItem menuViewOverview = new RadioButtonMenuItem("Overview"); menuViewOverview.Checked = true; menuViewOverview.Group = viewRadioGroup; viewMenu.SubMenu.Items.Add(menuViewOverview); RadioButtonMenuItem menuViewPipeline = new RadioButtonMenuItem("Pipeline"); menuViewPipeline.Group = menuViewOverview.Group; viewMenu.SubMenu.Items.Add(menuViewPipeline); menuViewOverview.Clicked += delegate { splitMain_Status.Remove(pipelineShelf); splitScan_Pipeline.Panel2.Content = pipelineShelf; splitMain_Status.PackStart(splitScan_Pipeline, true, true); }; menuViewPipeline.Clicked += delegate { splitScan_Pipeline.Panel2.Content = null; splitMain_Status.Remove(splitScan_Pipeline); splitMain_Status.PackStart(pipelineShelf, true, true); }; // Edit menu MenuItem editMenu = new MenuItem("_Edit"); editMenu.SubMenu = new Menu(); MenuItem menuWorksheetRename = new MenuItem("_Rename worksheet..."); editMenu.SubMenu.Items.Add(menuWorksheetRename); menuWorksheetRename.Clicked += (object sender, EventArgs e) => pipelineController.RenameCurrentWorksheetDialog(); // Pipeline menu MenuItem pipelineMenu = new MenuItem("_Pipeline"); pipelineMenu.SubMenu = new Menu(); MenuItem menuExecute = new MenuItem("_Execute"); menuExecute.Clicked += (object sender, EventArgs e) => pipelineController.CurrentPipeline.Execute(project); pipelineMenu.SubMenu.Items.Add(menuExecute); pipelineMenu.SubMenu.Items.Add(new SeparatorMenuItem()); MenuItem menuExport = new MenuItem("Export"); menuExport.SubMenu = new Menu(); pipelineMenu.SubMenu.Items.Add(menuExport); Type exporterType = typeof(BaseExporter); IEnumerable<Type> exporter = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(s => s.GetTypes()) .Where(t => t.BaseType == exporterType); foreach (Type export in exporter) { MenuItem ni = new MenuItem(string.Format("As {0}...", export.Name)); ni.Tag = export.Name; menuExport.SubMenu.Items.Add(ni); var lExport = export; ni.Clicked += delegate(object sender, EventArgs e) { MenuItem s = sender as MenuItem; if (s != null) { if (exporterList.ContainsKey(s.Tag.ToString())) { exporterList[s.Tag.ToString()].ShowDialog(pipelineController.CurrentPipeline.Nodes); } else { BaseExporter instance = Activator.CreateInstance(lExport, pipelineController.CurrentPipeline.PipelineName) as BaseExporter; if (instance != null) { exporterList[s.Tag.ToString()] = instance; instance.ShowDialog(pipelineController.CurrentPipeline.Nodes); } } } }; } // Extras menu MenuItem extrasMenu = new MenuItem("E_xtras"); extrasMenu.SubMenu = new Menu(); MenuItem menuResetAllMasks = new MenuItem("_Reset all masks"); menuResetAllMasks.Clicked += delegate { foreach (BaseScan scan in project.scanCollection) { scan.Mask.ResetMask(); } }; MenuItem menuExportLog = new MenuItem("Export _logs"); menuExportLog.Clicked += delegate { SaveFileDialog d = new SaveFileDialog("Export logs"); if (d.Run()) { string filename = d.FileName; if (!string.IsNullOrEmpty(filename)) { System.IO.File.WriteAllText(filename, Log.ToText()); } } d.Dispose(); }; extrasMenu.SubMenu.Items.Add(menuResetAllMasks); extrasMenu.SubMenu.Items.Add(menuExportLog); // main menu Menu menu = new Menu(); menu.Items.Add(fileMenu); menu.Items.Add(viewMenu); menu.Items.Add(editMenu); menu.Items.Add(pipelineMenu); menu.Items.Add(extrasMenu); MainMenu = menu; // initialize preview widget preview = new Preview(); // load tree view with all available files fileTree = new FileTreeView(); VBox splitFileTreeSearch_FileTree = new VBox(); splitFileTreeSearch_FileTree.PackStart(new FileTreeFilter(fileTree)); splitFileTreeSearch_FileTree.PackStart(fileTree, true); // load pipeline controller pipelineShelf = new VBox(); pipelineController = new PipelineController(project, pipelineShelf); splitFiletree_Preview = new HPaned(); splitFiletree_Preview.Panel1.Content = splitFileTreeSearch_FileTree; splitFiletree_Preview.Panel1.Shrink = true; fileTree.HorizontalScrollPolicy = ScrollPolicy.Never; splitFiletree_Preview.Panel2.Content = preview; splitFiletree_Preview.Panel2.Resize = true; splitController_Preview = new VBox(); //splitController_Preview.PackStart(controllbarShelf, false, false); splitController_Preview.PackEnd(splitFiletree_Preview, true, true); splitScan_Pipeline = new VPaned(); splitScan_Pipeline.Panel1.Content = splitController_Preview; splitScan_Pipeline.Panel2.Content = pipelineShelf; splitScan_Pipeline.Panel2.Resize = true; splitMain_Status = new VBox(); splitMain_Status.PackStart(splitScan_Pipeline, true, true); splitMain_Status.PackEnd(new StatusBar()); Content = splitMain_Status; }
/// <summary> /// Creates a BitmapImage from a tile repeated in each direction as required /// </summary> /// <param name="tile">Bitmap image to tile</param> /// <param name="final">final image size</param> /// <returns>the tiled image</returns> public static BitmapImage TiledImage(BitmapImage tile, Size final) { BitmapImage tiled = null; using (ImageBuilder ib = new ImageBuilder (final.Width, final.Height)) { using (Context ctx = ib.Context) { double w = tile.Size.Width; double h = tile.Size.Height; for (double x = 0; x < final.Width; x += w) { for (double y = 0; y < final.Height; y += h) { ctx.DrawImage (tile, x, y); } } } tiled = ib.ToBitmap (); } return tiled; }
public Rectangle(Point loc, Size sz) : this(loc.X, loc.Y, sz.Width, sz.Height) { }
// Get the preferred size of each child widget, including the margins Size[] GetPreferredChildrenSizes(TablePlacement[] visibleChildren, bool useWidthConstraint, bool useHeightConstraint) { var sizes = new Size [visibleChildren.Length]; for (int n=0; n<visibleChildren.Length; n++) { var bp = visibleChildren[n]; Size s; if (useWidthConstraint) s = bp.GetPreferredSize (bp.NextWidth - bp.LeftMargin - bp.RightMargin, double.PositiveInfinity); else if (useHeightConstraint) s = bp.GetPreferredSize (double.PositiveInfinity, bp.NextHeight - bp.TopMargin - bp.BottomMargin); else s = bp.GetPreferredSize (double.PositiveInfinity, double.PositiveInfinity); s.Width += bp.LeftMargin + bp.RightMargin; s.Height += bp.TopMargin + bp.BottomMargin; sizes [n] = s; } return sizes; }
/// <summary> /// Creates a BitmapImage from a tile repeated in each direction as required /// </summary> /// <param name="tile">Bitmap image to tile</param> /// <param name="final">final image size</param> /// <returns>the tiled image</returns> /// <remarks> /// For correct drawing, the tile and final images MUST have integer sizes /// </remarks> public static BitmapImage TiledImage(BitmapImage tile, Size final) { BitmapImage tiled = null; Rectangle src, dest; // Trim tile and final images to integer dimensions double tileWidth = Math.Truncate (tile.Size.Width); double tileHeight = Math.Truncate (tile.Size.Height); double finalWidth = Math.Truncate (final.Width); double finalHeight = Math.Truncate (final.Height); src = new Rectangle (0, 0, tileWidth, tileHeight); // Initial size for source tile using (ImageBuilder ib = new ImageBuilder (finalWidth, finalHeight)) { using (Context ctx = ib.Context) { double dh = tileHeight; double y = 0; while (y < finalHeight) { // allow for part-height tile at end if (tileHeight > (finalHeight - y)) { dh = (finalHeight - y); src.Height = dh; } double dw = tileWidth; double x = 0; src.Width = dw = tileWidth; // reset source Width for each X loop while (x < finalWidth) { // allow for part-width tile at end if (tileWidth > (finalWidth - x)) { dw = (finalWidth - x); src.Width = dw; } dest = new Rectangle (x, y, dw, dh); ctx.DrawImage (tile, src, dest); x += tileWidth; } y += tileHeight; } } tiled = ib.ToBitmap (); } return tiled; }
Point GetPackageImageLocation (Size imageSize, Rectangle cellArea) { double width = (packageImageAreaWidth - imageSize.Width) / 2; double height = (cellArea.Height - imageSize.Height - packageImagePadding.Bottom) / 2; return new Point (width, height); }
// Inflate and Offset public Rectangle Inflate(Size sz) { return Inflate (sz.Width, sz.Height); }