1 /**
2  * @file
3  * Pager Panel
4  *
5  * @authors
6  * Copyright (C) 2021 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 /**
24  * @page pager_ppanel Pager Panel
25  *
26  * The Pager Panel is a non-interactive container around the email list and a
27  * status bar.
28  *
29  * ## Windows
30  *
31  * | Name        | Type      | Constructor  |
32  * | :---------- | :-------- | :----------- |
33  * | Pager Panel | #WT_PAGER | ppanel_new() |
34  *
35  * **Parent**
36  * - @ref index_dialog
37  *
38  * **Children**
39  * - @ref pager_pager
40  * - @ref pager_pbar
41  *
42  * ## Data
43  * - #PagerPrivateData
44  *
45  * ## Events
46  *
47  * Once constructed, it is controlled by the following events:
48  *
49  * | Event Type  | Handler                  |
50  * | :---------- | :----------------------- |
51  * | #NT_CONFIG  | ppanel_config_observer() |
52  * | #NT_WINDOW  | ppanel_window_observer() |
53  *
54  * The Pager Panel does not implement MuttWindow::recalc() or MuttWindow::repaint().
55  */
56 
57 #include "config.h"
58 #include <inttypes.h> // IWYU pragma: keep
59 #include <stdbool.h>
60 #include "mutt/lib.h"
61 #include "config/lib.h"
62 #include "core/lib.h"
63 #include "gui/lib.h"
64 #include "lib.h"
65 #include "pbar.h"
66 #include "private_data.h"
67 
68 struct IndexSharedData;
69 
70 /**
71  * ppanel_config_observer - Notification that a Config Variable has changed - Implements ::observer_t - @ingroup observer_api
72  */
ppanel_config_observer(struct NotifyCallback * nc)73 static int ppanel_config_observer(struct NotifyCallback *nc)
74 {
75   if ((nc->event_type != NT_CONFIG) || !nc->global_data || !nc->event_data)
76     return -1;
77 
78   struct EventConfig *ev_c = nc->event_data;
79   struct MuttWindow *panel_pager = nc->global_data;
80 
81   if (mutt_str_equal(ev_c->name, "status_on_top"))
82   {
83     window_status_on_top(panel_pager, NeoMutt->sub);
84     mutt_debug(LL_DEBUG5, "config done\n");
85   }
86 
87   return 0;
88 }
89 
90 /**
91  * ppanel_window_observer - Notification that a Window has changed - Implements ::observer_t - @ingroup observer_api
92  */
ppanel_window_observer(struct NotifyCallback * nc)93 static int ppanel_window_observer(struct NotifyCallback *nc)
94 {
95   if ((nc->event_type != NT_WINDOW) || !nc->global_data || !nc->event_data)
96     return -1;
97 
98   if (nc->event_subtype != NT_WINDOW_DELETE)
99     return 0;
100 
101   struct MuttWindow *panel_pager = nc->global_data;
102   struct EventWindow *ev_w = nc->event_data;
103   if (ev_w->win != panel_pager)
104     return 0;
105 
106   notify_observer_remove(NeoMutt->notify, ppanel_config_observer, panel_pager);
107   notify_observer_remove(panel_pager->notify, ppanel_window_observer, panel_pager);
108   mutt_debug(LL_DEBUG5, "window delete done\n");
109 
110   return 0;
111 }
112 
113 /**
114  * ppanel_new - Create the Windows for the Pager panel
115  * @param status_on_top true, if the Pager bar should be on top
116  * @param shared        Shared Index data
117  * @retval ptr New Pager Panel
118  */
ppanel_new(bool status_on_top,struct IndexSharedData * shared)119 struct MuttWindow *ppanel_new(bool status_on_top, struct IndexSharedData *shared)
120 {
121   struct MuttWindow *panel_pager =
122       mutt_window_new(WT_PAGER, MUTT_WIN_ORIENT_VERTICAL, MUTT_WIN_SIZE_MAXIMISE,
123                       MUTT_WIN_SIZE_UNLIMITED, MUTT_WIN_SIZE_UNLIMITED);
124   panel_pager->state.visible = false; // The Pager and Pager Bar are initially hidden
125 
126   struct PagerPrivateData *priv = pager_private_data_new();
127   panel_pager->wdata = priv;
128   panel_pager->wdata_free = pager_private_data_free;
129 
130   struct MuttWindow *win_pager = pager_window_new(shared, priv);
131   panel_pager->focus = win_pager;
132 
133   struct MuttWindow *win_pbar = pbar_new(shared, priv);
134   if (status_on_top)
135   {
136     mutt_window_add_child(panel_pager, win_pbar);
137     mutt_window_add_child(panel_pager, win_pager);
138   }
139   else
140   {
141     mutt_window_add_child(panel_pager, win_pager);
142     mutt_window_add_child(panel_pager, win_pbar);
143   }
144 
145   notify_observer_add(NeoMutt->notify, NT_CONFIG, ppanel_config_observer, panel_pager);
146   notify_observer_add(panel_pager->notify, NT_WINDOW, ppanel_window_observer, panel_pager);
147 
148   return panel_pager;
149 }
150