diff --git a/src/Calculator/Common/KeyboardShortcutManager.cpp b/src/Calculator/Common/KeyboardShortcutManager.cpp index 378db34..bed0c4b 100644 --- a/src/Calculator/Common/KeyboardShortcutManager.cpp +++ b/src/Calculator/Common/KeyboardShortcutManager.cpp @@ -10,7 +10,7 @@ using namespace Concurrency; using namespace Platform; using namespace std; -using namespace std::chrono; +using namespace chrono; using namespace Windows::ApplicationModel::Resources; using namespace Windows::UI::Xaml; using namespace Windows::UI::Xaml::Controls; @@ -32,30 +32,20 @@ DEPENDENCY_PROPERTY_INITIALIZATION(KeyboardShortcutManager, VirtualKeyControlCho DEPENDENCY_PROPERTY_INITIALIZATION(KeyboardShortcutManager, VirtualKeyShiftChord); DEPENDENCY_PROPERTY_INITIALIZATION(KeyboardShortcutManager, VirtualKeyAltChord); DEPENDENCY_PROPERTY_INITIALIZATION(KeyboardShortcutManager, VirtualKeyControlShiftChord); -DEPENDENCY_PROPERTY_INITIALIZATION(KeyboardShortcutManager, VirtualKeyInverseChord); -DEPENDENCY_PROPERTY_INITIALIZATION(KeyboardShortcutManager, VirtualKeyControlInverseChord); -static multimap> s_CharacterForButtons; -static multimap> s_VirtualKeysForButtons; -static multimap> s_VirtualKeyControlChordsForButtons; -static multimap> s_VirtualKeyShiftChordsForButtons; -static multimap> s_VirtualKeyAltChordsForButtons; -static multimap> s_VirtualKeyControlShiftChordsForButtons; -static multimap> s_VirtualKeyInverseChordsForButtons; -static multimap> s_VirtualKeyControlInverseChordsForButtons; +map> KeyboardShortcutManager::s_characterForButtons; +map> KeyboardShortcutManager::s_virtualKey; +map> KeyboardShortcutManager::s_VirtualKeyControlChordsForButtons; +map> KeyboardShortcutManager::s_VirtualKeyShiftChordsForButtons; +map> KeyboardShortcutManager::s_VirtualKeyAltChordsForButtons; +map> KeyboardShortcutManager::s_VirtualKeyControlShiftChordsForButtons; -static map s_ShiftKeyPressed; -static map s_ControlKeyPressed; -static map s_ShiftButtonChecked; -static map s_IsDropDownOpen; - -static map s_ignoreNextEscape; -static map s_keepIgnoringEscape; -static map s_fHonorShortcuts; -static map s_fDisableShortcuts; -static map s_AboutFlyout; - -static reader_writer_lock s_keyboardShortcutMapLock; +map KeyboardShortcutManager::s_IsDropDownOpen; +map KeyboardShortcutManager::s_ignoreNextEscape; +map KeyboardShortcutManager::s_keepIgnoringEscape; +map KeyboardShortcutManager::s_fHonorShortcuts; +map KeyboardShortcutManager::s_fDisableShortcuts; +reader_writer_lock KeyboardShortcutManager::s_keyboardShortcutMapLock; namespace CalculatorApp { @@ -156,7 +146,7 @@ namespace CalculatorApp auto toggle = dynamic_cast(button); if (toggle) { - toggle->IsChecked = !toggle->IsChecked->Value; + toggle->IsChecked = !(toggle->IsChecked != nullptr && toggle->IsChecked->Value); return; } } @@ -208,9 +198,9 @@ void KeyboardShortcutManager::OnCharacterPropertyChanged(DependencyObject ^ targ auto button = safe_cast(target); int viewId = Utils::GetWindowId(); - auto iterViewMap = s_CharacterForButtons.find(viewId); + auto iterViewMap = s_characterForButtons.find(viewId); - if (iterViewMap != s_CharacterForButtons.end()) + if (iterViewMap != s_characterForButtons.end()) { if (oldValue) { @@ -222,26 +212,26 @@ void KeyboardShortcutManager::OnCharacterPropertyChanged(DependencyObject ^ targ if (newValue == L".") { wchar_t decSep = LocalizationSettings::GetInstance().GetDecimalSeparator(); - iterViewMap->second.insert(std::make_pair(decSep, WeakReference(button))); + iterViewMap->second.insert(make_pair(decSep, WeakReference(button))); } else { - iterViewMap->second.insert(std::make_pair(newValue->Data()[0], WeakReference(button))); + iterViewMap->second.insert(make_pair(newValue->Data()[0], WeakReference(button))); } } } else { - s_CharacterForButtons.insert(std::make_pair(viewId, std::multimap())); + s_characterForButtons.insert(make_pair(viewId, multimap())); if (newValue == L".") { wchar_t decSep = LocalizationSettings::GetInstance().GetDecimalSeparator(); - s_CharacterForButtons.find(viewId)->second.insert(std::make_pair(decSep, WeakReference(button))); + s_characterForButtons.find(viewId)->second.insert(make_pair(decSep, WeakReference(button))); } else { - s_CharacterForButtons.find(viewId)->second.insert(std::make_pair(newValue->Data()[0], WeakReference(button))); + s_characterForButtons.find(viewId)->second.insert(make_pair(newValue->Data()[0], WeakReference(button))); } } } @@ -254,18 +244,18 @@ void KeyboardShortcutManager::OnVirtualKeyPropertyChanged(DependencyObject ^ tar auto button = static_cast(target); int viewId = Utils::GetWindowId(); - auto iterViewMap = s_VirtualKeysForButtons.find(viewId); + auto iterViewMap = s_virtualKey.find(viewId); // Check if the View Id has already been registered - if (iterViewMap != s_VirtualKeysForButtons.end()) + if (iterViewMap != s_virtualKey.end()) { - iterViewMap->second.insert(std::make_pair(newValue, WeakReference(button))); + iterViewMap->second.insert(make_pair(newValue, WeakReference(button))); } else { // If the View Id is not already registered, then register it and make the entry - s_VirtualKeysForButtons.insert(std::make_pair(viewId, std::multimap())); - s_VirtualKeysForButtons.find(viewId)->second.insert(std::make_pair(newValue, WeakReference(button))); + s_virtualKey.insert(make_pair(viewId, multimap())); + s_virtualKey.find(viewId)->second.insert(make_pair(newValue, WeakReference(button))); } } @@ -288,13 +278,13 @@ void KeyboardShortcutManager::OnVirtualKeyControlChordPropertyChanged(Dependency // Check if the View Id has already been registered if (iterViewMap != s_VirtualKeyControlChordsForButtons.end()) { - iterViewMap->second.insert(std::make_pair(newValue, WeakReference(control))); + iterViewMap->second.insert(make_pair(newValue, WeakReference(control))); } else { // If the View Id is not already registered, then register it and make the entry - s_VirtualKeyControlChordsForButtons.insert(std::make_pair(viewId, std::multimap())); - s_VirtualKeyControlChordsForButtons.find(viewId)->second.insert(std::make_pair(newValue, WeakReference(control))); + s_VirtualKeyControlChordsForButtons.insert(make_pair(viewId, multimap())); + s_VirtualKeyControlChordsForButtons.find(viewId)->second.insert(make_pair(newValue, WeakReference(control))); } } @@ -311,13 +301,13 @@ void KeyboardShortcutManager::OnVirtualKeyShiftChordPropertyChanged(DependencyOb // Check if the View Id has already been registered if (iterViewMap != s_VirtualKeyShiftChordsForButtons.end()) { - iterViewMap->second.insert(std::make_pair(newValue, WeakReference(button))); + iterViewMap->second.insert(make_pair(newValue, WeakReference(button))); } else { // If the View Id is not already registered, then register it and make the entry - s_VirtualKeyShiftChordsForButtons.insert(std::make_pair(viewId, std::multimap())); - s_VirtualKeyShiftChordsForButtons.find(viewId)->second.insert(std::make_pair(newValue, WeakReference(button))); + s_VirtualKeyShiftChordsForButtons.insert(make_pair(viewId, multimap())); + s_VirtualKeyShiftChordsForButtons.find(viewId)->second.insert(make_pair(newValue, WeakReference(button))); } } @@ -334,13 +324,13 @@ void KeyboardShortcutManager::OnVirtualKeyAltChordPropertyChanged(DependencyObje // Check if the View Id has already been registered if (iterViewMap != s_VirtualKeyAltChordsForButtons.end()) { - iterViewMap->second.insert(std::make_pair(newValue, WeakReference(navView))); + iterViewMap->second.insert(make_pair(newValue, WeakReference(navView))); } else { // If the View Id is not already registered, then register it and make the entry - s_VirtualKeyAltChordsForButtons.insert(std::make_pair(viewId, std::multimap())); - s_VirtualKeyAltChordsForButtons.find(viewId)->second.insert(std::make_pair(newValue, WeakReference(navView))); + s_VirtualKeyAltChordsForButtons.insert(make_pair(viewId, multimap())); + s_VirtualKeyAltChordsForButtons.find(viewId)->second.insert(make_pair(newValue, WeakReference(navView))); } } @@ -357,59 +347,13 @@ void KeyboardShortcutManager::OnVirtualKeyControlShiftChordPropertyChanged(Depen // Check if the View Id has already been registered if (iterViewMap != s_VirtualKeyControlShiftChordsForButtons.end()) { - iterViewMap->second.insert(std::make_pair(newValue, WeakReference(button))); + iterViewMap->second.insert(make_pair(newValue, WeakReference(button))); } else { // If the View Id is not already registered, then register it and make the entry - s_VirtualKeyControlShiftChordsForButtons.insert(std::make_pair(viewId, std::multimap())); - s_VirtualKeyControlShiftChordsForButtons.find(viewId)->second.insert(std::make_pair(newValue, WeakReference(button))); - } -} - -void KeyboardShortcutManager::OnVirtualKeyInverseChordPropertyChanged(DependencyObject ^ target, MyVirtualKey /*oldValue*/, MyVirtualKey newValue) -{ - // Writer lock for the static maps - reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock); - - auto button = safe_cast(target); - - int viewId = Utils::GetWindowId(); - auto iterViewMap = s_VirtualKeyInverseChordsForButtons.find(viewId); - - // Check if the View Id has already been registered - if (iterViewMap != s_VirtualKeyInverseChordsForButtons.end()) - { - iterViewMap->second.insert(std::make_pair(newValue, WeakReference(button))); - } - else - { - // If the View Id is not already registered, then register it and make the entry - s_VirtualKeyInverseChordsForButtons.insert(std::make_pair(viewId, std::multimap())); - s_VirtualKeyInverseChordsForButtons.find(viewId)->second.insert(std::make_pair(newValue, WeakReference(button))); - } -} - -void KeyboardShortcutManager::OnVirtualKeyControlInverseChordPropertyChanged(DependencyObject ^ target, MyVirtualKey /*oldValue*/, MyVirtualKey newValue) -{ - // Writer lock for the static maps - reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock); - - auto button = safe_cast(target); - - int viewId = Utils::GetWindowId(); - auto iterViewMap = s_VirtualKeyControlInverseChordsForButtons.find(viewId); - - // Check if the View Id has already been registered - if (iterViewMap != s_VirtualKeyControlInverseChordsForButtons.end()) - { - iterViewMap->second.insert(std::make_pair(newValue, WeakReference(button))); - } - else - { - // If the View Id is not already registered, then register it and make the entry - s_VirtualKeyControlInverseChordsForButtons.insert(std::make_pair(viewId, std::multimap())); - s_VirtualKeyControlInverseChordsForButtons.find(viewId)->second.insert(std::make_pair(newValue, WeakReference(button))); + s_VirtualKeyControlShiftChordsForButtons.insert(make_pair(viewId, multimap())); + s_VirtualKeyControlShiftChordsForButtons.find(viewId)->second.insert(make_pair(newValue, WeakReference(button))); } } @@ -421,218 +365,153 @@ void KeyboardShortcutManager::OnCharacterReceivedHandler(CoreWindow ^ sender, Ch int viewId = Utils::GetWindowId(); auto currentHonorShortcuts = s_fHonorShortcuts.find(viewId); - if (currentHonorShortcuts != s_fHonorShortcuts.end()) + if (currentHonorShortcuts == s_fHonorShortcuts.end() || currentHonorShortcuts->second) { - if (currentHonorShortcuts->second) - { - wchar_t character = static_cast(args->KeyCode); - auto buttons = s_CharacterForButtons.find(viewId)->second.equal_range(character); - RunFirstEnabledButtonCommand(buttons); + wchar_t character = static_cast(args->KeyCode); + auto buttons = s_characterForButtons.find(viewId)->second.equal_range(character); + RunFirstEnabledButtonCommand(buttons); - LightUpButtons(buttons); - } + LightUpButtons(buttons); } } -const std::multimap& GetCurrentKeyDictionary(MyVirtualKey key, bool altPressed = false) +const multimap* KeyboardShortcutManager::GetCurrentKeyDictionary(bool controlKeyPressed, bool shiftKeyPressed, bool altPressed) { int viewId = Utils::GetWindowId(); - if (altPressed) + if (controlKeyPressed) { - return s_VirtualKeyAltChordsForButtons.find(viewId)->second; - } - else if ( - (s_ShiftKeyPressed.find(viewId)->second) - && ((Window::Current->CoreWindow->GetKeyState(VirtualKey::Control) & CoreVirtualKeyStates::Down) == CoreVirtualKeyStates::Down)) - { - return s_VirtualKeyControlShiftChordsForButtons.find(viewId)->second; - } - else if (s_ShiftKeyPressed.find(viewId)->second) - { - return s_VirtualKeyShiftChordsForButtons.find(viewId)->second; - } - else if (s_ShiftButtonChecked.find(viewId)->second) - { - if ((Window::Current->CoreWindow->GetKeyState(VirtualKey::Control) & CoreVirtualKeyStates::Down) == CoreVirtualKeyStates::Down) + if (altPressed) { - auto iterViewMap = s_VirtualKeyControlInverseChordsForButtons.find(viewId); - if (iterViewMap != s_VirtualKeyControlInverseChordsForButtons.end()) + return nullptr; + } + else + { + if (shiftKeyPressed) { - for (auto iterator = iterViewMap->second.begin(); iterator != iterViewMap->second.end(); ++iterator) - { - if (key == iterator->first) - { - return s_VirtualKeyControlInverseChordsForButtons.find(viewId)->second; - } - } + return &s_VirtualKeyControlShiftChordsForButtons.find(viewId)->second; + } + else + { + return &s_VirtualKeyControlChordsForButtons.find(viewId)->second; + } + } + } + else + { + if (altPressed) + { + if (!shiftKeyPressed) + { + return &s_VirtualKeyAltChordsForButtons.find(viewId)->second; + } + else + { + return nullptr; } } else { - auto iterViewMap = s_VirtualKeyInverseChordsForButtons.find(viewId); - if (iterViewMap != s_VirtualKeyInverseChordsForButtons.end()) + if (shiftKeyPressed) { - for (auto iterator = iterViewMap->second.begin(); iterator != iterViewMap->second.end(); ++iterator) - { - if (key == iterator->first) - { - return s_VirtualKeyInverseChordsForButtons.find(viewId)->second; - } - } + return &s_VirtualKeyShiftChordsForButtons.find(viewId)->second; + } + else + { + return &s_virtualKey.find(viewId)->second; } } } - if ((Window::Current->CoreWindow->GetKeyState(VirtualKey::Control) & CoreVirtualKeyStates::Down) == CoreVirtualKeyStates::Down) - { - return s_VirtualKeyControlChordsForButtons.find(viewId)->second; - } - else - { - return s_VirtualKeysForButtons.find(viewId)->second; - } } void KeyboardShortcutManager::OnKeyDownHandler(CoreWindow ^ sender, KeyEventArgs ^ args) { - // If keyboard shortcuts like Ctrl+C or Ctrl+V are not handled - if (!args->Handled) + if (args->Handled) { - auto key = args->VirtualKey; - int viewId = Utils::GetWindowId(); + return; + } - auto currentControlKeyPressed = s_ControlKeyPressed.find(viewId); - auto currentShiftKeyPressed = s_ShiftKeyPressed.find(viewId); + auto key = args->VirtualKey; + int viewId = Utils::GetWindowId(); - bool isControlKeyPressed = (currentControlKeyPressed != s_ControlKeyPressed.end()) && (currentControlKeyPressed->second); - bool isShiftKeyPressed = (currentShiftKeyPressed != s_ShiftKeyPressed.end()) && (currentShiftKeyPressed->second); + const bool isControlKeyPressed = (Window::Current->CoreWindow->GetKeyState(VirtualKey::Control) & CoreVirtualKeyStates::Down) == CoreVirtualKeyStates::Down; + const bool isShiftKeyPressed = (Window::Current->CoreWindow->GetKeyState(VirtualKey::Shift) & CoreVirtualKeyStates::Down) == CoreVirtualKeyStates::Down; + const bool isAltKeyPressed = (Window::Current->CoreWindow->GetKeyState(VirtualKey::Menu) & CoreVirtualKeyStates::Down) == CoreVirtualKeyStates::Down; - // Handle Ctrl + E for DateCalculator - if ((key == VirtualKey::E) && isControlKeyPressed && !isShiftKeyPressed) + // Handle Ctrl + E for DateCalculator + if ((key == VirtualKey::E) && isControlKeyPressed && !isShiftKeyPressed && !isAltKeyPressed) + { + const auto lookupMap = GetCurrentKeyDictionary(isControlKeyPressed, isShiftKeyPressed, false); + if (lookupMap == nullptr) { - const auto& lookupMap = GetCurrentKeyDictionary(static_cast(key)); - auto buttons = lookupMap.equal_range(static_cast(key)); - auto navView = buttons.first->second.Resolve(); + return; + } - if (navView == nullptr) + auto buttons = lookupMap->equal_range(static_cast(key)); + auto navView = buttons.first->second.Resolve(); + auto appViewModel = safe_cast(navView->DataContext); + appViewModel->Mode = ViewMode::Date; + auto categoryName = AppResourceProvider::GetInstance()->GetResourceString(L"DateCalculationModeText"); + appViewModel->CategoryName = categoryName; + + auto menuItems = static_cast ^>(navView->MenuItemsSource); + auto flatIndex = NavCategory::GetFlatIndex(ViewMode::Date); + navView->SelectedItem = menuItems->GetAt(flatIndex); + return; + } + + auto currentIgnoreNextEscape = s_ignoreNextEscape.find(viewId); + if (currentIgnoreNextEscape != s_ignoreNextEscape.end()) + { + if (currentIgnoreNextEscape->second && key == VirtualKey::Escape) + { + auto currentKeepIgnoringEscape = s_keepIgnoringEscape.find(viewId); + + if (currentKeepIgnoringEscape != s_keepIgnoringEscape.end()) + { + if (!currentKeepIgnoringEscape->second) + { + HonorEscape(); + } + return; + } + } + } + + auto currentHonorShortcuts = s_fHonorShortcuts.find(viewId); + if (currentHonorShortcuts != s_fHonorShortcuts.end()) + { + if (currentHonorShortcuts->second) + { + const auto myVirtualKey = static_cast(key); + const auto lookupMap = GetCurrentKeyDictionary(isControlKeyPressed, isShiftKeyPressed, isAltKeyPressed); + if (lookupMap == nullptr) { return; } - auto appViewModel = safe_cast(navView->DataContext); - appViewModel->Mode = ViewMode::Date; - auto categoryName = AppResourceProvider::GetInstance()->GetResourceString(L"DateCalculationModeText"); - appViewModel->CategoryName = categoryName; - - auto menuItems = static_cast ^>(navView->MenuItemsSource); - auto flatIndex = NavCategory::GetFlatIndex(ViewMode::Date); - navView->SelectedItem = menuItems->GetAt(flatIndex); - return; - } - - auto currentHonorShortcuts = s_fHonorShortcuts.find(viewId); - - auto currentIgnoreNextEscape = s_ignoreNextEscape.find(viewId); - - if (currentIgnoreNextEscape != s_ignoreNextEscape.end()) - { - if (currentIgnoreNextEscape->second && key == VirtualKey::Escape) + auto buttons = lookupMap->equal_range(myVirtualKey); + if (buttons.first == buttons.second) { - auto currentKeepIgnoringEscape = s_keepIgnoringEscape.find(viewId); + return; + } - if (currentKeepIgnoringEscape != s_keepIgnoringEscape.end()) + RunFirstEnabledButtonCommand(buttons); + + // Ctrl+C and Ctrl+V shifts focus to some button because of which enter doesn't work after copy/paste. So don't shift focus if Ctrl+C or Ctrl+V + // is pressed. When drop down is open, pressing escape shifts focus to clear button. So dont's shift focus if drop down is open. Ctrl+Insert is + // equivalent to Ctrl+C and Shift+Insert is equivalent to Ctrl+V + auto currentIsDropDownOpen = s_IsDropDownOpen.find(viewId); + if (currentIsDropDownOpen == s_IsDropDownOpen.end() || !currentIsDropDownOpen->second) + { + // Do not Light Up Buttons when Ctrl+C, Ctrl+V, Ctrl+Insert or Shift+Insert is pressed + if (!(isControlKeyPressed && (key == VirtualKey::C || key == VirtualKey::V || key == VirtualKey::Insert)) + && !(isShiftKeyPressed && (key == VirtualKey::Insert))) { - if (!currentKeepIgnoringEscape->second) - { - HonorEscape(); - } - return; + LightUpButtons(buttons); } } } - - if (key == VirtualKey::Control) - { - // Writer lock for the static maps - reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock); - - auto currControlKeyPressed = s_ControlKeyPressed.find(viewId); - - if (currControlKeyPressed != s_ControlKeyPressed.end()) - { - s_ControlKeyPressed[viewId] = true; - } - return; - } - else if (key == VirtualKey::Shift) - { - // Writer lock for the static maps - reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock); - - auto currShiftKeyPressed = s_ShiftKeyPressed.find(viewId); - - if (currShiftKeyPressed != s_ShiftKeyPressed.end()) - { - s_ShiftKeyPressed[viewId] = true; - } - return; - } - - if (currentHonorShortcuts != s_fHonorShortcuts.end()) - { - if (currentHonorShortcuts->second) - { - const auto myVirtualKey = static_cast(key); - const auto& lookupMap = GetCurrentKeyDictionary(myVirtualKey); - auto buttons = lookupMap.equal_range(myVirtualKey); - RunFirstEnabledButtonCommand(buttons); - - // Ctrl+C and Ctrl+V shifts focus to some button because of which enter doesn't work after copy/paste. So don't shift focus if Ctrl+C or Ctrl+V - // is pressed. When drop down is open, pressing escape shifts focus to clear button. So dont's shift focus if drop down is open. Ctrl+Insert is - // equivalent to Ctrl+C and Shift+Insert is equivalent to Ctrl+V - auto currentIsDropDownOpen = s_IsDropDownOpen.find(viewId); - if (currentIsDropDownOpen != s_IsDropDownOpen.end() && !currentIsDropDownOpen->second) - { - // Do not Light Up Buttons when Ctrl+C, Ctrl+V, Ctrl+Insert or Shift+Insert is pressed - if (!(isControlKeyPressed && (key == VirtualKey::C || key == VirtualKey::V || key == VirtualKey::Insert)) - && !(isShiftKeyPressed && (key == VirtualKey::Insert))) - { - LightUpButtons(buttons); - } - } - } - } - } -} - -void KeyboardShortcutManager::OnKeyUpHandler(CoreWindow ^ sender, KeyEventArgs ^ args) -{ - int viewId = Utils::GetWindowId(); - auto key = args->VirtualKey; - - if (key == VirtualKey::Shift) - { - // Writer lock for the static maps - reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock); - - auto currentShiftKeyPressed = s_ShiftKeyPressed.find(viewId); - - if (currentShiftKeyPressed != s_ShiftKeyPressed.end()) - { - s_ShiftKeyPressed[viewId] = false; - } - } - else if (key == VirtualKey::Control) - { - // Writer lock for the static maps - reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock); - - auto currControlKeyPressed = s_ControlKeyPressed.find(viewId); - - if (currControlKeyPressed != s_ControlKeyPressed.end()) - { - s_ControlKeyPressed[viewId] = false; - } } } @@ -641,7 +520,7 @@ void KeyboardShortcutManager::OnAcceleratorKeyActivated(CoreDispatcher ^, Accele if (args->KeyStatus.IsKeyReleased) { auto key = args->VirtualKey; - bool altPressed = args->KeyStatus.IsMenuKeyDown; + const bool altPressed = args->KeyStatus.IsMenuKeyDown; // If the Alt/Menu key is not pressed then we don't care about the key anymore if (!altPressed) @@ -649,52 +528,45 @@ void KeyboardShortcutManager::OnAcceleratorKeyActivated(CoreDispatcher ^, Accele return; } + const bool controlKeyPressed = (Window::Current->CoreWindow->GetKeyState(VirtualKey::Control) & CoreVirtualKeyStates::Down) == CoreVirtualKeyStates::Down; // Ctrl is pressed in addition to alt, this means Alt Gr is intended. do not navigate. - if ((static_cast(Window::Current->CoreWindow->GetKeyState(VirtualKey::Control)) & static_cast(CoreVirtualKeyStates::Down)) - == static_cast(CoreVirtualKeyStates::Down)) + if (controlKeyPressed) { return; } - const auto& lookupMap = GetCurrentKeyDictionary(static_cast(key), altPressed); - auto listItems = lookupMap.equal_range(static_cast(key)); - for (auto listIterator = listItems.first; listIterator != listItems.second; ++listIterator) + const bool shiftKeyPressed = (Window::Current->CoreWindow->GetKeyState(VirtualKey::Shift) & CoreVirtualKeyStates::Down) == CoreVirtualKeyStates::Down; + const auto lookupMap = GetCurrentKeyDictionary(controlKeyPressed, shiftKeyPressed, altPressed); + if (lookupMap != nullptr) { - auto item = listIterator->second.Resolve(); - if (item != nullptr) + auto listItems = lookupMap->equal_range(static_cast(key)); + for (auto listIterator = listItems.first; listIterator != listItems.second; ++listIterator) { - auto navView = safe_cast(item); - - auto menuItems = static_cast ^>(navView->MenuItemsSource); - if (menuItems != nullptr) + auto item = listIterator->second.Resolve(); + if (item != nullptr) { - auto vm = safe_cast(navView->DataContext); - if (nullptr != vm) + auto navView = safe_cast(item); + + auto menuItems = static_cast ^>(navView->MenuItemsSource); + if (menuItems != nullptr) { - ViewMode toMode = NavCategory::GetViewModeForVirtualKey(static_cast(key)); - auto nvi = dynamic_cast(menuItems->GetAt(NavCategory::GetFlatIndex(toMode))); - if (nvi && nvi->IsEnabled && NavCategory::IsValidViewMode(toMode)) + auto vm = safe_cast(navView->DataContext); + if (nullptr != vm) { - vm->Mode = toMode; - navView->SelectedItem = nvi; + ViewMode toMode = NavCategory::GetViewModeForVirtualKey(static_cast(key)); + auto nvi = dynamic_cast(menuItems->GetAt(NavCategory::GetFlatIndex(toMode))); + if (nvi && nvi->IsEnabled && NavCategory::IsValidViewMode(toMode)) + { + vm->Mode = toMode; + navView->SelectedItem = nvi; + } } } + break; } - break; } } } - - if (args->VirtualKey == VirtualKey::Escape) - { - int viewId = Utils::GetWindowId(); - auto iterViewMap = s_AboutFlyout.find(viewId); - - if ((iterViewMap != s_AboutFlyout.end()) && (iterViewMap->second != nullptr)) - { - iterViewMap->second->Hide(); - } - } } void KeyboardShortcutManager::Initialize() @@ -703,23 +575,12 @@ void KeyboardShortcutManager::Initialize() coreWindow->CharacterReceived += ref new TypedEventHandler(&KeyboardShortcutManager::OnCharacterReceivedHandler); coreWindow->KeyDown += ref new TypedEventHandler(&KeyboardShortcutManager::OnKeyDownHandler); - coreWindow->KeyUp += ref new TypedEventHandler(&KeyboardShortcutManager::OnKeyUpHandler); coreWindow->Dispatcher->AcceleratorKeyActivated += ref new TypedEventHandler(&KeyboardShortcutManager::OnAcceleratorKeyActivated); KeyboardShortcutManager::RegisterNewAppViewId(); } -void KeyboardShortcutManager::ShiftButtonChecked(bool checked) -{ - int viewId = Utils::GetWindowId(); - - if (s_ShiftButtonChecked.find(viewId) != s_ShiftButtonChecked.end()) - { - s_ShiftButtonChecked[viewId] = checked; - } -} - void KeyboardShortcutManager::UpdateDropDownState(bool isOpen) { int viewId = Utils::GetWindowId(); @@ -730,16 +591,6 @@ void KeyboardShortcutManager::UpdateDropDownState(bool isOpen) } } -void KeyboardShortcutManager::UpdateDropDownState(Flyout ^ aboutPageFlyout) -{ - int viewId = Utils::GetWindowId(); - - if (s_AboutFlyout.find(viewId) != s_AboutFlyout.end()) - { - s_AboutFlyout[viewId] = aboutPageFlyout; - } -} - void KeyboardShortcutManager::HonorShortcuts(bool allow) { // Writer lock for the static maps @@ -770,55 +621,41 @@ void KeyboardShortcutManager::RegisterNewAppViewId() int appViewId = Utils::GetWindowId(); // Check if the View Id has already been registered - if (s_CharacterForButtons.find(appViewId) == s_CharacterForButtons.end()) + if (s_characterForButtons.find(appViewId) == s_characterForButtons.end()) { - s_CharacterForButtons.insert(std::make_pair(appViewId, std::multimap())); + s_characterForButtons.insert(make_pair(appViewId, multimap())); } - if (s_VirtualKeysForButtons.find(appViewId) == s_VirtualKeysForButtons.end()) + if (s_virtualKey.find(appViewId) == s_virtualKey.end()) { - s_VirtualKeysForButtons.insert(std::make_pair(appViewId, std::multimap())); + s_virtualKey.insert(make_pair(appViewId, multimap())); } if (s_VirtualKeyControlChordsForButtons.find(appViewId) == s_VirtualKeyControlChordsForButtons.end()) { - s_VirtualKeyControlChordsForButtons.insert(std::make_pair(appViewId, std::multimap())); + s_VirtualKeyControlChordsForButtons.insert(make_pair(appViewId, multimap())); } if (s_VirtualKeyShiftChordsForButtons.find(appViewId) == s_VirtualKeyShiftChordsForButtons.end()) { - s_VirtualKeyShiftChordsForButtons.insert(std::make_pair(appViewId, std::multimap())); + s_VirtualKeyShiftChordsForButtons.insert(make_pair(appViewId, multimap())); } if (s_VirtualKeyAltChordsForButtons.find(appViewId) == s_VirtualKeyAltChordsForButtons.end()) { - s_VirtualKeyAltChordsForButtons.insert(std::make_pair(appViewId, std::multimap())); + s_VirtualKeyAltChordsForButtons.insert(make_pair(appViewId, multimap())); } if (s_VirtualKeyControlShiftChordsForButtons.find(appViewId) == s_VirtualKeyControlShiftChordsForButtons.end()) { - s_VirtualKeyControlShiftChordsForButtons.insert(std::make_pair(appViewId, std::multimap())); + s_VirtualKeyControlShiftChordsForButtons.insert(make_pair(appViewId, multimap())); } - if (s_VirtualKeyInverseChordsForButtons.find(appViewId) == s_VirtualKeyInverseChordsForButtons.end()) - { - s_VirtualKeyInverseChordsForButtons.insert(std::make_pair(appViewId, std::multimap())); - } - - if (s_VirtualKeyControlInverseChordsForButtons.find(appViewId) == s_VirtualKeyControlInverseChordsForButtons.end()) - { - s_VirtualKeyControlInverseChordsForButtons.insert(std::make_pair(appViewId, std::multimap())); - } - - s_ShiftKeyPressed[appViewId] = false; - s_ControlKeyPressed[appViewId] = false; - s_ShiftButtonChecked[appViewId] = false; s_IsDropDownOpen[appViewId] = false; s_ignoreNextEscape[appViewId] = false; s_keepIgnoringEscape[appViewId] = false; s_fHonorShortcuts[appViewId] = true; s_fDisableShortcuts[appViewId] = false; - s_AboutFlyout[appViewId] = nullptr; } void KeyboardShortcutManager::OnWindowClosed(int viewId) @@ -826,25 +663,19 @@ void KeyboardShortcutManager::OnWindowClosed(int viewId) // Writer lock for the static maps reader_writer_lock::scoped_lock lock(s_keyboardShortcutMapLock); - s_CharacterForButtons.erase(viewId); + s_characterForButtons.erase(viewId); - s_VirtualKeysForButtons.erase(viewId); + s_virtualKey.erase(viewId); s_VirtualKeyControlChordsForButtons.erase(viewId); s_VirtualKeyShiftChordsForButtons.erase(viewId); s_VirtualKeyAltChordsForButtons.erase(viewId); s_VirtualKeyControlShiftChordsForButtons.erase(viewId); - s_VirtualKeyInverseChordsForButtons.erase(viewId); - s_VirtualKeyControlInverseChordsForButtons.erase(viewId); - s_ShiftKeyPressed.erase(viewId); - s_ControlKeyPressed.erase(viewId); - s_ShiftButtonChecked.erase(viewId); s_IsDropDownOpen.erase(viewId); s_ignoreNextEscape.erase(viewId); s_keepIgnoringEscape.erase(viewId); s_fHonorShortcuts.erase(viewId); s_fDisableShortcuts.erase(viewId); - s_AboutFlyout.erase(viewId); } void KeyboardShortcutManager::DisableShortcuts(bool disable) diff --git a/src/Calculator/Common/KeyboardShortcutManager.h b/src/Calculator/Common/KeyboardShortcutManager.h index 32ace85..1ca7e48 100644 --- a/src/Calculator/Common/KeyboardShortcutManager.h +++ b/src/Calculator/Common/KeyboardShortcutManager.h @@ -26,8 +26,6 @@ namespace CalculatorApp DEPENDENCY_PROPERTY_ATTACHED_WITH_CALLBACK(MyVirtualKey, VirtualKeyShiftChord); DEPENDENCY_PROPERTY_ATTACHED_WITH_CALLBACK(MyVirtualKey, VirtualKeyAltChord); DEPENDENCY_PROPERTY_ATTACHED_WITH_CALLBACK(MyVirtualKey, VirtualKeyControlShiftChord); - DEPENDENCY_PROPERTY_ATTACHED_WITH_CALLBACK(MyVirtualKey, VirtualKeyInverseChord); - DEPENDENCY_PROPERTY_ATTACHED_WITH_CALLBACK(MyVirtualKey, VirtualKeyControlInverseChord); internal : @@ -45,8 +43,6 @@ namespace CalculatorApp static void HonorShortcuts(bool allow); static void DisableShortcuts(bool disable); static void UpdateDropDownState(bool); - static void ShiftButtonChecked(bool checked); - static void UpdateDropDownState(Windows::UI::Xaml::Controls::Flyout ^ aboutPageFlyout); static void RegisterNewAppViewId(); static void OnWindowClosed(int viewId); @@ -60,11 +56,6 @@ namespace CalculatorApp static void OnVirtualKeyShiftChordPropertyChanged(Windows::UI::Xaml::DependencyObject ^ target, MyVirtualKey oldValue, MyVirtualKey newValue); - static void OnVirtualKeyInverseChordPropertyChanged(Windows::UI::Xaml::DependencyObject ^ target, MyVirtualKey oldValue, MyVirtualKey newValue); - - static void - OnVirtualKeyControlInverseChordPropertyChanged(Windows::UI::Xaml::DependencyObject ^ target, MyVirtualKey oldValue, MyVirtualKey newValue); - static void OnVirtualKeyAltChordPropertyChanged(Windows::UI::Xaml::DependencyObject ^ target, MyVirtualKey oldValue, MyVirtualKey newValue); static void @@ -72,8 +63,25 @@ namespace CalculatorApp static void OnCharacterReceivedHandler(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::CharacterReceivedEventArgs ^ args); static void OnKeyDownHandler(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::KeyEventArgs ^ args); - static void OnKeyUpHandler(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::KeyEventArgs ^ args); static void OnAcceleratorKeyActivated(Windows::UI::Core::CoreDispatcher ^, Windows::UI::Core::AcceleratorKeyEventArgs ^ args); + static const std::multimap* + KeyboardShortcutManager::GetCurrentKeyDictionary(bool controlKeyPressed, bool shiftKeyPressed, bool altPressed); + + private: + static std::map> s_characterForButtons; + static std::map> s_virtualKey; + static std::map> s_VirtualKeyControlChordsForButtons; + static std::map> s_VirtualKeyShiftChordsForButtons; + static std::map> s_VirtualKeyAltChordsForButtons; + static std::map> s_VirtualKeyControlShiftChordsForButtons; + + static std::map s_IsDropDownOpen; + static std::map s_ignoreNextEscape; + static std::map s_keepIgnoringEscape; + static std::map s_fHonorShortcuts; + static std::map s_fDisableShortcuts; + + static Concurrency::reader_writer_lock s_keyboardShortcutMapLock; }; } } diff --git a/src/Calculator/Resources/en-US/Resources.resw b/src/Calculator/Resources/en-US/Resources.resw index 296f790..b4b9941 100644 --- a/src/Calculator/Resources/en-US/Resources.resw +++ b/src/Calculator/Resources/en-US/Resources.resw @@ -481,50 +481,26 @@ O {Locked}The shortcut for the inverted cos button - - O - {Locked}The shortcut for the inverted cos button - O {Locked}The shortcut for the inverted cosh button - - O - {Locked}The shortcut for the inverted cosh button - S {Locked}This is the shortcut for the inverted sin button - - S - {Locked}This is the shortcut for the inverted sin button - S {Locked}This is the shortcut for the inverted sinh button - - S - {Locked}This is the shortcut for the inverted sinh button - T {Locked}This is the shortcut for the inverted tan button. - - T - {Locked}This is the shortcut for the inverted tan button. - T {Locked}This is the shortcut for the inverted tanh button - - T - {Locked}This is the shortcut for the inverted tanh button - N {Locked}This is the shortcut for the power x button. @@ -3587,10 +3563,6 @@ U {Locked}The shortcut for the inverted sec button - - U - {Locked}The shortcut for the inverted sec button - Hyperbolic Arc Secant Screen reader prompt for the Calculator button arc sec in the scientific flyout keypad @@ -3599,10 +3571,6 @@ U {Locked}The shortcut for the inverted sech button - - U - {Locked}The shortcut for the inverted sech button - Cosecant Screen reader prompt for the Calculator button csc in the scientific flyout keypad @@ -3623,14 +3591,6 @@ Arc Cosecant Screen reader prompt for the Calculator button arc csc in the scientific flyout keypad - - I - {Locked}The shortcut for the inverted sec button - - - I - {Locked}The shortcut for the inverted sec button - Hyperbolic Arc Cosecant Screen reader prompt for the Calculator button arc csc in the scientific flyout keypad @@ -3639,10 +3599,6 @@ I {Locked}The shortcut for the inverted sech button - - I - {Locked}The shortcut for the inverted sech button - Cotangent Screen reader prompt for the Calculator button cot in the scientific flyout keypad @@ -3667,18 +3623,10 @@ J {Locked}The shortcut for the inverted sec button - - J - {Locked}The shortcut for the inverted sec button - Hyperbolic Arc Cotangent Screen reader prompt for the Calculator button arc coth in the scientific flyout keypad - - J - {Locked}The shortcut for the inverted sech button - J {Locked}The shortcut for the inverted sech button diff --git a/src/Calculator/Views/MainPage.xaml.cpp b/src/Calculator/Views/MainPage.xaml.cpp index 5af8f4d..f0c0b5e 100644 --- a/src/Calculator/Views/MainPage.xaml.cpp +++ b/src/Calculator/Views/MainPage.xaml.cpp @@ -436,16 +436,14 @@ 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); + KeyboardShortcutManager::HonorShortcuts(false); } void MainPage::OnAboutFlyoutClosed(_In_ Object ^ sender, _In_ Object ^ e) { // Start Honoring Escape once the About page flyout is closed KeyboardShortcutManager::HonorEscape(); - - KeyboardShortcutManager::UpdateDropDownState(nullptr); + KeyboardShortcutManager::HonorShortcuts(!NavView->IsPaneOpen); } void MainPage::OnNavSelectionChanged(_In_ Object ^ sender, _In_ MUXC::NavigationViewSelectionChangedEventArgs ^ e)