#define NUMBER_WIDTH (10)
#define DATE_WIDTH (4+1+2+1+2 +1+ 2+1+2)
+/* Widget accessors */
+#define FF_TEXT(f) (((form_text_t *)f)->text)
+#define FF_DATE(f) (((form_date_t *)f)->date)
+#define FF_NUMBER(f) (((form_number_t*)f)->number)
+#define FF_BUTTON(f) (((form_button_t*)f)->button)
+#define FF_LIST(f) (((form_list_t *)f))
+
/* Local variables */
static WINDOW *form_win;
static int form_row;
// Calculate list width
int list_size = 0;
if (field->type == FORM_LIST) {
- for (int i = 0; i < field->list.num; i++) {
- int width = strlen(field->list.map[i]);
+ for (int i = 0; i < FF_LIST(field)->num; i++) {
+ int width = strlen(FF_LIST(field)->map[i]);
if (width > list_size)
list_size = width;
}
void field_draw(WINDOW *win, form_field_t *field, int width, int hover)
{
- char **map = field->list.map;
- int idx = field->list.idx;
+ char **map = FF_LIST(field)->map;
+ int idx = FF_LIST(field)->idx;
char *before = field->before ?: "";
char *after = field->after ?: "";
break;
case FORM_TEXT:
wprintw(win, "%-.*s",
- maxstr, field->text);
+ maxstr, FF_TEXT(field));
break;
case FORM_DATE:
- if (no_date(&field->date))
+ if (no_date(&FF_DATE(field)))
wprintw(win, "%s", "undefined");
else
wprintw(win, "%04d-%02d-%02d %02d:%02d",
- field->date.year, field->date.month+1,
- field->date.day+1, field->date.hour,
- field->date.min);
+ FF_DATE(field).year, FF_DATE(field).month+1,
+ FF_DATE(field).day+1, FF_DATE(field).hour,
+ FF_DATE(field).min);
break;
case FORM_NUMBER:
- wprintw(win, "%d", field->number);
+ wprintw(win, "%d", FF_NUMBER(field));
break;
case FORM_BUTTON:
wprintw(win, "%s", field->label);
}
/* Test functions */
-static form_field_t title = TEXT('t');
-static form_field_t location = TEXT('o');
-static form_field_t start = DATE('s');
-static form_field_t end = DATE('e');
-static form_field_t due_date = DATE('u');
-static form_field_t completed = NUMBER('p', .after="%");
-static form_field_t calendar = LIST('c');
-static form_field_t category = LIST('g');
-static form_field_t repeat = LIST('r');
-static form_field_t frequency = NUMBER(0);
-static form_field_t weekdays = BUTTONS("Su Mo Tu We Th Fr Sa");
-static form_field_t details = TEXT('d');
+static form_text_t title = TEXT('t');
+static form_text_t location = TEXT('o');
+static form_date_t start = DATE('s');
+static form_date_t end = DATE('e');
+static form_date_t due_date = DATE('u');
+static form_number_t completed = NUMBER('p', .f.after="%");
+static form_list_t calendar = LIST('c');
+static form_list_t category = LIST('g');
+static form_list_t repeat = LIST('r');
+static form_number_t frequency = NUMBER(0);
+static form_button_t weekdays = BUTTONS("Su Mo Tu We Th Fr Sa");
+static form_text_t details = TEXT('d');
static form_t edit = { 12, 4, {
- { LABEL("_Title: "), &title },
- { LABEL("L_ocation: "), &location },
- { },
- { LABEL("_Start: "), &start, LABEL(" _End: "), &end },
- { LABEL("D_ue Date: "), &due_date, LABEL(" Com_pleted: "), &completed },
- { LABEL("_Calendar: "), &calendar, LABEL(" Cate_gory: "), &category },
- { },
- { LABEL("_Repeat: "), &repeat, LABEL(" Every: "), &frequency },
- { },
- { NULL, &weekdays },
- { },
- { LABEL("_Details: "), &details },
+ { LABEL("_Title: "), &title.f },
+ { LABEL("L_ocation: "), &location.f },
+ { },
+ { LABEL("_Start: "), &start.f, LABEL(" _End: "), &end.f },
+ { LABEL("D_ue Date: "), &due_date.f, LABEL(" Com_pleted: "), &completed.f },
+ { LABEL("_Calendar: "), &calendar.f, LABEL(" Cate_gory: "), &category.f },
+ { },
+ { LABEL("_Repeat: "), &repeat.f, LABEL(" Every: "), &frequency.f },
+ { },
+ { NULL, &weekdays.f },
+ { },
+ { LABEL("_Details: "), &details.f },
} };
void form_test(void)
*/
/* Widget Macros */
-#define TEXT(k,...) {.type=FORM_TEXT, .hotkey=k, __VA_ARGS__}
-#define NUMBER(k,...) {.type=FORM_NUMBER, .hotkey=k, __VA_ARGS__}
-#define DATE(k,...) {.type=FORM_DATE, .hotkey=k, __VA_ARGS__}
-#define BUTTON(k,...) {.type=FORM_BUTTON, .hotkey=k, __VA_ARGS__}
-#define LIST(k,...) {.type=FORM_LIST, .hotkey=k, __VA_ARGS__}
+#define TEXT(k,...) {.f.type=FORM_TEXT, .f.hotkey=k, __VA_ARGS__}
+#define NUMBER(k,...) {.f.type=FORM_NUMBER, .f.hotkey=k, __VA_ARGS__}
+#define DATE(k,...) {.f.type=FORM_DATE, .f.hotkey=k, __VA_ARGS__}
+#define BUTTON(k,...) {.f.type=FORM_BUTTON, .f.hotkey=k, __VA_ARGS__}
+#define LIST(k,...) {.f.type=FORM_LIST, .f.hotkey=k, __VA_ARGS__}
#define HEAD(t,...) &(form_field_t){.type=FORM_LABEL, .label=t, .attr.bold=1}
#define LABEL(t,...) &(form_field_t){.type=FORM_LABEL, .label=t}
-#define CHECK(t,...) {.type=FORM_BUTTON, .label=t}
-#define TOGGLE(t,...) {.type=FORM_BUTTON, .label=t}
-#define RADIO(t,...) {.type=FORM_BUTTON, .label=t}
-#define BUTTONS(t,...) {.type=FORM_BUTTON, .label=t} // LIST[buttons]
+#define CHECK(t,...) {.f.type=FORM_BUTTON, .f.label=t}
+#define TOGGLE(t,...) {.f.type=FORM_BUTTON, .f.label=t}
+#define RADIO(t,...) {.f.type=FORM_BUTTON, .f.label=t}
+#define BUTTONS(t,...) {.f.type=FORM_BUTTON, .f.label=t} // LIST[buttons]
/* Widget types */
typedef enum {
int bold : 1;
} form_attr_t;
-/* Form data type */
+/* Form header */
typedef struct {
form_type_t type;
form_attr_t attr;
char *before;
char *label;
char *after;
- union {
- char text[256];
- date_t date;
- int number;
- int button;
- struct {
- char **map;
- int num;
- int idx;
- } list;
- };
} form_field_t;
+/* Form types */
+typedef struct {
+ form_field_t f;
+ char *text;
+} form_text_t;
+
+typedef struct {
+ form_field_t f;
+ date_t date;
+} form_date_t;
+
+typedef struct {
+ form_field_t f;
+ int number;
+} form_number_t;
+
+typedef struct {
+ form_field_t f;
+ int button;
+} form_button_t;
+
+typedef struct {
+ form_field_t f;
+ char **map;
+ int num;
+ int idx;
+} form_list_t;
+
+/* Form structure */
typedef struct {
int rows;
int cols;