def move(self, md): """ Do one frame of movement: either move towards target position or take a step according to algorithm 1. item folding towards position in part of animation to disappear etc. 2. item is being dragged 3. item is locked by user 4. item is tightly attached to another node which is moving (then the move is handled by the other node, it is _not_ parent node, though.) 5. visualisation algorithm setting it specifically (6) or (0) -- places where subclasses can add new movements. :param md: movement data dict, collects sum of all movement to help normalize it :return: """ # _high_priority_move can be used together with _move_counter self.unmoved = False if not self._high_priority_move: # Dragging overrides (almost) everything, don't try to move this anywhere if self._dragged: return True, False # Locked nodes are immune to physics elif self.locked: return False, False #elif self.locked_to_node: # return False, False # MOVE_TO -based movement has priority over physics. This way e.g. triangles work without # additional stipulation if self._move_counter: position = self.current_position # stop even despite the _move_counter, if we are close enough if about_there(position, self.target_position): self.stop_moving() return False, False # move a precalculated step if self._use_easing: movement = multiply_xy(self._step, qt_prefs.easing_curve[self._move_counter - 1]) else: movement = div_xy(sub_xy(self.target_position, position), self._move_counter) self._move_counter -= 1 # if move counter reaches zero, stop and do clean-up. if not self._move_counter: self.stop_moving() self.current_position = add_xy(self.current_position, movement) if self.locked_to_node: self.locked_to_node.update_bounding_rect() return True, False # Physics move node around only if other movement types have not overridden it elif self.use_physics() and self.is_visible(): movement = ctrl.forest.visualization.calculate_movement(self) md['sum'] = add_xy(movement, md['sum']) md['nodes'].append(self) self.current_position = add_xy(self.current_position, movement) return abs(movement[0]) + abs(movement[1]) > 0.6, True return False, False
def group_traces_to_chain_head(self): """ Move traces to their multidominant originals, purely didactic thing """ self.rebuild_chains() y_adjust = {} for key, chain in self.chains.items(): head = self.get_chain_head(key) for node, parent, is_head in chain: if not is_head: if key not in y_adjust: y_adjust[key] = 0, head.boundingRect().height() dx, dy = y_adjust[key] node.use_adjustment = False node.adjustment = (0, 0) node.move_to(*add_xy(head.current_position, (-dx, dy)), can_adjust=False) y_adjust[key] = (dx + node.boundingRect().width(), dy + node.boundingRect().height()) ctrl.settings.set('traces_are_grouped_together', True, level=FOREST) ctrl.settings.set('uses_multidomination', False, level=FOREST)
def dragged_to(self, scene_pos): """ Dragged focus is in scene_pos. Move there. :param scene_pos: current drag focus :return: """ if self.parentItem(): p = self.parentItem().mapFromScene(scene_pos[0], scene_pos[1]) new_pos = p.x(), p.y() else: new_pos = scene_pos[0], scene_pos[1] if self.use_physics(): self.locked = True self.current_position = new_pos else: self.use_adjustment = True diff = sub_xy(new_pos, self.current_position) self.adjustment = add_xy(self.adjustment, diff) self.target_position = new_pos self.current_position = new_pos
def move(self, md: dict) -> (bool, bool): """ Do one frame of movement: either move towards target position or take a step according to algorithm 1. item folding towards position in part of animation to disappear etc. 2. item is being dragged 3. item is locked by user 4. item is tightly attached to another node which is moving (then the move is handled by the other node, it is _not_ parent node, though.) 5. visualisation algorithm setting it specifically (6) or (0) -- places where subclasses can add new movements. :param md: movement data dict, collects sum of all movement to help normalize it :return: """ # _high_priority_move can be used together with _move_counter self.unmoved = False if not self._high_priority_move: # Dragging overrides (almost) everything, don't try to move this anywhere if self._dragged: return True, False # Locked nodes are immune to physics elif self.locked: return False, False #elif self.locked_to_node: # return False, False # MOVE_TO -based movement has priority over physics. This way e.g. triangles work without # additional stipulation if self._move_counter: position = self.current_position # stop even despite the _move_counter, if we are close enough if about_there(position, self.target_position): self.stop_moving() return False, False self._move_counter -= 1 # move a precalculated step if self._use_easing: if self._move_frames != self._move_counter: time_f = 1 - (self._move_counter / self._move_frames) f = qt_prefs.curve.valueForProgress(time_f) else: f = 0 movement = multiply_xy(self._distance, f) self.current_position = add_xy(self._start_position, movement) else: movement = div_xy(sub_xy(self.target_position, position), self._move_counter) self.current_position = add_xy(self.current_position, movement) # if move counter reaches zero, stop and do clean-up. if not self._move_counter: self.stop_moving() if self.locked_to_node: self.locked_to_node.update_bounding_rect() return True, False # Physics move node around only if other movement types have not overridden it elif self.use_physics() and self.is_visible(): movement = ctrl.forest.visualization.calculate_movement(self) md['sum'] = add_xy(movement, md['sum']) md['nodes'].append(self) self.current_position = add_xy(self.current_position, movement) return abs(movement[0]) + abs(movement[1]) > 0.6, True return False, False