0.4.1
Loading...
Searching...
No Matches
LeftPane.cpp
Go to the documentation of this file.
1// This file is part of INSTINCT, the INS Toolkit for Integrated
2// Navigation Concepts and Training by the Institute of Navigation of
3// the University of Stuttgart, Germany.
4//
5// This Source Code Form is subject to the terms of the Mozilla Public
6// License, v. 2.0. If a copy of the MPL was not distributed with this
7// file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9#include "LeftPane.hpp"
10
11#include <imgui_node_editor.h>
12#include <imgui_internal.h>
13
15namespace nm = NAV::NodeManager;
16
19
20#include "util/StringUtil.hpp"
21
22#include <string>
23#include <algorithm>
24
25namespace ed = ax::NodeEditor;
26
27bool NAV::gui::panels::ShowLeftPane(float paneWidth)
28{
29 auto& io = ImGui::GetIO();
30
31 bool paneActive = false;
32
33 float insLogoWidth = paneWidth < 150 ? paneWidth : 150;
34
35 float insLogoHeight = insLogoWidth * 2967.0F / 4073.0F;
36 float childHeight = ImGui::GetContentRegionAvail().y - insLogoHeight;
37
38 ImGui::BeginGroup();
39
40 ImGui::BeginChild("Selection", ImVec2(paneWidth, childHeight));
41
42 paneWidth = ImGui::GetContentRegionAvail().x;
43
44 float colSum = ImGui::GetStyle().Colors[ImGuiCol_WindowBg].x + ImGui::GetStyle().Colors[ImGuiCol_WindowBg].y + ImGui::GetStyle().Colors[ImGuiCol_WindowBg].z;
45 ImTextureID instinctLogo = NodeEditorApplication::m_InstinctLogo.at(colSum > 2.0F ? 1 : 0);
46 ImTextureID insLogo = NodeEditorApplication::m_InsLogo.at(colSum > 2.0F ? 1 : 0);
47
48 ImGui::Image(instinctLogo, ImVec2(paneWidth, paneWidth * 3000.0F / 13070.0F));
49 ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5.0F);
50
51 { // Control Buttons
52 ImGui::BeginHorizontal("Control Buttons", ImVec2(paneWidth, 0));
53 ImGui::Spring(0.0F, 0.0F);
54 if (ImGui::Button("Zoom to Content"))
55 {
56 ed::NavigateToContent();
57 }
58 if (ImGui::IsItemHovered())
59 {
60 ImGui::SetTooltip("Shortcut: F");
61 }
62 ImGui::Spring();
63 ImGui::EndHorizontal();
64 }
65
66 std::vector<ed::NodeId> selectedNodes;
67 std::vector<ed::LinkId> selectedLinks;
68 selectedNodes.resize(static_cast<size_t>(ed::GetSelectedObjectCount()));
69 selectedLinks.resize(static_cast<size_t>(ed::GetSelectedObjectCount()));
70
71 auto nodeCount = static_cast<size_t>(ed::GetSelectedNodes(selectedNodes.data(), static_cast<int>(selectedNodes.size())));
72 auto linkCount = static_cast<size_t>(ed::GetSelectedLinks(selectedLinks.data(), static_cast<int>(selectedLinks.size())));
73
74 selectedNodes.resize(nodeCount);
75 selectedLinks.resize(linkCount);
76
77 { // Node List
78 ImGui::GetWindowDrawList()->AddRectFilled(
79 ImGui::GetCursorScreenPos(),
80 ImGui::GetCursorScreenPos() + ImVec2(paneWidth, ImGui::GetTextLineHeight()),
81 ImColor(ImGui::GetStyle().Colors[ImGuiCol_HeaderActive]), ImGui::GetTextLineHeight() * 0.25F);
82 ImGui::Spacing();
83 ImGui::SameLine();
84 ImGui::TextUnformatted("Nodes");
85 ImGui::Indent();
86 for (const auto* node : nm::m_Nodes())
87 {
88 ImGui::PushID(node->id.AsPointer());
89 auto start = ImGui::GetCursorScreenPos();
90
91 if (const auto progress = gui::GetTouchProgress(node->id); progress != 0.0F)
92 {
93 ImGui::GetWindowDrawList()->AddLine(
94 start + ImVec2(-18, 0),
95 start + ImVec2(-18, ImGui::GetTextLineHeight()),
96 IM_COL32(255, 0, 0, 255 - static_cast<int>(255 * progress)), 4.0F);
97 }
98
99 if (node->kind == Node::Kind::GroupBox)
100 {
101 ImGui::PopID();
102 continue;
103 }
104
105 // Circle to show init status
106 ImU32 circleCol = 0;
107 if (node->isDisabled())
108 {
109 circleCol = IM_COL32(192, 192, 192, 255);
110 }
111 else if (node->getState() == Node::State::DoInitialize)
112 {
113 circleCol = IM_COL32(144, 202, 238, 255);
114 }
115 else if (node->getState() == Node::State::Initializing)
116 {
117 circleCol = IM_COL32(143, 188, 143, 255);
118 }
119 else if (node->getState() == Node::State::DoDeinitialize)
120 {
121 circleCol = IM_COL32(255, 222, 122, 255);
122 }
123 else if (node->getState() == Node::State::Deinitializing)
124 {
125 circleCol = IM_COL32(240, 128, 128, 255);
126 }
127 else if (node->getState() == Node::State::Initialized)
128 {
129 circleCol = IM_COL32(0, 255, 0, 255);
130 }
131 else // if (!node->getState() == Node::State::Deinitialized)
132 {
133 circleCol = IM_COL32(255, 0, 0, 255);
134 }
135 ImGui::GetWindowDrawList()->AddCircleFilled(start + ImVec2(-8 + (NodeEditorApplication::panelFontRatio() - 1.F) * 5.F, ImGui::GetTextLineHeight() / 2.0F + 1.0F),
136 5.0F * NodeEditorApplication::panelFontRatio(), circleCol);
137
138 bool isSelected = std::ranges::find(selectedNodes, node->id) != selectedNodes.end();
139 if (NodeEditorApplication::panelFontRatio() != 1.F) { ImGui::Indent((NodeEditorApplication::panelFontRatio() - 1.F) * 15.F); }
140 if (ImGui::Selectable((str::replaceAll_copy(node->name, "\n", "") + "##" + std::to_string(size_t(node->id))).c_str(), &isSelected))
141 {
142 if (io.KeyCtrl)
143 {
144 if (isSelected)
145 {
146 ed::SelectNode(node->id, true);
147 }
148 else
149 {
150 ed::DeselectNode(node->id);
151 }
152 }
153 else
154 {
155 ed::SelectNode(node->id, false);
156 }
157
158 ed::NavigateToSelection();
159 }
160 if (ImGui::IsItemHovered())
161 {
162 ImGui::SetTooltip("Type: %s", node->type().c_str());
163 }
164 if (NodeEditorApplication::panelFontRatio() != 1.F) { ImGui::Unindent((NodeEditorApplication::panelFontRatio() - 1.F) * 15.F); }
165
166 // auto id = fmt::format("({})", size_t(node->id));
167 // auto textSize = ImGui::CalcTextSize(id.c_str(), nullptr);
168 // auto iconPanelPos = start + ImVec2(std::max(paneWidth, 150.F) - ImGui::GetStyle().FramePadding.x - ImGui::GetStyle().IndentSpacing - ImGui::GetStyle().ItemInnerSpacing.x * 1, ImGui::GetTextLineHeight() / 2);
169 // ImGui::GetWindowDrawList()->AddText(
170 // ImVec2(iconPanelPos.x - textSize.x - ImGui::GetStyle().ItemInnerSpacing.x, start.y),
171 // colSum > 2.0F ? IM_COL32(0, 0, 0, 255) : IM_COL32(255, 255, 255, 255), id.c_str(), nullptr);
172
173 ImGui::PopID();
174 }
175 ImGui::Unindent();
176 }
177
178 { // Selection List
179 ImGui::GetWindowDrawList()->AddRectFilled(
180 ImGui::GetCursorScreenPos(),
181 ImGui::GetCursorScreenPos() + ImVec2(paneWidth, ImGui::GetTextLineHeight()),
182 ImColor(ImGui::GetStyle().Colors[ImGuiCol_HeaderActive]), ImGui::GetTextLineHeight() * 0.25F);
183 ImGui::Spacing();
184 ImGui::SameLine();
185 ImGui::TextUnformatted("Selection");
186
187 ImGui::BeginHorizontal("Selection Stats", ImVec2(paneWidth, 0));
188 size_t selectedCount = selectedNodes.size() + selectedLinks.size();
189 ImGui::Text("%lu item%s selected", selectedCount, (selectedCount > 1 || selectedCount == 0) ? "s" : "");
190 ImGui::Spring();
191 if (ImGui::Button("Deselect"))
192 {
193 ed::ClearSelection();
194 }
195 ImGui::EndHorizontal();
196 ImGui::Indent();
197 for (size_t i = 0; i < nodeCount; ++i)
198 {
199 auto* node = nm::FindNode(selectedNodes[i]);
200 ImGui::Text("%s (%lu)", node != nullptr ? node->name.c_str() : "", size_t(selectedNodes[i]));
201 }
202 for (size_t i = 0; i < linkCount; ++i)
203 {
204 ImGui::Text("Link (%lu)", size_t(selectedLinks[i]));
205 }
206 ImGui::Unindent();
207 }
208
209 if (ImGui::IsWindowFocused())
210 {
211 paneActive = true;
212 }
213
214 ImGui::EndChild();
215
216 ImGui::Image(insLogo, ImVec2(insLogoWidth, insLogoHeight));
217
218 ImGui::EndGroup();
219
220 return paneActive;
221}
Left Pane where Nodes and Selection is shown.
Manages all Nodes.
Utility functions for working with std::strings.
Touch Event Tracker.
@ DoInitialize
Node should be initialized.
Definition Node.hpp:179
@ Initializing
Node is currently initializing.
Definition Node.hpp:180
@ Initialized
Node is initialized (green)
Definition Node.hpp:181
@ DoDeinitialize
Node should be deinitialized.
Definition Node.hpp:182
@ Deinitializing
Node is currently deinitializing.
Definition Node.hpp:183
static std::array< ImTextureID, 2 > m_InstinctLogo
Pointer to the texture for the instinct logo.
static std::array< ImTextureID, 2 > m_InsLogo
Pointer to the texture for the INS logo.
static float panelFontRatio()
Ratio to multiply for GUI editor elements.
const std::vector< Node * > & m_Nodes()
List of all registered Nodes.
Node * FindNode(ax::NodeEditor::NodeId id)
Finds the Node for the NodeId.
bool ShowLeftPane(float paneWidth)
Shows the left overview pane.
Definition LeftPane.cpp:27
float GetTouchProgress(ax::NodeEditor::NodeId id)
Get the Touch Progress for the specified node.
static std::string replaceAll_copy(std::string str, const std::string &from, const std::string &to, CaseSensitivity cs)
Replaces all occurrence of a search pattern with another sequence.
@ GroupBox
Group box which can group other nodes and drag them together.
Definition Node.hpp:102