mirror of
https://github.com/3b1b/manim.git
synced 2025-04-13 09:47:07 +00:00
Some cleanup for interactive mobjects
This commit is contained in:
parent
baab9ddf02
commit
5a2a363a87
4 changed files with 37 additions and 32 deletions
|
@ -414,7 +414,7 @@ class ControlsExample(Scene):
|
||||||
def text_updater(old_text):
|
def text_updater(old_text):
|
||||||
assert(isinstance(old_text, Text))
|
assert(isinstance(old_text, Text))
|
||||||
new_text = Text(self.textbox.get_value(), size=old_text.size)
|
new_text = Text(self.textbox.get_value(), size=old_text.size)
|
||||||
new_text.align_data_and_family(old_text)
|
# new_text.align_data_and_family(old_text)
|
||||||
new_text.move_to(old_text)
|
new_text.move_to(old_text)
|
||||||
if self.checkbox.get_value():
|
if self.checkbox.get_value():
|
||||||
new_text.set_fill(
|
new_text.set_fill(
|
||||||
|
@ -424,14 +424,13 @@ class ControlsExample(Scene):
|
||||||
else:
|
else:
|
||||||
new_text.set_opacity(0)
|
new_text.set_opacity(0)
|
||||||
old_text.become(new_text)
|
old_text.become(new_text)
|
||||||
|
|
||||||
text.add_updater(text_updater)
|
text.add_updater(text_updater)
|
||||||
|
|
||||||
self.add(MotionMobject(text))
|
self.add(MotionMobject(text))
|
||||||
|
|
||||||
self.textbox.set_value("Manim")
|
self.textbox.set_value("Manim")
|
||||||
self.wait(60)
|
# self.embed()
|
||||||
self.embed()
|
|
||||||
|
|
||||||
|
|
||||||
# See https://github.com/3b1b/videos for many, many more
|
# See https://github.com/3b1b/videos for many, many more
|
||||||
|
|
|
@ -353,7 +353,11 @@ class Camera(object):
|
||||||
if shader_wrapper.vert_indices is None:
|
if shader_wrapper.vert_indices is None:
|
||||||
ibo = None
|
ibo = None
|
||||||
else:
|
else:
|
||||||
ibo = self.ctx.buffer(shader_wrapper.vert_indices.astype('i4').tobytes())
|
vert_index_data = shader_wrapper.vert_indices.astype('i4').tobytes()
|
||||||
|
if vert_index_data:
|
||||||
|
ibo = self.ctx.buffer(vert_index_data)
|
||||||
|
else:
|
||||||
|
ibo = None
|
||||||
|
|
||||||
# Program and vertex array
|
# Program and vertex array
|
||||||
shader_program, vert_format = self.get_shader_program(shader_wrapper)
|
shader_program, vert_format = self.get_shader_program(shader_wrapper)
|
||||||
|
|
|
@ -29,7 +29,8 @@ class MotionMobject(Mobject):
|
||||||
def __init__(self, mobject, **kwargs):
|
def __init__(self, mobject, **kwargs):
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
self.mobject = mobject
|
self.mobject = mobject
|
||||||
self.mobject.add_updater(lambda mob: None) # To avoid locking it as static mobject
|
# To avoid locking it as static mobject
|
||||||
|
self.mobject.add_updater(lambda mob: None)
|
||||||
self.add(mobject)
|
self.add(mobject)
|
||||||
|
|
||||||
def on_mouse_drag(self, point, d_point, buttons, modifiers):
|
def on_mouse_drag(self, point, d_point, buttons, modifiers):
|
||||||
|
@ -40,7 +41,7 @@ class MotionMobject(Mobject):
|
||||||
|
|
||||||
class Button(Mobject):
|
class Button(Mobject):
|
||||||
"""
|
"""
|
||||||
Pass any mobject and register an on_click method
|
Pass any mobject and register an on_click method
|
||||||
"""
|
"""
|
||||||
|
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
|
@ -69,7 +70,8 @@ class ContolMobject(ValueTracker):
|
||||||
super().__init__(value=value, **kwargs)
|
super().__init__(value=value, **kwargs)
|
||||||
self.add(*mobjects)
|
self.add(*mobjects)
|
||||||
|
|
||||||
self.add_updater(lambda mob: None) # To avoid lock_static_mobject_data while waiting in scene
|
# To avoid lock_static_mobject_data while waiting in scene
|
||||||
|
self.add_updater(lambda mob: None)
|
||||||
self.fix_in_frame()
|
self.fix_in_frame()
|
||||||
|
|
||||||
def set_value(self, value):
|
def set_value(self, value):
|
||||||
|
@ -85,6 +87,7 @@ class ContolMobject(ValueTracker):
|
||||||
# To be implemented in subclasses
|
# To be implemented in subclasses
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class EnableDisableButton(ContolMobject):
|
class EnableDisableButton(ContolMobject):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"value_type": np.dtype(bool),
|
"value_type": np.dtype(bool),
|
||||||
|
@ -103,12 +106,12 @@ class EnableDisableButton(ContolMobject):
|
||||||
super().__init__(value, self.box, **kwargs)
|
super().__init__(value, self.box, **kwargs)
|
||||||
|
|
||||||
def assert_value(self, value):
|
def assert_value(self, value):
|
||||||
assert(value == True or value == False)
|
assert(isinstance(value, bool))
|
||||||
|
|
||||||
def set_value_anim(self, value):
|
def set_value_anim(self, value):
|
||||||
if value == True:
|
if value:
|
||||||
self.box.set_fill(self.enable_color)
|
self.box.set_fill(self.enable_color)
|
||||||
elif value == False:
|
else:
|
||||||
self.box.set_fill(self.disable_color)
|
self.box.set_fill(self.disable_color)
|
||||||
|
|
||||||
def toggle_value(self):
|
def toggle_value(self):
|
||||||
|
@ -146,15 +149,15 @@ class Checkbox(ContolMobject):
|
||||||
super().__init__(value, self.box, self.box_content, **kwargs)
|
super().__init__(value, self.box, self.box_content, **kwargs)
|
||||||
|
|
||||||
def assert_value(self, value):
|
def assert_value(self, value):
|
||||||
assert(value == True or value == False)
|
assert(isinstance(value, bool))
|
||||||
|
|
||||||
def toggle_value(self):
|
def toggle_value(self):
|
||||||
super().set_value(not self.get_value())
|
super().set_value(not self.get_value())
|
||||||
|
|
||||||
def set_value_anim(self, value):
|
def set_value_anim(self, value):
|
||||||
if value == True:
|
if value:
|
||||||
self.box_content.become(self.get_checkmark())
|
self.box_content.become(self.get_checkmark())
|
||||||
elif value == False:
|
else:
|
||||||
self.box_content.become(self.get_cross())
|
self.box_content.become(self.get_cross())
|
||||||
|
|
||||||
def on_mouse_press(self, point, button, mods):
|
def on_mouse_press(self, point, button, mods):
|
||||||
|
@ -191,7 +194,6 @@ class Checkbox(ContolMobject):
|
||||||
class LinearNumberSlider(ContolMobject):
|
class LinearNumberSlider(ContolMobject):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"value_type": np.float64,
|
"value_type": np.float64,
|
||||||
|
|
||||||
"min_value": -10.0,
|
"min_value": -10.0,
|
||||||
"max_value": 10.0,
|
"max_value": 10.0,
|
||||||
"step": 1.0,
|
"step": 1.0,
|
||||||
|
@ -245,6 +247,7 @@ class LinearNumberSlider(ContolMobject):
|
||||||
value_nearest_to_step = self.min_value + no_of_steps * self.step
|
value_nearest_to_step = self.min_value + no_of_steps * self.step
|
||||||
return value_nearest_to_step
|
return value_nearest_to_step
|
||||||
|
|
||||||
|
|
||||||
class ColorSliders(Group):
|
class ColorSliders(Group):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"sliders_kwargs": {},
|
"sliders_kwargs": {},
|
||||||
|
@ -265,7 +268,7 @@ class ColorSliders(Group):
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
digest_config(self, kwargs)
|
digest_config(self, kwargs)
|
||||||
|
|
||||||
rgb_kwargs = {"value": self.default_rgb_value,"min_value": 0, "max_value": 255, "step": 1}
|
rgb_kwargs = {"value": self.default_rgb_value, "min_value": 0, "max_value": 255, "step": 1}
|
||||||
a_kwargs = {"value": self.default_a_value, "min_value": 0, "max_value": 1, "step": 0.04}
|
a_kwargs = {"value": self.default_a_value, "min_value": 0, "max_value": 1, "step": 0.04}
|
||||||
|
|
||||||
self.r_slider = LinearNumberSlider(**self.sliders_kwargs, **rgb_kwargs)
|
self.r_slider = LinearNumberSlider(**self.sliders_kwargs, **rgb_kwargs)
|
||||||
|
@ -377,12 +380,16 @@ class Textbox(ContolMobject):
|
||||||
self.update_text(value)
|
self.update_text(value)
|
||||||
|
|
||||||
def update_text(self, value):
|
def update_text(self, value):
|
||||||
self.remove(self.text)
|
text = self.text
|
||||||
self.text.__init__(value, **self.text_kwargs)
|
self.remove(text)
|
||||||
self.text.set_width(self.box.get_width() - 2*self.text_buff, stretch=True)
|
text.__init__(value, **self.text_kwargs)
|
||||||
self.text.add_updater(lambda mob: mob.move_to(self.box))
|
height = text.get_height()
|
||||||
self.text.fix_in_frame()
|
text.set_width(self.box.get_width() - 2 * self.text_buff)
|
||||||
self.add(self.text)
|
if text.get_height() > height:
|
||||||
|
text.set_height(height)
|
||||||
|
text.add_updater(lambda mob: mob.move_to(self.box))
|
||||||
|
text.fix_in_frame()
|
||||||
|
self.add(text)
|
||||||
|
|
||||||
def active_anim(self, isActive):
|
def active_anim(self, isActive):
|
||||||
if isActive:
|
if isActive:
|
||||||
|
@ -411,14 +418,14 @@ class Textbox(ContolMobject):
|
||||||
elif symbol == PygletWindowKeys.TAB:
|
elif symbol == PygletWindowKeys.TAB:
|
||||||
new_value = old_value + '\t'
|
new_value = old_value + '\t'
|
||||||
elif symbol == PygletWindowKeys.BACKSPACE:
|
elif symbol == PygletWindowKeys.BACKSPACE:
|
||||||
new_value = old_value[:-1] or ''
|
new_value = old_value[:-1] or ''
|
||||||
self.set_value(new_value)
|
self.set_value(new_value)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
class ControlPanel(Group):
|
class ControlPanel(Group):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"listen_to_events": True,
|
"listen_to_events": True,
|
||||||
|
|
||||||
"panel_kwargs": {
|
"panel_kwargs": {
|
||||||
"width": FRAME_WIDTH / 4,
|
"width": FRAME_WIDTH / 4,
|
||||||
"height": MED_SMALL_BUFF + FRAME_HEIGHT,
|
"height": MED_SMALL_BUFF + FRAME_HEIGHT,
|
||||||
|
@ -478,7 +485,7 @@ class ControlPanel(Group):
|
||||||
direction=UP,
|
direction=UP,
|
||||||
buff=MED_SMALL_BUFF
|
buff=MED_SMALL_BUFF
|
||||||
)
|
)
|
||||||
|
|
||||||
self.controls.set_x(controls_old_x)
|
self.controls.set_x(controls_old_x)
|
||||||
|
|
||||||
def add_controls(self, *new_controls):
|
def add_controls(self, *new_controls):
|
||||||
|
@ -502,7 +509,7 @@ class ControlPanel(Group):
|
||||||
self.panel_opener.set_x(panel_opener_x)
|
self.panel_opener.set_x(panel_opener_x)
|
||||||
self.move_panel_and_controls_to_panel_opener()
|
self.move_panel_and_controls_to_panel_opener()
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def on_mouse_drag(self, point, d_point, buttons, modifiers):
|
def on_mouse_drag(self, point, d_point, buttons, modifiers):
|
||||||
if self.panel_opener.is_point_touching(point):
|
if self.panel_opener.is_point_touching(point):
|
||||||
self.panel_opener.match_y(Dot(point))
|
self.panel_opener.match_y(Dot(point))
|
||||||
|
@ -514,4 +521,3 @@ class ControlPanel(Group):
|
||||||
factor = 10 * offset[1]
|
factor = 10 * offset[1]
|
||||||
self.controls.set_y(self.controls.get_y() + factor)
|
self.controls.set_y(self.controls.get_y() + factor)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
|
@ -218,12 +218,8 @@ class Mobject(object):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def is_point_touching(self, point, buff=MED_SMALL_BUFF):
|
def is_point_touching(self, point, buff=MED_SMALL_BUFF):
|
||||||
self.refresh_bounding_box()
|
|
||||||
bb = self.get_bounding_box()
|
bb = self.get_bounding_box()
|
||||||
if np.all(point >= (bb[0] - buff)) and np.all(point <= (bb[2] + buff)):
|
return np.all(point >= (bb[0] - buff)) and np.all(point <= (bb[2] + buff))
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Family matters
|
# Family matters
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue