drag_image_view.cc revision 68043e1e95eeb07d5cae7aca370b26518b0867d6
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/drag_drop/drag_image_view.h" 6 7#include "skia/ext/image_operations.h" 8#include "ui/aura/window.h" 9#include "ui/compositor/dip_util.h" 10#include "ui/gfx/canvas.h" 11#include "ui/gfx/size_conversions.h" 12#include "ui/views/corewm/shadow_types.h" 13#include "ui/views/widget/widget.h" 14 15namespace ash { 16namespace internal { 17 18namespace { 19using views::Widget; 20 21Widget* CreateDragWidget(gfx::NativeView context) { 22 Widget* drag_widget = new Widget; 23 Widget::InitParams params; 24 params.type = Widget::InitParams::TYPE_TOOLTIP; 25 params.keep_on_top = true; 26 params.context = context; 27 params.accept_events = false; 28 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 29 params.opacity = Widget::InitParams::TRANSLUCENT_WINDOW; 30 drag_widget->Init(params); 31 drag_widget->SetOpacity(0xFF); 32 drag_widget->GetNativeWindow()->set_owned_by_parent(false); 33 drag_widget->GetNativeWindow()->SetName("DragWidget"); 34 SetShadowType(drag_widget->GetNativeView(), views::corewm::SHADOW_TYPE_NONE); 35 return drag_widget; 36} 37} 38 39DragImageView::DragImageView(gfx::NativeView context) : views::ImageView() { 40 widget_.reset(CreateDragWidget(context)); 41 widget_->SetContentsView(this); 42 widget_->SetAlwaysOnTop(true); 43 44 // We are owned by the DragDropController. 45 set_owned_by_client(); 46} 47 48DragImageView::~DragImageView() { 49 widget_->Hide(); 50} 51 52void DragImageView::SetBoundsInScreen(const gfx::Rect& bounds) { 53 widget_->SetBounds(bounds); 54 widget_size_ = bounds.size(); 55} 56 57void DragImageView::SetScreenPosition(const gfx::Point& position) { 58 widget_->SetBounds(gfx::Rect(position, widget_size_)); 59} 60 61gfx::Rect DragImageView::GetBoundsInScreen() const { 62 return widget_->GetWindowBoundsInScreen(); 63} 64 65void DragImageView::SetWidgetVisible(bool visible) { 66 if (visible != widget_->IsVisible()) { 67 if (visible) 68 widget_->Show(); 69 else 70 widget_->Hide(); 71 } 72} 73 74void DragImageView::SetOpacity(float visibility) { 75 DCHECK_GE(visibility, 0.0f); 76 DCHECK_LE(visibility, 1.0f); 77 widget_->SetOpacity(static_cast<int>(0xff * visibility)); 78} 79 80void DragImageView::OnPaint(gfx::Canvas* canvas) { 81 if (GetImage().isNull()) 82 return; 83 84 // |widget_size_| is in DIP. ImageSkia::size() also returns the size in DIP. 85 if (GetImage().size() == widget_size_) { 86 canvas->DrawImageInt(GetImage(), 0, 0); 87 } else { 88 float device_scale = 1; 89 if (widget_->GetNativeView() && widget_->GetNativeView()->layer()) { 90 device_scale = ui::GetDeviceScaleFactor( 91 widget_->GetNativeView()->layer()); 92 } 93 // The drag image already has device scale factor applied. But 94 // |widget_size_| is in DIP units. 95 gfx::Size scaled_widget_size = gfx::ToRoundedSize( 96 gfx::ScaleSize(widget_size_, device_scale)); 97 gfx::ImageSkiaRep image_rep = GetImage().GetRepresentation(device_scale); 98 if (image_rep.is_null()) 99 return; 100 SkBitmap scaled = skia::ImageOperations::Resize( 101 image_rep.sk_bitmap(), skia::ImageOperations::RESIZE_LANCZOS3, 102 scaled_widget_size.width(), scaled_widget_size.height()); 103 gfx::ImageSkia image_skia(gfx::ImageSkiaRep(scaled, device_scale)); 104 canvas->DrawImageInt(image_skia, 0, 0); 105 } 106} 107 108} // namespace internal 109} // namespace ash 110