Skip to content

Commit

Permalink
feat(Studio): choose line number padding based on visible rows
Browse files Browse the repository at this point in the history
  • Loading branch information
jakobhellermann committed Sep 17, 2024
1 parent 8e13cd9 commit 0bd4c75
Showing 1 changed file with 20 additions and 5 deletions.
25 changes: 20 additions & 5 deletions Studio/CelesteStudio/Editing/Editor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ void HandleTextChanged(Document _, int minRow, int maxRow) {
private Point scrollablePosition;
private Size scrollableSize;

private int previousMaxDigits = -1;

private readonly PixelLayout pixelLayout = new();
private readonly PopupMenu autoCompleteMenu = new();
private readonly PopupMenu contextActionsMenu = new();
Expand Down Expand Up @@ -233,6 +235,8 @@ public PopupMenu? ActivePopupMenu {
private static readonly Regex TimestampRegex = new(@"^\s*#+\s*(\d+:)?\d{1,2}:\d{2}\.\d{3}\(\d+\)", RegexOptions.Compiled);
private static readonly Regex RoomLabelRegex = new($@"^{RoomLabelPrefix}([^\(\)]*)(?:\s\((\d+)\))?$", RegexOptions.Compiled);

private const int offscreenLinePadding = 3;

public Editor(Document document, Scrollable scrollable) {
this.document = document;
this.scrollable = scrollable;
Expand Down Expand Up @@ -273,6 +277,16 @@ public Editor(Document document, Scrollable scrollable) {
// Need to redraw the line numbers when scrolling horizontally
scrollable.Scroll += (_, _) => {
scrollablePosition = scrollable.ScrollPosition;

int bottomVisualRow = (int)((scrollablePosition.Y + scrollableSize.Height) / Font.LineHeight()) + offscreenLinePadding;
int bottomRow = Math.Min(Document.Lines.Count - 1, GetActualRow(bottomVisualRow));

int maxDigits = bottomRow.Digits();
if (previousMaxDigits != maxDigits) {
Recalc();
}
previousMaxDigits = maxDigits;

Invalidate();
};
// Update wrapped lines
Expand Down Expand Up @@ -593,16 +607,19 @@ private void Recalc() {
// Clear invalid foldings
Document.RemoveAnchorsIf(anchor => anchor.UserData is FoldingAnchorData && foldings.All(fold => fold.MinRow != anchor.Row));

int bottomVisualRow = (int)((scrollablePosition.Y + scrollableSize.Height) / Font.LineHeight()) + offscreenLinePadding;
int bottomRow = Math.Min(Document.Lines.Count - 1, GetActualRow(bottomVisualRow));

// Calculate line numbers width
const float foldButtonPadding = 5.0f;
bool hasFoldings = Settings.Instance.ShowFoldIndicators && foldings.Count != 0;
// Only when the alignment is to the left, the folding indicator can fit into the existing space
float foldingWidth = !hasFoldings ? 0.0f : Settings.Instance.LineNumberAlignment switch {
LineNumberAlignment.Left => Font.CharWidth() * (foldings[^1].MinRow.Digits() + 1) + foldButtonPadding,
LineNumberAlignment.Right => Font.CharWidth() * (Document.Lines.Count.Digits() + 1) + foldButtonPadding,
LineNumberAlignment.Right => Font.CharWidth() * (bottomRow.Digits() + 1) + foldButtonPadding,
_ => throw new UnreachableException(),
};
textOffsetX = Math.Max(foldingWidth, Font.CharWidth() * Document.Lines.Count.Digits()) + LineNumberPadding * 3.0f;
textOffsetX = Math.Max(foldingWidth, Font.CharWidth() * bottomRow.Digits()) + LineNumberPadding * 3.0f;

const float paddingRight = 50.0f;
const float paddingBottom = 100.0f;
Expand Down Expand Up @@ -3172,8 +3189,6 @@ protected override void OnPaint(PaintEventArgs e) {
// To be reused below. Kinda annoying how C# handles out parameter conflicts
WrapEntry wrap;

const int offscreenLinePadding = 3;

int topVisualRow = (int)(scrollablePosition.Y / Font.LineHeight()) - offscreenLinePadding;
int bottomVisualRow = (int)((scrollablePosition.Y + scrollableSize.Height) / Font.LineHeight()) + offscreenLinePadding;
int topRow = Math.Max(0, GetActualRow(topVisualRow));
Expand Down Expand Up @@ -3389,7 +3404,7 @@ protected override void OnPaint(PaintEventArgs e) {
if (Settings.Instance.LineNumberAlignment == LineNumberAlignment.Left) {
e.Graphics.DrawText(Font, textColor, scrollablePosition.X + LineNumberPadding, yPos, numberString);
} else if (Settings.Instance.LineNumberAlignment == LineNumberAlignment.Right) {
float ident = Font.CharWidth() * (Document.Lines.Count.Digits() - (row + 1).Digits());
float ident = Font.CharWidth() * (bottomRow - (row + 1).Digits());
e.Graphics.DrawText(Font, textColor, scrollablePosition.X + LineNumberPadding + ident, yPos, numberString);
}

Expand Down

0 comments on commit 0bd4c75

Please sign in to comment.