Home | History | Annotate | Download | only in corewm
      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