1 /*
2  *  Copyright (c) 2012-2016, Bruno Levy
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  *  If you modify this software, you should include a notice giving the
30  *  name of the person performing the modification, the date of modification,
31  *  and the reason for such modification.
32  *
33  *  Contact: Bruno Levy
34  *
35  *     Bruno.Levy@inria.fr
36  *     http://www.loria.fr/~levy
37  *
38  *     ALICE Project
39  *     LORIA, INRIA Lorraine,
40  *     Campus Scientifique, BP 239
41  *     54506 VANDOEUVRE LES NANCY CEDEX
42  *     FRANCE
43  *
44  */
45 
46 #ifndef GEOGRAM_GFX_IMGUI_EXT
47 #define GEOGRAM_GFX_IMGUI_EXT
48 
49 #include <geogram_gfx/basic/common.h>
50 #include <string>
51 
52 #ifdef GEO_COMPILER_CLANG
53 #pragma GCC diagnostic push
54 #pragma GCC diagnostic ignored "-Wunknown-warning-option"
55 #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
56 #endif
57 
58 #include <geogram_gfx/third_party/ImGui/imgui.h>
59 
60 #ifdef GEO_COMPILER_CLANG
61 #pragma GCC diagnostic pop
62 #endif
63 
64 
65 /**
66  * \file geogram_gfx/ImGui_ext/imgui_ext.h
67  * \brief Extension functions for ImGui.
68  */
69 
70 namespace GEO {
71     /**
72      * \brief Maximum string length for ImGUI.
73      * TODO replace with ImGui functions to handle dynamic buffer with
74      *  InputText().
75      */
76     enum { geo_imgui_string_length = 4096 };
77 
78     namespace FileSystem {
79 	class Node;
80     }
81 }
82 
83 typedef int ImGuiExtFileDialogFlags;
84 
85 
86 enum ImGuiExtFileDialogFlags_ {
87     ImGuiExtFileDialogFlags_Load  = 1,
88     ImGuiExtFileDialogFlags_Save  = 2
89 };
90 
91 
92 namespace ImGui {
93 
94     /**
95      * \brief Gets the global application scaling.
96      * \details The global application scaling can be changed
97      *   for high DPI displays. Some GUI elements need to
98      *   be scaled accordingly.
99      * \return The global application scaling.
100      */
101     float GEOGRAM_GFX_API scaling();
102 
103     /**
104      * \brief Sets the global application scaling.
105      * \details The global application scaling can be changed
106      *   for high DPI displays. Some GUI elements need to
107      *   be scaled accordingly.
108      * \param x The global application scaling.
109      */
110     void GEOGRAM_GFX_API set_scaling(float x);
111 
112     /**
113      * \brief Manages the GUI of a color editor.
114      * \details This creates a custom dialog with the color editor and
115      *  a default palette, as in ImGUI example.
116      * \param[in] label the label of the widget, passed to ImGUI
117      * \param[in,out] color a pointer to an array of 3 floats
118      * \retval true if the color was changed
119      * \retval false otherwise
120      */
121     bool GEOGRAM_GFX_API ColorEdit3WithPalette(
122 	const char* label, float* color
123     );
124 
125     /**
126      * \brief Manages the GUI of a color editor.
127      * \details This creates a custom dialog with the color editor and
128      *  a default palette, as in ImGUI example.
129      * \param[in] label the label of the widget, passed to ImGUI
130      * \param[in,out] color a pointer to an array of 4 floats
131      * \retval true if the color was changed
132      * \retval false otherwise
133      */
134     bool GEOGRAM_GFX_API ColorEdit4WithPalette(
135 	const char* label, float* color
136     );
137 
138     /**
139      * \brief Opens a file dialog.
140      * \param[in] label the window label of the file dialog
141      * \param[in] extensions semi-colon-separated list of extensions, without
142      *  the dot
143      * \param[in] filename initial filename or empty string
144      * \param[in] root an optional root Node. If null or unspecified, then
145      *  the default root is used.
146      * \details The file dialog is drawn and handled after, by calling
147      *  FileDialog()
148      */
149     void GEOGRAM_GFX_API OpenFileDialog(
150 	const char* label,
151 	const char* extensions,
152 	const char* filename,
153 	ImGuiExtFileDialogFlags flags,
154 	GEO::FileSystem::Node* root = nullptr
155     );
156 
157     /**
158      * \brief Draws a FileDialog.
159      * \details If OpenFileDialog() was called before, then the dialog is drawn,
160      *  otherwise it is ignored.
161      * \param[in] label the window label of the file dialog
162      * \param[in,out] filename the file to be read
163      * \param[in] filename_buff_len the size of the buffer pointed by filename
164      * \retval true if a file was selected
165      * \retval false otherwise
166      */
167     bool GEOGRAM_GFX_API FileDialog(
168 	const char* label,
169 	char* filename, size_t filename_buff_len
170     );
171 
172     /**
173      * \brief Adapter for ImGui::MenuItem() for std::string.
174      */
175     inline bool MenuItem(
176 	const std::string& name, const char* shortcut,
177 	bool* p_selected = nullptr, bool enabled = true
178     ) {
179 	return ImGui::MenuItem(name.c_str(), shortcut, p_selected, enabled);
180     }
181 
182     /**
183      * \brief Adapter for ImGui::MenuItem() for std::string.
184      */
185     inline bool MenuItem(
186 	const std::string& name, const char* shortcut = nullptr,
187 	bool selected = false, bool enabled = true
188     ) {
189 	return ImGui::MenuItem(name.c_str(), shortcut, selected, enabled);
190     }
191 
192     /**
193      * \brief Adapter for ImGui::BeginMenu() for std::string.
194      */
BeginMenu(const std::string & name)195     inline bool BeginMenu(const std::string& name) {
196 	return ImGui::BeginMenu(name.c_str());
197     }
198 
199     /**
200      * \brief Adapter for ImGui::Button() for std::string.
201      */
Button(const std::string & name)202     inline bool Button(const std::string& name) {
203 	return ImGui::Button(name.c_str());
204     }
205 
206     /**
207      * \brief Displays a tooltip.
208      * \details The tooltip is displayed if the previous item is hovered,
209      *  \p str is non-null and tooltips are enabled.
210      * \param[in] str the tooltip to be displayed.
211      * \see EnableTooltips(), DisableToolTips()
212      */
213     void GEOGRAM_GFX_API Tooltip(const char* str);
214 
215     /**
216      * \brief Displays a tooltip.
217      * \details The tooltip is displayed if the previous item is hovered,
218      *  \p str is non-null and tooltips are enabled.
219      * \param[in] s the tooltip to be displayed.
220      * \see EnableTooltips(), DisableToolTips()
221      */
Tooltip(const std::string & s)222     inline void Tooltip(const std::string& s) {
223 	Tooltip(s.c_str());
224     }
225 
226     /**
227      * \brief Enables tooltips.
228      * \see ToolTip()
229      */
230     void GEOGRAM_GFX_API EnableTooltips();
231 
232     /**
233      * \brief Disables tooltips.
234      * \see ToolTip()
235      */
236     void GEOGRAM_GFX_API DisableTooltips();
237 
238 
239     /**
240      * \brief Button without border.
241      */
242     bool GEOGRAM_GFX_API SimpleButton(const char* label);
243 
244     /**
245      * \brief Button without border.
246      */
247     bool GEOGRAM_GFX_API SimpleButton(const char* label, const ImVec2& size);
248 
249     /**
250      * \brief Wrapper for std::string around SimpleButton()
251      */
SimpleButton(const std::string & label)252     inline bool SimpleButton(const std::string& label) {
253 	return SimpleButton(label.c_str());
254     }
255 
256     /**
257      * \brief Draws a text label centered in the current window.
258      * \param[in] text the text to be drawn.
259      */
260     void GEOGRAM_GFX_API CenteredText(const char* text);
261 }
262 
263 #endif
264 
265