diff --git a/3rdparty/boost b/3rdparty/boost index ab5cf9f9..d66ca365 160000 --- a/3rdparty/boost +++ b/3rdparty/boost @@ -1 +1 @@ -Subproject commit ab5cf9f99d979cf5954ad484c66be7e0f2f54e62 +Subproject commit d66ca3653a655d7e7d572ba8ba996fa29cf7c5c0 diff --git a/3rdparty/glfw b/3rdparty/glfw index 3eaf1255..b864e4ba 160000 --- a/3rdparty/glfw +++ b/3rdparty/glfw @@ -1 +1 @@ -Subproject commit 3eaf1255b29fdf5c2895856c7be7d7185ef2b241 +Subproject commit b864e4baeb590465700744a68d083fe0ebce5d74 diff --git a/3rdparty/imgui b/3rdparty/imgui index bce4db00..659fb41d 160000 --- a/3rdparty/imgui +++ b/3rdparty/imgui @@ -1 +1 @@ -Subproject commit bce4db00bcccef072cd5a596b2f123395561e869 +Subproject commit 659fb41d0a23efbb9ea6cf74f51ecae0a51575b5 diff --git a/CustomFont.cpp b/CustomFont.cpp index 08bacc88..94b4bb51 100644 --- a/CustomFont.cpp +++ b/CustomFont.cpp @@ -1,33 +1,47 @@ #include "CustomFont.h" -static const char IGFD_compressed_data_base85[3950+1] = - "7])#######Dl_0_'/###O@?>#+lQS%Ql#v#X^@iFm,6TH$&(##/i(##[[S=B7Rm.L:^Ee-]br-$KQshF=I&##'h$##p0FSQM:L3/Uw02)[w'o;Z%F7Acg--&OMkOQ&###U::d?odPirc[4gL_=$##+Yk>3;IGF%:=1?%+$-tL]em##PPL@-#VGs-Vi[+M4:T/Lr.TV-vtXR*" - "?=th#@fNX($W3&+5OOX(uue+MQxSfLaHUu)NuDOd$nGZ(%/@$Z$3.5F%>Lqk+GN=_/)@v;%V8C5M$@,gL1F5gL$@,gLKoG8.'5>##b9qObm;qn&nCq,R[SqOim4vn/-F.PjoF.m7VQIB5KG.?(5k#iYkr-EX:p/'cYS.$-_'#RAB;-d+$L-Swxe%P]UV$0u68%47no%8ONP&$u7XI)E$X=$FR]tuVbxX#KF-,$6+hF4Ns5c]5]4xt(l0o`" - "HG]Y,V=SqFs-*#/>BxY-2>6=1SS@n3BQQY>tQZ50K;6xtBE3muOYE6j1#'58SM?o'r)#,2]V5D#kTSf-S9w0#k5e4vgYq3vH+6AM3(.m//tTB#6k9'#l1^gLT,pY-" - "->pH7TGl0-lfn0-m:-nkQjR)vt=X4'FK5.8hjkA#.2T>-T5T>-.Z)/V6*;Ga,n8f0)5###u/f##@P+58FT`>nhvYK7x(f+MfN#Vd:E`48:P$$$bl9'#])UK*O*oMMqAh1TdFi(EPpkr7" - "Hp`Js$T-##[YEt$bcx5#->Ha2F(@8%&Y@C#i_Z=7No^I*7nJ,2&f^DNGM1eN47DcNFP(&cI)9r_V$6^`A.,k`Cjj&nA#Y7,HM+@75/8e9:)K4j'MdZwe-fcBN,g6'@9<5jD3YdUV$sRk&#l,>>#@D5##]o;T/,oK9/)$fF4k&B.*-7T^,k(TF4^.RM0Rq@.*bZ'u$" - "cJF/M;`6<.*M4gL;ngo0TAOZ6W.PV-RVx_4QmuX$KOj`ub>(6RTcZULbR39/oBfU+-p9x9SP>bnQ5&X%pbO-)&-g[us_.u-=^7>N8$EG'i_7MTv+qM#ReBtLg@RxktpqbrUv?rC*+8C8" - "i&X1)e61nLx-$O*%@h-Ml=DX-xv@=(`()?#B8WeFW-u?-vOlo.$&>uuu]iQjhx###6T&],vQnW_$Dh8.w-%jx-q-U&5" - "YZbA#Dc$a-1F-Z$3(m<-2&&b-cjHwB)j9e$*fF.#=F.%#bWt&#M3>V/2T/i)HrUv-F^?d))2pb4N*sKG'L/@#H`G>#x]5.3Z_[@#1N.Q@2eV5*k+)ul=^hA4+;wA4-l2%bt_NPoN%g1B" - "Yb]+42bMjLXF8:La,3.M58+**]kp)4JP`,u2U`k#Z-qDX;BgF/['9'#/W%RNV]UV$l(+&#g9e5/l)qH*c4oL(u3YD#=@)ns>4vr-Fdsw$/_?C+ohAYcqT@E+iW0KMes=p%%.MvUk'R3Tm&?`I34s'o7l=E^[#JN$q3JDDW-" - "ex,##/snC>+[Ch4DZVs%am^q%hh)?#51&>Nd:1##aJ^'/YdYEnVKpdm$7[0#G,>>#b1=Z-)7(dMjCCv-gc``36SqcNKQL,3L1O058b4-5mS4'5841'5%J/GV/1:B#'at%$q^DIM=X0DM" - "3)^fL6)0/Ldbb(NRdimM-a4o7qPa>$cMDX:W<=&5R^i'#C.0u$CGF&#]rgo.NV9h&h0`.3f`aI)wuj=)V_TLpB9o*%j70.)@*4F%C6pre.3^gL8u+.)$Ja1)1K2.)/us'4`1iv?[x[AX" - ">DQk=&2SfL>4-m'3HBMu2:nmL3Bi-McE;,)odGb@L.N'MU@9C-]?KoLDulhL#w5D-#TVA./JE/Lq>eA#/'+Q8l]9C,8&B.*5XKb@@hsPM2.VfLFI8GVRmDGV+:2X-*6##" - "#+d;%$9P-4avK'#?3B:%V::8.mNv)4#Vpr6xXl<:-%eX-Si(?#LR(*>=:mp1J4@]u2NVE87mV)4lKxnLI_lS7#e$YYd>h>fjqBj$S>1T2&idh#WNc]u,VoH+/^(B#dS3N0_HDbA:lD)%" - "rNHAOYMYGMDtJfLXqd##Q3=&#d72mLvG(u$+dfF4Awx-tS4vr-4Hc#6<-C]$N>.U%))^Y,SEW-$$;(v#B%C7&D$KH2;YvAupvh4L]/8$$n=x_uGM1-Mh?^;-0@;=->?DiL9El'0dWe`*>(t.L&A3/LnQE?#HnMR8HeFatBUj'0i%s^#X-L4." - "mV-6M3:#gL=E5',2F_oA&>uu#R%=cMEjV&#[S@^$Ki@@-s3emLjnU6v0w)-vjKJ_MYF$##iBBY$@Y6iL*JqY-M=#/?'.^.?\?@i%aI%'0%KGY##CoRe*5nOJ(h5.)*jr/+*dg0aYctH##" - "6^TlS;4T=YPuG;-K6^/N4i`>$agNe'Qk[X'ep.'5ab5'5uX(T73OWV$Pi[+MT([##PG5@R<=$/rVB#kwF>#euita$X82LhuA&GBihNXcIIa4u<'8@Pc&6/-@XA#R4r?#fgGj'x%MT/" - "ObE]-QtfM'-Wgf16HSP/kK(E#_3rhLE)t1)ter0,7D?whd]g^%11uU&FIJa^d/Gb%QIsYlG4`;$]Ya7Q.sc7Iw<6AO2CL97I)Ta#?u//LEJS8/^wJ/rD,?V%O)8'.x4Au" - "%>#*AY>#.Ml>#2Y(?#6f:?#:rL?#>(`?#B4r?#F@.@#JL@@#NXR@#WLF9n8AtHKCw/"; +static const char IGFD_compressed_data_base85[5965+1] = + "7])#######,#8oo'/###O@?>#+lQS%Ql#v#X^@iFLYQ^OT-$##^,'##l7W=BBaB]O:^Ee-]br-$KQshF>RA>#l)%##h$bw'Xnq0FRDQjUw#/SD_&8Jq-$Mu@['" + "b3K'=-gK_&UKo-$fZIkENjH@=H7'##c-%##BK@0FvhC:3%H(F7YWo-$t4GkOR&###U::d?odPirVEL8eVNm&#+Yk>3.r9#v;/9m$W;Mt-].=GMM%g+MPXZ##/C2=-r.TV-vtXR*?=th#" + "P@OX(/#4&+5OOX(uue+MQxSfLaH#([FU%Z+6;-7k+/(bV4q$p[dK'3EU?+T'<*2.x&n7fKPHC;FrmIxA^aV[wHWl(3TWcZ]1_3-sS:vk)sW#wRMq2ebxr2m7VQICfQq2wAvr2j&al#%.=G24;V`3" + "WP$^5-uYS.HDW)#^2^V-GhsL#FfgWhNL`Qjj?I##.GY##2Sl##6`($#:l:$#>xL$#B.`$#F:r$#JF.%#NR@%#R_R%#Vke%#Zww%#_-4&#c9F0qK-PY5<-r]gC-g?u`3a6YY#2>uu#" + "[[qr$KnQS%Dwmo%@(.m/w)35&'2NP&/PP8.pTT401k%##ms*##JMl-$=*+##M`###]4$##t-[Y#" + ">v&##je+gL]2#957*vM($i?X-,BG`a*HWf#Ybf;-?G^##rZ+,/$),##G=G6s37[0#O,>>#Xq.[#T;i`3twC.33qM>Pw+gF4p9%J3r4Z##$u7XI)E$X=$FR]tuVbxX#KF-,$6+hF4Ns5c]5]4xt(l0o`HG]Y," + "V=SqFs-*#/>BxY-2>6=1SS@n3BQQY>.8dA5K;6xtBE3muG?$##$&>uuZgUV$kxw%#vkM*IXP@&4A3jm.C:6u6wcmEM1Ha%$WuW?u-qvJ;oCR=lMqEl<+`teFnwrquoiD>LD;0^%DMxdP" + "hp9.1JY@W.&s_dsmn4VuV#,F@(.P/L+Qsr-Jx+na.J'f)u%Fs.W*?1/?D,c4kjSe$sC9C4/_XX$/%uN+eMRG#u:be)Jq5S7.u1B4:*2cu`vdUucXJPAhDQiKRrd+V(4)##cT^:/x)Qv$lf/+*sj$bew,?8`p&$@+K`t/uB#$EFG]u8neF@):lbMF;#gL%*'-#" + ",&>uuV/bo7*5c&#fiES7+N5^#%x-20p'2cige1ci'e4@'_o-'57:PS7.Anx45iNh#T[1^#KGxA-)^)/V6*;Ga%.%P.o5[o7T7rW-uu" + "XhFH(AkC?8@-/Z$vIPS.p'2ciOU;f'c^L7#*T$ct;hq.VEJnA-=Yaa-]8Xd4n#W,-]90[0HRq/#n2^I$oAhhLZoC:%S:Ls-%/65/#&AA4M7GgLwuYA#vTa@uD;Rc<^^xOS<,Qb%ps^^#" + "i>Mt-C6bOMZYBcNwVhw'*qx[ui.suL'x?>#+10ip&ExrQF7$##lnr?#&r&t%NEE/2XB+a4?c=?/^0Xp%kH$IM$?YCjwpRX:CNNjL-(,)Xn$##OZ'u$P0;hLE(e8/)$fF4#b-)*oFn8%0#qg-8nxZT6hwLM>Vt,4u3YD#<)]L(_[`V$8.g[uMw+Yu:bCB#P'?87J.9Z%HnsT%c]9c;P3tT%vLE5&nrR>?XELO'5$eEj" + "QVF;-F%r<1F;W+M>T-C#`Ic>#$a=P/eLgw%p:to7?K8?#-W*=&JZuu>=%vrbdDDO'IH$h%BG:;$06u%4Zu^##9kfi'0fJV6&(Gd30d%H)O([F%AwRKW;hL+*bhZV--3.)*S(Ls-SRUa4" + "J]2m9'N;h)77t[$N'^:/V_TfL^UiS%R*hr/j(0'5VZe1gg81k5P#u,0'&L_(>H]m(UDOo7995O0eH@E+c$N9`lSFEXHC)159i>;-J,%15U$$gNTQD15'TXB,3[,.)+4850&CfU+3-g[u" + "f/5##d98q`07[0#9%T*#?3B:%isAv-&O]s$Oaf;-Vnt(0ff]Y,k(TF4VD>8.Rq@.*,[jd3WH5<.*M4gL8=sB#TekD#3YJ,3VG+G4XX48nw8r%1]`6&[:^8/" + "AV@n&SQ#]#%2k3GSk4#G5GSS7sV/2T/i)HrUv-F^?d)" + ")2pb4YIYjLeC0@#H`G>#KjE.3Z_[@#1N.Q@2eV5*k+)ul=^hA4+;wA4-l2%bt_NPoN%g1BYb]+42bMjLXF8:La,3.M58+**/)RW%$=h1B-n4GVaVQu.gm^6X,&Gj/$),##RN&I$S6[0#" + "WH?D*@p*P(PZg@#.Zg*%>@*T.jAqB#^WgO0qHm0)mK][#AK%g:$U&A$j^pn&sNfU+%aMu54+0AXNgAE+'BXe$PnpF&#(7G;R(mcaJVoW&'IG,M1KUv-`fWI)9jDR:-rR_#a?7f3lCgG3" + "N5#r:N&l,=GNGA5AZ$XA`0(Q^(k'(GB.WKx+M/mi5###%D1MBZY8/J=jl&C?E`HO_Ur8eJdj'lx8B+kDA>,oZ_L#'i;A+v5+KMMsJfLfNB/LF7$##Sg'u$U^nENg:Cv-" + "gc``3-W&dMKQL,3L1O058b4-5mS4'5841'5%J/GV/1:B#'at%$q^DIM=X0DMg*^fL6)0/Ldbb(NRdimM-a4o7qPa>$cMDX:W<=&5R^i'#C.0u$CGF&#]rgo.X7-i&h0`.3f`aI)wuj=)" + "V_TLpB9o*%j70.)@*4F%C6pre.3^gL8u+.)$Ja1)1K2.)/us'4`1iv?[x[AX>DQk=c;q8gV3t_&o,7Au2:nmL3Bi-McE;,)odGb@L.N'MU@9C-]?KoLDulhL#w5D-#TVA./JE/LA$jE#" + "W9k(&-9jW^-R3n0#%3coLTq&%#N,>>#MhSM'@AxiLTj+c4A]DD3mMWB#,5Rv$g&?a3>nvGMeANv>s#V&1iJ&%bE2ZA#-.^g1" + "j;R)4443%b7RU`u`Kk(NHbeV@gJS'-BWcP3m?+#-VaDuL:`WY5kEaau^=lJ(_24J-KxeQ-):Im/9(V$#lpB'#.::t%h/oj2Y%@+<-H0Z-3R-b[k&qg3B)t1)O$pH*adP/(HZ%12ARj-$" + "h4-/V1(bT%xl`@$$F/a*/PDh'J3no[Uo5o7DAS?cvJm%$+99T([t&2BJODL5nctW#Aj*.)sA'%MS>`1p%bpK(i`2iK.K+QJ(" + "PGpkL'(MB#/T01YP6;hLqS&J3LR(f)9*SY-_l-l)3RXD#+UR29awZp.Z9OA#RcB##Oi./LlA)ZuTBqn'B]7%b/WMIFca,$_WAM$8&H<-YZ&v.&,###f0c-6?LN`<2cm9KRIG,M=P?uu5kBYt5Av7vdsOdJ._" + "(5G>#WtOO0h7<&Z.vW1u(x,V#dqbWB$f=#/JWfLl>T%#KSj**i%^F*0]WF3mx,.'mK$)*.:^^'ffo45P::&5;f^%%+GH##o-'O'" + "Y&R**Jx%ctG@l(5ewTs/`9>#>h(jw$6@%%#aKb&#*Q?(#kr/e=]6F_&$-2K(=5MB#=s+4/]p*P(5ZGb%+56J*qSc8/+gB.*kHx6,IC7`%UQspA=KGSIULS:d=vRdu75]CuOq$0ufu'L#" + ">Y[OVk1k3G(kZoAO9iQN'h5',b_mL,v?qr&4uG##%J/GV5J?`a'=@@MB>O_$kU:3t2ro&$)Xff.P=#+#0w)g%RR$v,Rapi'W#:u$`Ld5/UXUa4eU`v#cJ?C#=V&E#;lm=72q_F*`V(a4" + "kYF0M'm3KV2kblA.,IE3EvoM^h_en*4#s%u*;Gc-0'cw'V9dxu#pT_A10R`Act3gNnnt;.o>*584B4_A(v0kX%i0^#tEWS%C5$##*J(v#.c_V$2%@8%6=wo%:UWP&>n82'B0pi'" + "FHPJ(Ja1,)N#ic)R;ID*VS*&+Zla]+_.B>,cF#v,g_YV-d,=&F.$jtBdMd9rqLNiO7M13@_%r- RM + 1297 ..\ImGuiFontStudio\3rdparty\imgui\misc\fonts\Roboto-Medium.ttf 1 50 @@ -13,16 +14,25 @@ 1 1 9729 + true + false + + + + + + + @@ -34,12 +44,17 @@ + + + + IGFD + 1307 ..\ImGuiFontStudio\samples_Fonts\fontawesome-webfont.ttf 3 50 @@ -51,6 +66,8 @@ 1 1 9729 + true + false 20 @@ -76,9 +93,39 @@ false 1535 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100 diff --git a/CustomFont.png b/CustomFont.png index b2fede81..78b54e98 100644 Binary files a/CustomFont.png and b/CustomFont.png differ diff --git a/CustomImGuiFileDialogConfig.h b/CustomImGuiFileDialogConfig.h index 8f7dd410..6b7dc044 100644 --- a/CustomImGuiFileDialogConfig.h +++ b/CustomImGuiFileDialogConfig.h @@ -109,10 +109,20 @@ //#define tableHeaderFileSizeString " Size" //#define tableHeaderFileDateString " Date" -#define USE_BOOKMARK -//#define bookmarkPaneWith 150.0f +#define USE_PLACES_FEATURE +//#define placesPaneWith 150.0f //#define IMGUI_TOGGLE_BUTTON ToggleButton -#define bookmarksButtonString ICON_IGFD_BOOKMARK -//#define bookmarksButtonHelpString "bookmark" -#define addBookmarkButtonString ICON_IGFD_ADD -#define removeBookmarkButtonString ICON_IGFD_REMOVE +#define placesButtonString ICON_IGFD_PLACES +// #define placesButtonHelpString "Places" +#define addPlaceButtonString ICON_IGFD_ADD +#define removePlaceButtonString ICON_IGFD_REMOVE + +// a group for bookmarks will be added by default, but you can also create it yourself and many more +#define USE_PLACES_BOOKMARKS +#define placesBookmarksGroupName ICON_IGFD_BOOKMARK " Bookmarks" +#define placesBookmarksDisplayOrder 0 // to the first + +// a group for system devices (returned by IFileSystem), but you can also add yours +#define USE_PLACES_DEVICES +#define placesDevicesGroupName ICON_IGFD_DRIVES " Devices" +#define placesDevicesDisplayOrder 10 // to the end diff --git a/FileSystemBoost.hpp b/FileSystemBoost.hpp index 3c88d019..e2927849 100644 --- a/FileSystemBoost.hpp +++ b/FileSystemBoost.hpp @@ -83,8 +83,8 @@ class FileSystemBoost : public IGFD::IFileSystem { return res; } - std::vector> GetDevicesList() override { - std::vector> res; + std::vector GetDevicesList() override { + std::vector res; #ifdef _IGFD_WIN_ const DWORD mydrives = 2048; char lpBuffer[2048]; @@ -96,7 +96,7 @@ class FileSystemBoost : public IGFD::IFileSystem { IGFD::Utils::ReplaceString(var, "\\", ""); auto arr = IGFD::Utils::SplitStringToVector(var, '\0', false); wchar_t szVolumeName[2048]; - std::pair path_name; + IGFD::PathDisplayedName path_name; for (auto& a : arr) { path_name.first = a; path_name.second.clear(); diff --git a/ImGuiFileDialog b/ImGuiFileDialog index d00c1cbb..91146274 160000 --- a/ImGuiFileDialog +++ b/ImGuiFileDialog @@ -1 +1 @@ -Subproject commit d00c1cbbd3eb26258995f87beca2c89e89d30b28 +Subproject commit 91146274a3c8e154d738224743222eb3d8c9a2d5 diff --git a/LICENSE b/LICENSE index 3c17eee9..55e17ad5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2018-2022 Stephane Cuillerdier (aka Aiekick) +Copyright (c) 2018-2024 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 diff --git a/README.md b/README.md index 0555c21f..245efe8d 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ [![Win](https://github.com/aiekick/ImGuiFileDialog/actions/workflows/Win.yml/badge.svg?branch=DemoApp)](https://github.com/aiekick/ImGuiFileDialog/actions/workflows/Win.yml) [![Linux](https://github.com/aiekick/ImGuiFileDialog/actions/workflows/Linux.yml/badge.svg?branch=DemoApp)](https://github.com/aiekick/ImGuiFileDialog/actions/workflows/Linux.yml) [![Osx](https://github.com/aiekick/ImGuiFileDialog/actions/workflows/Osx.yml/badge.svg?branch=DemoApp)](https://github.com/aiekick/ImGuiFileDialog/actions/workflows/Osx.yml) -[![Wrapped Dear ImGui Version](https://img.shields.io/badge/Dear%20ImGui%20Version-1.90.1-blue.svg)](https://github.com/ocornut/imgui) +[![Wrapped Dear ImGui Version](https://img.shields.io/badge/Dear%20ImGui%20Version-1.90.4-blue.svg)](https://github.com/ocornut/imgui) # ImGuiFileDialog @@ -14,7 +14,7 @@ solutions. ## ImGui Supported Version -ImGuiFileDialog follow the master and docking branch of ImGui. Currently ImGui 1.90.1 +ImGuiFileDialog follow the master and docking branch of ImGui. Currently ImGui 1.90.4 ## Structure @@ -75,7 +75,7 @@ Android Requirements : Api 21 mini - can ignore filter Case for file searching - Keyboard navigation (arrows, backspace, enter) - Exploring by entering characters (case insensitive) -- Directory bookmarks +- Custom places (bookmarks, devices, whatever you want) - 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) @@ -493,47 +493,58 @@ ImGuiFileDialog::Instance()->SetFlashingAttenuationInSeconds(1.0f); -

Bookmarks :

+

Places :

-You can create/edit/call path bookmarks and load/save them. +the Places system is a generic way for add custom links in the left side pane -Activate this feature by uncommenting: `#define USE_BOOKMARK` in your custom config file (CustomImGuiFileDialogConfig.h) +you can organize them by groups -More customization options: +The bookmarks and devices are now groups in the left side pane. +for using it you need to ```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 +#define USE_PLACES_FEATURE + +// for have default bookmark editable groups +#define USE_PLACES_BOOKMARKS + +// for have default groups for system devices (returned by the IFileSystem interface) +#define USE_PLACES_DEVICES ``` -* You can select each bookmark to edit the displayed name corresponding to a path -* Double-click on the label to apply the bookmark +see the config file for more customization + +you can also add your custom groups editable or not like what is done +the DemoApp branch with the "quick access" paths of win10 -![bookmarks.gif](https://github.com/aiekick/ImGuiFileDialog/blob/DemoApp/doc/bookmarks.gif) +You must add a group first, then add a place to it : -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(); +// you must add a group first, specifu display order, and say if the user can add or remove palce like (bookmarks) +ImGuiFileDialog::Instance()->AddPlacesGroup(group_name, display_order, can_be_user_edited); +// then you must get the group +auto places_ptr = ImGuiFileDialog::Instance()->GetPlacesGroupPtr(group_name); +if (places_ptr != nullptr) { + // then add a place to the group + // you msut specify the place name, the palce path, say if the palce can be serialized, and sepcify the style + // for the moment the style support only the icon, can be extended if user needed in futur + places_ptr->AddPlace(place_name, place_path, can_be_saved, style); +} ``` -you can also add/remove bookmark by code : +for editable group : +* You can select each place to edit the displayed name corresponding to a path +* Double-click on the label to apply the place -and in this case, you can also avoid serialization of code based bookmark +![places.gif](https://github.com/aiekick/ImGuiFileDialog/blob/DemoApp/doc/places.gif) +You can also serialize/deserialize groups and places (for example to load/save from/to a file): ```cpp -Add => ImGuiFileDialog::Instance()->AddBookmark(bookmark_name, bookmark_path); -Remove => ImGuiFileDialog::Instance()->RemoveBookmark(bookmark_name); - -// true for prevent serialization of code based bookmarks -Save => std::string bookmarkString = ImGuiFileDialog::Instance()->SerializeBookmarks(true); +Load => ImGuiFileDialog::Instance()->DeserializePlaces(placesString); +Save => std::string placesString = ImGuiFileDialog::Instance()->SerializePlaces(); ``` -(please see example code for details) +(please see DemoApp branch for details)
diff --git a/doc/bookmarks.gif b/doc/bookmarks.gif deleted file mode 100644 index ce78e4cb..00000000 Binary files a/doc/bookmarks.gif and /dev/null differ diff --git a/doc/places.gif b/doc/places.gif new file mode 100644 index 00000000..bf14e25f Binary files /dev/null and b/doc/places.gif differ diff --git a/main.cpp b/main.cpp index 8ca7d036..ab50cba9 100644 --- a/main.cpp +++ b/main.cpp @@ -20,6 +20,7 @@ #if defined(__WIN32__) || defined(WIN32) || defined(_WIN32) || defined(__WIN64__) || defined(WIN64) || defined(_WIN64) || defined(_MSC_VER) #define stat _stat +#include // for get known folders #else // UNIX #include #include @@ -483,36 +484,73 @@ int main(int, char**) { IGFD_SetFileStyle(cfileDialog, IGFD_FileStyleByFullName, "doc", ImVec4(0.9f, 0.2f, 0.0f, 0.9f), ICON_IGFD_FILE_PIC, nullptr); IGFD_SetFileStyle(cfileDialog, IGFD_FileStyleByTypeDir | IGFD_FileStyleByContainedInFullName, ".git", ImVec4(0.9f, 0.2f, 0.0f, 0.9f), ICON_IGFD_BOOKMARK, nullptr); -#ifdef USE_BOOKMARK - // load bookmarks - std::ifstream docFile_1("bookmarks_1.conf", std::ios::in); +#ifdef USE_PLACES_FEATURE + // load place + std::ifstream docFile_1("places_1.conf", std::ios::in); if (docFile_1.is_open()) { std::stringstream strStream; strStream << docFile_1.rdbuf(); // read the file - ImGuiFileDialog::Instance()->DeserializeBookmarks(strStream.str()); + ImGuiFileDialog::Instance()->DeserializePlaces(strStream.str()); docFile_1.close(); } - std::ifstream docFile_2("bookmarks_2.conf", std::ios::in); + std::ifstream docFile_2("places_2.conf", std::ios::in); if (docFile_2.is_open()) { std::stringstream strStream; strStream << docFile_2.rdbuf(); // read the file - fileDialog2.DeserializeBookmarks(strStream.str()); + fileDialog2.DeserializePlaces(strStream.str()); docFile_2.close(); } // c interface - std::ifstream docFile_c("bookmarks_c.conf", std::ios::in); + std::ifstream docFile_c("places_c.conf", std::ios::in); if (docFile_c.is_open()) { std::stringstream strStream; strStream << docFile_c.rdbuf(); // read the file - IGFD_DeserializeBookmarks(cfileDialog, strStream.str().c_str()); + IGFD_DeserializePlaces(cfileDialog, strStream.str().c_str()); docFile_c.close(); } - // add bookmark by code (why ? because we can :-) ) - ImGuiFileDialog::Instance()->AddBookmark("Current Dir", "."); + // add places : + const char* group_name = ICON_IGFD_SHORTCUTS " Places"; + ImGuiFileDialog::Instance()->AddPlacesGroup(group_name, 1, false); + IGFD_AddPlacesGroup(cfileDialog, group_name, 1, false); + + // Places : + auto places_ptr = ImGuiFileDialog::Instance()->GetPlacesGroupPtr(group_name); + if (places_ptr != nullptr) { +#if defined(__WIN32__) || defined(WIN32) || defined(_WIN32) || defined(__WIN64__) || defined(WIN64) || defined(_WIN64) || defined(_MSC_VER) +#define addKnownFolderAsPlace(knownFolder, folderLabel, folderIcon) \ + { \ + PWSTR path = NULL; \ + HRESULT hr = SHGetKnownFolderPath(knownFolder, 0, NULL, &path); \ + if (SUCCEEDED(hr)) { \ + IGFD::FileStyle style; \ + style.icon = folderIcon; \ + auto place_path = IGFD::Utils::UTF8Encode(path); \ + places_ptr->AddPlace(folderLabel, place_path, false, style); \ + IGFD_AddPlace(cfileDialog, group_name, folderLabel, place_path.c_str(), false, folderIcon); \ + } \ + CoTaskMemFree(path); \ + } + addKnownFolderAsPlace(FOLDERID_Desktop, "Desktop", ICON_IGFD_DESKTOP) + addKnownFolderAsPlace(FOLDERID_Startup, "Startup", ICON_IGFD_HOME) + addKnownFolderAsPlace(FOLDERID_Downloads, "Downloads", ICON_IGFD_DOWNLOADS) + addKnownFolderAsPlace(FOLDERID_Pictures, "Pictures", ICON_IGFD_PICTURE) + addKnownFolderAsPlace(FOLDERID_Music, "Music", ICON_IGFD_MUSIC) + addKnownFolderAsPlace(FOLDERID_Videos, "Videos", ICON_IGFD_FILM) + +#undef addKnownFolderAsPlace +#else #endif + places_ptr = nullptr; + } + + // add place by code (why ? because we can :-) ) + //ImGuiFileDialog-> + // todo : do the code + //ImGuiFileDialog::Instance()->AddPlace("Current Dir", "."); +#endif // USE_PLACES_FEATURE static std::string filePathName; static std::string filePath; @@ -598,10 +636,10 @@ int main(int, char**) { #ifdef USE_THUMBNAILS RadioButtonLabeled_BitWize("Disable thumbnails mode", "Disable thumbnails display in dialo", &flags, ImGuiFileDialogFlags_DisableThumbnailMode); #endif // USE_THUMBNAILS -#ifdef USE_BOOKMARK +#ifdef USE_PLACES_FEATURE ImGui::SameLine(); - RadioButtonLabeled_BitWize("Disable bookmark mode", "Disable bookmark display in dialo", &flags, ImGuiFileDialogFlags_DisableBookmarkMode); -#endif // USE_BOOKMARK + RadioButtonLabeled_BitWize("Disable place mode", "Disable place display in dialo", &flags, ImGuiFileDialogFlags_DisablePlaceMode); +#endif // USE_PLACES_FEATURE ImGui::Text("Hide Column by default : (saved in imgui.ini, \n\tso defined when the imgui.ini is not existing)"); RadioButtonLabeled_BitWize("Hide Column Type", "Hide Column file type by default", &flags, ImGuiFileDialogFlags_HideColumnType); @@ -764,7 +802,6 @@ int main(int, char**) { if (vFileInfosPtr->SearchForExt(".gltf", true)) { auto bin_file_path_name = vFileInfosPtr->filePath + IGFD::Utils::GetPathSeparator() + vFileInfosPtr->fileNameLevels[0] + ".bin"; struct stat statInfos = {}; - char timebuf[100]; int result = stat(bin_file_path_name.c_str(), &statInfos); if (!result) { vFileInfosPtr->tooltipMessage = toStr("%s : %s\n%s : %s", // @@ -842,9 +879,9 @@ int main(int, char**) { IGFD::FileDialogConfig config; config.countSelectionMax = -1; config.flags = ImGuiFileDialogFlags_NoDialog | // permit the embedded, because no frame is used -#ifdef USE_BOOKMARK - ImGuiFileDialogFlags_DisableBookmarkMode | // bookmark mode -#endif // USE_BOOKMARK +#ifdef USE_PLACES_FEATURE + ImGuiFileDialogFlags_DisablePlaceMode | // place mode +#endif // USE_PLACES_FEATURE ImGuiFileDialogFlags_DisableCreateDirectoryButton | // no directory creation button ImGuiFileDialogFlags_ReadOnlyFileNameField; // file name filed is read only fileDialogEmbedded3.OpenDialog("embedded", "Select File", ".*", config); @@ -969,6 +1006,7 @@ int main(int, char**) { ///////////////////////////////////////////////////////////////// // C Interface ///////////////////////////////////////////////////////////////// + if (IGFD_DisplayDialog(cfileDialog, "ChooseFileDlgKey", ImGuiWindowFlags_NoCollapse, minSize, maxSize)) { if (IGFD_IsOk(cfileDialog)) { char* cfilePathName = IGFD_GetFilePathName(cfileDialog, IGFD_ResultMode_AddIfNoFileExt); @@ -1030,26 +1068,27 @@ int main(int, char**) { glfwSwapBuffers(window); } -#ifdef USE_BOOKMARK - // remove bookmark - ImGuiFileDialog::Instance()->RemoveBookmark("Current Dir"); +#ifdef USE_PLACES_FEATURE + // remove place + // todo : do the code + //ImGuiFileDialog::Instance()->RemovePlace("Current Dir"); - // save bookmarks dialog 1 - std::ofstream configFileWriter_1("bookmarks_1.conf", std::ios::out); + // save place dialog 1 + std::ofstream configFileWriter_1("places_1.conf", std::ios::out); if (!configFileWriter_1.bad()) { - configFileWriter_1 << ImGuiFileDialog::Instance()->SerializeBookmarks(); + configFileWriter_1 << ImGuiFileDialog::Instance()->SerializePlaces(); configFileWriter_1.close(); } - // save bookmarks dialog 2 - std::ofstream configFileWriter_2("bookmarks_2.conf", std::ios::out); + // save place dialog 2 + std::ofstream configFileWriter_2("places_2.conf", std::ios::out); if (!configFileWriter_2.bad()) { - configFileWriter_2 << fileDialog2.SerializeBookmarks(); + configFileWriter_2 << fileDialog2.SerializePlaces(); configFileWriter_2.close(); } - // save bookmarks dialog c interface - std::ofstream configFileWriter_c("bookmarks_c.conf", std::ios::out); + // save place dialog c interface + std::ofstream configFileWriter_c("places_c.conf", std::ios::out); if (!configFileWriter_c.bad()) { - char* s = IGFD_SerializeBookmarks(cfileDialog, true); + char* s = IGFD_SerializePlaces(cfileDialog, true); if (s) { configFileWriter_c << std::string(s); configFileWriter_c.close(); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e8818c20..a8889908 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -148,8 +148,14 @@ SetTest(Test_IGFD_Utils_ReplaceString_5) SetTest(Test_IGFD_Utils_ReplaceString_6) SetTest(Test_IGFD_Utils_ReplaceString_7) -## Test_IGFD_Utils -- SplitStringToVector -SetTest(Test_IGFD_Utils_SplitStringToVector_0) -SetTest(Test_IGFD_Utils_SplitStringToVector_1) -SetTest(Test_IGFD_Utils_SplitStringToVector_2) -SetTest(Test_IGFD_Utils_SplitStringToVector_3) +## Test_IGFD_Utils -- SplitStringToVector delimiter char +SetTest(Test_IGFD_Utils_SplitStringToVector_delimiter_char_0) +SetTest(Test_IGFD_Utils_SplitStringToVector_delimiter_char_1) +SetTest(Test_IGFD_Utils_SplitStringToVector_delimiter_char_2) +SetTest(Test_IGFD_Utils_SplitStringToVector_delimiter_char_3) + +## Test_IGFD_Utils -- SplitStringToVector delimiter std::string +SetTest(Test_IGFD_Utils_SplitStringToVector_delimiter_std_string_0) +SetTest(Test_IGFD_Utils_SplitStringToVector_delimiter_std_string_1) +SetTest(Test_IGFD_Utils_SplitStringToVector_delimiter_std_string_2) +SetTest(Test_IGFD_Utils_SplitStringToVector_delimiter_std_string_3) diff --git a/tests/ImGuiFileDialog/Test_Utils.cpp b/tests/ImGuiFileDialog/Test_Utils.cpp index 3276ff7a..d519c152 100644 --- a/tests/ImGuiFileDialog/Test_Utils.cpp +++ b/tests/ImGuiFileDialog/Test_Utils.cpp @@ -73,10 +73,10 @@ bool Test_IGFD_Utils_ReplaceString_7() { } //////////////////////////////////////////////////////////////////////////// -//// SplitStringToVector /////////////////////////////////////////////////// +//// SplitStringToVector // Delimiter char ///////////////////////////////// //////////////////////////////////////////////////////////////////////////// -bool Test_IGFD_Utils_SplitStringToVector_0() { +bool Test_IGFD_Utils_SplitStringToVector_delimiter_char_0() { std::string code = "TOTO;VA;AU;ZOO"; auto arr = IGFD::Utils::SplitStringToVector(code, ';', false); if (arr.size() != 4U) return false; @@ -87,7 +87,7 @@ bool Test_IGFD_Utils_SplitStringToVector_0() { return true; } -bool Test_IGFD_Utils_SplitStringToVector_1() { +bool Test_IGFD_Utils_SplitStringToVector_delimiter_char_1() { std::string code = "TOTO;VA;AU;;ZOO"; auto arr = IGFD::Utils::SplitStringToVector(code, ';', false); if (arr.size() != 4U) return false; @@ -98,7 +98,7 @@ bool Test_IGFD_Utils_SplitStringToVector_1() { return true; } -bool Test_IGFD_Utils_SplitStringToVector_2() { +bool Test_IGFD_Utils_SplitStringToVector_delimiter_char_2() { std::string code = "TOTO;VA;AU;;ZOO"; auto arr = IGFD::Utils::SplitStringToVector(code, ';', true); if (arr.size() != 5U) return false; @@ -110,7 +110,7 @@ bool Test_IGFD_Utils_SplitStringToVector_2() { return true; } -bool Test_IGFD_Utils_SplitStringToVector_3() { +bool Test_IGFD_Utils_SplitStringToVector_delimiter_char_3() { std::string code = "TOTO:VA;AU;;ZOO"; auto arr = IGFD::Utils::SplitStringToVector(code, ';', false); if (arr.size() != 3U) return false; @@ -120,6 +120,54 @@ bool Test_IGFD_Utils_SplitStringToVector_3() { return true; } +//////////////////////////////////////////////////////////////////////////// +//// SplitStringToVector // Delimiter std::string ////////////////////////// +//////////////////////////////////////////////////////////////////////////// + +bool Test_IGFD_Utils_SplitStringToVector_delimiter_std_string_0() { + std::string code = "TOTO##VA##AU##ZOO"; + auto arr = IGFD::Utils::SplitStringToVector(code, "##", false); + if (arr.size() != 4U) return false; + if (arr[0] != "TOTO") return false; + if (arr[1] != "VA") return false; + if (arr[2] != "AU") return false; + if (arr[3] != "ZOO") return false; + return true; +} + +bool Test_IGFD_Utils_SplitStringToVector_delimiter_std_string_1() { + std::string code = "TOTO##VA##AU####ZOO"; + auto arr = IGFD::Utils::SplitStringToVector(code, "##", false); + if (arr.size() != 4U) return false; + if (arr[0] != "TOTO") return false; + if (arr[1] != "VA") return false; + if (arr[2] != "AU") return false; + if (arr[3] != "ZOO") return false; + return true; +} + +bool Test_IGFD_Utils_SplitStringToVector_delimiter_std_string_2() { + std::string code = "TOTO##VA##AU####ZOO"; + auto arr = IGFD::Utils::SplitStringToVector(code, "##", true); + if (arr.size() != 5U) return false; + if (arr[0] != "TOTO") return false; + if (arr[1] != "VA") return false; + if (arr[2] != "AU") return false; + if (arr[3] != "") return false; + if (arr[4] != "ZOO") return false; + return true; +} + +bool Test_IGFD_Utils_SplitStringToVector_delimiter_std_string_3() { + std::string code = "TOTO:VA##AU####ZOO"; + auto arr = IGFD::Utils::SplitStringToVector(code, "##", false); + if (arr.size() != 3U) return false; + if (arr[0] != "TOTO:VA") return false; + if (arr[1] != "AU") return false; + if (arr[2] != "ZOO") return false; + return true; +} + //////////////////////////////////////////////////////////////////////////// //// ENTRY POINT /////////////////////////////////////////////////////////// @@ -138,10 +186,15 @@ bool Test_Utils(const std::string& vTest) { else IfTestExist(Test_IGFD_Utils_ReplaceString_6); else IfTestExist(Test_IGFD_Utils_ReplaceString_7); - IfTestExist(Test_IGFD_Utils_SplitStringToVector_0); - else IfTestExist(Test_IGFD_Utils_SplitStringToVector_1); - else IfTestExist(Test_IGFD_Utils_SplitStringToVector_2); - else IfTestExist(Test_IGFD_Utils_SplitStringToVector_3); + IfTestExist(Test_IGFD_Utils_SplitStringToVector_delimiter_char_0); + else IfTestExist(Test_IGFD_Utils_SplitStringToVector_delimiter_char_1); + else IfTestExist(Test_IGFD_Utils_SplitStringToVector_delimiter_char_2); + else IfTestExist(Test_IGFD_Utils_SplitStringToVector_delimiter_char_3); + + IfTestExist(Test_IGFD_Utils_SplitStringToVector_delimiter_std_string_0); + else IfTestExist(Test_IGFD_Utils_SplitStringToVector_delimiter_std_string_1); + else IfTestExist(Test_IGFD_Utils_SplitStringToVector_delimiter_std_string_2); + else IfTestExist(Test_IGFD_Utils_SplitStringToVector_delimiter_std_string_3); assert(0);