Browse code

Animate scrolling when you click on a node/edge.

From: Marius Gedminas <marius@gedmin.as>

Jose.R.Fonseca authored on 13/07/2008 03:20:38
Showing 1 changed files

  • xdot.py index 9c919be..b414d92 100755
... ...
@@ -27,6 +27,7 @@ import sys
27 27
 import subprocess
28 28
 import math
29 29
 import colorsys
30
+import time
30 31
 
31 32
 import gobject
32 33
 import gtk
... ...
@@ -598,6 +599,70 @@ class XDotParser:
598 599
         return x, y
599 600
 
600 601
 
602
+class Animation(object):
603
+
604
+    step = 0.03 # seconds
605
+
606
+    def __init__(self, dot_widget):
607
+        self.dot_widget = dot_widget
608
+        self.timeout_id = None
609
+
610
+    def start(self):
611
+        self.timeout_id = gobject.timeout_add(int(self.step * 1000), self.tick)
612
+
613
+    def stop(self):
614
+        self.dot_widget.animation = NoAnimation(self.dot_widget)
615
+        if self.timeout_id is not None:
616
+            gobject.source_remove(self.timeout_id)
617
+            self.timeout_id = None
618
+
619
+    def tick(self):
620
+        self.stop()
621
+
622
+
623
+class NoAnimation(Animation):
624
+
625
+    def start(self):
626
+        pass
627
+
628
+    def stop(self):
629
+        pass
630
+
631
+
632
+class LinearAnimation(Animation):
633
+
634
+    duration = 0.6
635
+
636
+    def start(self):
637
+        self.started = time.time()
638
+        Animation.start(self)
639
+
640
+    def tick(self):
641
+        t = (time.time() - self.started) / self.duration
642
+        self.animate(max(0, min(t, 1)))
643
+        return (t < 1)
644
+
645
+    def animate(self, t):
646
+        pass
647
+
648
+
649
+class MoveToAnimation(LinearAnimation):
650
+
651
+    def __init__(self, dot_widget, target_x, target_y):
652
+        Animation.__init__(self, dot_widget)
653
+        self.source_x = dot_widget.x
654
+        self.source_y = dot_widget.y
655
+        self.target_x = target_x
656
+        self.target_y = target_y
657
+
658
+    def animate(self, t):
659
+        sx, sy = self.source_x, self.source_y
660
+        tx, ty = self.target_x, self.target_y
661
+        self.dot_widget.x = tx * t + sx * (1-t)
662
+        self.dot_widget.y = ty * t + sy * (1-t)
663
+        self.dot_widget.queue_draw()
664
+
665
+
601 666
 class DotWidget(gtk.DrawingArea):
602 667
     """PyGTK widget that draws dot graphs."""
603 668
 
... ...
@@ -742,12 +807,9 @@ class DotWidget(gtk.DrawingArea):
742 807
             return True
743 808
 
744 809
         jump = self.get_jump(x, y)
745
-        x, y = self.window2graph(x, y)
746 810
         if jump is not None:
747 811
             jumpx, jumpy = jump
748
-            self.x += jumpx - x
749
-            self.y += jumpy - y
750
-            self.queue_draw()
812
+            self.animate_to(jumpx, jumpy)
751 813
         return False
752 814
 
753 815
     def on_area_button_release(self, area, event):
... ...
@@ -787,6 +849,10 @@ class DotWidget(gtk.DrawingArea):
787 849
 
788 850
         return True
789 851
 
852
+    def animate_to(self, x, y):
853
+        self.animation = MoveToAnimation(self, x, y)
854
+        self.animation.start()
855
+
790 856
     def window2graph(self, x, y):
791 857
         rect = self.get_allocation()
792 858
         x -= 0.5*rect.width