38 #include <QFontMetrics>
50 #include "boost/bind.hpp"
51 #include "libQtSignalAdapters/Qt2Func.h"
52 #include "libQtSignalAdapters/ConnectionFactories.h"
69 QRect rect = QFontMetrics(this->font()).boundingRect(text);
70 QSize s(rect.width()*1.0+5, 4*rect.height()*1.2+5);
90 BaseWidget(parent,
"Transform3DWidget",
"Transform 3D")
93 mBlockChanges =
false;
95 QVBoxLayout* toptopLayout =
new QVBoxLayout(
this);
96 toptopLayout->setMargin(4);
97 QHBoxLayout* mLayout =
new QHBoxLayout;
98 mLayout->setMargin(0);
99 toptopLayout->addLayout(mLayout);
102 mTextEdit->setSizePolicy(QSizePolicy::MinimumExpanding,QSizePolicy::Maximum);
103 mTextEdit->setLineWrapMode(QTextEdit::NoWrap);
104 mTextEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
105 mTextEdit->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
106 connect(mTextEdit, SIGNAL(textChanged()),
this, SLOT(textEditChangedSlot()));
108 mLayout->addWidget(mTextEdit, 1);
110 QVBoxLayout* buttonLayout =
new QVBoxLayout;
111 mLayout->addLayout(buttonLayout);
112 buttonLayout->setMargin(0);
115 QIcon(
":/icons/open_icon_library/system-run-5.png"),
117 "Toggle Edit Matrix",
118 SLOT(toggleEditSlot()),
120 mEditAction->setCheckable(
true);
123 QIcon(
":/icons/matrix_inverse.png"),
125 "Toggle Invert Matrix",
126 SLOT(toggleInvertSlot()),
128 mInvertAction->setCheckable(
true);
129 mInvertAction->setChecked(
false);
130 this->updateInvertAction();
134 aGroupBox =
new QFrame(
this);
135 QVBoxLayout* aLayout =
new QVBoxLayout;
136 aGroupBox->setLayout(aLayout);
137 aGroupBox->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
138 aGroupBox->setLineWidth(3);
139 aLayout->setMargin(4);
140 toptopLayout->addWidget(aGroupBox);
142 this->addAngleControls(
"xAngle",
"X Angle", 0, aLayout);
143 this->addAngleControls(
"yAngle",
"Y Angle", 1, aLayout);
144 this->addAngleControls(
"zAngle",
"Z Angle", 2, aLayout);
146 tGroupBox =
new QFrame(
this);
147 QVBoxLayout* tLayout =
new QVBoxLayout;
148 tGroupBox->setLayout(tLayout);
149 tGroupBox->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
150 tGroupBox->setLineWidth(3);
151 tLayout->setMargin(4);
152 toptopLayout->addWidget(tGroupBox);
154 this->addTranslationControls(
"xTranslation",
"X", 0, tLayout);
155 this->addTranslationControls(
"yTranslation",
"Y", 1, tLayout);
156 this->addTranslationControls(
"zTranslation",
"Z", 2, tLayout);
158 this->setMatrixInternal(Transform3D::Identity());
160 toptopLayout->addStretch();
168 "<h3>Transform 3D</h3>"
169 "<p>Lets you display and manipulat an affine matrix, i.e. a rotation+translation matrix.</p>"
174 void Transform3DWidget::textEditChangedSlot()
177 Transform3D M = Transform3D::fromString(mTextEdit->toPlainText(), &ok);
181 if (
similar(M, this->getMatrixInternal()))
184 this->setMatrixInternal(M);
187 void Transform3DWidget::toggleEditSlot()
189 bool visible = tGroupBox->isVisible();
194 void Transform3DWidget::toggleInvertSlot()
198 this->updateValues();
202 void Transform3DWidget::updateInvertAction()
204 if (mInvertAction->isChecked())
206 this->setActionText(mInvertAction,
"Inverted Matrix",
"The matrix is shown inverted");
210 this->setActionText(mInvertAction,
"Noninverted Matrix",
"The matrix is shown as is. Press to show inverted");
214 void Transform3DWidget::setActionText(QAction* action, QString text, QString tip)
218 action->setText(text);
219 action->setStatusTip(tip);
220 action->setWhatsThis(tip);
221 action->setToolTip(tip);
226 mTextEdit->setReadOnly(!edit);
227 aGroupBox->setVisible(edit);
228 tGroupBox->setVisible(edit);
231 void Transform3DWidget::addAngleControls(QString uid, QString name,
int index, QVBoxLayout* layout)
233 QHBoxLayout* hLayout =
new QHBoxLayout;
236 connect(adapter.get(), SIGNAL(
changed()),
this, SLOT(changedSlot()));
237 adapter->setInternal2Display(180/
M_PI);
240 QSize mMinBarSize = QSize(20,20);
243 hLayout->addWidget(pad);
246 QtSignalAdapters::connect1<void(QPointF)>(pad, SIGNAL(mouseMoved(QPointF)),
247 boost::bind(&Transform3DWidget::rotateSlot,
this, _1, index));
249 layout->addLayout(hLayout);
250 mAngleAdapter[index] = adapter;
253 void Transform3DWidget::addTranslationControls(QString uid, QString name,
int index, QVBoxLayout* layout)
255 QHBoxLayout* hLayout =
new QHBoxLayout;
258 connect(adapter.get(), SIGNAL(
changed()),
this, SLOT(changedSlot()));
259 adapter->setInternal2Display(1.0);
260 hLayout->addWidget(
new SpinBoxGroupWidget(
this, adapter));
262 QSize mMinBarSize = QSize(20,20);
263 MousePadWidget* pad =
new MousePadWidget(
this, mMinBarSize);
264 pad->setFixedYPos(
true);
265 hLayout->addWidget(pad);
268 QtSignalAdapters::connect1<void(QPointF)>(pad, SIGNAL(mouseMoved(QPointF)),
269 boost::bind(&Transform3DWidget::translateSlot,
this, _1, index));
271 layout->addLayout(hLayout);
272 mTranslationAdapter[index] = adapter;
275 void Transform3DWidget::rotateSlot(QPointF delta,
int index)
277 double scale = M_PI_2;
278 double factor = scale * delta.x();
279 double current = mAngleAdapter[index]->getValue();
280 mAngleAdapter[index]->setValue(current + factor);
283 void Transform3DWidget::translateSlot(QPointF delta,
int index)
286 double factor = scale * delta.x();
287 double current = mTranslationAdapter[index]->getValue();
288 mTranslationAdapter[index]->setValue(current + factor);
298 this->setMatrixInternal(this->convertToFromExternal(M));
303 return this->convertToFromExternal(this->getMatrixInternal());
308 if (mInvertAction->isChecked())
318 void Transform3DWidget::setMatrixInternal(
const Transform3D& M)
320 mDecomposition.
reset(M);
321 this->updateValues();
325 Transform3D Transform3DWidget::getMatrixInternal()
const
333 void Transform3DWidget::changedSlot()
335 if (recursive || mBlockChanges)
338 Vector3D xyz(mAngleAdapter[0]->getValue(),mAngleAdapter[1]->getValue(),mAngleAdapter[2]->getValue());
341 Vector3D t(mTranslationAdapter[0]->getValue(),mTranslationAdapter[1]->getValue(),mTranslationAdapter[2]->getValue());
344 this->updateValues();
354 double wrapAngle(
double angle)
356 angle = fmod(angle,
M_PI * 2);
365 void Transform3DWidget::updateValues()
369 mTextEdit->blockSignals(
true);
370 int textPos = mTextEdit->textCursor().position();
371 mTextEdit->setText(M);
372 QTextCursor cursor = mTextEdit->textCursor();
373 cursor.setPosition(textPos);
374 mTextEdit->setTextCursor(cursor);
375 mTextEdit->blockSignals(
false);
379 mBlockChanges =
true;
381 mAngleAdapter[0]->setValue(wrapAngle(xyz[0]));
382 mAngleAdapter[1]->setValue(wrapAngle(xyz[1]));
383 mAngleAdapter[2]->setValue(wrapAngle(xyz[2]));
386 mTranslationAdapter[0]->setValue(t[0]);
387 mTranslationAdapter[1]->setValue(t[1]);
388 mTranslationAdapter[2]->setValue(t[2]);
390 this->updateInvertAction();
392 mBlockChanges =
false;
QString qstring_cast(const T &val)
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
Utility class for describing a bounded numeric range.
bool similar(const DoubleBoundingBox3D &a, const DoubleBoundingBox3D &b, double tol)
MatrixTextEdit(QWidget *parent=NULL)
Transform3D createTransformTranslate(const Vector3D &translation)
boost::shared_ptr< class DoubleProperty > DoublePropertyPtr
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
QSize minimumSizeHint() const
static DoublePropertyPtr initialize(const QString &uid, QString name, QString help, double value, DoubleRange range, int decimals, QDomNode root=QDomNode())
Transform3D createTransformRotateZ(const double angle)
Transform3D createTransformRotateX(const double angle)