Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(313)

Side by Side Diff: ash/display/cursor_window_controller.cc

Issue 145313003: Implement cursor compositing mode on Ash (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix linux_aura build. Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ash/display/cursor_window_controller.h ('k') | ash/display/display_controller.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 "ash/display/cursor_window_controller.h"
6
7 #include "ash/shell.h"
8 #include "ui/aura/env.h"
9 #include "ui/aura/root_window.h"
10 #include "ui/aura/window_delegate.h"
11 #include "ui/base/cursor/cursors_aura.h"
12 #include "ui/base/hit_test.h"
13 #include "ui/base/resource/resource_bundle.h"
14 #include "ui/compositor/dip_util.h"
15 #include "ui/gfx/canvas.h"
16 #include "ui/gfx/display.h"
17 #include "ui/gfx/image/image_skia.h"
18 #include "ui/gfx/image/image_skia_operations.h"
19
20 namespace ash {
21 namespace internal {
22
23 class CursorWindowDelegate : public aura::WindowDelegate {
24 public:
25 CursorWindowDelegate(bool for_mirroring) : for_mirroring_(for_mirroring) {}
26 virtual ~CursorWindowDelegate() {}
27
28 // aura::WindowDelegate overrides:
29 virtual gfx::Size GetMinimumSize() const OVERRIDE {
30 return size_;
31 }
32 virtual gfx::Size GetMaximumSize() const OVERRIDE {
33 return size_;
34 }
35 virtual void OnBoundsChanged(const gfx::Rect& old_bounds,
36 const gfx::Rect& new_bounds) OVERRIDE {
37 }
38 virtual gfx::NativeCursor GetCursor(const gfx::Point& point) OVERRIDE {
39 return gfx::kNullCursor;
40 }
41 virtual int GetNonClientComponent(
42 const gfx::Point& point) const OVERRIDE {
43 return HTNOWHERE;
44 }
45 virtual bool ShouldDescendIntoChildForEventHandling(
46 aura::Window* child,
47 const gfx::Point& location) OVERRIDE {
48 return false;
49 }
50 virtual bool CanFocus() OVERRIDE {
51 return false;
52 }
53 virtual void OnCaptureLost() OVERRIDE {
54 }
55 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
56 canvas->DrawImageInt(cursor_image_, 0, 0);
57 }
58 virtual void OnDeviceScaleFactorChanged(
59 float device_scale_factor) OVERRIDE {
60 }
61 virtual void OnWindowDestroying() OVERRIDE {}
62 virtual void OnWindowDestroyed() OVERRIDE {}
63 virtual void OnWindowTargetVisibilityChanged(bool visible) OVERRIDE {
64 }
65 virtual bool HasHitTestMask() const OVERRIDE {
66 return false;
67 }
68 virtual void GetHitTestMask(gfx::Path* mask) const OVERRIDE {}
69 virtual void DidRecreateLayer(ui::Layer* old_layer,
70 ui::Layer* new_layer) OVERRIDE {}
71
72 // Set the cursor image for the |display|'s scale factor.
73 void SetCursorImage(const gfx::ImageSkia& image,
74 const gfx::Display& display) {
75 float scale_factor = display.device_scale_factor();
76 const gfx::ImageSkiaRep& image_rep = image.GetRepresentation(scale_factor);
77 if (for_mirroring_) {
78 // Note that mirror window's scale factor is always 1.0f, therefore we
79 // need to take 2x's image and paint as if it's 1x image.
80 size_ = image_rep.pixel_size();
81 cursor_image_ = gfx::ImageSkia::CreateFrom1xBitmap(image_rep.sk_bitmap());
82 } else {
83 size_ = image.size();
84 cursor_image_ = gfx::ImageSkia(
85 gfx::ImageSkiaRep(image_rep.sk_bitmap(), scale_factor));
86 }
87 }
88
89 const gfx::Size size() const { return size_; }
90
91 private:
92 bool for_mirroring_;
93 gfx::ImageSkia cursor_image_;
94 gfx::Size size_;
95
96 DISALLOW_COPY_AND_ASSIGN(CursorWindowDelegate);
97 };
98
99 CursorWindowController::CursorWindowController(bool for_mirroring)
100 : for_mirroring_(for_mirroring),
101 current_cursor_type_(ui::kCursorNone),
102 current_cursor_set_(ui::CURSOR_SET_NORMAL),
103 requested_cursor_set_(ui::CURSOR_SET_NORMAL),
104 current_cursor_rotation_(gfx::Display::ROTATE_0),
105 cursor_window_(NULL),
106 cursor_window_delegate_(new CursorWindowDelegate(for_mirroring)) {
107 }
108
109 CursorWindowController::~CursorWindowController() {
110 CloseCursorWindow();
111 }
112
113 void CursorWindowController::InitCursorWindow(aura::Window* container) {
114 DCHECK(container);
115
116 cursor_window_ = new aura::Window(cursor_window_delegate_.get());
117 cursor_window_->SetTransparent(true);
118 cursor_window_->Init(aura::WINDOW_LAYER_TEXTURED);
119 cursor_window_->set_ignore_events(true);
120 container->AddChild(cursor_window_);
121 cursor_window_->Show();
122 }
123
124 void CursorWindowController::CloseCursorWindow() {
125 cursor_window_ = NULL;
126 }
127
128 void CursorWindowController::UpdateCursorLocation() {
129 if (!cursor_window_)
130 return;
131
132 gfx::Point point = aura::Env::GetInstance()->last_mouse_location();
133 if (for_mirroring_) {
134 // TODO(oshima): Rotate cursor image (including hotpoint).
oshima 2014/02/03 20:35:53 can you remove this comment?
hshi1 2014/02/03 21:43:33 Done.
135 Shell::GetPrimaryRootWindow()->GetDispatcher()->host()->ConvertPointToHost(
136 &point);
137 }
138 point.Offset(-hot_point_.x(), -hot_point_.y());
139 gfx::Rect bounds = cursor_window_->bounds();
140 bounds.set_origin(point);
141 cursor_window_->SetBounds(bounds);
142 }
143
144 void CursorWindowController::SetCursor(gfx::NativeCursor cursor) {
145 const gfx::Display& display = Shell::GetScreen()->GetPrimaryDisplay();
146 if (current_cursor_type_ == cursor.native_type() &&
147 current_cursor_set_ == requested_cursor_set_ &&
148 current_cursor_rotation_ == display.rotation())
149 return;
150 current_cursor_type_ = cursor.native_type();
151 current_cursor_set_ = requested_cursor_set_;
152 current_cursor_rotation_ = display.rotation();
153 int resource_id;
154 bool success = ui::GetCursorDataFor(
155 current_cursor_set_, // Not support custom cursor set.
156 current_cursor_type_,
157 display.device_scale_factor(),
158 &resource_id,
159 &hot_point_);
160 if (!success)
161 return;
162 const gfx::ImageSkia* image =
163 ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id);
164 gfx::ImageSkia rotated = *image;
165 if (for_mirroring_) {
166 switch (current_cursor_rotation_) {
167 case gfx::Display::ROTATE_0:
168 break;
169 case gfx::Display::ROTATE_90:
170 rotated = gfx::ImageSkiaOperations::CreateRotatedImage(
171 *image, SkBitmapOperations::ROTATION_90_CW);
172 hot_point_.SetPoint(
173 rotated.width() - hot_point_.y(),
174 hot_point_.x());
175 break;
176 case gfx::Display::ROTATE_180:
177 rotated = gfx::ImageSkiaOperations::CreateRotatedImage(
178 *image, SkBitmapOperations::ROTATION_180_CW);
179 hot_point_.SetPoint(
180 rotated.height() - hot_point_.x(),
181 rotated.width() - hot_point_.y());
182 break;
183 case gfx::Display::ROTATE_270:
184 rotated = gfx::ImageSkiaOperations::CreateRotatedImage(
185 *image, SkBitmapOperations::ROTATION_270_CW);
186 hot_point_.SetPoint(
187 hot_point_.y(),
188 rotated.height() - hot_point_.x());
189 break;
190 }
191 } else {
192 hot_point_ = ui::ConvertPointToDIP(Shell::GetPrimaryRootWindow()->layer(),
193 hot_point_);
194 }
195 if (cursor_window_) {
196 cursor_window_->SetBounds(gfx::Rect(cursor_window_delegate_->size()));
197 cursor_window_->SchedulePaintInRect(
198 gfx::Rect(cursor_window_->bounds().size()));
199 cursor_window_delegate_->SetCursorImage(rotated, display);
200 }
201 }
202
203 void CursorWindowController::SetCursorSet(ui::CursorSetType cursor_set) {
204 requested_cursor_set_ = cursor_set;
205 SetCursor(gfx::NativeCursor(current_cursor_type_));
206 }
207
208 void CursorWindowController::SetCursorVisibility(bool visible) {
209 if (!cursor_window_)
210 return;
211 if (visible)
212 cursor_window_->Show();
213 else
214 cursor_window_->Hide();
215 }
216
217 } // namespace internal
218 } // namespace ash
OLDNEW
« no previous file with comments | « ash/display/cursor_window_controller.h ('k') | ash/display/display_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698