Always-on-Top mode implemented (#579)

This commit is contained in:
Wei (Waley) Zhang
2019-07-30 17:53:39 -07:00
committed by Pepe Rivera
parent af8322617f
commit 796d171960
30 changed files with 849 additions and 125 deletions

View File

@@ -31,6 +31,8 @@ using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::Foundation;
using namespace Concurrency;
namespace
{
@@ -55,6 +57,7 @@ void ApplicationViewModel::Mode::set(ViewMode value)
{
PreviousMode = m_mode;
m_mode = value;
SetDisplayNormalAlwaysOnTopOption();
OnModeChanged();
RaisePropertyChanged(ModePropertyName);
}
@@ -204,3 +207,60 @@ void ApplicationViewModel::SetMenuCategories()
// property setter logic.
Categories = NavCategoryGroup::CreateMenuOptions();
}
void ApplicationViewModel::ToggleAlwaysOnTop(float width, float height)
{
HandleToggleAlwaysOnTop(width, height);
}
task<void> ApplicationViewModel::HandleToggleAlwaysOnTop(float width, float height)
{
if (ApplicationView::GetForCurrentView()->ViewMode == ApplicationViewMode::CompactOverlay)
{
ApplicationDataContainer ^ localSettings = ApplicationData::Current->LocalSettings;
localSettings->Values->Insert(WidthLocalSettings, width);
localSettings->Values->Insert(HeightLocalSettings, height);
bool success = co_await ApplicationView::GetForCurrentView()->TryEnterViewModeAsync(ApplicationViewMode::Default);
CalculatorViewModel->AreHistoryShortcutsEnabled = success;
CalculatorViewModel->HistoryVM->AreHistoryShortcutsEnabled = success;
CalculatorViewModel->IsAlwaysOnTop = !success;
IsAlwaysOnTop = !success;
}
else
{
ApplicationDataContainer ^ localSettings = ApplicationData::Current->LocalSettings;
ViewModePreferences ^ compactOptions = ViewModePreferences::CreateDefault(ApplicationViewMode::CompactOverlay);
if (!localSettings->Values->GetView()->HasKey(LaunchedLocalSettings))
{
compactOptions->CustomSize = Size(320, 394);
localSettings->Values->Insert(LaunchedLocalSettings, true);
}
else
{
if (localSettings->Values->GetView()->HasKey(WidthLocalSettings) && localSettings->Values->GetView()->HasKey(HeightLocalSettings))
{
float oldWidth = safe_cast<IPropertyValue ^>(localSettings->Values->GetView()->Lookup(WidthLocalSettings))->GetSingle();
float oldHeight = safe_cast<IPropertyValue ^>(localSettings->Values->GetView()->Lookup(HeightLocalSettings))->GetSingle();
compactOptions->CustomSize = Size(oldWidth, oldHeight);
}
else
{
compactOptions->CustomSize = Size(320, 394);
}
}
bool success = co_await ApplicationView::GetForCurrentView()->TryEnterViewModeAsync(ApplicationViewMode::CompactOverlay, compactOptions);
CalculatorViewModel->AreHistoryShortcutsEnabled = !success;
CalculatorViewModel->HistoryVM->AreHistoryShortcutsEnabled = !success;
CalculatorViewModel->IsAlwaysOnTop = success;
IsAlwaysOnTop = success;
}
SetDisplayNormalAlwaysOnTopOption();
}
void ApplicationViewModel::SetDisplayNormalAlwaysOnTopOption()
{
DisplayNormalAlwaysOnTopOption =
m_mode == ViewMode::Standard && ApplicationView::GetForCurrentView()->IsViewModeSupported(ApplicationViewMode::CompactOverlay) && !IsAlwaysOnTop;
}

View File

@@ -25,6 +25,9 @@ namespace CalculatorApp
OBSERVABLE_PROPERTY_RW(CalculatorApp::Common::ViewMode, PreviousMode);
OBSERVABLE_NAMED_PROPERTY_RW(Platform::String ^, CategoryName);
// Indicates whether calculator is currently in standard mode _and_ supports CompactOverlay _and_ is not in Always-on-Top mode
OBSERVABLE_PROPERTY_RW(bool, DisplayNormalAlwaysOnTopOption);
COMMAND_FOR_METHOD(CopyCommand, ApplicationViewModel::OnCopyCommand);
COMMAND_FOR_METHOD(PasteCommand, ApplicationViewModel::OnPasteCommand);
@@ -64,6 +67,48 @@ namespace CalculatorApp
}
}
static property Platform::String ^ LaunchedLocalSettings
{
Platform::String ^ get()
{
return Platform::StringReference(L"calculatorAlwaysOnTopLaunched");
}
}
static property Platform::String ^ WidthLocalSettings
{
Platform::String ^ get()
{
return Platform::StringReference(L"calculatorAlwaysOnTopLastWidth");
}
}
static property Platform::String ^ HeightLocalSettings
{
Platform::String ^ get()
{
return Platform::StringReference(L"calculatorAlwaysOnTopLastHeight");
}
}
property bool IsAlwaysOnTop
{
bool get()
{
return m_isAlwaysOnTop;
}
void set(bool value)
{
if (m_isAlwaysOnTop != value)
{
m_isAlwaysOnTop = value;
RaisePropertyChanged(L"IsAlwaysOnTop");
}
}
}
void ToggleAlwaysOnTop(float width, float height);
private:
bool TryRecoverFromNavigationModeFailure();
@@ -76,6 +121,10 @@ namespace CalculatorApp
CalculatorApp::Common::ViewMode m_mode;
Windows::Foundation::Collections::IObservableVector<CalculatorApp::Common::NavCategoryGroup ^> ^ m_categories;
Concurrency::task<void> HandleToggleAlwaysOnTop(float width, float height);
void SetDisplayNormalAlwaysOnTopOption();
bool m_isAlwaysOnTop;
};
}
}

View File

@@ -668,10 +668,11 @@ void KeyboardShortcutManager::OnAcceleratorKeyActivated(CoreDispatcher ^, Accele
if (nullptr != vm)
{
ViewMode toMode = NavCategory::GetViewModeForVirtualKey(static_cast<MyVirtualKey>(key));
if (NavCategory::IsValidViewMode(toMode))
auto nvi = dynamic_cast<MUXC::NavigationViewItem ^>(menuItems->GetAt(NavCategory::GetFlatIndex(toMode)));
if (nvi && nvi->IsEnabled && NavCategory::IsValidViewMode(toMode))
{
vm->Mode = toMode;
navView->SelectedItem = menuItems->GetAt(NavCategory::GetFlatIndex(toMode));
navView->SelectedItem = nvi;
}
}
}

View File

@@ -117,7 +117,7 @@ namespace CalculatorApp
return true;
}
void TraceLogger::LogVisualStateChanged(ViewMode mode, wstring_view state) const
void TraceLogger::LogVisualStateChanged(ViewMode mode, wstring_view state, bool isAlwaysOnTop) const
{
if (!GetTraceLoggingProviderEnabled())
{
@@ -128,6 +128,7 @@ namespace CalculatorApp
fields.AddGuid(L"SessionGuid", sessionGuid);
fields.AddString(L"CalcMode", NavCategory::GetFriendlyName(mode)->Data());
fields.AddString(L"VisualState", state);
fields.AddBoolean(L"IsAlwaysOnTop", isAlwaysOnTop);
fields.AddUInt64(PDT_PRIVACY_DATA_TAG, PDT_PRODUCT_AND_SERVICE_USAGE);
LogLevel2Event(EVENT_NAME_VISUAL_STATE_CHANGED, fields);
}

View File

@@ -45,7 +45,7 @@ namespace CalculatorApp
void LogDateCalculationModeUsed(bool AddSubtractMode);
void UpdateWindowCount(size_t windowCount = 0);
bool IsWindowIdInLog(int windowId);
void LogVisualStateChanged(CalculatorApp::Common::ViewMode mode, std::wstring_view state) const;
void LogVisualStateChanged(CalculatorApp::Common::ViewMode mode, std::wstring_view state, bool isAlwaysOnTop = false) const;
void LogWindowCreated(CalculatorApp::Common::ViewMode mode, int windowId);
void LogConverterInputReceived(CalculatorApp::Common::ViewMode mode) const;
void LogNavBarOpened() const;

View File

@@ -35,6 +35,7 @@ namespace
StringReference IsStandardPropertyName(L"IsStandard");
StringReference IsScientificPropertyName(L"IsScientific");
StringReference IsProgrammerPropertyName(L"IsProgrammer");
StringReference IsAlwaysOnTopPropertyName(L"IsAlwaysOnTop");
StringReference DisplayValuePropertyName(L"DisplayValue");
StringReference CalculationResultAutomationNamePropertyName(L"CalculationResultAutomationName");
StringReference IsBitFlipCheckedPropertyName(L"IsBitFlipChecked");
@@ -202,7 +203,12 @@ void StandardCalculatorViewModel::SetPrimaryDisplay(_In_ wstring const& displayS
// not match what the narrator is saying
m_CalculationResultAutomationName = CalculateNarratorDisplayValue(displayStringValue, localizedDisplayStringValue, isError);
DisplayValue = localizedDisplayStringValue;
AreAlwaysOnTopResultsUpdated = false;
if (DisplayValue != localizedDisplayStringValue)
{
DisplayValue = localizedDisplayStringValue;
AreAlwaysOnTopResultsUpdated = true;
}
IsInError = isError;
@@ -415,7 +421,7 @@ void StandardCalculatorViewModel::SetMemorizedNumbers(const vector<wstring>& new
memorySlot->Value = Utils::LRO + ref new String(stringValue.c_str()) + Utils::PDF;
MemorizedNumbers->InsertAt(0, memorySlot);
IsMemoryEmpty = false;
IsMemoryEmpty = IsAlwaysOnTop;
// Update the slot position for the rest of the slots
for (unsigned int i = 1; i < MemorizedNumbers->Size; i++)

View File

@@ -78,6 +78,7 @@ namespace CalculatorApp
OBSERVABLE_PROPERTY_RW(bool, IsByteEnabled);
OBSERVABLE_PROPERTY_RW(int, CurrentRadixType);
OBSERVABLE_PROPERTY_RW(bool, AreTokensUpdated);
OBSERVABLE_PROPERTY_RW(bool, AreAlwaysOnTopResultsUpdated);
OBSERVABLE_PROPERTY_RW(bool, AreHistoryShortcutsEnabled);
OBSERVABLE_PROPERTY_RW(bool, AreProgrammerRadixOperatorsEnabled);
OBSERVABLE_PROPERTY_RW(CalculatorApp::Common::Automation::NarratorAnnouncement ^, Announcement);
@@ -213,6 +214,22 @@ namespace CalculatorApp
}
}
property bool IsAlwaysOnTop
{
bool get()
{
return m_isAlwaysOnTop;
}
void set(bool value)
{
if (m_isAlwaysOnTop != value)
{
m_isAlwaysOnTop = value;
RaisePropertyChanged(L"IsAlwaysOnTop");
}
}
}
property bool IsEditingEnabled
{
bool get()
@@ -406,6 +423,7 @@ namespace CalculatorApp
bool m_isStandard;
bool m_isScientific;
bool m_isProgrammer;
bool m_isAlwaysOnTop;
bool m_isBinaryBitFlippingEnabled;
bool m_isBitFlipChecked;
bool m_isShiftChecked;

View File

@@ -30,6 +30,7 @@
#include <concrt.h>
#include <regex>
#include <iterator>
#include <intsafe.h>
// C++\WinRT Headers
#include "winrt/base.h"
#include "winrt/Windows.Foundation.Diagnostics.h"