15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/base/interactive_test_utils.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/ui_test_utils.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/view_event_test_base.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/models/menu_model.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ui/base/test/ui_controls.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/button/menu_button.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/button/menu_button_listener.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/menu/menu_controller.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/menu/menu_item_view.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/menu/menu_model_adapter.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/menu/menu_runner.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/menu/submenu_view.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/root_view.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kTopMenuBaseId = 100; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kSubMenuBaseId = 200; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Implement most of the ui::MenuModel pure virtual methods for subclasses 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Exceptions: 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// virtual int GetItemCount() const = 0; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// virtual ItemType GetTypeAt(int index) const = 0; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// virtual int GetCommandIdAt(int index) const = 0; 33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// virtual base::string16 GetLabelAt(int index) const = 0; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CommonMenuModel : public ui::MenuModel { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommonMenuModel() { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~CommonMenuModel() { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ui::MenuModel implementation. 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool HasIcons() const OVERRIDE { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool IsItemDynamicAt(int index) const OVERRIDE { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool GetAcceleratorAt(int index, 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::Accelerator* accelerator) const OVERRIDE { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ui::MenuSeparatorType GetSeparatorTypeAt(int index) const OVERRIDE { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ui::NORMAL_SEPARATOR; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool IsItemCheckedAt(int index) const OVERRIDE { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int GetGroupIdAt(int index) const OVERRIDE { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool GetIconAt(int index, gfx::Image* icon) OVERRIDE { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ui::ButtonMenuItemModel* GetButtonMenuItemAt( 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index) const OVERRIDE { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool IsEnabledAt(int index) const OVERRIDE { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ui::MenuModel* GetSubmenuModelAt(int index) const OVERRIDE { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void HighlightChangedTo(int index) OVERRIDE { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void ActivatedAt(int index) OVERRIDE { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetMenuModelDelegate(ui::MenuModelDelegate* delegate) OVERRIDE { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ui::MenuModelDelegate* GetMenuModelDelegate() const OVERRIDE { 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(CommonMenuModel); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SubMenuModel : public CommonMenuModel { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SubMenuModel() 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : showing_(false) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~SubMenuModel() { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool showing() const { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return showing_; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ui::MenuModel implementation. 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int GetItemCount() const OVERRIDE { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ItemType GetTypeAt(int index) const OVERRIDE { 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TYPE_COMMAND; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int GetCommandIdAt(int index) const OVERRIDE { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return index + kSubMenuBaseId; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual base::string16 GetLabelAt(int index) const OVERRIDE { 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return base::ASCIIToUTF16("Item"); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void MenuWillShow() OVERRIDE { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) showing_ = true; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called when the menu has been closed. 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void MenuClosed() OVERRIDE { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) showing_ = false; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool showing_; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SubMenuModel); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TopMenuModel : public CommonMenuModel { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TopMenuModel() { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~TopMenuModel() { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsSubmenuShowing() { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sub_menu_model_.showing(); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ui::MenuModel implementation. 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int GetItemCount() const OVERRIDE { 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ItemType GetTypeAt(int index) const OVERRIDE { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TYPE_SUBMENU; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int GetCommandIdAt(int index) const OVERRIDE { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return index + kTopMenuBaseId; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual base::string16 GetLabelAt(int index) const OVERRIDE { 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return base::ASCIIToUTF16("submenu"); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual MenuModel* GetSubmenuModelAt(int index) const OVERRIDE { 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &sub_menu_model_; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutable SubMenuModel sub_menu_model_; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TopMenuModel); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MenuModelAdapterTest : public ViewEventTestBase, 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public views::MenuButtonListener { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MenuModelAdapterTest() 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : ViewEventTestBase(), 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button_(NULL), 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) menu_model_adapter_(&top_menu_model_), 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) menu_(NULL) { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~MenuModelAdapterTest() { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ViewEventTestBase implementation. 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() OVERRIDE { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button_ = new views::MenuButton( 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL, base::ASCIIToUTF16("Menu Adapter Test"), this, true); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) menu_ = menu_model_adapter_.CreateMenu(); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) menu_runner_.reset(new views::MenuRunner(menu_)); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ViewEventTestBase::SetUp(); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void TearDown() OVERRIDE { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) menu_runner_.reset(NULL); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) menu_ = NULL; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ViewEventTestBase::TearDown(); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual views::View* CreateContentsView() OVERRIDE { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return button_; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual gfx::Size GetPreferredSize() const OVERRIDE { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return button_->GetPreferredSize(); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // views::MenuButtonListener implementation. 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnMenuButtonClicked(views::View* source, 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Point& point) OVERRIDE { 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Point screen_location; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View::ConvertPointToScreen(source, &screen_location); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect bounds(screen_location, source->size()); 2345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ignore_result(menu_runner_->RunMenuAt(source->GetWidget(), 2355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu button_, 2365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu bounds, 2375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu views::MENU_ANCHOR_TOPLEFT, 2385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ui::MENU_SOURCE_NONE, 2395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu views::MenuRunner::HAS_MNEMONICS)); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ViewEventTestBase implementation 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DoTestOnMessageLoop() OVERRIDE { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Click(button_, CreateEventTask(this, &MenuModelAdapterTest::Step1)); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Open the submenu. 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Step1() { 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::SubmenuView* topmenu = menu_->GetSubmenu(); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(topmenu); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(topmenu->IsShowing()); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(top_menu_model_.IsSubmenuShowing()); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Click the first item to open the submenu. 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::MenuItemView* item = topmenu->GetMenuItemAt(0); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(item); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Click(item, CreateEventTask(this, &MenuModelAdapterTest::Step2)); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Rebuild the menu which should close the submenu. 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Step2() { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::SubmenuView* topmenu = menu_->GetSubmenu(); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(topmenu); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(topmenu->IsShowing()); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(top_menu_model_.IsSubmenuShowing()); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) menu_model_adapter_.BuildMenu(menu_); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 269b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoopForUI::current()->PostTask( 270b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) FROM_HERE, CreateEventTask(this, &MenuModelAdapterTest::Step3)); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that the submenu MenuModel received the close callback 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and close the menu. 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Step3() { 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::SubmenuView* topmenu = menu_->GetSubmenu(); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(topmenu); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(topmenu->IsShowing()); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(top_menu_model_.IsSubmenuShowing()); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Click the button to exit the menu. 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Click(button_, CreateEventTask(this, &MenuModelAdapterTest::Step4)); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // All done. 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Step4() { 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::SubmenuView* topmenu = menu_->GetSubmenu(); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(topmenu); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(topmenu->IsShowing()); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(top_menu_model_.IsSubmenuShowing()); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate a mouse click on the specified view and post a new task. 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Click(views::View* view, const base::Closure& next) { 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_test_utils::MoveMouseToCenterAndPress( 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view, 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_controls::LEFT, 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_controls::DOWN | ui_controls::UP, 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::MenuButton* button_; 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TopMenuModel top_menu_model_; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::MenuModelAdapter menu_model_adapter_; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::MenuItemView* menu_; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<views::MenuRunner> menu_runner_; 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)VIEW_TEST(MenuModelAdapterTest, RebuildMenu) 313