/// <summary> /// Draw the entity. /// </summary> /// <param name="spriteBatch">Sprite batch to draw on.</param> /// <param name="phase">The phase we are currently drawing.</param> override protected void DrawEntity(SpriteBatch spriteBatch, DrawPhase phase) { // call base draw function to draw the panel part base.DrawEntity(spriteBatch, phase); // get which paragraph we currently show - real or placeholder bool showPlaceholder = !(IsFocused || _value.Length > 0); Paragraph currParagraph = showPlaceholder ? PlaceholderParagraph : TextParagraph; // get actual processed string _actualDisplayText = PrepareInputTextForDisplay(showPlaceholder, IsFocused); // for multiline only - handle scrollbar visibility and max if (_multiLine && (_actualDisplayText != null) && (_destRectInternal.Height > 0)) { // get how many lines can fit in the textbox and how many lines display text actually have int linesFit = _destRectInternal.Height / (int)(System.Math.Max(currParagraph.LineHeightY(), 1)); int linesInText = _actualDisplayText.Split('\n').Length; // if there are more lines than can fit, show scrollbar and manage scrolling: if (linesInText > linesFit) { // fix paragraph width to leave room for the scrollbar float prevWidth = currParagraph.Size.X; currParagraph.Size = new Vector2(_destRectInternal.Width / GlobalScale - 20, 0); if (currParagraph.Size.X != prevWidth) { // update size and re-calculate lines in text _actualDisplayText = PrepareInputTextForDisplay(showPlaceholder, IsFocused); linesInText = _actualDisplayText.Split('\n').Length; } // set scrollbar max and steps _scrollbar.Max = (uint)System.Math.Max(linesInText - linesFit, 2); _scrollbar.StepsCount = _scrollbar.Max; _scrollbar.Visible = true; // update text to fit scrollbar. first, rebuild the text with just the visible segment List <string> lines = new List <string>(_actualDisplayText.Split('\n')); int from = System.Math.Min(_scrollbar.Value, lines.Count - 1); int size = System.Math.Min(linesFit, lines.Count - from); lines = lines.GetRange(from, size); _actualDisplayText = string.Join("\n", lines); currParagraph.Text = _actualDisplayText; } // if no need for scrollbar make it invisible else { currParagraph.Size = Vector2.Zero; _scrollbar.Visible = false; } } // set placeholder and main text visibility based on current value TextParagraph.Visible = !showPlaceholder; PlaceholderParagraph.Visible = showPlaceholder; }
/// <summary> /// When list is resized (also called on init), create the labels to show item values and init graphical stuff. /// </summary> protected virtual void OnResize() { // if not visible, skip if (!IsVisible()) { _hadResizeWhileNotVisible = true; return; } // clear the _hadResizeWhileNotVisible flag _hadResizeWhileNotVisible = false; // remove all children before re-creating them ClearChildren(); // remove previous paragraphs list _paragraphs.Clear(); // make sure destination rect is up-to-date UpdateDestinationRects(); // calculate paragraphs quantity int i = 0; while (true) { // create and add new paragraph Paragraph paragraph = _userinterface.DefaultParagraph(".", Anchor.Auto); paragraph.PromiscuousClicksMode = true; paragraph.WrapWords = false; paragraph.UpdateStyle(DefaultParagraphStyle); paragraph.Scale = paragraph.Scale * ItemsScale; paragraph.SpaceAfter = paragraph.SpaceAfter + new Vector2(0, ExtraSpaceBetweenLines - 2); paragraph.ExtraMargin.Y = ExtraSpaceBetweenLines / 2 + 3; paragraph.AttachedData = new ParagraphData(this, i++); paragraph.UseActualSizeForCollision = false; paragraph.Size = new Vector2(0, (float)paragraph.LineHeightY() + ExtraSpaceBetweenLines); paragraph.BackgroundColorPadding = new Point((int)Padding.X, 5); paragraph.BackgroundColorUseBoxSize = true; paragraph._hiddenInternalEntity = true; paragraph.PropagateEventsTo(this); AddChild(paragraph); // call the callback whenever a new paragraph is created OnCreatedListParagraph(paragraph); // add to paragraphs list _paragraphs.Add(paragraph); // add callback to selection paragraph.OnClick += (Entity entity) => { ParagraphData data = (ParagraphData)entity.AttachedData; if (!data.list.LockSelection) { data.list.Select(data.relativeIndex, true); } }; // to calculate paragraph actual bottom paragraph.UpdateDestinationRects(); // if out of list bounderies remove this paragraph and stop if ((paragraph.GetActualDestRect().Bottom > _destRect.Bottom - _scaledPadding.Y) || i > _list.Count) { RemoveChild(paragraph); _paragraphs.Remove(paragraph); break; } } // add scrollbar last, but only if needed if (_paragraphs.Count > 0 && _paragraphs.Count < _list.Count) { // add scrollbar to list AddChild(_scrollbar, false); // calc max scroll value _scrollbar.Max = (uint)(_list.Count - _paragraphs.Count); if (_scrollbar.Max < 2) { _scrollbar.Max = 2; } _scrollbar.StepsCount = _scrollbar.Max; _scrollbar.Visible = true; } // if no scrollbar is needed, hide it else { _scrollbar.Visible = false; if (_scrollbar.Value > 0) { _scrollbar.Value = 0; } } }
/// <summary> /// Draw the entity. /// </summary> /// <param name="spriteBatch">Sprite batch to draw on.</param> /// <param name="phase">The phase we are currently drawing.</param> override protected void DrawEntity(SpriteBatch spriteBatch, DrawPhase phase) { // call base draw function to draw the panel part base.DrawEntity(spriteBatch, phase); // get which paragraph we currently show - real or placeholder bool showPlaceholder = !(IsFocused || _value.Length > 0); Paragraph currParagraph = showPlaceholder ? PlaceholderParagraph : TextParagraph; // get actual processed string _actualDisplayText = PrepareInputTextForDisplay(showPlaceholder, false); // for multiline only - handle scrollbar visibility and max if (_multiLine && (_actualDisplayText != null) && (_destRectInternal.Height > 0)) { // get how many lines can fit in the textbox and how many lines display text actually have int linesFit = _destRectInternal.Height / (int)(System.Math.Max(currParagraph.LineHeightY(), 1)); var linesfull = _actualDisplayText.Split('\n'); int linesInText = linesfull.Length; if (GrowX) { var maxlen = 0.0f; if (TextParagraph.WrapWords == false) { foreach (var line in linesfull) { var len = TextParagraph.CurrentFont.MeasureString(line); if (len.X > maxlen) { maxlen = len.X; } } } if ((int)maxlen != _destRectInternal.Width) //do I want to round or something? { var diff = Size.X - _destRectInternal.Width; Size = new Vector2(maxlen + diff, Size.Y); } } // if there are more lines than can fit, show scrollbar and manage scrolling: if (linesInText >= 1 && linesFit != linesInText) { int changelines = linesInText - linesFit; Size = new Vector2(Size.X, (float)(Size.Y + changelines * currParagraph.LineHeightY())); /* * // fix paragraph width to leave room for the scrollbar * float prevWidth = currParagraph.Size.X; * currParagraph.Size = new Vector2(_destRectInternal.Width / GlobalScale - 20, 0); * if (currParagraph.Size.X != prevWidth) * { * // update size and re-calculate lines in text * _actualDisplayText = PrepareInputTextForDisplay(showPlaceholder, IsFocused); * linesInText = _actualDisplayText.Split('\n').Length; * } * * // set scrollbar max and steps * _scrollbar.Max = (uint)System.Math.Max(linesInText - linesFit, 2); * _scrollbar.StepsCount = _scrollbar.Max; * _scrollbar.Visible = true; * * // update text to fit scrollbar. first, rebuild the text with just the visible segment * List<string> lines = new List<string>(_actualDisplayText.Split('\n')); * int from = System.Math.Min(_scrollbar.Value, lines.Count - 1); * int size = System.Math.Min(linesFit, lines.Count - from); * lines = lines.GetRange(from, size); * _actualDisplayText = string.Join("\n", lines); * currParagraph.Text = _actualDisplayText; */ } // if no need for scrollbar make it invisible else { currParagraph.Size = Vector2.Zero; _scrollbar.Visible = false; } } // set placeholder and main text visibility based on current value TextParagraph.Visible = !showPlaceholder; PlaceholderParagraph.Visible = showPlaceholder; }