# The Application API

This section covers the basic application API. The application API consists of the main application class and several classes that represent the user interface. This sections presents a selection of classes that make up the application API. These classes provide the main entry points into the application API. Further classes are documented in RBA Class Index.

All classes discussed herein are contained in the RBA namespace. In you code you either have to use qualified names (i.e. RBA::Application) or include the RBA module in you macro's namespace.

## The Application class

The Application class is documented in detail in . It represents the application and because there is just one application, there also is just one instance of the application object. That instance can be obtained through the "instance" class method:

    Application::instance

The application object is the main entry point into the API. It offers several methods and attributes. In particular:

- : returns the user-local storage path. This is where KLayout saves user-specific files, for example the configuration file.
- : runs the application. Normally, this method is called implicitly when the application is started. It is possible to use KLayout as a Ruby interpreter by supplying a Ruby script on the command line with the "-r" option. Such scripts must run the application explicitly if they want to.
- : exits the application. This method unconditionally terminates the application in a clean way.
- and : read and write the configuration database. The configuration database is a storage of name/value pairs which is stored in the configuration file. These methods can be used to manipulate that storage. Use the method to retrieve the names of the configuration parameters stored inside the configuration database. Use the method to activate settings that have been made with "set_config".
- : returns the installation path. That is where the executable is located.
- : returns true, if KLayout runs in editable mode.
- : returns the KLAYOUT_PATH value. This is the search path where KLayout looks for library files or macros. This method delivers the application data path and can be used to look up files required by the macro.
- : delivers the MainWindow object which represents the application's main window. See below for a description of that class.
- : process pending events. If that method is called periodically during long operations, the application will be able to process events and thus handle clicks on a "Stop" button for example. Please note that calling this method is not safe in every context, because not every execution context is reentrant.
- and : reads and writes the configuration database from a file.
- : delivers KLayout's version string. This string can be used to switch the implementation of a script depending on KLayout's version.

## The MainWindow class

The MainWindow class is documented in detail in . It represents the main application window. The main window instance can be obtained with:

    Application::instance.main_window

The main window object is the entry point to all user-interface related objects. It offers a couple of methods. In particular:

- : cancels any pending operation (i.e. dragging of an object in move mode) and resets the mode to the default mode (Select). Use this method to establish a known user interface state.
- and : close all or the current tab.
- MainWindow#cm_*
  : these are methods which are bound to the menu items in the menu bar. They can be used to trigger a menu function from a script.
- : create a new layout and load it into a layout view. This method has a parameter that controls whether the layout is shown in a new tab, replaces the layout in the current tab or adds to the current tab.
- : creates a new, empty layout and loads it.
- : creates a new, empty tab.
- : returns a LayoutView object (see below) which represents the current tab.
- : returns the index of the current tab. Some methods like "select_view" operate with view indexes. The view index is the number of the tab (0 is the leftmost one). The "view" method allows obtaining the LayoutView object from a view index. The same way selects the view with the index given in this call.
- : gets the global grid in micrometer units.
- and : gets or sets the name of the technology to use to new layouts or for layouts loaded without an explicit technology specification.
- : loads a layout into a tab. There are various variants of this method, offering various levels of configuration. All these variants have a parameter that controls whether the layout is shown in a new tab, replaces the layout in the current tab or adds to the current tab.
- : provides access to the menu object of class AbstractMenu (see ). This object provides access to the main menu, the toolbar and various context menus. With this object it is possible to manipulate the menu.
- : show a message in the status bar.
- : gets the current layout reader options and allows modification of the latter. The reader options configure the reading of layouts.
- and : save or restore a session. Sessions contain a window settings and informations about the layouts loaded. Sessions allows storing and restoring of the state of the main window.
- : switches to the given tab. This equivalent to using .
- : gets the object for a given tab index.
- : gets the number of tabs.

The MainWindow supplies three events. See for details about events. These are the events:

- on_current_view_changed: This event is triggered when the current tab changes. The signal is available with an integer parameter: this is the index of the previous tab. The new tab is already the current tab when this event is triggered.
- on_view_created: This event is triggered when a new view is created. The signal is available with an integer parameter: this is the index of the new tab.
- on_view_closed: This event is triggered when a new view is closed. The signal is available with an integer parameter: this is the index of the tab that was closed.

In addition, the MainWindow class features many parameterless methods starting with "cm_...". These methods are identical with the methods called when the respective menu functions are triggered. They are of use when menu events need to be emulated in code, for example to implement special key bindings.

## The LayoutView class

The LayoutView class is documented in detail in . It represents one layout tab in the main window. A single layout view can show multiple layouts. The objects represent one layout loaded into a view. They specific the layout loaded plus the cell selected for drawing. Each LayoutView has a list of CellView objects corresponding to the layouts shown in the same panel.

A LayoutView object can be obtained from the main window either by reading the current view or by getting the view object for a tab by the tab index:

    # Current view:
    Application::instance.main_window.current_view
    # or short:
    LayoutView::current

    # By index:
    Application::instance.main_window.view(index)

    # Note: the index of the current view is
    Application::instance.main_window.current_view_index
    # and the number of views is
    Application::instance.main_window.views

The index is 0 for the first tab. Note that the value returned by or can be "nil" if no layout is shown.

A layout view is the container for a variety of "visual" objects. These resources are mainly display objects like annotations, markers and images. In addition, the report database system is anchored in the LayoutView object. The following resources are managed in the layout view:

- Annotations (rulers): an arbitrary number of annotations can be registered in the view. The annotations are objects of the Annotation class (). Annotations are independent of layouts and are defined in micron units.
- Images: images are also objects independent of layouts. Any number of images can be placed below the drawn layout.
- Markers: markers are temporary overlay objects which can be used a highlights or to add some elaborate annotation to a layout view. Markers can be layout database objects, hence it is possible to draw polygons or other objects over the layout. Markers can be configured to a large degree, so different colors can be used for example. Markers are objects of class Marker ().
- Local configuration: be default, the layout view pulls it's configuration from the global configuration database. It is possible however to override certain configuration parameters for a particular view. This allows for example to set the background color for a particular view without affecting the other views.
- Layer properties: the layer properties tree is also managed by the layout view. Since there can be multiple layer properties trees in different tabs in the layer properties panel, there are method to access either the current or a specific one of the layer properties trees.
- Custom stipples and line pattern: custom stipplesu and line styles can be set in the layout view and used in the layer properties. Custom stipples are bitmaps that define the fill pattern used for the inside area of a polygon. Line styles are bit pattern that make lines being resolved into dots.
- Selection: the layout view also manages the selection. This is a set of objects and their instantiation path in the layout database. It represents the set of selected objects. Each selected object is described by a instantiation path and the object itself. That information is combined in the ObjectInstPath object ().
- Transient selection: this is the object that is highlighted briefly when the mouse hovers over it.
- Cell views: the list of layouts and cells shown in the layout view as overlays. Cell views are created when layouts are loaded and deleted when layouts are closed. One of the cell views is the "active" one. That is the one which is selected in the drop-down box in the cell tree and for which the cell tree is shown.
- Cell visibility: the information about what cell is visible and what cell is not. Each cell can be made invisible. In that case, only the cell frame is drawn and the cell is shown stroked out in the cell tree.
- Hierarchy levels: this attribute controls which hierarchy levels are shown by default.
- Viewport: the geometrical dimensions of the area which is drawn in micron space.
- Report databases: a layout view can have multiple report databases attached to it. Report databases can be shown in the marker browser and are collections of general information or geometrical information related to a certain position or area.
- Transactions: transactions are grouped layout operations which form an atomic operation which can be undone. Transactions can be created within the layout view. Transactions must be opened and closed before they are available as operations on the undo stack.
- Plugins: plugins are a way to implement new functionality inside the layout view related to mouse actions. By using plugins it is possible to track the mouse and implement actions related to mouse activity.
- Title: finally, a layout view has a title which is shown in the tab.

Being the central class, the layout view naturally offers many methods and attributes. Here's a brief explanation of some of these methods:

- and : gets the active CellView object or index of this object. The active cell view is the one that is selected in the drop-down box above the cell tree. gets the active cellview of the current layout view.
- will add the layers to the layer tree for which there is no layer properties entry yet. This method can be used after a layout has been created and populated to show all layers of the layout.
- , and : manage custom stipples.
- , and : manage custom line styles.
- and : moves the context cell up or down in the hierarchy.
- and : gets an start or end iterator object that allows traversing of the layer properties tree in a recursive or non-recursive fashion. See below for a description of how to deal with the layer properties.
- is a convenient alternative way of iterating over the layers without directly using the layer tree iterator.
- : gets the display area in micron units (the viewport).
- : returns the view into idle state (nothing selected, no editing in progress, "Select" mode is active).
- : gets the CellView object for a given index.
- : gets the number of cell views registered.
- , , and : manage annotations (rulers).
- , , and : manage images.
- , , and : allow manipulation of the configuration for that layout view only. For example it is possible to set a different background color for that specific layout view.
- , , , , , and : manage the layer properties. See below for a detailed explanation.
- : clears all transactions (clears the undo stack).
- and : starts or ends a transaction. All operations between the start and end of a transaction can be undone in one step.
- : clears the selection of geometrical objects (shapes or cell instances).
- and : creates a new layout or loads a layout. In both cases, you can either replace the current layouts or add the new one to the layouts present.
- : returns an iterator pointing to the current layer (the one that has the focus frame in the layer tree.
- : returns the index of the current layer list (if multiple tabs are present in the layer control panel, the current layer list is the tab that is selected).
- and : delivers all or the selected annotations.
- and : delivers all or the selected images.
- and : delivers ObjectInstPath objects () that point to one selected object each.
- : close a cell view, i.e. remove that specific layout from the list of loaded layouts.
- : Enables or disables editing. This method will enable or disable all editing features. This is intended for temporarily disallowing edits. This is not the same than edit and viewer mode.
- , and : dumps the screen content into a QImage with or without a specific resolution.
- : provides an initialization of a "LayerProperties" object for a new layer according to the current settings of the view.
- , , and : manages cell visibility.
- and : loads or saves layer properties files.
- , and : manages hierarchy levels shown.
- , , and : return or manipulate the selection of geometrical objects (shapes, instances). The key descriptor object for that purpose is , which refers to a geometrical object throug an instantiation path.
- (and other pan... methods), (and other zoom... methods): changes the viewport.
- : reloads a given layout.
- , , and : Create, delete and get report databases stored inside the LayoutView object.
- : changes the name of a cellview.
- , and : sets or resets the layout view's title.
- : Saves a layout to a file (with options).
- : shows or hides an image.
- , and : gets the viewport parameters.

### Implementing Undo/Redo

Undo/Redo functionality is implemented by using "transactions". Transactions are groups of operations which implement one user operation. Transactions are built internally and automatically once a transaction is initiated. Most operations performed in the framework of the LayoutView and Layout objects are tracked within these transactions. When a transacting is finished, it needs to be committed. After that, a new operation will be available for "Undo" or "Redo".

Transactions can be initiated with and committed with . To ensure, every initiation of a transaction is matched by a "commit", it is recommended to employ "ensure":

    begin

      view.transaction("Some operation")

      ... do your thing here ...

    ensure
      view.commit
    end

### Manipulating the selection

The selection of geometrical objects can be manipulated by providing the necessary objects. Each such object provides a "pointer" to a shape or instance through the hierarchy. Specifically it lists all the cells and their instantiation transformations down to the shape selected. By accumulating these selections, a shape can be addressed in a flat view, even if the shape is instantiated many levels down in the hierarchy.

Generating such instantiation path objects is somewhat tedious, but usually the requirement is not to generate such paths, but to take an existing selecting, manipulate it somehow and then to set the selection to the new one. This is fairly easy by taking a copy of the selection, manipulation of the shapes and setting the manipulated selection as the new one.

The following is a sample which replaces all shapes by their hull polygons. Note that is provides undo/redo support through a "transaction":

    view = mw.current_view

    begin

      view.transaction("Convert selected shapes to polygons")

      sel = view.object_selection

      sel.each do |s|
        if !s.is_cell_inst? && !s.shape.is_text?
          ly = view.cellview(s.cv_index).layout
          # convert to polygon
          s.shape.polygon = s.shape.polygon
        end
      end

      view.object_selection = sel

    ensure
      view.commit
    end

### Events

The LayoutView object supplies several events. See for details about events. These are the events:

- on_active_cellview_changed: This event is triggered when the active cellview changes. The active cellview is the one indicated by the drop-down-box atop of the cell list if multiple layouts are loaded into one view.
- on_annotation_changed: This event is triggered if an annotation is changed. The ID of the annotation is sent along with the event.
- on_annotation_selection_changed: This event is triggered if the selection of annotations is changed.
- on_annotations_changed: This event is triggered if an annotation is added or deleted.
- on_cell_visibility_changed: This event is triggered when the visibility of a cell changes. The visibility of a cell is changed by using "Hide Cell" or "Show Cell" from the cell tree's context menu.
- on_cellviews_changed: This event is triggered when a new cellview is added or a cellview is removed.
- on_cellview_changed: This event is triggered when a cellview changed (i.e. the current cell has been changed. The index of the changed cell view is sent along with the event.
- on_close: This event is triggered when a cell view is closed.
- on_file_open: This event is triggered when a file is loaded.
- on_hide: This event is triggered when a cell view is going to become invisible (i.e the tab changed).
- on_current_layer_list_changed: This event is triggered when the current layer list was changed (i.e. the tab in the layer list has been changed).
- on_image_changed: This event is triggered when an image was edited. The ID of the image is sent along with the event.
- on_image_selection_changed: This event is triggered when an image was selected or unselected.
- on_images_changed: This event is triggered when an image was added or deleted.
- on_layer_list_changed: This event is triggered if a layer was changed, added or deleted.
- on_layer_list_deleted: This event is triggered if a layer list was deleted (i.e. a tab was removed).
- on_layer_list_inserted: This event is triggered if a layer list was inserted (i.e. a tab was added).
- on_rdb_list_changed: This event is triggered when a report database is opened or removed.
- on_selection_changed: This event is triggered when the selection has changed.
- on_show: This event is triggered when a cell view is going to become visible (i.e the tab changed).
- on_transient_selection_changed: This event is triggered when the transient selection has changed.
- on_viewport_changed: This event is triggered when the viewport has changed, for example the view is zoomed in or panned.

### Working with layer properties

The API provides methods by which the layer properties list of the layout view can be traversed and manipulated in many ways. In particular:

- Add or remove entries to or from the layer properties list: and
- Clear all entries:
- Manage custom stipple pattern: , and
- Add, rename or remove tabs, get or change the current tab: , , , and
- Remove unused layers from the layer list or add entries for missing layers: ,
- Load or save layer properties from or to a ".lyp" file: and
- Obtain the selected entries from the layer properties tree: and
- Initialize layer properties with the default settings:
- Expand layer properties which contain wildcard entries ("stylesheet" layer properties files):
- Manipulate layer properties by setting the properties of the object returned by or .

Many of these functions use objects to identify entries in the layer tree. Such an object is basically a pointer into the tree. The term "iterator" refers means that such a pointer can be moved to neighboring entries in the layer tree. By default, the LayerPropertiesIterator performs a preorder, depth-first traversal of the layer properties tree (the virtual root object is omitted). This is how to work with LayerPropertiesIterator objects:

    layout_view = Application::instance.main_window.current_view
    # Get the iterator for the first entry:
    lp = layout_view.begin_layers
    # advance to the next entry (preorder, depth-first traversal):
    lp.next
    # advance to the next sibling
    lp.next_sibling(1)
    # advance to the previous sibling
    lp.next_sibling(-1)
    # move down in the hierarchy to the first child
    lp.down_first_child
    # move down in the hierarchy to the last child
    lp.down_last_child
    # move up to the parent node
    lp.up
    # get the value of the current node
    props = lp.current

The LayerPropertiesIterator has a couple of attributes:

- : returns the LayerPropertiesNodeRef object () which is a representative for the layer the iterator points to. This object can be manipulated which has an immediate effect on the layer list of the view.
- : returns true, if the iterator is at the end of the layer properties tree (if "next" is used to traverse) or at the end of the current child node list if other methods of traversal are used. It "at_end?" is true, the iterator does not point to a valid entry.
- : returns true, if this iterator is a null iterator (i.e. default-constructed).
- : returns true, if this iterator is pointing to a top-level entry.
- : returns the index of the current entry in the current child list.

Iterators can be compared against each other. If two iterators point to the same object, the equality operator "==" returns true.

The actual entry that the iterators "current" property is a LayerPropertiesNodeRef object (a reference to a LayerPropertiesNode object). If behaves the same way than a LayerPropertiesNode object (), but modifications of the latter will change the way the layer is displayed in the view.

The LayerPropertiesNode object contributes only a few methods, namely:

- : an integer ID that uniquely identifies the entry in the tree.
- : computes and delivers an effective set of properties as a LayerProperties object.
- : computes the bounding box of the drawn layer represented by this entry.
- : returns true, if this node is not a leaf node.
- : adds a child node to the node. It returns a reference to the new node created inside the node's hierarchy. Is is possible to add new children to the node returned.
- : removes all children from the node.

The actual properties of the layer are accessible through methods of the object. Since the parent node may override or contribute properties, a LayerProperties object has a twofold identity: the way it appears finally ("real") and the way it is configured ("local"). The property accessors have a "real" parameter and deliver the real value if this parameter is set to true and the local value otherwise. There are also convenience methods which always deliver the "real" value.

    lp = layout_view.begin_layers

    # manipulate the layer
    lp.current.width = 2
    lp.current.fill_color = 0x80ff40

    # which is equivalent to this somewhat more efficient way:
    props = lp.current.dup
    props.width = 2
    props.fill_color = 0x80ff40
    lp.current.assign(props)

It is possible to directly manipulate the hierarchy this way:

    lp = layout_view.begin_layers
    # create a copy that we can manipulate
    # add two child nodes
    cp = RBA::LayerProperties::new
    cp.source = "100/0"
    lp.current.add_child(cp)
    cp = RBA::LayerProperties::new
    cp.source = "101/0"
    lp.current.add_child(cp)

New entries can be created by using LayoutView's insert_layer method and a LayerPropertiesIterator to specify the location where the node shall be created. Here is an example how to create a child entry using that technique. Please note how "down_first_child" is used to navigate into the node's child space which works even if there are no children yet:

    lp = layout_view.begin_layers
    # let the iterator point to the first child, even if it does not exist
    lp.down_first_child
    # (lp.current may not be valid, but still lp is a valid insert position)
    # prepare a new entry for insert:
    props = RBA::LayerProperties.new
    props.source = "100/0"
    # insert the child node:
    layout_view.insert_layer(lp, props)
    # now, lp points to a valid object: lp.current.source == "100/0"

### LayerProperties objects

The object represents one entry in the layer properties tree and has several basic properties. For each of these properties, a getter for the real and local value exists as well as a setter that installs a local value. For example, for the width property, the following methods are defined:

- width(real): the getter for the real ("width(true)") or local ("width(false)") value.
- width: the real value.
- width=: the setter for the local value.

Width is a "weak" property. That means that for computing the effective width, child nodes can override the settings inherited from the parent nodes. A width of 0 is considered "not set" and does not override parent defined widths. Other properties like visibility are "strong", i.e. the parent can override the properties set for it's children. Another form of combination is "additive" where the effective property value is the "sum" (or in general combination) of all local properties from parent to child.

Some properties like "fill_color" do not have a neutral value but instead they can be cleared (in that case with "clear_fill_color"). The LayerProperties object can be asked whether a fill color is set using the "has_fill_color?" method.

This is a brief list of properties:

- (strong): specifies animation (blinking, scrolling)
- (strong): specifies the fill pattern
- (strong): specifies the line style
- (additive): specifies the fill color's brightness
- (strong): specifies the fill color
- (additive): specifies the frame color's brightness
- (strong): specifies the frame color
- (weak): the lower hierarchy level shown. This property has various flavors related to the definition of "lower level".
- (weak): the upper hierarchy level shown. This property has various flavors related to the definition of "upper level".
- (strong): specifies whether the layout is rendered with small crosses at each vertex
- (strong): Specifies whether a cross is drawn in rectangles
- (strong): specifies whether the layer is semi-transparent (color bitmap combination)
- (strong): specifies whether the layer is visible
- (strong): specifies whether the layer is valid
- (weak): specifies the line width
- (weak, additive): specifies the origin of the data. This property can be set or obtained either a string using KLayout's source notation or be accessed through a couple of specialized properties delivering a part of the source specification each (, , , , and )

In addition, a couple of getters for computed and derived values are present (i.e. "eff_frame_color"). There are no setters for these properties. The effective frame color for example delivers the frame color which results from combining the frame color and the frame brightness.

## The CellView class

The CellView () identifies the cell drawn and the context the cell is drawn in. A CellView can be created as a object but usually it is obtained from a LayoutView object. In the following example, the active cell view is used:

    RBA::Application::instance.main_window.current_view.active_cellview

Alternatively, a cell view can be addressed by index:

    lv = RBA::Application::instance.main_window.current_view
    num_cellviews = lv.cellviews # number of cell views
    lv.cellview(0) # first one

A cellview carries the following information:

- : a reference to the cell shown (a Cell object: ).
- : a reference to the layout object (a Layout object: ) which contains the cell shown.
- : the unique name of the layout.
- : the name (actually the path) of the file loaded if the layout was loaded from a file.
- : the unspecific path (see below)
- : the specific path (see below)
- : the context cell (see below). Alternatively the cell index of the context cell is available by .
- : the technology (name) used with this layout
- : returns a value indicating whether a given cell is hidden

A cellview can be manipulated to change the cell shown in the layout view. For this purpose, assignment methods exist which will reconfigure the cellview:

- : a reference to the cell shown (a Cell object: ).
- : a reference to the cell shown (by cell index).
- : the unique name of the layout.
- : sets the unspecific path (see below)
- : sets the specific path (see below)
- : applies the given technology to this layout
- , , : shows or hides cells
- : closes this cell view (removes it from the layout view)

### Unspecific and specific path and context cell

In addition to the cell itself, the cell view specifies how the cell is embedded in the hierarchy. Embedding can happen in two ways: an unspecific and a specific way. Both ways contribute to a path which leads from a top cell to the cell drawn.

The first part is always the unspecific path. This path specifies, where the cell drawn is located in the cell tree. That has no effect on the drawing, but is determines what entry in the cell tree is selected. Giving a path for that information is required, because a cell can be child of different cells which itself can be children of other cells. The unspecific path lists the top cell and further cells which are all direct or indirect parents of the cell addressed.

The unspecific path ends at the "context cell" which usually is identical to the cell addressed by the cell view. KLayout allows addressing of a specific instance of a direct or indirect child cell as the actual cell. In that case, the specific path comes into play. Bascially that means, that a cell is drawn within a context of embedding layout. The specific path leads from the context cell to the cell view's target cell and consists of specific instances (hence the name "specific path"). The "descend" and "ascend" feature bascially adds or removes instances from that path.

The unspecific path can be obtained with the method, the specific path with the method. The unspecific path is just an array of cell indexes specifying the top cell and further cells down to the context cell and includes the context cell. The specific path is an array of InstElement objects (). Each InstElement object describes a specific instantiation (a cell instance plus information when a specific array instance is addressed). When there is no context, the specific path is an empty array. Using the setters and these paths can be changed to select a new cell into the layout view.

## The Image class

Images can be placed onto the drawing canvas and display colored or monochrome images below the layout. Images are represented by Image objects (). Basically an image is a two-dimensional array of pixel values with a specification how these pixels are to be displayed on the canvas. An image can be created an placed on the canvas like this:

    lv = RBA::Application::instance.main_window.current_view
    image = RBA::Image::new("image.png")
    lv.insert_image(image)

An image can be configured by using different properties and attributes:

- The images' data can be loaded from a file by using a constructor with a file name. In addition, the image can use data from an array of floating-point values using either a constructor or the method. An image can be colored, in which case three channels are present or it can be monochrome. In the latter case, a single channel is present only. Together with the data, the dimensions of the image have to be specified (width and height in pixel units).
- The image's data can be manipulated per pixel using the or method.
- The data range for the data stored in the image can be set using the and attributes. The data range determines which value is considered "maximum intensity" (max_value) and "zero intensity" (min_value).
- For monochrome images, a data mapping can be specified. A data mapping converts a monochrome value (a scalar) to a color. Data mapping is specified through a ImageDataMapping object () using the method.
- The geometrical properties of an image are encapsulated in a Matrix3d object (). Such a matrix describes the transformation from pixel coordinates to the micron unit space of the canvas. A 3x3 matrix is a generic way to specify a transformation, including translation, rotation, mirror, shear or perspective distortion. The matrix is obtained and set using the attribute. Convenience methods like , and allow to access sub-aspects of the generic transformation (affine transformation, scaling).

An image can be transformed using one of the methods. It can be hidden or shown using the method. The bounding box of the image can be obtained with the method.

## The Annotation class

Annotations () are basically rulers and other "overlay objects" but can be used for other purposes as well, for example to simply add a text object. Annotations, like images, are objects stored in the LayoutView and can be selected, deleted, transformed etc.

Programmatically, annotations are created this way:

    lv = RBA::Application::instance.main_window.current_view
    ant = RBA::Annotation::new
    ant.p1 = RBA::DPoint.new(0.0, 0.0)
    ant.p2 = RBA::DPoint.new(100.0, 0.0)
    lv.insert_annotation(ant)

The annotation carries several attributes. Those are the same attributes that can be configured in the annotation properties dialog. The most important properties are the two positions (start and end position) accessible through the and properties, the style ( property) and the outline ( property).

If properties are changed using the attribute setters, their appearance will change as well. The following example demonstrates how rulers are manipulated. In this example, the style of all rulers is set to "arrow on both sides". Note, how in this example transactions are used to implement undo/redo:

    view = RBA::LayoutView::current

    begin

      view.transaction("Restyle annotations")

      view.each_annotation do |a|
        adup.style = RBA::Annotation::StyleArrowBoth
      end

    ensure
      view.commit
    end

## The Marker class

A marker is a temporary highlight object. A marker is represented by the Marker class (). Markers appear when they are created and disappear when they are destroyed. Since destruction by the garbage collector happens at undefined times, the destroy method can be used to destroy the marker explicitly. Markers accept some plain shapes (i.e. a Box) which will be displayed as the marker. Markers can be configures in manifold ways, i.e. the colors, the fill pattern, line width etc. See the class documentation for details about the configuration properties.

This is how to create and destroy a marker:

    lv = RBA::Application::instance.main_window.current_view
    marker = RBA::Marker.new(lv)
    marker.set(RBA::DBox::new(0.0, 0.0, 100.0, 200.0))
    # to hide the marker:
    marker.destroy

Markers are temporary objects intended for highlighting a certain area or shape. Markers are not persisted in sessions nor can they be edited.

## The Plugin and PluginFactory classes

Plugins () are objects which provide modular extensions of KLayout. Plugins are the only way to handle mouse events in the canvas. The basic operation of a plugin is the following:

- For each plugin type, a PluginFactory () object must be provided. KLayout uses this object to configure itself and to create a particular plugin instance for each LayoutView. The PluginFactory must provide certain configuration information and can handle some events in a global manner, for example menu entries that do not refer to a certain plugin instance. The PluginFactory must register itself in the KLayout framework. After doing so, KLayout will provide a new button in the tool bar. If this button is selected, the plugin will be activated.
- When a LayoutView is created, it will use the PluginFactory to create a specific Plugin instance for the view. When the tool bar button is pressed which relates to this plugin, the plugin will be activated and mouse or other events will be redirected to this plugin.

The PluginFactory itself acts as a singleton per plugin class and provides not only the ability to create Plugin objects but also a couple of configuration options and a global handler for configuration and menu events. The configuration includes:

- Menu items: by configuring menu items in the PluginFactory, KLayout can create these items when the plugin is initialized. Each menu entry is connected with the plugin through a symbol: this is a string that tells the plugin's method which menu item was selected. By configuring a menu rather than creating it explicitly, KLayout has a somewhat better control over what menu items belong to which plugin. Menu items are configured by calling in the PluginFactory's constructor.
- Configuration options: Instead of directly taking values from the configuration database, it is more convenient to register configuration keys in the PluginFactory's constructor using the method. After an option is configured, the individual Plugin objects and the PluginFactory receives "configure" calls when a configuration option changes or for the initial configuration.

A PluginFactory must be instantiated and register itself. Menu items and configuration options should be set before the object is registered. Upon registration, a unique name must be specified for the plugin class. Also, the tool button title and optionally an icon can be specified.

The main objective of the PluginFactory class however is to create the actual plugin object. For this, the create_plugin method needs to be reimplemented. The implementation is supposed to create an object of the specific class.

The actual implementation of the plugin is a class derived from Plugin (). The plugin comes into life, when it is activated. That is, when the tool button is pressed that is associated with the plugin. When the plugin is activated, the method is called. The method can be reimplemented in order to prepare the plugin for taking actions on mouse events. When the plugin is not longer active, i.e. because another mode has been selected, the method is called.

Every plugin has the ability to receive and intercept mouse events. Various mouse events are available: mouse moved, mouse button clicked (button pressed and released), mouse button double clicked, mouse button pressed, mouse button released, entry or leave of the window and agitation of the mouse wheel. Each event follows a certain protocol depending whether the plugin is active or not. In addition, plugins can request exclusive control over the mouse by "grabbing" the mouse. Each event is associated with a certain callback. The callback has a parameter - "prio" - which determines the role of the event. The protocol is described here:

- First, all plugins that grabbed the mouse with grab_mouse will receive an event callback with 'prio' set to true in the reverse order the plugins grabbed the mouse. If any one of the mouse event handlers returns true, the protocol terminates.
- If that is not the case or no plugin has grabbed the mouse, the active plugin receives the mouse event with 'prio' set to true.
- If no receiver accepted the mouse event by returning true, it is sent again to all plugins with 'prio' set to false. Again, the loop terminates if one of the receivers returns true. The second pass gives inactive plugins a chance to monitor the mouse and implement specific actions - i.e. displaying the current position.

In an mouse event handler, the plugin can take any action, i.e. transform objects or create/remove markers. This allows implementing of interactive functionality upon KLayout's canvas object. Using "set_cursor", the plugin can set the mouse cursor to a specific shape for example. A plugin should consider implementing "drag_cancel" in order to terminate any pending dragging operations. is called by KLayout to regain control over the mouse in certain circumstances and is supposed to put the plugin into a "watching" instead of "dragging" state.