diff options
author | beng@google.com <beng@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-07 18:28:35 +0000 |
---|---|---|
committer | beng@google.com <beng@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-07 18:28:35 +0000 |
commit | a6b4a185656b7b16d965e5ff0e469658c424e85d (patch) | |
tree | 4112198f2f85677b00d3a81b4c6e7d4033816ef6 | |
parent | f197851787237e4fa2d343f536f8fc7231316168 (diff) | |
download | chromium_src-a6b4a185656b7b16d965e5ff0e469658c424e85d.zip chromium_src-a6b4a185656b7b16d965e5ff0e469658c424e85d.tar.gz chromium_src-a6b4a185656b7b16d965e5ff0e469658c424e85d.tar.bz2 |
Make tabs affected by context menu actions pulse. The effect is somewhat subtle since I'm re-using the selection animation.
Added support to the Menu Delegate for notifications of when selection moves within the menu.
B=1313339
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@523 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/tabs/tab.cc | 134 | ||||
-rw-r--r-- | chrome/browser/tabs/tab.h | 24 | ||||
-rw-r--r-- | chrome/browser/tabs/tab_renderer.cc | 77 | ||||
-rw-r--r-- | chrome/browser/tabs/tab_renderer.h | 15 | ||||
-rw-r--r-- | chrome/browser/tabs/tab_strip.cc | 46 | ||||
-rw-r--r-- | chrome/browser/tabs/tab_strip.h | 5 | ||||
-rw-r--r-- | chrome/browser/tabs/tab_strip_model.cc | 10 | ||||
-rw-r--r-- | chrome/browser/tabs/tab_strip_model.h | 4 | ||||
-rw-r--r-- | chrome/views/chrome_menu.cc | 3 | ||||
-rw-r--r-- | chrome/views/chrome_menu.h | 4 |
10 files changed, 248 insertions, 74 deletions
diff --git a/chrome/browser/tabs/tab.cc b/chrome/browser/tabs/tab.cc index df02a15..f253faa 100644 --- a/chrome/browser/tabs/tab.cc +++ b/chrome/browser/tabs/tab.cc @@ -36,11 +36,93 @@ #include "chrome/browser/user_metrics.h" #include "chrome/common/l10n_util.h" #include "chrome/common/resource_bundle.h" +#include "chrome/views/chrome_menu.h" #include "chrome/views/tooltip_manager.h" #include "generated_resources.h" const std::string Tab::kTabClassName = "browser/tabs/Tab"; +class TabContextMenuController : public ChromeViews::MenuDelegate { + public: + explicit TabContextMenuController(Tab* tab) + : tab_(tab), + last_command_(TabStripModel::CommandFirst) { + menu_.reset(new ChromeViews::MenuItemView(this)); + menu_->AppendMenuItemWithLabel(TabStripModel::CommandNewTab, + l10n_util::GetString(IDS_TAB_CXMENU_NEWTAB)); + menu_->AppendSeparator(); + menu_->AppendMenuItemWithLabel(TabStripModel::CommandReload, + l10n_util::GetString(IDS_TAB_CXMENU_RELOAD)); + menu_->AppendMenuItemWithLabel( + TabStripModel::CommandDuplicate, + l10n_util::GetString(IDS_TAB_CXMENU_DUPLICATE)); + menu_->AppendSeparator(); + menu_->AppendMenuItemWithLabel( + TabStripModel::CommandCloseTab, + l10n_util::GetString(IDS_TAB_CXMENU_CLOSETAB)); + menu_->AppendMenuItemWithLabel( + TabStripModel::CommandCloseOtherTabs, + l10n_util::GetString(IDS_TAB_CXMENU_CLOSEOTHERTABS)); + menu_->AppendMenuItemWithLabel( + TabStripModel::CommandCloseTabsToRight, + l10n_util::GetString(IDS_TAB_CXMENU_CLOSETABSTORIGHT)); + menu_->AppendMenuItemWithLabel( + TabStripModel::CommandCloseTabsOpenedBy, + l10n_util::GetString(IDS_TAB_CXMENU_CLOSETABSOPENEDBY)); + } + virtual ~TabContextMenuController() { + tab_->delegate()->StopAllHighlighting(); + } + + void RunMenuAt(int x, int y) { + menu_->RunMenuAt(tab_->GetViewContainer()->GetHWND(), + gfx::Rect(x, y, 0, 0), ChromeViews::MenuItemView::TOPLEFT, + false); + } + + private: + // ChromeViews::MenuDelegate implementation: + virtual bool IsCommandEnabled(int id) const { + // The MenuItemView used to contain the contents of the Context Menu itself + // has a command id of 0, and it will check to see if it's enabled for + // some reason during its construction. The TabStripModel can't handle + // command indices it doesn't know about, so we need to filter this out + // here. + if (id == 0) + return false; + return tab_->delegate()->IsCommandEnabledForTab( + static_cast<TabStripModel::ContextMenuCommand>(id), + tab_); + } + + virtual void ExecuteCommand(int id) { + tab_->delegate()->ExecuteCommandForTab( + static_cast<TabStripModel::ContextMenuCommand>(id), + tab_); + } + + virtual void SelectionChanged(ChromeViews::MenuItemView* menu) { + TabStripModel::ContextMenuCommand command = + static_cast<TabStripModel::ContextMenuCommand>(menu->GetCommand()); + tab_->delegate()->StopHighlightTabsForCommand(last_command_, tab_); + last_command_ = command; + tab_->delegate()->StartHighlightTabsForCommand(command, tab_); + } + + private: + // The context menu. + scoped_ptr<ChromeViews::MenuItemView> menu_; + + // The Tab the context menu was brought up for. + Tab* tab_; + + // The last command that was selected, so that we can start/stop highlighting + // appropriately as the user moves through the menu. + TabStripModel::ContextMenuCommand last_command_; + + DISALLOW_EVIL_CONSTRUCTORS(TabContextMenuController); +}; + /////////////////////////////////////////////////////////////////////////////// // Tab, public: @@ -51,6 +133,7 @@ Tab::Tab(TabDelegate* delegate) close_button()->SetListener(this, 0); close_button()->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_CLOSE)); close_button()->SetAnimationDuration(0); + SetContextMenuController(this); } Tab::~Tab() { @@ -89,13 +172,8 @@ void Tab::OnMouseReleased(const ChromeViews::MouseEvent& event, // Notify the drag helper that we're done with any potential drag operations. // Clean up the drag helper, which is re-created on the next mouse press. delegate_->EndDrag(canceled); - if (event.IsOnlyRightMouseButton()) { - CPoint screen_point = event.GetLocation(); - ConvertPointToScreen(this, &screen_point); - RunContextMenuAt(gfx::Point(screen_point)); - } else if (event.IsMiddleMouseButton()) { + if (event.IsMiddleMouseButton()) delegate_->CloseTab(this); - } } bool Tab::GetTooltipText(int x, int y, std::wstring* tooltip) { @@ -132,17 +210,14 @@ bool Tab::GetAccessibleName(std::wstring* name) { } /////////////////////////////////////////////////////////////////////////////// -// Tab, ChromeViews::Menu::Delegate implementation: +// Tab, ChromeViews::ContextMenuController implementation: -bool Tab::IsCommandEnabled(int id) const { - return delegate_->IsCommandEnabledForTab( - static_cast<TabStripModel::ContextMenuCommand>(id), this); +void Tab::ShowContextMenu(ChromeViews::View* source, int x, int y, + bool is_mouse_gesture) { + TabContextMenuController controller(this); + controller.RunMenuAt(x, y); } -void Tab::ExecuteCommand(int id) { - delegate_->ExecuteCommandForTab( - static_cast<TabStripModel::ContextMenuCommand>(id), this); -} /////////////////////////////////////////////////////////////////////////////// // ChromeViews::BaseButton::ButtonListener implementation: @@ -151,34 +226,3 @@ void Tab::ButtonPressed(ChromeViews::BaseButton* sender) { if (sender == close_button()) delegate_->CloseTab(this); } - -/////////////////////////////////////////////////////////////////////////////// -// Tab, private - -void Tab::RunContextMenuAt(const gfx::Point& screen_point) { - Menu menu(this, Menu::TOPLEFT, GetViewContainer()->GetHWND()); - menu.AppendMenuItem(TabStripModel::CommandNewTab, - l10n_util::GetString(IDS_TAB_CXMENU_NEWTAB), - Menu::NORMAL); - menu.AppendSeparator(); - menu.AppendMenuItem(TabStripModel::CommandReload, - l10n_util::GetString(IDS_TAB_CXMENU_RELOAD), - Menu::NORMAL); - menu.AppendMenuItem(TabStripModel::CommandDuplicate, - l10n_util::GetString(IDS_TAB_CXMENU_DUPLICATE), - Menu::NORMAL); - menu.AppendSeparator(); - menu.AppendMenuItem(TabStripModel::CommandCloseTab, - l10n_util::GetString(IDS_TAB_CXMENU_CLOSETAB), - Menu::NORMAL); - menu.AppendMenuItem(TabStripModel::CommandCloseOtherTabs, - l10n_util::GetString(IDS_TAB_CXMENU_CLOSEOTHERTABS), - Menu::NORMAL); - menu.AppendMenuItem(TabStripModel::CommandCloseTabsToRight, - l10n_util::GetString(IDS_TAB_CXMENU_CLOSETABSTORIGHT), - Menu::NORMAL); - menu.AppendMenuItem(TabStripModel::CommandCloseTabsOpenedBy, - l10n_util::GetString(IDS_TAB_CXMENU_CLOSETABSOPENEDBY), - Menu::NORMAL); - menu.RunMenuAt(screen_point.x(), screen_point.y()); -} diff --git a/chrome/browser/tabs/tab.h b/chrome/browser/tabs/tab.h index bb0a700..8c78190 100644 --- a/chrome/browser/tabs/tab.h +++ b/chrome/browser/tabs/tab.h @@ -50,7 +50,7 @@ class Profile; // /////////////////////////////////////////////////////////////////////////////// class Tab : public TabRenderer, - public Menu::Delegate, + public ChromeViews::ContextMenuController, public ChromeViews::BaseButton::ButtonListener { public: static const std::string kTabClassName; @@ -77,6 +77,14 @@ class Tab : public TabRenderer, virtual void ExecuteCommandForTab( TabStripModel::ContextMenuCommand command_id, Tab* tab) = 0; + // Starts/Stops highlighting the tabs that will be affected by the + // specified command for the specified Tab. + virtual void StartHighlightTabsForCommand( + TabStripModel::ContextMenuCommand command_id, Tab* tab) = 0; + virtual void StopHighlightTabsForCommand( + TabStripModel::ContextMenuCommand command_id, Tab* tab) = 0; + virtual void StopAllHighlighting() = 0; + // Potentially starts a drag for the specified Tab. virtual void MaybeStartDrag(Tab* tab, const ChromeViews::MouseEvent& event) = 0; @@ -92,6 +100,9 @@ class Tab : public TabRenderer, explicit Tab(TabDelegate* delegate); virtual ~Tab(); + // Access the delegate. + TabDelegate* delegate() const { return delegate_; } + // Used to set/check whether this Tab is being animated closed. void set_closing(bool closing) { closing_ = closing; } bool closing() const { return closing_; } @@ -111,16 +122,15 @@ class Tab : public TabRenderer, virtual bool GetAccessibleRole(VARIANT* role); virtual bool GetAccessibleName(std::wstring* name); - // ChromeViews::Menu::Delegate overrides: - virtual bool IsCommandEnabled(int id) const; - virtual void ExecuteCommand(int id); + // ChromeViews::ContextMenuController overrides: + virtual void ShowContextMenu(ChromeViews::View* source, + int x, + int y, + bool is_mouse_gesture); // ChromeViews::BaseButton::ButtonListener overrides: virtual void ButtonPressed(ChromeViews::BaseButton* sender); - // Run a context menu for this Tab at the specified screen point. - void RunContextMenuAt(const gfx::Point& screen_point); - // An instance of a delegate object that can perform various actions based on // user gestures. TabDelegate* delegate_; diff --git a/chrome/browser/tabs/tab_renderer.cc b/chrome/browser/tabs/tab_renderer.cc index 5bfbcf0..6f7030d 100644 --- a/chrome/browser/tabs/tab_renderer.cc +++ b/chrome/browser/tabs/tab_renderer.cc @@ -27,6 +27,8 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#include <limits> + #include "chrome/browser/tabs/tab_renderer.h" #include "base/gfx/image_operations.h" @@ -55,6 +57,9 @@ static const int kUnselectedTitleColor = SkColorSetRGB(64, 64, 64); // How long the hover state takes. static const int kHoverDurationMs = 90; +// How long the pulse throb takes. +static const int kPulseDurationMs = 200; + // How opaque to make the hover state (out of 1). static const double kHoverOpacity = 0.33; static const double kHoverOpacityVista = 0.7; @@ -272,6 +277,9 @@ TabRenderer::TabRenderer() hover_animation_.reset(new SlideAnimation(this)); hover_animation_->SetSlideDuration(kHoverDurationMs); + + pulse_animation_.reset(new ThrobAnimation(this)); + pulse_animation_->SetSlideDuration(kPulseDurationMs); } TabRenderer::~TabRenderer() { @@ -334,10 +342,14 @@ void TabRenderer::ValidateLoadingAnimation(AnimationState animation_state) { SchedulePaint(); } -void TabRenderer::AnimationProgressed(const Animation* animation) { - if (animation == hover_animation_.get()) { - SchedulePaint(); - } +void TabRenderer::StartPulse() { + pulse_animation_->Reset(); + pulse_animation_->StartThrobbing(std::numeric_limits<int>::max()); +} + +void TabRenderer::StopPulse() { + if (pulse_animation_->IsAnimating()) + pulse_animation_->Stop(); } // static @@ -403,21 +415,7 @@ void TabRenderer::Paint(ChromeCanvas* canvas) { show_close_button != showing_close_button_) Layout(); - if (IsSelected()) { - // Sometimes detaching a tab quickly can result in the model reporting it - // as not being selected, so is_drag_clone_ ensures that we always paint - // the active representation for the dragged tab. - PaintActiveTabBackground(canvas); - } else { - // Draw our hover state. - if (hover_animation_->GetCurrentValue() > 0) { - PaintHoverTabBackground(canvas, hover_animation_->GetCurrentValue() * - (win_util::ShouldUseVistaFrame() ? - kHoverOpacityVista : kHoverOpacity)); - } else { - PaintInactiveTabBackground(canvas); - } - } + PaintTabBackground(canvas); // Paint the loading animation if the page is currently loading, otherwise // show the page's favicon. @@ -573,9 +571,48 @@ void TabRenderer::OnMouseExited(const ChromeViews::MouseEvent& e) { hover_animation_->Hide(); } +/////////////////////////////////////////////////////////////////////////////// +// TabRenderer, AnimationDelegate implementation: + +void TabRenderer::AnimationProgressed(const Animation* animation) { + SchedulePaint(); +} + +void TabRenderer::AnimationCanceled(const Animation* animation) { + AnimationEnded(animation); +} + +void TabRenderer::AnimationEnded(const Animation* animation) { + SchedulePaint(); +} + //////////////////////////////////////////////////////////////////////////////// // TabRenderer, private +void TabRenderer::PaintTabBackground(ChromeCanvas* canvas) { + if (IsSelected()) { + // Sometimes detaching a tab quickly can result in the model reporting it + // as not being selected, so is_drag_clone_ ensures that we always paint + // the active representation for the dragged tab. + PaintActiveTabBackground(canvas); + } else { + // Draw our hover state. + Animation* animation = NULL; + if (hover_animation_->IsAnimating()) { + animation = hover_animation_.get(); + } else if (pulse_animation_->IsAnimating()) { + animation = pulse_animation_.get(); + } + if (animation && animation->GetCurrentValue() > 0) { + PaintHoverTabBackground(canvas, animation->GetCurrentValue() * + (win_util::ShouldUseVistaFrame() ? + kHoverOpacityVista : kHoverOpacity)); + } else { + PaintInactiveTabBackground(canvas); + } + } +} + void TabRenderer::PaintInactiveTabBackground(ChromeCanvas* canvas) { bool is_otr = data_.off_the_record; canvas->DrawBitmapInt(is_otr ? *tab_inactive_otr_l : *tab_inactive_l, 0, 0); @@ -609,7 +646,7 @@ void TabRenderer::PaintHoverTabBackground(ChromeCanvas* canvas, canvas->DrawBitmapInt(left, 0, 0); canvas->TileImageInt(center, tab_active_l_width, 0, - GetWidth() - tab_active_l_width - tab_active_r_width, GetHeight()); + GetWidth() - tab_active_l_width - tab_active_r_width, GetHeight()); canvas->DrawBitmapInt(right, GetWidth() - tab_active_r_width, 0); } diff --git a/chrome/browser/tabs/tab_renderer.h b/chrome/browser/tabs/tab_renderer.h index 310a8bc..2c7ad58 100644 --- a/chrome/browser/tabs/tab_renderer.h +++ b/chrome/browser/tabs/tab_renderer.h @@ -33,6 +33,7 @@ #include "base/gfx/point.h" #include "chrome/common/animation.h" #include "chrome/common/slide_animation.h" +#include "chrome/common/throb_animation.h" #include "chrome/views/button.h" #include "chrome/views/menu.h" #include "chrome/views/view.h" @@ -73,8 +74,9 @@ class TabRenderer : public ChromeViews::View, // the tab isn't loading. void ValidateLoadingAnimation(AnimationState animation_state); - // AnimationDelegate implementation. - virtual void AnimationProgressed(const Animation* animation); + // Starts/Stops a pulse animation. + void StartPulse(); + void StopPulse(); // Returns the minimum possible size of a single unselected Tab. static gfx::Size GetMinimumSize(); @@ -105,6 +107,11 @@ class TabRenderer : public ChromeViews::View, virtual void OnMouseEntered(const ChromeViews::MouseEvent& event); virtual void OnMouseExited(const ChromeViews::MouseEvent& event); + // Overridden from AnimationDelegate: + virtual void AnimationProgressed(const Animation* animation); + virtual void AnimationCanceled(const Animation* animation); + virtual void AnimationEnded(const Animation* animation); + // Starts/Stops the crash animation. void StartCrashAnimation(); void StopCrashAnimation(); @@ -119,6 +126,7 @@ class TabRenderer : public ChromeViews::View, void ResetCrashedFavIcon(); // Paint various portions of the Tab + void PaintTabBackground(ChromeCanvas* canvas); void PaintInactiveTabBackground(ChromeCanvas* canvas); void PaintActiveTabBackground(ChromeCanvas* canvas); void PaintHoverTabBackground(ChromeCanvas* canvas, double opacity); @@ -151,6 +159,9 @@ class TabRenderer : public ChromeViews::View, // Hover animation. scoped_ptr<SlideAnimation> hover_animation_; + // Pulse animation. + scoped_ptr<ThrobAnimation> pulse_animation_; + // Model data. We store this here so that we don't need to ask the underlying // model, which is tricky since instances of this object can outlive the // corresponding objects in the underlying model. diff --git a/chrome/browser/tabs/tab_strip.cc b/chrome/browser/tabs/tab_strip.cc index 327c3e5..04b33b3 100644 --- a/chrome/browser/tabs/tab_strip.cc +++ b/chrome/browser/tabs/tab_strip.cc @@ -890,6 +890,52 @@ void TabStrip::ExecuteCommandForTab( model_->ExecuteContextMenuCommand(index, command_id); } +void TabStrip::StartHighlightTabsForCommand( + TabStripModel::ContextMenuCommand command_id, Tab* tab) { + if (command_id == TabStripModel::CommandCloseTabsOpenedBy) { + int index = GetIndexOfTab(tab); + if (index != -1) { + std::vector<int> indices = model_->GetIndexesOpenedBy(index); + std::vector<int>::const_iterator iter = indices.begin(); + for (; iter != indices.end(); ++iter) { + int current_index = *iter; + DCHECK(current_index >= 0 && current_index < GetTabCount()); + Tab* current_tab = GetTabAt(current_index); + current_tab->StartPulse(); + } + } + } else if (command_id == TabStripModel::CommandCloseTabsToRight) { + int index = GetIndexOfTab(tab); + if (index != -1) { + for (int i = index + 1; i < GetTabCount(); ++i) { + Tab* current_tab = GetTabAt(i); + current_tab->StartPulse(); + } + } + } else if (command_id == TabStripModel::CommandCloseOtherTabs) { + for (int i = 0; i < GetTabCount(); ++i) { + Tab* current_tab = GetTabAt(i); + if (current_tab != tab) + current_tab->StartPulse(); + } + } +} + +void TabStrip::StopHighlightTabsForCommand( + TabStripModel::ContextMenuCommand command_id, Tab* tab) { + if (command_id == TabStripModel::CommandCloseTabsOpenedBy || + command_id == TabStripModel::CommandCloseTabsToRight || + command_id == TabStripModel::CommandCloseOtherTabs) { + // Just tell all Tabs to stop pulsing - it's safe. + StopAllHighlighting(); + } +} + +void TabStrip::StopAllHighlighting() { + for (int i = 0; i < GetTabCount(); ++i) + GetTabAt(i)->StopPulse(); +} + void TabStrip::MaybeStartDrag(Tab* tab, const ChromeViews::MouseEvent& event) { // Don't accidentally start any drag operations during animations if the // mouse is down... during an animation tabs are being resized automatically, diff --git a/chrome/browser/tabs/tab_strip.h b/chrome/browser/tabs/tab_strip.h index ec1e555..ce8b95c 100644 --- a/chrome/browser/tabs/tab_strip.h +++ b/chrome/browser/tabs/tab_strip.h @@ -162,6 +162,11 @@ class TabStrip : public ChromeViews::View, TabStripModel::ContextMenuCommand command_id, const Tab* tab) const; virtual void ExecuteCommandForTab( TabStripModel::ContextMenuCommand command_id, Tab* tab); + virtual void StartHighlightTabsForCommand( + TabStripModel::ContextMenuCommand command_id, Tab* tab); + virtual void StopHighlightTabsForCommand( + TabStripModel::ContextMenuCommand command_id, Tab* tab); + virtual void StopAllHighlighting(); virtual void MaybeStartDrag(Tab* tab, const ChromeViews::MouseEvent& event); virtual void ContinueDrag(const ChromeViews::MouseEvent& event); diff --git a/chrome/browser/tabs/tab_strip_model.cc b/chrome/browser/tabs/tab_strip_model.cc index 3b632fe..c71c089d 100644 --- a/chrome/browser/tabs/tab_strip_model.cc +++ b/chrome/browser/tabs/tab_strip_model.cc @@ -519,6 +519,16 @@ void TabStripModel::ExecuteContextMenuCommand( } } +std::vector<int> TabStripModel::GetIndexesOpenedBy(int index) const { + std::vector<int> indices; + NavigationController* opener = GetTabContentsAt(index)->controller(); + for (int i = count() - 1; i >= 0; --i) { + if (OpenerMatches(contents_data_.at(i), opener, true)) + indices.push_back(i); + } + return indices; +} + /////////////////////////////////////////////////////////////////////////////// // TabStripModel, NotificationObserver implementation: diff --git a/chrome/browser/tabs/tab_strip_model.h b/chrome/browser/tabs/tab_strip_model.h index c8e48f6..ab784d2 100644 --- a/chrome/browser/tabs/tab_strip_model.h +++ b/chrome/browser/tabs/tab_strip_model.h @@ -415,6 +415,10 @@ class TabStripModel : public NotificationObserver { void ExecuteContextMenuCommand(int context_index, ContextMenuCommand command_id); + // Returns a vector of indices of TabContentses opened from the TabContents + // at the specified |index|. + std::vector<int> GetIndexesOpenedBy(int index) const; + // Overridden from notificationObserver: virtual void Observe(NotificationType type, const NotificationSource& source, diff --git a/chrome/views/chrome_menu.cc b/chrome/views/chrome_menu.cc index 72fdf1b..271c19b 100644 --- a/chrome/views/chrome_menu.cc +++ b/chrome/views/chrome_menu.cc @@ -1633,6 +1633,9 @@ void MenuController::SetSelection(MenuItemView* menu_item, for (size_t i = paths_differ_at; i < new_size; ++i) new_path[i]->SetSelected(true); + if (menu_item && menu_item->GetDelegate()) + menu_item->GetDelegate()->SelectionChanged(menu_item); + pending_state_.item = menu_item; pending_state_.submenu_open = open_submenu; diff --git a/chrome/views/chrome_menu.h b/chrome/views/chrome_menu.h index 7a1d15b..0c478aa 100644 --- a/chrome/views/chrome_menu.h +++ b/chrome/views/chrome_menu.h @@ -198,6 +198,10 @@ class MenuDelegate : Controller { // menu for a drop. virtual void DropMenuClosed(MenuItemView* menu) { } + + // Notification that the user has highlighted the specified item. + virtual void SelectionChanged(MenuItemView* menu) { + } }; // MenuItemView -------------------------------------------------------------- |