CallOutBox标注窗详解

通常将本类对象组合到自定义类中使用,并且是临时使用。CallOutBox类的对象一旦容纳A组件并设置它所依附的B组件之后,将使A组件成为一个带有小箭头的无标题栏窗口,但是此时并不显示在屏幕上。只有当用户点击B组件时,标注类对象才自动弹出。A组件可以包含任何控件和绘制内容,而B组件通常需要自定义一个组件类,在该类的clicked()函数中临时定义并模态显示标注对象。

Jules在其传奇软件Tracktion的操作主界面中,大量使用了这个类的对象(激活“帮助”后,鼠标点击不同的界面元素或控件,将弹出标注窗,窗口里的文本块给出该元素或控件的详细解释)。

/* 带有标注功能的文本按钮,点击此按钮后弹出标注窗口。此窗口容纳了一个颜色选择器,可实时改变本类(按钮)的背景和文本颜色 */
class ColourChangeButton  : public TextButton,  
                            public ChangeListener 
{
public:
    ColourChangeButton() : TextButton (L"点击后择色...") { }
    ~ColourChangeButton()  { }

    void clicked() 
    {
        // 创建并设置标注所容纳的组件,本例为一个颜色选择器
        ColourSelector selector;
        selector.setName ("background");
        selector.setCurrentColour (findColour (TextButton::buttonColourId));
        selector.addChangeListener (this);
        selector.setColour (ColourSelector::backgroundColourId, 
			    Colour (0xffededed));
        selector.setSize (300, 400);

        /* 创建标注对象,栈对象即可。1参为标注所容纳的组件,即刚刚定义和设置的颜色选择器,2参为标注所指的组件,3参为标注所位于的组件,nullptr则作为桌面窗口 */
        CallOutBox callOut (selector, *this, nullptr);

        // 模态运行标注窗口
        callOut.runModalLoop();
    }

    /* 实现可变捕获器类的纯虚函数,参数对象发生变化时,自动调用本函数. 参数对象无需显式绑定捕获器,其本身即可产生可变消息。而本函数则自动捕获所产生的可变消息 */
    void changeListenerCallback (ChangeBroadcaster* source) 
    {
        // 定义一个颜色选择器指针变量,参数对象强转后赋值
        ColourSelector* cs = dynamic_cast <ColourSelector*> (source);

        setColour (TextButton::textColourOffId, 
		   cs->getCurrentColour().contrasting (0.8f));

        setColour (TextButton::buttonColourId, cs->getCurrentColour());
    }
};

内容组件类中,创添显设删ColourChangeButton类的对象,使用流程与其他普通控件完全一致。