5
5
#include < Poco/SortedDirectoryIterator.h>
6
6
#include < Poco/String.h>
7
7
8
+ #include < algorithm>
9
+
8
10
void GuiFileChooserWindow::Show ()
9
11
{
10
12
_visible = true ;
@@ -19,9 +21,10 @@ bool GuiFileChooserWindow::Draw()
19
21
20
22
bool fileSelected{false };
21
23
22
- if (!_currentDir.isDirectory () || !Poco::File (_currentDir).exists ())
24
+ if (!_currentDir.isDirectory ()
25
+ || (!_currentDir.toString ().empty () && !Poco::File (_currentDir).exists ()))
23
26
{
24
- _currentDir = Poco::Path::home ();
27
+ ChangeDirectory ( Poco::Path::home () );
25
28
}
26
29
27
30
if (ImGui::Begin (" Load Preset" , &_visible), ImGuiWindowFlags_NoCollapse)
@@ -30,74 +33,36 @@ bool GuiFileChooserWindow::Draw()
30
33
31
34
ImGui::Separator ();
32
35
33
- ImGui::Text (" %s" , _currentDir.toString ().c_str ());
36
+ char pathBuffer[2048 ]{};
37
+ strncpy (pathBuffer, _currentDir.toString ().c_str (), std::min<size_t >(2047 , _currentDir.toString ().size ()));
34
38
35
- if (ImGui::BeginListBox (" ##filelist " , ImVec2 (- 1 ,- 1 )) )
39
+ if (ImGui::InputText (" ##path " , &pathBuffer[ 0 ], IM_ARRAYSIZE (pathBuffer)), ImGuiInputTextFlags_EnterReturnsTrue )
36
40
{
37
- Poco::SortedDirectoryIterator directoryIterator (_currentDir );
38
- Poco::SortedDirectoryIterator directoryEnd;
41
+ ChangeDirectory ( std::string (pathBuffer) );
42
+ }
39
43
40
- int index = 0 ;
41
- while (directoryIterator != directoryEnd)
44
+ if (ImGui::BeginListBox (" ##filelist" , ImVec2 (-1 , -1 )))
45
+ {
46
+ if (_currentDir.toString ().empty ())
42
47
{
43
- bool isSelected = _selectedFileIndex == index ;
44
- bool isDirectory = false ;
45
- bool isHidden = false ;
46
- try
47
- {
48
- // This will throw for broken symlinks or if the file/dir isn't accessible
49
- isHidden = directoryIterator->isHidden ();
50
- isDirectory = directoryIterator->isDirectory ();
51
- }
52
- catch (...)
53
- {
54
- }
48
+ ImGui::TextColored (ImVec4 (1 .0f , 0 .0f , 0 .0f , 1 .0f ), " No path entered" );
49
+ }
50
+ else
51
+ {
52
+ Poco::File pathCheck (_currentDir);
55
53
56
- if (!_showhidden && isHidden )
54
+ if (!pathCheck. exists () )
57
55
{
58
- ++directoryIterator;
59
- continue ;
56
+ ImGui::TextColored (ImVec4 (1 .0f , 0 .0f , 0 .0f , 1 .0f ), " Directory does not exist" );
60
57
}
61
-
62
- auto filename = directoryIterator.name ();
63
-
64
- if (isDirectory)
58
+ else if (!pathCheck.canRead ())
65
59
{
66
- filename. append ( " / " );
60
+ ImGui::TextColored ( ImVec4 ( 1 . 0f , 0 . 0f , 0 . 0f , 1 . 0f ), " Directory cannot be accessed " );
67
61
}
68
62
else
69
63
{
70
- if (Poco::icompare (directoryIterator.path ().getExtension (), " milk" ) != 0 )
71
- {
72
- ++directoryIterator;
73
- continue ;
74
- }
75
- }
76
-
77
- if (ImGui::Selectable (filename.c_str (), isSelected, ImGuiSelectableFlags_AllowDoubleClick))
78
- {
79
- _selectedFileIndex = index ;
80
-
81
- if (ImGui::IsMouseDoubleClicked (0 ))
82
- {
83
- if (isDirectory)
84
- {
85
- _currentDir = directoryIterator.path ();
86
- _currentDir.makeDirectory ();
87
- poco_debug_f1 (_logger, " Changing dir to: %s" , _currentDir.toString ());
88
- }
89
- else
90
- {
91
- _selectedFile = directoryIterator.path ();
92
- poco_debug_f1 (_logger, " User selected file: %s" , _selectedFile.path ());
93
- fileSelected = true ;
94
- _visible = false ;
95
- }
96
- }
64
+ fileSelected = PopulateFileList ();
97
65
}
98
-
99
- ++directoryIterator;
100
- index ++;
101
66
}
102
67
103
68
ImGui::EndListBox ();
@@ -112,6 +77,12 @@ bool GuiFileChooserWindow::Draw()
112
77
113
78
return fileSelected;
114
79
}
80
+
81
+ const Poco::File& GuiFileChooserWindow::SelectedFile () const
82
+ {
83
+ return _selectedFile;
84
+ }
85
+
115
86
void GuiFileChooserWindow::DrawNavButtons ()
116
87
{
117
88
ImGui::Checkbox (" Show hidden files" , &_showhidden);
@@ -122,33 +93,138 @@ void GuiFileChooserWindow::DrawNavButtons()
122
93
123
94
if (ImGui::Button (" Up" ))
124
95
{
125
- _currentDir = _currentDir.parent ();
126
- _currentDir.makeDirectory ();
96
+ ChangeDirectory (_currentDir.parent ());
127
97
poco_debug_f1 (_logger, " Going one dir up: %s" , _currentDir.toString ());
128
98
}
129
99
130
100
ImGui::SameLine ();
131
101
132
102
if (ImGui::Button (" Home" ))
103
+ {
104
+ ChangeDirectory (Poco::Path::home ());
105
+ poco_debug_f1 (_logger, " Going to user's home dir: %s" , _currentDir.toString ());
106
+ }
107
+
108
+ for (const auto & root: roots)
109
+ {
110
+ ImGui::SameLine ();
111
+
112
+ if (ImGui::Button (root.c_str ()))
133
113
{
134
- _currentDir = Poco::Path::home ( );
135
- poco_debug_f1 (_logger, " Going to user's home dir : %s" , _currentDir.toString ());
114
+ ChangeDirectory (root );
115
+ poco_debug_f1 (_logger, " Changing root/drive to : %s" , _currentDir.toString ());
136
116
}
117
+ }
118
+ }
119
+
120
+ bool GuiFileChooserWindow::PopulateFileList ()
121
+ {
122
+ bool fileSelected{false };
123
+ bool changeDir{false };
124
+ Poco::Path newDir;
137
125
138
- for (const auto & root: roots)
126
+ int index = 0 ;
127
+ for (const auto & file : _currentFileList)
128
+ {
129
+ bool isSelected = _selectedFileIndex == index ;
130
+ bool isDirectory = false ;
131
+ try
132
+ {
133
+ // This will throw for broken symlinks or if the file/dir isn't accessible
134
+ isDirectory = file.isDirectory ();
135
+ }
136
+ catch (...)
139
137
{
140
- ImGui::SameLine ();
138
+ }
141
139
142
- if (ImGui::Button (root.c_str ()))
143
- {
144
- _currentDir = root;
140
+ Poco::Path filePath (file.path ());
141
+ auto filename = filePath.getFileName ();
142
+
143
+ if (isDirectory)
144
+ {
145
+ filename.append (" /" );
146
+ }
145
147
146
- poco_debug_f1 (_logger, " Changing root/drive to: %s" , _currentDir.toString ());
148
+ if (ImGui::Selectable (filename.c_str (), isSelected, ImGuiSelectableFlags_AllowDoubleClick))
149
+ {
150
+ _selectedFileIndex = index ;
151
+
152
+ if (ImGui::IsMouseDoubleClicked (0 ))
153
+ {
154
+ if (isDirectory)
155
+ {
156
+ newDir = filePath;
157
+ changeDir = true ;
158
+ poco_debug_f1 (_logger, " Changing dir to: %s" , _currentDir.toString ());
159
+ }
160
+ else
161
+ {
162
+ _selectedFile = filePath;
163
+ poco_debug_f1 (_logger, " User selected file: %s" , _selectedFile.path ());
164
+ fileSelected = true ;
165
+ _visible = false ;
166
+ }
147
167
}
148
168
}
169
+
170
+ index ++;
171
+ }
172
+
173
+ if (changeDir)
174
+ {
175
+ ChangeDirectory (newDir);
176
+ }
177
+
178
+ return fileSelected;
149
179
}
150
180
151
- const Poco::File& GuiFileChooserWindow::SelectedFile () const
181
+ void GuiFileChooserWindow::ChangeDirectory ( const Poco::Path& newDirectory)
152
182
{
153
- return _selectedFile;
183
+ _currentDir = newDirectory;
184
+ _currentDir.makeDirectory ();
185
+
186
+ _currentFileList.clear ();
187
+
188
+ if (_currentDir.toString ().empty ())
189
+ {
190
+ return ;
191
+ }
192
+
193
+ Poco::File pathCheck (_currentDir);
194
+ if (!pathCheck.exists () || !pathCheck.canRead ())
195
+ {
196
+ return ;
197
+ }
198
+
199
+ // Ideally, only use the directory iterator after cd'ing into a new dir and store the path list.
200
+ Poco::SortedDirectoryIterator directoryIterator (_currentDir);
201
+ Poco::SortedDirectoryIterator directoryEnd;
202
+
203
+ while (directoryIterator != directoryEnd)
204
+ {
205
+ bool isHidden = false ;
206
+ bool isDirectory = false ;
207
+ try
208
+ {
209
+ // This will throw for broken symlinks or if the file/dir isn't accessible
210
+ isHidden = directoryIterator->isHidden ();
211
+ isDirectory = directoryIterator->isDirectory ();
212
+ }
213
+ catch (...)
214
+ {
215
+ }
216
+
217
+ if (!isDirectory && Poco::icompare (directoryIterator.path ().getExtension (), " milk" ) != 0 )
218
+ {
219
+ ++directoryIterator;
220
+ continue ;
221
+ }
222
+
223
+ if (!isHidden || _showhidden)
224
+ {
225
+ _currentFileList.push_back (*directoryIterator);
226
+ }
227
+
228
+ ++directoryIterator;
229
+ }
154
230
}
0 commit comments