cxWidgets 1.0
cxDatePicker.h
Go to the documentation of this file.
1// Copyright (c) 2026 E. Oulashin
2#ifndef __CXDATEPICKER_H__
3#define __CXDATEPICKER_H__
4
5// Copyright (c) 2026 Eric Oulashin
6//
7// cxDatePicker.h - A text-based date-picker dialog for the cxWidgets library.
8// This was mde with the help of Claude AI.
9//
10// cxDatePicker presents a modal calendar view. The layout (38 wide × 20 tall)
11// is:
12//
13// ┌─────────────────────────────────────┐ ← title " Select Date"
14// │ Mon, March 16, 2026 │ ← selected-date header (row 1)
15// │─────────────────────────────────────│ ← separator (row 2)
16// │ [<] March [>] 2026 │ ← controls (rows 3–5)
17// │ │
18// │ Su Mo Tu We Th Fr Sa │ ← day headers (row 6)
19// │ 1 2 3 4 5 6 7 │ ← calendar rows 7–12
20// │ … │
21// │ │
22// │ [ OK ] [ Cancel ] │ ← buttons (rows 14–16)
23// └─────────────────────────────────────┘
24//
25// Navigation:
26// Tab / Shift-Tab : cycle focus between month-combo → year-input → [<] →
27// [>] → calendar → [Cancel] → [OK]
28// Arrow keys : move day cursor within the calendar; left/right at
29// month boundary navigates to the previous/next month
30// Enter : confirm focused control / select focused day
31// Mouse click : click a calendar day to focus it; click [OK]/[Cancel]
32// to confirm/abort; click [<]/[>] to navigate months
33//
34// Return codes from showModal():
35// cxID_OK : user pressed OK or double-clicked a day
36// cxID_CANCEL : user pressed Cancel or Escape
37//
38// Usage:
39// cxDatePicker picker(nullptr); // centered on screen, defaults to today
40// if (picker.showModal() == cxID_OK) {
41// cxDate chosen = picker.getSelectedDate();
42// }
43
44#include "cxWindow.h"
45#include "cxButton.h"
46#include "cxComboBox.h"
47#include "cxInput.h"
48#include "cxDate.h"
49#include <memory>
50
51namespace cx {
52
56class cxDatePicker : public cxWindow
57{
58public:
59 // -----------------------------------------------------------------------
60 // Layout constants
61 // -----------------------------------------------------------------------
62 static constexpr int PICKER_WIDTH = 38; // total window width
63 static constexpr int PICKER_HEIGHT = 20; // total window height
64
65 // Row offsets within the ncurses WINDOW (0 = top border)
66 static constexpr int ROW_DATE_HEADER = 1; // selected-date display
67 static constexpr int ROW_SEPARATOR = 2; // ACS_HLINE separator
68 static constexpr int ROW_CTRL_TOP = 3; // top border of nav buttons
69 static constexpr int ROW_CTRL_MID = 4; // content of controls
70 static constexpr int ROW_CTRL_BOT = 5; // bottom border of nav buttons
71 static constexpr int ROW_DAY_HEADERS = 6; // "Su Mo Tu We Th Fr Sa"
72 static constexpr int ROW_CAL_FIRST = 7; // first calendar week row
73 static constexpr int ROW_CAL_LAST = 12; // last calendar week row (6 weeks max)
74 static constexpr int ROW_BTN_TOP = 14; // top border of OK/Cancel
75 static constexpr int ROW_BTN_MID = 15; // button content
76 static constexpr int ROW_BTN_BOT = 16; // button bottom border
77
78 // Column offsets within the ncurses WINDOW (0 = left border)
79 // Control row layout: [<] [MonthCombo] [>] [Year____]
80 static constexpr int COL_CAL = 2; // left edge of calendar area
81 static constexpr int COL_PREV_BTN = 2; // [<] button column
82 static constexpr int NAV_BTN_W = 3; // nav button width (incl. border)
83 static constexpr int NAV_BTN_H = 3; // nav button height (incl. border)
84 static constexpr int COL_MONTH_COMBO = 6; // month combo box column
85 static constexpr int MONTH_COMBO_W = 13; // month combo box width
86 static constexpr int MONTH_COMBO_H = 10; // month combo box height (1 input + 9 menu)
87 static constexpr int COL_NEXT_BTN = 21; // [>] button column
88 static constexpr int COL_YEAR_INPUT = 27; // year input left edge
89 static constexpr int YEAR_INPUT_W = 6; // year input width (4 digits + padding)
90 static constexpr int COL_OK_BTN = 20; // OK button column
91 static constexpr int OK_BTN_W = 5; // OK button width
92 static constexpr int COL_CANCEL_BTN = 26; // Cancel button column
93 static constexpr int CANCEL_BTN_W = 10; // Cancel button width
94
95 static constexpr int DAY_CELL_W = 3; // chars per day cell (" %2d")
96
97 // -----------------------------------------------------------------------
98 // Constructors / Destructor
99 // -----------------------------------------------------------------------
100
111 explicit cxDatePicker(cxWindow *pParentWindow = nullptr,
112 int pRow = -1,
113 int pCol = -1,
114 const cxDate& pDate = cxDate::today());
115
128 explicit cxDatePicker(int pYear, int pMonth, int pDay,
129 cxWindow *pParentWindow = nullptr,
130 int pRow = -1,
131 int pCol = -1);
132
133 virtual ~cxDatePicker();
134
135 // -----------------------------------------------------------------------
136 // cxWindow overrides
137 // -----------------------------------------------------------------------
138
140 virtual std::string cxTypeStr() const override;
141
149 virtual long showModal(bool pShowSelf = true,
150 bool pBringToTop = true,
151 bool pShowSubwindows = true) override;
152
157 virtual void hide(bool pHideSubwindows = true) override;
158
165 virtual void unhide(bool pUnhideSubwindows = true) override;
166
174 virtual bool move(int pNewRow, int pNewCol, bool pRefresh = true) override;
175
177 virtual void draw() override;
178
179 // -----------------------------------------------------------------------
180 // Date picker interface
181 // -----------------------------------------------------------------------
182
188 [[nodiscard]] const cxDate& getSelectedDate() const noexcept
189 {
190 return mSelectedDate;
191 }
192
197 void setDate(const cxDate& pDate);
198
199private:
200 // -----------------------------------------------------------------------
201 // Internal focus tracker
202 // -----------------------------------------------------------------------
203 enum class FocusItem
204 {
205 MONTH_COMBO,
206 YEAR_INPUT,
207 PREV_BTN,
208 NEXT_BTN,
209 CALENDAR,
210 CANCEL_BTN,
211 OK_BTN
212 };
213
214 // -----------------------------------------------------------------------
215 // State
216 // -----------------------------------------------------------------------
217 cxDate mSelectedDate; // Date confirmed by the user (valid on cxID_OK)
218 cxDate mDisplayDate; // Month/year currently shown in the calendar
219 int mFocusDay = 1; // Which day (1-based) has the cursor in the calendar
220 FocusItem mFocusItem = FocusItem::CALENDAR;
221
222 // -----------------------------------------------------------------------
223 // Child widgets
224 // -----------------------------------------------------------------------
225 std::shared_ptr<cxComboBox> mMonthCombo;
226 std::shared_ptr<cxInput> mYearInput;
227 std::shared_ptr<cxButton> mPrevBtn;
228 std::shared_ptr<cxButton> mNextBtn;
229 std::shared_ptr<cxButton> mCancelBtn;
230 std::shared_ptr<cxButton> mOKBtn;
231
232 // -----------------------------------------------------------------------
233 // Private helpers
234 // -----------------------------------------------------------------------
235
237 void initWidgets();
238
240 void drawContent();
241
244 void redrawDay(int pDay);
245
247 void getDayWinPos(int pDay, int& pWinRow, int& pWinCol) const;
248
250 int getDayAtScreenPos(int pScreenRow, int pScreenCol) const;
251
253 void setFocusItem(FocusItem pItem);
254
256 void moveFocusDay(int pDelta);
257
259 void navigateMonth(int pDelta);
260
262 void highlightButton(std::shared_ptr<cxButton>& pBtn, bool pOn);
263
265 void applyYearInput();
266
268 void applyMonthCombo();
269
271 long doInputLoop();
272
274 void refreshCalendar();
275};
276
277} // namespace cx
278
279#endif // __CXDATEPICKER_H__
This is a dialog that displays a calendar, allowing the user to choose a date while viewing a calenda...
Definition cxDatePicker.h:57
static constexpr int ROW_BTN_BOT
Definition cxDatePicker.h:76
static constexpr int COL_MONTH_COMBO
Definition cxDatePicker.h:84
static constexpr int NAV_BTN_H
Definition cxDatePicker.h:83
static constexpr int ROW_SEPARATOR
Definition cxDatePicker.h:67
static constexpr int ROW_BTN_TOP
Definition cxDatePicker.h:74
static constexpr int ROW_DATE_HEADER
Definition cxDatePicker.h:66
virtual void hide(bool pHideSubwindows=true) override
Hides the date picker and all its child widgets.
Definition cxDatePicker.cpp:132
virtual bool move(int pNewRow, int pNewCol, bool pRefresh=true) override
Moves the date picker window and repositions all child widgets.
Definition cxDatePicker.cpp:156
static constexpr int COL_YEAR_INPUT
Definition cxDatePicker.h:88
static constexpr int COL_NEXT_BTN
Definition cxDatePicker.h:87
static constexpr int COL_CAL
Definition cxDatePicker.h:80
static constexpr int COL_CANCEL_BTN
Definition cxDatePicker.h:92
static constexpr int NAV_BTN_W
Definition cxDatePicker.h:82
virtual ~cxDatePicker()
Definition cxDatePicker.cpp:66
static constexpr int ROW_CTRL_MID
Definition cxDatePicker.h:69
static constexpr int COL_PREV_BTN
Definition cxDatePicker.h:81
virtual std::string cxTypeStr() const override
Definition cxDatePicker.cpp:76
static constexpr int ROW_DAY_HEADERS
Definition cxDatePicker.h:71
static constexpr int ROW_CTRL_BOT
Definition cxDatePicker.h:70
static constexpr int OK_BTN_W
Definition cxDatePicker.h:91
static constexpr int MONTH_COMBO_W
Definition cxDatePicker.h:85
static constexpr int PICKER_HEIGHT
Definition cxDatePicker.h:63
virtual void draw() override
Draws the window border and calendar content.
Definition cxDatePicker.cpp:81
static constexpr int MONTH_COMBO_H
Definition cxDatePicker.h:86
void setDate(const cxDate &pDate)
Pre-sets the date shown when the picker opens.
Definition cxDatePicker.cpp:179
static constexpr int CANCEL_BTN_W
Definition cxDatePicker.h:93
static constexpr int PICKER_WIDTH
Definition cxDatePicker.h:62
virtual void unhide(bool pUnhideSubwindows=true) override
Shows the date picker and its child widgets. Note: the month combo drop-down list stays hidden until ...
Definition cxDatePicker.cpp:143
static constexpr int ROW_CTRL_TOP
Definition cxDatePicker.h:68
static constexpr int YEAR_INPUT_W
Definition cxDatePicker.h:89
static constexpr int COL_OK_BTN
Definition cxDatePicker.h:90
static constexpr int ROW_BTN_MID
Definition cxDatePicker.h:75
static constexpr int ROW_CAL_FIRST
Definition cxDatePicker.h:72
static constexpr int ROW_CAL_LAST
Definition cxDatePicker.h:73
virtual long showModal(bool pShowSelf=true, bool pBringToTop=true, bool pShowSubwindows=true) override
Shows the date picker and enters the interactive input loop.
Definition cxDatePicker.cpp:89
static constexpr int DAY_CELL_W
Definition cxDatePicker.h:95
const cxDate & getSelectedDate() const noexcept
Returns the date the user confirmed. Only meaningful after showModal() returned cxID_OK.
Definition cxDatePicker.h:188
Enables easy management of dates. C++17-enhanced version of the original 'date' class.
Definition cxDate.h:84
static cxDate today() noexcept
Definition cxDate.cpp:646
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