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

Unified Diff: chrome/browser/extensions/extension_shelf.cc

Issue 119103: Part 1 of dragging extensions on the shelf. This part was just about getting... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/extensions/extension_shelf.h ('k') | chrome/browser/extensions/extension_view.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/extensions/extension_shelf.cc
===================================================================
--- chrome/browser/extensions/extension_shelf.cc (revision 17478)
+++ chrome/browser/extensions/extension_shelf.cc (working copy)
@@ -16,6 +16,8 @@
#include "chrome/common/notification_service.h"
#include "skia/ext/skia_utils.h"
#include "views/controls/label.h"
+#include "views/screen.h"
+#include "views/widget/root_view.h"
namespace {
@@ -52,6 +54,9 @@
// static const SkColor kBackgroundColor = SkColorSetRGB(237, 244, 252);
// static const SkColor kTopGradientColor = SkColorSetRGB(222, 234, 248);
+// Delays for showing and hiding the shelf handle.
+static const int kHideDelayMs = 500;
+
} // namespace
@@ -70,35 +75,41 @@
virtual void Layout();
virtual void OnMouseEntered(const views::MouseEvent& event);
virtual void OnMouseExited(const views::MouseEvent& event);
+ virtual bool OnMousePressed(const views::MouseEvent& event);
+ virtual bool OnMouseDragged(const views::MouseEvent& event);
+ virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled);
+ virtual bool IsFocusable() const { return true; }
private:
ExtensionShelf* shelf_;
ExtensionView* extension_view_;
- views::Label* title_;
+ scoped_ptr<views::Label> title_;
+ bool dragging_;
+ gfx::Point initial_drag_location_;
DISALLOW_COPY_AND_ASSIGN(ExtensionShelfHandle);
};
ExtensionShelfHandle::ExtensionShelfHandle(ExtensionShelf* shelf)
- : shelf_(shelf), extension_view_(NULL) {
+ : shelf_(shelf), extension_view_(NULL), dragging_(false) {
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- title_ = new views::Label(L"", rb.GetFont(ResourceBundle::BaseFont));
- // Set enabled to false so we get the events.
- title_->SetEnabled(false);
-
- // Set the colors afterwards so that the label doesn't get a disabled
- // color.
+ // |title_| isn't actually put in the view hierarchy. We just use it
+ // to draw in place. The reason for this is so that we can properly handle
+ // the various mouse events necessary for hovering and dragging.
+ title_.reset(new views::Label(L"", rb.GetFont(ResourceBundle::BaseFont)));
title_->SetColor(kHandleTextColor);
title_->SetDrawHighlighted(true);
title_->SetHighlightColor(kHandleTextHighlightColor);
title_->SetBounds(kHandlePadding, kHandlePadding, 100, 100);
title_->SizeToPreferredSize();
- AddChildView(title_);
}
void ExtensionShelfHandle::SetExtensionView(ExtensionView* v) {
+ DCHECK(v->extension());
extension_view_ = v;
+ if (!extension_view_->extension())
+ return;
title_->SetText(UTF8ToWide(extension_view_->extension()->name()));
title_->SizeToPreferredSize();
SizeToPreferredSize();
@@ -115,15 +126,39 @@
canvas->FillRectInt(kBorderColor, ext_width, height() - 1,
width() - ext_width, 1);
}
+
+ // Draw the title using a Label as a stamp.
+ // See constructor for comment about this.
+ title_->ProcessPaint(canvas);
+
+ if (dragging_) {
+ // when we're dragging, draw the bottom border.
+ canvas->FillRectInt(kBorderColor, 0, height() - 1, width(), 1);
+ }
}
gfx::Size ExtensionShelfHandle::GetPreferredSize() {
gfx::Size sz = title_->GetPreferredSize();
+ if (extension_view_) {
+ int width = std::max(extension_view_->width() + 2, sz.width());
+ sz.set_width(width);
+ }
sz.Enlarge(kHandlePadding * 2, kHandlePadding * 2);
+ if (dragging_) {
+ gfx::Size extension_size = extension_view_->GetPreferredSize();
+ sz.Enlarge(0, extension_size.height() + 2);
+ }
return sz;
}
void ExtensionShelfHandle::Layout() {
+ if (dragging_) {
+ int y = title_->bounds().bottom() + kHandlePadding + 1;
+ extension_view_->SetBounds(1,
+ y,
+ extension_view_->width(),
+ extension_view_->height());
+ }
}
void ExtensionShelfHandle::OnMouseEntered(const views::MouseEvent& event) {
@@ -136,7 +171,43 @@
shelf_->OnExtensionMouseLeave(extension_view_);
}
+bool ExtensionShelfHandle::OnMousePressed(const views::MouseEvent& event) {
+ initial_drag_location_ = event.location();
+ return true;
+}
+bool ExtensionShelfHandle::OnMouseDragged(const views::MouseEvent& event) {
+ if (!dragging_) {
+ int y_delta = abs(initial_drag_location_.y() - event.location().y());
+ if (y_delta > GetVerticalDragThreshold()) {
+ dragging_ = true;
+ shelf_->DragExtension();
+ }
+ } else {
+ // When freely dragging a window, you can really only trust the
+ // actual screen point. Coordinate conversions, just don't work.
+ gfx::Point screen = views::Screen::GetCursorScreenPoint();
+
+ // However, the handle is actually a child of the browser window
+ // so we need to convert it back to local coordinates.
+ gfx::Point origin(0, 0);
+ views::View::ConvertPointToScreen(shelf_->GetRootView(), &origin);
+ screen.set_x(screen.x() - origin.x() - initial_drag_location_.x());
+ screen.set_y(screen.y() - origin.y() - initial_drag_location_.y());
+ shelf_->DragHandleTo(screen);
+ }
+ return true;
+}
+
+void ExtensionShelfHandle::OnMouseReleased(const views::MouseEvent& event,
+ bool canceled) {
+ if (dragging_) {
+ views::View::OnMouseReleased(event, canceled);
+ dragging_ = false;
+ shelf_->DropExtension(event.location(), canceled);
+ }
+}
+
////////////////////////////////////////////////
ExtensionShelf::ExtensionShelf(Browser* browser)
@@ -144,7 +215,8 @@
handle_(NULL),
handle_visible_(false),
current_handle_view_(NULL),
- ALLOW_THIS_IN_INITIALIZER_LIST(timer_factory_(this)) {
+ ALLOW_THIS_IN_INITIALIZER_LIST(timer_factory_(this)),
+ drag_placeholder_view_(NULL) {
// Watch extensions loaded and unloaded notifications.
registrar_.Add(this, NotificationType::EXTENSIONS_LOADED,
NotificationService::AllSources());
@@ -253,7 +325,7 @@
}
void ExtensionShelf::OnMouseExited(const views::MouseEvent& event) {
- HideShelfHandle(100);
+ HideShelfHandle(kHideDelayMs);
}
void ExtensionShelf::Observe(NotificationType type,
@@ -332,6 +404,9 @@
}
void ExtensionShelf::OnExtensionMouseEvent(ExtensionView* view) {
+ // Ignore these events when dragging.
+ if (drag_placeholder_view_)
+ return;
if (view != current_handle_view_) {
current_handle_view_ = view;
}
@@ -339,8 +414,11 @@
}
void ExtensionShelf::OnExtensionMouseLeave(ExtensionView* view) {
+ // Ignore these events when dragging.
+ if (drag_placeholder_view_)
+ return;
if (view == current_handle_view_) {
- HideShelfHandle(100);
+ HideShelfHandle(kHideDelayMs);
}
}
@@ -353,6 +431,50 @@
HideShelfHandle(0);
}
+void ExtensionShelf::DragExtension() {
+ // Construct a placeholder view to replace the view.
+ // TODO(erikkay) the placeholder should draw a dimmed version of the
+ // extension view
+ int index = GetChildIndex(current_handle_view_);
+ drag_placeholder_view_ = new View();
+ drag_placeholder_view_->SetBounds(current_handle_view_->bounds());
+ AddChildView(index, drag_placeholder_view_);
+
+ // Now move the view into the handle's widget.
+ ExtensionShelfHandle* handle_view =
+ static_cast<ExtensionShelfHandle*>(GetHandle()->view());
+ handle_view->AddChildView(current_handle_view_);
+ handle_view->SizeToPreferredSize();
+ handle_->ResizeToView();
+ handle_view->Layout();
+ handle_->DetachFromBrowser();
+ SchedulePaint();
+}
+
+void ExtensionShelf::DropExtension(const gfx::Point& pt, bool cancel) {
+ handle_->AttachToBrowser();
+
+ // Replace the placeholder view with the original.
+ int index = GetChildIndex(drag_placeholder_view_);
+ AddChildView(index, current_handle_view_);
+ current_handle_view_->SetBounds(drag_placeholder_view_->bounds());
+ RemoveChildView(drag_placeholder_view_);
+ delete drag_placeholder_view_;
+ drag_placeholder_view_ = NULL;
+
+ ExtensionShelfHandle* handle_view =
+ static_cast<ExtensionShelfHandle*>(GetHandle()->view());
+ handle_view->SizeToPreferredSize();
+ handle_view->Layout();
+ handle_->ResizeToView();
+ LayoutShelfHandle();
+ SchedulePaint();
+}
+
+void ExtensionShelf::DragHandleTo(const gfx::Point& pt) {
+ handle_->MoveTo(pt.x(), pt.y());
+}
+
void ExtensionShelf::InitBackground(gfx::Canvas* canvas,
const SkRect& subset) {
if (!background_.empty())
@@ -389,6 +511,8 @@
}
void ExtensionShelf::ShowShelfHandle() {
+ if (drag_placeholder_view_)
+ return;
if (!timer_factory_.empty())
timer_factory_.RevokeAll();
if (handle_visible_) {
@@ -410,6 +534,8 @@
}
void ExtensionShelf::HideShelfHandle(int delay_ms) {
+ if (drag_placeholder_view_)
+ return;
if (!timer_factory_.empty())
timer_factory_.RevokeAll();
if (!handle_visible_)
@@ -427,8 +553,8 @@
if (handle_visible_) {
handle_visible_ = false;
handle_->Hide();
- // TODO(erikkay) with this enabled, I get an odd crash shortly after hide.
- //handle_.reset(NULL);
+ handle_->DetachFromBrowser();
+ handle_.reset(NULL);
current_handle_view_ = NULL;
}
}
« no previous file with comments | « chrome/browser/extensions/extension_shelf.h ('k') | chrome/browser/extensions/extension_view.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698