Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix caret cursor #212

Merged
merged 10 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
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
12 changes: 12 additions & 0 deletions src/Consolonia.Core/Drawing/CaretStyle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Consolonia.Core.Drawing
{
public enum CaretStyle
{
BlinkingBar,
SteadyBar,
BlinkingBlock,
SteadyBlock,
BlinkingUnderline,
SteadyUnderline
}
}
27 changes: 20 additions & 7 deletions src/Consolonia.Core/Drawing/DrawingContextImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,17 @@ public void DrawGeometry(IBrush brush, IPen pen, IGeometryImpl geometry)
if (sceneBrushContent != null) sceneBrushContent.Render(this, Matrix.Identity);
return;
}
case MoveConsoleCaretToPositionBrush moveBrush:
{
Point head = r.TopLeft.Transform(Transform);
_pixelBuffer.CaretStyle = moveBrush.CaretStyle;
CurrentClip.ExecuteWithClipping(head,
() =>
{
_pixelBuffer.Set((PixelBufferCoordinate)head, pixel => pixel.Blend(new Pixel(true)));
});
return;
}
}

FillRectangleWithBrush(brush, pen, r);
Expand Down Expand Up @@ -458,6 +469,15 @@ private void DrawLineInternal(IPen pen, Line line)
return;
}

if (pen.Brush is MoveConsoleCaretToPositionBrush moveBrush)
{
_pixelBuffer.CaretStyle = moveBrush.CaretStyle;
Point head = line.PStart.Transform(Transform);
CurrentClip.ExecuteWithClipping(head,
() => { _pixelBuffer.Set((PixelBufferCoordinate)head, pixel => pixel.Blend(new Pixel(true))); });
return;
}
tomlm marked this conversation as resolved.
Show resolved Hide resolved

DrawBoxLineInternal(pen, line, RectangleLinePosition.Unknown);
}

Expand Down Expand Up @@ -532,13 +552,6 @@ private void DrawBoxLineInternal(IPen pen, Line line, RectangleLinePosition line

Point head = line.PStart;

if (pen.Brush is MoveConsoleCaretToPositionBrush)
{
CurrentClip.ExecuteWithClipping(head,
() => { _pixelBuffer.Set((PixelBufferCoordinate)head, pixel => pixel.Blend(new Pixel(true))); });
return;
}

var extractColorCheckPlatformSupported = ExtractColorOrNullWithPlatformCheck(pen, out var lineStyle);
if (extractColorCheckPlatformSupported == null)
return;
Expand Down
14 changes: 13 additions & 1 deletion src/Consolonia.Core/Drawing/MoveConsoleCaretToPositionBrush.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,20 @@

namespace Consolonia.Core.Drawing
{
public class MoveConsoleCaretToPositionBrush : IImmutableBrush
public class MoveConsoleCaretToPositionBrush : AvaloniaObject, IImmutableBrush
{
public static readonly StyledProperty<CaretStyle> CaretStyleProperty =
AvaloniaProperty.Register<MoveConsoleCaretToPositionBrush, CaretStyle>(nameof(CaretStyle));

/// <summary>
/// style of caret
/// </summary>
public CaretStyle CaretStyle
{
get => GetValue(CaretStyleProperty);
set => SetValue(CaretStyleProperty, value);
}

//todo: Search for B75ABC91-2CDD-4557-9201-16AC483C8D7B
public double Opacity => 1;
public ITransform Transform => null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ public PixelBuffer(ushort width, ushort height)
public ushort Width { get; }
public ushort Height { get; }

public CaretStyle CaretStyle { get; set; } = CaretStyle.BlinkingBar;

// ReSharper disable once UnusedMember.Global
[JsonIgnore]
public Pixel this[int i]
Expand Down
13 changes: 13 additions & 0 deletions src/Consolonia.Core/Drawing/RenderTarget.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Avalonia.Platform;
using Consolonia.Core.Drawing.PixelBufferImplementation;
using Consolonia.Core.Infrastructure;
using Consolonia.Core.Text;

namespace Consolonia.Core.Drawing
{
Expand Down Expand Up @@ -141,11 +142,23 @@ private void RenderToDevice()
if (caretPosition != null)
{
_console.SetCaretPosition((PixelBufferCoordinate)caretPosition);
_console.WriteText(pixelBuffer.CaretStyle switch
{
CaretStyle.BlinkingBar => Esc.BlinkingBarCursor,
CaretStyle.SteadyBar => Esc.SteadyBarCursor,
CaretStyle.BlinkingBlock => Esc.BlinkingBlockCursor,
CaretStyle.SteadyBlock => Esc.SteadyBlockCursor,
CaretStyle.BlinkingUnderline => Esc.BlinkingUnderlineCursor,
CaretStyle.SteadyUnderline => Esc.SteadyUnderlineCursor,
_ => throw new ArgumentOutOfRangeException()
});
_console.WriteText(Esc.ShowCursor);
_console.CaretVisible = true;
}
else
{
_console.CaretVisible = false;
_console.WriteText(Esc.HideCursor);
}
}

Expand Down
14 changes: 1 addition & 13 deletions src/Consolonia.Core/Infrastructure/InputLessDefaultNetConsole.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ namespace Consolonia.Core.Infrastructure
public abstract class InputLessDefaultNetConsole : IConsole
{
private const string TestEmoji = "👨‍👩‍👧‍👦";
private bool _caretVisible;
private PixelBufferCoordinate _headBufferPoint;

private bool? _supportEmoji;
Expand All @@ -32,18 +31,7 @@ protected InputLessDefaultNetConsole()

protected Task PauseTask { get; private set; }

public bool CaretVisible
{
get => _caretVisible;
#pragma warning disable CA1303 // Do not pass literals as localized parameters
set
{
if (_caretVisible == value) return;
WriteText(value ? Esc.ShowCursor : Esc.HideCursor);
_caretVisible = value;
}
#pragma warning restore CA1303 // Do not pass literals as localized parameters
}
public bool CaretVisible { get; set; }

public PixelBufferSize Size { get; private set; }

Expand Down
8 changes: 8 additions & 0 deletions src/Consolonia.Core/Text/Esc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ internal static class Esc
public const string HideCursor = "\u001b[?25l";
public const string ShowCursor = "\u001b[?25h";

// cursor shape
public const string BlinkingBlockCursor = "\u001b[1 q";
public const string SteadyBlockCursor = "\u001b[2 q";
public const string BlinkingUnderlineCursor = "\u001b[3 q";
public const string SteadyUnderlineCursor = "\u001b[4 q";
public const string BlinkingBarCursor = "\u001b[5 q";
public const string SteadyBarCursor = "\u001b[6 q";

// move cursor
public static string MoveCursorUp(int n)
{
Expand Down
29 changes: 7 additions & 22 deletions src/Consolonia.Themes/Templates/Controls/CaretControl.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,37 +10,22 @@
<Setter.Value>
<ControlTemplate>
<Grid Background="{TemplateBinding Background}">
<TextBlock Width="1"
<Rectangle Name="PART_CaretLine"
Width="1"
Height="1"
HorizontalAlignment="Left"
VerticalAlignment="Top"
IsHitTestVisible="False"
Background="{DynamicResource ThemeActionBackgroundBrush}"
IsVisible="{TemplateBinding IsCaretShown}"
Margin="{TemplateBinding Padding}"
Tag="This TextBlock is a hack. Otherwise Line below does not get redrawn in CheckBox">
<!--<TextBlock.Background>
<drawing:ConsoleBrush Mode="Transparent"/>
</TextBlock.Background>-->
</TextBlock>
IsVisible="{TemplateBinding IsCaretShown}">
<Rectangle.Fill>
<drawing:MoveConsoleCaretToPositionBrush CaretStyle="{Binding CaretStyle}" />
</Rectangle.Fill>
</Rectangle>
<ContentPresenter Name="PART_ContentPresenter"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" />
<Line Margin="{TemplateBinding Padding}"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Name="PART_CaretLine"
Width="1"
Height="1"
IsHitTestVisible="False"
IsVisible="{TemplateBinding IsCaretShown}"
StrokeThickness="1">
<Line.Stroke>
<drawing:MoveConsoleCaretToPositionBrush />
</Line.Stroke>
</Line>
</Grid>
</ControlTemplate>
</Setter.Value>
Expand Down
3 changes: 2 additions & 1 deletion src/Consolonia.Themes/Templates/Controls/ComboBoxItem.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
Value="Left" />
<Setter Property="Template">
<ControlTemplate>
<helpers:CaretControl IsCaretShown="{TemplateBinding IsFocused}">
<helpers:CaretControl IsCaretShown="{TemplateBinding IsFocused}"
CaretStyle="BlinkingBlock">
<ContentPresenter Name="PART_ContentPresenter"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Consolonia.Core.Drawing;

namespace Consolonia.Themes.Templates.Controls.Helpers
{
Expand All @@ -9,13 +10,21 @@ public class CaretControl : ContentControl
public static readonly StyledProperty<bool> IsCaretShownProperty =
AvaloniaProperty.Register<CaretControl, bool>(nameof(IsCaretShown));

public static readonly StyledProperty<CaretStyle> CaretStyleProperty =
AvaloniaProperty.Register<CaretControl, CaretStyle>(nameof(CaretStyle));

public bool IsCaretShown
{
get => GetValue(IsCaretShownProperty);
set => SetValue(IsCaretShownProperty, value);
}

public CaretStyle CaretStyle
{
get => GetValue(CaretStyleProperty);
set => SetValue(CaretStyleProperty, value);
}

protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
Expand Down
Loading