diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-15 15:36:03 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-15 15:36:03 +0000 |
commit | 3da0bfd1d9974b55d3358aad5954836e9986ef4b (patch) | |
tree | fbe33a78ca5f6aba01b5544516c66c17953d6552 /views | |
parent | a20720983ddc7796ba3b93b3e57be2e5ba7f31a5 (diff) | |
download | chromium_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.h | 19 | ||||
-rw-r--r-- | views/event.h | 6 | ||||
-rw-r--r-- | views/view.cc | 33 | ||||
-rw-r--r-- | views/view.h | 30 | ||||
-rw-r--r-- | views/widget/root_view.cc | 71 | ||||
-rw-r--r-- | views/widget/root_view.h | 24 |
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); }; |