Merge branch 'master' of github.com:KLayout/klayout

This commit is contained in:
Matthias Koefferlein 2024-07-01 18:26:03 +02:00
commit 4746385dbd
29 changed files with 13029 additions and 742 deletions

View File

@ -55,7 +55,7 @@ echo "Generating stubs for tl .."
$python $inst/stubgen.py tl >$pyi_srcdir/tlcore.pyi
echo "Generating stubs for db .."
$python $inst/stubgen.py db tl >$pyi_srcdir/dbcore.pyi
$python $inst/stubgen.py db tl,lay,rdb >$pyi_srcdir/dbcore.pyi
echo "Generating stubs for rdb .."
$python $inst/stubgen.py rdb tl,db >$pyi_srcdir/rdbcore.pyi

View File

@ -192,6 +192,10 @@ class Stub:
stub.format_stub(include_docstring=include_docstring), " " * 4
)
if self.indent_docstring and (include_docstring or len(self.child_stubs)):
stub_str += "\n"
stub_str += indent("...", " " * 4)
return stub_str
@ -369,7 +373,8 @@ def get_py_methods(
# Exceptions:
# For X.__eq__(self, a:X), treat second argument as type object instead of X
if name in ("__eq__", "__ne__"):
arg_list[1] = arg_list[1][0], "object"
if arg_list[1][1].cls() is not None and arg_list[1][1].cls().__gsi_id__ == c.__gsi_id__:
arg_list[1] = arg_list[1][0], "object"
# X._assign(self, other:X), mypy complains if _assign is defined at base class.
# We can't specialize other in this case.
elif name in ("_assign", "assign"):
@ -454,6 +459,7 @@ def get_module_stubs(module: str) -> List[ClassStub]:
def print_mod(module, dependencies):
print("from typing import Any, ClassVar, Dict, Sequence, List, Iterator, Optional")
print("from typing import overload")
print("from __future__ import annotations")
for dep in dependencies:
print(f"import klayout.{dep} as {dep}")
for stub in get_module_stubs(module):

View File

@ -118,6 +118,9 @@ Optional, named parameters are
@li
@b:unit@/b: the unit string
@/li
@li
@btooltip@/b: the tool tip text displayed on the edit fields and labels
@/li
@li
@b:min_value@/b: the minimum value (effective for numerical types and if no choices are present)
@/li
@ -378,6 +381,7 @@ module RBA
# set additional attributes of the parameters
args[:default] && pdecl.default = args[:default]
args[:tooltip] && pdecl.tooltip = args[:tooltip]
args[:hidden] && pdecl.hidden = args[:hidden]
args[:readonly] && pdecl.readonly = args[:readonly]
args[:unit] && pdecl.unit = args[:unit]

View File

@ -127,6 +127,9 @@ Optional, named parameters are
@li
@bunit@/b: the unit string
@/li
@li
@btooltip@/b: the tool tip text displayed on the edit fields and labels
@/li
@li
@bmin_value@/b: the minimum value (effective for numerical types and if no choices are present)
@/li

View File

@ -168,6 +168,22 @@ public:
m_description = description;
}
/**
* @brief Getter for the tooltip property
*/
const std::string &get_tooltip () const
{
return m_tooltip;
}
/**
* @brief Setter for the tooltip property
*/
void set_tooltip (const std::string &tooltip)
{
m_tooltip = tooltip;
}
/**
* @brief Getter for the type property
*/
@ -331,6 +347,7 @@ public:
m_type == d.m_type &&
m_name == d.m_name &&
m_description == d.m_description &&
m_tooltip == d.m_tooltip &&
m_unit == d.m_unit &&
m_min_value == d.m_min_value &&
m_max_value == d.m_max_value;
@ -343,7 +360,7 @@ private:
bool m_hidden, m_readonly;
type m_type;
std::string m_name;
std::string m_description, m_unit;
std::string m_description, m_tooltip, m_unit;
tl::Variant m_min_value, m_max_value;
};

View File

@ -37,7 +37,7 @@ namespace db
{
Triangles::Triangles ()
: m_is_constrained (false), m_level (0), m_flips (0), m_hops (0)
: m_is_constrained (false), m_level (0), m_id (0), m_flips (0), m_hops (0)
{
// .. nothing yet ..
}
@ -1414,8 +1414,8 @@ Triangles::remove_outside_triangles ()
void
Triangles::clear ()
{
m_edges_heap.clear ();
mp_triangles.clear ();
m_edges_heap.clear ();
m_vertex_heap.clear ();
m_returned_edges.clear ();
m_is_constrained = false;

View File

@ -819,6 +819,14 @@ Class<db::PCellParameterDeclaration> decl_PCellParameterDeclaration ("db", "PCel
gsi::method ("description=", &db::PCellParameterDeclaration::set_description, gsi::arg ("description"),
"@brief Sets the description\n"
) +
gsi::method ("tooltip", &db::PCellParameterDeclaration::get_tooltip,
"@brief Gets the tool tip text\n"
"This attribute has been introduced in version 0.29.3."
) +
gsi::method ("tooltip=", &db::PCellParameterDeclaration::set_tooltip, gsi::arg ("tooltip"),
"@brief Sets the tool tip text\n"
"This attribute has been introduced in version 0.29.3."
) +
gsi::method ("hidden?", &db::PCellParameterDeclaration::is_hidden,
"@brief Returns true, if the parameter is a hidden parameter that should not be shown in the user interface\n"
"By making a parameter hidden, it is possible to create internal parameters which cannot be\n"

View File

@ -63,6 +63,13 @@ TEST(basic)
EXPECT_EQ (tris.to_string (), "((1, 0), (1, 4), (5, 0)), ((1, 4), (5, 4), (5, 0))");
EXPECT_EQ (tris.check (), true);
tris.clear ();
EXPECT_EQ (tris.bbox ().to_string (), "()");
EXPECT_EQ (tris.to_string (), "");
EXPECT_EQ (tris.check (), true);
}
TEST(flip)

View File

@ -416,8 +416,7 @@ PCellParametersPage::setup (lay::LayoutViewBase *view, int cv_index, const db::P
leader = tl::sprintf ("[%s] ", p->get_name ());
}
QLabel *l = new QLabel (tl::to_qstring (leader + description + range), inner_frame);
QLabel *l = new QLabel (tl::to_qstring (leader + description + range), inner_frame);
inner_grid->addWidget (l, row, 1);
m_all_widgets.back ().push_back (l);
@ -975,6 +974,7 @@ PCellParametersPage::update_widgets_from_states (const db::ParameterStates &stat
for (std::vector<db::PCellParameterDeclaration>::const_iterator p = pcp.begin (); p != pcp.end () && i < m_widgets.size (); ++p, ++i) {
const std::string &name = p->get_name ();
const std::string &static_tooltip = p->get_tooltip ();
const db::ParameterState &ps = states.parameter (name);
if (m_widgets [i]) {
@ -994,7 +994,11 @@ PCellParametersPage::update_widgets_from_states (const db::ParameterStates &stat
if (*w != m_icon_widgets [i]) {
(*w)->setVisible (ps.is_visible ());
}
(*w)->setToolTip (tl::to_qstring (ps.tooltip ()));
if (ps.tooltip ().empty ()) {
(*w)->setToolTip (tl::to_qstring (static_tooltip));
} else {
(*w)->setToolTip (tl::to_qstring (ps.tooltip ()));
}
}
if (m_icon_widgets [i]) {

View File

@ -28,6 +28,7 @@
#include "layLayoutViewBase.h"
#include "layDitherPattern.h"
#include "layLineStyles.h"
#include "layMarker.h"
#include "dbSaveLayoutOptions.h"
#include "dbLayoutToNetlist.h"
#include "dbLayoutVsSchematic.h"
@ -469,6 +470,22 @@ static LayerPropertiesConstIteratorWrapper each_layer2 (lay::LayoutViewBase *vie
return LayerPropertiesConstIteratorWrapper (view->begin_layers (list_index));
}
static void add_marker (lay::LayoutViewBase *view, lay::ManagedDMarker *object)
{
if (view->canvas ()) {
object->keep ();
object->set_view (view);
}
}
static void clear_markers (lay::LayoutViewBase *view)
{
// NOTE: this will clear *all* persistent objects, not just our markers
if (view->canvas ()) {
view->canvas ()->clear_objects ();
}
}
static lay::AbstractMenu *menu (lay::LayoutViewBase *view)
{
return view->menu ();
@ -679,6 +696,30 @@ LAYBASIC_PUBLIC Class<lay::LayoutViewBase> decl_LayoutViewBase ("lay", "LayoutVi
"\n"
"In 0.25, this method has been moved from MainWindow to LayoutView.\n"
) +
gsi::method_ext ("add_marker", &add_marker, gsi::arg ("marker"),
"@brief Adds a persistent marker to the view (transferring ownership)\n"
"\n"
"This method allows creating markers and transferring ownership to the view, hence making them persistent. "
"This means, when the variable with the marker object goes out of scope, the marker will still exist in the view.\n"
"\n"
"To create a persistent marker, use the following code:\n"
"\n"
"@code\n"
"marker = RBA::Marker::new\n"
"# ... configure marker ...\n"
"view.add_marker(marker)\n"
"@/code\n"
"\n"
"To remove all persistent markers owned by the view, use \\clear_markers.\n"
"\n"
"Persistent markers have been introduced in version 0.29.3\n"
) +
gsi::method_ext ("clear_markers", &clear_markers,
"@brief Clears all persistent markers from the view\n"
"See \\add_marker for details about persistent markers.\n"
"\n"
"Persistent markers have been introduced in version 0.29.3\n"
) +
gsi::method ("is_editable?", static_cast<bool (lay::LayoutViewBase::*) () const> (&lay::LayoutViewBase::is_editable),
"@brief Returns true if the view is in editable mode\n"
"\n"
@ -836,7 +877,7 @@ LAYBASIC_PUBLIC Class<lay::LayoutViewBase> decl_LayoutViewBase ("lay", "LayoutVi
gsi::method ("active_cellview_index", static_cast<int (lay::LayoutViewBase::*) () const> (&lay::LayoutViewBase::active_cellview_index),
"@brief Gets the index of the active cellview (shown in hierarchy browser)\n"
) +
gsi::method ("active_setview_index=|#set_active_cellview_index", &lay::LayoutViewBase::set_active_cellview_index, gsi::arg ("index"),
gsi::method ("active_cellview_index=|#active_setview_index=|#set_active_cellview_index", &lay::LayoutViewBase::set_active_cellview_index, gsi::arg ("index"),
"@brief Makes the cellview with the given index the active one (shown in hierarchy browser)\n"
"See \\active_cellview_index.\n"
"\n"

View File

@ -29,43 +29,43 @@ namespace gsi
{
static
lay::DMarker *create_marker (lay::LayoutViewBase *view)
lay::ManagedDMarker *create_marker (lay::LayoutViewBase *view)
{
return new lay::DMarker (view);
return new lay::ManagedDMarker (view);
}
static
void reset_frame_color (lay::DMarker *marker)
void reset_frame_color (lay::ManagedDMarker *marker)
{
marker->set_frame_color (tl::Color ());
}
static
void set_frame_color (lay::DMarker *marker, unsigned int color)
void set_frame_color (lay::ManagedDMarker *marker, unsigned int color)
{
marker->set_frame_color (tl::Color (color));
}
static
unsigned int get_frame_color (const lay::DMarker *marker)
unsigned int get_frame_color (const lay::ManagedDMarker *marker)
{
return marker->get_frame_color ().rgb ();
}
static
bool has_frame_color (const lay::DMarker *marker)
bool has_frame_color (const lay::ManagedDMarker *marker)
{
return marker->get_frame_color ().is_valid ();
}
static
void reset_color (lay::DMarker *marker)
void reset_color (lay::ManagedDMarker *marker)
{
marker->set_color (tl::Color ());
}
static
void set_color (lay::DMarker *marker, unsigned int color)
void set_color (lay::ManagedDMarker *marker, unsigned int color)
{
marker->set_color (tl::Color (color));
}
@ -77,44 +77,48 @@ unsigned int get_color (const lay::DMarker *marker)
}
static
bool has_color (const lay::DMarker *marker)
bool has_color (const lay::ManagedDMarker *marker)
{
return marker->get_color ().is_valid ();
}
Class<lay::DMarker> decl_Marker ("lay", "Marker",
gsi::constructor ("new", &create_marker, gsi::arg ("view"),
Class<lay::ManagedDMarker> decl_Marker ("lay", "Marker",
gsi::constructor ("new", &create_marker, gsi::arg ("view", (lay::LayoutViewBase *) 0, "nil"),
"@brief Creates a marker\n"
"\n"
"A marker is always associated with a view, in which it is shown. The "
"view this marker is associated with must be passed to the constructor."
"view this marker is associated with must be passed to the constructor.\n"
"\n"
"See the class description about the options for attaching markers to a view.\n"
"\n"
"The 'view' argument is optional since version 0.29.3."
) +
gsi::method ("set|set_box", (void (lay::DMarker::*) (const db::DBox &)) &lay::DMarker::set, gsi::arg ("box"),
gsi::method ("set|set_box", (void (lay::ManagedDMarker::*) (const db::DBox &)) &lay::ManagedDMarker::set, gsi::arg ("box"),
"@brief Sets the box the marker is to display\n"
"\n"
"Makes the marker show a box. The box must be given in micron units.\n"
"If the box is empty, no marker is drawn.\n"
"The set method has been added in version 0.20.\n"
) +
gsi::method ("set|set_text", (void (lay::DMarker::*) (const db::DText &)) &lay::DMarker::set, gsi::arg ("text"),
gsi::method ("set|set_text", (void (lay::ManagedDMarker::*) (const db::DText &)) &lay::ManagedDMarker::set, gsi::arg ("text"),
"@brief Sets the text the marker is to display\n"
"\n"
"Makes the marker show a text. The text must be given in micron units.\n"
"The set method has been added in version 0.20.\n"
) +
gsi::method ("set|set_edge", (void (lay::DMarker::*) (const db::DEdge &)) &lay::DMarker::set, gsi::arg ("edge"),
gsi::method ("set|set_edge", (void (lay::ManagedDMarker::*) (const db::DEdge &)) &lay::ManagedDMarker::set, gsi::arg ("edge"),
"@brief Sets the edge the marker is to display\n"
"\n"
"Makes the marker show a edge. The edge must be given in micron units.\n"
"The set method has been added in version 0.20.\n"
) +
gsi::method ("set|set_path", (void (lay::DMarker::*) (const db::DPath &)) &lay::DMarker::set, gsi::arg ("path"),
gsi::method ("set|set_path", (void (lay::ManagedDMarker::*) (const db::DPath &)) &lay::ManagedDMarker::set, gsi::arg ("path"),
"@brief Sets the path the marker is to display\n"
"\n"
"Makes the marker show a path. The path must be given in micron units.\n"
"The set method has been added in version 0.20.\n"
) +
gsi::method ("set|set_polygon", (void (lay::DMarker::*) (const db::DPolygon &)) &lay::DMarker::set, gsi::arg ("polygon"),
gsi::method ("set|set_polygon", (void (lay::ManagedDMarker::*) (const db::DPolygon &)) &lay::ManagedDMarker::set, gsi::arg ("polygon"),
"@brief Sets the polygon the marker is to display\n"
"\n"
"Makes the marker show a polygon. The polygon must be given in micron units.\n"
@ -156,59 +160,59 @@ Class<lay::DMarker> decl_Marker ("lay", "Marker",
"@brief Returns a value indicating whether the marker has a specific frame color\n"
"The set method has been added in version 0.20.\n"
) +
gsi::method ("dismissable=", &lay::DMarker::set_dismissable, gsi::arg ("flag"),
gsi::method ("dismissable=", (void (lay::ManagedDMarker::*) (bool)) &lay::ManagedDMarker::set_dismissable, gsi::arg ("flag"),
"@brief Sets a value indicating whether the marker can be hidden\n"
"Dismissable markers can be hidden setting \"View/Show Markers\" to \"off\". "
"The default setting is \"false\" meaning the marker can't be hidden.\n"
"\n"
"This attribute has been introduced in version 0.25.4."
) +
gsi::method ("dismissable?", &lay::DMarker::get_dismissable,
gsi::method ("dismissable?", (bool (lay::ManagedDMarker::*) () const) &lay::ManagedDMarker::get_dismissable,
"@brief Gets a value indicating whether the marker can be hidden\n"
"See \\dismissable= for a description of this predicate."
) +
gsi::method ("line_width=", &lay::DMarker::set_line_width, gsi::arg ("width"),
gsi::method ("line_width=", (void (lay::ManagedDMarker::*) (int)) &lay::ManagedDMarker::set_line_width, gsi::arg ("width"),
"@brief Sets the line width of the marker\n"
"This is the width of the line drawn for the outline of the marker."
) +
gsi::method ("line_width", &lay::DMarker::get_line_width,
gsi::method ("line_width", (int (lay::ManagedDMarker::*) () const) &lay::ManagedDMarker::get_line_width,
"@brief Gets the line width of the marker\n"
"See \\line_width= for a description of the line width."
) +
gsi::method ("vertex_size=", &lay::DMarker::set_vertex_size, gsi::arg ("size"),
gsi::method ("vertex_size=", (void (lay::ManagedDMarker::*) (int)) &lay::ManagedDMarker::set_vertex_size, gsi::arg ("size"),
"@brief Sets the vertex size of the marker\n"
"This is the size of the rectangles drawn for the vertices object."
) +
gsi::method ("vertex_size", &lay::DMarker::get_vertex_size,
gsi::method ("vertex_size", (int (lay::ManagedDMarker::*) () const) &lay::ManagedDMarker::get_vertex_size,
"@brief Gets the vertex size of the marker\n"
"See \\vertex_size= for a description."
) +
gsi::method ("halo=", &lay::DMarker::set_halo, gsi::arg ("halo"),
gsi::method ("halo=", (void (lay::ManagedDMarker::*) (int)) &lay::ManagedDMarker::set_halo, gsi::arg ("halo"),
"@brief Sets the halo flag\n"
"The halo flag is either -1 (for taking the default), 0 to disable the halo or 1 to enable it. "
"If the halo is enabled, a pixel border with the background color is drawn around the marker, the "
"vertices and texts."
) +
gsi::method ("halo", &lay::DMarker::get_halo,
gsi::method ("halo", (int (lay::ManagedDMarker::*) () const) &lay::ManagedDMarker::get_halo,
"@brief Gets the halo flag\n"
"See \\halo= for a description of the halo flag."
) +
gsi::method ("dither_pattern=", &lay::DMarker::set_dither_pattern, gsi::arg ("index"),
gsi::method ("dither_pattern=", (void (lay::ManagedDMarker::*) (int)) &lay::ManagedDMarker::set_dither_pattern, gsi::arg ("index"),
"@brief Sets the stipple pattern index\n"
"A value of -1 or less than zero indicates that the marker is not filled. Otherwise, the "
"value indicates which pattern to use for filling the marker."
) +
gsi::method ("dither_pattern", &lay::DMarker::get_dither_pattern,
gsi::method ("dither_pattern", (int (lay::ManagedDMarker::*) () const) &lay::ManagedDMarker::get_dither_pattern,
"@brief Gets the stipple pattern index\n"
"See \\dither_pattern= for a description of the stipple pattern index."
) +
gsi::method ("line_style=", &lay::DMarker::set_line_style, gsi::arg ("index"),
gsi::method ("line_style=", (void (lay::ManagedDMarker::*) (int)) &lay::ManagedDMarker::set_line_style, gsi::arg ("index"),
"@brief Sets the line style\n"
"The line style is given by an index. 0 is solid, 1 is dashed and so forth.\n"
"\n"
"This method has been introduced in version 0.25."
) +
gsi::method ("line_style", &lay::DMarker::get_line_style,
gsi::method ("line_style", (int (lay::ManagedDMarker::*) () const) &lay::ManagedDMarker::get_line_style,
"@brief Get the line style\n"
"See \\line_style= for a description of the line style index."
"\n"
@ -219,6 +223,32 @@ Class<lay::DMarker> decl_Marker ("lay", "Marker",
"The marker is a visual object that \"marks\" (highlights) a \n"
"certain area of the layout, given by a database object. "
"This object accepts database objects with floating-point coordinates in micron values.\n"
"\n"
"Since version 0.29.3, markers can be attached to views in two ways: self-managed or persistent.\n"
"\n"
"Self-managed markers are created with a view argument. When the variable goes out of scope, the "
"and the Marker object is released, the marker vanishes. This was the only concept before 0.29.3:\n"
"\n"
"@code\n"
"view = ... # some LayoutView\n"
"marker = RBA::Marker::new(view)\n"
"@/code\n"
"\n"
"Persistent markers on the other hand are attached to the view and stay within the view. To create a "
"persistent marker, do not use a view argument to the constructor. Instead add them to the view using "
"\\LayoutView#add_marker. To remove persistent markers, "
"use \\LayoutView#clear_markers (removes all) or call \\_destroy on a specific marker:\n"
"\n"
"@code\n"
"view = ... # some LayoutView\n"
"marker = RBA::Marker::new\n"
"view.add_marker(marker)\n"
"...\n"
"view.clear_markers\n"
"@/code\n"
"\n"
"Persistent markers do not need to be held in separate variables to keep them visible. In some applications "
"this may be useful."
);
}

View File

@ -197,13 +197,23 @@ void render_cell_inst (const db::Layout &layout, const db::CellInstArray &inst,
// ------------------------------------------------------------------------
MarkerBase::MarkerBase (lay::LayoutViewBase *view)
: lay::ViewObject (view->canvas ()),
: lay::ViewObject (view ? view->canvas () : 0),
m_line_width (-1), m_vertex_size (-1), m_halo (-1), m_text_enabled (true), m_vertex_shape (lay::ViewOp::Rect), m_line_style (-1), m_dither_pattern (-1), m_frame_pattern (0), mp_view (view)
{
// .. nothing yet ..
}
void
void
MarkerBase::set_view (LayoutViewBase *view)
{
if (mp_view != view) {
mp_view = view;
mp_view->canvas ()->add_object (this);
redraw ();
}
}
void
MarkerBase::set_frame_color (tl::Color color)
{
if (color != m_frame_color) {
@ -381,7 +391,7 @@ MarkerBase::get_bitmaps (const Viewport & /*vp*/, ViewObjectCanvas &canvas, lay:
// ------------------------------------------------------------------------
GenericMarkerBase::GenericMarkerBase (lay::LayoutViewBase *view, unsigned int cv_index)
: MarkerBase (view), mp_trans_vector (0), mp_view (view), m_cv_index (cv_index)
: MarkerBase (view), mp_trans_vector (0), m_cv_index (cv_index)
{
// .. nothing yet ..
}
@ -463,7 +473,7 @@ GenericMarkerBase::set (const db::DCplxTrans &t1, const std::vector<db::DCplxTra
db::DBox
GenericMarkerBase::bbox () const
{
const lay::CellView &cv = mp_view->cellview (m_cv_index);
const lay::CellView &cv = view ()->cellview (m_cv_index);
if (! cv.is_valid ()) {
return db::DBox ();
}
@ -483,11 +493,11 @@ GenericMarkerBase::bbox () const
const db::Layout *
GenericMarkerBase::layout () const
{
if (m_cv_index >= (unsigned int) (mp_view->cellviews ())) {
if (m_cv_index >= (unsigned int) (view ()->cellviews ())) {
return 0;
}
const lay::CellView &cv = mp_view->cellview (m_cv_index);
const lay::CellView &cv = view ()->cellview (m_cv_index);
if (! cv.is_valid ()) {
return 0;
} else {
@ -1175,7 +1185,7 @@ Marker::render (const Viewport &vp, ViewObjectCanvas &canvas)
// ------------------------------------------------------------------------
DMarker::DMarker (LayoutViewBase *view)
: MarkerBase (view), mp_view (view)
: MarkerBase (view)
{
m_type = None;
m_object.any = 0;
@ -1304,9 +1314,9 @@ DMarker::render (const Viewport &vp, ViewObjectCanvas &canvas)
lay::Renderer &r = canvas.renderer ();
r.set_font (db::Font (mp_view->text_font ()));
r.apply_text_trans (mp_view->apply_text_trans ());
r.default_text_size (mp_view->default_text_size ());
r.set_font (db::Font (view ()->text_font ()));
r.apply_text_trans (view ()->apply_text_trans ());
r.default_text_size (view ()->default_text_size ());
r.set_precise (true);
db::DCplxTrans t = vp.trans ();

View File

@ -40,6 +40,7 @@
#include "dbEdgePair.h"
#include "dbArray.h"
#include "gsi.h"
#include "gsiObject.h"
namespace lay
{
@ -61,6 +62,11 @@ public:
*/
MarkerBase (lay::LayoutViewBase *view);
/**
* @brief Attaches to a new view
*/
void set_view (lay::LayoutViewBase *view);
/**
* @brief Get the color by which the marker is drawn
*
@ -231,6 +237,11 @@ protected:
return mp_view;
}
const lay::LayoutViewBase *view () const
{
return mp_view;
}
private:
tl::Color m_color;
tl::Color m_frame_color;
@ -324,14 +335,6 @@ public:
return m_cv_index;
}
/**
* @brief Gets the view object
*/
lay::LayoutViewBase *view () const
{
return mp_view;
}
/**
* @brief Gets the bounding box
*/
@ -350,7 +353,6 @@ public:
private:
db::CplxTrans m_trans;
std::vector<db::DCplxTrans> *mp_trans_vector;
lay::LayoutViewBase *mp_view;
unsigned int m_cv_index;
/**
@ -827,8 +829,21 @@ private:
db::DText *text;
void *any;
} m_object;
};
lay::LayoutViewBase *mp_view;
/**
* @brief A managed version of the marker class
*
* It uses gsi::ObjectBase as a base class and serves as
* proxy for GSI binding.
*/
class ManagedDMarker
: public lay::DMarker, public gsi::ObjectBase
{
public:
ManagedDMarker (lay::LayoutViewBase *view)
: lay::DMarker (view)
{ }
};
}

View File

@ -118,12 +118,9 @@ BackgroundViewObject::z_order (int z)
// ViewObject implementation
ViewObject::ViewObject (ViewObjectUI *widget, bool _static)
: mp_widget (widget), m_static (_static), m_visible (true), m_dismissable (false)
: mp_widget (0), m_static (_static), m_visible (true), m_dismissable (false)
{
if (widget) {
widget->m_objects.push_back (this);
redraw ();
}
set_widget (widget);
}
ViewObject::~ViewObject ()
@ -131,6 +128,19 @@ ViewObject::~ViewObject ()
redraw ();
}
void
ViewObject::set_widget (ViewObjectUI *widget)
{
if (mp_widget) {
mp_widget->m_objects.erase (this);
}
mp_widget = widget;
if (widget) {
widget->m_objects.push_back (this);
redraw ();
}
}
void
ViewObject::set_dismissable (bool dismissable)
{
@ -535,6 +545,20 @@ ViewObjectUI::init_ui (QWidget *parent)
}
#endif
void
ViewObjectUI::add_object (lay::ViewObject *object)
{
object->set_widget (this);
m_owned_objects.push_back (object);
m_objects.push_back (object);
}
void
ViewObjectUI::clear_objects ()
{
m_owned_objects.clear ();
}
void
ViewObjectUI::register_service (lay::ViewService *svc)
{

View File

@ -439,6 +439,13 @@ public:
*/
virtual ~ViewObject ();
/**
* @brief Attaches a view object to a widget
*
* This will register the object at the widget, but not transfer ownership.
*/
void set_widget (ViewObjectUI *widget);
/**
* @brief Render the object on the planes provided by the canvas.
*
@ -785,6 +792,16 @@ public:
return m_objects.end ();
}
/**
* @brief Adds an object, transferring ownership to the view
*/
void add_object (lay::ViewObject *object);
/**
* @brief Clears all objects owned by the view
*/
void clear_objects ();
/**
* @brief Remaining leave event handler
*
@ -1073,6 +1090,7 @@ private:
QWidget *mp_widget;
#endif
tl::weak_collection<lay::ViewObject> m_objects;
tl::shared_collection<lay::ViewObject> m_owned_objects;
tl::weak_collection<lay::BackgroundViewObject> m_background_objects;
std::list<lay::ViewService *> m_services;
std::list<ViewService *> m_grabbed;

View File

@ -1440,7 +1440,8 @@ XORToolDialog::run_xor ()
}
XORJob job (nworkers, output_mode, op, el_handling, dbu, cva, cvb, tolerances, sub_categories, layer_categories, sub_cells, sub_output_layers, rdb, rdb_cell);
double common_dbu = tl::lcm (cva->layout ().dbu (), cvb->layout ().dbu ());
// NOTE: uses min of both DBUs (see issue #1743)
double common_dbu = std::min (cva->layout ().dbu (), cvb->layout ().dbu ());
for (std::vector<db::DBox>::const_iterator b = boxes.begin (); b != boxes.end (); ++b) {

View File

@ -66,7 +66,7 @@ class _PCellDeclarationHelperMixin:
self.layer = None
self.cell = None
def param(self, name, value_type, description, hidden = False, readonly = False, unit = None, default = None, choices = None, min_value = None, max_value = None):
def param(self, name, value_type, description, hidden = False, readonly = False, unit = None, default = None, choices = None, min_value = None, max_value = None, tooltip = None):
"""
Defines a parameter
name -> the short name of the parameter
@ -79,6 +79,7 @@ class _PCellDeclarationHelperMixin:
min_value -> the minimum value (only effective for numerical types and if no choices are present)
max_value -> the maximum value (only effective for numerical types and if no choices are present)
default -> the default value
tooltip -> tool tip text
choices -> ([ [ d, v ], ...) choice descriptions/value for choice type
this method defines accessor methods for the parameters
{name} -> read accessor
@ -104,6 +105,8 @@ class _PCellDeclarationHelperMixin:
pdecl.readonly = readonly
if not (default is None):
pdecl.default = default
if not (tooltip is None):
pdecl.tooltip = tooltip
pdecl.min_value = min_value
pdecl.max_value = max_value
if not (unit is None):

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,5 @@
from typing import Any, ClassVar, Dict, Sequence, List, Iterator, Optional
from typing import overload
from __future__ import annotations
import klayout.tl as tl
import klayout.db as db

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -22,6 +22,7 @@
#include "tlHttpStream.h"
#include "tlEnv.h"
namespace tl
{
@ -52,4 +53,22 @@ HttpErrorException::format_error (const std::string &em, int ec, const std::stri
return msg;
}
// ---------------------------------------------------------------
// Common implementation
double
InputHttpStream::get_default_timeout ()
{
// default timeout
double timeout_value = 10.0;
std::string timeout = tl::get_env ("KLAYOUT_HTTP_TIMEOUT");
if (! timeout.empty ()) {
tl::Extractor ex (timeout.c_str ());
ex.try_read (timeout_value);
}
return timeout_value;
}
}

View File

@ -98,6 +98,11 @@ public:
*/
virtual ~InputHttpStream ();
/**
* @brief Gets the timeout value (in seconds)
*/
static double get_default_timeout ();
/**
* @brief Sets the credential provider
*/

View File

@ -33,6 +33,7 @@
#include "tlProgress.h"
#include "tlFileUtils.h"
#include "tlUri.h"
#include "tlString.h"
#if !defined(_MSC_VER)
# include <sys/time.h>
@ -1282,7 +1283,7 @@ void CurlNetworkManager::tick ()
// InputHttpStreamPrivateData implementation
InputHttpStreamPrivateData::InputHttpStreamPrivateData (InputHttpStream *stream, const std::string &url)
: m_timeout (10.0), mp_stream (stream)
: m_timeout (InputHttpStream::get_default_timeout ()), mp_stream (stream)
{
m_sent = false;
m_ready = false;
@ -1391,7 +1392,13 @@ InputHttpStreamPrivateData::read (char *b, size_t n)
}
tl::Clock start_time = tl::Clock::current ();
while (n > m_connection->read_available () && ! m_connection->finished () && (m_timeout <= 0.0 || (tl::Clock::current() - start_time).seconds () < m_timeout) && ! tl::CurlNetworkManager::instance ()->has_reply ()) {
while (n > m_connection->read_available () && ! m_connection->finished () && ! tl::CurlNetworkManager::instance ()->has_reply ()) {
// Check for timeout
if (m_timeout > 0.0 && (tl::Clock::current() - start_time).seconds () >= m_timeout) {
throw tl::HttpErrorException (tl::sprintf (tl::to_string (tr ("Connection timed out (timeout is %.1fs)")), m_timeout), 0, m_connection->url ());
}
mp_stream->tick ();
if (m_progress.get ()) { // might have been reset by tick()
++*m_progress;

View File

@ -28,6 +28,7 @@
#include "tlObject.h"
#include "tlTimer.h"
#include "tlSleep.h"
#include "tlString.h"
#include <QNetworkAccessManager>
#include <QNetworkReply>
@ -256,7 +257,7 @@ static QNetworkAccessManager *s_network_manager (0);
static AuthenticationHandler *s_auth_handler (0);
InputHttpStreamPrivateData::InputHttpStreamPrivateData (InputHttpStream *stream, const std::string &url)
: m_url (url), mp_reply (0), m_request ("GET"), mp_buffer (0), mp_resend_timer (new QTimer (this)), m_timeout (10.0), mp_stream (stream)
: m_url (url), mp_reply (0), m_request ("GET"), mp_buffer (0), mp_resend_timer (new QTimer (this)), m_timeout (InputHttpStream::get_default_timeout ()), mp_stream (stream)
{
if (! s_network_manager) {
@ -466,7 +467,7 @@ InputHttpStreamPrivateData::read (char *b, size_t n)
// Reason for this may be HTTPS initialization failure (OpenSSL)
std::string em = tl::to_string (QObject::tr ("Request creation failed"));
std::string em = tl::sprintf (tl::to_string (QObject::tr ("Request creation failed (timeout is %.1fs)")), m_timeout);
if (tl::verbosity() >= 30) {
tl::info << "HTTP request creation failed";
}

View File

@ -25,6 +25,7 @@
#include "tlUnitTest.h"
#include "tlTimer.h"
#include "tlStream.h"
#include "tlEnv.h"
static std::string test_url1 ("http://www.klayout.org/svn-public/klayout-resources/trunk/testdata/text");
static std::string test_url1_gz ("http://www.klayout.org/svn-public/klayout-resources/trunk/testdata2/text.gz");
@ -153,3 +154,40 @@ TEST(5)
EXPECT_EQ (res, "hello, world.\n");
}
// tl::InputHttpStream timeout
TEST(6)
{
if (! tl::InputHttpStream::is_available ()) {
throw tl::CancelException ();
}
{
tl::set_env ("KLAYOUT_HTTP_TIMEOUT", "");
tl::InputHttpStream stream (test_url1);
stream.set_timeout (0.001); // probably too fast :)
try {
char b[100];
stream.read (b, sizeof (b));
EXPECT_EQ (true, false);
} catch (tl::HttpErrorException &ex) {
tl::info << "Got exception (expected): " << ex.msg ();
}
}
{
tl::set_env ("KLAYOUT_HTTP_TIMEOUT", "0.001");
tl::InputHttpStream stream (test_url1);
try {
char b[100];
stream.read (b, sizeof (b));
EXPECT_EQ (true, false);
} catch (tl::HttpErrorException &ex) {
tl::info << "Got exception (expected): " << ex.msg ();
}
}
tl::unset_env ("KLAYOUT_HTTP_TIMEOUT");
}

View File

@ -226,6 +226,8 @@ class DBPCellAPI_TestClass < TestBase
assert_equal(decl.description, "d")
decl.unit = "u"
assert_equal(decl.unit, "u")
decl.tooltip = "ttt"
assert_equal(decl.tooltip, "ttt")
decl.type = RBA::PCellParameterDeclaration::TypeBoolean
assert_equal(decl.type, RBA::PCellParameterDeclaration::TypeBoolean)
decl.default = true

View File

@ -77,6 +77,29 @@ class LAYMarkers_TestClass < TestBase
end
# persistent markers
def test_2
if !RBA.constants.member?(:Application)
return
end
app = RBA::Application.instance
mw = app.main_window
mw.create_layout(0)
cv = mw.current_view
m = RBA::Marker.new
m.set(RBA::DBox.new(1, 2, 3, 4))
m.vertex_size = 3
cv.add_marker(m)
cv.clear_markers
assert_equal(m.destroyed?, true)
end
end
load("test_epilogue.rb")