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