2 * Copyright 2004-2005 Timo Hirvonen
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
26 static void sel_changed(struct window
*win
)
33 struct window
*window_new(int (*get_prev
)(struct iter
*), int (*get_next
)(struct iter
*))
37 win
= xnew(struct window
, 1);
38 win
->get_next
= get_next
;
39 win
->get_prev
= get_prev
;
40 win
->sel_changed
= NULL
;
43 iter_init(&win
->head
);
49 void window_free(struct window
*win
)
54 void window_set_empty(struct window
*win
)
56 iter_init(&win
->head
);
62 void window_set_contents(struct window
*win
, void *head
)
66 win
->head
.data0
= head
;
67 win
->head
.data1
= NULL
;
68 win
->head
.data2
= NULL
;
70 win
->get_next(&first
);
76 void window_set_nr_rows(struct window
*win
, int nr_rows
)
82 win
->nr_rows
= nr_rows
;
88 void window_up(struct window
*win
, int rows
)
92 for (i
= 0; i
< rows
; i
++) {
93 struct iter prev
= win
->sel
;
95 if (!win
->get_prev(&prev
))
97 if (iters_equal(&win
->sel
, &win
->top
))
105 void window_down(struct window
*win
, int rows
)
108 int delta
, sel_down
, top_down
;
110 /* distance between top and sel */
113 while (!iters_equal(&iter
, &win
->sel
)) {
114 win
->get_next(&iter
);
118 for (sel_down
= 0; sel_down
< rows
; sel_down
++) {
120 if (!win
->get_next(&iter
))
125 top_down
= sel_down
- (win
->nr_rows
- delta
- 1);
126 while (top_down
> 0) {
127 win
->get_next(&win
->top
);
135 * minimize number of empty lines visible
136 * make sure selection is visible
138 void window_changed(struct window
*win
)
143 if (iter_is_null(&win
->head
)) {
144 BUG_ON(!iter_is_null(&win
->top
));
145 BUG_ON(!iter_is_null(&win
->sel
));
148 BUG_ON(iter_is_null(&win
->top
));
149 BUG_ON(iter_is_null(&win
->sel
));
151 /* make sure top and sel point to real row if possible */
152 if (iter_is_head(&win
->top
)) {
153 win
->get_next(&win
->top
);
159 /* make sure the selected row is visible */
161 /* get distance between top and sel */
164 while (!iters_equal(&iter
, &win
->sel
)) {
165 if (!win
->get_next(&iter
)) {
166 /* sel < top, scroll up until top == sel */
167 while (!iters_equal(&win
->top
, &win
->sel
))
168 win
->get_prev(&win
->top
);
174 /* scroll down until sel is visible */
175 while (delta
> win
->nr_rows
- 1) {
176 win
->get_next(&win
->top
);
180 /* minimize number of empty lines shown */
183 while (rows
< win
->nr_rows
) {
184 if (!win
->get_next(&iter
))
188 while (rows
< win
->nr_rows
) {
190 if (!win
->get_prev(&iter
))
198 void window_row_vanishes(struct window
*win
, struct iter
*iter
)
200 struct iter
new = *iter
;
202 BUG_ON(iter
->data0
!= win
->head
.data0
);
203 if (!win
->get_next(&new)) {
207 if (iters_equal(&win
->top
, iter
))
209 if (iters_equal(&win
->sel
, iter
)) {
216 int window_get_top(struct window
*win
, struct iter
*iter
)
219 return !iter_is_empty(iter
);
222 int window_get_sel(struct window
*win
, struct iter
*iter
)
225 return !iter_is_empty(iter
);
228 int window_get_prev(struct window
*win
, struct iter
*iter
)
230 return win
->get_prev(iter
);
233 int window_get_next(struct window
*win
, struct iter
*iter
)
235 return win
->get_next(iter
);
238 void window_set_sel(struct window
*win
, struct iter
*iter
)
243 BUG_ON(iter_is_empty(&win
->top
));
244 BUG_ON(iter_is_empty(iter
));
245 BUG_ON(iter
->data0
!= win
->head
.data0
);
247 if (iters_equal(&win
->sel
, iter
))
254 while (!iters_equal(&tmp
, &win
->top
)) {
262 while (!iters_equal(&tmp
, &win
->sel
)) {
263 BUG_ON(!win
->get_next(&tmp
));
269 while (sel_nr
- top_nr
>= win
->nr_rows
) {
270 win
->get_next(&win
->top
);
276 void window_goto_top(struct window
*win
)
281 win
->sel
= win
->head
;
282 win
->get_next(&win
->sel
);
284 if (!iters_equal(&old_sel
, &win
->sel
))
288 void window_goto_bottom(struct window
*win
)
294 win
->sel
= win
->head
;
295 win
->get_prev(&win
->sel
);
297 count
= win
->nr_rows
- 1;
299 struct iter iter
= win
->top
;
301 if (!win
->get_prev(&iter
))
306 if (!iters_equal(&old_sel
, &win
->sel
))
310 void window_page_up(struct window
*win
)
312 window_up(win
, win
->nr_rows
- 1);
315 void window_page_down(struct window
*win
)
317 window_down(win
, win
->nr_rows
- 1);
320 int window_get_nr_rows(struct window
*win
)