cxWidgets 1.0
cxOpenFileDialog.h
Go to the documentation of this file.
1// Copyright (c) 2026 Eric N. Oulashin
2#ifndef __CXOPENFILEDIALOG_H__
3#define __CXOPENFILEDIALOG_H__
4
5//
6// cxOpenFileDialog.h - A directory & file chooser dialog, similar to
7// OpenFileDialog in .NET or QFileDialog in Qt, adapted for text-based display.
8// This was made with the help of Claude AI.
9//
10// cxOpenFileDialog presents a modal file browser dialog. The layout
11// (72 wide x 20 tall) is:
12//
13// +-- Open File --------------------------------------------------+
14// | /current/directory/path |
15// +------------------------+--------------------------------------+
16// | Directories | Files |
17// | .. | readme.txt 1.2 KB |
18// | subfolder1 | document.pdf 3.4 MB |
19// | subfolder2 | notes.doc 512 B |
20// | | |
21// +------------------------+--------------------------------------+
22// | File name: [_______________________________________________] |
23// | File type: All Files (*) [ OK ] [ Cancel ] |
24// +---------------------------------------------------------------+
25//
26// Navigation:
27// Tab / Shift-Tab : cycle focus between dir list -> file list ->
28// filename -> file type -> OK -> Cancel
29// Arrow keys : navigate directory or file lists when focused
30// Enter : enter directory / confirm file / edit filename /
31// cycle filter / activate OK or Cancel
32// Escape : cancel the dialog
33// Mouse click : click items in lists, buttons, etc.
34//
35// Return codes from showModal():
36// cxID_OK : user confirmed a file selection
37// cxID_CANCEL : user cancelled or pressed Escape
38//
39// Usage:
40// cxOpenFileDialog dlg;
41// dlg.setDirectory("/home/user");
42// dlg.addFilter("Text Files (*.txt)", "*.txt");
43// dlg.addFilter("All Files (*)", "*");
44// if (dlg.showModal() == cxID_OK)
45// {
46// std::string path = dlg.getSelectedFilePath();
47// }
48
49#include "cxWindow.h"
50#include "cxInput.h"
51#include <string>
52#include <vector>
53#include <memory>
54
55namespace cx {
56
61{
62public:
63 // -----------------------------------------------------------------------
64 // Layout constants
65 // -----------------------------------------------------------------------
66 static constexpr int DIALOG_WIDTH = 72;
67 static constexpr int DIALOG_HEIGHT = 20;
68
69 // Row offsets within the ncurses WINDOW (0 = top border)
70 static constexpr int ROW_PATH = 1;
71 static constexpr int ROW_SEP_TOP = 2;
72 static constexpr int ROW_HEADER = 3;
73 static constexpr int ROW_LIST_FIRST = 4;
74 static constexpr int ROW_LIST_LAST = 15;
75 static constexpr int LIST_VISIBLE = 12; // ROW_LIST_LAST - ROW_LIST_FIRST + 1
76 static constexpr int ROW_SEP_BOTTOM = 16;
77 static constexpr int ROW_FILENAME = 17;
78 static constexpr int ROW_CONTROLS = 18;
79
80 // Column offsets
81 static constexpr int COL_DIVIDER = 24;
82 static constexpr int COL_LABEL = 2;
83 static constexpr int COL_VALUE = 14;
84
85 // Directory list display area: cols 1..(COL_DIVIDER-1)
86 static constexpr int DIR_COL_START = 1;
87 static constexpr int DIR_DISPLAY_W = COL_DIVIDER - DIR_COL_START; // 23
88
89 // File list display area: cols (COL_DIVIDER+1)..(DIALOG_WIDTH-2)
90 static constexpr int FILE_COL_START = COL_DIVIDER + 1;
91 static constexpr int FILE_DISPLAY_W = DIALOG_WIDTH - 2 - FILE_COL_START; // 45
92
93 // Filename input area
94 static constexpr int FILENAME_INPUT_W = DIALOG_WIDTH - 2 - COL_VALUE; // 56
95
96 // Bottom controls (row 18)
97 static constexpr int FILTER_DISPLAY_W = 30;
98 static constexpr int COL_OK_TEXT = 50;
99 static constexpr int OK_TEXT_W = 6; // "[ OK ]"
100 static constexpr int COL_CANCEL_TEXT = 58;
101 static constexpr int CANCEL_TEXT_W = 10; // "[ Cancel ]"
102
103 // -----------------------------------------------------------------------
104 // Constructors / Destructor
105 // -----------------------------------------------------------------------
106
115 explicit cxOpenFileDialog(cxWindow *pParentWindow = nullptr,
116 int pRow = -1,
117 int pCol = -1,
118 const std::string& pTitle = " Open File ",
119 const std::string& pInitialDir = "");
120
121 virtual ~cxOpenFileDialog();
122
123 // -----------------------------------------------------------------------
124 // cxWindow overrides
125 // -----------------------------------------------------------------------
126
127 virtual std::string cxTypeStr() const override;
128 virtual void draw() override;
129
130 virtual long showModal(bool pShowSelf = true,
131 bool pBringToTop = true,
132 bool pShowSubwindows = true) override;
133
134 virtual long show(bool pBringToTop = false,
135 bool pShowSubwindows = true) override;
136
137 virtual void hide(bool pHideSubwindows = true) override;
138 virtual void unhide(bool pUnhideSubwindows = true) override;
139 virtual bool move(int pNewRow, int pNewCol, bool pRefresh = true) override;
140
141 // -----------------------------------------------------------------------
142 // Public API
143 // -----------------------------------------------------------------------
144
146 void setDirectory(const std::string& pPath);
148 std::string getDirectory() const;
149
151 std::string getSelectedFilePath() const;
153 std::string getSelectedFileName() const;
154
156 void setFileName(const std::string& pFileName);
157
159 void addFilter(const std::string& pDescription, const std::string& pPattern);
161 void clearFilters();
162
164 void setShowHiddenFiles(bool pShow);
165 bool getShowHiddenFiles() const;
166
171 void setAllowNewFile(bool pAllow);
172 bool getAllowNewFile() const;
173
174private:
175 // -----------------------------------------------------------------------
176 // Internal focus tracker
177 // -----------------------------------------------------------------------
178 enum class FocusItem
179 {
180 DIR_LIST,
181 FILE_LIST,
182 FILENAME_INPUT,
183 FILETYPE,
184 OK_BTN,
185 CANCEL_BTN
186 };
187
188 // -----------------------------------------------------------------------
189 // Data types
190 // -----------------------------------------------------------------------
191 struct FileEntry
192 {
193 std::string name;
194 uintmax_t size;
195 };
196
197 struct FileFilter
198 {
199 std::string description;
200 std::string pattern;
201 };
202
203 // -----------------------------------------------------------------------
204 // State
205 // -----------------------------------------------------------------------
206 std::string mCurrentPath;
207 std::string mSelectedFileName;
208 std::vector<std::string> mDirEntries;
209 std::vector<FileEntry> mFileEntries;
210 int mDirSelection = 0;
211 int mFileSelection = 0;
212 int mDirScrollOffset = 0;
213 int mFileScrollOffset = 0;
214 FocusItem mFocusItem = FocusItem::FILE_LIST;
215
216 std::vector<FileFilter> mFilters;
217 int mCurrentFilter = 0;
218 bool mShowHidden = false;
219 bool mAllowNewFile = true;
220
221 // -----------------------------------------------------------------------
222 // Child widget
223 // -----------------------------------------------------------------------
224 std::shared_ptr<cxInput> mFileNameInput;
225
226 // -----------------------------------------------------------------------
227 // Private helpers
228 // -----------------------------------------------------------------------
229 void initWidgets();
230 void loadDirectory();
231
232 // Drawing
233 void drawContent();
234 void drawPath();
235 void drawSeparators();
236 void drawListHeaders();
237 void drawDirList();
238 void drawFileList();
239 void drawFilenameRow();
240 void drawControlsRow();
241
242 // Focus
243 void setFocusItem(FocusItem pItem);
244
245 // Input loop
246 long doInputLoop();
247
248 // Navigation
249 void moveDirSelection(int pDelta);
250 void moveFileSelection(int pDelta);
251 void enterSelectedDir();
252 void activateFilenameInput();
253 void cycleFilter(int pDelta);
254
255 // Validation
256 bool canAcceptSelection() const;
257
258 // Utilities
259 bool matchesFilter(const std::string& pFileName) const;
260 static std::string formatFileSize(uintmax_t pSize);
261 static std::string truncStr(const std::string& pStr, int pMaxW);
262};
263
264} // namespace cx
265
266#endif // __CXOPENFILEDIALOG_H__
This is a dialog class that is designed to allow the user to choose a filename in a specific director...
Definition cxOpenFileDialog.h:61
static constexpr int ROW_PATH
Definition cxOpenFileDialog.h:70
static constexpr int CANCEL_TEXT_W
Definition cxOpenFileDialog.h:101
void setDirectory(const std::string &pPath)
Set the initial directory to display.
Definition cxOpenFileDialog.cpp:164
static constexpr int FILENAME_INPUT_W
Definition cxOpenFileDialog.h:94
static constexpr int ROW_LIST_FIRST
Definition cxOpenFileDialog.h:73
virtual void draw() override
Fills the member ncurses window structure with the current.
Definition cxOpenFileDialog.cpp:81
static constexpr int DIALOG_WIDTH
Definition cxOpenFileDialog.h:66
void clearFilters()
Remove all file type filters.
Definition cxOpenFileDialog.cpp:210
static constexpr int DIALOG_HEIGHT
Definition cxOpenFileDialog.h:67
static constexpr int ROW_LIST_LAST
Definition cxOpenFileDialog.h:74
virtual long show(bool pBringToTop=false, bool pShowSubwindows=true) override
Shows the window.
Definition cxOpenFileDialog.cpp:124
static constexpr int LIST_VISIBLE
Definition cxOpenFileDialog.h:75
void addFilter(const std::string &pDescription, const std::string &pPattern)
Add a file type filter (e.g. "Text Files (*.txt)", "*.txt").
Definition cxOpenFileDialog.cpp:204
static constexpr int ROW_FILENAME
Definition cxOpenFileDialog.h:77
static constexpr int COL_LABEL
Definition cxOpenFileDialog.h:82
void setShowHiddenFiles(bool pShow)
Toggle display of hidden files (dotfiles).
Definition cxOpenFileDialog.cpp:216
static constexpr int FILE_COL_START
Definition cxOpenFileDialog.h:90
static constexpr int OK_TEXT_W
Definition cxOpenFileDialog.h:99
void setFileName(const std::string &pFileName)
Pre-populate the filename input.
Definition cxOpenFileDialog.cpp:199
static constexpr int DIR_COL_START
Definition cxOpenFileDialog.h:86
static constexpr int FILE_DISPLAY_W
Definition cxOpenFileDialog.h:91
static constexpr int ROW_CONTROLS
Definition cxOpenFileDialog.h:78
static constexpr int ROW_SEP_TOP
Definition cxOpenFileDialog.h:71
virtual void unhide(bool pUnhideSubwindows=true) override
Un-hides the window.
Definition cxOpenFileDialog.cpp:138
void setAllowNewFile(bool pAllow)
Definition cxOpenFileDialog.cpp:226
static constexpr int FILTER_DISPLAY_W
Definition cxOpenFileDialog.h:97
static constexpr int COL_VALUE
Definition cxOpenFileDialog.h:83
static constexpr int ROW_SEP_BOTTOM
Definition cxOpenFileDialog.h:76
std::string getDirectory() const
Returns the currently displayed directory.
Definition cxOpenFileDialog.cpp:179
bool getAllowNewFile() const
Definition cxOpenFileDialog.cpp:231
virtual bool move(int pNewRow, int pNewCol, bool pRefresh=true) override
Changes the window's position, based on a new upper-left corner.
Definition cxOpenFileDialog.cpp:146
static constexpr int COL_OK_TEXT
Definition cxOpenFileDialog.h:98
virtual long showModal(bool pShowSelf=true, bool pBringToTop=true, bool pShowSubwindows=true) override
Shows the window and waits for input.
Definition cxOpenFileDialog.cpp:88
static constexpr int COL_CANCEL_TEXT
Definition cxOpenFileDialog.h:100
virtual ~cxOpenFileDialog()
Definition cxOpenFileDialog.cpp:68
static constexpr int DIR_DISPLAY_W
Definition cxOpenFileDialog.h:87
virtual void hide(bool pHideSubwindows=true) override
Hides the window.
Definition cxOpenFileDialog.cpp:132
std::string getSelectedFilePath() const
Returns the full path of the selected file (directory + filename).
Definition cxOpenFileDialog.cpp:184
static constexpr int COL_DIVIDER
Definition cxOpenFileDialog.h:81
std::string getSelectedFileName() const
Returns just the selected filename.
Definition cxOpenFileDialog.cpp:194
virtual std::string cxTypeStr() const override
Returns the name of the cxWidgets class. This is overridden.
Definition cxOpenFileDialog.cpp:76
bool getShowHiddenFiles() const
Definition cxOpenFileDialog.cpp:221
static constexpr int ROW_HEADER
Definition cxOpenFileDialog.h:72
Represents a text-based window on the screen. Can contain a title, status, and a message to appear wi...
Definition cxWindow.h:195
cxBorderChars.h - Defines border characters to be used in drawing a box (i.e., in cxWindow and all it...
Definition cxApp.cpp:5