• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "ui/views/corewm/cursor_manager.h"
6 
7 #include "base/logging.h"
8 #include "ui/aura/client/cursor_client_observer.h"
9 #include "ui/views/corewm/native_cursor_manager.h"
10 #include "ui/views/corewm/native_cursor_manager_delegate.h"
11 
12 namespace views {
13 namespace corewm {
14 
15 namespace internal {
16 
17 // Represents the cursor state which is composed of cursor type, visibility, and
18 // mouse events enable state. When mouse events are disabled, the cursor is
19 // always invisible.
20 class CursorState {
21  public:
CursorState()22   CursorState()
23       : cursor_(ui::kCursorNone),
24         visible_(true),
25         scale_(1.f),
26         cursor_set_(ui::CURSOR_SET_NORMAL),
27         mouse_events_enabled_(true),
28         visible_on_mouse_events_enabled_(true) {
29   }
30 
cursor() const31   gfx::NativeCursor cursor() const { return cursor_; }
set_cursor(gfx::NativeCursor cursor)32   void set_cursor(gfx::NativeCursor cursor) { cursor_ = cursor; }
33 
visible() const34   bool visible() const { return visible_; }
SetVisible(bool visible)35   void SetVisible(bool visible) {
36     if (mouse_events_enabled_)
37       visible_ = visible;
38     // Ignores the call when mouse events disabled.
39   }
40 
scale() const41   float scale() const { return scale_; }
set_scale(float scale)42   void set_scale(float scale) {
43     scale_ = scale;
44   }
45 
cursor_set() const46   ui::CursorSetType cursor_set() const { return cursor_set_; }
set_cursor_set(ui::CursorSetType cursor_set)47   void set_cursor_set(ui::CursorSetType cursor_set) {
48     cursor_set_ = cursor_set;
49   }
50 
mouse_events_enabled() const51   bool mouse_events_enabled() const { return mouse_events_enabled_; }
SetMouseEventsEnabled(bool enabled)52   void SetMouseEventsEnabled(bool enabled) {
53     if (mouse_events_enabled_ == enabled)
54       return;
55     mouse_events_enabled_ = enabled;
56 
57     // Restores the visibility when mouse events are enabled.
58     if (enabled) {
59       visible_ = visible_on_mouse_events_enabled_;
60     } else {
61       visible_on_mouse_events_enabled_ = visible_;
62       visible_ = false;
63     }
64   }
65 
66  private:
67   gfx::NativeCursor cursor_;
68   bool visible_;
69   float scale_;
70   ui::CursorSetType cursor_set_;
71   bool mouse_events_enabled_;
72 
73   // The visibility to set when mouse events are enabled.
74   bool visible_on_mouse_events_enabled_;
75 
76   DISALLOW_COPY_AND_ASSIGN(CursorState);
77 };
78 
79 }  // namespace internal
80 
CursorManager(scoped_ptr<NativeCursorManager> delegate)81 CursorManager::CursorManager(scoped_ptr<NativeCursorManager> delegate)
82     : delegate_(delegate.Pass()),
83       cursor_lock_count_(0),
84       current_state_(new internal::CursorState),
85       state_on_unlock_(new internal::CursorState) {
86 }
87 
~CursorManager()88 CursorManager::~CursorManager() {
89 }
90 
SetCursor(gfx::NativeCursor cursor)91 void CursorManager::SetCursor(gfx::NativeCursor cursor) {
92   state_on_unlock_->set_cursor(cursor);
93   if (cursor_lock_count_ == 0 &&
94       GetCursor() != state_on_unlock_->cursor()) {
95     delegate_->SetCursor(state_on_unlock_->cursor(), this);
96   }
97 }
98 
GetCursor() const99 gfx::NativeCursor CursorManager::GetCursor() const {
100   return current_state_->cursor();
101 }
102 
ShowCursor()103 void CursorManager::ShowCursor() {
104   state_on_unlock_->SetVisible(true);
105   if (cursor_lock_count_ == 0 &&
106       IsCursorVisible() != state_on_unlock_->visible()) {
107     delegate_->SetVisibility(state_on_unlock_->visible(), this);
108     FOR_EACH_OBSERVER(aura::client::CursorClientObserver, observers_,
109                       OnCursorVisibilityChanged(true));
110   }
111 }
112 
HideCursor()113 void CursorManager::HideCursor() {
114   state_on_unlock_->SetVisible(false);
115   if (cursor_lock_count_ == 0 &&
116       IsCursorVisible() != state_on_unlock_->visible()) {
117     delegate_->SetVisibility(state_on_unlock_->visible(), this);
118     FOR_EACH_OBSERVER(aura::client::CursorClientObserver, observers_,
119                       OnCursorVisibilityChanged(false));
120   }
121 }
122 
IsCursorVisible() const123 bool CursorManager::IsCursorVisible() const {
124   return current_state_->visible();
125 }
126 
SetScale(float scale)127 void CursorManager::SetScale(float scale) {
128   state_on_unlock_->set_scale(scale);
129   if (GetScale() != state_on_unlock_->scale())
130     delegate_->SetScale(state_on_unlock_->scale(), this);
131 }
132 
GetScale() const133 float CursorManager::GetScale() const {
134   return current_state_->scale();
135 }
136 
SetCursorSet(ui::CursorSetType cursor_set)137 void CursorManager::SetCursorSet(ui::CursorSetType cursor_set) {
138   state_on_unlock_->set_cursor_set(cursor_set);
139   if (GetCursorSet() != state_on_unlock_->cursor_set())
140     delegate_->SetCursorSet(state_on_unlock_->cursor_set(), this);
141 }
142 
GetCursorSet() const143 ui::CursorSetType CursorManager::GetCursorSet() const {
144   return current_state_->cursor_set();
145 }
146 
EnableMouseEvents()147 void CursorManager::EnableMouseEvents() {
148   state_on_unlock_->SetMouseEventsEnabled(true);
149   if (cursor_lock_count_ == 0 &&
150       IsMouseEventsEnabled() != state_on_unlock_->mouse_events_enabled()) {
151     delegate_->SetMouseEventsEnabled(state_on_unlock_->mouse_events_enabled(),
152                                      this);
153   }
154 }
155 
DisableMouseEvents()156 void CursorManager::DisableMouseEvents() {
157   state_on_unlock_->SetMouseEventsEnabled(false);
158   if (cursor_lock_count_ == 0 &&
159       IsMouseEventsEnabled() != state_on_unlock_->mouse_events_enabled()) {
160     delegate_->SetMouseEventsEnabled(state_on_unlock_->mouse_events_enabled(),
161                                      this);
162   }
163 }
164 
IsMouseEventsEnabled() const165 bool CursorManager::IsMouseEventsEnabled() const {
166   return current_state_->mouse_events_enabled();
167 }
168 
SetDisplay(const gfx::Display & display)169 void CursorManager::SetDisplay(const gfx::Display& display) {
170   delegate_->SetDisplay(display, this);
171 }
172 
LockCursor()173 void CursorManager::LockCursor() {
174   cursor_lock_count_++;
175 }
176 
UnlockCursor()177 void CursorManager::UnlockCursor() {
178   cursor_lock_count_--;
179   DCHECK_GE(cursor_lock_count_, 0);
180   if (cursor_lock_count_ > 0)
181     return;
182 
183   if (GetCursor() != state_on_unlock_->cursor()) {
184     delegate_->SetCursor(state_on_unlock_->cursor(), this);
185   }
186   if (IsMouseEventsEnabled() != state_on_unlock_->mouse_events_enabled()) {
187     delegate_->SetMouseEventsEnabled(state_on_unlock_->mouse_events_enabled(),
188                                      this);
189   }
190   if (IsCursorVisible() != state_on_unlock_->visible()) {
191     delegate_->SetVisibility(state_on_unlock_->visible(),
192                              this);
193   }
194 }
195 
IsCursorLocked() const196 bool CursorManager::IsCursorLocked() const {
197   return cursor_lock_count_ > 0;
198 }
199 
AddObserver(aura::client::CursorClientObserver * observer)200 void CursorManager::AddObserver(
201     aura::client::CursorClientObserver* observer) {
202   observers_.AddObserver(observer);
203 }
204 
RemoveObserver(aura::client::CursorClientObserver * observer)205 void CursorManager::RemoveObserver(
206     aura::client::CursorClientObserver* observer) {
207   observers_.RemoveObserver(observer);
208 }
209 
CommitCursor(gfx::NativeCursor cursor)210 void CursorManager::CommitCursor(gfx::NativeCursor cursor) {
211   current_state_->set_cursor(cursor);
212 }
213 
CommitVisibility(bool visible)214 void CursorManager::CommitVisibility(bool visible) {
215   // TODO(tdanderson): Find a better place for this so we don't
216   // notify the observers more than is necessary.
217   FOR_EACH_OBSERVER(aura::client::CursorClientObserver, observers_,
218                     OnCursorVisibilityChanged(visible));
219   current_state_->SetVisible(visible);
220 }
221 
CommitScale(float scale)222 void CursorManager::CommitScale(float scale) {
223   current_state_->set_scale(scale);
224 }
225 
CommitCursorSet(ui::CursorSetType cursor_set)226 void CursorManager::CommitCursorSet(ui::CursorSetType cursor_set) {
227   current_state_->set_cursor_set(cursor_set);
228 }
229 
CommitMouseEventsEnabled(bool enabled)230 void CursorManager::CommitMouseEventsEnabled(bool enabled) {
231   current_state_->SetMouseEventsEnabled(enabled);
232 }
233 
234 }  // namespace corewm
235 }  // namespace views
236