mirror of https://github.com/KLayout/klayout.git
Adding samples for new plugin features, doc update.
This commit is contained in:
parent
e396b6ec29
commit
f1c16a0242
|
|
@ -976,7 +976,7 @@ marker.destroy</pre>
|
||||||
<p>
|
<p>
|
||||||
The PluginFactory itself acts as a singleton per plugin class and provides not only the ability to create
|
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
|
Plugin objects but also a couple of configuration options and a global handler for configuration and menu
|
||||||
events. The configuration includes:
|
events. The PluginFactory provides:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
|
|
@ -991,6 +991,10 @@ marker.destroy</pre>
|
||||||
After an option is configured, the individual Plugin objects and the PluginFactory receives "configure" calls
|
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.
|
when a configuration option changes or for the initial configuration.
|
||||||
</li>
|
</li>
|
||||||
|
<li>Widgets: The plugin factory can provide widgets for the configuration dialog ('File/Setup') and the
|
||||||
|
editor options dock. Respective callbacks are <class_doc href="PluginFactory#create_config_pages"/>
|
||||||
|
and <class_doc href="PluginFactory#create_editor_options_pages"/>.
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -1048,5 +1052,29 @@ marker.destroy</pre>
|
||||||
over the mouse in certain circumstances and is supposed to put the plugin into a "watching" instead of "dragging" state.
|
over the mouse in certain circumstances and is supposed to put the plugin into a "watching" instead of "dragging" state.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
A plugin may also create markers for visual feedback and highlights. This can be done explicitly
|
||||||
|
using marker objects (<class_doc href="Marker"/>) or in a application-defined fashion by generating
|
||||||
|
mouse cursors. The API functions for this purpose are <class_doc href="Plugin#clear_mouse_cursors"/>,
|
||||||
|
<class_doc href="Plugin#add_mouse_cursor"/> and <class_doc href="Plugin#add_edge_marker"/>. These
|
||||||
|
functions provide cursors and highlights that match the visual effects of other plugins and
|
||||||
|
interface with the mouse tracking feature of the application.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Another service the Plugin class provides is snapping:
|
||||||
|
there exist a number of global configuration options which control snapping (grids, snapping to
|
||||||
|
objects, angle constraints). The plugin offers a number of snap functions that follow the
|
||||||
|
application's current configuration and implement snapping accordingly. These methods are
|
||||||
|
<class_doc href="Plugin#snap"/> and <class_doc href="Plugin#snap2"/>. While the first
|
||||||
|
method provides grid and angle snapping, the second also implements snapping to layout objects.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The "drag box" sample macro demonstrates many of these features.
|
||||||
|
The sample is available from the macro templates when you create a new
|
||||||
|
macro in the macro IDE.
|
||||||
|
</p>
|
||||||
|
|
||||||
</doc>
|
</doc>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@
|
||||||
<file alias="new_macro.lym">macro_templates/new_macro.lym</file>
|
<file alias="new_macro.lym">macro_templates/new_macro.lym</file>
|
||||||
<file alias="new_text_file.txt">macro_templates/new_text_file.txt</file>
|
<file alias="new_text_file.txt">macro_templates/new_text_file.txt</file>
|
||||||
<file alias="new_ruby_file.rb">macro_templates/new_ruby_file.rb</file>
|
<file alias="new_ruby_file.rb">macro_templates/new_ruby_file.rb</file>
|
||||||
|
<file alias="drag_box_sample.lym">macro_templates/drag_box_sample.lym</file>
|
||||||
|
<file alias="drag_box_sample_python.lym">macro_templates/drag_box_sample_python.lym</file>
|
||||||
<file alias="pcell.lym">macro_templates/pcell.lym</file>
|
<file alias="pcell.lym">macro_templates/pcell.lym</file>
|
||||||
<file alias="pcell_sample.lym">macro_templates/pcell_sample.lym</file>
|
<file alias="pcell_sample.lym">macro_templates/pcell_sample.lym</file>
|
||||||
<file alias="qt_designer.lym">macro_templates/qt_designer.lym</file>
|
<file alias="qt_designer.lym">macro_templates/qt_designer.lym</file>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,258 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<klayout-macro>
|
||||||
|
<description>A plugin sample\nThis sample provides a box drawing feature and demonstrates UI components and snapping</description>
|
||||||
|
<format>general</format>
|
||||||
|
<autorun>true</autorun>
|
||||||
|
<autorun-early>false</autorun-early>
|
||||||
|
<show-in-menu>false</show-in-menu>
|
||||||
|
<shortcut></shortcut>
|
||||||
|
<interpreter>ruby</interpreter>
|
||||||
|
<text># Sample plugin
|
||||||
|
#
|
||||||
|
# This plugin implements a box that can be drawn by
|
||||||
|
# clicking at the first and then at the second point.
|
||||||
|
# There is one box which is replacing the previous one.
|
||||||
|
# Line color and line width of the box can be configured
|
||||||
|
# by editor options (line width) or configuration pages
|
||||||
|
# (color).
|
||||||
|
|
||||||
|
module DragBox
|
||||||
|
|
||||||
|
# Register this macro as "autorun" to enable the plugin
|
||||||
|
|
||||||
|
CFG_COLOR = "drag-box-color"
|
||||||
|
CFG_WIDTH = "drag-box-width"
|
||||||
|
|
||||||
|
# The widget placed into the editor options dock
|
||||||
|
|
||||||
|
class DragBoxEditorOptionsPage < RBA::EditorOptionsPage
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
|
||||||
|
# Creates a new page with title "Options" and at
|
||||||
|
# position 1 (second from left)
|
||||||
|
super("Options", 1)
|
||||||
|
|
||||||
|
layout2 = RBA::QVBoxLayout::new(self)
|
||||||
|
layout = RBA::QHBoxLayout::new(self)
|
||||||
|
layout2.addLayout(layout)
|
||||||
|
label = RBA::QLabel::new("Line width", self)
|
||||||
|
layout.addWidget(label)
|
||||||
|
@spin_box = RBA::QSpinBox::new(self)
|
||||||
|
@spin_box.setMinimum(1)
|
||||||
|
@spin_box.setMaximum(16)
|
||||||
|
layout.addWidget(@spin_box)
|
||||||
|
layout.addStretch(1)
|
||||||
|
layout2.addStretch(1)
|
||||||
|
@spin_box.valueChanged = lambda { |x| self.edited }
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def setup(dispatcher)
|
||||||
|
begin
|
||||||
|
@spin_box.setValue(dispatcher.get_config(CFG_WIDTH).to_i)
|
||||||
|
rescue
|
||||||
|
@spin_box.setValue(1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def apply(dispatcher)
|
||||||
|
dispatcher.set_config(CFG_WIDTH, @spin_box.value.to_s)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
# The widget placed into the configuration page
|
||||||
|
|
||||||
|
class DragBoxConfigPage < RBA::ConfigPage
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
|
||||||
|
# places the widget on a new section ("Drag Box")
|
||||||
|
# and "Configure" page
|
||||||
|
super("Drag Box|Configure")
|
||||||
|
|
||||||
|
# Qt user interfact setup
|
||||||
|
layout = RBA::QHBoxLayout::new(self)
|
||||||
|
label = RBA::QLabel::new("Color (hex, rrggbb)", self)
|
||||||
|
layout.addWidget(label)
|
||||||
|
@line_edit = RBA::QLineEdit::new(self)
|
||||||
|
layout.addWidget(@line_edit)
|
||||||
|
layout.addStretch(1)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def setup(dispatcher)
|
||||||
|
@line_edit.setText(dispatcher.get_config(CFG_COLOR))
|
||||||
|
end
|
||||||
|
|
||||||
|
def apply(dispatcher)
|
||||||
|
dispatcher.set_config(CFG_COLOR, @line_edit.text)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
class DragBoxPlugin < RBA::Plugin
|
||||||
|
|
||||||
|
def initialize(view)
|
||||||
|
super()
|
||||||
|
@marker = nil
|
||||||
|
@last_box = nil
|
||||||
|
@box = nil
|
||||||
|
@start_point = nil
|
||||||
|
@view = view
|
||||||
|
@color = nil
|
||||||
|
@width = 1
|
||||||
|
end
|
||||||
|
|
||||||
|
def configure(name, value)
|
||||||
|
# receives configuration callbacks
|
||||||
|
if name == CFG_COLOR
|
||||||
|
# configure marker color
|
||||||
|
begin
|
||||||
|
@color = value != "" ? value.to_i(16) : nil
|
||||||
|
rescue
|
||||||
|
self.color = nil
|
||||||
|
end
|
||||||
|
self._configure_marker
|
||||||
|
elsif name == CFG_WIDTH
|
||||||
|
# configure marker line width
|
||||||
|
begin
|
||||||
|
@width = value.to_i
|
||||||
|
rescue
|
||||||
|
@width = nil
|
||||||
|
end
|
||||||
|
self._configure_marker
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def _clear_marker
|
||||||
|
# clears all markers
|
||||||
|
[ @marker, @last_box ].each { |m| m && m._destroy }
|
||||||
|
@marker = nil
|
||||||
|
@last_box = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def _update_marker
|
||||||
|
# updates the marker with the current box
|
||||||
|
if !@marker
|
||||||
|
@marker = RBA::Marker::new(self.view)
|
||||||
|
self._configure_marker
|
||||||
|
end
|
||||||
|
@marker.set(@box)
|
||||||
|
end
|
||||||
|
|
||||||
|
def freeze_marker
|
||||||
|
# stop dragging the marker and copy to a static one
|
||||||
|
if @last_box
|
||||||
|
@last_box._destroy()
|
||||||
|
end
|
||||||
|
@last_box = @marker
|
||||||
|
@marker = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def _configure_marker
|
||||||
|
# change the marker's appearance
|
||||||
|
if @marker
|
||||||
|
@marker.line_style = 2 # short-dashed
|
||||||
|
@marker.vertex_size = 0 # no vertexes
|
||||||
|
@marker.line_width = @width
|
||||||
|
@marker.color = @color ? (@color | 0xff000000) : 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def activated
|
||||||
|
# plugin is activated - i.e. the mode is selected
|
||||||
|
RBA::MainWindow.instance.message("Click on point to start dragging a box", 10000)
|
||||||
|
end
|
||||||
|
|
||||||
|
def deactivated
|
||||||
|
# plugin is deactivated - i.e. the mode is unselected
|
||||||
|
self._clear_marker
|
||||||
|
RBA::MainWindow.instance.message("", 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
def mouse_click_event(p, buttons, prio)
|
||||||
|
if prio
|
||||||
|
# first-level event: start a new box or
|
||||||
|
# stop dragging it and freeze the box
|
||||||
|
if !@marker
|
||||||
|
p = self.snap2(p)
|
||||||
|
@box = RBA::DBox::new(p, p)
|
||||||
|
@start_point = p
|
||||||
|
self._clear_marker
|
||||||
|
self._update_marker
|
||||||
|
self.grab_mouse
|
||||||
|
RBA::MainWindow.instance.message("Drag the box and click again", 10000)
|
||||||
|
else
|
||||||
|
p = self.snap2(p, @start_point, true, self.ac_from_buttons(buttons))
|
||||||
|
self.freeze_marker
|
||||||
|
self.ungrab_mouse
|
||||||
|
RBA::MainWindow.instance.message("Box finished: " + @box.to_s, 10000)
|
||||||
|
end
|
||||||
|
# consume event
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def mouse_moved_event(p, buttons, prio)
|
||||||
|
if prio
|
||||||
|
# first-level event: if not dragging, provide a
|
||||||
|
# mouse cursor for tracking. If dragging, update
|
||||||
|
# the box and provide a mouse cursor.
|
||||||
|
if !@marker
|
||||||
|
self.clear_mouse_cursors
|
||||||
|
p = self.snap2(p, true)
|
||||||
|
self.add_mouse_cursor(p)
|
||||||
|
else
|
||||||
|
self.clear_mouse_cursors
|
||||||
|
p = self.snap2(p, @start_point, true, self.ac_from_buttons(buttons), true)
|
||||||
|
self.add_mouse_cursor(p)
|
||||||
|
@box = RBA::DBox::new(@start_point, p)
|
||||||
|
self._update_marker
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# NOTE: we must not digest this event (i.e. return true)
|
||||||
|
# to allow the mouse tracker to receive the events as well
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
# Implements a "plugin factory".
|
||||||
|
# Purpose of this object is to create a plugin object
|
||||||
|
# and corresponding UI objects.
|
||||||
|
|
||||||
|
class DragBoxPluginFactory < RBA::PluginFactory
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
super()
|
||||||
|
self.has_tool_entry = true
|
||||||
|
# NOTE: it's a good practice to register configuration options
|
||||||
|
self.add_option(CFG_WIDTH, "1")
|
||||||
|
self.add_option(CFG_COLOR, "")
|
||||||
|
self.register(-1000, "drag_box", "Drag Box")
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_config_pages
|
||||||
|
self.add_config_page(DragBoxConfigPage::new)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_editor_options_pages
|
||||||
|
self.add_editor_options_page(DragBoxEditorOptionsPage::new)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_plugin(manager, root, view)
|
||||||
|
return DragBoxPlugin::new(view)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
# Create the singleton instance - as we register it,
|
||||||
|
# it is not garbage collected
|
||||||
|
DragBoxPluginFactory::new
|
||||||
|
|
||||||
|
end</text>
|
||||||
|
</klayout-macro>
|
||||||
|
|
@ -0,0 +1,222 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<klayout-macro>
|
||||||
|
<description>A plugin sample\nThis sample provides a box drawing feature and demonstrates UI components and snapping</description>
|
||||||
|
<format>general</format>
|
||||||
|
<autorun>true</autorun>
|
||||||
|
<autorun-early>false</autorun-early>
|
||||||
|
<show-in-menu>false</show-in-menu>
|
||||||
|
<shortcut></shortcut>
|
||||||
|
<interpreter>python</interpreter>
|
||||||
|
<text># Sample plugin
|
||||||
|
#
|
||||||
|
# This plugin implements a box that can be drawn by
|
||||||
|
# clicking at the first and then at the second point.
|
||||||
|
# There is one box which is replacing the previous one.
|
||||||
|
# Line color and line width of the box can be configured
|
||||||
|
# by editor options (line width) or configuration pages
|
||||||
|
# (color).
|
||||||
|
|
||||||
|
# Register this macro as "autorun" to enable the plugin
|
||||||
|
|
||||||
|
cfg_color = "drag-box-color"
|
||||||
|
cfg_width = "drag-box-width"
|
||||||
|
|
||||||
|
# The widget placed into the editor options dock
|
||||||
|
|
||||||
|
class DragBoxEditorOptionsPage(pya.EditorOptionsPage):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
|
||||||
|
# Creates a new page with title "Options" and at
|
||||||
|
# position 1 (second from left)
|
||||||
|
super(DragBoxEditorOptionsPage, self).__init__("Options", 1)
|
||||||
|
|
||||||
|
layout2 = pya.QVBoxLayout(self)
|
||||||
|
layout = pya.QHBoxLayout(self)
|
||||||
|
layout2.addLayout(layout)
|
||||||
|
label = pya.QLabel("Line width", self)
|
||||||
|
layout.addWidget(label)
|
||||||
|
self.spin_box = pya.QSpinBox(self)
|
||||||
|
self.spin_box.setMinimum(1)
|
||||||
|
self.spin_box.setMaximum(16)
|
||||||
|
layout.addWidget(self.spin_box)
|
||||||
|
layout.addStretch(1)
|
||||||
|
layout2.addStretch(1)
|
||||||
|
|
||||||
|
self.spin_box.valueChanged = lambda x: self.edited()
|
||||||
|
|
||||||
|
def setup(self, dispatcher):
|
||||||
|
try:
|
||||||
|
self.spin_box.setValue(int(dispatcher.get_config(cfg_width)))
|
||||||
|
except:
|
||||||
|
self.spin_box.setValue(1)
|
||||||
|
|
||||||
|
def apply(self, dispatcher):
|
||||||
|
dispatcher.set_config(cfg_width, str(self.spin_box.value))
|
||||||
|
|
||||||
|
# The widget placed into the configuration page
|
||||||
|
|
||||||
|
class DragBoxConfigPage(pya.ConfigPage):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
|
||||||
|
# places the widget on a new section ("Drag Box")
|
||||||
|
# and "Configure" page
|
||||||
|
super(DragBoxConfigPage, self).__init__("Drag Box|Configure")
|
||||||
|
|
||||||
|
layout = pya.QHBoxLayout(self)
|
||||||
|
label = pya.QLabel("Color (hex, rrggbb)", self)
|
||||||
|
layout.addWidget(label)
|
||||||
|
self.line_edit = pya.QLineEdit(self)
|
||||||
|
layout.addWidget(self.line_edit)
|
||||||
|
layout.addStretch(1)
|
||||||
|
|
||||||
|
def setup(self, dispatcher):
|
||||||
|
self.line_edit.setText(dispatcher.get_config(cfg_color))
|
||||||
|
|
||||||
|
def apply(self, dispatcher):
|
||||||
|
dispatcher.set_config(cfg_color, self.line_edit.text)
|
||||||
|
|
||||||
|
class DragBoxPlugin(pya.Plugin):
|
||||||
|
|
||||||
|
def __init__(self, view):
|
||||||
|
super(DragBoxPlugin, self).__init__()
|
||||||
|
self.marker = None
|
||||||
|
self.last_box = None
|
||||||
|
self.box = None
|
||||||
|
self.start_point = None
|
||||||
|
self.view = view
|
||||||
|
self.color = None
|
||||||
|
self.width = 1
|
||||||
|
|
||||||
|
def configure(self, name, value):
|
||||||
|
# receives configuration callbacks
|
||||||
|
needs_update = False
|
||||||
|
if name == cfg_color:
|
||||||
|
# configure marker color
|
||||||
|
try:
|
||||||
|
if value != "":
|
||||||
|
self.color = int(value, 16)
|
||||||
|
else:
|
||||||
|
self.color = None
|
||||||
|
except:
|
||||||
|
self.color = None
|
||||||
|
self._configure_marker()
|
||||||
|
elif name == cfg_width:
|
||||||
|
# configure marker line width
|
||||||
|
try:
|
||||||
|
self.width = int(value)
|
||||||
|
except:
|
||||||
|
self.width = None
|
||||||
|
self._configure_marker()
|
||||||
|
|
||||||
|
def _clear_marker(self):
|
||||||
|
# clears all markers
|
||||||
|
for marker in [ self.marker, self.last_box ]:
|
||||||
|
if marker is not None:
|
||||||
|
marker._destroy()
|
||||||
|
self.marker = None
|
||||||
|
self.last_box = None
|
||||||
|
|
||||||
|
def _update_marker(self):
|
||||||
|
# updates the marker with the current box
|
||||||
|
if self.marker is None:
|
||||||
|
self.marker = pya.Marker(self.view)
|
||||||
|
self._configure_marker()
|
||||||
|
self.marker.set(self.box)
|
||||||
|
|
||||||
|
def freeze_marker(self):
|
||||||
|
# stop dragging the marker and copy to a static one
|
||||||
|
if self.last_box is not None:
|
||||||
|
self.last_box._destroy()
|
||||||
|
self.last_box = self.marker
|
||||||
|
self.marker = None
|
||||||
|
|
||||||
|
def _configure_marker(self):
|
||||||
|
# change the marker's appearance
|
||||||
|
if self.marker is not None:
|
||||||
|
self.marker.line_style = 2 # short-dashed
|
||||||
|
self.marker.vertex_size = 0 # no vertexes
|
||||||
|
self.marker.line_width = self.width
|
||||||
|
if self.color is not None:
|
||||||
|
self.marker.color = self.color | 0xff000000
|
||||||
|
else:
|
||||||
|
self.marker.color = 0 # auto
|
||||||
|
|
||||||
|
def activated(self):
|
||||||
|
# plugin is activated - i.e. the mode is selected
|
||||||
|
pya.MainWindow.instance().message("Click on point to start dragging a box", 10000)
|
||||||
|
|
||||||
|
def deactivated(self):
|
||||||
|
# plugin is deactivated - i.e. the mode is unselected
|
||||||
|
self._clear_marker()
|
||||||
|
pya.MainWindow.instance().message("", 0)
|
||||||
|
|
||||||
|
def mouse_click_event(self, p, buttons, prio):
|
||||||
|
if prio:
|
||||||
|
# first-level event: start a new box or
|
||||||
|
# stop dragging it and freeze the box
|
||||||
|
if self.marker is None:
|
||||||
|
p = self.snap2(p)
|
||||||
|
self.box = pya.DBox(p, p)
|
||||||
|
self.start_point = p
|
||||||
|
self._clear_marker()
|
||||||
|
self._update_marker()
|
||||||
|
self.grab_mouse()
|
||||||
|
pya.MainWindow.instance().message("Drag the box and click again", 10000)
|
||||||
|
else:
|
||||||
|
p = self.snap2(p, self.start_point, True, self.ac_from_buttons(buttons))
|
||||||
|
self.freeze_marker()
|
||||||
|
self.ungrab_mouse()
|
||||||
|
pya.MainWindow.instance().message("Box finished: " + str(self.box), 10000)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def mouse_moved_event(self, p, buttons, prio):
|
||||||
|
if prio:
|
||||||
|
# first-level event: if not dragging, provide a
|
||||||
|
# mouse cursor for tracking. If dragging, update
|
||||||
|
# the box and provide a mouse cursor.
|
||||||
|
if self.marker is None:
|
||||||
|
self.clear_mouse_cursors()
|
||||||
|
p = self.snap2(p, visualize=True)
|
||||||
|
self.add_mouse_cursor(p)
|
||||||
|
else:
|
||||||
|
self.clear_mouse_cursors()
|
||||||
|
p = self.snap2(p, self.start_point, True, self.ac_from_buttons(buttons), visualize=True)
|
||||||
|
self.add_mouse_cursor(p)
|
||||||
|
self.box = pya.DBox(self.start_point, p)
|
||||||
|
self._update_marker()
|
||||||
|
# NOTE: we must not digest this event (i.e. return True)
|
||||||
|
# to allow the mouse tracker to receive the events as well
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
# Implements a "plugin factory".
|
||||||
|
# Purpose of this object is to create a plugin object
|
||||||
|
# and corresponding UI objects.
|
||||||
|
|
||||||
|
class DragBoxPluginFactory(pya.PluginFactory):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(DragBoxPluginFactory, self).__init__()
|
||||||
|
self.has_tool_entry = True
|
||||||
|
# NOTE: it's a good practice to register configuration options
|
||||||
|
self.add_option(cfg_width, "1")
|
||||||
|
self.add_option(cfg_color, "")
|
||||||
|
self.register(-1000, "drag_box", "Drag Box")
|
||||||
|
|
||||||
|
def create_config_pages(self):
|
||||||
|
self.add_config_page(DragBoxConfigPage())
|
||||||
|
|
||||||
|
def create_editor_options_pages(self):
|
||||||
|
self.add_editor_options_page(DragBoxEditorOptionsPage())
|
||||||
|
|
||||||
|
def create_plugin(self, manager, root, view):
|
||||||
|
return DragBoxPlugin(view)
|
||||||
|
|
||||||
|
# Create the singleton instance - as we register it,
|
||||||
|
# it is not garbage collected
|
||||||
|
DragBoxPluginFactory()
|
||||||
|
</text>
|
||||||
|
</klayout-macro>
|
||||||
|
|
@ -23,6 +23,7 @@ pcell_sample.lym
|
||||||
qt_designer.lym
|
qt_designer.lym
|
||||||
qt_dialog.lym
|
qt_dialog.lym
|
||||||
qt_server.lym
|
qt_server.lym
|
||||||
|
drag_box_sample.lym
|
||||||
|
|
||||||
[pymacros]
|
[pymacros]
|
||||||
# General group
|
# General group
|
||||||
|
|
@ -41,4 +42,5 @@ pcell_sample_python.lym
|
||||||
qt_designer_python.lym
|
qt_designer_python.lym
|
||||||
qt_dialog_python.lym
|
qt_dialog_python.lym
|
||||||
qt_server_python.lym
|
qt_server_python.lym
|
||||||
|
drag_box_sample_python.lym
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue