mirror of https://github.com/KLayout/klayout.git
WIP: debugging, first implementation of new templates
This commit is contained in:
parent
79102d399e
commit
8cbe5a2359
|
|
@ -89,7 +89,7 @@
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/up_16px.png</normaloff>:/up_16px.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
@ -103,7 +103,7 @@
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/add_16px.png</normaloff>:/add_16px.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
@ -117,7 +117,7 @@
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/del_16px.png</normaloff>:/del_16px.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
@ -131,7 +131,7 @@
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/down_16px.png</normaloff>:/down_16px.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
@ -833,6 +833,16 @@
|
|||
<string>Auto measure (points will be set automatically)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Angle measurement (three mouse clicks)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Multi-segment (finish with double click)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
|
|
@ -866,7 +876,7 @@
|
|||
<tabstop>t_snap_cbx</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../../lay/lay/layResources.qrc"/>
|
||||
<include location="../../icons/icons.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
|
|||
|
|
@ -239,6 +239,10 @@ RulerModeConverter::to_string (ant::Template::ruler_mode_type m)
|
|||
return "single_click";
|
||||
} else if (m == ant::Template::RulerAutoMetric) {
|
||||
return "auto_metric";
|
||||
} else if (m == ant::Template::RulerMultiSegment) {
|
||||
return "multi_segment";
|
||||
} else if (m == ant::Template::RulerAngle) {
|
||||
return "angle";
|
||||
} else {
|
||||
return "normal";
|
||||
}
|
||||
|
|
@ -254,6 +258,10 @@ RulerModeConverter::from_string (const std::string &s, ant::Template::ruler_mode
|
|||
a = ant::Template::RulerSingleClick;
|
||||
} else if (t == "auto_metric") {
|
||||
a = ant::Template::RulerAutoMetric;
|
||||
} else if (t == "multi_segment") {
|
||||
a = ant::Template::RulerMultiSegment;
|
||||
} else if (t == "angle") {
|
||||
a = ant::Template::RulerAngle;
|
||||
} else {
|
||||
a = ant::Template::RulerNormal;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -292,6 +292,14 @@ public:
|
|||
*/
|
||||
void set_points (const point_list &points);
|
||||
|
||||
/**
|
||||
* @brief Sets the ruler's definition points without cleaning
|
||||
*/
|
||||
void set_points_exact (const point_list &points)
|
||||
{
|
||||
m_points = points;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the first point of the indicated segment
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -68,12 +68,18 @@ static std::vector<ant::Template> make_standard_templates ()
|
|||
|
||||
templates.push_back (ant::Template (tl::to_string (tr ("Ruler")), "$X", "$Y", "$D", ant::Object::STY_ruler, ant::Object::OL_diag, true, lay::AC_Global, "_ruler"));
|
||||
|
||||
templates.push_back (ant::Template (tl::to_string (tr ("Multi-ruler")), "$X", "$Y", "$D", ant::Object::STY_ruler, ant::Object::OL_diag, true, lay::AC_Global, "_multi_ruler"));
|
||||
templates.back ().set_mode (ant::Template::RulerMultiSegment);
|
||||
|
||||
templates.push_back (ant::Template (tl::to_string (tr ("Cross")), "", "", "$U,$V", ant::Object::STY_cross_both, ant::Object::OL_diag, true, lay::AC_Global, "_cross"));
|
||||
templates.back ().set_mode (ant::Template::RulerSingleClick);
|
||||
|
||||
templates.push_back (ant::Template (tl::to_string (tr ("Measure")), "$X", "$Y", "$D", ant::Object::STY_ruler, ant::Object::OL_diag, true, lay::AC_Global, "_measure"));
|
||||
templates.back ().set_mode (ant::Template::RulerAutoMetric);
|
||||
|
||||
templates.push_back (ant::Template (tl::to_string (tr ("Angle")), "$X", "$Y", "$D", ant::Object::STY_line, ant::Object::OL_diag, true, lay::AC_Global, "_angle"));
|
||||
templates.back ().set_mode (ant::Template::RulerAngle);
|
||||
|
||||
templates.push_back (ant::Template (tl::to_string (tr ("Ellipse")), "W=$(abs(X))", "H=$(abs(Y))", "", ant::Object::STY_line, ant::Object::OL_ellipse, true, lay::AC_Global, std::string ()));
|
||||
|
||||
templates.push_back (ant::Template (tl::to_string (tr ("Box")), "W=$(abs(X))", "H=$(abs(Y))", "", ant::Object::STY_line, ant::Object::OL_box, true, lay::AC_Global, std::string ()));
|
||||
|
|
@ -197,14 +203,50 @@ PluginDeclaration::initialized (lay::Dispatcher *root)
|
|||
// Check if we already have templates (initial setup)
|
||||
// NOTE: this is not done by using a default value for the configuration item but dynamically.
|
||||
// This provides a migration path from earlier versions (not having templates) to recent ones.
|
||||
bool any_templates = false;
|
||||
for (std::vector<ant::Template>::iterator i = m_templates.begin (); ! any_templates && i != m_templates.end (); ++i) {
|
||||
any_templates = ! i->category ().empty ();
|
||||
std::map<std::string, const ant::Template *> cat_names;
|
||||
for (auto i = m_templates.begin (); i != m_templates.end (); ++i) {
|
||||
if (! i->category ().empty ()) {
|
||||
cat_names.insert (std::make_pair (i->category (), i.operator-> ()));
|
||||
}
|
||||
}
|
||||
|
||||
if (! any_templates) {
|
||||
bool any_missing = false;
|
||||
auto std_templates = make_standard_templates ();
|
||||
for (auto t = std_templates.begin (); ! any_missing && t != std_templates.end (); ++t) {
|
||||
if (! t->category ().empty () && cat_names.find (t->category ()) == cat_names.end ()) {
|
||||
any_missing = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (cat_names.empty ()) {
|
||||
|
||||
// full initial configuration
|
||||
root->config_set (cfg_ruler_templates, ant::TemplatesConverter ().to_string (make_standard_templates ()));
|
||||
root->config_end ();
|
||||
|
||||
} else if (any_missing) {
|
||||
|
||||
// some standard templates are missing - add them now (migration path for later versions)
|
||||
decltype (m_templates) new_templates;
|
||||
for (auto t = std_templates.begin (); t != std_templates.end (); ++t) {
|
||||
if (! t->category ().empty ()) {
|
||||
auto tt = cat_names.find (t->category ());
|
||||
if (tt != cat_names.end ()) {
|
||||
new_templates.push_back (*tt->second);
|
||||
} else {
|
||||
new_templates.push_back (*t);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto i = m_templates.begin (); i != m_templates.end (); ++i) {
|
||||
if (i->category ().empty ()) {
|
||||
new_templates.push_back (*i);
|
||||
}
|
||||
}
|
||||
|
||||
root->config_set (cfg_ruler_templates, ant::TemplatesConverter ().to_string (new_templates));
|
||||
root->config_end ();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1560,11 +1560,52 @@ Service::mouse_press_event (const db::DPoint &p, unsigned int buttons, bool prio
|
|||
return mouse_click_event (p, buttons, prio);
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
Service::finish_drawing ()
|
||||
{
|
||||
// create the ruler object
|
||||
|
||||
// begin the transaction
|
||||
if (manager ()) {
|
||||
tl_assert (! manager ()->transacting ());
|
||||
manager ()->transaction (tl::to_string (tr ("Create ruler")));
|
||||
}
|
||||
|
||||
show_message ();
|
||||
|
||||
insert_ruler (ant::Object (m_current.points (), 0, current_template ()), true);
|
||||
|
||||
// stop dragging
|
||||
drag_cancel ();
|
||||
clear_transient_selection ();
|
||||
|
||||
// end the transaction
|
||||
if (manager ()) {
|
||||
manager ()->commit ();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Service::mouse_double_click_event (const db::DPoint & /*p*/, unsigned int buttons, bool prio)
|
||||
{
|
||||
if (m_drawing && prio && (buttons & lay::LeftButton) != 0) {
|
||||
|
||||
// ends the current ruler (specifically in multi-segment mode)
|
||||
finish_drawing ();
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
Service::mouse_click_event (const db::DPoint &p, unsigned int buttons, bool prio)
|
||||
{
|
||||
if (prio && (buttons & lay::LeftButton) != 0) {
|
||||
|
||||
const ant::Template &tpl = current_template ();
|
||||
|
||||
if (! m_drawing) {
|
||||
|
||||
// cancel any edit operations so far
|
||||
|
|
@ -1577,8 +1618,6 @@ Service::mouse_click_event (const db::DPoint &p, unsigned int buttons, bool prio
|
|||
// and clear surplus rulers
|
||||
reduce_rulers (m_max_number_of_rulers - 1);
|
||||
|
||||
const ant::Template &tpl = current_template ();
|
||||
|
||||
// create and start dragging the ruler
|
||||
|
||||
if (tpl.mode () == ant::Template::RulerSingleClick) {
|
||||
|
|
@ -1648,7 +1687,13 @@ Service::mouse_click_event (const db::DPoint &p, unsigned int buttons, bool prio
|
|||
|
||||
m_p1 = snap1 (p, m_obj_snap && tpl.snap ()).second;
|
||||
|
||||
m_current = ant::Object (m_p1, m_p1, 0, tpl);
|
||||
// NOTE: generating the ruler this way makes sure we have two points
|
||||
ant::Object::point_list pts;
|
||||
m_current = ant::Object (pts, 0, tpl);
|
||||
pts.push_back (m_p1);
|
||||
pts.push_back (m_p1);
|
||||
m_current.set_points_exact (pts);
|
||||
|
||||
show_message ();
|
||||
|
||||
if (mp_active_ruler) {
|
||||
|
|
@ -1662,29 +1707,29 @@ Service::mouse_click_event (const db::DPoint &p, unsigned int buttons, bool prio
|
|||
|
||||
}
|
||||
|
||||
} else if (tpl.mode () == ant::Template::RulerMultiSegment || tpl.mode () == ant::Template::RulerAngle) {
|
||||
|
||||
ant::Object::point_list pts = m_current.points ();
|
||||
tl_assert (! pts.empty ());
|
||||
|
||||
if (tpl.mode () == ant::Template::RulerAngle && pts.size () == 3) {
|
||||
|
||||
finish_drawing ();
|
||||
|
||||
} else {
|
||||
|
||||
// add a new point
|
||||
m_p1 = pts.back ();
|
||||
|
||||
pts.push_back (m_p1);
|
||||
m_current.set_points_exact (pts);
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// create the ruler object
|
||||
finish_drawing ();
|
||||
|
||||
// begin the transaction
|
||||
if (manager ()) {
|
||||
tl_assert (! manager ()->transacting ());
|
||||
manager ()->transaction (tl::to_string (tr ("Create ruler")));
|
||||
}
|
||||
|
||||
show_message ();
|
||||
|
||||
insert_ruler (ant::Object (m_current.p1 (), m_current.p2 (), 0, current_template ()), true);
|
||||
|
||||
// stop dragging
|
||||
drag_cancel ();
|
||||
clear_transient_selection ();
|
||||
|
||||
// end the transaction
|
||||
if (manager ()) {
|
||||
manager ()->commit ();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -1731,7 +1776,14 @@ Service::mouse_move_event (const db::DPoint &p, unsigned int buttons, bool prio)
|
|||
|
||||
set_cursor (lay::Cursor::cross);
|
||||
|
||||
m_current.p2 (snap2 (m_p1, p, mp_active_ruler->ruler (), ac_from_buttons (buttons)).second);
|
||||
// NOTE: we use the direct access path so we do not encounter cleanup by the p1 and p2 setters
|
||||
// otherwise we risk manipulating p1 too.
|
||||
ant::Object::point_list pts = m_current.points ();
|
||||
if (! pts.empty ()) {
|
||||
pts.back () = snap2 (m_p1, p, mp_active_ruler->ruler (), ac_from_buttons (buttons)).second;
|
||||
}
|
||||
m_current.set_points_exact (pts);
|
||||
|
||||
mp_active_ruler->redraw ();
|
||||
show_message ();
|
||||
|
||||
|
|
|
|||
|
|
@ -566,6 +566,7 @@ private:
|
|||
virtual bool mouse_move_event (const db::DPoint &p, unsigned int buttons, bool prio);
|
||||
virtual bool mouse_press_event (const db::DPoint &p, unsigned int buttons, bool prio);
|
||||
virtual bool mouse_click_event (const db::DPoint &p, unsigned int buttons, bool prio);
|
||||
virtual bool mouse_double_click_event (const db::DPoint &p, unsigned int buttons, bool prio);
|
||||
virtual void deactivated ();
|
||||
|
||||
/**
|
||||
|
|
@ -585,6 +586,11 @@ private:
|
|||
*/
|
||||
void reduce_rulers (int num);
|
||||
|
||||
/**
|
||||
* @brief Finishes drawing mode and creates the ruler
|
||||
*/
|
||||
void finish_drawing ();
|
||||
|
||||
/**
|
||||
* @brief Delete the selected rulers
|
||||
*
|
||||
|
|
|
|||
|
|
@ -62,7 +62,17 @@ public:
|
|||
/**
|
||||
* @brief The ruler is auto-metric: a single click will place a ruler and the ruler will extend to the next adjacent structures
|
||||
*/
|
||||
RulerAutoMetric = 2
|
||||
RulerAutoMetric = 2,
|
||||
|
||||
/**
|
||||
* @brief The ruler an angle type (two segments, three mouse clicks) for angle and circle radius measurements
|
||||
*/
|
||||
RulerAngle = 3,
|
||||
|
||||
/**
|
||||
* @brief The ruler is a multi-segment type
|
||||
*/
|
||||
RulerMultiSegment = 4
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -432,6 +432,16 @@ static int ruler_mode_auto_metric ()
|
|||
return ant::Template::RulerAutoMetric;
|
||||
}
|
||||
|
||||
static int ruler_mode_angle ()
|
||||
{
|
||||
return ant::Template::RulerAngle;
|
||||
}
|
||||
|
||||
static int ruler_mode_multi_segment ()
|
||||
{
|
||||
return ant::Template::RulerMultiSegment;
|
||||
}
|
||||
|
||||
static void register_annotation_template (const ant::Object &a, const std::string &title, int mode)
|
||||
{
|
||||
ant::Template t = ant::Template::from_object (a, title, mode);
|
||||
|
|
@ -503,16 +513,28 @@ gsi::Class<AnnotationRef> decl_Annotation (decl_BasicAnnotation, "lay", "Annotat
|
|||
) +
|
||||
gsi::method ("RulerModeSingleClick", &gsi::ruler_mode_single_click,
|
||||
"@brief Specifies single-click ruler mode for the \\register_template method\n"
|
||||
"In single click-mode, a ruler can be placed with a single click and p1 will be == p2."
|
||||
"In single click-mode, a ruler can be placed with a single click and p1 will be == p2.\n"
|
||||
"\n"
|
||||
"This constant has been introduced in version 0.25"
|
||||
) +
|
||||
gsi::method ("RulerModeAutoMetric", &gsi::ruler_mode_auto_metric,
|
||||
"@brief Specifies auto-metric ruler mode for the \\register_template method\n"
|
||||
"In auto-metric mode, a ruler can be placed with a single click and p1/p2 will be determined from the neighborhood."
|
||||
"In auto-metric mode, a ruler can be placed with a single click and p1/p2 will be determined from the neighborhood.\n"
|
||||
"\n"
|
||||
"This constant has been introduced in version 0.25"
|
||||
) +
|
||||
gsi::method ("RulerAngle", &gsi::ruler_mode_angle,
|
||||
"@brief Specifies angle ruler mode for the \\register_template method\n"
|
||||
"In angle ruler mode, two segments are created for angle and circle radius measurements. Three mouse clicks are required.\n"
|
||||
"\n"
|
||||
"This constant has been introduced in version 0.28"
|
||||
) +
|
||||
gsi::method ("RulerMultiSegment", &gsi::ruler_mode_multi_segment,
|
||||
"@brief Specifies multi-segment mode\n"
|
||||
"In multi-segment mode, multiple segments can be created. The ruler is finished with a double click.\n"
|
||||
"\n"
|
||||
"This constant has been introduced in version 0.28"
|
||||
) +
|
||||
gsi::method ("StyleRuler|#style_ruler", &gsi::style_ruler,
|
||||
"@brief Gets the ruler style code for use the \\style method\n"
|
||||
"When this style is specified, the annotation will show a ruler with "
|
||||
|
|
|
|||
Loading…
Reference in New Issue