Beispiel #1
0
	def generate_audio_menu(self):
		items = []
		for i in range(0, director.app.audio.input_device.nb_input_channels):
			items.append(ShakeMenuItem("Input %d" % (i+1), self.audio_menu_select_input, i+1))
		if len(items) == 0:
			# Can't create any input, so go back to the default behavior
			director.app.play_scene.messages.show("No input device in your system.")
			self.object.attach_behavior(DefaultBehavior.DefaultBehavior())
		self.menu = ShakeMenu(self.object, *items, no_shake=True)
Beispiel #2
0
 def generate_audio_menu(self):
     items = []
     # print samples
     for sample in self.samples:
         samplename = os.path.splitext(sample)[0]
         items.append(
             ShakeMenuItem(samplename, self.audio_menu_select_sample,
                           "loops/" + sample))
     if len(items) == 0:
         # Can't create any sample, so go back to the default behavior
         director.app.play_scene.messages.show("No loop in directory.")
         self.object.attach_behavior(DefaultBehavior.DefaultBehavior())
     self.menu = ShakeMenu(self.object, *items, no_shake=True)
Beispiel #3
0
class LooperBehavior(SourceBehavior):
    def __init__(self):
        super(LooperBehavior, self).__init__("looper/looper.pd")
        global behavior_name
        self.display_name = behavior_name
        self.samples = []
        for file in os.listdir(
                os.path.abspath(
                    os.path.join(os.path.dirname(__file__), 'loops'))):
            if file.endswith(".wav"):
                self.samples.append(os.path.basename(file))
        self.time_last_impulse = 0
        self.needs_to_reappear = False

    def has_just_attached(self, object):
        super(LooperBehavior, self).has_just_attached(object)
        self.generate_audio_menu()

    def generate_audio_menu(self):
        items = []
        # print samples
        for sample in self.samples:
            samplename = os.path.splitext(sample)[0]
            items.append(
                ShakeMenuItem(samplename, self.audio_menu_select_sample,
                              "loops/" + sample))
        if len(items) == 0:
            # Can't create any sample, so go back to the default behavior
            director.app.play_scene.messages.show("No loop in directory.")
            self.object.attach_behavior(DefaultBehavior.DefaultBehavior())
        self.menu = ShakeMenu(self.object, *items, no_shake=True)

    def audio_menu_select_sample(self, spl):
        self.menu = None
        self.symbol_to_patch("load", spl)
        self.bang()

    def update(self):
        super(LooperBehavior, self).update()
        if self.menu:
            self.menu.update()

    def draw_3d(self):
        super(LooperBehavior, self).draw_3d()
        if self.menu:
            self.menu.draw_3d()

    def draw_background(self):
        super(LooperBehavior, self).draw_background()
        if self.menu:
            self.menu.draw_background()

    def draw_foreground(self):
        super(LooperBehavior, self).draw_foreground()
        if self.menu:
            self.menu.draw_foreground()
Beispiel #4
0
class LooperBehavior(SourceBehavior):
	def __init__(self):
		super(LooperBehavior, self).__init__("looper/looper.pd")
		global behavior_name
		self.display_name = behavior_name
		self.samples = []
		for file in os.listdir(os.path.abspath(os.path.join(os.path.dirname(__file__), 'loops'))):
			if file.endswith(".wav"):
				self.samples.append(os.path.basename(file))
		self.time_last_impulse = 0
		self.needs_to_reappear = False
	
	def has_just_attached(self, object):
		super(LooperBehavior, self).has_just_attached(object)
		self.generate_audio_menu()

	def generate_audio_menu(self):
		items = []
		# print samples
		for sample in self.samples:
			samplename = os.path.splitext(sample)[0]
			items.append(ShakeMenuItem(samplename, self.audio_menu_select_sample, "loops/"+sample))
		if len(items) == 0:
			# Can't create any sample, so go back to the default behavior
			director.app.play_scene.messages.show("No loop in directory.")
			self.object.attach_behavior(DefaultBehavior.DefaultBehavior())
		self.menu = ShakeMenu(self.object, *items, no_shake=True)

	def audio_menu_select_sample(self, spl):
		self.menu = None
		self.symbol_to_patch("load", spl)
		self.bang()

	def update(self):
		super(LooperBehavior, self).update()
		if self.menu:
			self.menu.update()

	def draw_3d(self):
		super(LooperBehavior, self).draw_3d()
		if self.menu:
			self.menu.draw_3d()

	def draw_background(self):
		super(LooperBehavior, self).draw_background()
		if self.menu:
			self.menu.draw_background()

	def draw_foreground(self):
		super(LooperBehavior, self).draw_foreground()
		if self.menu:
			self.menu.draw_foreground()
Beispiel #5
0
	def generate_audio_menu(self):
		items = []
		# print samples
		for sample in self.samples:
			samplename = os.path.splitext(sample)[0]
			items.append(ShakeMenuItem(samplename, self.audio_menu_select_sample, "loops/"+sample))
		if len(items) == 0:
			# Can't create any sample, so go back to the default behavior
			director.app.play_scene.messages.show("No loop in directory.")
			self.object.attach_behavior(DefaultBehavior.DefaultBehavior())
		self.menu = ShakeMenu(self.object, *items, no_shake=True)
Beispiel #6
0
 def show_menu(self):
     self.target_mode = False
     items = []
     if not isinstance(self.target.behavior, DefaultBehavior):
         items.append(
             ShakeMenuItem(
                 "Detach",
                 self.on_detach_target,
                 description=
                 "Detaches the selected behavior from its object."))
         if self.target.behavior.association:
             items.append(
                 ShakeMenuItem("Un%s" %
                               self.target.behavior.association_name,
                               self.on_unassociate_target,
                               description=''))
         else:
             items.append(
                 ShakeMenuItem(self.target.behavior.association_name,
                               self.on_associate_target,
                               self.target,
                               description=''))
     else:
         items.append(
             ShakeMenuItem(
                 "Attach",
                 self.on_attach_target,
                 description="Attaches a behavior to the selected object."))
     items.append(
         ShakeMenuItem(
             "Inspect",
             self.on_inspect_target,
             description="Inspects the attributes of the selected behavior."
         ))
     self.menu = ShakeMenu(self.object,
                           *items,
                           no_shake=True,
                           on_cancel=self.menu_cancelled)
     # Still allow the user to cancel
     self.menu.no_shake = False
Beispiel #7
0
class AudioInBehavior(SourceBehavior):
	def __init__(self):
		super(AudioInBehavior, self).__init__("audio_in/audio_in.pd")
		global behavior_name
		self.display_name = behavior_name
		self.sprite = ObjectSprite("maracas.png")
		self.menu = None
		self.init_attribute('volume', 'Volume', (0.0, 10.0), 'audio_in_behavior_default_volume', 0.5)
	
	def has_just_attached(self, object):
		super(AudioInBehavior, self).has_just_attached(object)
		self.generate_audio_menu()
	
	def generate_audio_menu(self):
		items = []
		for i in range(0, director.app.audio.input_device.nb_input_channels):
			items.append(ShakeMenuItem("Input %d" % (i+1), self.audio_menu_select_input, i+1))
		if len(items) == 0:
			# Can't create any input, so go back to the default behavior
			director.app.play_scene.messages.show("No input device in your system.")
			self.object.attach_behavior(DefaultBehavior.DefaultBehavior())
		self.menu = ShakeMenu(self.object, *items, no_shake=True)
	
	def audio_menu_select_input(self, i):
		self.menu = None
		self.symbol_to_patch("input", "in%d" % i)
	
	def update(self):
		super(AudioInBehavior, self).update()
		if self.menu:
			self.menu.update()
	
	def draw_3d(self):
		super(AudioInBehavior, self).draw_3d()
		if self.menu:
			self.menu.draw_3d()
		else:
			self.sprite.opacity = self.object.alpha() * 255
			self.sprite.draw()
	
	def draw_background(self):
		super(AudioInBehavior, self).draw_background()
		if self.menu:
			self.menu.draw_background()
	
	def draw_foreground(self):
		super(AudioInBehavior, self).draw_foreground()
		if self.menu:
			self.menu.draw_foreground()
Beispiel #8
0
	def show_menu(self):
		self.target_mode = False
		items = []
		if not isinstance(self.target.behavior, DefaultBehavior):
			items.append(ShakeMenuItem("Detach", self.on_detach_target, description="Detaches the selected behavior from its object."))
			if self.target.behavior.association:
				items.append(ShakeMenuItem("Un%s" % self.target.behavior.association_name, self.on_unassociate_target, description=''))
			else:
				items.append(ShakeMenuItem(self.target.behavior.association_name, self.on_associate_target, self.target, description=''))
		else:
			items.append(ShakeMenuItem("Attach", self.on_attach_target, description="Attaches a behavior to the selected object."))	
		items.append(ShakeMenuItem("Inspect", self.on_inspect_target, description="Inspects the attributes of the selected behavior."))
		self.menu = ShakeMenu(self.object, *items, no_shake=True, on_cancel=self.menu_cancelled)
		# Still allow the user to cancel
		self.menu.no_shake = False
Beispiel #9
0
class AlphaObjectBehavior(Behavior):
    def __init__(self):
        super(AlphaObjectBehavior, self).__init__()
        global behavior_name
        self.display_name = behavior_name
        self.menu = None
        self.target = None
        self.target_mode = True
        self.lock = False
        self.lock_cancel_callback = None
        self.shaker = ShakeRecognizer()
        self.target_association_selection_shaker = ShakeRecognizer()
        self.target_association_mode = False
        self.target_association_selection = None

    def has_just_attached(self, object):
        super(AlphaObjectBehavior, self).has_just_attached(object)

    def update(self):
        super(AlphaObjectBehavior, self).update()
        if self.target_mode:
            # Must select a target
            new_target = None
            min_distance = sys.float_info.max
            for id in director.app.objects:
                current = director.app.objects[id]
                dist = current.translation.distance(self.object.translation)
                if current != self.object and not current.is_zombie(
                ) and dist < min_distance:
                    min_distance = dist
                    new_target = current
            if self.target != new_target:
                # The target has changed.
                self.target = new_target
                self.shaker.reset()
            else:
                if self.target and self.shaker.update(
                        self.object.raw_translation):
                    self.show_menu()
        else:
            if not self.lock and self.menu:
                self.menu.update()
            if self.target_association_mode:
                new_selection = None
                min_distance = sys.float_info.max
                for id in director.app.objects:
                    current = director.app.objects[id]
                    dist = current.translation.distance(
                        self.object.translation)
                    if current != self.object and current != self.target and not current.is_zombie(
                    ) and dist < min_distance:
                        min_distance = dist
                        new_selection = current
                if self.target_association_selection != new_selection:
                    # The selection has changed.
                    self.target_association_selection = new_selection
                    self.target_association_selection_shaker.reset()
                else:
                    if self.target_association_selection and self.target_association_selection_shaker.update(
                            self.object.raw_translation):
                        # Associate the selection
                        self.target_association_mode = False
                        if self.target.behavior.associate(
                                self.target_association_selection.behavior):
                            director.app.play_scene.messages.show(
                                "Behaviors associated.")
                        self.target_association_selection = None
                        self.lock = False
                        self.menu_cancelled()

    def show_menu(self):
        self.target_mode = False
        items = []
        if not isinstance(self.target.behavior, DefaultBehavior):
            items.append(
                ShakeMenuItem(
                    "Detach",
                    self.on_detach_target,
                    description=
                    "Detaches the selected behavior from its object."))
            if self.target.behavior.association:
                items.append(
                    ShakeMenuItem("Un%s" %
                                  self.target.behavior.association_name,
                                  self.on_unassociate_target,
                                  description=''))
            else:
                items.append(
                    ShakeMenuItem(self.target.behavior.association_name,
                                  self.on_associate_target,
                                  self.target,
                                  description=''))
        else:
            items.append(
                ShakeMenuItem(
                    "Attach",
                    self.on_attach_target,
                    description="Attaches a behavior to the selected object."))
        items.append(
            ShakeMenuItem(
                "Inspect",
                self.on_inspect_target,
                description="Inspects the attributes of the selected behavior."
            ))
        self.menu = ShakeMenu(self.object,
                              *items,
                              no_shake=True,
                              on_cancel=self.menu_cancelled)
        # Still allow the user to cancel
        self.menu.no_shake = False

    def menu_cancelled(self):
        self.target_mode = True
        self.target = None
        self.menu = None

    def on_detach_target(self):
        self.target.attach_behavior(DefaultBehavior())
        self.menu_cancelled()
        director.app.play_scene.messages.show("Behavior detached.")

    def on_attach_target(self):
        self.target.behavior.menu.object = self.object
        self.lock_end_callback = self.target.behavior.menu.end_callback
        self.target.behavior.menu.end_callback = self.target_menu_end_callback
        self.target.behavior.menu.show_menu()
        self.lock = True
        director.app.play_scene.messages.show(
            "Please select a behavior type to attach the object to.")

    def target_menu_end_callback(self):
        self.target.behavior.menu.object = self.target
        self.target.behavior.menu.end_callback = self.lock_end_callback
        self.lock_end_callback = None
        self.lock = False
        self.menu_cancelled()
        director.app.play_scene.messages.show("Behavior attached.")

    def on_inspect_target(self):
        items = []
        for attrid in self.target.behavior.attributes:
            attr = self.target.behavior.attributes[attrid]
            items.append(
                ShakeMenuItem("%s: %s" %
                              (attr.display_name, attr.to_string())))
        if len(items) == 0:
            director.app.play_scene.messages.show(
                "This behavior has no attribute to inspect.")
            self.menu_cancelled()
            return
        self.menu.items = items
        self.menu.show_menu()

    def on_associate_target(self, target):
        self.target = target
        self.target_mode = False
        self.target_association_mode = True
        self.target_association_selection = None
        self.lock = True
        self.target_association_selection_shaker.reset()
        director.app.play_scene.messages.show(
            "Please place the alpha object near the desired behavior and shake it."
        )

    def on_unassociate_target(self):
        self.target.behavior.unassociate()
        self.menu_cancelled()
        director.app.play_scene.messages.show("Behavior unassociated.")

    def draw_background(self):
        super(AlphaObjectBehavior, self).draw_background()
        if not self.lock and self.menu:
            self.menu.draw_background()

    def draw_foreground(self):
        super(AlphaObjectBehavior, self).draw_foreground()
        if not self.lock and self.menu:
            self.menu.draw_foreground()

    def draw_3d(self):
        super(AlphaObjectBehavior, self).draw_3d()
        if self.target and not self.target_association_mode:
            self.target.model_view_matrix.load_gl()
            Graphics2d.draw_rect(-1.5,
                                 -1.5,
                                 3,
                                 3, (0.0, 0.0, 0.0, self.object.alpha()),
                                 filled=False,
                                 line_width=2)
            Graphics2d.draw_rect(-1.5,
                                 -1.5,
                                 3,
                                 3,
                                 self.object.color +
                                 (self.object.alpha() * 0.4, ),
                                 filled=True)
            self.object.model_view_matrix.load_gl()
        if self.target_association_selection:
            self.target_association_selection.model_view_matrix.load_gl()
            Graphics2d.draw_rect(-1.5,
                                 -1.5,
                                 3,
                                 3, (0.0, 0.0, 0.0, self.object.alpha()),
                                 filled=False,
                                 line_width=2)
            Graphics2d.draw_rect(-1.5,
                                 -1.5,
                                 3,
                                 3,
                                 self.object.color +
                                 (self.object.alpha() * 0.4, ),
                                 filled=True)
            self.object.model_view_matrix.load_gl()
        if self.lock:
            return
        if self.menu:
            self.menu.draw_3d()
Beispiel #10
0
class AlphaObjectBehavior(Behavior):
	def __init__(self):
		super(AlphaObjectBehavior, self).__init__()
		global behavior_name
		self.display_name = behavior_name
		self.menu = None
		self.target = None
		self.target_mode = True
		self.lock = False
		self.lock_cancel_callback = None
		self.shaker = ShakeRecognizer()
		self.target_association_selection_shaker = ShakeRecognizer()
		self.target_association_mode = False
		self.target_association_selection = None
	
	def has_just_attached(self, object):
		super(AlphaObjectBehavior, self).has_just_attached(object)
	
	def update(self):
		super(AlphaObjectBehavior, self).update()
		if self.target_mode:
			# Must select a target
			new_target = None
			min_distance = sys.float_info.max
			for id in director.app.objects:
				current = director.app.objects[id]
				dist = current.translation.distance(self.object.translation)
				if current != self.object and not current.is_zombie() and dist < min_distance:
					min_distance = dist
					new_target = current
			if self.target != new_target:
				# The target has changed.
				self.target = new_target
				self.shaker.reset()
			else:
				if self.target and self.shaker.update(self.object.raw_translation):
					self.show_menu()
		else:
			if not self.lock and self.menu:
				self.menu.update()
			if self.target_association_mode:
				new_selection = None
				min_distance = sys.float_info.max
				for id in director.app.objects:
					current = director.app.objects[id]
					dist = current.translation.distance(self.object.translation)
					if current != self.object and current != self.target and not current.is_zombie() and dist < min_distance:
						min_distance = dist
						new_selection = current
				if self.target_association_selection != new_selection:
					# The selection has changed.
					self.target_association_selection = new_selection
					self.target_association_selection_shaker.reset()
				else:
					if self.target_association_selection and self.target_association_selection_shaker.update(self.object.raw_translation):
						# Associate the selection
						self.target_association_mode = False
						if self.target.behavior.associate(self.target_association_selection.behavior):
							director.app.play_scene.messages.show("Behaviors associated.")
						self.target_association_selection = None
						self.lock = False
						self.menu_cancelled()
	
	def show_menu(self):
		self.target_mode = False
		items = []
		if not isinstance(self.target.behavior, DefaultBehavior):
			items.append(ShakeMenuItem("Detach", self.on_detach_target, description="Detaches the selected behavior from its object."))
			if self.target.behavior.association:
				items.append(ShakeMenuItem("Un%s" % self.target.behavior.association_name, self.on_unassociate_target, description=''))
			else:
				items.append(ShakeMenuItem(self.target.behavior.association_name, self.on_associate_target, self.target, description=''))
		else:
			items.append(ShakeMenuItem("Attach", self.on_attach_target, description="Attaches a behavior to the selected object."))	
		items.append(ShakeMenuItem("Inspect", self.on_inspect_target, description="Inspects the attributes of the selected behavior."))
		self.menu = ShakeMenu(self.object, *items, no_shake=True, on_cancel=self.menu_cancelled)
		# Still allow the user to cancel
		self.menu.no_shake = False
	
	def menu_cancelled(self):
		self.target_mode = True
		self.target = None
		self.menu = None
	
	def on_detach_target(self):
		self.target.attach_behavior(DefaultBehavior())
		self.menu_cancelled()
		director.app.play_scene.messages.show("Behavior detached.")
	
	def on_attach_target(self):
		self.target.behavior.menu.object = self.object
		self.lock_end_callback = self.target.behavior.menu.end_callback
		self.target.behavior.menu.end_callback = self.target_menu_end_callback
		self.target.behavior.menu.show_menu()
		self.lock = True
		director.app.play_scene.messages.show("Please select a behavior type to attach the object to.")
	
	def target_menu_end_callback(self):
		self.target.behavior.menu.object = self.target
		self.target.behavior.menu.end_callback = self.lock_end_callback
		self.lock_end_callback = None
		self.lock = False
		self.menu_cancelled()
		director.app.play_scene.messages.show("Behavior attached.")
	
	def on_inspect_target(self):
		items = []
		for attrid in self.target.behavior.attributes:
			attr = self.target.behavior.attributes[attrid]
			items.append(ShakeMenuItem("%s: %s" % (attr.display_name, attr.to_string())))
		if len(items) == 0:
			director.app.play_scene.messages.show("This behavior has no attribute to inspect.")
			self.menu_cancelled()
			return
		self.menu.items = items
		self.menu.show_menu()
	
	def on_associate_target(self, target):
		self.target = target
		self.target_mode = False
		self.target_association_mode = True
		self.target_association_selection = None
		self.lock = True
		self.target_association_selection_shaker.reset()
		director.app.play_scene.messages.show("Please place the alpha object near the desired behavior and shake it.")
	
	def on_unassociate_target(self):
		self.target.behavior.unassociate()
		self.menu_cancelled()
		director.app.play_scene.messages.show("Behavior unassociated.")
	
	def draw_background(self):
		super(AlphaObjectBehavior, self).draw_background()
		if not self.lock and self.menu:
			self.menu.draw_background();

	def draw_foreground(self):
		super(AlphaObjectBehavior, self).draw_foreground()
		if not self.lock and self.menu:
			self.menu.draw_foreground();
			
	def draw_3d(self):
		super(AlphaObjectBehavior, self).draw_3d()
		if self.target and not self.target_association_mode:
			self.target.model_view_matrix.load_gl()
			Graphics2d.draw_rect(-1.5, -1.5, 3, 3, (0.0, 0.0, 0.0, self.object.alpha()), filled=False, line_width=2)
			Graphics2d.draw_rect(-1.5, -1.5, 3, 3, self.object.color +  (self.object.alpha() * 0.4,), filled=True)
			self.object.model_view_matrix.load_gl()
		if self.target_association_selection:
			self.target_association_selection.model_view_matrix.load_gl()
			Graphics2d.draw_rect(-1.5, -1.5, 3, 3, (0.0, 0.0, 0.0, self.object.alpha()), filled=False, line_width=2)
			Graphics2d.draw_rect(-1.5, -1.5, 3, 3, self.object.color +  (self.object.alpha() * 0.4,), filled=True)
			self.object.model_view_matrix.load_gl()
		if self.lock:
			return
		if self.menu:
			self.menu.draw_3d()
Beispiel #11
0
class SamplerBehavior(SourceBehavior):
	def __init__(self):
		super(SamplerBehavior, self).__init__("sampler/sampler.pd")
		global behavior_name
		self.display_name = behavior_name
		self.samples = []
		for file in os.listdir(os.path.abspath(os.path.join(os.path.dirname(__file__), 'samples'))):
			if file.endswith(".wav"):
				self.samples.append(os.path.basename(file))
		# [os.path.basename(f) for f in glob.glob(os.path.abspath(os.path.join(os.path.dirname(__file__), 'samples', '*.wav')))]
		self.time_last_impulse = 0
		self.needs_to_reappear = False
	
	def has_just_attached(self, object):
		super(SamplerBehavior, self).has_just_attached(object)
		self.generate_audio_menu()

	def generate_audio_menu(self):
		items = []
		# print samples
		for sample in self.samples:
			samplename = os.path.splitext(sample)[0]
			items.append(ShakeMenuItem(samplename, self.audio_menu_select_sample, "samples/"+sample))
		if len(items) == 0:
			# Can't create any sample, so go back to the default behavior
			director.app.play_scene.messages.show("No sample in directory.")
			self.object.attach_behavior(DefaultBehavior.DefaultBehavior())
		self.menu = ShakeMenu(self.object, *items, no_shake=True)

	def audio_menu_select_sample(self, spl):
		self.menu = None
		self.symbol_to_patch("load", spl)

	def update(self):
		super(SamplerBehavior, self).update()
		if self.menu:
			self.menu.update()
		else:
			time = director.app.time
			if time - self.time_last_impulse > 0.1:
				if self.object.absent_amount() > 0.25:
					self.needs_to_reappear = True
			if self.needs_to_reappear:
				if self.object.absent_amount() == 0:
					self.needs_to_reappear = False
					self.number_to_patch("impulse", 1)
					self.time_last_impulse = time
					director.app.play_scene.do(ScaleTo(1.5, duration=0.1) + ScaleTo(1, duration=0.1), self.display_name_label)

	def draw_3d(self):
		super(SamplerBehavior, self).draw_3d()
		if self.menu:
			self.menu.draw_3d()

	def draw_background(self):
		super(SamplerBehavior, self).draw_background()
		if self.menu:
			self.menu.draw_background()

	def draw_foreground(self):
		super(SamplerBehavior, self).draw_foreground()
		if self.menu:
			self.menu.draw_foreground()
Beispiel #12
0
class SamplerBehavior(SourceBehavior):
    def __init__(self):
        super(SamplerBehavior, self).__init__("sampler/sampler.pd")
        global behavior_name
        self.display_name = behavior_name
        self.samples = []
        for file in os.listdir(
                os.path.abspath(
                    os.path.join(os.path.dirname(__file__), 'samples'))):
            if file.endswith(".wav"):
                self.samples.append(os.path.basename(file))
        # [os.path.basename(f) for f in glob.glob(os.path.abspath(os.path.join(os.path.dirname(__file__), 'samples', '*.wav')))]
        self.time_last_impulse = 0
        self.needs_to_reappear = False

    def has_just_attached(self, object):
        super(SamplerBehavior, self).has_just_attached(object)
        self.generate_audio_menu()

    def generate_audio_menu(self):
        items = []
        # print samples
        for sample in self.samples:
            samplename = os.path.splitext(sample)[0]
            items.append(
                ShakeMenuItem(samplename, self.audio_menu_select_sample,
                              "samples/" + sample))
        if len(items) == 0:
            # Can't create any sample, so go back to the default behavior
            director.app.play_scene.messages.show("No sample in directory.")
            self.object.attach_behavior(DefaultBehavior.DefaultBehavior())
        self.menu = ShakeMenu(self.object, *items, no_shake=True)

    def audio_menu_select_sample(self, spl):
        self.menu = None
        self.symbol_to_patch("load", spl)

    def update(self):
        super(SamplerBehavior, self).update()
        if self.menu:
            self.menu.update()
        else:
            time = director.app.time
            if time - self.time_last_impulse > 0.1:
                if self.object.absent_amount() > 0.25:
                    self.needs_to_reappear = True
            if self.needs_to_reappear:
                if self.object.absent_amount() == 0:
                    self.needs_to_reappear = False
                    self.number_to_patch("impulse", 1)
                    self.time_last_impulse = time
                    director.app.play_scene.do(
                        ScaleTo(1.5, duration=0.1) + ScaleTo(1, duration=0.1),
                        self.display_name_label)

    def draw_3d(self):
        super(SamplerBehavior, self).draw_3d()
        if self.menu:
            self.menu.draw_3d()

    def draw_background(self):
        super(SamplerBehavior, self).draw_background()
        if self.menu:
            self.menu.draw_background()

    def draw_foreground(self):
        super(SamplerBehavior, self).draw_foreground()
        if self.menu:
            self.menu.draw_foreground()