Skip to content

Instantly share code, notes, and snippets.

@xeechou
Last active November 25, 2021 02:49
Show Gist options
  • Save xeechou/d5df8b0724821ecf8d4e87c4dbf45733 to your computer and use it in GitHub Desktop.
Save xeechou/d5df8b0724821ecf8d4e87c4dbf45733 to your computer and use it in GitHub Desktop.
Dynamic TreeNodes using ImGUI
#pragma once
#include <stack>
#include <vector>
#include <stack>
#include <utility>
#include <functional>
#include <tuple>
#include <imgui.h>
namespace ImGui
{
/*
* dynamically draw TreeNodes with ImGui
*
* @param tree_list: a Depth first tree expressed in the form of vector of (level, value).
* @param itr_func: a lambda which generates string to pass to TreeNode function.
*
*
* This function dynamically draw the tree nodes without hard coding the tree
* structure. It carefully maintain the stack of tree and push and pop tree at
* right moment. The minimum level should be 0.
*
*/
template <typename T>
void TreeVec(const std::vector<std::pair<int, T>>& tree_list,
std::function<std::string(const T&)> const itr_func)
{
unsigned level = 0;
bool expanded = true; //expanding for curr level?
bool local_expaned = true; //expanding for next level?
std::stack<std::tuple<unsigned, bool, bool>> stack;
auto itr = tree_list.begin();
while (itr != tree_list.end())
{
if (itr->first >= level) //push
{
std::string id = std::to_string(std::distance(tree_list.begin(),
itr));
std::string txt = itr_func(itr->second);
local_expaned = expanded &&
TreeNode(id.c_str(), "%s", txt.c_str());
stack.push(std::make_tuple(itr->first, local_expaned, expanded));
expanded = local_expaned;
level++;
itr++;
}
else //reduce
{
std::tie(level, local_expaned, expanded) = stack.top();
stack.pop();
if (local_expaned)
TreePop();
}
}
while (!stack.empty())
{
std::tie(level, local_expaned, expanded) = stack.top();
stack.pop();
if (local_expaned)
TreePop();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment