diff --git a/src/ant/ant/RulerConfigPage4.ui b/src/ant/ant/RulerConfigPage4.ui index 649d18d44..7e2c2365c 100644 --- a/src/ant/ant/RulerConfigPage4.ui +++ b/src/ant/ant/RulerConfigPage4.ui @@ -574,6 +574,16 @@ Ellipse + + + Angle measurement + + + + + Radius measurement + + diff --git a/src/ant/ant/RulerPropertiesPage.ui b/src/ant/ant/RulerPropertiesPage.ui index 567287ddc..28451b680 100644 --- a/src/ant/ant/RulerPropertiesPage.ui +++ b/src/ant/ant/RulerPropertiesPage.ui @@ -352,6 +352,16 @@ Ellipse + + + Angle measurement + + + + + Radius measurement + + diff --git a/src/ant/ant/antConfig.cc b/src/ant/ant/antConfig.cc index 250945a98..ed5230023 100644 --- a/src/ant/ant/antConfig.cc +++ b/src/ant/ant/antConfig.cc @@ -136,6 +136,10 @@ OutlineConverter::to_string (ant::Object::outline_type o) return "box"; } else if (o == ant::Object::OL_ellipse) { return "ellipse"; + } else if (o == ant::Object::OL_radius) { + return "radius"; + } else if (o == ant::Object::OL_angle) { + return "angle"; } else { return ""; } @@ -159,6 +163,10 @@ OutlineConverter::from_string (const std::string &s, ant::Object::outline_type & o = ant::Object::OL_box; } else if (t == "ellipse") { o = ant::Object::OL_ellipse; + } else if (t == "radius") { + o = ant::Object::OL_radius; + } else if (t == "angle") { + o = ant::Object::OL_angle; } else { o = ant::Object::OL_diag; } @@ -241,7 +249,7 @@ RulerModeConverter::to_string (ant::Template::ruler_mode_type m) return "auto_metric"; } else if (m == ant::Template::RulerMultiSegment) { return "multi_segment"; - } else if (m == ant::Template::RulerAngle) { + } else if (m == ant::Template::RulerThreeClicks) { return "angle"; } else { return "normal"; @@ -261,7 +269,7 @@ RulerModeConverter::from_string (const std::string &s, ant::Template::ruler_mode } else if (t == "multi_segment") { a = ant::Template::RulerMultiSegment; } else if (t == "angle") { - a = ant::Template::RulerAngle; + a = ant::Template::RulerThreeClicks; } else { a = ant::Template::RulerNormal; } diff --git a/src/ant/ant/antObject.h b/src/ant/ant/antObject.h index 6fd478c7a..e225ce593 100644 --- a/src/ant/ant/antObject.h +++ b/src/ant/ant/antObject.h @@ -77,8 +77,10 @@ public: * OL_diag_yx: both OL_diag and OL_yx * OL_box: draw a box defined by start and end point * OL_ellipse: draws an ellipse with p1 and p2 defining the extension (style is ignored) + * OL_angle: an angle measurement ruler (first vs. last segment) + * OL_radius: a radius measurement ruler */ - enum outline_type { OL_diag = 0, OL_xy = 1, OL_diag_xy = 2, OL_yx = 3, OL_diag_yx = 4, OL_box = 5, OL_ellipse = 6 }; + enum outline_type { OL_diag = 0, OL_xy = 1, OL_diag_xy = 2, OL_yx = 3, OL_diag_yx = 4, OL_box = 5, OL_ellipse = 6, OL_angle = 7, OL_radius = 8 }; /** * @brief The position type of the main label diff --git a/src/ant/ant/antPlugin.cc b/src/ant/ant/antPlugin.cc index 74918b24c..7175b11c9 100644 --- a/src/ant/ant/antPlugin.cc +++ b/src/ant/ant/antPlugin.cc @@ -77,8 +77,11 @@ static std::vector make_standard_templates () 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 ("Angle")), "$X", "$Y", "$D", ant::Object::STY_line, ant::Object::OL_angle, true, lay::AC_Global, "_angle")); + templates.back ().set_mode (ant::Template::RulerThreeClicks); + + templates.push_back (ant::Template (tl::to_string (tr ("Radius")), "$X", "$Y", "$D", ant::Object::STY_line, ant::Object::OL_radius, true, lay::AC_Global, "_radius")); + templates.back ().set_mode (ant::Template::RulerThreeClicks); 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 ())); diff --git a/src/ant/ant/antService.cc b/src/ant/ant/antService.cc index ffcf88a06..cee1d246e 100644 --- a/src/ant/ant/antService.cc +++ b/src/ant/ant/antService.cc @@ -503,9 +503,12 @@ draw_text (const db::DPoint &q1, * * @param q1 The first point in pixel space * @param q2 The second point in pixel space + * @param length_u The "typical dimension" - used to simplify for very small ellipses * @param sel True to draw ruler in "selected" mode * @param bitmap The bitmap to draw the ruler on * @param renderer The renderer object + * @param start_angle The starting angle (in radians) + * @param stop_angle The stop angle (in radians) */ void draw_ellipse (const db::DPoint &q1, @@ -513,7 +516,9 @@ draw_ellipse (const db::DPoint &q1, double length_u, bool sel, lay::CanvasPlane *bitmap, - lay::Renderer &renderer) + lay::Renderer &renderer, + double start_angle = 0.0, + double stop_angle = 2.0 * M_PI) { double sel_width = 2 / renderer.resolution (); @@ -532,7 +537,7 @@ draw_ellipse (const db::DPoint &q1, } else { - int npoints = 200; + int npoints = int (floor (200 * abs (stop_angle - start_angle) / (2.0 * M_PI))); // produce polygon stuff @@ -540,43 +545,29 @@ draw_ellipse (const db::DPoint &q1, double ry = fabs ((q2 - q1).y () * 0.5); db::DPoint c = q1 + (q2 - q1) * 0.5; - db::DPolygon p; - - std::vector pts; - pts.reserve (npoints); - if (sel) { rx += sel_width * 0.5; ry += sel_width * 0.5; } - double da = M_PI * 2.0 / double (npoints); - for (int i = 0; i < npoints; ++i) { - double a = da * i; + std::vector pts; + pts.reserve (npoints + 1); + + double da = fabs (stop_angle - start_angle) / double (npoints); + for (int i = 0; i < npoints + 1; ++i) { + double a = da * i + start_angle; pts.push_back (c + db::DVector (rx * cos (a), ry * sin (a))); } - p.assign_hull (pts.begin (), pts.end ()); - if (sel) { - pts.clear (); - - rx -= sel_width; - ry -= sel_width; - for (int i = 0; i < npoints; ++i) { - double a = da * i; - pts.push_back (c + db::DVector (rx * cos (a), ry * sin (a))); - } - - p.insert_hole (pts.begin (), pts.end ()); - + db::DPath p (pts.begin (), pts.end (), sel_width); renderer.draw (p, bitmap, bitmap, 0, 0); } else { - for (db::DPolygon::polygon_edge_iterator e = p.begin_edge (); ! e.at_end (); ++e) { - renderer.draw (*e, 0, bitmap, 0, 0); + for (size_t i = 0; i + 1 < pts.size (); ++i) { + renderer.draw (db::DEdge (pts [i], pts [i + 1]), 0, bitmap, 0, 0); } } @@ -639,52 +630,236 @@ draw_ruler_segment (const ant::Object &ruler, size_t index, const db::DCplxTrans draw_text (db::DPoint (q1.x (), q2.y ()), q2, lu, ruler.text_x (index, trans.fp_trans ()), r, ruler.style (), ant::Object::POS_center, ruler.xlabel_xalign (), ruler.xlabel_yalign (), bitmap, renderer); } +} - if (ruler.outline () == Object::OL_box) { +void +draw_ruler_box (const ant::Object &ruler, const db::DCplxTrans &trans, bool sel, lay::CanvasPlane *bitmap, lay::Renderer &renderer) +{ + db::DPoint p1 = ruler.p1 (), p2 = ruler.p2 (); - bool r = (q2.x () > q1.x ()) ^ (q2.y () < q1.y ()); + // round the starting point, shift both, and round the end point + std::pair v = lay::snap (trans * p1, trans * p2); + db::DPoint q1 = v.first; + db::DPoint q2 = v.second; - draw_ruler (q1, db::DPoint (q2.x (), q1.y ()), lu, mu, sel, r, ruler.style (), bitmap, renderer, true, true); - draw_text (q1, db::DPoint (q2.x (), q1.y ()), lu, ruler.text_x (index, trans.fp_trans ()), r, ruler.style (), ant::Object::POS_center, ruler.xlabel_xalign (), ruler.xlabel_yalign (), bitmap, renderer); - draw_ruler (db::DPoint (q2.x (), q1.y ()), q2, lu, mu, sel, r, ruler.style (), bitmap, renderer, true, true); - draw_text (db::DPoint (q2.x (), q1.y ()), q2, lu, ruler.text_y (index, trans.fp_trans ()), r, ruler.style (), ant::Object::POS_center, ruler.ylabel_xalign (), ruler.ylabel_yalign (), bitmap, renderer); - draw_ruler (q1, db::DPoint (q1.x (), q2.y ()), lu, mu, sel, !r, ruler.style (), bitmap, renderer, true, true); - draw_ruler (db::DPoint (q1.x (), q2.y ()), q2, lu, mu, sel, !r, ruler.style (), bitmap, renderer, true, true); - draw_text (q1, q2, lu, ruler.text (index), !r, ant::Object::STY_none, ruler.main_position (), ruler.main_xalign (), ruler.main_yalign (), bitmap, renderer); + double lu = p1.double_distance (p2); + int min_tick_spc = int (0.5 + 20 / renderer.resolution ()); // min tick spacing in canvas units + double mu = double (min_tick_spc) / trans.ctrans (1.0); - } else if (ruler.outline () == Object::OL_ellipse) { + bool r = (q2.x () > q1.x ()) ^ (q2.y () < q1.y ()); - bool r = (q2.x () > q1.x ()) ^ (q2.y () < q1.y ()); + size_t index = std::numeric_limits::max (); + draw_ruler (q1, db::DPoint (q2.x (), q1.y ()), lu, mu, sel, r, ruler.style (), bitmap, renderer, true, true); + draw_text (q1, db::DPoint (q2.x (), q1.y ()), lu, ruler.text_x (index, trans.fp_trans ()), r, ruler.style (), ant::Object::POS_center, ruler.xlabel_xalign (), ruler.xlabel_yalign (), bitmap, renderer); + draw_ruler (db::DPoint (q2.x (), q1.y ()), q2, lu, mu, sel, r, ruler.style (), bitmap, renderer, true, true); + draw_text (db::DPoint (q2.x (), q1.y ()), q2, lu, ruler.text_y (index, trans.fp_trans ()), r, ruler.style (), ant::Object::POS_center, ruler.ylabel_xalign (), ruler.ylabel_yalign (), bitmap, renderer); + draw_ruler (q1, db::DPoint (q1.x (), q2.y ()), lu, mu, sel, !r, ruler.style (), bitmap, renderer, true, true); + draw_ruler (db::DPoint (q1.x (), q2.y ()), q2, lu, mu, sel, !r, ruler.style (), bitmap, renderer, true, true); + draw_text (q1, q2, lu, ruler.text (index), !r, ant::Object::STY_none, ruler.main_position (), ruler.main_xalign (), ruler.main_yalign (), bitmap, renderer); +} - draw_text (q1, db::DPoint (q2.x (), q1.y ()), lu, ruler.text_x (index, trans.fp_trans ()), r, ant::Object::STY_none, ant::Object::POS_center, ruler.xlabel_xalign (), ruler.xlabel_yalign (), bitmap, renderer); - draw_text (db::DPoint (q2.x (), q1.y ()), q2, lu, ruler.text_y (index, trans.fp_trans ()), r, ant::Object::STY_none, ant::Object::POS_center, ruler.ylabel_xalign (), ruler.ylabel_yalign (), bitmap, renderer); - draw_text (q1, q2, lu, ruler.text (index), !r, ant::Object::STY_none, ruler.main_position (), ruler.main_xalign (), ruler.main_yalign (), bitmap, renderer); +void +draw_ruler_ellipse (const ant::Object &ruler, const db::DCplxTrans &trans, bool sel, lay::CanvasPlane *bitmap, lay::Renderer &renderer) +{ + db::DPoint p1 = ruler.p1 (), p2 = ruler.p2 (); - draw_ellipse (q1, q2, lu, sel, bitmap, renderer); + // round the starting point, shift both, and round the end point + std::pair v = lay::snap (trans * p1, trans * p2); + db::DPoint q1 = v.first; + db::DPoint q2 = v.second; + + double lu = p1.double_distance (p2); + + bool r = (q2.x () > q1.x ()) ^ (q2.y () < q1.y ()); + + size_t index = std::numeric_limits::max (); + draw_text (q1, db::DPoint (q2.x (), q1.y ()), lu, ruler.text_x (index, trans.fp_trans ()), r, ant::Object::STY_none, ant::Object::POS_center, ruler.xlabel_xalign (), ruler.xlabel_yalign (), bitmap, renderer); + draw_text (db::DPoint (q2.x (), q1.y ()), q2, lu, ruler.text_y (index, trans.fp_trans ()), r, ant::Object::STY_none, ant::Object::POS_center, ruler.ylabel_xalign (), ruler.ylabel_yalign (), bitmap, renderer); + draw_text (q1, q2, lu, ruler.text (index), !r, ant::Object::STY_none, ruler.main_position (), ruler.main_xalign (), ruler.main_yalign (), bitmap, renderer); + + draw_ellipse (q1, q2, lu, sel, bitmap, renderer); +} + +bool +compute_interpolating_circle (const ant::Object::point_list &points, double &radius, db::DPoint ¢er, double &start_angle, double &stop_angle) +{ + if (points.size () < 2) { + return false; + } + + double d = points.back ().distance (points.front ()) * 0.5; + if (d < db::epsilon) { + return false; + } + + db::DVector n = points.back () - points.front (); + db::DPoint m = points.front () + n * 0.5; + n = db::DVector (n.y (), -n.x ()) * (1.0 / d); + + double nom = 0.0; + double div = 0.0; + + for (size_t i = 1; i + 1 < points.size (); ++i) { + db::DVector p = points [i] - m; + double pn = db::sprod (p, n); + div += pn * pn; + nom += pn * (p.sq_double_length () - d * d); + } + + if (div < db::epsilon) { + return false; + } + + double l = 0.5 * nom / div; + radius = sqrt (l * l + d * d); + center = m + n * l; + + double a = atan2 (-n.y (), -n.x ()); + double da = atan2 (d, l); + + if (fabs (l) < db::epsilon) { + + start_angle = 0.0; + stop_angle = M_PI * 2.0; + + } else if (l < 0.0) { + + start_angle = a + da; + stop_angle = start_angle + 2.0 * (M_PI - da); + + } else { + + start_angle = a - da; + stop_angle = a + da; + + } + + while (stop_angle < start_angle - db::epsilon) { + stop_angle += M_PI * 2.0; + } + + return true; +} + +void +draw_ruler_radius (const ant::Object &ruler, const db::DCplxTrans &trans, bool sel, lay::CanvasPlane *bitmap, lay::Renderer &renderer) +{ + // draw crosses for the support points + for (auto p = ruler.points ().begin (); p != ruler.points ().end (); ++p) { + ant::Object supp (*p, *p, 0, std::string (), std::string (), std::string (), ant::Object::STY_cross_start, ant::Object::OL_diag, false, lay::AC_Global); + draw_ruler_segment (supp, 0, trans, sel, bitmap, renderer); + } + + double radius = 0.0; + double start_angle = 0.0, stop_angle = 0.0; + db::DPoint center; + + // circle interpolation + if (compute_interpolating_circle (ruler.points (), radius, center, start_angle, stop_angle)) { + + // draw circle segment + db::DVector rr (radius, radius); + std::pair v = lay::snap (trans * (center - rr), trans * (center + rr)); + draw_ellipse (v.first, v.second, radius * 2.0, sel, bitmap, renderer, start_angle, stop_angle); + + double a = 0.5 * (start_angle + stop_angle); + db::DPoint rc = center + db::DVector (cos (a), sin (a)) * radius; + + // draw a center marker + ant::Object center_loc (center, center, 0, std::string (), ruler.fmt_x (), ruler.fmt_y (), ant::Object::STY_cross_start, ant::Object::OL_diag, false, lay::AC_Global); + draw_ruler_segment (center_loc, 0, trans, sel, bitmap, renderer); + + // draw the radius ruler + ant::Object radius (center, rc, 0, ruler.fmt (), std::string (), std::string (), ruler.style (), ruler.outline (), false, lay::AC_Global); + draw_ruler_segment (radius, 0, trans, sel, bitmap, renderer); } } +void +draw_ruler_angle (const ant::Object &ruler, const db::DCplxTrans &trans, bool sel, lay::CanvasPlane *bitmap, lay::Renderer &renderer) +{ + // draw segments in diag mode + ant::Object basic = ruler; + basic.outline (ant::Object::OL_diag); + draw_ruler_segment (basic, 0, trans, sel, bitmap, renderer); + if (basic.segments () > 1) { + draw_ruler_segment (basic, basic.segments () - 1, trans, sel, bitmap, renderer); + } + + if (ruler.points ().size () < 3) { + return; + } + + db::DPoint p1 = ruler.p1 (), p2 = ruler.p2 (); + + db::DVector pc; + for (size_t i = 1; i + 1 < ruler.points ().size (); ++i) { + pc += ruler.points ()[i] - db::DPoint (); + } + db::DPoint center = db::DPoint () + pc * (1.0 / double (ruler.points ().size () - 2)); + + db::DVector v1 (p1 - center); + if (v1.double_length () < db::epsilon) { + return; + } + + db::DVector v2 (p2 - center); + if (v2.double_length () < db::epsilon) { + return; + } + + double radius = std::min (v1.double_length (), v2.double_length ()); + + v1 *= 1.0 / v1.double_length (); + v2 *= 1.0 / v2.double_length (); + + if (db::vprod_sign (v1, v2) == 0) { + return; + } + + double start_angle = 0.0, stop_angle = 0.0; + start_angle = atan2 (v1.y (), v1.x ()); + stop_angle = atan2 (v2.y (), v2.x ()); + + if (db::vprod_sign (v1, v2) < 0) { + std::swap (start_angle, stop_angle); + } + + while (stop_angle < start_angle - db::epsilon) { + stop_angle += M_PI * 2.0; + } + + db::DVector rr (radius * 0.9, radius * 0.9); + std::pair v = lay::snap (trans * (center - rr), trans * (center + rr)); + draw_ellipse (v.first, v.second, radius * 2.0, sel, bitmap, renderer, start_angle, stop_angle); + + // @@@ TODO: draw text, apply styles to circle segments? ... +} + void draw_ruler (const ant::Object &ruler, const db::DCplxTrans &trans, bool sel, lay::CanvasPlane *bitmap, lay::Renderer &renderer) { - if (ruler.outline () == Object::OL_box || ruler.outline () == Object::OL_ellipse) { - - draw_ruler_segment (ruler, std::numeric_limits::max (), trans, sel, bitmap, renderer); - + if (ruler.outline () == Object::OL_box) { + draw_ruler_box (ruler, trans, sel, bitmap, renderer); + } else if (ruler.outline () == Object::OL_ellipse) { + draw_ruler_ellipse (ruler, trans, sel, bitmap, renderer); + } else if (ruler.outline () == Object::OL_angle) { + draw_ruler_angle (ruler, trans, sel, bitmap, renderer); + } else if (ruler.outline () == Object::OL_radius) { + draw_ruler_radius (ruler, trans, sel, bitmap, renderer); } else { - - // other styles support segments, so paint them individually + // other outline styles support segments, so paint them individually for (size_t index = 0; index < ruler.segments (); ++index) { draw_ruler_segment (ruler, index, trans, sel, bitmap, renderer); } - } } static bool is_selected (const ant::Object &ruler, size_t index, const db::DPoint &pos, double enl, double &distance) { +// @@@ angle, radius ant::Object::outline_type outline = ruler.outline (); db::DPoint p1 = ruler.seg_p1 (index), p2 = ruler.seg_p2 (index); @@ -759,7 +934,7 @@ is_selected (const ant::Object &ruler, size_t index, const db::DPoint &pos, doub static bool is_selected (const ant::Object &ruler, const db::DPoint &pos, double enl, double &distance) { - if (ruler.outline () == ant::Object::OL_box || ruler.outline () == ant::Object::OL_ellipse) { + if (ruler.outline () == ant::Object::OL_box || ruler.outline () == ant::Object::OL_ellipse || ruler.outline () == ant::Object::OL_angle || ruler.outline () == ant::Object::OL_radius) { return is_selected (ruler, std::numeric_limits::max (), pos, enl, distance); } @@ -1078,6 +1253,7 @@ Service::insert_ruler (const ant::Object &ruler, bool limit_number) static bool dragging_what_seg (const ant::Object *robj, const db::DBox &search_dbox, ant::Service::MoveMode &mode, db::DPoint &p1, size_t index) { +// @@@ radius, angle ant::Object::outline_type outline = robj->outline (); db::DPoint p12, p21; @@ -1159,7 +1335,7 @@ dragging_what (const ant::Object *robj, const db::DBox &search_dbox, ant::Servic { ant::Object::outline_type outline = robj->outline (); - if (outline == ant::Object::OL_box || outline == ant::Object::OL_ellipse) { + if (outline == ant::Object::OL_box || outline == ant::Object::OL_ellipse || outline == ant::Object::OL_angle || outline == ant::Object::OL_radius) { index = std::numeric_limits::max (); return dragging_what_seg (robj, search_dbox, mode, p1, index); } @@ -1719,12 +1895,12 @@ 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) { + } else if (tpl.mode () == ant::Template::RulerMultiSegment || tpl.mode () == ant::Template::RulerThreeClicks) { ant::Object::point_list pts = m_current.points (); tl_assert (! pts.empty ()); - if (tpl.mode () == ant::Template::RulerAngle && pts.size () == 3) { + if (tpl.mode () == ant::Template::RulerThreeClicks && pts.size () == 3) { finish_drawing (); diff --git a/src/ant/ant/antTemplate.h b/src/ant/ant/antTemplate.h index 6b1bbbf8b..ab561a5e8 100644 --- a/src/ant/ant/antTemplate.h +++ b/src/ant/ant/antTemplate.h @@ -67,7 +67,7 @@ public: /** * @brief The ruler an angle type (two segments, three mouse clicks) for angle and circle radius measurements */ - RulerAngle = 3, + RulerThreeClicks = 3, /** * @brief The ruler is a multi-segment type diff --git a/src/ant/ant/gsiDeclAnt.cc b/src/ant/ant/gsiDeclAnt.cc index 24b3d47ca..032190b48 100644 --- a/src/ant/ant/gsiDeclAnt.cc +++ b/src/ant/ant/gsiDeclAnt.cc @@ -48,6 +48,8 @@ static int outline_yx () { return int (ant::Object::OL_yx); } static int outline_diag_yx () { return int (ant::Object::OL_diag_yx); } static int outline_box () { return int (ant::Object::OL_box); } static int outline_ellipse () { return int (ant::Object::OL_ellipse); } +static int outline_angle () { return int (ant::Object::OL_angle); } +static int outline_radius () { return int (ant::Object::OL_radius); } static int angle_any () { return int (lay::AC_Any); } static int angle_diagonal () { return int (lay::AC_Diagonal); } @@ -432,9 +434,9 @@ static int ruler_mode_auto_metric () return ant::Template::RulerAutoMetric; } -static int ruler_mode_angle () +static int ruler_mode_three_clicks () { - return ant::Template::RulerAngle; + return ant::Template::RulerThreeClicks; } static int ruler_mode_multi_segment () @@ -523,9 +525,9 @@ gsi::Class decl_Annotation (decl_BasicAnnotation, "lay", "Annotat "\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" + gsi::method ("RulerThreeClicks", &gsi::ruler_mode_three_clicks, + "@brief Specifies three-click ruler mode for the \\register_template method\n" + "In this 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" ) + @@ -535,58 +537,58 @@ gsi::Class decl_Annotation (decl_BasicAnnotation, "lay", "Annotat "\n" "This constant has been introduced in version 0.28" ) + - gsi::method ("StyleRuler|#style_ruler", &gsi::style_ruler, + gsi::method ("StyleRuler", &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 " "some ticks at distances indicating a decade of units and a suitable " "subdivision into minor ticks at intervals of 1, 2 or 5 units." ) + - gsi::method ("StyleArrowEnd|#style_arrow_end", &gsi::style_arrow_end, + gsi::method ("StyleArrowEnd", &gsi::style_arrow_end, "@brief Gets the end arrow style code for use the \\style method\n" "When this style is specified, an arrow is drawn pointing from the start to the end point." ) + - gsi::method ("StyleArrowStart|#style_arrow_start", &gsi::style_arrow_start, + gsi::method ("StyleArrowStart", &gsi::style_arrow_start, "@brief Gets the start arrow style code for use the \\style method\n" "When this style is specified, an arrow is drawn pointing from the end to the start point." ) + - gsi::method ("StyleArrowBoth|#style_arrow_both", &gsi::style_arrow_both, + gsi::method ("StyleArrowBoth", &gsi::style_arrow_both, "@brief Gets the both arrow ends style code for use the \\style method\n" "When this style is specified, a two-headed arrow is drawn." ) + - gsi::method ("StyleLine|#style_line", &gsi::style_line, + gsi::method ("StyleLine", &gsi::style_line, "@brief Gets the line style code for use with the \\style method\n" "When this style is specified, a plain line is drawn." ) + - gsi::method ("StyleCrossStart|#style_cross_start", &gsi::style_cross_start, + gsi::method ("StyleCrossStart", &gsi::style_cross_start, "@brief Gets the line style code for use with the \\style method\n" "When this style is specified, a cross is drawn at the start point.\n" "\n" "This constant has been added in version 0.26." ) + - gsi::method ("StyleCrossEnd|#style_cross_end", &gsi::style_cross_end, + gsi::method ("StyleCrossEnd", &gsi::style_cross_end, "@brief Gets the line style code for use with the \\style method\n" "When this style is specified, a cross is drawn at the end point.\n" "\n" "This constant has been added in version 0.26." ) + - gsi::method ("StyleCrossBoth|#style_cross_both", &gsi::style_cross_both, + gsi::method ("StyleCrossBoth", &gsi::style_cross_both, "@brief Gets the line style code for use with the \\style method\n" "When this style is specified, a cross is drawn at both points.\n" "\n" "This constant has been added in version 0.26." ) + - gsi::method ("OutlineDiag|#outline_diag", &gsi::outline_diag, + gsi::method ("OutlineDiag", &gsi::outline_diag, "@brief Gets the diagonal output code for use with the \\outline method\n" "When this outline style is specified, a line connecting start and " "end points in the given style (ruler, arrow or plain line) is drawn." ) + - gsi::method ("OutlineXY|#outline_xy", &gsi::outline_xy, + gsi::method ("OutlineXY", &gsi::outline_xy, "@brief Gets the xy outline code for use with the \\outline method\n" "When this outline style is specified, two lines are drawn: one horizontal from left " "to right and attached to the end of that a line from the bottom to the top. The lines " "are drawn in the specified style (see \\style method)." ) + - gsi::method ("OutlineDiagXY|#outline_diag_xy", &gsi::outline_diag_xy, + gsi::method ("OutlineDiagXY", &gsi::outline_diag_xy, "@brief Gets the xy plus diagonal outline code for use with the \\outline method\n" "@brief outline_xy code used by the \\outline method\n" "When this outline style is specified, three lines are drawn: one horizontal from left " @@ -594,53 +596,65 @@ gsi::Class decl_Annotation (decl_BasicAnnotation, "lay", "Annotat "is drawn connecting the start and end points directly. The lines " "are drawn in the specified style (see \\style method)." ) + - gsi::method ("OutlineYX|#outline_yx", &gsi::outline_yx , + gsi::method ("OutlineYX", &gsi::outline_yx , "@brief Gets the yx outline code for use with the \\outline method\n" "When this outline style is specified, two lines are drawn: one vertical from bottom " "to top and attached to the end of that a line from the left to the right. The lines " "are drawn in the specified style (see \\style method)." ) + - gsi::method ("OutlineDiagYX|#outline_diag_yx", &gsi::outline_diag_yx , + gsi::method ("OutlineDiagYX", &gsi::outline_diag_yx , "@brief Gets the yx plus diagonal outline code for use with the \\outline method\n" "When this outline style is specified, three lines are drawn: one vertical from bottom " "to top and attached to the end of that a line from the left to the right. Another line " "is drawn connecting the start and end points directly. The lines " "are drawn in the specified style (see \\style method)." ) + - gsi::method ("OutlineBox|#outline_box", &gsi::outline_box, + gsi::method ("OutlineBox", &gsi::outline_box, "@brief Gets the box outline code for use with the \\outline method\n" "When this outline style is specified, a box is drawn with the corners specified by the " "start and end point. All box edges are drawn in the style specified with the \\style " "attribute." ) + - gsi::method ("OutlineEllipse|#outline_ellipse", &gsi::outline_ellipse, + gsi::method ("OutlineEllipse", &gsi::outline_ellipse, "@brief Gets the ellipse outline code for use with the \\outline method\n" "When this outline style is specified, an ellipse is drawn with the extensions specified by the " "start and end point. The contour drawn as a line.\n" "\n" "This constant has been introduced in version 0.26." ) + - gsi::method ("AngleAny|#angle_any", &gsi::angle_any, + gsi::method ("OutlineAngle", &gsi::outline_angle, + "@brief Gets the angle measurement ruler outline code for use with the \\outline method\n" + "When this outline style is specified, the ruler is drawn to indicate the angle between the first and last segment.\n" + "\n" + "This constant has been introduced in version 0.28." + ) + + gsi::method ("OutlineRadius", &gsi::outline_radius, + "@brief Gets the radius measurement ruler outline code for use with the \\outline method\n" + "When this outline style is specified, the ruler is drawn to indicate a radius defined by at least three points of the ruler.\n" + "\n" + "This constant has been introduced in version 0.28." + ) + + gsi::method ("AngleAny", &gsi::angle_any, "@brief Gets the any angle code for use with the \\angle_constraint method\n" "If this value is specified for the angle constraint, all angles will be allowed." ) + - gsi::method ("AngleDiagonal|#angle_diagonal", &gsi::angle_diagonal, + gsi::method ("AngleDiagonal", &gsi::angle_diagonal, "@brief Gets the diagonal angle code for use with the \\angle_constraint method\n" "If this value is specified for the angle constraint, only multiples of 45 degree are allowed." ) + - gsi::method ("AngleOrtho|#angle_ortho", &gsi::angle_ortho, + gsi::method ("AngleOrtho", &gsi::angle_ortho, "@brief Gets the ortho angle code for use with the \\angle_constraint method\n" "If this value is specified for the angle constraint, only multiples of 90 degree are allowed." ) + - gsi::method ("AngleHorizontal|#angle_horizontal", &gsi::angle_horizontal, + gsi::method ("AngleHorizontal", &gsi::angle_horizontal, "@brief Gets the horizontal angle code for use with the \\angle_constraint method\n" "If this value is specified for the angle constraint, only horizontal rulers are allowed." ) + - gsi::method ("AngleVertical|#angle_vertical", &gsi::angle_vertical, + gsi::method ("AngleVertical", &gsi::angle_vertical, "@brief Gets the vertical angle code for use with the \\angle_constraint method\n" "If this value is specified for the angle constraint, only vertical rulers are allowed." ) + - gsi::method ("AngleGlobal|#angle_global", &gsi::angle_global, + gsi::method ("AngleGlobal", &gsi::angle_global, "@brief Gets the global angle code for use with the \\angle_constraint method.\n" "This code will tell the ruler or marker to use the angle constraint defined globally." ) +