Observers for putting the file name in the title bar

edited October 2013 in Ruby Scripting

Hi Matthias,

This question is more about the user interface, and not so much about KLayout's features.

When I have several windows open, I find it a little difficult to tell them apart at a glance because the title bar is the same for all windows.

I have been trying to write a Ruby script that shows the file name of the active cell in the title bar and its tab. I have included the script below.

module UpdateTitle

    include RBA

    class MainViewObserver < Observer    

        def signal

            version = RBA::Application.instance.version
            mw = RBA::Application.instance.main_window
            lv = mw.current_view

            if lv == nil
                # No layout is open
                mw.windowTitle = version
            else
                cv = lv.active_cellview
                if cv.ctx_cell == nil
                    # Created an empty panel
                    mw.windowTitle = version
                else
                    cv_fn = cv.filename
                    if cv.filename == ""
                        # Created a new layout, not saved yet
                        mw.windowTitle = version
                    else
                        # Layout with file name is in current tab
                        mw.windowTitle = "#{cv_fn} - #{version}"
                        lv.title = "#{cv_fn}"
                    end
                end
            end
        end
    end  

    observer = MainViewObserver::new  
    mw = RBA::Application.instance.main_window    
    mw.add_current_view_observer(observer)
end

The script works quite well; currently, the file name in the title bar and tab changes when the tab is closed or changed.

I can think of three cases, though, when the file name in the title bar should change without changing the tab.

  1. When there is more than one GDS file open in the same tab, and the active cell is closed with "File" > "Close".
  2. When the active cell is saved with a different file name.
  3. When there is more than one GDS file open in the same tab, and a different cell in the CellView drop-box is chosen.

I was wondering whether there are observers that can detect these events, and how they can be used. I have been trying add_cellview_observer, but have not been able to get it to detect the three cases above. I am new to Ruby, so that may be one of the reasons.

I am using version 0.22.9 on Windows 7.

A workaround for these cases is just to change to a different tab, but any help in solving them would be greatly appreciated.

Many thanks.

Best regards,
Z Lim

Comments

  • edited November 2013

    Hi zlim,

    For someone calling himself "new to Ruby" this is actually quite good :-)

    Regarding your request, there are some more event you can register at in the LayoutView class, but there is no event for "save as" currently, so that problem is hard to solve with the observables provided.

    It is possible however to solve the problem with a different approach: by registering a QTimer object which periodically (i.e. every 100ms) polls the current title and sets the window title accordingly.

    The code below demonstrates the solution. This approach uses Qt signals which provide a somewhat more convenient mechanism to register code with events.

    Regards,

    Matthias

    module UpdateTitle
    
      include RBA
    
      mw = RBA::Application::instance.main_window
    
      timer = RBA::QTimer::new(mw)
      timer.interval = 100
      timer.timeout do 
    
        version = RBA::Application.instance.version
        mw = RBA::Application.instance.main_window
        lv = mw.current_view
    
        if !lv
          # No layout is open
          mw.windowTitle = version
        else
          cv = lv.active_cellview
          if !cv.ctx_cell
            # Created an empty panel
            mw.windowTitle = version
          else
            cv_fn = cv.filename
            if cv.filename.empty?
              # Created a new layout, not saved yet
              mw.windowTitle = version
            else
              # Layout with file name is in current tab
              mw.windowTitle = "#{cv_fn} - #{version}"
              lv.title = "#{cv_fn}"
            end
          end
        end  
    
      end
    
      timer.start
    
    end
    

    Below is some code that demonstrates how to register an event at a new LayoutView object. It uses the "new_view" event to register a handler when a new view is opened. The code also demonstrates to extend the Observer class with such that it is somewhat more convenient to create event handlers. This scheme does not require to derive a new class and allows to reference variables from outside the block.

    But as I mentioned this does not solve your problem. The timer approach is better suited. This code is provided as add-on information.

    module UpdateTitle
    
        include RBA
    
        class RBA::Observer
            def on_signal(&block)
               @block = block
            end
            def signal
               @block && @block.call
            end
        end
    
        title_field_observer = Observer::new
        title_field_observer.on_signal do
            version = RBA::Application.instance.version
            mw = RBA::Application.instance.main_window
            lv = mw.current_view
    
            if lv == nil
                # No layout is open
                mw.windowTitle = version
            else
                cv = lv.active_cellview
                if cv.ctx_cell == nil
                    # Created an empty panel
                    mw.windowTitle = version
                else
                    cv_fn = cv.filename
                    if cv.filename == ""
                        # Created a new layout, not saved yet
                        mw.windowTitle = version
                    else
                        # Layout with file name is in current tab
                        mw.windowTitle = "#{cv_fn} - #{version}"
                        lv.title = "#{cv_fn}"
                    end
                end
            end
        end
    
        mw = RBA::Application.instance.main_window    
        mw.add_current_view_observer(title_field_observer)
    
        new_view_observer = Observer::new   
        new_view_observer.on_signal do
            if mw.current_view
                mw.current_view.add_cellview_observer(title_field_observer)       
            end
        end
    
        mw.add_current_view_observer(title_field_observer)
        mw.add_new_view_observer(new_view_observer)
    
    end
    
  • edited November -1

    Hi Matthias,

    The timer is a good idea and the script works well.

    Thank you!

    Best regards,
    Z Lim

Sign In or Register to comment.