# C++ ImGui questions

## Recommended Posts

I am playing around with ImGui, adding a UI to my level editor, but i am having trouble with mouse clicks in ImGui triggers a click in my actual editor (Because it uses the same input states).

Right know i have just a main menu bar and the editor rendering is behind that. When i click on a menuitem for example, and select another sub item and click, i place a block in my editor - just because the input events are the same for both ImGui and my editor.

So i have a few questions:

1.) Is there a way to detect when ImGui has taken any action/hover in the previous frame, so i can skip the input handling for my editor? (This way i can prevent the issue i have right now)

2.) Can i add a imgui window which fully fits the rest of the entire screen - after a main bar has been added? (Do i manually need to calculate the size?)

3.) Should i make the entire editor with ImGUI only - so i wont get any input fuzziness problems?

##### Share on other sites

1) When calling ImGui::NewFrame() it is updating the io.WantCaptureMouse and io.WantCaptureKeyboard fields. You can use those fields to hide the inputs from your own application/editor. The most obvious case is that io.WantCaptureMouse will be true when hovering an ImGui window (in reality the logic is a little more complex than that, it tracks clicks/drags and active widgets).

This is answered in the FAQ under "Q: How can I tell when Dear ImGui wants my mouse/keyboard inputs VS when I can pass them to my application?"

2) You can use ImGui::SetNextWindowPos, ImGui::SetNextWindowSize(). You do need to manually calculate the size but you can also create one fullscreen window (position = 0,0, size = io.DisplaySize) with a MenuBar, it's equivalent to creating a main menu bar.

3) I don't know what "input fuzziness" means. It should be fine to create an entire editor, many people have been doing that. One limitation of imgui with it handles inputs events is that if you expect to run at very low frame rates (e.g. 10 FPS) you will want to create a queue events and defer passing all of them to imgui at once (e.g. if you received 2 clicks in one frame). This should be handled by the library but eventually but it's not at the moment. If you don't expect to be running at super low framerate it won't be a problem.

##### Share on other sites
8 hours ago, ocornut said:

1) When calling ImGui::NewFrame() it is updating the io.WantCaptureMouse and io.WantCaptureKeyboard fields. You can use those fields to hide the inputs from your own application/editor. The most obvious case is that io.WantCaptureMouse will be true when hovering an ImGui window (in reality the logic is a little more complex than that, it tracks clicks/drags and active widgets).

This is answered in the FAQ under "Q: How can I tell when Dear ImGui wants my mouse/keyboard inputs VS when I can pass them to my application?"

2) You can use ImGui::SetNextWindowPos, ImGui::SetNextWindowSize(). You do need to manually calculate the size but you can also create one fullscreen window (position = 0,0, size = io.DisplaySize) with a MenuBar, it's equivalent to creating a main menu bar.

3) I don't know what "input fuzziness" means. It should be fine to create an entire editor, many people have been doing that. One limitation of imgui with it handles inputs events is that if you expect to run at very low frame rates (e.g. 10 FPS) you will want to create a queue events and defer passing all of them to imgui at once (e.g. if you received 2 clicks in one frame). This should be handled by the library but eventually but it's not at the moment. If you don't expect to be running at super low framerate it won't be a problem.

Thanks, that clears it up.

Now i have another one, which is also about preventing click events to happen after a imgui menuitem has been clicked.

I have built a simple level editor with imgui and its set a tile in the corner always when i load a level from the main menu - just because the click of the MenuItem is still true. Can i consume that click somehow?

		void Game::EditorUpdate() {
auto io = ImGui::GetIO();
auto ctx = ImGui::GetCurrentContext();
auto editorWindowSize = ImVec2(io.DisplaySize.x, io.DisplaySize.y);

ImGui::SetNextWindowSize(editorWindowSize, ImGuiSetCond_Always);
ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiSetCond_FirstUseEver);
const char *mapName = activeEditorFilePath.empty() ? "Unnamed map" : activeEditorFilePath.c_str();

ImGui::Begin(mapName, nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_MenuBar);

ClearLevel();
activeEditorFilePath = "";
}
showOpenDialog = true;
firstTimeOpenDialog = true;
}
showSaveDialog = activeEditorFilePath.empty();
if (!showSaveDialog)
SaveMap(activeEditorFilePath.c_str());
else
firstTimeSaveDialog = true;
}
showSaveDialog = firstTimeSaveDialog = true;
}
exitRequested = true;
}
}
}

// Canvas area
auto maxRegion = ImGui::GetWindowContentRegionMax();
auto minRegion = ImGui::GetWindowContentRegionMin();
auto regionSize = ImVec2(maxRegion.x - minRegion.x, maxRegion.y - minRegion.y);
const ImVec2 startCursorPos = ImGui::GetCursorScreenPos();

RenderArea canvasArea = {};
UpdateRenderArea(canvasArea, regionSize.x, regionSize.y, HalfGameWidth, HalfGameHeight, GameAspect);
const f32 canvasTileSize = TileSize * canvasArea.scale;

ImDrawList* draw_list = ImGui::GetWindowDrawList();

const ImVec2 canvasViewportStart = ImVec2(startCursorPos.x + canvasArea.viewportOffset.x, startCursorPos.y + canvasArea.viewportOffset.y);
const ImVec2 canvasViewportEnd = ImVec2(canvasViewportStart.x + canvasArea.viewportSize.w, canvasViewportStart.y + canvasArea.viewportSize.h);

// Draw tiles
for (u32 y = 0; y < TileCountForHeight; ++y) {
u32 tileY = (TileCountForHeight - 1 - y);
for (u32 x = 0; x < TileCountForWidth; ++x) {
const Tile &tile = tiles[tileY * TileCountForWidth + x];
if (tile.isSolid) {
f32 tx = canvasViewportStart.x + x * canvasTileSize;
f32 ty = canvasViewportStart.y + y * canvasTileSize;
draw_list->AddRectFilled(ImVec2(tx, ty), ImVec2(tx + canvasTileSize, ty + canvasTileSize), ImColor(255, 0, 0));
}
}
}

// Mouse hover and click actions
// HERE I DONT WANT TO TAKE ANY CLICK ACTION AFTER A MENU ITEM HAS BEEN CLICKED
if (ImGui::IsWindowFocused() && ImGui::IsMouseHoveringRect(canvasViewportStart, canvasViewportEnd)) {
auto mp = ImGui::GetMousePos();
s32 hoverTileX = (s32)((mp.x - canvasViewportStart.x) / canvasTileSize);
s32 hoverTileY = (s32)((mp.y - canvasViewportStart.y) / canvasTileSize);
f32 tx = canvasViewportStart.x + hoverTileX * canvasTileSize;
f32 ty = canvasViewportStart.y + hoverTileY * canvasTileSize;
draw_list->AddRect(ImVec2(tx, ty), ImVec2(tx + canvasTileSize, ty + canvasTileSize), ImColor(255, 255, 0));

u32 invertHoverTileY = (TileCountForHeight - 1 - hoverTileY);
if (ImGui::IsMouseDown(0)) {
SetTile(hoverTileX, invertHoverTileY, true);
} else if (ImGui::IsMouseDown(2)) {
SetTile(hoverTileX, invertHoverTileY, false);
}
}

ImGui::End();
}

Edited by Finalspace

##### Share on other sites

Are you running on latest? There was a bug in 1.51 which I think is what you are having here.

For general imgui questions may I suggest asking in the imgui github, this is where all the other questions are being asked.

##### Share on other sites
1 hour ago, ocornut said:

Are you running on latest? There was a bug in 1.51 which I think is what you are having here.

For general imgui questions may I suggest asking in the imgui github, this is where all the other questions are being asked.

Oh great, never thought it may be a bug... After updating to the latest everything seems to work properly now.

## Create an account

Register a new account

1. 1
2. 2
3. 3
4. 4
Rutin
15
5. 5

• 14
• 9
• 9
• 9
• 10
• ### Forum Statistics

• Total Topics
632912
• Total Posts
3009199
• ### Who's Online (See full list)

There are no registered users currently online

×