private void UpdateScrolling() { if (SelectedItem == null) { return; } var p = SelectedItem.Widget.Bounds; var bounds = _box.ActualBounds; InternalChild.UpdateLayout(); var sz = new Point(InternalChild.Bounds.Width, InternalChild.Bounds.Height); var maximum = InternalChild.ScrollMaximum; p.X -= bounds.X; p.Y -= bounds.Y; var lineHeight = CrossEngineStuff.LineSpacing(ListBoxStyle.ListItemStyle.LabelStyle.Font); var sp = InternalChild.ScrollPosition; if (p.Y < sp.Y) { sp.Y = p.Y; } else if (p.Y + lineHeight > sp.Y + sz.Y) { sp.Y = (p.Y + lineHeight - sz.Y); } InternalChild.ScrollPosition = sp; }
protected override Point InternalMeasure(Point availableSize) { if (Font == null) { return(Point.Zero); } var width = availableSize.X; if (Width != null && Width.Value < width) { width = Width.Value; } var result = Point.Zero; if (Font != null) { var formattedText = _formattedText.Clone(); formattedText.Width = _wrap ? width : default(int?); result = formattedText.Size; } if (result.Y < CrossEngineStuff.LineSpacing(Font)) { result.Y = CrossEngineStuff.LineSpacing(Font); } return(result); }
protected override Point InternalMeasure(Point availableSize) { if (Font == null) { return(Point.Zero); } var width = availableSize.X; width -= CursorWidth; var result = Point.Zero; if (Font != null) { result = _formattedText.Measure(_wrap ? width : default(int?)); } if (result.Y < CrossEngineStuff.LineSpacing(Font)) { result.Y = CrossEngineStuff.LineSpacing(Font); } if (Cursor != null) { result.X += CursorWidth; result.Y = Math.Max(result.Y, Cursor.Size.Y); } return(result); }
public override void InternalRender(RenderContext context) { if (_formattedText.Font == null) { return; } var bounds = ActualBounds; RenderSelection(context); var textColor = TextColor; if (!Enabled && DisabledTextColor != null) { textColor = DisabledTextColor.Value; } else if (IsKeyboardFocused && FocusedTextColor != null) { textColor = FocusedTextColor.Value; } var centeredBounds = LayoutUtils.Align(new Point(bounds.Width, bounds.Height), _formattedText.Size, HorizontalAlignment.Left, TextVerticalAlignment); centeredBounds.Offset(bounds.Location); var p = new Point(centeredBounds.Location.X - _internalScrolling.X, centeredBounds.Location.Y - _internalScrolling.Y); _formattedText.Draw(context.Batch, p, context.View, textColor, context.Opacity); if (!IsKeyboardFocused) { // Skip cursor rendering if the widget doesnt have the focus return; } var now = DateTime.Now; if ((now - _lastBlinkStamp).TotalMilliseconds >= BlinkIntervalInMs) { _cursorOn = !_cursorOn; _lastBlinkStamp = now; } if (Enabled && _cursorOn && Cursor != null) { p = GetRenderPositionByIndex(CursorPosition); p.X -= _internalScrolling.X; p.Y -= _internalScrolling.Y; context.Draw(Cursor, new Rectangle(p.X, p.Y, Cursor.Size.X, CrossEngineStuff.LineSpacing(_formattedText.Font))); } }
public override void InternalRender(RenderContext context) { if (_formattedText.Font == null) { return; } var bounds = ActualBounds; var textColor = TextColor; if (!Enabled && DisabledTextColor != null) { textColor = DisabledTextColor.Value; } else if (IsFocused && FocusedTextColor != null) { textColor = FocusedTextColor.Value; } var centeredBounds = LayoutUtils.Align(new Point(bounds.Width, bounds.Height), _formattedText.Size, HorizontalAlignment.Left, TextVerticalAlignment); centeredBounds.Offset(bounds.Location); _formattedText.Draw(context.Batch, centeredBounds, textColor, context.Opacity); if (!IsFocused) { // Skip cursor rendering if the widget doesnt have the focus return; } var now = DateTime.Now; if ((now - _lastBlinkStamp).TotalMilliseconds >= BlinkIntervalInMs) { _cursorOn = !_cursorOn; _lastBlinkStamp = now; } if (_cursorOn && Cursor != null) { var x = bounds.X; var y = bounds.Y; var glyphRender = _formattedText.GetGlyphInfoByIndex(_cursorIndex - 1); if (glyphRender != null && glyphRender.TextRun.RenderedPosition != null) { x = glyphRender.TextRun.RenderedPosition.Value.X + glyphRender.Bounds.Right; y = glyphRender.TextRun.RenderedPosition.Value.Y; } context.Draw(Cursor, new Rectangle(x, y, Cursor.Size.X, CrossEngineStuff.LineSpacing(_formattedText.Font))); } }
public Point Measure(int?width) { var result = Point.Zero; if (_text != null) { var i = 0; var y = 0; var remainingWidth = width; var lineWidth = 0; while (i < _text.Length) { var chunkInfo = LayoutRow(i, remainingWidth, false); if (i == chunkInfo.StartIndex && chunkInfo.CharsCount == 0) { break; } lineWidth += chunkInfo.X; i = chunkInfo.StartIndex + chunkInfo.CharsCount; if (remainingWidth.HasValue) { remainingWidth = remainingWidth.Value - chunkInfo.X; } if (chunkInfo.LineEnd) { if (lineWidth > result.X) { result.X = lineWidth; } lineWidth = 0; remainingWidth = width; y += chunkInfo.Y; y += _verticalSpacing; } } result.Y = y; } if (result.Y == 0) { result.Y = CrossEngineStuff.LineSpacing(_font); } return(result); }
private void _textEdit_CursorIndexChanged(object sender, EventArgs e) { var asScrollPane = Parent as ScrollPane; if (asScrollPane == null) { return; } var p = GetRenderPositionByIndex(_textEdit.CursorIndex); if (p.Y == _lastCursorY) { return; } var scrollMaximumPixels = asScrollPane.ScrollMaximumPixels; if (scrollMaximumPixels.Y == 0) { return; } var lineHeight = CrossEngineStuff.LineSpacing(_formattedText.Font); if (p.Y < asScrollPane.ActualBounds.Top) { var scrollMaximum = asScrollPane.ScrollMaximum; var newY = (-Top + p.Y - asScrollPane.ActualBounds.Top) * scrollMaximum.Y / scrollMaximumPixels.Y; var sp = asScrollPane.ScrollPosition; asScrollPane.ScrollPosition = new Point(sp.X, newY); } else if (p.Y + lineHeight > asScrollPane.ActualBounds.Bottom) { var scrollMaximum = asScrollPane.ScrollMaximum; var newY = (-Top + p.Y + lineHeight - asScrollPane.ActualBounds.Bottom) * scrollMaximum.Y / scrollMaximumPixels.Y; var sp = asScrollPane.ScrollPosition; asScrollPane.ScrollPosition = new Point(sp.X, newY); } _lastCursorY = p.Y; asScrollPane.UpdateLayout(); }
public Point Measure(int?width) { var result = Point.Zero; if (_text != null) { var i = 0; float y = 0; while (i < _text.Length) { var r = LayoutRow(i, width); if (r.num_chars == 0) { break; } if (r.x1 > result.X) { result.X = (int)r.x1; } i += r.num_chars; y += r.ymax; y += _verticalSpacing; } result.Y = (int)y; } if (result.Y == 0) { result.Y = CrossEngineStuff.LineSpacing(_font); } return(result); }
public Point Measure(int?width) { var result = Point.Zero; if (_text != null) { var i = 0; var y = 0; while (i < _text.Length) { var r = LayoutRow(i, width); if (r.CharsCount == 0) { break; } if (r.X > result.X) { result.X = r.X; } i += r.CharsCount; y += r.Y; y += _verticalSpacing; } result.Y = y; } if (result.Y == 0) { result.Y = CrossEngineStuff.LineSpacing(_font); } return(result); }
private void RenderSelection(RenderContext context) { var bounds = ActualBounds; if (string.IsNullOrEmpty(Text) || Selection == null) { return; } var selectStart = Math.Min(SelectStart, SelectEnd); var selectEnd = Math.Max(SelectStart, SelectEnd); if (selectStart >= selectEnd) { return; } var startGlyph = _formattedText.GetGlyphInfoByIndex(selectStart); if (startGlyph == null) { return; } var lineIndex = startGlyph.TextChunk.LineIndex; var i = selectStart; var lineHeight = CrossEngineStuff.LineSpacing(_formattedText.Font); while (true) { startGlyph = _formattedText.GetGlyphInfoByIndex(i); var startPosition = GetRenderPositionByIndex(i); var line = _formattedText.Lines[startGlyph.TextChunk.LineIndex]; if (selectEnd < line.TextStartIndex + line.Count) { var endPosition = GetRenderPositionByIndex(selectEnd); context.Draw(Selection, new Rectangle(startPosition.X - _internalScrolling.X, startPosition.Y - _internalScrolling.Y, endPosition.X - startPosition.X, lineHeight)); break; } context.Draw(Selection, new Rectangle(startPosition.X - _internalScrolling.X, startPosition.Y - _internalScrolling.Y, bounds.Left + startGlyph.TextChunk.Size.X - startPosition.X, lineHeight)); ++lineIndex; if (lineIndex >= _formattedText.Lines.Count) { break; } i = _formattedText.Lines[lineIndex].TextStartIndex; } }
private void UpdateScrolling() { var p = GetRenderPositionByIndex(CursorPosition); if (p == _lastCursorPosition) { return; } var asScrollViewer = Parent as ScrollViewer; Point sz, maximum; var bounds = ActualBounds; if (asScrollViewer != null) { asScrollViewer.UpdateLayout(); sz = new Point(asScrollViewer.Bounds.Width, asScrollViewer.Bounds.Height); maximum = asScrollViewer.ScrollMaximum; } else { sz = new Point(Bounds.Width, Bounds.Height); maximum = new Point(_formattedText.Size.X + CursorWidth - sz.X, _formattedText.Size.Y - sz.Y); if (maximum.X < 0) { maximum.X = 0; } if (maximum.Y < 0) { maximum.Y = 0; } } if (maximum == Point.Zero) { _internalScrolling = Point.Zero; _lastCursorPosition = p; return; } p.X -= bounds.X; p.Y -= bounds.Y; var lineHeight = CrossEngineStuff.LineSpacing(_formattedText.Font); Point sp; if (asScrollViewer != null) { sp = asScrollViewer.ScrollPosition; } else { sp = _internalScrolling; } if (p.Y < sp.Y) { sp.Y = p.Y; } else if (p.Y + lineHeight > sp.Y + sz.Y) { sp.Y = p.Y + lineHeight - sz.Y; } if (p.X < sp.X) { sp.X = p.X; } else if (p.X + CursorWidth > sp.X + sz.X) { sp.X = p.X + CursorWidth - sz.X; } if (asScrollViewer != null) { asScrollViewer.ScrollPosition = sp; } else { if (sp.X < 0) { sp.X = 0; } if (sp.X > maximum.X) { sp.X = maximum.X; } if (sp.Y < 0) { sp.Y = 0; } if (sp.Y > maximum.Y) { sp.Y = maximum.Y; } _internalScrolling = sp; } _lastCursorPosition = p; }
public Point Measure(int?width) { var result = Point.Zero; var key = GetMeasureKey(width); if (_measures.TryGetValue(key, out result)) { return(result); } if (!string.IsNullOrEmpty(_text)) { var i = 0; var y = 0; var remainingWidth = width; var lineWidth = 0; while (i < _text.Length) { var chunkInfo = LayoutRow(i, remainingWidth, false); if (i == chunkInfo.StartIndex && chunkInfo.CharsCount == 0) { break; } lineWidth += chunkInfo.X; i = chunkInfo.StartIndex + chunkInfo.CharsCount; if (remainingWidth.HasValue) { remainingWidth = remainingWidth.Value - chunkInfo.X; } if (chunkInfo.LineEnd) { if (lineWidth > result.X) { result.X = lineWidth; } lineWidth = 0; remainingWidth = width; y += chunkInfo.Y; y += _verticalSpacing; } } result.Y = y; } if (result.Y == 0) { result.Y = CrossEngineStuff.LineSpacing(_font); } _measures[key] = result; return(result); }
internal ChunkInfo LayoutRow(int startIndex, int?width, bool parseCommands) { var r = new ChunkInfo { StartIndex = startIndex, LineEnd = true }; if (string.IsNullOrEmpty(_text)) { return(r); } _stringBuilder.Clear(); int? lastBreakPosition = null; Point?lastBreakMeasure = null; for (var i = r.StartIndex; i < _text.Length; ++i) { var c = _text[i]; if (SupportsCommands && c == '\\') { if (i < _text.Length - 2 && _text[i + 1] == 'c' && _text[i + 2] == '[') { // Find end var startPos = i + 3; var j = _text.IndexOf(']', startPos); if (j != -1) { // Found if (i > r.StartIndex) { // Break right here, as next chunk has another color r.LineEnd = false; return(r); } if (parseCommands) { r.Color = ColorStorage.FromName(_text.Substring(startPos, j - startPos)); } r.StartIndex = j + 1; i = j; continue; } } } _stringBuilder.Append(c); var sz = Point.Zero; if (c != '\n') { var v = Font.MeasureString(_stringBuilder); sz = new Point((int)v.X, (int)v.Y); } else { sz = new Point(r.X + NewLineWidth, Math.Max(r.Y, CrossEngineStuff.LineSpacing(_font))); // Break right here ++r.CharsCount; r.X = sz.X; r.Y = sz.Y; break; } if (width != null && sz.X > width.Value) { if (lastBreakPosition != null) { r.CharsCount = lastBreakPosition.Value - r.StartIndex; } if (lastBreakMeasure != null) { r.X = lastBreakMeasure.Value.X; r.Y = lastBreakMeasure.Value.Y; } break; } if (char.IsWhiteSpace(c)) { lastBreakPosition = i + 1; lastBreakMeasure = sz; } ++r.CharsCount; r.X = sz.X; r.Y = sz.Y; } return(r); }
internal TextEditRow LayoutRow(int startIndex, int?width) { var r = new TextEditRow(); if (string.IsNullOrEmpty(_text)) { return(r); } _stringBuilder.Clear(); int? lastBreakPosition = null; Vector2?lastBreakMeasure = null; for (var i = startIndex; i < _text.Length; ++i) { var c = Text[i]; _stringBuilder.Append(c); Vector2 sz = Vector2.Zero; if (c != '\n') { sz = Font.MeasureString(_stringBuilder); } else { sz = new Vector2(r.x1 + NewLineWidth, Math.Max(r.ymax, CrossEngineStuff.LineSpacing(_font))); } if (width != null && c == '\n') { // Break right here ++r.num_chars; r.x1 = sz.X; r.ymax = sz.Y; r.baseline_y_delta = sz.Y; break; } if (width != null && sz.X > width.Value) { if (lastBreakPosition != null) { r.num_chars = lastBreakPosition.Value - startIndex; } if (lastBreakMeasure != null) { r.x1 = lastBreakMeasure.Value.X; r.ymax = lastBreakMeasure.Value.Y; r.baseline_y_delta = lastBreakMeasure.Value.Y; } break; } if (char.IsWhiteSpace(c)) { lastBreakPosition = i + 1; lastBreakMeasure = sz; } ++r.num_chars; r.x1 = sz.X; r.ymax = sz.Y; r.baseline_y_delta = sz.Y; } return(r); }
public override void InternalRender(RenderContext context) { if (_formattedText.Font == null) { return; } var bounds = ActualBounds; if (Selection != null && !string.IsNullOrEmpty(Text)) { var selectStart = Math.Min(SelectStart, SelectEnd); var selectEnd = Math.Max(SelectStart, SelectEnd); if (selectStart < selectEnd) { // Debug.WriteLine("{0} - {1}", selectStart, selectEnd); var startGlyph = _formattedText.GetGlyphInfoByIndex(selectStart); var lineIndex = startGlyph.TextLine.LineIndex; var i = selectStart; while (true) { startGlyph = _formattedText.GetGlyphInfoByIndex(i); var startPosition = GetRenderPositionByIndex(i); if (selectEnd < i + startGlyph.TextLine.Count) { var endPosition = GetRenderPositionByIndex(selectEnd); context.Draw(Selection, new Rectangle(startPosition.X - _internalScrolling.X, startPosition.Y - _internalScrolling.Y, endPosition.X - startPosition.X, CrossEngineStuff.LineSpacing(_formattedText.Font))); break; } context.Draw(Selection, new Rectangle(startPosition.X - _internalScrolling.X, startPosition.Y - _internalScrolling.Y, bounds.Left + startGlyph.TextLine.Size.X - startPosition.X, CrossEngineStuff.LineSpacing(_formattedText.Font))); ++lineIndex; if (lineIndex >= _formattedText.Strings.Length) { break; } i = 0; for (var k = 0; k < lineIndex; ++k) { i += _formattedText.Strings[k].Count; } } } } var textColor = TextColor; if (!Enabled && DisabledTextColor != null) { textColor = DisabledTextColor.Value; } else if (IsKeyboardFocused && FocusedTextColor != null) { textColor = FocusedTextColor.Value; } var centeredBounds = LayoutUtils.Align(new Point(bounds.Width, bounds.Height), _formattedText.Size, HorizontalAlignment.Left, TextVerticalAlignment); centeredBounds.Offset(bounds.Location); var p = new Point(centeredBounds.Location.X - _internalScrolling.X, centeredBounds.Location.Y - _internalScrolling.Y); _formattedText.Draw(context.Batch, p, context.View, textColor, context.Opacity); if (!IsKeyboardFocused) { // Skip cursor rendering if the widget doesnt have the focus return; } var now = DateTime.Now; if ((now - _lastBlinkStamp).TotalMilliseconds >= BlinkIntervalInMs) { _cursorOn = !_cursorOn; _lastBlinkStamp = now; } if (Enabled && _cursorOn && Cursor != null) { p = GetRenderPositionByIndex(CursorPosition); p.X -= _internalScrolling.X; p.Y -= _internalScrolling.Y; context.Draw(Cursor, new Rectangle(p.X, p.Y, Cursor.Size.X, CrossEngineStuff.LineSpacing(_formattedText.Font))); } }
internal void Update() { if (!_dirty) { return; } if (!string.IsNullOrEmpty(_text)) { var sz = _spriteFont.MeasureString(_text); _size = new Point((int)sz.X, (int)sz.Y); #if MONOGAME var fontGlyphs = _spriteFont.GetGlyphs(); var offset = Vector2.Zero; var firstGlyphOfLine = true; for (var i = 0; i < _text.Length; ++i) { SpriteFont.Glyph g; fontGlyphs.TryGetValue(_text[i], out g); // The first character on a line might have a negative left side bearing. // In this scenario, SpriteBatch/SpriteFont normally offset the text to the right, // so that text does not hang off the left side of its rectangle. if (firstGlyphOfLine) { offset.X = Math.Max(g.LeftSideBearing, 0); firstGlyphOfLine = false; } else { offset.X += _spriteFont.Spacing + g.LeftSideBearing; } var p = offset; p += g.Cropping.Location.ToVector2(); var result = new Rectangle((int)p.X, (int)p.Y, (int)(g.Width + g.RightSideBearing), g.BoundsInTexture.Height); _glyphs[i].Bounds = result; offset.X += g.Width + g.RightSideBearing; } #else var offset = Vector2.Zero; for (var i = 0; i < _text.Length; ++i) { Vector2 v = _spriteFont.MeasureString(_text[i].ToString()); var result = new Rectangle((int)offset.X, (int)offset.Y, (int)v.X, (int)v.Y); _glyphs[i].Bounds = result; offset.X += v.X; } #endif } else { _size = new Point(0, CrossEngineStuff.LineSpacing(_spriteFont)); } _dirty = false; }
internal TextEditRow LayoutRow(int startIndex, int?width) { var r = new TextEditRow(); if (string.IsNullOrEmpty(_text)) { return(r); } _stringBuilder.Clear(); int? lastBreakPosition = null; Point?lastBreakMeasure = null; for (var i = startIndex; i < _text.Length; ++i) { var c = _displayText[i]; _stringBuilder.Append(c); var sz = Point.Zero; if (c != '\n') { var v = Font.MeasureString(_stringBuilder); sz = new Point((int)v.X, (int)v.Y); } else { sz = new Point(r.X + NewLineWidth, Math.Max(r.Y, CrossEngineStuff.LineSpacing(_font))); // Break right here ++r.CharsCount; r.X = sz.X; r.Y = sz.Y; break; } if (width != null && sz.X > width.Value) { if (lastBreakPosition != null) { r.CharsCount = lastBreakPosition.Value - startIndex; } if (lastBreakMeasure != null) { r.X = lastBreakMeasure.Value.X; r.Y = lastBreakMeasure.Value.Y; } break; } if (char.IsWhiteSpace(c)) { lastBreakPosition = i + 1; lastBreakMeasure = sz; } ++r.CharsCount; r.X = sz.X; r.Y = sz.Y; } return(r); }
private void RenderSelection(RenderContext context) { var bounds = ActualBounds; if (string.IsNullOrEmpty(Text) || Selection == null) { return; } var selectStart = Math.Min(SelectStart, SelectEnd); var selectEnd = Math.Max(SelectStart, SelectEnd); if (selectStart >= selectEnd) { return; } var startGlyph = _formattedText.GetGlyphInfoByIndex(selectStart); if (startGlyph == null) { return; } var lineIndex = startGlyph.TextLine.LineIndex; var i = selectStart; while (true) { startGlyph = _formattedText.GetGlyphInfoByIndex(i); var startPosition = GetRenderPositionByIndex(i); if (selectEnd < i + startGlyph.TextLine.Count) { var endPosition = GetRenderPositionByIndex(selectEnd); context.Draw(Selection, new Rectangle(startPosition.X - _internalScrolling.X, startPosition.Y - _internalScrolling.Y, endPosition.X - startPosition.X, CrossEngineStuff.LineSpacing(_formattedText.Font))); break; } context.Draw(Selection, new Rectangle(startPosition.X - _internalScrolling.X, startPosition.Y - _internalScrolling.Y, bounds.Left + startGlyph.TextLine.Size.X - startPosition.X, CrossEngineStuff.LineSpacing(_formattedText.Font))); ++lineIndex; if (lineIndex >= _formattedText.Strings.Length) { break; } i = 0; for (var k = 0; k < lineIndex; ++k) { i += _formattedText.Strings[k].Count; } } }