File: draw-lines.py

package info (click to toggle)
golly 3.2-2
  • links: PTS
  • area: main
  • in suites: buster
  • size: 19,516 kB
  • sloc: cpp: 69,819; ansic: 25,894; python: 7,921; sh: 4,267; objc: 3,721; java: 2,781; xml: 1,362; makefile: 530; perl: 69
file content (125 lines) | stat: -rw-r--r-- 4,007 bytes parent folder | download | duplicates (5)
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
# Allow user to draw one or more straight lines by clicking end points.
# Author: Andrew Trevorrow (andrew@trevorrow.com), Jan 2011.

import golly as g

# ------------------------------------------------------------------------------

def drawline(x1, y1, x2, y2):
    # draw a line of cells from x1,y1 to x2,y2 using Bresenham's algorithm;
    # we also return the old cells in the line so we can erase line later
    oldcells = []
    # note that x1,y1 has already been drawn
    # oldcells.append( (x1, y1, g.getcell(x1, y1)) )
    # g.setcell(x1, y1, drawstate)
    if x1 == x2 and y1 == y2:
        g.update()
        return oldcells

    dx = x2 - x1
    ax = abs(dx) * 2
    sx = 1
    if dx < 0: sx = -1
    dy = y2 - y1
    ay = abs(dy) * 2
    sy = 1
    if dy < 0: sy = -1

    if ax > ay:
        d = ay - (ax / 2)
        while x1 != x2:
            oldcells.append( (x1, y1, g.getcell(x1, y1)) )
            g.setcell(x1, y1, drawstate)
            if d >= 0:
                y1 += sy
                d -= ax
            x1 += sx
            d += ay
    else:
        d = ax - (ay / 2)
        while y1 != y2:
            oldcells.append( (x1, y1, g.getcell(x1, y1)) )
            g.setcell(x1, y1, drawstate)
            if d >= 0:
                x1 += sx
                d -= ay
            y1 += sy
            d += ax

    oldcells.append( (x2, y2, g.getcell(x2, y2)) )
    g.setcell(x2, y2, drawstate)
    g.update()
    return oldcells

# ------------------------------------------------------------------------------

def eraseline(oldcells):
    for t in oldcells:
        x, y, s = t
        g.setcell(x, y, s)

# ------------------------------------------------------------------------------

def drawlines():
    global oldline, firstcell
    started = False
    oldmouse = ""
    while True:
        event = g.getevent()
        if event.startswith("click"):
            # event is a string like "click 10 20 left altctrlshift"
            evt, x, y, butt, mods = event.split()
            oldmouse = x + ' ' + y
            if started:
                # draw permanent line from start pos to end pos
                endx = int(x)
                endy = int(y)
                drawline(startx, starty, endx, endy)
                # this is also the start of another line
                startx = endx
                starty = endy
                oldline = []
                firstcell = []
            else:
                # start first line
                startx = int(x)
                starty = int(y)
                firstcell = [ startx, starty, g.getcell(startx, starty) ]
                g.setcell(startx, starty, drawstate)
                g.update()
                started = True
                g.show("Click where to end this line (and start another line)...")
        else:
            # event might be "" or "key m none"
            if len(event) > 0: g.doevent(event)
            mousepos = g.getxy()
            if started and len(mousepos) == 0:
                # erase old line if mouse is not over grid
                if len(oldline) > 0:
                    eraseline(oldline)
                    oldline = []
                    g.update()
            elif started and len(mousepos) > 0 and mousepos != oldmouse:
                # mouse has moved, so erase old line (if any) and draw new line
                if len(oldline) > 0: eraseline(oldline)
                x, y = mousepos.split()
                oldline = drawline(startx, starty, int(x), int(y))
                oldmouse = mousepos

# ------------------------------------------------------------------------------

g.show("Click where to start line...")
oldcursor = g.getcursor()
g.setcursor("Draw")
drawstate = g.getoption("drawingstate")
oldline = []
firstcell = []    # pos and state of the 1st cell clicked

try:
    drawlines()
finally:
    g.setcursor(oldcursor)
    if len(oldline) > 0: eraseline(oldline)
    if len(firstcell) > 0:
        x, y, s = firstcell
        g.setcell(x, y, s)