807 bool firstFrame = ImGui::GetFrameCount() == 1;
812 ed::NavigateToContent();
838 if (ed::AreShortcutsEnabled())
843 ImGui::PushFont(PanelFont());
848 ed::SetCurrentEditor(m_Editor);
850 static ed::NodeId contextNodeId = 0;
851 static ed::LinkId contextLinkId = 0;
852 static ed::PinId contextPinId = 0;
853 static bool createNewNode =
false;
854 static Pin* newNodeLinkPin =
nullptr;
856 bool leftPaneActive =
false;
861 ImGui::PushFont(PanelFont());
865 ImGui::SameLine(0.0F, 12.0F);
869 std::string tooltipText;
873 bool darkMode = ax::NodeEditor::GetStyle().Colors[ax::NodeEditor::StyleColor_Bg].x
874 + ax::NodeEditor::GetStyle().Colors[ax::NodeEditor::StyleColor_Bg].y
875 + ax::NodeEditor::GetStyle().Colors[ax::NodeEditor::StyleColor_Bg].z
880 float blueprintHeight = ImGui::GetContentRegionAvail().y -
bottomViewHeight + (isUsingBigPanelFont() ? 48.5F : 28.5F);
881 ImGui::PushStyleColor(ImGuiCol_Separator, IM_COL32_BLACK_TRANS);
883 ImGui::PopStyleColor();
888 static Pin* newLinkPin =
nullptr;
890 auto cursorTopLeft = ImGui::GetCursorScreenPos();
894 auto textColor = ax::NodeEditor::GetStyle().Colors[ax::NodeEditor::StyleColor_NodeBg].x
895 + ax::NodeEditor::GetStyle().Colors[ax::NodeEditor::StyleColor_NodeBg].y
896 + ax::NodeEditor::GetStyle().Colors[ax::NodeEditor::StyleColor_NodeBg].z
898 ? IM_COL32(0, 0, 0, 255)
899 : IM_COL32(255, 255, 255, 255);
910 bool hasOutputDelegates =
false;
911 for (
const auto& output : node->outputPins)
915 hasOutputDelegates =
true;
919 builder.
Begin(node->id);
923 if (node->isDisabled())
925 builder.
Header(ImColor(192, 192, 192));
927 else if (node->isInitialized())
929 builder.
Header(ImColor(128, 255, 128));
933 builder.
Header(ImColor(255, 128, 128));
936 ImGui::PushStyleColor(ImGuiCol_Text, textColor);
937 ImGui::TextUnformatted(node->name.c_str());
938 ImGui::PopStyleColor();
958 ImGui::Dummy(ImVec2(ImGui::GetStyle().ItemSpacing.x + 12.0F + ImGui::GetStyle().FramePadding.x, 26));
960 if (hasOutputDelegates)
962 ImGui::BeginVertical(
"delegates", ImVec2(0, 26));
964 for (
const auto& output : node->outputPins)
971 auto alpha = ImGui::GetStyle().Alpha;
975 alpha = alpha * (48.0F / 255.0F);
978 ed::BeginPin(output.id, ed::PinKind::Output);
979 ed::PinPivotAlignment(ImVec2(1.0F, 0.5F));
980 ed::PinPivotSize(ImVec2(0, 0));
981 ImGui::BeginHorizontal(output.id.AsPointer());
982 ImGui::PushStyleVar(ImGuiStyleVar_Alpha, alpha);
990 output.drawPinIcon(output.isPinLinked(),
static_cast<int>(alpha * 255));
991 ImGui::Spring(0, ImGui::GetStyle().ItemSpacing.x / 2);
992 ImGui::EndHorizontal();
993 ImGui::PopStyleVar();
999 ImGui::EndVertical();
1000 ImGui::Spring(0, ImGui::GetStyle().ItemSpacing.x / 2);
1009 for (
auto& input : node->inputPins)
1011 auto alpha = ImGui::GetStyle().Alpha;
1015 alpha = alpha * (48.0F / 255.0F);
1018 builder.
Input(input.id);
1019 ImGui::PushStyleVar(ImGuiStyleVar_Alpha, alpha);
1020 input.drawPinIcon(input.isPinLinked(),
static_cast<int>(alpha * 255));
1021 if (ImGui::IsItemHovered()) { tooltipText = fmt::format(
"{}", fmt::join(input.dataIdentifier,
"\n")); }
1024 auto cursor = ImGui::GetCursorPos();
1025 std::string text = fmt::format(
"{}{}", input.queue.size(), input.queueBlocked ?
"*" :
"");
1026 auto* drawList = ImGui::GetWindowDrawList();
1027 drawList->AddText(ImVec2(cursor.x - 26.0F, cursor.y + 2.F), IM_COL32(255, 0, 0, 255), text.c_str());
1031 if (!input.name.empty())
1036 ImGui::BeginDisabled();
1038 ImGui::PushStyleColor(ImGuiCol_Text, textColor);
1039 ImGui::TextUnformatted(input.name.c_str());
1040 ImGui::PopStyleColor();
1043 ImGui::EndDisabled();
1047 ImGui::PopStyleVar();
1055 ImGui::Spring(1, 0);
1056 ImGui::PushStyleColor(ImGuiCol_Text, textColor);
1057 ImGui::TextUnformatted(node->name.c_str());
1058 ImGui::PopStyleColor();
1059 ImGui::Spring(1, 0);
1062 for (
const auto& output : node->outputPins)
1069 auto alpha = ImGui::GetStyle().Alpha;
1073 alpha = alpha * (48.0F / 255.0F);
1076 ImGui::PushStyleVar(ImGuiStyleVar_Alpha, alpha);
1077 builder.
Output(output.id);
1078 if (!output.name.empty())
1084 ImGui::BeginDisabled();
1086 ImGui::PushStyleColor(ImGuiCol_Text, textColor);
1087 ImGui::TextUnformatted(output.name.c_str());
1088 ImGui::PopStyleColor();
1091 ImGui::EndDisabled();
1095 output.drawPinIcon(output.isPinLinked(),
static_cast<int>(alpha * 255));
1096 if (ImGui::IsItemHovered()) { tooltipText = fmt::format(
"{}", fmt::join(output.dataIdentifier,
"\n")); }
1099 auto cursor = ImGui::GetCursorPos();
1100 std::string text = fmt::format(
"{}", output.noMoreDataAvailable ?
"F" :
"P");
1101 auto* drawList = ImGui::GetWindowDrawList();
1102 drawList->AddText(ImVec2(cursor.x - 26.0F, cursor.y + 2.F), IM_COL32(255, 0, 0, 255), text.c_str());
1105 ImGui::PopStyleVar();
1119 ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.75F);
1122 ed::BeginNode(node->id);
1123 ImGui::PushID(node->id.AsPointer());
1124 ImGui::BeginVertical(
"content");
1125 ImGui::BeginHorizontal(
"horizontal");
1128 ImGui::TextUnformatted(node->name.c_str());
1129 ImGui::PopStyleColor();
1131 ImGui::EndHorizontal();
1132 ed::Group(node->_size);
1133 ImGui::EndVertical();
1136 ed::PopStyleColor(2);
1137 ImGui::PopStyleVar();
1142 for (
const auto& output : node->outputPins)
1144 auto color = output.getIconColor();
1147 color = darkMode ? ImColor{ 0, 0, 0 } : ImColor{ 255, 255, 255 };
1150 for (
const auto& link : output.links)
1152 ed::Link(link.linkId, output.id, link.connectedPinId, color, 2.0F *
defaultFontRatio());
1159 if (ed::BeginCreate(ImColor(255, 255, 255), 2.0F))
1161 auto showLabel = [](
const char* label, ImColor color) {
1162 ImGui::SetCursorPosY(ImGui::GetCursorPosY() - ImGui::GetTextLineHeight());
1163 auto size = ImGui::CalcTextSize(label);
1165 auto padding = ImGui::GetStyle().FramePadding;
1166 auto spacing = ImGui::GetStyle().ItemSpacing;
1168 ImGui::SetCursorPos(ImGui::GetCursorPos() + ImVec2(spacing.x, -spacing.y));
1170 auto rectMin = ImGui::GetCursorScreenPos() - padding;
1171 auto rectMax = ImGui::GetCursorScreenPos() + size + padding;
1173 auto* drawList = ImGui::GetWindowDrawList();
1174 drawList->AddRectFilled(rectMin, rectMax, color, size.y * 0.15F);
1175 ImGui::TextUnformatted(label);
1178 ed::PinId startPinId = 0;
1179 ed::PinId endPinId = 0;
1180 if (ed::QueryNewLink(&startPinId, &endPinId))
1187 newLinkPin = startPin ? startPin : endPin;
1191 std::swap(startPin, endPin);
1192 std::swap(startPinId, endPinId);
1195 if (startPin && endPin)
1197 if (endPin == startPin)
1199 ed::RejectNewItem(ImColor(255, 0, 0), 2.0F);
1201 else if (endPin->
kind == startPin->
kind)
1203 showLabel(
"x Incompatible Pin Kind", ImColor(45, 32, 32, 180));
1204 ed::RejectNewItem(ImColor(255, 0, 0), 2.0F);
1208 showLabel(
"x Cannot connect to self", ImColor(45, 32, 32, 180));
1209 ed::RejectNewItem(ImColor(255, 0, 0), 1.0F);
1211 else if (endPin->
type != startPin->
type)
1213 showLabel(
"x Incompatible Pin Type", ImColor(45, 32, 32, 180));
1214 ed::RejectNewItem(ImColor(255, 128, 128), 1.0F);
1216 else if (
reinterpret_cast<InputPin*
>(endPin)->isPinLinked())
1218 showLabel(
"End Pin already linked", ImColor(45, 32, 32, 180));
1219 ed::RejectNewItem(ImColor(255, 128, 128), 1.0F);
1224 showLabel(fmt::format(
"The data type [{}]\ncan't be linked to [{}]",
1228 ImColor(45, 32, 32, 180));
1229 ed::RejectNewItem(ImColor(255, 128, 128), 1.0F);
1237 showLabel(fmt::format(
"The delegate type [{}]\ncan't be linked to [{}]",
1241 ImColor(45, 32, 32, 180));
1244 ed::RejectNewItem(ImColor(255, 128, 128), 1.0F);
1249 showLabel(fmt::format(
"The data type [{}]\ncan't be linked to [{}]",
1253 ImColor(45, 32, 32, 180));
1254 ed::RejectNewItem(ImColor(255, 128, 128), 1.0F);
1258 showLabel(
"+ Create Link", ImColor(32, 45, 32, 180));
1259 if (ed::AcceptNewItem(ImColor(128, 255, 128), 4.0F))
1261 reinterpret_cast<OutputPin*
>(startPin)->createLink(*
reinterpret_cast<InputPin*
>(endPin));
1267 ed::PinId pinId = 0;
1268 if (ed::QueryNewNode(&pinId))
1275 showLabel(
"End Pin already linked", ImColor(45, 32, 32, 180));
1276 ed::RejectNewItem(ImColor(255, 128, 128), 1.0F);
1282 showLabel(
"+ Create Node", ImColor(32, 45, 32, 180));
1285 if (ed::AcceptNewItem())
1287 createNewNode =
true;
1290 newLinkPin =
nullptr;
1292 ImGui::OpenPopup(
"Create New Node");
1300 newLinkPin =
nullptr;
1305 if (ed::BeginDelete())
1307 ed::LinkId linkId = 0;
1308 while (ed::QueryDeletedLink(&linkId))
1310 if (ed::AcceptDeletedItem())
1312 bool deleted =
false;
1315 if (deleted) {
break; }
1316 for (
auto& output : node->outputPins)
1318 if (deleted) {
break; }
1319 for (
const auto& link : output.links)
1321 if (link.linkId == linkId)
1323 output.deleteLink(*link.getConnectedPin());
1333 ed::NodeId nodeId = 0;
1334 while (ed::QueryDeletedNode(&nodeId))
1338 if (node->isTransient())
1343 if (ed::AcceptDeletedItem())
1352 ImGui::SetCursorScreenPos(cursorTopLeft);
1356 ax::NodeEditor::EnableShortcuts(ed::IsActive() || leftPaneActive);
1360 if (ed::ShowNodeContextMenu(&contextNodeId))
1362 ImGui::OpenPopup(
"Node Context Menu");
1364 else if (ed::ShowPinContextMenu(&contextPinId))
1366 ImGui::OpenPopup(
"Pin Context Menu");
1368 else if (ed::ShowLinkContextMenu(&contextLinkId) && ed::IsActive())
1370 ImGui::OpenPopup(
"Link Context Menu");
1372 else if (ed::ShowBackgroundContextMenu() && ed::IsActive())
1374 ImGui::OpenPopup(
"Create New Node");
1375 newNodeLinkPin =
nullptr;
1377 else if (ed::NodeId doubleClickedNodeId = ed::GetDoubleClickedNode())
1386 ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8, 8));
1387 static Node* renameNode =
nullptr;
1388 static Pin* renamePin =
nullptr;
1389 if (ImGui::BeginPopup(
"Node Context Menu"))
1393 ImGui::TextUnformatted(
"Node Context Menu");
1397 ImGui::Text(
"ID: %lu",
size_t(node->id));
1398 ImGui::Text(
"Type: %s", node->type().c_str());
1399 ImGui::Text(
"Kind: %s", std::string(node->kind).c_str());
1400 ImGui::Text(
"Inputs: %lu", node->inputPins.size());
1401 ImGui::Text(
"Outputs: %lu", node->outputPins.size());
1402 ImGui::Text(
"State: %s",
Node::toString(node->getState()).c_str());
1407 if (ImGui::MenuItem(node->isInitialized() ?
"Reinitialize" :
"Initialize",
"",
1410 if (node->isInitialized()) { node->doReinitialize(); }
1411 else { node->doInitialize(); }
1413 if (ImGui::MenuItem(
"Deinitialize",
"",
false, node->isInitialized()))
1415 node->doDeinitialize();
1417 if (ImGui::MenuItem(
"Wake Worker"))
1422 if (node->_hasConfig && ImGui::MenuItem(
"Configure",
"",
false))
1424 node->_showConfig =
true;
1425 node->_configWindowFocus =
true;
1427 if (ImGui::MenuItem(node->isDisabled() ?
"Enable" :
"Disable",
"",
false, !node->isTransient()))
1429 if (node->isDisabled())
1440 if (ImGui::MenuItem(
"Rename"))
1445 if (ImGui::MenuItem(
"Delete",
"",
false, !node->isTransient()))
1447 ed::DeleteNode(contextNodeId);
1452 ImGui::Text(
"Unknown node: %lu",
size_t(contextNodeId));
1463 if (ImGui::BeginPopup(
"Pin Context Menu"))
1465 ImGui::TextUnformatted(
"Pin Context Menu");
1469 ImGui::Text(
"ID: %lu",
size_t(pin->id));
1470 ImGui::Text(
"Node: %s", pin->parentNode ? std::to_string(
size_t(pin->parentNode->id)).c_str() :
"<none>");
1471 ImGui::Text(
"Type: %s", std::string(pin->type).c_str());
1473 if (pin->isPinLinked())
1475 const auto& link = pin->link;
1476 ImGui::SetNextItemOpen(
true, ImGuiCond_Appearing);
1477 if (ImGui::TreeNode(fmt::format(
"LinkId: {}",
size_t(link.linkId)).c_str()))
1479 ImGui::BulletText(
"Connected Node: %s", link.connectedNode->nameId().c_str());
1480 ImGui::BulletText(
"Connected Pin: %s (%zu)", link.getConnectedPin()->name.c_str(),
1481 size_t(link.getConnectedPin()->id));
1485 else { ImGui::TextUnformatted(
"Link: Not linked"); }
1487 if (ImGui::TreeNode(fmt::format(
"Queue: {}", pin->queue.size()).c_str()))
1489 ImGui::BeginChild(
"QueueItems", ImVec2(ImGui::GetContentRegionAvail().x, 150),
false, ImGuiWindowFlags_None);
1490 for (
size_t i = 0; i < pin->queue.size(); i++)
1492 ImGui::Text(
"%s", std::string(pin->queue.at(i)->insTime.toYMDHMS()).c_str());
1498 ImGui::Text(
"Queue blocked: %s", pin->queueBlocked ?
"true" :
"false");
1499 ImGui::Text(
"Temporal check: %s", pin->neededForTemporalQueueCheck ?
"true" :
"false");
1500 ImGui::Text(
"Drop queue: %s", pin->dropQueueIfNotFirable ?
"true" :
"false");
1502 if (ImGui::MenuItem(
"Rename")) { renamePin = pin; }
1506 ImGui::Text(
"ID: %lu",
size_t(pin->id));
1507 ImGui::Text(
"Node: %s", pin->parentNode ? std::to_string(
size_t(pin->parentNode->id)).c_str() :
"<none>");
1508 ImGui::Text(
"Type: %s", std::string(pin->type).c_str());
1509 ImGui::Text(
"Data available: %s", pin->noMoreDataAvailable ?
"No" :
"Yes");
1510 if (!pin->blocksConnectedNodeFromFinishing)
1512 ImGui::TextUnformatted(
"Does not block connected pin from finishing!!!");
1515 if (pin->isPinLinked())
1517 ImGui::SetNextItemOpen(
true, ImGuiCond_Appearing);
1518 if (ImGui::TreeNode(fmt::format(
"Links: {}", pin->links.size()).c_str()))
1520 for (
const auto& link : pin->links)
1522 ImGui::SetNextItemOpen(
true, ImGuiCond_Appearing);
1523 if (ImGui::TreeNode(fmt::format(
"LinkId: {}",
size_t(link.linkId)).c_str()))
1525 ImGui::BulletText(
"Connected Node: %s", link.connectedNode->nameId().c_str());
1526 ImGui::BulletText(
"Connected Pin: %s (%zu)", link.getConnectedPin()->name.c_str(),
1527 size_t(link.getConnectedPin()->id));
1534 else { ImGui::TextUnformatted(
"Link: Not linked"); }
1536 if (ImGui::MenuItem(
"Rename"))
1543 ImGui::Text(
"Unknown pin: %lu",
size_t(contextPinId));
1554 if (ImGui::BeginPopup(
"Link Context Menu"))
1556 ax::NodeEditor::PinId startPinId = 0;
1557 ax::NodeEditor::PinId endPinId = 0;
1560 if (startPinId) {
break; }
1561 for (
const auto& output : node->outputPins)
1563 if (startPinId) {
break; }
1564 for (
const auto& link : output.links)
1566 if (link.linkId == contextLinkId)
1568 startPinId = output.id;
1569 endPinId = link.connectedPinId;
1576 ImGui::TextUnformatted(
"Link Context Menu");
1580 ImGui::Text(
"ID: %lu",
size_t(contextLinkId));
1581 ImGui::Text(
"From: %lu",
size_t(startPinId));
1582 ImGui::Text(
"To: %lu",
size_t(endPinId));
1586 ImGui::Text(
"Unknown link: %lu",
size_t(contextLinkId));
1589 if (ImGui::MenuItem(
"Delete"))
1591 ed::DeleteLink(contextLinkId);
1596 static bool setKeyboardFocus =
true;
1597 static ImVec2 newNodeSpawnPos{ -1, -1 };
1598 if (ImGui::BeginPopup(
"Create New Node"))
1600 if (newNodeSpawnPos.x == -1 || newNodeSpawnPos.y == -1)
1602 auto viewRect =
reinterpret_cast<ax::NodeEditor::Detail::EditorContext*
>(ed::GetCurrentEditor())->GetViewRect();
1603 newNodeSpawnPos = ImGui::GetMousePos();
1607 newNodeSpawnPos *= ed::GetCurrentZoom();
1609 newNodeSpawnPos += viewRect.GetTL();
1611 LOG_DEBUG(
"New Node will spawn at {}x{} - Zoom {}", newNodeSpawnPos.x, newNodeSpawnPos.y, ed::GetCurrentZoom());
1614 if (setKeyboardFocus)
1616 ImGui::SetKeyboardFocusHere(0);
1618 static ImGuiTextFilter filter;
1620 filter.Draw(
"##NewNodeFilter");
1622 if (setKeyboardFocus)
1625 setKeyboardFocus =
false;
1628 Node* node =
nullptr;
1632 bool categoryHasItems =
false;
1633 for (
const auto& nodeInfo : nodeInfoList)
1635 if (nodeInfo.hasCompatiblePin(newNodeLinkPin)
1636 && (filter.PassFilter(nodeInfo.type.c_str()) || filter.PassFilter(category.c_str())))
1638 categoryHasItems =
true;
1642 if (categoryHasItems)
1644 ImGui::SetNextItemOpen(
true, ImGuiCond_Once);
1645 if (ImGui::TreeNode((category +
"##NewNodeTree").c_str()))
1647 for (
const auto& nodeInfo : nodeInfoList)
1649 const auto& displayName = nodeInfo.type;
1650 const auto& constructor = nodeInfo.constructor;
1652 if (nodeInfo.hasCompatiblePin(newNodeLinkPin)
1653 && (filter.PassFilter(nodeInfo.type.c_str()) || filter.PassFilter(category.c_str()))
1654 && ImGui::MenuItem(displayName.c_str()))
1657 node = constructor();
1669 createNewNode =
false;
1671 ed::SetNodePosition(node->
id, newNodeSpawnPos);
1672 newNodeSpawnPos = { -1, -1 };
1674 if (
auto* startPin = newNodeLinkPin)
1680 if (
reinterpret_cast<InputPin*
>(startPin)->canCreateLink(pin))
1682 pin.createLink(*
reinterpret_cast<InputPin*
>(startPin));
1691 if (
reinterpret_cast<OutputPin*
>(startPin)->canCreateLink(pin))
1693 reinterpret_cast<OutputPin*
>(startPin)->createLink(pin);
1705 setKeyboardFocus =
true;
1706 createNewNode =
false;
1707 newNodeSpawnPos = { -1, -1 };
1709 ImGui::PopStyleVar();
1713 if (node->_hasConfig && node->_showConfig)
1715 ImVec2 center(ImGui::GetIO().DisplaySize.x * 0.5F, ImGui::GetIO().DisplaySize.y * 0.5F);
1716 if (node->_configWindowFocus)
1718 ImGui::SetNextWindowCollapsed(
false);
1719 ImGui::SetNextWindowFocus();
1720 node->_configWindowFocus =
false;
1722 ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5F, 0.5F));
1723 ImGui::SetNextWindowSize(node->_guiConfigDefaultWindowSize, ImGuiCond_FirstUseEver);
1724 if (!node->_configWindowMutex.try_lock())
1726 ImGui::SetNextWindowCollapsed(
true, ImGuiCond_Always);
1727 node->_configWindowForceCollapse =
true;
1731 node->_configWindowMutex.unlock();
1732 if (node->_configWindowForceCollapse)
1734 LOG_TRACE(
"Setting next window collapsed: {}", node->_configWindowIsCollapsed);
1735 ImGui::SetNextWindowCollapsed(node->_configWindowIsCollapsed);
1736 node->_configWindowForceCollapse =
false;
1739 if (ImGui::Begin(fmt::format(
"{} ({})", node->nameId(), node->type()).c_str(), &(node->_showConfig),
1740 ImGuiWindowFlags_None))
1742 ImGui::PushFont(WindowFont());
1744 if (locked) { ImGui::BeginDisabled(); }
1745 if (!node->_configWindowForceCollapse)
1747 node->_configWindowIsCollapsed =
false;
1750 if (locked) { ImGui::EndDisabled(); }
1755 if (!node->_configWindowForceCollapse) { node->_configWindowIsCollapsed =
true; }
1756 if (ImGui::IsWindowFocused())
1758 ed::EnableShortcuts(
true);
1769 ImGui::PushFont(PanelFont());
1771 ImGui::SetNextItemOpen(
true, ImGuiCond_Once);
1772 if (ImGui::BeginTabBar(
"BottomViewTabBar"))
1777 ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.0F);
1779 if (ImGui::BeginTabItem(
"▼"))
1783 ImGui::EndTabItem();
1791 ImGui::PopStyleVar();
1794 if (ImGui::BeginTabItem(
"Log Output",
nullptr, firstFrame ? ImGuiTabItemFlags_SetSelected : ImGuiTabItemFlags_None))
1796 static int scrollToBottom = 0;
1803 static bool autoScroll =
true;
1804 static ImGuiTextFilter textFilter;
1807 if (ImGui::BeginPopup(
"Options"))
1809 ImGui::Checkbox(
"Auto-scroll", &autoScroll);
1814 if (ImGui::Button(
"Options"))
1816 ImGui::OpenPopup(
"Options");
1820 static int logLevelFilterSelected = spdlog::level::info;
1821 if (ImGui::BeginCombo(
"##LogLevelCombo", spdlog::level::to_string_view(
static_cast<spdlog::level::level_enum
>(logLevelFilterSelected)).begin()))
1823 for (
int n = spdlog::level::debug; n < spdlog::level::critical; n++)
1825 const bool is_selected = (logLevelFilterSelected == n);
1826 if (ImGui::Selectable(spdlog::level::to_string_view(
static_cast<spdlog::level::level_enum
>(n)).begin(), is_selected))
1828 logLevelFilterSelected = n;
1834 ImGui::SetItemDefaultFocus();
1840 textFilter.Draw(
"Filter", -100.0F);
1843 ImGui::BeginChild(
"scrolling", ImVec2(0, 0),
false, ImGuiWindowFlags_HorizontalScrollbar);
1845 ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
1846 ImGui::PushFont(MonoFont());
1850 for (
auto& logLine : logMessages)
1852 for (
int n = logLevelFilterSelected; n < spdlog::level::n_levels; n++)
1854 if (logLine.find(fmt::format(
"] [{}]", spdlog::level::to_short_c_str(
static_cast<spdlog::level::level_enum
>(n)))) != std::string::npos)
1856 if (!textFilter.IsActive() || textFilter.PassFilter(logLine.c_str()))
1871 ImGui::PopStyleVar();
1875 ImGui::SetScrollHereY(1.0F);
1878 else if (autoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY())
1880 ImGui::SetScrollHereY(1.0F);
1885 ImGui::EndTabItem();
1897 if (!tooltipText.empty()) { ImGui::SetTooltip(
"%s", tooltipText.c_str()); }
1899 ImGui::PushFont(WindowFont());
1906 SetTitle(title.c_str());