'Apply' buttons and persistency of values for Layout+Selection 'move to', 'scale' and 'rotate by angle'

This commit is contained in:
Matthias Koefferlein 2026-01-24 16:19:11 +01:00
parent 86ddeb5970
commit 11701a300e
7 changed files with 318 additions and 77 deletions

View File

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>LayoutViewFunctionDialog</class>
<widget class="QDialog" name="LayoutViewFunctionDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>305</width>
<height>125</height>
</rect>
</property>
<property name="windowTitle">
<string>Adjust Cell Origin</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>_label</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="edit"/>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>19</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>edit</sender>
<signal>returnPressed()</signal>
<receiver>LayoutViewFunctionDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>152</x>
<y>44</y>
</hint>
<hint type="destinationlabel">
<x>152</x>
<y>62</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>LayoutViewFunctionDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>152</x>
<y>103</y>
</hint>
<hint type="destinationlabel">
<x>152</x>
<y>62</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>LayoutViewFunctionDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>152</x>
<y>103</y>
</hint>
<hint type="destinationlabel">
<x>152</x>
<y>62</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>240</width>
<width>306</width>
<height>168</height>
</rect>
</property>
@ -105,7 +105,7 @@
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>

View File

@ -42,6 +42,7 @@
#include "ui_NewLayoutPropertiesDialog.h"
#include "ui_NewLayerPropertiesDialog.h"
#include "ui_NewCellPropertiesDialog.h"
#include "ui_LayoutViewFunctionDialog.h"
#include "ui_MoveOptionsDialog.h"
#include "ui_MoveToOptionsDialog.h"
#include "ui_DeleteCellModeDialog.h"
@ -377,6 +378,58 @@ BEGIN_PROTECTED;
END_PROTECTED;
}
// --------------------------------------------------------------------------------
// LayoutViewFunctionDialog implementation
LayoutViewFunctionDialog::LayoutViewFunctionDialog (QWidget *parent, const QString &title, const QString &label)
: QDialog (parent)
{
setObjectName (QString::fromUtf8 ("layout_view_function_dialog"));
setWindowTitle (title);
mp_ui = new Ui::LayoutViewFunctionDialog ();
mp_ui->setupUi (this);
mp_ui->label->setText (label);
connect (mp_ui->buttonBox->button (QDialogButtonBox::Apply), SIGNAL (pressed ()), this, SLOT (apply_clicked ()));
}
LayoutViewFunctionDialog::~LayoutViewFunctionDialog ()
{
delete mp_ui;
mp_ui = 0;
}
bool
LayoutViewFunctionDialog::exec_dialog (QString &text)
{
mp_ui->edit->setText (text);
if (QDialog::exec ()) {
text = mp_ui->edit->text ();
return true;
} else {
return false;
}
}
void
LayoutViewFunctionDialog::apply_clicked ()
{
BEGIN_PROTECTED;
apply_event (tl::to_string (mp_ui->edit->text ()));
END_PROTECTED;
}
void
LayoutViewFunctionDialog::accept ()
{
BEGIN_PROTECTED;
accept_event (tl::to_string (mp_ui->edit->text ()));
QDialog::accept ();
END_PROTECTED;
}
// --------------------------------------------------------------------------------
// MoveOptionsDialog implementation
@ -387,6 +440,8 @@ MoveOptionsDialog::MoveOptionsDialog (QWidget *parent)
mp_ui = new Ui::MoveOptionsDialog ();
mp_ui->setupUi (this);
connect (mp_ui->buttonBox->button (QDialogButtonBox::Apply), SIGNAL (pressed ()), this, SLOT (apply_clicked ()));
}
MoveOptionsDialog::~MoveOptionsDialog ()
@ -402,27 +457,35 @@ MoveOptionsDialog::exec_dialog (db::DVector &disp)
mp_ui->disp_y_le->setText (tl::to_qstring (tl::to_string (disp.y ())));
if (QDialog::exec ()) {
double x = 0.0, y = 0.0;
tl::from_string_ext (tl::to_string (mp_ui->disp_x_le->text ()), x);
tl::from_string_ext (tl::to_string (mp_ui->disp_y_le->text ()), y);
disp = db::DVector (x, y);
disp = vector ();
return true;
} else {
return false;
}
}
void
db::DVector
MoveOptionsDialog::vector ()
{
double x = 0.0, y = 0.0;
tl::from_string_ext (tl::to_string (mp_ui->disp_x_le->text ()), x);
tl::from_string_ext (tl::to_string (mp_ui->disp_y_le->text ()), y);
return db::DVector (x, y);
}
void
MoveOptionsDialog::apply_clicked ()
{
BEGIN_PROTECTED;
apply_event (vector ());
END_PROTECTED;
}
void
MoveOptionsDialog::accept ()
{
BEGIN_PROTECTED;
double x = 0.0;
tl::from_string_ext (tl::to_string (mp_ui->disp_x_le->text ()), x);
tl::from_string_ext (tl::to_string (mp_ui->disp_y_le->text ()), x);
accept_event (vector ());
QDialog::accept ();
END_PROTECTED;
}

View File

@ -45,6 +45,7 @@ namespace Ui
class NewLayoutPropertiesDialog;
class NewLayerPropertiesDialog;
class NewCellPropertiesDialog;
class LayoutViewFunctionDialog;
class MoveOptionsDialog;
class MoveToOptionsDialog;
class DeleteCellModeDialog;
@ -128,11 +129,41 @@ private:
Ui::NewLayerPropertiesDialog *mp_ui;
};
/**
* @brief The generic layout view functions dialog
*
* This dialog replaces QInputDialog and offers
* an "apply" callback.
*/
class LAYUI_PUBLIC LayoutViewFunctionDialog
: public QDialog, public tl::Object
{
Q_OBJECT
public:
LayoutViewFunctionDialog (QWidget *parent, const QString &title, const QString &label);
virtual ~LayoutViewFunctionDialog ();
bool exec_dialog (QString &value);
tl::event<std::string> apply_event;
tl::event<std::string> accept_event;
private slots:
void apply_clicked ();
private:
virtual void accept ();
Ui::LayoutViewFunctionDialog *mp_ui;
};
/**
* @brief The move options dialog
*/
class LAYUI_PUBLIC MoveOptionsDialog
: public QDialog
: public QDialog, public tl::Object
{
Q_OBJECT
@ -142,8 +173,15 @@ public:
bool exec_dialog (db::DVector &disp);
tl::event<db::DVector> apply_event;
tl::event<db::DVector> accept_event;
private slots:
void apply_clicked ();
private:
virtual void accept ();
db::DVector vector ();
Ui::MoveOptionsDialog *mp_ui;
};

View File

@ -1399,53 +1399,69 @@ LayoutViewFunctions::cm_lay_rot_cw ()
void
LayoutViewFunctions::cm_lay_free_rot ()
{
bool ok = false;
QString s = QInputDialog::getText (QApplication::activeWindow (),
tr ("Free rotation"),
tr ("Rotation angle in degree (counterclockwise)"),
QLineEdit::Normal, QString::fromUtf8 ("0.0"),
&ok);
static QString s_angle_value = QString::fromUtf8 ("0.0");
if (ok) {
lay::LayoutViewFunctionDialog dialog (QApplication::activeWindow (),
tr ("Free rotation"),
tr ("Rotation angle in degree (counterclockwise)"));
double angle = 0.0;
tl::from_string_ext (tl::to_string (s), angle);
dialog.accept_event.add (this, &LayoutViewFunctions::on_lay_free_rot);
dialog.apply_event.add (this, &LayoutViewFunctions::on_lay_free_rot);
transform_layout (db::DCplxTrans (1.0, angle, false, db::DVector ()));
dialog.exec_dialog (s_angle_value);
}
}
void
LayoutViewFunctions::on_lay_free_rot (std::string text)
{
double angle = 0.0;
tl::from_string_ext (text, angle);
transform_layout (db::DCplxTrans (1.0, angle, false, db::DVector ()));
}
void
LayoutViewFunctions::cm_lay_scale ()
{
bool ok = false;
QString s = QInputDialog::getText (QApplication::activeWindow (),
tr ("Scaling"),
tr ("Scaling factor"),
QLineEdit::Normal, QString::fromUtf8 ("1.0"),
&ok);
static QString s_scale_value = QString::fromUtf8 ("1.0");
if (ok) {
lay::LayoutViewFunctionDialog dialog (QApplication::activeWindow (),
tr ("Scaling"),
tr ("Scaling factor"));
double scale = 0.0;
tl::from_string_ext (tl::to_string (s), scale);
dialog.accept_event.add (this, &LayoutViewFunctions::on_lay_scale);
dialog.apply_event.add (this, &LayoutViewFunctions::on_lay_scale);
transform_layout (db::DCplxTrans (scale));
dialog.exec_dialog (s_scale_value);
}
}
void
LayoutViewFunctions::on_lay_scale (std::string text)
{
double scale = 0.0;
tl::from_string_ext (text, scale);
transform_layout (db::DCplxTrans (scale));
}
void
LayoutViewFunctions::cm_lay_move ()
{
lay::MoveOptionsDialog options (parent_widget ());
if (options.exec_dialog (m_move_dist)) {
transform_layout (db::DCplxTrans (m_move_dist));
}
options.accept_event.add (this, &LayoutViewFunctions::on_lay_move);
options.apply_event.add (this, &LayoutViewFunctions::on_lay_move);
options.exec_dialog (m_move_dist);
}
void
void
LayoutViewFunctions::on_lay_move (db::DVector dist)
{
transform_layout (db::DCplxTrans (dist));
}
void
LayoutViewFunctions::cm_sel_flip_x ()
{
db::DCplxTrans tr (db::DFTrans::m90);
@ -1492,51 +1508,59 @@ LayoutViewFunctions::cm_sel_rot_cw ()
void
LayoutViewFunctions::cm_sel_free_rot ()
{
bool ok = false;
QString s = QInputDialog::getText (QApplication::activeWindow (),
tr ("Free rotation"),
tr ("Rotation angle in degree (counterclockwise)"),
QLineEdit::Normal, QString::fromUtf8 ("0.0"),
&ok);
static QString s_angle_value = QString::fromUtf8 ("0.0");
if (ok) {
lay::LayoutViewFunctionDialog dialog (QApplication::activeWindow (),
tr ("Free rotation"),
tr ("Rotation angle in degree (counterclockwise)"));
double angle = 0.0;
tl::from_string_ext (tl::to_string (s), angle);
dialog.accept_event.add (this, &LayoutViewFunctions::on_sel_free_rot);
dialog.apply_event.add (this, &LayoutViewFunctions::on_sel_free_rot);
db::DCplxTrans tr = db::DCplxTrans (1.0, angle, false, db::DVector ());
db::DBox sel_bbox (view ()->lay::Editables::selection_bbox ());
if (! sel_bbox.empty ()) {
tr = db::DCplxTrans (sel_bbox.center () - db::DPoint ()) * tr * db::DCplxTrans (db::DPoint () - sel_bbox.center ());
}
do_transform (tr);
}
dialog.exec_dialog (s_angle_value);
}
void
void
LayoutViewFunctions::on_sel_free_rot (std::string text)
{
double angle = 0.0;
tl::from_string_ext (text, angle);
db::DCplxTrans tr = db::DCplxTrans (1.0, angle, false, db::DVector ());
db::DBox sel_bbox (view ()->lay::Editables::selection_bbox ());
if (! sel_bbox.empty ()) {
tr = db::DCplxTrans (sel_bbox.center () - db::DPoint ()) * tr * db::DCplxTrans (db::DPoint () - sel_bbox.center ());
}
do_transform (tr);
}
void
LayoutViewFunctions::cm_sel_scale ()
{
bool ok = false;
QString s = QInputDialog::getText (QApplication::activeWindow (),
tr ("Scaling"),
tr ("Scaling factor"),
QLineEdit::Normal, QString::fromUtf8 ("1.0"),
&ok);
static QString s_scale_value = QString::fromUtf8 ("1.0");
if (ok) {
lay::LayoutViewFunctionDialog dialog (QApplication::activeWindow (),
tr ("Scaling"),
tr ("Scaling factor"));
double scale = 0.0;
tl::from_string_ext (tl::to_string (s), scale);
dialog.accept_event.add (this, &LayoutViewFunctions::on_sel_scale);
dialog.apply_event.add (this, &LayoutViewFunctions::on_sel_scale);
db::DCplxTrans tr = db::DCplxTrans (scale);
db::DBox sel_bbox (view ()->lay::Editables::selection_bbox ());
if (! sel_bbox.empty ()) {
tr = db::DCplxTrans (sel_bbox.center () - db::DPoint ()) * tr * db::DCplxTrans (db::DPoint () - sel_bbox.center ());
}
do_transform (tr);
dialog.exec_dialog (s_scale_value);
}
void
LayoutViewFunctions::on_sel_scale (std::string text)
{
double scale = 0.0;
tl::from_string_ext (text, scale);
db::DCplxTrans tr = db::DCplxTrans (scale);
db::DBox sel_bbox (view ()->lay::Editables::selection_bbox ());
if (! sel_bbox.empty ()) {
tr = db::DCplxTrans (sel_bbox.center () - db::DPoint ()) * tr * db::DCplxTrans (db::DPoint () - sel_bbox.center ());
}
do_transform (tr);
}
void
@ -1575,9 +1599,17 @@ void
LayoutViewFunctions::cm_sel_move ()
{
lay::MoveOptionsDialog options (parent_widget ());
if (options.exec_dialog (m_move_dist)) {
do_transform (db::DCplxTrans (m_move_dist));
}
options.apply_event.add (this, &LayoutViewFunctions::on_sel_move);
options.accept_event.add (this, &LayoutViewFunctions::on_sel_move);
options.exec_dialog (m_move_dist);
}
void
LayoutViewFunctions::on_sel_move(db::DVector disp)
{
do_transform (db::DCplxTrans (disp));
}
void

View File

@ -166,6 +166,13 @@ private:
bool m_clear_before;
int m_copy_cva, m_copy_cvr;
int m_copy_layera, m_copy_layerr;
void on_lay_free_rot (std::string text);
void on_lay_scale (std::string text);
void on_lay_move (db::DVector disp);
void on_sel_free_rot (std::string text);
void on_sel_scale (std::string text);
void on_sel_move (db::DVector disp);
};
}

View File

@ -41,6 +41,7 @@ FORMS = \
LayoutViewConfigPage7.ui \
LayoutViewConfigPage.ui \
LayoutViewConfigPage8.ui \
LayoutViewFunctionDialog.ui \
LibraryCellSelectionForm.ui \
LoadLayoutOptionsDialog.ui \
MarkerBrowserConfigPage2.ui \