1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
3 Copyright (C) 2002-2018 Ben Kibbey <bjk@luxsci.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
43 set_menu_vars (int c
, int rows
, int items
, int *item
, int *top
)
51 selected
= toppos
= 0;
55 toppos
= items
- rows
+ 1;
62 toppos
= selected
- rows
+ 1;
68 if (toppos
&& selected
<= toppos
)
73 if (selected
+ 1 > items
)
74 selected
= toppos
= 0;
79 if (selected
- toppos
>= rows
)
89 toppos
= selected
- rows
+ 1;
100 toppos
= selected
- rows
+ 1;
106 if (selected
== MAX_MENU_HEIGHT
- 4)
108 else if (selected
<= rows
)
112 if (selected
- toppos
> rows
)
113 toppos
= selected
- rows
+ 1;
121 if (selected
>= items
)
124 toppos
= selected
- rows
+ 1;
135 fix_menu_vals (WIN
* win
)
137 struct menu_input_s
*m
= win
->data
;
142 int n
, nlen
= 0, vlen
= 0;
144 for (i
= 0; m
->items
[i
]; i
++);
146 snprintf (buf
, sizeof (buf
), _("Item %i %s %i Type %ls for help"),
147 m
->selected
+ 1, _("of"), m
->total
,
148 key_lookup (global_keys
, do_global_help
));
154 for (i
= 0; m
->items
[i
]; i
++)
156 wc
= str_to_wchar (m
->items
[i
]->name
);
162 if (m
->items
[i
]->value
)
164 wc
= str_to_wchar (m
->items
[i
]->value
);
174 char *s
= _("empty value");
176 n
= (!m
->name_only
) ? mblen (s
, strlen (s
)) + nlen
: nlen
;
187 if (!m
->rstatic
&& win
->title
)
191 win
->cols
+= (!m
->name_only
) ? 5 : 2; // 2 box, 3 separator
194 win
->rows
+= 3; // 2 box, 1 prompt
196 if (!m
->rstatic
&& win
->rows
> MAX_MENU_HEIGHT
)
197 win
->rows
= MAX_MENU_HEIGHT
;
199 wc
= str_to_wchar (buf
);
204 win
->cols
= len
+ 2; // 2 box
206 if (win
->cols
> MAX_MENU_WIDTH
)
207 win
->cols
= MAX_MENU_WIDTH
;
209 wresize (win
->w
, win
->rows
, win
->cols
);
210 replace_panel (win
->p
, win
->w
);
211 move_panel (win
->p
, (m
->ystatic
== -1) ? CALCPOSY (win
->rows
) : m
->ystatic
,
212 (m
->xstatic
== -1) ? CALCPOSX (win
->cols
) : m
->xstatic
);
213 keypad (win
->w
, TRUE
);
214 wmove (win
->w
, 0, 0);
216 window_draw_title (win
->w
, win
->title
, win
->cols
, CP_INPUT_TITLE
,
218 window_draw_prompt (win
->w
, win
->rows
- 2, win
->cols
, buf
, CP_INPUT_PROMPT
);
222 redraw_menu (WIN
* win
)
226 struct menu_input_s
*m
= win
->data
;
233 for (i
= m
->top
, y
= 2; m
->items
[i
] && y
< win
->rows
- 2; i
++, y
++)
235 if (i
== m
->selected
)
236 wattron (win
->w
, CP_MENU_SELECTED
);
237 else if (m
->items
[i
]->selected
)
238 wattron (win
->w
, CP_MENU_HIGHLIGHT
);
243 m
->item
= m
->items
[i
];
244 (*m
->print_func
) (win
);
247 if (i
== m
->selected
)
248 wattroff (win
->w
, CP_MENU_SELECTED
);
249 else if (m
->items
[i
]->selected
)
250 wattroff (win
->w
, CP_MENU_HIGHLIGHT
);
255 display_menu (WIN
* win
)
257 struct menu_input_s
*m
= win
->data
;
263 keypad (win
->w
, TRUE
);
268 for (i
= 0; m
->keys
[i
]; i
++)
270 if (win
->c
== m
->keys
[i
]->c
)
272 (*m
->keys
[i
]->func
) (m
);
273 m
->items
= (*m
->func
) (win
);
283 m
->items
= (*m
->func
) (win
);
301 if (strlen (m
->search
) + 1 > sizeof (m
->search
) - 1)
315 for (i
= 0; m
->items
[i
]; i
++)
317 if (strncasecmp (m
->search
, m
->items
[i
]->name
,
318 strlen (m
->search
)) == 0)
326 if (n
== m
->selected
)
331 set_menu_vars (win
->c
, win
->rows
- 4, m
->total
- 1, &m
->selected
, &m
->top
);
334 if (m
->draw_exit_func
)
335 (*m
->draw_exit_func
) (m
);
345 for (i
= 0; m
->items
[i
]; i
++)
348 free (m
->items
[i
]->name
);
350 if (!m
->nofree
&& m
->items
[i
]->value
)
351 free (m
->items
[i
]->value
);
361 for (i
= 0; m
->keys
[i
]; i
++)
373 menu_resize_func (WIN
*w
)
375 struct menu_input_s
*m
= w
->data
;
377 w
->rows
= m
->total
>= LINES
- 5 ? LINES
- 1 : m
->total
+ 5;
378 w
->cols
= w
->cols
> COLS
- 2 ? COLS
- 2 : w
->cols
;
379 wresize (w
->w
, w
->rows
, w
->cols
);
380 move_panel (w
->p
, CALCPOSY (w
->rows
), CALCPOSX (w
->cols
));
386 construct_menu (int rows
, int cols
, int y
, int x
, const char *title
,
387 int name_only
, menu_items_fn
* func
,
388 struct menu_key_s
** keys
, void *data
,
389 menu_print_func
* pfunc
, window_exit_func
* efunc
,
390 window_resize_func
*rfunc
)
393 struct menu_input_s
*m
;
395 m
= Calloc (1, sizeof (struct menu_input_s
));
396 win
= window_create (title
, (rows
<= 0) ? 1 : rows
, (cols
<= 0) ? 1 : cols
,
397 (y
>= 0) ? y
: 0, (x
>= 0) ? x
: 0, display_menu
, m
,
398 efunc
, rfunc
? rfunc
: menu_resize_func
);
409 m
->print_func
= pfunc
;
413 m
->name_only
= name_only
;
414 wbkgd (win
->w
, CP_MENU
);
417 keypad (win
->w
, TRUE
);
419 m
->items
= (*m
->func
) (win
);
426 add_menu_key (struct menu_key_s
***dst
, wint_t c
, menu_key func
)
429 struct menu_key_s
**keys
= *dst
;
432 for (; keys
[n
]; n
++);
434 keys
= Realloc (keys
, (n
+ 2) * sizeof (struct menu_key_s
*));
435 keys
[n
] = Malloc (sizeof (struct menu_key_s
));
437 keys
[n
++]->func
= func
;