Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions TextControlBox-TestApp/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ public MainWindow()
textbox.NumberOfSpacesForTab = 4;
textbox.ShowWhitespaceCharacters = true;

textbox.ContentVerticalScrollOffset = new TextControlBoxNS.Models.Structs.VerticalScrollOffset(100, 100);

SetWindowTheme(this, ElementTheme.Dark);

textbox.LinkClicked += Textbox_LinkClicked;
Expand Down
6 changes: 5 additions & 1 deletion TextControlBox/Core/CoreTextControlBox.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<xaml:CanvasControl
Grid.Column="0"
x:Name="Canvas_LineNumber"
Expand Down Expand Up @@ -61,8 +65,8 @@
VerticalAlignment="Stretch"/>

<ScrollBar Grid.Column="2" PointerEntered="Scrollbar_PointerEntered" PointerExited="Scrollbar_PointerExited" SmallChange="10" Maximum="0" LargeChange="100" Minimum="0" x:Name="VerticalScrollbar" Value="0" IndicatorMode="MouseIndicator" Background="Transparent" HorizontalAlignment="Right" Orientation="Vertical" VerticalAlignment="Stretch"/>
<ScrollBar PointerEntered="Scrollbar_PointerEntered" PointerExited="Scrollbar_PointerExited" SmallChange="10" LargeChange="100" Minimum="0" Maximum="0" x:Name="HorizontalScrollbar" Value="0" IndicatorMode="MouseIndicator" Background="Transparent" HorizontalAlignment="Stretch" Orientation="Horizontal" VerticalAlignment="Bottom"/>
</Grid>
<ScrollBar Grid.Row="2" Grid.ColumnSpan="2" PointerEntered="Scrollbar_PointerEntered" PointerExited="Scrollbar_PointerExited" SmallChange="10" LargeChange="100" Minimum="0" Maximum="0" x:Name="HorizontalScrollbar" Value="0" IndicatorMode="MouseIndicator" Background="Transparent" HorizontalAlignment="Stretch" Orientation="Horizontal" VerticalAlignment="Bottom"/>
<controls:InputHandlerControl x:Name="inputHandler" GotFocus="InputManager_GotFocus" LostFocus="InputManager_LostFocus" PreviewKeyDown="InputHandler_KeyDown" TextEntered="InputHandler_TextEntered" Grid.Column="1" Opacity="0" Width="0" Height="0"/>
</Grid>
</UserControl>
18 changes: 18 additions & 0 deletions TextControlBox/Core/CoreTextControlBox.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using TextControlBoxNS.Languages;
using TextControlBoxNS.Models;
using TextControlBoxNS.Models.Enums;
using TextControlBoxNS.Models.Structs;
using Windows.ApplicationModel.DataTransfer;
using Windows.Foundation;
using Windows.System;
Expand Down Expand Up @@ -985,6 +986,23 @@ public void EndActionGroup()
}
public bool IsGroupingActions => undoRedo.IsGroupingActions;

private VerticalScrollOffset _ContentVerticalScrollOffset = new(0);

public VerticalScrollOffset ContentVerticalScrollOffset
{
get => _ContentVerticalScrollOffset;
set
{
_ContentVerticalScrollOffset = value;

textRenderer.UpdateScrollOffset(value);
Canvas_Text.UpdateLayout();
Canvas_Selection.UpdateLayout();
Canvas_Cursor.UpdateLayout();
Canvas_LineNumber.UpdateLayout();
}
}

public bool EnableSyntaxHighlighting { get; set; } = true;

public SyntaxHighlightLanguage SyntaxHighlighting
Expand Down
2 changes: 1 addition & 1 deletion TextControlBox/Core/PointerActionsManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ public void PointerWheelAction(ZoomManager zoomManager, PointerRoutedEventArgs e
{
scrollManager.verticalScrollBar.Value -= (delta * scrollManager._VerticalScrollSensitivity) / scrollManager.DefaultVerticalScrollSensitivity;
//Only update when a line was scrolled
if ((int)(scrollManager.verticalScrollBar.Value / textRenderer.SingleLineHeight * scrollManager.DefaultVerticalScrollSensitivity) != textRenderer.NumberOfStartLine)
if ((int)(scrollManager.verticalScrollBar.Value / textRenderer.SingleLineHeight * scrollManager.DefaultVerticalScrollSensitivity + textRenderer.VerticalDrawOffset) != textRenderer.NumberOfStartLine)
{
needsUpdate = true;
}
Expand Down
2 changes: 1 addition & 1 deletion TextControlBox/Core/Renderer/CursorRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public void Draw(CanvasControl canvasText, CanvasControl canvasCursor, CanvasDra
float singleLineHeight = textRenderer.SingleLineHeight;

//Calculate the distance to the top for the cursorposition and render the cursor
float renderPosY = (float)((cursorManager.LineNumber - startLine) * singleLineHeight) + singleLineHeight / scrollManager.DefaultVerticalScrollSensitivity;
float renderPosY = (float)((cursorManager.LineNumber - startLine) * singleLineHeight) + singleLineHeight / scrollManager.DefaultVerticalScrollSensitivity + textRenderer.VerticalDrawOffset;

//Out of display-region:
if (renderPosY > linesToRender * singleLineHeight || renderPosY < 0)
Expand Down
2 changes: 1 addition & 1 deletion TextControlBox/Core/Renderer/LineNumberRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public void Draw(CanvasControl canvas, CanvasDrawEventArgs args, float spaceBetw

OldLineNumberTextToRender = LineNumberTextToRender;
LineNumberTextLayout = textLayoutManager.CreateTextLayout(canvas, LineNumberTextFormat, LineNumberTextToRender, posX, (float)canvas.Size.Height);
args.DrawingSession.DrawTextLayout(LineNumberTextLayout, 10, textRenderer.SingleLineHeight, designHelper.LineNumberColorBrush);
args.DrawingSession.DrawTextLayout(LineNumberTextLayout, 10, textRenderer.VerticalDrawOffset + textRenderer.SingleLineHeight, designHelper.LineNumberColorBrush);
}

public void CreateLineNumberTextFormat()
Expand Down
2 changes: 1 addition & 1 deletion TextControlBox/Core/Renderer/SelectionRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ public void Draw(CanvasControl canvasSelection, CanvasDrawEventArgs args)
textRenderer.DrawnTextLayout,
args,
(float)-scrollManager.HorizontalScroll,
textRenderer.SingleLineHeight / scrollManager.DefaultVerticalScrollSensitivity,
textRenderer.SingleLineHeight / scrollManager.DefaultVerticalScrollSensitivity + textRenderer.VerticalDrawOffset,
textRenderer.NumberOfStartLine,
textRenderer.NumberOfRenderedLines,
zoomManager.ZoomedFontSize,
Expand Down
52 changes: 46 additions & 6 deletions TextControlBox/Core/Renderer/TextRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Runtime.InteropServices;
using TextControlBoxNS.Core.Text;
using TextControlBoxNS.Helper;
using TextControlBoxNS.Models.Structs;
using Windows.Foundation;

namespace TextControlBoxNS.Core.Renderer;
Expand All @@ -27,6 +28,10 @@ internal class TextRenderer
public int NumberOfRenderedLines = 0;
public string RenderedText = "";
public string OldRenderedText = null;
public float VerticalDrawOffset { get; private set; } = 0;

public double TopScrollOffset { get; private set; } = 0;
public double BottomScrollOffset { get; private set; } = 0;

private CursorManager cursorManager;
private TextManager textManager;
Expand Down Expand Up @@ -75,6 +80,14 @@ public void Init(
this.invisibleCharactersRenderer = invisibleCharactersRenderer;
this.linkRenderer = linkRenderer;
this.linkHighlightManager = linkHighlightManager;

UpdateScrollOffset(coreTextbox.ContentVerticalScrollOffset);
}

public void UpdateScrollOffset(VerticalScrollOffset verticalScrollOffset)
{
this.TopScrollOffset = verticalScrollOffset.Top;
this.BottomScrollOffset = verticalScrollOffset.Bottom;
}

//Check whether the current line is outside the bounds of the visible area
Expand All @@ -99,24 +112,49 @@ public void UpdateCurrentLineTextLayout(CanvasControl canvasText)
var singleLineHeight = SingleLineHeight;

//Measure text position and apply the value to the scrollbar
scrollManager.verticalScrollBar.Maximum = ((textManager.LinesCount + 1) * singleLineHeight - scrollGrid.ActualHeight) / scrollManager.DefaultVerticalScrollSensitivity;
scrollManager.verticalScrollBar.Maximum = ((textManager.LinesCount + 1) * singleLineHeight - scrollGrid.ActualHeight + BottomScrollOffset + TopScrollOffset) / scrollManager.DefaultVerticalScrollSensitivity;
scrollManager.verticalScrollBar.ViewportSize = coreTextbox.canvasText.ActualHeight;

//Calculate number of lines that need to be rendered
int linesToRenderCount = (int)(coreTextbox.canvasText.ActualHeight / singleLineHeight);
linesToRenderCount = Math.Min(linesToRenderCount, textManager.LinesCount);
linesToRenderCount = Math.Min(Math.Max(linesToRenderCount, 1), textManager.LinesCount);

int startLine = (int)((scrollManager.VerticalScroll * scrollManager.DefaultVerticalScrollSensitivity) / singleLineHeight);
int startLine = (int)(((scrollManager.VerticalScroll - VerticalDrawOffset) * scrollManager.DefaultVerticalScrollSensitivity - TopScrollOffset) / singleLineHeight);
startLine = Math.Min(startLine, textManager.LinesCount);

if (startLine < 0) startLine = 0;

int linesToRender = Math.Min(linesToRenderCount, textManager.LinesCount - startLine);

return (startLine, linesToRender);
}

public float CalculateDrawOffset()
{
double verticalScroll = scrollManager.VerticalScroll;

double scrollCoeff = scrollManager.verticalScrollBar.Maximum / scrollManager.VerticalScroll;

double realScrollPosition = verticalScroll * scrollManager.DefaultVerticalScrollSensitivity - TopScrollOffset;
double preCalcOffset = realScrollPosition < 0 ? -realScrollPosition : SingleLineHeight;

float drawOffset = (float)(preCalcOffset < SingleLineHeight ? SingleLineHeight : Math.Floor(preCalcOffset / SingleLineHeight) * SingleLineHeight);

if (drawOffset > SingleLineHeight)
{
if (scrollCoeff == 1)
{
drawOffset = SingleLineHeight;
}
}
return drawOffset - SingleLineHeight;
}


public void Draw(CanvasControl canvasText, CanvasDrawEventArgs args)
{
VerticalDrawOffset = CalculateDrawOffset();

//Create resources and layouts:
if (NeedsTextFormatUpdate || TextFormat == null || lineNumberRenderer.LineNumberTextFormat == null)
{
Expand Down Expand Up @@ -171,13 +209,13 @@ public void Draw(CanvasControl canvasText, CanvasDrawEventArgs args)
searchManager.MatchingSearchLines,
searchManager.searchParameter.SearchExpression,
(float)-scrollManager.HorizontalScroll,
SingleLineHeight / scrollManager.DefaultVerticalScrollSensitivity,
SingleLineHeight / scrollManager.DefaultVerticalScrollSensitivity + VerticalDrawOffset,
designHelper._Design.SearchHighlightColor
);

ccls.DrawTextLayout(DrawnTextLayout, (float)-scrollManager.HorizontalScroll, SingleLineHeight, designHelper.TextColorBrush);
ccls.DrawTextLayout(DrawnTextLayout, (float)-scrollManager.HorizontalScroll, VerticalDrawOffset + SingleLineHeight, designHelper.TextColorBrush);

invisibleCharactersRenderer.DrawTabsAndSpaces(args, ccls, RenderedText, DrawnTextLayout, SingleLineHeight);
invisibleCharactersRenderer.DrawTabsAndSpaces(args, ccls, RenderedText, DrawnTextLayout, VerticalDrawOffset + SingleLineHeight);
}
args.DrawingSession.DrawImage(canvasCommandList);

Expand All @@ -189,5 +227,7 @@ public void Draw(CanvasControl canvasText, CanvasDrawEventArgs args)
{
canvasUpdateManager.UpdateLineNumbers();
}
canvasUpdateManager.UpdateSelection(); // Possible bad for performanse
canvasUpdateManager.UpdateCursor(); // Possible bad for performanse
}
}
30 changes: 25 additions & 5 deletions TextControlBox/Core/ScrollManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ internal void HorizontalScrollBar_Scroll(object sender, ScrollEventArgs e)
internal void VerticalScrollBar_Scroll(object sender, ScrollEventArgs e)
{
//only update when a line was scrolled
if ((int)(verticalScrollBar.Value / textRenderer.SingleLineHeight * DefaultVerticalScrollSensitivity) != textRenderer.NumberOfStartLine)
if ((int)(verticalScrollBar.Value / textRenderer.SingleLineHeight * DefaultVerticalScrollSensitivity + textRenderer.VerticalDrawOffset ) != textRenderer.NumberOfStartLine)
{
canvasHelper.UpdateAll();
}
Expand All @@ -66,7 +66,7 @@ internal void VerticalScrollBar_Scroll(object sender, ScrollEventArgs e)
public void UpdateWhenScrolled()
{
//only update when a line was scrolled
if ((int)(verticalScrollBar.Value / textRenderer.SingleLineHeight) != textRenderer.NumberOfStartLine)
if ((int)(verticalScrollBar.Value / textRenderer.SingleLineHeight + textRenderer.VerticalDrawOffset) != textRenderer.NumberOfStartLine)
{
canvasHelper.UpdateAll();
}
Expand Down Expand Up @@ -133,10 +133,30 @@ public void ScrollPageDown()
}
public void UpdateScrollToShowCursor(bool update = true)
{
if (textRenderer.NumberOfStartLine + textRenderer.NumberOfRenderedLines <= cursorManager.LineNumber)
verticalScrollBar.Value = (cursorManager.LineNumber - textRenderer.NumberOfRenderedLines + 1) * textRenderer.SingleLineHeight / DefaultVerticalScrollSensitivity;
double globalOffset = textRenderer.VerticalDrawOffset == 0 ? textRenderer.TopScrollOffset : 0;
double localOffset = textRenderer.VerticalDrawOffset;

if (cursorManager.LineNumber == 0)
{
verticalScrollBar.Value = 0;
}
else if (textRenderer.NumberOfStartLine + textRenderer.NumberOfRenderedLines <= cursorManager.LineNumber)
{
verticalScrollBar.Value = ((cursorManager.LineNumber - textRenderer.NumberOfRenderedLines + 1) * textRenderer.SingleLineHeight + globalOffset) / DefaultVerticalScrollSensitivity + localOffset;
}
else if (textRenderer.NumberOfStartLine > cursorManager.LineNumber)
verticalScrollBar.Value = (cursorManager.LineNumber - 1) * textRenderer.SingleLineHeight / DefaultVerticalScrollSensitivity;
{
verticalScrollBar.Value = ((cursorManager.LineNumber - 1) * textRenderer.SingleLineHeight + globalOffset) / DefaultVerticalScrollSensitivity + localOffset;
}
else if (textRenderer.VerticalDrawOffset != 0)
{
int realLineDisplayedCount = (int)((verticalScrollBar.ViewportSize - textRenderer.VerticalDrawOffset) / textRenderer.SingleLineHeight);
if (realLineDisplayedCount <= cursorManager.LineNumber)
{
double offsetToMove = ((cursorManager.LineNumber - realLineDisplayedCount + 1) * textRenderer.SingleLineHeight);
verticalScrollBar.Value = ((cursorManager.LineNumber - 1) * textRenderer.SingleLineHeight) / DefaultVerticalScrollSensitivity + offsetToMove;
}
}

if (update)
canvasHelper.UpdateAll();
Expand Down
2 changes: 1 addition & 1 deletion TextControlBox/Helper/CursorHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ internal class CursorHelper
public static int GetCursorLineFromPoint(TextRenderer textRenderer, Point point)
{
//Calculate the relative linenumber, where the pointer was pressed at
int linenumber = (int)(point.Y / textRenderer.SingleLineHeight);
int linenumber = (int)((point.Y - textRenderer.VerticalDrawOffset) / textRenderer.SingleLineHeight);
linenumber += textRenderer.NumberOfStartLine;
return Math.Clamp(linenumber, 0, textRenderer.NumberOfStartLine + textRenderer.NumberOfRenderedLines - 1);
}
Expand Down
Loading