Add project files.

This commit is contained in:
dan_c
2024-01-04 17:32:36 +00:00
parent 6358cf9567
commit da8af59391
48 changed files with 1710 additions and 0 deletions
@@ -0,0 +1,56 @@
using Microsoft.UI.Xaml;
namespace Hyperbar.Desktop.Controls;
public class DesktopFlyout :
DependencyObject
{
public static readonly DependencyProperty ContentProperty =
DependencyProperty.Register(nameof(Content),
typeof(object), typeof(DesktopFlyout),
new PropertyMetadata(null));
public static readonly DependencyProperty PlacementProperty =
DependencyProperty.Register(nameof(Placement),
typeof(DesktopFlyoutPlacement), typeof(DesktopFlyout),
new PropertyMetadata(DesktopFlyoutPlacement.Left, OnPlacementPropertyChanged));
private readonly DesktopFlyoutHost host;
private readonly DesktopFlyoutPresenter presenter;
public DesktopFlyout()
{
presenter = new DesktopFlyoutPresenter
{
Parent = this
};
host = new DesktopFlyoutHost(presenter);
host.Activate();
}
public object Content
{
get => GetValue(ContentProperty);
set => SetValue(ContentProperty, value);
}
public DesktopFlyoutPlacement Placement
{
get => (DesktopFlyoutPlacement)GetValue(PlacementProperty);
set => SetValue(PlacementProperty, value);
}
private static void OnPlacementPropertyChanged(DependencyObject dependencyObject,
DependencyPropertyChangedEventArgs args)
{
if (dependencyObject is DesktopFlyout sender)
{
sender.OnPlacementPropertyChanged();
}
}
private void OnPlacementPropertyChanged() => UpdatePlacement();
private void UpdatePlacement() => host.UpdatePlacement(Placement);
}
@@ -0,0 +1,90 @@
using Microsoft.UI.Xaml;
using Hyperbar.Desktop.Win32;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Controls;
using Windows.Foundation;
using Microsoft.UI.Xaml.Media;
namespace Hyperbar.Desktop.Controls;
internal class DesktopFlyoutHost : Window
{
private readonly DesktopFlyoutPresenter presenter;
private DesktopFlyoutPlacement placement;
private Popup popup;
public DesktopFlyoutHost(DesktopFlyoutPresenter presenter)
{
Border root = new();
root.Loaded += OnLoaded;
this.presenter = presenter;
presenter.SizeChanged += OnChildSizeChanged;
Content = root;
this.SetOpacity(0);
this.SetStyle(WindowStyle.SysMenu | WindowStyle.Visible);
this.SetTopMost(true);
this.SetIsShownInSwitchers(false);
}
internal void UpdatePlacement(DesktopFlyoutPlacement placement)
{
this.placement = placement;
// Not ready
if (popup is null)
{
return;
}
// presenter.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
double height = presenter.DesiredSize.Height;
double width = presenter.DesiredSize.Width;
switch (placement)
{
case DesktopFlyoutPlacement.Left:
this.Snap(WindowPlacement.Left, 0, 0);
break;
case DesktopFlyoutPlacement.Top:
this.Snap(WindowPlacement.Top, width, height);
break;
case DesktopFlyoutPlacement.Right:
this.Snap(WindowPlacement.Right, 0, 0);
break;
case DesktopFlyoutPlacement.Bottom:
this.Snap(WindowPlacement.Bottom, width, height);
break;
default:
break;
}
presenter.TemplateSettings.SetValue(DesktopFlyoutPresenterTemplateSettings.HeightProperty, height);
presenter.TemplateSettings.SetValue(DesktopFlyoutPresenterTemplateSettings.WidthProperty, width);
presenter.TemplateSettings.SetValue(DesktopFlyoutPresenterTemplateSettings.NegativeHeightProperty, -height);
presenter.TemplateSettings.SetValue(DesktopFlyoutPresenterTemplateSettings.NegativeWidthProperty, -width);
presenter.UpdatePlacementState(placement);
}
private void OnChildSizeChanged(object sender,
SizeChangedEventArgs args) => UpdatePlacement(this.placement);
private void OnLoaded(object sender,
RoutedEventArgs args)
{
popup = new Popup
{
Child = presenter,
XamlRoot = Content.XamlRoot,
ShouldConstrainToRootBounds = false,
IsOpen = true,
};
UpdatePlacement(placement);
}
}
@@ -0,0 +1,9 @@
namespace Hyperbar.Desktop.Controls;
public enum DesktopFlyoutPlacement
{
Left,
Top,
Right,
Bottom
}
@@ -0,0 +1,40 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Data;
namespace Hyperbar.Desktop.Controls;
public class DesktopFlyoutPresenter :
ContentControl
{
public static readonly DependencyProperty TemplateSettingsProperty =
DependencyProperty.Register(nameof(TemplateSettings),
typeof(DesktopFlyoutPresenterTemplateSettings), typeof(DesktopFlyoutPresenter),
new PropertyMetadata(null));
internal new DesktopFlyout Parent;
public DesktopFlyoutPresenter()
{
DefaultStyleKey = typeof(DesktopFlyoutPresenter);
TemplateSettings = new DesktopFlyoutPresenterTemplateSettings();
}
protected override void OnApplyTemplate()
{
SetBinding(ContentProperty, new Binding
{
Source = Parent,
Mode = BindingMode.TwoWay,
Path = new PropertyPath(nameof(Parent.Content)),
});
}
public DesktopFlyoutPresenterTemplateSettings TemplateSettings
{
get => (DesktopFlyoutPresenterTemplateSettings)GetValue(TemplateSettingsProperty);
set => SetValue(TemplateSettingsProperty, value);
}
internal void UpdatePlacementState(DesktopFlyoutPlacement placement) => VisualStateManager.GoToState(this, $"{placement}Placement", true);
}
@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Hyperbar.Desktop.Controls">
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Default">
<StaticResource x:Key="CommandBarFlyoutBackground" ResourceKey="AcrylicInAppFillColorDefaultBrush" />
<StaticResource x:Key="CommandBarFlyoutForeground" ResourceKey="TextFillColorPrimaryBrush" />
<StaticResource x:Key="CommandBarFlyoutBorderBrush" ResourceKey="ControlStrokeColorDefaultBrush" />
</ResourceDictionary>
<ResourceDictionary x:Key="Light">
<StaticResource x:Key="CommandBarFlyoutBackground" ResourceKey="AcrylicInAppFillColorDefaultBrush" />
<StaticResource x:Key="CommandBarFlyoutForeground" ResourceKey="TextFillColorPrimaryBrush" />
<StaticResource x:Key="CommandBarFlyoutBorderBrush" ResourceKey="ControlStrokeColorDefaultBrush" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
<Style TargetType="controls:DesktopFlyoutPresenter">
<Setter Property="Background" Value="{ThemeResource CommandBarFlyoutBackground}" />
<Setter Property="Foreground" Value="{ThemeResource CommandBarFlyoutForeground}" />
<Setter Property="BorderBrush" Value="{ThemeResource CommandBarFlyoutBorderBrush}" />
<Setter Property="BorderThickness" Value="{ThemeResource CommandBarFlyoutBorderThemeThickness}" />
<Setter Property="CornerRadius" Value="{ThemeResource OverlayCornerRadius}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:DesktopFlyoutPresenter">
<Border x:Name="Container">
<Border
x:Name="BackgroundElement"
Height="48"
MinWidth="40"
Margin="24"
Background="{TemplateBinding Background}"
BackgroundSizing="InnerBorderEdge"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
FlowDirection="{TemplateBinding FlowDirection}">
<Border.Transitions>
<TransitionCollection>
<EntranceThemeTransition x:Name="EntranceThemeTransition" FromVerticalOffset="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.NegativeHeight}" />
</TransitionCollection>
</Border.Transitions>
<ContentControl
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTransitions="{TemplateBinding ContentTransitions}" />
</Border>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="PlacementStates">
<VisualState x:Name="DefaultPlacement" />
<VisualState x:Name="BottomPlacement">
<VisualState.Setters>
<Setter Target="EntranceThemeTransition.FromHorizontalOffset" Value="0" />
<Setter Target="EntranceThemeTransition.FromVerticalOffset" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.Height}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="TopPlacement">
<VisualState.Setters>
<Setter Target="EntranceThemeTransition.FromHorizontalOffset" Value="0" />
<Setter Target="EntranceThemeTransition.FromVerticalOffset" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.NegativeHeight}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="LeftPlacement">
<VisualState.Setters>
<Setter Target="EntranceThemeTransition.FromHorizontalOffset" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.NegativeWidth}" />
<Setter Target="EntranceThemeTransition.FromVerticalOffset" Value="0" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="RightPlacement">
<VisualState.Setters>
<Setter Target="EntranceThemeTransition.FromHorizontalOffset" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.Width}" />
<Setter Target="EntranceThemeTransition.FromVerticalOffset" Value="0" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
@@ -0,0 +1,49 @@
using Microsoft.UI.Xaml;
namespace Hyperbar.Desktop.Controls;
public class DesktopFlyoutPresenterTemplateSettings : DependencyObject
{
public static readonly DependencyProperty HeightProperty =
DependencyProperty.Register(nameof(Height),
typeof(double), typeof(DesktopFlyoutPresenterTemplateSettings),
new PropertyMetadata(0d));
public static readonly DependencyProperty NegativeHeightProperty =
DependencyProperty.Register(nameof(NegativeHeight),
typeof(double), typeof(DesktopFlyoutPresenterTemplateSettings),
new PropertyMetadata(0d));
public static readonly DependencyProperty NegativeWidthProperty =
DependencyProperty.Register(nameof(NegativeWidth),
typeof(double), typeof(DesktopFlyoutPresenterTemplateSettings),
new PropertyMetadata(0d));
public static readonly DependencyProperty WidthProperty =
DependencyProperty.Register(nameof(Width),
typeof(double), typeof(DesktopFlyoutPresenterTemplateSettings),
new PropertyMetadata(0d));
public double Height
{
get => (double)GetValue(HeightProperty);
set => SetValue(HeightProperty, value);
}
public double NegativeHeight
{
get => (double)GetValue(NegativeHeightProperty);
set => SetValue(NegativeHeightProperty, value);
}
public double NegativeWidth
{
get => (double)GetValue(NegativeWidthProperty);
set => SetValue(NegativeWidthProperty, value);
}
public double Width
{
get => (double)GetValue(WidthProperty);
set => SetValue(WidthProperty, value);
}
}