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 void __ui_browser__show_title(struct ui_browser
*browser
, const char *title
)
163 ui_browser__set_color(browser
, NEWT_COLORSET_ROOT
);
164 slsmg_write_nstring(title
, browser
->width
);
167 void ui_browser__show_title(struct ui_browser
*browser
, const char *title
)
169 pthread_mutex_lock(&ui__lock
);
170 __ui_browser__show_title(browser
, title
);
171 pthread_mutex_unlock(&ui__lock
);
174 int ui_browser__show(struct ui_browser
*self
, const char *title
,
175 const char *helpline
, ...)
178 int keys
[] = { NEWT_KEY_UP
, NEWT_KEY_DOWN
, NEWT_KEY_PGUP
,
179 NEWT_KEY_PGDN
, NEWT_KEY_HOME
, NEWT_KEY_END
, ' ',
180 NEWT_KEY_LEFT
, NEWT_KEY_ESCAPE
, 'q', CTRL('c'), 0 };
182 if (self
->form
!= NULL
)
183 newtFormDestroy(self
->form
);
185 ui_browser__refresh_dimensions(self
);
186 self
->form
= newtForm(NULL
, NULL
, 0);
187 if (self
->form
== NULL
)
190 self
->sb
= newtVerticalScrollbar(self
->width
, 1, self
->height
,
192 HE_COLORSET_SELECTED
);
193 if (self
->sb
== NULL
)
196 pthread_mutex_lock(&ui__lock
);
197 __ui_browser__show_title(self
, title
);
199 ui_browser__add_exit_keys(self
, keys
);
200 newtFormAddComponent(self
->form
, self
->sb
);
202 va_start(ap
, helpline
);
203 ui_helpline__vpush(helpline
, ap
);
205 pthread_mutex_unlock(&ui__lock
);
209 void ui_browser__hide(struct ui_browser
*self
)
211 pthread_mutex_lock(&ui__lock
);
212 newtFormDestroy(self
->form
);
215 pthread_mutex_unlock(&ui__lock
);
218 int ui_browser__refresh(struct ui_browser
*self
)
222 pthread_mutex_lock(&ui__lock
);
223 newtScrollbarSet(self
->sb
, self
->index
, self
->nr_entries
- 1);
224 row
= self
->refresh(self
);
225 ui_browser__set_color(self
, HE_COLORSET_NORMAL
);
226 SLsmg_fill_region(self
->y
+ row
, self
->x
,
227 self
->height
- row
, self
->width
, ' ');
228 pthread_mutex_unlock(&ui__lock
);
233 int ui_browser__run(struct ui_browser
*self
)
235 struct newtExitStruct es
;
237 if (ui_browser__refresh(self
) < 0)
243 newtFormRun(self
->form
, &es
);
245 if (es
.reason
!= NEWT_EXIT_HOTKEY
)
249 if (self
->index
== self
->nr_entries
- 1)
252 if (self
->index
== self
->top_idx
+ self
->height
) {
254 self
->seek(self
, +1, SEEK_CUR
);
258 if (self
->index
== 0)
261 if (self
->index
< self
->top_idx
) {
263 self
->seek(self
, -1, SEEK_CUR
);
268 if (self
->top_idx
+ self
->height
> self
->nr_entries
- 1)
271 offset
= self
->height
;
272 if (self
->index
+ offset
> self
->nr_entries
- 1)
273 offset
= self
->nr_entries
- 1 - self
->index
;
274 self
->index
+= offset
;
275 self
->top_idx
+= offset
;
276 self
->seek(self
, +offset
, SEEK_CUR
);
279 if (self
->top_idx
== 0)
282 if (self
->top_idx
< self
->height
)
283 offset
= self
->top_idx
;
285 offset
= self
->height
;
287 self
->index
-= offset
;
288 self
->top_idx
-= offset
;
289 self
->seek(self
, -offset
, SEEK_CUR
);
292 ui_browser__reset_index(self
);
295 offset
= self
->height
- 1;
296 if (offset
>= self
->nr_entries
)
297 offset
= self
->nr_entries
- 1;
299 self
->index
= self
->nr_entries
- 1;
300 self
->top_idx
= self
->index
- offset
;
301 self
->seek(self
, -offset
, SEEK_END
);
306 if (ui_browser__refresh(self
) < 0)
312 unsigned int ui_browser__list_head_refresh(struct ui_browser
*self
)
314 struct list_head
*pos
;
315 struct list_head
*head
= self
->entries
;
318 if (self
->top
== NULL
|| self
->top
== self
->entries
)
319 self
->top
= head
->next
;
323 list_for_each_from(pos
, head
) {
324 ui_browser__gotorc(self
, row
, 0);
325 self
->write(self
, pos
, row
);
326 if (++row
== self
->height
)
333 static struct newtPercentTreeColors
{
334 const char *topColorFg
, *topColorBg
;
335 const char *mediumColorFg
, *mediumColorBg
;
336 const char *normalColorFg
, *normalColorBg
;
337 const char *selColorFg
, *selColorBg
;
338 const char *codeColorFg
, *codeColorBg
;
339 } defaultPercentTreeColors
= {
341 "green", "lightgray",
342 "black", "lightgray",
343 "lightgray", "magenta",
347 void ui_browser__init(void)
349 struct newtPercentTreeColors
*c
= &defaultPercentTreeColors
;
351 sltt_set_color(HE_COLORSET_TOP
, NULL
, c
->topColorFg
, c
->topColorBg
);
352 sltt_set_color(HE_COLORSET_MEDIUM
, NULL
, c
->mediumColorFg
, c
->mediumColorBg
);
353 sltt_set_color(HE_COLORSET_NORMAL
, NULL
, c
->normalColorFg
, c
->normalColorBg
);
354 sltt_set_color(HE_COLORSET_SELECTED
, NULL
, c
->selColorFg
, c
->selColorBg
);
355 sltt_set_color(HE_COLORSET_CODE
, NULL
, c
->codeColorFg
, c
->codeColorBg
);