diff --git a/src/CalcViewModel/Common/NavCategory.cpp b/src/CalcViewModel/Common/NavCategory.cpp index 95603311..b8506073 100644 --- a/src/CalcViewModel/Common/NavCategory.cpp +++ b/src/CalcViewModel/Common/NavCategory.cpp @@ -47,45 +47,54 @@ static constexpr int CURRENCY_ID = 16; static constexpr int GRAPHING_ID = 17; // ^^^ THESE CONSTANTS SHOULD NEVER CHANGE ^^^ -wchar_t* towchar_t(int number) +namespace { - auto wstr = std::to_wstring(number); - return _wcsdup(wstr.c_str()); -} + Platform::Agile CurrentUser; + std::mutex GraphingModeCheckMutex; -bool IsGraphingModeAvailable() -{ - static bool supportGraph = Windows::Foundation::Metadata::ApiInformation::IsMethodPresent("Windows.UI.Text.RichEditTextDocument", "GetMath"); - return supportGraph; -} - -Box ^ _isGraphingModeEnabledCached = nullptr; -bool IsGraphingModeEnabled(User ^ currentUser = nullptr) -{ - if (!IsGraphingModeAvailable()) + wchar_t* towchar_t(int number) { - return false; + auto wstr = std::to_wstring(number); + return _wcsdup(wstr.c_str()); } - if (_isGraphingModeEnabledCached != nullptr) + bool IsGraphingModeAvailable() { - return _isGraphingModeEnabledCached->Value; + static bool supportGraph = Windows::Foundation::Metadata::ApiInformation::IsMethodPresent("Windows.UI.Text.RichEditTextDocument", "GetMath"); + return supportGraph; } - if (!currentUser) + bool IsGraphingModeEnabled() { - return true; + static bool isChecked = false; + static bool isEnabled = false; + + std::scoped_lock lock(GraphingModeCheckMutex); + if (isChecked) + { + return isEnabled; + } + else + { + if (IsGraphingModeAvailable()) + { + auto namedPolicyData = NamedPolicy::GetPolicyFromPathForUser( + CurrentUser.Get(), + L"Education", + L"AllowGraphingCalculator"); + isEnabled = namedPolicyData->GetBoolean(); + } + else + { + isEnabled = false; + } + isChecked = true; + return isEnabled; + } } - - auto namedPolicyData = NamedPolicy::GetPolicyFromPathForUser(currentUser, L"Education", L"AllowGraphingCalculator"); - _isGraphingModeEnabledCached = namedPolicyData->GetBoolean() == true; - - return _isGraphingModeEnabledCached->Value; } -Platform::Agile NavCategoryStates::_currentUser; - // The order of items in this list determines the order of items in the menu. static std::vector s_categoryManifest = [] { auto res = std::vector{ NavCategoryInitializer{ ViewMode::Standard, @@ -280,36 +289,6 @@ static std::vector s_categoryManifest = [] { return res; }(); -void NavCategory::InitializeCategoryManifest(User ^ user) -{ - //int i = 0; - //for (NavCategoryInitializer category : s_categoryManifest) - //{ - // if (category.viewMode == ViewMode::Graphing) - // { - // auto navCatInit = s_categoryManifest.begin(); - // std::advance(navCatInit, i); - // (*navCatInit).isEnabled = IsGraphingModeEnabled(user); - // break; - // } - // else - // { - // i++; - // } - //} -} - - -void NavCategory::UpdateGraphingModelManifest(Windows::System::User ^ user) -{ - static bool isEnabled = IsGraphingModeEnabled(user); - std::find_if( - s_categoryManifest.begin(), - s_categoryManifest.end(), - [](const auto& category) { return category.viewMode == ViewMode::Graphing;}) - ->isEnabled = isEnabled; -} - bool NavCategory::IsCalculatorViewMode(ViewMode mode) { // Historically, Calculator modes are Standard, Scientific, and Programmer. @@ -379,7 +358,8 @@ NavCategoryGroup::NavCategoryGroup(const NavCategoryGroupInitializer& groupIniti void NavCategoryStates::SetCurrentUser(Windows::System::User^ user) { - _currentUser = user; + std::scoped_lock lock(GraphingModeCheckMutex); + CurrentUser = user; } IObservableVector ^ NavCategoryStates::CreateMenuOptions() @@ -578,11 +558,16 @@ bool NavCategoryStates::IsValidViewMode(ViewMode mode) bool NavCategoryStates::IsViewModeEnabled(ViewMode mode) { - const auto& citer = find_if( - cbegin(s_categoryManifest), - cend(s_categoryManifest), - [mode](const auto& initializer) { return initializer.viewMode == mode && initializer.isEnabled; }); - - return citer != s_categoryManifest.cend(); + if (mode == ViewMode::Graphing) + { + return IsGraphingModeEnabled(); + } + else + { + return std::any_of( + s_categoryManifest.cbegin(), + s_categoryManifest.cend(), + [mode](const auto& initializer) { return initializer.viewMode == mode && initializer.isEnabled; }); + } } diff --git a/src/CalcViewModel/Common/NavCategory.h b/src/CalcViewModel/Common/NavCategory.h index f2bd1208..2e7a7fbc 100644 --- a/src/CalcViewModel/Common/NavCategory.h +++ b/src/CalcViewModel/Common/NavCategory.h @@ -99,7 +99,7 @@ namespace CalculatorApp::ViewModel PROPERTY_R(ViewMode, Mode); PROPERTY_R(Platform::String ^, AccessKey); PROPERTY_R(bool, SupportsNegative); - PROPERTY_R(bool, IsEnabled); + PROPERTY_RW(bool, IsEnabled); property Platform::String ^ AutomationId { Platform::String ^ get() { return m_Mode.ToString(); } } @@ -109,9 +109,6 @@ namespace CalculatorApp::ViewModel static bool IsDateCalculatorViewMode(ViewMode mode); static bool IsConverterViewMode(ViewMode mode); - static void InitializeCategoryManifest(Windows::System::User ^ user); - static void UpdateGraphingModelManifest(Windows::System::User ^ user); - internal : NavCategory( Platform::String ^ name, Platform::String ^ automationName, @@ -181,9 +178,6 @@ namespace CalculatorApp::ViewModel // Virtual key related static ViewMode GetViewModeForVirtualKey(MyVirtualKey virtualKey); static void GetCategoryAcceleratorKeys(Windows::Foundation::Collections::IVector ^ resutls); - - private: - static Platform::Agile _currentUser; }; } } diff --git a/src/Calculator/App.xaml.cs b/src/Calculator/App.xaml.cs index 7e1409ec..4f8af2c1 100644 --- a/src/Calculator/App.xaml.cs +++ b/src/Calculator/App.xaml.cs @@ -19,6 +19,7 @@ using Windows.ApplicationModel.Activation; using Windows.ApplicationModel.Core; using Windows.Foundation; using Windows.Storage; +using Windows.System; using Windows.UI.Core; using Windows.UI.StartScreen; using Windows.UI.ViewManagement; @@ -86,6 +87,10 @@ namespace CalculatorApp m_preLaunched = true; } NavCategoryStates.SetCurrentUser(args.User); + + // It takes time to check GraphingMode at the 1st time. So, do it in a background thread + Task.Run(() => NavCategoryStates.IsViewModeEnabled(ViewMode.Graphing)); + OnAppLaunch(args, args.Arguments); } @@ -411,7 +416,7 @@ namespace CalculatorApp foreach (NavCategory option in calculatorOptions.Categories) { - if (!option.IsEnabled) + if (!NavCategoryStates.IsViewModeEnabled(option.Mode)) { continue; } diff --git a/src/Calculator/Views/MainPage.xaml.cs b/src/Calculator/Views/MainPage.xaml.cs index 36b59c78..96dada16 100644 --- a/src/Calculator/Views/MainPage.xaml.cs +++ b/src/Calculator/Views/MainPage.xaml.cs @@ -147,6 +147,22 @@ namespace CalculatorApp NavViewCategoriesSource.Clear(); NavViewCategoriesSource = ExpandNavViewCategoryGroups(Model.Categories); }; + + _ = Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Low, () => + { + var graphCategory = (NavCategory)NavViewCategoriesSource.Find(x => + { + if(x is NavCategory category) + { + return category.Mode == ViewMode.Graphing; + } + else + { + return false; + } + }); + graphCategory.IsEnabled = NavCategoryStates.IsViewModeEnabled(ViewMode.Graphing); + }); } private List ExpandNavViewCategoryGroups(IEnumerable groups)