Improve performance of SupplementaryResult + Modify the height of RowDltrUnits when UnitConverter is in Landscape (#249)

* Modify the height of RowDltrUnits when UnitConverter  is in LandscapeLayout mode

* clean

* Use the same layout than the existing one while fixing the issue

* Refactor SupplementaryItemsControl to improve performance, not rely on parents and not force the parent element to be HorizonAlignment="stretch"

* take feedback into account

* add HorizontalNoOverflowStackPanel to vcproj.filters

* format conditionals

* replace max by std::max
This commit is contained in:
Rudy Huyn
2019-03-26 11:24:36 -07:00
committed by Pepe Rivera
parent e9aea9237d
commit ef3f5e9cbb
11 changed files with 151 additions and 82 deletions

View File

@@ -80,7 +80,7 @@
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
<local:SupplementaryResultNoOverflowStackPanel/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
@@ -102,6 +102,6 @@
Style="{ThemeResource SupplementaryValuesStyle}"
IsTextScaleFactorEnabled="False"
ItemTemplateSelector="{StaticResource ResultTemplateSelector}"
LayoutUpdated="OnSupplementaryValuesLayoutUpdated"/>
ItemsSource="{x:Bind Results, Mode=OneWay}"/>
</StackPanel>
</UserControl>

View File

@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//
@@ -27,6 +27,8 @@ using namespace Windows::UI::Xaml::Navigation;
// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
DEPENDENCY_PROPERTY_INITIALIZATION(SupplementaryResults, Results);
Object^ DelighterUnitToStyleConverter::Convert(Object^ value, TypeName /*targetType*/, Object^ /*parameter*/, String^ /*language*/)
{
Unit^ unit = safe_cast<Unit^>(value);
@@ -62,74 +64,22 @@ Windows::UI::Xaml::DataTemplate^ SupplementaryResultDataTemplateSelector::Select
}
}
SupplementaryResults::SupplementaryResults() :
m_data(ref new Vector<SupplementaryResult^>)
SupplementaryResults::SupplementaryResults()
{
InitializeComponent();
this->Loaded += ref new RoutedEventHandler(this, &SupplementaryResults::OnLoaded);
}
void SupplementaryResults::RefreshData()
bool SupplementaryResultNoOverflowStackPanel::ShouldPrioritizeLastItem()
{
// Copy the list so that when we chop stuff off, we don't modify the original
// complete list.
m_data->Clear();
for(SupplementaryResult^ sr : safe_cast<UnitConverterViewModel^>(this->DataContext)->SupplementaryResults)
if (Children->Size == 0)
{
m_data->Append(sr);
return false;
}
// Set as source
SupplementaryValues->ItemsSource = m_data;
}
void SupplementaryResults::OnLoaded(Object^ sender, RoutedEventArgs^ e)
{
UnitConverterViewModel^ vm = safe_cast<UnitConverterViewModel^>(this->DataContext);
vm->PropertyChanged += ref new PropertyChangedEventHandler(this, &SupplementaryResults::OnConverterPropertyChanged);
Window::Current->SizeChanged += ref new WindowSizeChangedEventHandler(this, &SupplementaryResults::OnWindowSizeChanged);
// We may be loaded into a state where we need to render (like rehydrate), so prepare data
RefreshData();
}
void SupplementaryResults::OnConverterPropertyChanged(Object^ /*sender*/, PropertyChangedEventArgs^ e)
{
if (e->PropertyName == UnitConverterViewModel::SupplementaryResultsPropertyName)
auto lastChild = dynamic_cast<FrameworkElement^>(Children->GetAt(Children->Size - 1));
if (lastChild == nullptr)
{
RefreshData();
}
}
void SupplementaryResults::OnWindowSizeChanged(Platform::Object^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ e)
{
// to reload supplementary results every time the window is resized
RefreshData();
}
void SupplementaryResults::OnSupplementaryValuesLayoutUpdated(Platform::Object^ sender, Platform::Object^ e)
{
// This means we overflowed and are cutting off, or in a very rare case we fit exactly. Unfortunately
// the fitting exactly case will still have an item removed, as there is no other way for us to
// detect that we need to trim.
Grid^ parentGrid = dynamic_cast<Grid^>(VisualTreeHelper::GetParent(this));
if (parentGrid != nullptr)
{
double parentWidth = parentGrid->ActualWidth;
if (SupplementaryValues && SupplementaryValues->ActualWidth >= parentWidth)
{
if (m_data->Size > 0)
{
SupplementaryResult^ last = m_data->GetAt(m_data->Size - 1);
if (!last->IsWhimsical() || m_data->Size <= 2)
{
m_data->RemoveAtEnd();
}
else
{
m_data->RemoveAt(m_data->Size - 2);
}
}
}
return false;
}
auto suppResult = dynamic_cast<SupplementaryResult^>(lastChild->DataContext);
return suppResult == nullptr? false: suppResult->IsWhimsical();
}

View File

@@ -12,6 +12,7 @@
#include "Controls/SupplementaryItemsControl.h"
#include "Controls/OperandTextBox.h"
#include "Controls/OperatorTextBox.h"
#include "Controls/HorizontalNoOverflowStackPanel.h"
#include "CalcViewModel/UnitConverterViewModel.h"
namespace CalculatorApp
@@ -58,18 +59,18 @@ namespace CalculatorApp
Windows::UI::Xaml::DataTemplate^ m_delighterTemplate;
};
public ref class SupplementaryResultNoOverflowStackPanel sealed: public CalculatorApp::Controls::HorizontalNoOverflowStackPanel
{
protected:
virtual bool ShouldPrioritizeLastItem() override;
};
[Windows::Foundation::Metadata::WebHostHidden]
public ref class SupplementaryResults sealed
{
public:
SupplementaryResults();
private:
void RefreshData();
void OnLoaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void OnConverterPropertyChanged(Platform::Object^ sender, Windows::UI::Xaml::Data::PropertyChangedEventArgs^ e);
void OnSupplementaryValuesLayoutUpdated(Platform::Object^ sender, Platform::Object^ e);
void OnWindowSizeChanged(Platform::Object^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ e);
Windows::Foundation::Collections::IObservableVector<ViewModel::SupplementaryResult^>^ m_data;
DEPENDENCY_PROPERTY_OWNER(SupplementaryResults);
DEPENDENCY_PROPERTY_WITH_DEFAULT(Windows::Foundation::Collections::IIterable<ViewModel::SupplementaryResult^>^, Results, nullptr);
};
}

View File

@@ -1,4 +1,4 @@
<UserControl x:Class="CalculatorApp.UnitConverter"
<UserControl x:Class="CalculatorApp.UnitConverter"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:automation="using:CalculatorApp.Common.Automation"
@@ -593,15 +593,20 @@
TabIndex="4"
Visibility="{x:Bind Model.IsCurrencyLoadingVisible, Mode=OneWay, Converter={StaticResource BooleanToVisibilityNegationConverter}}"/>
<Grid x:Name="SupplementaryResultsPanelInGrid"
Grid.Row="5"
Grid.Column="1"
Margin="12,0,12,0"
FlowDirection="{x:Bind LayoutDirection}"
Visibility="{x:Bind Model.IsCurrencyLoadingVisible, Mode=OneWay, Converter={StaticResource BooleanToVisibilityNegationConverter}}">
<StackPanel x:Name="SupplementaryResultsPanelInGrid"
Grid.Row="5"
Grid.Column="1"
MinHeight="48"
Margin="12,0,6,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
FlowDirection="{x:Bind LayoutDirection}"
SizeChanged="SupplementaryResultsPanelInGrid_SizeChanged"
Visibility="{x:Bind Model.IsCurrencyLoadingVisible, Mode=OneWay, Converter={StaticResource BooleanToVisibilityNegationConverter}}">
<local:SupplementaryResults x:Name="SupplementaryResults"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Results="{x:Bind Model.SupplementaryResults, Mode=OneWay}"
Visibility="{x:Bind Model.SupplementaryVisibility, Mode=OneWay}"/>
<StackPanel Visibility="{x:Bind Model.IsCurrencyCurrentCategory, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}">
<!-- Currency Ratio Equality -->
@@ -651,7 +656,7 @@
</TextBlock>
</ContentControl>
</StackPanel>
</Grid>
</StackPanel>
<Grid x:Name="ConverterNumPad"
Grid.Row="6"

View File

@@ -14,6 +14,7 @@
#include "CalcViewModel/Common/LocalizationService.h"
#include "CalcViewModel/Common/LocalizationSettings.h"
using namespace std;
using namespace CalculatorApp;
using namespace CalculatorApp::Common;
using namespace CalculatorApp::Controls;
@@ -376,3 +377,10 @@ void UnitConverter::HideProgressRing()
CurrencyLoadingProgressRing->IsActive = false;
}
// The function will make sure the UI will have enough space to display supplementary results and currency information
void CalculatorApp::UnitConverter::SupplementaryResultsPanelInGrid_SizeChanged(Platform::Object^ sender, Windows::UI::Xaml::SizeChangedEventArgs^ e)
{
//We add 0.01 to be sure to not create an infinite loop with SizeChanged events cascading due to float approximation
RowDltrUnits->MinHeight = max(48.0, e->NewSize.Height + 0.01);
}

View File

@@ -88,5 +88,6 @@ namespace CalculatorApp
Windows::UI::Xaml::DispatcherTimer^ m_delayTimer;
bool m_isAnimationEnabled;
void SupplementaryResultsPanelInGrid_SizeChanged(Platform::Object^ sender, Windows::UI::Xaml::SizeChangedEventArgs^ e);
};
}