JUCE中的消息送和listener

    //==============================================================================
    /**
        Used to receive callbacks when a button is clicked.

        @see Button::addListener, Button::removeListener
    */
    class JUCE_API  Listener
    {
    public:
        /** Destructor. */
        virtual ~Listener()  {}

        /** Called when the button is clicked. */
        virtual void buttonClicked (Button*) = 0;

        /** Called when the button's state changes. */
        virtual void buttonStateChanged (Button*)  {}
    };

上边是button类中定义的listener.

listener由发送消息者去定义,同时维护了一个listener的表,当事件发生的时候,先把消息发送到控件本身进行处理,处理完后,循环调用listoner进行消息处理,呵呵,一直不明白java的那个listener,没想到在这里明白了,真扯啊

enum { clickMessageId = 0x2f3f4f99 };

void Button::triggerClick()
{
    postCommandMessage (clickMessageId);
}

发送自定义消息

void Component::postCommandMessage (const int commandId)
{
    class CustomCommandMessage   : public CallbackMessage
    {
    public:
        CustomCommandMessage (Component* const c, const int command)
            : target (c), commandId (command) {}


        void messageCallback() override
        {
            if (target.get() != nullptr)  // (get() required for VS2003 bug)
                target->handleCommandMessage (commandId);
        }


    private:
        WeakReference<Component> target;
        int commandId;
    };


    (new CustomCommandMessage (this, commandId))->post();
}


当收到消息以后button先自己处理此消息,调用如下函数

void Component::postCommandMessage (const int commandId)
{
    class CustomCommandMessage   : public CallbackMessage
    {
    public:
        CustomCommandMessage (Component* const c, const int command)
            : target (c), commandId (command) {}


        void messageCallback() override
        {
            if (target.get() != nullptr)  // (get() required for VS2003 bug)
                target->handleCommandMessage (commandId);
        }


    private:
        WeakReference<Component> target;
        int commandId;
    };


    (new CustomCommandMessage (this, commandId))->post();
}


接着调用handleCommandMessage,这里更新了button的状态

//重写了这个消息

void Button::handleCommandMessage (int commandId)
{
    if (commandId == clickMessageId)
    {
        if (isEnabled())
        {
            flashButtonState();
            internalClickCallback (ModifierKeys::getCurrentModifiers());
        }
    }
    else
    {
        Component::handleCommandMessage (commandId);
    }
}


但是到这个地方还没有listener任何事情,接着往下看

void Button::internalClickCallback (const ModifierKeys& modifiers)
{
    if (clickTogglesState)
    {
        const bool shouldBeOn = (radioGroupId != 0 || ! lastToggleState);


        if (shouldBeOn != getToggleState())
        {
            setToggleState (shouldBeOn, sendNotification);
            return;
        }
    }


    sendClickMessage (modifiers);
}


最后又调用了sendClickMessage

void Button::sendClickMessage (const ModifierKeys& modifiers)
{
    Component::BailOutChecker checker (this);


    if (commandManagerToUse != nullptr && commandID != 0)
    {
        ApplicationCommandTarget::InvocationInfo info (commandID);
        info.invocationMethod = ApplicationCommandTarget::InvocationInfo::fromButton;
        info.originatingComponent = this;


        commandManagerToUse->invoke (info, true);
    }


    clicked (modifiers);


    if (! checker.shouldBailOut())
        buttonListeners.callChecked (checker, &ButtonListener::buttonClicked, this);  // (can't use Button::Listener due to idiotic VC2005 bug)
}


到这里,listener终于闪登场

    /** Calls a member function on each listener in the list, with no parameters and a bail-out-checker.
        See the class description for info about writing a bail-out checker. */
    template <class BailOutCheckerType>
    void callChecked (const BailOutCheckerType& bailOutChecker,
                      void (ListenerClass::*callbackFunction) ())
    {
        for (Iterator<BailOutCheckerType, ThisType> iter (*this); iter.next (bailOutChecker);)
            (iter.getListener()->*callbackFunction) ();
    }


此处,循环调用就不说了。 这里作个说明BailOutChecker的作用是防止消息处理过程中把button给删除了,后边的callback又使用到button这种情况,其实就是做个检查,这个在其它界面库中也遇到过这种情况。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值