2015-10-24 6 views
2

Я создал общую оболочку для объекта формы curses для использования с крупным проектом моделирования , над которым я работаю.Очистка буфера поля в ncurses

В принципе, я создаю экземпляр объекта generic_form, добавляю некоторые поля и их описания , а затем даю ему фокус и получаю пользовательский ввод с помощью процедуры fill_form().

Поскольку каждый объект generic_form может использоваться более одного раза, то есть, что fill_form() может вызываться более одного раза за экземпляр, мне нужно очистить буферы полей в начале процедуры fill_form(). В настоящее время я использую это в начале подпрограммы:

//clear the field buffers in case there's junk in them 
    for (std::vector<FIELD*>::iterator clear_iter = fields.begin(); 
      clear_iter != fields.end(); clear_iter++) 
    { 
     if (*clear_iter != nullptr) 
     { 
      set_field_buffer(*clear_iter, 0, " "); 
     } 
    } 

Однако, он бросает исключение с плавающей точкой на set_field_buffer линии на второй вызова подпрограммы fill_form(). Более того, строка set_field_buffer, по-видимому, ничего не делает, по крайней мере, не очищая буфер, поскольку без вызова free_field в конце подпрограммы и вместо этого в деструкторе объекта буферы полей остаются неизменными при каждом последующем вызове ,

Вот полнота (уродливой, в разработке) fill_form() рутины для краткости:

void generic_form::fill_form() 
{ 
    //fields.push_back(NULL); 
    if (fields.size() == 1) 
    { 
     fields.push_back(NULL); 
     form = new_form(static_cast<FIELD**>(fields.data())); 
     fields.erase((fields.end() - 1)); 
     assert(fields.size() == 1); 
    } 
    else 
    { 
     form = new_form(static_cast<FIELD**>(fields.data())); 
    } 
    WINDOW* form_win = derwin(screen, fields.size() + 1, largest_desc + 6, ypos, 
      xpos); 
    set_form_win(form, form_win); 
    set_form_sub(form, form_win); 
    //clear the field buffers in case there's junk in them 
    for (std::vector<FIELD*>::iterator clear_iter = fields.begin(); 
      clear_iter != fields.end(); clear_iter++) 
    { 
     if (*clear_iter != nullptr) 
     { 
      set_field_buffer(*clear_iter, 0, " "); 
     } 
    } 
    post_form(form); 
    for (int x = 0; x < descriptions.size(); x++) 
    { 
     mvwprintw(form_win, x, 0, descriptions.at(x).c_str()); 
    } 
    wmove(form_win, 0, largest_desc + 1); 
    touchwin(screen); 
    wrefresh(form_win); 
    /* Loop through to get user requests */ 
    int ch; 
    while((ch = getch()) != '\n')//KEY_F(1)) 
    { switch(ch) 
      {  
      case KEY_DOWN: 
        /* Go to next field */ 
        form_driver(form, REQ_NEXT_FIELD); 
        /* Go to the end of the present buffer */ 
        /* Leaves nicely at the last character */ 
        form_driver(form, REQ_END_LINE); 
        break; 
      case KEY_UP: 
        /* Go to previous field */ 
        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: 
        /* If this is a normal character, it gets */ 
        /* Printed    */  
        form_driver(form, ch); 
        break; 
      } 
    } 
    form_driver(form, REQ_VALIDATION); 
    for (int x = 0; x < fields.size() && first_run; x++) 
    { 
     //store the int_inputs from the forms 
     if ((fields.at(x) != nullptr) && (field_type(fields.at(x)) == 
       TYPE_INTEGER)) 
     { 
      int_inputs.push_back(std::atoi(field_buffer((fields.at(x)), 0))); 
     } 
     if ((fields.at(x) != nullptr) && (field_type(fields.at(x)) == 
       TYPE_ALPHA)) 
     { 
      str_inputs.push_back(field_buffer((fields.at(x)), 0)); 
     } 
    } 
    first_run = false; 
    /* Un post form and free the memory */ 
    unpost_form(form); 
    free_form(form); 
    for (int x = 0; x < fields.size(); x++) 
    { 
     free_field(fields.at(x)); 
    } 
    delwin(form_win); 
} 

Длинной короткая история/TLDR: Как я очистить или сбросить буфер поля в Ncurses, без удаления и повторного добавления?

ответ

1

Вы можете очистить буфер поля с помощью form_driver()

Отрывок man form_driver

REQ_CLR_EOL 
    Clear to end of line from cursor. 

REQ_CLR_EOF 
    Clear to end of field from cursor. 

REQ_CLR_FIELD 
    Clear the entire field. 

Для разработки этого немного больше :-), я использую код, похожий на следующий за клиринговые полей:

#include <stdio.h> 
#include <stdlib.h> 
#include <form.h> 

enum f_name_l 
{ 
    f_name, f_surname, f_last 
}; 

int main (void) 
{ 
    int ch = 0, i = 0; 
    FIELD *field[3], *save_field; 
    FORM *my_form; 

    initscr(); 
    start_color(); 
    noecho(); 
    raw(); 
    keypad (stdscr, TRUE); 
    refresh(); 

    field[f_name] = new_field (1, 10, 0, 25, 0, 0); 
    field[f_surname] = new_field (1, 10, 2, 25, 0, 0); 
    field[f_last] = NULL; 

    set_field_back (field[f_name], A_UNDERLINE); 
    set_field_back (field[f_surname], A_UNDERLINE); 

    my_form = new_form (field); 
    post_form (my_form); 

    // Form labels 
    mvprintw (0, 1, "Name: "); 
    mvprintw (2, 1, "Surname: "); 
    mvprintw (4, 1, "F5 to clear active field. F6 to clear form."); 

    pos_form_cursor (my_form); 

    refresh(); 

    // ^q to exit 
    while ((ch = getch()) != 17) 
    { 
    switch (ch) 
    { 
     case KEY_UP: 
     form_driver (my_form, REQ_PREV_FIELD); 
     break; 
     case KEY_DOWN: 
     form_driver (my_form, REQ_NEXT_FIELD); 
     break; 
     case KEY_F(5): 
     form_driver (my_form, REQ_CLR_FIELD); 
     break; 
     case KEY_F(6): 
     save_field = current_field (my_form); 

     for (i = 0; i < f_last; i++) 
     { 
      set_current_field (my_form, field[i]); 
      form_driver (my_form, REQ_CLR_FIELD); 
     } 

     set_current_field (my_form, save_field); 
     break; 
     default: 
     form_driver (my_form, ch); 
     break; 
    } 

    form_driver (my_form, REQ_VALIDATION); 
    } 

    endwin(); 

    return EXIT_SUCCESS; 
} 

Но смотря сообщение от Thomas Dickey Я начинаю чувствовать, что моя жизнь - это ложь :-).

+0

Можете ли вы подробнее объяснить ответ? :-) –

+0

Те очищают связанное окно, но не очищают буфер поля. –