How to emit event

Apr 16, 2013 at 5:07 PM
Edited Apr 16, 2013 at 5:07 PM
Hi Jinhao!
Tell me please is there any way to emit an event,for example emulate key press?

Thank you.
Apr 16, 2013 at 6:29 PM
I tried to change your example to nana :: gui :: place so that when you press the tab character when you type in one text field focus moves to another field without changes to the text.

Here's what I got http://pastebin.com/3XHTabkk
In this code, in the event handler I push in queue other event
which is processed faster than the first for some reason.

Could you please explain what am I doing wrong?
Sorry for bad English.

Thank you.
Coordinator
Apr 16, 2013 at 6:59 PM
Hi,
You can emite a key press by using nana::gui::API::raise_event(), for example:
using namespace nana::gui;

form fm;
fm.make_event<events::key_char>([](const eventinfo& ei)
{
    if(ei.keyboard.key == 'a')
    {
        
    }
});

fm.make_event<events::click>([&fm]()
{
    //Emulate an event of key_char.
    eventinfo ei;
    ei.keyboard.key = 'a';
    ei.keyboard.ignore = false;
    API::raise_event<events::key_char>(fm, ei);
});

fm.show();
exec();
But it is not a good way. I think invoking a method by emitting a special event is an error-prone and hard to maintain. A usual way is to define a method that can be invoked by others.
class myform
    : public form
{
public:
    myform()
    {
        this->make_event<events::click>(*this, &myform::a_method);
    }

    void a_method()
    {
        //Do something
    }
};

class other
{
public:
    void external_method(std::function<void()> method)  //Decouple
    {
        extr_method_ = method;
    }

    void business()
    {
        //Do something

        //Need an external method
        extr_method_();
    }
private:
    std::function<void()> extr_method_;
};

myform ui;

other oth;
oth.external_method(std::bind(&myform::a_method, &ui)); //Decouple
I hope this would be helpful.
Regards
Coordinator
Apr 16, 2013 at 7:10 PM
Edited Apr 16, 2013 at 7:36 PM
It's my mistake. There is no need to correct the tab key. Please call API::eat_tabstop().
//Disable sending the tab key to the specified widget by the framework.
//The framework will move the focus to the next widget if current focused
//widget does not eat tabstop. 
API::eat_tabstop(usr, false);
API::eat_tabstop(pswd, false);
If you want to determine whether a charactor would be accepted by textbox, you can do it in key_char. For example, only alphabet would be accepted by the textbox.
textbox.make_event<events::key_char>([](const eventinfo& ei)
{
    auto key = ei.keyboard.key;
    ei.keyboard.ignore = !(('a' <= key && key <='z') || ('A' <= key && key <= 'Z'));
});
Apr 16, 2013 at 7:13 PM
Edited Apr 16, 2013 at 7:22 PM
Thank you,I understand.
Can I ask one more question :
In this code
usr.make_event<nana::gui::events::key_char>([&usr,&pswd](const nana::gui::eventinfo& info)
{
    if(info.keyboard.key == '\t')
    {
        nana::gui::eventinfo new_event;
            new_event.identifier = nana::gui::events::key_char::identifier;
        new_event.keyboard.key = nana::gui::keyboard::backspace;
                nana::gui::API::raise_event<nana::gui::events::key_char>(usr,new_event);
        nana::gui::API::focus_window(pswd);
             }
     });                                                              
can we be sure,that new_event will be handled after current event will?

Thank you.
Coordinator
Apr 16, 2013 at 7:28 PM
No, the answer function of event will be invoked by raise_event immediately, it is not queued. As you saw from previous code, the whitespace was inserted in the usr textbox before you set the focus to the pswd textbox.
Apr 16, 2013 at 7:33 PM
Edited Apr 16, 2013 at 7:34 PM
Yes,I thought maybe I just didn't understand something.
So I have not any access to the event queue,have I?
Coordinator
Apr 16, 2013 at 7:49 PM
No, you haven't.
Apr 16, 2013 at 7:52 PM
Edited Apr 16, 2013 at 7:52 PM
Thank you very much for your help,I'm really grateful.)