817    bool firstFrame = ImGui::GetFrameCount() == 1;
 
  822        ed::NavigateToContent();
 
  848    if (ed::AreShortcutsEnabled())
 
  853    ImGui::PushFont(PanelFont());
 
  858    ed::SetCurrentEditor(m_Editor);
 
  860    static ed::NodeId contextNodeId = 0;
 
  861    static ed::LinkId contextLinkId = 0;
 
  862    static ed::PinId contextPinId = 0;
 
  863    static bool createNewNode = 
false;
 
  864    static Pin* newNodeLinkPin = 
nullptr;
 
  866    bool leftPaneActive = 
false;
 
  871        ImGui::PushFont(PanelFont());
 
  875        ImGui::SameLine(0.0F, 12.0F);
 
  879    std::string tooltipText;
 
  883    bool darkMode = ax::NodeEditor::GetStyle().Colors[ax::NodeEditor::StyleColor_Bg].x
 
  884                        + ax::NodeEditor::GetStyle().Colors[ax::NodeEditor::StyleColor_Bg].y
 
  885                        + ax::NodeEditor::GetStyle().Colors[ax::NodeEditor::StyleColor_Bg].z
 
  890        float blueprintHeight = ImGui::GetContentRegionAvail().y - 
bottomViewHeight + (isUsingBigPanelFont() ? 48.5F : 28.5F);
 
  891        ImGui::PushStyleColor(ImGuiCol_Separator, IM_COL32_BLACK_TRANS);
 
  893        ImGui::PopStyleColor();
 
  898        static Pin* newLinkPin = 
nullptr;
 
  900        auto cursorTopLeft = ImGui::GetCursorScreenPos();
 
  904        auto textColor = ax::NodeEditor::GetStyle().Colors[ax::NodeEditor::StyleColor_NodeBg].x
 
  905                                     + ax::NodeEditor::GetStyle().Colors[ax::NodeEditor::StyleColor_NodeBg].y
 
  906                                     + ax::NodeEditor::GetStyle().Colors[ax::NodeEditor::StyleColor_NodeBg].z
 
  908                             ? IM_COL32(0, 0, 0, 255)
 
  909                             : IM_COL32(255, 255, 255, 255);
 
  920            bool hasOutputDelegates = 
false;
 
  921            for (
const auto& output : node->outputPins)
 
  925                    hasOutputDelegates = 
true;
 
  929            builder.
Begin(node->id);
 
  933                if (node->isDisabled()) 
 
  935                    builder.
Header(ImColor(192, 192, 192)); 
 
  937                else if (node->isInitialized())
 
  939                    builder.
Header(ImColor(128, 255, 128)); 
 
  943                    builder.
Header(ImColor(255, 128, 128)); 
 
  946                ImGui::PushStyleColor(ImGuiCol_Text, textColor);
 
  947                ImGui::TextUnformatted(node->name.c_str());
 
  948                ImGui::PopStyleColor();
 
  968                    ImGui::Dummy(ImVec2(ImGui::GetStyle().ItemSpacing.x + 12.0F + ImGui::GetStyle().FramePadding.x, 26));
 
  970                if (hasOutputDelegates)
 
  972                    ImGui::BeginVertical(
"delegates", ImVec2(0, 26));
 
  974                    for (
const auto& output : node->outputPins)
 
  981                        auto alpha = ImGui::GetStyle().Alpha;
 
  985                            alpha = alpha * (48.0F / 255.0F);
 
  988                        ed::BeginPin(output.id, ed::PinKind::Output);
 
  989                        ed::PinPivotAlignment(ImVec2(1.0F, 0.5F));
 
  990                        ed::PinPivotSize(ImVec2(0, 0));
 
  991                        ImGui::BeginHorizontal(output.id.AsPointer());
 
  992                        ImGui::PushStyleVar(ImGuiStyleVar_Alpha, alpha);
 
 1000                        output.drawPinIcon(output.isPinLinked(), 
static_cast<int>(alpha * 255));
 
 1001                        ImGui::Spring(0, ImGui::GetStyle().ItemSpacing.x / 2);
 
 1002                        ImGui::EndHorizontal();
 
 1003                        ImGui::PopStyleVar();
 
 1008                    ImGui::Spring(1, 0);
 
 1009                    ImGui::EndVertical();
 
 1010                    ImGui::Spring(0, ImGui::GetStyle().ItemSpacing.x / 2);
 
 1019            for (
auto& input : node->inputPins) 
 
 1021                auto alpha = ImGui::GetStyle().Alpha;
 
 1025                    alpha = alpha * (48.0F / 255.0F);
 
 1028                builder.
Input(input.id);
 
 1029                ImGui::PushStyleVar(ImGuiStyleVar_Alpha, alpha);
 
 1030                input.drawPinIcon(input.isPinLinked(), 
static_cast<int>(alpha * 255));
 
 1031                if (ImGui::IsItemHovered()) { tooltipText = fmt::format(
"{}", fmt::join(input.dataIdentifier, 
"\n")); }
 
 1034                    auto cursor = ImGui::GetCursorPos();
 
 1035                    std::string text = fmt::format(
"{}{}", input.queue.size(), input.queueBlocked ? 
"*" : 
"");
 
 1036                    auto* drawList = ImGui::GetWindowDrawList();
 
 1037                    drawList->AddText(ImVec2(cursor.x - 26.0F, cursor.y + 2.F), IM_COL32(255, 0, 0, 255), text.c_str());
 
 1041                if (!input.name.empty())
 
 1046                        ImGui::BeginDisabled();
 
 1048                    ImGui::PushStyleColor(ImGuiCol_Text, textColor);
 
 1049                    ImGui::TextUnformatted(input.name.c_str());
 
 1050                    ImGui::PopStyleColor();
 
 1053                        ImGui::EndDisabled();
 
 1057                ImGui::PopStyleVar();
 
 1065                ImGui::Spring(1, 0);
 
 1066                ImGui::PushStyleColor(ImGuiCol_Text, textColor);
 
 1067                ImGui::TextUnformatted(node->name.c_str());
 
 1068                ImGui::PopStyleColor();
 
 1069                ImGui::Spring(1, 0);
 
 1072            for (
const auto& output : node->outputPins) 
 
 1079                auto alpha = ImGui::GetStyle().Alpha;
 
 1083                    alpha = alpha * (48.0F / 255.0F);
 
 1086                ImGui::PushStyleVar(ImGuiStyleVar_Alpha, alpha);
 
 1087                builder.
Output(output.id);
 
 1088                if (!output.name.empty())
 
 1094                        ImGui::BeginDisabled();
 
 1096                    ImGui::PushStyleColor(ImGuiCol_Text, textColor);
 
 1097                    ImGui::TextUnformatted(output.name.c_str());
 
 1098                    ImGui::PopStyleColor();
 
 1101                        ImGui::EndDisabled();
 
 1105                output.drawPinIcon(output.isPinLinked(), 
static_cast<int>(alpha * 255));
 
 1106                if (ImGui::IsItemHovered()) { tooltipText = fmt::format(
"{}", fmt::join(output.dataIdentifier, 
"\n")); }
 
 1109                    auto cursor = ImGui::GetCursorPos();
 
 1110                    std::string text = fmt::format(
"{}", output.noMoreDataAvailable ? 
"F" : 
"P");
 
 1111                    auto* drawList = ImGui::GetWindowDrawList();
 
 1112                    drawList->AddText(ImVec2(cursor.x - 26.0F, cursor.y + 2.F), IM_COL32(255, 0, 0, 255), text.c_str());
 
 1115                ImGui::PopStyleVar();
 
 1129            ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.75F);
 
 1132            ed::BeginNode(node->id);
 
 1133            ImGui::PushID(node->id.AsPointer());
 
 1134            ImGui::BeginVertical(
"content");
 
 1135            ImGui::BeginHorizontal(
"horizontal");
 
 1138            ImGui::TextUnformatted(node->name.c_str());
 
 1139            ImGui::PopStyleColor();
 
 1141            ImGui::EndHorizontal();
 
 1142            ed::Group(node->_size);
 
 1143            ImGui::EndVertical();
 
 1146            ed::PopStyleColor(2);
 
 1147            ImGui::PopStyleVar();
 
 1152            for (
const auto& output : node->outputPins) 
 
 1154                auto color = output.getIconColor();
 
 1157                    color = darkMode ? ImColor{ 0, 0, 0 } : ImColor{ 255, 255, 255 };
 
 1160                for (
const auto& link : output.links)
 
 1162                    ed::Link(link.linkId, output.id, link.connectedPinId, color, 2.0F * 
defaultFontRatio());
 
 1169            if (ed::BeginCreate(ImColor(255, 255, 255), 2.0F))
 
 1171                auto showLabel = [](
const char* label, ImColor color) {
 
 1172                    ImGui::SetCursorPosY(ImGui::GetCursorPosY() - ImGui::GetTextLineHeight());
 
 1173                    auto size = ImGui::CalcTextSize(label);
 
 1175                    auto padding = ImGui::GetStyle().FramePadding;
 
 1176                    auto spacing = ImGui::GetStyle().ItemSpacing;
 
 1178                    ImGui::SetCursorPos(ImGui::GetCursorPos() + ImVec2(spacing.x, -spacing.y));
 
 1180                    auto rectMin = ImGui::GetCursorScreenPos() - padding;
 
 1181                    auto rectMax = ImGui::GetCursorScreenPos() + size + padding;
 
 1183                    auto* drawList = ImGui::GetWindowDrawList();
 
 1184                    drawList->AddRectFilled(rectMin, rectMax, color, size.y * 0.15F);
 
 1185                    ImGui::TextUnformatted(label);
 
 1188                ed::PinId startPinId = 0;
 
 1189                ed::PinId endPinId = 0;
 
 1190                if (ed::QueryNewLink(&startPinId, &endPinId))
 
 1197                    newLinkPin = startPin ? startPin : endPin;
 
 1201                        std::swap(startPin, endPin);
 
 1202                        std::swap(startPinId, endPinId);
 
 1205                    if (startPin && endPin)
 
 1207                        if (endPin == startPin)
 
 1209                            ed::RejectNewItem(ImColor(255, 0, 0), 2.0F);
 
 1211                        else if (endPin->
kind == startPin->
kind)
 
 1213                            showLabel(
"x Incompatible Pin Kind", ImColor(45, 32, 32, 180));
 
 1214                            ed::RejectNewItem(ImColor(255, 0, 0), 2.0F);
 
 1218                            showLabel(
"x Cannot connect to self", ImColor(45, 32, 32, 180));
 
 1219                            ed::RejectNewItem(ImColor(255, 0, 0), 1.0F);
 
 1221                        else if (endPin->
type != startPin->
type)
 
 1223                            showLabel(
"x Incompatible Pin Type", ImColor(45, 32, 32, 180));
 
 1224                            ed::RejectNewItem(ImColor(255, 128, 128), 1.0F);
 
 1226                        else if (
reinterpret_cast<InputPin*
>(endPin)->isPinLinked())
 
 1228                            showLabel(
"End Pin already linked", ImColor(45, 32, 32, 180));
 
 1229                            ed::RejectNewItem(ImColor(255, 128, 128), 1.0F);
 
 1234                            showLabel(fmt::format(
"The data type [{}]\ncan't be linked to [{}]",
 
 1238                                      ImColor(45, 32, 32, 180));
 
 1239                            ed::RejectNewItem(ImColor(255, 128, 128), 1.0F);
 
 1247                                showLabel(fmt::format(
"The delegate type [{}]\ncan't be linked to [{}]",
 
 1251                                          ImColor(45, 32, 32, 180));
 
 1254                            ed::RejectNewItem(ImColor(255, 128, 128), 1.0F);
 
 1259                            showLabel(fmt::format(
"The data type [{}]\ncan't be linked to [{}]",
 
 1263                                      ImColor(45, 32, 32, 180));
 
 1264                            ed::RejectNewItem(ImColor(255, 128, 128), 1.0F);
 
 1268                            showLabel(
"+ Create Link", ImColor(32, 45, 32, 180));
 
 1269                            if (ed::AcceptNewItem(ImColor(128, 255, 128), 4.0F))
 
 1271                                reinterpret_cast<OutputPin*
>(startPin)->createLink(*
reinterpret_cast<InputPin*
>(endPin));
 
 1277                ed::PinId pinId = 0;
 
 1278                if (ed::QueryNewNode(&pinId))
 
 1285                        showLabel(
"End Pin already linked", ImColor(45, 32, 32, 180));
 
 1286                        ed::RejectNewItem(ImColor(255, 128, 128), 1.0F);
 
 1292                            showLabel(
"+ Create Node", ImColor(32, 45, 32, 180));
 
 1295                        if (ed::AcceptNewItem())
 
 1297                            createNewNode = 
true;
 
 1300                            newLinkPin = 
nullptr;
 
 1302                            ImGui::OpenPopup(
"Create New Node");
 
 1310                newLinkPin = 
nullptr;
 
 1315            if (ed::BeginDelete())
 
 1317                ed::LinkId linkId = 0;
 
 1318                while (ed::QueryDeletedLink(&linkId))
 
 1320                    if (ed::AcceptDeletedItem())
 
 1322                        bool deleted = 
false;
 
 1325                            if (deleted) { 
break; }
 
 1326                            for (
auto& output : node->outputPins)
 
 1328                                if (deleted) { 
break; }
 
 1329                                for (
const auto& link : output.links)
 
 1331                                    if (link.linkId == linkId)
 
 1333                                        output.deleteLink(*link.getConnectedPin());
 
 1343                ed::NodeId nodeId = 0;
 
 1344                while (ed::QueryDeletedNode(&nodeId))
 
 1348                        if (node->isTransient())
 
 1353                    if (ed::AcceptDeletedItem())
 
 1362        ImGui::SetCursorScreenPos(cursorTopLeft);
 
 1366    ax::NodeEditor::EnableShortcuts(ed::IsActive() || leftPaneActive);
 
 1370    if (ed::ShowNodeContextMenu(&contextNodeId))
 
 1372        ImGui::OpenPopup(
"Node Context Menu");
 
 1374    else if (ed::ShowPinContextMenu(&contextPinId))
 
 1376        ImGui::OpenPopup(
"Pin Context Menu");
 
 1378    else if (ed::ShowLinkContextMenu(&contextLinkId) && ed::IsActive())
 
 1380        ImGui::OpenPopup(
"Link Context Menu");
 
 1382    else if (ed::ShowBackgroundContextMenu() && ed::IsActive())
 
 1384        ImGui::OpenPopup(
"Create New Node");
 
 1385        newNodeLinkPin = 
nullptr;
 
 1387    else if (ed::NodeId doubleClickedNodeId = ed::GetDoubleClickedNode())
 
 1396    ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8, 8));
 
 1397    static Node* renameNode = 
nullptr;
 
 1398    static Pin* renamePin = 
nullptr;
 
 1399    if (ImGui::BeginPopup(
"Node Context Menu"))
 
 1403        ImGui::TextUnformatted(
"Node Context Menu");
 
 1407            ImGui::Text(
"ID: %lu", 
size_t(node->id));
 
 1408            ImGui::Text(
"Type: %s", node->type().c_str());
 
 1409            ImGui::Text(
"Kind: %s", std::string(node->kind).c_str());
 
 1410            ImGui::Text(
"Inputs: %lu", node->inputPins.size());
 
 1411            ImGui::Text(
"Outputs: %lu", node->outputPins.size());
 
 1412            ImGui::Text(
"State: %s", 
Node::toString(node->getState()).c_str());
 
 1417                if (ImGui::MenuItem(node->isInitialized() ? 
"Reinitialize" : 
"Initialize", 
"",
 
 1420                    if (node->isInitialized()) { node->doReinitialize(); }
 
 1421                    else { node->doInitialize(); }
 
 1423                if (ImGui::MenuItem(
"Deinitialize", 
"", 
false, node->isInitialized()))
 
 1425                    node->doDeinitialize();
 
 1427                if (ImGui::MenuItem(
"Wake Worker"))
 
 1432                if (node->_hasConfig && ImGui::MenuItem(
"Configure", 
"", 
false))
 
 1434                    node->_showConfig = 
true;
 
 1435                    node->_configWindowFocus = 
true;
 
 1437                if (ImGui::MenuItem(node->isDisabled() ? 
"Enable" : 
"Disable", 
"", 
false, !node->isTransient()))
 
 1439                    if (node->isDisabled())
 
 1450            if (ImGui::MenuItem(
"Rename"))
 
 1455            if (ImGui::MenuItem(
"Delete", 
"", 
false, !node->isTransient()))
 
 1457                ed::DeleteNode(contextNodeId);
 
 1462            ImGui::Text(
"Unknown node: %lu", 
size_t(contextNodeId));
 
 1473    if (ImGui::BeginPopup(
"Pin Context Menu"))
 
 1475        ImGui::TextUnformatted(
"Pin Context Menu");
 
 1479            ImGui::Text(
"ID: %lu", 
size_t(pin->id));
 
 1480            ImGui::Text(
"Node: %s", pin->parentNode ? std::to_string(
size_t(pin->parentNode->id)).c_str() : 
"<none>");
 
 1481            ImGui::Text(
"Type: %s", std::string(pin->type).c_str());
 
 1483            if (pin->isPinLinked())
 
 1485                const auto& link = pin->link;
 
 1486                ImGui::SetNextItemOpen(
true, ImGuiCond_Appearing);
 
 1487                if (ImGui::TreeNode(fmt::format(
"LinkId: {}", 
size_t(link.linkId)).c_str()))
 
 1489                    ImGui::BulletText(
"Connected Node: %s", link.connectedNode->nameId().c_str());
 
 1490                    ImGui::BulletText(
"Connected Pin:  %s (%zu)", link.getConnectedPin()->name.c_str(),
 
 1491                                      size_t(link.getConnectedPin()->id));
 
 1495            else { ImGui::TextUnformatted(
"Link: Not linked"); }
 
 1497            if (ImGui::TreeNode(fmt::format(
"Queue: {}", pin->queue.size()).c_str()))
 
 1499                ImGui::BeginChild(
"QueueItems", ImVec2(ImGui::GetContentRegionAvail().x, 150), 
false, ImGuiWindowFlags_None);
 
 1500                for (
size_t i = 0; i < pin->queue.size(); i++) 
 
 1502                    ImGui::Text(
"%s", std::string(pin->queue.at(i)->insTime.toYMDHMS()).c_str());
 
 1508            ImGui::Text(
"Queue blocked: %s", pin->queueBlocked ? 
"true" : 
"false");
 
 1509            ImGui::Text(
"Temporal check: %s", pin->neededForTemporalQueueCheck ? 
"true" : 
"false");
 
 1510            ImGui::Text(
"Drop queue: %s", pin->dropQueueIfNotFirable ? 
"true" : 
"false");
 
 1512            if (ImGui::MenuItem(
"Rename")) { renamePin = pin; }
 
 1516            ImGui::Text(
"ID: %lu", 
size_t(pin->id));
 
 1517            ImGui::Text(
"Node: %s", pin->parentNode ? std::to_string(
size_t(pin->parentNode->id)).c_str() : 
"<none>");
 
 1518            ImGui::Text(
"Type: %s", std::string(pin->type).c_str());
 
 1519            ImGui::Text(
"Data available: %s", pin->noMoreDataAvailable ? 
"No" : 
"Yes");
 
 1520            if (!pin->blocksConnectedNodeFromFinishing)
 
 1522                ImGui::TextUnformatted(
"Does not block connected pin from finishing!!!");
 
 1525            if (pin->isPinLinked())
 
 1527                ImGui::SetNextItemOpen(
true, ImGuiCond_Appearing);
 
 1528                if (ImGui::TreeNode(fmt::format(
"Links: {}", pin->links.size()).c_str()))
 
 1530                    for (
const auto& link : pin->links)
 
 1532                        ImGui::SetNextItemOpen(
true, ImGuiCond_Appearing);
 
 1533                        if (ImGui::TreeNode(fmt::format(
"LinkId: {}", 
size_t(link.linkId)).c_str()))
 
 1535                            ImGui::BulletText(
"Connected Node: %s", link.connectedNode->nameId().c_str());
 
 1536                            ImGui::BulletText(
"Connected Pin:  %s (%zu)", link.getConnectedPin()->name.c_str(),
 
 1537                                              size_t(link.getConnectedPin()->id));
 
 1544            else { ImGui::TextUnformatted(
"Link: Not linked"); }
 
 1546            if (ImGui::MenuItem(
"Rename"))
 
 1553            ImGui::Text(
"Unknown pin: %lu", 
size_t(contextPinId));
 
 1564    if (ImGui::BeginPopup(
"Link Context Menu"))
 
 1566        ax::NodeEditor::PinId startPinId = 0;
 
 1567        ax::NodeEditor::PinId endPinId = 0;
 
 1570            if (startPinId) { 
break; }
 
 1571            for (
const auto& output : node->outputPins)
 
 1573                if (startPinId) { 
break; }
 
 1574                for (
const auto& link : output.links)
 
 1576                    if (link.linkId == contextLinkId)
 
 1578                        startPinId = output.id;
 
 1579                        endPinId = link.connectedPinId;
 
 1586        ImGui::TextUnformatted(
"Link Context Menu");
 
 1590            ImGui::Text(
"ID: %lu", 
size_t(contextLinkId));
 
 1591            ImGui::Text(
"From: %lu", 
size_t(startPinId));
 
 1592            ImGui::Text(
"To: %lu", 
size_t(endPinId));
 
 1596            ImGui::Text(
"Unknown link: %lu", 
size_t(contextLinkId));
 
 1599        if (ImGui::MenuItem(
"Delete"))
 
 1601            ed::DeleteLink(contextLinkId);
 
 1606    static bool setKeyboardFocus = 
true;
 
 1607    static ImVec2 newNodeSpawnPos{ -1, -1 };
 
 1608    if (ImGui::BeginPopup(
"Create New Node"))
 
 1610        if (newNodeSpawnPos.x == -1 || newNodeSpawnPos.y == -1)
 
 1612            auto viewRect = 
reinterpret_cast<ax::NodeEditor::Detail::EditorContext*
>(ed::GetCurrentEditor())->GetViewRect();
 
 1613            newNodeSpawnPos = ImGui::GetMousePos();
 
 1617            newNodeSpawnPos *= ed::GetCurrentZoom();
 
 1619            newNodeSpawnPos += viewRect.GetTL();
 
 1621            LOG_DEBUG(
"New Node will spawn at {}x{} - Zoom {}", newNodeSpawnPos.x, newNodeSpawnPos.y, ed::GetCurrentZoom());
 
 1624        if (setKeyboardFocus)
 
 1626            ImGui::SetKeyboardFocusHere(0);
 
 1628        static ImGuiTextFilter filter;
 
 1630        filter.Draw(
"##NewNodeFilter");
 
 1632        if (setKeyboardFocus)
 
 1635            setKeyboardFocus = 
false;
 
 1638        Node* node = 
nullptr;
 
 1642            bool categoryHasItems = 
false;
 
 1643            for (
const auto& nodeInfo : nodeInfoList)
 
 1645                if (nodeInfo.hasCompatiblePin(newNodeLinkPin)
 
 1646                    && (filter.PassFilter(nodeInfo.type.c_str()) || filter.PassFilter(category.c_str())))
 
 1648                    categoryHasItems = 
true;
 
 1652            if (categoryHasItems)
 
 1654                ImGui::SetNextItemOpen(
true, ImGuiCond_Once);
 
 1655                if (ImGui::TreeNode((category + 
"##NewNodeTree").c_str()))
 
 1657                    for (
const auto& nodeInfo : nodeInfoList)
 
 1659                        const auto& displayName = nodeInfo.type;
 
 1660                        const auto& constructor = nodeInfo.constructor;
 
 1662                        if (nodeInfo.hasCompatiblePin(newNodeLinkPin)
 
 1663                            && (filter.PassFilter(nodeInfo.type.c_str()) || filter.PassFilter(category.c_str()))
 
 1664                            && ImGui::MenuItem(displayName.c_str()))
 
 1667                            node = constructor();
 
 1679            createNewNode = 
false;
 
 1681            ed::SetNodePosition(node->
id, newNodeSpawnPos);
 
 1682            newNodeSpawnPos = { -1, -1 };
 
 1684            if (
auto* startPin = newNodeLinkPin)
 
 1690                        if (
reinterpret_cast<InputPin*
>(startPin)->canCreateLink(pin))
 
 1692                            pin.createLink(*
reinterpret_cast<InputPin*
>(startPin));
 
 1701                        if (
reinterpret_cast<OutputPin*
>(startPin)->canCreateLink(pin))
 
 1703                            reinterpret_cast<OutputPin*
>(startPin)->createLink(pin);
 
 1715        setKeyboardFocus = 
true;
 
 1716        createNewNode = 
false;
 
 1717        newNodeSpawnPos = { -1, -1 };
 
 1719    ImGui::PopStyleVar();
 
 1723        if (node->_hasConfig && node->_showConfig)
 
 1725            ImVec2 center(ImGui::GetIO().DisplaySize.x * 0.5F, ImGui::GetIO().DisplaySize.y * 0.5F);
 
 1726            if (node->_configWindowFocus)
 
 1728                ImGui::SetNextWindowCollapsed(
false);
 
 1729                ImGui::SetNextWindowFocus();
 
 1730                node->_configWindowFocus = 
false;
 
 1732            ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5F, 0.5F));
 
 1733            ImGui::SetNextWindowSize(node->_guiConfigDefaultWindowSize, ImGuiCond_FirstUseEver);
 
 1734            if (!node->_configWindowMutex.try_lock())
 
 1736                ImGui::SetNextWindowCollapsed(
true, ImGuiCond_Always);
 
 1737                node->_configWindowForceCollapse = 
true;
 
 1741                node->_configWindowMutex.unlock();
 
 1742                if (node->_configWindowForceCollapse)
 
 1744                    LOG_TRACE(
"Setting next window collapsed: {}", node->_configWindowIsCollapsed);
 
 1745                    ImGui::SetNextWindowCollapsed(node->_configWindowIsCollapsed);
 
 1746                    node->_configWindowForceCollapse = 
false;
 
 1749            if (ImGui::Begin(fmt::format(
"{} ({})", node->nameId(), node->type()).c_str(), &(node->_showConfig),
 
 1750                             ImGuiWindowFlags_None))
 
 1752                ImGui::PushFont(WindowFont());
 
 1754                if (locked) { ImGui::BeginDisabled(); }
 
 1755                if (!node->_configWindowForceCollapse)
 
 1757                    node->_configWindowIsCollapsed = 
false;
 
 1760                if (locked) { ImGui::EndDisabled(); }
 
 1765                if (!node->_configWindowForceCollapse) { node->_configWindowIsCollapsed = 
true; }
 
 1766                if (ImGui::IsWindowFocused())
 
 1768                    ed::EnableShortcuts(
true);
 
 1779    ImGui::PushFont(PanelFont());
 
 1781    ImGui::SetNextItemOpen(
true, ImGuiCond_Once);
 
 1782    if (ImGui::BeginTabBar(
"BottomViewTabBar"))
 
 1787            ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.0F);
 
 1789        if (ImGui::BeginTabItem(
"▼"))
 
 1793            ImGui::EndTabItem();
 
 1801            ImGui::PopStyleVar();
 
 1804        if (ImGui::BeginTabItem(
"Log Output", 
nullptr, firstFrame ? ImGuiTabItemFlags_SetSelected : ImGuiTabItemFlags_None))
 
 1806            static int scrollToBottom = 0;
 
 1813            static bool autoScroll = 
true;
 
 1814            static ImGuiTextFilter textFilter;
 
 1817            if (ImGui::BeginPopup(
"Options"))
 
 1819                ImGui::Checkbox(
"Auto-scroll", &autoScroll);
 
 1824            if (ImGui::Button(
"Options"))
 
 1826                ImGui::OpenPopup(
"Options");
 
 1830            static int logLevelFilterSelected = spdlog::level::info;
 
 1831            if (ImGui::BeginCombo(
"##LogLevelCombo", spdlog::level::to_string_view(
static_cast<spdlog::level::level_enum
>(logLevelFilterSelected)).begin()))
 
 1833                for (
int n = spdlog::level::debug; n < spdlog::level::critical; n++)
 
 1835                    const bool is_selected = (logLevelFilterSelected == n);
 
 1836                    if (ImGui::Selectable(spdlog::level::to_string_view(
static_cast<spdlog::level::level_enum
>(n)).begin(), is_selected))
 
 1838                        logLevelFilterSelected = n;
 
 1844                        ImGui::SetItemDefaultFocus();
 
 1850            textFilter.Draw(
"Filter", -100.0F);
 
 1853            ImGui::BeginChild(
"scrolling", ImVec2(0, 0), 
false, ImGuiWindowFlags_HorizontalScrollbar);
 
 1855                ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
 
 1856                ImGui::PushFont(MonoFont());
 
 1860                for (
auto& logLine : logMessages)
 
 1862                    for (
int n = logLevelFilterSelected; n < spdlog::level::n_levels; n++)
 
 1864                        if (logLine.find(fmt::format(
"] [{}]", spdlog::level::to_short_c_str(
static_cast<spdlog::level::level_enum
>(n)))) != std::string::npos)
 
 1866                            if (!textFilter.IsActive() || textFilter.PassFilter(logLine.c_str()))
 
 1881                ImGui::PopStyleVar();
 
 1885                    ImGui::SetScrollHereY(1.0F);
 
 1888                else if (autoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY())
 
 1890                    ImGui::SetScrollHereY(1.0F);
 
 1895            ImGui::EndTabItem();
 
 1907    if (!tooltipText.empty()) { ImGui::SetTooltip(
"%s", tooltipText.c_str()); }
 
 1909    ImGui::PushFont(WindowFont());
 
 1916    SetTitle(title.c_str());