JeVois  1.23
JeVois Smart Embedded Machine Vision Toolkit
Share this page:
Loading...
Searching...
No Matches
GUIhelper.H
Go to the documentation of this file.
1// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2//
3// JeVois Smart Embedded Machine Vision Toolkit - Copyright (C) 2020 by Laurent Itti, the University of Southern
4// California (USC), and iLab at USC. See http://iLab.usc.edu and http://jevois.org for information about this project.
5//
6// This file is part of the JeVois Smart Embedded Machine Vision Toolkit. This program is free software; you can
7// redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software
8// Foundation, version 2. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
10// License for more details. You should have received a copy of the GNU General Public License along with this program;
11// if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
12//
13// Contact information: Laurent Itti - 3641 Watt Way, HNB-07A - Los Angeles, CA 90089-2520 - USA.
14// Tel: +1 213 740 3527 - itti@pollux.usc.edu - http://iLab.usc.edu - http://jevois.org
15// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
16/*! \file */
17
18#pragma once
19
20// To minimize the amount of ifdef junk in user code, define type alias OptGUIhelper here as either GUIhelper or void
21namespace jevois
22{
23#ifdef JEVOIS_PRO
24 class GUIhelper;
26#else
27 using OptGUIhelper = void;
28#endif
29}
30
31// This is only available on JeVoisPro
32#ifdef JEVOIS_PRO
33
35#include <jevois/Core/Engine.H>
40#include <jevois/Types/Enum.H>
41#include <chrono>
42#include <imgui.h>
43#include <glm/glm.hpp>
44#include <opencv2/core/core.hpp>
45
46namespace jevois
47{
48 class GPUimage;
49 class GUIeditor;
50
51 //! Parameters for GUIhelper class
52 namespace gui
53 {
54 static jevois::ParameterCategory const ParamCateg("Graphical Interface Options");
55
56 //! Parameter \relates jevois::GUIhelper
57 JEVOIS_DECLARE_PARAMETER(fullscreen, bool, "Use a fullscreen display when true, only has effect on host. "
58 "Platform always is fullscreen as the MALI OpenGL driver do not support windowing.",
59 false, ParamCateg);
60
61 //! Parameter \relates jevois::GUIhelper
62 JEVOIS_DECLARE_PARAMETER(winsize, cv::Size, "Initial window size to use on host. On platform, size is determined "
63 "by hardware and the value of this parameter will be overwritten on init. The "
64 "parameter can still be used to query display size.",
65#ifdef JEVOIS_PLATFORM
66 // Use 0 x 0 default on platform which will trigger a query for framebuffer size in
67 // VideoDisplayBackEndMali:
68 cv::Size(0, 0),
69#else
70 // On host, provide a default size since by default we run in a window:
71 cv::Size(1920, 1080),
72#endif
73 ParamCateg);
74
75 //! Parameter \relates jevois::GUIhelper
76 JEVOIS_DECLARE_PARAMETER(hidesecs, float, "Number of seconds of inactivity from keyboard/mouse/joystick/etc after "
77 "which we hide the GUI, or 0.0 to never hide it. Note: The GUI starts hidden until the "
78 "first input event from a keyboard, mouse, etc.",
79 30.0F, ParamCateg);
80
81 //! Parameter \relates jevois::GUIhelper
82 JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(scale, float, "Scale factor applied to the GUI",
83 2.0f, { 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f,
84 2.1f, 2.2f, 2.3f, 2.4f, 2.5f, 2.6f, 2.7f, 2.8f, 2.9f, 3.0f },
85 ParamCateg);
86
87 //! Enum for Parameter \relates jevois::GUIhelper
88 JEVOIS_DEFINE_ENUM_CLASS(GuiStyle, (Light) (Dark) (Classic) );
89
90 //! Parameter \relates jevois::GUIhelper
91 JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(style, GuiStyle, "Color style for the JeVois GUI",
92 GuiStyle::Light, GuiStyle_Values, ParamCateg);
93
94 //! Parameter \relates jevois::GUIhelper
95 JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(rounding, int, "Window and widget corner rounding for the JeVois GUI. "
96 "Note than changing GUI scale will update this parameter as well.",
97 4, jevois::Range<int>(0, 24), ParamCateg);
98
99 //! Parameter \relates jevois::GUIhelper
100 JEVOIS_DECLARE_PARAMETER(overlaycolor, ImColor, "Default color to use for overlay text",
101 ImColor(255, 255, 255, 255), ParamCateg);
102
103 //! Parameter \relates jevois::GUIhelper
104 JEVOIS_DECLARE_PARAMETER(linethick, float, "Line thickness for overlay drawings",
105 5.0F, jevois::Range<float>(0.1F, 20.0F), ParamCateg);
106
107 //! Parameter \relates jevois::GUIhelper
108 JEVOIS_DECLARE_PARAMETER(fillalpha, float, "Alpha multiplier for overlay fills",
109 0.25F, jevois::Range<float>(0.0F, 1.0F), ParamCateg);
110
111 //! Parameter \relates jevois::GUIhelper
112 JEVOIS_DECLARE_PARAMETER(allowquit, bool, "Quit application on ESC key (platform) or window close (host)",
113 false, ParamCateg);
114
115 //! Parameter \relates jevois::GUIhelper
116 JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(twirl, float, "Apply twirl effect to displayed video and images, useful "
117 "mainly for demo mode",
118 0.0F, jevois::Range<float>(-15.0F, 15.0F), ParamCateg);
119 } // namespace gui
120
121 /*! \defgroup gui JeVois-Pro Graphical Interface
122
123 Classes and utilities to provide a graphical interface using Dear ImGui. Supported on JeVois-Pro only.
124
125 \ingroup core */
126
127 //! Helper class to assist modules in creating graphical and GUI elements
128 /*! This class only works on JeVois-Pro. \ingroup gui */
129 class GUIhelper : public Component,
130 public Parameter<gui::fullscreen, gui::winsize, gui::hidesecs, gui::scale,
131 gui::style, gui::rounding, gui::overlaycolor, gui::linethick,
132 gui::fillalpha, gui::allowquit, gui::twirl>
133 {
134 public:
135 //! Constructor
136 GUIhelper(std::string const & instance, bool conslock = false);
137
138 //! Destructor
139 virtual ~GUIhelper();
140
141 //! Start a new rendering frame
142 /*! This should be called on every new video frame to be rendered. Will initialize OpenGL and open the window or
143 screen if needed. Sets the current window size into w and h, returns true if idle (no keyboard/mouse/etc
144 events received in more than hidesecs seconds). */
145 bool startFrame(unsigned short & w, unsigned short & h);
146
147 //! Check for idle in case startFrame() was called elsewhere
148 bool idle() const;
149
150 //! Helper to indicate that startFrame() was called, and thus endFrame() should be called
151 /*! Mostly useful during exception handling inside Engine. */
152 bool frameStarted() const;
153
154 //! Draw a RawImage, copying pixel data to an OpenGL texture
155 /*! Name should be a unique name, and should typically remain constant across successive video frames. This name
156 is used as an index to OpenGL textures, shaders, and programs created to render the images. Note that OpenGL
157 will slow down and eventually run out of resources if you create too many textures, thus Module writers should
158 try to minimize the number of different names that are used. Note that we will add a suffix to the name,
159 corresponding to the bufindex of the RawImage. If you pass w=0 or h=0 then the image will be rescaled to fill
160 the display as much as possible without changing the aspect ratio, and the actually used x,y,w,h will be
161 returned. Otherwise, x,y,w,h are not modified. If noalias is specified, the scaling factor will be rounded
162 down to the nearest integer to prevent aliasing in the display. This may reduce the displayed image size. For
163 example, with a 1920x1080 window, a 640x480 image would be letterboxed to 1440x1080 when noalias is false. But
164 that is a scaling factor of 2.25 which may create rendering aliasing. When noalias is true, the letterboxed
165 image size will be 1280x960 (scale factor of 2.0). If isoverlay is true, then the image is assumed to be a
166 semi-transparent overlay to be drawn on top of a previously drawn image, and we preserve the drawing
167 parameters of that previous image. */
168 void drawImage(char const * name, RawImage const & img, int & x, int & y, unsigned short & w, unsigned short & h,
169 bool noalias = false, bool isoverlay = false);
170
171 //! Draw an OpenCV image, copying pixel data to an OpenGL texture
172 /*! Name should be a unique name, and should typically remain constant across successive video frames. This name
173 is used as an index to OpenGL textures, shaders, and programs created to render the images. Note that OpenGL
174 will slow down and eventually run out of resources if you create too many textures, thus Module writers should
175 try to minimize the number of different names that are used. If image has three or four 8-bit channels,
176 interpret as RGB[A] if rgb is true, otherwise BGR[A]. If two 8-bit channels, interpret as YUYV. If one,
177 interpret as GRAY. If you pass w=0 or h=0 then the image will be rescaled to fill the display as much as
178 possible without changing the aspect ratio, and the actually used x,y,w,h will be returned. Further, if
179 noalias is true, that rescaling will ensure an integer scaling factor. Otherwise, x,y,w,h are not modified. If
180 isoverlay is true, then the image is assumed to be a semi-transparent overlay to be drawn on top of a
181 previously drawn image, and we preserve the drawing parameters of that previous image. */
182 void drawImage(char const * name, cv::Mat const & img, bool rgb, int & x, int & y, unsigned short & w,
183 unsigned short & h, bool noalias = false, bool isoverlay = false);
184
185 //! Draw the input video frame from the camera using zero-copy
186 /*! If you pass w=0 or h=0 then the image will be rescaled to fill the display as much as possible without
187 changing the aspect ratio, and the actually used x,y,w,h will be returned. Further, if noalias is true, that
188 rescaling will ensure an integer scaling factor. Otherwise, x,y,w,h are not modified. */
189 void drawInputFrame(char const * name, InputFrame const & frame, int & x, int & y,
190 unsigned short & w, unsigned short & h, bool noalias = false, bool casync = false);
191
192 //! Draw the second (scaled) input video frame from the camera using zero-copy
193 /*! If you pass w=0 or h=0 then the image will be rescaled to fill the display as much as possible without
194 changing the aspect ratio, and the actually used x,y,w,h will be returned. Further, if noalias is true, that
195 rescaling will ensure an integer scaling factor. Otherwise, x,y,w,h are not modified. Throws unless we are
196 JeVois-Pro Platform and the camera is set to CropScale mode. */
197 void drawInputFrame2(char const * name, InputFrame const & frame, int & x, int & y,
198 unsigned short & w, unsigned short & h, bool noalias = false, bool casync = false);
199
200 //! Get access to the InputFrame last drawn with drawInputFrame()
201 /*! Throws a fatal error unless called after drawInputFrame() and before endFrame(), useful to get access to the
202 pixel data of the current input frame, for example to extract an ROI. */
203 InputFrame const * getInputFrame() const;
204
205 //! Convert coordinates of a point from within a rendered image to on-screen
206 /*! If name is nullptr, the last image used by drawImage() or drawInputFrame() is used. In such case, if
207 drawInputFrame() was called on a frame that also had a second, scaled image, assume that we have displayed the
208 full-resolution input frame but sent the scaled image to processing, and that hence we also need to scale from
209 second to first frame. */
210 ImVec2 i2d(ImVec2 p, char const * name = nullptr);
211
212 //! Convert coordinates of a point from within a rendered image to on-screen
213 /*! If name is nullptr, the last image used by drawImage() or drawInputFrame() is used. In such case, if
214 drawInputFrame() was called on a frame that also had a second, scaled image, assume that we have displayed the
215 full-resolution input frame but sent the scaled image to processing, and that hence we also need to scale from
216 second to first frame. */
217 ImVec2 i2d(float x, float y, char const * name = nullptr);
218
219 //! Convert a 2D size from within a rendered image to on-screen
220 /*! If name is nullptr, the last image used by drawImage() or drawInputFrame() is used. In such case, if
221 drawInputFrame() was called on a frame that also had a second, scaled image, assume that we have displayed the
222 full-resolution input frame but sent the scaled image to processing, and that hence we also need to scale from
223 second to first frame. */
224 ImVec2 i2ds(ImVec2 p, char const * name = nullptr);
225
226 //! Convert a 2D size from within a rendered image to on-screen
227 /*! If name is nullptr, the last image used by drawImage() or drawInputFrame() is used. In such case, if
228 drawInputFrame() was called on a frame that also had a second, scaled image, assume that we have displayed the
229 full-resolution input frame but sent the scaled image to processing, and that hence we also need to scale from
230 second to first frame. */
231 ImVec2 i2ds(float x, float y, char const * name = nullptr);
232
233 //! Draw line over an image
234 /*! Coordinates used should be image coordinates, as this function internally calls i2d().
235 Color order is IMCOL_32(R,G,B,A). */
236 void drawLine(float x1, float y1, float x2, float y2, ImU32 col = IM_COL32(128,255,128,255));
237
238 //! Draw rectangular box over an image
239 /*! Coordinates used should be image coordinates, as this function internally calls i2d().
240 Color order is IMCOL_32(R,G,B,A). */
241 void drawRect(float x1, float y1, float x2, float y2, ImU32 col = IM_COL32(128,255,128,255), bool filled = true);
242
243 //! Draw polygon over an image
244 /*! Coordinates used should be image coordinates, as this function internally calls i2d().
245 Color order is IMCOL_32(R,G,B,A). */
246 void drawPoly(std::vector<cv::Point> const & pts, ImU32 col = IM_COL32(128,255,128,255), bool filled = true);
247
248 //! Draw polygon over an image
249 /*! Coordinates used should be image coordinates, as this function internally calls i2d().
250 Color order is IMCOL_32(R,G,B,A). */
251 void drawPoly(std::vector<cv::Point2f> const & pts, ImU32 col = IM_COL32(128,255,128,255), bool filled = true);
252
253 //! Draw polygon over an image
254 /*! For N vertices, pts should be either CV_32F and 2xN or Nx2 for x,x,x,x,... y,y,y,y,..., or 1x2N or 2Nx1 for
255 x,y,x,y,x,y...; or CV_32FC2 and 1xN or Nx1. If N < 2, nothing is drawn. Other shapes are illegal.
256 Color order is IMCOL_32(R,G,B,A). */
257 void drawPoly(cv::Mat const & pts, ImU32 col = IM_COL32(128,255,128,255), bool filled = true);
258
259 //! Draw circle over an image
260 /*! Coordinates used should be image coordinates, as this function internally calls i2d().
261 Color order is IMCOL_32(R,G,B,A). */
262 void drawCircle(float x, float y, float r, ImU32 col = IM_COL32(128,255,128,255), bool filled = true);
263
264 //! Draw ellipse over an image
265 /*! Coordinates used should be image coordinates, as this function internally calls i2d(). */
266 void drawEllipse(float x, float y, float rx, float ry, float rot = 0.0F,
267 ImU32 col = IM_COL32(128,255,128,255), bool filled = true);
268
269 //! Draw text over an image
270 /*! Coordinates used should be image coordinates, as this function internally calls i2d().
271 Color order is IMCOL_32(R,G,B,A). */
272 void drawText(float x, float y, char const * txt, ImU32 col = IM_COL32(128,255,128,255));
273
274 //! Draw text over an image
275 /*! Coordinates used should be image coordinates, as this function internally calls i2d().
276 Color order is IMCOL_32(R,G,B,A). */
277 void drawText(float x, float y, std::string const & txt, ImU32 col = IM_COL32(128,255,128,255));
278
279 //! Get coordinates of the start of a given line of text to be drawn as overlay on top of an image
280 /*! Use this to draw overlay text on top of a previously drawn image, it will scale by font size for you. If line
281 is -1, we will increment over the last time this function was called (use with caution). Line number is reset
282 to 0 when drawImage() or drawInputFrame(), etc are called. */
283 ImVec2 iline(int line = -1, char const * name = nullptr);
284
285 //! Draw some overlay text on top of an image
286 /* If line is -1, we will increment over the last time this function was called (use with caution). Line number is
287 reset to 0 when drawImage() or drawInputFrame(), etc are called. If col is not given, use overlaycolor. Color
288 order is IMCOL_32(R,G,B,A). */
289 void itext(char const * txt, ImU32 const & col = IM_COL32_BLACK_TRANS, int line = -1);
290
291 //! Draw some overlay text on top of an image
292 /* If line is -1, we will increment over the last time this function was called (use with caution). Line number is
293 reset to 0 when drawImage() or drawInputFrame(), etc are called. If col is not given, use overlaycolor. Color
294 order is IMCOL_32(R,G,B,A). */
295 void itext(std::string const & txt, ImU32 const & col = IM_COL32_BLACK_TRANS, int line = -1);
296
297 //! Display processing and video info at bottom of screen
298 /*! This helper is to be used by modules to provide a consistent info display at the bottom of the screen.
299 fpscpu should be the string returned by Timer::stop(). If winw and winh are not given, will query from display
300 backend, which will cost a few CPU cycles; so pass it on if you already have it, e.g, from running
301 startFrame() previously. */
302 void iinfo(jevois::InputFrame const & inframe, std::string const & fpscpu,
303 unsigned short winw = 0, unsigned short winh = 0);
304
305 //! Release an image
306 /*! Call this if you plan on re-using the same image name later for an image of different size or
307 format. Otherwise, once an image has been used once, its OpenGL texture (including its dims) will remain the
308 same and only the pixel values will be updated when the image is drawn again. Silently ignores if the image is
309 not found, i.e., has not been drawn before. */
310 void releaseImage(char const * name);
311
312 //! Release an image, second video stream
313 /*! Call this if you plan on re-using the same image name later for an image of different size or
314 format. Otherwise, once an image has been used once, its OpenGL texture (including its dims) will remain the
315 same and only the pixel values will be updated when the image is drawn again. Silently ignores if the image is
316 not found, i.e., has not been drawn before. */
317 void releaseImage2(char const * name);
318
319 //! Finish current frame and render it
320 /*! This should be called once for every call to startFrame(). */
321 void endFrame();
322
323 //! Reset to default state, typically called on Module or video format change
324 /*! Free images, reset matrices, etc. */
325 void resetstate(bool modulechanged = true);
326
327 //! Report an error in an overlay window
328 void reportError(std::string const & err);
329
330 //! Report a transient info message in an overlay window
331 void reportInfo(std::string const & inf);
332
333 //! Report current exception in a modal dialog, then ignore it
334 void reportAndIgnoreException(std::string const & prefix = "");
335
336 //! Report current exception in a modal dialog, then re-throw it
337 void reportAndRethrowException(std::string const & prefix = "");
338
339 //! Clear all errors currently displayed in the JeVois-Pro GUI
340 /*! In the JevoisPro GUI, errors reported via reportError() remain displayed for a few seconds, but sometimes we
341 want to clear them right away, e.g., after DNN pipeline threw, if the user selects another one, we want the
342 previous error to disappear immediately since it is not applicable anymore. */
343 void clearErrors();
344
345 //! Z distance from camera to image plane to achieve pixel-perfect rendering
346 float const pixel_perfect_z = 0.0F;
347
348 //! Our projection matrix
349 glm::mat4 proj;
350
351 //! Our view matrix
352 /*! On the first call to startFrame(), the whole OpenGL engine is initialized and the view matrix is set so that
353 the pixel perfect image plane is vertical and centered on the origin, while the camera is translated in
354 negative Z to achieve pixel perfect rendering. */
355 glm::mat4 view;
356
357 //! Display a (?) label and show tooltip when it is hovered
358 /*! If 2 or more messages are provided, they will be separated by a separator. */
359 void helpMarker(char const * msg, char const * msg2 = nullptr, char const * msg3 = nullptr);
360
361 //! Helper to draw a toggle button
362 bool toggleButton(char const * name, bool * val);
363
364 //! Helper to draw a modal with 2 choices
365 /*! Returns 1 if the first button was clicked, 2 if the second was, or some other value if no button was clicked
366 (caller should just wait and try again at the next frame if not 1 or 2, passing again that returned value). By
367 default, the first button is in focus. If default_val is not nullptr, add a "don't ask again" checkbox. If
368 *default_val is 1 or 2, just return that without even showing the modal. */
369 int modal(std::string const & title, char const * text, int * default_val = nullptr,
370 char const * b1txt = "Ok", char const * b2txt = "Cancel");
371
372 //! Helper to draw a combobox from a vector of strings
373 /*! Note that selected_index is read-write: the passed value is used to display the current item in the combobox,
374 and, when a new item is selected, its index is returned in selected_index and true is returned. */
375 bool combo(std::string const & name, std::vector<std::string> const & items, int & selected_index);
376
377 //! Helper to select a rectangular box by dragging the mouse over the display
378 /*! Once started, this function should be called on every video frame until the box is done. To start a selection,
379 set state to 0, and make sure its value and the values of tl and br are remembered across frames (e.g., using
380 static variables or class member variables). The value of state will change over time as the user presses the
381 mouse button down, then drags, then releases the button. Callers do not need to worry about this and just
382 preserve that value across frames. When selection is complete, true will be returned, the two corners tl and
383 br will be updated, and state will be set to -1. Otherwise, false will be returned (state, tl, and br may be
384 changed and should be preserved for the next call). Box corners are in Display coordinates; use d2i() and
385 related functions to convert to input image coordinates, processing image coordinates, etc. */
386 bool selectImageBox(int & state, ImVec2 & tl, ImVec2 & br, ImU32 col = IM_COL32(128,255,128,255));
387
388 //! Show a message that we are running headless
389 void headlessDisplay();
390
391 //! Tell whether user enabled serlog messages to GUI console
392 bool serlogEnabled() const;
393
394 //! Tell whether user enabled serout messages to GUI console
395 bool seroutEnabled() const;
396
397 //! Convert coordinates of a point from on-screen to within a rendered image
398 /*! If name is nullptr, the last image used by drawImage() or drawInputFrame() is used. In such case, if
399 drawInputFrame() was called on a frame that also had a second, scaled image, assume that we have displayed the
400 full-resolution input frame but sent the scaled image to processing, and that hence we also need to scale from
401 second to first frame. */
402 ImVec2 d2i(ImVec2 p, char const * name = nullptr);
403
404 //! Convert coordinates of a point from on-screen to within a rendered image
405 /*! If name is nullptr, the last image used by drawImage() or drawInputFrame() is used. In such case, if
406 drawInputFrame() was called on a frame that also had a second, scaled image, assume that we have displayed the
407 full-resolution input frame but sent the scaled image to processing, and that hence we also need to scale from
408 second to first frame. */
409 ImVec2 d2i(float x, float y, char const * name = nullptr);
410
411 //! Convert a 2D size from on-screen to within a rendered image
412 /*! If name is nullptr, the last image used by drawImage() or drawInputFrame() is used. In such case, if
413 drawInputFrame() was called on a frame that also had a second, scaled image, assume that we have displayed the
414 full-resolution input frame but sent the scaled image to processing, and that hence we also need to scale from
415 second to first frame. */
416 ImVec2 d2is(ImVec2 p, char const * name = nullptr);
417
418 //! Convert a 2D size from on-screen to within a rendered image
419 /*! If name is nullptr, the last image used by drawImage() or drawInputFrame() is used. In such case, if
420 drawInputFrame() was called on a frame that also had a second, scaled image, assume that we have displayed the
421 full-resolution input frame but sent the scaled image to processing, and that hence we also need to scale from
422 second to first frame. */
423 ImVec2 d2is(float x, float y, char const * name = nullptr);
424
425 //! Compile a newly created module
426 /*! This is mainly for internal use. Called by the code editor when saving C++ code to let us know to start the
427 compilation process again. itsNewMapping should contain the new module's data. */
428 void startCompilation();
429
430 //! Like ImGui::Textunformatted but in a highlight color (typically, red)
431 void highlightText(std::string const & str);
432
433 //! Display some text in a big banner, used by demo mode
434 /*! Any non-empty banner remains on screen until demoBanner() called again with empty title (default args). */
435 void demoBanner(std::string const & title = "", std::string const & msg = "");
436
437 protected:
438 std::map<std::string /* name */, GPUimage> itsImages, itsImages2;
440 InputFrame const * itsInputFrame = nullptr; //! caution, is nullptr except between drawInputFrame() and endFrame()
444
445 std::chrono::time_point<std::chrono::steady_clock> itsLastEventTime;
446 bool itsIdle = true; //!< Idle state, updated by startFrame(), used by endFrame() to decide whether to draw GUI
447 bool itsIdleBlocked = false; //!< While creating/compiling new modules, prevent idle
448 bool itsEndFrameCalled = true; // try to avoid violent assert() crash from ImGui if user forgets to endFrame()
449
450 mutable std::mutex itsErrorMtx;
452 {
453 std::string err;
454 std::chrono::time_point<std::chrono::steady_clock> firsttime;
455 std::chrono::time_point<std::chrono::steady_clock> lasttime;
456 bool is_info; // true if this is an info message rather than a true error
457 };
458 std::list<ErrorData> itsErrors;
459
460 std::set<std::string> itsOpenModals;
461
462 void drawPolyInternal(ImVec2 const * pts, size_t npts, ImU32 col, bool filled);
463 ImU32 applyFillAlpha(ImU32 col) const;
464
466#ifdef JEVOIS_PLATFORM_PRO
468#else
469 ImGuiBackendSDL itsBackend;
470#endif
471 std::string itsWindowTitle;
474 std::string itsModName;
475 std::string itsModDesc;
476 std::string itsModAuth;
477 std::string itsModLang;
478 std::vector<std::string> itsModDoc;
479 gui::GuiStyle itsCurrentStyle = gui::GuiStyle::Dark;
480 bool itsShowStyleEditor = false;
481 bool itsShowAppMetrics = false;
482 bool itsShowImGuiDemo = false;
483 bool itsSerLogEnabled = true;
484 bool itsSerOutEnabled = false;
487
488 void drawJeVoisGUI();
489 void drawInfo();
490 void drawParameters();
491 void drawConsole();
492 void drawCamCtrls();
493 void drawTweaks();
494 void drawSystem();
495 void drawMenuBar();
496 void drawModuleSelect();
497 void drawErrorPopup();
498 void drawNewModuleForm();
499 void compileModule();
500
501 void newModEntry(char const * wname, std::string & str, char const * desc, char const * hint, char const * hlp);
502
503 // Set a parameter by string, catch any exception and report it in popup modal
504 void setparstr(std::string const & descriptor, std::string const & val);
505
506 // Set a parameter by value, catch any exception and report it in popup modal
507 template <class T>
508 void setparval(std::string const & descriptor, T const & val);
509
510 void onParamChange(gui::scale const & param, float const & newval) override;
511 void onParamChange(gui::rounding const & param, int const & newval) override;
512 void onParamChange(gui::style const & param, gui::GuiStyle const & newval) override;
513 void onParamChange(gui::twirl const & param, float const & newval) override;
514
515 // Config files:
516 std::shared_ptr<GUIeditor> itsCfgEditor;
517
518 // Code editing:
519 std::shared_ptr<GUIeditor> itsCodeEditor;
520
521 // dnnget helpers
522 std::future<std::string> itsDnnGetFut;
523
524 // Flag to refresh video mappings when we save the file or add a new one by creating a new module:
527
528 // Flag to indicate whether we have a USB serial gadget
529 bool itsUSBserial = false;
530
531 // Compilation progress
535 std::future<std::string> itsCompileFut;
536 bool compileCommand(std::string const & cmd, std::string & msg); // true on success, false in progress, throws
537 std::array<std::string, 4> itsCompileMessages; // messages for the compilation steps
538 void runNewModule(); // install and load up the module defined in itsNewMapping
539
540 void reportErrorOrInfo(std::string const & err, bool is_info);
541
542 // Banner stuff:
544 float itsGlobalAlpha = 1.0F;
545 };
546
547} // namespace jevois
548
549// Include inlined implementation details that are of no interest to the end user
550#include <jevois/GPU/details/GUIhelperImpl.H>
551
552#endif // JEVOIS_PRO
int h
Definition GUIhelper.C:2580
A component of a model hierarchy.
Definition Component.H:182
std::string descriptor() const
Get our full descriptor (including all parents) as [Instancename]:[...]:[...].
Definition Component.C:276
Class to hold a GPUtexture, GPUprogram, and other data associated with rendering an image in OpenGL.
Definition GPUimage.H:39
Helper class to assist modules in creating graphical and GUI elements.
Definition GUIhelper.H:133
void setparval(std::string const &descriptor, T const &val)
glm::mat4 proj
Our projection matrix.
Definition GUIhelper.H:349
void drawCircle(float x, float y, float r, ImU32 col=IM_COL32(128, 255, 128, 255), bool filled=true)
Draw circle over an image.
Definition GUIhelper.C:608
void onParamChange(gui::style const &param, gui::GuiStyle const &newval) override
std::list< ErrorData > itsErrors
Definition GUIhelper.H:458
std::map< std::string, GPUimage > itsImages2
Definition GUIhelper.H:438
std::string itsBannerMsg
Definition GUIhelper.H:543
std::string itsBannerTitle
Definition GUIhelper.H:543
void endFrame()
Finish current frame and render it.
Definition GUIhelper.C:786
bool seroutEnabled() const
Tell whether user enabled serout messages to GUI console.
Definition GUIhelper.C:1659
bool combo(std::string const &name, std::vector< std::string > const &items, int &selected_index)
Helper to draw a combobox from a vector of strings.
Definition GUIhelper.C:1722
void resetstate(bool modulechanged=true)
Reset to default state, typically called on Module or video format change.
Definition GUIhelper.C:114
VideoMapping itsNewMapping
Definition GUIhelper.H:534
std::shared_ptr< GUIeditor > itsCfgEditor
Definition GUIhelper.H:516
ImVec2 iline(int line=-1, char const *name=nullptr)
Get coordinates of the start of a given line of text to be drawn as overlay on top of an image.
Definition GUIhelper.C:654
JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(scale, float, "Scale factor applied to the GUI", 2.0f, { 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f, 2.1f, 2.2f, 2.3f, 2.4f, 2.5f, 2.6f, 2.7f, 2.8f, 2.9f, 3.0f }, ParamCateg)
Parameter.
void reportAndIgnoreException(std::string const &prefix="")
Report current exception in a modal dialog, then ignore it.
Definition GUIhelper.C:2708
bool itsIdleBlocked
While creating/compiling new modules, prevent idle.
Definition GUIhelper.H:447
void drawInputFrame(char const *name, InputFrame const &frame, int &x, int &y, unsigned short &w, unsigned short &h, bool noalias=false, bool casync=false)
Draw the input video frame from the camera using zero-copy.
Definition GUIhelper.C:334
bool startFrame(unsigned short &w, unsigned short &h)
Start a new rendering frame.
Definition GUIhelper.C:169
GPUimage * itsLastDrawnImage
Definition GUIhelper.H:439
JEVOIS_DECLARE_PARAMETER(fillalpha, float, "Alpha multiplier for overlay fills", 0.25F, jevois::Range< float >(0.0F, 1.0F), ParamCateg)
Parameter.
ImVec2 i2ds(ImVec2 p, char const *name=nullptr)
Convert a 2D size from within a rendered image to on-screen.
Definition GUIhelper.C:446
bool itsShowHardSerialWin
Definition GUIhelper.H:485
JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(rounding, int, "Window and widget corner rounding for the JeVois GUI. " "Note than changing GUI scale will update this parameter as well.", 4, jevois::Range< int >(0, 24), ParamCateg)
Parameter.
void drawText(float x, float y, char const *txt, ImU32 col=IM_COL32(128, 255, 128, 255))
Draw text over an image.
Definition GUIhelper.C:634
void reportErrorOrInfo(std::string const &err, bool is_info)
Definition GUIhelper.C:2673
std::mutex itsErrorMtx
Definition GUIhelper.H:450
void drawEllipse(float x, float y, float rx, float ry, float rot=0.0F, ImU32 col=IM_COL32(128, 255, 128, 255), bool filled=true)
Draw ellipse over an image.
Definition GUIhelper.C:621
std::set< std::string > itsOpenModals
Definition GUIhelper.H:460
virtual ~GUIhelper()
Destructor.
Definition GUIhelper.C:107
std::string itsModName
Definition GUIhelper.H:474
JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(twirl, float, "Apply twirl effect to displayed video and images, useful " "mainly for demo mode", 0.0F, jevois::Range< float >(-15.0F, 15.0F), ParamCateg)
Parameter.
void drawRect(float x1, float y1, float x2, float y2, ImU32 col=IM_COL32(128, 255, 128, 255), bool filled=true)
Draw rectangular box over an image.
Definition GUIhelper.C:488
void onParamChange(gui::scale const &param, float const &newval) override
bool frameStarted() const
Helper to indicate that startFrame() was called, and thus endFrame() should be called.
Definition GUIhelper.C:283
void startCompilation()
Compile a newly created module.
Definition GUIhelper.C:2886
ImGuiImage itsHeadless
Definition GUIhelper.H:473
void drawInputFrame2(char const *name, InputFrame const &frame, int &x, int &y, unsigned short &w, unsigned short &h, bool noalias=false, bool casync=false)
Draw the second (scaled) input video frame from the camera using zero-copy.
Definition GUIhelper.C:366
std::shared_ptr< GUIeditor > itsCodeEditor
Definition GUIhelper.H:519
void drawNewModuleForm()
Definition GUIhelper.C:2120
void clearErrors()
Clear all errors currently displayed in the JeVois-Pro GUI.
Definition GUIhelper.C:2701
std::string itsModAuth
Definition GUIhelper.H:476
void newModEntry(char const *wname, std::string &str, char const *desc, char const *hint, char const *hlp)
Definition GUIhelper.C:1784
void releaseImage(char const *name)
Release an image.
Definition GUIhelper.C:698
void iinfo(jevois::InputFrame const &inframe, std::string const &fpscpu, unsigned short winw=0, unsigned short winh=0)
Display processing and video info at bottom of screen.
Definition GUIhelper.C:677
glm::mat4 view
Our view matrix.
Definition GUIhelper.H:355
void helpMarker(char const *msg, char const *msg2=nullptr, char const *msg3=nullptr)
Display a (?) label and show tooltip when it is hovered.
Definition GUIhelper.C:2814
void demoBanner(std::string const &title="", std::string const &msg="")
Display some text in a big banner, used by demo mode.
Definition GUIhelper.C:2878
void highlightText(std::string const &str)
Like ImGui::Textunformatted but in a highlight color (typically, red)
Definition GUIhelper.C:2870
void reportError(std::string const &err)
Report an error in an overlay window.
Definition GUIhelper.C:2665
void headlessDisplay()
Show a message that we are running headless.
Definition GUIhelper.C:2850
ImVec2 i2d(ImVec2 p, char const *name=nullptr)
Convert coordinates of a point from within a rendered image to on-screen.
Definition GUIhelper.C:410
float const pixel_perfect_z
Z distance from camera to image plane to achieve pixel-perfect rendering.
Definition GUIhelper.H:346
void reportAndRethrowException(std::string const &prefix="")
Report current exception in a modal dialog, then re-throw it.
Definition GUIhelper.C:2733
bool selectImageBox(int &state, ImVec2 &tl, ImVec2 &br, ImU32 col=IM_COL32(128, 255, 128, 255))
Helper to select a rectangular box by dragging the mouse over the display.
Definition GUIhelper.C:1736
void drawModuleSelect()
Definition GUIhelper.C:1031
int itsLastDrawnTextLine
caution, is nullptr except between drawInputFrame() and endFrame()
Definition GUIhelper.H:441
CompilationState itsCompileState
Definition GUIhelper.H:533
InputFrame const * itsInputFrame
Definition GUIhelper.H:440
bool idle() const
Check for idle in case startFrame() was called elsewhere.
Definition GUIhelper.C:227
ImVec2 d2is(ImVec2 p, char const *name=nullptr)
Convert a 2D size from on-screen to within a rendered image.
Definition GUIhelper.C:749
ImGuiImage itsIcon
Definition GUIhelper.H:472
void drawLine(float x1, float y1, float x2, float y2, ImU32 col=IM_COL32(128, 255, 128, 255))
Draw line over an image.
Definition GUIhelper.C:482
JEVOIS_DECLARE_PARAMETER(fullscreen, bool, "Use a fullscreen display when true, only has effect on host. " "Platform always is fullscreen as the MALI OpenGL driver do not support windowing.", false, ParamCateg)
Parameter.
void itext(char const *txt, ImU32 const &col=IM_COL32_BLACK_TRANS, int line=-1)
Draw some overlay text on top of an image.
Definition GUIhelper.C:664
void releaseImage2(char const *name)
Release an image, second video stream.
Definition GUIhelper.C:705
InputFrame const * getInputFrame() const
Get access to the InputFrame last drawn with drawInputFrame()
Definition GUIhelper.C:390
float itsScaledImageFacY
Definition GUIhelper.H:443
ImU32 applyFillAlpha(ImU32 col) const
Definition GUIhelper.C:646
std::chrono::time_point< std::chrono::steady_clock > itsLastEventTime
Definition GUIhelper.H:445
JEVOIS_DECLARE_PARAMETER(linethick, float, "Line thickness for overlay drawings", 5.0F, jevois::Range< float >(0.1F, 20.0F), ParamCateg)
Parameter.
int modal(std::string const &title, char const *text, int *default_val=nullptr, char const *b1txt="Ok", char const *b2txt="Cancel")
Helper to draw a modal with 2 choices.
Definition GUIhelper.C:1669
std::array< std::string, 4 > itsCompileMessages
Definition GUIhelper.H:537
void drawPoly(std::vector< cv::Point > const &pts, ImU32 col=IM_COL32(128, 255, 128, 255), bool filled=true)
Draw polygon over an image.
Definition GUIhelper.C:524
void onParamChange(gui::rounding const &param, int const &newval) override
bool itsRefreshVideoMappings
Definition GUIhelper.H:525
std::future< std::string > itsDnnGetFut
Definition GUIhelper.H:522
void drawPolyInternal(ImVec2 const *pts, size_t npts, ImU32 col, bool filled)
Definition GUIhelper.C:502
void setparstr(std::string const &descriptor, std::string const &val)
Definition GUIhelper.C:1285
gui::GuiStyle itsCurrentStyle
Definition GUIhelper.H:479
std::string itsWindowTitle
Definition GUIhelper.H:471
std::string itsModDesc
Definition GUIhelper.H:475
int itsVideoMappingListType
Definition GUIhelper.H:526
JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(style, GuiStyle, "Color style for the JeVois GUI", GuiStyle::Light, GuiStyle_Values, ParamCateg)
Parameter.
std::future< std::string > itsCompileFut
Definition GUIhelper.H:535
JEVOIS_DECLARE_PARAMETER(allowquit, bool, "Quit application on ESC key (platform) or window close (host)", false, ParamCateg)
Parameter.
ImGuiBackendMALI itsBackend
Definition GUIhelper.H:467
bool compileCommand(std::string const &cmd, std::string &msg)
Definition GUIhelper.C:3104
std::vector< std::string > itsModDoc
Definition GUIhelper.H:478
void reportInfo(std::string const &inf)
Report a transient info message in an overlay window.
Definition GUIhelper.C:2669
std::map< std::string, GPUimage > itsImages
Definition GUIhelper.H:438
bool itsIdle
Idle state, updated by startFrame(), used by endFrame() to decide whether to draw GUI.
Definition GUIhelper.H:446
JEVOIS_DEFINE_ENUM_CLASS(GuiStyle,(Light)(Dark)(Classic))
Enum for Parameter.
ImVec2 d2i(ImVec2 p, char const *name=nullptr)
Convert coordinates of a point from on-screen to within a rendered image.
Definition GUIhelper.C:712
float itsScaledImageFacX
Definition GUIhelper.H:443
bool toggleButton(char const *name, bool *val)
Helper to draw a toggle button.
Definition GUIhelper.C:2831
std::string itsModLang
Definition GUIhelper.H:477
void drawImage(char const *name, RawImage const &img, int &x, int &y, unsigned short &w, unsigned short &h, bool noalias=false, bool isoverlay=false)
Draw a RawImage, copying pixel data to an OpenGL texture.
Definition GUIhelper.C:287
JEVOIS_DECLARE_PARAMETER(hidesecs, float, "Number of seconds of inactivity from keyboard/mouse/joystick/etc after " "which we hide the GUI, or 0.0 to never hide it. Note: The GUI starts hidden until the " "first input event from a keyboard, mouse, etc.", 30.0F, ParamCateg)
Parameter.
bool serlogEnabled() const
Tell whether user enabled serlog messages to GUI console.
Definition GUIhelper.C:1655
JEVOIS_DECLARE_PARAMETER(winsize, cv::Size, "Initial window size to use on host. On platform, size is determined " "by hardware and the value of this parameter will be overwritten on init. The " "parameter can still be used to query display size.", cv::Size(0, 0), ParamCateg)
Parameter.
JEVOIS_DECLARE_PARAMETER(overlaycolor, ImColor, "Default color to use for overlay text", ImColor(255, 255, 255, 255), ParamCateg)
Parameter.
BackendMALI for ImGui on JeVois-Pro.
Wrapper for an image that can be rendered into ImGui.
Definition ImGuiImage.H:31
Exception-safe wrapper around a raw camera input frame.
Definition InputFrame.H:51
A generic range class.
Definition Range.H:81
A raw image as coming from a V4L2 Camera and/or being sent out to a USB Gadget.
Definition RawImage.H:111
Main namespace for all JeVois classes and functions.
Definition Concepts.dox:2
std::chrono::time_point< std::chrono::steady_clock > firsttime
Definition GUIhelper.H:454
std::chrono::time_point< std::chrono::steady_clock > lasttime
Definition GUIhelper.H:455
A category to which multiple ParameterDef definitions can belong.
Simple struct to hold video mapping definitions for the processing Engine.