Skip to content

Commit

Permalink
Add non-native title bar pointer over effects
Browse files Browse the repository at this point in the history
  • Loading branch information
bcssov committed Nov 20, 2024
1 parent e13f58e commit 21d3784
Show file tree
Hide file tree
Showing 8 changed files with 252 additions and 110 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
// Created : 11-23-2022
//
// Last Modified By : Mario
// Last Modified On : 11-23-2022
// Last Modified On : 11-20-2024
// ***********************************************************************
// <copyright file="IronyCaptionButtons.cs" company="Avalonia">
// Avalonia
// </copyright>
// <summary>Taken from avalonia.</summary>
// ***********************************************************************

using System;
using System.Collections.Generic;
using System.Linq;
Expand All @@ -19,6 +20,8 @@
using Avalonia.Controls;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Shapes;
using Avalonia.Media;
using Avalonia.Styling;

namespace IronyModManager.Controls.ClientSideDecorations
Expand All @@ -36,10 +39,40 @@ public class IronyCaptionButtons : TemplatedControl, IStyleable
{
#region Fields

/// <summary>
/// The full screen active
/// </summary>
private static readonly PathGeometry fullScreenActive = PathGeometry.Parse("M205 1024h819v-819h-205v469l-674 -674l-145 145l674 674h-469v205zM1374 1229h469v-205h-819v819h205v-469l674 674l145 -145z");

/// <summary>
/// The full screen normal
/// </summary>
private static readonly PathGeometry fullScreenNormal = PathGeometry.Parse("M2048 2048v-819h-205v469l-1493 -1493h469v-205h-819v819h205v-469l1493 1493h-469v205h819z");

/// <summary>
/// The restore screen active
/// </summary>
private static readonly PathGeometry restoreScreenActive = PathGeometry.Parse("M2048 410h-410v-410h-1638v1638h410v410h1638v-1638zM1434 1434h-1229v-1229h1229v1229zM1843 1843h-1229v-205h1024v-1024h205v1229z");

/// <summary>
/// The restore screen normal
/// </summary>
private static readonly PathGeometry restoreScreenNormal = PathGeometry.Parse("M2048 2048v-2048h-2048v2048h2048zM1843 1843h-1638v-1638h1638v1638z");

/// <summary>
/// The disposables
/// </summary>
private CompositeDisposable? _disposables;
private CompositeDisposable? disposables;

/// <summary>
/// The full screen button path
/// </summary>
private Path? fullScreenButtonPath;

/// <summary>
/// The restore button path
/// </summary>
private Path? restoreButtonPath;

#endregion Fields

Expand Down Expand Up @@ -67,20 +100,44 @@ public class IronyCaptionButtons : TemplatedControl, IStyleable
/// <param name="hostWindow">The host window.</param>
public virtual void Attach(Window hostWindow)
{
if (_disposables == null)
if (disposables == null)
{
HostWindow = hostWindow;

_disposables = new CompositeDisposable
disposables = new CompositeDisposable
{
HostWindow.GetObservable(Window.WindowStateProperty)
.Subscribe(x =>
{
PseudoClasses.Set(":minimized", x == WindowState.Minimized);
PseudoClasses.Set(":normal", x == WindowState.Normal);
PseudoClasses.Set(":maximized", x == WindowState.Maximized);
PseudoClasses.Set(":fullscreen", x == WindowState.FullScreen);
})
.Subscribe(x =>
{
PseudoClasses.Set(":minimized", x == WindowState.Minimized);
PseudoClasses.Set(":normal", x == WindowState.Normal);
PseudoClasses.Set(":maximized", x == WindowState.Maximized);
PseudoClasses.Set(":fullscreen", x == WindowState.FullScreen);

// Why here? Because I'm tired of dealing with a bug in pseudo classes.
if (fullScreenButtonPath != null && restoreButtonPath != null)
{
// ReSharper disable once SwitchStatementHandlesSomeKnownEnumValuesWithDefault
switch (x)
{
case WindowState.FullScreen:
fullScreenButtonPath.Data = fullScreenActive;
fullScreenButtonPath.IsVisible = true;
restoreButtonPath.Data = restoreScreenNormal;
break;
case WindowState.Maximized:
fullScreenButtonPath.Data = fullScreenNormal;
fullScreenButtonPath.IsVisible = false;
restoreButtonPath.Data = restoreScreenActive;
break;
default:
fullScreenButtonPath.Data = fullScreenNormal;
fullScreenButtonPath.IsVisible = true;
restoreButtonPath.Data = restoreScreenNormal;
break;
}
}
})
};
}
}
Expand All @@ -90,10 +147,10 @@ public virtual void Attach(Window hostWindow)
/// </summary>
public virtual void Detach()
{
if (_disposables != null)
if (disposables != null)
{
_disposables.Dispose();
_disposables = null;
disposables.Dispose();
disposables = null;

HostWindow = null;
}
Expand All @@ -102,7 +159,7 @@ public virtual void Detach()
/// <summary>
/// Handles the <see cref="E:ApplyTemplate" /> event.
/// </summary>
/// <param name="e">The <see cref="TemplateAppliedEventArgs"/> instance containing the event data.</param>
/// <param name="e">The <see cref="TemplateAppliedEventArgs" /> instance containing the event data.</param>
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
Expand All @@ -111,11 +168,13 @@ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
var restoreButton = e.NameScope.Get<Button>("PART_RestoreButton");
var minimiseButton = e.NameScope.Get<Button>("PART_MinimiseButton");
var fullScreenButton = e.NameScope.Get<Button>("PART_FullScreenButton");
fullScreenButtonPath = e.NameScope.Get<Path>("FullScreenButtonPath");
restoreButtonPath = e.NameScope.Get<Path>("RestoreButtonPath");

closeButton.Click += (sender, e) => OnClose();
restoreButton.Click += (sender, e) => OnRestore();
minimiseButton.Click += (sender, e) => OnMinimize();
fullScreenButton.Click += (sender, e) => OnToggleFullScreen();
closeButton.Click += (_, _) => OnClose();
restoreButton.Click += (_, _) => OnRestore();
minimiseButton.Click += (_, _) => OnMinimize();
fullScreenButton.Click += (_, _) => OnToggleFullScreen();
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@
// Created : 11-23-2022
//
// Last Modified By : Mario
// Last Modified On : 11-23-2022
// Last Modified On : 11-20-2024
// ***********************************************************************
// <copyright file="ThemeCaptionButton.cs" company="Mario">
// Mario
// </copyright>
// <summary></summary>
// ***********************************************************************

using System;
using System.Collections.Generic;
using System.Linq;
using Avalonia.Media;
using Avalonia.Styling;

namespace IronyModManager.Controls.ClientSideDecorations
Expand All @@ -27,6 +29,15 @@ namespace IronyModManager.Controls.ClientSideDecorations
/// <seealso cref="IStyleable" />
public class ThemeCaptionButton : Avalonia.Controls.Button, IStyleable
{
#region Constructors

/// <summary>
/// Initializes a new instance of the <see cref="ThemeCaptionButton"/> class.
/// </summary>
public ThemeCaptionButton() => Background = Brushes.Transparent;

#endregion Constructors

#region Properties

/// <summary>
Expand Down
42 changes: 27 additions & 15 deletions src/IronyModManager/Controls/Themes/Dark/IronyCaptionButtons.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,21 @@
<Setter Property="Template">
<ControlTemplate>
<ContentPresenter Name="PART_ContentPresenter"
Background="Transparent"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
Content="{TemplateBinding Content}"/>
</ControlTemplate>
</Setter>
</Style>


<Style Selector="controls|ThemeCaptionButton:pointerover /template/ ContentPresenter">
<Setter Property="Background" Value="{TemplateBinding Background}" />
</Style>

<Style Selector="controls|ThemeCaptionButton:pressed /template/ ContentPresenter">
<Setter Property="Background" Value="{TemplateBinding BorderBrush}" />
</Style>

<Style Selector="controls|IronyCaptionButtons">
<Setter Property="MaxHeight" Value="30" />
<Setter Property="Template">
<ControlTemplate>
<StackPanel Spacing="2" VerticalAlignment="Stretch" TextBlock.FontSize="10" Orientation="Horizontal">
<!-- ReSharper disable InconsistentNaming knock it off -->
<controls:ThemeCaptionButton x:Name="PART_FullScreenButton"
IsVisible="False">
IsVisible="False">
<Viewbox Width="11" Margin="2">
<Path Name="FullScreenButtonPath"
Stretch="UniformToFill"
Expand Down Expand Up @@ -75,21 +68,40 @@
Data="M1169 1024l879 -879l-145 -145l-879 879l-879 -879l-145 145l879 879l-879 879l145 145l879 -879l879 879l145 -145z" />
</Viewbox>
</controls:ThemeCaptionButton>
<!-- ReSharper restore InconsistentNaming -->
</StackPanel>
</ControlTemplate>
</Setter>
</Style>
<Style Selector="controls|IronyCaptionButtons:maximized /template/ Path#RestoreButtonPath">

<!-- Moved to code-behind, why? Best to avalonia devs while I'm still stuck on 0.10. -->
<!--<Style Selector="controls|IronyCaptionButtons:maximized /template/ Path#RestoreButtonPath">
<Setter Property="Data" Value="M2048 410h-410v-410h-1638v1638h410v410h1638v-1638zM1434 1434h-1229v-1229h1229v1229zM1843 1843h-1229v-205h1024v-1024h205v1229z" />
</Style>
<Style Selector="controls|IronyCaptionButtons:fullscreen /template/ Path#FullScreenButtonPath">
<Setter Property="IsVisible" Value="True" />
<Setter Property="Data" Value="M205 1024h819v-819h-205v469l-674 -674l-145 145l674 674h-469v205zM1374 1229h469v-205h-819v819h205v-469l674 674l145 -145z" />
</Style>
<Style Selector="controls|IronyCaptionButtons:fullscreen /template/ Button#PART_RestoreButton">
</Style>-->
<Style Selector="controls|IronyCaptionButtons:fullscreen /template/ controls|ThemeCaptionButton#PART_RestoreButton">
<Setter Property="IsVisible" Value="False" />
</Style>
<Style Selector="controls|IronyCaptionButtons:fullscreen /template/ Button#PART_MinimiseButton">
<Style Selector="controls|IronyCaptionButtons:fullscreen /template/ controls|ThemeCaptionButton#PART_MinimiseButton">
<Setter Property="IsVisible" Value="False" />
</Style>

<Style Selector="controls|ThemeCaptionButton:pointerover /template/ ContentPresenter">
<Setter Property="Background" Value="#7F7f7f7f" />
</Style>

<Style Selector="controls|ThemeCaptionButton:pressed /template/ ContentPresenter">
<Setter Property="Background" Value="#716F6D80" />
</Style>

<Style Selector="controls|IronyCaptionButtons /template/ controls|ThemeCaptionButton#PART_CloseButton:pointerover /template/ ContentPresenter">
<Setter Property="Background" Value="#7FFF0000" />
</Style>

<Style Selector="controls|IronyCaptionButtons /template/ controls|ThemeCaptionButton#PART_CloseButton:pressed /template/ ContentPresenter">
<Setter Property="Background" Value="#fff1707a" />
</Style>
</Styles>
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,21 @@
<Setter Property="Template">
<ControlTemplate>
<ContentPresenter Name="PART_ContentPresenter"
Background="Transparent"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
Content="{TemplateBinding Content}"/>
</ControlTemplate>
</Setter>
</Style>


<Style Selector="controls|ThemeCaptionButton:pointerover /template/ ContentPresenter">
<Setter Property="Background" Value="{TemplateBinding Background}" />
</Style>

<Style Selector="controls|ThemeCaptionButton:pressed /template/ ContentPresenter">
<Setter Property="Background" Value="{TemplateBinding BorderBrush}" />
</Style>

<Style Selector="controls|IronyCaptionButtons">
<Setter Property="MaxHeight" Value="30" />
<Setter Property="Template">
<ControlTemplate>
<StackPanel Spacing="2" VerticalAlignment="Stretch" TextBlock.FontSize="10" Orientation="Horizontal">
<!-- ReSharper disable InconsistentNaming knock it off -->
<controls:ThemeCaptionButton x:Name="PART_FullScreenButton"
IsVisible="False">
IsVisible="False">
<Viewbox Width="11" Margin="2">
<Path Name="FullScreenButtonPath"
Stretch="UniformToFill"
Expand Down Expand Up @@ -75,21 +68,40 @@
Data="M1169 1024l879 -879l-145 -145l-879 879l-879 -879l-145 145l879 879l-879 879l145 145l879 -879l879 879l145 -145z" />
</Viewbox>
</controls:ThemeCaptionButton>
<!-- ReSharper restore InconsistentNaming -->
</StackPanel>
</ControlTemplate>
</Setter>
</Style>
<Style Selector="controls|IronyCaptionButtons:maximized /template/ Path#RestoreButtonPath">

<!-- Moved to code-behind, why? Best to avalonia devs while I'm still stuck on 0.10. -->
<!--<Style Selector="controls|IronyCaptionButtons:maximized /template/ Path#RestoreButtonPath">
<Setter Property="Data" Value="M2048 410h-410v-410h-1638v1638h410v410h1638v-1638zM1434 1434h-1229v-1229h1229v1229zM1843 1843h-1229v-205h1024v-1024h205v1229z" />
</Style>
<Style Selector="controls|IronyCaptionButtons:fullscreen /template/ Path#FullScreenButtonPath">
<Setter Property="IsVisible" Value="True" />
<Setter Property="Data" Value="M205 1024h819v-819h-205v469l-674 -674l-145 145l674 674h-469v205zM1374 1229h469v-205h-819v819h205v-469l674 674l145 -145z" />
</Style>
<Style Selector="controls|IronyCaptionButtons:fullscreen /template/ Button#PART_RestoreButton">
</Style>-->
<Style Selector="controls|IronyCaptionButtons:fullscreen /template/ controls|ThemeCaptionButton#PART_RestoreButton">
<Setter Property="IsVisible" Value="False" />
</Style>
<Style Selector="controls|IronyCaptionButtons:fullscreen /template/ Button#PART_MinimiseButton">
<Style Selector="controls|IronyCaptionButtons:fullscreen /template/ controls|ThemeCaptionButton#PART_MinimiseButton">
<Setter Property="IsVisible" Value="False" />
</Style>

<Style Selector="controls|ThemeCaptionButton:pointerover /template/ ContentPresenter">
<Setter Property="Background" Value="#7F7f7f7f" />
</Style>

<Style Selector="controls|ThemeCaptionButton:pressed /template/ ContentPresenter">
<Setter Property="Background" Value="#716F6D80" />
</Style>

<Style Selector="controls|IronyCaptionButtons /template/ controls|ThemeCaptionButton#PART_CloseButton:pointerover /template/ ContentPresenter">
<Setter Property="Background" Value="#7FFF0000" />
</Style>

<Style Selector="controls|IronyCaptionButtons /template/ controls|ThemeCaptionButton#PART_CloseButton:pressed /template/ ContentPresenter">
<Setter Property="Background" Value="#fff1707a" />
</Style>
</Styles>
Loading

0 comments on commit 21d3784

Please sign in to comment.