Sketcher: Change enter behavior on OVP to put OVP in lock state only

This patch adds/changes a couple of things:
* if you press enter on a label now, it moves you to another label and
  adds the label and lock on the previous label, instead of previous behavior
  where it was accepting whole dimension
* if you press enter and have lock state on both labels then you move to
  next stage
* if you press ctrl+enter it's as is if you'd press enter on both labels
  (the object becomes constrained with whatever dimensions that were in
  both labels)
* tab still works the same way
* you can remove "Lock" state from the label by typing something
  additional or removing the dimension at all
This commit is contained in:
tetektoza
2025-06-11 23:59:07 +02:00
parent 889d708992
commit ef0b259097
14 changed files with 163 additions and 18 deletions

View File

@@ -33,8 +33,13 @@
#include <QEvent>
#include <QKeyEvent>
#include <QPixmap>
#include <QLabel>
#include <QHBoxLayout>
#include <QString>
#include <Gui/Application.h>
#include <Gui/BitmapFactory.h>
#include <Gui/View3DInventor.h>
#include <Gui/View3DInventorViewer.h>
@@ -62,6 +67,7 @@ EditableDatumLabel::EditableDatumLabel(View3DInventorViewer* view,
, value(0.0)
, viewer(view)
, spinBox(nullptr)
, lockIconLabel(nullptr)
, cameraSensor(nullptr)
, function(Function::Positioning)
{
@@ -151,6 +157,9 @@ void EditableDatumLabel::startEdit(double val, QObject* eventFilteringObj, bool
return;
}
// Reset locked state when starting to edit
this->resetLockedState();
QWidget* mdi = viewer->parentWidget();
label->string = " ";
@@ -209,11 +218,30 @@ bool EditableDatumLabel::eventFilter(QObject* watched, QEvent* event)
if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) {
if (auto* spinBox = qobject_cast<QAbstractSpinBox*>(watched)) {
this->hasFinishedEditing = true;
Q_EMIT this->valueChanged(this->value);
return false;
// for ctrl + enter we accept values as they are
if (keyEvent->modifiers() & Qt::ControlModifier) {
Q_EMIT this->finishEditingOnAllOVPs();
return true;
}
else {
// regular enter
this->hasFinishedEditing = true;
Q_EMIT this->spinBox->valueChanged(this->value);
// only set lock state if it passed validation
// (validation can unset isSet if value didn't pass
// confusion point for example)
if (this->isSet)
this->setLockedAppearance(true);
return true;
}
}
}
else if (this->hasFinishedEditing && keyEvent->key() != Qt::Key_Tab)
{
this->setLockedAppearance(false);
return false;
}
}
return QObject::eventFilter(watched, event);
@@ -233,6 +261,9 @@ void EditableDatumLabel::stopEdit()
spinBox->deleteLater();
spinBox = nullptr;
// Lock icon will be automatically destroyed as it's a child of spinbox
lockIconLabel = nullptr;
}
}
@@ -311,6 +342,19 @@ void EditableDatumLabel::positionSpinbox()
pxCoord.setX(posX);
pxCoord.setY(posY);
spinBox->move(pxCoord);
// Update lock icon position inside the spinbox if it exists and is visible
if (lockIconLabel && lockIconLabel->isVisible()) {
int iconSize = 14;
int padding = 4;
QSize spinboxSize = spinBox->size();
lockIconLabel->setGeometry(
spinboxSize.width() - iconSize - padding,
(spinboxSize.height() - iconSize) / 2,
iconSize,
iconSize
);
}
}
SbVec3f EditableDatumLabel::getTextCenterPoint() const
@@ -441,6 +485,70 @@ void EditableDatumLabel::setSpinboxVisibleToMouse(bool val)
spinBox->setAttribute(Qt::WA_TransparentForMouseEvents, !val);
}
void EditableDatumLabel::setLockedAppearance(bool locked)
{
if (locked) {
if (spinBox) {
QWidget* mdi = viewer->parentWidget();
// create lock icon label it it doesn't exist, if it does - show it
if (!lockIconLabel) {
lockIconLabel = new QLabel(spinBox);
lockIconLabel->setAttribute(Qt::WA_TransparentForMouseEvents, true);
lockIconLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
}
else
{
lockIconLabel->show();
}
// load icon and scale it to fit in spinbox
QPixmap lockIcon = Gui::BitmapFactory().pixmap("Constraint_Lock");
QPixmap scaledIcon = lockIcon.scaled(14, 14, Qt::KeepAspectRatio, Qt::SmoothTransformation);
lockIconLabel->setPixmap(scaledIcon);
// position lock icon inside the spinbox
int iconSize = 14;
int padding = 4;
QSize spinboxSize = spinBox->size();
lockIconLabel->setGeometry(
spinboxSize.width() - iconSize - padding,
(spinboxSize.height() - iconSize) / 2,
iconSize,
iconSize
);
lockIconLabel->show();
// style spinbox and add padding for lock
QString styleSheet = QString::fromLatin1(
"QSpinBox { "
"padding-right: %1px; "
"}"
).arg(iconSize + padding + 2);
spinBox->setStyleSheet(styleSheet);
}
} else {
this->hasFinishedEditing = false;
// if spinbox exists, reset its appearance
if (spinBox) {
spinBox->setStyleSheet(QString());
// hide lock icon if it exists for later reuse
if (lockIconLabel) {
lockIconLabel->hide();
}
}
}
}
void EditableDatumLabel::resetLockedState()
{
hasFinishedEditing = false;
setLockedAppearance(false);
}
EditableDatumLabel::Function EditableDatumLabel::getFunction()
{
return function;