Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1import numpy as np
3import ase.gui.ui as ui
4from ase.gui.i18n import _
7class Movie:
8 def __init__(self, gui):
9 self.win = win = ui.Window(_('Movie'), self.close)
10 win.add(_('Image number:'))
11 self.frame_number = ui.Scale(gui.frame + 1, 1,
12 len(gui.images),
13 callback=self.new_frame)
14 win.add(self.frame_number)
16 win.add([ui.Button(_('First'), self.click, -1, True),
17 ui.Button(_('Back'), self.click, -1),
18 ui.Button(_('Forward'), self.click, 1),
19 ui.Button(_('Last'), self.click, 1, True)])
21 play = ui.Button(_('Play'), self.play)
22 stop = ui.Button(_('Stop'), self.stop)
24 # TRANSLATORS: This function plays an animation forwards and backwards
25 # alternatingly, e.g. for displaying vibrational movement
26 self.rock = ui.CheckButton(_('Rock'))
28 win.add([play, stop, self.rock])
30 if len(gui.images) > 150:
31 skipdefault = len(gui.images) // 150
32 tdefault = min(max(len(gui.images) / (skipdefault * 5.0),
33 1.0), 30)
34 else:
35 skipdefault = 0
36 tdefault = min(max(len(gui.images) / 5.0, 1.0), 30)
37 self.time = ui.SpinBox(tdefault, 1.0, 99, 0.1)
38 self.skip = ui.SpinBox(skipdefault, 0, 99, 1)
39 win.add([_(' Frame rate: '), self.time, _(' Skip frames: '),
40 self.skip])
42 self.gui = gui
43 self.direction = 1
44 self.timer = None
45 gui.register_vulnerable(self)
47 def notify_atoms_changed(self):
48 """Called by gui object when the atoms have changed."""
49 self.close()
51 def close(self):
52 self.stop()
53 self.win.close()
55 def click(self, step, firstlast=False):
56 if firstlast and step < 0:
57 i = 0
58 elif firstlast:
59 i = len(self.gui.images) - 1
60 else:
61 i = max(0, min(len(self.gui.images) - 1, self.gui.frame + step))
63 self.frame_number.value = i + 1
64 if firstlast:
65 self.direction = np.sign(-step)
66 else:
67 self.direction = np.sign(step)
69 def new_frame(self, value):
70 self.gui.set_frame(value - 1)
72 def play(self):
73 self.stop()
74 t = 1 / self.time.value
75 self.timer = self.gui.window.after(t, self.step)
77 def stop(self):
78 if self.timer is not None:
79 self.timer.cancel()
81 def step(self):
82 i = self.gui.frame
83 nimages = len(self.gui.images)
84 delta = int(self.skip.value + 1)
86 if self.rock.value:
87 if i <= self.skip.value:
88 self.direction = 1
89 elif i >= nimages - delta:
90 self.direction = -1
91 i += self.direction * delta
92 else:
93 i = (i + self.direction * delta + nimages) % nimages
95 self.frame_number.value = i + 1
96 self.play()