Chromium Code Reviews| Index: chrome/browser/ui/views/tab_contents/native_tab_contents_view_aura.cc |
| diff --git a/chrome/browser/ui/views/tab_contents/native_tab_contents_view_aura.cc b/chrome/browser/ui/views/tab_contents/native_tab_contents_view_aura.cc |
| index 5084ddbd5014464c6c8dfb82e1500e9c406ae98f..f9a21ed3dbbce6d3e9987123c595e9cf3f208ec0 100644 |
| --- a/chrome/browser/ui/views/tab_contents/native_tab_contents_view_aura.cc |
| +++ b/chrome/browser/ui/views/tab_contents/native_tab_contents_view_aura.cc |
| @@ -4,14 +4,74 @@ |
| #include "chrome/browser/ui/views/tab_contents/native_tab_contents_view_aura.h" |
| +#include "base/event_types.h" |
| +#include "base/message_loop.h" |
| #include "chrome/browser/ui/views/tab_contents/native_tab_contents_view_delegate.h" |
| +#include "content/browser/renderer_host/render_view_host.h" |
| #include "content/browser/renderer_host/render_widget_host_view_aura.h" |
| #include "content/browser/tab_contents/tab_contents.h" |
| #include "content/browser/tab_contents/tab_contents_view.h" |
| +#include "ui/aura/client/aura_constants.h" |
| +#include "ui/aura/client/drag_drop_client.h" |
| +#include "ui/aura/desktop.h" |
| #include "ui/aura/event.h" |
| #include "ui/aura/window.h" |
| +#include "ui/base/dragdrop/drag_drop_types.h" |
| +#include "ui/base/dragdrop/os_exchange_data.h" |
| +#include "ui/base/dragdrop/os_exchange_data_provider_aura.h" |
| #include "ui/views/widget/widget.h" |
| #include "views/views_delegate.h" |
| +#include "webkit/glue/webdropdata.h" |
| + |
| +namespace { |
| + |
| +// Listens to all mouse drag events during a drag and drop and sends them to |
| +// the renderer. |
| +class WebDragSourceAura : public MessageLoopForUI::Observer { |
| + public: |
| + explicit WebDragSourceAura(NativeTabContentsViewAura* view) |
| + : view_(view) { |
| + MessageLoopForUI::current()->AddObserver(this); |
| + } |
| + |
| + virtual ~WebDragSourceAura() { |
| + MessageLoopForUI::current()->RemoveObserver(this); |
| + } |
| + |
| + // MessageLoop::Observer implementation: |
| + virtual base::EventStatus WillProcessEvent( |
| + const base::NativeEvent& event) OVERRIDE { |
| + return base::EVENT_CONTINUE; |
| + } |
| + virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE { |
| + ui::EventType type = ui::EventTypeFromNative(event); |
| + RenderViewHost* rvh = NULL; |
| + switch (type) { |
| + case ui::ET_MOUSE_DRAGGED: |
| + rvh = view_->GetTabContents()->render_view_host(); |
| + if (rvh) { |
| + gfx::Point screen_loc = ui::EventLocationFromNative(event); |
| + gfx::Point client_loc = screen_loc; |
| + aura::Window* window = static_cast<aura::Window*>( |
|
Ben Goodger (Google)
2011/11/28 17:07:44
Cast unnecessary.
varunjain
2011/11/28 17:32:29
Done.
|
| + rvh->view()->GetNativeView()); |
| + aura::Window::ConvertPointToWindow(aura::Desktop::GetInstance(), |
| + window, &client_loc); |
| + rvh->DragSourceMovedTo(client_loc.x(), client_loc.y(), |
| + screen_loc.x(), screen_loc.y()); |
| + } |
| + break; |
| + default: |
| + break; |
| + } |
| + } |
| + |
| + private: |
| + NativeTabContentsViewAura* view_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(WebDragSourceAura); |
| +}; |
| + |
| +} // namespace |
| //////////////////////////////////////////////////////////////////////////////// |
| // NativeTabContentsViewAura, public: |
| @@ -19,7 +79,8 @@ |
| NativeTabContentsViewAura::NativeTabContentsViewAura( |
| internal::NativeTabContentsViewDelegate* delegate) |
| : views::NativeWidgetAura(delegate->AsNativeWidgetDelegate()), |
| - delegate_(delegate) { |
| + delegate_(delegate), |
| + current_drag_op_(WebKit::WebDragOperationNone) { |
| } |
| NativeTabContentsViewAura::~NativeTabContentsViewAura() { |
| @@ -29,12 +90,6 @@ TabContents* NativeTabContentsViewAura::GetTabContents() const { |
| return delegate_->GetTabContents(); |
| } |
| -void NativeTabContentsViewAura::EndDragging() { |
| - delegate_->OnNativeTabContentsViewDraggingEnded(); |
| - // TODO(beng): |
| - NOTIMPLEMENTED(); |
| -} |
| - |
| //////////////////////////////////////////////////////////////////////////////// |
| // NativeTabContentsViewAura, NativeTabContentsView implementation: |
| @@ -67,6 +122,12 @@ RenderWidgetHostView* NativeTabContentsViewAura::CreateRenderWidgetHostView( |
| view->InitAsChild(); |
| GetNativeView()->AddChild(view->GetNativeView()); |
| view->Show(); |
| + |
| + // We listen to drag drop events in the newly created view's window. |
| + aura::Window* window = static_cast<aura::Window*>(view->GetNativeView()); |
| + DCHECK(window); |
| + window->SetProperty(aura::kDragDropDelegateKey, |
| + static_cast<aura::WindowDragDropDelegate*>(this)); |
| return view; |
| } |
| @@ -84,25 +145,51 @@ void NativeTabContentsViewAura::StartDragging(const WebDropData& drop_data, |
| WebKit::WebDragOperationsMask ops, |
| const SkBitmap& image, |
| const gfx::Point& image_offset) { |
| - // TODO(beng): |
| - NOTIMPLEMENTED(); |
| + aura::DragDropClient* client = static_cast<aura::DragDropClient*>( |
| + aura::Desktop::GetInstance()->GetProperty( |
| + aura::kDesktopDragDropClientKey)); |
| + if (!client) |
| + return; |
| + |
| + ui::OSExchangeDataProviderAura* provider = new ui::OSExchangeDataProviderAura; |
| + PrepareDragData(drop_data, provider); |
| + if (!image.isNull()) |
| + provider->set_drag_image(image); |
| + ui::OSExchangeData data(provider); // takes ownership of |provider|. |
| + |
| + scoped_ptr<WebDragSourceAura> drag_source(new WebDragSourceAura(this)); |
| + |
| + // We need to enable recursive tasks on the message loop so we can get |
| + // updates while in the system DoDragDrop loop. |
| + bool old_state = MessageLoop::current()->NestableTasksAllowed(); |
| + MessageLoop::current()->SetNestableTasksAllowed(true); |
| + int result_op = client->StartDragAndDrop(data, ConvertFromWeb(ops)); |
| + MessageLoop::current()->SetNestableTasksAllowed(old_state); |
| + |
| + EndDrag(ConvertToWeb(result_op)); |
| + GetTabContents()->render_view_host()->DragSourceSystemDragEnded(); |
| } |
| void NativeTabContentsViewAura::CancelDrag() { |
| - // TODO(beng): |
| - NOTIMPLEMENTED(); |
| + aura::DragDropClient* client = static_cast<aura::DragDropClient*>( |
| + aura::Desktop::GetInstance()->GetProperty( |
| + aura::kDesktopDragDropClientKey)); |
| + if (client) |
| + client->DragCancel(); |
| } |
| bool NativeTabContentsViewAura::IsDoingDrag() const { |
| - // TODO(beng): |
| - NOTIMPLEMENTED(); |
| + aura::DragDropClient* client = static_cast<aura::DragDropClient*>( |
| + aura::Desktop::GetInstance()->GetProperty( |
| + aura::kDesktopDragDropClientKey)); |
| + if (client) |
| + return client->IsDragDropInProgress(); |
| return false; |
| } |
| void NativeTabContentsViewAura::SetDragCursor( |
| WebKit::WebDragOperation operation) { |
| - // TODO(beng): |
| - NOTIMPLEMENTED(); |
| + current_drag_op_ = operation; |
| } |
| views::NativeWidget* NativeTabContentsViewAura::AsNativeWidget() { |
| @@ -136,6 +223,99 @@ bool NativeTabContentsViewAura::OnMouseEvent(aura::MouseEvent* event) { |
| return views::NativeWidgetAura::OnMouseEvent(event); |
| } |
| +void NativeTabContentsViewAura::OnDragEntered( |
| + const aura::DropTargetEvent& event) { |
| + WebDropData drop_data; |
| + PrepareWebDropData(&drop_data, event.data()); |
| + WebKit::WebDragOperationsMask op = ConvertToWeb(event.source_operations()); |
| + |
| + gfx::Point screen_pt = aura::Desktop::GetInstance()->last_mouse_location(); |
| + GetTabContents()->render_view_host()->DragTargetDragEnter( |
| + drop_data, event.location(), screen_pt, op); |
| +} |
| + |
| +int NativeTabContentsViewAura::OnDragUpdated( |
| + const aura::DropTargetEvent& event) { |
| + WebKit::WebDragOperationsMask op = ConvertToWeb(event.source_operations()); |
| + gfx::Point screen_pt = aura::Desktop::GetInstance()->last_mouse_location(); |
| + GetTabContents()->render_view_host()->DragTargetDragOver( |
| + event.location(), screen_pt, op); |
| + return ConvertFromWeb(current_drag_op_); |
| +} |
| + |
| +void NativeTabContentsViewAura::OnDragExited() { |
| + GetTabContents()->render_view_host()->DragTargetDragLeave(); |
| +} |
| + |
| +int NativeTabContentsViewAura::OnPerformDrop( |
| + const aura::DropTargetEvent& event) { |
| + GetTabContents()->render_view_host()->DragTargetDrop( |
| + event.location(), aura::Desktop::GetInstance()->last_mouse_location()); |
| + return current_drag_op_; |
| +} |
| + |
|
Ben Goodger (Google)
2011/11/28 17:07:44
Can we add a section marker here:
/////...etc
//
varunjain
2011/11/28 17:32:29
Done.
|
| +void NativeTabContentsViewAura::PrepareDragData( |
|
Ben Goodger (Google)
2011/11/28 17:07:44
Any of these functions that don't work with local
varunjain
2011/11/28 17:32:29
Done.
|
| + const WebDropData& drop_data, |
| + ui::OSExchangeDataProviderAura* provider) { |
| + if (!drop_data.plain_text.empty()) |
| + provider->SetString(drop_data.plain_text); |
| + if (drop_data.url.is_valid()) |
| + provider->SetURL(drop_data.url, drop_data.url_title); |
| + // TODO(varunjain): support other formats. |
| +} |
| + |
| +void NativeTabContentsViewAura::PrepareWebDropData( |
| + WebDropData* drop_data, |
| + const ui::OSExchangeData& data) { |
|
Ben Goodger (Google)
2011/11/28 17:07:44
ditto
varunjain
2011/11/28 17:32:29
Done.
|
| + string16 plain_text, url_title; |
| + GURL url; |
| + data.GetString(&plain_text); |
| + if (!plain_text.empty()) |
| + drop_data->plain_text = plain_text; |
| + data.GetURLAndTitle(&url, &url_title); |
| + if (url.is_valid()) { |
| + drop_data->url = url; |
| + drop_data->url_title = url_title; |
| + } |
| + // TODO(varunjain): support other formats. |
| +} |
| + |
| +int NativeTabContentsViewAura::ConvertFromWeb( |
|
Ben Goodger (Google)
2011/11/28 17:07:44
ditto
varunjain
2011/11/28 17:32:29
Done.
|
| + WebKit::WebDragOperationsMask ops) { |
| + int drag_op = ui::DragDropTypes::DRAG_NONE; |
| + if (ops & WebKit::WebDragOperationCopy) |
| + drag_op |= ui::DragDropTypes::DRAG_COPY; |
| + if (ops & WebKit::WebDragOperationMove) |
| + drag_op |= ui::DragDropTypes::DRAG_MOVE; |
| + if (ops & WebKit::WebDragOperationLink) |
| + drag_op |= ui::DragDropTypes::DRAG_LINK; |
| + return drag_op; |
| +} |
| + |
| +WebKit::WebDragOperationsMask NativeTabContentsViewAura::ConvertToWeb( |
| + int drag_op) { |
|
Ben Goodger (Google)
2011/11/28 17:07:44
ditto
varunjain
2011/11/28 17:32:29
Done.
|
| + int web_drag_op = WebKit::WebDragOperationNone; |
| + if (drag_op & ui::DragDropTypes::DRAG_COPY) |
| + web_drag_op |= WebKit::WebDragOperationCopy; |
| + if (drag_op & ui::DragDropTypes::DRAG_MOVE) |
| + web_drag_op |= WebKit::WebDragOperationMove; |
| + if (drag_op & ui::DragDropTypes::DRAG_LINK) |
| + web_drag_op |= WebKit::WebDragOperationLink; |
| + return (WebKit::WebDragOperationsMask) web_drag_op; |
| +} |
| + |
| +void NativeTabContentsViewAura::EndDrag(WebKit::WebDragOperationsMask ops) { |
| + gfx::Point screen_loc = aura::Desktop::GetInstance()->last_mouse_location(); |
| + gfx::Point client_loc = screen_loc; |
| + RenderViewHost* rvh = GetTabContents()->render_view_host(); |
| + aura::Window* window = static_cast<aura::Window*>( |
|
Ben Goodger (Google)
2011/11/28 17:07:44
This cast isn't necessary. NativeView typedefs to
varunjain
2011/11/28 17:32:29
Done.
|
| + rvh->view()->GetNativeView()); |
| + aura::Window::ConvertPointToWindow(aura::Desktop::GetInstance(), |
| + window, &client_loc); |
| + rvh->DragSourceEndedAt(client_loc.x(), client_loc.y(), screen_loc.x(), |
| + screen_loc.y(), ops); |
| +} |
| + |
| //////////////////////////////////////////////////////////////////////////////// |
| // NativeTabContentsView, public: |