一:程序效果
菜单6为自定义菜单。
二:菜单程序
2.1 新建JUCE GUI空项目,添加模版 MainWindow.h , MainWindow.cpp 和 Main.cpp。
2.2 新建MenusDemo.h 和 MenusDemo.cpp文件。
MenusDemo.h:
/* ============================================================================== MenusDemo.h Created: 6 Feb 2017 3:21:45pm Author: magewell ==============================================================================*/#ifndef MENUSDEMO_H_INCLUDED#define MENUSDEMO_H_INCLUDED#include "../JuceLibraryCode/JuceHeader.h"enum CommandIDs{ //menu1 menuDemoOneOne = 0x2000, menuDemoOneTwo = 0x2001, menuDemoOneThree = 0x2002, //menu2 menuDemoTwoOne = 0x2003, menuDemoTwoTwo = 0x2004, menuDemoTwoThree = 0x2005, menuDemoTwoFour = 0x2006, //menu3 menuDemoThreeOne = 0x2007, menuDemoThreeTwo = 0x2008, menuDemoThreeThree = 0x2009, menuDemoThreeFour = 0x200a, //menu4 menuDemoFourOne = 0x200b, menuDemoFourTwo = 0x200c, menuDemoFourThree = 0x200d, //menu5 menuDemoFiveOne = 0x2100, menuDemoFiveTwo = 0x2101, menuDemoFiveThree = 0x2102};class MenusDemo : public Component, public MenuBarModel, public Button::Listener{public: MenusDemo(); ~MenusDemo(); //======================================override void resized() override; StringArray getMenuBarNames() override; PopupMenu getMenuForIndex(int menuIndex, const String& /*menuName*/) override; void menuItemSelected(int menuItemID, int /*topLevelMenuIndex*/) override; void buttonClicked(Button* button) override;PRotected: PopupMenu getDummyPopupMenu();private: TextButton popupButton; ScopedPointer<MenuBarComponent> menuBar; //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MenusDemo)};#endif // MENUSDEMO_H_INCLUDEDCommandIDs 为定义的菜单项ID,当菜单被点击时返回这个值。JUCE基于MVC架构设计,因此实现菜单需要继承 MenuBarModel 。
菜单类主要完成对以下几个功能的重写:
void resized() override; 对Component类的重写,大小改变时调用,一般在内部重绘子组件(例如本例的TextButton)。StringArray getMenuBarNames() override; 对MenuBarModel 类的重写,返回菜单名称。PopupMenu getMenuForIndex(int menuIndex, const String& /*menuName*/) override; 对 MenuBarModel类的重写,返回菜单子项。void menuItemSelected(int menuItemID, int /*topLevelMenuIndex*/) override; 对 MenuBarModel类的重写,菜单选择事件响应。 void buttonClicked(Button* button) override;对 Button::Listener类的重写,TextButton的点击事件响应。MenusDemo.cpp:
/* ============================================================================== MenusDemo.cpp Created: 6 Feb 2017 3:21:45pm Author: magewell ==============================================================================*/#include "MenusDemo.h"//Construct/DeConstructMenusDemo::MenusDemo(){ menuBar = new MenuBarComponent(this); addAndMakeVisible(menuBar); popupButton.setButtonText("Show Popup Menu"); popupButton.setTriggeredOnMouseDown(true); popupButton.addListener(this); addAndMakeVisible(popupButton);}MenusDemo::~MenusDemo(){ PopupMenu::dismissAllActiveMenus(); popupButton.removeListener(this);}//overridevoid MenusDemo::resized(){ Rectangle<int> area(getLocalBounds()); menuBar->setBounds(area.removeFromTop(LookAndFeel::getDefaultLookAndFeel().getDefaultMenuBarHeight())); area.removeFromTop(20); area = area.removeFromTop(33); popupButton.setBounds(area.removeFromLeft(200).reduced(5));}StringArray MenusDemo::getMenuBarNames(){ const char* const names[] = { "Menu1", "Menu2", "Menu3", "Menu4", "Menu5", "Menu6", nullptr }; return StringArray(names);}PopupMenu MenusDemo::getMenuForIndex(int menuIndex, const String& /*menuName*/){ PopupMenu menu; if (menuIndex == 0) { menu.addItem(menuDemoOneOne,"menuDemoOneOne"); menu.addItem(menuDemoOneTwo,"menuDemoOneTwo"); menu.addSeparator(); menu.addItem(menuDemoOneThree,"menuDemoOneThree"); } else if (menuIndex == 1) { menu.addItem(menuDemoTwoOne,"menuDemoTwoOne"); menu.addItem(menuDemoTwoTwo,"menuDemoTwoTwo"); menu.addItem(menuDemoTwoThree,"menuDemoTwoThree"); menu.addSeparator(); menu.addItem(menuDemoTwoFour,"menuDemoTwoFour"); } else if (menuIndex == 2) { menu.addItem(menuDemoThreeOne,"menuDemoThreeOne"); menu.addItem(menuDemoThreeTwo,"menuDemoThreeTwo"); menu.addItem(menuDemoThreeThree,"menuDemoThreeThree"); menu.addItem(menuDemoThreeFour,"menuDemoThreeFour"); } else if (menuIndex == 3) { menu.addItem(menuDemoFourOne,"menuDemoFourOne"); menu.addItem(menuDemoFourTwo,"menuDemoFourTwo"); menu.addItem(menuDemoFourThree,"menuDemoFourThree"); } else if (menuIndex == 4) { menu.addItem(menuDemoFiveOne,"menuDemoFiveOne"); menu.addItem(menuDemoFiveTwo,"menuDemoFiveTwo"); menu.addItem(menuDemoFiveThree,"menuDemoFiveThree"); } else if (menuIndex == 5) { return getDummyPopupMenu(); } return menu;}void MenusDemo::menuItemSelected(int menuItemID, int /*topLevelMenuIndex*/){ //every command enter this... printf("commands .../n");}void MenusDemo::buttonClicked(Button* button){ if (button == &popupButton) getDummyPopupMenu().showMenuAsync(PopupMenu::Options().withTargetComponent(&popupButton), nullptr);}//protectedPopupMenu MenusDemo::getDummyPopupMenu(){ PopupMenu m; m.addItem(1, "Normal item"); m.addItem(2, "Disabled item", false); m.addItem(3, "Ticked item", true, true); m.addColouredItem(4, "Coloured item", Colours::green); m.addSeparator(); for (int i = 0; i < 8; ++i) { PopupMenu subMenu; for (int s = 0; s < 8; ++s) { PopupMenu subSubMenu; for (int item = 0; item < 8; ++item) subSubMenu.addItem(1000 + (i * s * item), "Item " + String(item + 1)); subMenu.addSubMenu("Sub-sub menu " + String(s + 1), subSubMenu); } m.addSubMenu("Sub menu " + String(i + 1), subMenu); } return m;}当菜单被点击时进入 menuItemSelected 消息响应。三:将MenusDemo加入主Component:
class MainContentComponent : public Component{public: MainContentComponent() { menusDemo = new MenusDemo; addAndMakeVisible(menusDemo); } ~MainContentComponent() { menusDemo = nullptr; } //=================================================override void paint(Graphics &g) override { g.fillAll(Colour(0xff001F36)); //g.setFont(Font(16.0f)); //g.setColour(Colours::white); //g.drawText("Hello World!", getLocalBounds(), Justification::centred, true); } void resized() override { Rectangle<int> area(getLocalBounds()); menusDemo->setBounds(area); }private: ScopedPointer<MenusDemo> menusDemo; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MainContentComponent);};
新闻热点
疑难解答