15c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Copyright 2014 The Chromium Authors. All rights reserved.
25c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Use of this source code is governed by a BSD-style license that can be
35c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// found in the LICENSE file.
45c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
55c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/base/cursor/image_cursors.h"
65c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
75c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include <float.h>
85c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
95c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/logging.h"
105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/strings/string16.h"
115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/base/cursor/cursor.h"
125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/base/cursor/cursor_loader.h"
135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/base/cursor/cursors_aura.h"
145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/gfx/display.h"
155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/gfx/point.h"
165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace ui {
185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace {
205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuconst int kImageCursorIds[] = {
225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorNull,
235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorPointer,
245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorNoDrop,
255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorNotAllowed,
265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorCopy,
275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorHand,
285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorMove,
295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorNorthEastResize,
305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorSouthWestResize,
315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorSouthEastResize,
325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorNorthWestResize,
335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorNorthResize,
345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorSouthResize,
355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorEastResize,
365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorWestResize,
375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorIBeam,
385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorAlias,
395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorCell,
405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorContextMenu,
415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorCross,
425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorHelp,
435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorVerticalText,
445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorZoomIn,
455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorZoomOut,
465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorRowResize,
475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorColumnResize,
485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorEastWestResize,
495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorNorthSouthResize,
505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorNorthEastSouthWestResize,
515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorNorthWestSouthEastResize,
525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorGrab,
535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorGrabbing,
545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu};
555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuconst int kAnimatedCursorIds[] = {
575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorWait,
585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  kCursorProgress
595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu};
605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}  // namespace
625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuImageCursors::ImageCursors() : cursor_set_(CURSOR_SET_NORMAL) {
645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuImageCursors::~ImageCursors() {
675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liufloat ImageCursors::GetScale() const {
705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!cursor_loader_) {
715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    NOTREACHED();
725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Returning default on release build as it's not serious enough to crash
735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // even if this ever happens.
745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return 1.0f;
755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return cursor_loader_->scale();
775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liugfx::Display::Rotation ImageCursors::GetRotation() const {
805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!cursor_loader_) {
815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    NOTREACHED();
825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Returning default on release build as it's not serious enough to crash
835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // even if this ever happens.
845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return gfx::Display::ROTATE_0;
855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return cursor_loader_->rotation();
875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool ImageCursors::SetDisplay(const gfx::Display& display,
905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                              float scale_factor) {
915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!cursor_loader_) {
925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    cursor_loader_.reset(CursorLoader::Create());
935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  } else if (cursor_loader_->rotation() == display.rotation() &&
945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu             cursor_loader_->scale() == scale_factor) {
955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return false;
965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  cursor_loader_->set_rotation(display.rotation());
995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  cursor_loader_->set_scale(scale_factor);
1005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ReloadCursors();
1015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return true;
1025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
1035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid ImageCursors::ReloadCursors() {
1055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  float device_scale_factor = cursor_loader_->scale();
1065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  cursor_loader_->UnloadAll();
1085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  for (size_t i = 0; i < arraysize(kImageCursorIds); ++i) {
1105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    int resource_id = -1;
1115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    gfx::Point hot_point;
1125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    bool success = GetCursorDataFor(cursor_set_,
1135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                    kImageCursorIds[i],
1145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                    device_scale_factor,
1155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                    &resource_id,
1165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                    &hot_point);
1175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    DCHECK(success);
1185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    cursor_loader_->LoadImageCursor(kImageCursorIds[i], resource_id, hot_point);
1195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
1205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  for (size_t i = 0; i < arraysize(kAnimatedCursorIds); ++i) {
1215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    int resource_id = -1;
1225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    gfx::Point hot_point;
1235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    bool success = GetAnimatedCursorDataFor(cursor_set_,
1245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                            kAnimatedCursorIds[i],
1255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                            device_scale_factor,
1265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                            &resource_id,
1275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                            &hot_point);
1285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    DCHECK(success);
1295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    cursor_loader_->LoadAnimatedCursor(kAnimatedCursorIds[i],
1305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                       resource_id,
1315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                       hot_point,
1325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                       kAnimatedCursorFrameDelayMs);
1335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
1345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
1355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid ImageCursors::SetCursorSet(CursorSetType cursor_set) {
1375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (cursor_set_ == cursor_set)
1385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return;
1395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  cursor_set_ = cursor_set;
1415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (cursor_loader_.get())
1435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    ReloadCursors();
1445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
1455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid ImageCursors::SetPlatformCursor(gfx::NativeCursor* cursor) {
1475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  cursor_loader_->SetPlatformCursor(cursor);
1485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
1495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}  // namespace ui
151