11# -*- coding: utf-8 -*-
22
33import sys
4+ from types import MethodType
45
56import yaml
6- from asciimatics .exceptions import ResizeScreenError
7+ from asciimatics .exceptions import NextScene , ResizeScreenError
78from asciimatics .effects import Stars , Snow
89from asciimatics .scene import Scene
910from asciimatics .screen import Screen
1718__all__ = ['termslides' ]
1819
1920
21+ def patch_draw_next_frame (self , repeat = True ):
22+ """
23+ Draw the next frame in the currently configured Scenes. You must call
24+ :py:meth:`.set_scenes` before using this for the first time.
25+
26+ :param repeat: Whether to repeat the Scenes once it has reached the end.
27+ Defaults to True.
28+
29+ :raises StopApplication: if the application should be terminated.
30+ """
31+ scene = self ._scenes [self ._scene_index ]
32+ try :
33+ # Check for an event now and remember for refresh reasons.
34+ event = self .get_event ()
35+ got_event = event is not None
36+
37+ # Now process all the input events
38+ while event is not None :
39+ event = scene .process_event (event )
40+ if event is not None and self ._unhandled_input is not None :
41+ self ._unhandled_input (event )
42+ event = self .get_event ()
43+
44+ # Only bother with a refresh if there was an event to process or
45+ # we have to refresh due to the refresh limit required for an
46+ # Effect.
47+ self ._frame += 1
48+ self ._idle_frame_count -= 1
49+ if got_event or self ._idle_frame_count <= 0 or self ._forced_update :
50+ self ._forced_update = False
51+ self ._idle_frame_count = 1000000
52+ for effect in scene .effects :
53+ # Update the effect and delete if needed.
54+ effect .update (self ._frame )
55+ if effect .delete_count is not None :
56+ effect .delete_count -= 1
57+ if effect .delete_count <= 0 :
58+ scene .remove_effect (effect )
59+
60+ # Sort out when we next _need_ to do a refresh.
61+ if effect .frame_update_count > 0 :
62+ self ._idle_frame_count = min (self ._idle_frame_count ,
63+ effect .frame_update_count )
64+ self .refresh ()
65+
66+ if 0 < scene .duration <= self ._frame :
67+ raise NextScene ()
68+ except NextScene as e :
69+ # Tidy up the current scene.
70+ scene .exit ()
71+
72+ # Find the specified next Scene
73+ if e .name is None :
74+ # Just allow next iteration of loop
75+ self ._scene_index += 1
76+ if self ._scene_index >= len (self ._scenes ):
77+ if repeat :
78+ self ._scene_index = 0
79+ else :
80+ raise StopApplication ("Repeat disabled" )
81+ else :
82+ # Find the required scene.
83+ for i , scene in enumerate (self ._scenes ):
84+ if scene .name == e .name :
85+ self ._scene_index = i
86+ break
87+ else :
88+ raise RuntimeError (
89+ "Could not find Scene: '{}'" .format (e .name ))
90+
91+ # Reset the screen if needed.
92+ scene = self ._scenes [self ._scene_index ]
93+ scene .reset ()
94+ self ._frame = 0
95+ self ._idle_frame_count = 0
96+ if scene .clear :
97+ self .clear ()
98+ else :
99+ self ._start_line = 0
100+ self ._x = self ._y = None
101+ self ._reset ()
102+
103+
20104@group ()
21105def cli ():
22106 pass
@@ -31,6 +115,7 @@ def termslides(file):
31115 def slides_show (screen , scene ):
32116 scenes = []
33117 screen .set_title (slides .pop ('title' , 'TermSlides' ))
118+ screen .draw_next_frame = MethodType (patch_draw_next_frame , screen )
34119
35120 # list view
36121 slide_view = SlideView (screen , slides )
@@ -67,7 +152,7 @@ def slides_show(screen, scene):
67152 # input handler
68153 effects .insert (0 , InputHandler (screen , list_view ))
69154 # add to scenes
70- scenes .append (Scene (effects , duration , name = name ))
155+ scenes .append (Scene (effects , duration , name = name , clear = ( start is None ) ))
71156
72157 screen .play (scenes , stop_on_resize = True , start_scene = scene )
73158
0 commit comments