def _draw_target(self, region_object, canvas, internal_target_name): regions = [] for region in region_object: shape = 0 raw_tags = region["tags"] # Get rid of the default internal name otherwise every target # will have it and selection won't work raw_tags = tuple([value for value in raw_tags if value != "_internal_name:target"]) raw_tags += (internal_target_name,) parsed_tags = TagParser.parse_tags(raw_tags) if parsed_tags["_shape"] == "rectangle": shape = canvas.create_rectangle(region["coords"], fill=region["fill"], stipple="gray25", tags=raw_tags) if parsed_tags["_shape"] == "oval": shape = canvas.create_oval(region["coords"], fill=region["fill"], stipple="gray25", tags=raw_tags) if parsed_tags["_shape"] == "triangle": shape = canvas.create_polygon(region["coords"], fill=region["fill"], outline="black", stipple="gray25", tags=raw_tags) if shape != 0: regions.append(shape) return regions
def process_hit(self, shot): is_hit = False x = shot.get_coords()[0] y = shot.get_coords()[1] regions = self._webcam_canvas.find_overlapping(x, y, x, y) # If we hit a targert region, run its commands and notify the # loaded plugin of the hit for region in reversed(regions): tags = TagParser.parse_tags( self._webcam_canvas.gettags(region)) if "_internal_name" in tags and "command" in tags: self.execute_region_commands(tags["command"]) if "_internal_name" in tags and self._loaded_training != None: self._loaded_training.hit_listener(region, tags, shot) if "_internal_name" in tags: is_hit = True # only run the commands and notify a hit for the top most # region break if self._loaded_training != None: self._loaded_training.shot_listener(shot, is_hit)
def load_training(self, plugin): # Create a list of targets, their regions, and the tags attached # to those regions so that the plugin can have a stock of what # can be shot targets = [] for target in self._targets: target_regions = self._webcam_canvas.find_withtag(target) target_data = {"name":target, "regions":[]} targets.append(target_data) for region in target_regions: tags = TagParser.parse_tags( self._webcam_canvas.gettags(region)) target_data["regions"].append(tags) if self._loaded_training: self._loaded_training.destroy() if self._protocol_operations: self._protocol_operations.destroy() self._protocol_operations = ProtocolOperations(self._webcam_canvas) self._loaded_training = imp.load_module("__init__", *plugin).load( self._protocol_operations, targets)
def process_hit(self, shot, shot_list_item): is_hit = False x = shot.get_coords()[0] y = shot.get_coords()[1] regions = self._webcam_canvas.find_overlapping(x, y, x, y) # If we hit a targert region, run its commands and notify the # loaded plugin of the hit for region in reversed(regions): tags = TagParser.parse_tags( self._webcam_canvas.gettags(region)) if "_internal_name" in tags and "command" in tags: self.execute_region_commands(tags["command"]) if "_internal_name" in tags and self._loaded_training != None: self._loaded_training.hit_listener(region, tags, shot, shot_list_item) if "_internal_name" in tags: is_hit = True # only run the commands and notify a hit for the top most # region break if self._loaded_training != None: self._loaded_training.shot_listener(shot, shot_list_item, is_hit)
def handle_shot(self, laser_color, x, y): hit_region = None hit_tags = None regions = self._arena_canvas.find_overlapping(x, y, x, y) # If we hit a targert region, run its commands and notify the # loaded plugin of the hit for region in reversed(regions): tags = TagParser.parse_tags(self._arena_canvas.gettags(region)) # If we hit an image on a transparent pixel, ignore the "hit" if "_shape:image" in self._arena_canvas.gettags( region) and self._canvas_manager.is_transparent_pixel( region, x, y): continue if "_internal_name" in tags and "command" in tags: self._canvas_manager.execute_region_commands( region, tags["command"], self._shootoff.get_protocol_operations()) if "_internal_name" in tags and self._loaded_training != None: hit_region = region hit_tags = TagParser.parse_tags( self._arena_canvas.gettags(region)) if "_internal_name" in tags: is_hit = True # only run the commands and notify a hit for the top most # region break # Also run commands for all hidden regions that were hit for region in regions: tags = TagParser.parse_tags(self._arena_canvas.gettags(region)) if "visible" in tags and "command" in tags and tags[ "visible"].lower() == "false": self._canvas_manager.execute_region_commands( region, tags["command"], self._shootoff.get_protocol_operations()) return hit_region, hit_tags
def process_hit(self, shot, shot_list_item): is_hit = False x = shot.get_coords()[0] y = shot.get_coords()[1] regions = self._webcam_canvas.find_overlapping(x, y, x, y) # If we hit a targert region, run its commands and notify the # loaded plugin of the hit for region in reversed(regions): tags = TagParser.parse_tags(self._webcam_canvas.gettags(region)) # If we hit an image on a transparent pixel, ignore the "hit" if "_shape:image" in self._webcam_canvas.gettags(region) and self._canvas_manager.is_transparent_pixel(region, x, y): continue if "_internal_name" in tags and "command" in tags: self._canvas_manager.execute_region_commands(region, tags["command"], self._protocol_operations) if "_internal_name" in tags and self._loaded_training != None: self._loaded_training.hit_listener(region, tags, shot, shot_list_item) if "_internal_name" in tags: is_hit = True # only run the commands and notify a hit for the top most # region break # Also run commands for all hidden regions that were hit for region in regions: tags = TagParser.parse_tags(self._webcam_canvas.gettags(region)) if "visible" in tags and "command" in tags and tags["visible"].lower() == "false": self._canvas_manager.execute_region_commands(region, tags["command"], self._protocol_operations) if self._loaded_training != None: self._loaded_training.shot_listener(shot, shot_list_item, is_hit)
def handle_shot(self, laser_color, x, y): hit_region = None hit_tags = None regions = self._arena_canvas.find_overlapping(x, y, x, y) # If we hit a targert region, run its commands and notify the # loaded plugin of the hit for region in reversed(regions): tags = TagParser.parse_tags(self._arena_canvas.gettags(region)) # If we hit an image on a transparent pixel, ignore the "hit" if "_shape:image" in self._arena_canvas.gettags(region) and self._canvas_manager.is_transparent_pixel(region, x, y): continue if "_internal_name" in tags and "command" in tags: self._canvas_manager.execute_region_commands(region, tags["command"], self._shootoff.get_protocol_operations()) if "_internal_name" in tags and self._loaded_training != None: hit_region = region hit_tags = TagParser.parse_tags(self._arena_canvas.gettags(region)) if "_internal_name" in tags: is_hit = True # only run the commands and notify a hit for the top most # region break # Also run commands for all hidden regions that were hit for region in regions: tags = TagParser.parse_tags(self._arena_canvas.gettags(region)) if "visible" in tags and "command" in tags and tags["visible"].lower() == "false": self._canvas_manager.execute_region_commands(region, tags["command"], self._shootoff.get_protocol_operations()) return hit_region, hit_tags
def aggregate_targets(self, current_targets): # Create a list of targets, their regions, and the tags attached # to those regions so that the plugin can have a stock of what # can be shot targets = [] for target in current_targets: target_regions = self._canvas.find_withtag(target) target_data = {"name": target, "regions": []} targets.append(target_data) for region in target_regions: tags = TagParser.parse_tags(self._canvas.gettags(region)) target_data["regions"].append(tags) return targets
def execute_region_commands(self, region, command_list, operations): # Don't run commands if the region is a non-reversable image that is on the last frame if ("command:reverse" not in self._canvas.gettags(region) and "_shape:image" in self._canvas.gettags(region) and str(self._canvas.itemcget(region, "image")) != str( self._image_regions_images[region][FIRST_PHOTOIMAGE_INDEX]) ): return args = [] for command in command_list: # Parse the command name and arguments arguments are expected to # be comma separated and in between paren: # command_name(arg0,arg1,...,argN) pattern = r'(\w[\w\d_]*)\((.*)\)$' match = re.match(pattern, command) if match: command = match.groups()[0] if len(match.groups()) > 0: args = match.groups()[1].split(",") # Run the commands if command == "reset": operations.reset() if command == "play_sound": operations.play_sound(args[0]) if command == "animate": reverse = False if "reverse" in command_list: reverse = True if len(args) != 0: tags = TagParser.parse_tags(self._canvas.gettags(region)) for region in self._canvas.find_withtag("name:" + args[0]): # Animate the named region internal_name = "_internal_name:" + tags[ "_internal_name"] current_tags = self._canvas.gettags(region) if internal_name in current_tags: self.animate(region, None, reverse) else: self.animate(region, None, reverse)
def execute_region_commands(self, region, command_list, operations): # Don't run commands if the region is a non-reversable image that is on the last frame if ( "command:reverse" not in self._canvas.gettags(region) and "_shape:image" in self._canvas.gettags(region) and str(self._canvas.itemcget(region, "image")) != str(self._image_regions_images[region][FIRST_PHOTOIMAGE_INDEX]) ): return args = [] for command in command_list: # Parse the command name and arguments arguments are expected to # be comma separated and in between paren: # command_name(arg0,arg1,...,argN) pattern = r"(\w[\w\d_]*)\((.*)\)$" match = re.match(pattern, command) if match: command = match.groups()[0] if len(match.groups()) > 0: args = match.groups()[1].split(",") # Run the commands if command == "reset": operations.reset() if command == "play_sound": operations.play_sound(args[0]) if command == "animate": reverse = False if "reverse" in command_list: reverse = True if len(args) != 0: tags = TagParser.parse_tags(self._canvas.gettags(region)) for region in self._canvas.find_withtag("name:" + args[0]): # Animate the named region internal_name = "_internal_name:" + tags["_internal_name"] current_tags = self._canvas.gettags(region) if internal_name in current_tags: self.animate(region, None, reverse) else: self.animate(region, None, reverse)
def _draw_target(self, region_object, canvas, internal_target_name): regions = [] for region in region_object: shape = 0 raw_tags = region["tags"] # Get rid of the default internal name otherwise every target # will have it and selection won't work raw_tags = tuple([ value for value in raw_tags if value != "_internal_name:target" ]) raw_tags += (internal_target_name, ) parsed_tags = TagParser.parse_tags(raw_tags) if parsed_tags["_shape"] == "rectangle": shape = canvas.create_rectangle(region["coords"], fill=region["fill"], stipple="gray25", tags=raw_tags) if parsed_tags["_shape"] == "oval": shape = canvas.create_oval(region["coords"], fill=region["fill"], stipple="gray25", tags=raw_tags) if parsed_tags["_shape"] == "triangle": shape = canvas.create_polygon(region["coords"], fill=region["fill"], outline="black", stipple="gray25", tags=raw_tags) if shape != 0: regions.append(shape) return regions
def load_training(self, plugin): # Create a list of targets, their regions, and the tags attached # to those regions so that the plugin can have a stock of what # can be shot targets = [] for target in self._targets: target_regions = self._webcam_canvas.find_withtag(target) target_data = {"name": target, "regions": []} targets.append(target_data) for region in target_regions: tags = TagParser.parse_tags( self._webcam_canvas.gettags(region)) target_data["regions"].append(tags) if self._loaded_training: self._loaded_training.destroy() self._protocol_operations.destroy() self._protocol_operations = ProtocolOperations(self._webcam_canvas) self._loaded_training = imp.load_module("__init__", *plugin).load( self._protocol_operations, targets)
def _draw_target(self, region_object, canvas, _canvas_manager, internal_target_name): regions = [] for region in region_object: shape = 0 raw_tags = region["tags"] # Get rid of the default internal name otherwise every target # will have it and selection won't work raw_tags = tuple([value for value in raw_tags if value != "_internal_name:target"]) raw_tags += (internal_target_name,) parsed_tags = TagParser.parse_tags(raw_tags) if parsed_tags["_shape"] == "image": shape = canvas.create_image(region["coords"], image=None, tags=raw_tags) image = _canvas_manager.cache_image_frames(shape, parsed_tags["_path"]) canvas.itemconfig(shape, image=image) _canvas_manager.animate(shape, image) if parsed_tags["_shape"] == "rectangle": shape = canvas.create_rectangle(region["coords"], fill=region["fill"], stipple="gray25", tags=raw_tags) if parsed_tags["_shape"] == "oval": shape = canvas.create_oval(region["coords"], fill=region["fill"], stipple="gray25", tags=raw_tags) if parsed_tags["_shape"] == "triangle": shape = canvas.create_polygon(region["coords"], fill=region["fill"], outline="black", stipple="gray25", tags=raw_tags) if parsed_tags["_shape"] == "aqt3": shape = canvas.create_polygon(region["coords"], fill=region["fill"], outline="black", stipple="gray25", tags=raw_tags) if parsed_tags["_shape"] == "aqt4": shape = canvas.create_polygon(region["coords"], fill=region["fill"], outline="black", stipple="gray25", tags=raw_tags) if parsed_tags["_shape"] == "aqt5": shape = canvas.create_polygon(region["coords"], fill=region["fill"], outline="black", stipple="gray25", tags=raw_tags) if parsed_tags["_shape"] == "freeform_polygon": shape = canvas.create_polygon(region["coords"], fill=region["fill"], outline="black", stipple="gray25", tags=raw_tags) if "visible" in parsed_tags and parsed_tags["visible"].lower() == "false": canvas.tag_lower(shape, "background") else: canvas.tag_raise(shape, "background") if shape != 0: regions.append(shape) return regions
def _scale_region(self, event, c, is_polygon, is_image, region, size_incr=1): # The region is scaled by a ratio, so we need to know the current # dimension so that we can calculate the ratio needed to scale # the selection by only one pixel # We have to know if it is a polygon (with more sides than the triangle # we draw) because polygons are used to approximate circles on windows. # Calculating the width and height is different in that case if is_polygon: width = max(c[::2]) - min(c[::2]) height = max(c[1::2]) - min(c[1::2]) elif is_image: b = self._image_regions_images[region][FIRST_IMAGE_INDEX].getbbox() width = b[2] - b[0] height = b[3] - b[1] else: width = c[2] - c[0] height = c[3] - c[1] if event.keysym == "Up": # The vertical growth direction is reverse with a polygon hack for # windows if is_polygon: scale_factor = (height + size_incr) / height if (scale_factor > 0): event.widget.scale(region, c[0], c[1], 1, scale_factor) elif is_image: height += size_incr else: if height - size_incr <= 0: return scale_factor = (height - size_incr) / height if (scale_factor > 0): event.widget.scale(region, c[0], c[1], 1, scale_factor) elif event.keysym == "Down": if is_polygon: if height - size_incr <= 0: return scale_factor = (height - size_incr) / height if (scale_factor > 0): event.widget.scale(region, c[0], c[1], 1, scale_factor) elif is_image: height -= size_incr else: scale_factor = (height + size_incr) / height if (scale_factor > 0): event.widget.scale(region, c[0], c[1], 1, scale_factor) elif event.keysym == "Right": if is_image: width += size_incr else: scale_factor = (width + size_incr) / width if (scale_factor > 0): event.widget.scale(region, c[0], c[1], scale_factor, 1) elif event.keysym == "Left" and width > 1: if is_image: width -= size_incr else: if width - size_incr <= 0: return scale_factor = (width - size_incr) / width if (scale_factor > 0): event.widget.scale(region, c[0], c[1], scale_factor, 1) if is_image: tags = TagParser.parse_tags(self._canvas.gettags(region)) self.cache_image_frames(region, tags["_path"], width, height) self._canvas.itemconfig(region, image=self._image_regions_images[region] [FIRST_PHOTOIMAGE_INDEX])
def _scale_region(self, event, c, is_polygon, is_image, region, size_incr=1): # The region is scaled by a ratio, so we need to know the current # dimension so that we can calculate the ratio needed to scale # the selection by only one pixel # We have to know if it is a polygon (with more sides than the triangle # we draw) because polygons are used to approximate circles on windows. # Calculating the width and height is different in that case if is_polygon: width = max(c[::2]) - min(c[::2]) height = max(c[1::2]) - min(c[1::2]) elif is_image: b = self._image_regions_images[region][FIRST_IMAGE_INDEX].getbbox() width = b[2] - b[0] height = b[3] - b[1] else: width = c[2] - c[0] height = c[3] - c[1] if event.keysym == "Up": # The vertical growth direction is reverse with a polygon hack for # windows if is_polygon: scale_factor = (height + size_incr) / height if scale_factor > 0: event.widget.scale(region, c[0], c[1], 1, scale_factor) elif is_image: height += size_incr else: if height - size_incr <= 0: return scale_factor = (height - size_incr) / height if scale_factor > 0: event.widget.scale(region, c[0], c[1], 1, scale_factor) elif event.keysym == "Down": if is_polygon: if height - size_incr <= 0: return scale_factor = (height - size_incr) / height if scale_factor > 0: event.widget.scale(region, c[0], c[1], 1, scale_factor) elif is_image: height -= size_incr else: scale_factor = (height + size_incr) / height if scale_factor > 0: event.widget.scale(region, c[0], c[1], 1, scale_factor) elif event.keysym == "Right": if is_image: width += size_incr else: scale_factor = (width + size_incr) / width if scale_factor > 0: event.widget.scale(region, c[0], c[1], scale_factor, 1) elif event.keysym == "Left" and width > 1: if is_image: width -= size_incr else: if width - size_incr <= 0: return scale_factor = (width - size_incr) / width if scale_factor > 0: event.widget.scale(region, c[0], c[1], scale_factor, 1) if is_image: tags = TagParser.parse_tags(self._canvas.gettags(region)) self.cache_image_frames(region, tags["_path"], width, height) self._canvas.itemconfig(region, image=self._image_regions_images[region][FIRST_PHOTOIMAGE_INDEX])