5 * slang versions <= 2.0.6 have a "#if HAVE_LONG_LONG" that breaks
6 * the build if it isn't defined. Use the equivalent one that glibc
10 #ifndef HAVE_LONG_LONG
11 #define HAVE_LONG_LONG __GLIBC_HAVE_LONG_LONG
14 #include <linux/list.h>
15 #include <linux/rbtree.h>
17 #include <sys/ttydefaults.h>
23 #if SLANG_VERSION < 20104
24 #define sltt_set_color(obj, name, fg, bg) \
25 SLtt_set_color(obj,(char *)name, (char *)fg, (char *)bg)
27 #define sltt_set_color SLtt_set_color
30 newtComponent newt_form__new(void);
32 int ui_browser__percent_color(double percent, bool current)
35 return HE_COLORSET_SELECTED;
36 if (percent >= MIN_RED)
37 return HE_COLORSET_TOP;
38 if (percent >= MIN_GREEN)
39 return HE_COLORSET_MEDIUM;
40 return HE_COLORSET_NORMAL;
43 void ui_browser__list_head_seek(struct ui_browser *self, off_t offset, int whence)
45 struct list_head *head = self->entries;
46 struct list_head *pos;
73 void ui_browser__rb_tree_seek(struct ui_browser *self, off_t offset, int whence)
75 struct rb_root *root = self->entries;
103 unsigned int ui_browser__rb_tree_refresh(struct ui_browser *self)
108 if (self->top == NULL)
109 self->top = rb_first(self->entries);
114 SLsmg_gotorc(self->y + row, self->x);
115 self->write(self, nd, row);
116 if (++row == self->height)
124 bool ui_browser__is_current_entry(struct ui_browser *self, unsigned row)
126 return self->top_idx + row == self->index;
129 void ui_browser__refresh_dimensions(struct ui_browser *self)
132 newtGetScreenSize(&cols, &rows);
134 if (self->width > cols - 4)
135 self->width = cols - 4;
136 self->height = rows - 5;
137 if (self->height > self->nr_entries)
138 self->height = self->nr_entries;
139 self->y = (rows - self->height) / 2;
140 self->x = (cols - self->width) / 2;
143 void ui_browser__reset_index(struct ui_browser *self)
145 self->index = self->top_idx = 0;
146 self->seek(self, 0, SEEK_SET);
149 int ui_browser__show(struct ui_browser *self, const char *title,
150 const char *helpline, ...)
154 if (self->form != NULL) {
155 newtFormDestroy(self->form);
158 ui_browser__refresh_dimensions(self);
159 newtCenteredWindow(self->width, self->height, title);
160 self->form = newt_form__new();
161 if (self->form == NULL)
164 self->sb = newtVerticalScrollbar(self->width, 0, self->height,
166 HE_COLORSET_SELECTED);
167 if (self->sb == NULL)
170 newtFormAddHotKey(self->form, NEWT_KEY_UP);
171 newtFormAddHotKey(self->form, NEWT_KEY_DOWN);
172 newtFormAddHotKey(self->form, NEWT_KEY_PGUP);
173 newtFormAddHotKey(self->form, NEWT_KEY_PGDN);
174 newtFormAddHotKey(self->form, NEWT_KEY_HOME);
175 newtFormAddHotKey(self->form, NEWT_KEY_END);
176 newtFormAddHotKey(self->form, ' ');
177 newtFormAddComponent(self->form, self->sb);
179 va_start(ap, helpline);
180 ui_helpline__vpush(helpline, ap);
185 void ui_browser__hide(struct ui_browser *self)
187 newtFormDestroy(self->form);
193 int ui_browser__refresh(struct ui_browser *self)
197 newtScrollbarSet(self->sb, self->index, self->nr_entries - 1);
198 row = self->refresh(self);
199 SLsmg_set_color(HE_COLORSET_NORMAL);
200 SLsmg_fill_region(self->y + row, self->x,
201 self->height - row, self->width, ' ');
206 int ui_browser__run(struct ui_browser *self, struct newtExitStruct *es)
208 if (ui_browser__refresh(self) < 0)
214 newtFormRun(self->form, es);
216 if (es->reason != NEWT_EXIT_HOTKEY)
218 if (is_exit_key(es->u.key))
222 if (self->index == self->nr_entries - 1)
225 if (self->index == self->top_idx + self->height) {
227 self->seek(self, +1, SEEK_CUR);
231 if (self->index == 0)
234 if (self->index < self->top_idx) {
236 self->seek(self, -1, SEEK_CUR);
241 if (self->top_idx + self->height > self->nr_entries - 1)
244 offset = self->height;
245 if (self->index + offset > self->nr_entries - 1)
246 offset = self->nr_entries - 1 - self->index;
247 self->index += offset;
248 self->top_idx += offset;
249 self->seek(self, +offset, SEEK_CUR);
252 if (self->top_idx == 0)
255 if (self->top_idx < self->height)
256 offset = self->top_idx;
258 offset = self->height;
260 self->index -= offset;
261 self->top_idx -= offset;
262 self->seek(self, -offset, SEEK_CUR);
265 ui_browser__reset_index(self);
268 offset = self->height - 1;
269 if (offset >= self->nr_entries)
270 offset = self->nr_entries - 1;
272 self->index = self->nr_entries - 1;
273 self->top_idx = self->index - offset;
274 self->seek(self, -offset, SEEK_END);
279 if (ui_browser__refresh(self) < 0)
285 unsigned int ui_browser__list_head_refresh(struct ui_browser *self)
287 struct list_head *pos;
288 struct list_head *head = self->entries;
291 if (self->top == NULL || self->top == self->entries)
292 self->top = head->next;
296 list_for_each_from(pos, head) {
297 SLsmg_gotorc(self->y + row, self->x);
298 self->write(self, pos, row);
299 if (++row == self->height)
306 static struct newtPercentTreeColors {
307 const char *topColorFg, *topColorBg;
308 const char *mediumColorFg, *mediumColorBg;
309 const char *normalColorFg, *normalColorBg;
310 const char *selColorFg, *selColorBg;
311 const char *codeColorFg, *codeColorBg;
312 } defaultPercentTreeColors = {
314 "green", "lightgray",
315 "black", "lightgray",
316 "lightgray", "magenta",
320 void ui_browser__init(void)
322 struct newtPercentTreeColors *c = &defaultPercentTreeColors;
324 sltt_set_color(HE_COLORSET_TOP, NULL, c->topColorFg, c->topColorBg);
325 sltt_set_color(HE_COLORSET_MEDIUM, NULL, c->mediumColorFg, c->mediumColorBg);
326 sltt_set_color(HE_COLORSET_NORMAL, NULL, c->normalColorFg, c->normalColorBg);
327 sltt_set_color(HE_COLORSET_SELECTED, NULL, c->selColorFg, c->selColorBg);
328 sltt_set_color(HE_COLORSET_CODE, NULL, c->codeColorFg, c->codeColorBg);