1

I have a popup system (GUI) that does this:

// creates popup with two possible answer-buttons
if (timeToEat())
  callPopup(ID_4, "What to eat?", "Cake", "Cookies!"); 

//elsewhere in code i check for key presses
if (popupAnswered(ID_4,0)) // clicked first button in popup
  eatCake();

if (popupAnswered(ID_4,1)) // clicked second button in popup
  eatCookiesDamnit();

Could I use some kind of lambda/callback to arrange it like below. So that the function "remains" and can be activated when the button in is was pressed (a value was returned).

Thanks!

if (timeToEat())
   callPopup("What to eat?", "Cake", "Cookies!"){
       <return was 0 :>  eatCake(); break;
       <return was 1 :>  eatCookies(); break;
}
HerrErik
  • 241
  • 3
  • 10
  • Can you elaborate on the `elsewhere in code`? Sound like you want to program with continuations. Such as described [here for `boost::future`](https://stackoverflow.com/questions/22597948/using-boostfuture-with-then-continuations). – StoryTeller - Unslander Monica Dec 20 '17 at 08:16
  • This is quite specific to the GUI framework you use - e. g. with QT, you could connect the buttons' signals to appropriate slots programmed by you, with wxWidgets, you still might handle the button presses directly, registering the appropriate command event and gettnig the pressed button's id from, ... – Aconcagua Dec 20 '17 at 08:53
  • I made my own gui framework using native c++. Or often c actually:) So i'm looking for a general solution using c++. – HerrErik Dec 20 '17 at 10:05

2 Answers2

1

You can add a continuation parameter to callPopup:

void callPopup(int id, std::function<void(int)> f)
{
    if (something)
        f(0);
    else
        f(1);
}

// ...

callPopup(ID_4, [](int x) { if (x == 0) eatCake(); });

or you can add another function layer and use a return value:

std::function<void(std::function<void(int)>)> 
callPopup(int id)
{
        return [](std::function<void(int)> f) { f(something ? 0 : 1); }
}

// ...
callPopup(ID_4)([](int x) { if (x == 0) ... ;});
// or
void popupHandler(int);
auto popupResult = callPopup(ID_4);
// ...
popupResult(popupHandler);
molbdnilo
  • 64,751
  • 3
  • 43
  • 82
0

You can associate choices with actions, and then execute the action associated with the clicked

using PopupActions = std::map<std::string, std::function<void()>>;

void callPopup(int id, std::string prompt, PopupActions actions)
{
    for (auto & pair : actions)
        // create button with text from pair.first and on-click from pair.second
    // show buttons
}

if (timeToEat())
   callPopup(ID_4, "What to eat?", { 
       { "Cake!", [this]{ eatCake(); } }
       { "Cookies!", [this]{ eatCookies(); } }
   });
}
Caleth
  • 52,200
  • 2
  • 44
  • 75