815 bool firstFrame = ImGui::GetFrameCount() == 1;
820 ed::NavigateToContent();
846 if (ed::AreShortcutsEnabled())
851 ImGui::PushFont(PanelFont());
856 ed::SetCurrentEditor(m_Editor);
858 static ed::NodeId contextNodeId = 0;
859 static ed::LinkId contextLinkId = 0;
860 static ed::PinId contextPinId = 0;
861 static bool createNewNode =
false;
862 static Pin* newNodeLinkPin =
nullptr;
864 bool leftPaneActive =
false;
869 ImGui::PushFont(PanelFont());
873 ImGui::SameLine(0.0F, 12.0F);
877 std::string tooltipText;
881 bool darkMode = ax::NodeEditor::GetStyle().Colors[ax::NodeEditor::StyleColor_Bg].x
882 + ax::NodeEditor::GetStyle().Colors[ax::NodeEditor::StyleColor_Bg].y
883 + ax::NodeEditor::GetStyle().Colors[ax::NodeEditor::StyleColor_Bg].z
888 float blueprintHeight = ImGui::GetContentRegionAvail().y -
bottomViewHeight + (isUsingBigPanelFont() ? 48.5F : 28.5F);
889 ImGui::PushStyleColor(ImGuiCol_Separator, IM_COL32_BLACK_TRANS);
891 ImGui::PopStyleColor();
896 static Pin* newLinkPin =
nullptr;
898 auto cursorTopLeft = ImGui::GetCursorScreenPos();
902 auto textColor = ax::NodeEditor::GetStyle().Colors[ax::NodeEditor::StyleColor_NodeBg].x
903 + ax::NodeEditor::GetStyle().Colors[ax::NodeEditor::StyleColor_NodeBg].y
904 + ax::NodeEditor::GetStyle().Colors[ax::NodeEditor::StyleColor_NodeBg].z
906 ? IM_COL32(0, 0, 0, 255)
907 : IM_COL32(255, 255, 255, 255);
918 bool hasOutputDelegates =
false;
919 for (
const auto& output : node->outputPins)
923 hasOutputDelegates =
true;
927 builder.
Begin(node->id);
931 if (node->isDisabled())
933 builder.
Header(ImColor(192, 192, 192));
935 else if (node->isInitialized())
937 builder.
Header(ImColor(128, 255, 128));
941 builder.
Header(ImColor(255, 128, 128));
944 ImGui::PushStyleColor(ImGuiCol_Text, textColor);
945 ImGui::TextUnformatted(node->name.c_str());
946 ImGui::PopStyleColor();
966 ImGui::Dummy(ImVec2(ImGui::GetStyle().ItemSpacing.x + 12.0F + ImGui::GetStyle().FramePadding.x, 26));
968 if (hasOutputDelegates)
970 ImGui::BeginVertical(
"delegates", ImVec2(0, 26));
972 for (
const auto& output : node->outputPins)
979 auto alpha = ImGui::GetStyle().Alpha;
983 alpha = alpha * (48.0F / 255.0F);
986 ed::BeginPin(output.id, ed::PinKind::Output);
987 ed::PinPivotAlignment(ImVec2(1.0F, 0.5F));
988 ed::PinPivotSize(ImVec2(0, 0));
989 ImGui::BeginHorizontal(output.id.AsPointer());
990 ImGui::PushStyleVar(ImGuiStyleVar_Alpha, alpha);
998 output.drawPinIcon(output.isPinLinked(),
static_cast<int>(alpha * 255));
999 ImGui::Spring(0, ImGui::GetStyle().ItemSpacing.x / 2);
1000 ImGui::EndHorizontal();
1001 ImGui::PopStyleVar();
1006 ImGui::Spring(1, 0);
1007 ImGui::EndVertical();
1008 ImGui::Spring(0, ImGui::GetStyle().ItemSpacing.x / 2);
1017 for (
auto& input : node->inputPins)
1019 auto alpha = ImGui::GetStyle().Alpha;
1023 alpha = alpha * (48.0F / 255.0F);
1026 builder.
Input(input.id);
1027 ImGui::PushStyleVar(ImGuiStyleVar_Alpha, alpha);
1028 input.drawPinIcon(input.isPinLinked(),
static_cast<int>(alpha * 255));
1029 if (ImGui::IsItemHovered()) { tooltipText = fmt::format(
"{}", fmt::join(input.dataIdentifier,
"\n")); }
1032 auto cursor = ImGui::GetCursorPos();
1033 std::string text = fmt::format(
"{}{}", input.queue.size(), input.queueBlocked ?
"*" :
"");
1034 auto* drawList = ImGui::GetWindowDrawList();
1035 drawList->AddText(ImVec2(cursor.x - 26.0F, cursor.y + 2.F), IM_COL32(255, 0, 0, 255), text.c_str());
1039 if (!input.name.empty())
1044 ImGui::BeginDisabled();
1046 ImGui::PushStyleColor(ImGuiCol_Text, textColor);
1047 ImGui::TextUnformatted(input.name.c_str());
1048 ImGui::PopStyleColor();
1051 ImGui::EndDisabled();
1055 ImGui::PopStyleVar();
1063 ImGui::Spring(1, 0);
1064 ImGui::PushStyleColor(ImGuiCol_Text, textColor);
1065 ImGui::TextUnformatted(node->name.c_str());
1066 ImGui::PopStyleColor();
1067 ImGui::Spring(1, 0);
1070 for (
const auto& output : node->outputPins)
1077 auto alpha = ImGui::GetStyle().Alpha;
1081 alpha = alpha * (48.0F / 255.0F);
1084 ImGui::PushStyleVar(ImGuiStyleVar_Alpha, alpha);
1085 builder.
Output(output.id);
1086 if (!output.name.empty())
1092 ImGui::BeginDisabled();
1094 ImGui::PushStyleColor(ImGuiCol_Text, textColor);
1095 ImGui::TextUnformatted(output.name.c_str());
1096 ImGui::PopStyleColor();
1099 ImGui::EndDisabled();
1103 output.drawPinIcon(output.isPinLinked(),
static_cast<int>(alpha * 255));
1104 if (ImGui::IsItemHovered()) { tooltipText = fmt::format(
"{}", fmt::join(output.dataIdentifier,
"\n")); }
1107 auto cursor = ImGui::GetCursorPos();
1108 std::string text = fmt::format(
"{}", output.noMoreDataAvailable ?
"F" :
"P");
1109 auto* drawList = ImGui::GetWindowDrawList();
1110 drawList->AddText(ImVec2(cursor.x - 26.0F, cursor.y + 2.F), IM_COL32(255, 0, 0, 255), text.c_str());
1113 ImGui::PopStyleVar();
1127 ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.75F);
1130 ed::BeginNode(node->id);
1131 ImGui::PushID(node->id.AsPointer());
1132 ImGui::BeginVertical(
"content");
1133 ImGui::BeginHorizontal(
"horizontal");
1136 ImGui::TextUnformatted(node->name.c_str());
1137 ImGui::PopStyleColor();
1139 ImGui::EndHorizontal();
1140 ed::Group(node->_size);
1141 ImGui::EndVertical();
1144 ed::PopStyleColor(2);
1145 ImGui::PopStyleVar();
1150 for (
const auto& output : node->outputPins)
1152 auto color = output.getIconColor();
1155 color = darkMode ? ImColor{ 0, 0, 0 } : ImColor{ 255, 255, 255 };
1158 for (
const auto& link : output.links)
1160 ed::Link(link.linkId, output.id, link.connectedPinId, color, 2.0F *
defaultFontRatio());
1167 if (ed::BeginCreate(ImColor(255, 255, 255), 2.0F))
1169 auto showLabel = [](
const char* label, ImColor color) {
1170 ImGui::SetCursorPosY(ImGui::GetCursorPosY() - ImGui::GetTextLineHeight());
1171 auto size = ImGui::CalcTextSize(label);
1173 auto padding = ImGui::GetStyle().FramePadding;
1174 auto spacing = ImGui::GetStyle().ItemSpacing;
1176 ImGui::SetCursorPos(ImGui::GetCursorPos() + ImVec2(spacing.x, -spacing.y));
1178 auto rectMin = ImGui::GetCursorScreenPos() - padding;
1179 auto rectMax = ImGui::GetCursorScreenPos() + size + padding;
1181 auto* drawList = ImGui::GetWindowDrawList();
1182 drawList->AddRectFilled(rectMin, rectMax, color, size.y * 0.15F);
1183 ImGui::TextUnformatted(label);
1186 ed::PinId startPinId = 0;
1187 ed::PinId endPinId = 0;
1188 if (ed::QueryNewLink(&startPinId, &endPinId))
1195 newLinkPin = startPin ? startPin : endPin;
1199 std::swap(startPin, endPin);
1200 std::swap(startPinId, endPinId);
1203 if (startPin && endPin)
1205 if (endPin == startPin)
1207 ed::RejectNewItem(ImColor(255, 0, 0), 2.0F);
1209 else if (endPin->
kind == startPin->
kind)
1211 showLabel(
"x Incompatible Pin Kind", ImColor(45, 32, 32, 180));
1212 ed::RejectNewItem(ImColor(255, 0, 0), 2.0F);
1216 showLabel(
"x Cannot connect to self", ImColor(45, 32, 32, 180));
1217 ed::RejectNewItem(ImColor(255, 0, 0), 1.0F);
1219 else if (endPin->
type != startPin->
type)
1221 showLabel(
"x Incompatible Pin Type", ImColor(45, 32, 32, 180));
1222 ed::RejectNewItem(ImColor(255, 128, 128), 1.0F);
1224 else if (
reinterpret_cast<InputPin*
>(endPin)->isPinLinked())
1226 showLabel(
"End Pin already linked", ImColor(45, 32, 32, 180));
1227 ed::RejectNewItem(ImColor(255, 128, 128), 1.0F);
1232 showLabel(fmt::format(
"The data type [{}]\ncan't be linked to [{}]",
1236 ImColor(45, 32, 32, 180));
1237 ed::RejectNewItem(ImColor(255, 128, 128), 1.0F);
1245 showLabel(fmt::format(
"The delegate type [{}]\ncan't be linked to [{}]",
1249 ImColor(45, 32, 32, 180));
1252 ed::RejectNewItem(ImColor(255, 128, 128), 1.0F);
1257 showLabel(fmt::format(
"The data type [{}]\ncan't be linked to [{}]",
1261 ImColor(45, 32, 32, 180));
1262 ed::RejectNewItem(ImColor(255, 128, 128), 1.0F);
1266 showLabel(
"+ Create Link", ImColor(32, 45, 32, 180));
1267 if (ed::AcceptNewItem(ImColor(128, 255, 128), 4.0F))
1269 reinterpret_cast<OutputPin*
>(startPin)->createLink(*
reinterpret_cast<InputPin*
>(endPin));
1275 ed::PinId pinId = 0;
1276 if (ed::QueryNewNode(&pinId))
1283 showLabel(
"End Pin already linked", ImColor(45, 32, 32, 180));
1284 ed::RejectNewItem(ImColor(255, 128, 128), 1.0F);
1290 showLabel(
"+ Create Node", ImColor(32, 45, 32, 180));
1293 if (ed::AcceptNewItem())
1295 createNewNode =
true;
1298 newLinkPin =
nullptr;
1300 ImGui::OpenPopup(
"Create New Node");
1308 newLinkPin =
nullptr;
1313 if (ed::BeginDelete())
1315 ed::LinkId linkId = 0;
1316 while (ed::QueryDeletedLink(&linkId))
1318 if (ed::AcceptDeletedItem())
1320 bool deleted =
false;
1323 if (deleted) {
break; }
1324 for (
auto& output : node->outputPins)
1326 if (deleted) {
break; }
1327 for (
const auto& link : output.links)
1329 if (link.linkId == linkId)
1331 output.deleteLink(*link.getConnectedPin());
1341 ed::NodeId nodeId = 0;
1342 while (ed::QueryDeletedNode(&nodeId))
1346 if (node->isTransient())
1351 if (ed::AcceptDeletedItem())
1360 ImGui::SetCursorScreenPos(cursorTopLeft);
1364 ax::NodeEditor::EnableShortcuts(ed::IsActive() || leftPaneActive);
1368 if (ed::ShowNodeContextMenu(&contextNodeId))
1370 ImGui::OpenPopup(
"Node Context Menu");
1372 else if (ed::ShowPinContextMenu(&contextPinId))
1374 ImGui::OpenPopup(
"Pin Context Menu");
1376 else if (ed::ShowLinkContextMenu(&contextLinkId) && ed::IsActive())
1378 ImGui::OpenPopup(
"Link Context Menu");
1380 else if (ed::ShowBackgroundContextMenu() && ed::IsActive())
1382 ImGui::OpenPopup(
"Create New Node");
1383 newNodeLinkPin =
nullptr;
1385 else if (ed::NodeId doubleClickedNodeId = ed::GetDoubleClickedNode())
1394 ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8, 8));
1395 static Node* renameNode =
nullptr;
1396 static Pin* renamePin =
nullptr;
1397 if (ImGui::BeginPopup(
"Node Context Menu"))
1401 ImGui::TextUnformatted(
"Node Context Menu");
1405 ImGui::Text(
"ID: %lu",
size_t(node->id));
1406 ImGui::Text(
"Type: %s", node->type().c_str());
1407 ImGui::Text(
"Kind: %s", std::string(node->kind).c_str());
1408 ImGui::Text(
"Inputs: %lu", node->inputPins.size());
1409 ImGui::Text(
"Outputs: %lu", node->outputPins.size());
1410 ImGui::Text(
"State: %s",
Node::toString(node->getState()).c_str());
1415 if (ImGui::MenuItem(node->isInitialized() ?
"Reinitialize" :
"Initialize",
"",
1418 if (node->isInitialized()) { node->doReinitialize(); }
1419 else { node->doInitialize(); }
1421 if (ImGui::MenuItem(
"Deinitialize",
"",
false, node->isInitialized()))
1423 node->doDeinitialize();
1425 if (ImGui::MenuItem(
"Wake Worker"))
1430 if (node->_hasConfig && ImGui::MenuItem(
"Configure",
"",
false))
1432 node->_showConfig =
true;
1433 node->_configWindowFocus =
true;
1435 if (ImGui::MenuItem(node->isDisabled() ?
"Enable" :
"Disable",
"",
false, !node->isTransient()))
1437 if (node->isDisabled())
1448 if (ImGui::MenuItem(
"Rename"))
1453 if (ImGui::MenuItem(
"Delete",
"",
false, !node->isTransient()))
1455 ed::DeleteNode(contextNodeId);
1460 ImGui::Text(
"Unknown node: %lu",
size_t(contextNodeId));
1471 if (ImGui::BeginPopup(
"Pin Context Menu"))
1473 ImGui::TextUnformatted(
"Pin Context Menu");
1477 ImGui::Text(
"ID: %lu",
size_t(pin->id));
1478 ImGui::Text(
"Node: %s", pin->parentNode ? std::to_string(
size_t(pin->parentNode->id)).c_str() :
"<none>");
1479 ImGui::Text(
"Type: %s", std::string(pin->type).c_str());
1481 if (pin->isPinLinked())
1483 const auto& link = pin->link;
1484 ImGui::SetNextItemOpen(
true, ImGuiCond_Appearing);
1485 if (ImGui::TreeNode(fmt::format(
"LinkId: {}",
size_t(link.linkId)).c_str()))
1487 ImGui::BulletText(
"Connected Node: %s", link.connectedNode->nameId().c_str());
1488 ImGui::BulletText(
"Connected Pin: %s (%zu)", link.getConnectedPin()->name.c_str(),
1489 size_t(link.getConnectedPin()->id));
1493 else { ImGui::TextUnformatted(
"Link: Not linked"); }
1495 if (ImGui::TreeNode(fmt::format(
"Queue: {}", pin->queue.size()).c_str()))
1497 ImGui::BeginChild(
"QueueItems", ImVec2(ImGui::GetContentRegionAvail().x, 150),
false, ImGuiWindowFlags_None);
1498 for (
size_t i = 0; i < pin->queue.size(); i++)
1500 ImGui::Text(
"%s", std::string(pin->queue.at(i)->insTime.toYMDHMS()).c_str());
1506 ImGui::Text(
"Queue blocked: %s", pin->queueBlocked ?
"true" :
"false");
1507 ImGui::Text(
"Temporal check: %s", pin->neededForTemporalQueueCheck ?
"true" :
"false");
1508 ImGui::Text(
"Drop queue: %s", pin->dropQueueIfNotFirable ?
"true" :
"false");
1510 if (ImGui::MenuItem(
"Rename")) { renamePin = pin; }
1514 ImGui::Text(
"ID: %lu",
size_t(pin->id));
1515 ImGui::Text(
"Node: %s", pin->parentNode ? std::to_string(
size_t(pin->parentNode->id)).c_str() :
"<none>");
1516 ImGui::Text(
"Type: %s", std::string(pin->type).c_str());
1517 ImGui::Text(
"Data available: %s", pin->noMoreDataAvailable ?
"No" :
"Yes");
1518 if (!pin->blocksConnectedNodeFromFinishing)
1520 ImGui::TextUnformatted(
"Does not block connected pin from finishing!!!");
1523 if (pin->isPinLinked())
1525 ImGui::SetNextItemOpen(
true, ImGuiCond_Appearing);
1526 if (ImGui::TreeNode(fmt::format(
"Links: {}", pin->links.size()).c_str()))
1528 for (
const auto& link : pin->links)
1530 ImGui::SetNextItemOpen(
true, ImGuiCond_Appearing);
1531 if (ImGui::TreeNode(fmt::format(
"LinkId: {}",
size_t(link.linkId)).c_str()))
1533 ImGui::BulletText(
"Connected Node: %s", link.connectedNode->nameId().c_str());
1534 ImGui::BulletText(
"Connected Pin: %s (%zu)", link.getConnectedPin()->name.c_str(),
1535 size_t(link.getConnectedPin()->id));
1542 else { ImGui::TextUnformatted(
"Link: Not linked"); }
1544 if (ImGui::MenuItem(
"Rename"))
1551 ImGui::Text(
"Unknown pin: %lu",
size_t(contextPinId));
1562 if (ImGui::BeginPopup(
"Link Context Menu"))
1564 ax::NodeEditor::PinId startPinId = 0;
1565 ax::NodeEditor::PinId endPinId = 0;
1568 if (startPinId) {
break; }
1569 for (
const auto& output : node->outputPins)
1571 if (startPinId) {
break; }
1572 for (
const auto& link : output.links)
1574 if (link.linkId == contextLinkId)
1576 startPinId = output.id;
1577 endPinId = link.connectedPinId;
1584 ImGui::TextUnformatted(
"Link Context Menu");
1588 ImGui::Text(
"ID: %lu",
size_t(contextLinkId));
1589 ImGui::Text(
"From: %lu",
size_t(startPinId));
1590 ImGui::Text(
"To: %lu",
size_t(endPinId));
1594 ImGui::Text(
"Unknown link: %lu",
size_t(contextLinkId));
1597 if (ImGui::MenuItem(
"Delete"))
1599 ed::DeleteLink(contextLinkId);
1604 static bool setKeyboardFocus =
true;
1605 static ImVec2 newNodeSpawnPos{ -1, -1 };
1606 if (ImGui::BeginPopup(
"Create New Node"))
1608 if (newNodeSpawnPos.x == -1 || newNodeSpawnPos.y == -1)
1610 auto viewRect =
reinterpret_cast<ax::NodeEditor::Detail::EditorContext*
>(ed::GetCurrentEditor())->GetViewRect();
1611 newNodeSpawnPos = ImGui::GetMousePos();
1615 newNodeSpawnPos *= ed::GetCurrentZoom();
1617 newNodeSpawnPos += viewRect.GetTL();
1619 LOG_DEBUG(
"New Node will spawn at {}x{} - Zoom {}", newNodeSpawnPos.x, newNodeSpawnPos.y, ed::GetCurrentZoom());
1622 if (setKeyboardFocus)
1624 ImGui::SetKeyboardFocusHere(0);
1626 static ImGuiTextFilter filter;
1628 filter.Draw(
"##NewNodeFilter");
1630 if (setKeyboardFocus)
1633 setKeyboardFocus =
false;
1636 Node* node =
nullptr;
1640 bool categoryHasItems =
false;
1641 for (
const auto& nodeInfo : nodeInfoList)
1643 if (nodeInfo.hasCompatiblePin(newNodeLinkPin)
1644 && (filter.PassFilter(nodeInfo.type.c_str()) || filter.PassFilter(category.c_str())))
1646 categoryHasItems =
true;
1650 if (categoryHasItems)
1652 ImGui::SetNextItemOpen(
true, ImGuiCond_Once);
1653 if (ImGui::TreeNode((category +
"##NewNodeTree").c_str()))
1655 for (
const auto& nodeInfo : nodeInfoList)
1657 const auto& displayName = nodeInfo.type;
1658 const auto& constructor = nodeInfo.constructor;
1660 if (nodeInfo.hasCompatiblePin(newNodeLinkPin)
1661 && (filter.PassFilter(nodeInfo.type.c_str()) || filter.PassFilter(category.c_str()))
1662 && ImGui::MenuItem(displayName.c_str()))
1665 node = constructor();
1677 createNewNode =
false;
1679 ed::SetNodePosition(node->
id, newNodeSpawnPos);
1680 newNodeSpawnPos = { -1, -1 };
1682 if (
auto* startPin = newNodeLinkPin)
1688 if (
reinterpret_cast<InputPin*
>(startPin)->canCreateLink(pin))
1690 pin.createLink(*
reinterpret_cast<InputPin*
>(startPin));
1699 if (
reinterpret_cast<OutputPin*
>(startPin)->canCreateLink(pin))
1701 reinterpret_cast<OutputPin*
>(startPin)->createLink(pin);
1713 setKeyboardFocus =
true;
1714 createNewNode =
false;
1715 newNodeSpawnPos = { -1, -1 };
1717 ImGui::PopStyleVar();
1721 if (node->_hasConfig && node->_showConfig)
1723 ImVec2 center(ImGui::GetIO().DisplaySize.x * 0.5F, ImGui::GetIO().DisplaySize.y * 0.5F);
1724 if (node->_configWindowFocus)
1726 ImGui::SetNextWindowCollapsed(
false);
1727 ImGui::SetNextWindowFocus();
1728 node->_configWindowFocus =
false;
1730 ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5F, 0.5F));
1731 ImGui::SetNextWindowSize(node->_guiConfigDefaultWindowSize, ImGuiCond_FirstUseEver);
1732 if (!node->_configWindowMutex.try_lock())
1734 ImGui::SetNextWindowCollapsed(
true, ImGuiCond_Always);
1735 node->_configWindowForceCollapse =
true;
1739 node->_configWindowMutex.unlock();
1740 if (node->_configWindowForceCollapse)
1742 LOG_TRACE(
"Setting next window collapsed: {}", node->_configWindowIsCollapsed);
1743 ImGui::SetNextWindowCollapsed(node->_configWindowIsCollapsed);
1744 node->_configWindowForceCollapse =
false;
1747 if (ImGui::Begin(fmt::format(
"{} ({})", node->nameId(), node->type()).c_str(), &(node->_showConfig),
1748 ImGuiWindowFlags_None))
1750 ImGui::PushFont(WindowFont());
1752 if (locked) { ImGui::BeginDisabled(); }
1753 if (!node->_configWindowForceCollapse)
1755 node->_configWindowIsCollapsed =
false;
1758 if (locked) { ImGui::EndDisabled(); }
1763 if (!node->_configWindowForceCollapse) { node->_configWindowIsCollapsed =
true; }
1764 if (ImGui::IsWindowFocused())
1766 ed::EnableShortcuts(
true);
1777 ImGui::PushFont(PanelFont());
1779 ImGui::SetNextItemOpen(
true, ImGuiCond_Once);
1780 if (ImGui::BeginTabBar(
"BottomViewTabBar"))
1785 ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.0F);
1787 if (ImGui::BeginTabItem(
"▼"))
1791 ImGui::EndTabItem();
1799 ImGui::PopStyleVar();
1802 if (ImGui::BeginTabItem(
"Log Output",
nullptr, firstFrame ? ImGuiTabItemFlags_SetSelected : ImGuiTabItemFlags_None))
1804 static int scrollToBottom = 0;
1811 static bool autoScroll =
true;
1812 static ImGuiTextFilter textFilter;
1815 if (ImGui::BeginPopup(
"Options"))
1817 ImGui::Checkbox(
"Auto-scroll", &autoScroll);
1822 if (ImGui::Button(
"Options"))
1824 ImGui::OpenPopup(
"Options");
1828 static int logLevelFilterSelected = spdlog::level::info;
1829 if (ImGui::BeginCombo(
"##LogLevelCombo", spdlog::level::to_string_view(
static_cast<spdlog::level::level_enum
>(logLevelFilterSelected)).begin()))
1831 for (
int n = spdlog::level::debug; n < spdlog::level::critical; n++)
1833 const bool is_selected = (logLevelFilterSelected == n);
1834 if (ImGui::Selectable(spdlog::level::to_string_view(
static_cast<spdlog::level::level_enum
>(n)).begin(), is_selected))
1836 logLevelFilterSelected = n;
1842 ImGui::SetItemDefaultFocus();
1848 textFilter.Draw(
"Filter", -100.0F);
1851 ImGui::BeginChild(
"scrolling", ImVec2(0, 0),
false, ImGuiWindowFlags_HorizontalScrollbar);
1853 ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
1854 ImGui::PushFont(MonoFont());
1858 for (
auto& logLine : logMessages)
1860 for (
int n = logLevelFilterSelected; n < spdlog::level::n_levels; n++)
1862 if (logLine.find(fmt::format(
"] [{}]", spdlog::level::to_short_c_str(
static_cast<spdlog::level::level_enum
>(n)))) != std::string::npos)
1864 if (!textFilter.IsActive() || textFilter.PassFilter(logLine.c_str()))
1879 ImGui::PopStyleVar();
1883 ImGui::SetScrollHereY(1.0F);
1886 else if (autoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY())
1888 ImGui::SetScrollHereY(1.0F);
1893 ImGui::EndTabItem();
1905 if (!tooltipText.empty()) { ImGui::SetTooltip(
"%s", tooltipText.c_str()); }
1907 ImGui::PushFont(WindowFont());
1914 SetTitle(title.c_str());