blob: 4a1f6592c23d4aa5cefbf90dbec4af85130c21cc [file] [log] [blame]
Benny Baumann0f526292020-09-19 13:55:23 +02001#include "config.h" // IWYU pragma: keep
2
Hisham Muhammad466d4da2016-01-12 06:00:58 -02003#include "InfoScreen.h"
4
Benny Baumann0f526292020-09-19 13:55:23 +02005#include <stdarg.h>
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9
Hisham Muhammad466d4da2016-01-12 06:00:58 -020010#include "CRT.h"
11#include "IncSet.h"
12#include "ListItem.h"
Benny Baumann0f526292020-09-19 13:55:23 +020013#include "Object.h"
14#include "ProvideCurses.h"
Benny Baumann872e5422020-10-14 20:21:09 +020015#include "XUtils.h"
Hisham Muhammad466d4da2016-01-12 06:00:58 -020016
Hisham Muhammad466d4da2016-01-12 06:00:58 -020017
Richardd5faf642017-07-22 21:41:19 -050018static const char* const InfoScreenFunctions[] = {"Search ", "Filter ", "Refresh", "Done ", NULL};
Hisham Muhammad466d4da2016-01-12 06:00:58 -020019
Richardd5faf642017-07-22 21:41:19 -050020static const char* const InfoScreenKeys[] = {"F3", "F4", "F5", "Esc"};
Hisham Muhammad466d4da2016-01-12 06:00:58 -020021
Christian Göttsche7e7a53c2020-12-20 16:58:37 +010022static const int InfoScreenEvents[] = {KEY_F(3), KEY_F(4), KEY_F(5), 27};
Hisham Muhammad466d4da2016-01-12 06:00:58 -020023
Christian Göttsche41eea8a2020-10-07 19:02:15 +020024InfoScreen* InfoScreen_init(InfoScreen* this, const Process* process, FunctionBar* bar, int height, const char* panelHeader) {
Hisham Muhammad466d4da2016-01-12 06:00:58 -020025 this->process = process;
26 if (!bar) {
27 bar = FunctionBar_new(InfoScreenFunctions, InfoScreenKeys, InfoScreenEvents);
28 }
Christian Göttschece9e7fd2021-01-02 23:51:53 +010029 this->display = Panel_new(0, 1, COLS, height, Class(ListItem), false, bar);
Hisham Muhammad466d4da2016-01-12 06:00:58 -020030 this->inc = IncSet_new(bar);
Christian Göttsched37d66b2021-03-12 16:46:55 +010031 this->lines = Vector_new(Vector_type(this->display->items), true, DEFAULT_SIZE);
Hisham Muhammad466d4da2016-01-12 06:00:58 -020032 Panel_setHeader(this->display, panelHeader);
33 return this;
34}
35
36InfoScreen* InfoScreen_done(InfoScreen* this) {
37 Panel_delete((Object*)this->display);
38 IncSet_delete(this->inc);
39 Vector_delete(this->lines);
40 return this;
41}
42
Christian Göttsche11f558f2020-08-20 21:58:14 +020043void InfoScreen_drawTitled(InfoScreen* this, const char* fmt, ...) {
Hisham Muhammad466d4da2016-01-12 06:00:58 -020044 va_list ap;
45 va_start(ap, fmt);
ryenusff455b02020-10-03 00:12:31 +080046
Christian Göttschee3862aa2020-12-16 21:46:11 +010047 char title[COLS + 1];
48 int len = vsnprintf(title, sizeof(title), fmt, ap);
49 va_end(ap);
50
ryenusff455b02020-10-03 00:12:31 +080051 if (len > COLS) {
52 memset(&title[COLS - 3], '.', 3);
53 }
54
Hisham Muhammad466d4da2016-01-12 06:00:58 -020055 attrset(CRT_colors[METER_TEXT]);
56 mvhline(0, 0, ' ', COLS);
Vbfcb8ca2021-01-08 05:11:45 +010057 mvaddstr(0, 0, title);
Hisham Muhammad466d4da2016-01-12 06:00:58 -020058 attrset(CRT_colors[DEFAULT_COLOR]);
Christian Göttschea3cced92020-12-28 23:26:14 +010059 Panel_draw(this->display, true, true, true, false);
Christian Göttschee3862aa2020-12-16 21:46:11 +010060
Hisham Muhammad466d4da2016-01-12 06:00:58 -020061 IncSet_drawBar(this->inc);
Hisham Muhammad466d4da2016-01-12 06:00:58 -020062}
63
64void InfoScreen_addLine(InfoScreen* this, const char* line) {
65 Vector_add(this->lines, (Object*) ListItem_new(line, 0));
66 const char* incFilter = IncSet_filter(this->inc);
Benny Baumann45869512020-11-01 01:09:51 +010067 if (!incFilter || String_contains_i(line, incFilter)) {
Benny Baumann61e14d42020-10-31 23:28:02 +010068 Panel_add(this->display, Vector_get(this->lines, Vector_size(this->lines) - 1));
Benny Baumann45869512020-11-01 01:09:51 +010069 }
Hisham Muhammad466d4da2016-01-12 06:00:58 -020070}
71
72void InfoScreen_appendLine(InfoScreen* this, const char* line) {
Benny Baumann61e14d42020-10-31 23:28:02 +010073 ListItem* last = (ListItem*)Vector_get(this->lines, Vector_size(this->lines) - 1);
Hisham Muhammad466d4da2016-01-12 06:00:58 -020074 ListItem_append(last, line);
75 const char* incFilter = IncSet_filter(this->inc);
Benny Baumann45869512020-11-01 01:09:51 +010076 if (incFilter && Panel_get(this->display, Panel_size(this->display) - 1) != (Object*)last && String_contains_i(line, incFilter)) {
Hisham Muhammad466d4da2016-01-12 06:00:58 -020077 Panel_add(this->display, (Object*)last);
Benny Baumann45869512020-11-01 01:09:51 +010078 }
Hisham Muhammad466d4da2016-01-12 06:00:58 -020079}
80
81void InfoScreen_run(InfoScreen* this) {
82 Panel* panel = this->display;
83
Benny Baumann61e14d42020-10-31 23:28:02 +010084 if (As_InfoScreen(this)->scan)
85 InfoScreen_scan(this);
86
Hisham Muhammad466d4da2016-01-12 06:00:58 -020087 InfoScreen_draw(this);
88
89 bool looping = true;
90 while (looping) {
91
Christian Göttschea3cced92020-12-28 23:26:14 +010092 Panel_draw(panel, false, true, true, false);
Christian Göttschee3862aa2020-12-16 21:46:11 +010093 IncSet_drawBar(this->inc);
Hisham Muhammad466d4da2016-01-12 06:00:58 -020094
Hisham Muhammad8c653212018-02-18 10:38:49 -030095 if (this->inc->active) {
Benny Baumann61e14d42020-10-31 23:28:02 +010096 (void) move(LINES - 1, CRT_cursorX);
Hisham Muhammad8c653212018-02-18 10:38:49 -030097 }
Hisham645057d2016-05-19 16:09:47 -030098 set_escdelay(25);
Hisham Muhammad466d4da2016-01-12 06:00:58 -020099 int ch = getch();
Daniel Flanagandd334442019-10-31 11:39:12 -0500100
Hisham Muhammad466d4da2016-01-12 06:00:58 -0200101 if (ch == ERR) {
102 if (As_InfoScreen(this)->onErr) {
103 InfoScreen_onErr(this);
104 continue;
105 }
106 }
107
108 if (ch == KEY_MOUSE) {
109 MEVENT mevent;
110 int ok = getmouse(&mevent);
Nathan Scott36ef4d42020-08-19 18:10:16 +1000111 if (ok == OK) {
Youngjae Lee3c618132021-01-14 13:37:46 +0900112 if (mevent.bstate & BUTTON1_RELEASED) {
113 if (mevent.y >= panel->y && mevent.y < LINES - 1) {
114 Panel_setSelected(panel, mevent.y - panel->y + panel->scrollV - 1);
115 ch = 0;
116 } else if (mevent.y == LINES - 1) {
117 ch = IncSet_synthesizeEvent(this->inc, mevent.x);
118 }
YJ Lee34da6fd2021-01-14 16:25:23 +0900119 }
Youngjae Lee3c618132021-01-14 13:37:46 +0900120 #if NCURSES_MOUSE_VERSION > 1
YJ Lee34da6fd2021-01-14 16:25:23 +0900121 else if (mevent.bstate & BUTTON4_PRESSED) {
Youngjae Lee3c618132021-01-14 13:37:46 +0900122 ch = KEY_WHEELUP;
123 } else if (mevent.bstate & BUTTON5_PRESSED) {
124 ch = KEY_WHEELDOWN;
Jorge Pereira8de04982020-06-11 13:41:13 -0300125 }
YJ Lee34da6fd2021-01-14 16:25:23 +0900126 #endif
Christian Göttschef8208f22020-10-20 13:14:32 +0200127 }
Hisham Muhammad466d4da2016-01-12 06:00:58 -0200128 }
129
130 if (this->inc->active) {
131 IncSet_handleKey(this->inc, ch, panel, IncSet_getListItemValue, this->lines);
132 continue;
133 }
Daniel Flanagandd334442019-10-31 11:39:12 -0500134
Hisham Muhammad466d4da2016-01-12 06:00:58 -0200135 switch(ch) {
136 case ERR:
137 continue;
138 case KEY_F(3):
139 case '/':
140 IncSet_activate(this->inc, INC_SEARCH, panel);
141 break;
142 case KEY_F(4):
143 case '\\':
144 IncSet_activate(this->inc, INC_FILTER, panel);
145 break;
146 case KEY_F(5):
147 clear();
Øystein Hiåsend8d83032021-02-15 20:32:01 +0100148 if (As_InfoScreen(this)->scan) {
149 Vector_prune(this->lines);
Benny Baumann45869512020-11-01 01:09:51 +0100150 InfoScreen_scan(this);
Øystein Hiåsend8d83032021-02-15 20:32:01 +0100151 }
Benny Baumann45869512020-11-01 01:09:51 +0100152
Hisham Muhammad466d4da2016-01-12 06:00:58 -0200153 InfoScreen_draw(this);
154 break;
155 case '\014': // Ctrl+L
156 clear();
157 InfoScreen_draw(this);
158 break;
Hisham Muhammad466d4da2016-01-12 06:00:58 -0200159 case 27:
Benny Baumannc49ca612020-11-21 16:59:38 +0100160 case 'q':
Hisham Muhammad466d4da2016-01-12 06:00:58 -0200161 case KEY_F(10):
162 looping = false;
163 break;
164 case KEY_RESIZE:
Benny Baumann61e14d42020-10-31 23:28:02 +0100165 Panel_resize(panel, COLS, LINES - 2);
Øystein Hiåsend8d83032021-02-15 20:32:01 +0100166 if (As_InfoScreen(this)->scan) {
167 Vector_prune(this->lines);
Benny Baumann61e14d42020-10-31 23:28:02 +0100168 InfoScreen_scan(this);
Øystein Hiåsend8d83032021-02-15 20:32:01 +0100169 }
Benny Baumann45869512020-11-01 01:09:51 +0100170
Hisham Muhammad466d4da2016-01-12 06:00:58 -0200171 InfoScreen_draw(this);
172 break;
173 default:
174 if (As_InfoScreen(this)->onKey && InfoScreen_onKey(this, ch)) {
175 continue;
176 }
177 Panel_onKey(panel, ch);
178 }
179 }
180}