11#ifdef IMGUI_IMPL_OPENGL_LOADER_GL3W
16 #include <imgui_internal.h>
17 #include <imgui_node_editor.h>
18 #include <imgui_node_editor_internal.h>
19 #include <imgui_canvas.h>
35std::string plotScreenshotImPlotStyleFile =
"implot-light.json";
36bool copyScreenshotsToClipboard =
true;
37bool printScreenshotSaveLocation =
true;
41ImRect _screenshotNavigateRect;
42ImRect _screenshotCaptureRect;
43bool _showScreenshotCaptureRect =
false;
44size_t _screenshotFrameCnt = 0;
49void NAV::gui::windows::ShowScreenshotter(
bool* show )
51 if (_screenshotFrameCnt > 0)
53 _screenshotFrameCnt++;
55 if (_screenshotFrameCnt == 8)
57 ImGuiIO& io = ImGui::GetIO();
58 ImGuiScreenshotImageBuf Output(
static_cast<int>(_screenshotCaptureRect.Min.x),
59 static_cast<int>(io.DisplaySize.y) -
static_cast<int>(_screenshotCaptureRect.Max.y),
60 static_cast<size_t>(_screenshotCaptureRect.GetWidth()),
61 static_cast<size_t>(_screenshotCaptureRect.GetHeight()));
63 std::time_t t = std::time(
nullptr);
64 std::tm* now = std::localtime(&t);
66 auto savePath = flow::GetOutputPath()
67 / fmt::format(
"Screenshot_{:04d}-{:02d}-{:02d}_{:02d}-{:02d}-{:02d}.png",
68 now->tm_year + 1900, now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec);
69 Output.SaveFile(savePath.c_str());
70 if (printScreenshotSaveLocation)
72 LOG_INFO(
"Screenshot saved as: {}", savePath);
75 if (copyScreenshotsToClipboard)
77 CopyFileToClipboard(savePath.c_str());
80 else if (_screenshotFrameCnt == 10)
82 _screenshotFrameCnt = 0;
88 if (_showScreenshotCaptureRect)
90 constexpr float thickness = 1.0F;
91 auto rect = _screenshotCaptureRect;
92 rect.Expand(thickness);
93 ImGui::GetForegroundDrawList()->AddRect(rect.Min, rect.Max, ImColor(255, 0, 0),
94 0.0F, ImDrawFlags_None, thickness);
97 if (!ImGui::Begin(
"Screenshotter", show, ImGuiWindowFlags_AlwaysAutoResize))
103 const float ITEM_WIDTH = 200.0F * NodeEditorApplication::windowFontRatio();
104 const float ITEM_WIDTH_HALF = (ITEM_WIDTH - ImGui::GetStyle().ItemInnerSpacing.x) / 2.0F;
106 ImGui::TextUnformatted(
"Plot screenshot style: ");
108 ImGui::SetNextItemWidth(100.0F * NodeEditorApplication::windowFontRatio());
109 if (widgets::FileDialogLoad(plotScreenshotImPlotStyleFile,
"Plot screenshot config file",
".json", {
".json" },
110 flow::GetConfigPath(), 1,
"ImPlotStyleEditorScreenshot"))
112 LOG_DEBUG(
"Plot screenshot config file changed to: {}", plotScreenshotImPlotStyleFile);
115 ImGui::Checkbox(
"Copy screenshots to clipboard", ©ScreenshotsToClipboard);
117 bool transparentWindows = ImGui::GetStyle().Colors[ImGuiCol_WindowBg].w != 1.0F;
118 if (ImGui::Checkbox(
"Light mode", &nodeEditorLightMode))
121 flow::ApplyChanges();
124 bool showGridLines = ed::GetStyle().Colors[ed::StyleColor_Grid].w != 0.0F;
125 if (ImGui::Checkbox(
"Grid lines", &showGridLines))
127 ed::GetStyle().Colors[ed::StyleColor_Grid].w = showGridLines ? ed::Style().Colors[ed::StyleColor_Grid].w : 0.0F;
128 flow::ApplyChanges();
131 if (ImGui::Checkbox(
"Transparent windows", &transparentWindows))
133 ImGui::GetStyle().Colors[ImGuiCol_WindowBg].w = transparentWindows ? ImGuiStyle().Colors[ImGuiCol_WindowBg].w : 1.0F;
134 ImGui::GetStyle().Colors[ImGuiCol_PopupBg].w = transparentWindows ? ImGuiStyle().Colors[ImGuiCol_PopupBg].w : 1.0F;
135 flow::ApplyChanges();
138 if (ImGui::Checkbox(
"Hide left pane", &NodeEditorApplication::hideLeftPane))
140 flow::ApplyChanges();
142 if (!NodeEditorApplication::hideLeftPane)
145 ImGui::SetNextItemWidth(ITEM_WIDTH_HALF);
146 ImGui::DragFloat(
"Left pane width", &NodeEditorApplication::leftPaneWidth);
148 if (ImGui::Checkbox(
"Hide FPS count", &NodeEditorApplication::hideFPS))
150 flow::ApplyChanges();
153 ImGui::Checkbox(
"Print save location", &printScreenshotSaveLocation);
157 auto* editor =
reinterpret_cast<ed::Detail::EditorContext*
>(ed::GetCurrentEditor());
158 if (_screenshotNavigateRect.GetArea() == 0.0F) { _screenshotNavigateRect = editor->GetContentBounds(); }
160 ImGui::SetNextItemOpen(
true, ImGuiCond_Once);
161 if (ImGui::TreeNode(
"Screenshot navigate area"))
163 ImGui::TextUnformatted(fmt::format(
"Current Content Bounds: Min({},{}), Max({},{})",
164 editor->GetContentBounds().Min.x, editor->GetContentBounds().Min.y,
165 editor->GetContentBounds().Max.x, editor->GetContentBounds().Max.y)
167 ImGui::TextUnformatted(fmt::format(
"Current View: Min({},{}), Max({},{})",
168 editor->GetViewRect().Min.x, editor->GetViewRect().Min.y,
169 editor->GetViewRect().Max.x, editor->GetViewRect().Max.y)
172 if (ImGui::Button(
"Set area to content")) { _screenshotNavigateRect = editor->GetContentBounds(); }
174 if (ImGui::Button(
"Set area to current view"))
176 _screenshotNavigateRect = editor->GetViewRect();
178 auto extend = ImMax(_screenshotNavigateRect.GetWidth(), _screenshotNavigateRect.GetHeight());
179 constexpr float c_NavigationZoomMargin = 0.1F;
180 _screenshotNavigateRect.Expand(-extend * c_NavigationZoomMargin * 0.5F);
183 ImGui::SetNextItemWidth(ITEM_WIDTH);
184 ImGui::DragFloat2(
"Min##Nav area", &_screenshotNavigateRect.Min.x);
185 ImGui::SetNextItemWidth(ITEM_WIDTH);
186 ImGui::DragFloat2(
"Max##Nav area", &_screenshotNavigateRect.Max.x);
188 if (ImGui::Button(
"Navigate to area"))
190 editor->NavigateTo(_screenshotNavigateRect,
true);
194 static float zoomFactor = editor->GetView().Scale;
195 if (ImGui::Button(
"Zoom"))
197 auto targetRect = editor->GetCanvas().CalcViewRect(ImGuiEx::CanvasView(editor->GetView().Origin, zoomFactor));
198 editor->NavigateTo(targetRect,
true, 0.15F);
201 ImGui::SetNextItemWidth(ITEM_WIDTH_HALF / 2.F);
202 ImGui::InputFloat(
"##Zoom Factor", &zoomFactor);
204 ImGui::TextUnformatted(fmt::format(
"Current: {:.3f}", editor->GetView().Scale).c_str());
209 ImGuiIO& io = ImGui::GetIO();
210 if (_screenshotCaptureRect.GetArea() == 0.0F && ImGui::GetFrameCount() > 10) { _screenshotCaptureRect.Max = io.DisplaySize; }
212 ImGui::SetNextItemOpen(
true, ImGuiCond_Once);
213 if (ImGui::TreeNode(
"Screenshot capture area"))
215 if (ImGui::Button(
"Set to display size"))
217 _screenshotCaptureRect.Min = ImVec2();
218 _screenshotCaptureRect.Max = io.DisplaySize;
221 ImGui::SetNextItemWidth(ITEM_WIDTH_HALF);
222 if (ImGui::BeginCombo(
"##Window list",
"Set to window"))
224 ImVector<ImGuiWindow*>& windows = ImGui::GetCurrentContext()->Windows;
225 for (ImGuiWindow* window : windows)
227 std::string windowName = window->Name;
228 if (!window->WasActive || windowName.find(
'#') != std::string::npos || windowName.starts_with(
"Content")) {
continue; }
229 const bool is_selected = window->Rect().Min == _screenshotCaptureRect.Min && window->Rect().Max == _screenshotCaptureRect.Max;
230 if (ImGui::Selectable(window->Name, is_selected))
232 _screenshotCaptureRect = window->Rect();
236 if (is_selected) { ImGui::SetItemDefaultFocus(); }
242 ImGui::Checkbox(
"Show Capture rect", &_showScreenshotCaptureRect);
244 ImGui::SetNextItemWidth(ITEM_WIDTH_HALF);
245 ImGui::DragFloat(
"##Min Capture area x", &_screenshotCaptureRect.Min.x, 1.0F, 0.0F, io.DisplaySize.x - 1);
247 ImGui::SetCursorPosX(ImGui::GetCursorPosX() - ImGui::GetStyle().ItemSpacing.x + ImGui::GetStyle().ItemInnerSpacing.x);
248 ImGui::SetNextItemWidth(ITEM_WIDTH_HALF);
249 ImGui::DragFloat(
"Min##Capture area y", &_screenshotCaptureRect.Min.y, 1.0F, 0.0F, io.DisplaySize.y - 1);
251 ImGui::SetNextItemWidth(ITEM_WIDTH_HALF);
252 ImGui::DragFloat(
"##Max Capture area x", &_screenshotCaptureRect.Max.x, 1.0F, _screenshotCaptureRect.Min.x + 1, io.DisplaySize.x);
254 ImGui::SetCursorPosX(ImGui::GetCursorPosX() - ImGui::GetStyle().ItemSpacing.x + ImGui::GetStyle().ItemInnerSpacing.x);
255 ImGui::SetNextItemWidth(ITEM_WIDTH_HALF);
256 ImGui::DragFloat(
"Max##Capture area y", &_screenshotCaptureRect.Max.y, 1.0F, _screenshotCaptureRect.Min.y + 1, io.DisplaySize.y);
258 if (ImGui::Button(
"Take screenshot"))
260 _screenshotFrameCnt = 1;
269void NAV::gui::windows::CopyFileToClipboard(
const char* path)
272 [[maybe_unused]]
int exitCode = system(fmt::format(
"command -v xclip > /dev/null 2>&1 && xclip -selection clipboard -target image/png -i {} && exit 0"
273 "|| command -v wl-copy > /dev/null 2>&1 && wl-copy < {}",
Utility class for logging to console and file.
#define LOG_DEBUG
Debug information. Should not be called on functions which receive observations (spamming)
#define LOG_INFO
Info to the user on the state of the program.
void ApplyDarkLightMode(std::vector< ImVec4 > &colors, bool transparentWindows)