33import signal
44import sys
55import time
6- from enum import Enum , IntEnum , auto , unique
6+ from enum import Enum , IntFlag , auto , unique
77from pathlib import Path
88from typing import Any , Dict , List , Optional , Tuple , Union
99
@@ -60,16 +60,20 @@ class AspectRatio(Enum):
6060
6161
6262@unique
63- class State (IntEnum ):
63+ class State (IntFlag ):
6464 """Represents all possible states of a slide presentation."""
6565
66+ """A video is actively being played."""
6667 PLAYING = auto ()
68+ """A video was manually paused."""
6769 PAUSED = auto ()
70+ """Waiting for user to press next (or else)."""
6871 WAIT = auto ()
72+ """Presentation was terminated."""
6973 END = auto ()
7074
7175 def __str__ (self ) -> str :
72- return self .name .capitalize ()
76+ return self .name .capitalize () # type: ignore
7377
7478
7579def now () -> float :
@@ -279,10 +283,10 @@ def reset(self) -> None:
279283
280284 def load_last_slide (self ) -> None :
281285 """Loads last slide."""
282- self .current_slide_index = len (self .slides ) - 2
286+ self .current_slide_index = len (self .slides ) - 1
283287 assert (
284288 self .current_slide_index >= 0
285- ), "Slides should be at list of a least two elements "
289+ ), "Slides should be at list of a least one element "
286290 self .current_animation = self .current_slide .start_animation
287291 self .load_animation_cap (self .current_animation )
288292 self .slides [- 1 ].terminated = False
@@ -315,41 +319,37 @@ def update_state(self, state: State) -> Tuple[np.ndarray, State]:
315319 It does this by reading the video information and checking if the state is still correct.
316320 It returns the frame to show (lastframe) and the new state.
317321 """
318- if state == State .PAUSED :
322+ if state ^ State .PLAYING : # If not playing, we return the same
319323 if self .lastframe is None :
320324 _ , self .lastframe = self .current_cap .read ()
321325 return self .lastframe , state
326+
322327 still_playing , frame = self .current_cap .read ()
328+
323329 if still_playing :
324330 self .lastframe = frame
325- elif state == state .WAIT or state == state .PAUSED : # type: ignore
326- return self .lastframe , state
327- elif self .current_slide .is_last () and self .current_slide .terminated :
328- return self .lastframe , State .END
329- else : # not still playing
330- if self .is_last_animation :
331- if self .current_slide .is_slide ():
331+ return self .lastframe , State .PLAYING
332+
333+ # Video was terminated
334+ if self .is_last_animation :
335+ if self .current_slide .is_loop ():
336+ if self .reverse :
332337 state = State .WAIT
333- elif self .current_slide .is_loop ():
334- if self .reverse :
335- state = State .WAIT
336- else :
337- self .current_animation = self .current_slide .start_animation
338- state = State .PLAYING
339- self .rewind_current_slide ()
340- elif self .current_slide .is_last ():
341- self .current_slide .terminated = True
342- elif (
343- self .current_slide .is_last ()
344- and self .current_slide .end_animation == self .current_animation
345- ):
346- state = State .WAIT
338+
339+ else :
340+ self .current_animation = self .current_slide .start_animation
341+ state = State .PLAYING
342+ self .rewind_current_slide ()
343+ elif self .current_slide .is_last ():
344+ state = State .END
347345 else :
348- # Play next video!
349- self .current_animation = self .next_animation
350- self .load_animation_cap (self .current_animation )
351- # Reset video to position zero if it has been played before
352- self .current_cap .set (cv2 .CAP_PROP_POS_FRAMES , 0 )
346+ state = State .WAIT
347+ else :
348+ # Play next video!
349+ self .current_animation = self .next_animation
350+ self .load_animation_cap (self .current_animation )
351+ # Reset video to position zero if it has been played before
352+ self .current_cap .set (cv2 .CAP_PROP_POS_FRAMES , 0 )
353353
354354 return self .lastframe , state
355355
@@ -431,6 +431,11 @@ def current_background_color(self) -> Color:
431431 """Returns the background color of the current presentation."""
432432 return self .current_presentation .background_color
433433
434+ @property
435+ def is_last_presentation (self ) -> bool :
436+ """Returns True if current presentation is the last one."""
437+ return self .current_presentation_index == len (self ) - 1
438+
434439 def start (self ) -> None :
435440 super ().start ()
436441 self .change_presentation_signal .emit ()
@@ -442,18 +447,15 @@ def run(self) -> None:
442447 self .lastframe , self .state = self .current_presentation .update_state (
443448 self .state
444449 )
445- if self .state == State .PLAYING or self . state == State .PAUSED :
450+ if self .state & ( State .PLAYING | State .PAUSED ) :
446451 if self .start_paused :
447452 self .state = State .PAUSED
448453 self .start_paused = False
449- if self .state == State .END :
454+ if self .state & State .END :
450455 if self .current_presentation_index == len (self .presentations ) - 1 :
451456 if self .exit_after_last_slide :
452457 self .run_flag = False
453458 continue
454- else :
455- self .current_presentation_index += 1
456- self .state = State .PLAYING
457459
458460 self .handle_key ()
459461 self .show_video ()
@@ -560,10 +562,14 @@ def handle_key(self) -> None:
560562 self .state = State .PAUSED
561563 elif self .state == State .PAUSED and keys .PLAY_PAUSE .match (key ):
562564 self .state = State .PLAYING
563- elif self .state == State .WAIT and (
564- keys .CONTINUE .match (key ) or keys .PLAY_PAUSE .match (key )
565+ elif self .state & ( State .END | State . WAIT ) and (
566+ keys .CONTINUE .match (key ) or keys .PLAY_PAUSE .match (key ) or self . skip_all
565567 ):
566- self .current_presentation .load_next_slide ()
568+ if (self .state & State .END ) and not self .is_last_presentation :
569+ self .current_presentation_index += 1
570+ self .current_presentation .rewind_current_slide ()
571+ else :
572+ self .current_presentation .load_next_slide ()
567573 self .state = State .PLAYING
568574 elif (
569575 self .state == State .PLAYING and keys .CONTINUE .match (key )
@@ -574,6 +580,7 @@ def handle_key(self) -> None:
574580 if self .current_presentation_index == 0 :
575581 self .current_presentation .load_previous_slide ()
576582 else :
583+ self .current_presentation .cancel_reverse ()
577584 self .current_presentation_index -= 1
578585 self .current_presentation .load_last_slide ()
579586 self .state = State .PLAYING
0 commit comments