diff --git a/src/Calculator/Calculator.vcxproj b/src/Calculator/Calculator.vcxproj
index f29fd3d4..4dfced8d 100644
--- a/src/Calculator/Calculator.vcxproj
+++ b/src/Calculator/Calculator.vcxproj
@@ -257,6 +257,7 @@
+
App.xaml
@@ -390,6 +391,7 @@
+
Create
Create
diff --git a/src/Calculator/Controls/HorizontalNoOverflowStackPanel.cpp b/src/Calculator/Controls/HorizontalNoOverflowStackPanel.cpp
new file mode 100644
index 00000000..fed185bc
--- /dev/null
+++ b/src/Calculator/Controls/HorizontalNoOverflowStackPanel.cpp
@@ -0,0 +1,66 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+// HorizontalNoOverflowStackPanel.xaml.cpp
+// Implementation of the HorizontalNoOverflowStackPanel class
+//
+
+#include "pch.h"
+#include "HorizontalNoOverflowStackPanel.h"
+
+using namespace std;
+using namespace CalculatorApp::Controls;
+using namespace Windows::Foundation;
+
+Size HorizontalNoOverflowStackPanel::MeasureOverride(Size availableSize)
+{
+ float maxHeight = 0;
+ float width = 0;
+ for (auto child : Children)
+ {
+ child->Measure(Size(numeric_limits::infinity(), numeric_limits::infinity()));
+ maxHeight = max(maxHeight, child->DesiredSize.Height);
+ width += child->DesiredSize.Width;
+ }
+ return Size(min(width, availableSize.Width), min(availableSize.Height, maxHeight));
+}
+
+bool HorizontalNoOverflowStackPanel::ShouldPrioritizeLastItem()
+{
+ return false;
+}
+
+Size HorizontalNoOverflowStackPanel::ArrangeOverride(Size finalSize)
+{
+ float posX = 0;
+ if (Children->Size == 0)
+ return finalSize;
+
+ auto lastChild = Children->GetAt(Children->Size - 1);
+ float lastChildWidth = 0;
+ if (Children->Size > 2 && ShouldPrioritizeLastItem())
+ lastChildWidth = lastChild->DesiredSize.Width;
+ for (auto item : Children)
+ {
+ auto widthAvailable = finalSize.Width - posX;
+ if (item != lastChild)
+ {
+ widthAvailable -= lastChildWidth;
+ }
+ float itemWidth = item->DesiredSize.Width;
+ if (widthAvailable > 0 && itemWidth <= widthAvailable)
+ {
+ //stack the items horizontally (left to right)
+ item->Arrange(Rect(posX, 0, itemWidth, finalSize.Height));
+ posX += item->DesiredSize.Width;
+ }
+ else
+ {
+ //Not display the item
+ item->Arrange(Rect(0, 0, 0, 0));
+ }
+ }
+ return finalSize;
+}
+
diff --git a/src/Calculator/Controls/HorizontalNoOverflowStackPanel.h b/src/Calculator/Controls/HorizontalNoOverflowStackPanel.h
new file mode 100644
index 00000000..7619faf4
--- /dev/null
+++ b/src/Calculator/Controls/HorizontalNoOverflowStackPanel.h
@@ -0,0 +1,28 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+//
+// HorizontalNoOverflowStackPanel.h
+// Declaration of the HorizontalNoOverflowStackPanel class
+//
+
+#pragma once
+#include "CalcViewModel/Common/Utils.h"
+
+namespace CalculatorApp
+{
+ namespace Controls
+ {
+ public ref class HorizontalNoOverflowStackPanel : public Windows::UI::Xaml::Controls::Panel
+ {
+ DEPENDENCY_PROPERTY_OWNER(HorizontalNoOverflowStackPanel);
+ //Prioritize the last item over all other items (except the first one)
+ internal:
+ HorizontalNoOverflowStackPanel() {}
+ protected:
+ virtual Windows::Foundation::Size MeasureOverride(Windows::Foundation::Size availableSize) override;
+ virtual Windows::Foundation::Size ArrangeOverride(Windows::Foundation::Size finalSize) override;
+ virtual bool ShouldPrioritizeLastItem();
+ };
+ }
+}
diff --git a/src/Calculator/Controls/SupplementaryItemsControl.cpp b/src/Calculator/Controls/SupplementaryItemsControl.cpp
index d5bc00a4..665c1d16 100644
--- a/src/Calculator/Controls/SupplementaryItemsControl.cpp
+++ b/src/Calculator/Controls/SupplementaryItemsControl.cpp
@@ -38,5 +38,3 @@ void SupplementaryItemsControl::PrepareContainerForItemOverride(DependencyObject
{
return ref new SupplementaryContentPresenterAP(this);
}
-
-
diff --git a/src/Calculator/Views/SupplementaryResults.xaml b/src/Calculator/Views/SupplementaryResults.xaml
index 9ac6421d..c3db4f40 100644
--- a/src/Calculator/Views/SupplementaryResults.xaml
+++ b/src/Calculator/Views/SupplementaryResults.xaml
@@ -80,7 +80,7 @@
-
+
@@ -102,6 +102,6 @@
Style="{ThemeResource SupplementaryValuesStyle}"
IsTextScaleFactorEnabled="False"
ItemTemplateSelector="{StaticResource ResultTemplateSelector}"
- LayoutUpdated="OnSupplementaryValuesLayoutUpdated"/>
+ ItemsSource="{x:Bind Results, Mode=OneWay}"/>
diff --git a/src/Calculator/Views/SupplementaryResults.xaml.cpp b/src/Calculator/Views/SupplementaryResults.xaml.cpp
index d598ae93..4f832777 100644
--- a/src/Calculator/Views/SupplementaryResults.xaml.cpp
+++ b/src/Calculator/Views/SupplementaryResults.xaml.cpp
@@ -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(value);
@@ -66,70 +68,17 @@ SupplementaryResults::SupplementaryResults() :
m_data(ref new Vector)
{
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(this->DataContext)->SupplementaryResults)
- {
- m_data->Append(sr);
- }
-
- // Set as source
- SupplementaryValues->ItemsSource = m_data;
-}
-
-void SupplementaryResults::OnLoaded(Object^ sender, RoutedEventArgs^ e)
-{
- UnitConverterViewModel^ vm = safe_cast(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 == UnitConverterViewModelProperties::SupplementaryResults)
- {
- 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(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);
- }
- }
- }
- }
+ if (Children->Size == 0)
+ return false;
+ auto lastChild = dynamic_cast(Children->GetAt(Children->Size - 1));
+ if (lastChild == nullptr)
+ return false;
+ auto suppResult = dynamic_cast(lastChild->DataContext);
+ if (suppResult == nullptr)
+ return false;
+ return suppResult->IsWhimsical();
}
diff --git a/src/Calculator/Views/SupplementaryResults.xaml.h b/src/Calculator/Views/SupplementaryResults.xaml.h
index 1d94b0ab..447f1de2 100644
--- a/src/Calculator/Views/SupplementaryResults.xaml.h
+++ b/src/Calculator/Views/SupplementaryResults.xaml.h
@@ -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,23 @@ 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();
-
+ DEPENDENCY_PROPERTY_OWNER(SupplementaryResults);
+ DEPENDENCY_PROPERTY_WITH_DEFAULT(Windows::Foundation::Collections::IIterable^, Results, nullptr);
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^ m_data;
};
}
diff --git a/src/Calculator/Views/UnitConverter.xaml b/src/Calculator/Views/UnitConverter.xaml
index ca3a63e4..2e3e2ed7 100644
--- a/src/Calculator/Views/UnitConverter.xaml
+++ b/src/Calculator/Views/UnitConverter.xaml
@@ -599,6 +599,7 @@