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)
|