~rabbits/orca

f85ebfc1bfe3e2a42d0530a57d62d79bf6b55046 — cancel 2 years ago 84d3819
Factor out repeated Qform single line input code

Qform (the popup text entry thing) is currently only used as a single
modal text input, but the TUI code still went through the motions of
setting each one up as if it could have a variety of things inside of
it. This commit saves on repeated code by providing a wrapper that does
the thing we want, but still leaves the door open in the future for
having other types of inputs in the form.

It also renames a few Qform functions for consistency.
3 files changed, 54 insertions(+), 75 deletions(-)

M term_util.c
M term_util.h
M tui_main.c
M term_util.c => term_util.c +33 -27
@@ 59,8 59,8 @@ struct Qform {
  int id;
};

void qmenu_free(Qmenu *qm);
void qform_free(Qform *qf);
static void qmenu_free(Qmenu *qm);
static void qform_free(Qform *qf);
ORCA_NOINLINE static void qmenu_reprint(Qmenu *qm);

Qnav_stack qnav_stack;


@@ 470,7 470,7 @@ void qmenu_push_to_nav(Qmenu *qm) {
  qnav_stack_push(&qm->qblock, menu_min_h, menu_min_w);
}

void qmenu_free(Qmenu *qm) {
static void qmenu_free(Qmenu *qm) {
  Qmenu_item *items = qm->items;
  for (Usz i = 0, n = qm->items_count; i < n; ++i) {
    if (items[i].owns_string)


@@ 553,12 553,21 @@ Qform *qform_create(int id) {
  qf->id = id;
  return qf;
}

Qform *qform_of(Qblock *qb) { return ORCA_CONTAINER_OF(qb, Qform, qblock); }

static void qform_free(Qform *qf) {
  curs_set(0);
  unpost_form(qf->ncurses_form);
  free_form(qf->ncurses_form);
  for (Usz i = 0; i < qf->fields_count; ++i) {
    free_field(qf->ncurses_fields[i]);
  }
  free(qf);
}
int qform_id(Qform const *qf) { return qf->id; }

void qform_add_text_line(Qform *qf, int id, char const *initial) {
Qform *qform_of(Qblock *qb) { return ORCA_CONTAINER_OF(qb, Qform, qblock); }
void qform_set_title(Qform *qf, char const *title) {
  qblock_set_title(&qf->qblock, title);
}
void qform_add_line_input(Qform *qf, int id, char const *initial) {
  FIELD *f = new_field(1, 30, 0, 0, 0, 0);
  if (initial)
    set_field_buffer(f, 0, initial);


@@ 568,7 577,6 @@ void qform_add_text_line(Qform *qf, int id, char const *initial) {
  ++qf->fields_count;
  qf->ncurses_fields[qf->fields_count] = NULL;
}

void qform_push_to_nav(Qform *qf) {
  qf->ncurses_form = new_form(qf->ncurses_fields);
  int form_min_h, form_min_w;


@@ 581,21 589,12 @@ void qform_push_to_nav(Qform *qf) {
  curs_set(1);
  form_driver(qf->ncurses_form, REQ_END_LINE);
}

void qform_set_title(Qform *qf, char const *title) {
  qblock_set_title(&qf->qblock, title);
}

void qform_free(Qform *qf) {
  curs_set(0);
  unpost_form(qf->ncurses_form);
  free_form(qf->ncurses_form);
  for (Usz i = 0; i < qf->fields_count; ++i) {
    free_field(qf->ncurses_fields[i]);
  }
  free(qf);
void qform_single_line_input(int id, char const *title, char const *initial) {
  Qform *qf = qform_create(id);
  qform_set_title(qf, title);
  qform_add_line_input(qf, 1, initial);
  qform_push_to_nav(qf);
}

bool qform_drive(Qform *qf, int key, Qform_action *out_action) {
  switch (key) {
  case 27:


@@ 635,7 634,6 @@ bool qform_drive(Qform *qf, int key, Qform_action *out_action) {
  form_driver(qf->ncurses_form, key);
  return false;
}

static Usz size_without_trailing_spaces(char const *str) {
  Usz size = strlen(str);
  for (;;) {


@@ 647,8 645,7 @@ static Usz size_without_trailing_spaces(char const *str) {
  }
  return size;
}

FIELD *qform_find_field(Qform const *qf, int id) {
static FIELD *qform_find_field(Qform const *qf, int id) {
  Usz count = qf->fields_count;
  for (Usz i = 0; i < count; ++i) {
    FIELD *f = qf->ncurses_fields[i];


@@ 657,7 654,6 @@ FIELD *qform_find_field(Qform const *qf, int id) {
  }
  return NULL;
}

bool qform_get_text_line(Qform const *qf, int id, oso **out) {
  FIELD *f = qform_find_field(qf, id);
  if (!f)


@@ 670,3 666,13 @@ bool qform_get_text_line(Qform const *qf, int id, oso **out) {
  osoputlen(out, buf, trimmed);
  return true;
}
bool qform_get_single_text_line(Qform const *qf, struct oso **out) {
  return qform_get_text_line(qf, 1, out);
}
oso *qform_get_nonempty_single_line_input(Qform *qf) {
  oso *s = NULL;
  if (qform_get_text_line(qf, 1, &s) && osolen(s) > 0)
    return s;
  osofree(s);
  return NULL;
}

M term_util.h => term_util.h +5 -2
@@ 154,11 154,14 @@ bool qmenu_top_is_menu(int id);
Qform *qform_create(int id);
int qform_id(Qform const *qf);
Qform *qform_of(Qblock *qb);
void qform_add_text_line(Qform *qf, int id, char const *initial);
void qform_push_to_nav(Qform *qf);
void qform_set_title(Qform *qf, char const *title);
void qform_add_line_input(Qform *qf, int id, char const *initial);
void qform_push_to_nav(Qform *qf);
void qform_single_line_input(int id, char const *title, char const* initial);
bool qform_drive(Qform *qf, int key, Qform_action *out_action);
bool qform_get_text_line(Qform const *qf, int id, struct oso **out);
bool qform_get_single_text_line(Qform const *qf, struct oso **out);
struct oso *qform_get_nonempty_single_line_input(Qform *qf);

extern Qnav_stack qnav_stack;


M tui_main.c => tui_main.c +16 -46
@@ 1989,9 1989,6 @@ enum {
#endif
};
enum {
  Single_form_item_id = 1,
};
enum {
  Autofit_nicely_id = 1,
  Autofit_tightly_id,
};


@@ 2084,13 2081,10 @@ static void push_cosmetics_menu(void) {
  qmenu_push_to_nav(qm);
}
static void push_soft_margins_form(int init_y, int init_x) {
  Qform *qf = qform_create(Set_soft_margins_form_id);
  char buff[128];
  int snres = snprintf(buff, sizeof buff, "%dx%d", init_x, init_y);
  char const *inistr = snres > 0 && (Usz)snres < sizeof buff ? buff : "2x1";
  qform_set_title(qf, "Set Margins");
  qform_add_text_line(qf, Single_form_item_id, inistr);
  qform_push_to_nav(qf);
  qform_single_line_input(Set_soft_margins_form_id, "Set Margins", inistr);
}
static void push_plainorfancy_menu(int menu_id, char const *title,
                                   bool initial_fancy) {


@@ 2117,16 2111,12 @@ static void push_osc_menu(bool output_enabled) {
  qmenu_push_to_nav(qm);
}
static void push_osc_output_address_form(char const *initial) {
  Qform *qf = qform_create(Osc_output_address_form_id);
  qform_set_title(qf, "Set OSC Output Address");
  qform_add_text_line(qf, Single_form_item_id, initial);
  qform_push_to_nav(qf);
  qform_single_line_input(Osc_output_address_form_id, "Set OSC Output Address",
                          initial);
}
static void push_osc_output_port_form(char const *initial) {
  Qform *qf = qform_create(Osc_output_port_form_id);
  qform_set_title(qf, "Set OSC Output Port");
  qform_add_text_line(qf, Single_form_item_id, initial);
  qform_push_to_nav(qf);
  qform_single_line_input(Osc_output_port_form_id, "Set OSC Output Port",
                          initial);
}
enum {
  Playback_menu_midi_bclock = 1,


@@ 2308,10 2298,7 @@ static void push_opers_guide_msg(void) {
  }
}
static void push_open_form(char const *initial) {
  Qform *qf = qform_create(Open_form_id);
  qform_set_title(qf, "Open");
  qform_add_text_line(qf, Single_form_item_id, initial);
  qform_push_to_nav(qf);
  qform_single_line_input(Open_form_id, "Open", initial);
}
staticni bool try_save_with_msg(Field *field, oso const *str) {
  if (!osolen(str))


@@ 2327,28 2314,19 @@ staticni bool try_save_with_msg(Field *field, oso const *str) {
  return ok;
}
static void push_save_as_form(char const *initial) {
  Qform *qf = qform_create(Save_as_form_id);
  qform_set_title(qf, "Save As");
  qform_add_text_line(qf, Single_form_item_id, initial);
  qform_push_to_nav(qf);
  qform_single_line_input(Save_as_form_id, "Save As", initial);
}
static void push_set_tempo_form(Usz initial) {
  Qform *qf = qform_create(Set_tempo_form_id);
  char buff[64];
  int snres = snprintf(buff, sizeof buff, "%zu", initial);
  char const *inistr = snres > 0 && (Usz)snres < sizeof buff ? buff : "120";
  qform_set_title(qf, "Set BPM");
  qform_add_text_line(qf, Single_form_item_id, inistr);
  qform_push_to_nav(qf);
  qform_single_line_input(Set_tempo_form_id, "Set BPM", inistr);
}
static void push_set_grid_dims_form(Usz init_height, Usz init_width) {
  Qform *qf = qform_create(Set_grid_dims_form_id);
  char buff[128];
  int snres = snprintf(buff, sizeof buff, "%zux%zu", init_width, init_height);
  char const *inistr = snres > 0 && (Usz)snres < sizeof buff ? buff : "57x25";
  qform_set_title(qf, "Set Grid Size");
  qform_add_text_line(qf, Single_form_item_id, inistr);
  qform_push_to_nav(qf);
  qform_single_line_input(Set_grid_dims_form_id, "Set Grid Size", inistr);
}

#ifdef FEAT_PORTMIDI


@@ 2393,14 2371,6 @@ staticni void push_portmidi_output_device_menu(Midi_mode const *midi_mode) {
}
#endif

staticni oso *get_nonempty_singular_form_text(Qform *qf) {
  oso *s = NULL;
  if (qform_get_text_line(qf, Single_form_item_id, &s) && osolen(s) > 0)
    return s;
  osofree(s);
  return NULL;
}

staticni bool read_int(char const *str, int *out) {
  int a;
  int res = sscanf(str, "%d", &a);


@@ 3123,7 3093,7 @@ staticni Tui_menus_result tui_drive_menus(Tui *t, int key) {
      case Qform_action_type_submitted: {
        switch (qform_id(qf)) {
        case Open_form_id: {
          oso *temp_name = get_nonempty_singular_form_text(qf);
          oso *temp_name = qform_get_nonempty_single_line_input(qf);
          if (!temp_name)
            break;
          expand_home_tilde(&temp_name);


@@ 3156,7 3126,7 @@ staticni Tui_menus_result tui_drive_menus(Tui *t, int key) {
          break;
        }
        case Save_as_form_id: {
          oso *temp_name = get_nonempty_singular_form_text(qf);
          oso *temp_name = qform_get_nonempty_single_line_input(qf);
          if (!temp_name)
            break;
          qnav_stack_pop();


@@ 3167,7 3137,7 @@ staticni Tui_menus_result tui_drive_menus(Tui *t, int key) {
          break;
        }
        case Set_tempo_form_id: {
          oso *tmpstr = get_nonempty_singular_form_text(qf);
          oso *tmpstr = qform_get_nonempty_single_line_input(qf);
          if (!tmpstr)
            break;
          int newbpm = atoi(osoc(tmpstr));


@@ 3181,7 3151,7 @@ staticni Tui_menus_result tui_drive_menus(Tui *t, int key) {
        case Osc_output_address_form_id: {
          oso *addr = NULL;
          // Empty string is OK here
          if (qform_get_text_line(qf, Single_form_item_id, &addr)) {
          if (qform_get_single_text_line(qf, &addr)) {
            if (osolen(addr))
              ososwap(&t->osc_address, &addr);
            else


@@ 3195,7 3165,7 @@ staticni Tui_menus_result tui_drive_menus(Tui *t, int key) {
          break;
        }
        case Osc_output_port_form_id: {
          oso *portstr = get_nonempty_singular_form_text(qf);
          oso *portstr = qform_get_nonempty_single_line_input(qf);
          if (!portstr)
            break;
          qnav_stack_pop();


@@ 3207,7 3177,7 @@ staticni Tui_menus_result tui_drive_menus(Tui *t, int key) {
          break;
        }
        case Set_grid_dims_form_id: {
          oso *tmpstr = get_nonempty_singular_form_text(qf);
          oso *tmpstr = qform_get_nonempty_single_line_input(qf);
          if (!tmpstr)
            break;
          int newheight, newwidth;


@@ 3231,7 3201,7 @@ staticni Tui_menus_result tui_drive_menus(Tui *t, int key) {
          break;
        }
        case Set_soft_margins_form_id: {
          oso *tmpstr = get_nonempty_singular_form_text(qf);
          oso *tmpstr = qform_get_nonempty_single_line_input(qf);
          if (!tmpstr)
            break;
          bool do_save = false;