3 #include <linux/compiler.h>
4 #include <linux/list.h>
5 #include <linux/rbtree.h>
7 #include <sys/ttydefaults.h>
14 static int ui_browser__percent_color(double percent
, bool current
)
17 return HE_COLORSET_SELECTED
;
18 if (percent
>= MIN_RED
)
19 return HE_COLORSET_TOP
;
20 if (percent
>= MIN_GREEN
)
21 return HE_COLORSET_MEDIUM
;
22 return HE_COLORSET_NORMAL
;
25 void ui_browser__set_color(struct ui_browser
*self __used
, int color
)
27 SLsmg_set_color(color
);
30 void ui_browser__set_percent_color(struct ui_browser
*self
,
31 double percent
, bool current
)
33 int color
= ui_browser__percent_color(percent
, current
);
34 ui_browser__set_color(self
, color
);
37 void ui_browser__gotorc(struct ui_browser
*self
, int y
, int x
)
39 SLsmg_gotorc(self
->y
+ y
, self
->x
+ x
);
42 void ui_browser__list_head_seek(struct ui_browser
*self
, off_t offset
, int whence
)
44 struct list_head
*head
= self
->entries
;
45 struct list_head
*pos
;
72 void ui_browser__rb_tree_seek(struct ui_browser
*self
, off_t offset
, int whence
)
74 struct rb_root
*root
= self
->entries
;
102 unsigned int ui_browser__rb_tree_refresh(struct ui_browser
*self
)
107 if (self
->top
== NULL
)
108 self
->top
= rb_first(self
->entries
);
113 ui_browser__gotorc(self
, row
, 0);
114 self
->write(self
, nd
, row
);
115 if (++row
== self
->height
)
123 bool ui_browser__is_current_entry(struct ui_browser
*self
, unsigned row
)
125 return self
->top_idx
+ row
== self
->index
;
128 void ui_browser__refresh_dimensions(struct ui_browser
*self
)
131 newtGetScreenSize(&cols
, &rows
);
133 self
->width
= cols
- 1;
134 self
->height
= rows
- 2;
139 void ui_browser__reset_index(struct ui_browser
*self
)
141 self
->index
= self
->top_idx
= 0;
142 self
->seek(self
, 0, SEEK_SET
);
145 void ui_browser__add_exit_key(struct ui_browser
*self
, int key
)
147 newtFormAddHotKey(self
->form
, key
);
150 void ui_browser__add_exit_keys(struct ui_browser
*self
, int keys
[])
154 while (keys
[i
] && i
< 64) {
155 ui_browser__add_exit_key(self
, keys
[i
]);
160 int ui_browser__show(struct ui_browser
*self
, const char *title
,
161 const char *helpline
, ...)
164 int keys
[] = { NEWT_KEY_UP
, NEWT_KEY_DOWN
, NEWT_KEY_PGUP
,
165 NEWT_KEY_PGDN
, NEWT_KEY_HOME
, NEWT_KEY_END
, ' ',
166 NEWT_KEY_LEFT
, NEWT_KEY_ESCAPE
, 'q', CTRL('c'), 0 };
168 if (self
->form
!= NULL
)
169 newtFormDestroy(self
->form
);
171 ui_browser__refresh_dimensions(self
);
172 self
->form
= newtForm(NULL
, NULL
, 0);
173 if (self
->form
== NULL
)
176 self
->sb
= newtVerticalScrollbar(self
->width
, 1, self
->height
,
178 HE_COLORSET_SELECTED
);
179 if (self
->sb
== NULL
)
183 ui_browser__set_color(self
, NEWT_COLORSET_ROOT
);
184 slsmg_write_nstring(title
, self
->width
);
186 ui_browser__add_exit_keys(self
, keys
);
187 newtFormAddComponent(self
->form
, self
->sb
);
189 va_start(ap
, helpline
);
190 ui_helpline__vpush(helpline
, ap
);
195 void ui_browser__hide(struct ui_browser
*self
)
197 newtFormDestroy(self
->form
);
202 int ui_browser__refresh(struct ui_browser
*self
)
206 newtScrollbarSet(self
->sb
, self
->index
, self
->nr_entries
- 1);
207 row
= self
->refresh(self
);
208 ui_browser__set_color(self
, HE_COLORSET_NORMAL
);
209 SLsmg_fill_region(self
->y
+ row
, self
->x
,
210 self
->height
- row
, self
->width
, ' ');
215 int ui_browser__run(struct ui_browser
*self
)
217 struct newtExitStruct es
;
219 if (ui_browser__refresh(self
) < 0)
225 newtFormRun(self
->form
, &es
);
227 if (es
.reason
!= NEWT_EXIT_HOTKEY
)
231 if (self
->index
== self
->nr_entries
- 1)
234 if (self
->index
== self
->top_idx
+ self
->height
) {
236 self
->seek(self
, +1, SEEK_CUR
);
240 if (self
->index
== 0)
243 if (self
->index
< self
->top_idx
) {
245 self
->seek(self
, -1, SEEK_CUR
);
250 if (self
->top_idx
+ self
->height
> self
->nr_entries
- 1)
253 offset
= self
->height
;
254 if (self
->index
+ offset
> self
->nr_entries
- 1)
255 offset
= self
->nr_entries
- 1 - self
->index
;
256 self
->index
+= offset
;
257 self
->top_idx
+= offset
;
258 self
->seek(self
, +offset
, SEEK_CUR
);
261 if (self
->top_idx
== 0)
264 if (self
->top_idx
< self
->height
)
265 offset
= self
->top_idx
;
267 offset
= self
->height
;
269 self
->index
-= offset
;
270 self
->top_idx
-= offset
;
271 self
->seek(self
, -offset
, SEEK_CUR
);
274 ui_browser__reset_index(self
);
277 offset
= self
->height
- 1;
278 if (offset
>= self
->nr_entries
)
279 offset
= self
->nr_entries
- 1;
281 self
->index
= self
->nr_entries
- 1;
282 self
->top_idx
= self
->index
- offset
;
283 self
->seek(self
, -offset
, SEEK_END
);
288 if (ui_browser__refresh(self
) < 0)
294 unsigned int ui_browser__list_head_refresh(struct ui_browser
*self
)
296 struct list_head
*pos
;
297 struct list_head
*head
= self
->entries
;
300 if (self
->top
== NULL
|| self
->top
== self
->entries
)
301 self
->top
= head
->next
;
305 list_for_each_from(pos
, head
) {
306 ui_browser__gotorc(self
, row
, 0);
307 self
->write(self
, pos
, row
);
308 if (++row
== self
->height
)
315 static struct newtPercentTreeColors
{
316 const char *topColorFg
, *topColorBg
;
317 const char *mediumColorFg
, *mediumColorBg
;
318 const char *normalColorFg
, *normalColorBg
;
319 const char *selColorFg
, *selColorBg
;
320 const char *codeColorFg
, *codeColorBg
;
321 } defaultPercentTreeColors
= {
323 "green", "lightgray",
324 "black", "lightgray",
325 "lightgray", "magenta",
329 void ui_browser__init(void)
331 struct newtPercentTreeColors
*c
= &defaultPercentTreeColors
;
333 sltt_set_color(HE_COLORSET_TOP
, NULL
, c
->topColorFg
, c
->topColorBg
);
334 sltt_set_color(HE_COLORSET_MEDIUM
, NULL
, c
->mediumColorFg
, c
->mediumColorBg
);
335 sltt_set_color(HE_COLORSET_NORMAL
, NULL
, c
->normalColorFg
, c
->normalColorBg
);
336 sltt_set_color(HE_COLORSET_SELECTED
, NULL
, c
->selColorFg
, c
->selColorBg
);
337 sltt_set_color(HE_COLORSET_CODE
, NULL
, c
->codeColorFg
, c
->codeColorBg
);