GCC Code Coverage Report


Directory: ./
File: lib/geogram_gfx/gui/simple_application.h
Date: 2026-09-07 02:28:19
Exec Total Coverage
Lines: 0 18 0.0%
Functions: 0 1 0.0%
Branches: 0 34 0.0%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2000-2022 Inria
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the ALICE Project-Team nor the names of its
14 * contributors may be used to endorse or promote products derived from this
15 * software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 *
29 * Contact: Bruno Levy
30 *
31 * https://www.inria.fr/fr/bruno-levy
32 *
33 * Inria,
34 * Domaine de Voluceau,
35 * 78150 Le Chesnay - Rocquencourt
36 * FRANCE
37 *
38 */
39
40 #ifndef H_GEOGRAM_GFX_GUI_SIMPLE_APPLICATION_H
41 #define H_GEOGRAM_GFX_GUI_SIMPLE_APPLICATION_H
42
43 #include <geogram_gfx/basic/common.h>
44 #include <geogram_gfx/gui/application.h>
45 #include <geogram_gfx/gui/status_bar.h>
46 #include <geogram_gfx/gui/console.h>
47 #include <geogram_gfx/gui/text_editor.h>
48 #include <geogram_gfx/gui/command.h>
49 #include <geogram_gfx/gui/arc_ball.h>
50 #include <geogram_gfx/full_screen_effects/full_screen_effect.h>
51 #include <geogram_gfx/imgui_ext/imgui_ext.h>
52 #include <geogram_gfx/imgui_ext/icon_font.h>
53
54 #include <map>
55 #include <functional>
56
57 struct lua_State;
58
59 namespace GEO {
60
61 /**
62 * \brief SimpleApplication is an Application with pre-created
63 * and customizable menus, commands, graphic attributes,
64 * load and save dialogs, and text editor.
65 */
66 class GEOGRAM_GFX_API SimpleApplication : public Application {
67 public:
68
69 /**
70 * \brief SimpleApplication constructor.
71 * \param[in] name the name of the application.
72 */
73 SimpleApplication(const std::string& name);
74
75 /**
76 * \brief SimpleApplication destructor.
77 */
78 ~SimpleApplication() override;
79
80 /**
81 * \copydoc GEO::Application::draw_gui()
82 */
83 void draw_gui() override;
84
85 /**
86 * \copydoc GEO::Application::draw_graphics()
87 */
88 void draw_graphics() override;
89
90 /**
91 * \brief Saves the current content to a file.
92 * \details Baseclass implementation does nothing. Derived classes
93 * may overload this function.
94 * \retval true if the file could be sucessfully saved.
95 * \retval false otherwise
96 */
97 virtual bool save(const std::string& filename);
98
99 /**
100 * \brief Loads a file.
101 * \details Baseclass implementation does nothing. Derived classes
102 * may overload this function.
103 * \retval true if the file could be sucessfully loaded
104 * \retval false otherwise
105 */
106 virtual bool load(const std::string& filename);
107
108 /**
109 * \brief Gets the text editor.
110 * \return a reference to the text editor.
111 */
112 TextEditor& text_editor() {
113 return text_editor_;
114 }
115
116 /**
117 * \brief Shows the text editor.
118 */
119 void show_text_editor() {
120 text_editor_visible_ = true;
121 }
122
123 /**
124 * \brief Hides the text editor.
125 */
126 void hide_text_editor() {
127 text_editor_visible_ = false;
128 }
129
130 /**
131 * \brief Shows the console.
132 */
133 void show_console() {
134 console_visible_ = true;
135 }
136
137 /**
138 * \brief Hides the console.
139 */
140 void hide_console() {
141 console_visible_ = false;
142 }
143
144 /**
145 * \brief Restores default viewing parameters.
146 */
147 void home();
148
149 /**
150 * \copydoc GEO::Application::set_style()
151 */
152 void set_style(const std::string& style) override;
153
154 /**
155 * \brief Sets the region of interest
156 * \details This defines the default target of the camera
157 * \param[in] xmin , ymin , zmin , xmax , ymax , zmax the
158 * bounds of the region of interest.
159 */
160 void set_region_of_interest(
161 double xmin, double ymin, double zmin,
162 double xmax, double ymax, double zmax
163 );
164
165 /**
166 * \brief Gets the region of interest
167 * \see set_region_of_interest()
168 * \param[out] xmin , ymin , zmin , xmax , ymax , zmax the
169 * bounds of the region of interest.
170 */
171 void get_region_of_interest(
172 double& xmin, double& ymin, double& zmin,
173 double& xmax, double& ymax, double& zmax
174 ) const;
175
176 void zoom_in() {
177 zoom_ *= 1.1;
178 }
179
180 void zoom_out() {
181 zoom_ /= 1.1;
182 }
183
184 void set_clipping(bool x) {
185 clipping_ = x;
186 }
187
188 void set_lighting(bool x) {
189 lighting_ = x;
190 }
191
192 void set_background_color(const vec4f& color) {
193 background_color_ = color;
194 }
195
196 virtual bool exec_command(const char* command);
197
198 static SimpleApplication* instance() {
199 return dynamic_cast<SimpleApplication*>(
200 GEO::Application::instance()
201 );
202 }
203
204 /**
205 * \brief Projects a point from model space to window coordinates.
206 * \param[in] p the point in model space coordinates.
207 * \return the point in window coordinates, that is
208 * [0,width-1] x [0,height-1]
209 */
210 vec3 project(const vec3& p);
211
212 /**
213 * \brief Unprojects a 3d point from window coordinates to model space.
214 * \param[in] p the 3d point in window coordinates, that is
215 * [0,width-1] x [0,height-1]
216 * \return the point in model space coordinates.
217 */
218 vec3 unproject(const vec3& p);
219
220 /**
221 * \brief Unprojects a 2d point from window coordinates to model space.
222 * \param[in] p the 2d point in screen space coordinates.
223 * \return the 2d point in model space coordinates.
224 */
225 vec2 unproject_2d(const vec2& p);
226
227
228 /**
229 * \copydoc Application::drop_callback()
230 */
231 void drop_callback(int nb, const char** f) override;
232
233 /**
234 * \brief Runs the key func associated with a given key
235 * \param[in] key the name of the key ("F5" for the F5 key)
236 * \details Does nothing if no function is associated with the key
237 */
238 void run_key_func(const std::string& key) {
239 auto it = key_funcs_.find(key);
240 if(it != key_funcs_.end()) {
241 it->second();
242 }
243 }
244
245 protected:
246 /**
247 * \brief Declares a function to be triggered when a key is pressed.
248 * \param[in] key the key ("a" for a, "F1" for F1)
249 * \param[in] cb the function to be called
250 * \param[in] help an optional help string
251 */
252 void add_key_func(
253 const std::string& key, std::function<void()> cb,
254 const char* help = nullptr
255 );
256
257 /**
258 * \brief Declares a boolean to be toggled when a key is pressed.
259 * \param[in] key the key ("a" for a, "F1" for F1)
260 * \param[in] p_val a pointer to the boolean
261 * \param[in] help an optional help string
262 */
263 void add_key_toggle(
264 const std::string& key, bool* p_val,
265 const char* help = nullptr
266 );
267
268 /**
269 * \copydoc GEO::Application::char_callback()
270 */
271 void char_callback(unsigned int c) override;
272
273 /**
274 * \copydoc GEO::Application::key_callback()
275 */
276 void key_callback(int key, int scancode, int action, int mods) override;
277
278 /**
279 * \copydoc GEO::Application::mouse_button_callback()
280 */
281 void mouse_button_callback(
282 int button, int action, int mods, int source
283 ) override;
284
285 /**
286 * \copydoc GEO::Application::cursor_pos_callback()
287 */
288 void cursor_pos_callback(double x, double y, int source) override;
289
290 /**
291 * \copydoc GEO::Application::scroll_callback()
292 */
293 void scroll_callback(double xoffset, double yoffset) override;
294
295 /**
296 * \brief Setups OpenGL for scene drawing.
297 */
298 virtual void draw_scene_begin();
299
300 /**
301 * \brief Draws the scene.
302 */
303 virtual void draw_scene();
304
305 /**
306 * \brief Cleanups OpenGL after scene drawing.
307 */
308 virtual void draw_scene_end();
309
310 /**
311 * \brief Draws the viewer properties window frame and contents.
312 */
313 virtual void draw_viewer_properties_window();
314
315 /**
316 * \brief Draws the contents of viewer properties window.
317 */
318 virtual void draw_viewer_properties();
319
320 /**
321 * \brief Draw the object properties window frame and contents.
322 */
323 virtual void draw_object_properties_window();
324
325 /**
326 * \brief Draws the contents of the object properties window.
327 */
328 virtual void draw_object_properties();
329
330
331 /**
332 * \brief Draws the active command window if any.
333 */
334 virtual void draw_command_window();
335
336 /**
337 * \brief Draws the console.
338 */
339 virtual void draw_console();
340
341
342 /**
343 * \brief Draws the menu bar.
344 */
345 virtual void draw_menu_bar();
346
347
348 /**
349 * \brief Draws the load menu and browser.
350 */
351 virtual void draw_load_menu();
352
353 /**
354 * \brief Draws the save menu.
355 */
356 virtual void draw_save_menu();
357
358 /**
359 * \brief Draws other file operation menu.
360 * \details Default implementation does nothing.
361 * It can be overloaded to add other menu
362 * items in the file menu.
363 */
364 virtual void draw_fileops_menu();
365
366 /**
367 * \brief Draws the about box in the file menu.
368 */
369 virtual void draw_about();
370
371 /**
372 * \brief Draws help info (accelarators)
373 */
374 virtual void draw_help();
375
376 /**
377 * \brief Draws the windows menu.
378 */
379 virtual void draw_windows_menu();
380
381 /**
382 * \brief Draws the application menus.
383 * \details Meant to be overloaded by derived classes.
384 */
385 virtual void draw_application_menus();
386
387 /**
388 * \brief Draws the application icons on the menubar.
389 * \details Meant to be overloaded by derived classes.
390 */
391 virtual void draw_application_icons();
392
393
394 /**
395 * \brief Draws a window to edit all command line arguments
396 */
397 virtual void draw_command_line_editor();
398
399
400 /**
401 * \copydoc Application::post_draw()
402 */
403 void post_draw() override;
404
405 /**
406 * \brief Tests whether a file can be loaded.
407 * \details This function can be used to filter the files displayed
408 * in the "Load..." menu. Baseclass implementation always return true.
409 * Derived classes may overload it and return false for files with
410 * unknown extensions.
411 */
412 virtual bool can_load(const std::string& filename);
413
414 /**
415 * \brief Gets the list of supported file extensions for reading.
416 * \details This function may be olverloaded by derived class. Base
417 * class implementation returns "". If this function returns "", then
418 * no "Load..." option is displayed in the "File" menu.
419 * \return The semi-colon separated list of supported file extensions,
420 * or "*" if all file extensions are supported.
421 */
422 virtual std::string supported_read_file_extensions();
423
424 /**
425 * \brief Gets the list of supported file extensions for writing.
426 * \details This function may be olverloaded by derived class. Base
427 * class implementation returns "". If this function returns "", then
428 * no "Save..." option is displayed in the "File" menu.
429 * If it returns a colon-separated list of extensions, then the
430 * "Save..." option displays a list of possible file names for each
431 * supported extension.
432 * \return The semi-colon separated list of supported file extensions,
433 * or "*" if all file extensions are supported.
434 */
435 virtual std::string supported_write_file_extensions();
436
437 /**
438 * \copydoc GEO::Application::GL_initialize()
439 */
440 void GL_initialize() override;
441
442 /**
443 * \copydoc GEO::Application::GL_terminate()
444 */
445 void GL_terminate() override;
446
447 /**
448 * \brief Recursively browses a directory and generates
449 * menu items.
450 * \param[in] path the path to be browsed
451 * \param[in] subdirs if true, browse subdirectories as well
452 */
453 void browse(const std::string& path, bool subdirs=false);
454
455 /**
456 * \copydoc GEO::Application::geogram_initialize()
457 */
458 void geogram_initialize(int argc, char** argv) override;
459
460 /**
461 * \brief Sets the default filename used to save
462 * the current file.
463 * \param[in] filename the default filename.
464 */
465 void set_default_filename(const std::string& filename) {
466 strcpy(filename_, filename.c_str());
467 }
468
469 /**
470 * \brief Initializes a new colormap from name and xpm data.
471 * \details This function can be called only once the OpenGL
472 * context is ready, for instance in the init_graphics() function.
473 * \param[in] name the name of the colormap
474 * \param[in] xpm_data the image data of the colormap.
475 */
476 void init_colormap(const std::string& name, const char** xpm_data);
477
478 /**
479 * \brief Initializes all the default colormaps.
480 * \details This function can be called only once the OpenGL
481 * context is ready, for instance in the init_graphics() function.
482 */
483 void init_colormaps();
484
485 /**
486 * \copydoc Application::ImGui_initialize()
487 */
488 void ImGui_initialize() override;
489
490 void set_2d() {
491 three_D_ = false;
492 }
493
494 void set_3d() {
495 three_D_ = true;
496 }
497
498 void set_default_layout();
499
500 void resize(index_t w, index_t h, index_t fb_w, index_t fb_h) override;
501
502 virtual const char* default_layout() const;
503 virtual const char* default_layout_android_vertical() const;
504 virtual const char* default_layout_android_horizontal() const;
505
506 /**
507 * \brief This function is changed each time the user changed the
508 * value of a command line argument in the command line editor.
509 * \param[in] argname the name of the argument that changed
510 */
511 virtual void command_line_arg_changed(const std::string& argname);
512
513 /**
514 * \brief Executes once again the latest issued command
515 * \details SimpleApplication has a mechanism to handle user commands
516 * implemented in menus. The latest command is memorized, and not
517 * directly executed when the user invokes a menu, this is to avoid
518 * launching a command while in ImGui rendering/event handler. In
519 * addition, one can use this mechanism to replay the latest
520 * memorized command (by default, this is bound to the F5 key).
521 */
522 static void replay_latest_command();
523
524 /**
525 * \brief Copies a rectangular zone of the framebuffer to an image
526 * \param[in,out] image pointer to an image. If uninitialized, then
527 * it will be initialized to an RGB image of the specified size, else
528 * the present allocated image and colore ecoding are used.
529 * \param[in] x0 , y0 origin
530 * \param[in] width , height size. If not set, then window size is used.
531 * \param[in] redraw if set (default), then scene is redrawn before
532 * taking the snapshot, without the GUI superimposed, else the current
533 * content of the framebuffer is used (may have the GUI superimposed).
534 */
535 virtual void snapshot(
536 Image* image,
537 index_t x0=0, index_t y0=0, index_t width=0, index_t height=0,
538 bool redraw = true
539 );
540
541 /**
542 * \brief Saves the framebuffer to an image
543 * \details The scene is redrawn without the gui.
544 * \param[in] filename if left unspecified, then the command line
545 * argument gui:snapshot_filename is used.
546 * \param[in] verbose if set, display a message with the snapshot
547 * filename
548 */
549 virtual void snapshot(std::string filename = "", bool verbose=false);
550
551 /**
552 * \copydoc Application::declare_args()
553 */
554 void declare_args() override;
555
556 protected:
557 bool locked_; // avoid starting command when command is running
558 bool lighting_;
559 bool edit_light_;
560 bool clipping_;
561 GLUPclipMode clip_mode_;
562 bool edit_clip_;
563 bool fixed_clip_;
564 GLenum effect_;
565 vec4f background_color_;
566
567 bool viewer_properties_visible_;
568 bool object_properties_visible_;
569 bool console_visible_;
570 bool text_editor_visible_;
571 bool use_text_editor_;
572 bool command_line_editor_visible_;
573
574 Box roi_;
575 double roi_radius_;
576 vec3 object_translation_;
577 ArcBall object_rotation_;
578 ArcBall light_rotation_;
579 ArcBall clip_rotation_;
580 vec3 clip_translation_;
581 bool three_D_;
582 double zoom_;
583 double zoom_down_; /**< Zoom when mouse down. */
584
585 bool props_pinned_;
586
587 enum MouseOp {
588 MOUSE_NOOP, MOUSE_ROTATE, MOUSE_TRANSLATE, MOUSE_ZOOM
589 } mouse_op_;
590
591 enum MouseTarget {
592 MOUSE_NOTARGET, MOUSE_OBJECT, MOUSE_LIGHT, MOUSE_CLIP
593 } mouse_target_;
594
595 vec2 mouse_down_xy_; // in [-1,1] x [-1,1]
596 vec2 mouse_xy_; // in [-1,1] x [-1,1]
597
598 // Current transform, for picking
599 GLint viewport_[4];
600 mat4 modelview_transpose_;
601 mat4 project_transpose_;
602
603 std::string path_;
604 std::string current_file_;
605 char filename_[geo_imgui_string_length]; // Buffer for file dialog.
606 GLuint geogram_logo_texture_;
607
608 Console_var console_;
609 StatusBar_var status_bar_;
610 TextEditor text_editor_;
611
612 std::map< std::string, std::function<void()> > key_funcs_;
613 std::map< std::string, std::string > key_funcs_help_;
614
615 struct ColormapInfo {
616 ColormapInfo() : texture(0) {
617 }
618 GLuint texture;
619 std::string name;
620 };
621
622 vector<ColormapInfo> colormaps_;
623 FullScreenEffectImpl_var full_screen_effect_;
624
625 lua_State* lua_state_;
626 bool lua_error_occured_;
627 };
628
629 }
630
631 #endif
632