First implementation

This commit is contained in:
Matthias Koefferlein 2024-06-29 23:02:29 +02:00
parent 564861abe1
commit f9899efea3
5 changed files with 154 additions and 35 deletions

View File

@ -469,6 +469,20 @@ static LayerPropertiesConstIteratorWrapper each_layer2 (lay::LayoutViewBase *vie
return LayerPropertiesConstIteratorWrapper (view->begin_layers (list_index));
}
static void add_object (lay::LayoutViewBase *view, lay::ViewObject *object)
{
if (view->canvas ()) {
view->canvas ()->add_object (object);
}
}
static void clear_objects (lay::LayoutViewBase *view)
{
if (view->canvas ()) {
view->canvas ()->clear_objects ();
}
}
static lay::AbstractMenu *menu (lay::LayoutViewBase *view)
{
return view->menu ();
@ -679,6 +693,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_object, 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 exists 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_objects,
"@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 +874,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

@ -28,44 +28,56 @@
namespace gsi
{
/**
* @brief A managed version of the marker class
*/
class ManagedDMarker
: public lay::DMarker, public gsi::ObjectBase
{
public:
ManagedDMarker (lay::LayoutViewBase *view)
: lay::DMarker (view)
{ }
};
static
lay::DMarker *create_marker (lay::LayoutViewBase *view)
{
return new lay::DMarker (view);
return new ManagedDMarker (view);
}
static
void reset_frame_color (lay::DMarker *marker)
void reset_frame_color (ManagedDMarker *marker)
{
marker->set_frame_color (tl::Color ());
}
static
void set_frame_color (lay::DMarker *marker, unsigned int color)
void set_frame_color (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 ManagedDMarker *marker)
{
return marker->get_frame_color ().rgb ();
}
static
bool has_frame_color (const lay::DMarker *marker)
bool has_frame_color (const ManagedDMarker *marker)
{
return marker->get_frame_color ().is_valid ();
}
static
void reset_color (lay::DMarker *marker)
void reset_color (ManagedDMarker *marker)
{
marker->set_color (tl::Color ());
}
static
void set_color (lay::DMarker *marker, unsigned int color)
void set_color (ManagedDMarker *marker, unsigned int color)
{
marker->set_color (tl::Color (color));
}
@ -77,44 +89,48 @@ unsigned int get_color (const lay::DMarker *marker)
}
static
bool has_color (const lay::DMarker *marker)
bool has_color (const ManagedDMarker *marker)
{
return marker->get_color ().is_valid ();
}
Class<lay::DMarker> decl_Marker ("lay", "Marker",
gsi::constructor ("new", &create_marker, gsi::arg ("view"),
Class<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 (ManagedDMarker::*) (const db::DBox &)) &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 (ManagedDMarker::*) (const db::DText &)) &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 (ManagedDMarker::*) (const db::DEdge &)) &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 (ManagedDMarker::*) (const db::DPath &)) &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 (ManagedDMarker::*) (const db::DPolygon &)) &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 +172,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 (ManagedDMarker::*) (bool)) &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 (ManagedDMarker::*) () const) &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 (ManagedDMarker::*) (int)) &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 (ManagedDMarker::*) () const) &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 (ManagedDMarker::*) (int)) &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 (ManagedDMarker::*) () const) &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 (ManagedDMarker::*) (int)) &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 (ManagedDMarker::*) () const) &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 (ManagedDMarker::*) (int)) &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 (ManagedDMarker::*) () const) &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 (ManagedDMarker::*) (int)) &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 (ManagedDMarker::*) () const) &ManagedDMarker::get_line_style,
"@brief Get the line style\n"
"See \\line_style= for a description of the line style index."
"\n"
@ -219,6 +235,29 @@ 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 concept before 0.29.3:\n"
"\n"
"@code\n"
"view = ... # some LayoutView\n"
"marker = RBA::Marker::new(view)\n"
"@/code\n"
"\n"
"Persistent markers are attached to the view and stay within the view. To remove persistent markers, "
"use \\LayoutView#clear_markers or use \\_destroy on the 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."
);
}

View File

@ -197,7 +197,7 @@ 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 ..

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;