diff --git a/src/ant/RulerConfigPage.ui b/src/ant/RulerConfigPage.ui index 71cc00e83..aba48d1fb 100644 --- a/src/ant/RulerConfigPage.ui +++ b/src/ant/RulerConfigPage.ui @@ -1,7 +1,8 @@ - + + RulerConfigPage - - + + 0 0 @@ -9,120 +10,141 @@ 191 - + Settings - - - 9 - - + + 6 + + 9 + + + 9 + + + 9 + + + 9 + - - + + Snapping - - + + 9 - + + 9 + + + 9 + + + 9 + + 6 - - - + + + If checked, all coordinates are snapped to the global grid - + Snap to grid - - - + + + If checked, all positions are snapped to edges and vertices in the vicinity unless this feature is disabled in the template - + Snap to edge / vertex (unless disabled in template) - - - - - 5 - 5 + + + + 0 0 - + QFrame::Raised - - - 0 - - + + 6 + + 0 + + + 0 + + + 0 + + + 0 + - - + + Snap range - - - - 5 - 0 + + + 0 0 - + 0 0 - + The range around the current cursor location which is searched for edges or vertices to snap to - - - - 5 - 5 + + + 0 0 - + pixel - + Qt::Horizontal - + QSizePolicy::Expanding - + 111 21 @@ -133,15 +155,15 @@ - + - + Qt::Vertical - + QSizePolicy::Fixed - + 597 10 @@ -154,9 +176,7 @@ - - - - + + diff --git a/src/ant/RulerConfigPage2.ui b/src/ant/RulerConfigPage2.ui index 3383616b2..3c97ba795 100644 --- a/src/ant/RulerConfigPage2.ui +++ b/src/ant/RulerConfigPage2.ui @@ -1,7 +1,8 @@ - + + RulerConfigPage2 - - + + 0 0 @@ -9,70 +10,95 @@ 132 - + Settings - - - 9 - - + + 6 + + 9 + + + 9 + + + 9 + + + 9 + - - + + Appearance - - + + 9 - + + 9 + + + 9 + + + 9 + + 6 - - - - - 7 - 5 + + + + 0 0 - + QFrame::NoFrame - + QFrame::Raised - - - 0 - - + + 6 + + 0 + + + 0 + + + 0 + + + 0 + - - + + The color in which the rulers are drawn - + - + Qt::Horizontal - + QSizePolicy::Fixed - + 16 21 @@ -81,16 +107,14 @@ - - - - 7 - 0 + + + 0 0 - + With halo @@ -98,53 +122,58 @@ - - - - - 7 - 5 + + + + 0 0 - + QFrame::NoFrame - + QFrame::Raised - - - 0 - - + + 6 + + 0 + + + 0 + + + 0 + + + 0 + - - - - 5 - 0 + + + 0 0 - + 0 0 - + If set, no markers are created than the specified number - older markers are deleted - - + + Leave empty for unlimited @@ -152,16 +181,16 @@ - - - + + + Color - - - + + + Limit number of annotations to @@ -171,7 +200,7 @@ - + lay::ColorButton @@ -184,8 +213,6 @@ halo_cb num_rulers_edit - - - + diff --git a/src/ant/RulerConfigPage3.ui b/src/ant/RulerConfigPage3.ui index 15da08e03..e9d90e434 100644 --- a/src/ant/RulerConfigPage3.ui +++ b/src/ant/RulerConfigPage3.ui @@ -1,7 +1,8 @@ - + + RulerConfigPage3 - - + + 0 0 @@ -9,67 +10,83 @@ 103 - + Settings - - - 9 - - + + 6 + + 9 + + + 9 + + + 9 + + + 9 + - - - - 5 - 5 + + + 0 0 - + Angle constraint (unless disabled in template) - - + + 9 - + + 9 + + + 9 + + + 9 + + 0 - - - - Horizontal only + + + + Hori&zontal only - - - + + + Any angle - - - + + + Orthogonal - - - + + + Diagonal - - - + + + Vertical only @@ -79,7 +96,7 @@ - + ruler_any_angle_rb ruler_ortho_rb @@ -87,8 +104,6 @@ ruler_hor_rb ruler_vert_rb - - - + diff --git a/src/ant/RulerConfigPage4.ui b/src/ant/RulerConfigPage4.ui index f0a1146cd..c5a7e1d62 100644 --- a/src/ant/RulerConfigPage4.ui +++ b/src/ant/RulerConfigPage4.ui @@ -1,7 +1,8 @@ - + + RulerConfigPage4 - - + + 0 0 @@ -9,130 +10,157 @@ 311 - + Settings - - - 9 - - + + 6 + + 9 + + + 9 + + + 9 + + + 9 + - - - - 5 - 5 + + + 0 0 - + Ruler / annotation templates - - - 9 - - + + 16 + + 9 + + + 9 + + + 9 + + + 9 + - - + + QFrame::NoFrame - + QFrame::Raised - - + + 0 - + + 0 + + + 0 + + + 0 + + 6 - - - + + + Move selected template up in list - + ... - - :/up.png + + + :/up.png:/up.png - - - + + + Add a new template - + ... - - :/add.png + + + :/add.png:/add.png - - - + + + Delete selected template - + ... - - :/del.png + + + :/del.png:/del.png - - - + + + Move selected template down in list - + ... - - :/down.png + + + :/down.png:/down.png - - - + + + Double-click to rename - + true - - - - - 7 - 13 + + + + 0 1 - + The template selected for editing - + false - + true @@ -141,203 +169,212 @@ - - + + QFrame::StyledPanel - + QFrame::Raised - - + + 9 - + + 9 + + + 9 + + + 9 + + 6 - - - + + + If checked, snap to edges or vertices of objects unless disabled above - + Snap to objects - - - + + + Specify outline mode of the ruler template - + Diagonal - + Horizonal and vertical (in this order) - + Diagonal plus horizonal and vertical (triangle) - + Vertical and horizonal (in this order) - + Diagonal plus vertical and horizontal (triangle) - + Box marker - - - + + + Specify the y label format (applicable only for outline modes that have a vertical component, i.e. box) - - - + + + Angle constraints - - - + + + Outline - - - + + + Style - - - + + + Label format - - - + + + Specify the x label format (applicable only for outline modes that have a horizontal component, i.e. box) - - - + + + Specify the main label format - - - + + + X label format - - - + + + Y label format - - - + + + Specify style of the ruler template - + Ruler - + Arrow at end - + Arrow at start - + Arrow at both ends - + Plain line - - - + + + Override the global angle constraint setting for this type of rulers - + Any angle - + Diagonal - + Orthogonal - + Horizontal only - + Vertical only - + Use global setting - - - - <html>(See <a href="int:/manual/ruler_properties.xml">here</a> for a description of the properties)</html> + + + + <html>(See <a href="int:/manual/ruler_properties.xml">here</a> for a description of the properties)</html> @@ -349,7 +386,7 @@ - + template_list add_templ_pb @@ -365,7 +402,7 @@ t_snap_cbx - + diff --git a/src/ant/RulerPropertiesPage.ui b/src/ant/RulerPropertiesPage.ui index 6d960e2db..ef0074318 100644 --- a/src/ant/RulerPropertiesPage.ui +++ b/src/ant/RulerPropertiesPage.ui @@ -1,79 +1,559 @@ - + + RulerPropertiesPage - - + + 0 0 - 525 - 414 + 622 + 502 - + Form - - - 9 - - + + 6 + + 9 + + + 9 + + + 9 + + + 9 + - - + + QFrame::NoFrame - + QFrame::Raised - - + + 0 - + + 0 + + + 0 + + + 0 + + 6 - - - - x = + + + + Qt::Vertical - + + + 20 + 5 + + + - - - - - 7 - 0 + + + + Qt::Vertical + + + + 20 + 5 + + + + + + + + 1 0 - + + + + + + x = + + + + + + + Outline + + + + + + + <html>(See <a href="int:/manual/ruler_properties.xml">here</a> for a description of the properties)</html> + + + + + + + + 1 + 0 + + + true - - - - Style + + + + X label format - - - - - 5 - 0 + + + + y = + + + + + + + y = + + + + + + + d = + + + + + + + + Ruler + + + + + Arrow at end + + + + + Arrow at start + + + + + Arrow at both ends + + + + + Plain line + + + + + Cross at end + + + + + Cross at start + + + + + Cross at both ends + + + + + + + + Length + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + Auto + + + + + H. center + + + + + Left + + + + + Right + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + H + + + + + + + + 0 + 0 + + + + + Auto + + + + + V. center + + + + + Bottom + + + + + Top + + + + + + + + QComboBox::AdjustToContentsOnFirstShow + + + + Auto + + + + + At first point + + + + + At second point + + + + + At center + + + + + + + + P + + + + + + + V + + + + + + + + + + + 1 + 0 + + + + true + + + + + + + Qt::Horizontal + + + + + + + + 1 + 0 + + + + + + + + + + + x = + + + + + + + + 1 + 0 + + + + true + + + + + + + + 1 + 0 + + + + + + + + + + + y = + + + + + + + ... position + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + 223 + 20 + + + + + + + + H + + + + + + + + 0 + 0 + + + + + Auto + + + + + H. center + + + + + Left + + + + + Right + + + + + + + + V + + + + + + + + 0 + 0 + + + + + Auto + + + + + V. center + + + + + Bottom + + + + + Top + + + + + + + + + + + x = + + + + + + + 0 0 - + Sans Serif 12 @@ -84,130 +564,87 @@ false - + Ruler Properties - - - - - - - Outline + + + + Delta (x/y) - - - - y = + + + + + Diagonal + + + + + Horizonal and vertical (in this order) + + + + + Diagonal plus horizonal and vertical (triangle) + + + + + Vertical and horizonal (in this order) + + + + + Diagonal plus vertical and horizontal (triangle) + + + + + Box + + + + + Ellipse + + + + + + + + Second point (x/y) - - - - - 7 - 0 - 1 - 0 - - - - - - - - X label format - - - - - - - - 7 - 0 - 1 - 0 - - - - - - - - x = - - - - - - - d = - - - - - - + + + Label format - - - - - 7 - 0 - 1 - 0 - + + + + First point (x/y) - - - - - Ruler - - - - - Arrow at end - - - - - Arrow at start - - - - - Arrow at both ends - - - - - Plain line - - - - - + - + Qt::Vertical - + QSizePolicy::Fixed - + 456 16 @@ -215,156 +652,169 @@ - - - - y = + + + + ... position - - - - y = + + + + + 1 + 0 + - - - - Length + + + + Style - - + + - - - - Delta (x/y) + + + + ... position - - - - First point (x/y) - - - - - - - - Diagonal - - - - - Horizonal and vertical (in this order) - - - - - Diagonal plus horizonal and vertical (triangle) - - - - - Vertical and horizonal (in this order) - - - - - Diagonal plus vertical and horizontal (triangle) - - - - - Box - - - - - - - + + + Y label format - - + + + + Qt::Vertical + + + + 20 + 5 + + + - - - - - 7 - 0 - 1 - 0 - + + + + QFrame::NoFrame - - true - - - - - - - Second point (x/y) - - - - - - - - 7 - 0 - 1 - 0 - - - - true - - - - - - - Qt::Horizontal - - - - - - - - 7 - 0 - 1 - 0 - - - - - - - - x = - - - - - - - <html>(See <a href="int:/manual/ruler_properties.xml">here</a> for a description of the properties)</html> + + QFrame::Raised + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + 223 + 20 + + + + + + + + H + + + + + + + + 0 + 0 + + + + + Auto + + + + + H. center + + + + + Left + + + + + Right + + + + + + + + V + + + + + + + + 0 + 0 + + + + + Auto + + + + + V. center + + + + + Bottom + + + + + Top + + + + + @@ -372,10 +822,10 @@ - + Qt::Vertical - + 20 0 @@ -386,7 +836,6 @@ - fmt_le fmt_x_le fmt_y_le style_cb diff --git a/src/ant/antConfig.cc b/src/ant/antConfig.cc index 052ce2d62..5bb886519 100644 --- a/src/ant/antConfig.cc +++ b/src/ant/antConfig.cc @@ -81,6 +81,12 @@ StyleConverter::to_string (ant::Object::style_type s) return "arrow_start"; } else if (s == ant::Object::STY_arrow_both) { return "arrow_both"; + } else if (s == ant::Object::STY_cross_start) { + return "cross_start"; + } else if (s == ant::Object::STY_cross_end) { + return "cross_end"; + } else if (s == ant::Object::STY_cross_both) { + return "cross_both"; } else if (s == ant::Object::STY_line) { return "line"; } else { @@ -100,6 +106,12 @@ StyleConverter::from_string (const std::string &tt, ant::Object::style_type &s) s = ant::Object::STY_arrow_start; } else if (t == "arrow_both") { s = ant::Object::STY_arrow_both; + } else if (t == "cross_start") { + s = ant::Object::STY_cross_start; + } else if (t == "cross_end") { + s = ant::Object::STY_cross_end; + } else if (t == "cross_both") { + s = ant::Object::STY_cross_both; } else if (t == "line") { s = ant::Object::STY_line; } else { @@ -122,6 +134,8 @@ OutlineConverter::to_string (ant::Object::outline_type o) return "diag_yx"; } else if (o == ant::Object::OL_box) { return "box"; + } else if (o == ant::Object::OL_ellipse) { + return "ellipse"; } else { return ""; } @@ -143,12 +157,80 @@ OutlineConverter::from_string (const std::string &s, ant::Object::outline_type & o = ant::Object::OL_diag_yx; } else if (t == "box") { o = ant::Object::OL_box; + } else if (t == "ellipse") { + o = ant::Object::OL_ellipse; } else { o = ant::Object::OL_diag; } } -std::string +std::string +PositionConverter::to_string (ant::Object::position_type p) +{ + if (p == ant::Object::POS_auto) { + return "auto"; + } else if (p == ant::Object::POS_p1) { + return "p1"; + } else if (p == ant::Object::POS_p2) { + return "p2"; + } else if (p == ant::Object::POS_center) { + return "center"; + } else { + return ""; + } +} + +void +PositionConverter::from_string (const std::string &s, ant::Object::position_type &p) +{ + std::string t (tl::trim (s)); + if (t == "auto") { + p = ant::Object::POS_auto; + } else if (t == "p1") { + p = ant::Object::POS_p1; + } else if (t == "p2") { + p = ant::Object::POS_p2; + } else if (t == "center") { + p = ant::Object::POS_center; + } else { + p = ant::Object::POS_auto; + } +} + +std::string +AlignmentConverter::to_string (ant::Object::alignment_type a) +{ + if (a == ant::Object::AL_auto) { + return "auto"; + } else if (a == ant::Object::AL_center) { + return "center"; + } else if (a == ant::Object::AL_down) { + return "down"; + } else if (a == ant::Object::AL_up) { + return "up"; + } else { + return ""; + } +} + +void +AlignmentConverter::from_string (const std::string &s, ant::Object::alignment_type &a) +{ + std::string t (tl::trim (s)); + if (t == "auto") { + a = ant::Object::AL_auto; + } else if (t == "center") { + a = ant::Object::AL_center; + } else if (t == "down") { + a = ant::Object::AL_down; + } else if (t == "up") { + a = ant::Object::AL_up; + } else { + a = ant::Object::AL_auto; + } +} + +std::string TemplatesConverter::to_string (const std::vector &t) { return ant::Template::to_string (t); diff --git a/src/ant/antConfig.h b/src/ant/antConfig.h index 87b302e98..8b94b6a09 100644 --- a/src/ant/antConfig.h +++ b/src/ant/antConfig.h @@ -69,7 +69,19 @@ struct OutlineConverter void from_string (const std::string &s, ant::Object::outline_type &outline); }; -struct TemplatesConverter +struct PositionConverter +{ + std::string to_string (ant::Object::position_type p); + void from_string (const std::string &s, ant::Object::position_type &pos); +}; + +struct AlignmentConverter +{ + std::string to_string (ant::Object::alignment_type a); + void from_string (const std::string &s, ant::Object::alignment_type &a); +}; + +struct TemplatesConverter { std::string to_string (const std::vector &t); void from_string (const std::string &s, std::vector &t); diff --git a/src/ant/antObject.cc b/src/ant/antObject.cc index 7bf5ba7ab..01e83ff3a 100644 --- a/src/ant/antObject.cc +++ b/src/ant/antObject.cc @@ -36,7 +36,11 @@ Object::Object () : m_p1 (), m_p2 (), m_id (-1), m_fmt_x ("$X"), m_fmt_y ("$Y"), m_fmt ("$D"), m_style (STY_ruler), m_outline (OL_diag), - m_snap (true), m_angle_constraint (lay::AC_Global) + m_snap (true), m_angle_constraint (lay::AC_Global), + m_main_position (POS_auto), + m_main_xalign (AL_auto), m_main_yalign (AL_auto), + m_xlabel_xalign (AL_auto), m_xlabel_yalign (AL_auto), + m_ylabel_xalign (AL_auto), m_ylabel_yalign (AL_auto) { // .. nothing yet .. } @@ -45,7 +49,11 @@ Object::Object (const db::DPoint &p1, const db::DPoint &p2, int id, const std::s : m_p1 (p1), m_p2 (p2), m_id (id), m_fmt_x (fmt_x), m_fmt_y (fmt_y), m_fmt (fmt), m_style (style), m_outline (outline), - m_snap (snap), m_angle_constraint (angle_constraint) + m_snap (snap), m_angle_constraint (angle_constraint), + m_main_position (POS_auto), + m_main_xalign (AL_auto), m_main_yalign (AL_auto), + m_xlabel_xalign (AL_auto), m_xlabel_yalign (AL_auto), + m_ylabel_xalign (AL_auto), m_ylabel_yalign (AL_auto) { // .. nothing else .. } @@ -54,7 +62,12 @@ Object::Object (const db::DPoint &p1, const db::DPoint &p2, int id, const ant::T : m_p1 (p1), m_p2 (p2), m_id (id), m_fmt_x (t.fmt_x ()), m_fmt_y (t.fmt_y ()), m_fmt (t.fmt ()), m_style (t.style ()), m_outline (t.outline ()), - m_snap (t.snap ()), m_angle_constraint (t.angle_constraint ()) + m_snap (t.snap ()), m_angle_constraint (t.angle_constraint ()), + // TODO: make this part of the template + m_main_position (POS_auto), + m_main_xalign (AL_auto), m_main_yalign (AL_auto), + m_xlabel_xalign (AL_auto), m_xlabel_yalign (AL_auto), + m_ylabel_xalign (AL_auto), m_ylabel_yalign (AL_auto) { // .. nothing else .. } @@ -63,7 +76,12 @@ Object::Object (const ant::Object &d) : m_p1 (d.m_p1), m_p2 (d.m_p2), m_id (d.m_id), m_fmt_x (d.m_fmt_x), m_fmt_y (d.m_fmt_y), m_fmt (d.m_fmt), m_style (d.m_style), m_outline (d.m_outline), - m_snap (d.m_snap), m_angle_constraint (d.m_angle_constraint) + m_snap (d.m_snap), m_angle_constraint (d.m_angle_constraint), + m_category (d.m_category), + m_main_position (d.m_main_position), + m_main_xalign (d.m_main_xalign), m_main_yalign (d.m_main_yalign), + m_xlabel_xalign (d.m_xlabel_xalign), m_xlabel_yalign (d.m_xlabel_yalign), + m_ylabel_xalign (d.m_ylabel_xalign), m_ylabel_yalign (d.m_ylabel_yalign) { // .. nothing else .. } @@ -82,6 +100,14 @@ Object::operator= (const ant::Object &d) m_outline = d.m_outline; m_snap = d.m_snap; m_angle_constraint = d.m_angle_constraint; + m_category = d.m_category; + m_main_position = d.m_main_position; + m_main_xalign = d.m_main_xalign; + m_main_yalign = d.m_main_yalign; + m_xlabel_xalign = d.m_xlabel_xalign; + m_xlabel_yalign = d.m_xlabel_yalign; + m_ylabel_xalign = d.m_ylabel_xalign; + m_ylabel_yalign = d.m_ylabel_yalign; property_changed (); } return *this; @@ -120,6 +146,30 @@ Object::operator< (const ant::Object &b) const if (m_angle_constraint != b.m_angle_constraint) { return m_angle_constraint < b.m_angle_constraint; } + if (m_category != b.m_category) { + return m_category < b.m_category; + } + if (m_main_position != b.m_main_position) { + return m_main_position < b.m_main_position; + } + if (m_main_xalign != b.m_main_xalign) { + return m_main_xalign < b.m_main_xalign; + } + if (m_main_yalign != b.m_main_yalign) { + return m_main_yalign < b.m_main_yalign; + } + if (m_xlabel_xalign != b.m_xlabel_xalign) { + return m_xlabel_xalign < b.m_xlabel_xalign; + } + if (m_xlabel_yalign != b.m_xlabel_yalign) { + return m_xlabel_yalign < b.m_xlabel_yalign; + } + if (m_ylabel_xalign != b.m_ylabel_xalign) { + return m_ylabel_xalign < b.m_ylabel_xalign; + } + if (m_ylabel_yalign != b.m_ylabel_yalign) { + return m_ylabel_yalign < b.m_ylabel_yalign; + } return false; } @@ -140,46 +190,23 @@ Object::operator== (const ant::Object &d) const return m_p1 == d.m_p1 && m_p2 == d.m_p2 && m_id == d.m_id && m_fmt_x == d.m_fmt_x && m_fmt_y == d.m_fmt_y && m_fmt == d.m_fmt && m_style == d.m_style && m_outline == d.m_outline && - m_snap == d.m_snap && m_angle_constraint == d.m_angle_constraint; + m_snap == d.m_snap && m_angle_constraint == d.m_angle_constraint && + m_main_position == d.m_main_position && + m_main_xalign == d.m_main_xalign && m_main_yalign == d.m_main_yalign && + m_xlabel_xalign == d.m_xlabel_xalign && m_xlabel_yalign == d.m_xlabel_yalign && + m_ylabel_xalign == d.m_ylabel_xalign && m_ylabel_yalign == d.m_ylabel_yalign + ; } bool Object::less (const db::DUserObjectBase *d) const { const ant::Object *ruler = dynamic_cast (d); - tl_assert (ruler != 0); - - if (m_id != ruler->m_id) { - return m_id < ruler->m_id; + if (ruler) { + return *this < *ruler; + } else { + return class_id () < d->class_id (); } - if (m_p1 != ruler->m_p1) { - return m_p1 < ruler->m_p1; - } - if (m_p2 != ruler->m_p2) { - return m_p2 < ruler->m_p2; - } - if (m_fmt_x != ruler->m_fmt_x) { - return m_fmt_x < ruler->m_fmt_x; - } - if (m_fmt_y != ruler->m_fmt_y) { - return m_fmt_y < ruler->m_fmt_y; - } - if (m_fmt != ruler->m_fmt) { - return m_fmt < ruler->m_fmt; - } - if (m_style != ruler->m_style) { - return m_style < ruler->m_style; - } - if (m_outline != ruler->m_outline) { - return m_outline < ruler->m_outline; - } - if (m_snap != ruler->m_snap) { - return m_snap < ruler->m_snap; - } - if (m_angle_constraint != ruler->m_angle_constraint) { - return m_angle_constraint < ruler->m_angle_constraint; - } - return false; } unsigned int @@ -324,6 +351,12 @@ Object::from_string (const char *s) ex.read (i); id (i); + } else if (ex.test ("category=")) { + + std::string s; + ex.read_word_or_quoted (s); + set_category (s); + } else if (ex.test ("fmt=")) { std::string s; @@ -374,6 +407,76 @@ Object::from_string (const char *s) p.set_y (q); p2 (p); + } else if (ex.test ("position=")) { + + std::string s; + ex.read_word (s); + ant::PositionConverter pc; + ant::Object::position_type pos; + pc.from_string (s, pos); + set_main_position (pos); + ex.test (","); + + } else if (ex.test ("xalign=")) { + + std::string s; + ex.read_word (s); + ant::AlignmentConverter ac; + ant::Object::alignment_type a; + ac.from_string (s, a); + set_main_xalign (a); + ex.test (","); + + } else if (ex.test ("yalign=")) { + + std::string s; + ex.read_word (s); + ant::AlignmentConverter ac; + ant::Object::alignment_type a; + ac.from_string (s, a); + set_main_yalign (a); + ex.test (","); + + } else if (ex.test ("xlabel_xalign=")) { + + std::string s; + ex.read_word (s); + ant::AlignmentConverter ac; + ant::Object::alignment_type a; + ac.from_string (s, a); + set_xlabel_xalign (a); + ex.test (","); + + } else if (ex.test ("xlabel_yalign=")) { + + std::string s; + ex.read_word (s); + ant::AlignmentConverter ac; + ant::Object::alignment_type a; + ac.from_string (s, a); + set_xlabel_yalign (a); + ex.test (","); + + } else if (ex.test ("ylabel_xalign=")) { + + std::string s; + ex.read_word (s); + ant::AlignmentConverter ac; + ant::Object::alignment_type a; + ac.from_string (s, a); + set_ylabel_xalign (a); + ex.test (","); + + } else if (ex.test ("ylabel_yalign=")) { + + std::string s; + ex.read_word (s); + ant::AlignmentConverter ac; + ant::Object::alignment_type a; + ac.from_string (s, a); + set_ylabel_yalign (a); + ex.test (","); + } else if (ex.test ("style=")) { std::string s; @@ -438,6 +541,10 @@ Object::to_string () const r += tl::to_string (p2 ().y ()); r += ","; + r += "category="; + r += tl::to_word_or_quoted_string (category ()); + r += ","; + r += "fmt="; r += tl::to_word_or_quoted_string (fmt ()); r += ","; @@ -448,6 +555,31 @@ Object::to_string () const r += tl::to_word_or_quoted_string (fmt_y ()); r += ","; + r += "pos="; + ant::PositionConverter pc; + r += pc.to_string (main_position ()); + r += ","; + + ant::AlignmentConverter ac; + r += "xalign="; + r += ac.to_string (main_xalign ()); + r += ","; + r += "yalign="; + r += ac.to_string (main_yalign ()); + r += ","; + r += "xlabel_xalign="; + r += ac.to_string (xlabel_xalign ()); + r += ","; + r += "xlabel_yalign="; + r += ac.to_string (xlabel_yalign ()); + r += ","; + r += "ylabel_xalign="; + r += ac.to_string (ylabel_xalign ()); + r += ","; + r += "ylabel_yalign="; + r += ac.to_string (ylabel_yalign ()); + r += ","; + r += "style="; ant::StyleConverter sc; r += sc.to_string (style ()); @@ -463,8 +595,8 @@ Object::to_string () const r += ","; r += "angle_constraint="; - ant::ACConverter ac; - r += ac.to_string (angle_constraint ()); + ant::ACConverter acc; + r += acc.to_string (angle_constraint ()); return r; } diff --git a/src/ant/antObject.h b/src/ant/antObject.h index 694e1b5c9..376cdc08a 100644 --- a/src/ant/antObject.h +++ b/src/ant/antObject.h @@ -58,9 +58,13 @@ public: * STY_arrow_end: a line with an arrow at the end * STY_arrow_start: a line with a arrow at the start * STY_arrow_both: a line with an arrow at both ends + * STY_cross_end: a cross at the end + * STY_cross_start: a cross at the start + * STY_cross_both: a cross at both ends * STY_line: a simple line + * STY_none: used internally */ - enum style_type { STY_ruler, STY_arrow_end, STY_arrow_start, STY_arrow_both, STY_line }; + enum style_type { STY_ruler = 0, STY_arrow_end = 1, STY_arrow_start = 2, STY_arrow_both = 3, STY_line = 4, STY_cross_end = 5, STY_cross_start = 6, STY_cross_both = 7, STY_none = 8 }; /** * @brief The outline modes @@ -71,274 +75,60 @@ public: * OL_yx: connecting start and end point, vertical first then horizontal * 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) */ - enum outline_type { OL_diag, OL_xy, OL_diag_xy, OL_yx, OL_diag_yx, OL_box }; + 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 }; + /** + * @brief The position type of the main label + * + * POS_auto: automatic + * POS_p1: at P1 + * POS_p2: at P2 + * POS_center: at mid point between P1 and P2 + */ + enum position_type { POS_auto = 0, POS_p1 = 1, POS_p2 = 2, POS_center = 3 }; + + /** + * @brief The alignment type + * + * AL_auto: automatic + * AL_center: centered + * AL_left, AL_bottom, AL_down: left or bottom + * AL_right, AL_top, AL_up: right or top + */ + enum alignment_type { AL_auto = 0, AL_center = 1, AL_down = 2, AL_left = 2, AL_bottom = 2, AL_up = 3, AL_right = 3, AL_top = 3 }; + + /** + * @brief Default constructor + */ Object (); + /** + * @brief Parametrized constructor + */ Object (const db::DPoint &p1, const db::DPoint &p2, int id, const std::string &fmt_x, const std::string &fmt_y, const std::string &fmt, style_type style, outline_type outline, bool snap, lay::angle_constraint_type angle_constraint); + /** + * @brief Parametrized constructor from a template + */ Object (const db::DPoint &p1, const db::DPoint &p2, int id, const ant::Template &d); + /** + * @brief Copy constructor + */ Object (const ant::Object &d); + /** + * @brief Assignment + */ Object &operator= (const ant::Object &d); - virtual bool equals (const db::DUserObjectBase *d) const; - - virtual bool less (const db::DUserObjectBase *d) const; - - virtual unsigned int class_id () const; - - virtual db::DUserObjectBase *clone () const; - - virtual db::DBox box () const; - - void transform (const db::ICplxTrans &t) - { - transform (db::DCplxTrans (t)); - property_changed (); - } - - virtual void transform (const db::DCplxTrans &t) - { - *this = ant::Object (t * m_p1, t * m_p2, m_id, m_fmt_x, m_fmt_y, m_fmt, m_style, m_outline, m_snap, m_angle_constraint); - property_changed (); - } - - virtual void transform (const db::DTrans &t) - { - *this = ant::Object (t * m_p1, t * m_p2, m_id, m_fmt_x, m_fmt_y, m_fmt, m_style, m_outline, m_snap, m_angle_constraint); - property_changed (); - } - - virtual void transform (const db::DFTrans &t) - { - *this = ant::Object (t * m_p1, t * m_p2, m_id, m_fmt_x, m_fmt_y, m_fmt, m_style, m_outline, m_snap, m_angle_constraint); - property_changed (); - } - - template - ant::Object transformed (const Trans &t) const - { - ant::Object obj (*this); - obj.transform (t); - return obj; - } - - Object &move (const db::DVector &p) - { - m_p1 += p; - m_p2 += p; - return *this; - } - - Object moved (const db::DVector &p) const - { - ant::Object d (*this); - d.move (p); - return d; - } - - const db::DPoint &p1 () const - { - return m_p1; - } - - const db::DPoint &p2 () const - { - return m_p2; - } - - void p1 (const db::DPoint &p) - { - if (!m_p1.equal (p)) { - m_p1 = p; - property_changed (); - } - } - - void p2 (const db::DPoint &p) - { - if (!m_p2.equal (p)) { - m_p2 = p; - property_changed (); - } - } - - int id () const - { - return m_id; - } - - void id (int _id) - { - m_id = _id; - } - - const std::string &fmt () const - { - return m_fmt; - } - - void fmt (const std::string &s) - { - if (m_fmt != s) { - m_fmt = s; - property_changed (); - } - } - - const std::string &fmt_x () const - { - return m_fmt_x; - } - - void fmt_x (const std::string &s) - { - if (m_fmt_x != s) { - m_fmt_x = s; - property_changed (); - } - } - - const std::string &fmt_y () const - { - return m_fmt_y; - } - - void fmt_y (const std::string &s) - { - if (m_fmt_y != s) { - m_fmt_y = s; - property_changed (); - } - } - - style_type style () const - { - return m_style; - } - - void style (style_type s) - { - if (m_style != s) { - m_style = s; - property_changed (); - } - } - - outline_type outline () const - { - return m_outline; - } - - void outline (outline_type s) - { - if (m_outline != s) { - m_outline = s; - property_changed (); - } - } - /** - * @brief Angle constraint flag read accessor - */ - bool snap () const - { - return m_snap; - } - - /** - * @brief Snap flag write accessor - * - * The snap flag controls whether snapping to objects (edges and vertices) - * is active when this template is selected. + * @brief Less operator */ - void snap (bool s) - { - if (m_snap != s) { - m_snap = s; - property_changed (); - } - } - - /** - * @brief Angle constraint read accessor - */ - lay::angle_constraint_type angle_constraint () const - { - return m_angle_constraint; - } - - /** - * @brief Angle constraint write accessor - * - * The angle constraint flag controls which angle constraint is to be used - * for this ruler or the global setting should be used - * (if ant::Service::Global is used for the angle constraint). - */ - void angle_constraint (lay::angle_constraint_type a) - { - if (m_angle_constraint != a) { - m_angle_constraint = a; - property_changed (); - } - } - bool operator< (const ant::Object &b) const; - /** - * @brief Obtain the formatted text for the x label - */ - std::string text_x () const - { - return formatted (m_fmt_x, db::DFTrans ()); - } - - /** - * @brief Obtain the formatted text for the y label - */ - std::string text_y () const - { - return formatted (m_fmt_y, db::DFTrans ()); - } - - /** - * @brief Obtain the formatted text for the main label - */ - std::string text () const - { - return formatted (m_fmt, db::DFTrans ()); - } - - /** - * @brief Obtain the formatted text for the x label - * @param t The transformation to apply to the vector before producing the text - */ - std::string text_x (const db::DFTrans &t) const - { - return formatted (m_fmt_x, t); - } - - /** - * @brief Obtain the formatted text for the y label - * @param t The transformation to apply to the vector before producing the text - */ - std::string text_y (const db::DFTrans &t) const - { - return formatted (m_fmt_y, t); - } - - /** - * @brief Obtain the formatted text for the main label - * @param t The transformation to apply to the vector before producing the text - */ - std::string text (const db::DFTrans &t) const - { - return formatted (m_fmt, t); - } - /** * @brief Equality */ @@ -353,12 +143,534 @@ public: } /** - * @brief The class name for the generic user object factory + * @brief Equality check + * This is the generic equality that involves an other object + * of any kind. + */ + virtual bool equals (const db::DUserObjectBase *d) const; + + /** + * @brief Less criterion + * This is the generic equality that involves an other object + * of any kind. + */ + virtual bool less (const db::DUserObjectBase *d) const; + + /** + * @brief Gets the user object class ID + */ + virtual unsigned int class_id () const; + + /** + * @brief Clones the user object + */ + virtual db::DUserObjectBase *clone () const; + + /** + * @brief Returns the bounding box of the object + */ + virtual db::DBox box () const; + + /** + * @brief Transforms the object (in place) + */ + void transform (const db::ICplxTrans &t) + { + transform (db::DCplxTrans (t)); + property_changed (); + } + + /** + * @brief Transforms the object (in place) + */ + virtual void transform (const db::DCplxTrans &t) + { + *this = ant::Object (t * m_p1, t * m_p2, m_id, m_fmt_x, m_fmt_y, m_fmt, m_style, m_outline, m_snap, m_angle_constraint); + property_changed (); + } + + /** + * @brief Transforms the object (in place) + */ + virtual void transform (const db::DTrans &t) + { + *this = ant::Object (t * m_p1, t * m_p2, m_id, m_fmt_x, m_fmt_y, m_fmt, m_style, m_outline, m_snap, m_angle_constraint); + property_changed (); + } + + /** + * @brief Transforms the object (in place) + */ + virtual void transform (const db::DFTrans &t) + { + *this = ant::Object (t * m_p1, t * m_p2, m_id, m_fmt_x, m_fmt_y, m_fmt, m_style, m_outline, m_snap, m_angle_constraint); + property_changed (); + } + + /** + * @brief Returns the transformed object + */ + template + ant::Object transformed (const Trans &t) const + { + ant::Object obj (*this); + obj.transform (t); + return obj; + } + + /** + * @brief Moves the object by the given distance + */ + Object &move (const db::DVector &p) + { + m_p1 += p; + m_p2 += p; + return *this; + } + + /** + * @brief Returns the moved object + */ + Object moved (const db::DVector &p) const + { + ant::Object d (*this); + d.move (p); + return d; + } + + /** + * @brief Gets the category string + * The category string is an arbitrary string that can be used to identify an annotation for + * a particular purpose. + */ + + const std::string &category () const + { + return m_category; + } + + /** + * @brief Sets the category string + * See \category for a description of this attribute. + */ + void set_category (const std::string &cat) + { + if (m_category != cat) { + m_category = cat; + property_changed (); + } + } + + /** + * @brief Gets the first definition point + */ + const db::DPoint &p1 () const + { + return m_p1; + } + + /** + * @brief Gets the second definition point + */ + const db::DPoint &p2 () const + { + return m_p2; + } + + /** + * @brief Sets the first definition point + */ + void p1 (const db::DPoint &p) + { + if (!m_p1.equal (p)) { + m_p1 = p; + property_changed (); + } + } + + /** + * @brief Sets the second definition point + */ + void p2 (const db::DPoint &p) + { + if (!m_p2.equal (p)) { + m_p2 = p; + property_changed (); + } + } + + /** + * @brief Gets the ID of the annotation object + * The ID is a unique identifier for the annotation object. The ID is used + * by the layout view to identify the object. + */ + int id () const + { + return m_id; + } + + /** + * @brief Sets the ID of the annotation object + * This method is provided for use by the layout view. + */ + void id (int _id) + { + m_id = _id; + } + + /** + * @brief Sets the main format string + * The central label is placed either at the first or the second point. + * \main_position, \main_xalign, \main_yalign control how the + * main label is positioned. + */ + const std::string &fmt () const + { + return m_fmt; + } + + /** + * @brief Sets the main format string + * See \fmt for details. + */ + void fmt (const std::string &s) + { + if (m_fmt != s) { + m_fmt = s; + property_changed (); + } + } + + /** + * @brief Sets the position of the main label + * See the \position_type enum for details. + */ + void set_main_position (position_type pos) + { + if (m_main_position != pos) { + m_main_position = pos; + property_changed (); + } + } + + /** + * @brief Gets the position of the main label + */ + position_type main_position () const + { + return m_main_position; + } + + /** + * @brief Sets the x alignment flag of the main label + * See \alignment_type for details. + */ + void set_main_xalign (alignment_type a) + { + if (m_main_xalign != a) { + m_main_xalign = a; + property_changed (); + } + } + + /** + * @brief Gets the x alignment flag of the main label + */ + alignment_type main_xalign () const + { + return m_main_xalign; + } + + /** + * @brief Sets the y alignment flag of the main label + * See \alignment_type for details. + */ + void set_main_yalign (alignment_type a) + { + if (m_main_yalign != a) { + m_main_yalign = a; + property_changed (); + } + } + + /** + * @brief Gets the y alignment flag of the main label + */ + alignment_type main_yalign () const + { + return m_main_yalign; + } + + /** + * @brief Gets the x label format string + * The x label is drawn at the x axis for styles that support a x axis. + * \xlabel_xalign and \xlabel_yalign control how the x label is + * positioned. + */ + const std::string &fmt_x () const + { + return m_fmt_x; + } + + /** + * @brief Gets the x label format string + * See \fmt_x for a description of this attribute. + */ + void fmt_x (const std::string &s) + { + if (m_fmt_x != s) { + m_fmt_x = s; + property_changed (); + } + } + + /** + * @brief Sets the x alignment flag of the x axis label + * See \alignment_type for details. + */ + void set_xlabel_xalign (alignment_type a) + { + if (m_xlabel_xalign != a) { + m_xlabel_xalign = a; + property_changed (); + } + } + + /** + * @brief Gets the x alignment flag of the x axis label + */ + alignment_type xlabel_xalign () const + { + return m_xlabel_xalign; + } + + /** + * @brief Sets the y alignment flag of the x axis label + * See \alignment_type for details. + */ + void set_xlabel_yalign (alignment_type a) + { + if (m_xlabel_yalign != a) { + m_xlabel_yalign = a; + property_changed (); + } + } + + /** + * @brief Gets the y alignment flag of the x axis label + */ + alignment_type xlabel_yalign () const + { + return m_xlabel_yalign; + } + + /** + * @brief Gets the y label format string + * The y label is drawn at the y axis for styles that support a y axis. + * \ylabel_xalign and \ylabel_yalign control how the y label is + * positioned. + */ + const std::string &fmt_y () const + { + return m_fmt_y; + } + + /** + * @brief Gets the y label format string + * See \fmt_y for a description of this attribute. + */ + void fmt_y (const std::string &s) + { + if (m_fmt_y != s) { + m_fmt_y = s; + property_changed (); + } + } + + /** + * @brief Sets the x alignment flag of the y axis label + * See \alignment_type for details. + */ + void set_ylabel_xalign (alignment_type a) + { + if (m_ylabel_xalign != a) { + m_ylabel_xalign = a; + property_changed (); + } + } + + /** + * @brief Gets the x alignment flag of the y axis label + */ + alignment_type ylabel_xalign () const + { + return m_ylabel_xalign; + } + + /** + * @brief Sets the y alignment flag of the y axis label + * See \alignment_type for details. + */ + void set_ylabel_yalign (alignment_type a) + { + if (m_ylabel_yalign != a) { + m_ylabel_yalign = a; + property_changed (); + } + } + + /** + * @brief Gets the y alignment flag of the y axis label + */ + alignment_type ylabel_yalign () const + { + return m_ylabel_yalign; + } + + /** + * @brief Sets the style + * See \style_type enum for the various styles available. + */ + style_type style () const + { + return m_style; + } + + /** + * @brief Gets the style + */ + void style (style_type s) + { + if (m_style != s) { + m_style = s; + property_changed (); + } + } + + /** + * @brief Sets the outline type + * See \outline_type enum for the various outline types available. + */ + outline_type outline () const + { + return m_outline; + } + + /** + * @brief Gets the outline type + */ + void outline (outline_type s) + { + if (m_outline != s) { + m_outline = s; + property_changed (); + } + } + + /** + * @brief Gets the snap mode + * See \snap for details about this attribute + */ + bool snap () const + { + return m_snap; + } + + /** + * @brief Sets snap mode + * + * The snap flag controls whether snapping to objects (edges and vertices) + * is active when this template is selected. + */ + void snap (bool s) + { + if (m_snap != s) { + m_snap = s; + property_changed (); + } + } + + /** + * @brief Gets the angle constraint + */ + lay::angle_constraint_type angle_constraint () const + { + return m_angle_constraint; + } + + /** + * @brief Sets the angle constraint + * + * The angle constraint flag controls which angle constraint is to be used + * for this ruler or the global setting should be used + * (if ant::Service::Global is used for the angle constraint). + */ + void angle_constraint (lay::angle_constraint_type a) + { + if (m_angle_constraint != a) { + m_angle_constraint = a; + property_changed (); + } + } + + /** + * @brief Gets the formatted text for the x label + */ + std::string text_x () const + { + return formatted (m_fmt_x, db::DFTrans ()); + } + + /** + * @brief Gets the formatted text for the y label + */ + std::string text_y () const + { + return formatted (m_fmt_y, db::DFTrans ()); + } + + /** + * @brief Gets the formatted text for the main label + */ + std::string text () const + { + return formatted (m_fmt, db::DFTrans ()); + } + + /** + * @brief Gets the formatted text for the x label + * @param t The transformation to apply to the vector before producing the text + */ + std::string text_x (const db::DFTrans &t) const + { + return formatted (m_fmt_x, t); + } + + /** + * @brief Gets the formatted text for the y label + * @param t The transformation to apply to the vector before producing the text + */ + std::string text_y (const db::DFTrans &t) const + { + return formatted (m_fmt_y, t); + } + + /** + * @brief Gets the formatted text for the main label + * @param t The transformation to apply to the vector before producing the text + */ + std::string text (const db::DFTrans &t) const + { + return formatted (m_fmt, t); + } + + /** + * @brief Gets the class name for the generic user object factory */ virtual const char *class_name () const; /** - * @brief Fill from a string + * @brief Initializes the object from a string * * This method needs to be implemented mainly if the object is to be created from the * generic factory. @@ -366,7 +678,7 @@ public: virtual void from_string (const char *); /** - * @brief Convert to a string + * @brief Converts the object to a string * * This method needs to be implemented mainly if the object is to be created from the * generic factory. @@ -374,7 +686,7 @@ public: virtual std::string to_string () const; /** - * @brief Return the memory used in bytes + * @brief Returns the memory used in bytes */ virtual size_t mem_used () const { @@ -382,7 +694,7 @@ public: } /** - * @brief Return the memory required in bytes + * @brief Returns the memory required in bytes */ virtual size_t mem_reqd () const { @@ -405,6 +717,11 @@ private: outline_type m_outline; bool m_snap; lay::angle_constraint_type m_angle_constraint; + std::string m_category; + position_type m_main_position; + alignment_type m_main_xalign, m_main_yalign; + alignment_type m_xlabel_xalign, m_xlabel_yalign; + alignment_type m_ylabel_xalign, m_ylabel_yalign; std::string formatted (const std::string &fmt, const db::DFTrans &trans) const; }; diff --git a/src/ant/antPropertiesPage.cc b/src/ant/antPropertiesPage.cc index 81695f581..2b17035bf 100644 --- a/src/ant/antPropertiesPage.cc +++ b/src/ant/antPropertiesPage.cc @@ -118,6 +118,14 @@ PropertiesPage::update () y2->setText (tl::to_qstring (tl::micron_to_string (current ().p2 ().y ()))); y2->setCursorPosition (0); + main_position->setCurrentIndex (current ().main_position ()); + main_xalign->setCurrentIndex (current ().main_xalign ()); + main_yalign->setCurrentIndex (current ().main_yalign ()); + xlabel_xalign->setCurrentIndex (current ().xlabel_xalign ()); + xlabel_yalign->setCurrentIndex (current ().xlabel_yalign ()); + ylabel_xalign->setCurrentIndex (current ().ylabel_xalign ()); + ylabel_yalign->setCurrentIndex (current ().ylabel_yalign ()); + double sx = (current ().p2 ().x () - current ().p1 ().x ()); double sy = (current ().p2 ().y () - current ().p1 ().y ()); dx->setText (tl::to_qstring (tl::micron_to_string (sx))); @@ -162,6 +170,16 @@ PropertiesPage::apply () ant::Object ruler (db::DPoint (dx1, dy1), db::DPoint (dx2, dy2), current ().id (), fmt_x, fmt_y, fmt, style, outline, current ().snap (), current ().angle_constraint ()); + ruler.set_main_position (Object::position_type (main_position->currentIndex ())); + ruler.set_main_xalign (Object::alignment_type (main_xalign->currentIndex ())); + ruler.set_main_yalign (Object::alignment_type (main_yalign->currentIndex ())); + ruler.set_xlabel_xalign (Object::alignment_type (xlabel_xalign->currentIndex ())); + ruler.set_xlabel_yalign (Object::alignment_type (xlabel_yalign->currentIndex ())); + ruler.set_ylabel_xalign (Object::alignment_type (ylabel_xalign->currentIndex ())); + ruler.set_ylabel_yalign (Object::alignment_type (ylabel_yalign->currentIndex ())); + + ruler.set_category (current ().category ()); + mp_rulers->change_ruler (*m_pos, ruler); } diff --git a/src/ant/antService.cc b/src/ant/antService.cc index a537c6a27..e6e7e21df 100644 --- a/src/ant/antService.cc +++ b/src/ant/antService.cc @@ -106,11 +106,27 @@ tick_spacings (double d, double min_d, int &minor_ticks, double &ticks) * @param label The label text to draw * @param sel True to draw ruler in "selected" mode * @param right True to draw the ruler with ticks to the right (as seem from p1 to p2 in transformed space) + * @param pos The position where to draw the text * @param style The style with which to draw the ruler + * @param halign The text's horizonal alignment + * @param valign The text's vertical alignment * @param bitmap The bitmap to draw the ruler on + * @param renderer The renderer object */ void -draw_ruler (const db::DPoint &q1, const db::DPoint &q2, double length_u, double min_spc_u, const std::string &label, bool sel, bool right, ant::Object::style_type style, lay::CanvasPlane *bitmap, lay::Renderer &renderer) +draw_ruler (const db::DPoint &q1, + const db::DPoint &q2, + double length_u, + double min_spc_u, + const std::string &label, + bool sel, + bool right, + ant::Object::style_type style, + ant::Object::position_type pos, + ant::Object::alignment_type halign, + ant::Object::alignment_type valign, + lay::CanvasPlane *bitmap, + lay::Renderer &renderer) { double arrow_width = 8 / renderer.resolution (); double arrow_length = 12 / renderer.resolution (); @@ -160,18 +176,26 @@ draw_ruler (const db::DPoint &q1, const db::DPoint &q2, double length_u, double } db::DVector qq (q2.y () - q1.y (), q1.x () - q2.x ()); - qq *= 1.0 / len; + if (len > 1e-10) { + qq *= 1.0 / len; + } else { + qq = db::DVector (1.0, 0.0); + } if (!right) { qq = -qq; } db::DVector qu = q2 - q1; - qu *= 1.0 / len; + if (len > 1e-10) { + qu *= 1.0 / len; + } else { + qu = db::DVector (1.0, 0.0); + } // produce polygon stuff - if (sel) { - + if (sel && style != ant::Object::STY_none) { + db::DVector qw = qq * (double (sel_width) * 0.5); db::DVector dq1, dq2; @@ -195,6 +219,7 @@ draw_ruler (const db::DPoint &q1, const db::DPoint &q2, double length_u, double } if (style == ant::Object::STY_arrow_end || style == ant::Object::STY_arrow_both) { + db::DPolygon p; db::DPoint points[] = { db::DPoint (q2), @@ -203,9 +228,25 @@ draw_ruler (const db::DPoint &q1, const db::DPoint &q2, double length_u, double }; p.assign_hull (points, points + sizeof (points) / sizeof (points [0])); renderer.draw (p, bitmap, bitmap, 0, 0); - } + + } else if (style == ant::Object::STY_cross_end || style == ant::Object::STY_cross_both) { + + db::DPolygon p; + db::DPoint points[] = { + db::DPoint (q2), + db::DPoint (q2 + qq * double (arrow_width)), + db::DPoint (q2 - qq * double (arrow_width)), + db::DPoint (q2), + db::DPoint (q2 + qu * double (arrow_width)), + db::DPoint (q2 - qu * double (arrow_width)), + }; + p.assign_hull (points, points + sizeof (points) / sizeof (points [0]), false /*don't compress*/); + renderer.draw (p, bitmap, bitmap, 0, 0); + + } if (style == ant::Object::STY_arrow_start || style == ant::Object::STY_arrow_both) { + db::DPolygon p; db::DPoint points[] = { db::DPoint (q1), @@ -214,36 +255,84 @@ draw_ruler (const db::DPoint &q1, const db::DPoint &q2, double length_u, double }; p.assign_hull (points, points + sizeof (points) / sizeof (points [0])); renderer.draw (p, bitmap, bitmap, 0, 0); + + } else if (style == ant::Object::STY_cross_start || style == ant::Object::STY_cross_both) { + + db::DPolygon p; + db::DPoint points[] = { + db::DPoint (q1), + db::DPoint (q1 + qq * double (arrow_width)), + db::DPoint (q1 - qq * double (arrow_width)), + db::DPoint (q1), + db::DPoint (q1 + qu * double (arrow_width)), + db::DPoint (q1 - qu * double (arrow_width)), + }; + p.assign_hull (points, points + sizeof (points) / sizeof (points [0]), false /*don't compress*/); + renderer.draw (p, bitmap, bitmap, 0, 0); + } // produce edge and text stuff - if (! sel) { + if (! sel && style != ant::Object::STY_none) { renderer.draw (db::DEdge (q1, q2), 0, bitmap, 0, 0); } // create three tick vectors in tv_text, tv_short and tv_long + double tf = tick_length; - db::DVector tv_text; - if (style == ant::Object::STY_arrow_start || style == ant::Object::STY_arrow_both || style == ant::Object::STY_arrow_end) { - tv_text = qq * (arrow_width * 0.5 + 2.0); - } else { - tv_text = qq * (tf + 2.0); - } db::DVector tv_short = qq * tf * 0.5; db::DVector tv_long = qq * tf; - bool text_left; - if (fabs (qq.x ()) > 1e-6) { - text_left = qq.x () > 0.0; - } else { - text_left = q2.x () < q1.x (); + db::HAlign text_halign = db::HAlignCenter; + if (halign == ant::Object::AL_auto) { + if (fabs (qq.x ()) > 1e-6) { + text_halign = qq.x () > 0.0 ? db::HAlignLeft : db::HAlignRight; + } else { + text_halign = q2.x () < q1.x () ? db::HAlignLeft : db::HAlignRight; + } + } else if (halign == ant::Object::AL_left) { + text_halign = db::HAlignLeft; + } else if (halign == ant::Object::AL_right) { + text_halign = db::HAlignRight; } - bool text_bottom; - if (fabs (qq.y ()) > 1e-6) { - text_bottom = qq.y () > 0.0; - } else { - text_bottom = q1.y () > q2.y (); + + db::VAlign text_valign = db::VAlignCenter; + if (valign == ant::Object::AL_auto) { + if (fabs (qq.y ()) > 1e-6) { + text_valign = qq.y () > 0.0 ? db::VAlignBottom : db::VAlignTop; + } else { + text_valign = q1.y () > q2.y () ? db::VAlignBottom : db::VAlignTop; + } + } else if (valign == ant::Object::AL_bottom) { + text_valign = db::VAlignBottom; + } else if (valign == ant::Object::AL_top) { + text_valign = db::VAlignTop; + } + + db::DVector tv_text; + if (style == ant::Object::STY_arrow_start || style == ant::Object::STY_arrow_both || style == ant::Object::STY_arrow_end) { + tv_text = qq * (arrow_width * 0.5 + 2.0); + } else if (style == ant::Object::STY_cross_start || style == ant::Object::STY_cross_both || style == ant::Object::STY_cross_end) { + tv_text = qq * (arrow_width + 2.0); + } else if (style == ant::Object::STY_ruler) { + tv_text = qq * (tf + 2.0); + } + + if (text_halign == db::HAlignCenter) { + tv_text.set_x (0); + } else if (text_halign == db::HAlignRight) { + tv_text.set_x (std::min (tv_text.x (), 0.0)); + } else if (text_halign == db::HAlignLeft){ + tv_text.set_x (std::max (tv_text.x (), 0.0)); + } + + if (text_valign == db::VAlignCenter) { + tv_text.set_y (0); + } else if (text_valign == db::VAlignTop) { + tv_text.set_y (std::min (tv_text.y (), 0.0)); + } else if (text_valign == db::VAlignBottom){ + tv_text.set_y (std::max (tv_text.y (), 0.0)); } if (tick_length > 0) { @@ -251,11 +340,18 @@ draw_ruler (const db::DPoint &q1, const db::DPoint &q2, double length_u, double renderer.draw (db::DEdge (q2, q2 + tv_long), 0, bitmap, 0, 0); } - renderer.draw (db::DBox (q2 + tv_text, q2 + tv_text), + db::DPoint tp = q2; + if (pos == ant::Object::POS_center) { + tp = q1 + (q2 - q1) * 0.5; + } else if (pos == ant::Object::POS_p1) { + tp = q1; + } + + renderer.draw (db::DBox (tp + tv_text, tp + tv_text), label, db::DefaultFont, - (text_left ? db::HAlignLeft : db::HAlignRight), - (text_bottom ? db::VAlignBottom : db::VAlignTop), + text_halign, + text_valign, db::DFTrans (db::DFTrans::r0), 0, 0, 0, bitmap); if (minor_ticks > 0 && ticks > 0.0) { @@ -283,7 +379,97 @@ draw_ruler (const db::DPoint &q1, const db::DPoint &q2, double length_u, double } } -void +/** + * @brief Draws an ellipse with the given parameters + * + * @param q1 The first point in pixel space + * @param q2 The second point in pixel space + * @param sel True to draw ruler in "selected" mode + * @param bitmap The bitmap to draw the ruler on + * @param renderer The renderer object + */ +void +draw_ellipse (const db::DPoint &q1, + const db::DPoint &q2, + double length_u, + bool sel, + lay::CanvasPlane *bitmap, + lay::Renderer &renderer) +{ + double sel_width = 2 / renderer.resolution (); + + if (length_u < 1e-5 /*micron*/) { + + if (sel) { + + db::DBox b (q1 - db::DVector (sel_width * 0.5, sel_width * 0.5), + q2 + db::DVector (sel_width * 0.5, sel_width * 0.5)); + + renderer.draw (b, bitmap, bitmap, 0, 0); + + } else { + renderer.draw (db::DEdge (q1, q1), 0, bitmap, 0, 0); + } + + } else { + + int npoints = 200; + + // produce polygon stuff + + if (sel) { + + double rx = fabs ((q2 - q1).x () * 0.5); + 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; + 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 ()); + + 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); + } + + } + + } + + } +} + +void draw_ruler (const ant::Object &ruler, const db::DCplxTrans &trans, bool sel, lay::CanvasPlane *bitmap, lay::Renderer &renderer) { // round the starting point, shift both, and round the end point @@ -297,32 +483,38 @@ draw_ruler (const ant::Object &ruler, const db::DCplxTrans &trans, bool sel, lay double mu = double (min_tick_spc) / trans.ctrans (1.0); if (ruler.outline () == Object::OL_diag) { - draw_ruler (q1, q2, lu, mu, ruler.text (), sel, q2.x () < q1.x (), ruler.style (), bitmap, renderer); + draw_ruler (q1, q2, lu, mu, ruler.text (), sel, q2.x () < q1.x (), ruler.style (), ruler.main_position (), ruler.main_xalign (), ruler.main_yalign (), bitmap, renderer); } if ((!xy_swapped && (ruler.outline () == Object::OL_xy || ruler.outline () == Object::OL_diag_xy)) || ( xy_swapped && (ruler.outline () == Object::OL_yx || ruler.outline () == Object::OL_diag_yx))) { bool r = (q2.x () > q1.x ()) ^ (q2.y () < q1.y ()); if (ruler.outline () == Object::OL_diag_xy || ruler.outline () == Object::OL_diag_yx) { - draw_ruler (q1, q2, lu, mu, ruler.text (), sel, !r, ruler.style (), bitmap, renderer); + draw_ruler (q1, q2, lu, mu, ruler.text (), sel, !r, ruler.style (), ruler.main_position (), ruler.main_xalign (), ruler.main_yalign (), bitmap, renderer); } - draw_ruler (q1, db::DPoint (q2.x (), q1.y ()), lu, mu, ruler.text_x (trans.fp_trans ()), sel, r, ruler.style (), bitmap, renderer); - draw_ruler (db::DPoint (q2.x (), q1.y ()), q2, lu, mu, ruler.text_y (trans.fp_trans ()), sel, r, ruler.style (), bitmap, renderer); + draw_ruler (q1, db::DPoint (q2.x (), q1.y ()), lu, mu, ruler.text_x (trans.fp_trans ()), sel, r, ruler.style (), ant::Object::POS_auto, ruler.xlabel_xalign (), ruler.xlabel_yalign (), bitmap, renderer); + draw_ruler (db::DPoint (q2.x (), q1.y ()), q2, lu, mu, ruler.text_y (trans.fp_trans ()), sel, r, ruler.style (), ant::Object::POS_auto, ruler.ylabel_xalign (), ruler.ylabel_yalign (), bitmap, renderer); } if ((!xy_swapped && (ruler.outline () == Object::OL_yx || ruler.outline () == Object::OL_diag_yx)) || ( xy_swapped && (ruler.outline () == Object::OL_xy || ruler.outline () == Object::OL_diag_xy))) { bool r = (q2.x () > q1.x ()) ^ (q2.y () > q1.y ()); if (ruler.outline () == Object::OL_diag_xy || ruler.outline () == Object::OL_diag_yx) { - draw_ruler (q1, q2, lu, mu, ruler.text (), sel, !r, ruler.style (), bitmap, renderer); + draw_ruler (q1, q2, lu, mu, ruler.text (), sel, !r, ruler.style (), ruler.main_position (), ruler.main_xalign (), ruler.main_yalign (), bitmap, renderer); } - draw_ruler (q1, db::DPoint (q1.x (), q2.y ()), lu, mu, ruler.text_y (trans.fp_trans ()), sel, r, ruler.style (), bitmap, renderer); - draw_ruler (db::DPoint (q1.x (), q2.y ()), q2, lu, mu, ruler.text_x (trans.fp_trans ()), sel, r, ruler.style (), bitmap, renderer); + draw_ruler (q1, db::DPoint (q1.x (), q2.y ()), lu, mu, ruler.text_y (trans.fp_trans ()), sel, r, ruler.style (), ant::Object::POS_auto, ruler.ylabel_xalign (), ruler.ylabel_yalign (), bitmap, renderer); + draw_ruler (db::DPoint (q1.x (), q2.y ()), q2, lu, mu, ruler.text_x (trans.fp_trans ()), sel, r, ruler.style (), ant::Object::POS_auto, ruler.xlabel_xalign (), ruler.xlabel_yalign (), bitmap, renderer); } if (ruler.outline () == Object::OL_box) { bool r = (q2.x () > q1.x ()) ^ (q2.y () < q1.y ()); - draw_ruler (q1, db::DPoint (q2.x (), q1.y ()), lu, mu, ruler.text_x (trans.fp_trans ()), sel, r, ruler.style (), bitmap, renderer); - draw_ruler (db::DPoint (q2.x (), q1.y ()), q2, lu, mu, ruler.text_y (trans.fp_trans ()), sel, r, ruler.style (), bitmap, renderer); - draw_ruler (q1, db::DPoint (q1.x (), q2.y ()), lu, mu, "", sel, !r, ruler.style (), bitmap, renderer); - draw_ruler (db::DPoint (q1.x (), q2.y ()), q2, lu, mu, ruler.text (), sel, !r, ruler.style (), bitmap, renderer); + draw_ruler (q1, db::DPoint (q2.x (), q1.y ()), lu, mu, ruler.text_x (trans.fp_trans ()), sel, 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, ruler.text_y (trans.fp_trans ()), sel, 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 (), ant::Object::POS_center, ant::Object::AL_auto, ant::Object::AL_auto, bitmap, renderer); + draw_ruler (db::DPoint (q1.x (), q2.y ()), q2, lu, mu, "", sel, !r, ruler.style (), ant::Object::POS_center, ant::Object::AL_auto, ant::Object::AL_auto, bitmap, renderer); + draw_ruler (q1, q2, lu, mu, ruler.text (), sel, !r, ant::Object::STY_none, ruler.main_position (), ruler.main_xalign (), ruler.main_yalign (), bitmap, renderer); + } else if (ruler.outline () == Object::OL_ellipse) { + draw_ruler (q1, db::DPoint (q2.x (), q1.y ()), lu, mu, ruler.text_x (trans.fp_trans ()), sel, false, ant::Object::STY_none, ant::Object::POS_center, ruler.xlabel_xalign (), ruler.xlabel_yalign (), bitmap, renderer); + draw_ruler (db::DPoint (q2.x (), q1.y ()), q2, lu, mu, ruler.text_y (trans.fp_trans ()), sel, false, ant::Object::STY_none, ant::Object::POS_center, ruler.ylabel_xalign (), ruler.ylabel_yalign (), bitmap, renderer); + draw_ruler (q1, q2, lu, mu, ruler.text (), sel, false, ant::Object::STY_none, ruler.main_position (), ruler.main_xalign (), ruler.main_yalign (), bitmap, renderer); + draw_ellipse (q1, q2, lu, sel, bitmap, renderer); } } diff --git a/src/ant/antTemplate.cc b/src/ant/antTemplate.cc index 309736a12..c55444431 100644 --- a/src/ant/antTemplate.cc +++ b/src/ant/antTemplate.cc @@ -34,7 +34,11 @@ Template::Template () : m_title (tl::to_string (QObject::tr ("Ruler"))), m_fmt_x ("$X"), m_fmt_y ("$Y"), m_fmt ("$D"), m_style (ant::Object::STY_ruler), m_outline (ant::Object::OL_diag), - m_snap (true), m_angle_constraint (lay::AC_Global) + m_snap (true), m_angle_constraint (lay::AC_Global), + m_main_position (ant::Object::POS_auto), + m_main_xalign (ant::Object::AL_auto), m_main_yalign (ant::Object::AL_auto), + m_xlabel_xalign (ant::Object::AL_auto), m_xlabel_yalign (ant::Object::AL_auto), + m_ylabel_xalign (ant::Object::AL_auto), m_ylabel_yalign (ant::Object::AL_auto) { // .. nothing yet .. } @@ -45,7 +49,11 @@ Template::Template (const std::string &title, : m_title (title), m_fmt_x (fmt_x), m_fmt_y (fmt_y), m_fmt (fmt), m_style (style), m_outline (outline), - m_snap (snap), m_angle_constraint (angle_constraint) + m_snap (snap), m_angle_constraint (angle_constraint), + m_main_position (ant::Object::POS_auto), + m_main_xalign (ant::Object::AL_auto), m_main_yalign (ant::Object::AL_auto), + m_xlabel_xalign (ant::Object::AL_auto), m_xlabel_yalign (ant::Object::AL_auto), + m_ylabel_xalign (ant::Object::AL_auto), m_ylabel_yalign (ant::Object::AL_auto) { // .. nothing else .. } @@ -54,7 +62,11 @@ Template::Template (const ant::Template &d) : m_title (d.m_title), m_fmt_x (d.m_fmt_x), m_fmt_y (d.m_fmt_y), m_fmt (d.m_fmt), m_style (d.m_style), m_outline (d.m_outline), - m_snap (d.m_snap), m_angle_constraint (d.m_angle_constraint) + m_snap (d.m_snap), m_angle_constraint (d.m_angle_constraint), + m_main_position (d.m_main_position), + m_main_xalign (d.m_main_xalign), m_main_yalign (d.m_main_yalign), + m_xlabel_xalign (d.m_xlabel_xalign), m_xlabel_yalign (d.m_xlabel_yalign), + m_ylabel_xalign (d.m_ylabel_xalign), m_ylabel_yalign (d.m_ylabel_yalign) { // .. nothing else .. } @@ -71,6 +83,13 @@ Template::operator= (const ant::Template &d) m_outline = d.m_outline; m_snap = d.m_snap; m_angle_constraint = d.m_angle_constraint; + m_main_position = d.m_main_position; + m_main_xalign = d.m_main_xalign; + m_main_yalign = d.m_main_yalign; + m_xlabel_xalign = d.m_xlabel_xalign; + m_xlabel_yalign = d.m_xlabel_yalign; + m_ylabel_xalign = d.m_ylabel_xalign; + m_ylabel_yalign = d.m_ylabel_yalign; } return *this; } @@ -118,6 +137,76 @@ Template::from_string (const std::string &s) r.back ().fmt_y (s); ex.test (","); + } else if (ex.test ("position=")) { + + std::string s; + ex.read_word (s); + ant::PositionConverter pc; + ant::Object::position_type pos; + pc.from_string (s, pos); + r.back ().set_main_position (pos); + ex.test (","); + + } else if (ex.test ("xalign=")) { + + std::string s; + ex.read_word (s); + ant::AlignmentConverter ac; + ant::Object::alignment_type a; + ac.from_string (s, a); + r.back ().set_main_xalign (a); + ex.test (","); + + } else if (ex.test ("yalign=")) { + + std::string s; + ex.read_word (s); + ant::AlignmentConverter ac; + ant::Object::alignment_type a; + ac.from_string (s, a); + r.back ().set_main_yalign (a); + ex.test (","); + + } else if (ex.test ("xlabel_xalign=")) { + + std::string s; + ex.read_word (s); + ant::AlignmentConverter ac; + ant::Object::alignment_type a; + ac.from_string (s, a); + r.back ().set_xlabel_xalign (a); + ex.test (","); + + } else if (ex.test ("xlabel_yalign=")) { + + std::string s; + ex.read_word (s); + ant::AlignmentConverter ac; + ant::Object::alignment_type a; + ac.from_string (s, a); + r.back ().set_xlabel_yalign (a); + ex.test (","); + + } else if (ex.test ("ylabel_xalign=")) { + + std::string s; + ex.read_word (s); + ant::AlignmentConverter ac; + ant::Object::alignment_type a; + ac.from_string (s, a); + r.back ().set_ylabel_xalign (a); + ex.test (","); + + } else if (ex.test ("ylabel_yalign=")) { + + std::string s; + ex.read_word (s); + ant::AlignmentConverter ac; + ant::Object::alignment_type a; + ac.from_string (s, a); + r.back ().set_ylabel_yalign (a); + ex.test (","); + } else if (ex.test ("style=")) { std::string s; @@ -200,6 +289,31 @@ Template::to_string (const std::vector