def update(self):
x, y = mouse()<EOL>if self.show_grid:<EOL><INDENT>x, y = self.grid.snap(x, y)<EOL><DEDENT>if _ctx._ns["<STR_LIT>"]and not self.freehand:<EOL><INDENT>self._dirty = True<EOL>if self.edit != Noneand not self.drag_pointand not self.drag_handle1and not self.drag_handle2:<EOL><INDENT>pt = self._points[self.edit]<EOL>dx = pt.x+self.btn_x<EOL>dy = pt.y+self.btn_y<EOL>if self.overlap(dx, dy, x, y, r=self.btn_r):<EOL><INDENT>self.delete = self.edit<EOL>return<EOL><DEDENT>dx += self.btn_r*<NUM_LIT:2> + <NUM_LIT:2><EOL>if self.edit == len(self._points) -<NUM_LIT:1> andself.overlap(dx, dy, x, y, r=self.btn_r):<EOL><INDENT>self.moveto = self.edit<EOL>return<EOL><DEDENT><DEDENT>if self.insert:<EOL><INDENT>self.inserting = True<EOL>return<EOL><DEDENT>if not self.drag_point andnot self.drag_handle1 andnot self.drag_handle2:<EOL><INDENT>self.editing = False<EOL>indices = range(len(self._points))<EOL>indices.reverse()<EOL>for i in indices:<EOL><INDENT>pt = self._points[i]<EOL>if pt != self.newand self.overlap(x, y, pt.x, pt.y)and self.new == None:<EOL><INDENT>if self.edit == i+<NUM_LIT:1>and self.overlap(self._points[i+<NUM_LIT:1>].ctrl1.x,<EOL>self._points[i+<NUM_LIT:1>].ctrl1.y, x, y):<EOL><INDENT>continue<EOL><DEDENT>else:<EOL><INDENT>self.edit = i<EOL>self.editing = True<EOL>break<EOL><DEDENT><DEDENT><DEDENT><DEDENT>if not self.editing:<EOL><INDENT>if self.edit != None:<EOL><INDENT>pt = self._points[self.edit]<EOL>if self.overlap(pt.ctrl1.x, pt.ctrl1.y, x, y) orself.overlap(pt.ctrl2.x, pt.ctrl2.y, x, y):<EOL><INDENT>self.editing = True<EOL><DEDENT>else:<EOL><INDENT>self.edit = None<EOL><DEDENT><DEDENT><DEDENT>if self.edit == None:<EOL><INDENT>if self.new == None:<EOL><INDENT>self.new = PathElement()<EOL>if self.moveto == Trueor len(self._points) == <NUM_LIT:0>:<EOL><INDENT>cmd = MOVETO<EOL>self.moveto = None<EOL>self.last_moveto = self.new<EOL><DEDENT>else:<EOL><INDENT>cmd = CURVETO<EOL><DEDENT>self.new.cmd = cmd<EOL>self.new.x = x<EOL>self.new.y = y<EOL>self.new.ctrl1 = Point(x, y)<EOL>self.new.ctrl2 = Point(x, y)<EOL>self.new.freehand = False<EOL>if len(self._points) > <NUM_LIT:0>:<EOL><INDENT>prev = self._points[-<NUM_LIT:1>]<EOL>rx, ry = self.reflect(prev.x, prev.y, prev.ctrl2.x, prev.ctrl2.y)<EOL>self.new.ctrl1 = Point(rx, ry)<EOL><DEDENT>self._points.append(self.new)<EOL><DEDENT>else:<EOL><INDENT>rx, ry = self.reflect(self.new.x, self.new.y, x, y)<EOL>self.new.ctrl2 = Point(rx, ry)<EOL><DEDENT><DEDENT>elif self.new == None:<EOL><INDENT>pt = self._points[self.edit]<EOL>if self.overlap(pt.x, pt.y, x, y)and not self.drag_handle1and not self.drag_handle2and not self.new != None:<EOL><INDENT>self.drag_point = True<EOL>self.drag_handle1 = False<EOL>self.drag_handle2 = False<EOL><DEDENT>if self.overlap(pt.ctrl1.x, pt.ctrl1.y, x, y)and pt.cmd == CURVETOand not self.drag_pointand not self.drag_handle2:<EOL><INDENT>self.drag_point = False<EOL>self.drag_handle1 = True<EOL>self.drag_handle2 = False<EOL><DEDENT>if self.overlap(pt.ctrl2.x, pt.ctrl2.y, x, y)and pt.cmd == CURVETOand not self.drag_pointand not self.drag_handle1:<EOL><INDENT>self.drag_point = False<EOL>self.drag_handle1 = False<EOL>self.drag_handle2 = True<EOL><DEDENT>if self.drag_point == True:<EOL><INDENT>dx = x - pt.x<EOL>dy = y - pt.y<EOL>pt.x = x<EOL>pt.y = y<EOL>pt.ctrl2.x += dx<EOL>pt.ctrl2.y += dy<EOL>if self.edit < len(self._points)-<NUM_LIT:1>:<EOL><INDENT>rx, ry = self.reflect(pt.x, pt.y, x, y)<EOL>next = self._points[self.edit+<NUM_LIT:1>]<EOL>next.ctrl1.x += dx<EOL>next.ctrl1.y += dy<EOL><DEDENT><DEDENT>if self.drag_handle1 == True:<EOL><INDENT>pt.ctrl1 = Point(x, y)<EOL>if self.edit > <NUM_LIT:0>and self.last_key != "<STR_LIT:x>":<EOL><INDENT>prev = self._points[self.edit-<NUM_LIT:1>]<EOL>d = self.distance(prev.x, prev.y, prev.ctrl2.x, prev.ctrl2.y)<EOL>a = self.angle(prev.x, prev.y, pt.ctrl1.x, pt.ctrl1.y)<EOL>prev.ctrl2 = self.coordinates(prev.x, prev.y, d, a+<NUM_LIT>)                        <EOL><DEDENT><DEDENT>if self.drag_handle2 == True:   <EOL><INDENT>pt.ctrl2 = Point(x, y)<EOL>if self.edit < len(self._points)-<NUM_LIT:1>and self.last_key != "<STR_LIT:x>":<EOL><INDENT>next = self._points[self.edit+<NUM_LIT:1>]<EOL>d = self.distance(pt.x, pt.y, next.ctrl1.x, next.ctrl1.y)<EOL>a = self.angle(pt.x, pt.y, pt.ctrl2.x, pt.ctrl2.y)<EOL>next.ctrl1 = self.coordinates(pt.x, pt.y, d, a+<NUM_LIT>)<EOL><DEDENT><DEDENT><DEDENT><DEDENT>elif not self.freehand:<EOL><INDENT>self.new = None<EOL>self.drag_point = False<EOL>self.drag_handle1 = False<EOL>self.drag_handle2 = False<EOL>if self.delete != None and len(self._points) > <NUM_LIT:0>:<EOL><INDENT>i = self.delete<EOL>cmd = self._points[i].cmd<EOL>del self._points[i]<EOL>if <NUM_LIT:0> < i < len(self._points):<EOL><INDENT>prev = self._points[i-<NUM_LIT:1>]<EOL>rx, ry = self.reflect(prev.x, prev.y, prev.ctrl2.x, prev.ctrl2.y)<EOL>self._points[i].ctrl1 = Point(rx, ry)<EOL><DEDENT>start_i = i<EOL>while i > <NUM_LIT:1>:<EOL><INDENT>i -= <NUM_LIT:1><EOL>pt = self._points[i]<EOL>if pt.freehand:<EOL><INDENT>del self._points[i]<EOL><DEDENT>elif i < start_i-<NUM_LIT:1> and pt.freehand == False:<EOL><INDENT>if pt.cmd == MOVETO:<EOL><INDENT>del self._points[i]<EOL><DEDENT>break<EOL><DEDENT><DEDENT>if len(self._points) > <NUM_LIT:0>and (cmd == MOVETO or i == <NUM_LIT:0>):<EOL><INDENT>self.last_moveto = self._points[<NUM_LIT:0>]<EOL>for pt in self._points:<EOL><INDENT>if pt.cmd == MOVETO:<EOL><INDENT>self.last_moveto = pt<EOL><DEDENT><DEDENT><DEDENT>self.delete = None<EOL>self.edit = None<EOL><DEDENT>elif isinstance(self.moveto, int):<EOL><INDENT>self.moveto = True<EOL>self.edit = None<EOL><DEDENT>elif self.edit == Noneand self.contains_point(x, y, d=<NUM_LIT:2>):<EOL><INDENT>self.insert = True<EOL><DEDENT>else:<EOL><INDENT>self.insert = False<EOL><DEDENT>if self.insertingand self.contains_point(x, y, d=<NUM_LIT:2>): <EOL><INDENT>self.insert_point(x, y)<EOL>self.insert = False<EOL><DEDENT>self.inserting = False<EOL>if self._dirty == True:<EOL><INDENT>self.export_svg()<EOL>self._dirty = False<EOL><DEDENT><DEDENT>if _ctx._ns["<STR_LIT>"]:<EOL><INDENT>self.last_key = _ctx._ns["<STR_LIT:key>"]<EOL>self.last_keycode = _ctx._ns["<STR_LIT>"]<EOL><DEDENT>if not _ctx._ns["<STR_LIT>"] and self.last_key != None:<EOL><INDENT>if self.last_keycode == KEY_TAB:<EOL><INDENT>self.show_grid = not self.show_grid<EOL><DEDENT>if self.last_key == "<STR_LIT:f>":<EOL><INDENT>self.edit = None<EOL>self.freehand = not self.freehand<EOL>if self.freehand:<EOL><INDENT>self.msg = "<STR_LIT>"<EOL><DEDENT>else:<EOL><INDENT>self.msg = "<STR_LIT>"<EOL><DEDENT><DEDENT>if self.last_keycode == KEY_ESC:<EOL><INDENT>self.edit = None<EOL><DEDENT>if self.last_keycode == _ctx.KEY_BACKSPACEand self.edit != None:<EOL><INDENT>self.delete = self.edit<EOL><DEDENT>self.last_key = None<EOL>self.last_code = None<EOL><DEDENT>if _ctx._ns["<STR_LIT>"]:<EOL><INDENT>dx = <NUM_LIT:0><EOL>dy = <NUM_LIT:0><EOL>keycode = _ctx._ns["<STR_LIT>"]<EOL>if keycode == _ctx.KEY_LEFT:<EOL><INDENT>dx = -<NUM_LIT:10><EOL><DEDENT>elif keycode == _ctx.KEY_RIGHT:<EOL><INDENT>dx = <NUM_LIT:10><EOL><DEDENT>if keycode == _ctx.KEY_UP:<EOL><INDENT>dy = -<NUM_LIT:10><EOL><DEDENT>elif keycode == _ctx.KEY_DOWN:<EOL><INDENT>dy = <NUM_LIT:10><EOL><DEDENT>if dx != <NUM_LIT:0> or dy != <NUM_LIT:0>:<EOL><INDENT>for pt in self._points:<EOL><INDENT>pt.x += dx<EOL>pt.y += dy<EOL>pt.ctrl1.x += dx<EOL>pt.ctrl1.y += dy<EOL>pt.ctrl2.x += dx<EOL>pt.ctrl2.y += dy<EOL><DEDENT><DEDENT><DEDENT>
Update runs each frame to check for mouse interaction.

        Alters the path by allowing the user to add new points,
        drag point handles and move their location.
        Updates are automatically stored as SVG
        in the given filename.