diff --git a/src/edt/edt/RoundCornerOptionsDialog.ui b/src/edt/edt/RoundCornerOptionsDialog.ui index bd9144a68..1a43d2892 100644 --- a/src/edt/edt/RoundCornerOptionsDialog.ui +++ b/src/edt/edt/RoundCornerOptionsDialog.ui @@ -1,70 +1,78 @@ - + + RoundCornerOptionsDialog - - + + 0 0 469 - 241 + 271 - + Dialog - - - - - - - - Outer corner radius + + + + + Amend mode (undo existing rounding before applying new one) - - - + + + Number of points (for full circle) - - - + + + Inner corner radius - - + + - - + + - - - + + + + Outer corner radius + + + + + + + + + Qt::Horizontal - - - + + + Radius to apply on polygon corners (Radius for inner corners can be specified separately. Leave empty to get the same radius than for outer corners) - - - + + + Qt::Vertical - + 448 11 @@ -72,29 +80,29 @@ Leave empty to get the same radius than for outer corners) - - - + + + micron - - - + + + micron - - - + + + Qt::Vertical - + QSizePolicy::Fixed - + 20 10 @@ -102,28 +110,33 @@ Leave empty to get the same radius than for outer corners) - - - + + + Qt::Horizontal - + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 5 + + + + - router_le - label - label_2 - label_3 - rinner_le - points_le - line - label_4 - label_5 - label_6 - buttonBox @@ -133,11 +146,11 @@ Leave empty to get the same radius than for outer corners) RoundCornerOptionsDialog accept() - + 248 254 - + 157 274 @@ -149,11 +162,11 @@ Leave empty to get the same radius than for outer corners) RoundCornerOptionsDialog reject() - + 316 260 - + 286 274 diff --git a/src/edt/edt/edtDialogs.cc b/src/edt/edt/edtDialogs.cc index b1a932cba..ae20ad27e 100644 --- a/src/edt/edt/edtDialogs.cc +++ b/src/edt/edt/edtDialogs.cc @@ -414,11 +414,13 @@ MakeCellOptionsDialog::button_clicked () // RoundCornerOptionsDialog implementation RoundCornerOptionsDialog::RoundCornerOptionsDialog (QWidget *parent) - : QDialog (parent), mp_layout (0) + : QDialog (parent), mp_layout (0), m_router_extracted (0.0), m_rinner_extracted (0.0), m_npoints_extracted (64), m_has_extracted (false) { setObjectName (QString::fromUtf8 ("round_corners_options_dialog")); Ui::RoundCornerOptionsDialog::setupUi (this); + + connect (amend_cb, SIGNAL (stateChanged (int)), this, SLOT (amend_changed ())); } RoundCornerOptionsDialog::~RoundCornerOptionsDialog () @@ -426,21 +428,51 @@ RoundCornerOptionsDialog::~RoundCornerOptionsDialog () // .. nothing yet .. } -bool -RoundCornerOptionsDialog::exec_dialog (const db::Layout &layout, double &router, double &rinner, unsigned int &npoints) +void +RoundCornerOptionsDialog::amend_changed () { + if (amend_cb->isChecked () && m_has_extracted) { + router_le->setText (tl::to_qstring (tl::to_string (m_router_extracted))); + if (db::coord_traits::equal (m_router_extracted, m_rinner_extracted)) { + rinner_le->setText (QString ()); + } else { + rinner_le->setText (tl::to_qstring (tl::to_string (m_rinner_extracted))); + } + points_le->setText (tl::to_qstring (tl::to_string (m_npoints_extracted))); + } +} + +bool +RoundCornerOptionsDialog::exec_dialog (const db::Layout &layout, double &router, double &rinner, unsigned int &npoints, bool &undo_before_apply, double router_extracted, double rinner_extracted, unsigned int npoints_extracted, bool has_extracted) +{ + m_router_extracted = router_extracted; + m_rinner_extracted = rinner_extracted; + m_npoints_extracted = npoints_extracted; + m_has_extracted = has_extracted; + + amend_cb->blockSignals (true); + amend_cb->setEnabled (has_extracted); + amend_cb->setChecked (undo_before_apply && has_extracted); + amend_cb->blockSignals (false); + mp_layout = &layout; - router_le->setText (tl::to_qstring (tl::to_string (router))); - if (fabs (router - rinner) < 1e-6) { + double ro = undo_before_apply && has_extracted ? router_extracted : router; + double ri = undo_before_apply && has_extracted ? rinner_extracted : rinner; + unsigned int n = undo_before_apply && has_extracted ? npoints_extracted : npoints; + + router_le->setText (tl::to_qstring (tl::to_string (ro))); + if (db::coord_traits::equal (ro, ri)) { rinner_le->setText (QString ()); } else { - rinner_le->setText (tl::to_qstring (tl::to_string (rinner))); + rinner_le->setText (tl::to_qstring (tl::to_string (ri))); } - points_le->setText (tl::to_qstring (tl::to_string (npoints))); + points_le->setText (tl::to_qstring (tl::to_string (n))); if (QDialog::exec ()) { + undo_before_apply = m_has_extracted && amend_cb->isChecked (); + tl::from_string (tl::to_string (router_le->text ()), router); if (rinner_le->text ().isEmpty ()) { rinner = router; diff --git a/src/edt/edt/edtDialogs.h b/src/edt/edt/edtDialogs.h index 165cc650a..e7d8d6258 100644 --- a/src/edt/edt/edtDialogs.h +++ b/src/edt/edt/edtDialogs.h @@ -173,12 +173,18 @@ public: RoundCornerOptionsDialog (QWidget *parent); ~RoundCornerOptionsDialog (); - bool exec_dialog (const db::Layout &layout, double &rhull, double &rholes, unsigned int &npoints); + bool exec_dialog (const db::Layout &layout, double &router, double &rinner, unsigned int &npoints, bool &undo_before_apply, double router_extracted, double rinner_extracted, unsigned int npoints_extracted, bool has_extracted); virtual void accept (); +private slots: + void amend_changed (); + private: const db::Layout *mp_layout; + double m_router_extracted, m_rinner_extracted; + unsigned int m_npoints_extracted; + bool m_has_extracted; }; } // namespace edt diff --git a/src/edt/edt/edtMainService.cc b/src/edt/edt/edtMainService.cc index 5e572fc5b..67d3fd24d 100644 --- a/src/edt/edt/edtMainService.cc +++ b/src/edt/edt/edtMainService.cc @@ -60,7 +60,13 @@ MainService::MainService (db::Manager *manager, lay::LayoutView *view, lay::Plug m_align_hmode (0), m_align_vmode (0), m_align_visible_layers (false), m_origin_mode_x (-1), m_origin_mode_y (-1), m_origin_visible_layers_for_bbox (false), m_array_a (0.0, 1.0), m_array_b (1.0, 0.0), - m_array_na (1), m_array_nb (1) + m_array_na (1), m_array_nb (1), + m_router (0.0), m_rinner (0.0), m_npoints (64), m_undo_before_apply (true), + mp_round_corners_dialog (0), + mp_align_options_dialog (0), + mp_flatten_inst_options_dialog (0), + mp_make_cell_options_dialog (0), + mp_make_array_options_dialog (0) { // .. nothing yet .. } @@ -70,7 +76,52 @@ MainService::~MainService () // .. nothing yet .. } -void +edt::RoundCornerOptionsDialog * +MainService::round_corners_dialog () +{ + if (! mp_round_corners_dialog) { + mp_round_corners_dialog = new edt::RoundCornerOptionsDialog (view ()); + } + return mp_round_corners_dialog; +} + +edt::AlignOptionsDialog * +MainService::align_options_dialog () +{ + if (! mp_align_options_dialog) { + mp_align_options_dialog = new edt::AlignOptionsDialog (view ()); + } + return mp_align_options_dialog; +} + +lay::FlattenInstOptionsDialog * +MainService::flatten_inst_options_dialog () +{ + if (! mp_flatten_inst_options_dialog) { + mp_flatten_inst_options_dialog = new lay::FlattenInstOptionsDialog (view (), false /*don't allow prunining*/); + } + return mp_flatten_inst_options_dialog; +} + +edt::MakeCellOptionsDialog * +MainService::make_cell_options_dialog () +{ + if (! mp_make_cell_options_dialog) { + mp_make_cell_options_dialog = new edt::MakeCellOptionsDialog (view ()); + } + return mp_make_cell_options_dialog; +} + +edt::MakeArrayOptionsDialog * +MainService::make_array_options_dialog () +{ + if (! mp_make_array_options_dialog) { + mp_make_array_options_dialog = new edt::MakeArrayOptionsDialog (view ()); + } + return mp_make_array_options_dialog; +} + +void MainService::menu_activated (const std::string &symbol) { if (symbol == "edt::descend") { @@ -318,9 +369,7 @@ MainService::cm_flatten_insts () tl_assert (view ()->is_editable ()); check_no_guiding_shapes (); - lay::FlattenInstOptionsDialog options_dialog (view (), false /*don't allow prunining*/); - - if (options_dialog.exec_dialog (m_flatten_insts_levels, m_flatten_prune) && m_flatten_insts_levels != 0) { + if (flatten_inst_options_dialog ()->exec_dialog (m_flatten_insts_levels, m_flatten_prune) && m_flatten_insts_levels != 0) { view ()->cancel_edits (); @@ -908,11 +957,9 @@ MainService::cm_make_cell () if (cv_index >= 0) { - MakeCellOptionsDialog dialog (view ()); - const lay::CellView &cv = view ()->cellview (cv_index); - if (dialog.exec_dialog (cv->layout (), m_make_cell_name, m_origin_mode_x, m_origin_mode_y)) { + if (make_cell_options_dialog ()->exec_dialog (cv->layout (), m_make_cell_name, m_origin_mode_x, m_origin_mode_y)) { // Compute the selection's bbox to establish a good origin for the new cell db::Box selection_bbox; @@ -1231,9 +1278,10 @@ MainService::cm_convert_to_pcell () } } -static void extract_rad (std::vector &poly, double &rinner, double &router, unsigned int &n) +static bool extract_rad (std::vector &poly, double &rinner, double &router, unsigned int &n) { std::vector new_pts; + bool any_extracted = false; for (std::vector::iterator p = poly.begin (); p != poly.end (); ++p) { @@ -1246,6 +1294,7 @@ static void extract_rad (std::vector &poly, double &rinner, double new_poly.assign_hull (p->begin_hull (), p->end_hull (), false /*don't compress*/); } else { new_poly.assign_hull (new_pts.begin (), new_pts.end (), true /*compress*/); + any_extracted = true; } for (unsigned int h = 0; h < p->holes (); ++h) { @@ -1257,13 +1306,16 @@ static void extract_rad (std::vector &poly, double &rinner, double new_poly.insert_hole (p->begin_hole (h), p->end_hole (h), false /*don't compress*/); } else { new_poly.insert_hole (new_pts.begin (), new_pts.end (), true /*compress*/); + any_extracted = true; } } p->swap (new_poly); - } + } + + return any_extracted; } void @@ -1310,15 +1362,17 @@ MainService::cm_round_corners () // prepare: merge to remove cutlines and smooth to remove effects of cutlines db::EdgeProcessor ep; - std::vector out; - ep.merge (primary, out, 0 /*min_wc*/, false /*resolve holes*/, true /*min coherence*/); - for (std::vector ::iterator p = out.begin (); p != out.end (); ++p) { + std::vector in; + ep.merge (primary, in, 0 /*min_wc*/, false /*resolve holes*/, true /*min coherence*/); + for (std::vector ::iterator p = in.begin (); p != in.end (); ++p) { *p = smooth (*p, 1); } + std::vector out = in; + unsigned int n = 100; double rinner = 0.0, router = 0.0; - extract_rad (out, rinner, router, n); + bool has_extracted = extract_rad (out, rinner, router, n); const lay::CellView &cv = view ()->cellview (cv_index); double dbu = cv->layout ().dbu (); @@ -1326,13 +1380,16 @@ MainService::cm_round_corners () rinner *= dbu; router *= dbu; - RoundCornerOptionsDialog dialog (view ()); - if (! dialog.exec_dialog (cv->layout (), router, rinner, n)) { + if (! round_corners_dialog ()->exec_dialog (cv->layout (), m_router, m_rinner, m_npoints, m_undo_before_apply, router, rinner, n, has_extracted)) { return; } + if (! m_undo_before_apply || ! has_extracted) { + out.swap (in); + } + for (std::vector ::iterator p = out.begin (); p != out.end (); ++p) { - *p = compute_rounded (*p, rinner / dbu, router / dbu, n); + *p = compute_rounded (*p, m_rinner / dbu, m_router / dbu, m_npoints); } // remove holes (result in primary) @@ -1700,8 +1757,7 @@ MainService::cm_align () std::vector edt_services = view ()->get_plugins (); - AlignOptionsDialog dialog (view ()); - if (! dialog.exec_dialog (view (), m_align_hmode, m_align_vmode, m_align_visible_layers)) { + if (! align_options_dialog ()->exec_dialog (view (), m_align_hmode, m_align_vmode, m_align_visible_layers)) { return; } @@ -1797,9 +1853,7 @@ MainService::cm_make_array () throw tl::Exception (tl::to_string (QObject::tr ("Nothing selected to make arrays of"))); } - MakeArrayOptionsDialog dialog (view ()); - - if (dialog.exec_dialog (m_array_a, m_array_na, m_array_b, m_array_nb)) { + if (make_array_options_dialog ()->exec_dialog (m_array_a, m_array_na, m_array_b, m_array_nb)) { view ()->cancel_edits (); diff --git a/src/edt/edt/edtMainService.h b/src/edt/edt/edtMainService.h index 67aa8755d..3c6331c08 100644 --- a/src/edt/edt/edtMainService.h +++ b/src/edt/edt/edtMainService.h @@ -39,6 +39,7 @@ namespace lay { class PluginRoot; + class FlattenInstOptionsDialog; } namespace edt { @@ -46,6 +47,10 @@ namespace edt { class Service; class EditorOptionsPages; class EditorOptionsPage; +class RoundCornerOptionsDialog; +class MakeCellOptionsDialog; +class MakeArrayOptionsDialog; +class AlignOptionsDialog; // ------------------------------------------------------------- @@ -205,9 +210,22 @@ private: bool m_origin_visible_layers_for_bbox; db::DVector m_array_a, m_array_b; unsigned int m_array_na, m_array_nb; + double m_router, m_rinner; + unsigned int m_npoints; + bool m_undo_before_apply; + edt::RoundCornerOptionsDialog *mp_round_corners_dialog; + edt::AlignOptionsDialog *mp_align_options_dialog; + lay::FlattenInstOptionsDialog *mp_flatten_inst_options_dialog; + edt::MakeCellOptionsDialog *mp_make_cell_options_dialog; + edt::MakeArrayOptionsDialog *mp_make_array_options_dialog; void boolean_op (int mode); void check_no_guiding_shapes (); + edt::RoundCornerOptionsDialog *round_corners_dialog (); + edt::AlignOptionsDialog *align_options_dialog (); + lay::FlattenInstOptionsDialog *flatten_inst_options_dialog (); + edt::MakeCellOptionsDialog *make_cell_options_dialog (); + edt::MakeArrayOptionsDialog *make_array_options_dialog (); }; }