0.5.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
15
18
19#include "util/StringUtil.hpp"
20
21#include <string>
22#include <algorithm>
23
24namespace ed = ax::NodeEditor;
25
26bool NAV::gui::panels::ShowLeftPane(float paneWidth)
27{
28 auto& io = ImGui::GetIO();
29
30 bool paneActive = false;
31
32 float insLogoWidth = paneWidth < 150 ? paneWidth : 150;
33
34 float insLogoHeight = insLogoWidth * 2967.0F / 4073.0F;
35 float childHeight = ImGui::GetContentRegionAvail().y - insLogoHeight;
36
37 ImGui::BeginGroup();
38
39 ImGui::BeginChild("Selection", ImVec2(paneWidth, childHeight));
40
41 paneWidth = ImGui::GetContentRegionAvail().x;
42
43 float colSum = ImGui::GetStyle().Colors[ImGuiCol_WindowBg].x + ImGui::GetStyle().Colors[ImGuiCol_WindowBg].y + ImGui::GetStyle().Colors[ImGuiCol_WindowBg].z;
44 ImTextureID instinctLogo = NodeEditorApplication::m_InstinctLogo.at(colSum > 2.0F ? 1 : 0);
45 ImTextureID insLogo = NodeEditorApplication::m_InsLogo.at(colSum > 2.0F ? 1 : 0);
46
47 ImGui::Image(instinctLogo, ImVec2(paneWidth, paneWidth * 3000.0F / 13070.0F));
48 ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5.0F);
49
50 { // Control Buttons
51 ImGui::BeginHorizontal("Control Buttons", ImVec2(paneWidth, 0));
52 ImGui::Spring(0.0F, 0.0F);
53 if (ImGui::Button("Zoom to Content"))
54 {
55 ed::NavigateToContent();
56 }
57 if (ImGui::IsItemHovered())
58 {
59 ImGui::SetTooltip("Shortcut: F");
60 }
61 ImGui::Spring();
62 ImGui::EndHorizontal();
63 }
64
65 std::vector<ed::NodeId> selectedNodes;
66 std::vector<ed::LinkId> selectedLinks;
67 selectedNodes.resize(static_cast<size_t>(ed::GetSelectedObjectCount()));
68 selectedLinks.resize(static_cast<size_t>(ed::GetSelectedObjectCount()));
69
70 auto nodeCount = static_cast<size_t>(ed::GetSelectedNodes(selectedNodes.data(), static_cast<int>(selectedNodes.size())));
71 auto linkCount = static_cast<size_t>(ed::GetSelectedLinks(selectedLinks.data(), static_cast<int>(selectedLinks.size())));
72
73 selectedNodes.resize(nodeCount);
74 selectedLinks.resize(linkCount);
75
76 { // Node List
77 ImGui::GetWindowDrawList()->AddRectFilled(
78 ImGui::GetCursorScreenPos(),
79 ImGui::GetCursorScreenPos() + ImVec2(paneWidth, ImGui::GetTextLineHeight()),
80 ImColor(ImGui::GetStyle().Colors[ImGuiCol_HeaderActive]), ImGui::GetTextLineHeight() * 0.25F);
81 ImGui::Spacing();
82 ImGui::SameLine();
83 ImGui::TextUnformatted("Nodes");
84 ImGui::Indent();
85 for (const auto* node : flow::m_Nodes())
86 {
87 ImGui::PushID(node->id.AsPointer());
88 auto start = ImGui::GetCursorScreenPos();
89
90 if (const auto progress = gui::GetTouchProgress(node->id); progress != 0.0F)
91 {
92 ImGui::GetWindowDrawList()->AddLine(
93 start + ImVec2(-18, 0),
94 start + ImVec2(-18, ImGui::GetTextLineHeight()),
95 IM_COL32(255, 0, 0, 255 - static_cast<int>(255 * progress)), 4.0F);
96 }
97
98 if (node->kind == Node::Kind::GroupBox)
99 {
100 ImGui::PopID();
101 continue;
102 }
103
104 // Circle to show init status
105 ImU32 circleCol = 0;
106 if (node->isDisabled())
107 {
108 circleCol = IM_COL32(192, 192, 192, 255);
109 }
110 else if (node->getState() == Node::State::DoInitialize)
111 {
112 circleCol = IM_COL32(144, 202, 238, 255);
113 }
114 else if (node->getState() == Node::State::Initializing)
115 {
116 circleCol = IM_COL32(143, 188, 143, 255);
117 }
118 else if (node->getState() == Node::State::DoDeinitialize)
119 {
120 circleCol = IM_COL32(255, 222, 122, 255);
121 }
122 else if (node->getState() == Node::State::Deinitializing)
123 {
124 circleCol = IM_COL32(240, 128, 128, 255);
125 }
126 else if (node->getState() == Node::State::Initialized)
127 {
128 circleCol = IM_COL32(0, 255, 0, 255);
129 }
130 else // if (!node->getState() == Node::State::Deinitialized)
131 {
132 circleCol = IM_COL32(255, 0, 0, 255);
133 }
134 ImGui::GetWindowDrawList()->AddCircleFilled(start + ImVec2(-8 + (NodeEditorApplication::panelFontRatio() - 1.F) * 5.F, ImGui::GetTextLineHeight() / 2.0F + 1.0F),
135 5.0F * NodeEditorApplication::panelFontRatio(), circleCol);
136
137 bool isSelected = std::ranges::find(selectedNodes, node->id) != selectedNodes.end();
138 if (NodeEditorApplication::panelFontRatio() != 1.F) { ImGui::Indent((NodeEditorApplication::panelFontRatio() - 1.F) * 15.F); }
139 if (ImGui::Selectable((str::replaceAll_copy(node->name, "\n", "") + "##" + std::to_string(size_t(node->id))).c_str(), &isSelected))
140 {
141 if (io.KeyCtrl)
142 {
143 if (isSelected)
144 {
145 ed::SelectNode(node->id, true);
146 }
147 else
148 {
149 ed::DeselectNode(node->id);
150 }
151 }
152 else
153 {
154 ed::SelectNode(node->id, false);
155 }
156
157 ed::NavigateToSelection();
158 }
159 if (ImGui::IsItemHovered())
160 {
161 ImGui::SetTooltip("Type: %s", node->type().c_str());
162 }
163 if (NodeEditorApplication::panelFontRatio() != 1.F) { ImGui::Unindent((NodeEditorApplication::panelFontRatio() - 1.F) * 15.F); }
164
165 // auto id = fmt::format("({})", size_t(node->id));
166 // auto textSize = ImGui::CalcTextSize(id.c_str(), nullptr);
167 // auto iconPanelPos = start + ImVec2(std::max(paneWidth, 150.F) - ImGui::GetStyle().FramePadding.x - ImGui::GetStyle().IndentSpacing - ImGui::GetStyle().ItemInnerSpacing.x * 1, ImGui::GetTextLineHeight() / 2);
168 // ImGui::GetWindowDrawList()->AddText(
169 // ImVec2(iconPanelPos.x - textSize.x - ImGui::GetStyle().ItemInnerSpacing.x, start.y),
170 // colSum > 2.0F ? IM_COL32(0, 0, 0, 255) : IM_COL32(255, 255, 255, 255), id.c_str(), nullptr);
171
172 ImGui::PopID();
173 }
174 ImGui::Unindent();
175 }
176
177 { // Selection List
178 ImGui::GetWindowDrawList()->AddRectFilled(
179 ImGui::GetCursorScreenPos(),
180 ImGui::GetCursorScreenPos() + ImVec2(paneWidth, ImGui::GetTextLineHeight()),
181 ImColor(ImGui::GetStyle().Colors[ImGuiCol_HeaderActive]), ImGui::GetTextLineHeight() * 0.25F);
182 ImGui::Spacing();
183 ImGui::SameLine();
184 ImGui::TextUnformatted("Selection");
185
186 ImGui::BeginHorizontal("Selection Stats", ImVec2(paneWidth, 0));
187 size_t selectedCount = selectedNodes.size() + selectedLinks.size();
188 ImGui::Text("%lu item%s selected", selectedCount, (selectedCount > 1 || selectedCount == 0) ? "s" : "");
189 ImGui::Spring();
190 if (ImGui::Button("Deselect"))
191 {
192 ed::ClearSelection();
193 }
194 ImGui::EndHorizontal();
195 ImGui::Indent();
196 for (size_t i = 0; i < nodeCount; ++i)
197 {
198 auto* node = flow::FindNode(selectedNodes[i]);
199 ImGui::Text("%s (%lu)", node != nullptr ? node->name.c_str() : "", size_t(selectedNodes[i]));
200 }
201 for (size_t i = 0; i < linkCount; ++i)
202 {
203 ImGui::Text("Link (%lu)", size_t(selectedLinks[i]));
204 }
205 ImGui::Unindent();
206 }
207
208 if (ImGui::IsWindowFocused())
209 {
210 paneActive = true;
211 }
212
213 ImGui::EndChild();
214
215 ImGui::Image(insLogo, ImVec2(insLogoWidth, insLogoHeight));
216
217 ImGui::EndGroup();
218
219 return paneActive;
220}
Save/Load the Nodes.
Left Pane where Nodes and Selection is shown.
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:26
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