Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site













SourceForge.net Logo

CallbackArgTarget

 

"value" return callback for local MenuBar

 

In previous example "reference\Callback" we saw basics of U++ callbacks. This article will explore some more features of callback mechanism.

First we will take a look on CallbackArgTarget template class. This is helper template class which is useful in situation when set of callbacks define some output value. Example is pop-up menu that provides selection of one character - in that case, CallbackArgTarget can be used instead of dedicated method to obtain result of user selection. Note that the type of the output value must be able to be assigned Null.

Lets look at the code of "reference\CallbackArgTarget" example:

 

#include <CtrlLib/CtrlLib.h>

 

GUI_APP_MAIN

{

    CallbackArgTarget<int> result;

    MenuBar menu;

    for(int i = 0; i < 10; i++)

        menu.Add(AsString(i), result[i]);

    menu.Execute();

    if(IsNull(result))

        PromptOK("Menu was cancelled");

    else

        PromptOK("You have selected " + AsString((int)result));

}

 

In first line we are making new object of type CallbackArgTarget and we tell U++ that output value of callbacks is int. Constructor of this class will assign Null to output value. Then we create menu and in for loop add ten menu items into it. result[i] will return callback that, when invoked, assigns i to the result output value.

Although we don't have main window with menu bar in this example, we can still show our menu like pop up window with Execute method - when program executes it will show pop up window on current position of mouse. If we don't select anything in pop up menu bar window than IsNull(result) will return True. Instead of using IsNull we could use IsNullInstance  template method wich will call IsNull(int). On the other hand if we select some menu item, appropriate callback will be executed and output value of result will get some number.

 

Another feature of U++ callbacks is that they can easily imitate proxy behavior. If we want to make callback which is in the same time proxy we can do that with a help of Proxy function like in next example

 

#include <Core/Core.h>

 

void Foo()

{

    LOG("Foo");

}

 

void Bar()

{

    LOG("Bar");

}

 

CONSOLE_APP_MAIN

{

    Callback a, b;

    a = Proxy(b);

    b = callback(Foo);

    a();

    b = callback(Bar);

    a();

}

 

We have two callbacks a and b, and in the next line Proxy(b) will return new callback which when executed will execute b callback. So when we assign to b callback to Foo and then execute a callback, a will behave like a proxy callback and will then execute b callback and b will then callback Foo function.

This example is also interesting because it uses some basics of U++ login capabilities. In Foo and Bar we can see how easy is to log program execution with a help of LOG() macro. When program executes on Linux, it will create log file in the home dir, or if you start it on Windows on the same path where executable of program is. When we execute this example U++ will create file named ".CallbackProxy.log" and it content will be like this

 

* CallbackProxy 22.11.2005 22:44:48, user: ivica

 

Foo

Bar

 

If log file with same name already exist, U++ will first rename existing log file (it will append ".old" extension) and then it will write new log.

 

U++ callbaks also have gates. There is nothing complicated about the "gate" - it is just callback that returns "bool" value. Note that perhaps a little more generalisation here would seem fine (like possibility to define returns values for callbacks) but so far, in 7 years, no more variants were really needed. Also, reducing the real number of callback variants is somewhat benefical in order to keep code ortoghonal.

 

main.cpp

 

#include <CtrlLib/CtrlLib.h>

 

using namespace Upp;

 

struct MyApp : TopWindow {

    virtual void RightDown(Point p, dword keyflags) {

        CallbackArgTarget<int> result;

        MenuBar menu;

        for(int i = 0; i < 10; i++)

            menu.Add(AsString(i), result[i]);

        menu.Execute();

        if(IsNull(result))

            PromptOK("Menu was cancelled");

        else

            PromptOK("You have selected " + AsString((int)result));

    }

};

 

GUI_APP_MAIN

{

    MyApp().Run();

}

 

 

 

 

Do you want to contribute?