Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <draw.h>
4
#include <thread.h>
5
#include <cursor.h>
6
#include <mouse.h>
7
#include <keyboard.h>
8
#include <frame.h>
9
#include <fcall.h>
10
#include <plumb.h>
11
#include "dat.h"
12
#include "fns.h"
13
 
14
static Image *scrtmp;
15
 
16
static
17
Rectangle
18
scrpos(Rectangle r, uint p0, uint p1, uint tot)
19
{
20
	Rectangle q;
21
	int h;
22
 
23
	q = r;
24
	h = q.max.y-q.min.y;
25
	if(tot == 0)
26
		return q;
27
	if(tot > 1024*1024){
28
		tot>>=10;
29
		p0>>=10;
30
		p1>>=10;
31
	}
32
	if(p0 > 0)
33
		q.min.y += h*p0/tot;
34
	if(p1 < tot)
35
		q.max.y -= h*(tot-p1)/tot;
36
	if(q.max.y < q.min.y+2){
37
		if(q.min.y+2 <= r.max.y)
38
			q.max.y = q.min.y+2;
39
		else
40
			q.min.y = q.max.y-2;
41
	}
42
	return q;
43
}
44
 
45
void
46
scrlresize(void)
47
{
48
	freeimage(scrtmp);
49
	scrtmp = allocimage(display, Rect(0, 0, 32, screen->r.max.y), screen->chan, 0, DNofill);
50
	if(scrtmp == nil)
51
		error("scroll alloc");
52
}
53
 
54
void
55
textscrdraw(Text *t)
56
{
57
	Rectangle r, r1, r2;
58
	Image *b;
59
 
60
	if(t->w==nil || t!=&t->w->body)
61
		return;
62
	if(scrtmp == nil)
63
		scrlresize();
64
	r = t->scrollr;
65
	b = scrtmp;
66
	r1 = r;
67
	r1.min.x = 0;
68
	r1.max.x = Dx(r);
69
	r2 = scrpos(r1, t->org, t->org+t->nchars, t->file->nc);
70
	if(!eqrect(r2, t->lastsr)){
71
		t->lastsr = r2;
72
		draw(b, r1, t->cols[BORD], nil, ZP);
73
		draw(b, r2, t->cols[BACK], nil, ZP);
74
		r2.min.x = r2.max.x-1;
75
		draw(b, r2, t->cols[BORD], nil, ZP);
76
		draw(t->b, r, b, nil, Pt(0, r1.min.y));
77
/*flushimage(display, 1);/*BUG?*/
78
	}
79
}
80
 
81
void
82
scrsleep(uint dt)
83
{
84
	Timer	*timer;
85
	static Alt alts[3];
86
 
87
	timer = timerstart(dt);
88
	alts[0].c = timer->c;
89
	alts[0].v = nil;
90
	alts[0].op = CHANRCV;
91
	alts[1].c = mousectl->c;
92
	alts[1].v = &mousectl->Mouse;
93
	alts[1].op = CHANRCV;
94
	alts[2].op = CHANEND;
95
	for(;;)
96
		switch(alt(alts)){
97
		case 0:
98
			timerstop(timer);
99
			return;
100
		case 1:
101
			timercancel(timer);
102
			return;
103
		}
104
}
105
 
106
void
107
textscroll(Text *t, int but)
108
{
109
	uint p0, oldp0;
110
	Rectangle s;
111
	int x, y, my, h, first;
112
 
113
	s = insetrect(t->scrollr, 1);
114
	h = s.max.y-s.min.y;
115
	x = (s.min.x+s.max.x)/2;
116
	oldp0 = ~0;
117
	first = TRUE;
118
	do{
119
		flushimage(display, 1);
120
		my = mouse->xy.y;
121
		if(my < s.min.y)
122
			my = s.min.y;
123
		if(my >= s.max.y)
124
			my = s.max.y;
125
		if(!eqpt(mouse->xy, Pt(x, my))){
126
			moveto(mousectl, Pt(x, my));
127
			readmouse(mousectl);		/* absorb event generated by moveto() */
128
		}
129
		if(but == 2){
130
			y = my;
131
			p0 = (vlong)t->file->nc*(y-s.min.y)/h;
132
			if(p0 >= t->q1)
133
				p0 = textbacknl(t, p0, 2);
134
			if(oldp0 != p0)
135
				textsetorigin(t, p0, FALSE);
136
			oldp0 = p0;
137
			readmouse(mousectl);
138
			continue;
139
		}
140
		if(but == 1)
141
			p0 = textbacknl(t, t->org, (my-s.min.y)/t->font->height);
142
		else
143
			p0 = t->org+frcharofpt(t, Pt(s.max.x, my));
144
		if(oldp0 != p0)
145
			textsetorigin(t, p0, TRUE);
146
		oldp0 = p0;
147
		/* debounce */
148
		if(first){
149
			flushimage(display, 1);
150
			sleep(200);
151
			nbrecv(mousectl->c, &mousectl->Mouse);
152
			first = FALSE;
153
		}
154
		scrsleep(80);
155
	}while(mouse->buttons & (1<<(but-1)));
156
	while(mouse->buttons)
157
		readmouse(mousectl);
158
}