mirror of https://github.com/KLayout/klayout.git
Bugfix: instance selection cycling wasn't working
When instanced overlay, it wasn't possible to select the "other" instances. This is fixed. (reference: Trac 1015). In addition: - The instance selection now shows the label - Bugfix: the transient selection now really is disabled (it was popping up once after selection happened) - RBA::Marker#line_style has been added
This commit is contained in:
parent
1b0dcb5bf9
commit
cb296a802e
|
|
@ -932,11 +932,14 @@ Service::transient_select (const db::DPoint &pos)
|
|||
marker->set (inst, gt, tv);
|
||||
marker->set_line_width (1);
|
||||
marker->set_halo (0);
|
||||
marker->set_text_enabled (false);
|
||||
|
||||
mp_transient_marker = marker;
|
||||
|
||||
} else {
|
||||
|
||||
// In viewer mode, individual instances of arrays can be selected. Since that is not supported by
|
||||
// InstanceMarker, we just indicate the individual instance's bounding box.
|
||||
lay::Marker *marker = new lay::Marker (view (), r->cv_index ());
|
||||
db::box_convert<db::CellInst> bc (cv->layout ());
|
||||
marker->set (bc (r->back ().inst_ptr.cell_inst ().object ()), gt * r->back ().inst_ptr.cell_inst ().complex_trans (*r->back ().array_inst), tv);
|
||||
|
|
|
|||
|
|
@ -84,14 +84,14 @@ bool has_color (const lay::DMarker *marker)
|
|||
|
||||
Class<lay::DMarker> decl_Marker ("Marker",
|
||||
gsi::constructor ("new", &create_marker,
|
||||
"@brief The constructor for a marker\n"
|
||||
"@brief Creates a marker\n"
|
||||
"@args view\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."
|
||||
) +
|
||||
gsi::method ("set|set_box", (void (lay::DMarker::*) (const db::DBox &)) &lay::DMarker::set,
|
||||
"@brief Set the box the marker is to display\n"
|
||||
"@brief Sets the box the marker is to display\n"
|
||||
"@args box\n"
|
||||
"\n"
|
||||
"Makes the marker show a box. The box must be given in micron units.\n"
|
||||
|
|
@ -99,109 +99,122 @@ Class<lay::DMarker> decl_Marker ("Marker",
|
|||
"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,
|
||||
"@brief Set the text the marker is to display\n"
|
||||
"@brief Sets the text the marker is to display\n"
|
||||
"@args text\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,
|
||||
"@brief Set the edge the marker is to display\n"
|
||||
"@brief Sets the edge the marker is to display\n"
|
||||
"@args edge\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,
|
||||
"@brief Set the path the marker is to display\n"
|
||||
"@brief Sets the path the marker is to display\n"
|
||||
"@args path\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,
|
||||
"@brief Set the polygon the marker is to display\n"
|
||||
"@brief Sets the polygon the marker is to display\n"
|
||||
"@args polygon\n"
|
||||
"\n"
|
||||
"Makes the marker show a polygon. The polygon must be given in micron units.\n"
|
||||
"The set method has been added in version 0.20.\n"
|
||||
) +
|
||||
gsi::method_ext ("color=", set_color,
|
||||
"@brief Set the color of the marker\n"
|
||||
"@brief Sets the color of the marker\n"
|
||||
"@args color\n"
|
||||
"The color is a 32bit unsigned integer encoding the RGB values in the lower 3 bytes (blue in the lowest significant byte). "
|
||||
"The color can be reset with \\reset_color, in which case, the default foreground color is used."
|
||||
) +
|
||||
gsi::method_ext ("reset_color", reset_color,
|
||||
"@brief Reset the color of the marker\n"
|
||||
"@brief Resets the color of the marker\n"
|
||||
"See \\set_color for a description of the color property of the marker."
|
||||
) +
|
||||
gsi::method_ext ("color", get_color,
|
||||
"@brief Get the color of the marker\n"
|
||||
"@brief Gets the color of the marker\n"
|
||||
"This value is valid only if \\has_color? is true."
|
||||
) +
|
||||
gsi::method_ext ("has_color?", has_color,
|
||||
"@brief True, if the marker has a specific color\n"
|
||||
"@brief Returns a value indicating whether the marker has a specific color\n"
|
||||
) +
|
||||
gsi::method_ext ("frame_color=", set_frame_color,
|
||||
"@brief Set the frame color of the marker\n"
|
||||
"@brief Sets the frame color of the marker\n"
|
||||
"@args color\n"
|
||||
"The color is a 32bit unsigned integer encoding the RGB values in the lower 3 bytes (blue in the lowest significant byte). "
|
||||
"The color can be reset with \\reset_frame_color, in which case the fill color is used.\n"
|
||||
"The set method has been added in version 0.20.\n"
|
||||
) +
|
||||
gsi::method_ext ("reset_frame_color", reset_frame_color,
|
||||
"@brief Reset the frame color of the marker\n"
|
||||
"@brief Resets the frame color of the marker\n"
|
||||
"See \\set_frame_color for a description of the frame color property of the marker."
|
||||
"The set method has been added in version 0.20.\n"
|
||||
) +
|
||||
gsi::method_ext ("frame_color", get_frame_color,
|
||||
"@brief Get the frame color of the marker\n"
|
||||
"@brief Gets the frame color of the marker\n"
|
||||
"This value is valid only if \\has_frame_color? is true."
|
||||
"The set method has been added in version 0.20.\n"
|
||||
) +
|
||||
gsi::method_ext ("has_frame_color?", has_frame_color,
|
||||
"@brief True, if the marker has a specific frame color\n"
|
||||
"@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 ("line_width=", &lay::DMarker::set_line_width,
|
||||
"@brief Set the line width of the marker\n"
|
||||
"@brief Sets the line width of the marker\n"
|
||||
"@args width\n"
|
||||
"This is the width of the line drawn for the outline of the marker."
|
||||
) +
|
||||
gsi::method ("line_width", &lay::DMarker::get_line_width,
|
||||
"@brief Get the line width of the marker\n"
|
||||
"@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,
|
||||
"@brief Set the vertex size of the marker\n"
|
||||
"@brief Sets the vertex size of the marker\n"
|
||||
"@args size\n"
|
||||
"This is the size of the rectangles drawn for the vertices object."
|
||||
) +
|
||||
gsi::method ("vertex_size", &lay::DMarker::get_vertex_size,
|
||||
"@brief Get the vertex size of the marker\n"
|
||||
"@brief Gets the vertex size of the marker\n"
|
||||
"See \\vertex_size= for a description."
|
||||
) +
|
||||
gsi::method ("halo=", &lay::DMarker::set_halo,
|
||||
"@brief Set the halo flag\n"
|
||||
"@brief Sets the halo flag\n"
|
||||
"@args halo\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,
|
||||
"@brief Get the halo flag\n"
|
||||
"@brief Gets the halo flag\n"
|
||||
"See \\halo= for a description of the halo flag."
|
||||
) +
|
||||
gsi::method ("dither_pattern=", &lay::DMarker::set_dither_pattern,
|
||||
"@brief Set the stipple pattern index\n"
|
||||
"@brief Sets the stipple pattern index\n"
|
||||
"@args 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,
|
||||
"@brief Get the stipple pattern index\n"
|
||||
"@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,
|
||||
"@brief Sets the line style\n"
|
||||
"@args index\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,
|
||||
"@brief Get the line style\n"
|
||||
"See \\line_style= for a description of the line style index."
|
||||
"\n"
|
||||
"This method has been introduced in version 0.25."
|
||||
),
|
||||
"@brief The floating-point coordinate marker object\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -205,8 +205,6 @@ Editables::transient_select (const db::DPoint &pt)
|
|||
clear_previous_selection ();
|
||||
}
|
||||
|
||||
m_last_selected_point = db::DBox (pt, pt);
|
||||
|
||||
// in a first pass evaluate the point selection proximity value to select
|
||||
// those plugins that are active. This code is a copy of the code for the single-point selection below.
|
||||
|
||||
|
|
@ -257,6 +255,8 @@ Editables::transient_select (const db::DPoint &pt)
|
|||
|
||||
}
|
||||
|
||||
m_last_selected_point = db::DBox (pt, pt);
|
||||
|
||||
// send a signal to the observers
|
||||
signal_transient_selection_changed ();
|
||||
}
|
||||
|
|
@ -343,8 +343,6 @@ Editables::select (const db::DPoint &pt, lay::Editable::SelectionMode mode)
|
|||
clear_previous_selection ();
|
||||
}
|
||||
|
||||
m_last_selected_point = db::DBox (pt, pt);
|
||||
|
||||
cancel_edits ();
|
||||
clear_transient_selection ();
|
||||
|
||||
|
|
@ -404,6 +402,8 @@ Editables::select (const db::DPoint &pt, lay::Editable::SelectionMode mode)
|
|||
}
|
||||
}
|
||||
|
||||
m_last_selected_point = db::DBox (pt, pt);
|
||||
|
||||
// send a signal to the observers
|
||||
signal_selection_changed ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -844,27 +844,6 @@ InstFinder::visit_cell (const db::Cell &cell, const db::Box &search_box, const d
|
|||
|
||||
d += 1; // the instance has a small penalty so that shapes win over instances
|
||||
|
||||
if (match && closer (d)) {
|
||||
|
||||
// in point mode just store that found that has the least "distance"
|
||||
if (m_founds.empty ()) {
|
||||
m_founds.push_back (lay::ObjectInstPath ());
|
||||
}
|
||||
|
||||
m_founds.back ().set_cv_index (m_cv_index);
|
||||
m_founds.back ().set_topcell (m_topcell);
|
||||
m_founds.back ().assign_path (path ().begin (), path ().end ());
|
||||
|
||||
// add the selected instance as the last element of the path
|
||||
db::InstElement el;
|
||||
el.inst_ptr = *inst;
|
||||
if (! m_full_arrays) {
|
||||
el.array_inst = p;
|
||||
}
|
||||
m_founds.back ().add_path (el);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (match) {
|
||||
|
|
|
|||
|
|
@ -39,11 +39,12 @@ namespace lay
|
|||
|
||||
void render_cell_inst (const db::Layout &layout, const db::CellInstArray &inst, const db::CplxTrans &tr, lay::Renderer &r,
|
||||
unsigned int font, lay::CanvasPlane *fill, lay::CanvasPlane *contour, lay::CanvasPlane *vertex, lay::CanvasPlane *text,
|
||||
bool draw_outline, size_t max_shapes)
|
||||
bool cell_name_text_transform, int min_size_for_label, bool draw_outline, size_t max_shapes)
|
||||
{
|
||||
bool render_origins = false;
|
||||
|
||||
const db::Cell &cell = layout.cell (inst.object ().cell_index ());
|
||||
std::string cell_name = layout.cell_name (inst.object ().cell_index ());
|
||||
db::Box cell_box = cell.bbox ();
|
||||
|
||||
db::Vector a, b;
|
||||
|
|
@ -103,12 +104,30 @@ void render_cell_inst (const db::Layout &layout, const db::CellInstArray &inst,
|
|||
|
||||
db::DBox arr_box (db::DPoint (), db::DPoint () + tr * (av * long (amax - 1) + bv * long (bmax - 1)));
|
||||
arr_box *= cb;
|
||||
r.draw (arr_box, tl::sprintf (tl::to_string (QObject::tr ("Array %ldx%ld")), amax, bmax), (db::Font) font, db::HAlignCenter, db::VAlignCenter, db::DFTrans (db::DFTrans::r0), 0, 0, 0, text);
|
||||
r.draw (arr_box, tl::sprintf (tl::to_string (QObject::tr ("Array %ldx%ld")), amax, bmax), db::Font (font), db::HAlignCenter, db::VAlignCenter, db::DFTrans (db::DFTrans::r0), 0, 0, 0, text);
|
||||
|
||||
} else {
|
||||
|
||||
for (db::CellInstArray::iterator arr = inst.begin (); ! arr.at_end (); ++arr) {
|
||||
r.draw (cell_box, tr * inst.complex_trans (*arr), fill, contour, 0, text);
|
||||
|
||||
// fallback to simpler representation using a description text
|
||||
db::CplxTrans tbox (tr * inst.complex_trans ());
|
||||
|
||||
r.draw (cell_box, tbox, fill, contour, 0, 0);
|
||||
|
||||
db::DBox dbox = tbox * cell_box;
|
||||
if (! cell_name.empty () && dbox.width () > min_size_for_label && dbox.height () > min_size_for_label) {
|
||||
|
||||
// Hint: we render to contour because the texts plane is reserved for properties
|
||||
r.draw (dbox, cell_name,
|
||||
db::Font (font),
|
||||
db::HAlignCenter,
|
||||
db::VAlignCenter,
|
||||
// TODO: apply "real" transformation?
|
||||
db::DFTrans (cell_name_text_transform ? tbox.fp_trans ().rot () : db::DFTrans::r0), 0, 0, 0, text);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
render_origins = true;
|
||||
|
|
@ -154,7 +173,7 @@ void render_cell_inst (const db::Layout &layout, const db::CellInstArray &inst,
|
|||
|
||||
MarkerBase::MarkerBase (lay::LayoutView *view)
|
||||
: lay::ViewObject (view->view_object_widget ()),
|
||||
m_line_width (-1), m_vertex_size (-1), m_halo (-1), m_vertex_shape (lay::ViewOp::Rect), m_line_style (-1), m_dither_pattern (-1), m_frame_pattern (0), mp_view (view)
|
||||
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 ..
|
||||
}
|
||||
|
|
@ -213,7 +232,16 @@ MarkerBase::set_halo (int halo)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
MarkerBase::set_text_enabled (bool en)
|
||||
{
|
||||
if (m_text_enabled != en) {
|
||||
m_text_enabled = en;
|
||||
redraw ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MarkerBase::set_frame_pattern (int frame_pattern)
|
||||
{
|
||||
if (m_frame_pattern != frame_pattern) {
|
||||
|
|
@ -283,7 +311,9 @@ MarkerBase::get_bitmaps (const Viewport & /*vp*/, ViewObjectCanvas &canvas, lay:
|
|||
ops[1] = lay::ViewOp (frame_color.rgb (), lay::ViewOp::Copy, (unsigned int) line_style, (unsigned int) m_frame_pattern, 0, lay::ViewOp::Rect, line_width * basic_width, 1);
|
||||
contour = canvas.plane (ops);
|
||||
|
||||
if (line_width == 1) {
|
||||
if (! m_text_enabled) {
|
||||
text = 0;
|
||||
} else if (line_width == 1) {
|
||||
text = contour;
|
||||
} else {
|
||||
ops[0] = lay::ViewOp (canvas.background_color ().rgb (), lay::ViewOp::Copy, 0, 0, 0, lay::ViewOp::Rect, 3 * basic_width, 0);
|
||||
|
|
@ -312,7 +342,9 @@ MarkerBase::get_bitmaps (const Viewport & /*vp*/, ViewObjectCanvas &canvas, lay:
|
|||
|
||||
contour = canvas.plane (lay::ViewOp (frame_color.rgb (), lay::ViewOp::Copy, (unsigned int) line_style, (unsigned int) m_frame_pattern, 0, lay::ViewOp::Rect, line_width * basic_width));
|
||||
vertex = canvas.plane (lay::ViewOp (frame_color.rgb (), lay::ViewOp::Copy, 0, 0, 0, m_vertex_shape, vertex_size * basic_width));
|
||||
if (line_width == 1) {
|
||||
if (! m_text_enabled) {
|
||||
text = 0;
|
||||
} else if (line_width == 1) {
|
||||
text = contour;
|
||||
} else {
|
||||
text = canvas.plane (lay::ViewOp (frame_color.rgb (), lay::ViewOp::Copy, 0, 0, 0, lay::ViewOp::Rect, basic_width));
|
||||
|
|
@ -487,19 +519,16 @@ InstanceMarker::render (const Viewport &vp, ViewObjectCanvas &canvas)
|
|||
}
|
||||
|
||||
lay::Renderer &r = canvas.renderer ();
|
||||
|
||||
r.set_font (db::Font (view ()->text_font ()));
|
||||
r.apply_text_trans (view ()->apply_text_trans ());
|
||||
r.default_text_size (db::Coord (view ()->default_text_size () / ly->dbu ()));
|
||||
r.set_precise (true);
|
||||
bool label_transform = view ()->cell_box_text_transform ();
|
||||
int min_size = view ()->min_inst_label_size ();
|
||||
|
||||
db::box_convert<db::CellInst> bc (*ly);
|
||||
|
||||
if (! trans_vector ()) {
|
||||
render_cell_inst (*ly, m_inst.cell_inst (), vp.trans () * trans (), r, view ()->cell_box_text_font (), fill, contour, vertex, text, m_draw_outline, m_max_shapes);
|
||||
render_cell_inst (*ly, m_inst.cell_inst (), vp.trans () * trans (), r, view ()->cell_box_text_font (), fill, contour, vertex, text, label_transform, min_size, m_draw_outline, m_max_shapes);
|
||||
} else {
|
||||
for (std::vector<db::DCplxTrans>::const_iterator tr = trans_vector ()->begin (); tr != trans_vector ()->end (); ++tr) {
|
||||
render_cell_inst (*ly, m_inst.cell_inst (), vp.trans () * *tr * trans (), r, view ()->cell_box_text_font (), fill, contour, vertex, text, m_draw_outline, m_max_shapes);
|
||||
render_cell_inst (*ly, m_inst.cell_inst (), vp.trans () * *tr * trans (), r, view ()->cell_box_text_font (), fill, contour, vertex, text, label_transform, min_size, m_draw_outline, m_max_shapes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1026,7 +1055,9 @@ Marker::draw (lay::Renderer &r, const db::CplxTrans &t, lay::CanvasPlane *fill,
|
|||
r.draw (poly, db::DCplxTrans (t), fill, 0, 0, 0);
|
||||
} else if (m_type == Instance) {
|
||||
const lay::CellView &cv = view ()->cellview (cv_index ());
|
||||
render_cell_inst (cv->layout (), *m_object.inst, t, r, view ()->cell_box_text_font (), fill, contour, vertex, text, m_draw_outline, m_max_shapes);
|
||||
bool label_transform = view ()->cell_box_text_transform ();
|
||||
int min_size = view ()->min_inst_label_size ();
|
||||
render_cell_inst (cv->layout (), *m_object.inst, t, r, view ()->cell_box_text_font (), fill, contour, vertex, text, label_transform, min_size, m_draw_outline, m_max_shapes);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -204,6 +204,22 @@ public:
|
|||
*/
|
||||
void set_halo (int halo);
|
||||
|
||||
/**
|
||||
* @brief Gets a value indicating whether text drawing is enabled
|
||||
*
|
||||
* If this value is false, texts are never drawn. If true (the default), texts are drawn as usual.
|
||||
* This is specifically useful for disabling cell boxes of instances.
|
||||
*/
|
||||
bool is_text_enabled () const
|
||||
{
|
||||
return m_text_enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a value indicating whether text drawing is enabled
|
||||
*/
|
||||
void set_text_enabled (bool en);
|
||||
|
||||
/**
|
||||
* @brief Gets the bounding box
|
||||
*/
|
||||
|
|
@ -215,6 +231,7 @@ protected:
|
|||
QColor m_color;
|
||||
QColor m_frame_color;
|
||||
char m_line_width, m_vertex_size, m_halo;
|
||||
bool m_text_enabled;
|
||||
lay::ViewOp::Shape m_vertex_shape;
|
||||
int m_line_style, m_dither_pattern, m_frame_pattern;
|
||||
lay::LayoutView *mp_view;
|
||||
|
|
|
|||
|
|
@ -188,9 +188,12 @@ SelectionService::mouse_click_event (const db::DPoint &p, unsigned int buttons,
|
|||
|
||||
mp_view->select (p, mode);
|
||||
|
||||
m_hover_wait = true;
|
||||
m_timer.start ();
|
||||
m_hover_point = p;
|
||||
// add a transient selection trigger to capture the "next" selection.
|
||||
if (mp_view->transient_selection_mode ()) {
|
||||
m_hover_wait = true;
|
||||
m_timer.start ();
|
||||
m_hover_point = p;
|
||||
}
|
||||
|
||||
} catch (tl::Exception &ex) {
|
||||
tl::error << ex.msg ();
|
||||
|
|
|
|||
Loading…
Reference in New Issue