Animation Mod ?

Hi Matthias,
I would like to build a module that assists in the visualization of one (or a just a handful of) layer(s) of a layout. It would be great if there was a "highlight" button that the user could press that does the following:

(1) Save all layer properties (to memory)
(2) Changes all un-selected layers to:
- light grey, the very sparse stipple[3], 0-width frame width
(3) Changes all visible and selected layers to:
- black frame 3 pixels wide, no stipple (stipple[1])
(4) Turns on animation for the visible and selected layers, but:
- changes the blink frequency to something like 2 - 3 times a second
- cycles the visible and selected layers meaning: show first later for 300ms, then hide first layer and show 2nd layer for 300ms, and so on
so it gives the impression of a cascaded blinking. All while allowing the main thread to let the user drive around as usual.
(5) Restore everything once the "highlight" button is pressed again.

I am sure I can write the code for (1), (2), (3), and (5), but I am not sure where even to begin with the animation and if it is even possible to use it this way. Any thoughts ?

Thanks.

Thomas.

Comments

  • Hi Thomas,

    It's possible to modify the layer views through script, so that's how you can implement animation.

    My recommendation is to create a plugin (see https://www.klayout.de/doc-qt5/code/class_PluginFactory.html). Plugins are intended to supply new modes (toolbar entries), so that new editors or similar features can be implemented. Although this is not exactly the case here - by creating a separate mode you basically decouple editing features from animation mode. This implies you don't need to care so much about how these modes interfere. From the user perspective this means you can either choose animation mode or one of the other modes. So you cannot draw rulers for example while animation is running.

    On this plus side, the plugin system manages all the activation and deactivation and provides nice callbacks for these state transitions. This simplifies the installation of a timer which provides the regular events. Based on these and the activation/deactivation events you can implement the code for the cycling animation.

    For the regular callbacks I'd use a QTimer (Caution: this needs klayout >=0.26.8 on Qt5). Here is some code which presents a skeleton of your mod:

    # Register this macro as "autorun" to enable the plugin
    
    # First thing is to implement a "plugin factory". This 
    # object is asked to provide a plugin for each view
    
    class AnimationPluginFactory(pya.PluginFactory):
    
      def __init__(self):
        super(AnimationPluginFactory, self).__init__()
        # Registers the Plugin with a toolbar entry
        # TODO: icon etc.     
        self.register(10000, "LayerAnimationCycler", "Cycler")
    
      def create_plugin(self, manager, root, view):
        return AnimationPlugin()
    
      # Keeps the singleton instance
      instance = None
    
    # Create and store the singleton instance
    AnimationPluginFactory.instance = AnimationPluginFactory()
    
    
    # Second thing is the actual plugin
    
    class AnimationPlugin(pya.Plugin):
    
      def __init__(self):
        # Important: initialize super class for proper operation
        super(AnimationPlugin, self).__init__()
        # Set up a QTimer for the regular events
        # CAUTION: needs KLayout >=0.26.8 on Qt5!
        self.timer = pya.QTimer(None)
        # calls self.timer_event every 300ms when the timer is enabled
        self.timer.interval = 300
        self.timer.timeout = self.timer_event
    
      def timer_event(self):
        # TODO: implement
        print("timer event ...")
    
      def start_animation(self):
        # TODO: implement
        print("start animation ...")
    
      def stop_animation(self):
        # TODO: implement
        print("stop animation ...")
    
      # This method is called when the user selects the "Cycler" mode  
      def activated(self):
        self.start_animation()
        self.timer.start()
        pya.MainWindow.instance().message("Animation running ...", 10000)
    
      # This method is called when the user choses a different mode on the view is closed  
      def deactivated(self):
        self.timer.stop()
        self.stop_animation()
        pya.MainWindow.instance().message("", 0)
    

    Kind regards,

    Matthias

  • Hi Matthias,
    thank you ! I should have mentioned that I was planning to do this in Ruby :smile: but I can probably translate this ok.
    So I am taking from this that the internal animations cannot be modified to blink faster etc ?

    Thomas

  • Hi Thomas,

    Oh yes, there is still Ruby :) Most users prefer Python, that's why I was implicitly assuming that's the case here.

    The animation speed is kind of fixed - of course it can be changed by modifying the C++ code. The background is that many users are working through a VNC and those get crazy when the screen updates quickly. I was even told people are working over mobile internet connections and one was blaming me to waste his phone's energy, because it has to provide the bandwidth for the blinking feature. So you should consider these poor people without a wired connection here ;)

    Best regards,

    Matthias

  • yes, I should probably transition to python eventually.

    Well, for those who don't work on remote computers, here is the code that works. It highlights and cycles through each selected and visible layer every 250ms, and recovers everything after 60sec.

Sign In or Register to comment.