Imgui: ImGUI Concept

Created on 15 Apr 2019  路  8Comments  路  Source: ocornut/imgui

Dear ImGui:

Version: 1.69
Branch: master_

Compiler: Visual Studio 2015, C++
Operating System: Windows 10

My question is related to GUI design when using Dear ImGUI.

I am new to C++ (writing in C++ code for only several months). My past experience with coding: C# and wpf and very high level languages like matlab, python and Labview .
I probably missed the concept of dear ImGUI and sorry in advanced if it is already was explained and I missed it.

I currently writing a project in C++ and found ImGUI to be very good GUI solution for me. However, I found myself with GUI state machine that has lots of lock guard logic which made me think that it is probably not the way that dear ImGUI was planned to be used.

Therefore I am asking if someone can give guide lines how he think it is recommended to use dear ImGUI from SW design point of view.

Kind Regards,
Amir

question

All 8 comments

Hello Amir,

The question asked may be a little too wide.
If you want to learn about the IMGUI paradigm, the Readme has links to articles and video discussing the fundamental idea.

However from your later paragraph it looks like you are more interested in learning about idioms and tricks which may allow to simplify and improve your UI code. Those tricks are intimately related to your usage of the language, your general application design and the library implementation. My suggestion would be that you post snippets of your own ImGui-using code and request specific feedback from there.

Regards,
Omar

Omar, thanks for your response.

Bellow there is a snip of my code.

The snip code is part of cameraGUI class which should hold the GUI which is related to the camera. The idea is to make the GUI separated from the camera class (which wrap the camera device API).
Also there is a machine state object which is used to hold and transfer information between the modules.

in the connectButton example it should write true or false to update it state.
in the SettingSensorOption it should get data from the machine state and also update it.
The GUI update the machine state object and other SW components triggered according to it.

My concern related to reading and writing to same object might pop exceptions. In order to prevent it a lock guard mechanism is applied to the state machine object.
In C# and WPF I used binding and register to GUI events. C++ is different and I am not sure how it is recommended to transfer the dear ImGUI state to the other SW modules.
It feels to me that the current concept which I use is wrong.

Hope that now my question is more clear.

Thanks!

my code:

class CameraGui
{
...
}

void CameraGui::ConnectButton()
{
if (ImGui::Button("Connect"))
{
machineState->cameraState->IsConnect = true;
}
}
void CameraGui::SettingSensorOption()
{
const char* SliderName = machineState->cameraState->selectedOption;
ImGui::PushItemWidth(150);
if (ImGui::SliderFloat(SliderName, &machineState->cameraState->sliderVal.Val, machineState->cameraState->sliderVal.min, machineState->cameraState->sliderVal.max))
{
machineState->cameraState->selectedOptionValChanged = true;
}
ImGui::PopItemWidth();
}
...

The core philosophy being IMGUI is to avoid state duplication, aka the UI code should ideally update your real data, not some intermediate data that will then need to be synced with the real data.. Otherwise you are losing many of the advantage of the system.

If you have a function ConnectButton solely devoted to showing 1 button you already have more overhead (which you created) than useful code. Why not calling ImGui::Button directly?

It is unclear what selectedOptionValChanged = true is for, whatever code polls that value could be in the same spot?

As a minor stylistic thing to make your code shorter, you should probably cache machineState->cameraState in a variable.

The core philosophy being IMGUI is to avoid state duplication, aka the UI code should ideally update your real data, not some intermediate data that will then need to be synced with the real data.. Otherwise you are losing many of the advantage of the system.

Maybe I should think about it differently. Till now I tried to write GUI which update state object and is not seeing any of the other modules. However all modules needed to monitor the state. Maybe I should abandon this concept and mix the ImGUI directly near the object. Which eliminate the need for state objects. Thanks!

Why not calling ImGui::Button directly?

It should contain styling and other thing which did not implemented yet. also after connect is called this button will not be render any more till 'disconnect' will be called so I don't want to render it unless it is needed. And it is a Little bit more easy to read the code. Indeed it can be as part of the entire code without a function.

It is unclear what selectedOptionValChanged = true is for, whatever code polls that value could be in the same spot?

In the current concept it cannot be at the same spot.

As a minor stylistic thing to make your code shorter, you should probably cache machineState->cameraState in a variable.

I agree :).

Omar, thanks for your support!

the GUI totally separated from the apps and algorithms. Using a struct to monitor the app state works well, however, a better way for my app is to use callbacks which eliminated the need for _machineState_.

Currently using _std::function_ and _std::bind_ do the job and a lot easy to read and develop my app.

originally:

void CameraGui::ConnectButton()
{
if (ImGui::Button("Connect"))
{
machineState->cameraState->IsConnect = true;
}
}

instead to do something like:

if (ImGui::Button("Connect"))
{
obj.callback(event&)
}

You are still making it way more complicated than it could be tho...

I guess the most easy way is to include the relevant object (or reference) and do the following:

if (ImGui::Button("Connect"))
{
obj->connect();
}

Similarly to other cases ImGUI items. BTW this is how the app was written and indeed nothing else is required. only in specific situations when actual data transfer between objects, thread or other cases it require callbacks or similar.

However, in case that there is a constrain to have total separation between GUI and app logic / algorithms - how would you recommend a simplify implementation, I would love to use simple design?

10x!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

BlackWatersInc picture BlackWatersInc  路  3Comments

SlNPacifist picture SlNPacifist  路  3Comments

DarkLinux picture DarkLinux  路  3Comments

noche-x picture noche-x  路  3Comments

namuda picture namuda  路  3Comments