nodes: 0, module; 1, function_definition; 2, function_name:_filter_hovered_items; 3, parameters; 4, block; 5, identifier:self; 6, identifier:items; 7, identifier:event; 8, expression_statement; 9, expression_statement; 10, if_statement; 11, expression_statement; 12, expression_statement; 13, comment:# States/Names take precedence over connections if the connections are on the same hierarchy and if there is; 14, comment:# a port beneath the cursor; 15, expression_statement; 16, expression_statement; 17, if_statement; 18, comment:# NameView can only be hovered if it or its parent state is selected; 19, if_statement; 20, return_statement; 21, comment:"""Filters out items that cannot be hovered
  
          :param list items: Sorted list of items beneath the cursor
          :param Gtk.Event event: Motion event
          :return: filtered items
          :rtype: list
          """; 22, assignment; 23, not_operator; 24, block; 25, assignment; 26, assignment; 27, assignment; 28, assignment; 29, identifier:first_state_v; 30, comment:# There can be several connections above the state/name skip those and find the first non-connection-item; 31, block; 32, call; 33, block; 34, identifier:items; 35, identifier:items; 36, call; 37, identifier:items; 38, return_statement; 39, identifier:top_most_item; 40, subscript; 41, identifier:second_top_most_item; 42, conditional_expression:items[1] if len(items) > 1 else None; 43, identifier:first_state_v; 44, call; 45, identifier:first_state_v; 46, conditional_expression:first_state_v.parent if isinstance(first_state_v, NameView) else first_state_v; 47, for_statement; 48, comment:# Connections are only dismissed, if there is a port beneath the cursor. Search for ports here:; 49, expression_statement; 50, expression_statement; 51, expression_statement; 52, expression_statement; 53, for_statement; 54, if_statement; 55, identifier:isinstance; 56, argument_list; 57, expression_statement; 58, comment:# second item in the list must be the parent state of the NameView; 59, if_statement; 60, attribute; 61, argument_list; 62, identifier:items; 63, identifier:items; 64, integer:0; 65, subscript; 66, comparison_operator:len(items) > 1; 67, None; 68, identifier:next; 69, argument_list; 70, attribute; 71, call; 72, identifier:first_state_v; 73, identifier:item; 74, identifier:items; 75, block; 76, assignment; 77, assignment; 78, assignment; 79, assignment; 80, identifier:port_v; 81, identifier:state_ports; 82, block; 83, identifier:port_beneath_cursor; 84, block; 85, identifier:top_most_item; 86, identifier:NameView; 87, assignment; 88, boolean_operator; 89, block; 90, identifier:self; 91, identifier:_filter_library_state; 92, identifier:items; 93, identifier:items; 94, integer:1; 95, call; 96, integer:1; 97, call; 98, identifier:first_state_v; 99, identifier:parent; 100, identifier:isinstance; 101, argument_list; 102, if_statement; 103, break_statement; 104, identifier:port_beneath_cursor; 105, False; 106, identifier:state_ports; 107, call; 108, identifier:position; 109, call; 110, identifier:i2v_matrix; 111, call; 112, expression_statement; 113, expression_statement; 114, if_statement; 115, expression_statement; 116, expression_statement; 117, expression_statement; 118, identifier:state_v; 119, identifier:second_top_most_item; 120, comparison_operator:state_v not in self.view.selected_items; 121, comparison_operator:top_most_item not in self.view.selected_items; 122, expression_statement; 123, identifier:len; 124, argument_list; 125, identifier:filter; 126, argument_list; 127, identifier:first_state_v; 128, identifier:NameView; 129, call; 130, comment:# connection is on the same hierarchy level as the state/name, thus we dismiss it; 131, block; 132, attribute; 133, argument_list; 134, attribute; 135, argument_list; 136, attribute; 137, argument_list; 138, assignment; 139, assignment; 140, comparison_operator:view_distance == 0; 141, block; 142, assignment; 143, assignment; 144, assignment; 145, identifier:state_v; 146, attribute; 147, identifier:top_most_item; 148, attribute; 149, assignment; 150, identifier:items; 151, lambda; 152, identifier:items; 153, identifier:isinstance; 154, argument_list; 155, if_statement; 156, identifier:first_state_v; 157, identifier:get_all_ports; 158, call; 159, identifier:transform_point; 160, attribute; 161, attribute; 162, attribute; 163, identifier:get_matrix_i2v; 164, identifier:first_state_v; 165, identifier:item_distance; 166, subscript; 167, identifier:view_distance; 168, subscript; 169, identifier:view_distance; 170, integer:0; 171, expression_statement; 172, break_statement; 173, identifier:items; 174, call; 175, identifier:top_most_item; 176, subscript; 177, identifier:second_top_most_item; 178, conditional_expression:items[1] if len(items) > 1 else None; 179, attribute; 180, identifier:selected_items; 181, attribute; 182, identifier:selected_items; 183, identifier:items; 184, subscript; 185, lambda_parameters; 186, call; 187, identifier:item; 188, identifier:ConnectionView; 189, comparison_operator:self.view.canvas.get_parent(top_most_item) is not first_state_v; 190, block; 191, attribute; 192, argument_list; 193, identifier:event; 194, identifier:x; 195, identifier:event; 196, identifier:y; 197, identifier:self; 198, identifier:view; 199, call; 200, integer:1; 201, call; 202, integer:0; 203, assignment; 204, attribute; 205, argument_list; 206, identifier:items; 207, integer:0; 208, subscript; 209, comparison_operator:len(items) > 1; 210, None; 211, identifier:self; 212, identifier:view; 213, identifier:self; 214, identifier:view; 215, identifier:items; 216, slice; 217, identifier:item; 218, identifier:isinstance; 219, argument_list; 220, call; 221, identifier:first_state_v; 222, continue_statement; 223, attribute; 224, identifier:get_matrix_v2i; 225, identifier:first_state_v; 226, attribute; 227, argument_list; 228, attribute; 229, argument_list; 230, identifier:port_beneath_cursor; 231, True; 232, identifier:self; 233, identifier:dismiss_upper_items; 234, identifier:items; 235, identifier:item; 236, identifier:items; 237, integer:1; 238, call; 239, integer:1; 240, integer:1; 241, identifier:item; 242, tuple; 243, attribute; 244, argument_list; 245, identifier:self; 246, identifier:view; 247, attribute; 248, identifier:glue; 249, identifier:position; 250, identifier:i2v_matrix; 251, identifier:transform_distance; 252, identifier:item_distance; 253, integer:0; 254, identifier:len; 255, argument_list; 256, identifier:NameView; 257, identifier:StateView; 258, attribute; 259, identifier:get_parent; 260, identifier:top_most_item; 261, identifier:port_v; 262, identifier:port; 263, identifier:items; 264, attribute; 265, identifier:canvas; 266, identifier:self; 267, identifier:view
code: def _filter_hovered_items(self, items, event):
          """Filters out items that cannot be hovered
  
          :param list items: Sorted list of items beneath the cursor
          :param Gtk.Event event: Motion event
          :return: filtered items
          :rtype: list
          """
          items = self._filter_library_state(items)
          if not items:
              return items
          top_most_item = items[0]
          second_top_most_item = items[1] if len(items) > 1 else None
  
          # States/Names take precedence over connections if the connections are on the same hierarchy and if there is
          # a port beneath the cursor
          first_state_v = next(filter(lambda item: isinstance(item, (NameView, StateView)), items))
          first_state_v = first_state_v.parent if isinstance(first_state_v, NameView) else first_state_v
          if first_state_v:
              # There can be several connections above the state/name skip those and find the first non-connection-item
              for item in items:
                  if isinstance(item, ConnectionView):
                      # connection is on the same hierarchy level as the state/name, thus we dismiss it
                      if self.view.canvas.get_parent(top_most_item) is not first_state_v:
                          continue
                  break
  
              # Connections are only dismissed, if there is a port beneath the cursor. Search for ports here:
              port_beneath_cursor = False
              state_ports = first_state_v.get_all_ports()
              position = self.view.get_matrix_v2i(first_state_v).transform_point(event.x, event.y)
              i2v_matrix = self.view.get_matrix_i2v(first_state_v)
              for port_v in state_ports:
                  item_distance = port_v.port.glue(position)[1]
                  view_distance = i2v_matrix.transform_distance(item_distance, 0)[0]
                  if view_distance == 0:
                      port_beneath_cursor = True
                      break
  
              if port_beneath_cursor:
                  items = self.dismiss_upper_items(items, item)
                  top_most_item = items[0]
                  second_top_most_item = items[1] if len(items) > 1 else None
  
          # NameView can only be hovered if it or its parent state is selected
          if isinstance(top_most_item, NameView):
              state_v = second_top_most_item  # second item in the list must be the parent state of the NameView
              if state_v not in self.view.selected_items and top_most_item not in self.view.selected_items:
                  items = items[1:]
  
          return items