2 #include <linux/compiler.h>
3 #include <linux/list.h>
4 #include <linux/rbtree.h>
6 #include <sys/ttydefaults.h>
13 static int ui_browser__percent_color(double percent
, bool current
)
16 return HE_COLORSET_SELECTED
;
17 if (percent
>= MIN_RED
)
18 return HE_COLORSET_TOP
;
19 if (percent
>= MIN_GREEN
)
20 return HE_COLORSET_MEDIUM
;
21 return HE_COLORSET_NORMAL
;
24 void ui_browser__set_color(struct ui_browser
*self __used
, int color
)
26 SLsmg_set_color(color
);
29 void ui_browser__set_percent_color(struct ui_browser
*self
,
30 double percent
, bool current
)
32 int color
= ui_browser__percent_color(percent
, current
);
33 ui_browser__set_color(self
, color
);
36 void ui_browser__gotorc(struct ui_browser
*self
, int y
, int x
)
38 SLsmg_gotorc(self
->y
+ y
, self
->x
+ x
);
41 void ui_browser__list_head_seek(struct ui_browser
*self
, off_t offset
, int whence
)
43 struct list_head
*head
= self
->entries
;
44 struct list_head
*pos
;
71 void ui_browser__rb_tree_seek(struct ui_browser
*self
, off_t offset
, int whence
)
73 struct rb_root
*root
= self
->entries
;
101 unsigned int ui_browser__rb_tree_refresh(struct ui_browser
*self
)
106 if (self
->top
== NULL
)
107 self
->top
= rb_first(self
->entries
);
112 ui_browser__gotorc(self
, row
, 0);
113 self
->write(self
, nd
, row
);
114 if (++row
== self
->height
)
122 bool ui_browser__is_current_entry(struct ui_browser
*self
, unsigned row
)
124 return self
->top_idx
+ row
== self
->index
;
127 void ui_browser__refresh_dimensions(struct ui_browser
*self
)
130 newtGetScreenSize(&cols
, &rows
);
132 self
->width
= cols
- 1;
133 self
->height
= rows
- 2;
138 void ui_browser__reset_index(struct ui_browser
*self
)
140 self
->index
= self
->top_idx
= 0;
141 self
->seek(self
, 0, SEEK_SET
);
144 void ui_browser__add_exit_key(struct ui_browser
*self
, int key
)
146 newtFormAddHotKey(self
->form
, key
);
149 void ui_browser__add_exit_keys(struct ui_browser
*self
, int keys
[])
153 while (keys
[i
] && i
< 64) {
154 ui_browser__add_exit_key(self
, keys
[i
]);
159 int ui_browser__show(struct ui_browser
*self
, const char *title
,
160 const char *helpline
, ...)
163 int keys
[] = { NEWT_KEY_UP
, NEWT_KEY_DOWN
, NEWT_KEY_PGUP
,
164 NEWT_KEY_PGDN
, NEWT_KEY_HOME
, NEWT_KEY_END
, ' ',
165 NEWT_KEY_LEFT
, NEWT_KEY_ESCAPE
, 'q', CTRL('c'), 0 };
167 if (self
->form
!= NULL
)
168 newtFormDestroy(self
->form
);
170 ui_browser__refresh_dimensions(self
);
171 self
->form
= newtForm(NULL
, NULL
, 0);
172 if (self
->form
== NULL
)
175 self
->sb
= newtVerticalScrollbar(self
->width
, 1, self
->height
,
177 HE_COLORSET_SELECTED
);
178 if (self
->sb
== NULL
)
182 ui_browser__set_color(self
, NEWT_COLORSET_ROOT
);
183 slsmg_write_nstring(title
, self
->width
);
185 ui_browser__add_exit_keys(self
, keys
);
186 newtFormAddComponent(self
->form
, self
->sb
);
188 va_start(ap
, helpline
);
189 ui_helpline__vpush(helpline
, ap
);
194 void ui_browser__hide(struct ui_browser
*self
)
196 newtFormDestroy(self
->form
);
201 int ui_browser__refresh(struct ui_browser
*self
)
205 newtScrollbarSet(self
->sb
, self
->index
, self
->nr_entries
- 1);
206 row
= self
->refresh(self
);
207 ui_browser__set_color(self
, HE_COLORSET_NORMAL
);
208 SLsmg_fill_region(self
->y
+ row
, self
->x
,
209 self
->height
- row
, self
->width
, ' ');
214 int ui_browser__run(struct ui_browser
*self
)
216 struct newtExitStruct es
;
218 if (ui_browser__refresh(self
) < 0)
224 newtFormRun(self
->form
, &es
);
226 if (es
.reason
!= NEWT_EXIT_HOTKEY
)
230 if (self
->index
== self
->nr_entries
- 1)
233 if (self
->index
== self
->top_idx
+ self
->height
) {
235 self
->seek(self
, +1, SEEK_CUR
);
239 if (self
->index
== 0)
242 if (self
->index
< self
->top_idx
) {
244 self
->seek(self
, -1, SEEK_CUR
);
249 if (self
->top_idx
+ self
->height
> self
->nr_entries
- 1)
252 offset
= self
->height
;
253 if (self
->index
+ offset
> self
->nr_entries
- 1)
254 offset
= self
->nr_entries
- 1 - self
->index
;
255 self
->index
+= offset
;
256 self
->top_idx
+= offset
;
257 self
->seek(self
, +offset
, SEEK_CUR
);
260 if (self
->top_idx
== 0)
263 if (self
->top_idx
< self
->height
)
264 offset
= self
->top_idx
;
266 offset
= self
->height
;
268 self
->index
-= offset
;
269 self
->top_idx
-= offset
;
270 self
->seek(self
, -offset
, SEEK_CUR
);
273 ui_browser__reset_index(self
);
276 offset
= self
->height
- 1;
277 if (offset
>= self
->nr_entries
)
278 offset
= self
->nr_entries
- 1;
280 self
->index
= self
->nr_entries
- 1;
281 self
->top_idx
= self
->index
- offset
;
282 self
->seek(self
, -offset
, SEEK_END
);
287 if (ui_browser__refresh(self
) < 0)
293 unsigned int ui_browser__list_head_refresh(struct ui_browser
*self
)
295 struct list_head
*pos
;
296 struct list_head
*head
= self
->entries
;
299 if (self
->top
== NULL
|| self
->top
== self
->entries
)
300 self
->top
= head
->next
;
304 list_for_each_from(pos
, head
) {
305 ui_browser__gotorc(self
, row
, 0);
306 self
->write(self
, pos
, row
);
307 if (++row
== self
->height
)
314 static struct newtPercentTreeColors
{
315 const char *topColorFg
, *topColorBg
;
316 const char *mediumColorFg
, *mediumColorBg
;
317 const char *normalColorFg
, *normalColorBg
;
318 const char *selColorFg
, *selColorBg
;
319 const char *codeColorFg
, *codeColorBg
;
320 } defaultPercentTreeColors
= {
322 "green", "lightgray",
323 "black", "lightgray",
324 "lightgray", "magenta",
328 void ui_browser__init(void)
330 struct newtPercentTreeColors
*c
= &defaultPercentTreeColors
;
332 sltt_set_color(HE_COLORSET_TOP
, NULL
, c
->topColorFg
, c
->topColorBg
);
333 sltt_set_color(HE_COLORSET_MEDIUM
, NULL
, c
->mediumColorFg
, c
->mediumColorBg
);
334 sltt_set_color(HE_COLORSET_NORMAL
, NULL
, c
->normalColorFg
, c
->normalColorBg
);
335 sltt_set_color(HE_COLORSET_SELECTED
, NULL
, c
->selColorFg
, c
->selColorBg
);
336 sltt_set_color(HE_COLORSET_CODE
, NULL
, c
->codeColorFg
, c
->codeColorBg
);