24
#include "PreCompiled.h"
26
# include <Inventor/sensors/SoNodeSensor.h>
27
# include <Inventor/nodes/SoAnnotation.h>
28
# include <Inventor/nodes/SoOrthographicCamera.h>
29
# include <Inventor/nodes/SoTransform.h>
32
#include <Gui/Application.h>
33
#include <Gui/View3DInventor.h>
34
#include <Gui/View3DInventorViewer.h>
36
#include "EditableDatumLabel.h"
44
EditableDatumLabel* label;
47
EditableDatumLabel::EditableDatumLabel(View3DInventorViewer* view,
48
const Base::Placement& plc,
51
bool avoidMouseCursor)
53
, autoDistance(autoDistance)
54
, autoDistanceReverse(false)
55
, avoidMouseCursor(avoidMouseCursor)
59
, cameraSensor(nullptr)
60
, function(Function::Positioning)
63
root = new SoAnnotation;
65
root->renderCaching = SoSeparator::OFF;
67
transform = new SoTransform();
69
root->addChild(transform);
71
label = new SoDatumLabel();
74
label->textColor = color;
75
label->size.setValue(17);
76
label->lineWidth = 2.0;
77
label->useAntialiasing = false;
78
label->datumtype = SoDatumLabel::DISTANCE;
83
setLabelRecommendedDistance();
85
root->addChild(label);
91
EditableDatumLabel::~EditableDatumLabel()
99
void EditableDatumLabel::activate()
101
if (!viewer || isActive()) {
105
static_cast<SoSeparator*>(viewer->getSceneGraph())->addChild(root);
108
auto info = new NodeData{ this };
109
cameraSensor = new SoNodeSensor([](void* data, SoSensor* sensor) {
111
auto info = static_cast<NodeData*>(data);
112
info->label->positionSpinbox();
113
if (info->label->autoDistance) {
114
info->label->setLabelRecommendedDistance();
117
cameraSensor->attach(viewer->getCamera());
120
void EditableDatumLabel::deactivate()
125
auto data = static_cast<NodeData*>(cameraSensor->getData());
127
cameraSensor->detach();
129
cameraSensor = nullptr;
133
static_cast<SoSeparator*>(viewer->getSceneGraph())->removeChild(root);
137
void EditableDatumLabel::startEdit(double val, QObject* eventFilteringObj, bool visibleToMouse)
143
QWidget* mdi = viewer->parentWidget();
147
spinBox = new QuantitySpinBox(mdi);
148
spinBox->setUnit(Base::Unit::Length);
149
spinBox->setMinimum(-INT_MAX);
150
spinBox->setMaximum(INT_MAX);
151
spinBox->setButtonSymbols(QAbstractSpinBox::NoButtons);
152
spinBox->setKeyboardTracking(false);
153
spinBox->setFocusPolicy(Qt::ClickFocus);
154
if (eventFilteringObj) {
155
spinBox->installEventFilter(eventFilteringObj);
158
if (!visibleToMouse) {
159
setSpinboxVisibleToMouse(visibleToMouse);
163
setSpinboxValue(val);
165
spinBox->adjustSize();
168
connect(spinBox, qOverload<double>(&QuantitySpinBox::valueChanged),
169
this, [this](double value) {
172
Q_EMIT this->valueChanged(value);
176
void EditableDatumLabel::stopEdit()
180
Base::Quantity quantity = spinBox->value();
185
valueStr = quantity.getUserString(factor, unitStr);
186
label->string = SbString(valueStr.toUtf8().constData());
188
spinBox->deleteLater();
193
bool EditableDatumLabel::isActive() const
195
return cameraSensor != nullptr;
198
bool EditableDatumLabel::isInEdit() const
200
return spinBox != nullptr;
204
double EditableDatumLabel::getValue() const
210
void EditableDatumLabel::setSpinboxValue(double val, const Base::Unit& unit)
213
Base::Console().DeveloperWarning("EditableDatumLabel::setSpinboxValue", "Spinbox doesn't exist in");
217
QSignalBlocker block(spinBox);
218
spinBox->setValue(Base::Quantity(val, unit));
222
if (spinBox->hasFocus()) {
223
spinBox->selectNumber();
227
void EditableDatumLabel::setFocusToSpinbox()
230
Base::Console().DeveloperWarning("EditableDatumLabel::setFocusToSpinbox", "Spinbox doesn't exist in");
233
if (!spinBox->hasFocus()) {
235
spinBox->selectNumber();
239
void EditableDatumLabel::positionSpinbox()
245
if (spinBox->hasFocus()) {
249
QSize wSize = spinBox->size();
250
QSize vSize = viewer->size();
251
QPoint pxCoord = viewer->toQPoint(viewer->getPointOnViewport(getTextCenterPoint()));
253
int posX = std::min(std::max(pxCoord.x() - wSize.width() / 2, 0), vSize.width() - wSize.width());
254
int posY = std::min(std::max(pxCoord.y() - wSize.height() / 2, 0), vSize.height() - wSize.height());
256
if (avoidMouseCursor) {
257
QPoint cursorPos = viewer->mapFromGlobal(QCursor::pos());
258
int margin = static_cast<int>(wSize.height() * 0.7);
259
if ((cursorPos.x() > posX - margin && cursorPos.x() < posX + wSize.width() + margin)
260
&& (cursorPos.y() > posY - margin && cursorPos.y() < posY + wSize.height() + margin)) {
261
posY = cursorPos.y() + ((cursorPos.y() > pxCoord.y()) ? - wSize.height() - margin : margin);
267
spinBox->move(pxCoord);
270
SbVec3f EditableDatumLabel::getTextCenterPoint() const
274
SbVec3f point2D = label->getLabelTextCenter();
276
SbVec3f translation = transform->translation.getValue();
277
SbRotation rotation = transform->rotation.getValue();
280
SbVec3f invTranslation = -translation;
281
SbRotation invRotation = rotation.inverse();
289
invRotation.multVec(RX, RX);
290
invRotation.multVec(RY, RY);
291
invRotation.multVec(invTranslation, invTranslation);
295
Base::Vector3d pos(invTranslation[0], invTranslation[1], invTranslation[2]);
296
Base::Vector3d RXb(RX[0], RX[1], RX[2]);
297
Base::Vector3d RYb(RY[0], RY[1], RY[2]);
298
Base::Vector3d P2D(point2D[0], point2D[1], point2D[2]);
299
P2D.TransformToCoordinateSystem(pos, RXb, RYb);
301
return {float(P2D.x), float(P2D.y), float(P2D.z)};
304
void EditableDatumLabel::setPlacement(const Base::Placement& plc)
306
double x{}, y{}, z{}, w{};
307
plc.getRotation().getValue(x, y, z, w);
308
transform->rotation.setValue(x, y, z, w);
310
Base::Vector3d pos = plc.getPosition();
311
transform->translation.setValue(float(pos.x), float(pos.y), float(pos.z));
313
Base::Vector3d RN(0, 0, 1);
314
RN = plc.getRotation().multVec(RN);
315
label->norm.setValue(SbVec3f(float(RN.x), float(RN.y), float(RN.z)));
319
void EditableDatumLabel::setColor(SbColor color)
321
label->textColor = color;
324
void EditableDatumLabel::setFocus()
327
spinBox->selectNumber();
331
void EditableDatumLabel::setPoints(SbVec3f p1, SbVec3f p2)
333
label->setPoints(p1, p2);
339
setLabelRecommendedDistance();
343
void EditableDatumLabel::setPoints(Base::Vector3d p1, Base::Vector3d p2)
345
setPoints(SbVec3f(float(p1.x), float(p1.y), float(p1.z)),
346
SbVec3f(float(p2.x), float(p2.y), float(p2.z)));
350
void EditableDatumLabel::setLabelType(SoDatumLabel::Type type, Function funct)
352
label->datumtype = type;
357
void EditableDatumLabel::setLabelDistance(double val)
359
label->param1 = float(val);
363
void EditableDatumLabel::setLabelStartAngle(double val)
365
label->param2 = float(val);
369
void EditableDatumLabel::setLabelRange(double val)
371
label->param3 = float(val);
374
void EditableDatumLabel::setLabelRecommendedDistance()
379
viewer->getDimensions(width, length);
381
if (width == -1. || length == -1.) {
385
label->param1 = (autoDistanceReverse ? -1.0F : 1.0F) * (width + length) * 0.03F;
388
void EditableDatumLabel::setLabelAutoDistanceReverse(bool val)
390
autoDistanceReverse = val;
393
void EditableDatumLabel::setSpinboxVisibleToMouse(bool val)
395
spinBox->setAttribute(Qt::WA_TransparentForMouseEvents, !val);
398
EditableDatumLabel::Function EditableDatumLabel::getFunction()
403
#include "moc_EditableDatumLabel.cpp"