all repos — acme @ 2908f1ff9b0a64cfba245aa0a748d8babc889e12

fork of the acme editor from plan9port - keybinds, tweaks, config.h, etc

libframe/frselect.c (raw)

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
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <mouse.h>
#include "frame.h"

static int region(int a, int b) {
  if (a < b)
    return -1;
  if (a == b)
    return 0;
  return 1;
}

void frselect(Frame* f, Mousectl* mc) /* when called, button 1 is down */
{
  ulong p0, p1, q;
  Point mp, pt0, pt1, qt;
  int reg, b, scrled;

  mp = mc->m.xy;
  b = mc->m.buttons;

  f->modified = 0;
  frdrawsel(f, frptofchar(f, f->p0), f->p0, f->p1, 0);
  p0 = p1 = frcharofpt(f, mp);
  f->p0 = p0;
  f->p1 = p1;
  pt0 = frptofchar(f, p0);
  pt1 = frptofchar(f, p1);
  frdrawsel(f, pt0, p0, p1, 1);
  reg = 0;
  do {
    scrled = 0;
    if (f->scroll) {
      if (mp.y < f->r.min.y) {
        (*f->scroll)(f, -(f->r.min.y - mp.y) / (int)f->font->height - 1);
        p0 = f->p1;
        p1 = f->p0;
        scrled = 1;
      } else if (mp.y > f->r.max.y) {
        (*f->scroll)(f, (mp.y - f->r.max.y) / (int)f->font->height + 1);
        p0 = f->p0;
        p1 = f->p1;
        scrled = 1;
      }
      if (scrled) {
        if (reg != region(p1, p0))
          q = p0, p0 = p1, p1 = q; /* undo the swap that will happen below */
        pt0 = frptofchar(f, p0);
        pt1 = frptofchar(f, p1);
        reg = region(p1, p0);
      }
    }
    q = frcharofpt(f, mp);
    if (p1 != q) {
      if (reg != region(q, p0)) { /* crossed starting point; reset */
        if (reg > 0)
          frdrawsel(f, pt0, p0, p1, 0);
        else if (reg < 0)
          frdrawsel(f, pt1, p1, p0, 0);
        p1 = p0;
        pt1 = pt0;
        reg = region(q, p0);
        if (reg == 0)
          frdrawsel(f, pt0, p0, p1, 1);
      }
      qt = frptofchar(f, q);
      if (reg > 0) {
        if (q > p1)
          frdrawsel(f, pt1, p1, q, 1);
        else if (q < p1)
          frdrawsel(f, qt, q, p1, 0);
      } else if (reg < 0) {
        if (q > p1)
          frdrawsel(f, pt1, p1, q, 0);
        else
          frdrawsel(f, qt, q, p1, 1);
      }
      p1 = q;
      pt1 = qt;
    }
    f->modified = 0;
    if (p0 < p1) {
      f->p0 = p0;
      f->p1 = p1;
    } else {
      f->p0 = p1;
      f->p1 = p0;
    }
    if (scrled)
      (*f->scroll)(f, 0);
    flushimage(f->display, 1);
    if (!scrled)
      readmouse(mc);
    mp = mc->m.xy;
  } while (mc->m.buttons == b);
}

void frselectpaint(Frame* f, Point p0, Point p1, Image* col) {
  int n;
  Point q0, q1;

  q0 = p0;
  q1 = p1;
  q0.y += f->font->height;
  q1.y += f->font->height;
  n = (p1.y - p0.y) / f->font->height;
  if (f->b == nil)
    drawerror(f->display, "frselectpaint b==0");
  if (p0.y == f->r.max.y)
    return;
  if (n == 0)
    draw(f->b, Rpt(p0, q1), col, nil, ZP);
  else {
    if (p0.x >= f->r.max.x)
      p0.x = f->r.max.x - 1;
    draw(f->b, Rect(p0.x, p0.y, f->r.max.x, q0.y), col, nil, ZP);
    if (n > 1)
      draw(f->b, Rect(f->r.min.x, q0.y, f->r.max.x, p1.y), col, nil, ZP);
    draw(f->b, Rect(f->r.min.x, p1.y, q1.x, q1.y), col, nil, ZP);
  }
}