forked from aiekick/ImGuiFileDialog
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathImGuiFileDialog.h
2280 lines (1830 loc) · 106 KB
/
ImGuiFileDialog.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#pragma once
#pragma warning(disable : 4251)
#pragma region IGFD LICENSE
/*
MIT License
Copyright (c) 2018-2023 Stephane Cuillerdier (aka aiekick)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#pragma endregion
#pragma region IGFD DOCUMENTATION
/*
// generated with "Text to ASCII Art Generator (TAAG)"
// https://patorjk.com/software/taag/#p=display&h=1&v=0&f=Big&t=ImGuiFileDialog%0Av0.6.5
_____ _____ _ ______ _ _ _____ _ _
|_ _| / ____| (_) ____(_) | | __ \(_) | |
| | _ __ ___ | | __ _ _ _| |__ _| | ___| | | |_ __ _| | ___ __ _
| | | '_ ` _ \| | |_ | | | | | __| | | |/ _ \ | | | |/ _` | |/ _ \ / _` |
_| |_| | | | | | |__| | |_| | | | | | | __/ |__| | | (_| | | (_) | (_| |
|_____|_| |_| |_|\_____|\__,_|_|_| |_|_|\___|_____/|_|\__,_|_|\___/ \__, |
_________________________________________________________________________/ |
|__________________________________________________________________________/
___ __ __
/ _ \ / / / /
__ __| | | | / /_ / /_
\ \ / /| | | | | '_ \ | '_ \
\ V / | |_| |_| (_) |_| (_) |
\_/ \___/(_)\___/(_)\___/
github repo : https://github.com/aiekick/ImGuiFileDialog
this section is the content of the ReadMe.md file
# ImGuiFileDialog
## Purpose
ImGuiFileDialog is a file selection dialog built for (and using only) [Dear ImGui](https://github.com/ocornut/imgui).
My primary goal was to have a custom pane with widgets according to file extension. This was not possible using other
solutions.
## ImGui Supported Version
ImGuiFileDialog follow the master and docking branch of ImGui . currently ImGui 1.89.7 WIP
## Structure
* The library is in [Lib_Only branch](https://github.com/aiekick/ImGuiFileDialog/tree/Lib_Only)
* A demo app can be found the [master branch](https://github.com/aiekick/ImGuiFileDialog/tree/master)
This library is designed to be dropped into your source code rather than compiled separately.
From your project directory:
```
mkdir lib <or 3rdparty, or externals, etc.>
cd lib
git clone https://github.com/aiekick/ImGuiFileDialog.git
git checkout Lib_Only
```
These commands create a `lib` directory where you can store any third-party dependencies used in your project, downloads
the ImGuiFileDialog git repository and checks out the Lib_Only branch where the actual library code is located.
Add `lib/ImGuiFileDialog/ImGuiFileDialog.cpp` to your build system and include
`lib/ImGuiFileDialog/ImGuiFileDialog.h` in your source code. ImGuiFileLib will compile with and be included directly in
your executable file.
If, for example, your project uses cmake, look for a line like `add_executable(my_project_name main.cpp)`
and change it to `add_executable(my_project_name lib/ImGuiFileDialog/ImGuiFileDialog.cpp main.cpp)`. This tells the
compiler where to find the source code declared in `ImGuiFileDialog.h` which you included in your own source code.
## Requirements:
You must also, of course, have added [Dear ImGui](https://github.com/ocornut/imgui) to your project for this to work at
all.
[dirent v1.23](https://github.com/tronkko/dirent/tree/v1.23) is required to use ImGuiFileDialog under Windows. It is
included in the Lib_Only branch for your convenience.
################################################################
## Features
################################################################
- C Api (succesfully tested with CimGui)
- Separate system for call and display
- Can have many function calls with different parameters for one display function, for example
- Can create a custom pane with any widgets via function binding
- This pane can block the validation of the dialog
- Can also display different things according to current filter and UserDatas
- Advanced file style for file/dir/link coloring / icons / font
- predefined form or user custom form by lambda function (the lambda mode is not available for the C API)
- Multi-selection (ctrl/shift + click) :
- 0 => Infinite
- 1 => One file (default)
- n => n files
- Compatible with MacOs, Linux, Windows
- Windows version can list drives
- Supports modal or standard dialog types
- Select files or directories
- Filter groups and custom filter names
- can ignore filter Case for file searching
- Keyboard navigation (arrows, backspace, enter)
- Exploring by entering characters (case insensitive)
- Directory bookmarks
- Directory manual entry (right click on any path element)
- Optional 'Confirm to Overwrite" dialog if file exists
- Thumbnails Display (agnostic way for compatibility with any backend, sucessfully tested with OpenGl and Vulkan)
- The dialog can be embedded in another user frame than the standard or modal dialog
- Can tune validation buttons (placements, widths, inversion)
- Can quick select a parrallel directory of a path, in the path composer (when you clikc on a / you have a popup)
- regex support for filters, collection of filters and filestyle (the regex is recognized when between (( and )) in a filter)
- multi layer extentions like : .a.b.c .json.cpp .vcxproj.filters etc..
- advanced behavior regarding asterisk based filter. like : .* .*.* .vcx.* .*.filters .vcs*.filt.* etc.. (internally regex is used)
- result modes GetFilePathName, GetFileName and GetSelection (overwrite file ext, keep file, add ext if no user ext exist)
################################################################
## Filter format
################################################################
A filter is recognized only if he respects theses rules :
0) a filter must have 2 chars mini and the first must be a .
1) a regex must be in (( and ))
2) a , will separate filters except if between a ( and )
3) name{filter1, filter2} is a special form for collection filters
3.1) the name can be composed of what you want except { and }
3.2) a filter can be a regex
4) the filters cannot integrate these chars '(' ')' '{' '}' ' ' except for a regex with respect to rule 1)
5) the filters cannot integrate a ','
################################################################
## Singleton Pattern vs. Multiple Instances
################################################################
### Single Dialog :
If you only need to display one file dialog at a time, use ImGuiFileDialog's singleton pattern to avoid explicitly
declaring an object:
```cpp
ImGuiFileDialog::Instance()->method_of_your_choice();
```
### Multiple Dialogs :
If you need to have multiple file dialogs open at once, declare each dialog explicity:
```cpp
ImGuiFileDialog instance_a;
instance_a.method_of_your_choice();
ImGuiFileDialog instance_b;
instance_b.method_of_your_choice();
```
################################################################
## Simple Dialog :
################################################################
```cpp
void drawGui()
{
// open Dialog Simple
if (ImGui::Button("Open File Dialog"))
ImGuiFileDialog::Instance()->OpenDialog("ChooseFileDlgKey", "Choose File", ".cpp,.h,.hpp", ".");
// display
if (ImGuiFileDialog::Instance()->Display("ChooseFileDlgKey"))
{
// action if OK
if (ImGuiFileDialog::Instance()->IsOk())
{
std::string filePathName = ImGuiFileDialog::Instance()->GetFilePathName();
std::string filePath = ImGuiFileDialog::Instance()->GetCurrentPath();
// action
}
// close
ImGuiFileDialog::Instance()->Close();
}
}
```
![alt text](https://github.com/aiekick/ImGuiFileDialog/blob/master/doc/dlg_simple.gif)
################################################################
## Modal dialog :
################################################################
you have now a flag for open modal dialog :
```cpp
ImGuiFileDialogFlags_Modal
```
you can use it like that :
```cpp
ImGuiFileDialog::Instance()->OpenDialog("ChooseFileDlgKey", "Choose File", ".cpp,.h,.hpp",
".", 1, nullptr, ImGuiFileDialogFlags_Modal);
```
################################################################
## Directory Chooser :
################################################################
To have a directory chooser, set the file extension filter to nullptr:
```cpp
ImGuiFileDialog::Instance()->OpenDialog("ChooseDirDlgKey", "Choose a Directory", nullptr, ".");
```
In this mode you can select any directory with one click and open a directory with a double-click.
![directoryChooser](https://github.com/aiekick/ImGuiFileDialog/blob/master/doc/directoryChooser.gif)
################################################################
## Dialog with Custom Pane :
################################################################
The signature of the custom pane callback is:
### for C++ :
```cpp
void(const char *vFilter, IGFDUserDatas vUserDatas, bool *vCantContinue)
```
### for C :
```c
void(const char *vFilter, void* vUserDatas, bool *vCantContinue)
```
### Example :
```cpp
static bool canValidateDialog = false;
inline void InfosPane(cosnt char *vFilter, IGFDUserDatas vUserDatas, bool *vCantContinue) // if vCantContinue is false, the user cant validate the dialog
{
ImGui::TextColored(ImVec4(0, 1, 1, 1), "Infos Pane");
ImGui::Text("Selected Filter : %s", vFilter.c_str());
if (vUserDatas)
ImGui::Text("UserDatas : %s", vUserDatas);
ImGui::Checkbox("if not checked you cant validate the dialog", &canValidateDialog);
if (vCantContinue)
*vCantContinue = canValidateDialog;
}
void drawGui()
{
// open Dialog with Pane
if (ImGui::Button("Open File Dialog with a custom pane"))
ImGuiFileDialog::Instance()->OpenDialog("ChooseFileDlgKey", "Choose File", ".cpp,.h,.hpp",
".", "", std::bind(&InfosPane, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), 350, 1, UserDatas("InfosPane"));
// display and action if ok
if (ImGuiFileDialog::Instance()->Display("ChooseFileDlgKey"))
{
if (ImGuiFileDialog::Instance()->IsOk())
{
std::string filePathName = ImGuiFileDialog::Instance()->GetFilePathName();
std::string filePath = ImGuiFileDialog::Instance()->GetCurrentPath();
std::string filter = ImGuiFileDialog::Instance()->GetCurrentFilter();
// here convert from string because a string was passed as a userDatas, but it can be what you want
std::string userDatas;
if (ImGuiFileDialog::Instance()->GetUserDatas())
userDatas = std::string((const char*)ImGuiFileDialog::Instance()->GetUserDatas());
auto selection = ImGuiFileDialog::Instance()->GetSelection(); // multiselection
// action
}
// close
ImGuiFileDialog::Instance()->Close();
}
}
```
![alt text](https://github.com/aiekick/ImGuiFileDialog/blob/master/doc/doc/dlg_with_pane.gif)
################################################################
## File Style : Custom icons and colors by extension
################################################################
You can define style for files/dirs/links in many ways :
the style can be colors, icons and fonts
the general form is :
```cpp
ImGuiFileDialog::Instance()->SetFileStyle(styleType, criteria, color, icon, font);
```
### Predefined Form :
styleType can be thoses :
```cpp
IGFD_FileStyleByTypeFile // define style for all files
IGFD_FileStyleByTypeDir // define style for all dir
IGFD_FileStyleByTypeLink // define style for all link
IGFD_FileStyleByExtention // define style by extention, for files or links
IGFD_FileStyleByFullName // define style for particular file/dir/link full name (filename + extention)
IGFD_FileStyleByContainedInFullName // define style for file/dir/link when criteria is contained in full name
```
### Lambda Function Form :
You can define easily your own style include your own detection by using lambda function :
** To note, this mode is not available with the C API **
this lamba will treat a file and return a shared pointer of your files style
see in action a styling of all files and dir starting by a dot
this lambda input a FileInfos and output a FileStyle
return true if a FileStyle was defined
```cpp
ImGuiFileDialog::Instance()->SetFileStyle([](const IGFD::FileInfos& vFile, IGFD::FileStyle &vOutStyle) -> bool {
if (!vFile.fileNameExt.empty() && vFile.fileNameExt[0] == '.') {
vOutStyle = IGFD::FileStyle(ImVec4(0.0f, 0.9f, 0.9f, 1.0f), ICON_IGFD_REMOVE);
return true;
}
return false;
});
```
see sample app for the code in action
### Samples :
ImGuiFileDialog accepts icon font macros as well as text tags for file types.
[ImGuIFontStudio](https://github.com/aiekick/ImGuiFontStudio) is useful here. I wrote it to make it easy to create
custom icon sets for use with Dear ImGui.
It is inspired by [IconFontCppHeaders](https://github.com/juliettef/IconFontCppHeaders), which can also be used with
ImGuiFileDialog.
samples :
```cpp
// define style by file extention and Add an icon for .png files
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByExtention, ".png", ImVec4(0.0f, 1.0f, 1.0f, 0.9f), ICON_IGFD_FILE_PIC, font1);
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByExtention, ".gif", ImVec4(0.0f, 1.0f, 0.5f, 0.9f), "[GIF]");
// define style for all directories
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByTypeDir, "", ImVec4(0.5f, 1.0f, 0.9f, 0.9f), ICON_IGFD_FOLDER);
// can be for a specific directory
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByTypeDir, ".git", ImVec4(0.5f, 1.0f, 0.9f, 0.9f), ICON_IGFD_FOLDER);
// define style for all files
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByTypeFile, "", ImVec4(0.5f, 1.0f, 0.9f, 0.9f), ICON_IGFD_FILE);
// can be for a specific file
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByTypeFile, ".git", ImVec4(0.5f, 1.0f, 0.9f, 0.9f), ICON_IGFD_FILE);
// define style for all links
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByTypeLink, "", ImVec4(0.5f, 1.0f, 0.9f, 0.9f));
// can be for a specific link
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByTypeLink, "Readme.md", ImVec4(0.5f, 1.0f, 0.9f, 0.9f));
// define style for any files/dirs/links by fullname
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByFullName, "doc", ImVec4(0.9f, 0.2f, 0.0f, 0.9f), ICON_IGFD_FILE_PIC);
// define style by file who are containing this string
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByContainedInFullName, ".git", ImVec4(0.9f, 0.2f, 0.0f, 0.9f), ICON_IGFD_BOOKMARK);
all of theses can be miwed with IGFD_FileStyleByTypeDir / IGFD_FileStyleByTypeFile / IGFD_FileStyleByTypeLink
like theses by ex :
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByTypeDir | IGFD_FileStyleByContainedInFullName, ".git", ImVec4(0.9f, 0.2f, 0.0f, 0.9f), ICON_IGFD_BOOKMARK);
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByTypeFile | IGFD_FileStyleByFullName, "cmake", ImVec4(0.5f, 0.8f, 0.5f, 0.9f), ICON_IGFD_SAVE);
// for all these,s you can use a regex
// ex for color files like Custom*.h
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByFullName, "((Custom.+[.]h))", ImVec4(0.0f, 1.0f, 1.0f, 0.9f), ICON_IGFD_FILE_PIC, font1);
// lambda function
// set file style with a lambda function
// return true is a file style was defined
ImGuiFileDialog::Instance()->SetFileStyle([](const IGFD::FileInfos& vFile, IGFD::FileStyle &vOutStyle) -> bool {
if (!vFile.fileNameExt.empty() && vFile.fileNameExt[0] == '.') {
vOutStyle = IGFD::FileStyle(ImVec4(0.0f, 0.9f, 0.9f, 1.0f), ICON_IGFD_REMOVE);
return true;
}
return false;
});
```
this sample code of [master/main.cpp](https://github.com/aiekick/ImGuiFileDialog/blob/master/main.cpp) produce the picture above :
```cpp
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByExtention, ".cpp", ImVec4(1.0f, 1.0f, 0.0f, 0.9f));
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByExtention, ".h", ImVec4(0.0f, 1.0f, 0.0f, 0.9f));
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByExtention, ".hpp", ImVec4(0.0f, 0.0f, 1.0f, 0.9f));
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByExtention, ".md", ImVec4(1.0f, 0.0f, 1.0f, 0.9f));
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByExtention, ".png", ImVec4(0.0f, 1.0f, 1.0f, 0.9f), ICON_IGFD_FILE_PIC); // add an icon for the filter type
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByExtention, ".gif", ImVec4(0.0f, 1.0f, 0.5f, 0.9f), "[GIF]"); // add an text for a filter type
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByTypeDir, nullptr, ImVec4(0.5f, 1.0f, 0.9f, 0.9f), ICON_IGFD_FOLDER); // for all dirs
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByTypeFile, "CMakeLists.txt", ImVec4(0.1f, 0.5f, 0.5f, 0.9f), ICON_IGFD_ADD);
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByFullName, "doc", ImVec4(0.9f, 0.2f, 0.0f, 0.9f), ICON_IGFD_FILE_PIC);
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByTypeDir | IGFD_FileStyleByContainedInFullName, ".git", ImVec4(0.9f, 0.2f, 0.0f, 0.9f), ICON_IGFD_BOOKMARK);
ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByTypeFile | IGFD_FileStyleByContainedInFullName, ".git", ImVec4(0.5f, 0.8f, 0.5f, 0.9f), ICON_IGFD_SAVE);
```
![alt text](https://github.com/aiekick/ImGuiFileDialog/blob/master/doc/color_filter.png)
################################################################
## Filter Collections
################################################################
You can define a custom filter name that corresponds to a group of filters using this syntax:
```custom_name1{filter1,filter2,filter3},custom_name2{filter1,filter2},filter1```
When you select custom_name1, filters 1 to 3 will be applied. The characters `{` and `}` are reserved. Don't use them
for filter names.
this code :
```cpp
const char *filters = "Source files (*.cpp *.h *.hpp){.cpp,.h,.hpp},Image files (*.png *.gif *.jpg *.jpeg){.png,.gif,.jpg,.jpeg},.md";
ImGuiFileDialog::Instance()->OpenDialog("ChooseFileDlgKey", ICON_IMFDLG_FOLDER_OPEN " Choose a File", filters, ".");
```
will produce :
![alt text](https://github.com/aiekick/ImGuiFileDialog/blob/master/doc/filters.gif)
################################################################
## Multi Selection
################################################################
You can define in OpenDialog call the count file you want to select :
- 0 => infinite
- 1 => one file only (default)
- n => n files only
See the define at the end of these funcs after path.
```cpp
ImGuiFileDialog::Instance()->OpenDialog("ChooseFileDlgKey", "Choose File", ".*,.cpp,.h,.hpp", ".");
ImGuiFileDialog::Instance()->OpenDialog("ChooseFileDlgKey", "Choose 1 File", ".*,.cpp,.h,.hpp", ".", 1);
ImGuiFileDialog::Instance()->OpenDialog("ChooseFileDlgKey", "Choose 5 File", ".*,.cpp,.h,.hpp", ".", 5);
ImGuiFileDialog::Instance()->OpenDialog("ChooseFileDlgKey", "Choose many File", ".*,.cpp,.h,.hpp", ".", 0);
ImGuiFileDialog::Instance()->OpenDialog("ChooseFileDlgKey", "Choose File", ".png,.jpg",
".", "", std::bind(&InfosPane, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), 350, 1, "SaveFile"); // 1 file
```
![alt text](https://github.com/aiekick/ImGuiFileDialog/blob/master/doc/multiSelection.gif)
################################################################
## File Dialog Constraints
################################################################
You can set the minimum and/or maximum size of the dialog:
```cpp
ImVec2 maxSize = ImVec2((float)display_w, (float)display_h); // The full display area
ImVec2 minSize = maxSize * 0.5f; // Half the display area
ImGuiFileDialog::Instance()->Display("ChooseFileDlgKey", ImGuiWindowFlags_NoCollapse, minSize, maxSize);
```
![alt text](https://github.com/aiekick/ImGuiFileDialog/blob/master/doc/dialog_constraints.gif)
################################################################
## Exploring by keys
################################################################
You can activate this feature by uncommenting `#define USE_EXPLORATION_BY_KEYS`
in your custom config file (CustomImGuiFileDialogConfig.h)
You can also uncomment the next lines to define navigation keys:
* IGFD_KEY_UP => Up key for explore to the top
* IGFD_KEY_DOWN => Down key for explore to the bottom
* IGFD_KEY_ENTER => Enter key for open directory
* IGFD_KEY_BACKSPACE => BackSpace for comming back to the last directory
You can also jump to a point in the file list by pressing the corresponding key of the first filename character.
![alt text](https://github.com/aiekick/ImGuiFileDialog/blob/master/doc/explore_ny_keys.gif)
As you see the current item is flashed by default for 1 second. You can define the flashing lifetime with the function
```cpp
ImGuiFileDialog::Instance()->SetFlashingAttenuationInSeconds(1.0f);
```
################################################################
## Bookmarks
################################################################
You can create/edit/call path bookmarks and load/save them.
Activate this feature by uncommenting: `#define USE_BOOKMARK` in your custom config file (CustomImGuiFileDialogConfig.h)
More customization options:
```cpp
#define bookmarkPaneWith 150.0f => width of the bookmark pane
#define IMGUI_TOGGLE_BUTTON ToggleButton => customize the Toggled button (button stamp must be : (const char* label, bool *toggle)
#define bookmarksButtonString "Bookmark" => the text in the toggle button
#define bookmarksButtonHelpString "Bookmark" => the helper text when mouse over the button
#define addBookmarkButtonString "+" => the button for add a bookmark
#define removeBookmarkButtonString "-" => the button for remove the selected bookmark
```
* You can select each bookmark to edit the displayed name corresponding to a path
* Double-click on the label to apply the bookmark
![bookmarks.gif](https://github.com/aiekick/ImGuiFileDialog/blob/master/doc/bookmarks.gif)
You can also serialize/deserialize bookmarks (for example to load/save from/to a file):
```cpp
Load => ImGuiFileDialog::Instance()->DeserializeBookmarks(bookmarString);
Save => std::string bookmarkString = ImGuiFileDialog::Instance()->SerializeBookmarks();
```
(please see example code for details)
you can also add/remove bookmark by code :
and in this case, you can also avoid serialization of code based bookmark
```cpp
Add => ImGuiFileDialog::Instance()->AddBookmark(bookmark_name, bookmark_path);
Remove => ImGuiFileDialog::Instance()->RemoveBookmark(bookmark_name);
Save => std::string bookmarkString = ImGuiFileDialog::Instance()->SerializeBookmarks(true); // true for prevent serialization of code based bookmarks
```
################################################################
## Path Edition :
################################################################
Right clicking on any path element button allows the user to manually edit the path from that portion of the tree.
Pressing the completion key (GLFW uses `enter` by default) validates the new path. Pressing the cancel key (GLFW
uses`escape` by default) cancels the manual entry and restores the original path.
Here's the manual entry operation in action:
![inputPathEdition.gif](https://github.com/aiekick/ImGuiFileDialog/blob/master/doc/inputPathEdition.gif)
################################################################
## Confirm Overwrite Dialog :
################################################################
If you want avoid overwriting files after selection, ImGuiFileDialog can show a dialog to confirm or cancel the
operation.
To do so, define the flag ImGuiFileDialogFlags_ConfirmOverwrite in your call to OpenDialog.
By default this flag is not set since there is no pre-defined way to define if a dialog will be for Open or Save
behavior. (by design! :) )
Example code For Standard Dialog :
```cpp
ImGuiFileDialog::Instance()->OpenDialog("ChooseFileDlgKey",
ICON_IGFD_SAVE " Choose a File", filters,
".", "", 1, nullptr, ImGuiFileDialogFlags_ConfirmOverwrite);
```
Example code For Modal Dialog :
```cpp
ImGuiFileDialog::Instance()->OpenDialog("ChooseFileDlgKey",
ICON_IGFD_SAVE " Choose a File", filters,
".", "", 1, nullptr, ImGuiFileDialogFlags_Modal | ImGuiFileDialogFlags_ConfirmOverwrite);
```
This dialog will only verify the file in the file field, not with `GetSelection()`.
The confirmation dialog will be a non-movable modal (input blocking) dialog displayed in the middle of the current
ImGuiFileDialog window.
As usual, you can customize the dialog in your custom config file (CustomImGuiFileDialogConfig.h in this example)
Uncomment these line for customization options:
```cpp
//#define OverWriteDialogTitleString "The file Already Exist !"
//#define OverWriteDialogMessageString "Would you like to OverWrite it ?"
//#define OverWriteDialogConfirmButtonString "Confirm"
//#define OverWriteDialogCancelButtonString "Cancel"
```
See the result :
![ConfirmToOverWrite.gif](https://github.com/aiekick/ImGuiFileDialog/blob/master/doc/ConfirmToOverWrite.gif)
################################################################
## Open / Save dialog Behavior :
################################################################
ImGuiFileDialog uses the same code internally for Open and Save dialogs. To distinguish between them access the various
data return functions depending on what the dialog is doing.
When selecting an existing file (for example, a Load or Open dialog), use
```cpp
std::map<std::string, std::string> GetSelection(); // Returns selection via a map<FileName, FilePathName>
UserDatas GetUserDatas(); // Get user data provided by the Open dialog
```
To selecting a new file (for example, a Save As... dialog), use:
```cpp
std::string GetFilePathName(); // Returns the content of the selection field with current file extension and current path
std::string GetCurrentFileName(); // Returns the content of the selection field with current file extension but no path
std::string GetCurrentPath(); // Returns current path only
std::string GetCurrentFilter(); // The file extension
```
################################################################
## Thumbnails Display
################################################################
You can now, display thumbnails of pictures.
![thumbnails.gif](https://github.com/aiekick/ImGuiFileDialog/blob/master/doc/thumbnails.gif)
The file resize use stb/image so the following files extentions are supported :
* .png (tested sucessfully)
* .bmp (tested sucessfully)
* .tga (tested sucessfully)
* .jpg (tested sucessfully)
* .jpeg (tested sucessfully)
* .gif (tested sucessfully_ but not animation just first frame)
* .psd (not tested)
* .pic (not tested)
* .ppm (not tested)
* .pgm (not tested)
Corresponding to your backend (ex : OpenGl) you need to define two callbacks :
* the first is a callback who will be called by ImGuiFileDialog for create the backend texture
* the second is a callback who will be called by ImGuiFileDialog for destroy the backend texture
After that you need to call the function who is responsible to create / destroy the textures.
this function must be called in your GPU Rendering zone for avoid destroying of used texture.
if you do that at the same place of your imgui code, some backend can crash your app, by ex with vulkan.
To Clarify :
This feature is spliited in two zones :
- CPU Zone : for load/destroy picture file
- GPU Zone : for load/destroy gpu textures.
This modern behavior for avoid destroying of used texture,
was needed for vulkan.
This feature was Successfully tested on my side with Opengl and Vulkan.
But im sure is perfectly compatible with other modern apis like DirectX and Metal
ex, for opengl :
```cpp
// Create thumbnails texture
ImGuiFileDialog::Instance()->SetCreateThumbnailCallback([](IGFD_Thumbnail_Info *vThumbnail_Info) -> void
{
if (vThumbnail_Info &&
vThumbnail_Info->isReadyToUpload &&
vThumbnail_Info->textureFileDatas)
{
GLuint textureId = 0;
glGenTextures(1, &textureId);
vThumbnail_Info->textureID = (void*)textureId;
glBindTexture(GL_TEXTURE_2D, textureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
(GLsizei)vThumbnail_Info->textureWidth, (GLsizei)vThumbnail_Info->textureHeight,
0, GL_RGBA, GL_UNSIGNED_BYTE, vThumbnail_Info->textureFileDatas);
glFinish();
glBindTexture(GL_TEXTURE_2D, 0);
delete[] vThumbnail_Info->textureFileDatas;
vThumbnail_Info->textureFileDatas = nullptr;
vThumbnail_Info->isReadyToUpload = false;
vThumbnail_Info->isReadyToDisplay = true;
}
});
```
```cpp
// Destroy thumbnails texture
ImGuiFileDialog::Instance()->SetDestroyThumbnailCallback([](IGFD_Thumbnail_Info* vThumbnail_Info)
{
if (vThumbnail_Info)
{
GLuint texID = (GLuint)vThumbnail_Info->textureID;
glDeleteTextures(1, &texID);
glFinish();
}
});
```
```cpp
// GPU Rendering Zone // To call for Create/ Destroy Textures
ImGuiFileDialog::Instance()->ManageGPUThumbnails();
```
################################################################
## Embedded in other frames :
################################################################
The dialog can be embedded in another user frame than the standard or modal dialog
You have to create a variable of type ImGuiFileDialog. (if you are suing the singleton, you will not have the possibility to open other dialog)
ex :
```cpp
ImGuiFileDialog fileDialog;
// open dialog; in this case, Bookmark, directory creation are disabled with, and also the file input field is readonly.
// btw you can od what you want
fileDialog.OpenDialog("embedded", "Select File", ".*", "", -1, nullptr,
ImGuiFileDialogFlags_NoDialog |
ImGuiFileDialogFlags_DisableBookmarkMode |
ImGuiFileDialogFlags_DisableCreateDirectoryButton |
ImGuiFileDialogFlags_ReadOnlyFileNameField);
// then display, here
// to note, when embedded the ImVec2(0,0) (MinSize) do nothing, only the ImVec2(0,350) (MaxSize) can size the dialog frame
fileDialog.Display("embedded", ImGuiWindowFlags_NoCollapse, ImVec2(0,0), ImVec2(0,350)))
```
the result :
![Embedded.gif](https://github.com/aiekick/ImGuiFileDialog/blob/master/doc/Embedded.gif)
################################################################
## Quick Parallel Path Selection in Path Composer
################################################################
you have a separator between two directories in the path composer
when you click on it you can explore a list of parrallels directories of this point
this feature is disabled by default
you can enable it with the compiler flag : flags
you can also customize the spacing between path button's with and without this mode
you can do that by define the compiler flag : #define CUSTOM_PATH_SPACING 2
if undefined the spacing is defined by the imgui theme
![quick_composer_path_select.gif](https://github.com/aiekick/ImGuiFileDialog/blob/master/doc/quick_composer_path_select.gif)
################################################################
## Case Insensitive Filtering
################################################################
you can use this flag 'ImGuiFileDialogFlags_CaseInsensitiveExtention' when you call the display function
```
by ex :
if the flag ImGuiFileDialogFlags_CaseInsensitiveExtention is used
with filters like .jpg or .Jpg or .JPG
all files with extentions by ex : .jpg and .JPG will be displayed
```
################################################################
## Tune the validations button group
################################################################
You can specify :
- the width of "ok" and "cancel" buttons, by the set the defines "okButtonWidth" and "cancelButtonWidth"
- the alignement of the button group (left, right, middle, etc..) by set the define "okCancelButtonAlignement"
- if you want to have the ok button on the left and cancel button on the right or inverted by set the define "invertOkAndCancelButtons"
just see theses defines in the config file
```cpp
//Validation buttons
//#define okButtonString " OK"
//#define okButtonWidth 0.0f
//#define cancelButtonString " Cancel"
//#define cancelButtonWidth 0.0f
//alignement [0:1], 0.0 is left, 0.5 middle, 1.0 right, and other ratios
//#define okCancelButtonAlignement 0.0f
//#define invertOkAndCancelButtons false
```
with Alignement 0.0 => left
![alignement_0.0.gif](https://github.com/aiekick/ImGuiFileDialog/blob/master/doc/alignement_0.0.png)
with Alignement 1.0 => right
![alignement_1.0.gif](https://github.com/aiekick/ImGuiFileDialog/blob/master/doc/alignement_1.0.png)
with Alignement 0.5 => middle
![alignement_0.5.gif](https://github.com/aiekick/ImGuiFileDialog/blob/master/doc/alignement_0.5.png)
ok and cancel buttons inverted (cancel on the left and ok on the right)
![validation_buttons_inverted.gif](https://github.com/aiekick/ImGuiFileDialog/blob/master/doc/validation_buttons_inverted.png)
################################################################
## Regex support for Filtering and File Styling
################################################################
you can use a regex for filtering and file Styling
for have a filter recognized as a regex, you must have it between a (( and a ))
this one will filter files who start by the word "Common" and finish by ".h"
```cpp
ex : "((Custom.+[.]h))"
```
use cases :
* Simple filter :
```cpp
OpenDialog("toto", "Choose File", "((Custom.+[.]h))");
```
* Collections filter :
for this one the filter is between "{" and "}", so you can use the "(" and ")" outside
```cpp
OpenDialog("toto", "Choose File", "Source files (*.cpp *.h *.hpp){((Custom.+[.]h)),.h,.hpp}");
```
* file coloring :
this one will colorized all files who start by the word "Common" and finish by ".h"
```cpp
SetFileStyle(IGFD_FileStyleByFullName, "((Custom.+[.]h))", ImVec4(1.0f, 1.0f, 0.0f, 0.9f));
```
* with this feature you can by ex filter and colorize render frame pictures who have ext like .000, .001, .002, etc..
```cpp
OpenDialog("toto", "Choose File", "(([.][0-9]{3}))");
SetFileStyle(IGFD_FileStyleByFullName, "(([.][0-9]{3}))", ImVec4(1.0f, 1.0f, 0.0f, 0.9f));
```
################################################################
## Multi Layer / asterisk based filter
################################################################
you can add filter in the form : .a.b.c .json.cpp .vcxproj.filters
you can also add filter in the form : .* .*.* .vcx.* .*.filters .vcx*.filt.* etc..
all the * based filter are internally using regex's
################################################################
## Result Modes for GetFilePathName, getFileName and GetSelection
################################################################
you can add have various behavior when you get the file results at dialog end
you can specify a result mode to thoses function :
```cpp
GetFilePathName(IGFD_ResultMode = IGFD_ResultMode_AddIfNoFileExt)
GetFileName(IGFD_ResultMode = IGFD_ResultMode_AddIfNoFileExt)
GetFileSelection(IGFD_ResultMode = IGFD_ResultMode_KeepInputFile)
```
You can see these function who their default modes.
but you can modify them.
There is 3 Modes :
```cpp
IGFD_ResultMode_AddIfNoFileExt [DEFAULT for
This mode add the filter ext only if there is no file ext. (compatible multi layer)
ex :
filter {.cpp,.h} with file :
toto.h => toto.h
toto.a.h => toto.a.h
toto.a. => toto.a.cpp
toto. => toto.cpp
toto => toto.cpp
filter {.z,.a.b} with file :
toto.a.h => toto.a.h
toto. => toto.z
toto => toto.z
filter {.g.z,.a} with file :
toto.a.h => toto.a.h
toto. => toto.g.z
toto => toto.g.z
IGFD_ResultMode_OverwriteFileExt
This mode Overwrite the file extention by the current filter
This mode is the old behavior for imGuiFileDialog pre v0.6.6
ex :
filter {.cpp,.h} with file :
toto.h => toto.cpp
toto.a.h => toto.a.cpp
toto.a. => toto.a.cpp
toto.a.h.t => toto.a.h.cpp
toto. => toto.cpp
toto => toto.cpp
filter {.z,.a.b} with file :
toto.a.h => toto.z
toto.a.h.t => toto.a.z
toto. => toto.z
toto => toto.z
filter {.g.z,.a} with file :
toto.a.h => toto.g.z
toto.a.h.y => toto.a.g.z
toto.a. => toto.g.z
toto. => toto.g.z
toto => toto.g.z
IGFD_ResultMode_KeepInputFile
This mode keep the input file. no modification
es :
filter {.cpp,.h} with file :
toto.h => toto.h
toto. => toto.
toto => toto
filter {.z,.a.b} with file :
toto.a.h => toto.a.h
toto. => toto.
toto => toto
filter {.g.z,.a} with file :
toto.a.h => toto.a.h
toto. => toto.
toto => toto
```
to note :
- in case of a collection of filter. the default filter will be the first.
so in collection {.cpp,((.vcxproj.*)), .ft.*}, the default filter used for renaming will be .cpp
- when you have multilayer filter in collection.
we consider a filter to be replaced according to the max dot of filters for a whole collection
a collection {.a, .b.z} is a two dots filter, so a file toto.g.z will be replaced by toto.a
a collection {.z; .b} is a one dot filter, so a file toto.g.z will be replaced by toto.g.a
################################################################
## How to Integrate ImGuiFileDialog in your project
################################################################
### Customize ImGuiFileDialog :
You can customize many aspects of ImGuiFileDialog by overriding `ImGuiFileDialogConfig.h`.
To enable your customizations, define the preprocessor directive CUSTOM_IMGUIFILEDIALOG_CONFIG with the path of your
custom config file. This path must be relative to the directory where you put the ImGuiFileDialog module.
This operation is demonstrated in `CustomImGuiFileDialog.h` in the example project to:
* Have a custom icon font instead of labels for buttons or message titles
* Customize the button text (the button call signature must be the same, by the way! :)
The custom icon font used in the example code ([CustomFont.cpp](CustomFont.cpp) and [CustomFont.h](CustomFont.h)) was made
with [ImGuiFontStudio](https://github.com/aiekick/ImGuiFontStudio), which I wrote. :)
ImGuiFontStudio uses ImGuiFileDialog! Check it out.
################################################################
## Api's C/C++ :
################################################################
### the C Api
this api was sucessfully tested with CImGui
A C API is available let you include ImGuiFileDialog in your C project.
btw, ImGuiFileDialog depend of ImGui and dirent (for windows)
Sample code with cimgui :
```cpp
// create ImGuiFileDialog
ImGuiFileDialog *cfileDialog = IGFD_Create();
// open dialog
if (igButton("Open File", buttonSize))
{
IGFD_OpenDialog(cfiledialog,
"filedlg", // dialog key (make it possible to have different treatment reagrding the dialog key
"Open a File", // dialog title
"c files(*.c *.h){.c,.h}", // dialog filter syntax : simple => .h,.c,.pp, etc and collections : text1{filter0,filter1,filter2}, text2{filter0,filter1,filter2}, etc..
".", // base directory for files scan
"", // base filename
0, // a fucntion for display a right pane if you want