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
typedef
struct
{
30
int
flin;
31
int
fcol;
32
int
flen;
33
int
ff;
34
char
fill_char;
35
WINDOW *win;
36
bool
cf_erase_remainder;
37
} CmField;
38
39
bool
f_erase_remainder
=
true
;
40
41
int
cf_accept
(WINDOW *win,
char
*accept_s,
int
flin,
int
fcol,
int
flen);
42
43
/** @brief Accepts input for a field in a C-Menu window
44
@param win The window to accept input from
45
@param accept_s The string to accept input into
46
@param flin The line number of the field
47
@param fcol The column number of the field
48
@param flen The length of the field
49
@return The key pressed to exit the field (KEY_ENTER, KEY_F(9), etc.)
50
*/
51
int
cf_accept
(WINDOW *win,
char
*accept_s,
int
flin,
int
fcol,
int
flen) {
52
bool
f_insert =
FALSE
;
53
int
in_key = 0;
54
char
*s, *d;
55
char
*fstart;
56
57
click_x
=
click_y
= -1;
58
char
*p = fstart = accept_s;
59
char
*fend = fstart + flen;
60
int
x = fcol;
61
char
*str_end = p + strlen(p);
62
while
(1) {
63
if
(in_key == 0) {
64
mvwaddstr(win, flin, fcol, accept_s);
65
wclrtoeol(win);
66
wmove(win, flin, x);
67
tcflush(0, TCIFLUSH);
68
in_key =
vgetch
(
win
,
0
)
;
69
}
70
curs_set(0);
71
switch
(in_key) {
72
case
KEY_F(9):
73
in_key = KEY_F(9);
74
return
(in_key);
75
case
'\t'
:
76
case
KEY_END:
77
case
Ctrl
(
'e'
):
78
while
(*p !=
'\0'
)
79
p++;
80
x = fcol + (p - fstart);
81
in_key = 0;
82
continue
;
83
/**< Enter accepts the field and moves to the next field if
84
* f_erase_remainder is set, it will clear the remaining
85
* characters above and after the current cursor location */
86
case
'\n'
:
87
case
KEY_ENTER:
88
if
(
f_erase_remainder
)
89
*p =
'\0'
;
90
in_key = KEY_ENTER;
91
return
(in_key);
92
/** KEY_IC toggles insert mode */
93
case
KEY_IC:
94
f_insert = !f_insert;
95
in_key = 0;
96
continue
;
97
/** KEY_DC deletes character at cursor */
98
case
KEY_DC:
99
s = p + 1;
100
d = p;
101
while
(*s !=
'\0'
)
102
*d++ = *s++;
103
*d =
'\0'
;
104
str_end = d;
105
f_insert =
FALSE
;
106
in_key = 0;
107
continue
;
108
/** KEY_HOME moves cursor to start of field */
109
case
KEY_HOME:
110
case
Ctrl
(
'a'
):
111
p = fstart;
112
x = fcol;
113
in_key = 0;
114
continue
;
115
/** KEY_BACKSPACE deletes character before cursor */
116
case
KEY_BACKSPACE:
117
if
(p > fstart) {
118
p--;
119
x--;
120
}
121
s = p + 1;
122
d = p;
123
while
(*s !=
'\0'
)
124
*d++ = *s++;
125
*d =
'\0'
;
126
str_end = d;
127
in_key = 0;
128
continue
;
129
/** KEY_LEFT moves cursor left one character */
130
case
KEY_LEFT:
131
if
(p > fstart) {
132
p--;
133
x--;
134
}
135
in_key = 0;
136
continue
;
137
/** KEY_RIGHT moves cursor right one character */
138
case
KEY_RIGHT:
139
if
(p < fend && p < str_end) {
140
p++;
141
x++;
142
}
143
in_key = 0;
144
continue
;
145
/** Handles mouse events for field editing */
146
case
KEY_MOUSE:
147
x =
click_x
;
148
flin =
click_y
;
149
fstart = accept_s;
150
fend = fstart + flen;
151
str_end = fstart + strlen(fstart);
152
p = fstart + (x - fcol);
153
if
(p > str_end)
154
x -= p - str_end;
155
p =
min
(p, str_end);
156
in_key = 0;
157
continue
;
158
default
:
159
if
(p >= fend) {
160
in_key = 0;
161
continue
;
162
}
163
if
(in_key <
' '
|| in_key >
'~'
) {
164
in_key = 0;
165
continue
;
166
}
167
if
(f_insert) {
168
if
(str_end < fend) {
169
s = str_end - 1;
170
d = str_end;
171
while
(s >= p)
172
*d-- = *s--;
173
*p++ = in_key;
174
str_end++;
175
x++;
176
}
177
}
else
{
178
if
(p < fend) {
179
if
(p < str_end) {
180
if
(p == accept_s && in_key ==
' '
) {
181
d = accept_s;
182
s = accept_s + 1;
183
while
(*s !=
'\0'
)
184
*d++ = *s++;
185
*d =
'\0'
;
186
in_key = 0;
187
continue
;
188
}
189
*p++ = in_key;
190
x++;
191
}
else
if
(p == str_end) {
192
*p++ = in_key;
193
*p =
'\0'
;
194
str_end = p;
195
x++;
196
}
197
}
198
}
199
in_key = 0;
200
continue
;
201
}
202
}
203
}
click_x
int click_x
Definition
dwin.c:81
click_y
int click_y
Definition
dwin.c:80
min
#define min(x, y)
min macro evaluates two expressions, returning least result
Definition
cm.h:89
Ctrl
#define Ctrl(c)
Definition
cm.h:52
FALSE
#define FALSE
Definition
iloan.c:18
cf_accept
int cf_accept(WINDOW *win, char *accept_s, int flin, int fcol, int flen)
Accepts input for a field in a C-Menu window.
Definition
cm_fields.c:51
f_erase_remainder
bool f_erase_remainder
Definition
cm_fields.c:39
vgetch
int vgetch(WINDOW *, int)
Wrapper for wgetch that handles signals and mouse events, and accepts a single character answer.
Definition
dwin.c:2258
cm_fields.c
Generated by
1.17.0