1 /**
2  * @file
3  * Window management
4  *
5  * @authors
6  * Copyright (C) 2018-2020 Richard Russon <rich@flatcap.org>
7  *
8  * @copyright
9  * This program is free software: you can redistribute it and/or modify it under
10  * the terms of the GNU General Public License as published by the Free Software
11  * Foundation, either version 2 of the License, or (at your option) any later
12  * version.
13  *
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
17  * details.
18  *
19  * You should have received a copy of the GNU General Public License along with
20  * this program.  If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #ifndef MUTT_MUTT_WINDOW_H
24 #define MUTT_MUTT_WINDOW_H
25 
26 #include "config.h"
27 #include <stdbool.h>
28 #include <stdint.h>
29 #include "mutt/lib.h"
30 
31 struct ConfigSubset;
32 
33 /**
34  * enum MuttWindowOrientation - Which way does the Window expand?
35  */
36 enum MuttWindowOrientation
37 {
38   MUTT_WIN_ORIENT_VERTICAL = 1, ///< Window uses all available vertical space
39   MUTT_WIN_ORIENT_HORIZONTAL,   ///< Window uses all available horizontal space
40 };
41 
42 /**
43  * enum MuttWindowSize - Control the allocation of Window space
44  */
45 enum MuttWindowSize
46 {
47   MUTT_WIN_SIZE_FIXED = 1, ///< Window has a fixed size
48   MUTT_WIN_SIZE_MAXIMISE,  ///< Window wants as much space as possible
49   MUTT_WIN_SIZE_MINIMISE,  ///< Window size depends on its children
50 };
51 
52 #define MUTT_WIN_SIZE_UNLIMITED -1 ///< Use as much space as possible
53 
54 /**
55  * struct WindowState - The current, or old, state of a Window
56  */
57 struct WindowState
58 {
59   bool visible;     ///< Window is visible
60   short cols;       ///< Number of columns, can be #MUTT_WIN_SIZE_UNLIMITED
61   short rows;       ///< Number of rows, can be #MUTT_WIN_SIZE_UNLIMITED
62   short col_offset; ///< Absolute on-screen column
63   short row_offset; ///< Absolute on-screen row
64 };
65 
66 /**
67  * enum WindowType - Type of Window
68  */
69 enum WindowType
70 {
71   // Structural Windows
72   WT_ROOT,            ///< Parent of All Windows
73   WT_CONTAINER,       ///< Invisible shaping container Window
74   WT_ALL_DIALOGS,     ///< Container for All Dialogs (nested Windows)
75 
76   // Dialogs (nested Windows) displayed to the user
77   WT_DLG_ALIAS,       ///< Alias Dialog,       dlg_select_alias()
78   WT_DLG_ATTACH,      ///< Attach Dialog,      dlg_select_attachment()
79   WT_DLG_AUTOCRYPT,   ///< Autocrypt Dialog,   dlg_select_autocrypt_account()
80   WT_DLG_BROWSER,     ///< Browser Dialog,     mutt_buffer_select_file()
81   WT_DLG_CERTIFICATE, ///< Certificate Dialog, dlg_verify_certificate()
82   WT_DLG_COMPOSE,     ///< Compose Dialog,     mutt_compose_menu()
83   WT_DLG_CRYPT_GPGME, ///< Crypt-GPGME Dialog, dlg_select_gpgme_key()
84   WT_DLG_DO_PAGER,    ///< Pager Dialog,       mutt_do_pager()
85   WT_DLG_HISTORY,     ///< History Dialog,     dlg_select_history()
86   WT_DLG_INDEX,       ///< Index Dialog,       index_pager_init()
87   WT_DLG_PATTERN,     ///< Pattern Dialog,     create_pattern_menu()
88   WT_DLG_PGP,         ///< Pgp Dialog,         dlg_select_pgp_key()
89   WT_DLG_POSTPONE,    ///< Postpone Dialog,    dlg_select_postponed_email()
90   WT_DLG_QUERY,       ///< Query Dialog,       dlg_select_query()
91   WT_DLG_REMAILER,    ///< Remailer Dialog,    dlg_select_mixmaster_chain()
92   WT_DLG_SMIME,       ///< Smime Dialog,       dlg_select_smime_key()
93 
94   // Common Windows
95   WT_CUSTOM,          ///< Window with a custom drawing function
96   WT_HELP_BAR,        ///< Help Bar containing list of useful key bindings
97   WT_INDEX,           ///< A panel containing the Index Window
98   WT_MENU,            ///< An Window containing a Menu
99   WT_MESSAGE,         ///< Window for messages/errors and command entry
100   WT_PAGER,           ///< A panel containing the Pager Window
101   WT_SIDEBAR,         ///< Side panel containing Accounts or groups of data
102   WT_STATUS_BAR,      ///< Status Bar containing extra info about the Index/Pager/etc
103 };
104 
105 TAILQ_HEAD(MuttWindowList, MuttWindow);
106 
107 typedef uint8_t WindowActionFlags; ///< Flags for Actions waiting to be performed on a MuttWindow, e.g. #WA_REFLOW
108 #define WA_NO_FLAGS        0       ///< No flags are set
109 #define WA_REFLOW    (1 << 0)      ///< Reflow the Window and its children
110 #define WA_RECALC    (1 << 1)      ///< Recalculate the contents of the Window
111 #define WA_REPAINT   (1 << 2)      ///< Redraw the contents of the Window
112 
113 /**
114  * @defgroup window_api Window API
115  *
116  * The Window API
117  *
118  * A division of the screen.
119  *
120  * Windows for different parts of the screen
121  */
122 struct MuttWindow
123 {
124   short req_cols;                    ///< Number of columns required
125   short req_rows;                    ///< Number of rows required
126 
127   struct WindowState state;          ///< Current state of the Window
128   struct WindowState old;            ///< Previous state of the Window
129 
130   enum MuttWindowOrientation orient; ///< Which direction the Window will expand
131   enum MuttWindowSize size;          ///< Type of Window, e.g. #MUTT_WIN_SIZE_FIXED
132   WindowActionFlags actions;         ///< Actions to be performed, e.g. #WA_RECALC
133 
134   TAILQ_ENTRY(MuttWindow) entries;   ///< Linked list
135   struct MuttWindow *parent;         ///< Parent Window
136   struct MuttWindowList children;    ///< Children Windows
137 
138   struct Notify *notify;             ///< Notifications: #NotifyWindow, #EventWindow
139 
140   struct MuttWindow *focus;          ///< Focused Window
141   int help_menu;                     ///< Menu for key bindings, e.g. #MENU_PAGER
142   const struct Mapping *help_data;   ///< Data for the Help Bar
143 
144   enum WindowType type;              ///< Window type, e.g. #WT_SIDEBAR
145   void *wdata;                       ///< Private data
146 
147   /**
148    * @defgroup window_wdata_free wdata_free()
149    * @ingroup window_api
150    *
151    * wdata_free - Free the private data attached to the MuttWindow
152    * @param win Window
153    * @param ptr Window data to free
154    *
155    * **Contract**
156    * - @a win  is not NULL
157    * - @a ptr  is not NULL
158    * - @a *ptr is not NULL
159    */
160   void (*wdata_free)(struct MuttWindow *win, void **ptr);
161 
162   /**
163    * @defgroup window_recalc recalc()
164    * @ingroup window_api
165    *
166    * recalc - Recalculate the Window data
167    * @param win Window
168    * @retval  0 Success
169    * @retval -1 Error
170    */
171   int (*recalc)(struct MuttWindow *win);
172 
173   /**
174    * @defgroup window_repaint repaint()
175    * @ingroup window_api
176    *
177    * repaint - Repaint the Window
178    * @param win Window
179    * @retval  0 Success
180    * @retval -1 Error
181    */
182   int (*repaint)(struct MuttWindow *win);
183 };
184 
185 typedef uint8_t WindowNotifyFlags; ///< Flags for Changes to a MuttWindow, e.g. #WN_TALLER
186 #define WN_NO_FLAGS        0       ///< No flags are set
187 #define WN_TALLER    (1 << 0)      ///< Window became taller
188 #define WN_SHORTER   (1 << 1)      ///< Window became shorter
189 #define WN_WIDER     (1 << 2)      ///< Window became wider
190 #define WN_NARROWER  (1 << 3)      ///< Window became narrower
191 #define WN_MOVED     (1 << 4)      ///< Window moved
192 #define WN_VISIBLE   (1 << 5)      ///< Window became visible
193 #define WN_HIDDEN    (1 << 6)      ///< Window became hidden
194 
195 /**
196  * enum NotifyWindow - Window notification types
197  *
198  * Observers of #NT_WINDOW will be passed an #EventWindow.
199  *
200  * @note Delete notifications are sent **before** the object is deleted.
201  * @note Other notifications are sent **after** the event.
202  */
203 enum NotifyWindow
204 {
205   NT_WINDOW_ADD = 1, ///< New Window has been added
206   NT_WINDOW_DELETE,  ///< Window is about to be deleted
207   NT_WINDOW_STATE,   ///< Window state has changed, e.g. #WN_VISIBLE
208   NT_WINDOW_DIALOG,  ///< A new Dialog Window has been created, e.g. #WT_DLG_INDEX
209   NT_WINDOW_FOCUS,   ///< Window focus has changed
210 };
211 
212 /**
213  * struct EventWindow - An Event that happened to a Window
214  */
215 struct EventWindow
216 {
217   struct MuttWindow *win;  ///< Window that changed
218   WindowNotifyFlags flags; ///< Attributes of Window that changed
219 };
220 
221 // Functions that deal with the Window
222 void               mutt_window_add_child          (struct MuttWindow *parent, struct MuttWindow *child);
223 void               mutt_window_free               (struct MuttWindow **ptr);
224 void               mutt_window_get_coords         (struct MuttWindow *win, int *col, int *row);
225 struct MuttWindow *mutt_window_new                (enum WindowType type, enum MuttWindowOrientation orient, enum MuttWindowSize size, int cols, int rows);
226 void               mutt_window_reflow             (struct MuttWindow *win);
227 struct MuttWindow *mutt_window_remove_child       (struct MuttWindow *parent, struct MuttWindow *child);
228 int                mutt_window_wrap_cols          (int width, short wrap);
229 
230 // Functions for drawing on the Window
231 int  mutt_window_addch    (struct MuttWindow *win, int ch);
232 int  mutt_window_addnstr  (struct MuttWindow *win, const char *str, int num);
233 int  mutt_window_addstr   (struct MuttWindow *win, const char *str);
234 void mutt_window_clearline(struct MuttWindow *win, int row);
235 void mutt_window_clear    (struct MuttWindow *win);
236 void mutt_window_clrtoeol (struct MuttWindow *win);
237 int  mutt_window_move     (struct MuttWindow *win, int col, int row);
238 int  mutt_window_mvaddstr (struct MuttWindow *win, int col, int row, const char *str);
239 int  mutt_window_mvprintw (struct MuttWindow *win, int col, int row, const char *fmt, ...);
240 int  mutt_window_printf   (struct MuttWindow *win, const char *format, ...);
241 bool mutt_window_is_visible(struct MuttWindow *win);
242 
243 void               mutt_winlist_free (struct MuttWindowList *head);
244 struct MuttWindow *window_find_child (struct MuttWindow *win, enum WindowType type);
245 struct MuttWindow *window_find_parent(struct MuttWindow *win, enum WindowType type);
246 void               window_notify_all (struct MuttWindow *win);
247 void               window_set_visible(struct MuttWindow *win, bool visible);
248 struct MuttWindow *window_set_focus  (struct MuttWindow *win);
249 struct MuttWindow *window_get_focus  (void);
250 bool               window_is_focused (struct MuttWindow *win);
251 
252 void window_redraw(struct MuttWindow *win);
253 void window_invalidate_all(void);
254 const char *mutt_window_win_name(const struct MuttWindow *win);
255 bool window_status_on_top(struct MuttWindow *panel, struct ConfigSubset *sub);
256 
257 #endif /* MUTT_MUTT_WINDOW_H */
258