messenger-cli

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

list_input.h (6444B)


      1 /*
      2    This file is part of GNUnet.
      3    Copyright (C) 2022 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 #include <stdlib.h>
     30 
     31 /**
     32  * Resets the list controls.
     33  */
     34 #define list_input_reset(list) { \
     35   (list)->line_prev = 0;         \
     36   (list)->line_next = 0;         \
     37   (list)->line_index = 0;        \
     38   (list)->selected = 0;          \
     39 }
     40 
     41 /**
     42  * Handles the list controls selection and
     43  * indices to move the selection via events.
     44  */
     45 #define list_input_select(list, line_width, item) {                \
     46   const bool selected = (                                          \
     47       ((list)->line_selected >= (list)->line_index) &&             \
     48       ((list)->line_selected < (list)->line_index + (line_width))  \
     49   );                                                               \
     50                                                                    \
     51   if ((!selected) && ((list)->line_selected > (list)->line_index)) \
     52     (list)->line_prev = (list)->line_index;                        \
     53                                                                    \
     54   (list)->line_index += (line_width);                              \
     55                                                                    \
     56   if (selected) {                                                  \
     57     (list)->line_next = (list)->line_index;                        \
     58     (list)->selected = item;                                       \
     59   }                                                                \
     60 }
     61 
     62 /**
     63  * Handles the key event to move the selection
     64  * of list controls and adjust its view area.
     65  */
     66 #define list_input_event(list, key) {                          \
     67   int count = (list)->line_index;                              \
     68                                                                \
     69   switch (key)                                                 \
     70   {                                                            \
     71     case KEY_UP:                                               \
     72     {                                                          \
     73       (list)->line_selected = (list)->line_prev;               \
     74       break;                                                   \
     75     }                                                          \
     76     case KEY_DOWN:                                             \
     77     {                                                          \
     78       (list)->line_selected = (list)->line_next;               \
     79       break;                                                   \
     80     }                                                          \
     81     default:                                                   \
     82       break;                                                   \
     83   }                                                            \
     84                                                                \
     85   if ((list)->line_selected < 0)                               \
     86     (list)->line_selected = 0;                                 \
     87   else if ((list)->line_selected >= count)                     \
     88     (list)->line_selected = count - 1;                         \
     89                                                                \
     90   if ((list)->window)                                          \
     91   {                                                            \
     92     const int height = getmaxy((list)->window);                \
     93     const int y = (list)->line_selected - (list)->line_offset; \
     94                                                                \
     95     if (y < 0)                                                 \
     96       (list)->line_offset += y;                                \
     97     else if (y + 1 >= height)                                  \
     98       (list)->line_offset += y + 1 - height;                   \
     99                                                                \
    100     if ((list)->line_offset < 0)                               \
    101       (list)->line_offset = 0;                                 \
    102     else if ((list)->line_offset >= count)                     \
    103       (list)->line_offset = count - 1;                         \
    104   }                                                            \
    105 }
    106 
    107 /**
    108  * Prepares for printing an item in list controls
    109  * as well as providing its selection and its
    110  * y location in the current view.
    111  */
    112 #define list_input_print_(list, line_width, yes_res, no_res)      \
    113   const bool selected = (                                         \
    114       ((list)->line_selected >= (list)->line_index) &&            \
    115       ((list)->line_selected < (list)->line_index + (line_width)) \
    116   );                                                              \
    117                                                                   \
    118   const int y = (list)->line_index - (list)->line_offset; {       \
    119                                                                   \
    120   (list)->line_index += (line_width);                             \
    121                                                                   \
    122   if (y + (line_width) < 1)                                       \
    123     return yes_res;                                               \
    124                                                                   \
    125   const int height = getmaxy((list)->window);                     \
    126                                                                   \
    127   if (y >= height)                                                \
    128     return no_res;                                                \
    129 }
    130 
    131 #define list_input_print_gnunet(list, line_width) \
    132     list_input_print_(list, line_width, GNUNET_YES, GNUNET_NO)
    133 
    134 #define list_input_print(list, line_width) \
    135     list_input_print_(list, line_width, , )
    136 
    137 #endif /* UI_LIST_INPUT_H_ */