cursors_aura.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
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/base/cursor/cursors_aura.h" 6 7#include "grit/ui_resources.h" 8#include "ui/base/resource/resource_bundle.h" 9#include "ui/gfx/point.h" 10 11namespace ui { 12namespace { 13 14struct HotPoint { 15 int x; 16 int y; 17}; 18 19struct CursorData { 20 int id; 21 int resource_id; 22 HotPoint hot_1x; 23 HotPoint hot_2x; 24}; 25 26struct CursorSet { 27 const CursorSetType id; 28 const CursorData* cursors; 29 const int length; 30 const CursorData* animated_cursors; 31 const int animated_length; 32}; 33 34const CursorData kNormalCursors[] = { 35 {ui::kCursorNull, IDR_AURA_CURSOR_PTR, {4, 4}, {8, 9}}, 36 {ui::kCursorPointer, IDR_AURA_CURSOR_PTR, {4, 4}, {8, 9}}, 37 {ui::kCursorNoDrop, IDR_AURA_CURSOR_NO_DROP, {9, 9}, {18, 18}}, 38 {ui::kCursorNotAllowed, IDR_AURA_CURSOR_NO_DROP, {9, 9}, {18, 18}}, 39 {ui::kCursorCopy, IDR_AURA_CURSOR_COPY, {9, 9}, {18, 18}}, 40 {ui::kCursorHand, IDR_AURA_CURSOR_HAND, {9, 4}, {19, 8}}, 41 {ui::kCursorMove, IDR_AURA_CURSOR_MOVE, {11, 11}, {23, 23}}, 42 {ui::kCursorNorthEastResize, IDR_AURA_CURSOR_NORTH_EAST_RESIZE, 43 {12, 11}, {25, 23}}, 44 {ui::kCursorSouthWestResize, IDR_AURA_CURSOR_SOUTH_WEST_RESIZE, 45 {12, 11}, {25, 23}}, 46 {ui::kCursorSouthEastResize, IDR_AURA_CURSOR_SOUTH_EAST_RESIZE, 47 {11, 11}, {24, 23}}, 48 {ui::kCursorNorthWestResize, IDR_AURA_CURSOR_NORTH_WEST_RESIZE, 49 {11, 11}, {24, 23}}, 50 {ui::kCursorNorthResize, IDR_AURA_CURSOR_NORTH_RESIZE, {11, 12}, {23, 23}}, 51 {ui::kCursorSouthResize, IDR_AURA_CURSOR_SOUTH_RESIZE, {11, 12}, {23, 23}}, 52 {ui::kCursorEastResize, IDR_AURA_CURSOR_EAST_RESIZE, {12, 11}, {25, 23}}, 53 {ui::kCursorWestResize, IDR_AURA_CURSOR_WEST_RESIZE, {12, 11}, {25, 23}}, 54 {ui::kCursorIBeam, IDR_AURA_CURSOR_IBEAM, {12, 12}, {24, 25}}, 55 {ui::kCursorAlias, IDR_AURA_CURSOR_ALIAS, {8, 6}, {15, 11}}, 56 {ui::kCursorCell, IDR_AURA_CURSOR_CELL, {11, 11}, {24, 23}}, 57 {ui::kCursorContextMenu, IDR_AURA_CURSOR_CONTEXT_MENU, {4, 4}, {8, 9}}, 58 {ui::kCursorCross, IDR_AURA_CURSOR_CROSSHAIR, {12, 12}, {25, 23}}, 59 {ui::kCursorHelp, IDR_AURA_CURSOR_HELP, {4, 4}, {8, 9}}, 60 {ui::kCursorVerticalText, IDR_AURA_CURSOR_XTERM_HORIZ, {12, 11}, {26, 23}}, 61 {ui::kCursorZoomIn, IDR_AURA_CURSOR_ZOOM_IN, {10, 10}, {20, 20}}, 62 {ui::kCursorZoomOut, IDR_AURA_CURSOR_ZOOM_OUT, {10, 10}, {20, 20}}, 63 {ui::kCursorRowResize, IDR_AURA_CURSOR_ROW_RESIZE, {11, 12}, {23, 23}}, 64 {ui::kCursorColumnResize, IDR_AURA_CURSOR_COL_RESIZE, {12, 11}, {25, 23}}, 65 {ui::kCursorEastWestResize, IDR_AURA_CURSOR_EAST_WEST_RESIZE, 66 {12, 11}, {25, 23}}, 67 {ui::kCursorNorthSouthResize, IDR_AURA_CURSOR_NORTH_SOUTH_RESIZE, 68 {11, 12}, {23, 23}}, 69 {ui::kCursorNorthEastSouthWestResize, 70 IDR_AURA_CURSOR_NORTH_EAST_SOUTH_WEST_RESIZE, {12, 11}, {25, 23}}, 71 {ui::kCursorNorthWestSouthEastResize, 72 IDR_AURA_CURSOR_NORTH_WEST_SOUTH_EAST_RESIZE, {11, 11}, {24, 23}}, 73 {ui::kCursorGrab, IDR_AURA_CURSOR_GRAB, {8, 5}, {16, 10}}, 74 {ui::kCursorGrabbing, IDR_AURA_CURSOR_GRABBING, {9, 9}, {18, 18}}, 75}; 76 77const CursorData kLargeCursors[] = { 78 // The 2x hotspots should be double of the 1x, even though the cursors are 79 // shown as same size as 1x (64x64). Since, in 2x dpi screen, the 1x large 80 // cursor assets (64x64) are internally enlarged to the double size (128x128) 81 // by ResourceBundleImageSource. 82 {ui::kCursorNull, IDR_AURA_CURSOR_BIG_PTR, {10, 10}, {20, 20}}, 83 {ui::kCursorPointer, IDR_AURA_CURSOR_BIG_PTR, {10, 10}, {20, 20}}, 84 {ui::kCursorNoDrop, IDR_AURA_CURSOR_BIG_NO_DROP, {10, 10}, {20, 20}}, 85 {ui::kCursorNotAllowed, IDR_AURA_CURSOR_BIG_NO_DROP, {23, 23}, {46, 46}}, 86 {ui::kCursorCopy, IDR_AURA_CURSOR_BIG_COPY, {10, 10}, {20, 20}}, 87 {ui::kCursorHand, IDR_AURA_CURSOR_BIG_HAND, {25, 7}, {50, 14}}, 88 {ui::kCursorMove, IDR_AURA_CURSOR_BIG_MOVE, {32, 31}, {64, 62}}, 89 {ui::kCursorNorthEastResize, IDR_AURA_CURSOR_BIG_NORTH_EAST_RESIZE, 90 {31, 28}, {62, 56}}, 91 {ui::kCursorSouthWestResize, IDR_AURA_CURSOR_BIG_SOUTH_WEST_RESIZE, 92 {31, 28}, {62, 56}}, 93 {ui::kCursorSouthEastResize, IDR_AURA_CURSOR_BIG_SOUTH_EAST_RESIZE, 94 {28, 28}, {56, 56}}, 95 {ui::kCursorNorthWestResize, IDR_AURA_CURSOR_BIG_NORTH_WEST_RESIZE, 96 {28, 28}, {56, 56}}, 97 {ui::kCursorNorthResize, IDR_AURA_CURSOR_BIG_NORTH_RESIZE, 98 {29, 32}, {58, 64}}, 99 {ui::kCursorSouthResize, IDR_AURA_CURSOR_BIG_SOUTH_RESIZE, 100 {29, 32}, {58, 64}}, 101 {ui::kCursorEastResize, IDR_AURA_CURSOR_BIG_EAST_RESIZE, {35, 29}, {70, 58}}, 102 {ui::kCursorWestResize, IDR_AURA_CURSOR_BIG_WEST_RESIZE, {35, 29}, {70, 58}}, 103 {ui::kCursorIBeam, IDR_AURA_CURSOR_BIG_IBEAM, {30, 32}, {30, 64}}, 104 {ui::kCursorAlias, IDR_AURA_CURSOR_BIG_ALIAS, {19, 11}, {38, 22}}, 105 {ui::kCursorCell, IDR_AURA_CURSOR_BIG_CELL, {30, 30}, {60, 60}}, 106 {ui::kCursorContextMenu, IDR_AURA_CURSOR_BIG_CONTEXT_MENU, 107 {11, 11}, {22, 22}}, 108 {ui::kCursorCross, IDR_AURA_CURSOR_BIG_CROSSHAIR, {31, 30}, {62, 60}}, 109 {ui::kCursorHelp, IDR_AURA_CURSOR_BIG_HELP, {10, 11}, {20, 22}}, 110 {ui::kCursorVerticalText, IDR_AURA_CURSOR_BIG_XTERM_HORIZ, 111 {32, 30}, {64, 60}}, 112 {ui::kCursorZoomIn, IDR_AURA_CURSOR_BIG_ZOOM_IN, {25, 26}, {50, 52}}, 113 {ui::kCursorZoomOut, IDR_AURA_CURSOR_BIG_ZOOM_OUT, {26, 26}, {52, 52}}, 114 {ui::kCursorRowResize, IDR_AURA_CURSOR_BIG_ROW_RESIZE, {29, 32}, {58, 64}}, 115 {ui::kCursorColumnResize, IDR_AURA_CURSOR_BIG_COL_RESIZE, {35, 29}, {70, 58}}, 116 {ui::kCursorEastWestResize, IDR_AURA_CURSOR_BIG_EAST_WEST_RESIZE, 117 {35, 29}, {70, 58}}, 118 {ui::kCursorNorthSouthResize, IDR_AURA_CURSOR_BIG_NORTH_SOUTH_RESIZE, 119 {29, 32}, {58, 64}}, 120 {ui::kCursorNorthEastSouthWestResize, 121 IDR_AURA_CURSOR_BIG_NORTH_EAST_SOUTH_WEST_RESIZE, {32, 30}, {64, 60}}, 122 {ui::kCursorNorthWestSouthEastResize, 123 IDR_AURA_CURSOR_BIG_NORTH_WEST_SOUTH_EAST_RESIZE, {32, 31}, {64, 62}}, 124 {ui::kCursorGrab, IDR_AURA_CURSOR_BIG_GRAB, {21, 11}, {42, 22}}, 125 {ui::kCursorGrabbing, IDR_AURA_CURSOR_BIG_GRABBING, {20, 12}, {40, 24}}, 126}; 127 128const CursorData kAnimatedCursors[] = { 129 {ui::kCursorWait, IDR_THROBBER, {7, 7}, {14, 14}}, 130 {ui::kCursorProgress, IDR_THROBBER, {7, 7}, {14, 14}}, 131}; 132 133const CursorSet kCursorSets[] = { 134 { 135 CURSOR_SET_NORMAL, 136 kNormalCursors, arraysize(kNormalCursors), 137 kAnimatedCursors, arraysize(kAnimatedCursors) 138 }, 139 { 140 CURSOR_SET_LARGE, 141 kLargeCursors, arraysize(kLargeCursors), 142 // TODO(yoshiki): Replace animated cursors with big assets. crbug.com/247254 143 kAnimatedCursors, arraysize(kAnimatedCursors) 144 }, 145}; 146 147const CursorSet* GetCursorSetByType(CursorSetType cursor_set_id) { 148 for (size_t i = 0; i < arraysize(kCursorSets); ++i) { 149 if (kCursorSets[i].id == cursor_set_id) 150 return &kCursorSets[i]; 151 } 152 153 return NULL; 154} 155 156bool SearchTable(const CursorData* table, 157 size_t table_length, 158 int id, 159 float scale_factor, 160 int* resource_id, 161 gfx::Point* point) { 162 bool resource_2x_available = 163 ResourceBundle::GetSharedInstance().GetMaxScaleFactor() == 164 SCALE_FACTOR_200P; 165 for (size_t i = 0; i < table_length; ++i) { 166 if (table[i].id == id) { 167 *resource_id = table[i].resource_id; 168 *point = scale_factor == 1.0f || !resource_2x_available ? 169 gfx::Point(table[i].hot_1x.x, table[i].hot_1x.y) : 170 gfx::Point(table[i].hot_2x.x, table[i].hot_2x.y); 171 return true; 172 } 173 } 174 175 return false; 176} 177 178} // namespace 179 180bool GetCursorDataFor(CursorSetType cursor_set_id, 181 int id, 182 float scale_factor, 183 int* resource_id, 184 gfx::Point* point) { 185 const CursorSet* cursor_set = GetCursorSetByType(cursor_set_id); 186 if (cursor_set && 187 SearchTable(cursor_set->cursors, 188 cursor_set->length, 189 id, scale_factor, resource_id, point)) { 190 return true; 191 } 192 193 // Falls back to the default cursor set. 194 cursor_set = GetCursorSetByType(ui::CURSOR_SET_NORMAL); 195 DCHECK(cursor_set); 196 return SearchTable(cursor_set->cursors, 197 cursor_set->length, 198 id, scale_factor, resource_id, point); 199} 200 201bool GetAnimatedCursorDataFor(CursorSetType cursor_set_id, 202 int id, 203 float scale_factor, 204 int* resource_id, 205 gfx::Point* point) { 206 const CursorSet* cursor_set = GetCursorSetByType(cursor_set_id); 207 if (cursor_set && 208 SearchTable(cursor_set->animated_cursors, 209 cursor_set->animated_length, 210 id, scale_factor, resource_id, point)) { 211 return true; 212 } 213 214 // Falls back to the default cursor set. 215 cursor_set = GetCursorSetByType(ui::CURSOR_SET_NORMAL); 216 DCHECK(cursor_set); 217 return SearchTable(cursor_set->animated_cursors, 218 cursor_set->animated_length, 219 id, scale_factor, resource_id, point); 220} 221 222} // namespace ui 223