C-Menu
0.2.9
A User Interface Toolkit
Toggle main menu visibility
Loading...
Searching...
No Matches
cm_fields.c
Go to the documentation of this file.
1
/** @file cm_fields.c
2
@brief Stand-alone Field Edit and Entry for C-Menu
3
@details Currently, this modules contains a single function, cf_accept(),
4
a lightweight yet fully functional field editor. For text fields, it is
5
equivalent to the field editor in fields.c. Instead of the built-in
6
formatting and validation in fields.c, this module provides a clean slate
7
for a modular plug-in architecture to accomodate formatting, validation, and
8
high-precision numeric data. It will eventually replace the field editor in
9
fields.c. It is a work in progress.
10
@author Bill Waller
11
Copyright (c) 2025, 2026
12
MIT License
13
billxwaller@gmail.com
14
@date 2026-02-09
15
*/
16
17
#
include
<
common
.
h
>
18
#
include
<
monetary
.
h
>
19
#
include
<
stdbool
.
h
>
20
#
include
<
stddef
.
h
>
21
#
include
<
string
.
h
>
22
#
include
<
termios
.
h
>
23
#
include
<
unistd
.
h
>
24
25
/** @brief Structure to hold field information for C-Menu
26
@note Not currently used in the code, but may be used in
27
future versions of C-Menu
28
*/
29
30
bool
f_erase_remainder
=
true
;
31
32
/** @brief Accepts input for a field in a C-Menu window
33
@param UiSurface *sfc The surface to accept input from
34
@param win The window to accept input from
35
@param accept_s The string to accept input into
36
@param flin The line number of the field
37
@param fcol The column number of the field
38
@param flen The length of the field
39
@return The key pressed to exit the field (KEY_ENTER, KEY_F09, etc.)
40
*/
41
int
cf_accept
(UiSurface *sfc, uint w,
char
*accept_s, uint flin, uint fcol, uint flen) {
42
bool
f_insert =
false
;
43
int
in_key = 0;
44
char
*s, *d;
45
char
*fstart;
46
UiEvent event;
47
48
click_x
=
click_y
= -1;
49
char
*p = fstart = accept_s;
50
char
*fend = fstart + flen;
51
int
x = fcol;
52
char
*str_end = p + strlen(p);
53
while
(1) {
54
if
(in_key == 0) {
55
ui_mvwaddstr
(
sfc
,
w
,
flin
,
fcol
,
accept_s
)
;
56
ui_wclrtoeol
(
sfc
,
w
)
;
57
ui_cursor_move
(
sfc
,
w
,
flin
,
x
)
;
58
ui_render
(
)
;
59
in_key =
ui_get_event
(
sfc
,
WIN
,
&event
,
-1
)
;
60
}
61
ui_curs_set
(
0
)
;
62
switch
(in_key) {
63
case
KEY_F09
:
64
in_key =
KEY_F09
;
65
return
(in_key);
66
case
'\t'
:
67
case
KEY_END
:
68
case
Ctrl
(
'e'
):
69
while
(*p !=
'\0'
)
70
p++;
71
x = fcol + (p - fstart);
72
in_key = 0;
73
continue
;
74
/**< Enter accepts the field and moves to the next field if
75
* f_erase_remainder is set, it will clear the remaining
76
* characters above and after the current cursor location */
77
case
'\n'
:
78
case
KEY_ENTER
:
79
if
(
f_erase_remainder
)
80
*p =
'\0'
;
81
in_key =
KEY_ENTER
;
82
return
(in_key);
83
/** KEY_IC toggles insert mode */
84
case
KEY_IC
:
85
f_insert = !f_insert;
86
in_key = 0;
87
continue
;
88
/** KEY_DC deletes character at cursor */
89
case
KEY_DC
:
90
s = p + 1;
91
d = p;
92
while
(*s !=
'\0'
)
93
*d++ = *s++;
94
*d =
'\0'
;
95
str_end = d;
96
f_insert =
false
;
97
in_key = 0;
98
continue
;
99
/** KEY_HOME moves cursor to start of field */
100
case
KEY_HOME
:
101
case
Ctrl
(
'a'
):
102
p = fstart;
103
x = fcol;
104
in_key = 0;
105
continue
;
106
/** KEY_BACKSPACE deletes character before cursor */
107
case
KEY_BACKSPACE
:
108
if
(p > fstart) {
109
p--;
110
x--;
111
}
112
s = p + 1;
113
d = p;
114
while
(*s !=
'\0'
)
115
*d++ = *s++;
116
*d =
'\0'
;
117
str_end = d;
118
in_key = 0;
119
continue
;
120
/** KEY_LEFT moves cursor left one character */
121
case
KEY_LEFT
:
122
if
(p > fstart) {
123
p--;
124
x--;
125
}
126
in_key = 0;
127
continue
;
128
/** KEY_RIGHT moves cursor right one character */
129
case
KEY_RIGHT
:
130
if
(p < fend && p < str_end) {
131
p++;
132
x++;
133
}
134
in_key = 0;
135
continue
;
136
/** Handles mouse events for field editing */
137
case
KEY_MOUSE
:
138
x =
click_x
;
139
flin =
click_y
;
140
fstart = accept_s;
141
fend = fstart + flen;
142
str_end = fstart + strlen(fstart);
143
p = fstart + (x - fcol);
144
if
(p > str_end)
145
x -= p - str_end;
146
p =
min
(p, str_end);
147
in_key = 0;
148
continue
;
149
default
:
150
if
(p >= fend) {
151
in_key = 0;
152
continue
;
153
}
154
if
(in_key <
' '
|| in_key >
'~'
) {
155
in_key = 0;
156
continue
;
157
}
158
if
(f_insert) {
159
if
(str_end < fend) {
160
s = str_end - 1;
161
d = str_end;
162
while
(s >= p)
163
*d-- = *s--;
164
*p++ = in_key;
165
str_end++;
166
x++;
167
}
168
}
else
{
169
if
(p < fend) {
170
if
(p < str_end) {
171
if
(p == accept_s && in_key ==
' '
) {
172
d = accept_s;
173
s = accept_s + 1;
174
while
(*s !=
'\0'
)
175
*d++ = *s++;
176
*d =
'\0'
;
177
in_key = 0;
178
continue
;
179
}
180
*p++ = in_key;
181
x++;
182
}
else
if
(p == str_end) {
183
*p++ = in_key;
184
*p =
'\0'
;
185
str_end = p;
186
x++;
187
}
188
}
189
}
190
in_key = 0;
191
continue
;
192
}
193
}
194
}
min
#define min(x, y)
min macro evaluates two expressions, returning least result
Definition
cm.h:91
Ctrl
#define Ctrl(c)
Definition
cm.h:54
ui_render
void ui_render()
Definition
ui_ncurses.c:800
ui_cursor_move
int ui_cursor_move(UiSurface *s, uint w, uint y, uint x)
Definition
ui_ncurses.c:727
ui_mvwaddstr
int ui_mvwaddstr(UiSurface *s, uint w, uint y, uint x, const char *text)
Definition
ui_ncurses_draw.c:132
ui_get_event
int ui_get_event(UiSurface *s, uint w, UiEvent *ev, int timeout_ms)
Wait for an input event on target (or stdscr if NULL).
Definition
ui_ncurses_input.c:103
ui_wclrtoeol
int ui_wclrtoeol(UiSurface *s, uint w)
Definition
ui_ncurses_draw.c:31
ui_curs_set
int ui_curs_set(int visibility)
Definition
ui_ncurses.c:737
KEY_F09
#define KEY_F09
Definition
ui_ncurses_internal.h:33
KEY_RIGHT
#define KEY_RIGHT
Definition
ui_notcurses_internal.h:27
KEY_DC
#define KEY_DC
Definition
ui_notcurses_internal.h:44
KEY_BACKSPACE
#define KEY_BACKSPACE
Definition
ui_notcurses_internal.h:29
WIN
@ WIN
Definition
ui_notcurses_internal.h:99
KEY_END
#define KEY_END
Definition
ui_notcurses_internal.h:50
KEY_ENTER
#define KEY_ENTER
Definition
ui_notcurses_internal.h:48
KEY_MOUSE
#define KEY_MOUSE
Definition
ui_notcurses_internal.h:52
KEY_IC
#define KEY_IC
Definition
ui_notcurses_internal.h:45
KEY_LEFT
#define KEY_LEFT
Definition
ui_notcurses_internal.h:26
KEY_HOME
#define KEY_HOME
Definition
ui_notcurses_internal.h:28
cf_accept
int cf_accept(UiSurface *sfc, uint w, char *accept_s, uint flin, uint fcol, uint flen)
Accepts input for a field in a C-Menu window.
Definition
cm_fields.c:41
f_erase_remainder
bool f_erase_remainder
Structure to hold field information for C-Menu.
Definition
cm_fields.c:30
click_x
int click_x
Definition
dwin.c:45
click_y
int click_y
Definition
dwin.c:44
cm_fields.c
Generated by
1.17.0