1 #include <stdlib.h>
2 #include <unistd.h>
3 #include <string.h>
4 #include <glib.h>
5 #include <ncurses.h>
7 #include "support.h"
8 #include "command.h"
9 #include "list_window.h"
11 list_window_t *
12 list_window_init(WINDOW *w, int width, int height)
13 {
14 list_window_t *lw;
16 lw = malloc(sizeof(list_window_t));
17 memset(lw, 0, sizeof(list_window_t));
18 lw->w = w;
19 lw->cols = width;
20 lw->rows = height;
21 lw->clear = 1;
22 return lw;
23 }
25 list_window_t *
26 list_window_free(list_window_t *lw)
27 {
28 if( lw )
29 {
30 memset(lw, 0, sizeof(list_window_t));
31 free(lw);
32 }
33 return NULL;
34 }
36 void
37 list_window_reset(list_window_t *lw)
38 {
39 lw->selected = 0;
40 lw->start = 0;
41 lw->clear = 1;
42 }
44 void
45 list_window_set_selected(list_window_t *lw, int n)
46 {
47 lw->selected=n;
48 }
50 void
51 list_window_next(list_window_t *lw, int length)
52 {
53 if( lw->selected < length-1 )
54 lw->selected++;
55 }
57 void
58 list_window_previous(list_window_t *lw)
59 {
60 if( lw->selected > 0 )
61 lw->selected--;
62 }
64 void
65 list_window_first(list_window_t *lw)
66 {
67 lw->selected = 0;
68 }
70 void
71 list_window_last(list_window_t *lw, int length)
72 {
73 lw->selected = length-1;
74 }
76 void
77 list_window_next_page(list_window_t *lw, int length)
78 {
79 int step = lw->rows-1;
80 if( step<= 0 )
81 return;
82 if( lw->selected+step < length-1 )
83 lw->selected+=step;
84 else
85 return list_window_last(lw,length);
86 }
88 void
89 list_window_previous_page(list_window_t *lw)
90 {
91 int step = lw->rows-1;
92 if( step<= 0 )
93 return;
94 if( lw->selected-step > 0 )
95 lw->selected-=step;
96 else
97 list_window_first(lw);
98 }
101 void
102 list_window_paint(list_window_t *lw,
103 list_window_callback_fn_t callback,
104 void *callback_data)
105 {
106 int i;
108 while( lw->selected < lw->start )
109 {
110 lw->start--;
111 lw->clear=1;
112 }
113 while( lw->selected >= lw->start+lw->rows )
114 {
115 lw->start++;
116 lw->clear=1;
117 }
118 if( lw->clear )
119 {
120 wclear(lw->w);
121 lw->clear=0;
122 }
124 for(i=0; i<lw->rows; i++)
125 {
126 int highlight;
127 char *label;
129 label = (callback) (lw->start+i, &highlight, callback_data);
130 if( label )
131 {
132 wmove(lw->w, i, 0);
133 if( highlight )
134 wattron(lw->w, A_BOLD);
135 if( lw->start+i == lw->selected )
136 wattron(lw->w, A_REVERSE);
138 waddnstr(lw->w, label, lw->cols);
140 if( highlight )
141 wattroff(lw->w, A_BOLD);
142 if( lw->start+i == lw->selected )
143 wattroff(lw->w, A_REVERSE);
144 }
145 }
146 }
149 int
150 list_window_find(list_window_t *lw,
151 list_window_callback_fn_t callback,
152 void *callback_data,
153 char *str)
154 {
155 int h;
156 int i = lw->selected+1;
157 char *label;
159 while( (label=(callback) (i,&h,callback_data)) )
160 {
161 if( str && label && strcasestr(label, str) )
162 {
163 lw->selected = i;
164 return 0;
165 }
166 i++;
167 }
168 return 1;
169 }
172 /* perform basic list window commands (movement) */
173 int
174 list_window_cmd(list_window_t *lw, int rows, command_t cmd)
175 {
176 switch(cmd)
177 {
178 case CMD_LIST_PREVIOUS:
179 list_window_previous(lw);
180 lw->repaint=1;
181 break;
182 case CMD_LIST_NEXT:
183 list_window_next(lw, rows);
184 lw->repaint=1;
185 break;
186 case CMD_LIST_FIRST:
187 list_window_first(lw);
188 lw->repaint = 1;
189 break;
190 case CMD_LIST_LAST:
191 list_window_last(lw, rows);
192 lw->repaint = 1;
193 break;
194 case CMD_LIST_NEXT_PAGE:
195 list_window_next_page(lw, rows);
196 lw->repaint = 1;
197 break;
198 case CMD_LIST_PREVIOUS_PAGE:
199 list_window_previous_page(lw);
200 lw->repaint = 1;
201 break;
202 default:
203 return 0;
204 }
205 return 1;
206 }