Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to check ImGui if has no persistant data present? #4988

Closed
aeris170 opened this issue Feb 6, 2022 · 9 comments
Closed

How to check ImGui if has no persistant data present? #4988

aeris170 opened this issue Feb 6, 2022 · 9 comments
Labels
docking settings .ini persistance

Comments

@aeris170
Copy link

aeris170 commented Feb 6, 2022

Is there a built-in way to check if imgui has persistant data present?
I'm asking this because I have a block of code that should only run if the program has no persistant data. (opening for the first time etc.)

I thought about writing my user data in the form of a bool and then try reading it before the aforementioned block of code, but I couldn't wrap my head around how the ImGuiSettingsHandler worked (when it fired those callbacks etc.)

Thank you in advance.

@aeris170 aeris170 changed the title How to check if has no persistant data present? How to check ImGui if has no persistant data present? Feb 6, 2022
@ocornut
Copy link
Owner

ocornut commented Feb 6, 2022 via email

@aeris170
Copy link
Author

aeris170 commented Feb 6, 2022

I understand, I'll try to explain as best as I can. The block in question sets up the docking layout with the help of dock builder API. It sets upa "default" layout which users can then change for their liking. I only want to set up this default layout if there is no saved .ini file because otherwise I'd be overwriting the users' preferences. That's why I want to check if ImGui has persistant data present.

My question has many parallels with #4829 so you may want to close this right away, but I also think (if there already isn't) having a function to query whether or not ImGui has persisted any amount of data would be a fine addition.

@ocornut
Copy link
Owner

ocornut commented Feb 6, 2022 via email

@aeris170
Copy link
Author

aeris170 commented Feb 6, 2022

I'm already checking to see if my docknode exists but it's never "not existing", ImGui::DockBuilderGetNode() always retuns a non-null pointer. Here is my code:

        window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
	ImGuiViewport* viewport = ImGui::GetMainViewport();
	ImGui::SetNextWindowPos(viewport->Pos);
	ImGui::SetNextWindowSize(viewport->Size);
	ImGui::SetNextWindowViewport(viewport->ID);
	ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
	ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
	window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
	window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;

	dockspace_flags = ImGuiDockNodeFlags_NoCloseButton;
	if (dockspace_flags & ImGuiDockNodeFlags_PassthruCentralNode) {
		window_flags |= ImGuiWindowFlags_NoBackground;
	}

	ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, { 0.0f, 0.0f });
	ImGui::SetNextWindowBgAlpha(0.0f);
	ImGui::Begin(dockSpaceName, &dockspaceOpen, window_flags);
	ImGui::PopStyleVar();

	ImGui::PopStyleVar(2);
	
	if (io->ConfigFlags & ImGuiConfigFlags_DockingEnable) {
		ImGuiID dockspace_id = ImGui::GetID("MyDockspace");

		ImGui::DockSpace(dockspace_id, { 0, 0 }, dockspace_flags);

		if (ImGui::DockBuilderGetNode(dockspace_id) == nullptr) { // this if never executes
			// Clear out existing layout
			ImGui::DockBuilderRemoveNode(dockspace_id);
			// Add empty node
			ImGui::DockBuilderAddNode(dockspace_id, ImGuiDockNodeFlags_DockSpace);
			// Main node should cover entire window
			ImGui::DockBuilderSetNodeSize(dockspace_id, ImGui::GetWindowSize());
			// Build dock layout
			ImGuiID top = ImGui::DockBuilderSplitNode(dockspace_id, ImGuiDir_Up, 0.2f, nullptr, &dockspace_id);
			ImGuiID down = ImGui::DockBuilderSplitNode(dockspace_id, ImGuiDir_Down, 0.25f, nullptr, &dockspace_id);
			ImGuiID left = ImGui::DockBuilderSplitNode(dockspace_id, ImGuiDir_Left, 0.25f, nullptr, &dockspace_id);
			ImGuiID right = ImGui::DockBuilderSplitNode(dockspace_id, ImGuiDir_Right, 0.25f, nullptr, &dockspace_id);

			ImGuiID rightDown;
			ImGuiID rightUp = ImGui::DockBuilderSplitNode(right, ImGuiDir_Up, 0.65f, nullptr, &rightDown);

			ImGui::DockBuilderDockWindow(SOME_ID1, left);
			ImGui::DockBuilderDockWindow(SOME_ID2, rightUp);
			ImGui::DockBuilderDockWindow(SOME_ID3, rightDown);
			ImGui::DockBuilderDockWindow(SOME_ID4, rightDown);
			ImGui::DockBuilderFinish(dockspace_id);
		}
	}

What am I doing wrong here? If I convert the expression to instead check for the existence of imgui.ini, the if executes only once when the program is launched for the first time.

@ocornut
Copy link
Owner

ocornut commented Feb 6, 2022 via email

@aeris170
Copy link
Author

aeris170 commented Feb 6, 2022

That makes sense, however, moving the call to ImGui::DockSpace below the if causes the program to hit this assert in ImGui::DockSpace:
image

@aeris170
Copy link
Author

aeris170 commented Feb 6, 2022

I found the cause of my problem, I changed these lines:

ImGuiID top = ImGui::DockBuilderSplitNode(dockspace_id, ImGuiDir_Up, 0.2f, nullptr, &dockspace_id);
ImGuiID down = ImGui::DockBuilderSplitNode(dockspace_id, ImGuiDir_Down, 0.25f, nullptr, &dockspace_id);
ImGuiID left = ImGui::DockBuilderSplitNode(dockspace_id, ImGuiDir_Left, 0.25f, nullptr, &dockspace_id);
ImGuiID right = ImGui::DockBuilderSplitNode(dockspace_id, ImGuiDir_Right, 0.25f, nullptr, &dockspace_id);

to these:

ImGuiID dockspace_id_copy = dockspace_id;
ImGuiID top = ImGui::DockBuilderSplitNode(dockspace_id_copy, ImGuiDir_Up, 0.2f, nullptr, &dockspace_id_copy);
ImGuiID down = ImGui::DockBuilderSplitNode(dockspace_id_copy, ImGuiDir_Down, 0.25f, nullptr, &dockspace_id_copy);
ImGuiID left = ImGui::DockBuilderSplitNode(dockspace_id_copy, ImGuiDir_Left, 0.25f, nullptr, &dockspace_id_copy);
ImGuiID right = ImGui::DockBuilderSplitNode(dockspace_id_copy, ImGuiDir_Right, 0.25f, nullptr, &dockspace_id_copy);

Now that I've fixed my initial problem, should we close this issue without adressing the question on the title and change the title or keep it open consider the possible use cases of such a function?

@ocornut
Copy link
Owner

ocornut commented Feb 7, 2022

I'll close this and let searches do the rest :)

should we close this issue without adressing the question on the title

You can also simply read ImGui::GetCurrentContext()->SettingsLoaded using imgui_internal.h but again since this is an XY Problem I don't think the question is worthy.

@ocornut ocornut closed this as completed Feb 7, 2022
@ocornut ocornut added docking settings .ini persistance labels Feb 7, 2022
@Seneral
Copy link

Seneral commented Feb 25, 2024

Seems that for DockSpaceOverViewport, this is currently problematic.
Since you can't specify the ID, and it creates it's own window (modifying the ID stack), that means short of hardcoding the integer ID returned, we do not know the dockspace ID before creation.
And checking SettingsLoaded in the current version always returns false before NewFrame, and always returns true after NewFrame, so that's useless, too.
Removing the faulty line (that sets SettingsLoaded to true even when nothing was read from disk), we'd still need to make sure to only apply it once, but that's alright.
So I guess I'll add another modification to the list for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docking settings .ini persistance
Projects
None yet
Development

No branches or pull requests

3 participants