JUCE类库之PopupMenu 3-1

PopupMenu(弹出式菜单)是一个独立的类,没有继承自Component。其实质是弹出一个模态窗口(组件容器),该容器中的每个元素均为组件,即显示了一条文本信息的菜单项,该菜单项具有唯一的ID信息,则信息由添加此菜单项时所指定。鼠标点击某个菜单项,其实是点击了某个组件。点击后,窗口退出模态,消失不见,同时返回所点击的菜单项组件的ID,后续代码或其他函数根据此ID判断哪个菜单项被点选了,从而给出对应的代码,实现具体的功能。

普通的弹出式菜单

PopupMenu常用于鼠标右键菜单,或单击某个控件(按钮)后弹出下拉菜单等。通常,在内容组件类的mouseDown(),mouseUp()或buttonClicked()等函数中判断鼠标点击的按键并弹出菜单、判断处理 。流程有6:

  1. 判断鼠标是否点击了右键(仅右键弹出菜单的情况下才需判断)
  2. 临时创建PopupMenu栈对象
  3. 添加菜单项(命令项)、分隔线、子菜单和子菜单项(子菜单需额外创建PopupMenu对象)
  4. 添加菜单项时,ID不能小于1。可设置该项是否可用,是否已选(左侧出现一个对号)
  5. show()或showAt()显示菜单并返回用户点选的菜单ID
  6. 根据show()胡showAt()的返回值,执行该菜单项所对应的代码

示例代码:

// 右键单击弹出菜单,此处的代码位于内容组件类的mouseUp()函数中
if (e.mods.isPopupMenu())
{
    PopupMenu m; // 创建PopupMenu对象,添加菜单项和分隔线
    m.addItem (1, "Some menu item 1");
    m.addItem (2, "Some menu item 2", false);
    m.addSeparator();
    m.addItem (3, "Some menu item 3", isValid && !showMnem);
    m.addSeparator();

    // 添加自定义的菜单项。自定义菜单项的详情见后
    m.addCustomItem (4, new CustomMenuComponent());

    /* 添加命令项。1参为ApplicationCommandManager对象,2参为1参中具体的命令ID,即ApplicationCommandTarget类的getAllCommands()函数中所定义的命令ID */
    m.addCommandItem (commandManager, 1);

    // 二级子菜单
    PopupMenu tm;

    // 二级子菜单添加菜单项,分隔线等等..

    // 二级菜单添加到一级菜单...
    m.addSubMenu ("Sub menu item", tm);

    // 显示弹出式菜单并基于用户点选的菜单项ID执行对应的代码
    switch (m.show())
    {  //... }
}

上述步骤,定义弹出式菜单对象、添加菜单项和子菜单、显示并判断处理等操作全部集中到了一起。如果菜单项内容较多,情况比较复杂,这么做则显得臃肿凌乱,不够清晰优雅。更好的做法是将判断处理和菜单项的功能性代码单独拿出来,在另外的函数中进行处理。

此外,关于菜单项ID索引值,实际编程时,并不建议直接使用数字(魔数)。这也是C++编程的原则之一。较好的做法是类中声明并定义枚举类型,每个枚举常量都采用清晰直观的文本名称。其它需使用ID、索引值的控件,同理。