OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/base/accelerators/accelerator_manager.h" | 5 #include "ui/base/accelerators/accelerator_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 | 10 |
11 namespace ui { | 11 namespace ui { |
12 | 12 |
13 AcceleratorManager::AcceleratorManager() : last_event_type_(ET_KEY_PRESSED) { | 13 AcceleratorManager::AcceleratorManager() : last_event_type_(ET_KEY_PRESSED) { |
14 } | 14 } |
15 | 15 |
16 AcceleratorManager::~AcceleratorManager() { | 16 AcceleratorManager::~AcceleratorManager() { |
17 } | 17 } |
18 | 18 |
19 void AcceleratorManager::Register(const Accelerator& accelerator, | 19 void AcceleratorManager::Register(const Accelerator& accelerator, |
20 bool priority, | |
20 AcceleratorTarget* target) { | 21 AcceleratorTarget* target) { |
21 AcceleratorTargetList& targets = accelerators_[accelerator]; | 22 AcceleratorTargetList& targets = accelerators_[accelerator].second; |
22 DCHECK(std::find(targets.begin(), targets.end(), target) == targets.end()) | 23 DCHECK(std::find(targets.begin(), targets.end(), target) == targets.end()) |
23 << "Registering the same target multiple times"; | 24 << "Registering the same target multiple times"; |
24 targets.push_front(target); | 25 |
26 // All priority accelerators go to the front of the line. | |
27 if (priority) { | |
28 DCHECK(!accelerators_[accelerator].first) | |
29 << "Only one _priority_ handler can be registered"; | |
30 targets.push_front(target); | |
31 // Mark that we have a priority accelerator at the front. | |
32 accelerators_[accelerator].first = true; | |
33 return; | |
34 } | |
35 | |
36 // We are registering a normal priority handler. If no priority accelerator | |
37 // handler has been registered before us, just add the new handler to the | |
38 // front. Otherwise, register it after the first (only) priority handler. | |
39 if (!accelerators_[accelerator].first) | |
40 targets.push_front(target); | |
41 else | |
42 targets.insert(++targets.begin(), target); | |
25 } | 43 } |
26 | 44 |
27 void AcceleratorManager::Unregister(const Accelerator& accelerator, | 45 void AcceleratorManager::Unregister(const Accelerator& accelerator, |
28 AcceleratorTarget* target) { | 46 AcceleratorTarget* target) { |
29 AcceleratorMap::iterator map_iter = accelerators_.find(accelerator); | 47 AcceleratorMap::iterator map_iter = accelerators_.find(accelerator); |
30 if (map_iter == accelerators_.end()) { | 48 if (map_iter == accelerators_.end()) { |
31 NOTREACHED() << "Unregistering non-existing accelerator"; | 49 NOTREACHED() << "Unregistering non-existing accelerator"; |
32 return; | 50 return; |
33 } | 51 } |
34 | 52 |
35 AcceleratorTargetList* targets = &map_iter->second; | 53 AcceleratorTargetList* targets = &map_iter->second.second; |
36 AcceleratorTargetList::iterator target_iter = | 54 AcceleratorTargetList::iterator target_iter = |
37 std::find(targets->begin(), targets->end(), target); | 55 std::find(targets->begin(), targets->end(), target); |
38 if (target_iter == targets->end()) { | 56 if (target_iter == targets->end()) { |
39 NOTREACHED() << "Unregistering accelerator for wrong target"; | 57 NOTREACHED() << "Unregistering accelerator for wrong target"; |
40 return; | 58 return; |
41 } | 59 } |
42 | 60 |
61 // Check to see if we have a priority handler and whether we are removing it. | |
62 if (accelerators_[accelerator].first && target_iter == targets->begin()) { | |
63 // We've are taking the priority accelerator away, flip the priority flag. | |
64 accelerators_[accelerator].first = false; | |
65 } | |
66 | |
43 targets->erase(target_iter); | 67 targets->erase(target_iter); |
44 } | 68 } |
45 | 69 |
46 void AcceleratorManager::UnregisterAll(AcceleratorTarget* target) { | 70 void AcceleratorManager::UnregisterAll(AcceleratorTarget* target) { |
47 for (AcceleratorMap::iterator map_iter = accelerators_.begin(); | 71 for (AcceleratorMap::iterator map_iter = accelerators_.begin(); |
48 map_iter != accelerators_.end(); ++map_iter) { | 72 map_iter != accelerators_.end(); ++map_iter) { |
49 AcceleratorTargetList* targets = &map_iter->second; | 73 AcceleratorTargetList* targets = &map_iter->second.second; |
50 targets->remove(target); | 74 targets->remove(target); |
51 } | 75 } |
52 } | 76 } |
53 | 77 |
54 bool AcceleratorManager::Process(const Accelerator& accelerator) { | 78 bool AcceleratorManager::Process(const Accelerator& accelerator) { |
55 bool result = false; | 79 bool result = false; |
56 AcceleratorMap::iterator map_iter = accelerators_.find(accelerator); | 80 AcceleratorMap::iterator map_iter = accelerators_.find(accelerator); |
57 if (map_iter != accelerators_.end() && ShouldHandle(accelerator)) { | 81 if (map_iter != accelerators_.end() && ShouldHandle(accelerator)) { |
58 // We have to copy the target list here, because an AcceleratorPressed | 82 // We have to copy the target list here, because an AcceleratorPressed |
59 // event handler may modify the list. | 83 // event handler may modify the list. |
60 AcceleratorTargetList targets(map_iter->second); | 84 AcceleratorTargetList targets(map_iter->second.second); |
61 for (AcceleratorTargetList::iterator iter = targets.begin(); | 85 for (AcceleratorTargetList::iterator iter = targets.begin(); |
62 iter != targets.end(); ++iter) { | 86 iter != targets.end(); ++iter) { |
63 if ((*iter)->CanHandleAccelerators() && | 87 if ((*iter)->CanHandleAccelerators() && |
64 (*iter)->AcceleratorPressed(accelerator)) { | 88 (*iter)->AcceleratorPressed(accelerator)) { |
65 result = true; | 89 result = true; |
66 break; | 90 break; |
67 } | 91 } |
68 } | 92 } |
69 } | 93 } |
70 last_event_type_ = accelerator.type(); | 94 last_event_type_ = accelerator.type(); |
71 return result; | 95 return result; |
72 } | 96 } |
73 | 97 |
74 AcceleratorTarget* AcceleratorManager::GetCurrentTarget( | 98 AcceleratorTarget* AcceleratorManager::GetCurrentTarget( |
75 const Accelerator& accelerator) const { | 99 const Accelerator& accelerator) const { |
76 AcceleratorMap::const_iterator map_iter = accelerators_.find(accelerator); | 100 AcceleratorMap::const_iterator map_iter = accelerators_.find(accelerator); |
77 if (map_iter == accelerators_.end() || map_iter->second.empty()) | 101 if (map_iter == accelerators_.end() || map_iter->second.second.empty()) |
78 return NULL; | 102 return NULL; |
79 return map_iter->second.front(); | 103 return map_iter->second.second.front(); |
104 } | |
105 | |
106 bool AcceleratorManager::HasPriorityHandler( | |
107 const Accelerator& accelerator) const { | |
108 AcceleratorMap::const_iterator map_iter = accelerators_.find(accelerator); | |
109 if (map_iter == accelerators_.end() || map_iter->second.second.empty()) | |
110 return false; | |
111 | |
112 // Check if we have a priority handler. If not, there's no more work needed. | |
113 if (!map_iter->second.first) | |
114 return false; | |
115 | |
116 // If the priority handler says it cannot handle the accelerator, we must not | |
117 // count it as one. | |
sadrul
2012/02/21 16:17:28
In this case, does it make sense to have multiple
Finnur
2012/02/21 21:58:21
Right now, we DCHECK if there is more than one. In
| |
118 return map_iter->second.second.front()->CanHandleAccelerators(); | |
80 } | 119 } |
81 | 120 |
82 bool AcceleratorManager::ShouldHandle(const Accelerator& accelerator) const { | 121 bool AcceleratorManager::ShouldHandle(const Accelerator& accelerator) const { |
83 if (accelerator.type() != ET_KEY_RELEASED && | 122 if (accelerator.type() != ET_KEY_RELEASED && |
84 accelerator.type() != ET_TRANSLATED_KEY_RELEASE) { | 123 accelerator.type() != ET_TRANSLATED_KEY_RELEASE) { |
85 return true; | 124 return true; |
86 } | 125 } |
87 // This check is necessary e.g. not to process the Shift+Alt+ET_KEY_RELEASED | 126 // This check is necessary e.g. not to process the Shift+Alt+ET_KEY_RELEASED |
88 // Accelerator for Chrome OS (see ash/accelerators/accelerator_controller.cc) | 127 // Accelerator for Chrome OS (see ash/accelerators/accelerator_controller.cc) |
89 // when Shift+Alt+Tab is pressed and then Tab is released. | 128 // when Shift+Alt+Tab is pressed and then Tab is released. |
90 if (last_event_type_ == ET_KEY_PRESSED || | 129 if (last_event_type_ == ET_KEY_PRESSED || |
91 last_event_type_ == ET_TRANSLATED_KEY_PRESS) { | 130 last_event_type_ == ET_TRANSLATED_KEY_PRESS) { |
92 return true; | 131 return true; |
93 } | 132 } |
94 return false; | 133 return false; |
95 } | 134 } |
96 | 135 |
97 } // namespace ui | 136 } // namespace ui |
OLD | NEW |