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