EchoMap 2026-07-25 6d3977c
An experimental cross-platform digital signal processing application for sound-source localisation.
Loading...
Searching...
No Matches
echomap::FilesystemCombo Class Reference

Provides a platform-independent Dear ImGui combo box for browsing the file-system and selecting files. More...

#include <FilesystemCombo.hpp>

Classes

struct  Entry
 A drawable and selectable representation of a file or directory on the file-system. More...
struct  BrowseTarget
 A root target selected by the user to focus on. More...
struct  EntryCache
 A cache of Entry objects under a single root directory. More...

Public Member Functions

 FilesystemCombo (EchoMap *app)
 Sets up a new FilesystemCombo with the given EchoMap application context.
bool operator() (std::filesystem::path &selected_path)
 Draws the FilesystemCombo control.

Private Member Functions

void invalidate_cache ()
 Invalidates the EntryCache.
void update_current_state (const std::filesystem::path &path)
 Copies and formats the given path into the fixed-size current directory state member variable.
bool draw_combo_body (std::filesystem::path &selected_path)
BrowseTarget get_browse_target () const
bool draw_parent_entry (const std::filesystem::path &directory)
bool draw_child_entries (std::string_view filter, std::filesystem::path &selected_path)
void accept_path (std::filesystem::path &selected_path, const std::filesystem::path &path)

Private Attributes

std::array< char, max_path_lengthcurrent_root {}
 The current raw string entered by the user.
BrowseTarget current_target
 The current target specified in the filter window.
std::optional< EntryCachecache
 Cache of entries visible in the combo box.
EchoMapapp
 Pointer to the owning application instance.

Static Private Attributes

static constexpr unsigned int max_path_length = 4096
 Maximum number of characters in a filesystem path.

Detailed Description

Provides a platform-independent Dear ImGui combo box for browsing the file-system and selecting files.

Definition at line 31 of file FilesystemCombo.hpp.

Constructor & Destructor Documentation

◆ FilesystemCombo()

echomap::FilesystemCombo::FilesystemCombo ( EchoMap * app)
explicit

Sets up a new FilesystemCombo with the given EchoMap application context.

The initial location is the current working directory.

Parameters
appThe owning application instance.
Exceptions
std::runtime_errorThe CWD could not be interrogated.

Definition at line 24 of file FilesystemCombo.cpp.

26 :
27 app(app)
28{
29 std::error_code error_code;
30 const auto cwd = std::filesystem::current_path(error_code);
31
32 if (error_code || cwd.empty() || !std::filesystem::is_directory(cwd))
33 throw std::runtime_error("Could not get the current working directory. Is the filesystem readable?");
34
36}
EchoMap * app
Pointer to the owning application instance.
void update_current_state(const std::filesystem::path &path)
Copies and formats the given path into the fixed-size current directory state member variable.
T current_path(T... args)
T is_directory(T... args)

Member Function Documentation

◆ accept_path()

void echomap::FilesystemCombo::accept_path ( std::filesystem::path & selected_path,
const std::filesystem::path & path )
private

Definition at line 266 of file FilesystemCombo.cpp.

270{
273 return;
274 }
275
276 selected_path = path;
277
278 if (path.has_parent_path())
280 else
282}
T has_parent_path(T... args)
T parent_path(T... args)

◆ draw_child_entries()

bool echomap::FilesystemCombo::draw_child_entries ( std::string_view filter,
std::filesystem::path & selected_path )
private

Definition at line 227 of file FilesystemCombo.cpp.

231{
232 assert(cache.has_value());
233
234 bool has_visible_entries = false;
235 bool changed = false;
236
237 for (const auto& entry : cache->entries) {
238 if (!filter.empty() && !entry.name.contains(filter))
239 continue;
240
241 has_visible_entries = true;
242
243 if (!entry.draw())
244 continue;
245
246 if (entry.is_directory) {
247 update_current_state(entry.path);
248 return false;
249 }
250
251 selected_path = entry.path;
252 update_current_state(entry.path.parent_path());
253
254 changed = true;
255 ImGui::CloseCurrentPopup();
256
257 return changed;
258 }
259
260 if (!has_visible_entries)
261 ImGui::TextDisabled("No matching entries.");
262
263 return changed;
264}
std::optional< EntryCache > cache
Cache of entries visible in the combo box.
T empty(T... args)

◆ draw_combo_body()

bool echomap::FilesystemCombo::draw_combo_body ( std::filesystem::path & selected_path)
private

Definition at line 136 of file FilesystemCombo.cpp.

139{
140 ImGui::SetNextItemWidth(-std::numeric_limits<float>::min());
141 const std::string old_root = current_root.data();
142 const bool enter_pressed =
143 ImGui::InputText("##path", current_root.data(), current_root.size(), ImGuiInputTextFlags_EnterReturnsTrue);
144
145 bool changed = false;
146
147 if (old_root != current_root.data())
148 // If the browse target has changed, update the cached member variable.
149 current_target = get_browse_target();
150
151 if (enter_pressed) {
152 // If the user has explicitly pressed 'enter', accept whatever is selected at this time.
153 accept_path(
154 selected_path,
155 current_target.target_path.empty() ? current_target.parent_directory : current_target.target_path
156 );
157
158 changed = true;
159 ImGui::CloseCurrentPopup();
160 }
161
162 ImGui::Separator();
163
164 if (!std::filesystem::is_directory(current_target.parent_directory))
165 ImGui::TextDisabled("Not a readable directory.");
166 else {
167 changed |= draw_parent_entry(current_target.parent_directory);
168 if (!cache || cache->directory != current_target.parent_directory)
169 cache.emplace(current_target.parent_directory);
170
171 changed |= draw_child_entries(current_target.filter, selected_path);
172 }
173
174 return changed;
175}
BrowseTarget current_target
The current target specified in the filter window.
std::array< char, max_path_length > current_root
The current raw string entered by the user.
T min(T... args)

◆ draw_parent_entry()

bool echomap::FilesystemCombo::draw_parent_entry ( const std::filesystem::path & directory)
private

Definition at line 210 of file FilesystemCombo.cpp.

213{
214 const std::filesystem::path parent = directory.parent_path();
215
216 if (parent.empty() || parent == directory)
217 return false;
218
219 if (ImGui::Selectable("../", false, ImGuiSelectableFlags_NoAutoClosePopups)) {
220 update_current_state(parent);
221 return true;
222 }
223
224 return false;
225}

◆ get_browse_target()

FilesystemCombo::BrowseTarget echomap::FilesystemCombo::get_browse_target ( ) const
nodiscardprivate

Definition at line 177 of file FilesystemCombo.cpp.

178{
179 std::error_code error_code;
180 const std::string typed_string = current_root.data();
181 auto const typed_path = typed_string.empty() ? std::filesystem::path{} : std::filesystem::path{typed_string};
182 auto lookup_path = typed_path;
183
184 if (lookup_path.empty())
185 lookup_path = std::filesystem::current_path(error_code);
186 else if (lookup_path.is_relative())
187 lookup_path = std::filesystem::absolute(lookup_path, error_code);
188
189 if (error_code || lookup_path.empty())
190 lookup_path = ".";
191
192 error_code.clear();
193
194 if (std::filesystem::is_directory(lookup_path, error_code))
195 return {.target_path = lookup_path, .parent_directory = lookup_path, .filter = {}};
196
197 std::filesystem::path directory = lookup_path.parent_path();
198
199 if (directory.empty()) {
200 error_code.clear();
201 directory = std::filesystem::current_path(error_code);
202
203 if (error_code || directory.empty())
204 directory = ".";
205 }
206
207 return {.target_path = lookup_path, .parent_directory = directory, .filter = lookup_path.filename().string()};
208}
T absolute(T... args)
T clear(T... args)
T filename(T... args)

◆ invalidate_cache()

void echomap::FilesystemCombo::invalidate_cache ( )
private

Invalidates the EntryCache.

Definition at line 81 of file FilesystemCombo.cpp.

82{
83 cache.reset();
84}

◆ operator()()

bool echomap::FilesystemCombo::operator() ( std::filesystem::path & selected_path)

Draws the FilesystemCombo control.

Parameters
selected_pathOutput parameter for the selected file.
Returns
Has a new file been selected?
Precondition
A Dear ImGui panel's draw cycle must already be underway.

Definition at line 38 of file FilesystemCombo.cpp.

41{
42 bool changed = false;
43
44 ImGui::SetNextItemWidth(-std::numeric_limits<float>::min());
45
46 const std::string preview = selected_path.empty() ? std::string{current_root.data()} : selected_path.string();
47
48 if (ImGui::BeginCombo("##FilesystemCombo", preview.c_str(), ImGuiComboFlags_HeightLarge)) {
49 if (ImGui::IsWindowAppearing()) {
50 ImGui::SetKeyboardFocusHere();
52 }
53
54 changed = draw_combo_body(selected_path);
55
56 ImGui::EndCombo();
57 app->increment_forced_frames();
58 }
59
60 return changed;
61}
T c_str(T... args)
void invalidate_cache()
Invalidates the EntryCache.

◆ update_current_state()

void echomap::FilesystemCombo::update_current_state ( const std::filesystem::path & path)
private

Copies and formats the given path into the fixed-size current directory state member variable.

The current directory array is always NULL-terminated following this operation. The current BrowseTarget is also updated to the given path.

Parameters
pathThe path to the new root directory.

Definition at line 123 of file FilesystemCombo.cpp.

126{
127 const std::string path_string = path.string();
128 const std::size_t length = std::min(current_root.size() - 1, path_string.size());
129
130 std::memcpy(current_root.data(), path_string.data(), length);
131 current_root[length] = '\0';
132
133 current_target = get_browse_target();
134}
T data(T... args)
T memcpy(T... args)
T size(T... args)

Member Data Documentation

◆ app

EchoMap* echomap::FilesystemCombo::app
private

Pointer to the owning application instance.

Definition at line 186 of file FilesystemCombo.hpp.

◆ cache

std::optional<EntryCache> echomap::FilesystemCombo::cache
private

Cache of entries visible in the combo box.

Definition at line 185 of file FilesystemCombo.hpp.

◆ current_root

std::array<char, max_path_length> echomap::FilesystemCombo::current_root {}
private

The current raw string entered by the user.

Definition at line 183 of file FilesystemCombo.hpp.

183{};

◆ current_target

BrowseTarget echomap::FilesystemCombo::current_target
private

The current target specified in the filter window.

Definition at line 184 of file FilesystemCombo.hpp.

◆ max_path_length

unsigned int echomap::FilesystemCombo::max_path_length = 4096
staticconstexprprivate

Maximum number of characters in a filesystem path.

Definition at line 55 of file FilesystemCombo.hpp.


The documentation for this class was generated from the following files: