Как добавить тайм-аут во всплывающий диалог FLTK

Я использую библиотеку FLTK и использовал всплывающую функцию fl_input() от Fl_ask.h, Я хочу функцию, которая, если пользователь не вводит и данные в течение 3 секунд, функция должна вернуться. Как я могу вернуть эту функцию без нажатия OK или же cancel, Есть ли в любом случае, чтобы получить ручку для этого всплывающего диалога? Это код, который я использую

const char *message = "Enter name here";

Fl::lock();
char *c = (char*)fl_input(message, "");
if(c == NULL)
    c = "";
Fl::unlock();

1 ответ

Вы не можете сделать это легко, используя fl_input, потому что у окна нет дескриптора. Посмотрите на источник fl_input в src/fl_ask.cxx. Вы увидите, что он вызывает input_innards. Если вы перейдете к input_innards, вы увидите, что он вызывает innards. Если вы затем следуете внутренностям, вы найдете цикл while, который читает

while (message_form->shown()) Fl::wait();

Сделайте копию fl_ask.cxx, скажем, timed_ask.cxx. Сделайте все подпрограммы fl_ статическими. Измените fl_input следующим образом:

const char* timed_input(double timeout, const char *fmt, const char *defstr, ...) {

  if (avoidRecursion) return 0;

  va_list ap;
  va_start(ap, defstr);
  const char* r = timed_input_innards(timeout, fmt, ap, defstr, FL_NORMAL_INPUT);
  va_end(ap);
  return r;
}

Сделайте копию input_innards и переименуйте новую в timed_input_innards (это сделает другие fl_routines счастливыми, если вы не захотите их удалить).

static const char* timed_input_innards(double timeout, const char* fmt, va_list ap,
             const char* defstr, uchar type) {
...
int r = timed_innards(timeout, fmt, ap, fl_cancel, fl_ok, 0);
...

Сделайте копию innards и переименуйте новую в timed_innards

static int timed_innards(double timeout, const char* fmt, va_list ap,
  const char *b0,
  const char *b1,
  const char *b2)
{
    ...
    Fl::add_timeout(timeout, hide_form, message_form);
    while (message_form->shown()) Fl::wait();
    ...
}

Добавьте процедуру ожидания

void hide_form(void* data)
{
    // You could do this or use message_form directly
    Fl_Window* form = reinterpret_cast<Fl_Window*>(data);
    form->hide();
}

Это приведет к тому, что message_form->selected () будет ложным, и выйдет из цикла while.

Другие вопросы по тегам