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

Side by Side Diff: ash/common/drag_drop/drag_image_view.cc

Issue 2734653002: chromeos: Move files in //ash/common to //ash (Closed)
Patch Set: fix a11y tests, fix docs Created 3 years, 9 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
OLDNEW
(Empty)
1 // Copyright (c) 2012 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/common/drag_drop/drag_image_view.h"
6
7 #include <memory>
8
9 #include "ash/common/wm_window.h"
10 #include "ash/public/cpp/shell_window_ids.h"
11 #include "ash/root_window_controller.h"
12 #include "skia/ext/image_operations.h"
13 #include "ui/base/resource/resource_bundle.h"
14 #include "ui/display/display.h"
15 #include "ui/gfx/canvas.h"
16 #include "ui/resources/grit/ui_resources.h"
17 #include "ui/views/widget/widget.h"
18
19 namespace ash {
20 namespace {
21 using views::Widget;
22
23 std::unique_ptr<Widget> CreateDragWidget(WmWindow* root_window) {
24 std::unique_ptr<Widget> drag_widget(new Widget);
25 Widget::InitParams params;
26 params.type = Widget::InitParams::TYPE_TOOLTIP;
27 params.name = "DragWidget";
28 params.keep_on_top = true;
29 params.accept_events = false;
30 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
31 params.shadow_type = Widget::InitParams::SHADOW_TYPE_NONE;
32 params.opacity = Widget::InitParams::TRANSLUCENT_WINDOW;
33 root_window->GetRootWindowController()->ConfigureWidgetInitParamsForContainer(
34 drag_widget.get(), kShellWindowId_DragImageAndTooltipContainer, &params);
35 drag_widget->Init(params);
36 drag_widget->SetOpacity(1.f);
37 return drag_widget;
38 }
39
40 } // namespace
41
42 DragImageView::DragImageView(WmWindow* root_window,
43 ui::DragDropTypes::DragEventSource event_source)
44 : drag_event_source_(event_source),
45 touch_drag_operation_(ui::DragDropTypes::DRAG_NONE) {
46 DCHECK(root_window);
47 widget_ = CreateDragWidget(root_window);
48 widget_->SetContentsView(this);
49 widget_->SetAlwaysOnTop(true);
50
51 // We are owned by the DragDropController.
52 set_owned_by_client();
53 }
54
55 DragImageView::~DragImageView() {
56 widget_->Hide();
57 }
58
59 void DragImageView::SetBoundsInScreen(const gfx::Rect& bounds) {
60 drag_image_size_ = bounds.size();
61 widget_->SetBounds(bounds);
62 }
63
64 void DragImageView::SetScreenPosition(const gfx::Point& position) {
65 widget_->SetBounds(
66 gfx::Rect(position, widget_->GetWindowBoundsInScreen().size()));
67 }
68
69 gfx::Rect DragImageView::GetBoundsInScreen() const {
70 return widget_->GetWindowBoundsInScreen();
71 }
72
73 void DragImageView::SetWidgetVisible(bool visible) {
74 if (visible != widget_->IsVisible()) {
75 if (visible)
76 widget_->Show();
77 else
78 widget_->Hide();
79 }
80 }
81
82 void DragImageView::SetTouchDragOperationHintOff() {
83 // Simply set the drag type to non-touch so that no hint is drawn.
84 drag_event_source_ = ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE;
85
86 // This disables the drag hint image. This should reduce the widget size if
87 // the drag image is smaller than the drag hint image, so we set new bounds.
88 gfx::Rect new_bounds = GetBoundsInScreen();
89 new_bounds.set_size(drag_image_size_);
90 SetBoundsInScreen(new_bounds);
91 SchedulePaint();
92 }
93
94 void DragImageView::SetTouchDragOperation(int operation) {
95 if (touch_drag_operation_ == operation)
96 return;
97 touch_drag_operation_ = operation;
98 SchedulePaint();
99 }
100
101 void DragImageView::SetTouchDragOperationHintPosition(
102 const gfx::Point& position) {
103 if (touch_drag_operation_indicator_position_ == position)
104 return;
105 touch_drag_operation_indicator_position_ = position;
106 SchedulePaint();
107 }
108
109 void DragImageView::SetOpacity(float visibility) {
110 DCHECK_GE(visibility, 0.0f);
111 DCHECK_LE(visibility, 1.0f);
112 widget_->SetOpacity(visibility);
113 }
114
115 void DragImageView::OnPaint(gfx::Canvas* canvas) {
116 if (GetImage().isNull())
117 return;
118
119 // |drag_image_size_| is in DIP.
120 // ImageSkia::size() also returns the size in DIP.
121 if (GetImage().size() == drag_image_size_) {
122 canvas->DrawImageInt(GetImage(), 0, 0);
123 } else {
124 WmWindow* window = WmWindow::Get(widget_->GetNativeWindow());
125 const float device_scale =
126 window->GetDisplayNearestWindow().device_scale_factor();
127 // The drag image already has device scale factor applied. But
128 // |drag_image_size_| is in DIP units.
129 gfx::Size drag_image_size_pixels =
130 gfx::ScaleToRoundedSize(drag_image_size_, device_scale);
131 gfx::ImageSkiaRep image_rep = GetImage().GetRepresentation(device_scale);
132 if (image_rep.is_null())
133 return;
134 SkBitmap scaled = skia::ImageOperations::Resize(
135 image_rep.sk_bitmap(), skia::ImageOperations::RESIZE_LANCZOS3,
136 drag_image_size_pixels.width(), drag_image_size_pixels.height());
137 gfx::ImageSkia image_skia(gfx::ImageSkiaRep(scaled, device_scale));
138 canvas->DrawImageInt(image_skia, 0, 0);
139 }
140
141 gfx::Image* drag_hint = DragHint();
142 if (!ShouldDrawDragHint() || drag_hint->IsEmpty())
143 return;
144
145 // Make sure drag hint image is positioned within the widget.
146 gfx::Size drag_hint_size = drag_hint->Size();
147 gfx::Point drag_hint_position = touch_drag_operation_indicator_position_;
148 drag_hint_position.Offset(-drag_hint_size.width() / 2, 0);
149 gfx::Rect drag_hint_bounds(drag_hint_position, drag_hint_size);
150
151 gfx::Size widget_size = widget_->GetWindowBoundsInScreen().size();
152 drag_hint_bounds.AdjustToFit(gfx::Rect(widget_size));
153
154 // Draw image.
155 canvas->DrawImageInt(*(drag_hint->ToImageSkia()), drag_hint_bounds.x(),
156 drag_hint_bounds.y());
157 }
158
159 gfx::Image* DragImageView::DragHint() const {
160 // Select appropriate drag hint.
161 gfx::Image* drag_hint =
162 &ui::ResourceBundle::GetSharedInstance().GetImageNamed(
163 IDR_TOUCH_DRAG_TIP_NODROP);
164 if (touch_drag_operation_ & ui::DragDropTypes::DRAG_COPY) {
165 drag_hint = &ui::ResourceBundle::GetSharedInstance().GetImageNamed(
166 IDR_TOUCH_DRAG_TIP_COPY);
167 } else if (touch_drag_operation_ & ui::DragDropTypes::DRAG_MOVE) {
168 drag_hint = &ui::ResourceBundle::GetSharedInstance().GetImageNamed(
169 IDR_TOUCH_DRAG_TIP_MOVE);
170 } else if (touch_drag_operation_ & ui::DragDropTypes::DRAG_LINK) {
171 drag_hint = &ui::ResourceBundle::GetSharedInstance().GetImageNamed(
172 IDR_TOUCH_DRAG_TIP_LINK);
173 }
174 return drag_hint;
175 }
176
177 bool DragImageView::ShouldDrawDragHint() const {
178 return drag_event_source_ == ui::DragDropTypes::DRAG_EVENT_SOURCE_TOUCH;
179 }
180
181 gfx::Size DragImageView::GetMinimumSize() const {
182 gfx::Size minimum_size = drag_image_size_;
183 if (ShouldDrawDragHint())
184 minimum_size.SetToMax(DragHint()->Size());
185 return minimum_size;
186 }
187
188 void DragImageView::Layout() {
189 View::Layout();
190
191 // Only consider resizing the widget for the drag hint image if we are in a
192 // touch initiated drag.
193 gfx::Image* drag_hint = DragHint();
194 if (!ShouldDrawDragHint() || drag_hint->IsEmpty())
195 return;
196
197 gfx::Size drag_hint_size = drag_hint->Size();
198
199 // Enlarge widget if required to fit the drag hint image.
200 gfx::Size widget_size = widget_->GetWindowBoundsInScreen().size();
201 if (drag_hint_size.width() > widget_size.width() ||
202 drag_hint_size.height() > widget_size.height()) {
203 widget_size.SetToMax(drag_hint_size);
204 widget_->SetSize(widget_size);
205 }
206 }
207
208 } // namespace ash
OLDNEW
« no previous file with comments | « ash/common/drag_drop/drag_image_view.h ('k') | ash/common/drag_drop/drag_image_view_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698