Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / ui / views / tabs / dragged_tab_view.cc
blob4b8d28556eeace0274dd8d56830267b302180983
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.
5 #include "chrome/browser/ui/views/tabs/dragged_tab_view.h"
7 #include "base/stl_util.h"
8 #include "chrome/browser/ui/views/tabs/native_view_photobooth.h"
9 #include "third_party/skia/include/core/SkShader.h"
10 #include "ui/gfx/canvas.h"
11 #include "ui/views/widget/widget.h"
13 #if defined(USE_AURA)
14 #include "ui/views/widget/native_widget_aura.h"
15 #elif defined(OS_WIN)
16 #include "ui/gfx/win/dpi.h"
17 #include "ui/views/widget/native_widget_win.h"
18 #endif
20 static const int kTransparentAlpha = 200;
21 static const int kDragFrameBorderSize = 2;
22 static const int kTwiceDragFrameBorderSize = 2 * kDragFrameBorderSize;
23 static const float kScalingFactor = 0.5;
24 static const SkColor kDraggedTabBorderColor = SkColorSetRGB(103, 129, 162);
26 ////////////////////////////////////////////////////////////////////////////////
27 // DraggedTabView, public:
29 DraggedTabView::DraggedTabView(const std::vector<views::View*>& renderers,
30 const std::vector<gfx::Rect>& renderer_bounds,
31 const gfx::Point& mouse_tab_offset,
32 const gfx::Size& contents_size,
33 NativeViewPhotobooth* photobooth)
34 : renderers_(renderers),
35 renderer_bounds_(renderer_bounds),
36 show_contents_on_drag_(true),
37 mouse_tab_offset_(mouse_tab_offset),
38 photobooth_(photobooth),
39 contents_size_(contents_size) {
40 set_owned_by_client();
42 container_.reset(new views::Widget);
43 views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
44 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
45 params.keep_on_top = true;
46 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
47 params.bounds = gfx::Rect(PreferredContainerSize());
48 container_->Init(params);
49 container_->SetContentsView(this);
50 #if defined(OS_WIN) && !defined(USE_AURA)
51 static_cast<views::NativeWidgetWin*>(container_->native_widget())->
52 SetCanUpdateLayeredWindow(false);
54 BOOL drag;
55 if ((::SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, &drag, 0) != 0) &&
56 (drag == FALSE)) {
57 show_contents_on_drag_ = false;
59 #endif
60 container_->SetOpacity(kTransparentAlpha);
61 container_->SetBounds(gfx::Rect(params.bounds.size()));
64 DraggedTabView::~DraggedTabView() {
65 parent()->RemoveChildView(this);
66 container_->CloseNow();
67 STLDeleteElements(&renderers_);
70 void DraggedTabView::MoveTo(const gfx::Point& screen_point) {
71 int x;
72 if (base::i18n::IsRTL()) {
73 // On RTL locales, a dragged tab (when it is not attached to a tab strip)
74 // is rendered using a right-to-left orientation so we should calculate the
75 // window position differently.
76 gfx::Size ps = GetPreferredSize();
77 x = screen_point.x() + ScaleValue(mouse_tab_offset_.x() - ps.width());
78 } else {
79 x = screen_point.x() - ScaleValue(mouse_tab_offset_.x());
81 int y = screen_point.y() - ScaleValue(mouse_tab_offset_.y());
83 gfx::Rect bounds = container_->GetWindowBoundsInScreen();
84 container_->SetBounds(gfx::Rect(x, y, bounds.width(), bounds.height()));
85 if (!container_->IsVisible())
86 container_->Show();
89 void DraggedTabView::Update() {
90 SchedulePaint();
93 ///////////////////////////////////////////////////////////////////////////////
94 // DraggedTabView, views::View overrides:
96 void DraggedTabView::OnPaint(gfx::Canvas* canvas) {
97 if (show_contents_on_drag_)
98 PaintDetachedView(canvas);
99 else
100 PaintFocusRect(canvas);
103 void DraggedTabView::Layout() {
104 int max_width = GetPreferredSize().width();
105 for (size_t i = 0; i < renderers_.size(); ++i) {
106 gfx::Rect bounds = renderer_bounds_[i];
107 bounds.set_y(0);
108 if (base::i18n::IsRTL())
109 bounds.set_x(max_width - bounds.x() - bounds.width());
110 renderers_[i]->SetBoundsRect(bounds);
114 gfx::Size DraggedTabView::GetPreferredSize() {
115 DCHECK(!renderer_bounds_.empty());
116 int max_renderer_x = renderer_bounds_.back().right();
117 int width = std::max(max_renderer_x, contents_size_.width()) +
118 kTwiceDragFrameBorderSize;
119 int height = renderer_bounds_.back().height() + kDragFrameBorderSize +
120 contents_size_.height();
121 return gfx::Size(width, height);
124 ////////////////////////////////////////////////////////////////////////////////
125 // DraggedTabView, private:
127 void DraggedTabView::PaintDetachedView(gfx::Canvas* canvas) {
128 gfx::Size ps = GetPreferredSize();
129 // TODO(pkotwicz): DIP enable this class.
130 gfx::Canvas scale_canvas(ps, 1.0f, false);
131 SkBitmap& bitmap_device = const_cast<SkBitmap&>(
132 skia::GetTopDevice(*scale_canvas.sk_canvas())->accessBitmap(true));
133 bitmap_device.eraseARGB(0, 0, 0, 0);
135 int tab_height = renderer_bounds_.back().height();
136 scale_canvas.FillRect(gfx::Rect(0, tab_height - kDragFrameBorderSize,
137 ps.width(), ps.height() - tab_height),
138 kDraggedTabBorderColor);
139 gfx::Rect image_rect(kDragFrameBorderSize,
140 tab_height,
141 ps.width() - kTwiceDragFrameBorderSize,
142 contents_size_.height());
143 scale_canvas.FillRect(image_rect, SK_ColorBLACK);
144 photobooth_->PaintScreenshotIntoCanvas(&scale_canvas, image_rect);
145 for (size_t i = 0; i < renderers_.size(); ++i)
146 renderers_[i]->Paint(&scale_canvas);
148 SkBitmap mipmap = scale_canvas.ExtractImageRep().sk_bitmap();
149 mipmap.buildMipMap(true);
151 skia::RefPtr<SkShader> bitmap_shader = skia::AdoptRef(
152 SkShader::CreateBitmapShader(mipmap, SkShader::kClamp_TileMode,
153 SkShader::kClamp_TileMode));
155 SkMatrix shader_scale;
156 shader_scale.setScale(kScalingFactor, kScalingFactor);
157 bitmap_shader->setLocalMatrix(shader_scale);
159 SkPaint paint;
160 paint.setShader(bitmap_shader.get());
161 paint.setAntiAlias(true);
163 canvas->DrawRect(gfx::Rect(ps), paint);
166 void DraggedTabView::PaintFocusRect(gfx::Canvas* canvas) {
167 gfx::Size ps = GetPreferredSize();
168 canvas->DrawFocusRect(
169 gfx::Rect(0, 0,
170 static_cast<int>(ps.width() * kScalingFactor),
171 static_cast<int>(ps.height() * kScalingFactor)));
174 gfx::Size DraggedTabView::PreferredContainerSize() {
175 gfx::Size ps = GetPreferredSize();
176 return gfx::Size(ScaleValue(ps.width()), ScaleValue(ps.height()));
179 int DraggedTabView::ScaleValue(int value) {
180 return static_cast<int>(value * kScalingFactor);