feat: implement drag.

This commit is contained in:
rabbitism
2024-01-14 23:11:24 +08:00
parent 631913145b
commit fbdef7d758
4 changed files with 118 additions and 40 deletions

View File

@@ -9,7 +9,13 @@
d:DesignWidth="800" d:DesignWidth="800"
mc:Ignorable="d"> mc:Ignorable="d">
<StackPanel> <StackPanel>
<u:IntUpDown Name="input" Step="1" Value="2" EmptyInputValue="0" /> <u:IntUpDown Name="input" Step="1" Value="2" Watermark="Input Value" />
<TextBlock Text="{Binding #input.Value}" ></TextBlock> <TextBlock Text="{Binding #input.Value}" ></TextBlock>
<u:DoubleUpDown Name="inputDouble" Step="0.5" Value="3.1" EmptyInputValue="1"></u:DoubleUpDown>
<TextBlock Text="{Binding #inputDouble.Value}"></TextBlock>
<u:ByteUpDown Name="inputByte" Step="1" Value="3" EmptyInputValue="1"></u:ByteUpDown>
<TextBlock Text="{Binding #inputByte.Value}"></TextBlock>
<TextBlock Text="Drag"></TextBlock>
<u:IntUpDown Step="1" Value="2" Watermark="Input Value" TextEditable="False" />
</StackPanel> </StackPanel>
</UserControl> </UserControl>

View File

@@ -1,7 +1,8 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui" <ResourceDictionary
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns="https://github.com/avaloniaui"
xmlns:u="https://irihi.tech/ursa"> xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
<!-- Add Resources Here --> xmlns:u="https://irihi.tech/ursa">
<!-- Add Resources Here -->
<ControlTheme x:Key="{x:Type u:NumericUpDown}" TargetType="{x:Type u:NumericUpDown}"> <ControlTheme x:Key="{x:Type u:NumericUpDown}" TargetType="{x:Type u:NumericUpDown}">
<Setter Property="NumericUpDown.VerticalContentAlignment" Value="Center" /> <Setter Property="NumericUpDown.VerticalContentAlignment" Value="Center" />
<Setter Property="NumericUpDown.CornerRadius" Value="{DynamicResource NumericUpDownCornerRadius}" /> <Setter Property="NumericUpDown.CornerRadius" Value="{DynamicResource NumericUpDownCornerRadius}" />
@@ -16,21 +17,30 @@
AllowSpin="{TemplateBinding AllowSpin}" AllowSpin="{TemplateBinding AllowSpin}"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}">
> <Panel>
<TextBox <TextBox
Name="PART_TextBox" Name="PART_TextBox"
Height="{TemplateBinding Height}" Height="{TemplateBinding Height}"
MinHeight="{DynamicResource NumericUpDownWrapperDefaultHeight}" MinHeight="{DynamicResource NumericUpDownWrapperDefaultHeight}"
AcceptsReturn="False" AcceptsReturn="False"
CornerRadius="{TemplateBinding CornerRadius}" CornerRadius="{TemplateBinding CornerRadius}"
DataValidationErrors.Errors="{ReflectionBinding $parent[NumericUpDown].(DataValidationErrors.Errors)}" DataValidationErrors.Errors="{ReflectionBinding $parent[NumericUpDown].(DataValidationErrors.Errors)}"
FontSize="{TemplateBinding FontSize}" FontSize="{TemplateBinding FontSize}"
Foreground="{TemplateBinding Foreground}" Foreground="{TemplateBinding Foreground}"
IsReadOnly="{TemplateBinding IsReadOnly}" IsReadOnly="{TemplateBinding IsReadOnly}"
TextWrapping="NoWrap" TextWrapping="NoWrap"
Theme="{DynamicResource NonErrorTextBox}" Theme="{DynamicResource NonErrorTextBox}"
Watermark="{TemplateBinding Watermark}" /> Watermark="{TemplateBinding Watermark}" />
<Panel
Name="PART_DragPanel"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="Transparent"
Cursor="SizeAll"
IsVisible="{TemplateBinding TextEditable,
Converter={x:Static BoolConverters.Not}}" />
</Panel>
</ButtonSpinner> </ButtonSpinner>
</DataValidationErrors> </DataValidationErrors>
</ControlTemplate> </ControlTemplate>

View File

@@ -30,3 +30,58 @@ public class IntUpDown : NumericUpDownBase<int>
protected override int? Minus(int? a, int? b) => a - b; protected override int? Minus(int? a, int? b) => a - b;
} }
public class DoubleUpDown : NumericUpDownBase<double>
{
protected override Type StyleKeyOverride { get; } = typeof(NumericUpDown);
static DoubleUpDown()
{
MaximumProperty.OverrideDefaultValue<DoubleUpDown>(double.MaxValue);
MinimumProperty.OverrideDefaultValue<DoubleUpDown>(double.MinValue);
StepProperty.OverrideDefaultValue<DoubleUpDown>(1);
}
protected override bool ParseText(string? text, out double? number)
{
// Weird bug
var result = double.TryParse(text, out var value);
number = value;
return result;
}
protected override string? ValueToString(double? value) => value?.ToString(FormatString, NumberFormat);
protected override double Zero => 0;
protected override double? Add(double? a, double? b) => a + b;
protected override double? Minus(double? a, double? b) => a - b;
}
public class ByteUpDown : NumericUpDownBase<byte>
{
protected override Type StyleKeyOverride { get; } = typeof(NumericUpDown);
static ByteUpDown()
{
MaximumProperty.OverrideDefaultValue<ByteUpDown>(byte.MaxValue);
MinimumProperty.OverrideDefaultValue<ByteUpDown>(byte.MinValue);
StepProperty.OverrideDefaultValue<ByteUpDown>(1);
}
protected override bool ParseText(string? text, out byte? number)
{
var result = byte.TryParse(text, ParsingNumberStyle, NumberFormat, out var value);
number = value;
return result;
}
protected override string? ValueToString(byte? value) => value?.ToString(FormatString, NumberFormat);
protected override byte Zero => 0;
protected override byte? Add(byte? a, byte? b) => (byte?) (a + b);
protected override byte? Minus(byte? a, byte? b) => (byte?) (a - b);
}

View File

@@ -1,4 +1,5 @@
using System.Globalization; using System.Diagnostics;
using System.Globalization;
using System.Net.Mime; using System.Net.Mime;
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
@@ -156,12 +157,6 @@ public abstract class NumericUpDown : TemplatedControl
{ {
_spinner.Spin -= OnSpin; _spinner.Spin -= OnSpin;
} }
if(_textBox is not null)
{
_textBox.TextChanged -= OnTextChange;
}
if (_dragPanel is not null) if (_dragPanel is not null)
{ {
_dragPanel.PointerPressed -= OnDragPanelPointerPressed; _dragPanel.PointerPressed -= OnDragPanelPointerPressed;
@@ -170,16 +165,11 @@ public abstract class NumericUpDown : TemplatedControl
} }
_spinner = e.NameScope.Find<ButtonSpinner>(PART_Spinner); _spinner = e.NameScope.Find<ButtonSpinner>(PART_Spinner);
_textBox = e.NameScope.Find<TextBox>(PART_TextBox); _textBox = e.NameScope.Find<TextBox>(PART_TextBox);
_dragPanel = e.NameScope.Find<Panel>(PART_DragPanel);
if (_spinner is not null) if (_spinner is not null)
{ {
_spinner.Spin += OnSpin; _spinner.Spin += OnSpin;
} }
if (_textBox is not null)
{
_textBox.TextChanged += OnTextChange;
}
if (_dragPanel is not null) if (_dragPanel is not null)
{ {
_dragPanel.PointerPressed+= OnDragPanelPointerPressed; _dragPanel.PointerPressed+= OnDragPanelPointerPressed;
@@ -199,7 +189,7 @@ public abstract class NumericUpDown : TemplatedControl
{ {
if (e.Key == Key.Enter) if (e.Key == Key.Enter)
{ {
var commitSuccess = CommitInput(); var commitSuccess = CommitInput(true);
e.Handled = !commitSuccess; e.Handled = !commitSuccess;
} }
} }
@@ -216,20 +206,36 @@ public abstract class NumericUpDown : TemplatedControl
private void OnDragPanelPointerMoved(object sender, PointerEventArgs e) private void OnDragPanelPointerMoved(object sender, PointerEventArgs e)
{ {
if (TextEditable) return;
if(!e.GetCurrentPoint(this).Properties.IsLeftButtonPressed) return;
var point = e.GetPosition(this); var point = e.GetPosition(this);
var delta = point - _point; var delta = point - _point;
if (delta is null) if (delta is null)
{ {
return; return;
} }
int d = GetDelta(delta.Value);
if(d > 0)
{
Increase();
}
else if (d < 0)
{
Decrease();
}
_point = point;
} }
[Obsolete] private int GetDelta(Point point)
private void OnTextChange(object sender, TextChangedEventArgs e)
{ {
_updateFromTextInput = true; bool horizontal = Math.Abs(point.X) > Math.Abs(point.Y);
SyncTextAndValue(); var value = horizontal ? point.X : point.Y;
_updateFromTextInput = false; return value switch
{
> 0 => 1,
< 0 => -1,
_ => 0
};
} }
private void OnSpin(object sender, SpinEventArgs e) private void OnSpin(object sender, SpinEventArgs e)
@@ -495,6 +501,7 @@ public abstract class NumericUpDownBase<T>: NumericUpDown where T: struct, IComp
if (_textBox!= null && !Equals(_textBox.Text, newText)) if (_textBox!= null && !Equals(_textBox.Text, newText))
{ {
_textBox.Text = newText; _textBox.Text = newText;
_textBox.CaretIndex = newText?.Length??0;
} }
} }
} }