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 (UIKEY_ENTER, UIKEY_F09, etc.)
40
*/
41
int
cf_accept
(UiSurface *sfc, ss_t 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
,
w
,
NULL
,
&event
,
-1
)
;
60
}
61
ui_curs_set
(
0
)
;
62
switch
(in_key) {
63
case
UIKEY_F09
:
64
in_key =
UIKEY_F09
;
65
return
(in_key);
66
case
'\t'
:
67
case
UIKEY_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
UIKEY_ENTER
:
79
if
(
f_erase_remainder
)
80
*p =
'\0'
;
81
in_key =
UIKEY_ENTER
;
82
return
(in_key);
83
/** UIKEY_IC toggles insert mode */
84
case
UIKEY_IC
:
85
f_insert = !f_insert;
86
in_key = 0;
87
continue
;
88
/** UIKEY_DC deletes character at cursor */
89
case
UIKEY_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
/** UIKEY_HOME moves cursor to start of field */
100
case
UIKEY_HOME
:
101
case
Ctrl
(
'a'
):
102
p = fstart;
103
x = fcol;
104
in_key = 0;
105
continue
;
106
/** UIKEY_BACKSPACE deletes character before cursor */
107
case
UIKEY_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
/** UIKEY_LEFT moves cursor left one character */
121
case
UIKEY_LEFT
:
122
if
(p > fstart) {
123
p--;
124
x--;
125
}
126
in_key = 0;
127
continue
;
128
/** UIKEY_RIGHT moves cursor right one character */
129
case
UIKEY_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
UIKEY_BUTTON1
:
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:104
Ctrl
#define Ctrl(c)
Definition
cm.h:67
ui_render
void ui_render()
Render the UI by updating panels and refreshing the display.
Definition
ui_ncurses.c:884
ui_cursor_move
int ui_cursor_move(UiSurface *s, ss_t w, uint y, uint x)
Move the cursor to a specified position within a UiSurface.
Definition
ui_ncurses.c:666
click_x
int click_x
Definition
ui_common.c:30
ui_curs_set
int ui_curs_set(int visibility)
Set the visibility of the cursor.
Definition
ui_ncurses.c:840
click_y
int click_y
Definition
ui_common.c:29
ui_wclrtoeol
int ui_wclrtoeol(UiSurface *s, ss_t w)
Clear to the end of the line in a surface window.
Definition
ui_ncurses_draw.c:38
UIKEY_DC
#define UIKEY_DC
Definition
ui_ncurses_internal.h:30
UIKEY_BACKSPACE
#define UIKEY_BACKSPACE
Definition
ui_ncurses_internal.h:31
UIKEY_LEFT
#define UIKEY_LEFT
Definition
ui_ncurses_internal.h:28
UIKEY_F09
#define UIKEY_F09
Definition
ui_ncurses_internal.h:44
UIKEY_IC
#define UIKEY_IC
Definition
ui_ncurses_internal.h:29
UIKEY_END
#define UIKEY_END
Definition
ui_ncurses_internal.h:35
UIKEY_BUTTON1
#define UIKEY_BUTTON1
Definition
ui_ncurses_internal.h:118
UIKEY_RIGHT
#define UIKEY_RIGHT
Definition
ui_ncurses_internal.h:26
UIKEY_HOME
#define UIKEY_HOME
Definition
ui_ncurses_internal.h:34
UIKEY_ENTER
#define UIKEY_ENTER
Definition
ui_ncurses_internal.h:48
ui_get_event
int ui_get_event(UiSurface *s, ss_t w, UiChyron *chyron, UiEvent *ev, int timeout_ms)
Read input events.
Definition
ui_ncurses_input.c:116
ui_mvwaddstr
int ui_mvwaddstr(UiSurface *s, ss_t w, uint y, uint x, const char *text)
Draw a text string at a specific position in a surface window.
Definition
ui_ncurses_draw.c:174
cf_accept
int cf_accept(UiSurface *sfc, ss_t 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
cm_fields.c
Generated by
1.17.0