private void InnerSelect(VirtualSnapshotPoint anchorPoint, VirtualSnapshotPoint activePoint) { bool isEmpty = this.IsEmpty; this.ActivationTracksFocus = true; this._anchorPoint = anchorPoint; this._activePoint = activePoint; VirtualSnapshotPoint bufferPosition1 = this._anchorPoint; VirtualSnapshotPoint bufferPosition2 = this._activePoint; if (this._anchorPoint > this._activePoint) { bufferPosition1 = this._activePoint; bufferPosition2 = this._anchorPoint; } if (this.Mode == TextSelectionMode.Box) { IWpfTextViewLine containingBufferPosition1 = this._wpfTextView.GetTextViewLineContainingBufferPosition(bufferPosition1.Position); IWpfTextViewLine containingBufferPosition2 = this._wpfTextView.GetTextViewLineContainingBufferPosition(bufferPosition2.Position); TextBounds extendedCharacterBounds = containingBufferPosition1.GetExtendedCharacterBounds(bufferPosition1); this._leftX = extendedCharacterBounds.Leading; extendedCharacterBounds = containingBufferPosition2.GetExtendedCharacterBounds(bufferPosition2); this._rightX = extendedCharacterBounds.Leading; if (this._rightX < this._leftX) { double leftX = this._leftX; this._leftX = this._rightX; this._rightX = leftX; } } //TODO: this.RaiseChangedEvent(isEmpty, this.IsEmpty, true); }
public ITextPosition GetTextPosition(Point p) { int l = 0, r = textline.Length; TextBounds bound = null; double ml = TextCore.View.MarginLeft; if (p.X < ml) { return(null); } while (r - l > 1) { int mid = (l + r) >> 1; bound = textline.GetTextBounds(l, mid - l).FirstOrDefault(); if (p.X - ml >= bound.Rectangle.Right) { l = mid; } else { r = mid; } } if (l == r) { return(GetTextPosition(l + 1)); } l = Math.Min(l, r); bound = textline.GetTextBounds(l, 1).FirstOrDefault(); return((p.X - ml >= bound.Rectangle.Right) ? GetTextPosition(l + 2) : GetTextPosition(l + 1)); }
public Rect GetColumnActualRect(int column) { TextBounds bound = textline.GetTextBounds(column - 1, 1).FirstOrDefault(); Rect rect = bound.Rectangle; rect.X += TextCore.View.MarginLeft; return(rect); }
public static Rect?GetViewSpanRect(IWpfTextView wpfTextView, SnapshotSpan span) { var nullable = new Rect?(); if (span.Length > 0) { double num1 = double.MaxValue; double num2 = double.MaxValue; double val1_1 = double.MinValue; double val1_2 = double.MinValue; foreach (TextBounds textBounds in wpfTextView.TextViewLines.GetNormalizedTextBounds(span)) { num1 = Math.Min(num1, textBounds.Left); num2 = Math.Min(num2, textBounds.TextTop); val1_1 = Math.Max(val1_1, textBounds.Right); val1_2 = Math.Max(val1_2, textBounds.TextBottom + 1.0); } IWpfTextViewLine containingBufferPosition = wpfTextView.TextViewLines.GetTextViewLineContainingBufferPosition(span.Start); if (containingBufferPosition != null) { TextBounds extendedCharacterBounds = containingBufferPosition.GetExtendedCharacterBounds(span.Start); if (extendedCharacterBounds.Left < val1_1 && extendedCharacterBounds.Left >= wpfTextView.ViewportLeft && extendedCharacterBounds.Left < wpfTextView.ViewportRight) { num1 = extendedCharacterBounds.Left; } } ITextViewLine textViewLine = wpfTextView.TextViewLines.GetTextViewLineContainingBufferPosition(span.End); if (textViewLine != null && textViewLine.Start == span.End) { val1_2 = Math.Max(val1_2, textViewLine.TextBottom + 1.0); } if (num1 < val1_1) { nullable = new Rect(num1, num2, val1_1 - num1, val1_2 - num2); } } else { ITextViewLine textViewLine = wpfTextView.TextViewLines.GetTextViewLineContainingBufferPosition(span.Start); if (textViewLine != null) { TextBounds characterBounds = textViewLine.GetCharacterBounds(span.Start); nullable = new Rect(characterBounds.Left, characterBounds.TextTop, 0.0, characterBounds.TextHeight + 1.0); } } if (!nullable.HasValue || nullable.Value.IsEmpty) { return(null); } Rect rect1 = new Rect(wpfTextView.ViewportLeft, wpfTextView.ViewportTop, wpfTextView.ViewportWidth, wpfTextView.ViewportHeight); Rect rect2 = nullable.Value; rect2.Intersect(rect1); var point1 = GetScreenPointFromTextXY(wpfTextView, rect2.Left, rect2.Top); var point2 = GetScreenPointFromTextXY(wpfTextView, rect2.Right, rect2.Bottom); return(new Rect(point1, point2)); }
public void GetParagraphRect() { TestUtils.Upload(c_fileName, c_folderName + "/" + c_fileName); TextBounds response = TestUtils.SlidesApi.GetParagraphRectangle(c_fileName, c_slideIndex, c_shapeIndex, 1, c_password, c_folderName); Assert.IsNotNull(response); Assert.Greater(response.X, 0); Assert.Greater(response.Y, 0); Assert.Greater(response.Width, 0); Assert.Greater(response.Height, 0); }
private void CreateBlockAdornments(IMappingTagSpan <IBlockTag> tag, NormalizedSnapshotSpanCollection newOrReformattedSpans) { NormalizedSnapshotSpanCollection spans = tag.Span.GetSpans(this.view.TextSnapshot); if (spans.Count > 0) { //Get the start of the tag's span (which could be out of the view or not even mappable to //the view's text snapshot). var start = this.view.BufferGraph.MapUpToSnapshot(tag.Tag.Span.Start, PointTrackingMode.Positive, PositionAffinity.Predecessor, this.view.TextSnapshot); if (start.HasValue) { double x = -1.0; foreach (var span in spans) { if (newOrReformattedSpans.IntersectsWith(new NormalizedSnapshotSpanCollection(span))) { ITextViewLine spanTop = this.view.TextViewLines.GetTextViewLineContainingBufferPosition(span.Start); double yTop = (spanTop == null) ? this.view.ViewportTop : spanTop.Bottom; ITextViewLine spanBottom = this.view.TextViewLines.GetTextViewLineContainingBufferPosition(span.End); double yBottom = (spanBottom == null) ? this.view.ViewportBottom : spanBottom.Top; if (yBottom > yTop) { if (x < 0.0) { //Get the x-coordinate of the adornment == middle of the character that starts the block. //The first non-whitespace character on the line that defines the start of the block. ITextSnapshotLine startLine = start.Value.GetContainingLine(); int i = startLine.Start; while (i < startLine.End) { char c = this.view.TextSnapshot[i]; if ((c != ' ') && (c != '\t')) { break; } ++i; } SnapshotPoint blockStart = new SnapshotPoint(this.view.TextSnapshot, i); ITextViewLine tagTop = this.view.GetTextViewLineContainingBufferPosition(blockStart); TextBounds bounds = tagTop.GetCharacterBounds(blockStart); x = Math.Floor((bounds.Left + bounds.Right) * 0.5); //Make sure this is only a pixel wide. } this.CreateBlockAdornment(tag.Tag, span, x, yTop, yBottom); } } } } } }
protected void DrawTextRectangle(DrawingContext ctx, Brush brush, Pen pen, int start, int count) { if (count <= 0) { return; } WinTextLine text = ViewParent?.TextLine; TextBounds bound = text.GetTextBounds(start, count).FirstOrDefault(); Rect rect = bound.Rectangle; rect.X += ViewParent.TextCore.View.MarginLeft; ctx.DrawRectangle(brush, null, rect); }
public override void Draw(GdxSpriteBatch spriteBatch, float parentAlpha) { ISceneDrawable background; if (_list != null && _list.Parent != null && _style.BackgroundOpen != null) { background = _style.BackgroundOpen; } else if (IsDisabled && _style.BackgroundDisabled != null) { background = _style.BackgroundDisabled; } else if (_pointerIsOver && _style.BackgroundOver != null) { background = _style.BackgroundOver; } else { background = _style.Background; } BitmapFont font = _style.Font; Color fontColor = _style.FontColor; if (IsDisabled && _style.FontColorDisabled != null) { fontColor = _style.FontColorDisabled.Value; } float x = (int)X; float y = (int)Y; float width = Width; float height = Height; spriteBatch.Color = Color.MultiplyAlpha(parentAlpha); background.Draw(spriteBatch, x, y, width, height); if (_items.Length > 0) { float availableWidth = width - background.LeftWidth - background.RightWidth; int numGlyphs = font.ComputeVisibleGlyphs(_itemsText[SelectionIndex], 0, _itemsText[SelectionIndex].Length, availableWidth); _bounds = font.GetBounds(_itemsText[SelectionIndex]); height -= background.BottomHeight + background.TopHeight; float textY = (int)(height / 2 + background.BottomHeight + _bounds.Height / 2); font.Color = fontColor.MultiplyAlpha(parentAlpha); font.Draw(spriteBatch, _itemsText[SelectionIndex], x + background.LeftWidth, y + textY, 0, numGlyphs); } }
/// <summary> /// Occurs after the document text is changed. /// </summary> /// <param name="sender">The sender of the event.</param> /// <param name="e">A <see cref="EditorSnapshotChangedEventArgs"/> that contains the event data.</param> private void OnSyntaxEditorDocumentTextChanged(object sender, EditorSnapshotChangedEventArgs e) { // Don't add effects if the view doesn't have focus if (!this.IsActive) { return; } // Get the caret bounds in the view TextBounds caretBounds = this.View.GetCharacterBounds(this.View.Selection.EndPosition); // Render the smoke using adornments this.PuffSmoke(new Point(caretBounds.Left, caretBounds.Top + (caretBounds.Height / 2))); }
protected override void DrawBackground(GdxSpriteBatch spriteBatch, float parentAlpha) { if (_style.StageBackground != null) { spriteBatch.Color = Color.MultiplyAlpha(parentAlpha); Stage stage = Stage; Vector2 localPos = StageToLocalCoordinates(Vector2.Zero); Vector2 localSize = StageToLocalCoordinates(new Vector2(stage.Width, stage.Height)); _style.StageBackground.Draw(spriteBatch, X + localPos.X, Y + localPos.Y, X + localSize.X, Y + localSize.Y); } base.DrawBackground(spriteBatch, parentAlpha); float x = X; float y = Y + Height; TextBounds bounds = _titleCache.Bounds; if ((_titleAlignment & Alignment.Left) != 0) { x += PadLeft; } else if ((_titleAlignment & Alignment.Right) != 0) { x += Width - bounds.Width - PadRight; } else { x += (Width - bounds.Width) / 2; } if ((_titleAlignment & Alignment.Top) == 0) { if ((_titleAlignment & Alignment.Bottom) != 0) { y -= PadTop - bounds.Height; } else { y -= (PadTop - bounds.Height) / 2; } } _titleCache.Color = Color.Multiply(_style.TitleFontColor); _titleCache.SetPosition((int)x, (int)y); _titleCache.Draw(spriteBatch, parentAlpha); }
IList <TextBounds> GetTextBounds(ITextViewLine line, SnapshotSpan fullSpan) { if (fullSpan.Length == 0) { if (line.ExtentIncludingLineBreak.Contains(fullSpan)) { var bounds = line.GetCharacterBounds(fullSpan.Start); // It's just a point, so use zero width bounds = new TextBounds(bounds.Leading, bounds.Top, 0, bounds.Height, bounds.TextTop, bounds.TextHeight); return(new TextBounds[] { bounds }); } return(Array.Empty <TextBounds>()); } else { return(line.GetNormalizedTextBounds(fullSpan)); } }
public void SetItems(object[] objects) { if (objects == null) { throw new ArgumentNullException("objects"); } _items = objects; if (!(objects is string[])) { string[] strings = new string[objects.Length]; for (int i = 0, n = objects.Length; i < n; i++) { strings[i] = objects[i].ToString(); } _itemsText = strings; } else { _itemsText = objects as string[]; } _selectedIndex = 0; BitmapFont font = _style.Font; ISceneDrawable selectedDrawable = _style.Selection; _itemHeight = font.CapHeight - font.Descent * 2; _itemHeight += selectedDrawable.TopHeight + selectedDrawable.BottomHeight; _textOffsetX = selectedDrawable.LeftWidth; _textOffsetY = selectedDrawable.TopHeight - font.Descent; _prefWidth = 0; for (int i = 0; i < _items.Length; i++) { TextBounds bounds = font.GetBounds(_itemsText[i]); _prefWidth = Math.Max(bounds.Width, _prefWidth); } _prefWidth += selectedDrawable.LeftWidth + selectedDrawable.RightWidth; _prefHeight = _items.Length * _itemHeight; InvalidateHierarchy(); }
protected override void Render(DrawingContext ctx) { if (Core == null || Core.IsDisposed) { return; } base.Render(ctx); ViewParent?.TextLine?.Draw(ctx, new Point(ViewParent.TextCore.View.MarginLeft, ViewParent.ActualHeight - ViewParent.TextCore.FontSize), InvertAxes.None); if (ViewParent.SkipZone != null && ViewParent.SkipZoneStart >= 0) { TextBounds bound = ViewParent.TextLine.GetTextBounds(ViewParent.SkipZoneStart, ViewParent.SkipZoneCount).FirstOrDefault(); Brush foreground = Brushes.Gray; ViewParent.TextCore.DictBrush.TryGetValue("foreground_skipzone", out foreground); Pen pen = new Pen(foreground, 1.0); Rect rect = bound.Rectangle; rect.X += ViewParent.TextCore.View.MarginLeft; ctx.DrawRectangle(null, pen, rect); } }
private void ComputeSize() { _sizeInvalid = false; if (_wrap) { float width = Width; if (_style.Background != null) { width -= _style.Background.LeftWidth + _style.Background.RightWidth; } _bounds = _cache.Font.GetWrappedBounds(_text, width); } else { _bounds = _cache.Font.GetMultiLineBounds(_text); } _bounds.Width *= _fontScaleX; _bounds.Height *= _fontScaleY; }
public VirtualSnapshotPoint GetInsertionBufferPositionFromXCoordinate(double x) { this.ThrowIfInvalid(); int virtualSpaces = 0; SnapshotPoint?bufferPosition = this.GetBufferPositionFromXCoordinate(x); // If the buffer position is in the interior of the line if (bufferPosition.HasValue && bufferPosition.Value.Position < _extentIncludingLineBreak.End.Position - _lineBreakLength) { TextBounds bounds = this.GetExtendedCharacterBounds(bufferPosition.Value); // check to see if the provided x coordinate is closer to the trailing edge of the // text element and if so, return the following buffer position since x is closer // to following buffer position if (bounds.IsRightToLeft == (x < bounds.Left + (bounds.Width * 0.5))) { bufferPosition = this.GetTextElementSpan(bufferPosition.Value).End; } } else if (x <= TextLeft) { // return the start of the line if x is left of text left bufferPosition = _extentIncludingLineBreak.Start; } else { // This is almost identical to the logic in GetVirtualBufferPositionFromXCoordinate, // except that it rounds to the nearest column instead of truncating bufferPosition = _extentIncludingLineBreak.End - _lineBreakLength; // Only return a position in virtual space if at the physical end of line. if (this.IsLastTextViewLineForSnapshotLine && (x > TextRight)) { virtualSpaces = (int)Math.Round((x - TextRight) / VirtualSpaceWidth); } } return(new VirtualSnapshotPoint(bufferPosition.Value, virtualSpaces)); }
// Draw the adornment private void RenderAdornment() { Debug.Assert(_adornmentLayer.IsEmpty, "An adornment already exists"); if (_trackingPoint != null && _brush != null && !_textView.IsClosed && _textView.TextViewLines != null) { // map up from the subject buffer SnapshotSpan?span = TranslatedSpan; // check that the span is visible if (span.HasValue && _textView.TextViewLines.FormattedSpan.Contains(span.Value.Start)) { #if !WINDOWS TextBounds textBounds = _textView.TextViewLines.GetCharacterBounds(span.Value.Start); var nsview = new AppKit.NSView(); nsview.WantsLayer = true; var color = ((SolidColorBrush)_brush).Color; nsview.Layer.BackgroundColor = new CoreGraphics.CGColor(color.R / 255f, color.G / 255f, color.B / 255f); nsview.Frame = new CoreGraphics.CGRect(textBounds.Left, textBounds.TextBottom, textBounds.Width, 2); _adornmentLayer.AddAdornment(XPlatAdornmentPositioningBehavior.TextRelative, span, null, nsview, null); #endif } } }
private Rect?GetViewSpanRect(ITrackingSpan viewSpan) { var view = WpfTextView; if (view == null || view.TextViewLines == null || view.IsClosed) { return(null); } SnapshotSpan visualSpan = viewSpan.GetSpan(view.TextSnapshot); 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 = view.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 + ToolTipVerticalOffset); } // 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 = view.TextViewLines.GetTextViewLineContainingBufferPosition(visualSpan.Start); if (startLine != null) { var startPointBounds = startLine.GetExtendedCharacterBounds(visualSpan.Start); if ((startPointBounds.Left < right) && (startPointBounds.Left >= view.ViewportLeft) && (startPointBounds.Left < view.ViewportRight)) { left = startPointBounds.Left; } } //Special case handling for when the end of the span is at the start of a line. ITextViewLine line = view.TextViewLines.GetTextViewLineContainingBufferPosition(visualSpan.End); if ((line != null) && (line.Start == visualSpan.End)) { bottom = Math.Max(bottom, line.TextBottom + ToolTipVerticalOffset); } 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 = view.TextViewLines.GetTextViewLineContainingBufferPosition(visualSpan.Start); if (line != null) { TextBounds bounds = line.GetCharacterBounds(visualSpan.Start); spanRectangle = new Rect(bounds.Left, bounds.TextTop, 0.0, bounds.TextHeight + ToolTipVerticalOffset); } } if (spanRectangle.HasValue && !spanRectangle.Value.IsEmpty) { //Get the portion of the span geometry that is inside the view. Rect viewRect = new Rect(view.ViewportLeft, view.ViewportTop, view.ViewportWidth, view.ViewportHeight); Rect spanRect = spanRectangle.Value; spanRect.Intersect(viewRect); Rect spanRectInScreenCoordinates = new Rect(this.GetScreenPointFromTextXY(spanRect.Left, spanRect.Top), this.GetScreenPointFromTextXY(spanRect.Right, spanRect.Bottom)); return(spanRectInScreenCoordinates); } return(null); }
/// <summary> /// Convert client coordiates of the button to client coordiantes of this form. /// </summary> /// <param name="control">Control to calculate form client coordiantes for.</param> /// <param name="textBounds">Calculated client coordiantes will be stored in textBounds.</param> /// <returns>Point object that has the button's left and right sides stored in X and Y variable.</returns> private void ConvertContainedWinBoundsToFormClientCoordiantes(Control control, TextBounds textBounds) { Point ptControlClientLocation = new Point(control.ClientRectangle.Left, control.ClientRectangle.Right); Point ptControlScreenLocation = control.PointToScreen(ptControlClientLocation); Point ptControlFormClientLocation = this.PointToClient(ptControlScreenLocation); textBounds.SetBounds(ptControlFormClientLocation.X, ptControlFormClientLocation.X + (control.ClientRectangle.Right - control.ClientRectangle.Left)); }
public TextBounds AddText(CharSequence str, float x, float y, int start, int end) { Require(end - start); y += Font.Data.Ascent; return Bounds = new TextBounds() { Width = AddToCache(str, x, y, start, end), Height = Font.Data.CapHeight, }; }
public TextBounds AddWrappedText(CharSequence str, float x, float y, float wrapWidth, HAlignment alignment) { BitmapFont font = Font; int length = str.Length; Require(length); y += font.Data.Ascent; float down = font.Data.Down; if (wrapWidth <= 0) wrapWidth = int.MaxValue; float maxWidth = 0; int start = 0; int numLines = 0; while (start < length) { int newLine = BitmapFont.IndexOf(str, '\n', start); while (start < newLine) { if (!BitmapFont.IsWhitespace(str[start])) break; start++; } int lineEnd = start + font.ComputeVisibleGlyphs(str, start, newLine, wrapWidth); int nextStart = lineEnd + 1; if (lineEnd < newLine) { while (lineEnd > start) { if (BitmapFont.IsWhitespace(str[lineEnd])) break; lineEnd--; } if (lineEnd == start) { if (nextStart > start + 1) nextStart--; lineEnd = nextStart; } else { nextStart = lineEnd; while (lineEnd > start) { if (!BitmapFont.IsWhitespace(str[lineEnd - 1])) break; lineEnd--; } } } if (lineEnd > start) { float xOffset = 0; float lineWidth = 0; if (alignment != HAlignment.Left) { lineWidth = font.GetBounds(str, start, lineEnd).Width; xOffset = wrapWidth - lineWidth; if (alignment == HAlignment.Center) xOffset /= 2; } lineWidth = AddToCache(str, x + xOffset, y, start, lineEnd); maxWidth = Math.Max(maxWidth, lineWidth); } start = nextStart; y += down; numLines++; } return Bounds = new TextBounds() { Width = maxWidth, Height = font.Data.CapHeight + (numLines - 1) * font.Data.LineHeight, }; }
///////////////////////////////////////////////////////////////////////////////////////////////////// // PUBLIC PROCEDURES ///////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Adds an adornment to the <see cref="AdornmentLayer"/>. /// </summary> /// <param name="reason">An <see cref="AdornmentChangeReason"/> indicating the add reason.</param> /// <param name="viewLine">The current <see cref="ITextViewLine"/> being examined.</param> /// <param name="tagRange">The <see cref="ITag"/> and the range it covers.</param> /// <param name="bounds">The text bounds in which to render an adornment.</param> protected override void AddAdornment(AdornmentChangeReason reason, ITextViewLine viewLine, TagSnapshotRange <IntraTextNoteTag> tagRange, TextBounds bounds) { // Create the adornment var image = new DynamicImage(); image.Width = 16; image.Height = 16; image.SnapsToDevicePixels = true; image.Source = new BitmapImage(new Uri("/Images/Icons/Notes16.png", UriKind.Relative)); image.Stretch = Stretch.Fill; // Create a popup button PopupButton button = new PopupButton(); button.Content = image; button.Cursor = Cursors.Arrow; button.DisplayMode = PopupButtonDisplayMode.Merged; button.Focusable = false; button.IsTabStop = false; button.IsTransparencyModeEnabled = true; button.Margin = new Thickness(0); button.Padding = new Thickness(-1); button.ToolTip = new HtmlContentProvider(String.Format("<span style=\"color: green;\">{0}</span><br/>Created at <b>{1}</b> by <span style=\"color: blue;\">{2}</span><br/>Status: <b>{3}</b>", tagRange.Tag.Message, tagRange.Tag.Created.ToShortTimeString(), tagRange.Tag.Author, tagRange.Tag.Status)).GetContent(); // Add a context menu ContextMenu contextMenu = new ContextMenu(); button.PopupMenu = contextMenu; MenuItem removeItem = new MenuItem(); removeItem.Header = "Remove Note"; removeItem.Tag = tagRange; removeItem.Click += new RoutedEventHandler(OnRemoveNote); contextMenu.Items.Add(removeItem); contextMenu.Items.Add(new Separator()); MenuItem pendingItem = new MenuItem(); pendingItem.Header = "Mark as Pending"; pendingItem.IsChecked = (tagRange.Tag.Status == ReviewStatus.Pending); pendingItem.Tag = tagRange; pendingItem.Click += new RoutedEventHandler(OnMarkNoteAsPending); contextMenu.Items.Add(pendingItem); MenuItem acceptedItem = new MenuItem(); acceptedItem.Header = "Mark as Accepted"; acceptedItem.IsChecked = (tagRange.Tag.Status == ReviewStatus.Accepted); acceptedItem.Tag = tagRange; acceptedItem.Click += new RoutedEventHandler(OnMarkNoteAsAccpeted); contextMenu.Items.Add(acceptedItem); MenuItem rejectedItem = new MenuItem(); rejectedItem.Header = "Mark as Rejected"; rejectedItem.IsChecked = (tagRange.Tag.Status == ReviewStatus.Rejected); rejectedItem.Tag = tagRange; rejectedItem.Click += new RoutedEventHandler(OnMarkNoteAsRejected); contextMenu.Items.Add(rejectedItem); // Get the location Point location = new Point(Math.Round(bounds.Left) + 1, Math.Round(bounds.Top + (bounds.Height - tagRange.Tag.Size.Height) / 2)); // Add the adornment to the layer this.AdornmentLayer.AddAdornment(reason, button, location, tagRange.Tag.Key, null); }
public TextBounds AddMultiLineText(CharSequence str, float x, float y, float alignmentWidth, HAlignment alignment) { BitmapFont font = Font; int length = str.Length; Require(length); y += Font.Data.Ascent; float down = font.Data.Down; float maxWidth = 0; float startY = y; int start = 0; int numLines = 0; while (start < length) { int lineEnd = BitmapFont.IndexOf(str, '\n', start); float xOffset = 0; float lineWidth = 0; if (alignment != HAlignment.Left) { lineWidth = font.GetBounds(str, start, lineEnd).Width; xOffset = alignmentWidth - lineWidth; if (alignment == HAlignment.Center) xOffset /= 2; } lineWidth = AddToCache(str, x + xOffset, y, start, lineEnd); maxWidth = Math.Max(maxWidth, lineWidth); start = lineEnd + 1; y += down; numLines++; } return Bounds = new TextBounds() { Width = maxWidth, Height = font.Data.CapHeight + (numLines - 1) * font.Data.LineHeight, }; }
///////////////////////////////////////////////////////////////////////////////////////////////////// // PUBLIC PROCEDURES ///////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Adds an adornment to the <see cref="AdornmentLayer"/>. /// </summary> /// <param name="reason">An <see cref="AdornmentChangeReason"/> indicating the add reason.</param> /// <param name="viewLine">The current <see cref="ITextViewLine"/> being examined.</param> /// <param name="tagRange">The <see cref="ITag"/> and the range it covers.</param> /// <param name="bounds">The text bounds in which to render an adornment.</param> protected override void AddAdornment(AdornmentChangeReason reason, ITextViewLine viewLine, TagSnapshotRange <ColorPreviewTag> tagRange, TextBounds bounds) { // Round off the bounds to integers to help ensure crispness var adornmentBounds = new Rect(Math.Round(bounds.Left, MidpointRounding.AwayFromZero), Math.Round(bounds.Top, MidpointRounding.AwayFromZero), Math.Round(bounds.Width, MidpointRounding.AwayFromZero), Math.Round(bounds.Height, MidpointRounding.AwayFromZero)); // Add the adornment to the layer this.AdornmentLayer.AddAdornment(reason, OnDrawHighlightAdornment, adornmentBounds, tagRange.Tag, viewLine, tagRange.SnapshotRange, TextRangeTrackingModes.ExpandBothEdges, null); }
protected override void AddAdornment(ITextViewLine viewLine, TagSnapshotRange <LinkTag> tagRange, TextBounds bounds) { // Create the adornment var element = CreateDecorator(bounds.Width); var location = new Point(Math.Round(bounds.Left), bounds.Bottom - 2); // Add the adornment to the layer AdornmentLayer.AddAdornment(element, location, viewLine, tagRange.SnapshotRange, TextRangeTrackingModes.ExpandBothEdges, null); }
private void CreateBlockAdornments(IMappingTagSpan <IBlockTag> tag, NormalizedSnapshotSpanCollection newOrReformattedSpans, double left, double right) { NormalizedSnapshotSpanCollection spans = tag.Span.GetSpans(_view.TextSnapshot); if (spans.Count > 0) { //Get the start of the tag's span (which could be out of the view or not even mappable to //the view's text snapshot). var statementStart = _view.BufferGraph.MapUpToSnapshot(tag.Tag.StatementStart, PointTrackingMode.Positive, PositionAffinity.Predecessor, _view.TextSnapshot); if (statementStart.HasValue) { var end = _view.BufferGraph.MapUpToSnapshot(tag.Tag.Span.End, PointTrackingMode.Positive, PositionAffinity.Predecessor, _view.TextSnapshot); if (end.HasValue) { //Get the full extent of the block tag so that its adornments will be destroyed if anything in the block changes. SnapshotSpan extent = new SnapshotSpan(statementStart.Value, end.Value); bool intersecting = newOrReformattedSpans.IntersectsWith(new NormalizedSnapshotSpanCollection(extent)); if (intersecting) { var start = _view.BufferGraph.MapUpToSnapshot(tag.Tag.Span.Start, PointTrackingMode.Positive, PositionAffinity.Predecessor, _view.TextSnapshot); if (start.HasValue) { ITextSnapshotLine startLine = start.Value.GetContainingLine(); if (_showAdornments) { double x = -1.0; foreach (var span in spans) { if (span.OverlapsWith(_view.TextViewLines.FormattedSpan)) { ITextViewLine spanTop = _view.TextViewLines.GetTextViewLineContainingBufferPosition(span.Start); double yTop = (spanTop == null) ? _view.TextViewLines.FirstVisibleLine.Top : spanTop.Bottom; ITextViewLine spanBottom = _view.TextViewLines.GetTextViewLineContainingBufferPosition(span.End); double yBottom = (spanBottom == null) ? _view.TextViewLines.LastVisibleLine.Bottom : spanBottom.Top; if (yBottom > yTop) { if (x < 0.0) { //We have a starting point ... but it may be the wrong one. We have three cases to consider: //1) if (foo) { // | //Line goes here // //2) if (foo) // { // | //Line goes here // //3) if (bar && // foo) { // | //Line goes here // // //In each of these cases, we need to find the position of the first non-whitespace character on the line SnapshotPoint blockStart = FindFirstNonwhitespace(startLine); //If the span start's on the first non-whitespace character of the line, then we have case 2 //(& we're done). if (blockStart != start.Value) { //Case 1 or 3 ... see if the start & statement start are on the same line. //Is the span start on the same line as the statement start (if so, we have case 1 & are done). if (!startLine.Extent.Contains(statementStart.Value)) { //Case 3. blockStart = statementStart.Value; } } //Get the x-coordinate of the adornment == middle of the character that starts the block. ITextViewLine tagTop = _view.GetTextViewLineContainingBufferPosition(blockStart); TextBounds bounds = tagTop.GetCharacterBounds(blockStart); x = Math.Floor((bounds.Left + bounds.Right) * 0.5); //Make sure this is only a pixel wide. } this.CreateBlockAdornment(tag.Tag, extent, x, yTop, yBottom); } } } } if (_showMethodSeparator && (tag.Tag.Type == BlockType.Method) && (startLine.End < end.Value)) { var point = _view.BufferGraph.MapUpToBuffer(end.Value, PointTrackingMode.Negative, PositionAffinity.Predecessor, _view.VisualSnapshot.TextBuffer); if (point.HasValue) { ITextViewLine spanBottom = _view.TextViewLines.GetTextViewLineContainingBufferPosition(end.Value); if (spanBottom != null) { GeometryAdornment adornment = new GeometryAdornment(_coloring.MethodSeparatorAndHighlightColoring.LineBrush, new RectangleGeometry(new Rect(0.0, 0.0, right - left, 1.0))); Canvas.SetLeft(adornment, left); Canvas.SetTop(adornment, spanBottom.Bottom - 1.0); _methodSeparators.Add(adornment); _layer.AddAdornment(AdornmentPositioningBehavior.TextRelative, extent, adornment, adornment, OnMethodSeparatorRemoved); } } } } } } } } }
///////////////////////////////////////////////////////////////////////////////////////////////////// // PUBLIC PROCEDURES ///////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Adds an adornment to the <see cref="AdornmentLayer"/>. /// </summary> /// <param name="reason">An <see cref="AdornmentChangeReason"/> indicating the add reason.</param> /// <param name="viewLine">The current <see cref="ITextViewLine"/> being examined.</param> /// <param name="tagRange">The <see cref="ITag"/> and the range it covers.</param> /// <param name="bounds">The text bounds in which to render an adornment.</param> protected override void AddAdornment(AdornmentChangeReason reason, ITextViewLine viewLine, TagSnapshotRange <CustomTag> tagRange, TextBounds bounds) { // Create the adornment UIElement element = CustomAdornmentManager.CreateDecorator(bounds.Width); Point location = new Point(Math.Round(bounds.Left), bounds.Bottom - 2); // Add the adornment to the layer this.AdornmentLayer.AddAdornment(reason, element, location, null, viewLine, tagRange.SnapshotRange, TextRangeTrackingModes.ExpandBothEdges, null); }
void UpdateAdornmentUIState(ITextViewLine line, AdornmentTagInfo adornmentInfo, TextBounds bounds) { double verticalScale = line.LineTransform.VerticalScale; adornmentInfo.TopUIElement.SetScale(verticalScale); Canvas.SetTop(adornmentInfo.TopUIElement, bounds.TextTop + line.Baseline - verticalScale * adornmentInfo.Tag.Baseline); Canvas.SetLeft(adornmentInfo.TopUIElement, bounds.Left); }
public static void AutoNums() { Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database acDb = acDoc.Database; Editor acEd = acDoc.Editor; string currentFormat = "0"; bool continuePick = true; Point3d basePoint; bool isFirstPick = true; while (continuePick) { string s = (AutoType == AutoType.Number) ? start.ToString("F" + precision, CultureInfo.InvariantCulture) : startChar.ToString(); string incrementString = (AutoType == AutoType.Number) ? ", Increment: " + step + ", Current Format: " + currentFormat : ""; PromptPointOptions po2 = new PromptPointOptions("\nPick a point to insert text (Next: " + prefix + s + surfix + incrementString + ", Text height: " + textHeight + ")" + " or "); if (!isFirstPick) { po2.UseBasePoint = true; po2.BasePoint = basePoint; } po2.Keywords.Add("Start"); if (AutoType == AutoType.Number) { po2.Keywords.Add("Increment"); } po2.Keywords.Add("Options"); PromptPointResult pr; pr = acEd.GetPoint(po2); if (pr.Status == PromptStatus.OK) { Point3d thisPoint = pr.Value; if (isFirstPick) { basePoint = thisPoint; isFirstPick = false; } using (Transaction tr = acDoc.TransactionManager.StartTransaction()) { DBText thisText = new DBText(); if (AutoType == AutoType.Number) { thisText.TextString = prefix + start.ToString("F" + precision, CultureInfo.InvariantCulture) + surfix; } else { thisText.TextString = prefix + startChar + surfix; } thisText.Position = pr.Value; thisText.Height = textHeight; BlockTable acBlkTbl; acBlkTbl = tr.GetObject(acDb.BlockTableId, OpenMode.ForRead) as BlockTable; BlockTableRecord acBlkTblRec; acBlkTblRec = tr.GetObject(acDb.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord; acBlkTblRec.AppendEntity(thisText); tr.AddNewlyCreatedDBObject(thisText, true); t = thisText; TextBounds.CreateTextBound(thisText, boundType); tr.Commit(); if (AutoType == AutoType.Number) { start += step; } else { startChar++; } } } else if (pr.Status == PromptStatus.Keyword) { switch (pr.StringResult) { case "Start": if (AutoType == AutoType.Number) { PromptDoubleOptions pdo = new PromptDoubleOptions("\nSpecify starting number [" + start + "]"); PromptDoubleResult pdr = acEd.GetDouble(pdo); if (pdr.Status == PromptStatus.OK) { start = pdr.Value; } } else { PromptStringOptions pso = new PromptStringOptions("\nSpecify Start Letter (" + startChar + ")"); pso.AllowSpaces = false; PromptResult psrs = acEd.GetString(pso); if (psrs.Status == PromptStatus.OK) { startChar = psrs.StringResult[0]; } } break; case "Increment": PromptDoubleOptions pdo2 = new PromptDoubleOptions("\nSpecify increment number [" + step + "]"); PromptDoubleResult pdr2 = acEd.GetDouble(pdo2); if (pdr2.Status == PromptStatus.OK) { step = pdr2.Value; } break; case "Options": PromptKeywordOptions pko = new PromptKeywordOptions("\nSelect Options: "); pko.Keywords.Add("Prefix"); pko.Keywords.Add("Surfix"); pko.Keywords.Add("Format"); pko.Keywords.Add("Bounds"); pko.Keywords.Add("TextHeight"); pko.Keywords.Add("NumberOrLetter"); pko.Keywords.Default = "Format"; PromptResult pkr = acEd.GetKeywords(pko); if (pkr.Status == PromptStatus.OK) { string resultKeyword = pkr.StringResult; switch (resultKeyword) { case "Prefix": PromptStringOptions pso = new PromptStringOptions("\nSpecify prefix (" + prefix + ")"); pso.AllowSpaces = true; PromptResult psrs = acEd.GetString(pso); if (psrs.Status == PromptStatus.OK) { prefix = psrs.StringResult; } break; case "Surfix": PromptStringOptions pso2 = new PromptStringOptions("\nSpecify Surfix (" + surfix + ")"); pso2.AllowSpaces = true; PromptResult psrs2 = acEd.GetString(pso2); if (psrs2.Status == PromptStatus.OK) { surfix = psrs2.StringResult; } break; case "Format": PromptIntegerOptions piio = new PromptIntegerOptions("\nSpecify NUMBER symbol after decimal symbol [" + " | Current Format:" + currentFormat + "]"); piio.AllowNone = true; piio.AllowZero = true; piio.AllowNegative = false; PromptIntegerResult piir = acEd.GetInteger(piio); if (piir.Status == PromptStatus.OK) { precision = piir.Value; } if (precision > 0) { currentFormat = "0"; currentFormat += "."; for (int i = 1; i <= precision; i++) { currentFormat += "0"; } } break; case "Bounds": PromptKeywordOptions pkob = new PromptKeywordOptions("\nSpecify Text bound type (" + boundType.ToString() + ")"); pkob.AllowNone = true; pkob.Keywords.Add("None"); pkob.Keywords.Add("Rectangle"); pkob.Keywords.Add("Circle"); pkob.Keywords.Add("Triangle"); pkob.Keywords.Default = "None"; PromptResult pkrb = acEd.GetKeywords(pkob); if (pkrb.Status == PromptStatus.OK) { string result = pkrb.StringResult; switch (result) { case "None": boundType = TextBounds.BoundType.None; break; case "Rectangle": boundType = TextBounds.BoundType.Rectangle; break; case "Circle": boundType = TextBounds.BoundType.Circle; break; case "Triangle": boundType = TextBounds.BoundType.Triangle; break; default: break; } } break; case "TextHeight": PromptDoubleOptions pdo3 = new PromptDoubleOptions("\nSpecify height for new text (" + textHeight + ")"); PromptDoubleResult pdr3 = acEd.GetDouble(pdo3); if (pdr3.Status == PromptStatus.OK) { textHeight = pdr3.Value; } break; case "NumberOrLetter": PromptKeywordOptions pkob2 = new PromptKeywordOptions("\nUsing Number or Letter? (" + AutoType.ToString() + ")"); pkob2.AllowNone = true; pkob2.Keywords.Add("Number"); pkob2.Keywords.Add("Letter"); PromptResult pkrb2 = acEd.GetKeywords(pkob2); if (pkrb2.Status == PromptStatus.OK) { string result = pkrb2.StringResult; switch (result) { case "Number": AutoType = AutoType.Number; break; case "Letter": AutoType = AutoType.Letter; break; default: break; } } break; default: break; } } break; default: break; } } else { continuePick = false; } } }
private void ComputeSize() { _sizeInvalid = false; if (_wrap) { float width = Width; if (_style.Background != null) width -= _style.Background.LeftWidth + _style.Background.RightWidth; _bounds = _cache.Font.GetWrappedBounds(_text, width); } else _bounds = _cache.Font.GetMultiLineBounds(_text); _bounds.Width *= _fontScaleX; _bounds.Height *= _fontScaleY; }
///////////////////////////////////////////////////////////////////////////////////////////////////// // PUBLIC PROCEDURES ///////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Adds an adornment to the <see cref="AdornmentLayer"/>. /// </summary> /// <param name="reason">An <see cref="AdornmentChangeReason"/> indicating the add reason.</param> /// <param name="viewLine">The current <see cref="ITextViewLine"/> being examined.</param> /// <param name="tagRange">The <see cref="ITag"/> and the range it covers.</param> /// <param name="bounds">The text bounds in which to render an adornment.</param> protected override void AddAdornment(AdornmentChangeReason reason, ITextViewLine viewLine, TagSnapshotRange <CollapsedRegionTag> tagRange, TextBounds bounds) { // Create a border Border outerBorder = new Border(); outerBorder.Background = Brushes.Transparent; outerBorder.BorderBrush = Brushes.Gray; outerBorder.BorderThickness = new Thickness(1.0); outerBorder.CornerRadius = new CornerRadius(2.0); outerBorder.Cursor = Cursors.Arrow; outerBorder.SnapsToDevicePixels = true; outerBorder.Width = bounds.Width; outerBorder.Height = bounds.Height; this.AdornmentLayer.AddAdornment(reason, outerBorder, new Point(Math.Round(bounds.Left), Math.Round(bounds.Top)), tagRange.Tag.Key, null); // Create the text adornment TextBlock element = new TextBlock(); element.IsHitTestVisible = false; element.Text = tagRange.Tag.Text; element.FontFamily = this.View.SyntaxEditor.FontFamily; element.FontSize = this.View.SyntaxEditor.FontSize; element.Foreground = Brushes.Gray; element.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); // Get the location Point location = new Point(Math.Round(bounds.Left), Math.Round(bounds.Top + (bounds.Height - element.DesiredSize.Height) / 2)); // Add the text adornment to the layer this.AdornmentLayer.AddAdornment(reason, element, location, tagRange.Tag.Key, null); }
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); }
public override void Draw(GdxSpriteBatch spriteBatch, float parentAlpha) { ISceneDrawable background; if (_list != null && _list.Parent != null && _style.BackgroundOpen != null) background = _style.BackgroundOpen; else if (IsDisabled && _style.BackgroundDisabled != null) background = _style.BackgroundDisabled; else if (_pointerIsOver && _style.BackgroundOver != null) background = _style.BackgroundOver; else background = _style.Background; BitmapFont font = _style.Font; Color fontColor = _style.FontColor; if (IsDisabled && _style.FontColorDisabled != null) fontColor = _style.FontColorDisabled.Value; float x = (int)X; float y = (int)Y; float width = Width; float height = Height; spriteBatch.Color = Color.MultiplyAlpha(parentAlpha); background.Draw(spriteBatch, x, y, width, height); if (_items.Length > 0) { float availableWidth = width - background.LeftWidth - background.RightWidth; int numGlyphs = font.ComputeVisibleGlyphs(_itemsText[SelectionIndex], 0, _itemsText[SelectionIndex].Length, availableWidth); _bounds = font.GetBounds(_itemsText[SelectionIndex]); height -= background.BottomHeight + background.TopHeight; float textY = (int)(height / 2 + background.BottomHeight + _bounds.Height / 2); font.Color = fontColor.MultiplyAlpha(parentAlpha); font.Draw(spriteBatch, _itemsText[SelectionIndex], x + background.LeftWidth, y + textY, 0, numGlyphs); } }
protected override void Render(DrawingContext ctx) { if (Core == null || Core.IsDisposed) { return; } base.Render(ctx); IMRATextItemInfo item = ViewParent?.Core; ITextBoxCore core = ViewParent?.TextCore; WinTextLine text = ViewParent?.TextLine; if (core == null) { return; } ITextPosition start = core.SelectedStart; ITextPosition end = core.SelectedEnd; if (start.CompareTo(end) == 0) { ITextPosition pos = start.NextSeek(); RenderBracket(ctx, pos); RenderDefaultMatch(ctx, pos); pos = pos.PrevSeek(); RenderBracket(ctx, pos); RenderDefaultMatch(ctx, pos); } if (start.Line == end.Line && start.Column == end.Column) { status = start.Line == item.Line ? SelectionStatus.Caret : SelectionStatus.None; } else if (item.Line >= start.Line && item.Line <= end.Line) { status = SelectionStatus.Range; } else { status = SelectionStatus.None; } switch (status) { case SelectionStatus.None: break; case SelectionStatus.Caret: { if (!blinkshow && !forceshow) { break; } int index = start.Column - 1; TextBounds bound = text.GetTextBounds(index, 1).FirstOrDefault(); Brush brush = null; double thickness = 1.0; ViewParent.TextCore.DictBrush.TryGetValue("foreground_rawtext_caret", out brush); ViewParent.TextCore.DictValue.TryGetValue("rawtext_caret_thickness", out thickness); Pen pen = new Pen(brush, thickness); Point p1 = bound.Rectangle.TopLeft; Point p2 = bound.Rectangle.BottomLeft; p1.Y -= 2; p1.X += ViewParent.TextCore.View.MarginLeft; p2.X += ViewParent.TextCore.View.MarginLeft; ctx.DrawLine(pen, p1, p2); } break; case SelectionStatus.Range: { //int left = start.Column - 1; //int right = end.Column - 1; if (start.Line < item.Line) { start = Core.Start; } if (end.Line > item.Line) { end = Core.End; } //if (right - left <= 0) break; //TextBounds bound = text.GetTextBounds(left, right - left).FirstOrDefault(); Brush brush = null; //Rect rect = bound.Rectangle; ViewParent.TextCore.DictBrush.TryGetValue("background_rawtext_selected", out brush); //rect.X += ViewParent.TextCore.View.MarginLeft; //ctx.DrawRectangle(brush, null, rect); DrawTextRectangle(ctx, brush, null, start, end); } break; } }