@@ -121,6 +121,8 @@ class ScriptController(NSWindowController):
121121 outputView = IBOutlet ()
122122 editorView = IBOutlet ()
123123 statusView = IBOutlet ()
124+ runButton = IBOutlet ()
125+ stopButton = IBOutlet ()
124126
125127 # auxiliary windows
126128 dashboardController = IBOutlet ()
@@ -198,6 +200,7 @@ def awakeFromNib(self):
198200 # wire up the statusView in the title bar
199201 statusItem = win .toolbar ().items ()[0 ]
200202 statusItem .setView_ (self .statusView )
203+ self .setToolbarMode_ ('stop' )
201204
202205 # sign up for autoresume on quit-and-relaunch (but only if this isn't console.py)
203206 if self .editorView :
@@ -236,7 +239,6 @@ def windowDidLoad(self):
236239 if self .vm .source :
237240 self .editorView .source = self .vm .source
238241
239-
240242 def encodeRestorableStateWithCoder_ (self , coder ):
241243 # walk through editor's superviews to autosave the splitview positions
242244 if self .editorView :
@@ -357,6 +359,27 @@ def runFullscreen_(self, sender):
357359 NSCursor .hide ()
358360 self .runScript ()
359361
362+ def validateToolbarItem_ (self , item ):
363+ return item .isEnabled ()
364+
365+ def setToolbarMode_ (self , mode ):
366+ # mode is export/play/pause/stop
367+ toolbar = self .window ().toolbar ()
368+ if mode == 'export' :
369+ while len (toolbar .items ()) > 1 :
370+ toolbar .removeItemAtIndex_ (1 )
371+ else :
372+ if len (toolbar .items ()) == 1 :
373+ toolbar .insertItemWithItemIdentifier_atIndex_ (self .stopButton .itemIdentifier (), 1 )
374+ toolbar .insertItemWithItemIdentifier_atIndex_ (self .runButton .itemIdentifier (), 2 )
375+
376+ if mode == 'stop' :
377+ run_style = ('play.fill' , 'Run Script' )
378+ else :
379+ run_style = ('play.fill' , 'Resume' ) if mode == 'pause' else ('pause.fill' , 'Pause' )
380+ self .runButton .setImage_ (NSImage .imageWithSystemSymbolName_accessibilityDescription_ (* run_style ))
381+ self .stopButton .setEnabled_ (mode != 'stop' )
382+
360383 def runScript (self ):
361384 """Compile the script and run its global scope.
362385
@@ -368,13 +391,16 @@ def runScript(self):
368391 call self.invoke('draw') until cancelled by the user.
369392 """
370393
371- # halt any animation that was already running
394+ # if an animation is already running, either pause or resume it
372395 if self .animationTimer :
373- self .animationTimer .invalidate ()
374- self .animationTimer = None
396+ if self .animationTimer .isValid ():
397+ self .animationTimer .invalidate ()
398+ else :
399+ self .animationTimer = set_timeout (self , 'step' , 1.0 / self .vm .speed , repeat = True )
400+ self .setToolbarMode_ ("play" if self .animationTimer .isValid () else "pause" )
401+ return
375402
376- # get all the output progress indicators going
377- self .statusView .beginRun ()
403+ # clear the previous run's output
378404 if (self .outputView ):
379405 self .editorView .clearErrors ()
380406 self .outputView .clear (timestamp = True )
@@ -392,9 +418,6 @@ def runScript(self):
392418 success = self .invoke ("setup" )
393419
394420 if not success or not self .vm .animated :
395- # halt the progress indicator if we crashed (or if we succeeded in a non-anim)
396- self .statusView .endRun ()
397-
398421 # don't mess with the gui window-state if running in fullscreen until the
399422 # user explicitly cancels with esc or cmd-period
400423 if success and not self .fullScreen :
@@ -416,6 +439,9 @@ def runScript(self):
416439 # Start the timer
417440 self .animationTimer = set_timeout (self , 'step' , 1.0 / self .vm .speed , repeat = True )
418441
442+ # enable the stop button in the toolbar
443+ self .setToolbarMode_ ("play" )
444+
419445 def step (self ):
420446 """Keep calling the script's draw method until an error occurs or the animation complete."""
421447 ok = self .invoke ("draw" )
@@ -518,6 +544,9 @@ def exportInit(self, kind, fname, opts):
518544 # if we're exporting multiple frames, give some ui feedback
519545 if self .outputView :
520546 self .outputView .clear (timestamp = True )
547+
548+ # replace the toolbar buttons with a progress indicator
549+ self .setToolbarMode_ ("export" )
521550 if self .statusView :
522551 self .statusView .beginExport ()
523552
@@ -580,9 +609,8 @@ def stopScript(self):
580609 result = self .vm .stop ()
581610 self .echo (result .output )
582611
583- # disable progress spinner
584- if self .statusView and not self .vm .session :
585- self .statusView .endRun ()
612+ # re-enable the play button
613+ self .setToolbarMode_ ("stop" )
586614
587615 # relay any errors to the text panes (if we're in the app)
588616 if self .editorView :
0 commit comments