Synced slider with frame index rather than active keyframe - #99
Conversation
…. Frame sequence changed to contain the first keyframe.
Codecov Report
@@ Coverage Diff @@
## main #99 +/- ##
==========================================
+ Coverage 90.08% 90.59% +0.51%
==========================================
Files 20 20
Lines 827 851 +24
==========================================
+ Hits 745 771 +26
+ Misses 82 80 -2
Continue to review full report at Codecov.
|
…sync with slider.
There was a problem hiding this comment.
hey @Fifourche - I love the idea but am not 100% on the implementation, especially the generation of the whole list to obtain the required index
Could you explain the purpose of the extra code you added into the cache too? 🙂
| def _on_frame_index_changed(self, event=None): | ||
| frame_index = event.value | ||
| self.animationSlider.blockSignals(True) | ||
| self.animationSlider.setValue(frame_index) | ||
| self.animationSlider.blockSignals(False) | ||
|
|
||
| def _on_active_keyframe_changed(self, event): | ||
| active_keyframe = event.value |
There was a problem hiding this comment.
just making sure I understand what's going on here
frame_index is linked to the frame in the whole animation, active keyframe is linked to the key-frame in the key-frames list?
If I've got that right, would you mind adding some docstrings to these methods?
There was a problem hiding this comment.
Yes and yes ! will do :)
| self.__set_frame_index = 0 | ||
| self.events = EmitterGroup(source=self, _set_frame_index=None) | ||
|
|
||
| @property | ||
| def _set_frame_index(self): | ||
| return self.__set_frame_index | ||
|
|
||
| @_set_frame_index.setter | ||
| def _set_frame_index(self, frame_index): | ||
| if frame_index != self._set_frame_index: | ||
| self.__set_frame_index = frame_index | ||
| self.events._set_frame_index(value=frame_index) | ||
|
|
There was a problem hiding this comment.
What do you think about renaming this to _frame_index? I feel like it doesn't make sense to 'get' a _set_frame_index property
|
|
||
| def _keyframe_frame_index(self, keyframe): | ||
| n_frames = len(self._frames) | ||
| kf1_list = [self._frames._frame_index[n][0] for n in range(n_frames)] |
There was a problem hiding this comment.
it feels quite heavy to generate the whole list of keyframes to get an index... maybe we can find a better way?
There was a problem hiding this comment.
I'm switching back to something I wrote on a previous version. I hope it feels lighter ! :)
| else: | ||
| f = 0 | ||
| if len(self._key_frames) == 1: | ||
| kf1 = self._key_frames[0] | ||
| else: | ||
| for kf0, kf1 in pairwise(self._key_frames): | ||
| for s in range(kf1.steps): | ||
| fraction = s / kf1.steps | ||
| self._frame_index[f] = (kf0, kf1, fraction) | ||
| f += 1 |
There was a problem hiding this comment.
can you remove the outer else here to make the whole block less nested?
There was a problem hiding this comment.
I still kept an elif, for probably a better readability !
| else: | ||
| f = 0 | ||
| if len(self._key_frames) == 1: | ||
| kf1 = self._key_frames[0] |
There was a problem hiding this comment.
I don't really understand the purpose of this little section, could you explain it?
There was a problem hiding this comment.
Previously, if there was only one keyframe, it was not added as a frame and _frames was empty. I just added this here so _frames would be empty only when there are no keyframes at all.
|
Okay cool! Maybe we could refactor this logic into a ‘has_frames’ properly rather than adding it here?
|
|
Wasn't sure of what you meant, as it's mostly the number of key frames that is needed there. Would you still go for an attribute for this ?
|
|
Hey :) |
alisterburt
left a comment
There was a problem hiding this comment.
hey @Fifourche - this is looking really nice now! Thanks for your patience with my reviewing here, let's get this in!
| steps_to_keyframe = [ | ||
| kf.steps for kf in self.key_frames[1 : keyframe_index + 1] | ||
| ] |
There was a problem hiding this comment.
this is looking much nicer! 🙂
| @property | ||
| def _current_index(self): | ||
| return self.__current_index | ||
|
|
||
| @_current_index.setter | ||
| def _current_index(self, frame_index): | ||
| if frame_index != self._frame_index: | ||
| self.__current_index = frame_index | ||
| self.events._current_index(value=frame_index) |
There was a problem hiding this comment.
I really like having this directly on the FrameSequence
A PR to link the
AnimationSliderwith the frame index being set.Before it was synced with the change of
key_frames.selection.active, and now with the signal of anEmitter:frame_index, added toAnimation. This way, if we useset_movie_frame_index, it'll put the slider at the frame's position and not at the closest key frame.For some context, the idea I had was to sync the slider with a frame_index signal to prepare the way for a "previewer" capability. The preview would be launched via a method of
Animation, or a button next to the slider.