1 // Scroll class implementation
2
3 #include <std.h>
4 #include "scroll.h"
5 #include "margin.h"
6
expose(XEvent * event,void * arg)7 static void expose(XEvent* event, void* arg)
8 {
9 scroll* s = arg;
10 s->list();
11 }
12
button_press(XEvent * event,void * arg)13 static void button_press(XEvent* event, void* arg)
14 {
15 scroll* s = arg;
16 int i = event->xbutton.y / s->char_height();
17 s->select(i);
18 }
19
scroll(container * parent,int w,int h)20 scroll::scroll(container* parent, int w, int h) :
21 (parent, ExposureMask|ButtonPressMask|ButtonReleaseMask)
22 {
23 set_wh(w * kcwidth(), h * char_height());
24 vs = h;
25 list_files();
26 add_event(Expose, expose, this);
27 add_event(ButtonPress, button_press, this);
28 }
29
list_files()30 void scroll::list_files()
31 {
32 delete_all();
33 FILE* fp = popen("ls -a", "r");
34 char buf[81];
35 while (fgets(buf, 80, fp) != 0)
36 {
37 char* n = strchr(buf, '\n');
38 if (n)
39 *n = 0;
40 add_line(buf);
41 }
42 pclose(fp);
43 }
44
delete_all()45 void scroll::delete_all()
46 {
47 aline* n;
48 for (aline* i = fl; i != 0; i = n)
49 {
50 n = i->down;
51 delete i;
52 }
53 fl = 0;
54 sl = 0;
55 last_line = 0;
56 select_line = 0;
57 ts = 0;
58 }
59
add_line(char * str)60 void scroll::add_line(char* str)
61 {
62 aline* n = new aline;
63 if (last_line)
64 last_line->down = n;
65 n->up = last_line;
66 n->down = 0;
67 strcpy(n->buf, str);
68 last_line = n;
69 if (fl == 0)
70 {
71 fl = n;
72 sp = 0;
73 }
74 ts++;
75 }
76
list()77 void scroll::list()
78 {
79 XClearWindow(display(), window());
80 select_y = -1;
81 int y = char_ascent();
82 for (aline* i = fl; i != 0 && y < height(); i = i->down)
83 {
84 out(i->buf, border_text_m, y);
85 if (i == select_line)
86 {
87 select_y = y-char_ascent();
88 XFillRectangle(display(), window(), igc(),
89 0, select_y, width(), char_height());
90 }
91 sl = i;
92 y += char_height();
93 }
94 sy = y - char_height();
95 }
96
up()97 void scroll::up()
98 {
99 if (fl->up)
100 {
101 fl = fl->up;
102 sp--;
103 XCopyArea(display(), window(), window(), gc(), 0, 0,
104 width(), height() - char_height(), 0, char_height());
105 sl = sl->up;
106 XClearArea(display(), window(), 0, 0, 0, char_height(), False);
107 out(fl->buf, border_text_m, char_ascent());
108 if (fl == select_line)
109 {
110 select_y = 0;
111 XFillRectangle(display(), window(), igc(),
112 0, select_y, width(), char_height());
113 }
114 if (select_line)
115 select_y += char_height();
116 }
117 }
118
down()119 void scroll::down()
120 {
121 if (sl->down)
122 {
123 fl = fl->down;
124 sp++;
125 XCopyArea(display(), window(), window(), gc(), 0, char_height(),
126 width(), height() - char_height(), 0, 0);
127 sl = sl->down;
128 XClearArea(display(), window(), 0, sy-char_ascent(), 0, 0, False);
129 out(sl->buf, border_text_m, sy);
130 if (sl == select_line)
131 {
132 select_y = sy-char_ascent();
133 XFillRectangle(display(), window(), igc(),
134 0, select_y, width(), char_height());
135 }
136 if (select_line)
137 select_y -= char_height();
138 }
139 }
140
set_start(int l)141 void scroll::set_start(int l)
142 {
143 if (l > sp)
144 {
145 while (l > sp && sl->down)
146 {
147 fl = fl->down;
148 sp++;
149 sl = sl->down;
150 }
151 list();
152 }
153 else
154 {
155 while (l < sp && fl->up)
156 {
157 fl = fl->up;
158 sp--;
159 sl = sl->up;
160 }
161 list();
162 }
163 }
164
select(int i)165 void scroll::select(int i)
166 {
167 if (select_line && select_y >= 0 && select_y < height())
168 XFillRectangle(display(), window(), igc(),
169 0, select_y, width(), char_height());
170 select_line = fl;
171 int y = 0;
172 while (i-- > 0)
173 {
174 select_line = select_line->down;
175 y += char_height();
176 }
177 select_y = y;
178 XFillRectangle(display(), window(), igc(),
179 0, select_y, width(), char_height());
180 }
181