Skip to content

Instantly share code, notes, and snippets.

@alan-mushi
Created July 29, 2014 10:05
Show Gist options
  • Save alan-mushi/c8a6f34d1df18574f643 to your computer and use it in GitHub Desktop.
Save alan-mushi/c8a6f34d1df18574f643 to your computer and use it in GitHub Desktop.
Simple ncurses form example with fields that actually behaves like fields
/*
* 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;
}
@SapuSeven
Copy link

You could add the following lines to the driver function to support POS1 and END:

case KEY_HOME:
	form_driver(form, REQ_BEG_LINE);
	break;
case KEY_END:
	form_driver(form, REQ_END_LINE);
	break;

@sunbqto
Copy link

sunbqto commented Sep 2, 2021

I need help. How i can to store field[5] value to char array[5][],

@klee3
Copy link

klee3 commented Jan 19, 2023

How can we delete the subwindow which is created on line 145 using derwin function?

@Timh1970
Copy link

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 nsdesign@inplico.uk 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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment