class_docstr: Mixin enabling time interaction controls.
class_docstr_tok: ["Mixin","enabling","time","interaction","controls","."]
code: def _enable_time_interaction(
      self,
      fig,
      current_time_func,
      times,
      init_playback_speed=0.01,
      playback_speed_range=[0.01, 0.1],
  ):
      from ..ui_events import (
          PlaybackSpeed,
          TimeChange,
          publish,
          subscribe,
      )
  
      self._fig = fig
      self._current_time_func = current_time_func
      self._times = times
      self._init_time = current_time_func()
      self._init_playback_speed = init_playback_speed
      self._playback_speed_range = playback_speed_range
  
      if not hasattr(self, "_dock"):
          self._dock_initialize()
  
      if not hasattr(self, "_tool_bar") or self._tool_bar is None:
          self._tool_bar_initialize(name="Toolbar")
  
      if not hasattr(self, "_widgets"):
          self._widgets = dict()
  
      # Dock widgets
      @_auto_weakref
      def publish_time_change(time_index):
          publish(
              fig,
              TimeChange(
                  time=np.interp(
                      time_index, np.arange(len(times)), times
                  )
              ),
          )
  
      layout = self._dock_add_group_box("")
      self._widgets["time_slider"] = self._dock_add_slider(
          name="Time (s)",
          value=np.interp(
              current_time_func(), times, np.arange(len(times))
          ),
          rng=[0, len(times) - 1],
          double=True,
          callback=publish_time_change,
          compact=False,
          layout=layout,
      )
      hlayout = self._dock_add_layout(vertical=False)
      self._widgets["min_time"] = self._dock_add_label(
          "-", layout=hlayout
      )
      self._dock_add_stretch(hlayout)
      self._widgets["current_time"] = self._dock_add_label(
          value="x", layout=hlayout
      )
      self._dock_add_stretch(hlayout)
      self._widgets["max_time"] = self._dock_add_label(
          value="+", layout=hlayout
      )
      self._layout_add_widget(layout, hlayout)
  
      self._widgets["min_time"].set_value(f"{times[0]: .3f}")
      self._widgets["current_time"].set_value(
          f"{current_time_func(): .3f}"
      )
      self._widgets["max_time"].set_value(f"{times[-1]: .3f}")
  
      @_auto_weakref
      def publish_playback_speed(speed):
          publish(fig, PlaybackSpeed(speed=speed))
  
      self._widgets["playback_speed"] = self._dock_add_spin_box(
          name="Speed",
          value=init_playback_speed,
          rng=playback_speed_range,
          callback=publish_playback_speed,
          layout=layout,
      )
  
      # Tool bar buttons
      self._widgets["reset"] = self._tool_bar_add_button(
          name="reset", desc="Reset", func=self._reset_time
      )
      self._widgets["play"] = self._tool_bar_add_play_button(
          name="play",
          desc="Play/Pause",
          func=self._toggle_playback,
          shortcut=" ",
      )
  
      # Configure playback
      self._playback = False
      self._playback_initialize(
          func=self._play,
          timeout=17,
          value=np.interp(
              current_time_func(), times, np.arange(len(times))
          ),
          rng=[0, len(times) - 1],
          time_widget=self._widgets["time_slider"],
          play_widget=self._widgets["play"],
      )
  
      # Keyboard shortcuts
      @_auto_weakref
      def shift_time(direction):
          amount = self._widgets["playback_speed"].get_value()
          publish(
              self._fig,
              TimeChange(
                  time=self._current_time_func() + direction * amount
              ),
          )
  
      if self.plotter.iren is not None:
          self.plotter.add_key_event(
              "n", partial(shift_time, direction=1)
          )
          self.plotter.add_key_event(
              "b", partial(shift_time, direction=-1)
          )
  
      # Subscribe to relevant UI events
      subscribe(fig, "time_change", self._on_time_change)
      subscribe(fig, "playback_speed", self._on_playback_speed)
  
imports: import importlib
  import time
  from contextlib import contextmanager
  from functools import partial
  import numpy
  from ...utils import _auto_weakref, _check_option, _validate_type, fill_doc, get_config, logger, verbose
  from .._3d import _get_3d_option
  from ..utils import safe_event
  from ._utils import VALID_3D_BACKENDS
label_desc: Use image node_id 1 for calling the _TimeInteraction obj's underlying member method code with example usage: obj._enable_time_interaction(fig, current_time_func, times, init_playback_speed, playback_speed_range) without return types