Upstream version 5.34.98.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / tabs / dragged_tab_view.cc
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 "chrome/browser/ui/views/tabs/dragged_tab_view.h"
6
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"
12
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
19
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);
25
26 ////////////////////////////////////////////////////////////////////////////////
27 // DraggedTabView, public:
28
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();
41
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);
53
54   BOOL drag;
55   if ((::SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, &drag, 0) != 0) &&
56       (drag == FALSE)) {
57     show_contents_on_drag_ = false;
58   }
59 #endif
60   container_->SetOpacity(kTransparentAlpha);
61   container_->SetBounds(gfx::Rect(params.bounds.size()));
62 }
63
64 DraggedTabView::~DraggedTabView() {
65   parent()->RemoveChildView(this);
66   container_->CloseNow();
67   STLDeleteElements(&renderers_);
68 }
69
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());
80   }
81   int y = screen_point.y() - ScaleValue(mouse_tab_offset_.y());
82
83   gfx::Rect bounds = container_->GetWindowBoundsInScreen();
84   container_->SetBounds(gfx::Rect(x, y, bounds.width(), bounds.height()));
85   if (!container_->IsVisible())
86     container_->Show();
87 }
88
89 void DraggedTabView::Update() {
90   SchedulePaint();
91 }
92
93 ///////////////////////////////////////////////////////////////////////////////
94 // DraggedTabView, views::View overrides:
95
96 void DraggedTabView::OnPaint(gfx::Canvas* canvas) {
97   if (show_contents_on_drag_)
98     PaintDetachedView(canvas);
99   else
100     PaintFocusRect(canvas);
101 }
102
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);
111   }
112 }
113
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);
122 }
123
124 ////////////////////////////////////////////////////////////////////////////////
125 // DraggedTabView, private:
126
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);
134
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);
147
148   SkBitmap mipmap = scale_canvas.ExtractImageRep().sk_bitmap();
149   mipmap.buildMipMap(true);
150
151   skia::RefPtr<SkShader> bitmap_shader = skia::AdoptRef(
152       SkShader::CreateBitmapShader(mipmap, SkShader::kClamp_TileMode,
153                                    SkShader::kClamp_TileMode));
154
155   SkMatrix shader_scale;
156   shader_scale.setScale(kScalingFactor, kScalingFactor);
157   bitmap_shader->setLocalMatrix(shader_scale);
158
159   SkPaint paint;
160   paint.setShader(bitmap_shader.get());
161   paint.setAntiAlias(true);
162
163   canvas->DrawRect(gfx::Rect(ps), paint);
164 }
165
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)));
172 }
173
174 gfx::Size DraggedTabView::PreferredContainerSize() {
175   gfx::Size ps = GetPreferredSize();
176   return gfx::Size(ScaleValue(ps.width()), ScaleValue(ps.height()));
177 }
178
179 int DraggedTabView::ScaleValue(int value) {
180   return static_cast<int>(value * kScalingFactor);
181 }