Implementing change of layer accross all shape types

Plus: simplify behavior of "change all" button, so it
is not turned on or off.
This commit is contained in:
Matthias Koefferlein 2025-12-02 00:05:38 +01:00
parent 78b62e13d1
commit cdaf34cd77
8 changed files with 80 additions and 15 deletions

View File

@ -120,6 +120,12 @@ db::Instance ChangePropertiesApplicator::do_apply_inst (db::Cell &cell, const db
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// ChangeLayerApplicator implementation // ChangeLayerApplicator implementation
ChangeLayerApplicator::ChangeLayerApplicator (const ChangeLayerApplicator &other)
: ChangeApplicator (), m_cv_index (other.m_cv_index), m_new_layer (other.m_new_layer), m_skipped_layers (other.m_skipped_layers)
{
// .. nothing yet ...
}
ChangeLayerApplicator::ChangeLayerApplicator (unsigned int cv_index, unsigned int new_layer) ChangeLayerApplicator::ChangeLayerApplicator (unsigned int cv_index, unsigned int new_layer)
: m_cv_index (cv_index), m_new_layer (new_layer) : m_cv_index (cv_index), m_new_layer (new_layer)
{ {

View File

@ -121,6 +121,7 @@ class ChangeLayerApplicator
: public ChangeApplicator : public ChangeApplicator
{ {
public: public:
ChangeLayerApplicator (const ChangeLayerApplicator &other);
ChangeLayerApplicator (unsigned int cv_index, unsigned int new_layer); ChangeLayerApplicator (unsigned int cv_index, unsigned int new_layer);
bool supports_relative_mode () const { return false; } bool supports_relative_mode () const { return false; }

View File

@ -261,6 +261,7 @@ ShapePropertiesPage::do_apply (bool current_only, bool relative, bool commit)
} }
std::unique_ptr<ChangeApplicator> applicator; std::unique_ptr<ChangeApplicator> applicator;
std::unique_ptr<ChangeApplicator> other_applicator;
unsigned int cv_index = m_selection_ptrs [m_indexes.front ()]->cv_index (); unsigned int cv_index = m_selection_ptrs [m_indexes.front ()]->cv_index ();
@ -277,6 +278,9 @@ ShapePropertiesPage::do_apply (bool current_only, bool relative, bool commit)
if (m_prop_id != pos->shape ().prop_id ()) { if (m_prop_id != pos->shape ().prop_id ()) {
applicator.reset (new CombinedChangeApplicator (applicator.release (), new ChangePropertiesApplicator (m_prop_id))); applicator.reset (new CombinedChangeApplicator (applicator.release (), new ChangePropertiesApplicator (m_prop_id)));
if (! current_only) {
other_applicator.reset (new ChangePropertiesApplicator (m_prop_id));
}
} }
int new_layer = layer_selector ()->current_layer (); int new_layer = layer_selector ()->current_layer ();
@ -285,6 +289,9 @@ ShapePropertiesPage::do_apply (bool current_only, bool relative, bool commit)
ChangeLayerApplicator *cla = new ChangeLayerApplicator (cv_index, (unsigned int) new_layer); ChangeLayerApplicator *cla = new ChangeLayerApplicator (cv_index, (unsigned int) new_layer);
cla->skip_layer (gs_layer); cla->skip_layer (gs_layer);
applicator.reset (new CombinedChangeApplicator (applicator.release (), cla)); applicator.reset (new CombinedChangeApplicator (applicator.release (), cla));
if (! current_only) {
other_applicator.reset (new CombinedChangeApplicator (other_applicator.release (), new ChangeLayerApplicator (*cla)));
}
} }
} }
@ -292,6 +299,29 @@ ShapePropertiesPage::do_apply (bool current_only, bool relative, bool commit)
return; return;
} }
apply_change (applicator.get (), cv_index, current_only, relative, commit);
if (other_applicator.get () && page_set ()) {
// apply to other pages
auto pages = page_set ()->properties_pages ();
for (auto p = pages.begin (); p != pages.end (); ++p) {
ShapePropertiesPage *sp = dynamic_cast<ShapePropertiesPage *> (*p);
if (sp && sp != this) {
sp->apply_change (other_applicator.get (), cv_index, current_only, relative, commit);
}
}
}
}
void
ShapePropertiesPage::apply_change (const ChangeApplicator *applicator, unsigned int cv_index, bool current_only, bool relative, bool commit)
{
if (m_indexes.empty ()) {
return;
}
// Ask whether to use relative or absolute mode // Ask whether to use relative or absolute mode
bool relative_mode = false; bool relative_mode = false;
if (! current_only && applicator->supports_relative_mode ()) { if (! current_only && applicator->supports_relative_mode ()) {

View File

@ -68,8 +68,9 @@ private:
virtual void apply (bool commit); virtual void apply (bool commit);
virtual void apply_to_all (bool relative, bool commit); virtual void apply_to_all (bool relative, bool commit);
virtual bool can_apply_to_all () const; virtual bool can_apply_to_all () const;
virtual void do_apply (bool current_only, bool relative, bool commit); void do_apply (bool current_only, bool relative, bool commit);
void recompute_selection_ptrs (const std::vector<lay::ObjectInstPath> &new_sel); void recompute_selection_ptrs (const std::vector<lay::ObjectInstPath> &new_sel);
void apply_change (const ChangeApplicator *applicator, unsigned int cv_index, bool current_only, bool relative, bool commit);
protected: protected:
std::string m_description; std::string m_description;

View File

@ -28,7 +28,7 @@ namespace lay
{ {
PropertiesPage::PropertiesPage (QWidget *parent, db::Manager *manager, lay::Editable *editable) PropertiesPage::PropertiesPage (QWidget *parent, db::Manager *manager, lay::Editable *editable)
: QFrame (parent), mp_manager (manager), mp_editable (editable) : QFrame (parent), mp_manager (manager), mp_editable (editable), mp_page_set (0)
{ {
// .. nothing else .. // .. nothing else ..
} }

View File

@ -41,6 +41,16 @@ namespace lay
class Editable; class Editable;
/**
* @brief An interface delivering all properties pages
*/
class LAYBASIC_PUBLIC PropertiesPageSet
{
public:
virtual ~PropertiesPageSet () { }
virtual const std::vector<lay::PropertiesPage *> &properties_pages () const = 0;
};
/** /**
* @brief The properties page object * @brief The properties page object
* *
@ -211,6 +221,22 @@ public:
return mp_manager; return mp_manager;
} }
/**
* @brief Gets the page set
*/
const PropertiesPageSet *page_set () const
{
return mp_page_set;
}
/**
* @brief Sets the page set
*/
void set_page_set (PropertiesPageSet *page_set)
{
mp_page_set = page_set;
}
signals: signals:
/** /**
* @brief This signal is emitted if a value has been changed * @brief This signal is emitted if a value has been changed
@ -220,6 +246,7 @@ signals:
private: private:
db::Manager *mp_manager; db::Manager *mp_manager;
tl::weak_ptr<lay::Editable> mp_editable; tl::weak_ptr<lay::Editable> mp_editable;
PropertiesPageSet *mp_page_set;
}; };
} }

View File

@ -214,6 +214,7 @@ PropertiesDialog::PropertiesDialog (QWidget * /*parent*/, db::Manager *manager,
delete *p; delete *p;
} else { } else {
mp_properties_pages.push_back (*p); mp_properties_pages.push_back (*p);
(*p)->set_page_set (this);
} }
} }
} }
@ -263,7 +264,7 @@ PropertiesDialog::PropertiesDialog (QWidget * /*parent*/, db::Manager *manager,
update_controls (); update_controls ();
mp_ui->apply_to_all_cbx->setChecked (false); mp_ui->apply_to_all_cbx->setChecked (true); // TODO: persist
mp_ui->relative_cbx->setChecked (true); mp_ui->relative_cbx->setChecked (true);
fetch_config (); fetch_config ();
@ -321,13 +322,7 @@ PropertiesDialog::disconnect ()
void void
PropertiesDialog::apply_to_all_pressed () PropertiesDialog::apply_to_all_pressed ()
{ {
m_signals_enabled = false; mp_ui->relative_cbx->setEnabled (mp_ui->apply_to_all_cbx->isEnabled () && mp_ui->apply_to_all_cbx->isChecked ());
if (mp_ui->apply_to_all_cbx->isChecked ()) {
mp_ui->tree->setCurrentIndex (mp_tree_model->index_for (m_index));
} else if (! m_object_indexes.empty ()) {
mp_ui->tree->setCurrentIndex (mp_tree_model->index_for (m_index, int (m_object_indexes.front ())));
}
m_signals_enabled = true;
} }
void void
@ -495,7 +490,6 @@ PropertiesDialog::current_index_changed (const QModelIndex &index, const QModelI
} else { } else {
m_index = index.row (); m_index = index.row ();
mp_ui->apply_to_all_cbx->setChecked (mp_properties_pages [m_index]->can_apply_to_all ());
if (mp_properties_pages [m_index]->can_apply_to_all ()) { if (mp_properties_pages [m_index]->can_apply_to_all ()) {
@ -537,8 +531,6 @@ PropertiesDialog::update_controls ()
} }
m_prev_index = m_index; m_prev_index = m_index;
mp_ui->apply_to_all_cbx->setChecked (m_object_indexes.size () > 1);
if (m_index < 0 || m_index >= int (mp_properties_pages.size ())) { if (m_index < 0 || m_index >= int (mp_properties_pages.size ())) {
mp_stack->setCurrentWidget (mp_none); mp_stack->setCurrentWidget (mp_none);

View File

@ -26,6 +26,7 @@
#define HDR_layPropertiesDialog #define HDR_layPropertiesDialog
#include "layuiCommon.h" #include "layuiCommon.h"
#include "layProperties.h"
#include <vector> #include <vector>
@ -52,7 +53,6 @@ namespace lay
class Editable; class Editable;
class Editables; class Editables;
class PropertiesPage;
class MainWindow; class MainWindow;
class PropertiesTreeModel; class PropertiesTreeModel;
@ -65,7 +65,7 @@ class PropertiesTreeModel;
*/ */
class LAYUI_PUBLIC PropertiesDialog class LAYUI_PUBLIC PropertiesDialog
: public QDialog : public QDialog, public lay::PropertiesPageSet
{ {
Q_OBJECT Q_OBJECT
@ -80,6 +80,14 @@ public:
*/ */
~PropertiesDialog (); ~PropertiesDialog ();
/**
* @brief Implementation of PropertiesPageSet
*/
virtual const std::vector<lay::PropertiesPage *> &properties_pages () const
{
return mp_properties_pages;
}
private: private:
friend class PropertiesTreeModel; friend class PropertiesTreeModel;