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
);