Modal dialog box from C++

Hello, I would like to be able to call up a modal dialog box to get user input (enter a number, click ok), then continue working with that number within the same block of C++.

I can’t seem to find any reference to a modal feature in-built in UMG. In C# forms it would be something like frm.ShowDialog(); which opens ‘frm’ and once the modal form is closed, will continue with the next line of code. I understand with a managed language like C# much of the messy work is taken care of, but how would i achieve this with C++, unreal and UMG Widgets?

Currently I have a BlueprintNativeEvent which I call from C++. In Blueprints I “Add To Viewport” the widget, and that’s all fine. The widget shows up with my question, an editable TextBlock for input and the OK button. The problem is my c++ code block will then continue without waiting for user input.

I could use a loop and flag to wait for input before exiting my BlueprintNativeEvent but that’s messy. I’m not sure how to solve this problem with an event based solution.

Thanks for any help.

1 Like

BTW I don’t need a full detailed explanation as I realize there may be a lot to this But some hints to send me in the right direction would be very helpful. Thx.

First of all UMG is just a wrapper for Slate… and even Slate does not have such feature at its core, as it does not come with predefined window control system… or rether it does not enforce that on you. But there is 2 features in engine that can fulfill this functionality but they may not satisfy you:

First one is editor implementation of message box… problem is this is editor only :stuck_out_tongue: But if you do any editor extension it is worth to know it and you should use this in that case, it is global functions, there also non blocking version:

2nd, UE4 have a wrapper to platform specific implementation of message box, only problem is those are once always block and some platforms may not support it (as they dont have it)

And as you said yourself, yes your own implementation is best way to go on game runtime. And you don’t need to block the thread, as you can always use delegates (in fact first editor message box implementation use those too):

Since FMessageDialog sits in Core module, you can also reuse enums declered in there EAppMsgType and EAppReturnType

If you want to create blueprints support for it, it little bit more tricky as blueprints does not really support delegate over pins… with exception of FTimerDelegate which you can reuse, but you can only binds functions without arguments to it. You can also use laten function:

wit enum exec pin output:

2 Likes

This is perfect , thanks for taking the time to put this together. I have lots to work with here. I’ll mark this as solved, and can post back later what I ended up doing. Thanks.

Look for the OnTextCommitted event for you text input widget. You can add an Event handler node to the UMG blueprint and it will call that event when the user hits Enter or moves focus away from the text entry (it comes with an Enum parameter to determine what kind of text commit it was).

Ok I really thought i could get somewhere with this but I’m stuck.

I think what I’m trying to do is straightforward, but maybe it’s not clear how I explained it before, so I’ll try here. I need to do something like this… First line gets user input, immediately after, the code continues and deals with the user input.

int32 UserInput = GetUserInput("Enter a number");  
UE_LOG(LogTemp, Warning, TEXT("You entered: %s"), *UserInput);  

In the case above the function GetUserInput would need to display the UMG Widget, wait for the user to enter the number and click ok, then the function returns the value entered. I can’t see how to achieve this using delegates. At some point the program has to wait for user input otherwise it will bump over the next line UE_LOG with a zero value for UserInput. The only way I can see to do this is to cause a delay function, polling some return value property to be set when the player hits ok.

You obviously can’t do that without locking the thread in C++. Even if you use bind delegate, thread magicly won’t wait for user reaction… so just do nothing after dialog popup. There no way around it.

Insted, give it delegate as function argument that will pass it to widget (you can use BlueprintAssignable to make delegate work as event dispacher) and execute it when user finishes input and pass the result via delegate arguments. Binded function will executed processing the result

Again, learn how to make delegates first, once you do that it will became obviues

I believe I understand how delegates operate (similar to Blueprints dispatcher), but isn’t the binded function that processes the result going to be a different function than where the call to “GetUserInput” was made. So the UE_LOG in my code above still won’t have a value to work from unless I move it into a different function which then responds to the user input.

So if I have a function which might need to ask a few different questions of the user, and respond differently based on the answers, I would have to break that up into several functions? (Ie, some functions are asking questions, others are responding to the player input.)

But to be clear then, there is nothing I can do in C++/Unreal to allow me to ask for player input and get the response back within the same c++ function? If that’s a for-sure, then I’ll work around it.

Not direcly, atleast in current C++ standard. You need to remember there no such things as “UE4 C++” which community created myth of it and make people think it is something special, but what you working in UE4 is normal C++ just with extra tools that generate extra code and some API syntax tricks, but it is 100% valid C++ code and any compiler should able to process it as long as it can be configure to do so (for example can be made to work with any library).

C and C++ is converted directly to CPU machine code and as far as i know x86 CPUs does not support out of order returns. CPU don’t keep track of that, it only support normal call stack, when call is done the function address is prenamently removed from stack. C# can do that because is managed and can track those things in runtime code an can do things beyond what CPU support, while C and C++ is raw, at it made to not need runtime (no body force you use standard libraries and those libraries are coded in C or C++ it self too) and bound to what CPU it self can do… at least on syntax level itself.

But there things that may help you out:

-First of all is fact you can bind same function, only problem is it will reexecute function code and you will need to do some pays arguments to avoid that.

-2nd which probably will be moee suitable for what you want, C++ actully supports lambdas which got introduce in C++11 allowing to make nested functions, similar way you can do in JavaScript, commonly used in JSNode which was made to feel async

https://en.cppreference.com/w/cpp/language/lambda

Lambda should work anywhere you can use function pointers, but delegates have special stresful function to bind those too

https://api.unrealengine.com/INT/API/Runtime/Core/Delegates/TBaseDelegate/CreateLambda/index.html

Ok thanks, knowing it’s a “hard no” is great, so I can stop trying to do the impossible. I appreciate you taking the time to answer.

My plan moving forward is to create a FIFO message queue that includes details of the dialog message to be displayed, and includes a lambda expression to handle what happens with the user input. I think this will work.