Created
July 29, 2014 10:05
-
-
Save alan-mushi/c8a6f34d1df18574f643 to your computer and use it in GitHub Desktop.
Simple ncurses form example with fields that actually behaves like fields
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Simple ncurses form example with fields that actually behaves like fields. | |
* | |
* How to run: | |
* gcc -Wall -Werror -g -pedantic -o test fields_magic.c -lform -lncurses | |
*/ | |
#include <ncurses/ncurses.h> | |
#include <ncurses/form.h> | |
#include <assert.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <ctype.h> | |
static FORM *form; | |
static FIELD *fields[5]; | |
static WINDOW *win_body, *win_form; | |
/* | |
* This is useful because ncurses fill fields blanks with spaces. | |
*/ | |
static char* trim_whitespaces(char *str) | |
{ | |
char *end; | |
// trim leading space | |
while(isspace(*str)) | |
str++; | |
if(*str == 0) // all spaces? | |
return str; | |
// trim trailing space | |
end = str + strnlen(str, 128) - 1; | |
while(end > str && isspace(*end)) | |
end--; | |
// write new null terminator | |
*(end+1) = '\0'; | |
return str; | |
} | |
static void driver(int ch) | |
{ | |
int i; | |
switch (ch) { | |
case KEY_F(2): | |
// Or the current field buffer won't be sync with what is displayed | |
form_driver(form, REQ_NEXT_FIELD); | |
form_driver(form, REQ_PREV_FIELD); | |
move(LINES-3, 2); | |
for (i = 0; fields[i]; i++) { | |
printw("%s", trim_whitespaces(field_buffer(fields[i], 0))); | |
if (field_opts(fields[i]) & O_ACTIVE) | |
printw("\"\t"); | |
else | |
printw(": \""); | |
} | |
refresh(); | |
pos_form_cursor(form); | |
break; | |
case KEY_DOWN: | |
form_driver(form, REQ_NEXT_FIELD); | |
form_driver(form, REQ_END_LINE); | |
break; | |
case KEY_UP: | |
form_driver(form, REQ_PREV_FIELD); | |
form_driver(form, REQ_END_LINE); | |
break; | |
case KEY_LEFT: | |
form_driver(form, REQ_PREV_CHAR); | |
break; | |
case KEY_RIGHT: | |
form_driver(form, REQ_NEXT_CHAR); | |
break; | |
// Delete the char before cursor | |
case KEY_BACKSPACE: | |
case 127: | |
form_driver(form, REQ_DEL_PREV); | |
break; | |
// Delete the char under the cursor | |
case KEY_DC: | |
form_driver(form, REQ_DEL_CHAR); | |
break; | |
default: | |
form_driver(form, ch); | |
break; | |
} | |
wrefresh(win_form); | |
} | |
int main() | |
{ | |
int ch; | |
initscr(); | |
noecho(); | |
cbreak(); | |
keypad(stdscr, TRUE); | |
win_body = newwin(24, 80, 0, 0); | |
assert(win_body != NULL); | |
box(win_body, 0, 0); | |
win_form = derwin(win_body, 20, 78, 3, 1); | |
assert(win_form != NULL); | |
box(win_form, 0, 0); | |
mvwprintw(win_body, 1, 2, "Press F1 to quit and F2 to print fields content"); | |
fields[0] = new_field(1, 10, 0, 0, 0, 0); | |
fields[1] = new_field(1, 40, 0, 15, 0, 0); | |
fields[2] = new_field(1, 10, 2, 0, 0, 0); | |
fields[3] = new_field(1, 40, 2, 15, 0, 0); | |
fields[4] = NULL; | |
assert(fields[0] != NULL && fields[1] != NULL && fields[2] != NULL && fields[3] != NULL); | |
set_field_buffer(fields[0], 0, "label1"); | |
set_field_buffer(fields[1], 0, "val1"); | |
set_field_buffer(fields[2], 0, "label2"); | |
set_field_buffer(fields[3], 0, "val2"); | |
set_field_opts(fields[0], O_VISIBLE | O_PUBLIC | O_AUTOSKIP); | |
set_field_opts(fields[1], O_VISIBLE | O_PUBLIC | O_EDIT | O_ACTIVE); | |
set_field_opts(fields[2], O_VISIBLE | O_PUBLIC | O_AUTOSKIP); | |
set_field_opts(fields[3], O_VISIBLE | O_PUBLIC | O_EDIT | O_ACTIVE); | |
set_field_back(fields[1], A_UNDERLINE); | |
set_field_back(fields[3], A_UNDERLINE); | |
form = new_form(fields); | |
assert(form != NULL); | |
set_form_win(form, win_form); | |
set_form_sub(form, derwin(win_form, 18, 76, 1, 1)); | |
post_form(form); | |
refresh(); | |
wrefresh(win_body); | |
wrefresh(win_form); | |
while ((ch = getch()) != KEY_F(1)) | |
driver(ch); | |
unpost_form(form); | |
free_form(form); | |
free_field(fields[0]); | |
free_field(fields[1]); | |
free_field(fields[2]); | |
free_field(fields[3]); | |
delwin(win_form); | |
delwin(win_body); | |
endwin(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
If you need help with designing the front end of your form (in particular coordinates) then you can try our form designer utility. It is not fully featured but it can save a lot of time putting in wrong coordinates, building, moving things around, rebuilding etc. ssh [email protected] password is "nc". If you want to know how to use it then head over to https://level2.support?_req=form_designer.
It only does the basics though because the rest need our library (which currently needs to much work to release into the wild and has a bucket load of dependencies).