mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-11-27 15:08:33 +01:00
Compare commits
No commits in common. "476e1dd2a6485b82753f1f76b72f3a6956bb1908" and "41a1a8aef1a0ea8b6a7fd714cef56307036d0629" have entirely different histories.
476e1dd2a6
...
41a1a8aef1
6 changed files with 23 additions and 42 deletions
|
@ -23,7 +23,6 @@ Additions
|
||||||
|
|
||||||
Improvements
|
Improvements
|
||||||
- Stopped the text formatter throwing if a color can't be parsed
|
- Stopped the text formatter throwing if a color can't be parsed
|
||||||
- Improved text formatter tokenization performance
|
|
||||||
|
|
||||||
Fixes
|
Fixes
|
||||||
- Fixed TextInput not working correctly when using surrogate pairs
|
- Fixed TextInput not working correctly when using surrogate pairs
|
||||||
|
@ -33,10 +32,6 @@ Improvements
|
||||||
- Allow scrolling panels to contain other scrolling panels
|
- Allow scrolling panels to contain other scrolling panels
|
||||||
- Allow dropdowns to have scrolling panels
|
- Allow dropdowns to have scrolling panels
|
||||||
|
|
||||||
Fixes
|
|
||||||
- Fixed panels updating their relevant children too much when the scroll bar is hidden
|
|
||||||
- Fixed a stack overflow exception when a panel's scroll bar auto-hiding causes elements to gain height
|
|
||||||
|
|
||||||
### MLEM.Data
|
### MLEM.Data
|
||||||
Fixes
|
Fixes
|
||||||
- Fixed various exception types not being wrapped by ContentLoadExceptions when loading raw or JSON content
|
- Fixed various exception types not being wrapped by ContentLoadExceptions when loading raw or JSON content
|
||||||
|
|
|
@ -56,7 +56,6 @@ namespace MLEM.Ui.Elements {
|
||||||
|
|
||||||
private readonly List<Element> relevantChildren = new List<Element>();
|
private readonly List<Element> relevantChildren = new List<Element>();
|
||||||
private readonly HashSet<Element> scrolledChildren = new HashSet<Element>();
|
private readonly HashSet<Element> scrolledChildren = new HashSet<Element>();
|
||||||
private readonly float[] scrollBarMaxHistory;
|
|
||||||
private readonly bool scrollOverflow;
|
private readonly bool scrollOverflow;
|
||||||
|
|
||||||
private RenderTarget2D renderTarget;
|
private RenderTarget2D renderTarget;
|
||||||
|
@ -97,10 +96,6 @@ namespace MLEM.Ui.Elements {
|
||||||
this.ScrollToElement(e);
|
this.ScrollToElement(e);
|
||||||
};
|
};
|
||||||
this.AddChild(this.ScrollBar);
|
this.AddChild(this.ScrollBar);
|
||||||
|
|
||||||
this.scrollBarMaxHistory = new float[3];
|
|
||||||
for (var i = 0; i < this.scrollBarMaxHistory.Length; i++)
|
|
||||||
this.scrollBarMaxHistory[i] = -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,13 +110,7 @@ namespace MLEM.Ui.Elements {
|
||||||
throw new NotSupportedException($"A panel that handles overflow can't contain non-automatic anchors ({child})");
|
throw new NotSupportedException($"A panel that handles overflow can't contain non-automatic anchors ({child})");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
base.ForceUpdateArea();
|
base.ForceUpdateArea();
|
||||||
if (this.scrollOverflow) {
|
|
||||||
for (var i = 0; i < this.scrollBarMaxHistory.Length; i++)
|
|
||||||
this.scrollBarMaxHistory[i] = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.SetScrollBarStyle();
|
this.SetScrollBarStyle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,18 +271,11 @@ namespace MLEM.Ui.Elements {
|
||||||
}
|
}
|
||||||
|
|
||||||
// the max value of the scroll bar is the amount of non-scaled pixels taken up by overflowing components
|
// the max value of the scroll bar is the amount of non-scaled pixels taken up by overflowing components
|
||||||
var scrollBarMax = Math.Max(0, (childrenHeight - this.ChildPaddedArea.Height) / this.Scale);
|
var scrollBarMax = (childrenHeight - this.ChildPaddedArea.Height) / this.Scale;
|
||||||
if (!this.ScrollBar.MaxValue.Equals(scrollBarMax, Element.Epsilon)) {
|
if (!this.ScrollBar.MaxValue.Equals(scrollBarMax, Element.Epsilon)) {
|
||||||
// avoid a show/hide oscillation that occurs while updating our area with children that can lose height when the scroll bar is shown (like long paragraphs)
|
|
||||||
if (!this.scrollBarMaxHistory[0].Equals(this.scrollBarMaxHistory[2], Element.Epsilon) || !this.scrollBarMaxHistory[1].Equals(scrollBarMax, Element.Epsilon)) {
|
|
||||||
this.scrollBarMaxHistory[0] = this.scrollBarMaxHistory[1];
|
|
||||||
this.scrollBarMaxHistory[1] = this.scrollBarMaxHistory[2];
|
|
||||||
this.scrollBarMaxHistory[2] = scrollBarMax;
|
|
||||||
|
|
||||||
this.ScrollBar.MaxValue = scrollBarMax;
|
this.ScrollBar.MaxValue = scrollBarMax;
|
||||||
this.relevantChildrenDirty = true;
|
this.relevantChildrenDirty = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// update child padding based on whether the scroll bar is visible
|
// update child padding based on whether the scroll bar is visible
|
||||||
var childOffset = this.ScrollBar.IsHidden ? 0 : this.ScrollerSize.Value.X + this.ScrollBarOffset;
|
var childOffset = this.ScrollBar.IsHidden ? 0 : this.ScrollerSize.Value.X + this.ScrollBarOffset;
|
||||||
|
|
|
@ -23,9 +23,9 @@ namespace MLEM.Formatting.Codes {
|
||||||
public readonly Match Match;
|
public readonly Match Match;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The tokens that this formatting code is a part of.
|
/// The tokens that this formatting code is a part of.
|
||||||
/// Note that this collection only has multiple entries if additional tokens have to be started while this code is still applied.
|
/// Note that this array only has multiple entries if additional tokens have to be started while this code is still applied.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly List<Token> Tokens = new List<Token>();
|
public IList<Token> Tokens { get; internal set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new formatting code based on a formatting code regex and its match.
|
/// Creates a new formatting code based on a formatting code regex and its match.
|
||||||
|
|
|
@ -156,12 +156,11 @@ namespace MLEM.Formatting {
|
||||||
// resolve macros
|
// resolve macros
|
||||||
s = this.ResolveMacros(s);
|
s = this.ResolveMacros(s);
|
||||||
var tokens = new List<Token>();
|
var tokens = new List<Token>();
|
||||||
var applied = new List<Code>();
|
var codes = new List<Code>();
|
||||||
var allCodes = new List<Code>();
|
|
||||||
// add the formatting code right at the start of the string
|
// add the formatting code right at the start of the string
|
||||||
var firstCode = this.GetNextCode(s, 0, 0);
|
var firstCode = this.GetNextCode(s, 0, 0);
|
||||||
if (firstCode != null)
|
if (firstCode != null)
|
||||||
applied.Add(firstCode);
|
codes.Add(firstCode);
|
||||||
var index = 0;
|
var index = 0;
|
||||||
var rawIndex = 0;
|
var rawIndex = 0;
|
||||||
while (rawIndex < s.Length) {
|
while (rawIndex < s.Length) {
|
||||||
|
@ -169,25 +168,24 @@ namespace MLEM.Formatting {
|
||||||
// if we've reached the end of the string
|
// if we've reached the end of the string
|
||||||
if (next == null) {
|
if (next == null) {
|
||||||
var sub = s.Substring(rawIndex, s.Length - rawIndex);
|
var sub = s.Substring(rawIndex, s.Length - rawIndex);
|
||||||
tokens.Add(new Token(applied.ToArray(), index, rawIndex, TextFormatter.StripFormatting(font, sub, applied), sub));
|
tokens.Add(new Token(codes.ToArray(), index, rawIndex, TextFormatter.StripFormatting(font, sub, codes), sub));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
allCodes.Add(next);
|
|
||||||
|
|
||||||
// create a new token for the content up to the next code
|
// create a new token for the content up to the next code
|
||||||
var ret = s.Substring(rawIndex, next.Match.Index - rawIndex);
|
var ret = s.Substring(rawIndex, next.Match.Index - rawIndex);
|
||||||
var strippedRet = TextFormatter.StripFormatting(font, ret, applied);
|
var strippedRet = TextFormatter.StripFormatting(font, ret, codes);
|
||||||
tokens.Add(new Token(applied.ToArray(), index, rawIndex, strippedRet, ret));
|
tokens.Add(new Token(codes.ToArray(), index, rawIndex, strippedRet, ret));
|
||||||
|
|
||||||
// move to the start of the next code
|
// move to the start of the next code
|
||||||
rawIndex = next.Match.Index;
|
rawIndex = next.Match.Index;
|
||||||
index += strippedRet.Length;
|
index += strippedRet.Length;
|
||||||
|
|
||||||
// remove all codes that are incompatible with the next one and apply it
|
// remove all codes that are incompatible with the next one and apply it
|
||||||
applied.RemoveAll(c => c.EndsHere(next) || next.EndsOther(c));
|
codes.RemoveAll(c => c.EndsHere(next) || next.EndsOther(c));
|
||||||
applied.Add(next);
|
codes.Add(next);
|
||||||
}
|
}
|
||||||
return new TokenizedString(font, alignment, s, TextFormatter.StripFormatting(font, s, allCodes), tokens.ToArray(), allCodes.ToArray());
|
return new TokenizedString(font, alignment, s, TextFormatter.StripFormatting(font, s, tokens.SelectMany(t => t.AppliedCodes)), tokens.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -50,8 +50,6 @@ namespace MLEM.Formatting {
|
||||||
this.RawIndex = rawIndex;
|
this.RawIndex = rawIndex;
|
||||||
this.Substring = substring;
|
this.Substring = substring;
|
||||||
this.RawSubstring = rawSubstring;
|
this.RawSubstring = rawSubstring;
|
||||||
foreach (var code in appliedCodes)
|
|
||||||
code.Tokens.Add(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using MLEM.Extensions;
|
||||||
using MLEM.Font;
|
using MLEM.Font;
|
||||||
using MLEM.Formatting.Codes;
|
using MLEM.Formatting.Codes;
|
||||||
using MLEM.Misc;
|
using MLEM.Misc;
|
||||||
|
@ -40,11 +42,17 @@ namespace MLEM.Formatting {
|
||||||
private float initialInnerOffset;
|
private float initialInnerOffset;
|
||||||
private RectangleF area;
|
private RectangleF area;
|
||||||
|
|
||||||
internal TokenizedString(GenericFont font, TextAlignment alignment, string rawString, string strg, Token[] tokens, Code[] allCodes) {
|
internal TokenizedString(GenericFont font, TextAlignment alignment, string rawString, string strg, Token[] tokens) {
|
||||||
this.RawString = rawString;
|
this.RawString = rawString;
|
||||||
this.String = strg;
|
this.String = strg;
|
||||||
this.Tokens = tokens;
|
this.Tokens = tokens;
|
||||||
this.AllCodes = allCodes;
|
|
||||||
|
// since a code can be present in multiple tokens, we use Distinct here
|
||||||
|
this.AllCodes = tokens.SelectMany(t => t.AppliedCodes).Distinct().ToArray();
|
||||||
|
// TODO this can probably be optimized by keeping track of a code's tokens while tokenizing
|
||||||
|
foreach (var code in this.AllCodes)
|
||||||
|
code.Tokens = new ReadOnlyCollection<Token>(this.Tokens.Where(t => t.AppliedCodes.Contains(code)).ToList());
|
||||||
|
|
||||||
this.Realign(font, alignment);
|
this.Realign(font, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue