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

Side by Side Diff: ash/utility/screenshot_controller.cc

Issue 1997193002: Update selection region style (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 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
« no previous file with comments | « no previous file | ash/utility/screenshot_controller_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ash/utility/screenshot_controller.h" 5 #include "ash/utility/screenshot_controller.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 8
9 #include "ash/display/mouse_cursor_event_filter.h" 9 #include "ash/display/mouse_cursor_event_filter.h"
10 #include "ash/screenshot_delegate.h" 10 #include "ash/screenshot_delegate.h"
11 #include "ash/shell.h" 11 #include "ash/shell.h"
12 #include "ash/shell_window_ids.h" 12 #include "ash/shell_window_ids.h"
13 #include "ash/wm/window_util.h" 13 #include "ash/wm/window_util.h"
14 #include "base/stl_util.h" 14 #include "base/stl_util.h"
15 #include "ui/aura/client/capture_client.h" 15 #include "ui/aura/client/capture_client.h"
16 #include "ui/aura/client/screen_position_client.h" 16 #include "ui/aura/client/screen_position_client.h"
17 #include "ui/aura/window_targeter.h" 17 #include "ui/aura/window_targeter.h"
18 #include "ui/compositor/paint_recorder.h" 18 #include "ui/compositor/paint_recorder.h"
19 #include "ui/display/screen.h" 19 #include "ui/display/screen.h"
20 #include "ui/events/event.h" 20 #include "ui/events/event.h"
21 #include "ui/events/event_handler.h" 21 #include "ui/events/event_handler.h"
22 #include "ui/gfx/canvas.h" 22 #include "ui/gfx/canvas.h"
23 #include "ui/views/widget/widget.h" 23 #include "ui/views/widget/widget.h"
24 #include "ui/wm/core/cursor_manager.h" 24 #include "ui/wm/core/cursor_manager.h"
25 25
26 namespace ash { 26 namespace ash {
27 27
28 namespace { 28 namespace {
29 29
30 // The size to increase the invalidated area in the layer to repaint. The area 30 const int kCursorSize = 12;
31 // should be slightly bigger than the actual region because the region indicator
32 // rectangles are drawn outside of the selected region.
33 const int kInvalidateRegionAdditionalSize = 3;
34 31
35 // This will prevent the user from taking a screenshot across multiple 32 // This will prevent the user from taking a screenshot across multiple
36 // monitors. it will stop the mouse at the any edge of the screen. must 33 // monitors. it will stop the mouse at the any edge of the screen. must
37 // swtich back on when the screenshot is complete. 34 // swtich back on when the screenshot is complete.
38 void EnableMouseWarp(bool enable) { 35 void EnableMouseWarp(bool enable) {
39 Shell::GetInstance()->mouse_cursor_filter()->set_mouse_warp_enabled(enable); 36 Shell::GetInstance()->mouse_cursor_filter()->set_mouse_warp_enabled(enable);
40 } 37 }
41 38
42 class ScreenshotWindowTargeter : public aura::WindowTargeter { 39 class ScreenshotWindowTargeter : public aura::WindowTargeter {
43 public: 40 public:
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 layer()->set_delegate(this); 95 layer()->set_delegate(this);
99 } 96 }
100 ~ScreenshotLayer() override {} 97 ~ScreenshotLayer() override {}
101 98
102 const gfx::Rect& region() const { return region_; } 99 const gfx::Rect& region() const { return region_; }
103 100
104 void SetRegion(const gfx::Rect& region) { 101 void SetRegion(const gfx::Rect& region) {
105 // Invalidates the region which covers the current and new region. 102 // Invalidates the region which covers the current and new region.
106 gfx::Rect union_rect(region_); 103 gfx::Rect union_rect(region_);
107 union_rect.Union(region); 104 union_rect.Union(region);
108 union_rect.Inset(-kInvalidateRegionAdditionalSize,
109 -kInvalidateRegionAdditionalSize);
110 union_rect.Intersects(layer()->bounds()); 105 union_rect.Intersects(layer()->bounds());
106 union_rect.Inset(-kCursorSize, -kCursorSize, -kCursorSize, -kCursorSize);
111 region_ = region; 107 region_ = region;
112 layer()->SchedulePaint(union_rect); 108 layer()->SchedulePaint(union_rect);
113 } 109 }
114 110
111 void set_cursor_location_in_root(const gfx::Point& point) {
112 cursor_location_in_root_ = point;
113 }
114
115 private: 115 private:
116 // ui::LayerDelegate: 116 // ui::LayerDelegate:
117 void OnPaintLayer(const ui::PaintContext& context) override { 117 void OnPaintLayer(const ui::PaintContext& context) override {
118 const SkColor kSelectedAreaOverlayColor = 0x40000000; 118 const SkColor kSelectedAreaOverlayColor = 0x60000000;
119 if (region_.IsEmpty()) 119 // Screenshot area representation: transparent hole with half opaque gray
120 return; 120 // overlay.
121 // Screenshot area representation: black rectangle with white
122 // rectangle inside. To avoid capturing these rectangles when mouse
123 // release, they should be outside of the actual capturing area.
124 gfx::Rect rect(region_); 121 gfx::Rect rect(region_);
125 ui::PaintRecorder recorder(context, layer()->size()); 122 ui::PaintRecorder recorder(context, layer()->size());
126 123
127 recorder.canvas()->FillRect(region_, kSelectedAreaOverlayColor); 124 recorder.canvas()->FillRect(gfx::Rect(layer()->size()),
125 kSelectedAreaOverlayColor);
128 126
129 rect.Inset(-1, -1); 127 DrawPseudoCursor(recorder.canvas());
130 recorder.canvas()->DrawRect(rect, SK_ColorWHITE); 128
131 rect.Inset(-1, -1); 129 if (!region_.IsEmpty())
132 recorder.canvas()->DrawRect(rect, SK_ColorBLACK); 130 recorder.canvas()->FillRect(region_, SK_ColorBLACK,
131 SkXfermode::kClear_Mode);
133 } 132 }
134 133
135 void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {} 134 void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {}
136 135
137 void OnDeviceScaleFactorChanged(float device_scale_factor) override {} 136 void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
138 137
139 base::Closure PrepareForLayerBoundsChange() override { 138 base::Closure PrepareForLayerBoundsChange() override {
140 return base::Closure(); 139 return base::Closure();
141 } 140 }
142 141
142 // Mouse cursor may move sub DIP, so paint pseudo cursor instead of
143 // using platform cursor so that it's aliend with the region.
144 void DrawPseudoCursor(gfx::Canvas* canvas) {
145 // Don't draw if window selection mode.
146 if (cursor_location_in_root_.IsOrigin())
147 return;
148
149 gfx::Point pseudo_cursor_point = cursor_location_in_root_;
150
151 // The cursor is above/before region.
152 if (pseudo_cursor_point.x() == region_.x())
153 pseudo_cursor_point.Offset(-1, 0);
154
155 if (pseudo_cursor_point.y() == region_.y())
156 pseudo_cursor_point.Offset(0, -1);
157
158 SkPaint paint;
159 paint.setAntiAlias(false);
160 paint.setStrokeWidth(1);
161 paint.setColor(SK_ColorWHITE);
162 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
163 gfx::Vector2d width(kCursorSize / 2, 0);
164 gfx::Vector2d height(0, kCursorSize / 2);
165 gfx::Vector2d white_x_offset(1, -1);
166 gfx::Vector2d white_y_offset(1, -1);
167 // Horizontal
168 canvas->DrawLine(pseudo_cursor_point - width + white_x_offset,
169 pseudo_cursor_point + width + white_x_offset, paint);
170 paint.setStrokeWidth(1);
171 // Vertical
172 canvas->DrawLine(pseudo_cursor_point - height + white_y_offset,
173 pseudo_cursor_point + height + white_y_offset, paint);
174
175 paint.setColor(SK_ColorBLACK);
176 // Horizontal
177 canvas->DrawLine(pseudo_cursor_point - width, pseudo_cursor_point + width,
178 paint);
179 // Vertical
180 canvas->DrawLine(pseudo_cursor_point - height, pseudo_cursor_point + height,
181 paint);
182 }
183
143 gfx::Rect region_; 184 gfx::Rect region_;
144 185
186 gfx::Point cursor_location_in_root_;
187
145 DISALLOW_COPY_AND_ASSIGN(ScreenshotLayer); 188 DISALLOW_COPY_AND_ASSIGN(ScreenshotLayer);
146 }; 189 };
147 190
148 class ScreenshotController::ScopedCursorSetter { 191 class ScreenshotController::ScopedCursorSetter {
149 public: 192 public:
150 ScopedCursorSetter(::wm::CursorManager* cursor_manager, 193 ScopedCursorSetter(::wm::CursorManager* cursor_manager,
151 gfx::NativeCursor cursor) 194 gfx::NativeCursor cursor)
152 : cursor_manager_(nullptr) { 195 : cursor_manager_(nullptr) {
153 if (cursor_manager->IsCursorLocked()) 196 if (cursor_manager->IsCursorLocked())
154 return; 197 return;
155 gfx::NativeCursor original_cursor = cursor_manager->GetCursor(); 198 gfx::NativeCursor original_cursor = cursor_manager->GetCursor();
156 cursor_manager_ = cursor_manager; 199 cursor_manager_ = cursor_manager;
157 cursor_manager_->SetCursor(cursor); 200 if (cursor == ui::kCursorNone) {
158 if (!cursor_manager_->IsCursorVisible()) 201 cursor_manager_->HideCursor();
202 } else {
203 cursor_manager_->SetCursor(cursor);
159 cursor_manager_->ShowCursor(); 204 cursor_manager_->ShowCursor();
205 }
160 cursor_manager_->LockCursor(); 206 cursor_manager_->LockCursor();
161 // SetCursor does not make any effects at this point but it sets back to 207 // Set/ShowCursor does not make any effects at this point but it sets
162 // the original cursor when unlocked. 208 // back to the original cursor when unlocked.
163 cursor_manager_->SetCursor(original_cursor); 209 cursor_manager_->SetCursor(original_cursor);
210 cursor_manager_->ShowCursor();
164 } 211 }
165 212
166 ~ScopedCursorSetter() { 213 ~ScopedCursorSetter() {
167 if (cursor_manager_) 214 if (cursor_manager_)
168 cursor_manager_->UnlockCursor(); 215 cursor_manager_->UnlockCursor();
169 } 216 }
170 217
171 private: 218 private:
172 ::wm::CursorManager* cursor_manager_; 219 ::wm::CursorManager* cursor_manager_;
173 220
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 // It's already started. This can happen when the second finger touches 288 // It's already started. This can happen when the second finger touches
242 // the screen, or combination of the touch and mouse. We should grab the 289 // the screen, or combination of the touch and mouse. We should grab the
243 // partial screenshot instead of restarting. 290 // partial screenshot instead of restarting.
244 if (current_root == root_window_) { 291 if (current_root == root_window_) {
245 Update(event); 292 Update(event);
246 CompletePartialScreenshot(); 293 CompletePartialScreenshot();
247 } 294 }
248 } else { 295 } else {
249 root_window_ = current_root; 296 root_window_ = current_root;
250 start_position_ = event.root_location(); 297 start_position_ = event.root_location();
298 // ScopedCursorSetter must be reset first to make sure that its dtor is
299 // called before ctor is called.
300 cursor_setter_.reset();
301 cursor_setter_.reset(new ScopedCursorSetter(
302 Shell::GetInstance()->cursor_manager(), ui::kCursorNone));
303 Update(event);
251 } 304 }
252 } 305 }
253 306
254 void ScreenshotController::CompleteWindowScreenshot() { 307 void ScreenshotController::CompleteWindowScreenshot() {
255 if (selected_) 308 if (selected_)
256 screenshot_delegate_->HandleTakeWindowScreenshot(selected_); 309 screenshot_delegate_->HandleTakeWindowScreenshot(selected_);
257 Cancel(); 310 Cancel();
258 } 311 }
259 312
260 void ScreenshotController::CompletePartialScreenshot() { 313 void ScreenshotController::CompletePartialScreenshot() {
(...skipping 26 matching lines...) Expand all
287 STLDeleteValues(&layers_); 340 STLDeleteValues(&layers_);
288 cursor_setter_.reset(); 341 cursor_setter_.reset();
289 EnableMouseWarp(true); 342 EnableMouseWarp(true);
290 } 343 }
291 344
292 void ScreenshotController::Update(const ui::LocatedEvent& event) { 345 void ScreenshotController::Update(const ui::LocatedEvent& event) {
293 // Update may happen without MaybeStart() if the partial screenshot session 346 // Update may happen without MaybeStart() if the partial screenshot session
294 // starts when dragging. 347 // starts when dragging.
295 if (!root_window_) 348 if (!root_window_)
296 MaybeStart(event); 349 MaybeStart(event);
350 DCHECK(layers_.find(root_window_) != layers_.end());
297 351
298 DCHECK(layers_.find(root_window_) != layers_.end()); 352 ScreenshotLayer* layer = layers_.at(root_window_);
299 layers_.at(root_window_) 353 layer->set_cursor_location_in_root(event.root_location());
300 ->SetRegion( 354 layer->SetRegion(
301 gfx::Rect(std::min(start_position_.x(), event.root_location().x()), 355 gfx::Rect(std::min(start_position_.x(), event.root_location().x()),
302 std::min(start_position_.y(), event.root_location().y()), 356 std::min(start_position_.y(), event.root_location().y()),
303 ::abs(start_position_.x() - event.root_location().x()), 357 ::abs(start_position_.x() - event.root_location().x()),
304 ::abs(start_position_.y() - event.root_location().y()))); 358 ::abs(start_position_.y() - event.root_location().y())));
305 } 359 }
306 360
307 void ScreenshotController::UpdateSelectedWindow(ui::LocatedEvent* event) { 361 void ScreenshotController::UpdateSelectedWindow(ui::LocatedEvent* event) {
308 aura::Window* selected = ScreenshotWindowTargeter().FindWindowForEvent(event); 362 aura::Window* selected = ScreenshotWindowTargeter().FindWindowForEvent(event);
309 363
310 // Find a window that is backed with a widget. 364 // Find a window that is backed with a widget.
311 while (selected && (selected->type() == ui::wm::WINDOW_TYPE_CONTROL || 365 while (selected && (selected->type() == ui::wm::WINDOW_TYPE_CONTROL ||
312 !selected->delegate())) { 366 !selected->delegate())) {
313 selected = selected->parent(); 367 selected = selected->parent();
314 } 368 }
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 504
451 void ScreenshotController::OnDisplayMetricsChanged( 505 void ScreenshotController::OnDisplayMetricsChanged(
452 const display::Display& display, 506 const display::Display& display,
453 uint32_t changed_metrics) {} 507 uint32_t changed_metrics) {}
454 508
455 void ScreenshotController::OnWindowDestroying(aura::Window* window) { 509 void ScreenshotController::OnWindowDestroying(aura::Window* window) {
456 SetSelectedWindow(nullptr); 510 SetSelectedWindow(nullptr);
457 } 511 }
458 512
459 } // namespace ash 513 } // namespace ash
OLDNEW
« no previous file with comments | « no previous file | ash/utility/screenshot_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698