Hello GitHub

This commit is contained in:
Howard Wolosky
2019-01-28 16:24:37 -08:00
parent 456fe5e355
commit c13b8a099e
822 changed files with 276650 additions and 75 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,762 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "pch.h"
#include "Calculator.xaml.h"
#include "CalculatorStandardOperators.xaml.h"
#include "CalcViewModel\Common\CopyPasteManager.h"
#include "CalcViewModel\StandardCalculatorViewModel.h"
#include "CalcViewModel\ViewState.h"
#include "CalcViewModel\Common\LocalizationSettings.h"
#include "Memory.xaml.h"
#include "HistoryList.xaml.h"
using namespace CalculatorApp;
using namespace CalculatorApp::Common;
using namespace CalculatorApp::Converters;
using namespace CalculatorApp::Controls;
using namespace CalculatorApp::ViewModel;
using namespace Concurrency;
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::Globalization::NumberFormatting;
using namespace Windows::System;
using namespace Windows::UI::Core;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Automation;
using namespace Windows::UI::Xaml::Automation::Peers;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
using namespace Windows::System::Threading;
using namespace Windows::UI::ViewManagement;
DEPENDENCY_PROPERTY_INITIALIZATION(Calculator, IsStandard);
DEPENDENCY_PROPERTY_INITIALIZATION(Calculator, IsScientific);
DEPENDENCY_PROPERTY_INITIALIZATION(Calculator, IsProgrammer);
Calculator::Calculator() :
m_doAnimate(false),
m_isLastAnimatedInScientific(false),
m_isLastAnimatedInProgrammer(false),
m_resultAnimate(false)
{
SetFontSizeResources();
InitializeComponent();
LoadResourceStrings();
if (LocalizationService::GetInstance()->IsRtlLayout())
{
HistoryButton->HorizontalAlignment = ::HorizontalAlignment::Left;
}
m_displayFlyout = static_cast<MenuFlyout^>(Resources->Lookup(L"DisplayContextMenu"));
auto resLoader = AppResourceProvider::GetInstance();
CopyMenuItem->Text = resLoader.GetResourceString(L"copyMenuItem");
PasteMenuItem->Text = resLoader.GetResourceString(L"pasteMenuItem");
}
void Calculator::LoadResourceStrings()
{
auto resProvider = AppResourceProvider::GetInstance();
m_openMemoryFlyoutAutomationName = resProvider.GetResourceString(L"MemoryButton_Open");
m_closeMemoryFlyoutAutomationName = resProvider.GetResourceString(L"MemoryButton_Close");
m_openHistoryFlyoutAutomationName = resProvider.GetResourceString(L"HistoryButton_Open");
m_closeHistoryFlyoutAutomationName = resProvider.GetResourceString(L"HistoryButton_Close");
AutomationProperties::SetName(MemoryButton, m_openMemoryFlyoutAutomationName);
AutomationProperties::SetName(HistoryButton, m_openHistoryFlyoutAutomationName);
}
void Calculator::InitializeHistoryView(_In_ HistoryViewModel^ historyVM)
{
if (m_historyList == nullptr)
{
m_historyList = ref new HistoryList();
m_historyList->DataContext = historyVM;
historyVM->HideHistoryClicked += ref new ViewModel::HideHistoryClickedHandler(this, &Calculator::OnHideHistoryClicked);
historyVM->HistoryItemClicked += ref new ViewModel::HistoryItemClickedHandler(this, &Calculator::OnHistoryItemClicked);
}
}
void Calculator::SetFontSizeResources()
{
// Since we need different font sizes for different numeric system,
// we use a table of optimal font sizes for each numeric system.
static const FontTable fontTables[] = {
{ L"Arab", 104, 29.333, 23, 40, 56, 40, 56 },
{ L"ArabExt", 104, 29.333, 23, 40, 56, 40, 56 },
{ L"Beng", 104, 26, 17, 40, 56, 40, 56 },
{ L"Deva", 104, 29.333, 20.5, 40, 56, 40, 56 },
{ L"Gujr", 104, 29.333, 18.5, 40, 56, 40, 56 },
{ L"Khmr", 104, 29.333, 19.5, 40, 56, 40, 56 },
{ L"Knda", 104, 25, 17, 40, 56, 40, 56 },
{ L"Laoo", 104, 28, 18, 40, 56, 40, 56 },
{ L"Latn", 104, 29.333, 23, 40, 56, 40, 56 },
{ L"Mlym", 80, 22, 15.5, 30, 56, 35, 48 },
{ L"Mymr", 104, 29.333, 20, 35, 48, 36, 48 },
{ L"Orya", 88, 26, 20, 40, 56, 40, 56 },
{ L"TamlDec", 77, 25, 16, 28, 48, 34, 48 },
{ L"Telu", 104, 25, 16.5, 40, 56, 40, 56 },
{ L"Thai", 104, 28, 18, 40, 56, 40, 56 },
{ L"Tibt", 104, 29.333, 20, 40, 56, 40, 56 },
{ L"Default", 104, 29.333, 23, 40, 56, 40, 56 }
};
DecimalFormatter^ formatter = LocalizationService::GetRegionalSettingsAwareDecimalFormatter();
const FontTable* currentItem = fontTables;
while (currentItem->numericSystem.compare(std::wstring(L"Default")) != 0 &&
currentItem->numericSystem.compare(formatter->NumeralSystem->Data()) != 0)
{
currentItem++;
}
this->Resources->Insert(StringReference(L"ResultFullFontSize"), currentItem->fullFont);
this->Resources->Insert(StringReference(L"ResultFullMinFontSize"), currentItem->fullFontMin);
this->Resources->Insert(StringReference(L"ResultPortraitMinFontSize"), currentItem->portraitMin);
this->Resources->Insert(StringReference(L"ResultSnapFontSize"), currentItem->snapFont);
this->Resources->Insert(StringReference(L"CalcButtonCaptionSizeOverride"), currentItem->fullNumPadFont);
this->Resources->Insert(StringReference(L"CalcButtonScientificSnapCaptionSizeOverride"), currentItem->snapScientificNumPadFont);
this->Resources->Insert(StringReference(L"CalcButtonScientificPortraitCaptionSizeOverride"), currentItem->portraitScientificNumPadFont);
}
void Calculator::OnLoaded(_In_ Object^, _In_ RoutedEventArgs^)
{
Model->PropertyChanged += ref new PropertyChangedEventHandler(this, &Calculator::OnCalcPropertyChanged);
Model->HideMemoryClicked += ref new HideMemoryClickedHandler(this, &Calculator::OnHideMemoryClicked);
InitializeHistoryView(Model->HistoryVM);
String^ historyPaneName = AppResourceProvider::GetInstance().GetResourceString(L"HistoryPane");
HistoryFlyout->FlyoutPresenterStyle->Setters->Append(ref new Setter(AutomationProperties::NameProperty, historyPaneName));
String^ memoryPaneName = AppResourceProvider::GetInstance().GetResourceString(L"MemoryPane");
MemoryFlyout->FlyoutPresenterStyle->Setters->Append(ref new Setter(AutomationProperties::NameProperty, memoryPaneName));
if (Windows::Foundation::Metadata::ApiInformation::IsEventPresent(L"Windows.UI.Xaml.Controls.Primitives.FlyoutBase", L"Closing"))
{
HistoryFlyout->Closing += ref new TypedEventHandler<FlyoutBase^, FlyoutBaseClosingEventArgs^>(this, &Calculator::HistoryFlyout_Closing);
MemoryFlyout->Closing += ref new TypedEventHandler<FlyoutBase^, FlyoutBaseClosingEventArgs^>(this, &Calculator::OnMemoryFlyoutClosing);
}
// Delay load things later when we get a chance.
WeakReference weakThis(this);
this->Dispatcher->RunAsync(CoreDispatcherPriority::Normal, ref new DispatchedHandler([weakThis]()
{
if (TraceLogger::GetInstance().UpdateWindowIdLog(ApplicationView::GetApplicationViewIdForWindow(CoreWindow::GetForCurrentThread())))
{
auto refThis = weakThis.Resolve<Calculator>();
if (refThis != nullptr)
{
refThis->GetMemory();
}
}
}));
}
std::wstring Calculator::GetCurrentLayoutState()
{
std::wstring state;
if (IsProgrammer)
{
state = L"Programmer";
}
else if (IsScientific)
{
state = L"Scientific";
}
else
{
state = L"Standard";
}
return state;
}
void Calculator::UpdateViewState()
{
std::wstring state;
if (IsProgrammer)
{
state = L"Programmer";
Model->IsDecimalEnabled = false;
}
else if (IsScientific)
{
state = L"Scientific";
Model->IsDecimalEnabled = true;
}
else
{
state = L"Standard";
Model->IsDecimalEnabled = true;
}
CloseHistoryFlyout();
CloseMemoryFlyout();
VisualStateManager::GoToState(this, ref new String(state.c_str()), true/*useTransitions*/);
}
void Calculator::SetResultStyles()
{
CoreWindow^ window = CoreWindow::GetForCurrentThread();
if (window)
{
float curHeight = window->Bounds.Height;
if (curHeight >= 800)
{
Results->Style = ResultsStyleL;
RowResult->MinHeight = 108;
RowResult->Height = GridLength(72, GridUnitType::Star);
}
else if ((IsProgrammer && curHeight >= 640) || (IsScientific && curHeight >= 544) || IsStandard)
{
Results->Style = ResultsStyleM;
RowResult->MinHeight = 72;
RowResult->Height = GridLength(72, GridUnitType::Star);
}
else
{
Results->Style = ResultsStyleS;
RowResult->MinHeight = 42;
RowResult->Height = GridLength(42, GridUnitType::Star);
}
}
}
void Calculator::AnimateCalculator(bool resultAnimate)
{
if (App::IsAnimationEnabled())
{
m_doAnimate = true;
m_resultAnimate = resultAnimate;
if (((m_isLastAnimatedInScientific && IsScientific) || (!m_isLastAnimatedInScientific && !IsScientific)) && ((m_isLastAnimatedInProgrammer && IsProgrammer) || (!m_isLastAnimatedInProgrammer && !IsProgrammer)))
{
// We are forcing the animation here
// It's because if last animation was in standard, then go to unit converter, then comes back to standard
// The state for the calculator does not change and the animation would not get run.
this->OnStoryboardCompleted(nullptr, nullptr);
}
}
}
void Calculator::OnContextRequested(UIElement^ sender, ContextRequestedEventArgs^ e)
{
auto requestedElement = safe_cast<FrameworkElement^>(e->OriginalSource);
PasteMenuItem->IsEnabled = CopyPasteManager::HasStringToPaste();
Point point;
if (e->TryGetPosition(requestedElement, &point))
{
m_displayFlyout->ShowAt(requestedElement, point);
}
else
{
// Not invoked via pointer, so let XAML choose a default location.
m_displayFlyout->ShowAt(requestedElement);
}
e->Handled = true;
}
void Calculator::OnContextCanceled(UIElement^ sender, RoutedEventArgs^ e)
{
m_displayFlyout->Hide();
}
void Calculator::OnLayoutStateChanged(_In_ Object^ sender, _In_ Object^ e)
{
UpdateViewState();
UpdatePanelViewState();
}
void Calculator::OnIsStandardPropertyChanged(bool /*oldValue*/, bool newValue)
{
UpdateViewState();
UpdatePanelViewState();
}
void Calculator::OnIsScientificPropertyChanged(bool /*oldValue*/, bool newValue)
{
if (newValue)
{
EnsureScientific();
}
UpdateViewState();
UpdatePanelViewState();
}
void Calculator::OnIsProgrammerPropertyChanged(bool /*oldValue*/, bool newValue)
{
if (newValue)
{
EnsureProgrammer();
m_pivotItem = static_cast<Windows::UI::Xaml::Controls::PivotItem^>(DockPivot->Items->GetAt(0));
DockPivot->Items->RemoveAt(0);
}
else
{
if (m_pivotItem != nullptr && DockPivot->Items->Size == 1)
{
DockPivot->Items->InsertAt(0, m_pivotItem);
}
}
DockPivot->SelectedIndex = 0;
UpdateViewState();
UpdatePanelViewState();
}
void Calculator::OnIsInErrorPropertyChanged()
{
bool isError = Model->IsInError;
String^ newState = isError ? L"ErrorLayout" : L"NoErrorLayout";
VisualStateManager::GoToState(this, newState, false);
if (m_memory != nullptr)
{
m_memory->IsErrorVisualState = isError;
}
OpsPanel->IsErrorVisualState = isError;
if (IsScientific && ScientificAngleButtons)
{
ScientificAngleButtons->IsErrorVisualState = isError;
}
else if (IsProgrammer && ProgrammerDisplayPanel)
{
ProgrammerDisplayPanel->IsErrorVisualState = isError;
}
}
// Once the storyboard that rearranges the buttons completed,
// We do the animation based on the Mode or Orientation change.
void Calculator::OnStoryboardCompleted(_In_ Object^ sender, _In_ Object^ e)
{
m_isLastAnimatedInScientific = IsScientific;
m_isLastAnimatedInProgrammer = IsProgrammer;
if (m_doAnimate)
{
m_doAnimate = false;
if (m_resultAnimate)
{
m_resultAnimate = false;
Animate->Begin();
}
else
{
AnimateWithoutResult->Begin();
}
}
SetResultStyles();
}
void Calculator::EnsureScientific()
{
OpsPanel->EnsureScientificOps();
if (!ScientificAngleButtons)
{
this->FindName(L"ScientificAngleButtons");
}
}
void Calculator::EnsureProgrammer()
{
if (!ProgrammerOperators)
{
this->FindName(L"ProgrammerOperators");
}
if (!ProgrammerDisplayPanel)
{
this->FindName(L"ProgrammerDisplayPanel");
}
OpsPanel->EnsureProgrammerRadixOps();
ProgrammerOperators->SetRadixButton(Model->GetCurrentRadixType());
}
void Calculator::OnCalcPropertyChanged(_In_ Object^ sender, _In_ PropertyChangedEventArgs^ e)
{
String^ prop = e->PropertyName;
if (e->PropertyName->Equals(CalculatorViewModelProperties::IsMemoryEmpty))
{
UpdateMemoryState();
}
else if (e->PropertyName->Equals(CalculatorViewModelProperties::IsInError))
{
OnIsInErrorPropertyChanged();
}
}
void Calculator::UpdatePanelViewState()
{
UpdateHistoryState();
UpdateMemoryState();
}
void Calculator::UpdateHistoryState()
{
String^ viewState = App::GetAppViewState();
if (viewState == ViewState::DockedView)
{
// docked view
CloseHistoryFlyout();
SetChildAsHistory();
HistoryButton->Visibility = ::Visibility::Collapsed;
if (m_IsLastFlyoutHistory)
{
DockPivot->SelectedIndex = 0;
}
}
else
{ // flyout view
DockHistoryHolder->Child = nullptr;
if (!IsProgrammer)
{
HistoryButton->Visibility = ::Visibility::Visible;
}
}
}
void Calculator::UpdateMemoryState()
{
if (!Model->IsMemoryEmpty)
{
MemRecall->IsEnabled = true;
ClearMemoryButton->IsEnabled = true;
}
else
{
MemRecall->IsEnabled = false;
ClearMemoryButton->IsEnabled = false;
}
String^ viewState = App::GetAppViewState();
if (viewState == ViewState::DockedView)
{
CloseMemoryFlyout();
SetChildAsMemory();
MemoryButton->Visibility = ::Visibility::Collapsed;
if (m_IsLastFlyoutMemory && !IsProgrammer)
{
DockPivot->SelectedIndex = 1;
}
}
else
{
MemoryButton->Visibility = ::Visibility::Visible;
DockMemoryHolder->Child = nullptr;
}
}
void Calculator::SetChildAsMemory()
{
DockMemoryHolder->Child = GetMemory();
}
void Calculator::SetChildAsHistory()
{
if (m_historyList == nullptr)
{
InitializeHistoryView(Model->HistoryVM);
}
DockHistoryHolder->Child = m_historyList;
}
void Calculator::OnHideHistoryClicked()
{
ToggleHistoryFlyout(nullptr);
}
void Calculator::OnHistoryItemClicked(_In_ HistoryItemViewModel^ e)
{
unsigned int tokenSize;
assert(e->GetTokens() != nullptr);
e->GetTokens()->GetSize(&tokenSize);
TraceLogger::GetInstance().LogHistoryItemLoadBegin();
Model->SetHistoryExpressionDisplay(e->GetTokens(), e->GetCommands());
Model->SetExpressionDisplay(e->GetTokens(), e->GetCommands());
Model->SetPrimaryDisplay(e->Result->Data(), false);
Model->IsFToEEnabled = false;
TraceLogger::GetInstance().LogHistoryItemLoadEnd(tokenSize);
CloseHistoryFlyout();
this->Focus(::FocusState::Programmatic);
}
void Calculator::HistoryFlyout_Opened(_In_ Object ^sender, _In_ Object ^args)
{
m_fIsHistoryFlyoutOpen = true;
m_IsLastFlyoutMemory = false;
m_IsLastFlyoutHistory = true;
EnableControls(false);
AutomationProperties::SetName(HistoryButton, m_closeHistoryFlyoutAutomationName);
TraceLogger::GetInstance().LogHistoryFlyoutOpenEnd(Model->HistoryVM->ItemSize);
TraceLogger::GetInstance().LogHistoryBodyOpened();
}
void Calculator::HistoryFlyout_Closing(_In_ FlyoutBase^ sender, _In_ FlyoutBaseClosingEventArgs^ args)
{
// Set in the Closing event so the new name is available when the Flyout has Closed.
AutomationProperties::SetName(HistoryButton, m_openHistoryFlyoutAutomationName);
}
void Calculator::HistoryFlyout_Closed(_In_ Object ^sender, _In_ Object ^args)
{
// Ideally, this would be renamed in the Closing event because the Closed event is too late.
// Closing is not available until RS1+ so we set the name again here for TH2 support.
AutomationProperties::SetName(HistoryButton, m_openHistoryFlyoutAutomationName);
m_fIsHistoryFlyoutOpen = false;
EnableControls(true);
if (HistoryButton->IsEnabled)
{
HistoryButton->Focus(::FocusState::Programmatic);
}
FullscreenFlyoutClosed();
}
void Calculator::CloseHistoryFlyout()
{
if (m_fIsHistoryFlyoutOpen)
{
HistoryFlyout->Hide();
}
}
void Calculator::CloseMemoryFlyout()
{
if (m_fIsMemoryFlyoutOpen)
{
MemoryFlyout->Hide();
}
}
void Calculator::SetDefaultFocus()
{
Results->Focus(::FocusState::Programmatic);
}
void Calculator::ToggleHistoryFlyout(Object^ /*parameter*/)
{
String^ viewState = App::GetAppViewState();
// If app starts correctly in snap mode and shortcut is used for history then we need to load history if not yet initialized.
if (viewState != ViewState::DockedView)
{
if (m_fIsHistoryFlyoutOpen)
{
HistoryFlyout->Hide();
}
else
{
TraceLogger::GetInstance().LogHistoryFlyoutOpenBegin(Model->HistoryVM->ItemSize);
HistoryFlyout->Content = m_historyList;
m_historyList->RowHeight = NumpadPanel->ActualHeight;
FlyoutBase::ShowAttachedFlyout(HistoryButton);
}
}
}
void Calculator::ToggleMemoryFlyout()
{
String^ viewState = App::GetAppViewState();
if (viewState != ViewState::DockedView)
{
if (m_fIsMemoryFlyoutOpen)
{
MemoryFlyout->Hide();
}
else
{
TraceLogger::GetInstance().LogMemoryFlyoutOpenBegin(Model->MemorizedNumbers->Size);
MemoryFlyout->Content = GetMemory();
m_memory->RowHeight = NumpadPanel->ActualHeight;
FlyoutBase::ShowAttachedFlyout(MemoryButton);
}
}
}
void Calculator::OnMemoryFlyoutOpened(_In_ Object ^sender, _In_ Object ^args)
{
TraceLogger::GetInstance().LogMemoryFlyoutOpenEnd(Model->MemorizedNumbers->Size);
m_IsLastFlyoutMemory = true;
m_IsLastFlyoutHistory = false;
m_fIsMemoryFlyoutOpen = true;
AutomationProperties::SetName(MemoryButton, m_closeMemoryFlyoutAutomationName);
EnableControls(false);
TraceLogger::GetInstance().LogMemoryBodyOpened();
}
void Calculator::OnMemoryFlyoutClosing(_In_ FlyoutBase^ sender, _In_ FlyoutBaseClosingEventArgs^ args)
{
// Set in the Closing event so the new name is available when the Flyout has Closed.
AutomationProperties::SetName(MemoryButton, m_openMemoryFlyoutAutomationName);
}
void Calculator::OnMemoryFlyoutClosed(_In_ Object ^sender, _In_ Object ^args)
{
// Ideally, this would be renamed in the Closing event because the Closed event is too late.
// Closing is not available until RS1+ so we set the name again here for TH2 support.
AutomationProperties::SetName(MemoryButton, m_openMemoryFlyoutAutomationName);
m_fIsMemoryFlyoutOpen = false;
EnableControls(true);
if (MemoryButton->IsEnabled)
{
MemoryButton->Focus(::FocusState::Programmatic);
}
FullscreenFlyoutClosed();
}
Memory^ Calculator::GetMemory()
{
if (m_memory == nullptr)
{
m_memory = ref new Memory();
VisualStateManager::GoToState(m_memory, ref new String(GetCurrentLayoutState().c_str()), true/*useTransitions*/);
}
return m_memory;
}
void Calculator::OnHideMemoryClicked()
{
if (!m_fIsMemoryFlyoutOpen)
{
this->Focus(::FocusState::Programmatic);
}
MemoryFlyout->Hide();
}
void Calculator::EnableMemoryControls(bool enable)
{
memButton->IsEnabled = enable;
MemMinus->IsEnabled = enable;
MemPlus->IsEnabled = enable;
if (!Model->IsMemoryEmpty)
{
MemRecall->IsEnabled = enable;
ClearMemoryButton->IsEnabled = enable;
}
}
void Calculator::EnableControls(bool enable)
{
OpsPanel->IsEnabled = enable;
EnableMemoryControls(enable);
}
void Calculator::OnMemoryFlyOutTapped(_In_ Object^ sender, _In_ TappedRoutedEventArgs^ e)
{
Grid^ grid = safe_cast<Grid^> (sender);
Point point = e->GetPosition(nullptr);
if (point.Y < (grid->ActualHeight - NumpadPanel->ActualHeight))
{
MemoryFlyout->Hide();
}
}
void Calculator::OnHistoryFlyOutTapped(_In_ Object^ sender, _In_ TappedRoutedEventArgs^ e)
{
Grid^ grid = safe_cast<Grid^> (sender);
Point point = e->GetPosition(nullptr);
if (point.Y < (grid->ActualHeight - NumpadPanel->ActualHeight))
{
HistoryFlyout->Hide();
}
}
void Calculator::expressionContainer_LayoutUpdated(_In_ Object^ sender, _In_ Object^ e)
{
expressionText->UpdateScrollButtons();
}
bool Calculator::IsValidRegularExpression(std::wstring str)
{
bool result = false;
std::wregex regexPatterns[3];
regexPatterns[0] = L"[-]{0,1}[0-9]{0,}[.]{0,1}[0-9]{0,}";
regexPatterns[1] = L"[-]{0,1}[0-9]{0,}[.]{0,1}[0-9]{0,}[e]{1}[+]{1}[0-9]{1,}";
regexPatterns[2] = L"[-]{0,1}[0-9]{0,}[.]{0,1}[0-9]{0,}[e]{1}[-]{1}[0-9]{1,}";
const auto& localizer = LocalizationSettings::GetInstance();
String^ englishString = localizer.GetEnglishValueFromLocalizedDigits(str);
for (int i = 0; i < 3; ++i)
{
if (regex_match(englishString->Data(), regexPatterns[i]))
{
result = true;
break;
}
}
return result;
}
void Calculator::DockPanelTapped(_In_ TappedRoutedEventArgs^ e)
{
int index = DockPivot->SelectedIndex;
if (index == 1 && !IsProgrammer)
{
SetChildAsMemory();
}
m_IsLastFlyoutMemory = false;
m_IsLastFlyoutHistory = false;
}
void Calculator::OnResultsLayoutChanged(_In_ Object^ sender, _In_ Object^ e)
{
SetResultStyles();
}
void Calculator::UnregisterEventHandlers()
{
expressionText->UnregisterEventHandlers();
}
void Calculator::OnErrorLayoutCompleted(_In_ Object^ sender, _In_ Object^ e)
{
SetDefaultFocus();
}
void Calculator::OnHistoryAccessKeyInvoked(_In_ UIElement^ sender, _In_ AccessKeyInvokedEventArgs^ args)
{
DockPivot->SelectedItem = HistoryPivotItem;
}
void Calculator::OnMemoryAccessKeyInvoked(_In_ UIElement^ sender, _In_ AccessKeyInvokedEventArgs^ args)
{
DockPivot->SelectedItem = MemoryPivotItem;
}
void CalculatorApp::Calculator::DockPivot_SelectionChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e)
{
if (DockPivot->SelectedIndex == 0)
{
TraceLogger::GetInstance().LogHistoryBodyOpened();
}
else
{
TraceLogger::GetInstance().LogMemoryBodyOpened();
}
}

View File

@@ -0,0 +1,143 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
#include "Views\Calculator.g.h"
#include "Converters\BooleanNegationConverter.h"
#include "Converters\ExpressionItemContainerStyle.h"
#include "Converters\ExpressionItemTemplateSelector.h"
#include "Converters\VisibilityNegationConverter.h"
#include "CalcViewModel\Common\Automation\NarratorNotifier.h"
#include "Controls\CalculatorButton.h"
#include "Controls\CalculationResult.h"
#include "Controls\OverflowTextBlock.h"
#include "CalcViewModel\HistoryViewModel.h"
#include "Views\CalculatorProgrammerDisplayPanel.xaml.h"
#include "Views\CalculatorProgrammerOperators.xaml.h"
#include "Views\CalculatorScientificAngleButtons.xaml.h"
#include "Views\HistoryList.xaml.h"
#include "Views\Memory.xaml.h"
#include "Views\OperatorsPanel.xaml.h"
namespace CalculatorApp
{
struct FontTable
{
std::wstring numericSystem;
double fullFont;
double fullFontMin;
double portraitMin;
double snapFont;
double fullNumPadFont;
double snapScientificNumPadFont;
double portraitScientificNumPadFont;
};
public delegate void FullscreenFlyoutClosedEventHandler();
[Windows::Foundation::Metadata::WebHostHidden]
public ref class Calculator sealed
{
public:
event FullscreenFlyoutClosedEventHandler^ FullscreenFlyoutClosed;
Calculator();
property CalculatorApp::ViewModel::StandardCalculatorViewModel^ Model
{
CalculatorApp::ViewModel::StandardCalculatorViewModel^ get() {
return static_cast<CalculatorApp::ViewModel::StandardCalculatorViewModel^>(this->DataContext);
}
}
DEPENDENCY_PROPERTY_OWNER(Calculator);
DEPENDENCY_PROPERTY_WITH_DEFAULT_AND_CALLBACK(bool, IsStandard, false);
DEPENDENCY_PROPERTY_WITH_DEFAULT_AND_CALLBACK(bool, IsScientific, false);
DEPENDENCY_PROPERTY_WITH_DEFAULT_AND_CALLBACK(bool, IsProgrammer, false);
COMMAND_FOR_METHOD(HistoryButtonPressed, Calculator::ToggleHistoryFlyout);
void AnimateCalculator(bool resultAnimate);
void InitializeHistoryView(CalculatorApp::ViewModel::HistoryViewModel^ historyVM);
void UpdatePanelViewState();
void UnregisterEventHandlers();
void CloseHistoryFlyout();
void CloseMemoryFlyout();
void SetDefaultFocus();
private:
void OnLoaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void LoadResourceStrings();
void UpdateViewState();
void UpdateMemoryState();
void UpdateHistoryState();
void CalculationResultsOnSelected(_In_ Platform::Object^ sender);
void OnContextRequested(Windows::UI::Xaml::UIElement^ sender, Windows::UI::Xaml::Input::ContextRequestedEventArgs^ e);
void OnContextCanceled(Windows::UI::Xaml::UIElement^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void OnIsScientificPropertyChanged(bool oldValue, bool newValue);
void OnIsProgrammerPropertyChanged(bool oldValue, bool newValue);
void OnIsStandardPropertyChanged(bool oldValue, bool newValue);
void OnIsInErrorPropertyChanged();
void OnCalcPropertyChanged(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::Data::PropertyChangedEventArgs^ e);
void OnStoryboardCompleted(_In_ Platform::Object^ sender, _In_ Platform::Object^ e);
void OnLayoutStateChanged(_In_ Platform::Object^ sender, _In_ Platform::Object^ e);
void EnsureScientific();
void EnsureProgrammer();
void SetFontSizeResources();
std::wstring GetCurrentLayoutState();
private:
Windows::UI::Xaml::Controls::ListView^ m_tokenList;
Windows::UI::Xaml::Controls::MenuFlyout^ m_displayFlyout;
bool m_doAnimate;
bool m_resultAnimate;
bool m_isLastAnimatedInScientific;
bool m_isLastAnimatedInProgrammer;
bool m_IsLastFlyoutMemory = false;
bool m_IsLastFlyoutHistory = false;
Platform::String^ m_openMemoryFlyoutAutomationName;
Platform::String^ m_closeMemoryFlyoutAutomationName;
Platform::String^ m_openHistoryFlyoutAutomationName;
Platform::String^ m_closeHistoryFlyoutAutomationName;
Windows::UI::Xaml::Controls::PivotItem^ m_pivotItem;
bool m_IsDigit = false;
Memory^ m_memory;
void HistoryFlyout_Opened(_In_ Platform::Object ^sender, _In_ Platform::Object ^args);
void HistoryFlyout_Closing(_In_ Windows::UI::Xaml::Controls::Primitives::FlyoutBase^ sender, _In_ Windows::UI::Xaml::Controls::Primitives::FlyoutBaseClosingEventArgs^ args);
void HistoryFlyout_Closed(_In_ Platform::Object ^sender, _In_ Platform::Object ^args);
void OnHideHistoryClicked();
void OnHideMemoryClicked();
void OnHistoryItemClicked(_In_ CalculatorApp::ViewModel::HistoryItemViewModel^ e);
void ToggleHistoryFlyout(Platform::Object^ parameter);
void ToggleMemoryFlyout();
CalculatorApp::HistoryList^ m_historyList;
bool m_fIsHistoryFlyoutOpen;
bool m_fIsMemoryFlyoutOpen;
void OnMemoryFlyoutOpened(_In_ Platform::Object ^sender, _In_ Platform::Object ^args);
void OnMemoryFlyoutClosing(_In_ Windows::UI::Xaml::Controls::Primitives::FlyoutBase^ sender, _In_ Windows::UI::Xaml::Controls::Primitives::FlyoutBaseClosingEventArgs^ args);
void OnMemoryFlyoutClosed(_In_ Platform::Object ^sender, _In_ Platform::Object ^args);
void SetChildAsMemory();
void SetChildAsHistory();
Memory^ GetMemory();
void EnableControls(bool enable);
void EnableMemoryControls(bool enable);
void OnMemoryFlyOutTapped(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::Input::TappedRoutedEventArgs^ e);
void OnHistoryFlyOutTapped(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::Input::TappedRoutedEventArgs^ e);
void expressionContainer_LayoutUpdated(_In_ Platform::Object^ sender, _In_ Platform::Object^ e);
bool IsValidRegularExpression(std::wstring str);
void DockPanelTapped(_In_ Windows::UI::Xaml::Input::TappedRoutedEventArgs^ e);
void OnResultsLayoutChanged(_In_ Platform::Object^ sender, _In_ Platform::Object^ e);
void SetResultStyles();
void OnErrorLayoutCompleted(_In_ Platform::Object^ sender, _In_ Platform::Object^ e);
void OnHistoryAccessKeyInvoked(_In_ Windows::UI::Xaml::UIElement^ sender, _In_ Windows::UI::Xaml::Input::AccessKeyInvokedEventArgs^ args);
void OnMemoryAccessKeyInvoked(_In_ Windows::UI::Xaml::UIElement^ sender, _In_ Windows::UI::Xaml::Input::AccessKeyInvokedEventArgs^ args);
void DockPivot_SelectionChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e);
};
}

View File

@@ -0,0 +1,872 @@
<UserControl x:Class="CalculatorApp.CalculatorProgrammerBitFlipPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:common="using:CalculatorApp.Common"
xmlns:controls="using:CalculatorApp.Controls"
xmlns:converters="using:CalculatorApp.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:CalculatorApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="BitFlip"
d:DesignHeight="395"
d:DesignWidth="315"
Loaded="OnLoaded"
Unloaded="OnUnloaded"
mc:Ignorable="d">
<UserControl.Resources>
<converters:BooleanNegationConverter x:Key="BooleanNegationConverter"/>
<converters:BooleanToVisibilityNegationConverter x:Key="BooleanToVisibilityNegationConverter"/>
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<converters:BitFlipAutomationNameConverter x:Key="BitFlipAutomationNameConverter"/>
<Style x:Key="FlippingToggleButtonStyle" TargetType="ToggleButton">
<Setter Property="FontSize" Value="20"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="Background" Value="{ThemeResource SystemControlBackgroundTransparentBrush}"/>
<Setter Property="Padding" Value="0,0,0,0"/>
<Setter Property="MinWidth" Value="12"/>
<Setter Property="MinHeight" Value="20"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="BinaryZero.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseMediumBrush}"/>
<Setter Target="ContentPanel.Background" Value="{ThemeResource SystemControlHighlightTransparentBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Target="BinaryZero.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseMediumLowBrush}"/>
<Setter Target="ContentPanel.Background" Value="{ThemeResource SystemControlHighlightTransparentBrush}"/>
</VisualState.Setters>
<Storyboard>
<PointerDownThemeAnimation Storyboard.TargetName="ContentPanel"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Target="BinaryZero.Foreground" Value="{ThemeResource SystemControlDisabledBaseLowBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Checked">
<VisualState.Setters>
<Setter Target="BinaryZero.Visibility" Value="Collapsed"/>
<Setter Target="BinaryOne.Visibility" Value="Visible"/>
</VisualState.Setters>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Content">
<DiscreteObjectKeyFrame KeyTime="0" Value="{Binding Text, ElementName=BinaryOne, Mode=OneWay}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="CheckedPointerOver">
<VisualState.Setters>
<Setter Target="BinaryZero.Visibility" Value="Collapsed"/>
<Setter Target="BinaryOne.Visibility" Value="Visible"/>
<Setter Target="BinaryOne.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}"/>
<Setter Target="ContentPanel.Background" Value="{ThemeResource SystemControlHighlightTransparentBrush}"/>
</VisualState.Setters>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Content">
<DiscreteObjectKeyFrame KeyTime="0" Value="{Binding Text, ElementName=BinaryOne, Mode=OneWay}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="CheckedPressed">
<VisualState.Setters>
<Setter Target="BinaryZero.Visibility" Value="Collapsed"/>
<Setter Target="BinaryOne.Visibility" Value="Visible"/>
<Setter Target="BinaryOne.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseMediumLowBrush}"/>
<Setter Target="ContentPanel.Background" Value="{ThemeResource SystemControlHighlightTransparentBrush}"/>
</VisualState.Setters>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Content">
<DiscreteObjectKeyFrame KeyTime="0" Value="{Binding Text, ElementName=BinaryOne}"/>
</ObjectAnimationUsingKeyFrames>
<PointerDownThemeAnimation Storyboard.TargetName="ContentPanel"/>
</Storyboard>
</VisualState>
<VisualState x:Name="CheckedDisabled"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid x:Name="ContentPanel" Background="{TemplateBinding Background}">
<ContentPresenter x:Name="ContentPresenter"
Opacity="0"
AutomationProperties.AccessibilityView="Raw"
Content="{Binding Text, ElementName=BinaryZero, Mode=OneWay}"/>
<TextBlock x:Name="BinaryZero"
x:Uid="BinaryZero"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Foreground="{TemplateBinding Foreground}"
FontSize="{TemplateBinding FontSize}"
FontWeight="Bold"
AutomationProperties.AccessibilityView="Raw"
IsTextScaleFactorEnabled="False"/>
<TextBlock x:Name="BinaryOne"
x:Uid="BinaryOne"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Foreground="{ThemeResource SystemControlForegroundAccentBrush}"
FontSize="{TemplateBinding FontSize}"
FontWeight="Bold"
AutomationProperties.AccessibilityView="Raw"
IsTextScaleFactorEnabled="False"
Visibility="Collapsed"/>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="TextBlockStyle"
BasedOn="{StaticResource CaptionTextBlockStyle}"
TargetType="TextBlock">
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="TextAlignment" Value="Center"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="Foreground" Value="{ThemeResource AppControlPageTextBaseMediumHighBrush}"/>
<Setter Property="AutomationProperties.AccessibilityView" Value="Raw"/>
</Style>
</UserControl.Resources>
<Grid x:Name="BitFlipPanel"
x:Uid="BitFlipPanel"
Margin="0,1,0,1"
Background="{ThemeResource SystemControlAcrylicWindowBrush}"
AutomationProperties.HeadingLevel="Level1">
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="Gutter0"
Width="0.8*"
MinWidth="12"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition x:Name="Gutter1" Width="0.8*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition x:Name="Gutter2" Width="0.8*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition x:Name="Gutter3" Width="0.8*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition x:Name="Gutter4"
Width="0.8*"
MinWidth="12"/>
</Grid.ColumnDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="Sizing">
<VisualState x:Name="MinSizeLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="{StaticResource AppMinWindowHeight}" MinWindowWidth="{StaticResource AppMinWindowWidth}"/>
</VisualState.StateTriggers>
</VisualState>
<VisualState x:Name="DefaultLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="0" MinWindowWidth="0"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="Label60.FontSize" Value="10"/>
<Setter Target="Label56.FontSize" Value="10"/>
<Setter Target="Label52.FontSize" Value="10"/>
<Setter Target="Label48.FontSize" Value="10"/>
<Setter Target="Label44.FontSize" Value="10"/>
<Setter Target="Label40.FontSize" Value="10"/>
<Setter Target="Label36.FontSize" Value="10"/>
<Setter Target="Label32.FontSize" Value="10"/>
<Setter Target="Label28.FontSize" Value="10"/>
<Setter Target="Label24.FontSize" Value="10"/>
<Setter Target="Label20.FontSize" Value="10"/>
<Setter Target="Label16.FontSize" Value="10"/>
<Setter Target="Label12.FontSize" Value="10"/>
<Setter Target="Label8.FontSize" Value="10"/>
<Setter Target="Label4.FontSize" Value="10"/>
<Setter Target="Label0.FontSize" Value="10"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<TextBlock x:Name="Label60"
Grid.Row="1"
Grid.Column="4"
Style="{StaticResource TextBlockStyle}"
Text="60"/>
<TextBlock x:Name="Label56"
Grid.Row="1"
Grid.Column="9"
Style="{StaticResource TextBlockStyle}"
Text="56"/>
<TextBlock x:Name="Label52"
Grid.Row="1"
Grid.Column="14"
Style="{StaticResource TextBlockStyle}"
Text="52"/>
<TextBlock x:Name="Label48"
Grid.Row="1"
Grid.Column="19"
Style="{StaticResource TextBlockStyle}"
Text="48"/>
<TextBlock x:Name="Label44"
Grid.Row="3"
Grid.Column="4"
Style="{StaticResource TextBlockStyle}"
Text="44"/>
<TextBlock x:Name="Label40"
Grid.Row="3"
Grid.Column="9"
Style="{StaticResource TextBlockStyle}"
Text="40"/>
<TextBlock x:Name="Label36"
Grid.Row="3"
Grid.Column="14"
Style="{StaticResource TextBlockStyle}"
Text="36"/>
<TextBlock x:Name="Label32"
Grid.Row="3"
Grid.Column="19"
Style="{StaticResource TextBlockStyle}"
Text="32"/>
<TextBlock x:Name="Label28"
Grid.Row="5"
Grid.Column="4"
Style="{StaticResource TextBlockStyle}"
Text="28"/>
<TextBlock x:Name="Label24"
Grid.Row="5"
Grid.Column="9"
Style="{StaticResource TextBlockStyle}"
Text="24"/>
<TextBlock x:Name="Label20"
Grid.Row="5"
Grid.Column="14"
Style="{StaticResource TextBlockStyle}"
Text="20"/>
<TextBlock x:Name="Label16"
Grid.Row="5"
Grid.Column="19"
Style="{StaticResource TextBlockStyle}"
Text="16"/>
<TextBlock x:Name="Label12"
Grid.Row="7"
Grid.Column="4"
Style="{StaticResource TextBlockStyle}"
Text="12"/>
<TextBlock x:Name="Label8"
Grid.Row="7"
Grid.Column="9"
Style="{StaticResource TextBlockStyle}"
Text="8"/>
<TextBlock x:Name="Label4"
Grid.Row="7"
Grid.Column="14"
Style="{StaticResource TextBlockStyle}"
Text="4"/>
<TextBlock x:Name="Label0"
Grid.Row="7"
Grid.Column="19"
Style="{StaticResource TextBlockStyle}"
Text="0"/>
<controls:FlipButtons x:Name="Bit63"
Grid.Column="1"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='63', Mode=OneWay}"
ButtonId="BINPOS63"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit62"
Grid.Column="2"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='62', Mode=OneWay}"
ButtonId="BINPOS62"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit61"
Grid.Column="3"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='61', Mode=OneWay}"
ButtonId="BINPOS61"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit60"
Grid.Column="4"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='60', Mode=OneWay}"
ButtonId="BINPOS60"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit59"
Grid.Column="6"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='59', Mode=OneWay}"
ButtonId="BINPOS59"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit58"
Grid.Column="7"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='58', Mode=OneWay}"
ButtonId="BINPOS58"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit57"
Grid.Column="8"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='57', Mode=OneWay}"
ButtonId="BINPOS57"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit56"
Grid.Column="9"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='56', Mode=OneWay}"
ButtonId="BINPOS56"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit55"
Grid.Column="11"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='55', Mode=OneWay}"
ButtonId="BINPOS55"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit54"
Grid.Column="12"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='54', Mode=OneWay}"
ButtonId="BINPOS54"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit53"
Grid.Column="13"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='53', Mode=OneWay}"
ButtonId="BINPOS53"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit52"
Grid.Column="14"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='52', Mode=OneWay}"
ButtonId="BINPOS52"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit51"
Grid.Column="16"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='51', Mode=OneWay}"
ButtonId="BINPOS51"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit50"
Grid.Column="17"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='50', Mode=OneWay}"
ButtonId="BINPOS50"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit49"
Grid.Column="18"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='49', Mode=OneWay}"
ButtonId="BINPOS49"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit48"
Grid.Column="19"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='48', Mode=OneWay}"
ButtonId="BINPOS48"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit47"
Grid.Row="2"
Grid.Column="1"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='47', Mode=OneWay}"
ButtonId="BINPOS47"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit46"
Grid.Row="2"
Grid.Column="2"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='46', Mode=OneWay}"
ButtonId="BINPOS46"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit45"
Grid.Row="2"
Grid.Column="3"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='45', Mode=OneWay}"
ButtonId="BINPOS45"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit44"
Grid.Row="2"
Grid.Column="4"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='44', Mode=OneWay}"
ButtonId="BINPOS44"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit43"
Grid.Row="2"
Grid.Column="6"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='43', Mode=OneWay}"
ButtonId="BINPOS43"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit42"
Grid.Row="2"
Grid.Column="7"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='42', Mode=OneWay}"
ButtonId="BINPOS42"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit41"
Grid.Row="2"
Grid.Column="8"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='41', Mode=OneWay}"
ButtonId="BINPOS41"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit40"
Grid.Row="2"
Grid.Column="9"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='40', Mode=OneWay}"
ButtonId="BINPOS40"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit39"
Grid.Row="2"
Grid.Column="11"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='39', Mode=OneWay}"
ButtonId="BINPOS39"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit38"
Grid.Row="2"
Grid.Column="12"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='38', Mode=OneWay}"
ButtonId="BINPOS38"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit37"
Grid.Row="2"
Grid.Column="13"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='37', Mode=OneWay}"
ButtonId="BINPOS37"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit36"
Grid.Row="2"
Grid.Column="14"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='36', Mode=OneWay}"
ButtonId="BINPOS36"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit35"
Grid.Row="2"
Grid.Column="16"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='35', Mode=OneWay}"
ButtonId="BINPOS35"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit34"
Grid.Row="2"
Grid.Column="17"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='34', Mode=OneWay}"
ButtonId="BINPOS34"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit33"
Grid.Row="2"
Grid.Column="18"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='33', Mode=OneWay}"
ButtonId="BINPOS33"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit32"
Grid.Row="2"
Grid.Column="19"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='32', Mode=OneWay}"
ButtonId="BINPOS32"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsQwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit31"
Grid.Row="4"
Grid.Column="1"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='31', Mode=OneWay}"
ButtonId="BINPOS31"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsDwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit30"
Grid.Row="4"
Grid.Column="2"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='30', Mode=OneWay}"
ButtonId="BINPOS30"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsDwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit29"
Grid.Row="4"
Grid.Column="3"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='29', Mode=OneWay}"
ButtonId="BINPOS29"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsDwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit28"
Grid.Row="4"
Grid.Column="4"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='28', Mode=OneWay}"
ButtonId="BINPOS28"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsDwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit27"
Grid.Row="4"
Grid.Column="6"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='27', Mode=OneWay}"
ButtonId="BINPOS27"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsDwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit26"
Grid.Row="4"
Grid.Column="7"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='26', Mode=OneWay}"
ButtonId="BINPOS26"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsDwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit25"
Grid.Row="4"
Grid.Column="8"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='25', Mode=OneWay}"
ButtonId="BINPOS25"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsDwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit24"
Grid.Row="4"
Grid.Column="9"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='24', Mode=OneWay}"
ButtonId="BINPOS24"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsDwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit23"
Grid.Row="4"
Grid.Column="11"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='23', Mode=OneWay}"
ButtonId="BINPOS23"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsDwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit22"
Grid.Row="4"
Grid.Column="12"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='22', Mode=OneWay}"
ButtonId="BINPOS22"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsDwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit21"
Grid.Row="4"
Grid.Column="13"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='21', Mode=OneWay}"
ButtonId="BINPOS21"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsDwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit20"
Grid.Row="4"
Grid.Column="14"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='20', Mode=OneWay}"
ButtonId="BINPOS20"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsDwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit19"
Grid.Row="4"
Grid.Column="16"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='19', Mode=OneWay}"
ButtonId="BINPOS19"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsDwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit18"
Grid.Row="4"
Grid.Column="17"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='18', Mode=OneWay}"
ButtonId="BINPOS18"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsDwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit17"
Grid.Row="4"
Grid.Column="18"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='17', Mode=OneWay}"
ButtonId="BINPOS17"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsDwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit16"
Grid.Row="4"
Grid.Column="19"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='16', Mode=OneWay}"
ButtonId="BINPOS16"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsDwordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit15"
Grid.Row="6"
Grid.Column="1"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='15', Mode=OneWay}"
ButtonId="BINPOS15"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsWordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit14"
Grid.Row="6"
Grid.Column="2"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='14', Mode=OneWay}"
ButtonId="BINPOS14"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsWordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit13"
Grid.Row="6"
Grid.Column="3"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='13', Mode=OneWay}"
ButtonId="BINPOS13"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsWordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit12"
Grid.Row="6"
Grid.Column="4"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='12', Mode=OneWay}"
ButtonId="BINPOS12"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsWordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit11"
Grid.Row="6"
Grid.Column="6"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='11', Mode=OneWay}"
ButtonId="BINPOS11"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsWordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit10"
Grid.Row="6"
Grid.Column="7"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='10', Mode=OneWay}"
ButtonId="BINPOS10"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsWordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit9"
Grid.Row="6"
Grid.Column="8"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='9', Mode=OneWay}"
ButtonId="BINPOS9"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsWordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit8"
Grid.Row="6"
Grid.Column="9"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='8', Mode=OneWay}"
ButtonId="BINPOS8"
Checked="OnBitToggled"
IsEnabled="{x:Bind Model.IsWordEnabled, Mode=OneWay}"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit7"
Grid.Row="6"
Grid.Column="11"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='7', Mode=OneWay}"
ButtonId="BINPOS7"
Checked="OnBitToggled"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit6"
Grid.Row="6"
Grid.Column="12"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='6', Mode=OneWay}"
ButtonId="BINPOS6"
Checked="OnBitToggled"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit5"
Grid.Row="6"
Grid.Column="13"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='5', Mode=OneWay}"
ButtonId="BINPOS5"
Checked="OnBitToggled"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit4"
Grid.Row="6"
Grid.Column="14"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='4', Mode=OneWay}"
ButtonId="BINPOS4"
Checked="OnBitToggled"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit3"
Grid.Row="6"
Grid.Column="16"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='3', Mode=OneWay}"
ButtonId="BINPOS3"
Checked="OnBitToggled"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit2"
Grid.Row="6"
Grid.Column="17"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='2', Mode=OneWay}"
ButtonId="BINPOS2"
Checked="OnBitToggled"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit1"
Grid.Row="6"
Grid.Column="18"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='1', Mode=OneWay}"
ButtonId="BINPOS1"
Checked="OnBitToggled"
Unchecked="OnBitToggled"/>
<controls:FlipButtons x:Name="Bit0"
Grid.Row="6"
Grid.Column="19"
Style="{StaticResource FlippingToggleButtonStyle}"
AutomationProperties.Name="{x:Bind Model.BinaryDisplayValue, Converter={StaticResource BitFlipAutomationNameConverter}, ConverterParameter='0', Mode=OneWay}"
ButtonId="BINPOS0"
Checked="OnBitToggled"
Unchecked="OnBitToggled"/>
</Grid>
</UserControl>

View File

@@ -0,0 +1,222 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//
// CalculatorProgrammerBitFlipPanel.xaml.cpp
// Implementation of the CalculatorProgrammerBitFlipPanel class
//
#include "pch.h"
#include "CalculatorProgrammerBitFlipPanel.xaml.h"
#include "CalcViewModel\Common\LocalizationSettings.h"
#include "Converters\BooleanToVisibilityConverter.h"
using namespace CalculatorApp;
using namespace CalculatorApp::Common;
using namespace CalculatorApp::Controls;
using namespace CalculatorApp::ViewModel;
using namespace Platform;
using namespace std;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236
CalculatorProgrammerBitFlipPanel::CalculatorProgrammerBitFlipPanel() :
m_updatingCheckedStates(false)
{
InitializeComponent();
auto booleanToVisibilityConverter = ref new Converters::BooleanToVisibilityConverter;
auto booleanToVisibilityNegationConverter = ref new Converters::BooleanToVisibilityNegationConverter;
SetVisibilityBinding(BitFlipPanel, L"IsBinaryBitFlippingEnabled", booleanToVisibilityConverter);
AssignFlipButtons();
}
void CalculatorProgrammerBitFlipPanel::OnLoaded(Object^ sender, RoutedEventArgs^ e)
{
UnsubscribePropertyChanged();
SubscribePropertyChanged();
}
void CalculatorProgrammerBitFlipPanel::OnUnloaded(Object^ sender, RoutedEventArgs^ e)
{
UnsubscribePropertyChanged();
}
void CalculatorProgrammerBitFlipPanel::SubscribePropertyChanged()
{
if (Model != nullptr)
{
m_propertyChangedToken =
Model->PropertyChanged += ref new PropertyChangedEventHandler(this, &CalculatorProgrammerBitFlipPanel::OnPropertyChanged);
UpdateCheckedStates();
}
}
void CalculatorProgrammerBitFlipPanel::UnsubscribePropertyChanged()
{
if (Model != nullptr && m_propertyChangedToken.Value != 0)
{
Model->PropertyChanged -= m_propertyChangedToken;
m_propertyChangedToken.Value = 0;
}
}
void CalculatorProgrammerBitFlipPanel::OnPropertyChanged(Object^ sender, PropertyChangedEventArgs^ e)
{
if (e->PropertyName == CalculatorViewModelProperties::BinaryDisplayValue)
{
UpdateCheckedStates();
}
}
StandardCalculatorViewModel^ CalculatorProgrammerBitFlipPanel::Model::get()
{
return static_cast<StandardCalculatorViewModel^>(this->DataContext);
}
void CalculatorProgrammerBitFlipPanel::AssignFlipButtons()
{
assert(m_flipButtons.size() == 64);
m_flipButtons[0] = this->Bit0;
m_flipButtons[1] = this->Bit1;
m_flipButtons[2] = this->Bit2;
m_flipButtons[3] = this->Bit3;
m_flipButtons[4] = this->Bit4;
m_flipButtons[5] = this->Bit5;
m_flipButtons[6] = this->Bit6;
m_flipButtons[7] = this->Bit7;
m_flipButtons[8] = this->Bit8;
m_flipButtons[9] = this->Bit9;
m_flipButtons[10] = this->Bit10;
m_flipButtons[11] = this->Bit11;
m_flipButtons[12] = this->Bit12;
m_flipButtons[13] = this->Bit13;
m_flipButtons[14] = this->Bit14;
m_flipButtons[15] = this->Bit15;
m_flipButtons[16] = this->Bit16;
m_flipButtons[17] = this->Bit17;
m_flipButtons[18] = this->Bit18;
m_flipButtons[19] = this->Bit19;
m_flipButtons[20] = this->Bit20;
m_flipButtons[21] = this->Bit21;
m_flipButtons[22] = this->Bit22;
m_flipButtons[23] = this->Bit23;
m_flipButtons[24] = this->Bit24;
m_flipButtons[25] = this->Bit25;
m_flipButtons[26] = this->Bit26;
m_flipButtons[27] = this->Bit27;
m_flipButtons[28] = this->Bit28;
m_flipButtons[29] = this->Bit29;
m_flipButtons[30] = this->Bit30;
m_flipButtons[31] = this->Bit31;
m_flipButtons[32] = this->Bit32;
m_flipButtons[33] = this->Bit33;
m_flipButtons[34] = this->Bit34;
m_flipButtons[35] = this->Bit35;
m_flipButtons[36] = this->Bit36;
m_flipButtons[37] = this->Bit37;
m_flipButtons[38] = this->Bit38;
m_flipButtons[39] = this->Bit39;
m_flipButtons[40] = this->Bit40;
m_flipButtons[41] = this->Bit41;
m_flipButtons[42] = this->Bit42;
m_flipButtons[43] = this->Bit43;
m_flipButtons[44] = this->Bit44;
m_flipButtons[45] = this->Bit45;
m_flipButtons[46] = this->Bit46;
m_flipButtons[47] = this->Bit47;
m_flipButtons[48] = this->Bit48;
m_flipButtons[49] = this->Bit49;
m_flipButtons[50] = this->Bit50;
m_flipButtons[51] = this->Bit51;
m_flipButtons[52] = this->Bit52;
m_flipButtons[53] = this->Bit53;
m_flipButtons[54] = this->Bit54;
m_flipButtons[55] = this->Bit55;
m_flipButtons[56] = this->Bit56;
m_flipButtons[57] = this->Bit57;
m_flipButtons[58] = this->Bit58;
m_flipButtons[59] = this->Bit59;
m_flipButtons[60] = this->Bit60;
m_flipButtons[61] = this->Bit61;
m_flipButtons[62] = this->Bit62;
m_flipButtons[63] = this->Bit63;
}
void CalculatorProgrammerBitFlipPanel::SetVisibilityBinding(_In_ FrameworkElement^ element, _In_ String^ path, _In_ IValueConverter^ converter)
{
Binding^ commandBinding = ref new Binding();
commandBinding->Path = ref new PropertyPath(path);
commandBinding->Converter = converter;
element->SetBinding(VisibilityProperty, commandBinding);
}
void CalculatorProgrammerBitFlipPanel::OnBitToggled(_In_ Object^ sender, _In_ RoutedEventArgs^ e)
{
if (m_updatingCheckedStates) { return; }
// Handle this the bit toggled event only if it is coming from BitFlip mode.
// Any input from the Numpad may also result in toggling the bit as their state is bound to the BinaryDisplayValue.
// Also, if the mode is switched to other Calculator modes when the BitFlip panel is open,
// a race condition exists in which the IsProgrammerMode property is still true and the UpdatePrimaryResult() is called,
// which continously alters the Display Value and the state of the Bit Flip buttons.
if ((Model->IsBitFlipChecked)
&& Model->IsProgrammer)
{
TraceLogger::GetInstance().LogBitFlipUsed();
auto flipButton = static_cast<FlipButtons^>(sender);
Model->ButtonPressed->Execute(flipButton->ButtonId);
}
}
void CalculatorProgrammerBitFlipPanel::UpdateCheckedStates()
{
assert(!m_updatingCheckedStates);
assert(m_flipButtons.size() == s_numBits);
if (Model == nullptr) { return; }
static const wchar_t ch0 = LocalizationSettings::GetInstance().GetDigitSymbolFromEnUsDigit(L'0');
// Filter any unwanted characters from the displayed string.
static constexpr array<wchar_t, 4> unwantedChars = {
L' ',
Utils::LRE,
Utils::PDF,
Utils::LRO
};
wstringstream stream;
wstring displayValue = Model->BinaryDisplayValue->Data();
for (const wchar_t& c : displayValue)
{
if (find(begin(unwantedChars), end(unwantedChars), c) == unwantedChars.end())
{
stream << c;
}
}
wstring rawDisplay = stream.str();
size_t paddingCount = s_numBits - rawDisplay.length();
wstring setBits = wstring(paddingCount, ch0) + rawDisplay;
assert(setBits.length() == s_numBits);
m_updatingCheckedStates = true;
for (unsigned int bitIndex = 0; bitIndex < s_numBits; bitIndex++)
{
// Highest bit (64) is at index 0 in bit string.
// To get bit 0, grab from opposite end of string.
wchar_t bit = setBits[s_numBits - bitIndex - 1];
m_flipButtons[bitIndex]->IsChecked = (bit != ch0);
}
m_updatingCheckedStates = false;
}

View File

@@ -0,0 +1,52 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//
// CalculatorProgrammerBitFlipPanel.xaml.h
// Declaration of the CalculatorProgrammerBitFlipPanel class
//
#pragma once
#include "Views\CalculatorProgrammerBitFlipPanel.g.h"
#include "Controls\FlipButtons.h"
#include "Converters\BitFlipAutomationNameConverter.h"
#include "Converters\BooleanNegationConverter.h"
#include "Converters\VisibilityNegationConverter.h"
#include "CalcViewModel\StandardCalculatorViewModel.h"
namespace CalculatorApp
{
[Windows::Foundation::Metadata::WebHostHidden]
public ref class CalculatorProgrammerBitFlipPanel sealed
{
public:
CalculatorProgrammerBitFlipPanel();
property CalculatorApp::ViewModel::StandardCalculatorViewModel^ Model
{
CalculatorApp::ViewModel::StandardCalculatorViewModel^ get();
}
private:
void OnLoaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void OnUnloaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void SubscribePropertyChanged();
void UnsubscribePropertyChanged();
void OnPropertyChanged(Platform::Object^ sender, Windows::UI::Xaml::Data::PropertyChangedEventArgs^ e);
void AssignFlipButtons();
void SetVisibilityBinding(_In_ Windows::UI::Xaml::FrameworkElement^ element, _In_ Platform::String^ path, _In_ Windows::UI::Xaml::Data::IValueConverter^ converter);
void OnBitToggled(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
void UpdateCheckedStates();
private:
Windows::Foundation::EventRegistrationToken m_propertyChangedToken;
static const unsigned int s_numBits = 64;
std::array<CalculatorApp::Controls::FlipButtons^, s_numBits> m_flipButtons;
bool m_updatingCheckedStates;
};
}

View File

@@ -0,0 +1,118 @@
<UserControl x:Class="CalculatorApp.CalculatorProgrammerDisplayPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:common="using:CalculatorApp.Common"
xmlns:controls="using:CalculatorApp.Controls"
xmlns:converters="using:CalculatorApp.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:CalculatorApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Margin="3,0,0,0"
d:DesignHeight="300"
d:DesignWidth="400"
mc:Ignorable="d">
<UserControl.Resources>
<converters:BooleanNegationConverter x:Key="BooleanNegationConverter"/>
</UserControl.Resources>
<Grid x:Name="ProgrammerDisplay">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" MaxWidth="160"/>
<ColumnDefinition Width="0.01*"/>
<ColumnDefinition Width="1*" MaxWidth="80"/>
<ColumnDefinition Width="1*" MaxWidth="80"/>
<ColumnDefinition Width="1*" MaxWidth="80"/>
<ColumnDefinition Width="1*" MaxWidth="80"/>
</Grid.ColumnDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="Layouts">
<VisualState x:Name="MinSizeLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="{StaticResource AppMinWindowHeight}" MinWindowWidth="{StaticResource AppMinWindowWidth}"/>
</VisualState.StateTriggers>
</VisualState>
<VisualState x:Name="DefaultLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="0" MinWindowWidth="0"/>
</VisualState.StateTriggers>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="ErrorVisualStates">
<VisualState x:Name="NoErrorLayout"/>
<VisualState x:Name="ErrorLayout">
<VisualState.Setters>
<Setter Target="qwordButton.IsEnabled" Value="False"/>
<Setter Target="dwordButton.IsEnabled" Value="False"/>
<Setter Target="wordButton.IsEnabled" Value="False"/>
<Setter Target="byteButton.IsEnabled" Value="False"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid x:Uid="InputModeSelectionGroup"
Grid.Column="0"
AutomationProperties.HeadingLevel="Level1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" MaxWidth="80"/>
<ColumnDefinition Width="1*" MaxWidth="80"/>
</Grid.ColumnDefinitions>
<RadioButton x:Name="fullKeypad"
x:Uid="fullKeypad"
Style="{StaticResource ProgKeypadRadioButtonStyle}"
AutomationProperties.AutomationId="fullKeypad"
Content="&#xe75f;"
IsChecked="{x:Bind Model.IsBitFlipChecked, Converter={StaticResource BooleanNegationConverter}, Mode=TwoWay}"/>
<RadioButton x:Name="bitFlip"
x:Uid="bitFlip"
Grid.Column="1"
Style="{StaticResource ProgKeypadRadioButtonStyle}"
AutomationProperties.AutomationId="bitFlip"
Checked="ShowBitFlip"
Content="&#xf7d0;"
IsChecked="{x:Bind Model.IsBitFlipChecked, Mode=TwoWay}"/>
</Grid>
<Button x:Name="qwordButton"
x:Uid="qwordButton"
Grid.Column="0"
Grid.ColumnSpan="7"
Style="{StaticResource ProgWordSizeButtonStyle}"
AutomationProperties.AutomationId="qwordButton"
Command="{x:Bind BitLengthButtonPressed, Mode=OneTime}"
CommandParameter="0"
Content="QWORD"/>
<Button x:Name="dwordButton"
x:Uid="dwordButton"
Grid.Column="0"
Grid.ColumnSpan="7"
Style="{StaticResource ProgWordSizeButtonStyle}"
AutomationProperties.AutomationId="dwordButton"
Command="{x:Bind BitLengthButtonPressed, Mode=OneTime}"
CommandParameter="1"
Content="DWORD"
Visibility="Collapsed"/>
<Button x:Name="wordButton"
x:Uid="wordButton"
Grid.Column="0"
Grid.ColumnSpan="7"
Style="{StaticResource ProgWordSizeButtonStyle}"
AutomationProperties.AutomationId="wordButton"
Command="{x:Bind BitLengthButtonPressed, Mode=OneTime}"
CommandParameter="2"
Content="WORD"
Visibility="Collapsed"/>
<Button x:Name="byteButton"
x:Uid="byteButton"
Grid.Column="0"
Grid.ColumnSpan="7"
Style="{StaticResource ProgWordSizeButtonStyle}"
AutomationProperties.AutomationId="byteButton"
Command="{x:Bind BitLengthButtonPressed, Mode=OneTime}"
CommandParameter="3"
Content="BYTE"
Visibility="Collapsed"/>
</Grid>
</UserControl>

View File

@@ -0,0 +1,95 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "pch.h"
#include "CalculatorProgrammerDisplayPanel.xaml.h"
using namespace CalculatorApp;
using namespace CalculatorApp::ViewModel;
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
using namespace Windows::UI::ViewManagement;
using namespace Windows::UI::Core;
CalculatorProgrammerDisplayPanel::CalculatorProgrammerDisplayPanel() :
m_isErrorVisualState(false)
{
InitializeComponent();
}
void CalculatorProgrammerDisplayPanel::ShowBitFlip(Object^ sender, RoutedEventArgs^ e)
{
TraceLogger::GetInstance().LogBitFlipPaneClicked();
}
void CalculatorProgrammerDisplayPanel::OnBitLengthButtonPressed(Object^ parameter)
{
TraceLogger::GetInstance().LogBitLengthButtonUsed(ApplicationView::GetApplicationViewIdForWindow(CoreWindow::GetForCurrentThread()));
String^ buttonId = parameter->ToString();
qwordButton->Visibility = ::Visibility::Collapsed;
dwordButton->Visibility = ::Visibility::Collapsed;
wordButton->Visibility = ::Visibility::Collapsed;
byteButton->Visibility = ::Visibility::Collapsed;
if (buttonId == "0")
{
Model->ButtonPressed->Execute(NumbersAndOperatorsEnum::Dword);
dwordButton->Visibility = ::Visibility::Visible;
dwordButton->Focus(::FocusState::Programmatic);
Model->IsQwordEnabled = false;
Model->IsDwordEnabled = true;
Model->IsWordEnabled = true;
}
else if (buttonId == "1")
{
Model->ButtonPressed->Execute(NumbersAndOperatorsEnum::Word);
wordButton->Visibility = ::Visibility::Visible;
wordButton->Focus(::FocusState::Programmatic);
Model->IsQwordEnabled = false;
Model->IsDwordEnabled = false;
Model->IsWordEnabled = true;
}
else if (buttonId == "2")
{
Model->ButtonPressed->Execute(NumbersAndOperatorsEnum::Byte);
byteButton->Visibility = ::Visibility::Visible;
byteButton->Focus(::FocusState::Programmatic);
Model->IsQwordEnabled = false;
Model->IsDwordEnabled = false;
Model->IsWordEnabled = false;
}
else if (buttonId == "3")
{
Model->ButtonPressed->Execute(NumbersAndOperatorsEnum::Qword);
qwordButton->Visibility = ::Visibility::Visible;
qwordButton->Focus(::FocusState::Programmatic);
Model->IsQwordEnabled = true;
Model->IsDwordEnabled = true;
Model->IsWordEnabled = true;
}
// update memory list according to bit length
Model->SetMemorizedNumbersString();
}
bool CalculatorProgrammerDisplayPanel::IsErrorVisualState::get()
{
return m_isErrorVisualState;
}
void CalculatorProgrammerDisplayPanel::IsErrorVisualState::set(bool value)
{
if (m_isErrorVisualState != value)
{
m_isErrorVisualState = value;
String^ newState = m_isErrorVisualState ? L"ErrorLayout" : L"NoErrorLayout";
VisualStateManager::GoToState(this, newState, false);
}
}

View File

@@ -0,0 +1,37 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
#include "Views\CalculatorProgrammerDisplayPanel.g.h"
#include "CalcViewModel\StandardCalculatorViewModel.h"
namespace CalculatorApp
{
[Windows::Foundation::Metadata::WebHostHidden]
public ref class CalculatorProgrammerDisplayPanel sealed
{
public:
CalculatorProgrammerDisplayPanel();
COMMAND_FOR_METHOD(BitLengthButtonPressed, CalculatorProgrammerDisplayPanel::OnBitLengthButtonPressed);
property CalculatorApp::ViewModel::StandardCalculatorViewModel^ Model
{
CalculatorApp::ViewModel::StandardCalculatorViewModel^ get() {
return static_cast<CalculatorApp::ViewModel::StandardCalculatorViewModel^>(this->DataContext);
}
}
property bool IsErrorVisualState {
bool get();
void set(bool value);
}
private:
void ShowBitFlip(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void OnBitLengthButtonPressed(Platform::Object^ parameter);
bool m_isErrorVisualState;
};
}

View File

@@ -0,0 +1,240 @@
<UserControl x:Class="CalculatorApp.CalculatorProgrammerOperators"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:common="using:CalculatorApp.Common"
xmlns:controls="using:CalculatorApp.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:designdata="using:CalculatorApp.DesignData"
xmlns:local="using:CalculatorApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="ControlRoot"
d:DesignHeight="400"
d:DesignWidth="315"
mc:Ignorable="d">
<UserControl.Resources>
<!-- Programmer mode display radio button -->
<Style x:Key="ProgModeRadioButtonStyle" TargetType="RadioButton">
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}"/>
<Setter Property="MinHeight" Value="12"/>
<Setter Property="MinWidth" Value="280"/>
<Setter Property="MaxHeight" Value="60"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="Padding" Value="8,0,0,0"/>
<Setter Property="Typography.NumeralAlignment" Value="Tabular"/>
<Setter Property="FontSize" Value="{ThemeResource CaptionFontSize}"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="IsTextScaleFactorEnabled" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RadioButton">
<Grid x:Name="ControlRoot"
VerticalAlignment="Stretch"
Background="{ThemeResource SystemControlBackgroundTransparentBrush}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="ControlRoot.(RevealBrush.State)" Value="PointerOver"/>
<Setter Target="ControlRoot.Background" Value="{ThemeResource ListViewItemRevealBackgroundPointerOver}"/>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}"/>
<Setter Target="LabelPresenter.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Target="ControlRoot.(RevealBrush.State)" Value="Pressed"/>
<Setter Target="ControlRoot.Background" Value="{ThemeResource ListViewItemRevealBackgroundPressed}"/>
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}"/>
<Setter Target="LabelPresenter.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Target="RevealBackplate.Visibility" Value="Collapsed"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<VisualState.Setters>
<Setter Target="CheckedStatesGrid.Opacity" Value="1"/>
<Setter Target="NormalStatesGrid.Opacity" Value="0"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Unchecked"/>
<VisualState x:Name="Indeterminate"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="RevealBackplate"
Margin="0,-1,0,0"
Background="{ThemeResource ListViewItemRevealBackground}"
BorderBrush="{ThemeResource ListViewItemRevealBorderBrush}"
BorderThickness="0,1,0,1"/>
<Grid x:Name="NormalStatesGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4"/>
<ColumnDefinition Width="Auto" MinWidth="48"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="ContentPresenter"
Grid.Column="2"
Margin="0,2,4,-2"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Foreground="{ThemeResource SystemControlForegroundBaseHighBrush}"
FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
FontWeight="{TemplateBinding FontWeight}"
AutomationProperties.AccessibilityView="Raw"
IsTextScaleFactorEnabled="False"
Text="{TemplateBinding Content}"
TextLineBounds="TrimToCapHeight"
TextWrapping="Wrap"/>
<TextBlock x:Name="LabelPresenter"
Grid.Column="1"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Foreground="{ThemeResource SystemControlForegroundBaseHighBrush}"
FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
FontWeight="{TemplateBinding FontWeight}"
AutomationProperties.AccessibilityView="Raw"
IsTextScaleFactorEnabled="False"
Text="{TemplateBinding Tag}"/>
</Grid>
<Grid x:Name="CheckedStatesGrid"
Background="{ThemeResource SystemControlHighlightTransparentBrush}"
Opacity="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4"/>
<ColumnDefinition Width="Auto" MinWidth="48"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Rectangle x:Name="CheckedRectangle"
Grid.Column="0"
Margin="0,5,0,5"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Fill="{ThemeResource SystemControlHighlightAccentBrush}"/>
<TextBlock x:Name="CheckedContentPresenter"
Grid.Column="2"
Margin="0,2,4,-2"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Foreground="{ThemeResource SystemControlHighlightAltBaseHighBrush}"
FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
FontWeight="{TemplateBinding FontWeight}"
AutomationProperties.AccessibilityView="Raw"
IsTextScaleFactorEnabled="False"
Text="{TemplateBinding Content}"
TextLineBounds="TrimToCapHeight"
TextWrapping="Wrap"/>
<TextBlock x:Name="CheckedLabelPresenter"
Grid.Column="1"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Foreground="{ThemeResource SystemControlHighlightAltBaseHighBrush}"
FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
FontWeight="{TemplateBinding FontWeight}"
AutomationProperties.AccessibilityView="Raw"
IsTextScaleFactorEnabled="False"
Text="{TemplateBinding Tag}"/>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<MenuFlyout x:Key="ProgrammerOperatorsContextMenu" x:Name="ProgrammerOperatorsContextMenu">
<MenuFlyoutItem x:Name="CopyMenuItem"
x:Uid="CopyMenuItem"
Click="OnCopyMenuItemClicked"
Icon="Copy"/>
</MenuFlyout>
</UserControl.Resources>
<Grid x:Name="ProgrammerOperators"
x:Uid="RadixGroup"
MaxHeight="244"
AutomationProperties.HeadingLevel="Level1">
<Grid.RowDefinitions>
<RowDefinition Height="1*" MinHeight="0"/>
<RowDefinition Height="1*" MinHeight="0"/>
<RowDefinition Height="1*" MinHeight="0"/>
<RowDefinition Height="1*" MinHeight="{Binding ActualHeight, ElementName=binaryButton, FallbackValue=16, Mode=OneWay}"/>
<RowDefinition Height="4"/>
</Grid.RowDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="LargeLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="768" MinWindowWidth="1024"/>
</VisualState.StateTriggers>
</VisualState>
<VisualState x:Name="MinSizeLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="{StaticResource AppMinWindowHeight}" MinWindowWidth="{StaticResource AppMinWindowWidth}"/>
</VisualState.StateTriggers>
</VisualState>
<VisualState x:Name="DefaultLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="0" MinWindowWidth="0"/>
</VisualState.StateTriggers>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<controls:RadixButton x:Name="hexButton"
x:Uid="hexButton"
HorizontalAlignment="Stretch"
Style="{ThemeResource ProgModeRadioButtonStyle}"
AutomationProperties.AutomationId="hexButton"
AutomationProperties.Name="{x:Bind Model.HexDisplayValue_AutomationName, Mode=OneWay}"
Checked="HexButtonChecked"
Content="{x:Bind Model.HexDisplayValue, Mode=OneWay}"
ContextFlyout="{StaticResource ProgrammerOperatorsContextMenu}"
GroupName="BaseConversion"/>
<controls:RadixButton x:Name="decimalButton"
x:Uid="decimalButton"
Grid.Row="1"
HorizontalAlignment="Stretch"
Style="{ThemeResource ProgModeRadioButtonStyle}"
AutomationProperties.AutomationId="decimalButton"
AutomationProperties.Name="{x:Bind Model.DecDisplayValue_AutomationName, Mode=OneWay}"
Checked="DecButtonChecked"
Content="{x:Bind Model.DecimalDisplayValue, Mode=OneWay}"
ContextFlyout="{StaticResource ProgrammerOperatorsContextMenu}"
GroupName="BaseConversion"
IsChecked="true"/>
<controls:RadixButton x:Name="octButton"
x:Uid="octButton"
Grid.Row="2"
HorizontalAlignment="Stretch"
Style="{ThemeResource ProgModeRadioButtonStyle}"
AutomationProperties.AutomationId="octolButton"
AutomationProperties.Name="{x:Bind Model.OctDisplayValue_AutomationName, Mode=OneWay}"
Checked="OctButtonChecked"
Content="{x:Bind Model.OctalDisplayValue, Mode=OneWay}"
ContextFlyout="{StaticResource ProgrammerOperatorsContextMenu}"
GroupName="BaseConversion"/>
<controls:RadixButton x:Name="binaryButton"
x:Uid="binaryButton"
Grid.Row="3"
HorizontalAlignment="Stretch"
Style="{ThemeResource ProgModeRadioButtonStyle}"
AutomationProperties.AutomationId="binaryButton"
AutomationProperties.Name="{x:Bind Model.BinDisplayValue_AutomationName, Mode=OneWay}"
Checked="BinButtonChecked"
Content="{x:Bind Model.BinaryDisplayValue, Mode=OneWay}"
ContextFlyout="{StaticResource ProgrammerOperatorsContextMenu}"
GroupName="BaseConversion"/>
</Grid>
</UserControl>

View File

@@ -0,0 +1,108 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "pch.h"
#include "CalculatorProgrammerOperators.xaml.h"
#include "CalcViewModel\StandardCalculatorViewModel.h"
#include "CalcViewModel\Common\CopyPasteManager.h"
using namespace CalculatorApp;
using namespace CalculatorApp::Common;
using namespace CalculatorApp::Controls;
using namespace CalculatorApp::ViewModel;
using namespace Windows::Devices::Input;
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
using namespace Windows::UI::Xaml::Automation;
using namespace Windows::UI::Xaml::Automation::Peers;
using namespace Windows::UI::ViewManagement;
using namespace Windows::UI::Core;
DEPENDENCY_PROPERTY_INITIALIZATION(CalculatorProgrammerOperators, SymbolButtonStyle);
CalculatorProgrammerOperators::CalculatorProgrammerOperators()
{
InitializeComponent();
CopyMenuItem->Text = AppResourceProvider::GetInstance().GetResourceString(L"copyMenuItem");
}
void CalculatorProgrammerOperators::HexButtonChecked(_In_ Object^ sender, _In_ RoutedEventArgs^ e)
{
TraceLogger::GetInstance().LogRadixButtonUsed(ApplicationView::GetApplicationViewIdForWindow(CoreWindow::GetForCurrentThread()));
if (Model)
{
Model->SwitchProgrammerModeBase(RADIX_TYPE::HEX_RADIX);
}
}
void CalculatorProgrammerOperators::DecButtonChecked(_In_ Object^ sender, _In_ RoutedEventArgs^ e)
{
TraceLogger::GetInstance().LogRadixButtonUsed(ApplicationView::GetApplicationViewIdForWindow(CoreWindow::GetForCurrentThread()));
if (Model)
{
Model->SwitchProgrammerModeBase(RADIX_TYPE::DEC_RADIX);
}
}
void CalculatorProgrammerOperators::OctButtonChecked(_In_ Object^ sender, _In_ RoutedEventArgs^ e)
{
TraceLogger::GetInstance().LogRadixButtonUsed(ApplicationView::GetApplicationViewIdForWindow(CoreWindow::GetForCurrentThread()));
if (Model)
{
Model->SwitchProgrammerModeBase(RADIX_TYPE::OCT_RADIX);
}
}
void CalculatorProgrammerOperators::BinButtonChecked(_In_ Object^ sender, _In_ RoutedEventArgs^ e)
{
TraceLogger::GetInstance().LogRadixButtonUsed(ApplicationView::GetApplicationViewIdForWindow(CoreWindow::GetForCurrentThread()));
if (Model)
{
Model->SwitchProgrammerModeBase(RADIX_TYPE::BIN_RADIX);
}
}
void CalculatorProgrammerOperators::SetRadixButton(RADIX_TYPE radixType)
{
switch (radixType)
{
case RADIX_TYPE::DEC_RADIX:
{
decimalButton->IsChecked = true;
break;
}
case RADIX_TYPE::HEX_RADIX:
{
hexButton->IsChecked = true;
break;
}
case RADIX_TYPE::OCT_RADIX:
{
octButton->IsChecked = true;
break;
}
case RADIX_TYPE::BIN_RADIX:
{
binaryButton->IsChecked = true;
break;
}
default:
assert(false);
}
}
void CalculatorProgrammerOperators::OnCopyMenuItemClicked(_In_ Object^ sender, _In_ RoutedEventArgs^ e)
{
auto source = safe_cast<RadixButton^>(ProgrammerOperatorsContextMenu->Target);
CopyPasteManager::CopyToClipboard(source->GetRawDisplayValue());
}

View File

@@ -0,0 +1,38 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
#include "Views\CalculatorProgrammerOperators.g.h"
#include "Controls\RadixButton.h"
#include "CalcViewModel\StandardCalculatorViewModel.h"
namespace CalculatorApp
{
[Windows::Foundation::Metadata::WebHostHidden]
public ref class CalculatorProgrammerOperators sealed
{
public:
CalculatorProgrammerOperators();
property CalculatorApp::ViewModel::StandardCalculatorViewModel^ Model
{
CalculatorApp::ViewModel::StandardCalculatorViewModel^ get() {
return static_cast<CalculatorApp::ViewModel::StandardCalculatorViewModel^>(this->DataContext);
}
}
DEPENDENCY_PROPERTY_OWNER(CalculatorProgrammerOperators);
DEPENDENCY_PROPERTY(_In_ Windows::UI::Xaml::Style^, SymbolButtonStyle);
internal:
void SetRadixButton(RADIX_TYPE radixType);
private:
void DecButtonChecked(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
void HexButtonChecked(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
void BinButtonChecked(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
void OctButtonChecked(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
void OnCopyMenuItemClicked(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
};
}

View File

@@ -0,0 +1,434 @@
<UserControl x:Class="CalculatorApp.CalculatorProgrammerRadixOperators"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:common="using:CalculatorApp.Common"
xmlns:controls="using:CalculatorApp.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:CalculatorApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="ControlRoot"
d:DesignHeight="395"
d:DesignWidth="315"
Loaded="OnLoaded"
mc:Ignorable="d">
<Grid x:Name="ProgRadixOps">
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="GutterLeft" Width="0"/>
<ColumnDefinition x:Name="C0" Width="1*"/>
<ColumnDefinition x:Name="C1" Width="1*"/>
<ColumnDefinition x:Name="C2" Width="1*"/>
<ColumnDefinition x:Name="C3" Width="1*"/>
<ColumnDefinition x:Name="C4" Width="1*"/>
<ColumnDefinition x:Name="C5" Width="1*"/>
<ColumnDefinition x:Name="GutterRight" Width="0"/>
</Grid.ColumnDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ErrorVisualStates">
<VisualState x:Name="NoErrorLayout"/>
<VisualState x:Name="ErrorLayout">
<VisualState.Setters>
<Setter Target="rolButton.IsEnabled" Value="False"/>
<Setter Target="rorButton.IsEnabled" Value="False"/>
<Setter Target="lshButton.IsEnabled" Value="False"/>
<Setter Target="rshButton.IsEnabled" Value="False"/>
<Setter Target="orButton.IsEnabled" Value="False"/>
<Setter Target="xorButton.IsEnabled" Value="False"/>
<Setter Target="notButton.IsEnabled" Value="False"/>
<Setter Target="andButton.IsEnabled" Value="False"/>
<Setter Target="shiftButton.IsEnabled" Value="False"/>
<Setter Target="modButton.IsEnabled" Value="False"/>
<Setter Target="divideButton.IsEnabled" Value="False"/>
<Setter Target="multiplyButton.IsEnabled" Value="False"/>
<Setter Target="minusButton.IsEnabled" Value="False"/>
<Setter Target="plusButton.IsEnabled" Value="False"/>
<Setter Target="openParenthesisButton.IsEnabled" Value="False"/>
<Setter Target="closeParenthesisButton.IsEnabled" Value="False"/>
<Setter Target="negateButton.IsEnabled" Value="False"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup>
<VisualState x:Name="Portrait768x1366">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="1366" MinWindowWidth="768"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="clearEntryButton.FontSize" Value="{StaticResource CalcOperatorCaptionSize}"/>
<Setter Target="clearButton.FontSize" Value="{StaticResource CalcOperatorCaptionSize}"/>
<Setter Target="backSpaceButton.FontSize" Value="{StaticResource CalcOperatorCaptionSize}"/>
<Setter Target="divideButton.FontSize" Value="{StaticResource CalcOperatorCaptionSize}"/>
<Setter Target="multiplyButton.FontSize" Value="{StaticResource CalcOperatorCaptionSize}"/>
<Setter Target="minusButton.FontSize" Value="{StaticResource CalcOperatorCaptionSize}"/>
<Setter Target="plusButton.FontSize" Value="{StaticResource CalcOperatorCaptionSize}"/>
<Setter Target="equalButton.FontSize" Value="{StaticResource CalcOperatorCaptionSize}"/>
<Setter Target="aButton.FontSize" Value="{StaticResource TitleFontSize}"/>
<Setter Target="bButton.FontSize" Value="{StaticResource TitleFontSize}"/>
<Setter Target="cButton.FontSize" Value="{StaticResource TitleFontSize}"/>
<Setter Target="dButton.FontSize" Value="{StaticResource TitleFontSize}"/>
<Setter Target="eButton.FontSize" Value="{StaticResource TitleFontSize}"/>
<Setter Target="fButton.FontSize" Value="{StaticResource TitleFontSize}"/>
<Setter Target="NumberPad.ButtonStyle" Value="{StaticResource NumericButtonStyle24}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="FullLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="768" MinWindowWidth="1024"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="NumberPad.ButtonStyle" Value="{StaticResource NumericButtonStyle24}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="MinSizeLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="{StaticResource AppMinWindowHeight}" MinWindowWidth="{StaticResource AppMinWindowWidth}"/>
</VisualState.StateTriggers>
</VisualState>
<VisualState x:Name="DefaultLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="0" MinWindowWidth="0"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="openParenthesisButton.FontSize" Value="12"/>
<Setter Target="openParenthesisButton.Padding" Value="0"/>
<Setter Target="closeParenthesisButton.FontSize" Value="12"/>
<Setter Target="closeParenthesisButton.Padding" Value="0"/>
<Setter Target="NumberPad.ButtonStyle" Value="{StaticResource NumericButtonStyle12}"/>
<Setter Target="aButton.Style" Value="{StaticResource NumericButtonStyle12}"/>
<Setter Target="bButton.Style" Value="{StaticResource NumericButtonStyle12}"/>
<Setter Target="cButton.Style" Value="{StaticResource NumericButtonStyle12}"/>
<Setter Target="dButton.Style" Value="{StaticResource NumericButtonStyle12}"/>
<Setter Target="eButton.Style" Value="{StaticResource NumericButtonStyle12}"/>
<Setter Target="fButton.Style" Value="{StaticResource NumericButtonStyle12}"/>
<Setter Target="shiftButton.Style" Value="{StaticResource CaptionToggleButtonSmallStyle}"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid x:Uid="ProgrammerOperators"
Grid.Column="1"
Grid.ColumnSpan="6"
AutomationProperties.HeadingLevel="Level1">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<controls:CalculatorButton x:Name="rolButton"
x:Uid="rolButton"
Grid.Column="0"
Style="{StaticResource OperatorButtonStyle}"
FontSize="12"
x:DeferLoadStrategy="Lazy"
AutomationProperties.AutomationId="rolButton"
ButtonId="Rol"
Content="RoL"
Visibility="Collapsed"/>
<controls:CalculatorButton x:Name="rorButton"
x:Uid="rorButton"
Grid.Column="1"
Style="{StaticResource OperatorButtonStyle}"
FontSize="12"
x:DeferLoadStrategy="Lazy"
AutomationProperties.AutomationId="rorButton"
ButtonId="Ror"
Content="RoR"
Visibility="Collapsed"/>
<controls:CalculatorButton x:Name="lshButton"
x:Uid="lshButton"
Grid.Column="0"
Style="{StaticResource OperatorButtonStyle}"
FontSize="12"
AutomationProperties.AutomationId="lshButton"
ButtonId="Lsh"
Content="Lsh"/>
<controls:CalculatorButton x:Name="rshButton"
x:Uid="rshButton"
Grid.Column="1"
Style="{StaticResource OperatorButtonStyle}"
FontSize="12"
AutomationProperties.AutomationId="rshButton"
ButtonId="Rsh"
Content="Rsh"/>
<controls:CalculatorButton x:Name="orButton"
x:Uid="orButton"
Grid.Column="2"
Style="{StaticResource OperatorButtonStyle}"
FontSize="12"
AutomationProperties.AutomationId="orButton"
ButtonId="Or"
Content="Or"/>
<controls:CalculatorButton x:Name="xorButton"
x:Uid="xorButton"
Grid.Column="3"
Style="{StaticResource OperatorButtonStyle}"
FontSize="12"
AutomationProperties.AutomationId="xorButton"
ButtonId="Xor"
Content="Xor"/>
<controls:CalculatorButton x:Name="notButton"
x:Uid="notButton"
Grid.Column="4"
Style="{StaticResource OperatorButtonStyle}"
FontSize="12"
AutomationProperties.AutomationId="notButton"
ButtonId="Not"
Content="Not"/>
<controls:CalculatorButton x:Name="andButton"
x:Uid="andButton"
Grid.Column="5"
Style="{StaticResource OperatorButtonStyle}"
FontSize="12"
AutomationProperties.AutomationId="andButton"
ButtonId="And"
Content="And"/>
</Grid>
<ToggleButton x:Name="shiftButton"
x:Uid="shiftButton"
Grid.Row="1"
Grid.Column="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Style="{StaticResource CaptionToggleButtonStyle}"
FontFamily="{StaticResource CalculatorFontFamily}"
FontSize="16"
AutomationProperties.AutomationId="shiftButton"
Checked="Shift_Clicked"
Content="&#xE752;"
Unchecked="Shift_Clicked"/>
<controls:CalculatorButton x:Name="modButton"
x:Uid="modButton"
Grid.Row="1"
Grid.Column="2"
Style="{StaticResource OperatorButtonStyle}"
FontSize="12"
AutomationProperties.AutomationId="modButton"
ButtonId="Mod"
Content="Mod"/>
<Grid x:Uid="StandardOperators"
Grid.Row="1"
Grid.RowSpan="5"
Grid.Column="6"
AutomationProperties.HeadingLevel="Level1">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<controls:CalculatorButton x:Name="divideButton"
x:Uid="divideButton"
Grid.Row="0"
Style="{StaticResource AccentCalcButtonStyle}"
FontSize="12"
AutomationProperties.AutomationId="divideButton"
ButtonId="Divide"
Content="&#xE94A;"/>
<controls:CalculatorButton x:Name="multiplyButton"
x:Uid="multiplyButton"
Grid.Row="1"
Style="{StaticResource AccentCalcButtonStyle}"
FontSize="12"
AutomationProperties.AutomationId="multiplyButton"
ButtonId="Multiply"
Content="&#xE947;"/>
<controls:CalculatorButton x:Name="minusButton"
x:Uid="minusButton"
Grid.Row="2"
Style="{StaticResource AccentCalcButtonStyle}"
FontSize="12"
AutomationProperties.AutomationId="minusButton"
ButtonId="Subtract"
Content="&#xE949;"/>
<controls:CalculatorButton x:Name="plusButton"
x:Uid="plusButton"
Grid.Row="3"
Style="{StaticResource AccentCalcButtonStyle}"
FontSize="12"
AutomationProperties.AutomationId="plusButton"
ButtonId="Add"
Content="&#xE948;"/>
<controls:CalculatorButton x:Name="equalButton"
x:Uid="equalButton"
Grid.Row="4"
Style="{StaticResource AccentCalcButtonStyle}"
FontSize="12"
AutomationProperties.AutomationId="equalButton"
ButtonId="Equals"
Content="&#xE94E;"/>
</Grid>
<Grid x:Uid="DisplayControls"
Grid.Row="1"
Grid.Column="3"
Grid.ColumnSpan="3"
AutomationProperties.HeadingLevel="Level1">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<controls:CalculatorButton x:Name="clearEntryButton"
x:Uid="clearEntryButton"
Grid.Column="0"
Style="{StaticResource OperatorButtonStyle}"
FontSize="12"
FontWeight="SemiBold"
AutomationProperties.AutomationId="clearEntryButton"
ButtonId="ClearEntry"
Content="CE"/>
<controls:CalculatorButton x:Name="clearButton"
x:Uid="clearButton"
Grid.Column="1"
Style="{StaticResource OperatorButtonStyle}"
FontSize="12"
FontWeight="SemiBold"
AutomationProperties.AutomationId="clearButton"
ButtonId="Clear"
Content="C"/>
<controls:CalculatorButton x:Name="backSpaceButton"
x:Uid="backSpaceButton"
Grid.Column="2"
Style="{StaticResource SymbolOperatorButtonStyle}"
FontSize="12"
AutomationProperties.AutomationId="backSpaceButton"
ButtonId="Backspace"
Content="&#xE94F;"/>
</Grid>
<Grid x:Uid="NumberPad"
Grid.Row="2"
Grid.RowSpan="4"
Grid.Column="1"
Grid.ColumnSpan="5"
AutomationProperties.AutomationId="NumberPad"
AutomationProperties.HeadingLevel="Level1">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<local:NumberPad x:Name="NumberPad"
Grid.RowSpan="4"
Grid.Column="2"
Grid.ColumnSpan="3"
ButtonStyle="{StaticResource NumericButtonStyle18}"/>
<controls:CalculatorButton x:Name="aButton"
x:Uid="aButton"
Grid.Row="0"
Grid.Column="0"
Style="{StaticResource NumericButtonStyle12}"
AutomationProperties.AutomationId="aButton"
ButtonId="A"
Content="A"
IsEnabled="{x:Bind Model.AreHEXButtonsEnabled, Mode=OneWay}"/>
<controls:CalculatorButton x:Name="bButton"
x:Uid="bButton"
Grid.Row="0"
Grid.Column="1"
Style="{StaticResource NumericButtonStyle12}"
AutomationProperties.AutomationId="bButton"
ButtonId="B"
Content="B"
IsEnabled="{x:Bind Model.AreHEXButtonsEnabled, Mode=OneWay}"/>
<controls:CalculatorButton x:Name="cButton"
x:Uid="cButton"
Grid.Row="1"
Grid.Column="0"
Style="{StaticResource NumericButtonStyle12}"
AutomationProperties.AutomationId="cButton"
ButtonId="C"
Content="C"
IsEnabled="{x:Bind Model.AreHEXButtonsEnabled, Mode=OneWay}"/>
<controls:CalculatorButton x:Name="dButton"
x:Uid="dButton"
Grid.Row="1"
Grid.Column="1"
Style="{StaticResource NumericButtonStyle12}"
AutomationProperties.AutomationId="dButton"
ButtonId="D"
Content="D"
IsEnabled="{x:Bind Model.AreHEXButtonsEnabled, Mode=OneWay}"/>
<controls:CalculatorButton x:Name="eButton"
x:Uid="eButton"
Grid.Row="2"
Grid.Column="0"
Style="{StaticResource NumericButtonStyle12}"
AutomationProperties.AutomationId="eButton"
ButtonId="E"
Content="E"
IsEnabled="{x:Bind Model.AreHEXButtonsEnabled, Mode=OneWay}"/>
<controls:CalculatorButton x:Name="fButton"
x:Uid="fButton"
Grid.Row="2"
Grid.Column="1"
Style="{StaticResource NumericButtonStyle12}"
AutomationProperties.AutomationId="fButton"
ButtonId="F"
Content="F"
IsEnabled="{x:Bind Model.AreHEXButtonsEnabled, Mode=OneWay}"/>
</Grid>
<controls:CalculatorButton x:Name="openParenthesisButton"
x:Uid="openParenthesisButton"
Grid.Row="5"
Grid.Column="1"
Style="{StaticResource ParenthesisCalcButtonStyle}"
FontSize="18"
AutomationProperties.AutomationId="openParenthesisButton"
AutomationProperties.Name="{Binding LeftParenthesisAutomationName}"
ButtonId="OpenParenthesis"
Content="("
Tag="{x:Bind Model.OpenParenthesisCount, Mode=OneWay}"/>
<controls:CalculatorButton x:Name="closeParenthesisButton"
x:Uid="closeParenthesisButton"
Grid.Row="5"
Grid.Column="2"
Style="{StaticResource OperatorButtonStyle}"
FontSize="18"
AutomationProperties.AutomationId="closeParenthesisButton"
ButtonId="CloseParenthesis"
Content=")"/>
<controls:CalculatorButton x:Name="negateButton"
x:Uid="negateButton"
Grid.Row="5"
Grid.Column="3"
Style="{StaticResource SymbolOperatorButtonStyle}"
FontSize="12"
AutomationProperties.AutomationId="negateButton"
ButtonId="Negate"
Content="&#xE94D;"/>
</Grid>
</UserControl>

View File

@@ -0,0 +1,96 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//
// CalculatorProgrammerRadixOperators.xaml.cpp
// Implementation of the CalculatorProgrammerRadixOperators class
//
#include "pch.h"
#include "CalculatorProgrammerRadixOperators.xaml.h"
#include "Controls\CalculatorButton.h"
#include "Converters\BooleanToVisibilityConverter.h"
#include "Views\NumberPad.xaml.h"
using namespace CalculatorApp;
using namespace CalculatorApp::ViewModel;
using namespace Platform;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace CalculatorApp::Common;
using namespace Windows::UI::Xaml::Media;
CalculatorProgrammerRadixOperators::CalculatorProgrammerRadixOperators() :
m_isErrorVisualState(false)
{
InitializeComponent();
auto booleanToVisibilityNegationConverter = ref new Converters::BooleanToVisibilityNegationConverter;
SetVisibilityBinding(ProgRadixOps, L"IsBinaryBitFlippingEnabled", booleanToVisibilityNegationConverter);
}
void CalculatorProgrammerRadixOperators::OnLoaded(Object^, RoutedEventArgs^)
{
auto viewmodel = safe_cast<StandardCalculatorViewModel^>(this->DataContext);
viewmodel->ProgModeRadixChange += ref new ProgModeRadixChangeHandler(this, &CalculatorProgrammerRadixOperators::ProgModeRadixChange);
}
void CalculatorProgrammerRadixOperators::Shift_Clicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
bool isShiftChecked = static_cast<ToggleButton^>(sender)->IsChecked->Value;
auto scvm = safe_cast<StandardCalculatorViewModel^>(this->DataContext);
scvm->IsShiftProgrammerChecked = isShiftChecked;
if (rolButton == nullptr)
{
FindName("rolButton");
FindName("rorButton");
}
if (isShiftChecked)
{
rolButton->Visibility = ::Visibility::Visible;
rorButton->Visibility = ::Visibility::Visible;
lshButton->Visibility = ::Visibility::Collapsed;
rshButton->Visibility = ::Visibility::Collapsed;
}
else
{
rolButton->Visibility = ::Visibility::Collapsed;
rorButton->Visibility = ::Visibility::Collapsed;
lshButton->Visibility = ::Visibility::Visible;
rshButton->Visibility = ::Visibility::Visible;
}
}
void CalculatorProgrammerRadixOperators::SetVisibilityBinding(FrameworkElement^ element, String^ path, IValueConverter^ converter)
{
Binding^ commandBinding = ref new Binding();
commandBinding->Path = ref new PropertyPath(path);
commandBinding->Converter = converter;
element->SetBinding(VisibilityProperty, commandBinding);
}
void CalculatorProgrammerRadixOperators::ProgModeRadixChange()
{
NumberPad->ProgModeRadixChange();
}
bool CalculatorProgrammerRadixOperators::IsErrorVisualState::get()
{
return m_isErrorVisualState;
}
void CalculatorProgrammerRadixOperators::IsErrorVisualState::set(bool value)
{
if (m_isErrorVisualState != value)
{
m_isErrorVisualState = value;
String^ newState = m_isErrorVisualState ? L"ErrorLayout" : L"NoErrorLayout";
VisualStateManager::GoToState(this, newState, false);
NumberPad->IsErrorVisualState = m_isErrorVisualState;
}
}

View File

@@ -0,0 +1,40 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
#include "Views\CalculatorProgrammerRadixOperators.g.h"
#include "Converters\VisibilityNegationConverter.h"
#include "CalcViewModel\StandardCalculatorViewModel.h"
namespace CalculatorApp
{
[Windows::Foundation::Metadata::WebHostHidden]
public ref class CalculatorProgrammerRadixOperators sealed
{
public:
CalculatorProgrammerRadixOperators();
property CalculatorApp::ViewModel::StandardCalculatorViewModel^ Model
{
CalculatorApp::ViewModel::StandardCalculatorViewModel^ get() {
return static_cast<CalculatorApp::ViewModel::StandardCalculatorViewModel^>(this->DataContext);
}
}
property bool IsErrorVisualState {
bool get();
void set(bool value);
}
DEPENDENCY_PROPERTY_OWNER(CalculatorProgrammerRadixOperators);
private:
void Shift_Clicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void SetVisibilityBinding(Windows::UI::Xaml::FrameworkElement^ element, Platform::String^ path, Windows::UI::Xaml::Data::IValueConverter^ converter);
void OnLoaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void ProgModeRadixChange();
bool m_isErrorVisualState;
};
}

View File

@@ -0,0 +1,120 @@
<UserControl x:Class="CalculatorApp.CalculatorScientificAngleButtons"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="using:CalculatorApp.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:CalculatorApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="ControlRoot"
d:DesignHeight="315"
d:DesignWidth="400"
mc:Ignorable="d">
<UserControl.Resources>
<Style x:Key="CaptionButtonSmallStyle"
BasedOn="{StaticResource CaptionButtonStyle}"
TargetType="Button">
<Setter Property="MinHeight" Value="0"/>
</Style>
</UserControl.Resources>
<Grid x:Name="ScientificAngleOperators"
x:Uid="ScientificAngleOperators"
Margin="3,0,3,0"
AutomationProperties.HeadingLevel="Level1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" MaxWidth="80"/>
<ColumnDefinition Width="1*" MaxWidth="80"/>
<ColumnDefinition Width="1*" MaxWidth="80"/>
<ColumnDefinition Width="1*" MaxWidth="80"/>
<ColumnDefinition Width="1*" MaxWidth="80"/>
<ColumnDefinition Width="0.01*"/>
<ColumnDefinition Width="1*" MaxWidth="80"/>
</Grid.ColumnDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="Sizing">
<VisualState x:Name="MinSizeLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="{StaticResource AppMinWindowHeight}" MinWindowWidth="{StaticResource AppMinWindowWidth}"/>
</VisualState.StateTriggers>
</VisualState>
<VisualState x:Name="DefaultLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="0" MinWindowWidth="0"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="degreeButton.Style" Value="{StaticResource CaptionButtonSmallStyle}"/>
<Setter Target="radianButton.Style" Value="{StaticResource CaptionButtonSmallStyle}"/>
<Setter Target="gradsButton.Style" Value="{StaticResource CaptionButtonSmallStyle}"/>
<Setter Target="hyperbolicButton.Style" Value="{StaticResource CaptionToggleButtonSmallStyle}"/>
<Setter Target="ftoeButton.Style" Value="{StaticResource CaptionToggleButtonSmallStyle}"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="ErrorVisualStates">
<VisualState x:Name="NoErrorLayout"/>
<VisualState x:Name="ErrorLayout">
<VisualState.Setters>
<Setter Target="degreeButton.IsEnabled" Value="False"/>
<Setter Target="radianButton.IsEnabled" Value="False"/>
<Setter Target="gradsButton.IsEnabled" Value="False"/>
<Setter Target="hyperbolicButton.IsEnabled" Value="False"/>
<Setter Target="ftoeButton.IsEnabled" Value="False"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Button x:Name="degreeButton"
x:Uid="degButton"
Style="{StaticResource CaptionButtonStyle}"
AutomationProperties.AutomationId="degButton"
Command="{x:Bind ButtonPressed}"
CommandParameter="0"
Content="DEG"/>
<Button x:Name="radianButton"
x:Uid="radButton"
Style="{StaticResource CaptionButtonStyle}"
AutomationProperties.AutomationId="radButton"
Command="{x:Bind ButtonPressed}"
CommandParameter="1"
Content="RAD"
Visibility="Collapsed"/>
<Button x:Name="gradsButton"
x:Uid="gradButton"
Style="{StaticResource CaptionButtonStyle}"
AutomationProperties.AutomationId="gradButton"
Command="{x:Bind ButtonPressed}"
CommandParameter="2"
Content="GRAD"
Visibility="Collapsed"/>
<ToggleButton x:Name="hyperbolicButton"
x:Uid="hyperbolicButton"
Grid.Column="1"
Style="{StaticResource CaptionToggleButtonStyle}"
Background="{ThemeResource SystemControlBackgroundTransparentBrush}"
FontWeight="SemiBold"
AutomationProperties.AutomationId="hyperbolicButton"
Checked="HypButton_Toggled"
Content="HYP"
IsChecked="{Binding IsHyperbolicChecked, Mode=TwoWay}"
Unchecked="HypButton_Toggled"/>
<ToggleButton x:Name="ftoeButton"
x:Uid="ftoeButton"
Grid.Column="2"
Style="{StaticResource CaptionToggleButtonStyle}"
Background="{ThemeResource SystemControlBackgroundTransparentBrush}"
FontWeight="SemiBold"
AutomationProperties.AutomationId="ftoeButton"
Checked="FToEButton_Toggled"
Content="F-E"
IsChecked="{Binding IsFToEChecked, Mode=TwoWay}"
IsEnabled="{x:Bind Model.IsFToEEnabled, Mode=OneWay}"
Unchecked="FToEButton_Toggled">
<ToggleButton.CommandParameter>
<local:NumbersAndOperatorsEnum>FToE</local:NumbersAndOperatorsEnum>
</ToggleButton.CommandParameter>
</ToggleButton>
</Grid>
</UserControl>

View File

@@ -0,0 +1,90 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//
// CalculatorScientificAngleButtons.xaml.cpp
// Implementation of the CalculatorScientificAngleButtons class
//
#include "pch.h"
#include "CalculatorScientificAngleButtons.xaml.h"
#include "CalcViewModel\StandardCalculatorViewModel.h"
using namespace CalculatorApp;
using namespace CalculatorApp::ViewModel;
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
using namespace Windows::UI::ViewManagement;
using namespace Windows::UI::Core;
// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236
CalculatorScientificAngleButtons::CalculatorScientificAngleButtons() :
m_isErrorVisualState(false)
{
InitializeComponent();
}
void CalculatorScientificAngleButtons::HypButton_Toggled(_In_ Object^ sender, _In_ RoutedEventArgs^ e)
{
TraceLogger::GetInstance().LogHypButtonUsed(ApplicationView::GetApplicationViewIdForWindow(CoreWindow::GetForCurrentThread()));
}
void CalculatorScientificAngleButtons::FToEButton_Toggled(_In_ Object^ sender,_In_ RoutedEventArgs^ e)
{
auto viewModel = safe_cast<StandardCalculatorViewModel^>(this->DataContext);
viewModel->FtoEButtonToggled();
}
void CalculatorApp::CalculatorScientificAngleButtons::OnAngleButtonPressed(_In_ Object^ commandParameter)
{
TraceLogger::GetInstance().LogAngleButtonUsed(ApplicationView::GetApplicationViewIdForWindow(CoreWindow::GetForCurrentThread()));
String^ buttonId = static_cast<String^>(commandParameter);
degreeButton->Visibility = ::Visibility::Collapsed;
radianButton->Visibility = ::Visibility::Collapsed;
gradsButton->Visibility = ::Visibility::Collapsed;
if (buttonId == L"0")
{
Model->SwitchAngleType(NumbersAndOperatorsEnum::Radians);
radianButton->Visibility = ::Visibility::Visible;
radianButton->Focus(::FocusState::Programmatic);
}
else if (buttonId == L"1")
{
Model->SwitchAngleType(NumbersAndOperatorsEnum::Grads);
gradsButton->Visibility = ::Visibility::Visible;
gradsButton->Focus(::FocusState::Programmatic);
}
else if (buttonId == L"2")
{
Model->SwitchAngleType(NumbersAndOperatorsEnum::Degree);
degreeButton->Visibility = ::Visibility::Visible;
degreeButton->Focus(::FocusState::Programmatic);
}
}
bool CalculatorScientificAngleButtons::IsErrorVisualState::get()
{
return m_isErrorVisualState;
}
void CalculatorScientificAngleButtons::IsErrorVisualState::set(bool value)
{
if (m_isErrorVisualState != value)
{
m_isErrorVisualState = value;
String^ newState = m_isErrorVisualState ? L"ErrorLayout" : L"NoErrorLayout";
VisualStateManager::GoToState(this, newState, false);
}
}

View File

@@ -0,0 +1,42 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//
// CalculatorScientificAngleButtons.xaml.h
// Declaration of the CalculatorScientificAngleButtons class
//
#pragma once
#include "Views\CalculatorScientificAngleButtons.g.h"
#include "CalcViewModel\StandardCalculatorViewModel.h"
namespace CalculatorApp
{
[Windows::Foundation::Metadata::WebHostHidden]
public ref class CalculatorScientificAngleButtons sealed
{
public:
CalculatorScientificAngleButtons();
property CalculatorApp::ViewModel::StandardCalculatorViewModel^ Model
{
CalculatorApp::ViewModel::StandardCalculatorViewModel^ get() {
return static_cast<CalculatorApp::ViewModel::StandardCalculatorViewModel^>(this->DataContext);
}
}
COMMAND_FOR_METHOD(ButtonPressed, CalculatorScientificAngleButtons::OnAngleButtonPressed)
property bool IsErrorVisualState {
bool get();
void set(bool value);
}
private:
void OnAngleButtonPressed(_In_ Platform::Object^ commandParameter);
void FToEButton_Toggled(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
void HypButton_Toggled(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
bool m_isErrorVisualState;
};
}

View File

@@ -0,0 +1,753 @@
<UserControl x:Class="CalculatorApp.CalculatorScientificOperators"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:common="using:CalculatorApp.Common"
xmlns:controls="using:CalculatorApp.Controls"
xmlns:converters="using:CalculatorApp.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:designdata="using:CalculatorApp.DesignData"
xmlns:local="using:CalculatorApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="ControlRoot"
d:DesignHeight="400"
d:DesignWidth="315"
mc:Ignorable="d">
<UserControl.Resources>
<converters:BooleanNegationConverter x:Key="BooleanNegationConverter"/>
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<converters:BooleanToVisibilityNegationConverter x:Key="BooleanToVisibilityNegationConverter"/>
</UserControl.Resources>
<Grid x:Name="ScientificOperators">
<Grid.RowDefinitions>
<RowDefinition x:Name="R0" Height="1*"/>
<RowDefinition x:Name="R1" Height="0"/>
<RowDefinition x:Name="R2" Height="1*"/>
<RowDefinition x:Name="R3" Height="0"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="GutterLeft" Width="0"/>
<ColumnDefinition x:Name="C0" Width="0"/>
<ColumnDefinition x:Name="C1" Width="0"/>
<ColumnDefinition x:Name="C2" Width="0"/>
<ColumnDefinition x:Name="C3" Width="0"/>
<ColumnDefinition x:Name="C4" Width="1*"/>
<ColumnDefinition x:Name="C5" Width="1*"/>
<ColumnDefinition x:Name="C6" Width="1*"/>
<ColumnDefinition x:Name="C7" Width="1*"/>
<ColumnDefinition x:Name="C8" Width="1*"/>
<ColumnDefinition x:Name="GutterRight" Width="0"/>
</Grid.ColumnDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ErrorVisualStates">
<VisualState x:Name="NoErrorLayout"/>
<VisualState x:Name="ErrorLayout">
<VisualState.Setters>
<Setter Target="xpower2Button.IsEnabled" Value="False"/>
<Setter Target="powerButton.IsEnabled" Value="False"/>
<Setter Target="sinButton.IsEnabled" Value="False"/>
<Setter Target="cosButton.IsEnabled" Value="False"/>
<Setter Target="tanButton.IsEnabled" Value="False"/>
<Setter Target="sinhButton.IsEnabled" Value="False"/>
<Setter Target="coshButton.IsEnabled" Value="False"/>
<Setter Target="tanhButton.IsEnabled" Value="False"/>
<Setter Target="xpower3Button.IsEnabled" Value="False"/>
<Setter Target="ySquareRootButton.IsEnabled" Value="False"/>
<Setter Target="invsinButton.IsEnabled" Value="False"/>
<Setter Target="invcosButton.IsEnabled" Value="False"/>
<Setter Target="invtanButton.IsEnabled" Value="False"/>
<Setter Target="invsinhButton.IsEnabled" Value="False"/>
<Setter Target="invcoshButton.IsEnabled" Value="False"/>
<Setter Target="invtanhButton.IsEnabled" Value="False"/>
<Setter Target="squareRootButton.IsEnabled" Value="False"/>
<Setter Target="powerOf10Button.IsEnabled" Value="False"/>
<Setter Target="logBase10Button.IsEnabled" Value="False"/>
<Setter Target="expButton.IsEnabled" Value="False"/>
<Setter Target="modButton.IsEnabled" Value="False"/>
<Setter Target="invertButton.IsEnabled" Value="False"/>
<Setter Target="powerOfEButton.IsEnabled" Value="False"/>
<Setter Target="logBaseEButton.IsEnabled" Value="False"/>
<Setter Target="dmsButton.IsEnabled" Value="False"/>
<Setter Target="degreesButton.IsEnabled" Value="False"/>
<Setter Target="shiftButton.IsEnabled" Value="False"/>
<Setter Target="divideButton.IsEnabled" Value="False"/>
<Setter Target="multiplyButton.IsEnabled" Value="False"/>
<Setter Target="minusButton.IsEnabled" Value="False"/>
<Setter Target="plusButton.IsEnabled" Value="False"/>
<Setter Target="piButton.IsEnabled" Value="False"/>
<Setter Target="factorialButton.IsEnabled" Value="False"/>
<Setter Target="negateButton.IsEnabled" Value="False"/>
<Setter Target="openParenthesisButton.IsEnabled" Value="False"/>
<Setter Target="closeParenthesisButton.IsEnabled" Value="False"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="SizeLayouts">
<VisualState x:Name="Portrait">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="1366" MinWindowWidth="768"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="R1.Height" Value="1*"/>
<Setter Target="R3.Height" Value="1*"/>
<Setter Target="OpR2.Height" Value="1*"/>
<Setter Target="OpR3.Height" Value="1*"/>
<Setter Target="Row1.Visibility" Value="Visible"/>
<Setter Target="Row2.Visibility" Value="Visible"/>
<Setter Target="InvRow1.(Grid.Row)" Value="1"/>
<Setter Target="Row2.(Grid.Row)" Value="2"/>
<Setter Target="InvRow2.(Grid.Row)" Value="3"/>
<Setter Target="InvRow1.Visibility" Value="Visible"/>
<Setter Target="InvRow2.Visibility" Value="Visible"/>
<Setter Target="negateButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="piButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="factorialButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="openParenthesisButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="closeParenthesisButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="sinButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="cosButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="tanButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="sinhButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="coshButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="tanhButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="invsinButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="invcosButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="invtanButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="invsinhButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="invcoshButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="invtanhButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="powerButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="powerOf10Button.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="logBase10Button.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="expButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="modButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="ySquareRootButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="powerOfEButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="logBaseEButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="dmsButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="degreesButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="xpower2Button.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="xpower3Button.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="squareRootButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="invertButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="clearEntryButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="clearButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="backSpaceButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="divideButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="multiplyButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="minusButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="plusButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="equalButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="NumberPad.ButtonStyle" Value="{ThemeResource NumericButtonStyle34}"/>
</VisualState.Setters>
<Storyboard Completed="WideLayout_Completed"/>
</VisualState>
<VisualState x:Name="WideL">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="768" MinWindowWidth="1200"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="R0.Height" Value="0"/>
<Setter Target="R2.Height" Value="0"/>
<Setter Target="C0.Width" Value="1*"/>
<Setter Target="C1.Width" Value="1*"/>
<Setter Target="C2.Width" Value="1*"/>
<Setter Target="C3.Width" Value="1*"/>
<Setter Target="shiftButton.(Grid.Row)" Value="8"/>
<Setter Target="shiftButton.(Grid.Column)" Value="1"/>
<Setter Target="ScientificFunctions.(Grid.Row)" Value="4"/>
<Setter Target="ScientificFunctions.(Grid.Column)" Value="1"/>
<Setter Target="OpR2.Height" Value="1*"/>
<Setter Target="OpR3.Height" Value="1*"/>
<Setter Target="Row1.Visibility" Value="Visible"/>
<Setter Target="Row2.Visibility" Value="Visible"/>
<Setter Target="InvRow1.(Grid.Row)" Value="1"/>
<Setter Target="Row2.(Grid.Row)" Value="2"/>
<Setter Target="InvRow2.(Grid.Row)" Value="3"/>
<Setter Target="InvRow1.Visibility" Value="Visible"/>
<Setter Target="InvRow2.Visibility" Value="Visible"/>
<Setter Target="negateButton.(Grid.Row)" Value="8"/>
<Setter Target="negateButton.(Grid.Column)" Value="6"/>
<Setter Target="piButton.(Grid.Row)" Value="8"/>
<Setter Target="piButton.(Grid.Column)" Value="2"/>
<Setter Target="factorialButton.(Grid.Row)" Value="8"/>
<Setter Target="factorialButton.(Grid.Column)" Value="3"/>
<Setter Target="openParenthesisButton.(Grid.Row)" Value="8"/>
<Setter Target="openParenthesisButton.(Grid.Column)" Value="4"/>
<Setter Target="closeParenthesisButton.(Grid.Row)" Value="8"/>
<Setter Target="closeParenthesisButton.(Grid.Column)" Value="5"/>
<Setter Target="negateButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="piButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="factorialButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="openParenthesisButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="closeParenthesisButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="sinButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="cosButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="tanButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="sinhButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="coshButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="tanhButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="invsinButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="invcosButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="invtanButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="invsinhButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="invcoshButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="invtanhButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="powerButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="powerOf10Button.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="logBase10Button.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="expButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="modButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="ySquareRootButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="powerOfEButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="logBaseEButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="dmsButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="degreesButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="xpower2Button.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="xpower3Button.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="squareRootButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="invertButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="clearEntryButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="clearButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="backSpaceButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="divideButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="multiplyButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="minusButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="plusButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="equalButton.FontSize" Value="{ThemeResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="NumberPad.ButtonStyle" Value="{ThemeResource NumericButtonStyle34}"/>
</VisualState.Setters>
<Storyboard Completed="WideLayout_Completed"/>
</VisualState>
<VisualState x:Name="WideMINI">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="0" MinWindowWidth="1024"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="R0.Height" Value="0"/>
<Setter Target="R2.Height" Value="0"/>
<Setter Target="C0.Width" Value="1*"/>
<Setter Target="C1.Width" Value="1*"/>
<Setter Target="C2.Width" Value="1*"/>
<Setter Target="C3.Width" Value="1*"/>
<Setter Target="shiftButton.(Grid.Row)" Value="8"/>
<Setter Target="shiftButton.(Grid.Column)" Value="1"/>
<Setter Target="ScientificFunctions.(Grid.Row)" Value="4"/>
<Setter Target="ScientificFunctions.(Grid.Column)" Value="1"/>
<Setter Target="OpR2.Height" Value="1*"/>
<Setter Target="OpR3.Height" Value="1*"/>
<Setter Target="Row1.Visibility" Value="Visible"/>
<Setter Target="Row2.Visibility" Value="Visible"/>
<Setter Target="InvRow1.(Grid.Row)" Value="1"/>
<Setter Target="Row2.(Grid.Row)" Value="2"/>
<Setter Target="InvRow2.(Grid.Row)" Value="3"/>
<Setter Target="InvRow1.Visibility" Value="Visible"/>
<Setter Target="InvRow2.Visibility" Value="Visible"/>
<Setter Target="negateButton.(Grid.Row)" Value="8"/>
<Setter Target="negateButton.(Grid.Column)" Value="6"/>
<Setter Target="piButton.(Grid.Row)" Value="8"/>
<Setter Target="piButton.(Grid.Column)" Value="2"/>
<Setter Target="factorialButton.(Grid.Row)" Value="8"/>
<Setter Target="factorialButton.(Grid.Column)" Value="3"/>
<Setter Target="openParenthesisButton.(Grid.Row)" Value="8"/>
<Setter Target="openParenthesisButton.(Grid.Column)" Value="4"/>
<Setter Target="closeParenthesisButton.(Grid.Row)" Value="8"/>
<Setter Target="closeParenthesisButton.(Grid.Column)" Value="5"/>
</VisualState.Setters>
<Storyboard Completed="WideLayout_Completed"/>
</VisualState>
<VisualState x:Name="Fill640x800">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="800" MinWindowWidth="640"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="R1.Height" Value="1*"/>
<Setter Target="R3.Height" Value="1*"/>
<Setter Target="OpR2.Height" Value="1*"/>
<Setter Target="OpR3.Height" Value="1*"/>
<Setter Target="Row1.Visibility" Value="Visible"/>
<Setter Target="Row2.Visibility" Value="Visible"/>
<Setter Target="InvRow1.(Grid.Row)" Value="1"/>
<Setter Target="Row2.(Grid.Row)" Value="2"/>
<Setter Target="InvRow2.(Grid.Row)" Value="3"/>
<Setter Target="InvRow1.Visibility" Value="Visible"/>
<Setter Target="InvRow2.Visibility" Value="Visible"/>
</VisualState.Setters>
<Storyboard Completed="WideLayout_Completed"/>
</VisualState>
<VisualState x:Name="Fill640x528">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="0" MinWindowWidth="640"/>
</VisualState.StateTriggers>
<Storyboard Completed="ShortLayout_Completed"/>
</VisualState>
<VisualState x:Name="Snap320x800">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="800" MinWindowWidth="0"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="R1.Height" Value="1*"/>
<Setter Target="R3.Height" Value="1*"/>
<Setter Target="OpR2.Height" Value="1*"/>
<Setter Target="OpR3.Height" Value="1*"/>
<Setter Target="Row1.Visibility" Value="Visible"/>
<Setter Target="Row2.Visibility" Value="Visible"/>
<Setter Target="InvRow1.(Grid.Row)" Value="1"/>
<Setter Target="Row2.(Grid.Row)" Value="2"/>
<Setter Target="InvRow2.(Grid.Row)" Value="3"/>
<Setter Target="InvRow1.Visibility" Value="Visible"/>
<Setter Target="InvRow2.Visibility" Value="Visible"/>
</VisualState.Setters>
<Storyboard Completed="WideLayout_Completed"/>
</VisualState>
<VisualState x:Name="MinSizeLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="{StaticResource AppMinWindowHeight}" MinWindowWidth="{StaticResource AppMinWindowWidth}"/>
</VisualState.StateTriggers>
<Storyboard Completed="ShortLayout_Completed"/>
</VisualState>
<VisualState x:Name="DefaultLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="0" MinWindowWidth="0"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="shiftButton.Style" Value="{StaticResource CaptionToggleButtonSmallStyle}"/>
</VisualState.Setters>
<Storyboard Completed="ShortLayout_Completed"/>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid x:Name="ScientificFunctions"
x:Uid="ScientificFunctions"
Grid.RowSpan="4"
Grid.Column="5"
Grid.ColumnSpan="5"
AutomationProperties.HeadingLevel="Level1">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition x:Name="OpR2" Height="0"/>
<RowDefinition x:Name="OpR3" Height="0"/>
</Grid.RowDefinitions>
<!-- Scientific Row 1 -->
<Grid x:Name="Row1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<controls:CalculatorButton x:Name="xpower2Button"
x:Uid="xpower2Button"
Style="{StaticResource SymbolOperatorButtonStyle}"
AutomationProperties.AutomationId="xpower2Button"
ButtonId="XPower2"
Content="&#xf7c8;"/>
<controls:CalculatorButton x:Name="powerButton"
x:Uid="powerButton"
Grid.Column="1"
Style="{StaticResource SymbolOperatorButtonStyle}"
AutomationProperties.AutomationId="powerButton"
ButtonId="XPowerY"
Content="&#xf7ca;"/>
<controls:CalculatorButton x:Name="sinButton"
x:Uid="sinButton"
Grid.Column="2"
Style="{StaticResource OperatorButtonStyle}"
AutomationProperties.AutomationId="sinButton"
ButtonId="Sin"
Content="sin"
Visibility="{Binding IsHyperbolicChecked, Converter={StaticResource BooleanToVisibilityNegationConverter}}"/>
<controls:CalculatorButton x:Name="cosButton"
x:Uid="cosButton"
Grid.Column="3"
Style="{StaticResource OperatorButtonStyle}"
AutomationProperties.AutomationId="cosButton"
ButtonId="Cos"
Content="cos"
Visibility="{Binding IsHyperbolicChecked, Converter={StaticResource BooleanToVisibilityNegationConverter}}"/>
<controls:CalculatorButton x:Name="tanButton"
x:Uid="tanButton"
Grid.Column="4"
Style="{StaticResource OperatorButtonStyle}"
AutomationProperties.AutomationId="tanButton"
ButtonId="Tan"
Content="tan"
Visibility="{Binding IsHyperbolicChecked, Converter={StaticResource BooleanToVisibilityNegationConverter}}"/>
<controls:CalculatorButton x:Name="sinhButton"
x:Uid="sinhButton"
Grid.Column="2"
Style="{StaticResource OperatorButtonStyle}"
AutomationProperties.AutomationId="sinhButton"
ButtonId="Sinh"
Content="sinh"
Visibility="{Binding IsHyperbolicChecked, Converter={StaticResource BooleanToVisibilityConverter}}"/>
<controls:CalculatorButton x:Name="coshButton"
x:Uid="coshButton"
Grid.Column="3"
Style="{StaticResource OperatorButtonStyle}"
AutomationProperties.AutomationId="coshButton"
ButtonId="Cosh"
Content="cosh"
Visibility="{Binding IsHyperbolicChecked, Converter={StaticResource BooleanToVisibilityConverter}}"/>
<controls:CalculatorButton x:Name="tanhButton"
x:Uid="tanhButton"
Grid.Column="4"
Style="{StaticResource OperatorButtonStyle}"
AutomationProperties.AutomationId="tanhButton"
ButtonId="Tanh"
Content="tanh"
Visibility="{Binding IsHyperbolicChecked, Converter={StaticResource BooleanToVisibilityConverter}}"/>
</Grid>
<!-- Scientific INV Row 1 -->
<Grid x:Name="InvRow1" Visibility="Collapsed">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="CX0" Width="1*"/>
<ColumnDefinition x:Name="CX1" Width="1*"/>
<ColumnDefinition x:Name="CX2" Width="1*"/>
<ColumnDefinition x:Name="Cx3" Width="1*"/>
<ColumnDefinition x:Name="CX4" Width="1*"/>
</Grid.ColumnDefinitions>
<controls:CalculatorButton x:Name="xpower3Button"
x:Uid="xpower3Button"
Style="{StaticResource SymbolOperatorButtonStyle}"
AutomationProperties.AutomationId="xpower3Button"
ButtonId="Cube"
Content="&#xf7cb;"/>
<controls:CalculatorButton x:Name="ySquareRootButton"
x:Uid="ySquareRootButton"
Grid.Column="1"
Style="{StaticResource SymbolOperatorButtonStyle}"
AutomationProperties.AutomationId="ySquareRootButton"
ButtonId="YRootX"
Content="&#xf7cd;"/>
<controls:CalculatorButton x:Name="invsinButton"
x:Uid="invsinButton"
Grid.Column="2"
Style="{StaticResource OperatorButtonStyle}"
AutomationProperties.AutomationId="invsinButton"
ButtonId="InvSin"
Content="sin⁻¹"
Visibility="{Binding IsHyperbolicChecked, Converter={StaticResource BooleanToVisibilityNegationConverter}}"/>
<controls:CalculatorButton x:Name="invcosButton"
x:Uid="invcosButton"
Grid.Column="3"
Style="{StaticResource OperatorButtonStyle}"
AutomationProperties.AutomationId="invcosButton"
ButtonId="InvCos"
Content="cos⁻¹"
Visibility="{Binding IsHyperbolicChecked, Converter={StaticResource BooleanToVisibilityNegationConverter}}"/>
<controls:CalculatorButton x:Name="invtanButton"
x:Uid="invtanButton"
Grid.Column="4"
Style="{StaticResource OperatorButtonStyle}"
AutomationProperties.AutomationId="invtanButton"
ButtonId="InvTan"
Content="tan⁻¹"
Visibility="{Binding IsHyperbolicChecked, Converter={StaticResource BooleanToVisibilityNegationConverter}}"/>
<controls:CalculatorButton x:Name="invsinhButton"
x:Uid="invsinhButton"
Grid.Column="2"
Style="{StaticResource OperatorButtonStyle}"
AutomationProperties.AutomationId="invsinhButton"
ButtonId="InvSinh"
Content="sinh⁻¹"
Visibility="{Binding IsHyperbolicChecked, Converter={StaticResource BooleanToVisibilityConverter}}"/>
<controls:CalculatorButton x:Name="invcoshButton"
x:Uid="invcoshButton"
Grid.Column="3"
Style="{StaticResource OperatorButtonStyle}"
AutomationProperties.AutomationId="invcoshButton"
ButtonId="InvCosh"
Content="cosh⁻¹"
Visibility="{Binding IsHyperbolicChecked, Converter={StaticResource BooleanToVisibilityConverter}}"/>
<controls:CalculatorButton x:Name="invtanhButton"
x:Uid="invtanhButton"
Grid.Column="4"
Style="{StaticResource OperatorButtonStyle}"
AutomationProperties.AutomationId="invtanhButton"
ButtonId="InvTanh"
Content="tanh⁻¹"
Visibility="{Binding IsHyperbolicChecked, Converter={StaticResource BooleanToVisibilityConverter}}"/>
</Grid>
<!-- Scientific Row 2 -->
<Grid x:Name="Row2" Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<controls:CalculatorButton x:Name="squareRootButton"
x:Uid="squareRootButton"
Style="{StaticResource SymbolOperatorButtonStyle}"
AutomationProperties.AutomationId="squareRootButton"
ButtonId="Sqrt"
Content="&#xE94B;"/>
<controls:CalculatorButton x:Name="powerOf10Button"
x:Uid="powerOf10Button"
Grid.Column="1"
Style="{StaticResource SymbolOperatorButtonStyle}"
AutomationProperties.AutomationId="powerOf10Button"
ButtonId="TenPowerX"
Content="&#xF7CC;"/>
<controls:CalculatorButton x:Name="logBase10Button"
x:Uid="logBase10Button"
Grid.Column="2"
Style="{StaticResource OperatorButtonStyle}"
AutomationProperties.AutomationId="logBase10Button"
ButtonId="LogBase10"
Content="log"/>
<controls:CalculatorButton x:Name="expButton"
x:Uid="expButton"
Grid.Column="3"
Style="{StaticResource OperatorButtonStyle}"
AutomationProperties.AutomationId="expButton"
ButtonId="Exp"
Content="Exp"/>
<controls:CalculatorButton x:Name="modButton"
x:Uid="modButton"
Grid.Column="4"
Style="{StaticResource OperatorButtonStyle}"
AutomationProperties.AutomationId="modButton"
ButtonId="Mod"
Content="Mod"/>
</Grid>
<!-- Scientific INV Row 2 -->
<Grid x:Name="InvRow2"
Grid.Row="1"
Visibility="Collapsed">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<controls:CalculatorButton x:Name="invertButton"
x:Uid="invertButton"
Style="{StaticResource SymbolOperatorButtonStyle}"
AutomationProperties.AutomationId="invertButton"
ButtonId="Invert"
Content="&#xf7c9;"/>
<controls:CalculatorButton x:Name="powerOfEButton"
x:Uid="powerOfEButton"
Grid.Column="1"
Style="{StaticResource SymbolOperatorButtonStyle}"
AutomationProperties.AutomationId="powerOfEButton"
ButtonId="EPowerX"
Content="&#xf7ce;"/>
<controls:CalculatorButton x:Name="logBaseEButton"
x:Uid="logBaseEButton"
Grid.Column="2"
Style="{StaticResource OperatorButtonStyle}"
AutomationProperties.AutomationId="logBaseEButton"
ButtonId="LogBaseE"
Content="ln"/>
<controls:CalculatorButton x:Name="dmsButton"
x:Uid="dmsButton"
Grid.Column="3"
Style="{StaticResource OperatorButtonStyle}"
AutomationProperties.AutomationId="dmsButton"
ButtonId="DMS"
Content="dms"/>
<controls:CalculatorButton x:Name="degreesButton"
x:Uid="degreesButton"
Grid.Column="4"
Style="{StaticResource OperatorButtonStyle}"
AutomationProperties.AutomationId="degreesButton"
ButtonId="Degrees"
Content="deg"/>
</Grid>
</Grid>
<ToggleButton x:Name="shiftButton"
x:Uid="shiftButton"
Grid.Row="4"
Grid.Column="5"
Style="{StaticResource CaptionToggleButtonStyle}"
FontFamily="{StaticResource CalculatorFontFamily}"
FontSize="20"
AutomationProperties.AutomationId="shiftButton"
Checked="shiftButton_Check"
Content="&#xE752;"
IsEnabled="{x:Bind IsShiftEnabled(IsWideLayout, IsErrorVisualState), Mode=OneWay}"
IsEnabledChanged="shiftButton_IsEnabledChanged"
Unchecked="shiftButton_Check"/>
<Grid x:Name="StandardOperators"
x:Uid="StandardOperators"
Grid.Row="4"
Grid.RowSpan="5"
Grid.Column="9"
AutomationProperties.HeadingLevel="Level1">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<controls:CalculatorButton x:Name="divideButton"
x:Uid="divideButton"
Grid.Row="0"
Style="{StaticResource AccentCalcButtonStyle}"
AutomationProperties.AutomationId="divideButton"
ButtonId="Divide"
Content="&#xE94A;"/>
<controls:CalculatorButton x:Name="multiplyButton"
x:Uid="multiplyButton"
Grid.Row="1"
Style="{StaticResource AccentCalcButtonStyle}"
AutomationProperties.AutomationId="multiplyButton"
ButtonId="Multiply"
Content="&#xE947;"/>
<controls:CalculatorButton x:Name="minusButton"
x:Uid="minusButton"
Grid.Row="2"
Style="{StaticResource AccentCalcButtonStyle}"
AutomationProperties.AutomationId="minusButton"
ButtonId="Subtract"
Content="&#xE949;"/>
<controls:CalculatorButton x:Name="plusButton"
x:Uid="plusButton"
Grid.Row="3"
Style="{StaticResource AccentCalcButtonStyle}"
AutomationProperties.AutomationId="plusButton"
ButtonId="Add"
Content="&#xE948;"/>
<controls:CalculatorButton x:Name="equalButton"
x:Uid="equalButton"
Grid.Row="4"
Style="{StaticResource AccentCalcButtonStyle}"
AutomationProperties.AutomationId="equalButton"
ButtonId="Equals"
Content="&#xE94E;"/>
</Grid>
<Grid x:Name="DisplayControls"
x:Uid="DisplayControls"
Grid.Row="4"
Grid.Column="6"
Grid.ColumnSpan="3"
AutomationProperties.HeadingLevel="Level1">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<controls:CalculatorButton x:Name="clearEntryButton"
x:Uid="clearEntryButton"
Style="{StaticResource OperatorButtonStyle}"
FontSize="16"
AutomationProperties.AutomationId="clearEntryButton"
ButtonId="ClearEntry"
Content="CE"/>
<controls:CalculatorButton x:Name="clearButton"
x:Uid="clearButton"
Grid.Column="1"
Style="{StaticResource OperatorButtonStyle}"
FontSize="16"
AutomationProperties.AutomationId="clearButton"
ButtonId="Clear"
Content="C"/>
<controls:CalculatorButton x:Name="backSpaceButton"
x:Uid="backSpaceButton"
Grid.Column="2"
Style="{StaticResource SymbolOperatorButtonStyle}"
FontFamily="{StaticResource CalculatorFontFamily}"
FontSize="16"
AutomationProperties.AutomationId="backSpaceButton"
ButtonId="Backspace"
Content="&#xE94F;"/>
</Grid>
<controls:CalculatorButton x:Name="piButton"
x:Uid="piButton"
Grid.Row="5"
Grid.Column="5"
Style="{StaticResource SymbolOperatorButtonStyle}"
FontSize="14"
AutomationProperties.AutomationId="piButton"
ButtonId="Pi"
Content="&#xf7cf;"/>
<controls:CalculatorButton x:Name="factorialButton"
x:Uid="factorialButton"
Grid.Row="6"
Grid.Column="5"
Style="{StaticResource OperatorButtonStyle}"
FontSize="18"
AutomationProperties.AutomationId="factorialButton"
ButtonId="Factorial"
Content="n!"/>
<controls:CalculatorButton x:Name="negateButton"
x:Uid="negateButton"
Grid.Row="7"
Grid.Column="5"
Style="{StaticResource SymbolOperatorButtonStyle}"
FontSize="16"
AutomationProperties.AutomationId="negateButton"
ButtonId="Negate"
Content="&#xE94D;"
IsEnabled="{x:Bind Model.IsNegateEnabled, Mode=OneWay}"/>
<controls:CalculatorButton x:Name="openParenthesisButton"
x:Uid="openParenthesisButton"
Grid.Row="8"
Grid.Column="5"
Style="{StaticResource ParenthesisCalcButtonStyle}"
FontSize="19"
AutomationProperties.AutomationId="openParenthesisButton"
AutomationProperties.Name="{Binding LeftParenthesisAutomationName}"
ButtonId="OpenParenthesis"
Content="("
Tag="{x:Bind Model.OpenParenthesisCount, Mode=OneWay}"/>
<controls:CalculatorButton x:Name="closeParenthesisButton"
x:Uid="closeParenthesisButton"
Grid.Row="8"
Grid.Column="6"
Style="{StaticResource OperatorButtonStyle}"
FontSize="19"
AutomationProperties.AutomationId="closeParenthesisButton"
ButtonId="CloseParenthesis"
Content=")"/>
<local:NumberPad x:Name="NumberPad"
x:Uid="NumberPad"
Grid.Row="5"
Grid.RowSpan="4"
Grid.Column="6"
Grid.ColumnSpan="3"
AutomationProperties.HeadingLevel="Level1"
ButtonStyle="{StaticResource NumericButtonStyle24}"/>
</Grid>
</UserControl>

View File

@@ -0,0 +1,99 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//
// CalculatorScientificOperators.xaml.cpp
// Implementation of the CalculatorScientificOperators class
//
#include "pch.h"
#include "CalculatorScientificOperators.xaml.h"
#include "CalcViewModel\Common\KeyboardShortcutManager.h"
#include "Controls\CalculatorButton.h"
#include "CalcViewModel\StandardCalculatorViewModel.h"
using namespace CalculatorApp;
using namespace CalculatorApp::Common;
using namespace CalculatorApp::ViewModel;
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
DEPENDENCY_PROPERTY_INITIALIZATION(CalculatorScientificOperators, IsErrorVisualState);
DEPENDENCY_PROPERTY_INITIALIZATION(CalculatorScientificOperators, IsWideLayout);
CalculatorScientificOperators::CalculatorScientificOperators()
{
InitializeComponent();
expButton->SetValue(Common::KeyboardShortcutManager::VirtualKeyProperty, Common::MyVirtualKey::E);
Common::KeyboardShortcutManager::ShiftButtonChecked(false);
}
void CalculatorScientificOperators::ShortLayout_Completed(_In_ Platform::Object^ /*sender*/, _In_ Platform::Object^ /*e*/)
{
IsWideLayout = false;
SetOperatorRowVisibility();
Common::KeyboardShortcutManager::ShiftButtonChecked(Model->IsShiftChecked);
}
void CalculatorScientificOperators::WideLayout_Completed(_In_ Platform::Object^ /*sender*/, _In_ Platform::Object^ /*e*/)
{
IsWideLayout = true;
SetOperatorRowVisibility();
Common::KeyboardShortcutManager::ShiftButtonChecked(Model->IsShiftChecked);
}
void CalculatorScientificOperators::OnIsErrorVisualStatePropertyChanged(bool /*oldValue*/, bool newValue)
{
String^ newState = newValue ? L"ErrorLayout" : L"NoErrorLayout";
VisualStateManager::GoToState(this, newState, false);
NumberPad->IsErrorVisualState = newValue;
}
void CalculatorScientificOperators::shiftButton_Check(_In_ Platform::Object^ /*sender*/, _In_ Windows::UI::Xaml::RoutedEventArgs^ /*e*/)
{
bool isChecked = shiftButton->IsChecked->Value;
Model->IsShiftChecked = isChecked;
Common::KeyboardShortcutManager::ShiftButtonChecked(isChecked);
SetOperatorRowVisibility();
}
void CalculatorScientificOperators::shiftButton_IsEnabledChanged(_In_ Platform::Object^ /*sender*/, _In_ Windows::UI::Xaml::DependencyPropertyChangedEventArgs^ /*e*/)
{
SetOperatorRowVisibility();
Common::KeyboardShortcutManager::ShiftButtonChecked(shiftButton->IsEnabled && shiftButton->IsChecked->Value);
}
void CalculatorScientificOperators::SetOperatorRowVisibility()
{
::Visibility rowVis, invRowVis;
if (IsWideLayout)
{
rowVis = ::Visibility::Visible;
invRowVis = ::Visibility::Visible;
}
else if (shiftButton->IsChecked->Value)
{
rowVis = ::Visibility::Collapsed;
invRowVis = ::Visibility::Visible;
}
else
{
rowVis = ::Visibility::Visible;
invRowVis = ::Visibility::Collapsed;
}
Row1->Visibility = rowVis;
Row2->Visibility = rowVis;
InvRow1->Visibility = invRowVis;
InvRow2->Visibility = invRowVis;
}

View File

@@ -0,0 +1,45 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//
// CalculatorScientificOperators.xaml.h
// Declaration of the CalculatorScientificOperators class
//
#pragma once
#include "Views\CalculatorScientificOperators.g.h"
#include "Views\NumberPad.xaml.h"
#include "Converters\BooleanNegationConverter.h"
#include "Converters\VisibilityNegationConverter.h"
#include "CalcViewModel\StandardCalculatorViewModel.h"
namespace CalculatorApp
{
[Windows::Foundation::Metadata::WebHostHidden]
public ref class CalculatorScientificOperators sealed
{
public:
CalculatorScientificOperators();
property CalculatorApp::ViewModel::StandardCalculatorViewModel^ Model
{
CalculatorApp::ViewModel::StandardCalculatorViewModel^ get() {
return static_cast<CalculatorApp::ViewModel::StandardCalculatorViewModel^>(this->DataContext);
}
}
DEPENDENCY_PROPERTY_OWNER(CalculatorScientificOperators);
DEPENDENCY_PROPERTY_WITH_DEFAULT_AND_CALLBACK(bool, IsErrorVisualState, false);
DEPENDENCY_PROPERTY_WITH_DEFAULT(bool, IsWideLayout, false);
bool IsShiftEnabled(bool isWideLayout, bool isErrorState) { return !(isWideLayout || isErrorState); }
private:
void ShortLayout_Completed(_In_ Platform::Object^ sender, _In_ Platform::Object^ e);
void WideLayout_Completed(_In_ Platform::Object^ sender, _In_ Platform::Object^ e);
void OnIsErrorVisualStatePropertyChanged(bool oldValue, bool newValue);
void shiftButton_Check(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
void shiftButton_IsEnabledChanged(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::DependencyPropertyChangedEventArgs^ e);
void SetOperatorRowVisibility();
};
}

View File

@@ -0,0 +1,415 @@
<UserControl x:Class="CalculatorApp.CalculatorStandardOperators"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:common="using:CalculatorApp.Common"
xmlns:controls="using:CalculatorApp.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:CalculatorApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="ControlRoot"
mc:Ignorable="d">
<Grid x:Name="Root">
<Grid.RowDefinitions>
<RowDefinition x:Name="R0" Height="1*"/>
<RowDefinition x:Name="R1" Height="1*"/>
<RowDefinition x:Name="R2" Height="1*"/>
<RowDefinition x:Name="R3" Height="1*"/>
<RowDefinition x:Name="R4" Height="1*"/>
<RowDefinition x:Name="R5" Height="1*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="GutterLeft" Width="0"/>
<ColumnDefinition x:Name="C0" Width="0"/>
<ColumnDefinition x:Name="C1" Width="1*"/>
<ColumnDefinition x:Name="C2" Width="1*"/>
<ColumnDefinition x:Name="C3" Width="1*"/>
<ColumnDefinition x:Name="C4" Width="1*"/>
<ColumnDefinition x:Name="GutterRight" Width="0"/>
</Grid.ColumnDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ErrorVisualStates">
<VisualState x:Name="NoErrorLayout"/>
<VisualState x:Name="ErrorLayout">
<VisualState.Setters>
<Setter Target="percentButton.IsEnabled" Value="False"/>
<Setter Target="squareRootButton.IsEnabled" Value="False"/>
<Setter Target="xpower2Button.IsEnabled" Value="False"/>
<Setter Target="xpower3Button.IsEnabled" Value="False"/>
<Setter Target="invertButton.IsEnabled" Value="False"/>
<Setter Target="divideButton.IsEnabled" Value="False"/>
<Setter Target="multiplyButton.IsEnabled" Value="False"/>
<Setter Target="minusButton.IsEnabled" Value="False"/>
<Setter Target="plusButton.IsEnabled" Value="False"/>
<Setter Target="negateButton.IsEnabled" Value="False"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup>
<VisualState x:Name="Portrait768x1366">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="1366" MinWindowWidth="768"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="percentButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="squareRootButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="xpower2Button.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="xpower3Button.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="invertButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="negateButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="clearEntryButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="clearButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="backSpaceButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="divideButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="multiplyButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="minusButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="plusButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="equalButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="NumberPad.ButtonStyle" Value="{StaticResource NumericButtonStyle46}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Landscape13InchLaptop">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="768" MinWindowWidth="1366"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="C0.Width" Value="1*"/>
<Setter Target="R0.Height" Value="0"/>
<Setter Target="StandardFunctions.(Grid.Row)" Value="1"/>
<Setter Target="StandardFunctions.(Grid.Column)" Value="1"/>
<Setter Target="StandardFunctions.(Grid.RowSpan)" Value="5"/>
<Setter Target="StandardFunctions.(Grid.ColumnSpan)" Value="1"/>
<Setter Target="FnR1.Height" Value="1*"/>
<Setter Target="FnR2.Height" Value="1*"/>
<Setter Target="FnR3.Height" Value="1*"/>
<Setter Target="FnR4.Height" Value="1*"/>
<Setter Target="FnC1.Width" Value="0"/>
<Setter Target="FnC2.Width" Value="0"/>
<Setter Target="FnC3.Width" Value="0"/>
<Setter Target="squareRootButton.(Grid.Row)" Value="1"/>
<Setter Target="squareRootButton.(Grid.Column)" Value="0"/>
<Setter Target="xpower2Button.(Grid.Row)" Value="2"/>
<Setter Target="xpower2Button.(Grid.Column)" Value="0"/>
<Setter Target="xpower3Button.Visibility" Value="Visible"/>
<Setter Target="invertButton.(Grid.Row)" Value="4"/>
<Setter Target="invertButton.(Grid.Column)" Value="0"/>
<Setter Target="negateButton.(Grid.Row)" Value="5"/>
<Setter Target="negateButton.(Grid.Column)" Value="2"/>
<Setter Target="percentButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSizeLarge}"/>
<Setter Target="squareRootButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSizeLarge}"/>
<Setter Target="xpower2Button.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSizeLarge}"/>
<Setter Target="invertButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSizeLarge}"/>
<Setter Target="negateButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSizeLarge}"/>
<Setter Target="clearEntryButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSizeLarge}"/>
<Setter Target="clearButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSizeLarge}"/>
<Setter Target="backSpaceButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSizeLarge}"/>
<Setter Target="divideButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSizeLarge}"/>
<Setter Target="multiplyButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSizeLarge}"/>
<Setter Target="minusButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSizeLarge}"/>
<Setter Target="plusButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSizeLarge}"/>
<Setter Target="equalButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSizeLarge}"/>
<Setter Target="NumberPad.ButtonStyle" Value="{StaticResource NumericButtonStyle34}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Landscape8InchTab">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="640" MinWindowWidth="1024"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="C0.Width" Value="1*"/>
<Setter Target="R0.Height" Value="0"/>
<Setter Target="StandardFunctions.(Grid.Row)" Value="1"/>
<Setter Target="StandardFunctions.(Grid.Column)" Value="1"/>
<Setter Target="StandardFunctions.(Grid.RowSpan)" Value="5"/>
<Setter Target="StandardFunctions.(Grid.ColumnSpan)" Value="1"/>
<Setter Target="FnR1.Height" Value="1*"/>
<Setter Target="FnR2.Height" Value="1*"/>
<Setter Target="FnR3.Height" Value="1*"/>
<Setter Target="FnR4.Height" Value="1*"/>
<Setter Target="FnC1.Width" Value="0"/>
<Setter Target="FnC2.Width" Value="0"/>
<Setter Target="FnC3.Width" Value="0"/>
<Setter Target="squareRootButton.(Grid.Row)" Value="1"/>
<Setter Target="squareRootButton.(Grid.Column)" Value="0"/>
<Setter Target="xpower2Button.(Grid.Row)" Value="2"/>
<Setter Target="xpower2Button.(Grid.Column)" Value="0"/>
<Setter Target="xpower3Button.Visibility" Value="Visible"/>
<Setter Target="invertButton.(Grid.Row)" Value="4"/>
<Setter Target="invertButton.(Grid.Column)" Value="0"/>
<Setter Target="negateButton.(Grid.Row)" Value="5"/>
<Setter Target="negateButton.(Grid.Column)" Value="2"/>
<Setter Target="percentButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="squareRootButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="xpower2Button.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="xpower3Button.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="invertButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="negateButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="clearEntryButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="clearButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="backSpaceButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="divideButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="multiplyButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="minusButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="plusButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="equalButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="NumberPad.ButtonStyle" Value="{StaticResource NumericButtonStyle28}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Portrait8InchTab">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="1024" MinWindowWidth="640"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="percentButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="squareRootButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="xpower2Button.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="xpower3Button.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="invertButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="negateButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="clearEntryButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="clearButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="backSpaceButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="divideButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="multiplyButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="minusButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="plusButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="equalButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="NumberPad.ButtonStyle" Value="{StaticResource NumericButtonStyle28}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Portrait6InchPhone">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="854" MinWindowWidth="480"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="percentButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSizeLarge}"/>
<Setter Target="squareRootButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSizeLarge}"/>
<Setter Target="xpower2Button.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSizeLarge}"/>
<Setter Target="invertButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSizeLarge}"/>
<Setter Target="negateButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSizeLarge}"/>
<Setter Target="clearEntryButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSizeLarge}"/>
<Setter Target="clearButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSizeLarge}"/>
<Setter Target="backSpaceButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSizeLarge}"/>
<Setter Target="divideButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSizeLarge}"/>
<Setter Target="multiplyButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSizeLarge}"/>
<Setter Target="minusButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSizeLarge}"/>
<Setter Target="plusButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSizeLarge}"/>
<Setter Target="equalButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSizeLarge}"/>
<Setter Target="NumberPad.ButtonStyle" Value="{StaticResource NumericButtonStyle34}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Portrait5InchPhone">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="640" MinWindowWidth="360"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="percentButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="squareRootButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="xpower2Button.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="invertButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="negateButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="clearEntryButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="clearButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="backSpaceButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="divideButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="multiplyButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="minusButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="plusButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="equalButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="NumberPad.ButtonStyle" Value="{StaticResource NumericButtonStyle28}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="MinSizeLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="{StaticResource AppMinWindowHeight}" MinWindowWidth="{StaticResource AppMinWindowWidth}"/>
</VisualState.StateTriggers>
</VisualState>
<VisualState x:Name="DefaultLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="0" MinWindowWidth="0"/>
</VisualState.StateTriggers>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid x:Name="StandardFunctions"
x:Uid="StandardFunctions"
Grid.Row="0"
Grid.Column="2"
Grid.ColumnSpan="4"
AutomationProperties.HeadingLevel="Level1">
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition x:Name="FnR1" Height="0"/>
<RowDefinition x:Name="FnR2" Height="0"/>
<RowDefinition x:Name="FnR3" Height="0"/>
<RowDefinition x:Name="FnR4" Height="0"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition x:Name="FnC1" Width="1*"/>
<ColumnDefinition x:Name="FnC2" Width="1*"/>
<ColumnDefinition x:Name="FnC3" Width="1*"/>
</Grid.ColumnDefinitions>
<controls:CalculatorButton x:Name="percentButton"
x:Uid="percentButton"
Grid.Column="0"
Style="{StaticResource SymbolOperatorButtonStyle}"
AutomationProperties.AutomationId="percentButton"
ButtonId="Percent"
Content="&#xE94C;"/>
<controls:CalculatorButton x:Name="squareRootButton"
x:Uid="squareRootButton"
Grid.Column="1"
Style="{StaticResource SymbolOperatorButtonStyle}"
AutomationProperties.AutomationId="squareRootButton"
ButtonId="Sqrt"
Content="&#xE94B;"/>
<controls:CalculatorButton x:Name="xpower2Button"
x:Uid="xpower2Button"
Grid.Column="2"
Style="{StaticResource SymbolOperatorButtonStyle}"
FontSize="18"
AutomationProperties.AutomationId="xpower2Button"
ButtonId="XPower2"
Content="&#xf7c8;"/>
<controls:CalculatorButton x:Name="xpower3Button"
x:Uid="xpower3Button"
Grid.Row="3"
Style="{StaticResource SymbolOperatorButtonStyle}"
FontSize="18"
AutomationProperties.AutomationId="xpower3Button"
ButtonId="Cube"
Content="&#xf7cb;"
Visibility="Collapsed"/>
<controls:CalculatorButton x:Name="invertButton"
x:Uid="invertButton"
Grid.Column="3"
Style="{StaticResource SymbolOperatorButtonStyle}"
FontSize="18"
AutomationProperties.AutomationId="invertButton"
ButtonId="Invert"
Content="&#xf7c9;"/>
</Grid>
<Grid x:Name="StandardOperators"
x:Uid="StandardOperators"
Grid.Row="1"
Grid.RowSpan="5"
Grid.Column="5"
AutomationProperties.HeadingLevel="Level1">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<controls:CalculatorButton x:Name="divideButton"
x:Uid="divideButton"
Grid.Row="0"
Style="{StaticResource AccentCalcButtonStyle}"
AutomationProperties.AutomationId="divideButton"
ButtonId="Divide"
Content="&#xE94A;"/>
<controls:CalculatorButton x:Name="multiplyButton"
x:Uid="multiplyButton"
Grid.Row="1"
Style="{StaticResource AccentCalcButtonStyle}"
AutomationProperties.AutomationId="multiplyButton"
ButtonId="Multiply"
Content="&#xE947;"/>
<controls:CalculatorButton x:Name="minusButton"
x:Uid="minusButton"
Grid.Row="2"
Style="{StaticResource AccentCalcButtonStyle}"
AutomationProperties.AutomationId="minusButton"
ButtonId="Subtract"
Content="&#xE949;"/>
<controls:CalculatorButton x:Name="plusButton"
x:Uid="plusButton"
Grid.Row="3"
Style="{StaticResource AccentCalcButtonStyle}"
AutomationProperties.AutomationId="plusButton"
ButtonId="Add"
Content="&#xE948;"/>
<controls:CalculatorButton x:Name="equalButton"
x:Uid="equalButton"
Grid.Row="4"
Style="{StaticResource AccentCalcButtonStyle}"
AutomationProperties.AutomationId="equalButton"
ButtonId="Equals"
Content="&#xE94E;"/>
</Grid>
<Grid x:Name="DisplayControls"
x:Uid="DisplayControls"
Grid.Row="1"
Grid.Column="2"
Grid.ColumnSpan="3"
AutomationProperties.HeadingLevel="Level1">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<controls:CalculatorButton x:Name="clearEntryButton"
x:Uid="clearEntryButton"
Grid.Column="0"
Style="{StaticResource OperatorButtonStyle}"
FontSize="16"
AutomationProperties.AutomationId="clearEntryButton"
ButtonId="ClearEntry"
Content="CE"/>
<controls:CalculatorButton x:Name="clearButton"
x:Uid="clearButton"
Grid.Column="1"
Style="{StaticResource OperatorButtonStyle}"
FontSize="16"
AutomationProperties.AutomationId="clearButton"
ButtonId="Clear"
Content="C"/>
<controls:CalculatorButton x:Name="backSpaceButton"
x:Uid="backSpaceButton"
Grid.Column="2"
Style="{StaticResource SymbolOperatorButtonStyle}"
FontSize="16"
AutomationProperties.AutomationId="backSpaceButton"
ButtonId="Backspace"
Content="&#xE94F;"/>
</Grid>
<local:NumberPad x:Name="NumberPad"
x:Uid="NumberPad"
Grid.Row="2"
Grid.RowSpan="4"
Grid.Column="2"
Grid.ColumnSpan="3"
AutomationProperties.HeadingLevel="Level1"
ButtonStyle="{StaticResource NumericButtonStyle24}"/>
<controls:CalculatorButton x:Name="negateButton"
x:Uid="negateButton"
Grid.Row="5"
Grid.Column="2"
Style="{StaticResource SymbolOperatorButtonStyle}"
AutomationProperties.AutomationId="negateButton"
ButtonId="Negate"
Content="&#xE94D;"/>
</Grid>
</UserControl>

View File

@@ -0,0 +1,46 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//
// CalculatorStandardOperators.xaml.cpp
// Implementation of the CalculatorStandardOperators class
//
#include "pch.h"
#include "CalculatorStandardOperators.xaml.h"
using namespace CalculatorApp;
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236
CalculatorStandardOperators::CalculatorStandardOperators() :
m_isErrorVisualState(false)
{
InitializeComponent();
}
bool CalculatorStandardOperators::IsErrorVisualState::get() {
return m_isErrorVisualState;
}
void CalculatorStandardOperators::IsErrorVisualState::set(bool value)
{
if (m_isErrorVisualState != value)
{
m_isErrorVisualState = value;
String^ newState = m_isErrorVisualState ? L"ErrorLayout" : L"NoErrorLayout";
VisualStateManager::GoToState(this, newState, false);
NumberPad->IsErrorVisualState = m_isErrorVisualState;
}
}

View File

@@ -0,0 +1,33 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//
// CalculatorStandardOperators.xaml.h
// Declaration of the CalculatorStandardOperators class
//
#pragma once
#include "Views\CalculatorStandardOperators.g.h"
#include "Views\NumberPad.xaml.h"
namespace CalculatorApp
{
[Windows::Foundation::Metadata::WebHostHidden]
public ref class CalculatorStandardOperators sealed
{
public:
CalculatorStandardOperators();
DEPENDENCY_PROPERTY_OWNER(CalculatorStandardOperators);
property bool IsErrorVisualState
{
bool get();
void set(bool value);
}
private:
bool m_isErrorVisualState;
};
}

View File

@@ -0,0 +1,606 @@
<UserControl x:Class="CalculatorApp.DateCalculator"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CalculatorApp.Controls"
xmlns:converters="using:CalculatorApp.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:CalculatorApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="300"
d:DesignWidth="400"
Loaded="OnLoaded"
mc:Ignorable="d">
<UserControl.Resources>
<converters:BooleanNegationConverter x:Key="BooleanNegationConverter"/>
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<converters:BooleanToVisibilityNegationConverter x:Key="BooleanToVisibilityNegationConverter"/>
<DataTemplate x:Key="ComboBoxItemContentTemplate">
<TextBlock Text="{Binding}" TextWrapping="WrapWholeWords"/>
</DataTemplate>
<Style x:Key="DateCalculation_ComboStyle" TargetType="ComboBox">
<Setter Property="Padding" Value="0,0,0,0"/>
<Setter Property="MinHeight" Value="20"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="Background" Value="{ThemeResource SystemControlBackgroundTransparentBrush}"/>
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumLowBrush}"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="TabNavigation" Value="Once"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled"/>
<Setter Property="ScrollViewer.VerticalScrollMode" Value="Auto"/>
<Setter Property="ScrollViewer.IsVerticalRailEnabled" Value="True"/>
<Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False"/>
<Setter Property="ScrollViewer.BringIntoViewOnFocusChange" Value="True"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="UseSystemFocusVisuals" Value="True"/>
<Setter Property="FocusVisualMargin" Value="-5,0,0,0"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<CarouselPanel/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="BackgroundElement.Background" Value="{ThemeResource SystemControlHighlightTransparentBrush}"/>
<Setter Target="SelectedContentPresenter.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseMediumHighBrush}"/>
<Setter Target="DropDownGlyph.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseMediumHighBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Target="BackgroundElement.Background" Value="{ThemeResource SystemControlHighlightTransparentBrush}"/>
<Setter Target="SelectedContentPresenter.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseMediumBrush}"/>
<Setter Target="DropDownGlyph.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseMediumBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
<VisualStateGroup x:Name="DropDownStates">
<VisualState x:Name="Opened">
<Storyboard>
<SplitOpenThemeAnimation ClosedTargetName="SelectedContentPresenter"
OffsetFromCenter="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.DropDownOffset}"
OpenedLength="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.DropDownOpenedHeight}"
OpenedTargetName="PopupBorder"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Closed">
<Storyboard>
<SplitCloseThemeAnimation ClosedTargetName="SelectedContentPresenter"
OffsetFromCenter="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.DropDownOffset}"
OpenedLength="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.DropDownOpenedHeight}"
OpenedTargetName="PopupBorder"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter" Opacity="0"/>
<Popup x:Name="Popup">
<Border x:Name="PopupBorder"
Margin="0,-1,0,-1"
HorizontalAlignment="Stretch"
Background="{ThemeResource SystemControlBackgroundChromeMediumLowBrush}"
BorderBrush="{ThemeResource SystemControlForegroundChromeHighBrush}"
BorderThickness="{ThemeResource ComboBoxDropdownBorderThickness}">
<ScrollViewer x:Name="ScrollViewer"
MinWidth="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.DropDownContentMinWidth}"
Foreground="{ThemeResource SystemControlForegroundBaseHighBrush}"
AutomationProperties.AccessibilityView="Raw"
BringIntoViewOnFocusChange="{TemplateBinding ScrollViewer.BringIntoViewOnFocusChange}"
HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}"
IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}"
IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}"
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
VerticalSnapPointsAlignment="Near"
VerticalSnapPointsType="OptionalSingle"
ZoomMode="Disabled">
<ItemsPresenter/>
</ScrollViewer>
</Border>
</Popup>
<Border x:Name="BackgroundElement"
Grid.ColumnSpan="2"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"/>
<TextBlock x:Name="SelectedContentPresenter"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Style="{ThemeResource BodyTextBlockStyle}"
FontWeight="SemiBold"
AutomationProperties.AccessibilityView="Raw"
FlowDirection="{TemplateBinding FlowDirection}"
Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=SelectedValue.Content}"
TextWrapping="WrapWholeWords"/>
<TextBlock x:Name="DropDownGlyph"
Grid.Column="1"
Margin="8,3,12,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Foreground="{ThemeResource SystemControlForegroundBaseHighBrush}"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="12"
AutomationProperties.AccessibilityView="Raw"
IsHitTestVisible="False"
Text="&#xE0E5;"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="DateCalculation_CalendarPickerStyle" TargetType="CalendarDatePicker">
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="Background" Value="{ThemeResource SystemControlBackgroundTransparentBrush}"/>
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumLowBrush}"/>
<Setter Property="BorderThickness" Value="{ThemeResource CalendarDatePickerBorderThemeThickness}"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="UseSystemFocusVisuals" Value="True"/>
<Setter Property="FocusVisualMargin" Value="-5,0,0,0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CalendarDatePicker">
<Grid x:Name="Root">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="32"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="32"/>
</Grid.RowDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Target="DateText.Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumHighBrush}"/>
<Setter Target="CalendarGlyph.Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="BorderElement.Background" Value="{ThemeResource SystemControlHighlightTransparentBrush}"/>
<Setter Target="DateText.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseMediumHighBrush}"/>
<Setter Target="CalendarGlyph.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseMediumHighBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Target="BorderElement.Background" Value="{ThemeResource SystemControlHighlightTransparentBrush}"/>
<Setter Target="DateText.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseMediumBrush}"/>
<Setter Target="CalendarGlyph.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseMediumBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<FlyoutBase.AttachedFlyout>
<Flyout Placement="Full">
<Flyout.FlyoutPresenterStyle>
<Style TargetType="FlyoutPresenter">
<Setter Property="MaxHeight" Value="9000"/>
<Setter Property="MaxWidth" Value="9000"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="FlyoutPresenter">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="128"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="LeftGutter" Width="0"/>
<ColumnDefinition x:Name="C0" Width="*"/>
<ColumnDefinition x:Name="RightGutter" Width="0"/>
</Grid.ColumnDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="LeftAlignedLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="360"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="LeftGutter.Width" Value="12"/>
<Setter Target="RightGutter.Width" Value="*"/>
<Setter Target="C0.Width" Value="336"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="DefaultLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0"/>
</VisualState.StateTriggers>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter Grid.Row="1"
Grid.Column="1"
Margin="0,0,0,0"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
Background="{ThemeResource SystemControlBackgroundChromeMediumLowBrush}"
BorderBrush="{ThemeResource SystemControlForegroundChromeHighBrush}"
BorderThickness="{ThemeResource ComboBoxDropdownBorderThickness}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTransitions="{TemplateBinding ContentTransitions}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Flyout.FlyoutPresenterStyle>
<CalendarView x:Name="CalendarView"
Style="{TemplateBinding CalendarViewStyle}"
CalendarIdentifier="{TemplateBinding CalendarIdentifier}"
DayOfWeekFormat="{TemplateBinding DayOfWeekFormat}"
DisplayMode="{TemplateBinding DisplayMode}"
FirstDayOfWeek="{TemplateBinding FirstDayOfWeek}"
IsGroupLabelVisible="{TemplateBinding IsGroupLabelVisible}"
IsOutOfScopeEnabled="{TemplateBinding IsOutOfScopeEnabled}"
IsTodayHighlighted="{TemplateBinding IsTodayHighlighted}"
MaxDate="{TemplateBinding MaxDate}"
MinDate="{TemplateBinding MinDate}"/>
</Flyout>
</FlyoutBase.AttachedFlyout>
<ContentPresenter x:Name="HeaderContentPresenter"
Margin="{ThemeResource ComboBoxHeaderThemeMargin}"
x:DeferLoadStrategy="Lazy"
Content="{TemplateBinding Header}"
ContentTemplate="{TemplateBinding HeaderTemplate}"
Visibility="Collapsed"/>
<Border x:Name="BorderElement"
Grid.Row="1"
Grid.ColumnSpan="2"
Background="{TemplateBinding Background}"
BorderThickness="0"/>
<TextBlock x:Name="DateText"
Grid.Row="1"
Padding="0,0,0,2"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Style="{ThemeResource BaseTextBlockStyle}"
Foreground="{ThemeResource SystemControlForegroundBaseMediumBrush}"
Text="{TemplateBinding PlaceholderText}"/>
<FontIcon x:Name="CalendarGlyph"
Grid.Row="1"
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{ThemeResource SystemControlForegroundBaseHighBrush}"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="16"
Glyph="&#xE787;"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="DateCalculation_CalendarViewStyle" TargetType="CalendarView">
<Setter Property="FocusBorderBrush" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="SelectedHoverBorderBrush" Value="{ThemeResource SystemControlHighlightListAccentMediumBrush}"/>
<Setter Property="SelectedPressedBorderBrush" Value="{ThemeResource SystemControlHighlightListAccentHighBrush}"/>
<Setter Property="SelectedBorderBrush" Value="{ThemeResource SystemControlHighlightAccentBrush}"/>
<Setter Property="HoverBorderBrush" Value="{ThemeResource SystemControlHighlightBaseMediumLowBrush}"/>
<Setter Property="PressedBorderBrush" Value="{ThemeResource SystemControlHighlightBaseMediumBrush}"/>
<Setter Property="TodayForeground" Value="{ThemeResource SystemControlHighlightAltChromeWhiteBrush}"/>
<Setter Property="BlackoutForeground" Value="{ThemeResource SystemControlDisabledBaseMediumLowBrush}"/>
<Setter Property="SelectedForeground" Value="{ThemeResource SystemControlHighlightBaseHighBrush}"/>
<Setter Property="PressedForeground" Value="{ThemeResource SystemControlHighlightBaseHighBrush}"/>
<Setter Property="OutOfScopeForeground" Value="{ThemeResource SystemControlForegroundBaseMediumLowBrush}"/>
<Setter Property="CalendarItemForeground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="OutOfScopeBackground" Value="Transparent"/>
<Setter Property="CalendarItemBackground" Value="Transparent"/>
<Setter Property="CalendarItemBorderBrush" Value="Transparent"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlHyperlinkBaseMediumHighBrush}"/>
<Setter Property="Background" Value="{ThemeResource SystemControlBackgroundChromeMediumLowBrush}"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="CalendarItemBorderThickness" Value="2"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="DayItemFontSize" Value="18"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Margin" Value="0,12,0,12"/>
<Setter Property="IsTabStop" Value="False"/>
</Style>
<MenuFlyout x:Key="ResultsContextMenu" x:Name="ResultsContextMenu">
<MenuFlyoutItem x:Name="CopyMenuItem"
x:Uid="CopyMenuItem"
Click="OnCopyMenuItemClicked"
Icon="Copy"/>
</MenuFlyout>
</UserControl.Resources>
<Grid x:Name="DateCalculatorGrid"
Margin="12,0,12,0"
AutomationProperties.LandmarkType="Main">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="C0" Width="*"/>
<ColumnDefinition x:Name="C1" Width="0"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*"
MinHeight="{StaticResource HamburgerHeight}"
MaxHeight="52"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="8*"/>
</Grid.RowDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="LeftAlignedLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="480"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="C0.Width" Value="456"/>
<Setter Target="C1.Width" Value="*"/>
<Setter Target="DateDiffAllUnitsResultLabel.FontSize" Value="24"/>
<Setter Target="DateResultLabel.FontSize" Value="24"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="DefaultLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="DateDiffAllUnitsResultLabel.FontSize" Value="20"/>
<Setter Target="DateResultLabel.FontSize" Value="20"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<!-- ComboBox for Date Calculation options -->
<ComboBox x:Name="DateCalculationOption"
x:Uid="DateCalculationOption"
Grid.Row="1"
Style="{ThemeResource DateCalculation_ComboStyle}"
SelectedIndex="0">
<ComboBoxItem x:Uid="Date_DifferenceOption"
MinWidth="276"
ContentTemplate="{StaticResource ComboBoxItemContentTemplate}"
IsSelected="{Binding IsDateDiffMode, Mode=TwoWay}"/>
<ComboBoxItem x:Uid="Date_AddSubtractOption"
MinWidth="276"
ContentTemplate="{StaticResource ComboBoxItemContentTemplate}"
IsSelected="{Binding IsDateDiffMode, Converter={StaticResource BooleanNegationConverter}, Mode=TwoWay}"/>
</ComboBox>
<!-- Grid to Calculate Difference between Two Dates -->
<Grid x:Name="DateDiffGrid"
Grid.Row="2"
Visibility="{Binding IsDateDiffMode, Converter={StaticResource BooleanToVisibilityConverter}}">
<Grid.RowDefinitions>
<RowDefinition Height="1*" MaxHeight="17"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto" MinHeight="32"/>
<RowDefinition Height="1*" MaxHeight="24"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto" MinHeight="32"/>
<RowDefinition Height="1*" MaxHeight="24"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="1*" MaxHeight="8"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- From Date -->
<TextBlock x:Name="Date_FromLabel"
x:Uid="Date_FromLabel"
Grid.Row="1"
Margin="0,0,0,2"
Foreground="{ThemeResource SystemControlPageTextBaseHighBrush}"
TextWrapping="Wrap"/>
<CalendarDatePicker x:Name="DateDiff_FromDate"
Grid.Row="2"
Style="{StaticResource DateCalculation_CalendarPickerStyle}"
AutomationProperties.LabeledBy="{x:Bind Date_FromLabel}"
CalendarViewStyle="{StaticResource DateCalculation_CalendarViewStyle}"
Closed="CalendarFlyoutClosed"
DateChanged="FromDate_DateChanged"/>
<!-- To Date -->
<TextBlock x:Name="Date_ToLabel"
x:Uid="Date_ToLabel"
Grid.Row="4"
Margin="0,0,0,2"
Foreground="{ThemeResource SystemControlPageTextBaseHighBrush}"
TextWrapping="Wrap"/>
<CalendarDatePicker x:Name="DateDiff_ToDate"
Grid.Row="5"
Margin="0,0,0,0"
Style="{StaticResource DateCalculation_CalendarPickerStyle}"
AutomationProperties.LabeledBy="{x:Bind Date_ToLabel}"
CalendarViewStyle="{StaticResource DateCalculation_CalendarViewStyle}"
Closed="CalendarFlyoutClosed"
DateChanged="ToDate_DateChanged"/>
<!-- Difference Result -->
<TextBlock x:Uid="Date_DifferenceLabel"
Grid.Row="7"
Margin="0,0,0,0"
Foreground="{ThemeResource SystemControlPageTextBaseHighBrush}"/>
<TextBlock x:Name="DateDiffAllUnitsResultLabel"
Grid.Row="8"
Style="{ThemeResource SubtitleTextBlockStyle}"
FontWeight="SemiBold"
AutomationProperties.LiveSetting="Polite"
AutomationProperties.Name="{Binding StrDateDiffResultAutomationName}"
ContextFlyout="{StaticResource ResultsContextMenu}"
Text="{Binding StrDateDiffResult}"/>
<TextBlock Grid.Row="10"
Style="{ThemeResource BaseTextBlockStyle}"
Foreground="{ThemeResource SystemControlPageTextBaseMediumBrush}"
ContextFlyout="{StaticResource ResultsContextMenu}"
Text="{Binding StrDateDiffResultInDays, Mode=OneWay}"
Visibility="{Binding IsDiffInDays, Converter={StaticResource BooleanToVisibilityNegationConverter}}"/>
</Grid>
<!-- Grid for Add/Subtract Date -->
<Grid x:Name="AddSubtractDateGrid"
Grid.Row="2"
x:DeferLoadStrategy="Lazy"
Loaded="AddSubtractDateGrid_Loaded"
Visibility="{Binding IsDateDiffMode, Converter={StaticResource BooleanToVisibilityNegationConverter}}">
<Grid.RowDefinitions>
<RowDefinition Height="1*" MaxHeight="17"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto" MinHeight="32"/>
<RowDefinition Height="1*" MaxHeight="23"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="1*" MaxHeight="29"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="1*" MaxHeight="35"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- From Date -->
<TextBlock x:Name="AddSubtract_Date_FromLabel"
x:Uid="Date_FromLabel"
Grid.Row="1"
Margin="0,0,0,2"
Style="{ThemeResource BodyTextBlockStyle}"
Foreground="{ThemeResource SystemControlPageTextBaseMediumBrush}"
TextWrapping="Wrap"/>
<CalendarDatePicker x:Name="AddSubtract_FromDate"
Grid.Row="2"
Margin="0,0,0,0"
Style="{StaticResource DateCalculation_CalendarPickerStyle}"
AutomationProperties.LabeledBy="{x:Bind AddSubtract_Date_FromLabel}"
CalendarViewStyle="{StaticResource DateCalculation_CalendarViewStyle}"
Closed="CalendarFlyoutClosed"
DateChanged="AddSubtract_DateChanged"/>
<Grid Grid.Row="4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<RadioButton x:Name="AddOption"
x:Uid="AddOption"
MinWidth="80"
MaxWidth="160"
VerticalAlignment="Top"
IsChecked="{Binding IsAddMode, Mode=TwoWay}"/>
<RadioButton x:Name="SubtractOption"
x:Uid="SubtractOption"
Grid.Column="1"
MinWidth="80"
MaxWidth="160"
Margin="20,0,0,0"
VerticalAlignment="Top"
IsChecked="{Binding IsAddMode, Converter={StaticResource BooleanNegationConverter}, Mode=TwoWay}"/>
</Grid>
<!-- Date Offset to be Added/Subtracted -->
<Grid x:Name="DateOffsetGrid" Grid.Row="6">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="YearsLabel"
x:Uid="YearsLabel"
Margin="0,0,0,6"
Foreground="{ThemeResource SystemControlPageTextBaseMediumBrush}"
TextWrapping="Wrap"/>
<ComboBox x:Name="YearsValue"
Grid.Row="1"
MinWidth="84"
AutomationProperties.LabeledBy="{Binding ElementName=YearsLabel}"
DropDownClosed="OffsetDropDownClosed"
ItemsSource="{Binding OffsetValues, Mode=OneTime}"
SelectedIndex="{Binding YearsOffset, Mode=TwoWay}"
SelectionChanged="OffsetValue_Changed"/>
<TextBlock x:Name="MonthsLabel"
x:Uid="MonthsLabel"
Grid.Column="1"
Margin="12,0,12,6"
Foreground="{ThemeResource SystemControlPageTextBaseMediumBrush}"
TextWrapping="Wrap"/>
<ComboBox x:Name="MonthsValue"
Grid.Row="1"
Grid.Column="1"
MinWidth="84"
Margin="12,0,12,0"
AutomationProperties.LabeledBy="{Binding ElementName=MonthsLabel}"
DropDownClosed="OffsetDropDownClosed"
ItemsSource="{Binding OffsetValues, Mode=OneTime}"
SelectedIndex="{Binding MonthsOffset, Mode=TwoWay}"
SelectionChanged="OffsetValue_Changed"/>
<TextBlock x:Name="DaysLabel"
x:Uid="DaysLabel"
Grid.Column="2"
Margin="0,0,0,6"
Foreground="{ThemeResource SystemControlPageTextBaseMediumBrush}"
TextWrapping="Wrap"/>
<ComboBox x:Name="DaysValue"
Grid.Row="1"
Grid.Column="2"
MinWidth="84"
AutomationProperties.LabeledBy="{Binding ElementName=DaysLabel}"
DropDownClosed="OffsetDropDownClosed"
ItemsSource="{Binding OffsetValues, Mode=OneTime}"
SelectedIndex="{Binding DaysOffset, Mode=TwoWay}"
SelectionChanged="OffsetValue_Changed"/>
</Grid>
<!-- Resulting Date -->
<TextBlock x:Uid="DateLabel"
Grid.Row="8"
Foreground="{ThemeResource SystemControlPageTextBaseMediumBrush}"/>
<TextBlock x:Name="DateResultLabel"
Grid.Row="9"
Style="{ThemeResource SubtitleTextBlockStyle}"
FontWeight="SemiBold"
AutomationProperties.LiveSetting="Polite"
AutomationProperties.Name="{Binding StrDateResultAutomationName}"
ContextFlyout="{StaticResource ResultsContextMenu}"
Text="{Binding StrDateResult}"/>
</Grid>
</Grid>
</UserControl>

View File

@@ -0,0 +1,225 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//
// DateCalculator.xaml.cpp
// Implementation of the DateCalculator class
//
#include "pch.h"
#include "DateCalculator.xaml.h"
#include "CalcViewModel\Common\CopyPasteManager.h"
#include "CalcViewModel\Common\LocalizationSettings.h"
#include "CalcViewModel\DateCalculatorViewModel.h"
using namespace CalculatorApp;
using namespace CalculatorApp::Common;
using namespace CalculatorApp::ViewModel;
using namespace Platform;
using namespace Platform::Collections;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::Globalization;
using namespace Windows::Globalization::DateTimeFormatting;
using namespace Windows::System::UserProfile;
using namespace Windows::UI::Core;
using namespace Windows::UI::ViewManagement;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Automation;
using namespace Windows::UI::Xaml::Automation::Peers;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236
DateCalculator::DateCalculator()
{
InitializeComponent();
const auto& localizationSettings = LocalizationSettings::GetInstance();
// Set Calendar Identifier
DateDiff_FromDate->CalendarIdentifier = localizationSettings.GetCalendarIdentifier();
DateDiff_ToDate->CalendarIdentifier = localizationSettings.GetCalendarIdentifier();;
// Setting the FirstDayofWeek
DateDiff_FromDate->FirstDayOfWeek = localizationSettings.GetFirstDayOfWeek();
DateDiff_ToDate->FirstDayOfWeek = localizationSettings.GetFirstDayOfWeek();
// Setting the Language explicitly is not required,
// this is a workaround for the bug in the control due to which
// the displayed date is incorrect for non Gregorian Calendar Systems
// The displayed date doesn't honor the shortdate format, on setting the Language the format is refreshed
DateDiff_FromDate->Language = localizationSettings.GetLocaleName();
DateDiff_ToDate->Language = localizationSettings.GetLocaleName();
// Set Min and Max Dates according to the Gregorian Calendar(1601 & 9999)
auto calendar = ref new Calendar();
auto today = calendar->GetDateTime();
calendar->ChangeCalendarSystem(CalendarIdentifiers::Gregorian);
calendar->Day = 1;
calendar->Month = 1;
calendar->Year = c_minYear;
auto minYear = calendar->GetDateTime(); // 1st January, 1601
DateDiff_FromDate->MinDate = minYear;
DateDiff_ToDate->MinDate = minYear;
calendar->Day = 31;
calendar->Month = 12;
calendar->Year = c_maxYear;
auto maxYear = calendar->GetDateTime(); // 31st December, 9878
DateDiff_FromDate->MaxDate = maxYear;
DateDiff_ToDate->MaxDate = maxYear;
// Set the PlaceHolderText for CalendarDatePicker
DateTimeFormatter^ dateTimeFormatter = LocalizationService::GetRegionalSettingsAwareDateTimeFormatter(
L"day month year",
localizationSettings.GetCalendarIdentifier(),
ClockIdentifiers::TwentyFourHour); // Clock Identifier is not used
DateDiff_FromDate->DateFormat = L"day month year";
DateDiff_ToDate->DateFormat = L"day month year";
auto placeholderText = dateTimeFormatter->Format(today);
DateDiff_FromDate->PlaceholderText = placeholderText;
DateDiff_ToDate->PlaceholderText = placeholderText;
CopyMenuItem->Text = AppResourceProvider::GetInstance().GetResourceString(L"copyMenuItem");
m_dateCalcOptionChangedEventToken = DateCalculationOption->SelectionChanged += ref new SelectionChangedEventHandler(this, &DateCalculator::DateCalcOption_Changed);
}
void DateCalculator::FromDate_DateChanged(_In_ CalendarDatePicker^ sender, _In_ CalendarDatePickerDateChangedEventArgs^ e)
{
if (e->NewDate != nullptr)
{
auto dateCalcViewModel = safe_cast<DateCalculatorViewModel^>(this->DataContext);
dateCalcViewModel->FromDate = e->NewDate->Value;
TraceLogger::GetInstance().LogDateDifferenceModeUsed(ApplicationView::GetApplicationViewIdForWindow(CoreWindow::GetForCurrentThread()));
}
else
{
ReselectCalendarDate(sender, e->OldDate->Value);
}
}
void DateCalculator::ToDate_DateChanged(_In_ CalendarDatePicker^ sender, _In_ CalendarDatePickerDateChangedEventArgs^ e)
{
if (e->NewDate != nullptr)
{
auto dateCalcViewModel = safe_cast<DateCalculatorViewModel^>(this->DataContext);
dateCalcViewModel->ToDate = e->NewDate->Value;
TraceLogger::GetInstance().LogDateDifferenceModeUsed(ApplicationView::GetApplicationViewIdForWindow(CoreWindow::GetForCurrentThread()));
}
else
{
ReselectCalendarDate(sender, e->OldDate->Value);
}
}
void DateCalculator::AddSubtract_DateChanged(_In_ CalendarDatePicker^ sender, _In_ CalendarDatePickerDateChangedEventArgs^ e)
{
if (e->NewDate != nullptr)
{
auto dateCalcViewModel = safe_cast<DateCalculatorViewModel^>(this->DataContext);
dateCalcViewModel->StartDate = e->NewDate->Value;
TraceLogger::GetInstance().LogDateAddSubtractModeUsed(ApplicationView::GetApplicationViewIdForWindow(CoreWindow::GetForCurrentThread()), dateCalcViewModel->IsAddMode);
}
else
{
ReselectCalendarDate(sender, e->OldDate->Value);
}
}
void CalculatorApp::DateCalculator::OffsetValue_Changed(_In_ Platform::Object^ sender, _In_ SelectionChangedEventArgs^ e)
{
auto dateCalcViewModel = safe_cast<DateCalculatorViewModel^>(this->DataContext);
TraceLogger::GetInstance().LogDateAddSubtractModeUsed(ApplicationView::GetApplicationViewIdForWindow(CoreWindow::GetForCurrentThread()), dateCalcViewModel->IsAddMode);
}
void DateCalculator::OnCopyMenuItemClicked(_In_ Object^ sender, _In_ RoutedEventArgs^ e)
{
auto calcResult = safe_cast<TextBlock^>(ResultsContextMenu->Target);
CopyPasteManager::CopyToClipboard(calcResult->Text);
}
void CalculatorApp::DateCalculator::OnLoaded(_In_ Platform::Object ^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs ^ e)
{
}
void DateCalculator::CloseCalendarFlyout()
{
if (DateDiff_FromDate->IsCalendarOpen)
{
DateDiff_FromDate->IsCalendarOpen = false;
}
if (DateDiff_ToDate->IsCalendarOpen)
{
DateDiff_ToDate->IsCalendarOpen = false;
}
if ((AddSubtract_FromDate != nullptr) && (AddSubtract_FromDate->IsCalendarOpen))
{
AddSubtract_FromDate->IsCalendarOpen = false;
}
}
void DateCalculator::SetDefaultFocus()
{
DateCalculationOption->Focus(::FocusState::Programmatic);
}
void DateCalculator::DateCalcOption_Changed(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e)
{
FindName("AddSubtractDateGrid");
DateCalculationOption->SelectionChanged -= m_dateCalcOptionChangedEventToken;
}
void CalculatorApp::DateCalculator::AddSubtractDateGrid_Loaded(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e)
{
const auto& localizationSettings = LocalizationSettings::GetInstance();
AddSubtract_FromDate->PlaceholderText = DateDiff_FromDate->PlaceholderText;
AddSubtract_FromDate->CalendarIdentifier = localizationSettings.GetCalendarIdentifier();
AddSubtract_FromDate->FirstDayOfWeek = localizationSettings.GetFirstDayOfWeek();
AddSubtract_FromDate->Language = localizationSettings.GetLocaleName();
AddSubtract_FromDate->MinDate = DateDiff_FromDate->MinDate;
AddSubtract_FromDate->MaxDate = DateDiff_FromDate->MaxDate;
AddSubtract_FromDate->DateFormat = L"day month year";
}
void DateCalculator::ReselectCalendarDate(_In_ Windows::UI::Xaml::Controls::CalendarDatePicker^ calendarDatePicker, Windows::Foundation::DateTime dateTime)
{
// Reselect the unselected Date
calendarDatePicker->Date = ref new Box<DateTime>(dateTime);
// Dismiss the Calendar flyout
calendarDatePicker->IsCalendarOpen = false;
}
void DateCalculator::OffsetDropDownClosed(_In_ Object^ sender, _In_ Object^ e)
{
RaiseLiveRegionChangedAutomationEvent(false);
}
void DateCalculator::CalendarFlyoutClosed(_In_ Object^ sender, _In_ Object^ e)
{
auto dateCalcViewModel = safe_cast<DateCalculatorViewModel^>(this->DataContext);
RaiseLiveRegionChangedAutomationEvent(dateCalcViewModel->IsDateDiffMode);
}
void DateCalculator::RaiseLiveRegionChangedAutomationEvent(_In_ bool isDateDiffMode)
{
TextBlock^ resultTextBlock = (isDateDiffMode ? DateDiffAllUnitsResultLabel : DateResultLabel);
String^ automationName = AutomationProperties::GetName(resultTextBlock);
TextBlockAutomationPeer::FromElement(resultTextBlock)->RaiseAutomationEvent(AutomationEvents::LiveRegionChanged);
}

View File

@@ -0,0 +1,48 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//
// DateCalculator.xaml.h
// Declaration of the DateCalculator class
//
#pragma once
#include "Converters\BooleanNegationConverter.h"
#include "Converters\VisibilityNegationConverter.h"
#include "Views\DateCalculator.g.h"
// We choose 2550 as the max year because CalendarDatePicker experiences clipping
// issues just after 2558. We would like 9999 but will need to wait for a platform
// fix before we use a higher max year. This platform issue is tracked by
// TODO: MSFT-9273247
const int c_maxYear = 2550;
const int c_minYear = 1601;
namespace CalculatorApp
{
[Windows::Foundation::Metadata::WebHostHidden]
public ref class DateCalculator sealed
{
public:
DateCalculator();
void CloseCalendarFlyout();
void SetDefaultFocus();
private:
void FromDate_DateChanged(_In_ Windows::UI::Xaml::Controls::CalendarDatePicker^ sender, _In_ Windows::UI::Xaml::Controls::CalendarDatePickerDateChangedEventArgs^ e);
void ToDate_DateChanged(_In_ Windows::UI::Xaml::Controls::CalendarDatePicker^ sender, _In_ Windows::UI::Xaml::Controls::CalendarDatePickerDateChangedEventArgs^ e);
void AddSubtract_DateChanged(_In_ Windows::UI::Xaml::Controls::CalendarDatePicker^ sender, _In_ Windows::UI::Xaml::Controls::CalendarDatePickerDateChangedEventArgs^ e);
void OffsetValue_Changed(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e);
void OnCopyMenuItemClicked(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
void OnLoaded(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
void DateCalcOption_Changed(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e);
void AddSubtractDateGrid_Loaded(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
void ReselectCalendarDate(_In_ Windows::UI::Xaml::Controls::CalendarDatePicker^ calendarDatePicker, Windows::Foundation::DateTime dateTime);
void OffsetDropDownClosed(_In_ Platform::Object^ sender, _In_ Platform::Object^ e);
void CalendarFlyoutClosed(_In_ Platform::Object^ sender, _In_ Platform::Object^ e);
void RaiseLiveRegionChangedAutomationEvent(_In_ bool isDateDiffMode);
Windows::Foundation::EventRegistrationToken m_dateCalcOptionChangedEventToken;
};
}

View File

@@ -0,0 +1,216 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CalculatorApp">
<Style x:Key="DelighterBaseStyle" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Segoe UI Symbol"/>
<Setter Property="FontSize" Value="20"/>
<Setter Property="IsTextScaleFactorEnabled" Value="False"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlPageTextBaseHighBrush}"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Margin" Value="0,3,8,-3"/>
</Style>
<Style x:Key="Unit_118"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Hand #1 (Area) -->
<Setter Property="Text" Value="👋"/>
<Setter Property="Margin" Value="0,3,8,-3"/>
</Style>
<Style x:Key="Unit_127"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Paper -->
<Setter Property="Text" Value="📄"/>
<Setter Property="Margin" Value="0,3,8,-3"/>
</Style>
<Style x:Key="Unit_99"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Soccer field -->
<Setter Property="Text" Value="⚽"/>
<Setter Property="Margin" Value="0,3,10,-3"/>
</Style>
<Style x:Key="Unit_128"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Castle -->
<Setter Property="Text" Value="🏰"/>
<Setter Property="Margin" Value="0,2,10,-2"/>
</Style>
<Style x:Key="Unit_100"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Floppy disk -->
<Setter Property="Text" Value="💾"/>
<Setter Property="Margin" Value="0,3,9,-3"/>
</Style>
<!-- Duplicate of Unit_97 as CD appears twice in config -->
<Style x:Key="Unit_101"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- CD -->
<Setter Property="Text" Value="💿"/>
<Setter Property="Margin" Value="0,3,9,-3"/>
</Style>
<Style x:Key="Unit_102"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- DVD -->
<Setter Property="Text" Value="📀"/>
<Setter Property="Margin" Value="0,3,10,-3"/>
</Style>
<Style x:Key="Unit_103"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Battery -->
<Setter Property="Text" Value="🔋"/>
<Setter Property="Margin" Value="0,3,10,-3"/>
</Style>
<Style x:Key="Unit_129"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Banana -->
<Setter Property="Text" Value="🍌"/>
</Style>
<Style x:Key="Unit_130"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Slice of cake -->
<Setter Property="Text" Value="🍰"/>
</Style>
<Style x:Key="Unit_105"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Paperclip -->
<Setter Property="Text" Value="📎"/>
<Setter Property="Margin" Value="0,3,6,-3"/>
</Style>
<Style x:Key="Unit_131"
BasedOn="{StaticResource Unit_118}"
TargetType="TextBlock">
<!-- Hand #2 (Length) -->
</Style>
<Style x:Key="Unit_107"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Jumbojet -->
<Setter Property="Text" Value="✈"/>
<Setter Property="Margin" Value="0,2,8,-2"/>
</Style>
<Style x:Key="Unit_108"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Lightbulb -->
<Setter Property="Text" Value="💡"/>
<Setter Property="Margin" Value="0,3,10,-3"/>
</Style>
<Style x:Key="Unit_109"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Horse -->
<Setter Property="Text" Value="🐎"/>
<Setter Property="Margin" Value="0,3,8,-2"/>
</Style>
<Style x:Key="Unit_132"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Train Engine -->
<Setter Property="Text" Value="🚂"/>
<Setter Property="Margin" Value="0,2,9,-2"/>
</Style>
<Style x:Key="Unit_121"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Turtle -->
<Setter Property="Text" Value="🐢"/>
<Setter Property="Margin" Value="0,2,9,-2"/>
</Style>
<Style x:Key="Unit_126"
BasedOn="{StaticResource Unit_109}"
TargetType="TextBlock">
<!-- Horse -->
</Style>
<Style x:Key="Unit_122"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Jet -->
<Setter Property="Text" Value="✈"/>
<Setter Property="Margin" Value="0,3,8,-3"/>
</Style>
<Style x:Key="Unit_124"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- CoffeeCup -->
<Setter Property="Text" Value="☕"/>
<Setter Property="Margin" Value="0,-1,8,1"/>
</Style>
<Style x:Key="Unit_111"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Bathtub -->
<Setter Property="Text" Value="🛀"/>
<Setter Property="Margin" Value="0,2,10,-2"/>
</Style>
<Style x:Key="Unit_125"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- SwimmingPool -->
<Setter Property="Text" Value="🏊"/>
<Setter Property="Margin" Value="0,2,8,-2"/>
</Style>
<Style x:Key="Unit_113"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Snowflake -->
<Setter Property="Text" Value="❄"/>
<Setter Property="Margin" Value="0,3,8,-3"/>
</Style>
<Style x:Key="Unit_133"
BasedOn="{StaticResource Unit_99}"
TargetType="TextBlock">
<!-- Soccer ball -->
<Setter Property="Margin" Value="0,3,8,-3"/>
</Style>
<Style x:Key="Unit_114"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Elephant -->
<Setter Property="Text" Value="🐘"/>
<Setter Property="Margin" Value="0,2,9,-2"/>
</Style>
<Style x:Key="Unit_123"
BasedOn="{StaticResource DelighterBaseStyle}"
TargetType="TextBlock">
<!-- Whale -->
<Setter Property="Text" Value="🐳"/>
<Setter Property="Margin" Value="0,1,9,-1"/>
</Style>
</ResourceDictionary>

View File

@@ -0,0 +1,176 @@
<UserControl x:Class="CalculatorApp.HistoryList"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:automation="using:CalculatorApp.Common.Automation"
xmlns:controls="using:CalculatorApp.Controls"
xmlns:converters="using:CalculatorApp.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:CalculatorApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:model="using:CalculatorApp.ViewModel"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
x:Name="HistoryList"
AutomationProperties.AutomationId="HistoryList"
FlowDirection="LeftToRight"
Loaded="HistoryList_Loaded"
Unloaded="HistoryList_Unloaded"
mc:Ignorable="d">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Default">
<Style x:Key="BodyTextBlockMediumStyle"
BasedOn="{StaticResource BodyTextBlockStyle}"
TargetType="TextBlock">
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}"/>
</Style>
</ResourceDictionary>
<ResourceDictionary x:Key="Light">
<Style x:Key="BodyTextBlockMediumStyle"
BasedOn="{StaticResource BodyTextBlockStyle}"
TargetType="TextBlock">
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}"/>
</Style>
</ResourceDictionary>
<ResourceDictionary x:Key="HighContrast">
<Style x:Key="BodyTextBlockMediumStyle"
BasedOn="{StaticResource BodyTextBlockStyle}"
TargetType="TextBlock"/>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
<converters:ItemSizeToVisibilityNegationConverter x:Key="ItemSizeToVisibilityNegationConverter"/>
<converters:ItemSizeToVisibilityConverter x:Key="ItemSizeToVisibilityConverter"/>
<automation:NarratorNotifier x:Name="NarratorNotifier" Announcement="{x:Bind Model.HistoryAnnouncement, Mode=OneWay}"/>
<muxc:SymbolIconSource x:Key="DeleteSymbol" Symbol="Delete"/>
<muxc:SwipeItems x:Key="HistorySwipeItems" Mode="Execute">
<muxc:SwipeItem x:Uid="DeleteHistorySwipeItem"
IconSource="{StaticResource DeleteSymbol}"
Invoked="OnDeleteSwipeInvoked"/>
</muxc:SwipeItems>
<MenuFlyout x:Key="HistoryContextMenu">
<MenuFlyoutItem x:Uid="DeleteHistoryMenuItem"
Click="OnDeleteMenuItemClicked"
Icon="Delete"/>
</MenuFlyout>
<DataTemplate x:Key="HistoryItemTemplate" x:DataType="model:HistoryItemViewModel">
<muxc:SwipeControl RightItems="{StaticResource HistorySwipeItems}">
<StackPanel Margin="0,6,4,6"
Background="Transparent"
ContextFlyout="{StaticResource HistoryContextMenu}">
<TextBlock x:Name="exprTextBlock"
Margin="0,0,0,4"
Style="{ThemeResource BodyTextBlockMediumStyle}"
AutomationProperties.Name="{x:Bind AccExpression}"
Text="{x:Bind Expression}"
TextAlignment="Right"
TextWrapping="Wrap"/>
<TextBlock x:Name="resultTextBlock"
Style="{ThemeResource TitleTextBlockStyle}"
FontWeight="SemiBold"
AutomationProperties.Name="{x:Bind AccResult}"
Text="{x:Bind Result}"
TextAlignment="Right"
TextWrapping="Wrap"/>
</StackPanel>
</muxc:SwipeControl>
</DataTemplate>
<Style x:Key="HistoryItemContainerStyle"
BasedOn="{StaticResource HistoryMemoryItemContainerStyle}"
TargetType="ListViewItem">
<Setter Property="Margin" Value="0,0,0,20"/>
</Style>
</ResourceDictionary>
</UserControl.Resources>
<Grid x:Name="LayoutGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="{Binding RowHeight, ElementName=HistoryList, Mode=OneWay}"/>
</Grid.RowDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="DockedLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="560"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="HistoryListRootGrid.(Grid.Row)" Value="1"/>
<Setter Target="HistoryListRootGrid.(Grid.RowSpan)" Value="2"/>
<Setter Target="HistoryListView.Padding" Value="0"/>
<Setter Target="BackgroundShade.Opacity" Value="0"/>
<Setter Target="CustomTitleBar.Height" Value="0"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="DefaultLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0"/>
</VisualState.StateTriggers>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="BackgroundShade"
Grid.Row="2"
Margin="0,-1,0,0"
Padding="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="{ThemeResource SystemControlChromeMediumLowAcrylicElementMediumBrush}"
BorderBrush="{ThemeResource SystemControlForegroundChromeHighBrush}"
BorderThickness="{ThemeResource HighContrastThicknessTop}"/>
<Grid x:Name="HistoryListRootGrid" Grid.Row="2">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock x:Name="HistoryEmpty"
x:Uid="HistoryEmpty"
Margin="12,14,24,0"
Style="{ThemeResource BaseTextBlockStyle}"
Foreground="{ThemeResource SystemControlPageTextBaseHighBrush}"
TextWrapping="Wrap"
Visibility="{Binding ItemSize, Converter={StaticResource ItemSizeToVisibilityConverter}}"/>
<ListView x:Name="HistoryListView"
MinHeight="60"
Padding="0,12,0,0"
HorizontalAlignment="Stretch"
AutomationProperties.AutomationId="HistoryListView"
IsItemClickEnabled="True"
ItemClick="ListView_ItemClick"
ItemContainerStyle="{StaticResource HistoryItemContainerStyle}"
ItemTemplate="{StaticResource HistoryItemTemplate}"
ItemsSource="{x:Bind Model.Items, Mode=OneWay}"
SelectionMode="None"
TabIndex="0"
Visibility="{x:Bind Model.ItemSize, Mode=OneWay, Converter={StaticResource ItemSizeToVisibilityNegationConverter}}">
<ListView.ItemContainerTransitions>
<TransitionCollection>
<AddDeleteThemeTransition/>
<ContentThemeTransition/>
<ReorderThemeTransition/>
</TransitionCollection>
</ListView.ItemContainerTransitions>
</ListView>
<Button x:Name="ClearHistory"
x:Uid="ClearHistory"
Grid.Row="1"
Style="{StaticResource ClearAllHistoryMemoryButtonStyle}"
AutomationProperties.AutomationId="ClearHistory"
Command="{x:Bind Model.ClearCommand, Mode=OneWay}"
Content="&#xE74D;"
Visibility="{x:Bind Model.ItemSize, Mode=OneWay, Converter={StaticResource ItemSizeToVisibilityNegationConverter}}"/>
</Grid>
<Border x:Name="CustomTitleBar"
Height="32"
HorizontalAlignment="Stretch"
Background="{ThemeResource TitleBarBackgroundTransparentBrush}"/>
</Grid>
</UserControl>

View File

@@ -0,0 +1,89 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//
// HistoryList.xaml.cpp
// Implementation of the HistoryList class
//
#include "pch.h"
#include "HistoryList.xaml.h"
#include "CalcViewModel\Common\LocalizationService.h"
using namespace CalculatorApp;
using namespace CalculatorApp::Common;
using namespace CalculatorApp::ViewModel;
using namespace Platform;
using namespace std;
using namespace Windows::ApplicationModel::Core;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
using namespace Windows::UI::ViewManagement;
namespace MUXC = Microsoft::UI::Xaml::Controls;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=390556
DEPENDENCY_PROPERTY_INITIALIZATION(HistoryList, RowHeight);
HistoryList::HistoryList()
{
InitializeComponent();
HistoryEmpty->FlowDirection = LocalizationService::GetInstance()->GetFlowDirection();
}
void HistoryList::HistoryList_Loaded(Object^ sender, RoutedEventArgs^ e)
{
// When transitioning between docked and undocked view states, the history list is
// unloaded and then loaded, so we attempt to create the titlebarhelper every time
// we are loaded, letting the util function check if we are docked or not.
m_titleBarHelper = TitleBarHelper::CreateTitleBarHelperIfNotDocked(CustomTitleBar);
}
void HistoryList::HistoryList_Unloaded(Object^ sender, RoutedEventArgs^ e)
{
m_titleBarHelper = nullptr;
}
void HistoryList::ListView_ItemClick(_In_ Object^ sender, _In_ ItemClickEventArgs^ e)
{
HistoryViewModel^ historyVM = static_cast<HistoryViewModel^>(this->DataContext);
HistoryItemViewModel^ clickedItem = safe_cast<HistoryItemViewModel^>(e->ClickedItem);
// When the user clears the history list in the overlay view and presses enter, the clickedItem is nullptr
if (clickedItem != nullptr)
{
historyVM->ShowItem(clickedItem);
}
}
void HistoryList::OnDeleteMenuItemClicked(_In_ Object^ sender, _In_ RoutedEventArgs^ e)
{
auto clickedItem = safe_cast<HistoryItemViewModel^>(safe_cast<FrameworkElement^>(sender)->DataContext);
Model->DeleteItem(clickedItem);
}
void HistoryList::OnDeleteSwipeInvoked(_In_ MUXC::SwipeItem^ sender, _In_ MUXC::SwipeItemInvokedEventArgs^ e)
{
auto swipedItem = safe_cast<HistoryItemViewModel^>(e->SwipeControl->DataContext);
Model->DeleteItem(swipedItem);
}
void HistoryList::ScrollToBottom()
{
auto historyItems = this->HistoryListView->Items;
if (historyItems->Size > 0)
{
this->HistoryListView->ScrollIntoView(historyItems->GetAt(historyItems->Size - 1));
}
}

View File

@@ -0,0 +1,47 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//
// HistoryList.xaml.h
// Declaration of the HistoryList class
//
#pragma once
#include "Views\HistoryList.g.h"
#include "Common\TitleBarHelper.h"
#include "Converters\ItemSizeToVisibilityConverter.h"
#include "Converters\VisibilityNegationConverter.h"
#include "CalcViewModel\HistoryViewModel.h"
namespace CalculatorApp
{
[Windows::Foundation::Metadata::WebHostHidden]
public ref class HistoryList sealed
{
public:
HistoryList();
property CalculatorApp::ViewModel::HistoryViewModel^ Model
{
CalculatorApp::ViewModel::HistoryViewModel^ get() {
return static_cast<CalculatorApp::ViewModel::HistoryViewModel^>(this->DataContext);
}
}
void ScrollToBottom();
DEPENDENCY_PROPERTY_OWNER(HistoryList);
DEPENDENCY_PROPERTY(Windows::UI::Xaml::GridLength, RowHeight);
private:
Windows::Foundation::Rect m_visibleBounds;
Windows::Foundation::Rect m_coreBounds;
void ListView_ItemClick(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::Controls::ItemClickEventArgs^ e);
void OnDeleteMenuItemClicked(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
void OnDeleteSwipeInvoked(_In_ Microsoft::UI::Xaml::Controls::SwipeItem^ sender, _In_ Microsoft::UI::Xaml::Controls::SwipeItemInvokedEventArgs^ e);
void HistoryList_Loaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void HistoryList_Unloaded(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
std::unique_ptr<CalculatorApp::Common::TitleBarHelper> m_titleBarHelper;
};
}

View File

@@ -0,0 +1,163 @@
<common:LayoutAwarePage x:Class="CalculatorApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:automation="using:CalculatorApp.Common.Automation"
xmlns:common="using:CalculatorApp.Common"
xmlns:controls="using:CalculatorApp.Controls"
xmlns:converters="using:CalculatorApp.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:CalculatorApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
xmlns:vm="using:CalculatorApp.ViewModel"
x:Name="pageRoot"
Background="{ThemeResource AppChromeAcrylicHostBackdropMediumLowBrush}"
Loaded="OnPageLoaded"
Unloaded="OnPageUnLoaded"
mc:Ignorable="d">
<Page.Resources>
<automation:NarratorNotifier x:Name="NarratorNotifier"/>
<Style x:Name="CalculatorBaseStyle" TargetType="local:Calculator">
<Setter Property="Margin" Value="0,0,0,0"/>
</Style>
<Style x:Name="UnitConverterBaseStyle" TargetType="local:UnitConverter">
<Setter Property="Visibility" Value="Collapsed"/>
<Setter Property="IsEnabled" Value="False"/>
<Setter Property="Margin" Value="0,0,0,0"/>
</Style>
<Style x:Key="AboutFlyoutPresenterStyle" TargetType="FlyoutPresenter">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="AutomationProperties.AccessibilityView" Value="Raw"/>
</Style>
<Style x:Key="NavViewItemStyle" TargetType="muxc:NavigationViewItem">
<Setter Property="KeyTipPlacementMode" Value="Right"/>
</Style>
</Page.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<!--
This row is padding for the SystemFocusVisuals,
otherwise the focus rectangles render under the title bar controls.
-->
<RowDefinition x:Name="FocusVisualMargin" Height="3"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="Mode">
<VisualState x:Name="ConverterWide">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="{StaticResource AppMinWindowHeight}" MinWindowWidth="640"/>
</VisualState.StateTriggers>
</VisualState>
<VisualState x:Name="DockVisible">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="{StaticResource AppMinWindowHeight}" MinWindowWidth="560"/>
</VisualState.StateTriggers>
</VisualState>
<VisualState x:Name="MinSizeLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="{StaticResource AppMinWindowHeight}" MinWindowWidth="{StaticResource AppMinWindowWidth}"/>
</VisualState.StateTriggers>
</VisualState>
<VisualState x:Name="DefaultLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="0" MinWindowWidth="0"/>
</VisualState.StateTriggers>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<StackPanel Visibility="Collapsed">
<!--
These buttons are only here to serve as the target for copy/paste commands
they are not to be shown, only to have the command and shortcut assigned to them.
-->
<Button x:Name="copyButton"
x:Uid="copyButton"
Command="{x:Bind Model.CopyCommand}"/>
<Button x:Name="pasteButton"
x:Uid="pasteButton"
Command="{x:Bind Model.PasteCommand}"/>
<Button x:Name="copyButtonAlternate"
x:Uid="copyButtonAlternate"
Command="{x:Bind Model.CopyCommand}"/>
<Button x:Name="pasteButtonAlternate"
x:Uid="pasteButtonAlternate"
Command="{x:Bind Model.PasteCommand}"/>
</StackPanel>
<!-- Title Bar -->
<local:TitleBar x:Name="CustomTitleBar"
Grid.Row="0"
Visibility="Collapsed"/>
<muxc:NavigationView x:Name="NavView"
x:Uid="NavView"
Grid.Row="2"
CompactModeThresholdWidth="Infinity"
DataContext="{x:Bind Model}"
ExpandedModeThresholdWidth="Infinity"
IsBackButtonVisible="Collapsed"
IsSettingsVisible="False"
Loaded="OnNavLoaded"
MenuItemsSource="{x:Bind CreateUIElementsForCategories(Model.Categories), Mode=OneWay}"
OpenPaneLength="{StaticResource SplitViewOpenPaneLength}"
PaneClosed="OnNavPaneClosed"
PaneOpened="OnNavPaneOpened"
PaneOpening="OnNavPaneOpening"
SelectionChanged="OnNavSelectionChanged"
TabIndex="1"
UseSystemFocusVisuals="True">
<muxc:NavigationView.PaneFooter>
<StackPanel HorizontalAlignment="Stretch" Orientation="Vertical">
<muxc:NavigationViewList x:Name="NavFooter"
Width="{x:Bind NavView.OpenPaneLength, Mode=Oneway}"
x:Load="False"
IsItemClickEnabled="True"
ItemClick="OnAboutButtonClick">
<muxc:NavigationViewList.Items>
<muxc:NavigationViewItem x:Name="AboutButton"
x:Uid="AboutButton"
Style="{StaticResource NavViewItemStyle}">
<muxc:NavigationViewItem.Icon>
<FontIcon FontFamily="{StaticResource CalculatorFontFamily}" Glyph="&#xe946;"/>
</muxc:NavigationViewItem.Icon>
<FlyoutBase.AttachedFlyout>
<Flyout x:Name="AboutPageFlyout"
x:Uid="AboutPageFlyout"
Closed="OnAboutFlyoutClosed"
FlyoutPresenterStyle="{StaticResource AboutFlyoutPresenterStyle}"
Opened="OnAboutFlyoutOpened">
<local:AboutFlyout x:Name="AboutPage" x:Load="False"/>
</Flyout>
</FlyoutBase.AttachedFlyout>
</muxc:NavigationViewItem>
</muxc:NavigationViewList.Items>
</muxc:NavigationViewList>
</StackPanel>
</muxc:NavigationView.PaneFooter>
<Grid>
<TextBlock x:Name="Header"
Margin="52,6,12,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Style="{StaticResource SubtitleTextBlockStyle}"
Text="{x:Bind Model.CategoryName, Mode=OneWay}"/>
<Border x:Name="CalcHolder">
<!-- PLACEHOLDER!!!! This is where the calculator goes when it is delay loaded -->
</Border>
<Border x:Name="DateCalcHolder">
<!-- PLACEHOLDER!!!! This is where the date calculator goes when it is delay loaded -->
</Border>
<Border x:Name="ConverterHolder">
<!-- PLACEHOLDER!!!! This is where the converter goes when it is delay loaded -->
</Border>
</Grid>
</muxc:NavigationView>
</Grid>
</common:LayoutAwarePage>

View File

@@ -0,0 +1,674 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "pch.h"
#include "MainPage.xaml.h"
#include "Views\Memory.xaml.h"
#include "Converters\BooleanToVisibilityConverter.h"
#include "CalcViewModel\Common\KeyboardShortcutManager.h"
#include "CalcViewModel\Common\LocalizationService.h"
#include "CalcViewModel\Common\Automation\NarratorNotifier.h"
#include "CalcViewModel\Common\AppResourceProvider.h"
#include "Common\AppLifecycleLogger.h"
using namespace CalculatorApp;
using namespace CalculatorApp::Common;
using namespace CalculatorApp::Common::Automation;
using namespace CalculatorApp::Converters;
using namespace CalculatorApp::ViewModel;
using namespace Concurrency;
using namespace Platform;
using namespace Platform::Collections;
using namespace std;
using namespace Windows::ApplicationModel::Core;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::Graphics::Display;
using namespace Windows::UI;
using namespace Windows::UI::Core;
using namespace Windows::UI::ViewManagement;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Automation;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
using namespace Windows::UI::ViewManagement;
using namespace Windows::Graphics::Display;
using namespace Windows::Storage;
using namespace Windows::System;
using namespace Windows::System::Threading;
using namespace Utils;
namespace MUXC = Microsoft::UI::Xaml::Controls;
namespace CalculatorApp::VisualStates
{
namespace Mode
{
StringReference Calculator(L"Calculator");
StringReference DateCalculator(L"Date");
StringReference UnitConverter(L"Converter");
}
namespace Memory
{
StringReference MemoryEmpty(L"MemoryEmpty");
StringReference MemoryRight(L"MemoryRight");
StringReference MemoryBottom(L"MemoryBottom");
StringReference MemoryDock(L"MemoryDock");
}
}
MainPage::MainPage() :
m_model(ref new ApplicationViewModel())
{
InitializeComponent();
m_uiSettings = ref new UISettings();
KeyboardShortcutManager::Initialize();
m_model->PropertyChanged += ref new PropertyChangedEventHandler(this, &MainPage::OnAppPropertyChanged);
double sizeInInches = 0.0;
if (SUCCEEDED(GetIntegratedDisplaySize(&sizeInInches)))
{
if (sizeInInches < 7.0) // If device's display size (diagonal length) is less than 7 inches then keep the calc always in Portrait mode only
{
DisplayInformation::AutoRotationPreferences = DisplayOrientations::Portrait | DisplayOrientations::PortraitFlipped;
}
}
}
/// <summary>
/// Populates the page with content passed during navigation. Any saved state is also
/// provided when recreating a page from a prior session.
/// </summary>
/// <param name="navigationParameter">The parameter value passed to
/// <see cref="Frame::Navigate(Type, Object)"/> when this page was initially requested.
/// </param>
/// <param name="pageState">A map of state preserved by this page during an earlier
/// session. This will be null the first time a page is visited.</param>
void MainPage::LoadState(_In_ Object^ navigationParameter, _In_ IMap<String^, Object^>^ pageState)
{
if (pageState != nullptr)
{
if (pageState->HasKey("ConverterViewModelState"))
{
auto converterViewModelState = safe_cast<String^>(pageState->Lookup("ConverterViewModelState"));
m_model->ConverterViewModel->Deserialize(converterViewModelState);
}
//Moving these below the converter view model deserialize, since the converter modes are also displayed in the MainPage NavBar and thus need to be deserialized before setting the current mode
if (pageState->HasKey(ApplicationViewModelProperties::Mode))
{
m_model->Mode = NavCategory::Deserialize(pageState->Lookup(ApplicationViewModelProperties::Mode));
}
if (pageState->HasKey(ApplicationViewModelProperties::PreviousMode))
{
m_model->PreviousMode = NavCategory::Deserialize(pageState->Lookup(ApplicationViewModelProperties::PreviousMode));
}
// rehydrate
if (pageState->HasKey("CalculatorViewModelState"))
{
auto calculatorViewModelState = safe_cast<Array<unsigned char>^>(pageState->Lookup("CalculatorViewModelState"));
m_model->CalculatorViewModel->Deserialize(calculatorViewModelState);
}
m_model->CalculatorViewModel->HistoryVM->RestoreCompleteHistory();
m_model->CalculatorViewModel->HistoryVM->ReloadHistory(m_model->Mode);
}
else
{
// initialize
if (m_model->CalculatorViewModel)
{
m_model->CalculatorViewModel->HistoryVM->ClearHistory();
}
ViewMode initialMode = ViewMode::Standard;
if (navigationParameter != nullptr)
{
String^ stringParameter = dynamic_cast<String^>(navigationParameter);
if (stringParameter != nullptr)
{
initialMode = (ViewMode)stoi(stringParameter->Data());
}
}
else
{
ApplicationDataContainer^ localSettings = ApplicationData::Current->LocalSettings;
if (localSettings->Values->HasKey(ApplicationViewModelProperties::Mode))
{
initialMode = NavCategory::Deserialize(localSettings->Values->Lookup(ApplicationViewModelProperties::Mode));
}
}
m_model->Initialize(initialMode);
}
}
/// <summary>
/// Preserves state associated with this page in case the application is suspended or the
/// page is discarded from the navigation cache. Values must conform to the serialization
/// requirements of <see cref="SuspensionManager::SessionState"/>.
/// </summary>
/// <param name="pageState">An empty map to be populated with serializable state.</param>
void MainPage::SaveState(_In_ IMap<String^, Object^>^ pageState)
{
int serializedCurrentMode = NavCategory::Serialize(m_model->Mode);
pageState->Insert(ApplicationViewModelProperties::Mode, serializedCurrentMode);
pageState->Insert(ApplicationViewModelProperties::PreviousMode, NavCategory::Serialize(m_model->PreviousMode));
ApplicationDataContainer^ localSettings = ApplicationData::Current->LocalSettings;
localSettings->Values->Insert(ApplicationViewModelProperties::Mode, serializedCurrentMode);
auto serializedCalculatorData = m_model->CalculatorViewModel->Serialize();
auto serializedConverterData = m_model->ConverterViewModel->Serialize();
if (serializedCalculatorData->Length > 0)
{
pageState->Insert("CalculatorViewModelState", serializedCalculatorData);
}
if (serializedConverterData != nullptr)
{
pageState->Insert("ConverterViewModelState", serializedConverterData);
}
}
void MainPage::WindowSizeChanged(_In_ Platform::Object^ /*sender*/, _In_ Windows::UI::Core::WindowSizeChangedEventArgs^ e)
{
// We dont use layout aware page's view states, we have our own
UpdateViewState();
}
void MainPage::OnAppPropertyChanged(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::Data::PropertyChangedEventArgs^ e)
{
if (e->PropertyName->Equals(ApplicationViewModelProperties::Mode))
{
ViewMode newValue = m_model->Mode;
ViewMode previousMode = m_model->PreviousMode;
if (newValue == ViewMode::Standard)
{
EnsureCalculator();
m_model->CalculatorViewModel->AreHistoryShortcutsEnabled = true;
m_model->CalculatorViewModel->HistoryVM->AreHistoryShortcutsEnabled = true;
m_calculator->AnimateCalculator(NavCategory::IsConverterViewMode(previousMode));
m_model->CalculatorViewModel->HistoryVM->ReloadHistory(newValue);
}
else if (newValue == ViewMode::Scientific)
{
EnsureCalculator();
m_model->CalculatorViewModel->AreHistoryShortcutsEnabled = true;
m_model->CalculatorViewModel->HistoryVM->AreHistoryShortcutsEnabled = true;
if (m_model->PreviousMode != ViewMode::Scientific)
{
m_calculator->AnimateCalculator(NavCategory::IsConverterViewMode(previousMode));
}
m_model->CalculatorViewModel->HistoryVM->ReloadHistory(newValue);
}
else if (newValue == ViewMode::Programmer)
{
m_model->CalculatorViewModel->AreHistoryShortcutsEnabled = false;
m_model->CalculatorViewModel->HistoryVM->AreHistoryShortcutsEnabled = false;
EnsureCalculator();
if (m_model->PreviousMode != ViewMode::Programmer)
{
m_calculator->AnimateCalculator(NavCategory::IsConverterViewMode(previousMode));
}
}
else if (NavCategory::IsDateCalculatorViewMode(newValue))
{
if (m_model->CalculatorViewModel)
{
m_model->CalculatorViewModel->AreHistoryShortcutsEnabled = false;
m_model->CalculatorViewModel->HistoryVM->AreHistoryShortcutsEnabled = false;
}
EnsureDateCalculator();
}
else if (NavCategory::IsConverterViewMode(newValue))
{
if (m_model->CalculatorViewModel)
{
m_model->CalculatorViewModel->AreHistoryShortcutsEnabled = false;
m_model->CalculatorViewModel->HistoryVM->AreHistoryShortcutsEnabled = false;
}
EnsureConverter();
if (!NavCategory::IsConverterViewMode(previousMode))
{
m_converter->AnimateConverter();
}
}
ShowHideControls(newValue);
UpdateViewState();
SetTitleBarControlColors();
SetDefaultFocus();
}
else if (e->PropertyName->Equals(ApplicationViewModelProperties::CategoryName))
{
SetHeaderAutomationName();
AnnounceCategoryName();
}
}
void MainPage::ShowHideControls(ViewMode mode)
{
auto isCalcViewMode = NavCategory::IsCalculatorViewMode(mode);
auto isDateCalcViewMode = NavCategory::IsDateCalculatorViewMode(mode);
auto isConverterViewMode = NavCategory::IsConverterViewMode(mode);
if (m_calculator)
{
m_calculator->Visibility = BooleanToVisibilityConverter::Convert(isCalcViewMode);
m_calculator->IsEnabled = isCalcViewMode;
}
if (m_dateCalculator)
{
m_dateCalculator->Visibility = BooleanToVisibilityConverter::Convert(isDateCalcViewMode);
m_dateCalculator->IsEnabled = isDateCalcViewMode;
}
if (m_converter)
{
m_converter->Visibility = BooleanToVisibilityConverter::Convert(isConverterViewMode);
m_converter->IsEnabled = isConverterViewMode;
}
}
void MainPage::UpdateViewState()
{
// All layout related view states are now handled only inside individual controls (standard, scientific, programmer, date, converter)
if (NavCategory::IsConverterViewMode(m_model->Mode))
{
int modeIndex = NavCategory::GetIndexInGroup(m_model->Mode, CategoryGroupType::Converter);
m_model->ConverterViewModel->CurrentCategory = m_model->ConverterViewModel->Categories->GetAt(modeIndex);
}
}
void MainPage::UpdatePanelViewState()
{
if (m_calculator != nullptr)
{
m_calculator->UpdatePanelViewState();
}
}
void MainPage::OnPageLoaded(_In_ Object^, _In_ RoutedEventArgs^ args)
{
if (!m_converter && !m_calculator && !m_dateCalculator)
{
// We have just launched into our default mode (standard calc) so ensure calc is loaded
EnsureCalculator();
m_model->CalculatorViewModel->IsStandard = true;
}
_windowSizeEventToken = Window::Current->SizeChanged += ref new WindowSizeChangedEventHandler(this, &MainPage::WindowSizeChanged);
UpdateViewState();
// Set custom XAML Title Bar window caption control button brushes
m_uiSettings->ColorValuesChanged -= m_colorValuesChangedToken;
m_colorValuesChangedToken = m_uiSettings->ColorValuesChanged += ref new TypedEventHandler<UISettings^, Object^>(this, &MainPage::ColorValuesChanged);
SetTitleBarControlColors();
SetHeaderAutomationName();
SetDefaultFocus();
// Delay load things later when we get a chance.
this->Dispatcher->RunAsync(CoreDispatcherPriority::Normal, ref new DispatchedHandler([]()
{
if (TraceLogger::GetInstance().UpdateWindowIdLog(ApplicationView::GetApplicationViewIdForWindow(CoreWindow::GetForCurrentThread())))
{
TraceLogger::GetInstance().LogAppLaunchComplete();
AppLifecycleLogger::GetInstance().LaunchUIResponsive();
AppLifecycleLogger::GetInstance().LaunchVisibleComplete();
}
}));
}
void MainPage::OnPageUnLoaded(_In_ Object^, _In_ RoutedEventArgs^)
{
// OnPageUnloaded Event Handler does not get fired when the calc window is closed.
// On closing the instance of a window, On Window Consolidate gets fired.
}
void MainPage::PinUnpinAppBarButtonOnClicked(
_In_ Object^ sender,
_In_ RoutedEventArgs^ e)
{
m_model->CalculatorViewModel->OnPinUnpinCommand(sender);
}
void MainPage::SetDefaultFocus()
{
if (m_calculator != nullptr && m_calculator->Visibility == ::Visibility::Visible)
{
m_calculator->SetDefaultFocus();
}
if (m_dateCalculator != nullptr && m_dateCalculator->Visibility == ::Visibility::Visible)
{
m_dateCalculator->SetDefaultFocus();
}
if (m_converter != nullptr && m_converter->Visibility == ::Visibility::Visible)
{
m_converter->SetDefaultFocus();
}
}
void MainPage::EnsureCalculator()
{
if (!m_calculator)
{
// delay load calculator.
m_calculator = ref new Calculator();
m_calculator->Name = L"Calculator";
m_calculator->DataContext = m_model->CalculatorViewModel;
Binding^ isStandardBinding = ref new Binding();
isStandardBinding->Path = ref new PropertyPath(L"IsStandard");
m_calculator->SetBinding(m_calculator->IsStandardProperty, isStandardBinding);
Binding^ isScientificBinding = ref new Binding();
isScientificBinding->Path = ref new PropertyPath(L"IsScientific");
m_calculator->SetBinding(m_calculator->IsScientificProperty, isScientificBinding);
Binding^ isProgramerBinding = ref new Binding();
isProgramerBinding->Path = ref new PropertyPath(L"IsProgrammer");
m_calculator->SetBinding(m_calculator->IsProgrammerProperty, isProgramerBinding);
m_calculator->Style = CalculatorBaseStyle;
m_fullscreenFlyoutClosedToken =
m_calculator->FullscreenFlyoutClosed += ref new FullscreenFlyoutClosedEventHandler(this, &MainPage::OnFullscreenFlyoutClosed);
CalcHolder->Child = m_calculator;
// Calculator's "default" state is visibile, but if we get delay loaded
// when in converter, we should not be visible. This is not a problem for converter
// since it's default state is hidden.
ShowHideControls(this->Model->Mode);
}
if (m_dateCalculator != nullptr)
{
m_dateCalculator->CloseCalendarFlyout();
}
}
void MainPage::EnsureDateCalculator()
{
if (!m_dateCalculator)
{
// delay loading converter
m_dateCalculator = ref new DateCalculator();
m_dateCalculator->Name = L"dateCalculator";
m_dateCalculator->DataContext = m_model->DateCalcViewModel;
DateCalcHolder->Child = m_dateCalculator;
}
if (m_calculator != nullptr)
{
m_calculator->CloseHistoryFlyout();
m_calculator->CloseMemoryFlyout();
}
}
void MainPage::EnsureConverter()
{
if (!m_converter)
{
// delay loading converter
m_converter = ref new CalculatorApp::UnitConverter();
m_converter->Name = L"unitConverter";
m_converter->DataContext = m_model->ConverterViewModel;
m_converter->Style = UnitConverterBaseStyle;
ConverterHolder->Child = m_converter;
}
}
void MainPage::OnNavLoaded(_In_ Object^ sender, _In_ RoutedEventArgs^ e)
{
if (NavView->SelectedItem == nullptr)
{
auto menuItems = static_cast<IObservableVector<Object^>^>(NavView->MenuItemsSource);
auto itemCount = static_cast<int>(menuItems->Size);
auto flatIndex = NavCategory::GetFlatIndex(Model->Mode);
if (flatIndex >= 0 && flatIndex < itemCount)
{
NavView->SelectedItem = menuItems->GetAt(flatIndex);
}
}
auto acceleratorList = NavCategory::GetCategoryAcceleratorKeys();
for (auto accelerator : acceleratorList)
{
NavView->SetValue(Common::KeyboardShortcutManager::VirtualKeyAltChordProperty, accelerator);
}
// Special case logic for Ctrl+E accelerator for Date Calculation Mode
NavView->SetValue(Common::KeyboardShortcutManager::VirtualKeyControlChordProperty, Common::MyVirtualKey::E);
}
void MainPage::OnNavPaneOpening(_In_ MUXC::NavigationView^ sender, _In_ Object^ args)
{
if (!NavFooter)
{
this->FindName(L"NavFooter");
}
}
void MainPage::OnNavPaneOpened(_In_ MUXC::NavigationView^ sender, _In_ Object^ args)
{
KeyboardShortcutManager::HonorShortcuts(false);
TraceLogger::GetInstance().LogNavBarOpened();
}
void MainPage::OnNavPaneClosed(_In_ MUXC::NavigationView^ sender, _In_ Object^ args)
{
KeyboardShortcutManager::HonorShortcuts(true);
this->SetDefaultFocus();
}
void MainPage::OnAboutButtonClick(Object^ sender, ItemClickEventArgs^ e)
{
ShowAboutPage();
}
void MainPage::OnAboutFlyoutOpened(_In_ Object^ sender, _In_ Object^ e)
{
// Keep Ignoring Escape till the About page flyout is opened
KeyboardShortcutManager::IgnoreEscape(false);
KeyboardShortcutManager::UpdateDropDownState(this->AboutPageFlyout);
}
void MainPage::OnAboutFlyoutClosed(_In_ Object^ sender, _In_ Object^ e)
{
// Start Honoring Escape once the About page flyout is closed
KeyboardShortcutManager::HonorEscape();
KeyboardShortcutManager::UpdateDropDownState(nullptr);
}
void MainPage::OnNavSelectionChanged(_In_ Object^ sender, _In_ MUXC::NavigationViewSelectionChangedEventArgs^ e)
{
auto item = dynamic_cast<MUXC::NavigationViewItem^>(e->SelectedItemContainer);
if (item != nullptr)
{
auto selectedItem = static_cast<NavCategory^>(item->DataContext);
Model->Mode = selectedItem->Mode;
}
}
IObservableVector<Object^>^ MainPage::CreateUIElementsForCategories(_In_ IObservableVector<NavCategoryGroup^>^ categories)
{
auto menuCategories = ref new Vector<Object^>();
for (auto group : categories)
{
menuCategories->Append(CreateNavViewHeaderFromGroup(group));
for (auto category : group->Categories)
{
menuCategories->Append(CreateNavViewItemFromCategory(category));
}
}
return menuCategories;
}
MUXC::NavigationViewItemHeader^ MainPage::CreateNavViewHeaderFromGroup(NavCategoryGroup^ group)
{
auto header = ref new MUXC::NavigationViewItemHeader();
header->DataContext = group;
header->Content = group->Name;
AutomationProperties::SetName(header, group->AutomationName);
AutomationProperties::SetHeadingLevel(header, Peers::AutomationHeadingLevel::Level1);
return header;
}
MUXC::NavigationViewItem^ MainPage::CreateNavViewItemFromCategory(NavCategory^ category)
{
auto item = ref new MUXC::NavigationViewItem();
item->DataContext = category;
auto icon = ref new FontIcon();
icon->FontFamily = static_cast<Windows::UI::Xaml::Media::FontFamily^>(App::Current->Resources->Lookup(L"CalculatorFontFamily"));
icon->Glyph = category->Glyph;
item->Icon = icon;
item->Content = category->Name;
item->AccessKey = category->AccessKey;
item->Style = static_cast<Windows::UI::Xaml::Style^>(Resources->Lookup(L"NavViewItemStyle"));
AutomationProperties::SetName(item, category->AutomationName);
AutomationProperties::SetAutomationId(item, category->AutomationId);
return item;
}
void MainPage::ShowAboutPage()
{
if (!AboutPage)
{
this->FindName(L"AboutPage");
}
FlyoutBase::ShowAttachedFlyout(AboutButton);
}
void MainPage::ColorValuesChanged(_In_ UISettings^ sender, _In_ Object^ e)
{
WeakReference weakThis(this);
RunOnUIThreadNonblocking([weakThis]()
{
auto refThis = weakThis.Resolve<MainPage>();
if (refThis != nullptr)
{
refThis->SetTitleBarControlColors();
}
}, this->Dispatcher);
}
void MainPage::SetTitleBarControlColors()
{
auto applicationView = ApplicationView::GetForCurrentView();
if (applicationView == nullptr) { return; }
auto applicationTitleBar = applicationView->TitleBar;
if (applicationTitleBar == nullptr) { return; }
auto bgbrush = safe_cast<SolidColorBrush^>(Application::Current->Resources->Lookup("SystemControlBackgroundTransparentBrush"));
auto fgbrush = safe_cast<SolidColorBrush^>(Application::Current->Resources->Lookup("SystemControlPageTextBaseHighBrush"));
auto inactivefgbrush = safe_cast<SolidColorBrush^>(Application::Current->Resources->Lookup("SystemControlForegroundChromeDisabledLowBrush"));
auto hoverbgbrush = safe_cast<SolidColorBrush^>(Application::Current->Resources->Lookup("SystemControlBackgroundListLowBrush"));
auto hoverfgbrush = safe_cast<SolidColorBrush^>(Application::Current->Resources->Lookup("SystemControlForegroundBaseHighBrush"));
auto pressedbgbrush = safe_cast<SolidColorBrush^>(Application::Current->Resources->Lookup("SystemControlBackgroundListMediumBrush"));
auto pressedfgbrush = safe_cast<SolidColorBrush^>(Application::Current->Resources->Lookup("SystemControlForegroundBaseHighBrush"));
applicationTitleBar->ButtonBackgroundColor = bgbrush->Color;
applicationTitleBar->ButtonForegroundColor = fgbrush->Color;
applicationTitleBar->ButtonInactiveBackgroundColor = bgbrush->Color;
applicationTitleBar->ButtonInactiveForegroundColor = inactivefgbrush->Color;
applicationTitleBar->ButtonHoverBackgroundColor = hoverbgbrush->Color;
applicationTitleBar->ButtonHoverForegroundColor = hoverfgbrush->Color;
applicationTitleBar->ButtonPressedBackgroundColor = pressedbgbrush->Color;
applicationTitleBar->ButtonPressedForegroundColor = pressedfgbrush->Color;
}
void MainPage::UnregisterEventHandlers()
{
m_uiSettings->ColorValuesChanged -= m_colorValuesChangedToken;
m_colorValuesChangedToken.Value = 0;
Window::Current->SizeChanged -= _windowSizeEventToken;
_windowSizeEventToken.Value = 0;
if (m_calculator != nullptr)
{
m_calculator->FullscreenFlyoutClosed -= m_fullscreenFlyoutClosedToken;
m_fullscreenFlyoutClosedToken.Value = 0;
m_calculator->UnregisterEventHandlers();
}
m_titleBarHelper = nullptr;
}
void MainPage::SetHeaderAutomationName()
{
ViewMode mode = m_model->Mode;
auto resProvider = AppResourceProvider::GetInstance();
String^ name;
if (NavCategory::IsDateCalculatorViewMode(mode))
{
name = resProvider.GetResourceString(L"HeaderAutomationName_Date");
}
else
{
wstring full;
if (NavCategory::IsCalculatorViewMode(mode))
{
full = resProvider.GetResourceString(L"HeaderAutomationName_Calculator")->Data();
}
else if (NavCategory::IsConverterViewMode(mode))
{
full = resProvider.GetResourceString(L"HeaderAutomationName_Converter")->Data();
}
string::size_type found = full.find(L"%1");
wstring strMode = m_model->CategoryName->Data();
full = full.replace(found, 2, strMode);
name = ref new String(full.c_str());
}
AutomationProperties::SetName(Header, name);
}
void MainPage::OnFullscreenFlyoutClosed()
{
this->CustomTitleBar->SetTitleBar();
}
void MainPage::AnnounceCategoryName()
{
String^ categoryName = AutomationProperties::GetName(Header);
NarratorAnnouncement^ announcement = CalculatorAnnouncement::GetCategoryNameChangedAnnouncement(categoryName);
NarratorNotifier->Announce(announcement);
}

View File

@@ -0,0 +1,96 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
#include "Common\LayoutAwarePage.h" // Required by generated header
#include "Views\Calculator.xaml.h"
#include "Views\MainPage.g.h"
#include "Views\DateCalculator.xaml.h"
#include "Views\UnitConverter.xaml.h"
#include "CalcViewModel\ApplicationViewModel.h"
#include "Views\TitleBar.xaml.h"
namespace CalculatorApp
{
namespace WUC = Windows::UI::Core;
namespace WUXI = Windows::UI::Xaml::Input;
namespace WUXD = Windows::UI::Xaml::Data;
namespace WUXC = Windows::UI::Xaml::Controls;
/// <summary>
/// A basic page that provides characteristics common to most applications.
/// </summary>
public ref class MainPage sealed
{
public:
MainPage();
property CalculatorApp::ViewModel::ApplicationViewModel^ Model
{
CalculatorApp::ViewModel::ApplicationViewModel^ get(){
return m_model;
}
}
void UnregisterEventHandlers();
void SetDefaultFocus();
void SetHeaderAutomationName();
Windows::Foundation::Collections::IObservableVector<Platform::Object^>^ CreateUIElementsForCategories(_In_ Windows::Foundation::Collections::IObservableVector<CalculatorApp::Common::NavCategoryGroup^>^ categories);
protected:
virtual void LoadState(_In_ Platform::Object^ navigationParameter,
_In_ Windows::Foundation::Collections::IMap<Platform::String^, Platform::Object^>^ pageState) override;
virtual void SaveState(_In_ Windows::Foundation::Collections::IMap<Platform::String^, Platform::Object^>^ pageState) override;
private:
void WindowSizeChanged(_In_ Platform::Object^ sender, _In_ Windows::UI::Core::WindowSizeChangedEventArgs^ e);
void OnAppPropertyChanged(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::Data::PropertyChangedEventArgs^ e);
void SetTitleBarControlColors();
void ColorValuesChanged(_In_ Windows::UI::ViewManagement::UISettings^ sender, _In_ Platform::Object^ e);
void OnNavLoaded(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
void OnNavPaneOpening(_In_ Microsoft::UI::Xaml::Controls::NavigationView^ sender, _In_ Platform::Object^ args);
void OnNavPaneOpened(_In_ Microsoft::UI::Xaml::Controls::NavigationView^ sender, _In_ Platform::Object^ args);
void OnNavPaneClosed(_In_ Microsoft::UI::Xaml::Controls::NavigationView^ sender, _In_ Platform::Object^ args);
void OnNavSelectionChanged(_In_ Platform::Object^ sender, _In_ Microsoft::UI::Xaml::Controls::NavigationViewSelectionChangedEventArgs^ e);
void OnAboutButtonClick(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::Controls::ItemClickEventArgs^ e);
void OnAboutFlyoutOpened(_In_ Platform::Object^ sender, _In_ Platform::Object^ e);
void OnAboutFlyoutClosed(_In_ Platform::Object^ sender, _In_ Platform::Object^ e);
Microsoft::UI::Xaml::Controls::NavigationViewItemHeader^ CreateNavViewHeaderFromGroup(CalculatorApp::Common::NavCategoryGroup^ group);
Microsoft::UI::Xaml::Controls::NavigationViewItem^ CreateNavViewItemFromCategory(CalculatorApp::Common::NavCategory^ category);
Windows::Foundation::EventRegistrationToken m_fullscreenFlyoutClosedToken;
void OnFullscreenFlyoutClosed();
void ShowHideControls(CalculatorApp::Common::ViewMode mode);
void UpdateViewState();
void UpdatePanelViewState();
void OnPageLoaded(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
void OnPageUnLoaded(_In_ Platform::Object^, _In_ Windows::UI::Xaml::RoutedEventArgs^);
void PinUnpinAppBarButtonOnClicked(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
void EnsureCalculator();
void EnsureConverter();
void EnsureDateCalculator();
void ShowAboutPage();
void AnnounceCategoryName();
CalculatorApp::Calculator^ m_calculator;
CalculatorApp::UnitConverter^ m_converter;
CalculatorApp::DateCalculator^ m_dateCalculator;
Windows::Foundation::EventRegistrationToken _windowSizeEventToken;
Windows::Foundation::EventRegistrationToken m_hardwareButtonsBackPressedToken;
Windows::Foundation::EventRegistrationToken m_colorValuesChangedToken;
CalculatorApp::ViewModel::ApplicationViewModel^ m_model;
Windows::UI::ViewManagement::UISettings^ m_uiSettings;
std::unique_ptr<CalculatorApp::Common::TitleBarHelper> m_titleBarHelper;
};
}

View File

@@ -0,0 +1,143 @@
<UserControl x:Class="CalculatorApp.Memory"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:common="using:CalculatorApp.Common"
xmlns:controls="using:CalculatorApp.Controls"
xmlns:converters="using:CalculatorApp.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:CalculatorApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:model="using:CalculatorApp.ViewModel"
x:Name="MemoryList"
FlowDirection="LeftToRight"
Loaded="MemoryList_Loaded"
Unloaded="MemoryList_Unloaded"
mc:Ignorable="d">
<UserControl.Resources>
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<converters:BooleanToVisibilityNegationConverter x:Key="BooleanToVisibilityNegationConverter"/>
<converters:BooleanNegationConverter x:Key="BooleanNegationConverter"/>
<MenuFlyout x:Key="MemoryContextMenu">
<MenuFlyoutItem x:Uid="ClearMemoryMenuItem" Click="OnClearMenuItemClicked">
<MenuFlyoutItem.Icon>
<FontIcon FontFamily="{StaticResource CalculatorFontFamily}" Glyph="&#xf754;"/>
</MenuFlyoutItem.Icon>
</MenuFlyoutItem>
<MenuFlyoutItem x:Uid="MemPlusMenuItem" Click="OnMemoryAddMenuItemClicked">
<MenuFlyoutItem.Icon>
<FontIcon FontFamily="{StaticResource CalculatorFontFamily}" Glyph="&#xf757;"/>
</MenuFlyoutItem.Icon>
</MenuFlyoutItem>
<MenuFlyoutItem x:Uid="MemMinusMenuItem" Click="OnMemorySubtractMenuItemClicked">
<MenuFlyoutItem.Icon>
<FontIcon FontFamily="{StaticResource CalculatorFontFamily}" Glyph="&#xf758;"/>
</MenuFlyoutItem.Icon>
</MenuFlyoutItem>
</MenuFlyout>
<DataTemplate x:Key="MemoryItemTemplate" x:DataType="model:MemoryItemViewModel">
<local:MemoryListItem Model="{x:Bind Mode=OneWay}"/>
</DataTemplate>
<Style x:Key="MemoryItemContainerStyle"
BasedOn="{StaticResource HistoryMemoryItemContainerStyle}"
TargetType="ListViewItem">
<Setter Property="Margin" Value="0,0,0,8"/>
</Style>
</UserControl.Resources>
<Grid x:Name="LayoutGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="{Binding RowHeight, ElementName=MemoryList, Mode=OneWay}"/>
</Grid.RowDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ErrorVisualStates">
<VisualState x:Name="NoErrorLayout"/>
<VisualState x:Name="ErrorLayout">
<VisualState.Setters>
<Setter Target="MemoryListView.IsEnabled" Value="False"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup>
<VisualState x:Name="DockedLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="560"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="MemoryPanel.(Grid.Row)" Value="1"/>
<Setter Target="MemoryPanel.(Grid.RowSpan)" Value="2"/>
<Setter Target="MemoryListView.Padding" Value="0"/>
<Setter Target="BackgroundShade.Opacity" Value="0"/>
<Setter Target="CustomTitleBar.Height" Value="0"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="DefaultLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0"/>
</VisualState.StateTriggers>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="BackgroundShade"
Grid.Row="2"
Margin="0,-1,0,0"
Padding="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="{ThemeResource SystemControlChromeMediumLowAcrylicElementMediumBrush}"
BorderBrush="{ThemeResource SystemControlForegroundChromeHighBrush}"
BorderThickness="{ThemeResource HighContrastThicknessTop}"/>
<Grid x:Name="MemoryPanel" Grid.Row="2">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock x:Name="MemoryPaneEmpty"
x:Uid="MemoryPaneEmpty"
Margin="12,14,24,0"
Style="{ThemeResource BaseTextBlockStyle}"
Foreground="{ThemeResource SystemControlPageTextBaseHighBrush}"
TextWrapping="Wrap"
Visibility="{Binding IsMemoryEmpty, Converter={StaticResource BooleanToVisibilityConverter}}"/>
<ListView x:Name="MemoryListView"
Padding="0,12,0,0"
HorizontalAlignment="Stretch"
ContextCanceled="OnContextCanceled"
ContextRequested="OnContextRequested"
IsItemClickEnabled="true"
ItemClick="MemoryListItemClick"
ItemContainerStyle="{ThemeResource MemoryItemContainerStyle}"
ItemTemplate="{ThemeResource MemoryItemTemplate}"
ItemsSource="{x:Bind Model.MemorizedNumbers, Mode=OneWay}"
SelectionMode="None"
TabIndex="0"
Visibility="{x:Bind Model.IsMemoryEmpty, Mode=OneWay, Converter={StaticResource BooleanToVisibilityNegationConverter}}">
<ListView.ItemContainerTransitions>
<TransitionCollection>
<AddDeleteThemeTransition/>
<ContentThemeTransition/>
<ReorderThemeTransition/>
</TransitionCollection>
</ListView.ItemContainerTransitions>
</ListView>
<Button x:Name="ClearMemory"
x:Uid="ClearMemory"
Grid.Row="1"
Style="{ThemeResource ClearAllHistoryMemoryButtonStyle}"
AutomationProperties.AutomationId="ClearMemory"
Command="{x:Bind Model.ClearMemoryCommand, Mode=OneWay}"
Content="&#xE74D;"
Visibility="{x:Bind Model.IsMemoryEmpty, Mode=OneWay, Converter={StaticResource BooleanToVisibilityNegationConverter}}"/>
</Grid>
<Border x:Name="CustomTitleBar"
Height="32"
HorizontalAlignment="Stretch"
Background="{ThemeResource TitleBarBackgroundTransparentBrush}"/>
</Grid>
</UserControl>

View File

@@ -0,0 +1,141 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//
// Memory.xaml.cpp
// Implementation of the Memory class
//
#include "pch.h"
#include "Memory.xaml.h"
#include "Controls\CalculatorButton.h"
#include "CalcViewModel\StandardCalculatorViewModel.h"
#include "CalcViewModel\Common\LocalizationService.h"
using namespace CalculatorApp;
using namespace CalculatorApp::Common;
using namespace CalculatorApp::Controls;
using namespace CalculatorApp::ViewModel;
using namespace Platform;
using namespace Platform::Collections;
using namespace Windows::ApplicationModel::Resources;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Popups;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
using namespace Windows::UI::ViewManagement;
// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236
DEPENDENCY_PROPERTY_INITIALIZATION(Memory, RowHeight);
Memory::Memory() :
m_isErrorVisualState(false)
{
InitializeComponent();
m_memoryItemFlyout = safe_cast<MenuFlyout^>(Resources->Lookup("MemoryContextMenu"));
MemoryPaneEmpty->FlowDirection = LocalizationService::GetInstance()->GetFlowDirection();
}
void Memory::MemoryListItemClick(_In_ Object^ sender, _In_ ItemClickEventArgs^ e)
{
MemoryItemViewModel^ memorySlot = safe_cast<MemoryItemViewModel^>(e->ClickedItem);
// Incase the memory list is clicked and enter is pressed,
// On Item clicked event gets fired and e->ClickedItem is Null.
if (memorySlot != nullptr)
{
Model->OnMemoryItemPressed(memorySlot->Position);
}
}
void Memory::OnContextRequested(Windows::UI::Xaml::UIElement^ sender, Windows::UI::Xaml::Input::ContextRequestedEventArgs^ e)
{
// Walk up the tree to find the ListViewItem.
// There may not be one if the click wasn't on an item.
auto requestedElement = safe_cast<FrameworkElement^>(e->OriginalSource);
while ((requestedElement != sender) && !dynamic_cast<ListViewItem^>(requestedElement))
{
requestedElement = safe_cast<FrameworkElement^>(VisualTreeHelper::GetParent(requestedElement));
}
if (requestedElement != sender)
{
// The context menu request was for a ListViewItem.
auto memorySlot = safe_cast<MemoryItemViewModel^>(MemoryListView->ItemFromContainer(requestedElement));
Point point;
if (e->TryGetPosition(requestedElement, &point))
{
m_memoryItemFlyout->ShowAt(requestedElement, point);
}
else
{
// Not invoked via pointer, so let XAML choose a default location.
m_memoryItemFlyout->ShowAt(requestedElement);
}
e->Handled = true;
}
}
void Memory::OnContextCanceled(Windows::UI::Xaml::UIElement^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
m_memoryItemFlyout->Hide();
}
void Memory::OnClearMenuItemClicked(_In_ Object^ sender, _In_ RoutedEventArgs^ e)
{
GetMemoryItemForCurrentFlyout()->Clear();
}
void Memory::OnMemoryAddMenuItemClicked(_In_ Object^ sender, _In_ RoutedEventArgs^ e)
{
GetMemoryItemForCurrentFlyout()->MemoryAdd();
}
void Memory::OnMemorySubtractMenuItemClicked(_In_ Object^ sender, _In_ RoutedEventArgs^ e)
{
GetMemoryItemForCurrentFlyout()->MemorySubtract();
}
bool Memory::IsErrorVisualState::get()
{
return m_isErrorVisualState;
}
void Memory::IsErrorVisualState::set(bool value)
{
if (m_isErrorVisualState != value)
{
m_isErrorVisualState = value;
String^ newState = m_isErrorVisualState ? L"ErrorLayout" : L"NoErrorLayout";
VisualStateManager::GoToState(this, newState, false);
}
}
void Memory::MemoryList_Loaded(_In_ Object^ sender, _In_ RoutedEventArgs^ e)
{
// When transitioning between docked and undocked view states, the memory list is
// unloaded and then loaded, so we attempt to create the titlebarhelper every time
// we are loaded, letting the util function check if we are docked or not.
m_titleBarHelper = TitleBarHelper::CreateTitleBarHelperIfNotDocked(CustomTitleBar);
}
void Memory::MemoryList_Unloaded(_In_ Object^ sender, _In_ RoutedEventArgs^ e)
{
m_titleBarHelper = nullptr;
}
MemoryItemViewModel^ Memory::GetMemoryItemForCurrentFlyout()
{
auto listViewItem = m_memoryItemFlyout->Target;
return safe_cast<MemoryItemViewModel^>(MemoryListView->ItemFromContainer(listViewItem));
}

View File

@@ -0,0 +1,58 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//
// Memory.xaml.h
// Declaration of the Memory class
//
#pragma once
#include "Views\Memory.g.h"
#include "Common\TitleBarHelper.h"
#include "Converters\BooleanNegationConverter.h"
#include "Converters\VisibilityNegationConverter.h"
#include "CalcViewModel\StandardCalculatorViewModel.h"
namespace CalculatorApp
{
[Windows::Foundation::Metadata::WebHostHidden]
public ref class Memory sealed
{
public:
Memory();
property CalculatorApp::ViewModel::StandardCalculatorViewModel^ Model
{
CalculatorApp::ViewModel::StandardCalculatorViewModel^ get() {
return static_cast<CalculatorApp::ViewModel::StandardCalculatorViewModel^>(this->DataContext);
}
}
DEPENDENCY_PROPERTY_OWNER(Memory);
DEPENDENCY_PROPERTY(Windows::UI::Xaml::GridLength, RowHeight);
property bool IsErrorVisualState {
bool get();
void set(bool value);
}
private:
Windows::UI::Xaml::Controls::MenuFlyout^ m_memoryItemFlyout;
Windows::Foundation::Rect m_visibleBounds;
Windows::Foundation::Rect m_coreBounds;
bool m_isErrorVisualState;
void MemoryListItemClick(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::Controls::ItemClickEventArgs^ e);
void OnContextRequested(Windows::UI::Xaml::UIElement^ sender, Windows::UI::Xaml::Input::ContextRequestedEventArgs^ e);
void OnContextCanceled(Windows::UI::Xaml::UIElement^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void OnClearMenuItemClicked(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
void OnMemoryAddMenuItemClicked(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
void OnMemorySubtractMenuItemClicked(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
void MemoryList_Loaded(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
void MemoryList_Unloaded(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
CalculatorApp::ViewModel::MemoryItemViewModel^ GetMemoryItemForCurrentFlyout();
std::unique_ptr<CalculatorApp::Common::TitleBarHelper> m_titleBarHelper;
};
}

View File

@@ -0,0 +1,100 @@
<UserControl x:Class="CalculatorApp.MemoryListItem"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:common="using:CalculatorApp.Common"
xmlns:controls="using:CalculatorApp.Controls"
xmlns:converters="using:CalculatorApp.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:CalculatorApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:model="using:CalculatorApp.ViewModel"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
x:Name="MemoryListItem"
FlowDirection="LeftToRight"
mc:Ignorable="d">
<UserControl.Resources>
<muxc:FontIconSource x:Key="MemClearGlyph"
FontFamily="{StaticResource CalculatorFontFamily}"
Glyph="&#xf754;"/>
<muxc:FontIconSource x:Key="MemPlusGlyph"
FontFamily="{StaticResource CalculatorFontFamily}"
Glyph="&#xf757;"/>
<muxc:FontIconSource x:Key="MemMinusGlyph"
FontFamily="{StaticResource CalculatorFontFamily}"
Glyph="&#xf758;"/>
<muxc:SwipeItems x:Key="MemorySwipeItems" Mode="Reveal">
<muxc:SwipeItem x:Uid="ClearMemorySwipeItem"
Background="{ThemeResource SystemControlBackgroundAccentBrush}"
IconSource="{StaticResource MemClearGlyph}"
Invoked="OnClearSwipeInvoked"/>
<muxc:SwipeItem x:Uid="MemPlusSwipeItem"
Background="{ThemeResource SystemControlBackgroundAccentBrush}"
IconSource="{StaticResource MemPlusGlyph}"
Invoked="OnMemoryAddSwipeInvoked"/>
<muxc:SwipeItem x:Uid="MemMinusSwipeItem"
Background="{ThemeResource SystemControlBackgroundAccentBrush}"
IconSource="{StaticResource MemMinusGlyph}"
Invoked="OnMemorySubtractSwipeInvoked"/>
</muxc:SwipeItems>
</UserControl.Resources>
<muxc:SwipeControl RightItems="{StaticResource MemorySwipeItems}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="HoverStates">
<VisualState x:Name="MemoryButtonsVisible">
<VisualState.Setters>
<Setter Target="MemoryHoverButtons.Opacity" Value="1"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="MemoryButtonsHidden"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Margin="0,2,14,0"
Style="{ThemeResource TitleTextBlockStyle}"
FontWeight="SemiBold"
FlowDirection="LeftToRight"
Text="{x:Bind Model.Value, Mode=OneWay}"
TextAlignment="Right"
TextReadingOrder="DetectFromContent"
TextWrapping="Wrap"/>
<Grid x:Name="MemoryHoverButtons"
Grid.Row="1"
Margin="0,0,10,2"
HorizontalAlignment="Right"
Opacity="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Button x:Uid="ClearMemoryItemButton"
Style="{StaticResource MemoryHoverButtonStyle}"
Background="{ThemeResource SystemControlBackgroundAltMediumHighBrush}"
AutomationProperties.AutomationId="MClearButton"
Click="OnClearButtonClicked"
Content="MC"/>
<Button x:Uid="MemPlusItem"
Grid.Column="1"
Margin="0"
Style="{StaticResource MemoryHoverButtonStyle}"
Background="{ThemeResource SystemControlBackgroundAltMediumHighBrush}"
AutomationProperties.AutomationId="MAddButton"
Click="OnMemoryAddButtonClicked"
Content="M+"/>
<Button x:Uid="MemMinusItem"
Grid.Column="2"
Style="{StaticResource MemoryHoverButtonStyle}"
Background="{ThemeResource SystemControlBackgroundAltMediumHighBrush}"
AutomationProperties.AutomationId="MSubButton"
Click="OnMemorySubtractButtonClicked"
Content="M-"/>
</Grid>
</Grid>
</muxc:SwipeControl>
</UserControl>

View File

@@ -0,0 +1,81 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "pch.h"
#include "MemoryListItem.xaml.h"
#include "Controls\CalculatorButton.h"
using namespace CalculatorApp;
using namespace CalculatorApp::Common;
using namespace CalculatorApp::Controls;
using namespace CalculatorApp::ViewModel;
using namespace Platform;
using namespace Platform::Collections;
using namespace Windows::ApplicationModel::Resources;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Popups;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
using namespace Windows::UI::ViewManagement;
DEPENDENCY_PROPERTY_INITIALIZATION(MemoryListItem, Model);
MemoryListItem::MemoryListItem()
{
InitializeComponent();
}
void MemoryListItem::OnPointerEntered(Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e)
{
Control::OnPointerEntered(e);
// Only show hover buttons when the user is using mouse or pen.
if (e->Pointer->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse || e->Pointer->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Pen)
{
VisualStateManager::GoToState(this, "MemoryButtonsVisible", true);
}
}
void MemoryListItem::OnPointerExited(Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e)
{
Control::OnPointerExited(e);
VisualStateManager::GoToState(this, "MemoryButtonsHidden", true);
}
void MemoryListItem::OnClearButtonClicked(_In_ Object^ sender, _In_ RoutedEventArgs^ e)
{
Model->Clear();
}
void MemoryListItem::OnMemoryAddButtonClicked(_In_ Object^ sender, _In_ RoutedEventArgs^ e)
{
Model->MemoryAdd();
}
void MemoryListItem::OnMemorySubtractButtonClicked(_In_ Object^ sender, _In_ RoutedEventArgs^ e)
{
Model->MemorySubtract();
}
void MemoryListItem::OnClearSwipeInvoked(_In_ SwipeItem^ sender, SwipeItemInvokedEventArgs^ e)
{
Model->Clear();
}
void MemoryListItem::OnMemoryAddSwipeInvoked(_In_ SwipeItem^ sender, SwipeItemInvokedEventArgs^ e)
{
Model->MemoryAdd();
}
void MemoryListItem::OnMemorySubtractSwipeInvoked(_In_ SwipeItem^ sender, SwipeItemInvokedEventArgs^ e)
{
Model->MemorySubtract();
}

View File

@@ -0,0 +1,36 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
#include "Views\MemoryListItem.g.h"
#include "CalcViewModel\MemoryItemViewModel.h"
namespace CalculatorApp
{
/// <summary>
/// Represents a single item in the Memory list.
/// </summary>
[Windows::Foundation::Metadata::WebHostHidden]
public ref class MemoryListItem sealed
{
public:
MemoryListItem();
DEPENDENCY_PROPERTY_OWNER(MemoryListItem);
DEPENDENCY_PROPERTY(CalculatorApp::ViewModel::MemoryItemViewModel^, Model);
protected:
void OnPointerEntered(Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e) override;
void OnPointerExited(Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e) override;
private:
void OnClearButtonClicked(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
void OnMemoryAddButtonClicked(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
void OnMemorySubtractButtonClicked(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
void OnClearSwipeInvoked(_In_ Windows::UI::Xaml::Controls::SwipeItem^ sender, Windows::UI::Xaml::Controls::SwipeItemInvokedEventArgs^ e);
void OnMemoryAddSwipeInvoked(_In_ Windows::UI::Xaml::Controls::SwipeItem^ sender, Windows::UI::Xaml::Controls::SwipeItemInvokedEventArgs^ e);
void OnMemorySubtractSwipeInvoked(_In_ Windows::UI::Xaml::Controls::SwipeItem^ sender, Windows::UI::Xaml::Controls::SwipeItemInvokedEventArgs^ e);
};
}

View File

@@ -0,0 +1,121 @@
<UserControl x:Class="CalculatorApp.NumberPad"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:common="using:CalculatorApp.Common"
xmlns:controls="using:CalculatorApp.Controls"
xmlns:converters="using:CalculatorApp.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:CalculatorApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="ControlRoot"
d:DesignHeight="315"
d:DesignWidth="235"
mc:Ignorable="d">
<Grid x:Name="Root">
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ErrorVisualStates">
<VisualState x:Name="NoErrorLayout"/>
<VisualState x:Name="ErrorLayout">
<VisualState.Setters>
<Setter Target="decimalSeparatorButton.IsEnabled" Value="false"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<controls:CalculatorButton x:Name="num0Button"
x:Uid="num0Button"
Grid.Row="3"
Grid.Column="1"
Style="{x:Bind Path=ButtonStyle, Mode=OneWay}"
AutomationProperties.AutomationId="num0Button"
ButtonId="Zero"/>
<controls:CalculatorButton x:Name="num1Button"
x:Uid="num1Button"
Grid.Row="2"
Style="{x:Bind Path=ButtonStyle, Mode=OneWay}"
AutomationProperties.AutomationId="num1Button"
ButtonId="One"/>
<controls:CalculatorButton x:Name="num2Button"
x:Uid="num2Button"
Grid.Row="2"
Grid.Column="1"
Style="{x:Bind Path=ButtonStyle, Mode=OneWay}"
AutomationProperties.AutomationId="num2Button"
ButtonId="Two"/>
<controls:CalculatorButton x:Name="num3Button"
x:Uid="num3Button"
Grid.Row="2"
Grid.Column="2"
Style="{x:Bind Path=ButtonStyle, Mode=OneWay}"
AutomationProperties.AutomationId="num3Button"
ButtonId="Three"/>
<controls:CalculatorButton x:Name="num4Button"
x:Uid="num4Button"
Grid.Row="1"
Style="{x:Bind Path=ButtonStyle, Mode=OneWay}"
AutomationProperties.AutomationId="num4Button"
ButtonId="Four"/>
<controls:CalculatorButton x:Name="num5Button"
x:Uid="num5Button"
Grid.Row="1"
Grid.Column="1"
Style="{x:Bind Path=ButtonStyle, Mode=OneWay}"
AutomationProperties.AutomationId="num5Button"
ButtonId="Five"/>
<controls:CalculatorButton x:Name="num6Button"
x:Uid="num6Button"
Grid.Row="1"
Grid.Column="2"
Style="{x:Bind Path=ButtonStyle, Mode=OneWay}"
AutomationProperties.AutomationId="num6Button"
ButtonId="Six"/>
<controls:CalculatorButton x:Name="num7Button"
x:Uid="num7Button"
Style="{x:Bind Path=ButtonStyle, Mode=OneWay}"
AutomationProperties.AutomationId="num7Button"
ButtonId="Seven"/>
<controls:CalculatorButton x:Name="num8Button"
x:Uid="num8Button"
Grid.Column="1"
Style="{x:Bind Path=ButtonStyle, Mode=OneWay}"
AutomationProperties.AutomationId="num8Button"
ButtonId="Eight"/>
<controls:CalculatorButton x:Name="num9Button"
x:Uid="num9Button"
Grid.Column="2"
Style="{x:Bind Path=ButtonStyle, Mode=OneWay}"
AutomationProperties.AutomationId="num9Button"
ButtonId="Nine"/>
<!--
This is the only button in all of the app that should ever have a explicit reference to KeyboardShortcutManager in Xaml
this is needed because we need to have at least 1 refernece from Xaml so the right metadata is generated for the
KeyboardShortcutManager class, otherwise the Xaml will stop parsing and the app won't boot therefore:
DO NOT REMOVE the common:KeyboardShortcutManager.Character from this element, it's value will be overwritten by the
string coming from the RESW file
-->
<controls:CalculatorButton x:Name="decimalSeparatorButton"
x:Uid="decimalSeparatorButton"
Grid.Row="4"
Grid.Column="2"
Style="{Binding ElementName=ControlRoot, Path=ButtonStyle}"
Background="{ThemeResource AppBackgroundAltMediumLowBrush}"
common:KeyboardShortcutManager.Character="."
AutomationProperties.AutomationId="decimalSeparatorButton"
ButtonId="Decimal"
IsEnabled="{Binding IsDecimalEnabled}"/>
</Grid>
</UserControl>

View File

@@ -0,0 +1,101 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//
// NumberPad.xaml.cpp
// Implementation of the NumberPad class
//
#include "pch.h"
#include "NumberPad.xaml.h"
#include "Controls\CalculatorButton.h"
#include "CalcViewModel\StandardCalculatorViewModel.h"
#include "CalcViewModel\Common\LocalizationSettings.h"
using namespace CalculatorApp;
using namespace CalculatorApp::ViewModel;
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
using namespace CalculatorApp::Common;
// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236
DEPENDENCY_PROPERTY_INITIALIZATION(NumberPad, ButtonStyle);
NumberPad::NumberPad() :
m_isErrorVisualState(false)
{
InitializeComponent();
const auto& localizationSettings = LocalizationSettings::GetInstance();
this->decimalSeparatorButton->Content = localizationSettings.GetDecimalSeparator();
this->num0Button->Content = localizationSettings.GetDigitSymbolFromEnUsDigit('0');
this->num1Button->Content = localizationSettings.GetDigitSymbolFromEnUsDigit('1');
this->num2Button->Content = localizationSettings.GetDigitSymbolFromEnUsDigit('2');
this->num3Button->Content = localizationSettings.GetDigitSymbolFromEnUsDigit('3');
this->num4Button->Content = localizationSettings.GetDigitSymbolFromEnUsDigit('4');
this->num5Button->Content = localizationSettings.GetDigitSymbolFromEnUsDigit('5');
this->num6Button->Content = localizationSettings.GetDigitSymbolFromEnUsDigit('6');
this->num7Button->Content = localizationSettings.GetDigitSymbolFromEnUsDigit('7');
this->num8Button->Content = localizationSettings.GetDigitSymbolFromEnUsDigit('8');
this->num9Button->Content = localizationSettings.GetDigitSymbolFromEnUsDigit('9');
}
void NumberPad::ProgModeRadixChange()
{
num0Button->IsEnabled = true;
num1Button->IsEnabled = true;
num2Button->IsEnabled = true;
num3Button->IsEnabled = true;
num4Button->IsEnabled = true;
num5Button->IsEnabled = true;
num6Button->IsEnabled = true;
num7Button->IsEnabled = true;
num8Button->IsEnabled = true;
num9Button->IsEnabled = true;
auto vm = safe_cast<StandardCalculatorViewModel^>(this->DataContext);
RADIX_TYPE radixType = vm->GetCurrentRadixType();
if (radixType == RADIX_TYPE::BIN_RADIX)
{
num2Button->IsEnabled = false;
num3Button->IsEnabled = false;
num4Button->IsEnabled = false;
num5Button->IsEnabled = false;
num6Button->IsEnabled = false;
num7Button->IsEnabled = false;
num8Button->IsEnabled = false;
num9Button->IsEnabled = false;
}
else if (radixType == RADIX_TYPE::OCT_RADIX)
{
num8Button->IsEnabled = false;
num9Button->IsEnabled = false;
}
}
bool NumberPad::IsErrorVisualState::get()
{
return m_isErrorVisualState;
}
void NumberPad::IsErrorVisualState::set(bool value)
{
if (m_isErrorVisualState != value)
{
m_isErrorVisualState = value;
String^ newState = m_isErrorVisualState ? L"ErrorLayout" : L"NoErrorLayout";
VisualStateManager::GoToState(this, newState, false);
}
}

View File

@@ -0,0 +1,36 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//
// NumberPad.xaml.h
// Declaration of the NumberPad class
//
#pragma once
#include "Views\NumberPad.g.h"
#include "CalcViewModel\Common\KeyboardShortcutManager.h"
namespace CalculatorApp
{
[Windows::Foundation::Metadata::WebHostHidden]
public ref class NumberPad sealed
{
public:
NumberPad();
DEPENDENCY_PROPERTY_OWNER(NumberPad);
DEPENDENCY_PROPERTY(Windows::UI::Xaml::Style^, ButtonStyle);
property bool IsErrorVisualState
{
bool get();
void set(bool value);
}
void ProgModeRadixChange();
private:
bool m_isErrorVisualState;
};
}

View File

@@ -0,0 +1,38 @@
<UserControl x:Class="CalculatorApp.OperatorsPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:common="using:CalculatorApp.Common"
xmlns:controls="using:CalculatorApp.Controls"
xmlns:converters="using:CalculatorApp.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:CalculatorApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
UseLayoutRounding="False"
d:DesignHeight="315"
d:DesignWidth="235"
mc:Ignorable="d">
<Grid>
<local:CalculatorStandardOperators x:Name="StandardOperators"
x:Load="{x:Bind Model.IsStandard, Mode=OneWay}"
IsEnabled="{x:Bind Model.IsStandard, Mode=OneWay}"
TabIndex="17"/>
<local:CalculatorScientificOperators x:Name="ScientificOperators"
x:Load="False"
IsEnabled="{x:Bind Model.IsScientific, Mode=OneWay}"
TabIndex="16"
Visibility="{x:Bind Model.IsScientific, Mode=OneWay}"/>
<local:CalculatorProgrammerBitFlipPanel x:Name="BitFlipPanel"
x:Load="False"
IsEnabled="{x:Bind Model.IsBinaryBitFlippingEnabled, Mode=OneWay}"
Visibility="{x:Bind IsBitFlipChecked, Mode=OneWay}"/>
<local:CalculatorProgrammerRadixOperators x:Name="ProgrammerRadixOperators"
x:Load="False"
IsEnabled="{x:Bind Model.AreProgrammerRadixOperatorsEnabled, Mode=OneWay}"
TabIndex="16"
Visibility="{x:Bind Model.IsProgrammer, Mode=OneWay}"/>
</Grid>
</UserControl>

View File

@@ -0,0 +1,81 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "pch.h"
#include "OperatorsPanel.xaml.h"
using namespace CalculatorApp;
using namespace CalculatorApp::ViewModel;
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
using namespace CalculatorApp::Common;
using namespace CalculatorApp::Converters;
DEPENDENCY_PROPERTY_INITIALIZATION(OperatorsPanel, IsBitFlipChecked);
DEPENDENCY_PROPERTY_INITIALIZATION(OperatorsPanel, IsErrorVisualState);
OperatorsPanel::OperatorsPanel()
{
InitializeComponent();
}
StandardCalculatorViewModel^ OperatorsPanel::Model::get() {
return static_cast<CalculatorApp::ViewModel::StandardCalculatorViewModel^>(this->DataContext);
}
void OperatorsPanel::OnIsBitFlipCheckedPropertyChanged(bool /*oldValue*/, bool newValue)
{
if (newValue)
{
EnsureProgrammerBitFlipPanel();
}
}
void OperatorsPanel::OnIsErrorVisualStatePropertyChanged(bool /*oldValue*/, bool newValue)
{
if (Model->IsStandard)
{
StandardOperators->IsErrorVisualState = newValue;
}
else if (Model->IsScientific)
{
ScientificOperators->IsErrorVisualState = newValue;
}
else if (Model->IsProgrammer)
{
ProgrammerRadixOperators->IsErrorVisualState = newValue;
}
}
void OperatorsPanel::EnsureScientificOps()
{
if (!ScientificOperators)
{
this->FindName(L"ScientificOperators");
}
}
void OperatorsPanel::EnsureProgrammerRadixOps()
{
if (!ProgrammerRadixOperators)
{
this->FindName(L"ProgrammerRadixOperators");
}
}
void OperatorsPanel::EnsureProgrammerBitFlipPanel()
{
if (!BitFlipPanel)
{
this->FindName(L"BitFlipPanel");
}
}

View File

@@ -0,0 +1,36 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
#include "Views\OperatorsPanel.g.h"
#include "Views\CalculatorStandardOperators.xaml.h"
#include "Views\CalculatorScientificOperators.xaml.h"
#include "Views\CalculatorProgrammerBitFlipPanel.xaml.h"
#include "Views\CalculatorProgrammerRadixOperators.xaml.h"
namespace CalculatorApp
{
[Windows::Foundation::Metadata::WebHostHidden]
public ref class OperatorsPanel sealed
{
public:
OperatorsPanel();
property CalculatorApp::ViewModel::StandardCalculatorViewModel^ Model
{
CalculatorApp::ViewModel::StandardCalculatorViewModel^ get();
}
DEPENDENCY_PROPERTY_OWNER(OperatorsPanel);
DEPENDENCY_PROPERTY_WITH_CALLBACK(bool, IsBitFlipChecked);
DEPENDENCY_PROPERTY_WITH_CALLBACK(bool, IsErrorVisualState);
void EnsureProgrammerBitFlipPanel();
void EnsureScientificOps();
void EnsureProgrammerRadixOps();
private:
void OnIsBitFlipCheckedPropertyChanged(bool oldValue, bool newValue);
void OnIsErrorVisualStatePropertyChanged(bool oldValue, bool newValue);
};
}

View File

@@ -0,0 +1,84 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "pch.h"
#include "AspectRatioTrigger.h"
using namespace CalculatorApp::Views::StateTriggers;
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::UI::Xaml;
DEPENDENCY_PROPERTY_INITIALIZATION(AspectRatioTrigger, Source);
DEPENDENCY_PROPERTY_INITIALIZATION(AspectRatioTrigger, NumeratorAspect);
DEPENDENCY_PROPERTY_INITIALIZATION(AspectRatioTrigger, Threshold);
DEPENDENCY_PROPERTY_INITIALIZATION(AspectRatioTrigger, ActiveIfEqual);
AspectRatioTrigger::AspectRatioTrigger()
{
SetActive(false);
}
AspectRatioTrigger::~AspectRatioTrigger()
{
UnregisterSizeChanged(Source);
}
void AspectRatioTrigger::OnSourcePropertyChanged(FrameworkElement^ oldValue, FrameworkElement^ newValue)
{
UnregisterSizeChanged(oldValue);
RegisterSizeChanged(newValue);
}
void AspectRatioTrigger::RegisterSizeChanged(FrameworkElement^ element)
{
if (element == nullptr) { return; }
if (element != Source)
{
UnregisterSizeChanged(Source);
}
m_sizeChangedToken =
element->SizeChanged += ref new SizeChangedEventHandler(this, &AspectRatioTrigger::OnSizeChanged);
}
void AspectRatioTrigger::UnregisterSizeChanged(FrameworkElement^ element)
{
if ((element != nullptr) && (m_sizeChangedToken.Value != 0))
{
element->SizeChanged -= m_sizeChangedToken;
m_sizeChangedToken.Value = 0;
}
}
void AspectRatioTrigger::OnSizeChanged(Object^ sender, SizeChangedEventArgs^ e)
{
UpdateIsActive(e->NewSize);
}
void AspectRatioTrigger::UpdateIsActive(Size sourceSize)
{
double numerator, denominator;
if (NumeratorAspect == Aspect::Height)
{
numerator = sourceSize.Height;
denominator = sourceSize.Width;
}
else
{
numerator = sourceSize.Width;
denominator = sourceSize.Height;
}
bool isActive = false;
if (denominator > 0)
{
double ratio = numerator / denominator;
double threshold = abs(Threshold);
isActive = ((ratio > threshold) || (ActiveIfEqual && (ratio == threshold)));
}
SetActive(isActive);
}

View File

@@ -0,0 +1,54 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
/* The AspectRatioTrigger class is a custom trigger for use with a VisualState. The trigger is designed to fire when the
height/width of the source FrameworkElement is greater than a specified threshold. In order to be a flexible class, it
exposes a NumeratorAspect property that can be either Height or Width. The property chosen will be the numerator when
calculating the ratio between the two properties. Additionally, users can configure whether the ratio must be strictly
greater than the threshold, or if equal should be considered acceptable for the state to trigger. */
#pragma once
namespace CalculatorApp::Views::StateTriggers
{
public enum class Aspect
{
Height,
Width
};
public ref class AspectRatioTrigger sealed : public Windows::UI::Xaml::StateTriggerBase
{
public:
AspectRatioTrigger();
DEPENDENCY_PROPERTY_OWNER(AspectRatioTrigger);
/* The source for which this class will respond to size changed events. */
DEPENDENCY_PROPERTY_WITH_CALLBACK(Windows::UI::Xaml::FrameworkElement^, Source);
/* Either Height or Width. The property will determine which aspect is used as the numerator when calculating
the aspect ratio. */
DEPENDENCY_PROPERTY(Aspect, NumeratorAspect);
/* The threshold that will cause the trigger to fire when the aspect ratio exceeds this value. */
DEPENDENCY_PROPERTY_WITH_DEFAULT(double, Threshold, 0.0);
/* If true, the trigger will fire if the aspect ratio is greater than or equal to the threshold. */
DEPENDENCY_PROPERTY_WITH_DEFAULT(bool, ActiveIfEqual, false);
private:
~AspectRatioTrigger();
void OnSourcePropertyChanged(Windows::UI::Xaml::FrameworkElement^ oldValue, Windows::UI::Xaml::FrameworkElement^ newValue);
void RegisterSizeChanged(Windows::UI::Xaml::FrameworkElement^ element);
void UnregisterSizeChanged(Windows::UI::Xaml::FrameworkElement^ element);
void OnSizeChanged(Platform::Object^ sender, Windows::UI::Xaml::SizeChangedEventArgs^ e);
void UpdateIsActive(Windows::Foundation::Size sourceSize);
private:
Windows::Foundation::EventRegistrationToken m_sizeChangedToken;
};
}

View File

@@ -0,0 +1,107 @@
<UserControl x:Class="CalculatorApp.SupplementaryResults"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:common="using:CalculatorApp.Common"
xmlns:controls="using:CalculatorApp.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:designdata="using:CalculatorApp.DesignData"
xmlns:local="using:CalculatorApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:CalculatorApp.ViewModel"
d:DesignHeight="300"
d:DesignWidth="400"
mc:Ignorable="d">
<UserControl.Resources>
<DataTemplate x:Name="SupplementaryValueTemplate" x:DataType="vm:SupplementaryResult">
<StackPanel Margin="0" Orientation="Horizontal">
<TextBlock Margin="0,0,4,0"
Padding="0"
VerticalAlignment="Bottom"
Style="{ThemeResource BaseTextBlockStyle}"
Foreground="{ThemeResource SystemControlPageTextBaseHighBrush}"
AutomationProperties.AutomationId="SupplementaryResultValue"
IsTextScaleFactorEnabled="False"
Text="{x:Bind Value}"/>
<TextBlock Margin="0,0,16,0"
Padding="0"
VerticalAlignment="Bottom"
Style="{ThemeResource BodyTextBlockStyle}"
Foreground="{ThemeResource SystemControlPageTextBaseMediumBrush}"
AutomationProperties.AutomationId="SupplementaryResultUnit"
IsTextScaleFactorEnabled="False"
Text="{x:Bind Unit.Abbreviation}"/>
</StackPanel>
</DataTemplate>
<local:DelighterUnitToStyleConverter x:Key="DelighterUnitStyleConverter"/>
<DataTemplate x:Name="DelighterValueTemplate" x:DataType="vm:SupplementaryResult">
<StackPanel Margin="0" Orientation="Horizontal">
<TextBlock VerticalAlignment="Bottom"
Style="{Binding Unit, Converter={StaticResource DelighterUnitStyleConverter}, Mode=OneTime}"
AutomationProperties.AutomationId="DelighterResultGlyph"/>
<TextBlock Margin="-2,0,4,0"
Padding="0"
VerticalAlignment="Bottom"
Style="{ThemeResource BaseTextBlockStyle}"
Foreground="{ThemeResource SystemControlPageTextBaseHighBrush}"
AutomationProperties.AutomationId="DelighterResultValue"
IsTextScaleFactorEnabled="False"
Text="{x:Bind Value}"/>
<TextBlock Margin="0"
Padding="0"
VerticalAlignment="Bottom"
Style="{ThemeResource BodyTextBlockStyle}"
Foreground="{ThemeResource SystemControlPageTextBaseMediumBrush}"
AutomationProperties.AutomationId="DelighterResultUnit"
IsTextScaleFactorEnabled="False"
Text="{x:Bind Unit.Abbreviation}"/>
</StackPanel>
</DataTemplate>
<local:SupplementaryResultDataTemplateSelector x:Key="ResultTemplateSelector"
DelighterTemplate="{StaticResource DelighterValueTemplate}"
RegularTemplate="{StaticResource SupplementaryValueTemplate}"/>
<Style x:Key="SupplementaryValuesStyle" TargetType="controls:SupplementaryItemsControl">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:SupplementaryItemsControl">
<ItemsPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemContainerTransitions">
<Setter.Value>
<TransitionCollection/>
</Setter.Value>
</Setter>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<StackPanel>
<TextBlock x:Uid="SupplementaryResultsHeader"
Margin="0,0,0,-6"
HorizontalAlignment="Left"
Style="{ThemeResource CaptionTextBlockStyle}"
Foreground="{ThemeResource SystemControlPageTextBaseMediumBrush}"
IsTextScaleFactorEnabled="False"
Text="Also equal to"/>
<controls:SupplementaryItemsControl x:Name="SupplementaryValues"
MinHeight="27"
HorizontalAlignment="Left"
Style="{ThemeResource SupplementaryValuesStyle}"
IsTextScaleFactorEnabled="False"
ItemTemplateSelector="{StaticResource ResultTemplateSelector}"
LayoutUpdated="OnSupplementaryValuesLayoutUpdated"/>
</StackPanel>
</UserControl>

View File

@@ -0,0 +1,135 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//
// SupplementaryResults.xaml.cpp
// Implementation of the SupplementaryResults class
//
#include "pch.h"
#include "SupplementaryResults.xaml.h"
using namespace CalculatorApp;
using namespace Platform;
using namespace Platform::Collections;
using namespace ViewModel;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Interop;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236
Object^ DelighterUnitToStyleConverter::Convert(Object^ value, TypeName /*targetType*/, Object^ /*parameter*/, String^ /*language*/)
{
Unit^ unit = safe_cast<Unit^>(value);
assert(unit->GetModelUnit().isWhimsical);
if (!unit->GetModelUnit().isWhimsical)
{
return nullptr;
}
std::wstring key = L"Unit_";
key.append(std::to_wstring(unit->GetModelUnit().id));
return safe_cast<IStyle^>(m_delighters->Lookup(ref new String(key.c_str())));
}
Object^ DelighterUnitToStyleConverter::ConvertBack(Object^ /*value*/, TypeName /*targetType*/, Object^ /*parameter*/, String^ /*language*/)
{
// We never use convert back, only one way binding supported
assert(false);
return nullptr;
}
Windows::UI::Xaml::DataTemplate^ SupplementaryResultDataTemplateSelector::SelectTemplateCore(Object^ item, DependencyObject^ /*container*/)
{
SupplementaryResult^ result = safe_cast<SupplementaryResult^>(item);
if (result->IsWhimsical())
{
return DelighterTemplate;
}
else
{
return RegularTemplate;
}
}
SupplementaryResults::SupplementaryResults() :
m_data(ref new Vector<SupplementaryResult^>)
{
InitializeComponent();
this->Loaded += ref new RoutedEventHandler(this, &SupplementaryResults::OnLoaded);
}
void SupplementaryResults::RefreshData()
{
// Copy the list so that when we chop stuff off, we dont modify the original
// complete list.
m_data->Clear();
for(SupplementaryResult^ sr : safe_cast<UnitConverterViewModel^>(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<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 == UnitConverterViewModelProperties::SupplementaryResults)
{
RefreshData();
}
}
void SupplementaryResults::OnWindowSizeChanged(Platform::Object^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ e)
{
// to reload supplementary results everytime 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. Unforunately
// 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);
}
}
}
}
}

View File

@@ -0,0 +1,75 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//
// SupplementaryResults.xaml.h
// Declaration of the SupplementaryResults class
//
#pragma once
#include "Views\SupplementaryResults.g.h"
#include "Controls\SupplementaryItemsControl.h"
#include "Controls\OperandTextBox.h"
#include "Controls\OperatorTextBox.h"
#include "CalcViewModel\UnitConverterViewModel.h"
namespace CalculatorApp
{
public ref class DelighterUnitToStyleConverter sealed : public Windows::UI::Xaml::Data::IValueConverter
{
public:
DelighterUnitToStyleConverter()
{
m_delighters = ref new Windows::UI::Xaml::ResourceDictionary();
m_delighters->Source = ref new Windows::Foundation::Uri(L"ms-appx:///Views/DelighterUnitStyles.xaml");
}
internal:
virtual Platform::Object^ Convert(Platform::Object^ value, Windows::UI::Xaml::Interop::TypeName targetType, Platform::Object^ parameter, Platform::String^ language) = Windows::UI::Xaml::Data::IValueConverter::Convert;
virtual Platform::Object^ ConvertBack(Platform::Object^ value, Windows::UI::Xaml::Interop::TypeName targetType, Platform::Object^ parameter, Platform::String^ language) = Windows::UI::Xaml::Data::IValueConverter::ConvertBack;
private:
Windows::UI::Xaml::ResourceDictionary^ m_delighters;
};
public ref class SupplementaryResultDataTemplateSelector sealed : public Windows::UI::Xaml::Controls::DataTemplateSelector
{
public:
SupplementaryResultDataTemplateSelector() {}
property Windows::UI::Xaml::DataTemplate^ RegularTemplate
{
Windows::UI::Xaml::DataTemplate^ get() { return m_regularTemplate; }
void set(Windows::UI::Xaml::DataTemplate^ value) { m_regularTemplate = value; }
}
property Windows::UI::Xaml::DataTemplate^ DelighterTemplate
{
Windows::UI::Xaml::DataTemplate^ get() { return m_delighterTemplate; }
void set(Windows::UI::Xaml::DataTemplate^ value) { m_delighterTemplate = value; }
}
protected:
virtual Windows::UI::Xaml::DataTemplate^ SelectTemplateCore(Platform::Object^ item, Windows::UI::Xaml::DependencyObject^ container) override;
private:
Windows::UI::Xaml::DataTemplate^ m_regularTemplate;
Windows::UI::Xaml::DataTemplate^ m_delighterTemplate;
};
[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;
};
}

View File

@@ -0,0 +1,23 @@
<UserControl x:Class="CalculatorApp.TitleBar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid x:Name="LayoutRoot"
Height="32"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
Background="{ThemeResource TitleBarBackgroundTransparentBrush}">
<TextBlock x:Name="AppName"
x:Uid="AppName"
Margin="12,0,12,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Foreground="{ThemeResource TitleBarForegroundBaseHighBrush}"
FontSize="12"
TextAlignment="Left"
TextTrimming="CharacterEllipsis"/>
</Grid>
</UserControl>

View File

@@ -0,0 +1,116 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "pch.h"
#include "TitleBar.xaml.h"
#include "CalcViewModel\Common\AppResourceProvider.h"
using namespace std;
using namespace Platform;
using namespace Windows::ApplicationModel;
using namespace Windows::ApplicationModel::Core;
using namespace Windows::Foundation;
using namespace Windows::UI::Xaml;
using namespace Windows::Foundation::Collections;
namespace CalculatorApp
{
TitleBar::TitleBar() :
m_coreTitleBar(CoreApplication::GetCurrentView()->TitleBar)
{
InitializeComponent();
Loaded += ref new RoutedEventHandler(this, &TitleBar::OnLoaded);
Unloaded += ref new RoutedEventHandler(this, &TitleBar::OnUnloaded);
m_coreTitleBar->ExtendViewIntoTitleBar = true;
this->Initialize();
}
void TitleBar::OnLoaded(_In_ Object^ sender, _In_ RoutedEventArgs^ e)
{
this->RegisterForLayoutChanged();
this->RegisterForVisibilityChanged();
}
void TitleBar::OnUnloaded(_In_ Object^ sender, _In_ RoutedEventArgs^ e)
{
m_coreTitleBar->LayoutMetricsChanged -= m_layoutChangedToken;
m_coreTitleBar->IsVisibleChanged -= m_visibilityChangedToken;
}
void TitleBar::Initialize()
{
SetTitleBarText(AppResourceProvider::GetInstance().GetResourceString(L"AppName"));
SetTitleBarHeight(m_coreTitleBar->Height);
SetTitleBarVisibility(m_coreTitleBar->IsVisible);
SetTitleBarPadding();
SetTitleBar();
}
void TitleBar::RegisterForLayoutChanged()
{
m_layoutChangedToken =
m_coreTitleBar->LayoutMetricsChanged += ref new TypedEventHandler<CoreApplicationViewTitleBar^, Object^>(
[this](CoreApplicationViewTitleBar^ cTitleBar, Object^)
{
// Update title bar control size as needed to account for system size changes
SetTitleBarHeight(cTitleBar->Height);
SetTitleBarPadding();
});
}
void TitleBar::RegisterForVisibilityChanged()
{
m_visibilityChangedToken =
m_coreTitleBar->IsVisibleChanged += ref new TypedEventHandler<CoreApplicationViewTitleBar^, Object^>(
[this](CoreApplicationViewTitleBar^ cTitleBar, Object^)
{
// Update title bar visibility
SetTitleBarVisibility(cTitleBar->IsVisible);
});
}
void TitleBar::SetTitleBarText(String^ text)
{
this->AppName->Text = text;
}
void TitleBar::SetTitleBarHeight(double height)
{
this->Height = height;
}
void TitleBar::SetTitleBarVisibility(bool isVisible)
{
this->Visibility = isVisible ? ::Visibility::Visible : ::Visibility::Collapsed;
}
void TitleBar::SetTitleBarPadding()
{
double leftAddition = 0;
double rightAddition = 0;
if (this->FlowDirection == ::FlowDirection::LeftToRight)
{
leftAddition = m_coreTitleBar->SystemOverlayLeftInset;
rightAddition = m_coreTitleBar->SystemOverlayRightInset;
}
else
{
leftAddition = m_coreTitleBar->SystemOverlayRightInset;
rightAddition = m_coreTitleBar->SystemOverlayLeftInset;
}
auto padding = Thickness(leftAddition, 0, rightAddition, 0);
this->LayoutRoot->Margin = padding;
}
void TitleBar::SetTitleBar()
{
Window::Current->SetTitleBar(this->LayoutRoot);
}
}

View File

@@ -0,0 +1,32 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
#include "Views\TitleBar.g.h"
namespace CalculatorApp
{
public ref class TitleBar sealed
{
public:
TitleBar();
void SetTitleBar();
private:
void OnLoaded(_In_ Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void OnUnloaded(_In_ Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void Initialize();
void RegisterForLayoutChanged();
void RegisterForVisibilityChanged();
void SetTitleBarText(Platform::String^ text);
void SetTitleBarHeight(double height);
void SetTitleBarVisibility(bool isVisible);
void SetTitleBarPadding();
Platform::Agile<Windows::ApplicationModel::Core::CoreApplicationViewTitleBar^> m_coreTitleBar;
Windows::Foundation::EventRegistrationToken m_layoutChangedToken;
Windows::Foundation::EventRegistrationToken m_visibilityChangedToken;
};
}

View File

@@ -0,0 +1,725 @@
<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"
xmlns:common="using:CalculatorApp.Common"
xmlns:controls="using:CalculatorApp.Controls"
xmlns:converters="using:CalculatorApp.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:CalculatorApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:triggers="using:CalculatorApp.Views.StateTriggers"
xmlns:vm="using:CalculatorApp.ViewModel"
d:DesignHeight="658"
d:DesignWidth="830"
DataContextChanged="OnDataContextChanged"
FlowDirection="LeftToRight"
Loaded="OnLoaded"
mc:Ignorable="d">
<UserControl.Resources>
<common:VisibilityNegationConverter x:Name="VisibilityNegationConverter"/>
<common:AlwaysSelectedCollectionViewConverter x:Name="AlwaysSelectedConverter"/>
<common:ValidSelectedItemConverter x:Name="ValidSelectedItemConverter"/>
<converters:BooleanToVisibilityConverter x:Name="BooleanToVisibilityConverter"/>
<converters:BooleanToVisibilityNegationConverter x:Name="BooleanToVisibilityNegationConverter"/>
<automation:NarratorNotifier x:Name="NarratorNotifier" Announcement="{x:Bind Model.Announcement, Mode=OneWay}"/>
<DataTemplate x:Key="UnitTemplate" x:DataType="vm:Unit">
<TextBlock Style="{ThemeResource BodyTextBlockStyle}"
AutomationProperties.Name="{x:Bind AccessibleName}"
Text="{x:Bind Name}"
TextWrapping="NoWrap"/>
</DataTemplate>
<DataTemplate x:Key="SelectedUnitTemplate" x:DataType="vm:Unit">
<TextBlock Style="{ThemeResource BodyTextBlockStyle}"
FontWeight="SemiBold"
AutomationProperties.Name="{x:Bind AccessibleName}"
Text="{x:Bind Name}"
TextWrapping="NoWrap"/>
</DataTemplate>
<Style x:Key="ComboStyle" TargetType="ComboBox">
<Setter Property="Padding" Value="12,0,0,0"/>
<Setter Property="MinHeight" Value="32"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="Background" Value="{ThemeResource SystemControlBackgroundTransparentBrush}"/>
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumLowBrush}"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="TabNavigation" Value="Once"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled"/>
<Setter Property="ScrollViewer.VerticalScrollMode" Value="Auto"/>
<Setter Property="ScrollViewer.IsVerticalRailEnabled" Value="True"/>
<Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False"/>
<Setter Property="ScrollViewer.BringIntoViewOnFocusChange" Value="True"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="IsTextScaleFactorEnabled" Value="False"/>
<Setter Property="UseSystemFocusVisuals" Value="True"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<CarouselPanel/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="BackgroundElement.Background" Value="{ThemeResource SystemControlHighlightTransparentBrush}"/>
<Setter Target="SelectedContentPresenter.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseMediumHighBrush}"/>
<Setter Target="DropDownGlyph.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseMediumHighBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Target="BackgroundElement.Background" Value="{ThemeResource SystemControlHighlightTransparentBrush}"/>
<Setter Target="SelectedContentPresenter.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseMediumBrush}"/>
<Setter Target="DropDownGlyph.Foreground" Value="{ThemeResource SystemControlHighlightAltBaseMediumBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
<VisualStateGroup x:Name="DropDownStates">
<VisualState x:Name="Opened">
<Storyboard>
<SplitOpenThemeAnimation ClosedTargetName="SelectedContentPresenter"
OffsetFromCenter="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.DropDownOffset}"
OpenedLength="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.DropDownOpenedHeight}"
OpenedTargetName="PopupBorder"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Closed">
<Storyboard>
<SplitCloseThemeAnimation ClosedTargetName="SelectedContentPresenter"
OffsetFromCenter="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.DropDownOffset}"
OpenedLength="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.DropDownOpenedHeight}"
OpenedTargetName="PopupBorder"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border x:Name="BackgroundElement"
Grid.ColumnSpan="2"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"/>
<!--
This first ContentPresenter must be named "ContentPresenter" because
XAML expects it in the template and has dependencies. It is not used
because we want to style the selected item differently than the items
list but XAML forces the same style. Do not remove
this element.
-->
<ContentPresenter x:Name="ContentPresenter" Opacity="0"/>
<ContentPresenter x:Name="SelectedContentPresenter"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
AutomationProperties.AccessibilityView="Raw"
Content="{TemplateBinding SelectedItem}"
ContentTemplate="{StaticResource SelectedUnitTemplate}"
FlowDirection="{TemplateBinding FlowDirection}"/>
<TextBlock x:Name="DropDownGlyph"
Grid.Column="1"
Margin="8,3,12,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Foreground="{ThemeResource SystemControlForegroundBaseHighBrush}"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="12"
AutomationProperties.AccessibilityView="Raw"
IsHitTestVisible="False"
Text="&#xE0E5;"/>
<Popup x:Name="Popup">
<Border x:Name="PopupBorder"
Margin="0,-1,0,-1"
HorizontalAlignment="Stretch"
Background="{ThemeResource SystemControlBackgroundChromeMediumLowBrush}"
BorderBrush="{ThemeResource SystemControlForegroundChromeHighBrush}"
BorderThickness="{ThemeResource ComboBoxDropdownBorderThickness}">
<ScrollViewer x:Name="ScrollViewer"
MinWidth="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.DropDownContentMinWidth}"
Foreground="{ThemeResource SystemControlForegroundBaseHighBrush}"
AutomationProperties.AccessibilityView="Raw"
BringIntoViewOnFocusChange="{TemplateBinding ScrollViewer.BringIntoViewOnFocusChange}"
HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}"
IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}"
IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}"
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
VerticalSnapPointsAlignment="Near"
VerticalSnapPointsType="OptionalSingle"
ZoomMode="Disabled">
<ItemsPresenter/>
</ScrollViewer>
</Border>
</Popup>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ValueLargeStyle"
BasedOn="{StaticResource CalculationResultStyleL}"
TargetType="controls:CalculationResult">
<Setter Property="Background" Value="{ThemeResource SystemControlBackgroundTransparentBrush}"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Bottom"/>
<Setter Property="FontSize" Value="46"/>
<Setter Property="MinFontSize" Value="{ThemeResource BodyFontSize}"/>
<Setter Property="FontWeight" Value="Light"/>
<Setter Property="Margin" Value="-2,0,0,0"/>
<Setter Property="DisplayMargin" Value="0,0,0,12"/>
</Style>
<Style x:Key="ValueMediumStyle"
BasedOn="{StaticResource CalculationResultStyleM}"
TargetType="controls:CalculationResult">
<Setter Property="FontSize" Value="34"/>
<Setter Property="Background" Value="{ThemeResource SystemControlBackgroundTransparentBrush}"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="MinFontSize" Value="{ThemeResource BodyFontSize}"/>
<Setter Property="FontWeight" Value="Light"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Bottom"/>
<Setter Property="Margin" Value="0,0,0,0"/>
<Setter Property="DisplayMargin" Value="0,0,0,4"/>
</Style>
<Style x:Key="ValueSmallStyle"
BasedOn="{StaticResource CalculationResultStyleS}"
TargetType="controls:CalculationResult">
<Setter Property="Background" Value="{ThemeResource SystemControlBackgroundTransparentBrush}"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="FontSize" Value="24"/>
<Setter Property="MinFontSize" Value="{ThemeResource BodyFontSize}"/>
<Setter Property="FontWeight" Value="Light"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Bottom"/>
<Setter Property="Margin" Value="0,0,0,0"/>
<Setter Property="DisplayMargin" Value="0,0,0,4"/>
</Style>
<Style x:Key="CurrencySymbolBaseStyle" TargetType="TextBlock">
<Setter Property="FontWeight" Value="Light"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Bottom"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlPageTextBaseHighBrush}"/>
</Style>
<Style x:Key="CurrencySymbolLargeStyle"
BasedOn="{StaticResource CurrencySymbolBaseStyle}"
TargetType="TextBlock">
<Setter Property="FontSize" Value="32"/>
<Setter Property="Margin" Value="12,0,0,17"/>
</Style>
<Style x:Key="CurrencySymbolMediumStyle"
BasedOn="{StaticResource CurrencySymbolBaseStyle}"
TargetType="TextBlock">
<Setter Property="FontSize" Value="24"/>
<Setter Property="Margin" Value="12,0,0,8"/>
</Style>
<Style x:Key="CurrencySymbolSmallStyle"
BasedOn="{StaticResource CurrencySymbolBaseStyle}"
TargetType="TextBlock">
<Setter Property="FontSize" Value="17"/>
<Setter Property="Margin" Value="12,0,0,7"/>
</Style>
<Style x:Key="ValueContainerStyle" TargetType="Grid">
<Setter Property="AutomationProperties.AccessibilityView" Value="Raw"/>
</Style>
<Storyboard x:Name="AnimationStory">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ConverterNumPad" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)">
<EasingDoubleKeyFrame KeyTime="0" Value="0.92">
<EasingDoubleKeyFrame.EasingFunction>
<ExponentialEase EasingMode="EaseOut" Exponent="5"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
<EasingDoubleKeyFrame KeyTime="0:0:0.367" Value="1">
<EasingDoubleKeyFrame.EasingFunction>
<ExponentialEase EasingMode="EaseOut" Exponent="5"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ConverterNumPad" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)">
<EasingDoubleKeyFrame KeyTime="0" Value="0.92">
<EasingDoubleKeyFrame.EasingFunction>
<ExponentialEase EasingMode="EaseOut" Exponent="5"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
<EasingDoubleKeyFrame KeyTime="0:0:0.367" Value="1">
<EasingDoubleKeyFrame.EasingFunction>
<ExponentialEase EasingMode="EaseOut" Exponent="5"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Name="TimestampFadeInAnimation">
<DoubleAnimation Duration="0:0:1"
From="0"
Storyboard.TargetName="CurrencyTimestampTextBlock"
Storyboard.TargetProperty="Opacity"
To="1"/>
</Storyboard>
<MenuFlyout x:Key="CalculationResultContextMenu">
<MenuFlyoutItem x:Name="CopyMenuItem"
x:Uid="CopyMenuItem"
Click="OnCopyMenuItemClicked"
Icon="Copy"/>
<MenuFlyoutItem x:Name="PasteMenuItem"
x:Uid="PasteMenuItem"
Click="OnPasteMenuItemClicked"
Icon="Paste"/>
</MenuFlyout>
</UserControl.Resources>
<Grid x:Name="UnitConverterRootGrid"
HorizontalAlignment="Stretch"
AutomationProperties.LandmarkType="Main">
<Grid.RowDefinitions>
<RowDefinition x:Name="RowTopNav" Height="{StaticResource HamburgerHeightGridLength}"/>
<RowDefinition x:Name="RowDisplay1"
Height="56*"
MinHeight="56"/>
<RowDefinition x:Name="RowUnit1"
Height="32*"
MinHeight="32"/>
<RowDefinition x:Name="RowDisplay2"
Height="56*"
MinHeight="56"/>
<RowDefinition x:Name="RowUnit2"
Height="32*"
MinHeight="32"/>
<RowDefinition x:Name="RowDltrUnits"
Height="Auto"
MinHeight="48"/>
<RowDefinition x:Name="RowNumPad" Height="272*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="GutterLeft" Width="0"/>
<ColumnDefinition x:Name="ColumnLeft" Width="1*"/>
<ColumnDefinition x:Name="ColumnRight" Width="0"/>
<ColumnDefinition x:Name="GutterRight" Width="0"/>
</Grid.ColumnDefinitions>
<!-- End ConverterNumPad -->
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="Layout">
<VisualState x:Name="PortraitLayout"/>
<VisualState x:Name="LandscapeLayout">
<VisualState.StateTriggers>
<triggers:AspectRatioTrigger ActiveIfEqual="True"
NumeratorAspect="Width"
Source="{x:Bind}"
Threshold="1"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="GutterTop.Height" Value="0.5*"/>
<Setter Target="GutterBottom.Height" Value="0.5*"/>
<Setter Target="GutterLeft.Width" Value="48"/>
<Setter Target="GutterRight.Width" Value="48"/>
<Setter Target="ColumnLeft.Width" Value="1*"/>
<Setter Target="ColumnRight.Width" Value="1*"/>
<Setter Target="RowDisplay1.Height" Value="4*"/>
<Setter Target="RowUnit1.Height" Value="2*"/>
<Setter Target="RowDisplay2.Height" Value="4*"/>
<Setter Target="RowUnit2.Height" Value="2*"/>
<Setter Target="RowDltrUnits.Height" Value="2*"/>
<Setter Target="CurrencyLoadingGrid.(Grid.ColumnSpan)" Value="2"/>
<Setter Target="ConverterNumPad.(Grid.Row)" Value="1"/>
<Setter Target="ConverterNumPad.(Grid.RowSpan)" Value="5"/>
<Setter Target="ConverterNumPad.(Grid.Column)" Value="2"/>
<Setter Target="ConverterNumPad.(Grid.ColumnSpan)" Value="2"/>
<Setter Target="SupplementaryResults.VerticalAlignment" Value="Top"/>
<Setter Target="RowNumPad.MinHeight" Value="0"/>
<Setter Target="RowNumPad.Height" Value="0"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="Sizing">
<VisualState x:Name="Wide">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="768" MinWindowWidth="1280"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="Value1.Style" Value="{ThemeResource ValueLargeStyle}"/>
<Setter Target="Value2.Style" Value="{ThemeResource ValueLargeStyle}"/>
<Setter Target="CurrencySymbol1Block.Style" Value="{ThemeResource CurrencySymbolLargeStyle}"/>
<Setter Target="CurrencySymbol2Block.Style" Value="{ThemeResource CurrencySymbolLargeStyle}"/>
<Setter Target="Units1.Height" Value="44"/>
<Setter Target="Units2.Height" Value="44"/>
<Setter Target="converterNegateButton.FontSize" Value="24"/>
<Setter Target="clearEntryButtonPos0.FontSize" Value="24"/>
<Setter Target="backSpaceButtonSmall.FontSize" Value="24"/>
<Setter Target="numberPad.ButtonStyle" Value="{StaticResource NumericButtonStyle46}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Portrait">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="1024" MinWindowWidth="640"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="SupplementaryResults.VerticalAlignment" Value="Top"/>
<Setter Target="Value1.Style" Value="{ThemeResource ValueLargeStyle}"/>
<Setter Target="Value2.Style" Value="{ThemeResource ValueLargeStyle}"/>
<Setter Target="CurrencySymbol1Block.Style" Value="{ThemeResource CurrencySymbolLargeStyle}"/>
<Setter Target="CurrencySymbol2Block.Style" Value="{ThemeResource CurrencySymbolLargeStyle}"/>
<Setter Target="Units1.Height" Value="44"/>
<Setter Target="Units2.Height" Value="44"/>
<Setter Target="converterNegateButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="clearEntryButtonPos0.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="numberPad.ButtonStyle" Value="{StaticResource NumericButtonStyle34}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Wide640">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="0" MinWindowWidth="640"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="Value1.Style" Value="{ThemeResource ValueLargeStyle}"/>
<Setter Target="Value2.Style" Value="{ThemeResource ValueLargeStyle}"/>
<Setter Target="CurrencySymbol1Block.Style" Value="{ThemeResource CurrencySymbolLargeStyle}"/>
<Setter Target="CurrencySymbol2Block.Style" Value="{ThemeResource CurrencySymbolLargeStyle}"/>
<Setter Target="Units1.Height" Value="44"/>
<Setter Target="Units2.Height" Value="44"/>
<Setter Target="converterNegateButton.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="clearEntryButtonPos0.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="backSpaceButtonSmall.FontSize" Value="{StaticResource CalcStandardOperatorCaptionSize}"/>
<Setter Target="numberPad.ButtonStyle" Value="{StaticResource NumericButtonStyle34}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="MinSizeLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="{StaticResource AppMinWindowHeight}" MinWindowWidth="{StaticResource AppMinWindowWidth}"/>
</VisualState.StateTriggers>
</VisualState>
<VisualState x:Name="DefaultLayout">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowHeight="0" MinWindowWidth="0"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="clearEntryButtonPos0.Margin" Value="1"/>
<Setter Target="backSpaceButtonSmall.Margin" Value="1"/>
<Setter Target="converterNegateButton.Margin" Value="1"/>
<Setter Target="numberPad.ButtonStyle" Value="{StaticResource NumericButtonStyle18}"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CurrencyTimestampStates">
<VisualState x:Name="DefaultTimestamp">
<VisualState.Setters>
<Setter Target="CurrencyTimestampTextBlock.Foreground" Value="{ThemeResource SystemControlPageTextBaseHighBrush}"/>
<Setter Target="CurrencyTimestampTextBlock.FontWeight" Value="Normal"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="WeekOldTimestamp">
<VisualState.Setters>
<Setter Target="CurrencyTimestampTextBlock.Foreground" Value="{ThemeResource AppControlPageTextRedColorBrush}"/>
<Setter Target="CurrencyTimestampTextBlock.FontWeight" Value="SemiBold"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CurrencySecondaryStatusStates">
<VisualState x:Name="ChargesMayApplyCurrencyStatus">
<VisualState.Setters>
<Setter Target="CurrencySecondaryStatus.Foreground" Value="{ThemeResource AppControlPageTextBaseHighColorBrush}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="FailedCurrencyStatus">
<VisualState.Setters>
<Setter Target="CurrencySecondaryStatus.Foreground" Value="{ThemeResource AppControlPageTextRedColorBrush}"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid x:Name="CurrencyLoadingGrid"
Grid.Row="1"
Grid.RowSpan="5"
Grid.Column="0"
Grid.ColumnSpan="4"
Visibility="{x:Bind Model.IsCurrencyLoadingVisible, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}">
<Grid.RowDefinitions>
<RowDefinition Height="10*"/>
<RowDefinition Height="7*"/>
<RowDefinition Height="10*"/>
</Grid.RowDefinitions>
<ProgressRing x:Name="CurrencyLoadingProgressRing"
Grid.Row="1"
Grid.Column="1"
MaxWidth="140"
MaxHeight="140"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
IsActive="False"/>
</Grid>
<Grid x:Name="Value1Container"
Grid.Row="1"
Grid.Column="1"
Style="{ThemeResource ValueContainerStyle}"
FlowDirection="{x:Bind LayoutDirection}"
Visibility="{x:Bind Model.IsCurrencyLoadingVisible, Mode=OneWay, Converter={StaticResource BooleanToVisibilityNegationConverter}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="CurrencySymbol1Block"
Grid.Column="0"
Style="{ThemeResource CurrencySymbolMediumStyle}"
AutomationProperties.AccessibilityView="Raw"
Text="{x:Bind Model.CurrencySymbol1, Mode=OneWay}"
Visibility="{x:Bind Model.CurrencySymbolVisibility, Mode=OneWay}"/>
<controls:CalculationResult x:Name="Value1"
Grid.Column="1"
Style="{ThemeResource ValueMediumStyle}"
AutomationProperties.AutomationId="Value1"
AutomationProperties.Name="{x:Bind Model.Value1AutomationName, Mode=OneWay}"
ContextCanceled="OnContextCanceled"
ContextRequested="OnContextRequested"
DisplayValue="{x:Bind Model.Value1, Mode=OneWay}"
ExpressionVisibility="Collapsed"
FlowDirection="{x:Bind LayoutDirection}"
IsActive="{Binding Value1Active, Mode=TwoWay}"
KeyDown="OnValueKeyDown"
RenderTransformOrigin="0.5,0.5"
Selected="OnValueSelected"
TabIndex="1">
<controls:CalculationResult.RenderTransform>
<CompositeTransform/>
</controls:CalculationResult.RenderTransform>
</controls:CalculationResult>
</Grid>
<ComboBox x:Name="Units1"
Grid.Row="2"
Grid.Column="1"
Style="{ThemeResource ComboStyle}"
AutomationProperties.AutomationId="Units1"
AutomationProperties.Name="{x:Bind Model.Unit1AutomationName, Mode=OneWay}"
DropDownClosed="UpdateDropDownState"
DropDownOpened="UpdateDropDownState"
FlowDirection="{x:Bind LayoutDirection}"
IsEnabled="{Binding IsDropDownEnabled}"
IsEnabledChanged="Units1_IsEnabledChanged"
ItemTemplate="{StaticResource UnitTemplate}"
ItemsSource="{Binding Units, Converter={StaticResource AlwaysSelectedConverter}}"
SelectedItem="{Binding Unit1, Mode=TwoWay, Converter={StaticResource ValidSelectedItemConverter}}"
TabIndex="2"
Visibility="{x:Bind Model.IsCurrencyLoadingVisible, Mode=OneWay, Converter={StaticResource BooleanToVisibilityNegationConverter}}"/>
<Grid x:Name="Value2Container"
Grid.Row="3"
Grid.Column="1"
Style="{ThemeResource ValueContainerStyle}"
FlowDirection="{x:Bind LayoutDirection}"
Visibility="{x:Bind Model.IsCurrencyLoadingVisible, Mode=OneWay, Converter={StaticResource BooleanToVisibilityNegationConverter}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="CurrencySymbol2Block"
Grid.Column="0"
Style="{ThemeResource CurrencySymbolMediumStyle}"
AutomationProperties.AccessibilityView="Raw"
Text="{x:Bind Model.CurrencySymbol2, Mode=OneWay}"
Visibility="{x:Bind Model.CurrencySymbolVisibility, Mode=OneWay}"/>
<controls:CalculationResult x:Name="Value2"
Grid.Column="1"
Style="{ThemeResource ValueMediumStyle}"
AutomationProperties.AutomationId="Value2"
AutomationProperties.LiveSetting="Polite"
AutomationProperties.Name="{x:Bind Model.Value2AutomationName, Mode=OneWay}"
ContextCanceled="OnContextCanceled"
ContextRequested="OnContextRequested"
DisplayValue="{x:Bind Model.Value2, Mode=OneWay}"
ExpressionVisibility="Collapsed"
FlowDirection="{x:Bind LayoutDirection}"
IsActive="{Binding Value2Active, Mode=TwoWay}"
KeyDown="OnValueKeyDown"
RenderTransformOrigin="0.5,0.5"
Selected="OnValueSelected"
TabIndex="3">
<controls:CalculationResult.RenderTransform>
<CompositeTransform/>
</controls:CalculationResult.RenderTransform>
</controls:CalculationResult>
</Grid>
<ComboBox x:Name="Units2"
Grid.Row="4"
Grid.Column="1"
Style="{ThemeResource ComboStyle}"
AutomationProperties.AutomationId="Units2"
AutomationProperties.Name="{x:Bind Model.Unit2AutomationName, Mode=OneWay}"
DropDownClosed="UpdateDropDownState"
DropDownOpened="UpdateDropDownState"
FlowDirection="{x:Bind LayoutDirection}"
IsEnabled="{Binding IsDropDownEnabled}"
ItemTemplate="{StaticResource UnitTemplate}"
ItemsSource="{Binding Units, Converter={StaticResource AlwaysSelectedConverter}}"
SelectedItem="{Binding Unit2, Mode=TwoWay, Converter={StaticResource ValidSelectedItemConverter}}"
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}}">
<local:SupplementaryResults x:Name="SupplementaryResults"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Visibility="{x:Bind Model.SupplementaryVisibility, Mode=OneWay}"/>
<StackPanel Visibility="{x:Bind Model.IsCurrencyCurrentCategory, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}">
<!-- Currency Ratio Equality -->
<TextBlock x:Name="CurrencyRatioEqualityBlock"
Style="{ThemeResource CaptionTextBlockStyle}"
Foreground="{ThemeResource SystemControlPageTextBaseHighBrush}"
AutomationProperties.Name="{x:Bind Model.CurrencyRatioEqualityAutomationName, Mode=OneWay}"
Text="{x:Bind Model.CurrencyRatioEquality, Mode=OneWay}"/>
<!-- Currency Timestamp -->
<TextBlock x:Name="CurrencyTimestampTextBlock"
Style="{ThemeResource CaptionTextBlockStyle}"
Text="{x:Bind Model.CurrencyTimestamp, Mode=OneWay}"/>
<!-- Currency Refresh button and additional status text -->
<ContentControl x:Name="CurrencyRefreshBlockControl"
IsTabStop="False"
TabIndex="5"
Visibility="Collapsed">
<TextBlock x:Name="CurrencyRefreshBlock"
Style="{ThemeResource CaptionTextBlockStyle}"
AutomationProperties.AccessibilityView="Raw">
<Hyperlink Foreground="{ThemeResource SystemControlHyperlinkBaseHighBrush}" Click="CurrencyRefreshButton_Click">
<Run x:Uid="RefreshButtonText"/>
</Hyperlink>
<Run x:Name="Spacing" Text="&#x200A;"/>
<Run x:Name="CurrencySecondaryStatus"
FontWeight="SemiBold"
Text=""/>
</TextBlock>
</ContentControl>
<!-- Offline TextBlock -->
<ContentControl x:Name="OfflineBlock"
IsTabStop="False"
TabIndex="5"
Visibility="Collapsed">
<TextBlock Style="{ThemeResource CaptionTextBlockStyle}"
Foreground="{ThemeResource SystemControlPageTextBaseHighBrush}"
AutomationProperties.AccessibilityView="Raw">
<Run x:Name="OfflineRunBeforeLink"/>
<Hyperlink NavigateUri="ms-settings:network-status">
<Run x:Name="OfflineRunLink"/>
</Hyperlink>
<Run x:Name="OfflineRunAfterLink"/>
</TextBlock>
</ContentControl>
</StackPanel>
</Grid>
<Grid x:Name="ConverterNumPad"
Grid.Row="6"
Grid.Column="1"
Margin="0,0,0,6"
FlowDirection="LeftToRight"
RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<CompositeTransform/>
</Grid.RenderTransform>
<Grid.RowDefinitions>
<RowDefinition x:Name="GutterTop" Height="0"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition x:Name="GutterBottom" Height="0"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.25*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="0.25*"/>
</Grid.ColumnDefinitions>
<Grid x:Uid="DisplayControls"
Grid.Row="1"
Grid.Column="2"
Grid.ColumnSpan="2"
AutomationProperties.HeadingLevel="Level1">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<controls:CalculatorButton x:Name="clearEntryButtonPos0"
x:Uid="clearEntryButton"
HorizontalAlignment="Stretch"
Style="{StaticResource OperatorButtonStyle}"
FontSize="16"
ButtonId="Clear"
Content="CE"
TabIndex="7"/>
<controls:CalculatorButton x:Name="backSpaceButtonSmall"
x:Uid="backSpaceButton"
Grid.Column="1"
Style="{StaticResource SymbolOperatorButtonStyle}"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="16"
ButtonId="Backspace"
Content="&#xE750;"
TabIndex="8"/>
</Grid>
<local:NumberPad x:Name="numberPad"
x:Uid="NumberPad"
Grid.Row="2"
Grid.RowSpan="4"
Grid.Column="1"
Grid.ColumnSpan="3"
VerticalAlignment="Stretch"
AutomationProperties.HeadingLevel="Level1"
ButtonStyle="{StaticResource NumericButtonStyle24}"
TabIndex="10"
TabNavigation="Local"/>
<controls:CalculatorButton x:Name="converterNegateButton"
x:Uid="converterNegateButton"
Grid.Row="5"
Grid.Column="1"
Style="{StaticResource SymbolOperatorButtonStyle}"
FontSize="16"
ButtonId="Negate"
Content="&#xe94d;"
TabIndex="6"
Visibility="{x:Bind Model.CurrentCategory.NegateVisibility, Mode=OneWay}"/>
</Grid>
<!-- End ConverterNumPad -->
</Grid>
</UserControl>

View File

@@ -0,0 +1,388 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// UnitConverter.xaml.cpp
// Implementation of the UnitConverter class
#include "pch.h"
#include "UnitConverter.xaml.h"
#include "CalcViewModel\UnitConverterViewModel.h"
#include "Controls\CalculationResult.h"
#include "Controls\CalculatorButton.h"
#include "CalcViewModel\Common\CopyPasteManager.h"
#include "CalcViewModel\Common\KeyboardShortcutManager.h"
#include "CalcViewModel\Common\LocalizationService.h"
#include "CalcViewModel\Common\LocalizationSettings.h"
using namespace CalculatorApp;
using namespace CalculatorApp::Common;
using namespace CalculatorApp::Controls;
using namespace concurrency;
using namespace Windows::System;
using namespace Platform;
using namespace ViewModel;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Core;
using namespace Windows::UI::Text;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Automation;
using namespace Windows::UI::Xaml::Automation::Peers;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Documents;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Interop;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
using namespace Windows::UI::ViewManagement;
// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236
// Calculate number of 100-nanosecond intervals in 500 milliseconds.
// There are 10,000 intervals in 1 ms.
static const long long DURATION_500_MS = 10000 * 500;
UnitConverter::UnitConverter() :
m_layoutDirection(::FlowDirection::LeftToRight),
m_meteredConnectionOverride(false),
m_isAnimationEnabled(false)
{
InitializeComponent();
//adding ESC key shortcut binding to clear button
clearEntryButtonPos0->SetValue(Common::KeyboardShortcutManager::VirtualKeyProperty, Common::MyVirtualKey::Escape);
m_layoutDirection = LocalizationService::GetInstance()->GetFlowDirection();
if (m_layoutDirection == ::FlowDirection::RightToLeft)
{
Units1->HorizontalContentAlignment = ::HorizontalAlignment::Right;
Units2->HorizontalContentAlignment = ::HorizontalAlignment::Right;
}
// Is currency symbol preference set to right side
bool preferRight = LocalizationSettings::GetInstance().GetCurrencySymbolPrecedence() == 0;
if (preferRight)
{
// Currency symbol should appear on the right. Reverse the order of children.
Grid::SetColumn(Value1, 0);
Grid::SetColumn(CurrencySymbol1Block, 1);
Grid::SetColumn(Value2, 0);
Grid::SetColumn(CurrencySymbol2Block, 1);
}
auto userSettings = ref new UISettings();
m_isAnimationEnabled = userSettings->AnimationsEnabled;
auto resLoader = AppResourceProvider::GetInstance();
m_chargesMayApplyText = resLoader.GetResourceString(L"DataChargesMayApply");
m_failedToRefreshText = resLoader.GetResourceString(L"FailedToRefresh");
InitializeOfflineStatusTextBlock();
m_resultsFlyout = static_cast<MenuFlyout^>(Resources->Lookup(L"CalculationResultContextMenu"));
CopyMenuItem->Text = resLoader.GetResourceString(L"copyMenuItem");
PasteMenuItem->Text = resLoader.GetResourceString(L"pasteMenuItem");
}
void UnitConverter::OnPropertyChanged(_In_ Object^ sender, _In_ PropertyChangedEventArgs^ e)
{
String^ propertyName = e->PropertyName;
if (propertyName->Equals(UnitConverterViewModelProperties::NetworkBehavior) ||
propertyName->Equals(UnitConverterViewModelProperties::CurrencyDataLoadFailed))
{
OnNetworkBehaviorChanged();
}
else if (propertyName->Equals(UnitConverterViewModelProperties::CurrencyDataIsWeekOld))
{
SetCurrencyTimestampFontWeight();
}
else if (propertyName->Equals(UnitConverterViewModelProperties::IsCurrencyLoadingVisible))
{
OnIsDisplayVisibleChanged();
}
}
void UnitConverter::OnNetworkBehaviorChanged()
{
switch (Model->NetworkBehavior)
{
case NetworkAccessBehavior::Normal:
OnNormalNetworkAccess();
break;
case NetworkAccessBehavior::OptIn:
OnOptInNetworkAccess();
break;
case NetworkAccessBehavior::Offline:
OnOfflineNetworkAccess();
break;
}
}
void UnitConverter::OnNormalNetworkAccess()
{
CurrencyRefreshBlockControl->Visibility = ::Visibility::Visible;
OfflineBlock->Visibility = ::Visibility::Collapsed;
if (Model->CurrencyDataLoadFailed)
{
SetFailedToRefreshStatus();
}
else
{
SetNormalCurrencyStatus();
}
}
void UnitConverter::OnOptInNetworkAccess()
{
CurrencyRefreshBlockControl->Visibility = ::Visibility::Visible;
OfflineBlock->Visibility = ::Visibility::Collapsed;
if (m_meteredConnectionOverride && Model->CurrencyDataLoadFailed)
{
SetFailedToRefreshStatus();
}
else
{
SetChargesMayApplyStatus();
}
}
void UnitConverter::OnOfflineNetworkAccess()
{
CurrencyRefreshBlockControl->Visibility = ::Visibility::Collapsed;
OfflineBlock->Visibility = ::Visibility::Visible;
}
void UnitConverter::SetNormalCurrencyStatus()
{
AutomationProperties::SetAccessibilityView(CurrencyRefreshBlock, AccessibilityView::Raw);
CurrencySecondaryStatus->Text = L"";
}
void UnitConverter::SetChargesMayApplyStatus()
{
VisualStateManager::GoToState(this, L"ChargesMayApplyCurrencyStatus", false);
CurrencySecondaryStatus->Text = m_chargesMayApplyText;
}
void UnitConverter::SetFailedToRefreshStatus()
{
VisualStateManager::GoToState(this, L"FailedCurrencyStatus", false);
CurrencySecondaryStatus->Text = m_failedToRefreshText;
}
void UnitConverter::InitializeOfflineStatusTextBlock()
{
auto resProvider = AppResourceProvider::GetInstance();
std::wstring offlineStatusHyperlinkText = static_cast<String^>(resProvider.GetResourceString(L"OfflineStatusHyperlinkText"))->Data();
// The resource string has the 'NetworkSettings' hyperlink wrapped with '%HL%'.
// Break the string and assign pieces appropriately.
static const std::wstring delimiter{ L"%HL%" };
static const size_t delimiterLength{ delimiter.length() };
// Find the delimiters.
size_t firstSplitPosition = offlineStatusHyperlinkText.find(delimiter, 0);
assert(firstSplitPosition != std::wstring::npos);
size_t secondSplitPosition = offlineStatusHyperlinkText.find(delimiter, firstSplitPosition + 1);
assert(secondSplitPosition != std::wstring::npos);
size_t hyperlinkTextLength = secondSplitPosition - (firstSplitPosition + delimiterLength);
// Assign pieces.
auto offlineStatusTextBeforeHyperlink = ref new String(offlineStatusHyperlinkText.substr(0, firstSplitPosition).c_str());
auto offlineStatusTextLink = ref new String(offlineStatusHyperlinkText.substr(firstSplitPosition + delimiterLength, hyperlinkTextLength).c_str());
auto offlineStatusTextAfterHyperlink = ref new String(offlineStatusHyperlinkText.substr(secondSplitPosition + delimiterLength).c_str());
OfflineRunBeforeLink->Text = offlineStatusTextBeforeHyperlink;
OfflineRunLink->Text = offlineStatusTextLink;
OfflineRunAfterLink->Text = offlineStatusTextAfterHyperlink;
AutomationProperties::SetName(OfflineBlock,
offlineStatusTextBeforeHyperlink + L" " +
offlineStatusTextLink + L" " +
offlineStatusTextAfterHyperlink);
}
void UnitConverter::SetCurrencyTimestampFontWeight()
{
if (Model->CurrencyDataIsWeekOld)
{
VisualStateManager::GoToState(this, L"WeekOldTimestamp", false);
}
else
{
VisualStateManager::GoToState(this, L"DefaultTimestamp", false);
}
}
void UnitConverter::OnValueKeyDown(Platform::Object^ sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e)
{
if (e->Key == VirtualKey::Space)
{
OnValueSelected(sender);
}
}
void UnitConverter::OnContextRequested(UIElement^ sender, ContextRequestedEventArgs^ e)
{
OnValueSelected(sender);
auto requestedElement = safe_cast<FrameworkElement^>(sender);
PasteMenuItem->IsEnabled = CopyPasteManager::HasStringToPaste();
Point point;
if (e->TryGetPosition(requestedElement, &point))
{
m_resultsFlyout->ShowAt(requestedElement, point);
}
else
{
// Not invoked via pointer, so let XAML choose a default location.
m_resultsFlyout->ShowAt(requestedElement);
}
e->Handled = true;
}
void UnitConverter::OnContextCanceled(UIElement^ sender, RoutedEventArgs^ e)
{
m_resultsFlyout->Hide();
}
void UnitConverter::OnCopyMenuItemClicked(_In_ Object^ sender, _In_ RoutedEventArgs^ e)
{
auto calcResult = safe_cast<CalculationResult^>(m_resultsFlyout->Target);
CopyPasteManager::CopyToClipboard(calcResult->GetRawDisplayValue());
}
void UnitConverter::OnPasteMenuItemClicked(_In_ Object^ sender, _In_ RoutedEventArgs^ e)
{
CopyPasteManager::GetStringToPaste(Model->Mode, CategoryGroupType::Converter).then([this](String^ pastedString)
{
Model->OnPaste(pastedString, Model->Mode);
});
}
void UnitConverter::AnimateConverter()
{
if (App::IsAnimationEnabled())
{
AnimationStory->Begin();
}
}
void UnitConverter::OnValueSelected(_In_ Platform::Object^ sender)
{
auto value = safe_cast<CalculationResult^>(sender);
//update the font size since the font is changed to bold
value->UpdateTextState();
safe_cast<UnitConverterViewModel^>(this->DataContext)->OnValueActivated(AsActivatable(value));
}
void UnitConverter::UpdateDropDownState(_In_ Platform::Object^ sender, _In_ Platform::Object^ e)
{
safe_cast<UnitConverterViewModel^>(this->DataContext)->IsDropDownOpen = (Units1->IsDropDownOpen) || (Units2->IsDropDownOpen);
KeyboardShortcutManager::UpdateDropDownState((Units1->IsDropDownOpen) || (Units2->IsDropDownOpen));
}
void UnitConverter::OnLoaded(_In_ Object^, _In_ RoutedEventArgs^)
{
}
void UnitConverter::SetDefaultFocus()
{
const std::vector<Control^> focusPrecedence = {
Value1,
CurrencyRefreshBlockControl,
OfflineBlock,
clearEntryButtonPos0
};
for (Control^ control : focusPrecedence)
{
if (control->Focus(::FocusState::Programmatic))
{
break;
}
}
}
void UnitConverter::CurrencyRefreshButton_Click(_In_ Object^ /*sender*/, _In_ RoutedEventArgs^ /*e*/)
{
if (Model->NetworkBehavior == NetworkAccessBehavior::OptIn)
{
m_meteredConnectionOverride = true;
}
Model->RefreshCurrencyRatios();
}
void UnitConverter::OnDataContextChanged(_In_ FrameworkElement^ sender, _In_ DataContextChangedEventArgs^ args)
{
Model->PropertyChanged -= m_propertyChangedToken;
m_propertyChangedToken =
Model->PropertyChanged += ref new PropertyChangedEventHandler(this, &UnitConverter::OnPropertyChanged);
OnNetworkBehaviorChanged();
}
void UnitConverter::Units1_IsEnabledChanged(Object^ sender, DependencyPropertyChangedEventArgs^ e)
{
if ((Units1->Visibility == ::Visibility::Visible) && Units1->IsEnabled)
{
SetDefaultFocus();
}
}
void UnitConverter::OnIsDisplayVisibleChanged()
{
if (Model->IsCurrencyLoadingVisible)
{
StartProgressRingWithDelay();
}
else
{
HideProgressRing();
if (m_isAnimationEnabled && Model->IsCurrencyCurrentCategory && !Model->CurrencyTimestamp->IsEmpty())
{
TimestampFadeInAnimation->Begin();
}
}
}
void UnitConverter::StartProgressRingWithDelay()
{
HideProgressRing();
TimeSpan delay{};
delay.Duration = DURATION_500_MS;
m_delayTimer = ref new DispatcherTimer();
m_delayTimer->Interval = delay;
m_delayTimer->Tick += ref new EventHandler<Object^>(this, &UnitConverter::OnDelayTimerTick);
m_delayTimer->Start();
}
void UnitConverter::OnDelayTimerTick(Object^ /*sender*/, Object^ /*e*/)
{
CurrencyLoadingProgressRing->IsActive = true;
m_delayTimer->Stop();
}
void UnitConverter::HideProgressRing()
{
if (m_delayTimer != nullptr)
{
m_delayTimer->Stop();
}
CurrencyLoadingProgressRing->IsActive = false;
}

View File

@@ -0,0 +1,92 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// UnitConverter.xaml.h
// Declaration of the UnitConverter class
#pragma once
#include "Views\UnitConverter.g.h"
#include "Common\AlwaysSelectedCollectionView.h"
#include "CalcViewModel\Common\ValidatingConverters.h"
#include "Converters\BooleanToVisibilityConverter.h"
#include "Converters\VisibilityNegationConverter.h"
#include "CalcViewModel\UnitConverterViewModel.h"
#include "Views\StateTriggers\AspectRatioTrigger.h"
namespace CalculatorApp
{
[Windows::Foundation::Metadata::WebHostHidden]
public ref class UnitConverter sealed
{
public:
UnitConverter();
DEPENDENCY_PROPERTY_OWNER(UnitConverter);
void AnimateConverter();
property CalculatorApp::ViewModel::UnitConverterViewModel^ Model
{
CalculatorApp::ViewModel::UnitConverterViewModel^ get() {
return static_cast<CalculatorApp::ViewModel::UnitConverterViewModel^>(this->DataContext);
}
}
property Windows::UI::Xaml::FlowDirection LayoutDirection
{
Windows::UI::Xaml::FlowDirection get()
{
return m_layoutDirection;
}
}
void SetDefaultFocus();
private:
void OnValueKeyDown(Platform::Object^ sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e);
void OnContextRequested(Windows::UI::Xaml::UIElement^ sender, Windows::UI::Xaml::Input::ContextRequestedEventArgs^ e);
void OnContextCanceled(Windows::UI::Xaml::UIElement^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void OnCopyMenuItemClicked(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
void OnPasteMenuItemClicked(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
void OnValueSelected(_In_ Platform::Object^ sender);
void UpdateDropDownState(_In_ Platform::Object^ sender, _In_ Platform::Object^ e);
void OnLoaded(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
void CurrencyRefreshButton_Click(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::RoutedEventArgs^ e);
void OnPropertyChanged(_In_ Platform::Object^ sender, _In_ Windows::UI::Xaml::Data::PropertyChangedEventArgs^ e);
void OnDataContextChanged(_In_ Windows::UI::Xaml::FrameworkElement^ sender, _In_ Windows::UI::Xaml::DataContextChangedEventArgs^ args);
void OnIsDisplayVisibleChanged();
void Units1_IsEnabledChanged(Platform::Object^ sender, Windows::UI::Xaml::DependencyPropertyChangedEventArgs^ e);
void OnNetworkBehaviorChanged();
void OnNormalNetworkAccess();
void OnOptInNetworkAccess();
void OnOfflineNetworkAccess();
void InitializeOfflineStatusTextBlock();
void SetNormalCurrencyStatus();
void SetChargesMayApplyStatus();
void SetFailedToRefreshStatus();
void SetCurrencyTimestampFontWeight();
void StartProgressRingWithDelay();
void OnDelayTimerTick(Platform::Object^ sender, Platform::Object^ e);
void HideProgressRing();
private:
Windows::UI::Xaml::FlowDirection m_layoutDirection;
Windows::Foundation::EventRegistrationToken m_propertyChangedToken;
Windows::UI::Xaml::Controls::MenuFlyout^ m_resultsFlyout;
Platform::String^ m_chargesMayApplyText;
Platform::String^ m_failedToRefreshText;
bool m_meteredConnectionOverride;
Windows::UI::Xaml::DispatcherTimer^ m_delayTimer;
bool m_isAnimationEnabled;
};
}