feat: use thumb in titlebar.

This commit is contained in:
rabbitism
2025-04-02 00:48:47 +08:00
parent 13891062c7
commit ddcaa9483d
3 changed files with 28 additions and 67 deletions

View File

@@ -107,8 +107,7 @@
<ControlTemplate TargetType="u:TitleBar">
<Panel Background="Transparent">
<Panel>
<Border
Name="PART_Background"
<u:WindowThumb
Background="{TemplateBinding Background}"
IsHitTestVisible="{TemplateBinding IsTitleBarHitTestVisible}" />
<Grid HorizontalAlignment="Stretch" ColumnDefinitions="Auto, *, Auto, Auto">
@@ -125,7 +124,7 @@
Content="{TemplateBinding RightContent}"
IsVisible="{TemplateBinding IsTitleVisible}" />
<u:CaptionButtons
x:Name="PART_CaptionButtons"
Name="{x:Static u:TitleBar.PART_CaptionButtons}"
Grid.Column="3"
HorizontalAlignment="Right"
VerticalAlignment="Top"

View File

@@ -2,17 +2,18 @@ using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Irihi.Avalonia.Shared.Common;
using Irihi.Avalonia.Shared.Helpers;
namespace Ursa.Controls;
[PseudoClasses(PseudoClassName.PC_Active)]
[TemplatePart(Name = PART_CaptionButtons, Type = typeof(CaptionButtons))]
public class TitleBar: ContentControl
{
public const string PART_CaptionButtons = "PART_CaptionButtons";
private CaptionButtons? _captionButtons;
private InputElement? _background;
private Window? _visualRoot;
private IDisposable? _activeSubscription;
@@ -58,10 +59,7 @@ public class TitleBar: ContentControl
{
base.OnApplyTemplate(e);
this._captionButtons?.Detach();
this._captionButtons = e.NameScope.Get<CaptionButtons>("PART_CaptionButtons");
this._background = e.NameScope.Get<InputElement>("PART_Background");
DoubleTappedEvent.AddHandler(OnDoubleTapped, _background);
PointerPressedEvent.AddHandler(OnPointerPressed, _background);
this._captionButtons = e.NameScope.Get<CaptionButtons>(PART_CaptionButtons);
this._captionButtons?.Attach(_visualRoot);
}
@@ -78,48 +76,6 @@ public class TitleBar: ContentControl
}
}
private void OnPointerPressed(object? sender, PointerPressedEventArgs e)
{
if(_visualRoot is not null && _visualRoot.WindowState == WindowState.FullScreen)
{
return;
}
if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
{
if (e.ClickCount < 2)
{
_visualRoot?.BeginMoveDrag(e);
}
}
}
private void OnDoubleTapped(object? sender, TappedEventArgs e)
{
if (_visualRoot is null) return;
if (!_visualRoot.CanResize) return;
if ( _visualRoot.WindowState == WindowState.FullScreen) return;
_visualRoot.WindowState = _visualRoot.WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized;
}
private void UpdateSize(Window window)
{
Thickness offScreenMargin = window.OffScreenMargin;
var left = offScreenMargin.Left;
offScreenMargin = window.OffScreenMargin;
double top = offScreenMargin.Top;
offScreenMargin = window.OffScreenMargin;
double right = offScreenMargin.Right;
offScreenMargin = window.OffScreenMargin;
double bottom = offScreenMargin.Bottom;
this.Margin = new Thickness(left, top, right, bottom);
if (window.WindowState != WindowState.FullScreen)
{
this.Height = window.WindowDecorationMargin.Top;
if (this._captionButtons != null)
this._captionButtons.Height = this.Height;
}
}
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnDetachedFromVisualTree(e);

View File

@@ -1,5 +1,6 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Media;
@@ -8,44 +9,49 @@ namespace Ursa.Controls;
public class WindowThumb: Control
{
public static readonly StyledProperty<IBrush?> BackgroundProperty = AvaloniaProperty.Register<WindowThumb, IBrush?>(
nameof(Background), Brushes.Transparent);
public static readonly StyledProperty<IBrush?> BackgroundProperty =
TemplatedControl.BackgroundProperty.AddOwner<WindowThumb>();
public IBrush? Background
{
get => GetValue(BackgroundProperty);
set => SetValue(BackgroundProperty, value);
}
static WindowThumb()
{
IsHitTestVisibleProperty.OverrideDefaultValue<WindowThumb>(true);
HorizontalAlignmentProperty.OverrideDefaultValue<WindowThumb>(Avalonia.Layout.HorizontalAlignment.Stretch);
VerticalAlignmentProperty.OverrideDefaultValue<WindowThumb>(Avalonia.Layout.VerticalAlignment.Stretch);
}
public WindowThumb()
{
this.AddHandler(PointerPressedEvent, OnPressed, RoutingStrategies.Direct);
this.AddHandler(DoubleTappedEvent, OnTapped, RoutingStrategies.Direct);
this.AddHandler(PointerPressedEvent, OnPressed);
this.AddHandler(DoubleTappedEvent, OnTapped);
}
private void OnTapped(object sender, TappedEventArgs e)
{
if (this.VisualRoot is not Window visualRoot) return;
if (!visualRoot.CanResize) return;
if ( visualRoot.WindowState == WindowState.FullScreen) return;
visualRoot.WindowState = visualRoot.WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized;
if (this.VisualRoot is not Window window) return;
if (!window.CanResize) return;
if ( window.WindowState == WindowState.FullScreen) return;
window.WindowState = window.WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized;
}
private void OnPressed(object sender, PointerPressedEventArgs e)
{
if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
if (!e.GetCurrentPoint(this).Properties.IsLeftButtonPressed) return;
if (e.ClickCount > 1) return;
if (VisualRoot is Window window)
{
if (VisualRoot is Window window)
{
window.BeginMoveDrag(e);
}
window.BeginMoveDrag(e);
}
}
public override void Render(DrawingContext context)
{
base.Render(context);
if(Background is not null)
{
context.FillRectangle(Background, new Rect(Bounds.Size));
}
}
}