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());