summaryrefslogtreecommitdiffstats
path: root/views
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-15 15:36:03 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-15 15:36:03 +0000
commit3da0bfd1d9974b55d3358aad5954836e9986ef4b (patch)
treefbe33a78ca5f6aba01b5544516c66c17953d6552 /views
parenta20720983ddc7796ba3b93b3e57be2e5ba7f31a5 (diff)
downloadchromium_src-3da0bfd1d9974b55d3358aad5954836e9986ef4b.zip
chromium_src-3da0bfd1d9974b55d3358aad5954836e9986ef4b.tar.gz
chromium_src-3da0bfd1d9974b55d3358aad5954836e9986ef4b.tar.bz2
Changes the tab close button to a dot, unless you're near the button
or the tab is selected. I'm not to keen on the mouse near names, if you have better ideas please say so. BUG=45743 TEST=none Review URL: http://codereview.chromium.org/2796006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@49795 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views')
-rw-r--r--views/controls/button/image_button.h19
-rw-r--r--views/event.h6
-rw-r--r--views/view.cc33
-rw-r--r--views/view.h30
-rw-r--r--views/widget/root_view.cc71
-rw-r--r--views/widget/root_view.h24
6 files changed, 162 insertions, 21 deletions
diff --git a/views/controls/button/image_button.h b/views/controls/button/image_button.h
index f65118a..c99c77f 100644
--- a/views/controls/button/image_button.h
+++ b/views/controls/button/image_button.h
@@ -18,6 +18,14 @@ namespace views {
class ImageButton : public CustomButton {
public:
+ enum HorizontalAlignment { ALIGN_LEFT = 0,
+ ALIGN_CENTER,
+ ALIGN_RIGHT, };
+
+ enum VerticalAlignment { ALIGN_TOP = 0,
+ ALIGN_MIDDLE,
+ ALIGN_BOTTOM };
+
explicit ImageButton(ButtonListener* listener);
virtual ~ImageButton();
@@ -29,13 +37,10 @@ class ImageButton : public CustomButton {
const SkBitmap* image,
const SkBitmap* mask);
- enum HorizontalAlignment { ALIGN_LEFT = 0,
- ALIGN_CENTER,
- ALIGN_RIGHT, };
-
- enum VerticalAlignment { ALIGN_TOP = 0,
- ALIGN_MIDDLE,
- ALIGN_BOTTOM };
+ // Explicitly sets the background image.
+ void set_background_image(const SkBitmap& background) {
+ background_image_ = background;
+ }
// Sets how the image is laid out within the button's bounds.
void SetImageAlignment(HorizontalAlignment h_align,
diff --git a/views/event.h b/views/event.h
index 6f96a71..91c0a53 100644
--- a/views/event.h
+++ b/views/event.h
@@ -41,6 +41,8 @@ class Event {
ET_MOUSE_MOVED,
ET_MOUSE_ENTERED,
ET_MOUSE_EXITED,
+ ET_MOUSE_NEAR,
+ ET_MOUSE_EXITED_NEAR,
ET_KEY_PRESSED,
ET_KEY_RELEASED,
ET_MOUSEWHEEL,
@@ -100,7 +102,9 @@ class Event {
type_ == ET_MOUSE_MOVED ||
type_ == ET_MOUSE_ENTERED ||
type_ == ET_MOUSE_EXITED ||
- type_ == ET_MOUSEWHEEL;
+ type_ == ET_MOUSEWHEEL ||
+ type_ == ET_MOUSE_NEAR ||
+ type_ == ET_MOUSE_EXITED_NEAR;
}
#if defined(OS_WIN)
diff --git a/views/view.cc b/views/view.cc
index 012240a..988e76b 100644
--- a/views/view.cc
+++ b/views/view.cc
@@ -132,6 +132,21 @@ void View::SetBounds(const gfx::Rect& bounds) {
}
}
+void View::RegisterForMouseNearEvents(const gfx::Insets& insets) {
+ RootView* root = GetRootView();
+ if (insets.empty()) {
+ near_insets_.reset(NULL);
+ if (root)
+ root->UnregisterViewForNearNotification(this);
+ } else {
+ near_insets_.reset(
+ new gfx::Insets(insets.top(), insets.left(), insets.bottom(),
+ insets.right()));
+ if (root)
+ root->RegisterViewForNearNotification(this);
+ }
+}
+
gfx::Rect View::GetLocalBounds(bool include_border) const {
if (include_border || !border_.get())
return gfx::Rect(0, 0, width(), height());
@@ -537,7 +552,7 @@ void View::AddChildView(int index, View* v) {
UpdateTooltip();
RootView* root = GetRootView();
if (root)
- RegisterChildrenForVisibleBoundsNotification(root, v);
+ RegisterChildrenForRootNotifications(root, v);
if (layout_manager_.get())
layout_manager_->ViewAdded(this, v);
@@ -609,7 +624,7 @@ void View::DoRemoveChildView(View* a_view,
RootView* root = GetRootView();
if (root)
- UnregisterChildrenForVisibleBoundsNotification(root, a_view);
+ UnregisterChildrenForRootNotifications(root, a_view);
a_view->PropagateRemoveNotifications(this);
a_view->SetParent(NULL);
@@ -1440,24 +1455,26 @@ ThemeProvider* View::GetThemeProvider() const {
}
// static
-void View::RegisterChildrenForVisibleBoundsNotification(
- RootView* root, View* view) {
+void View::RegisterChildrenForRootNotifications(RootView* root, View* view) {
DCHECK(root && view);
if (view->GetNotifyWhenVisibleBoundsInRootChanges())
root->RegisterViewForVisibleBoundsNotification(view);
+ if (view->near_insets_.get())
+ root->RegisterViewForNearNotification(view);
for (int i = 0; i < view->GetChildViewCount(); ++i)
- RegisterChildrenForVisibleBoundsNotification(root, view->GetChildViewAt(i));
+ RegisterChildrenForRootNotifications(root, view->GetChildViewAt(i));
}
// static
-void View::UnregisterChildrenForVisibleBoundsNotification(
+void View::UnregisterChildrenForRootNotifications(
RootView* root, View* view) {
DCHECK(root && view);
if (view->GetNotifyWhenVisibleBoundsInRootChanges())
root->UnregisterViewForVisibleBoundsNotification(view);
+ if (view->near_insets_.get())
+ root->UnregisterViewForNearNotification(view);
for (int i = 0; i < view->GetChildViewCount(); ++i)
- UnregisterChildrenForVisibleBoundsNotification(root,
- view->GetChildViewAt(i));
+ UnregisterChildrenForRootNotifications(root, view->GetChildViewAt(i));
}
void View::AddDescendantToNotify(View* view) {
diff --git a/views/view.h b/views/view.h
index c0f6f07..a9012a5 100644
--- a/views/view.h
+++ b/views/view.h
@@ -178,6 +178,11 @@ class View : public AcceleratorTarget {
void SetX(int x) { SetBounds(x, y(), width(), height()); }
void SetY(int y) { SetBounds(x(), y, width(), height()); }
+ // Registers this view for mouse near events (OnMouseNear and
+ // OnMouseExitedNear). Mouse near events are sent for the extended rectangle
+ // defined by the bounds of this view + |insets|.
+ void RegisterForMouseNearEvents(const gfx::Insets& insets);
+
// Returns the left coordinate of the View, relative to the parent View,
// which is the value of bounds_.x().
//
@@ -686,6 +691,18 @@ class View : public AcceleratorTarget {
// Default implementation does nothing. Override as needed.
virtual void OnMouseExited(const MouseEvent& event);
+ // Sent when the mouse enters the rectangle defined by this views bounds and
+ // the insets passed to RegisterForMouseNearEvents. This is only sent for
+ // views that have explicitly registered for near notification
+ // (RegisterForMouseNearEvents).
+ virtual void OnMouseNear(const MouseEvent& event) {}
+
+ // Sent when the mouse exits the rectangle defined by this views bounds and
+ // the insets passed to RegisterForMouseNearEvents. This is only sent for
+ // views that have explicitly registered for near notification
+ // (RegisterForMouseNearEvents).
+ virtual void OnMouseExitedNear(const MouseEvent& event) {}
+
// Set the MouseHandler for a drag session.
//
// A drag session is a stream of mouse events starting
@@ -1176,11 +1193,11 @@ class View : public AcceleratorTarget {
// Recursively descends through all descendant views,
// registering/unregistering all views that want visible bounds in root
- // view notification.
- static void RegisterChildrenForVisibleBoundsNotification(RootView* root,
- View* view);
- static void UnregisterChildrenForVisibleBoundsNotification(RootView* root,
- View* view);
+ // view notification and/or mouse near events.
+ static void RegisterChildrenForRootNotifications(RootView* root, View* view);
+ static void UnregisterChildrenForRootNotifications(RootView* root,
+ View* view);
+
// Adds/removes view to the list of descendants that are notified any time
// this views location and possibly size are changed.
@@ -1280,6 +1297,9 @@ class View : public AcceleratorTarget {
// right-to-left locales for this View.
bool flip_canvas_on_paint_for_rtl_ui_;
+ // Insets passed to RegisterForMouseNearEvents.
+ scoped_ptr<gfx::Insets> near_insets_;
+
// The default value for how long to wait (in ms) before showing a menu
// button on hover. This value is used if the OS doesn't supply one.
static const int kShowFolderDropMenuDelay;
diff --git a/views/widget/root_view.cc b/views/widget/root_view.cc
index 3ea101c..2a6798c 100644
--- a/views/widget/root_view.cc
+++ b/views/widget/root_view.cc
@@ -489,6 +489,33 @@ void RootView::OnMouseMoved(const MouseEvent& e) {
mouse_move_handler_->OnMouseExited(exited_event);
SetActiveCursor(NULL);
}
+
+ if (registered_near_views_.empty())
+ return;
+
+ std::set<View*> near_views;
+ GetViewsRegisteredForNearNotification(e, &near_views);
+
+ MouseEvent exited_near_event(Event::ET_MOUSE_EXITED_NEAR, 0, 0, 0);
+ for (std::set<View*>::const_iterator i = near_views_.begin();
+ i != near_views_.end(); ++i) {
+ if (near_views.find(*i) == near_views.end())
+ (*i)->OnMouseExitedNear(exited_near_event);
+ }
+
+ for (std::set<View*>::const_iterator i = near_views.begin();
+ i != near_views.end(); ++i) {
+ if (near_views_.find(*i) == near_views_.end()) {
+ MouseEvent entered_event(Event::ET_MOUSE_ENTERED,
+ this,
+ *i,
+ e.location(),
+ 0);
+ (*i)->OnMouseNear(entered_event);
+ }
+ }
+
+ near_views_.swap(near_views);
}
void RootView::ProcessOnMouseExited() {
@@ -497,6 +524,8 @@ void RootView::ProcessOnMouseExited() {
mouse_move_handler_->OnMouseExited(exited_event);
mouse_move_handler_ = NULL;
}
+
+ SendMouseExitedNear();
}
void RootView::SetMouseHandler(View *new_mh) {
@@ -880,6 +909,14 @@ void RootView::UnregisterViewForVisibleBoundsNotification(View* view) {
}
}
+void RootView::RegisterViewForNearNotification(View* view) {
+ registered_near_views_.insert(view);
+}
+
+void RootView::UnregisterViewForNearNotification(View* view) {
+ registered_near_views_.erase(view);
+}
+
void RootView::SetMouseLocationAndFlags(const MouseEvent& e) {
last_mouse_event_flags_ = e.GetFlags();
last_mouse_event_x_ = e.x();
@@ -936,4 +973,38 @@ void RootView::SetActiveCursor(gfx::NativeCursor cursor) {
#endif
}
+void RootView::GetViewsRegisteredForNearNotification(
+ const MouseEvent& e,
+ std::set<View*>* near_views) {
+ const gfx::Point& location = e.location();
+ for (std::set<View*>::const_iterator i = registered_near_views_.begin();
+ i != registered_near_views_.end(); ++i) {
+ View* view = *i;
+ DCHECK(view->near_insets_.get());
+ const gfx::Insets& insets = *view->near_insets_;
+ gfx::Point view_loc(view->x() - insets.left(),
+ view->y() - insets.top());
+ View::ConvertPointToView(view->GetParent(), this, &view_loc);
+ if (location.x() >= view_loc.x() &&
+ location.y() >= view_loc.y() &&
+ location.x() < view_loc.x() + (view->width() + insets.width()) &&
+ location.y() < view_loc.y() + (view->height() + insets.height())) {
+ near_views->insert(view);
+ }
+ }
+}
+
+void RootView::SendMouseExitedNear() {
+ if (near_views_.empty())
+ return;
+
+ MouseEvent exited_near_event(Event::ET_MOUSE_EXITED_NEAR, 0, 0, 0);
+ for (std::set<View*>::const_iterator i = near_views_.begin();
+ i != near_views_.end(); ++i) {
+ (*i)->OnMouseExitedNear(exited_near_event);
+ }
+
+ near_views_.clear();
+}
+
} // namespace views
diff --git a/views/widget/root_view.h b/views/widget/root_view.h
index 05887e1..ba1d5d22 100644
--- a/views/widget/root_view.h
+++ b/views/widget/root_view.h
@@ -5,6 +5,7 @@
#ifndef VIEWS_WIDGET_ROOT_VIEW_H_
#define VIEWS_WIDGET_ROOT_VIEW_H_
+#include <set>
#include <string>
#include "base/ref_counted.h"
@@ -217,6 +218,10 @@ class RootView : public View,
void RegisterViewForVisibleBoundsNotification(View* view);
void UnregisterViewForVisibleBoundsNotification(View* view);
+ // Registers/unregisters the View for mouse near events.
+ void RegisterViewForNearNotification(View* view);
+ void UnregisterViewForNearNotification(View* view);
+
// Returns the next focusable view or view containing a FocusTraversable (NULL
// if none was found), starting at the starting_view.
// check_starting_view, can_go_up and can_go_down controls the traversal of
@@ -258,6 +263,15 @@ class RootView : public View,
// Sets the current cursor, or resets it to the last one if NULL is provided.
void SetActiveCursor(gfx::NativeCursor cursor);
+ // Returns in |near_views| the set of views registered for mouse near events
+ // that overlap with the location of the specified event.
+ void GetViewsRegisteredForNearNotification(const MouseEvent& e,
+ std::set<View*>* near_views);
+
+ // Sends OnMouseExitedNear to the set of views the mouse is near and empties
+ // the set.
+ void SendMouseExitedNear();
+
// The view currently handing down - drag - up
View* mouse_pressed_handler_;
@@ -330,6 +344,16 @@ class RootView : public View,
bool is_processing_paint_;
#endif
+ // Set of views registered for mouse near events.
+ // NOTE: because views registered for near mouse events can overlap other
+ // views and extend outside the bounds of themselves and ancestors we store
+ // the registered views here and treat them separately. This is generally ok
+ // as there are a small set of views registered for near notification.
+ std::set<View*> registered_near_views_;
+
+ // Set of views the mouse is currently near.
+ std::set<View*> near_views_;
+
DISALLOW_COPY_AND_ASSIGN(RootView);
};