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: 22 CursorState() 23 : cursor_(ui::kCursorNone), 24 visible_(true), 25 scale_(1.f), 26 mouse_events_enabled_(true), 27 visible_on_mouse_events_enabled_(true) { 28 } 29 30 gfx::NativeCursor cursor() const { return cursor_; } 31 void set_cursor(gfx::NativeCursor cursor) { cursor_ = cursor; } 32 33 bool visible() const { return visible_; } 34 void SetVisible(bool visible) { 35 if (mouse_events_enabled_) 36 visible_ = visible; 37 // Ignores the call when mouse events disabled. 38 } 39 40 float scale() const { return scale_; } 41 void set_scale(float scale) { 42 scale_ = scale; 43 } 44 45 bool mouse_events_enabled() const { return mouse_events_enabled_; } 46 void SetMouseEventsEnabled(bool enabled) { 47 if (mouse_events_enabled_ == enabled) 48 return; 49 mouse_events_enabled_ = enabled; 50 51 // Restores the visibility when mouse events are enabled. 52 if (enabled) { 53 visible_ = visible_on_mouse_events_enabled_; 54 } else { 55 visible_on_mouse_events_enabled_ = visible_; 56 visible_ = false; 57 } 58 } 59 60 private: 61 gfx::NativeCursor cursor_; 62 bool visible_; 63 float scale_; 64 bool mouse_events_enabled_; 65 66 // The visibility to set when mouse events are enabled. 67 bool visible_on_mouse_events_enabled_; 68 69 DISALLOW_COPY_AND_ASSIGN(CursorState); 70 }; 71 72 } // namespace internal 73 74 CursorManager::CursorManager(scoped_ptr<NativeCursorManager> delegate) 75 : delegate_(delegate.Pass()), 76 cursor_lock_count_(0), 77 current_state_(new internal::CursorState), 78 state_on_unlock_(new internal::CursorState) { 79 } 80 81 CursorManager::~CursorManager() { 82 } 83 84 void CursorManager::SetCursor(gfx::NativeCursor cursor) { 85 state_on_unlock_->set_cursor(cursor); 86 if (cursor_lock_count_ == 0 && 87 GetCurrentCursor() != state_on_unlock_->cursor()) { 88 delegate_->SetCursor(state_on_unlock_->cursor(), this); 89 } 90 } 91 92 void CursorManager::ShowCursor() { 93 state_on_unlock_->SetVisible(true); 94 if (cursor_lock_count_ == 0 && 95 IsCursorVisible() != state_on_unlock_->visible()) { 96 delegate_->SetVisibility(state_on_unlock_->visible(), this); 97 FOR_EACH_OBSERVER(aura::client::CursorClientObserver, observers_, 98 OnCursorVisibilityChanged(true)); 99 } 100 } 101 102 void CursorManager::HideCursor() { 103 state_on_unlock_->SetVisible(false); 104 if (cursor_lock_count_ == 0 && 105 IsCursorVisible() != state_on_unlock_->visible()) { 106 delegate_->SetVisibility(state_on_unlock_->visible(), this); 107 FOR_EACH_OBSERVER(aura::client::CursorClientObserver, observers_, 108 OnCursorVisibilityChanged(false)); 109 } 110 } 111 112 bool CursorManager::IsCursorVisible() const { 113 return current_state_->visible(); 114 } 115 116 void CursorManager::SetScale(float scale) { 117 state_on_unlock_->set_scale(scale); 118 if (GetCurrentScale() != state_on_unlock_->scale()) 119 delegate_->SetScale(state_on_unlock_->scale(), this); 120 } 121 122 float CursorManager::GetCurrentScale() const { 123 return current_state_->scale(); 124 } 125 126 void CursorManager::EnableMouseEvents() { 127 state_on_unlock_->SetMouseEventsEnabled(true); 128 if (cursor_lock_count_ == 0 && 129 IsMouseEventsEnabled() != state_on_unlock_->mouse_events_enabled()) { 130 delegate_->SetMouseEventsEnabled(state_on_unlock_->mouse_events_enabled(), 131 this); 132 } 133 } 134 135 void CursorManager::DisableMouseEvents() { 136 state_on_unlock_->SetMouseEventsEnabled(false); 137 if (cursor_lock_count_ == 0 && 138 IsMouseEventsEnabled() != state_on_unlock_->mouse_events_enabled()) { 139 delegate_->SetMouseEventsEnabled(state_on_unlock_->mouse_events_enabled(), 140 this); 141 } 142 } 143 144 bool CursorManager::IsMouseEventsEnabled() const { 145 return current_state_->mouse_events_enabled(); 146 } 147 148 void CursorManager::SetDisplay(const gfx::Display& display) { 149 delegate_->SetDisplay(display, this); 150 } 151 152 void CursorManager::LockCursor() { 153 cursor_lock_count_++; 154 } 155 156 void CursorManager::UnlockCursor() { 157 cursor_lock_count_--; 158 DCHECK_GE(cursor_lock_count_, 0); 159 if (cursor_lock_count_ > 0) 160 return; 161 162 if (GetCurrentCursor() != state_on_unlock_->cursor()) { 163 delegate_->SetCursor(state_on_unlock_->cursor(), this); 164 } 165 if (IsMouseEventsEnabled() != state_on_unlock_->mouse_events_enabled()) { 166 delegate_->SetMouseEventsEnabled(state_on_unlock_->mouse_events_enabled(), 167 this); 168 } 169 if (IsCursorVisible() != state_on_unlock_->visible()) { 170 delegate_->SetVisibility(state_on_unlock_->visible(), 171 this); 172 } 173 } 174 175 void CursorManager::AddObserver( 176 aura::client::CursorClientObserver* observer) { 177 observers_.AddObserver(observer); 178 } 179 180 void CursorManager::RemoveObserver( 181 aura::client::CursorClientObserver* observer) { 182 observers_.RemoveObserver(observer); 183 } 184 185 gfx::NativeCursor CursorManager::GetCurrentCursor() const { 186 return current_state_->cursor(); 187 } 188 189 bool CursorManager::GetCurrentVisibility() const { 190 return current_state_->visible(); 191 } 192 193 bool CursorManager::GetMouseEventsEnabled() const { 194 return current_state_->mouse_events_enabled(); 195 } 196 197 void CursorManager::CommitCursor(gfx::NativeCursor cursor) { 198 current_state_->set_cursor(cursor); 199 } 200 201 void CursorManager::CommitVisibility(bool visible) { 202 FOR_EACH_OBSERVER(aura::client::CursorClientObserver, observers_, 203 OnCursorVisibilityChanged(visible)); 204 current_state_->SetVisible(visible); 205 } 206 207 void CursorManager::CommitScale(float scale) { 208 current_state_->set_scale(scale); 209 } 210 211 void CursorManager::CommitMouseEventsEnabled(bool enabled) { 212 current_state_->SetMouseEventsEnabled(enabled); 213 } 214 215 } // namespace corewm 216 } // namespace views 217