From 6aad691f7b4e47a46e2fbabe93821ad52f44f2c5 Mon Sep 17 00:00:00 2001
From: Dongle <29563098+dongle-the-gadget@users.noreply.github.com>
Date: Wed, 20 Nov 2024 22:16:12 +0700
Subject: [PATCH] Make UI more compliant with Windows 11 design (#26)
* Make UI more compliant with Windows 11 design.
* Fix to 2-space indent.
---
NanaBox/App.xaml | 3 +
NanaBox/NanaBox.vcxproj | 11 +++
NanaBox/NanaBox.vcxproj.filters | 3 +
NanaBox/NewVirtualHardDiskPage.xaml | 4 +-
NanaBox/ProgressRing.cpp | 114 +++++++++++++++++++++++++
NanaBox/ProgressRing.h | 37 ++++++++
NanaBox/ProgressRing.idl | 9 ++
NanaBox/ResizeVirtualHardDiskPage.xaml | 4 +-
NanaBox/Utils.cpp | 4 +-
9 files changed, 183 insertions(+), 6 deletions(-)
create mode 100644 NanaBox/ProgressRing.cpp
create mode 100644 NanaBox/ProgressRing.h
create mode 100644 NanaBox/ProgressRing.idl
diff --git a/NanaBox/App.xaml b/NanaBox/App.xaml
index 7ff467c..a158005 100644
--- a/NanaBox/App.xaml
+++ b/NanaBox/App.xaml
@@ -8,6 +8,9 @@
+
diff --git a/NanaBox/NanaBox.vcxproj b/NanaBox/NanaBox.vcxproj
index 8d08168..899e51c 100644
--- a/NanaBox/NanaBox.vcxproj
+++ b/NanaBox/NanaBox.vcxproj
@@ -68,6 +68,10 @@
NewVirtualHardDiskPage.xaml
Code
+
+ ProgressRing.idl
+ Code
+
QuickStartPage.xaml
Code
@@ -128,6 +132,9 @@
NewVirtualHardDiskPage.xaml
Code
+
+ Code
+
QuickStartPage.xaml
Code
@@ -175,6 +182,10 @@
Code
+
+ ProgressRing.idl
+ Code
+
QuickStartPage.xaml
Code
diff --git a/NanaBox/NanaBox.vcxproj.filters b/NanaBox/NanaBox.vcxproj.filters
index c1bfa2f..60b6c46 100644
--- a/NanaBox/NanaBox.vcxproj.filters
+++ b/NanaBox/NanaBox.vcxproj.filters
@@ -160,4 +160,7 @@
Strings\zh-Hans
+
+
+
\ No newline at end of file
diff --git a/NanaBox/NewVirtualHardDiskPage.xaml b/NanaBox/NewVirtualHardDiskPage.xaml
index dd86c5f..2bcd6e2 100644
--- a/NanaBox/NewVirtualHardDiskPage.xaml
+++ b/NanaBox/NewVirtualHardDiskPage.xaml
@@ -24,7 +24,7 @@
x:Uid="/NewVirtualHardDiskPage/ContentTextBlock"
Text="[You can create a VHD (up to 2040 GiB) or VHDX (up to 64 TiB, but not supported before Windows 8) dynamically expanding virtual hard disk with this dialog.]"
TextWrapping="Wrap" />
-
+
@@ -45,7 +45,7 @@
x:Uid="/NewVirtualHardDiskPage/SizeTextBlock"
Padding="0,2"
Text="Size (at least 3 MiB and must be a multiple of 512 bytes)" />
-
+
diff --git a/NanaBox/ProgressRing.cpp b/NanaBox/ProgressRing.cpp
new file mode 100644
index 0000000..af38940
--- /dev/null
+++ b/NanaBox/ProgressRing.cpp
@@ -0,0 +1,114 @@
+#include "pch.h"
+#include "ProgressRing.h"
+#if __has_include("ProgressRing.g.cpp")
+#include "ProgressRing.g.cpp"
+#endif
+
+namespace winrt::NanaBox::implementation
+{
+ ProgressRing::ProgressRing()
+ {
+ m_compositor = Windows::UI::Xaml::Hosting::ElementCompositionPreview::GetElementVisual(*this).Compositor();
+
+ auto ellipse = m_compositor.CreateEllipseGeometry();
+ ellipse.Radius({ 7, 7 });
+
+ m_shape = m_compositor.CreateSpriteShape(ellipse);
+ m_shape.StrokeDashCap(Windows::UI::Composition::CompositionStrokeCap::Round);
+ m_shape.StrokeStartCap(Windows::UI::Composition::CompositionStrokeCap::Round);
+ m_shape.StrokeEndCap(Windows::UI::Composition::CompositionStrokeCap::Round);
+ m_shape.StrokeThickness(m_strokeThickness);
+ m_shape.TransformMatrix({ 5.0f, 0.0f, 0.0f, 5.0f, 40.0f, 40.0f });
+
+ m_visual = m_compositor.CreateShapeVisual();
+ m_visual.Size({ m_defaultProgressRingSize, m_defaultProgressRingSize });
+ m_visual.Shapes().Append(m_shape);
+
+ Windows::UI::Xaml::Hosting::ElementCompositionPreview::SetElementChildVisual(*this, m_visual);
+
+ auto holdThenStepEasing = m_compositor.CreateStepEasingFunction();
+ holdThenStepEasing.IsFinalStepSingleFrame(true);
+
+ auto cubicBezierEasing = m_compositor.CreateCubicBezierEasingFunction({ 0.166999996f, 0.166999996f }, { 0.833000004f, 0.833000004f });
+
+ auto rotationAnimation = m_compositor.CreateScalarKeyFrameAnimation();
+ rotationAnimation.InsertKeyFrame(0.0f, 0.0f, holdThenStepEasing);
+ rotationAnimation.InsertKeyFrame(0.5f, 450.0f, cubicBezierEasing);
+ rotationAnimation.InsertKeyFrame(1.0f, 1080.0f, cubicBezierEasing);
+ rotationAnimation.Duration(Windows::Foundation::TimeSpan{ std::chrono::seconds(2) });
+ rotationAnimation.IterationBehavior(Windows::UI::Composition::AnimationIterationBehavior::Forever);
+
+ auto sizeAnimation = m_compositor.CreateScalarKeyFrameAnimation();
+ sizeAnimation.InsertKeyFrame(0.0f, 0.0f, holdThenStepEasing);
+ sizeAnimation.InsertKeyFrame(0.5f, 0.5f, cubicBezierEasing);
+ sizeAnimation.InsertKeyFrame(1.0f, 0.0f, cubicBezierEasing);
+ sizeAnimation.Duration(Windows::Foundation::TimeSpan{ std::chrono::seconds(2) });
+ sizeAnimation.IterationBehavior(Windows::UI::Composition::AnimationIterationBehavior::Forever);
+
+ m_shape.StartAnimation(L"RotationAngleInDegrees", rotationAnimation);
+ ellipse.StartAnimation(L"TrimEnd", sizeAnimation);
+ }
+
+ Windows::Foundation::Size ProgressRing::MeasureOverride(Windows::Foundation::Size const& availableSize)
+ {
+ auto size = availableSize.Width > availableSize.Height ? availableSize.Height : availableSize.Width;
+ if (size == INFINITY)
+ {
+ size = m_defaultProgressRingSize;
+ }
+
+ return { size, size };
+ }
+
+ Windows::Foundation::Size ProgressRing::ArrangeOverride(Windows::Foundation::Size const& finalSize)
+ {
+ auto size = finalSize.Width > finalSize.Height ? finalSize.Height : finalSize.Width;
+
+ float scale = size / m_defaultProgressRingSize;
+ m_visual.Scale({ scale, scale, scale });
+
+ float widthOffset = (finalSize.Width - size) / 2;
+ float heightOffset = (finalSize.Height - size) / 2;
+ m_visual.Offset({ widthOffset, heightOffset, 0.0f });
+
+ return finalSize;
+ }
+
+ Windows::UI::Xaml::DependencyProperty ProgressRing::m_foregroundProperty =
+ Windows::UI::Xaml::DependencyProperty::Register(
+ L"Foreground",
+ winrt::xaml_typename(),
+ winrt::xaml_typename(),
+ Windows::UI::Xaml::PropertyMetadata{ nullptr, &OnForegroundChanged }
+ );
+
+ void ProgressRing::OnForegroundChanged(Windows::UI::Xaml::DependencyObject d, Windows::UI::Xaml::DependencyPropertyChangedEventArgs args)
+ {
+ auto progressRing = d.as();
+ auto progressRingImpl = winrt::get_self(progressRing);
+
+ auto oldBrush = progressRingImpl->m_shape.StrokeBrush();
+ auto newBrush = progressRingImpl->m_compositor.CreateColorBrush(args.NewValue().as().Color());
+ progressRingImpl->m_shape.StrokeBrush(newBrush);
+
+ if (oldBrush)
+ {
+ oldBrush.Close();
+ }
+ }
+
+ Windows::UI::Xaml::DependencyProperty ProgressRing::ForegroundProperty()
+ {
+ return m_foregroundProperty;
+ }
+
+ Windows::UI::Xaml::Media::SolidColorBrush ProgressRing::Foreground()
+ {
+ return winrt::unbox_value(GetValue(m_foregroundProperty));
+ }
+
+ void ProgressRing::Foreground(Windows::UI::Xaml::Media::SolidColorBrush const& value)
+ {
+ SetValue(m_foregroundProperty, value);
+ }
+}
diff --git a/NanaBox/ProgressRing.h b/NanaBox/ProgressRing.h
new file mode 100644
index 0000000..3262602
--- /dev/null
+++ b/NanaBox/ProgressRing.h
@@ -0,0 +1,37 @@
+#pragma once
+
+#include "ProgressRing.g.h"
+#include
+
+namespace winrt::NanaBox::implementation
+{
+ struct ProgressRing : ProgressRingT
+ {
+ ProgressRing();
+
+ static Windows::UI::Xaml::DependencyProperty ForegroundProperty();
+ Windows::UI::Xaml::Media::SolidColorBrush Foreground();
+ void Foreground(Windows::UI::Xaml::Media::SolidColorBrush const& value);
+
+ Windows::Foundation::Size MeasureOverride(Windows::Foundation::Size const& availableSize);
+ Windows::Foundation::Size ArrangeOverride(Windows::Foundation::Size const& finalSize);
+
+ private:
+ static void OnForegroundChanged(Windows::UI::Xaml::DependencyObject d, Windows::UI::Xaml::DependencyPropertyChangedEventArgs args);
+
+ Windows::UI::Composition::Compositor m_compositor{ nullptr };
+ Windows::UI::Composition::CompositionSpriteShape m_shape{ nullptr };
+ Windows::UI::Composition::ShapeVisual m_visual{ nullptr };
+
+ static Windows::UI::Xaml::DependencyProperty m_foregroundProperty;
+ const float m_defaultProgressRingSize = 80.0f;
+ const float m_strokeThickness = 1.5f;
+ };
+}
+
+namespace winrt::NanaBox::factory_implementation
+{
+ struct ProgressRing : ProgressRingT
+ {
+ };
+}
diff --git a/NanaBox/ProgressRing.idl b/NanaBox/ProgressRing.idl
new file mode 100644
index 0000000..3647a57
--- /dev/null
+++ b/NanaBox/ProgressRing.idl
@@ -0,0 +1,9 @@
+namespace NanaBox
+{
+ runtimeclass ProgressRing : Windows.UI.Xaml.FrameworkElement
+ {
+ ProgressRing();
+ static Windows.UI.Xaml.DependencyProperty ForegroundProperty { get; };
+ Windows.UI.Xaml.Media.SolidColorBrush Foreground;
+ }
+}
diff --git a/NanaBox/ResizeVirtualHardDiskPage.xaml b/NanaBox/ResizeVirtualHardDiskPage.xaml
index 6ddea65..a031ec8 100644
--- a/NanaBox/ResizeVirtualHardDiskPage.xaml
+++ b/NanaBox/ResizeVirtualHardDiskPage.xaml
@@ -24,7 +24,7 @@
x:Uid="/ResizeVirtualHardDiskPage/ContentTextBlock"
Text="[Specify the new size for the virtual hard disk.]"
TextWrapping="Wrap" />
-
+
@@ -45,7 +45,7 @@
x:Uid="/ResizeVirtualHardDiskPage/SizeTextBlock"
Padding="0,2"
Text="[Size (at least 3 MiB and must be a multiple of 512 bytes)]" />
-
+
diff --git a/NanaBox/Utils.cpp b/NanaBox/Utils.cpp
index 4c05ddb..780cad8 100644
--- a/NanaBox/Utils.cpp
+++ b/NanaBox/Utils.cpp
@@ -29,7 +29,7 @@ namespace winrt
using Windows::UI::Xaml::HorizontalAlignment;
using Windows::UI::Xaml::ThicknessHelper;
using Windows::UI::Xaml::VerticalAlignment;
- using Windows::UI::Xaml::Controls::ProgressRing;
+ using NanaBox::ProgressRing;
}
void SplitCommandLineEx(
@@ -937,7 +937,7 @@ HWND ShowOperationWaitingWindow(
Content.Margin(winrt::ThicknessHelper::FromUniformLength(12));
Content.HorizontalAlignment(winrt::HorizontalAlignment::Stretch);
Content.VerticalAlignment(winrt::VerticalAlignment::Stretch);
- Content.IsActive(true);
+ // Content.IsActive(true);
::ShowXamlDialog(
WindowHandle,