field.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /*https://gist.github.com/alan-mushi/c8a6f34d1df18574f643
  2. * Simple ncurses form example with fields that actually behaves like fields.
  3. *
  4. * How to run:
  5. * gcc -Wall -Werror -g -pedantic -o test fields_magic.c -lform -lncurses
  6. */
  7. #include "ncurses-interface.h"
  8. #include <assert.h>
  9. #include <ctype.h>
  10. #include <form.h>
  11. #include <ncurses.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. extern OptionBox options;
  15. static bool selected = false;
  16. static FORM *form;
  17. static FIELD *fields[5];
  18. static WINDOW *win_body, *win_form;
  19. /*
  20. * This is useful because ncurses fill fields blanks with spaces.
  21. */
  22. static char *trim_whitespaces(char *str) {
  23. char *end;
  24. // trim leading space
  25. while (isspace(*str))
  26. str++;
  27. if (*str == 0) // all spaces?
  28. return str;
  29. // trim trailing space
  30. end = str + strnlen(str, 128) - 1;
  31. while (end > str && isspace(*end))
  32. end--;
  33. // write new null terminator
  34. *(end + 1) = '\0';
  35. return str;
  36. }
  37. static void driver(int ch) {
  38. int i;
  39. const char *searchtext;
  40. switch (ch) {
  41. case 10: /*enter*/
  42. // Or the current field buffer won't be sync with what is displayed
  43. form_driver(form, REQ_NEXT_FIELD);
  44. form_driver(form, REQ_PREV_FIELD);
  45. move(LINES - 3, 2);
  46. for (i = 0; fields[i]; i++) {
  47. printw("%s", trim_whitespaces(field_buffer(fields[i], 0)));
  48. if (field_opts(fields[i]) & O_ACTIVE)
  49. printw("\"\t");
  50. else
  51. printw(": \"");
  52. }
  53. refresh();
  54. pos_form_cursor(form);
  55. searchtext = field_buffer(fields[1], 0);
  56. memcpy(options.searchtext, searchtext, strlen(searchtext));
  57. options.countOfThreads = atoi(field_buffer(fields[1], 0));
  58. selected = true;
  59. // printf("Count of threads: %d;
  60. // searchtext:%s\n",options.countOfThreads,options.searchtext);
  61. break;
  62. case KEY_DOWN:
  63. form_driver(form, REQ_NEXT_FIELD);
  64. form_driver(form, REQ_END_LINE);
  65. break;
  66. case KEY_UP:
  67. form_driver(form, REQ_PREV_FIELD);
  68. form_driver(form, REQ_END_LINE);
  69. break;
  70. case KEY_LEFT:
  71. form_driver(form, REQ_PREV_CHAR);
  72. break;
  73. case KEY_RIGHT:
  74. form_driver(form, REQ_NEXT_CHAR);
  75. break;
  76. // Delete the char before cursor
  77. case KEY_BACKSPACE:
  78. case 127:
  79. form_driver(form, REQ_DEL_PREV);
  80. break;
  81. // Delete the char under the cursor
  82. case KEY_DC:
  83. form_driver(form, REQ_DEL_CHAR);
  84. break;
  85. default:
  86. form_driver(form, ch);
  87. break;
  88. }
  89. wrefresh(win_form);
  90. }
  91. int start_field() {
  92. int ch;
  93. initscr();
  94. noecho();
  95. cbreak();
  96. keypad(stdscr, TRUE);
  97. win_body = newwin(24, 80, 0, 0);
  98. assert(win_body != NULL);
  99. box(win_body, 0, 0);
  100. win_form = derwin(win_body, 20, 78, 3, 1);
  101. assert(win_form != NULL);
  102. box(win_form, 0, 0);
  103. mvwprintw(win_body, 1, 2,
  104. "Press F1 to quit and ENTER to start(three times, of control+C to "
  105. "abort)");
  106. fields[0] = new_field(1, 10, 0, 0, 0, 0);
  107. fields[1] = new_field(1, 40, 0, 15, 0, 0);
  108. fields[2] = new_field(1, 10, 2, 0, 0, 0);
  109. fields[3] = new_field(1, 40, 2, 15, 0, 0);
  110. fields[4] = NULL;
  111. assert(fields[0] != NULL && fields[1] != NULL && fields[2] != NULL &&
  112. fields[3] != NULL);
  113. set_field_buffer(fields[0], 0, "SearchText");
  114. set_field_buffer(fields[1], 0, "200");
  115. set_field_buffer(fields[2], 0, "Count of threads");
  116. set_field_buffer(fields[3], 0, "3");
  117. set_field_opts(fields[0], O_VISIBLE | O_PUBLIC | O_AUTOSKIP);
  118. set_field_opts(fields[1], O_VISIBLE | O_PUBLIC | O_EDIT | O_ACTIVE);
  119. set_field_opts(fields[2], O_VISIBLE | O_PUBLIC | O_AUTOSKIP);
  120. set_field_opts(fields[3], O_VISIBLE | O_PUBLIC | O_EDIT | O_ACTIVE);
  121. set_field_back(fields[1], A_UNDERLINE);
  122. set_field_back(fields[3], A_UNDERLINE);
  123. form = new_form(fields);
  124. assert(form != NULL);
  125. set_form_win(form, win_form);
  126. set_form_sub(form, derwin(win_form, 18, 76, 1, 1));
  127. post_form(form);
  128. refresh();
  129. wrefresh(win_body);
  130. wrefresh(win_form);
  131. while ((ch = getch()) != KEY_F(1) && !selected)
  132. driver(ch);
  133. unpost_form(form);
  134. free_form(form);
  135. free_field(fields[0]);
  136. free_field(fields[1]);
  137. free_field(fields[2]);
  138. free_field(fields[3]);
  139. delwin(win_form);
  140. delwin(win_body);
  141. endwin();
  142. return 0;
  143. }