def timerEvent(self, event): """ Main loop for animations and movement in the scene -- calls nodes and tells them to update their position :param event: timer event? sent by Qt """ # Uncomment to check what is the actual framerate: # n_time = time.time() # print((n_time - self.prev_time) * 1000, prefs._fps_in_msec) # self.prev_time = n_time items_have_moved = False frame_has_moved = False background_fade = False can_normalize = True md = {'sum': (0, 0), 'nodes': []} ctrl.items_moving = True if self._fade_steps: self.setBackgroundBrush(self._fade_steps_list[self._fade_steps - 1]) self._fade_steps -= 1 if self._fade_steps: background_fade = True f = self.main.forest f.edge_visibility_check() for e in f.edges.values(): e.make_path() e.update() if ctrl.pressed: return for node in f.nodes.values(): if not node.isVisible(): continue # Computed movement moved, normalizable = node.move(md) if moved: items_have_moved = True if not normalizable: can_normalize = False # normalize movement so that the trees won't glide away ln = len(md['nodes']) if ln and can_normalize: avg = div_xy(md['sum'], ln) for node in md['nodes']: node.current_position = sub_xy(node.current_position, avg) if items_have_moved and (not self.manual_zoom) and (not ctrl.dragged_focus): self.fit_to_window() if items_have_moved: self.main.ui_manager.get_activity_marker().show() # for area in f.touch_areas: # area.update_position() for group in f.groups.values(): group.update_shape() elif not (items_have_moved or frame_has_moved or background_fade): self.stop_animations() self.main.ui_manager.get_activity_marker().hide() ctrl.items_moving = False self.keep_updating_visible_area = False f.edge_visibility_check() # only does something if flagged
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 timerEvent(self, event): """ Main loop for animations and movement in the scene -- calls nodes and tells them to update their position :param event: timer event? sent by Qt """ # Uncomment to check what is the actual framerate: # n_time = time.time() # print((n_time - self.prev_time) * 1000, prefs._fps_in_msec) # self.prev_time = n_time items_have_moved = False frame_has_moved = False background_fade = False can_normalize = True md = {'sum': (0, 0), 'nodes': []} ctrl.items_moving = True if self._fade_steps: self.setBackgroundBrush(self._fade_steps_list[self._fade_steps - 1]) self._fade_steps -= 1 if self._fade_steps: background_fade = True f = self.main.forest #e.update() if ctrl.pressed: return for node in chain(f.nodes.values(), f.trees): if not node.isVisible(): continue # Computed movement moved, normalizable = node.move(md) if moved: items_have_moved = True if not normalizable: can_normalize = False # normalize movement so that the trees won't glide away ln = len(md['nodes']) if ln and can_normalize: avg = div_xy(md['sum'], ln) for node in md['nodes']: node.current_position = sub_xy(node.current_position, avg) if items_have_moved: for e in f.edges.values(): e.make_path() if items_have_moved and (not self.manual_zoom) and ( not ctrl.dragged_focus): self.fit_to_window() if items_have_moved: #self.main.ui_manager.get_activity_marker().show() # for area in f.touch_areas: # area.update_position() for group in f.groups.values(): group.update_shape() elif not (items_have_moved or frame_has_moved or background_fade): self.stop_animations() self.main.ui_manager.get_activity_marker().hide() ctrl.items_moving = False self.keep_updating_visible_area = False f.edge_visibility_check() # only does something if flagged
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