File: draw-lines.py

package info (click to toggle)
golly 2.3-1
  • links: PTS
  • area: main
  • in suites: wheezy
  • size: 10,080 kB
  • sloc: cpp: 41,951; python: 6,339; sh: 3,912; perl: 1,172; java: 49; makefile: 47
file content (125 lines) | stat: -rw-r--r-- 3,773 bytes parent folder | download
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)