messenger-cli

Command-line user interface for GNUnet Messenger
Log | Files | Refs | README | LICENSE

list_input.h (6430B)


      1 /*
      2    This file is part of GNUnet.
      3    Copyright (C) 2022, 2026 GNUnet e.V.
      4 
      5    GNUnet is free software: you can redistribute it and/or modify it
      6    under the terms of the GNU Affero General Public License as published
      7    by the Free Software Foundation, either version 3 of the License,
      8    or (at your option) any later version.
      9 
     10    GNUnet is distributed in the hope that it will be useful, but
     11    WITHOUT ANY WARRANTY; without even the implied warranty of
     12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13    Affero General Public License for more details.
     14 
     15    You should have received a copy of the GNU Affero General Public License
     16    along with this program.  If not, see <http://www.gnu.org/licenses/>.
     17 
     18    SPDX-License-Identifier: AGPL3.0-or-later
     19  */
     20 /*
     21  * @author Tobias Frisch
     22  * @file ui/list_input.h
     23  */
     24 
     25 #ifndef UI_LIST_INPUT_H_
     26 #define UI_LIST_INPUT_H_
     27 
     28 #include <stdbool.h>
     29 
     30 /**
     31  * Resets the list controls.
     32  */
     33 #define list_input_reset(list) { \
     34   (list)->line_prev = 0;         \
     35   (list)->line_next = 0;         \
     36   (list)->line_index = 0;        \
     37   (list)->selected = 0;          \
     38 }
     39 
     40 /**
     41  * Handles the list controls selection and
     42  * indices to move the selection via events.
     43  */
     44 #define list_input_select(list, line_width, item) {                \
     45   const bool selected = (                                          \
     46       ((list)->line_selected >= (list)->line_index) &&             \
     47       ((list)->line_selected < (list)->line_index + (line_width))  \
     48   );                                                               \
     49                                                                    \
     50   if ((!selected) && ((list)->line_selected > (list)->line_index)) \
     51     (list)->line_prev = (list)->line_index;                        \
     52                                                                    \
     53   (list)->line_index += (line_width);                              \
     54                                                                    \
     55   if (selected) {                                                  \
     56     (list)->line_next = (list)->line_index;                        \
     57     (list)->selected = item;                                       \
     58   }                                                                \
     59 }
     60 
     61 /**
     62  * Handles the key event to move the selection
     63  * of list controls and adjust its view area.
     64  */
     65 #define list_input_event(list, key) {                          \
     66   int count = (list)->line_index;                              \
     67                                                                \
     68   switch (key)                                                 \
     69   {                                                            \
     70     case KEY_UP:                                               \
     71     {                                                          \
     72       (list)->line_selected = (list)->line_prev;               \
     73       break;                                                   \
     74     }                                                          \
     75     case KEY_DOWN:                                             \
     76     {                                                          \
     77       (list)->line_selected = (list)->line_next;               \
     78       break;                                                   \
     79     }                                                          \
     80     default:                                                   \
     81       break;                                                   \
     82   }                                                            \
     83                                                                \
     84   if ((list)->line_selected < 0)                               \
     85     (list)->line_selected = 0;                                 \
     86   else if ((list)->line_selected >= count)                     \
     87     (list)->line_selected = count - 1;                         \
     88                                                                \
     89   if ((list)->window)                                          \
     90   {                                                            \
     91     const int height = getmaxy((list)->window);                \
     92     const int y = (list)->line_selected - (list)->line_offset; \
     93                                                                \
     94     if (y < 0)                                                 \
     95       (list)->line_offset += y;                                \
     96     else if (y + 1 >= height)                                  \
     97       (list)->line_offset += y + 1 - height;                   \
     98                                                                \
     99     if ((list)->line_offset < 0)                               \
    100       (list)->line_offset = 0;                                 \
    101     else if ((list)->line_offset >= count)                     \
    102       (list)->line_offset = count - 1;                         \
    103   }                                                            \
    104 }
    105 
    106 /**
    107  * Prepares for printing an item in list controls
    108  * as well as providing its selection and its
    109  * y location in the current view.
    110  */
    111 #define list_input_print_(list, line_width, yes_res, no_res)      \
    112   const bool selected = (                                         \
    113       ((list)->line_selected >= (list)->line_index) &&            \
    114       ((list)->line_selected < (list)->line_index + (line_width)) \
    115   );                                                              \
    116                                                                   \
    117   const int y = (list)->line_index - (list)->line_offset; {       \
    118                                                                   \
    119   (list)->line_index += (line_width);                             \
    120                                                                   \
    121   if (y + (line_width) < 1)                                       \
    122     return yes_res;                                               \
    123                                                                   \
    124   const int height = getmaxy((list)->window);                     \
    125                                                                   \
    126   if (y >= height)                                                \
    127     return no_res;                                                \
    128 }
    129 
    130 #define list_input_print_gnunet(list, line_width) \
    131     list_input_print_(list, line_width, GNUNET_YES, GNUNET_NO)
    132 
    133 #define list_input_print(list, line_width) \
    134     list_input_print_(list, line_width, , )
    135 
    136 #endif /* UI_LIST_INPUT_H_ */