-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcursel.c
140 lines (114 loc) · 2.22 KB
/
cursel.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include "mace.h"
struct cursel *
curseladd(struct mace *m, struct textbox *t,
int type, size_t pos)
{
struct cursel *c, **h;
c = malloc(sizeof(struct cursel));
if (c == NULL) {
return NULL;
}
c->tb = t;
c->type = type | CURSEL_right;
c->cur = 0;
c->start = pos;
c->end = pos;
/* Insert new cursel in order */
h = &m->cursels;
while (*h != NULL) {
if ((*h)->tb == c->tb && c->start < (*h)->start) {
break;
}
h = &(*h)->next;
}
c->next = *h;
*h = c;
return c;
}
void
curselremove(struct mace *m, struct cursel *c)
{
struct cursel **p;
if (c == NULL) {
return;
}
for (p = &m->cursels; *p != NULL
&& *p != c; p = &(*p)->next)
;
if (*p == c) {
*p = c->next;
}
free(c);
}
void
curselremoveall(struct mace *m)
{
struct cursel *s, *n;
for (s = m->cursels; s != NULL; s = n) {
n = s->next;
free(s);
}
m->cursels = NULL;
}
bool
curselupdate(struct cursel *s, size_t pos)
{
if ((s->type & CURSEL_right) == CURSEL_right) {
if (pos < s->start) {
/* Going left */
s->type &= ~CURSEL_right;
s->end = s->start;
s->start = pos;
s->cur = 0;
return true;
} else if (pos != s->end) {
/* Updating end */
s->end = pos;
s->cur = s->end - s->start;
return true;
}
} else {
if (pos > s->end) {
/* Going right. */
s->type |= CURSEL_right;
s->start = s->end;
s->end = pos;
s->cur = s->end - s->start;
return true;
} else if (pos != s->start) {
/* Changing start */
s->start = pos;
s->cur = 0;
return true;
}
}
/* No change */
return false;
}
struct cursel *
curselat(struct mace *m, struct textbox *t, size_t pos)
{
struct cursel *s;
for (s = m->cursels; s != NULL; s = s->next) {
if (s->tb == t && s->start <= pos && pos <= s->end) {
return s;
}
}
return NULL;
}
/* TODO: Improve this. */
void
shiftcursels(struct mace *m, struct textbox *t,
size_t from, int dist)
{
struct cursel *s;
for (s = m->cursels; s != NULL; s = s->next) {
if (s->tb != t) {
continue;
}
if (s->start >= from) {
s->start += dist;
s->end += dist;
}
}
}