WIP: some rework, targetting proper use of recent attributes when entering an editor tool

This commit is contained in:
Matthias Koefferlein 2025-08-21 21:56:15 +02:00
parent 9137919894
commit 59432fb6ed
6 changed files with 133 additions and 160 deletions

View File

@ -33,6 +33,9 @@
#include "layFinder.h"
#include "layLayoutView.h"
#include "laySnap.h"
#if defined(HAVE_QT)
# include "layEditorOptionsPages.h"
#endif
#include "tlProgress.h"
#include "tlTimer.h"
@ -2014,6 +2017,23 @@ Service::handle_guiding_shape_changes (bool commit)
}
}
void
Service::commit_recent ()
{
#if defined(HAVE_QT)
lay::EditorOptionsPages *eo_pages = view ()->editor_options_pages ();
if (!eo_pages) {
return;
}
for (std::vector<lay::EditorOptionsPage *>::const_iterator op = eo_pages->pages ().begin (); op != eo_pages->pages ().end (); ++op) {
if ((*op)->plugin_declaration () == plugin_declaration ()) {
(*op)->commit_recent (view ());
}
}
#endif
}
// -------------------------------------------------------------
// Implementation of EditableSelectionIterator

View File

@ -648,6 +648,11 @@ protected:
return m_mouse_pos;
}
/**
* @brief Commits the current configuration to the recent attributes list
*/
void commit_recent ();
/**
* @brief Point snapping with detailed return value
*/

View File

@ -44,6 +44,7 @@
# include "layTipDialog.h"
# include "layDragDropData.h"
# include "layBusy.h"
# include "layEditorOptionsPages.h"
#endif
#if defined(HAVE_QT)
@ -79,24 +80,48 @@ ShapeEditService::activated ()
{
edt::Service::activated ();
#if defined(HAVE_QT)
if (view () == lay::LayoutView::current ()) {
lay::LayerPropertiesConstIterator cl = view ()->current_layer ();
if (! cl.is_null () && ! cl->visible (true)) {
lay::TipDialog td (QApplication::activeWindow (),
tl::to_string (tr ("You are about to draw on a hidden layer. The result won't be visible.")),
"drawing-on-invisible-layer");
td.exec_dialog ();
update_edit_layer (cl);
}
}
void
ShapeEditService::config_recent_for_layer (const db::LayerProperties &lp, int cv_index)
{
if (lp.is_null ()) {
return;
}
#if defined(HAVE_QT)
lay::EditorOptionsPages *eo_pages = view ()->editor_options_pages ();
if (!eo_pages) {
return;
}
for (std::vector<lay::EditorOptionsPage *>::const_iterator op = eo_pages->pages ().begin (); op != eo_pages->pages ().end (); ++op) {
if ((*op)->plugin_declaration () == plugin_declaration ()) {
(*op)->config_recent_for_layer (dispatcher (), lp, cv_index);
}
}
#endif
}
void
ShapeEditService::get_edit_layer ()
{
lay::LayerPropertiesConstIterator cl = view ()->current_layer ();
#if defined(HAVE_QT)
if (! cl->visible (true)) {
lay::TipDialog td (QApplication::activeWindow (),
tl::to_string (tr ("You are now drawing on a hidden layer. The result won't be visible.")),
"drawing-on-invisible-layer");
td.exec_dialog ();
}
#endif
if (cl.is_null ()) {
throw tl::Exception (tl::to_string (tr ("Please select a layer first")));
} else if (! cl->valid (true)) {
@ -105,12 +130,12 @@ ShapeEditService::get_edit_layer ()
int cv_index = cl->cellview_index ();
const lay::CellView &cv = view ()->cellview (cv_index);
int layer = cl->layer_index ();
if (cv_index < 0 || ! cv.is_valid ()) {
throw tl::Exception (tl::to_string (tr ("Please select a cell first")));
}
int layer = cl->layer_index ();
if (layer < 0 || ! cv->layout ().is_valid_layer ((unsigned int) layer)) {
if (cl->has_children ()) {
@ -120,13 +145,7 @@ ShapeEditService::get_edit_layer ()
// create this layer now
const lay::ParsedLayerSource &source = cl->source (true /*real*/);
db::LayerProperties db_lp;
if (source.has_name ()) {
db_lp.name = source.name ();
}
db_lp.layer = source.layer ();
db_lp.datatype = source.datatype ();
db::LayerProperties db_lp = source.layer_props ();
cv->layout ().insert_layer (db_lp);
// update the layer index inside the layer view
@ -152,7 +171,6 @@ ShapeEditService::get_edit_layer ()
// fetches the last configuration for the given layer
view ()->set_active_cellview_index (cv_index);
edt::config_recent_for_layer (view (), dispatcher (), cv->layout ().get_properties ((unsigned int) layer), cv_index);
}
void
@ -172,7 +190,7 @@ ShapeEditService::change_edit_layer (const db::LayerProperties &lp)
// fetches the last configuration for the given layer
view ()->set_active_cellview_index (m_cv_index);
edt::config_recent_for_layer (view (), dispatcher (), lp, m_cv_index);
config_recent_for_layer (lp, m_cv_index);
}
void
@ -216,70 +234,59 @@ ShapeEditService::update_edit_layer (const lay::LayerPropertiesConstIterator &cl
return;
}
if (! editing ()) {
return;
}
if (cl.is_null () || cl->has_children ()) {
return;
}
int cv_index = cl->cellview_index ();
const lay::CellView &cv = view ()->cellview (cv_index);
int layer = cl->layer_index ();
if (cv_index < 0 || ! cv.is_valid ()) {
return;
}
if (cv.cell ()->is_proxy ()) {
return;
}
#if defined(HAVE_QT)
if (! cl->visible (true)) {
lay::TipDialog td (QApplication::activeWindow (),
tl::to_string (tr ("You are now drawing on a hidden layer. The result won't be visible.")),
"drawing-on-invisible-layer");
td.exec_dialog ();
}
#endif
if (layer < 0 || ! cv->layout ().is_valid_layer ((unsigned int) layer)) {
// create this layer now
const lay::ParsedLayerSource &source = cl->source (true /*real*/);
db::LayerProperties db_lp;
if (source.has_name ()) {
db_lp.name = source.name ();
}
db_lp.layer = source.layer ();
db_lp.datatype = source.datatype ();
cv->layout ().insert_layer (db_lp);
// update the layer index inside the layer view
cl->realize_source ();
// Hint: we could have taken the new index from insert_layer, but this
// is a nice test:
layer = cl->layer_index ();
tl_assert (layer >= 0);
}
m_layer = (unsigned int) layer;
m_cv_index = (unsigned int) cv_index;
m_trans = (cl->trans ().front () * db::CplxTrans (cv->layout ().dbu ()) * cv.context_trans ()).inverted ();
mp_layout = &(cv->layout ());
mp_cell = cv.cell ();
// fetches the last configuration for the given layer
view ()->set_active_cellview_index (cv_index);
edt::config_recent_for_layer (view (), dispatcher (), cv->layout ().get_properties ((unsigned int) layer), cv_index);
current_layer_changed ();
const lay::ParsedLayerSource &source = cl->source (true /*real*/);
int layer = cl->layer_index ();
db::LayerProperties db_lp = source.layer_props ();
if (! editing ()) {
if (layer < 0 || ! cv->layout ().is_valid_layer ((unsigned int) layer)) {
config_recent_for_layer (db_lp, cv_index);
} else {
config_recent_for_layer (cv->layout ().get_properties ((unsigned int) layer), cv_index);
}
} else {
if (layer < 0 || ! cv->layout ().is_valid_layer ((unsigned int) layer)) {
// create this layer now
cv->layout ().insert_layer (db_lp);
// update the layer index inside the layer view
cl->realize_source ();
// Hint: we could have taken the new index from insert_layer, but this
// is a nice test:
layer = cl->layer_index ();
tl_assert (layer >= 0);
}
m_layer = (unsigned int) layer;
m_cv_index = (unsigned int) cv_index;
m_trans = (cl->trans ().front () * db::CplxTrans (cv->layout ().dbu ()) * cv.context_trans ()).inverted ();
mp_layout = &(cv->layout ());
mp_cell = cv.cell ();
// fetches the last configuration for the given layer
config_recent_for_layer (cv->layout ().get_properties ((unsigned int) layer), cv_index);
current_layer_changed ();
}
}
void
@ -600,7 +607,7 @@ void
PolygonService::do_finish_edit ()
{
deliver_shape (get_polygon (false));
commit_recent (view ());
commit_recent ();
close_editor_hooks (true);
}
@ -939,7 +946,7 @@ void
BoxService::do_finish_edit ()
{
deliver_shape (get_box ());
commit_recent (view ());
commit_recent ();
close_editor_hooks (true);
}
@ -1050,7 +1057,7 @@ void
PointService::do_finish_edit ()
{
deliver_shape (get_point ());
commit_recent (view ());
commit_recent ();
close_editor_hooks (true);
}
@ -1199,7 +1206,7 @@ TextService::do_finish_edit ()
manager ()->commit ();
}
commit_recent (view ());
commit_recent ();
#if defined(HAVE_QT)
if (! view ()->text_visible ()) {
@ -1418,7 +1425,7 @@ PathService::do_finish_edit ()
deliver_shape (get_path ());
commit_recent (view ());
commit_recent ();
close_editor_hooks (true);
}
@ -1566,6 +1573,26 @@ PathService::get_via_for (const db::LayerProperties &lp, unsigned int cv_index,
return true;
}
db::Instance
PathService::make_via (const db::SelectedViaDefinition &via_def, double w_bottom, double h_bottom, double w_top, double h_top, const db::DPoint &via_pos)
{
if (! via_def.via_type.cut.is_null ()) {
edt::set_or_request_current_layer (view (), via_def.via_type.cut, cv_index (), false /*don't make current*/);
}
std::map<std::string, tl::Variant> params;
params.insert (std::make_pair ("via", tl::Variant (via_def.via_type.name)));
params.insert (std::make_pair ("w_bottom", tl::Variant (w_bottom)));
params.insert (std::make_pair ("w_top", tl::Variant (w_top)));
params.insert (std::make_pair ("h_bottom", tl::Variant (h_bottom)));
params.insert (std::make_pair ("h_top", tl::Variant (h_top)));
auto via_lib_cell = via_def.lib->layout ().get_pcell_variant_dict (via_def.pcell, params);
auto via_cell = layout ().get_lib_proxy (via_def.lib, via_lib_cell);
return cell ().insert (db::CellInstArray (db::CellInst (via_cell), db::Trans (trans () * via_pos - db::Point ())));
}
void
PathService::via_initial (int dir)
{
@ -1612,30 +1639,11 @@ PathService::via_initial (int dir)
change_edit_layer (lp_new);
begin_edit (pos);
db::DPoint via_pos = m_last;
// create the via cell
// (using 0.0 for all dimensions to indicate "place here")
db::Instance via_instance = make_via (via_def, 0.0, 0.0, 0.0, 0.0, m_last);
double w_bottom = 0.0, h_bottom = 0.0, w_top = 0.0, h_top = 0.0;
std::map<std::string, tl::Variant> params;
params.insert (std::make_pair ("via", tl::Variant (via_def.via_type.name)));
params.insert (std::make_pair ("w_bottom", tl::Variant (w_bottom)));
params.insert (std::make_pair ("w_top", tl::Variant (w_top)));
params.insert (std::make_pair ("h_bottom", tl::Variant (h_bottom)));
params.insert (std::make_pair ("h_top", tl::Variant (h_top)));
auto via_lib_cell = via_def.lib->layout ().get_pcell_variant_dict (via_def.pcell, params);
auto via_cell = layout ().get_lib_proxy (via_def.lib, via_lib_cell);
db::Instance via_instance = cell ().insert (db::CellInstArray (db::CellInst (via_cell), db::Trans (trans () * via_pos - db::Point ())));
push_segment (db::Shape (), via_instance, via_def.via_type, transaction.id ());
if (! via_def.via_type.cut.is_null ()) {
edt::set_or_request_current_layer (view (), via_def.via_type.cut, cv_index (), false /*don't make current*/);
}
}
}
@ -1654,10 +1662,7 @@ PathService::via_editing (int dir)
return;
}
commit_recent (view ());
// produce the path up to the current point
db::DPoint via_pos = m_points.back ();
commit_recent ();
bool is_bottom = via_def.via_type.bottom.log_equal (lp);
db::LayerProperties lp_new = is_bottom ? via_def.via_type.top : via_def.via_type.bottom;
@ -1673,30 +1678,18 @@ PathService::via_editing (int dir)
(is_bottom ? h_bottom : h_top) = m_width;
}
// create the via cell
// create the path and via
std::map<std::string, tl::Variant> params;
params.insert (std::make_pair ("via", tl::Variant (via_def.via_type.name)));
params.insert (std::make_pair ("w_bottom", tl::Variant (w_bottom)));
params.insert (std::make_pair ("w_top", tl::Variant (w_top)));
params.insert (std::make_pair ("h_bottom", tl::Variant (h_bottom)));
params.insert (std::make_pair ("h_top", tl::Variant (h_top)));
db::DPoint via_pos = m_points.back ();
{
db::Transaction transaction (manager (), tl::to_string (tr ("Create path segment")));
db::Shape path_shape = cell ().shapes (layer ()).insert (get_path ());
db::Instance via_instance = make_via (via_def, w_bottom, h_bottom, w_top, h_top, via_pos);
auto via_lib_cell = via_def.lib->layout ().get_pcell_variant_dict (via_def.pcell, params);
auto via_cell = layout ().get_lib_proxy (via_def.lib, via_lib_cell);
db::Instance via_instance = cell ().insert (db::CellInstArray (db::CellInst (via_cell), db::Trans (trans () * via_pos - db::Point ())));
push_segment (path_shape, via_instance, via_def.via_type, transaction.id ());
if (! via_def.via_type.cut.is_null ()) {
edt::set_or_request_current_layer (view (), via_def.via_type.cut, cv_index (), false /*don't make current*/);
}
change_edit_layer (lp_new);
}
@ -2300,7 +2293,7 @@ InstService::do_finish_edit ()
manager ()->commit ();
}
commit_recent (view ());
commit_recent ();
if (m_in_drag_drop) {

View File

@ -77,6 +77,7 @@ protected:
void deliver_shape_to_hooks (const Shape &shape);
void close_editor_hooks (bool with_commit);
combine_mode_type combine_mode () const { return m_combine_mode; }
void config_recent_for_layer (const db::LayerProperties &lp, int cv_index);
const tl::weak_collection<edt::EditorHooks> &editor_hooks ()
{
@ -274,6 +275,7 @@ private:
db::Path get_path () const;
void set_last_point (const db::DPoint &p);
void update_via ();
db::Instance make_via (const db::SelectedViaDefinition &via_def, double w_bottom, double h_bottom, double w_top, double h_top, const db::DPoint &via_pos);
void via_initial (int dir);
void via_editing (int dir);
bool get_via_for (const db::LayerProperties &lp, unsigned int cv_index, int dir, db::SelectedViaDefinition &via_def);

View File

@ -31,7 +31,6 @@
#include "layCellView.h"
#include "layLayoutViewBase.h"
#include "layEditable.h"
#include "layEditorOptionsPages.h"
#include "tlException.h"
#if defined(HAVE_QT)
@ -79,40 +78,6 @@ std::map<std::string, tl::Variant> pcell_parameters_from_string (const std::stri
return pm;
}
void
commit_recent (lay::LayoutViewBase *view)
{
#if defined(HAVE_QT)
lay::EditorOptionsPages *eo_pages = view->editor_options_pages ();
if (!eo_pages) {
return;
}
for (std::vector<lay::EditorOptionsPage *>::const_iterator op = eo_pages->pages ().begin (); op != eo_pages->pages ().end (); ++op) {
if ((*op)->active ()) {
(*op)->commit_recent (view);
}
}
#endif
}
void
config_recent_for_layer (lay::LayoutViewBase *view, lay::Dispatcher *dispatcher, const db::LayerProperties &lp, int cv_index)
{
#if defined(HAVE_QT)
lay::EditorOptionsPages *eo_pages = view->editor_options_pages ();
if (!eo_pages) {
return;
}
for (std::vector<lay::EditorOptionsPage *>::const_iterator op = eo_pages->pages ().begin (); op != eo_pages->pages ().end (); ++op) {
if ((*op)->active ()) {
(*op)->config_recent_for_layer (dispatcher, lp, cv_index);
}
}
#endif
}
bool
set_or_request_current_layer (lay::LayoutViewBase *view, const db::LayerProperties &lp, unsigned int cv_index, bool make_current)
{

View File

@ -68,18 +68,6 @@ bool
get_parameters_from_pcell_and_guiding_shapes (db::Layout *layout, db::cell_index_type cell_index, db::pcell_parameters_type &parameters_for_pcell);
/**
* @brief Commits the current configuration for the recently used configuration list
*/
void
commit_recent (lay::LayoutViewBase *view);
/**
* @brief Configure attributes for the most-recent entry with the given layer
*/
void
config_recent_for_layer (lay::LayoutViewBase *view, lay::Dispatcher *dispatcher, const db::LayerProperties &lp, int cv_index);
/**
* @brief Request to make the given layer the current one (asks whether to create the layer if needed)
*/