Skip to content

Commit

Permalink
feat: 移植 ControlSizeTrigger
Browse files Browse the repository at this point in the history
  • Loading branch information
Blinue committed Dec 6, 2023
1 parent 4d1c68e commit 4c83669
Show file tree
Hide file tree
Showing 16 changed files with 270 additions and 44 deletions.
1 change: 1 addition & 0 deletions src/Magpie.App/App.idl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "BoolNegationConverter.idl"
#include "BoolToNegativeVisibilityConverter.idl"
#include "ControlSizeTrigger.idl"
#include "IsEqualStateTrigger.idl"
#include "IsNullStateTrigger.idl"
#include "LoggerHelper.idl"
Expand Down
89 changes: 89 additions & 0 deletions src/Magpie.App/ControlSizeTrigger.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#include "pch.h"
#include "ControlSizeTrigger.h"
#if __has_include("ControlSizeTrigger.g.cpp")
#include "ControlSizeTrigger.g.cpp"
#endif

namespace winrt::Magpie::App::implementation {

const DependencyProperty ControlSizeTrigger::_canTriggerProperty = DependencyProperty::Register(
L"CanTrigger",
xaml_typename<bool>(),
xaml_typename<Magpie::App::ControlSizeTrigger>(),
PropertyMetadata(box_value(true), &ControlSizeTrigger::_OnPropertyChanged)
);

const DependencyProperty ControlSizeTrigger::_maxWidthProperty = DependencyProperty::Register(
L"MaxWidth",
xaml_typename<double>(),
xaml_typename<Magpie::App::ControlSizeTrigger>(),
PropertyMetadata(box_value(std::numeric_limits<double>::infinity()), &ControlSizeTrigger::_OnPropertyChanged)
);

const DependencyProperty ControlSizeTrigger::_minWidthProperty = DependencyProperty::Register(
L"MinWidth",
xaml_typename<double>(),
xaml_typename<Magpie::App::ControlSizeTrigger>(),
PropertyMetadata(box_value(0.0), &ControlSizeTrigger::_OnPropertyChanged)
);

const DependencyProperty ControlSizeTrigger::_maxHeightProperty = DependencyProperty::Register(
L"MaxHeight",
xaml_typename<double>(),
xaml_typename<Magpie::App::ControlSizeTrigger>(),
PropertyMetadata(box_value(std::numeric_limits<double>::infinity()), &ControlSizeTrigger::_OnPropertyChanged)
);

const DependencyProperty ControlSizeTrigger::_minHeightProperty = DependencyProperty::Register(
L"MinHeight",
xaml_typename<double>(),
xaml_typename<Magpie::App::ControlSizeTrigger>(),
PropertyMetadata(box_value(0.0), &ControlSizeTrigger::_OnPropertyChanged)
);

const DependencyProperty ControlSizeTrigger::_targetElementProperty = DependencyProperty::Register(
L"TargetElement",
xaml_typename<FrameworkElement>(),
xaml_typename<Magpie::App::ControlSizeTrigger>(),
PropertyMetadata(nullptr, &ControlSizeTrigger::_OnTargetElementChanged)
);

void ControlSizeTrigger::_OnPropertyChanged(DependencyObject const& sender, DependencyPropertyChangedEventArgs const&) {
get_self<ControlSizeTrigger>(sender.as<Magpie::App::ControlSizeTrigger>())->_UpdateTrigger();
}

void ControlSizeTrigger::_OnTargetElementChanged(DependencyObject const& sender, DependencyPropertyChangedEventArgs const& e) {
ControlSizeTrigger* that = get_self<ControlSizeTrigger>(sender.as<Magpie::App::ControlSizeTrigger>());

that->_targetElementSizeChangedRevoker.revoke();

if (IInspectable newValue = e.NewValue()) {
that->_targetElementSizeChangedRevoker = newValue.as<FrameworkElement>().SizeChanged(auto_revoke,
[that](IInspectable const&, SizeChangedEventArgs const&) {
that->_UpdateTrigger();
}
);
}

that->_UpdateTrigger();
}

void ControlSizeTrigger::_UpdateTrigger() {
const FrameworkElement targetElement = TargetElement();

if (!targetElement || !CanTrigger()) {
SetActive(false);
return;
}

const double actualWidth = targetElement.ActualWidth();
const double actualHeight = targetElement.ActualHeight();
SetActive(
actualWidth >= MinWidth() &&
actualWidth < MaxWidth() &&
actualHeight >= MinHeight() &&
actualHeight < MaxHeight()
);
}

}
102 changes: 102 additions & 0 deletions src/Magpie.App/ControlSizeTrigger.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#pragma once
#include "ControlSizeTrigger.g.h"

namespace winrt::Magpie::App::implementation {

struct ControlSizeTrigger : ControlSizeTriggerT<ControlSizeTrigger> {
bool CanTrigger() {
return GetValue(_canTriggerProperty).as<bool>();
}

void CanTrigger(bool value) {
SetValue(_canTriggerProperty, box_value(value));
}

double MaxWidth() {
return GetValue(_maxWidthProperty).as<double>();
}

void MaxWidth(double value) {
SetValue(_maxWidthProperty, box_value(value));
}

double MinWidth() {
return GetValue(_minWidthProperty).as<double>();
}

void MinWidth(double value) {
SetValue(_minWidthProperty, box_value(value));
}

double MaxHeight() {
return GetValue(_maxHeightProperty).as<double>();
}

void MaxHeight(double value) {
SetValue(_maxHeightProperty, box_value(value));
}

double MinHeight() {
return GetValue(_minHeightProperty).as<double>();
}

void MinHeight(double value) {
SetValue(_minHeightProperty, box_value(value));
}

FrameworkElement TargetElement() {
return GetValue(_targetElementProperty).as<FrameworkElement>();
}

void TargetElement(FrameworkElement const& value) {
SetValue(_targetElementProperty, box_value(value));
}

static DependencyProperty CanTriggerProperty() {
return _canTriggerProperty;
}

static DependencyProperty MaxWidthProperty() {
return _maxWidthProperty;
}

static DependencyProperty MinWidthProperty() {
return _minWidthProperty;
}

static DependencyProperty MaxHeightProperty() {
return _maxHeightProperty;
}

static DependencyProperty MinHeightProperty() {
return _minHeightProperty;
}

static DependencyProperty TargetElementProperty() {
return _targetElementProperty;
}

private:
static const DependencyProperty _canTriggerProperty;
static const DependencyProperty _maxWidthProperty;
static const DependencyProperty _minWidthProperty;
static const DependencyProperty _maxHeightProperty;
static const DependencyProperty _minHeightProperty;
static const DependencyProperty _targetElementProperty;

static void _OnPropertyChanged(DependencyObject const& sender, DependencyPropertyChangedEventArgs const&);
static void _OnTargetElementChanged(DependencyObject const& sender, DependencyPropertyChangedEventArgs const& );

void _UpdateTrigger();

FrameworkElement::SizeChanged_revoker _targetElementSizeChangedRevoker;
};

}

namespace winrt::Magpie::App::factory_implementation {

struct ControlSizeTrigger : ControlSizeTriggerT<ControlSizeTrigger, implementation::ControlSizeTrigger> {
};

}
19 changes: 19 additions & 0 deletions src/Magpie.App/ControlSizeTrigger.idl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace Magpie.App {
runtimeclass ControlSizeTrigger : Windows.UI.Xaml.StateTriggerBase {
ControlSizeTrigger();

Boolean CanTrigger;
Double MaxWidth;
Double MinWidth;
Double MaxHeight;
Double MinHeight;
Windows.UI.Xaml.FrameworkElement TargetElement;

static Windows.UI.Xaml.DependencyProperty CanTriggerProperty { get; };
static Windows.UI.Xaml.DependencyProperty MaxWidthProperty { get; };
static Windows.UI.Xaml.DependencyProperty MinWidthProperty { get; };
static Windows.UI.Xaml.DependencyProperty MaxHeightProperty { get; };
static Windows.UI.Xaml.DependencyProperty MinHeightProperty { get; };
static Windows.UI.Xaml.DependencyProperty TargetElementProperty{ get; };
}
}
4 changes: 2 additions & 2 deletions src/Magpie.App/EffectParametersViewModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ void EffectParametersViewModel::_ScalingModeBoolParameter_PropertyChanged(
}

ScalingModeBoolParameter* boolParamImpl =
get_self<ScalingModeBoolParameter>(sender.as<default_interface<ScalingModeBoolParameter>>());
get_self<ScalingModeBoolParameter>(sender.as<Magpie::App::ScalingModeBoolParameter>());
const std::string& effectName = _effectInfo->params[boolParamImpl->Index()].name;
_Data()[StrUtils::UTF8ToUTF16(effectName)] = (float)boolParamImpl->Value();

Expand All @@ -146,7 +146,7 @@ void EffectParametersViewModel::_ScalingModeFloatParameter_PropertyChanged(
}

ScalingModeFloatParameter* floatParamImpl =
get_self<ScalingModeFloatParameter>(sender.as<default_interface<ScalingModeFloatParameter>>());
get_self<ScalingModeFloatParameter>(sender.as<Magpie::App::ScalingModeFloatParameter>());
const std::string& effectName = _effectInfo->params[floatParamImpl->Index()].name;
_Data()[StrUtils::UTF8ToUTF16(effectName)] = (float)floatParamImpl->Value();

Expand Down
17 changes: 11 additions & 6 deletions src/Magpie.App/IsEqualStateTrigger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,22 @@ static bool AreValuesEqual(IInspectable const& value1, IInspectable const& value
if (get_class_name(value1) != get_class_name(value2)) {
return false;
}

// IsEqualStateTrigger 目前只在 SettingsCard 中用于比较枚举类型,其他类型都不支持。
// 与 C# 不同,C++ 无法在运行时动态转换类型,或者需要付出很大的代价才能实现。

if (IPropertyValue v1 = value1.try_as<IPropertyValue>()) {
IPropertyValue v2 = value1.as<IPropertyValue>();

if (!v1.IsNumericScalar()) {
// 没有必要为每种类型都添加处理逻辑,IsEqualStateTrigger 目前只在 SettingsCard 中用于比较枚举类型
switch (v1.Type()) {
case PropertyType::OtherType:
{
return value1.as<IReference<ContentAlignment>>() == value2.as<IReference<ContentAlignment>>();
/*int a = v1.GetInt32();
int b = v2.GetInt32();
return a == b;*/
}
default:
return false;
}

return v1.GetInt32() == v2.GetInt32();
} else {
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Magpie.App/KeyVisual.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@ void KeyVisual::OnApplyTemplate() {
}

void KeyVisual::_OnPropertyChanged(DependencyObject const& sender, DependencyPropertyChangedEventArgs const&) {
get_self<KeyVisual>(sender.as<default_interface<KeyVisual>>())->_Update();
get_self<KeyVisual>(sender.as<Magpie::App::KeyVisual>())->_Update();
}

void KeyVisual::_OnIsErrorChanged(DependencyObject const& sender, DependencyPropertyChangedEventArgs const&) {
get_self<KeyVisual>(sender.as<default_interface<KeyVisual>>())->_SetErrorState();
get_self<KeyVisual>(sender.as<Magpie::App::KeyVisual>())->_SetErrorState();
}

void KeyVisual::_IsEnabledChanged(IInspectable const&, DependencyPropertyChangedEventArgs const&) {
Expand Down
13 changes: 12 additions & 1 deletion src/Magpie.App/Magpie.App.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@
</ClInclude>
<ClInclude Include="ComboBoxHelper.h" />
<ClInclude Include="ContentDialogHelper.h" />
<ClInclude Include="ControlSizeTrigger.h">
<DependentUpon>ControlSizeTrigger.idl</DependentUpon>
<SubType>Code</SubType>
</ClInclude>
<ClInclude Include="EffectHelper.h" />
<ClInclude Include="EffectParametersViewModel.h">
<DependentUpon>EffectParametersViewModel.idl</DependentUpon>
Expand Down Expand Up @@ -259,6 +263,10 @@
<SubType>Code</SubType>
</ClCompile>
<ClCompile Include="ContentDialogHelper.cpp" />
<ClCompile Include="ControlSizeTrigger.cpp">
<DependentUpon>ControlSizeTrigger.idl</DependentUpon>
<SubType>Code</SubType>
</ClCompile>
<ClCompile Include="EffectParametersViewModel.cpp">
<DependentUpon>EffectParametersViewModel.idl</DependentUpon>
<SubType>Code</SubType>
Expand Down Expand Up @@ -394,6 +402,9 @@
<None Include="IsNullStateTrigger.idl">
<SubType>Designer</SubType>
</None>
<None Include="ControlSizeTrigger.idl">
<SubType>Designer</SubType>
</None>
<None Include="SettingsCard2.idl">
<SubType>Code</SubType>
</None>
Expand Down Expand Up @@ -605,4 +616,4 @@
<Error Condition="!Exists('..\..\packages\Microsoft.UI.Xaml.2.8.6\build\native\Microsoft.UI.Xaml.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.UI.Xaml.2.8.6\build\native\Microsoft.UI.Xaml.props'))" />
<Error Condition="!Exists('..\..\packages\Microsoft.UI.Xaml.2.8.6\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.UI.Xaml.2.8.6\build\native\Microsoft.UI.Xaml.targets'))" />
</Target>
</Project>
</Project>
5 changes: 4 additions & 1 deletion src/Magpie.App/Magpie.App.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,9 @@
<None Include="IsNullStateTrigger.idl">
<Filter>Triggers</Filter>
</None>
<None Include="ControlSizeTrigger.idl">
<Filter>Triggers</Filter>
</None>
</ItemGroup>
<ItemGroup>
<Page Include="RootPage.xaml" />
Expand Down Expand Up @@ -331,4 +334,4 @@
<ItemGroup>
<Text Include="conanfile.txt" />
</ItemGroup>
</Project>
</Project>
8 changes: 4 additions & 4 deletions src/Magpie.App/PageFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,25 +83,25 @@ void PageFrame::_Update() {
}

void PageFrame::_OnTitleChanged(DependencyObject const& sender, DependencyPropertyChangedEventArgs const&) {
PageFrame* that = get_self<PageFrame>(sender.as<default_interface<PageFrame>>());
PageFrame* that = get_self<PageFrame>(sender.as<Magpie::App::PageFrame>());
that->_Update();
that->_propertyChangedEvent(*that, PropertyChangedEventArgs{ L"Title" });
}

void PageFrame::_OnIconChanged(DependencyObject const& sender, DependencyPropertyChangedEventArgs const&) {
PageFrame* that = get_self<PageFrame>(sender.as<default_interface<PageFrame>>());
PageFrame* that = get_self<PageFrame>(sender.as<Magpie::App::PageFrame>());
that->_Update();
that->_propertyChangedEvent(*that, PropertyChangedEventArgs{ L"Icon" });
}

void PageFrame::_OnHeaderActionChanged(DependencyObject const& sender, DependencyPropertyChangedEventArgs const&) {
PageFrame* that = get_self<PageFrame>(sender.as<default_interface<PageFrame>>());
PageFrame* that = get_self<PageFrame>(sender.as<Magpie::App::PageFrame>());
that->_Update();
that->_propertyChangedEvent(*that, PropertyChangedEventArgs{ L"HeaderAction" });
}

void PageFrame::_OnMainContentChanged(DependencyObject const& sender, DependencyPropertyChangedEventArgs const&) {
PageFrame* that = get_self<PageFrame>(sender.as<default_interface<PageFrame>>());
PageFrame* that = get_self<PageFrame>(sender.as<Magpie::App::PageFrame>());
that->_propertyChangedEvent(*that, PropertyChangedEventArgs{ L"MainContent" });
}

Expand Down
Loading

0 comments on commit 4c83669

Please sign in to comment.