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 3 // found in the LICENSE file. 4 5 #include "ash/wm/image_cursors.h" 6 7 #include <float.h> 8 9 #include "base/logging.h" 10 #include "base/strings/string16.h" 11 #include "ui/base/cursor/cursor.h" 12 #include "ui/base/cursor/cursor_loader.h" 13 #include "ui/base/cursor/cursors_aura.h" 14 #include "ui/gfx/display.h" 15 #include "ui/gfx/point.h" 16 17 namespace ash { 18 19 const int kImageCursorIds[] = { 20 ui::kCursorNull, 21 ui::kCursorPointer, 22 ui::kCursorNoDrop, 23 ui::kCursorNotAllowed, 24 ui::kCursorCopy, 25 ui::kCursorHand, 26 ui::kCursorMove, 27 ui::kCursorNorthEastResize, 28 ui::kCursorSouthWestResize, 29 ui::kCursorSouthEastResize, 30 ui::kCursorNorthWestResize, 31 ui::kCursorNorthResize, 32 ui::kCursorSouthResize, 33 ui::kCursorEastResize, 34 ui::kCursorWestResize, 35 ui::kCursorIBeam, 36 ui::kCursorAlias, 37 ui::kCursorCell, 38 ui::kCursorContextMenu, 39 ui::kCursorCross, 40 ui::kCursorHelp, 41 ui::kCursorVerticalText, 42 ui::kCursorZoomIn, 43 ui::kCursorZoomOut, 44 ui::kCursorRowResize, 45 ui::kCursorColumnResize, 46 ui::kCursorEastWestResize, 47 ui::kCursorNorthSouthResize, 48 ui::kCursorNorthEastSouthWestResize, 49 ui::kCursorNorthWestSouthEastResize, 50 ui::kCursorGrab, 51 ui::kCursorGrabbing, 52 }; 53 54 const int kAnimatedCursorIds[] = { 55 ui::kCursorWait, 56 ui::kCursorProgress 57 }; 58 59 ImageCursors::ImageCursors() : scale_(1.f), cursor_set_(ui::CURSOR_SET_NORMAL) { 60 } 61 62 ImageCursors::~ImageCursors() { 63 } 64 65 gfx::Display ImageCursors::GetDisplay() const { 66 if (!cursor_loader_) { 67 NOTREACHED(); 68 // Returning default on release build as it's not serious enough to crash 69 // even if this ever happens. 70 return gfx::Display(); 71 } 72 return cursor_loader_->display(); 73 } 74 75 bool ImageCursors::SetDisplay(const gfx::Display& display) { 76 float device_scale_factor = display.device_scale_factor(); 77 if (!cursor_loader_) { 78 cursor_loader_.reset(ui::CursorLoader::Create()); 79 cursor_loader_->set_scale(scale_); 80 } else if (cursor_loader_->display().rotation() == display.rotation() && 81 cursor_loader_->display().device_scale_factor() == 82 device_scale_factor) { 83 return false; 84 } 85 86 cursor_loader_->set_display(display); 87 ReloadCursors(); 88 return true; 89 } 90 91 void ImageCursors::ReloadCursors() { 92 const gfx::Display& display = cursor_loader_->display(); 93 float device_scale_factor = display.device_scale_factor(); 94 95 cursor_loader_->UnloadAll(); 96 97 for (size_t i = 0; i < arraysize(kImageCursorIds); ++i) { 98 int resource_id = -1; 99 gfx::Point hot_point; 100 bool success = ui::GetCursorDataFor(cursor_set_, 101 kImageCursorIds[i], 102 device_scale_factor, 103 &resource_id, 104 &hot_point); 105 DCHECK(success); 106 cursor_loader_->LoadImageCursor(kImageCursorIds[i], resource_id, hot_point); 107 } 108 for (size_t i = 0; i < arraysize(kAnimatedCursorIds); ++i) { 109 int resource_id = -1; 110 gfx::Point hot_point; 111 bool success = ui::GetAnimatedCursorDataFor(cursor_set_, 112 kAnimatedCursorIds[i], 113 device_scale_factor, 114 &resource_id, 115 &hot_point); 116 DCHECK(success); 117 cursor_loader_->LoadAnimatedCursor(kAnimatedCursorIds[i], 118 resource_id, 119 hot_point, 120 ui::kAnimatedCursorFrameDelayMs); 121 } 122 } 123 124 void ImageCursors::SetScale(float scale) { 125 if (scale < FLT_EPSILON) { 126 NOTREACHED() << "Scale must be bigger than 0."; 127 scale = 1.0f; 128 } 129 130 scale_ = scale; 131 132 if (cursor_loader_.get()) { 133 cursor_loader_->set_scale(scale); 134 ReloadCursors(); 135 } 136 } 137 138 void ImageCursors::SetCursorSet(ui::CursorSetType cursor_set) { 139 if (cursor_set_ == cursor_set) 140 return; 141 142 cursor_set_ = cursor_set; 143 144 if (cursor_loader_.get()) 145 ReloadCursors(); 146 } 147 148 void ImageCursors::SetPlatformCursor(gfx::NativeCursor* cursor) { 149 cursor_loader_->SetPlatformCursor(cursor); 150 } 151 152 } // namespace ash 153