1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
4 #include "GotoPositionDlg.h"
6 #include "ViewManager.h"
7 #include "GameEngine.h"
9 #include <RenderViewport.h>
11 #include <QFormLayout>
12 #include <QVBoxLayout>
13 #include <QSpacerItem>
15 #include <QDialogButtonBox>
18 #include <QDoubleSpinBox>
21 class CPositionSpinBox
: public QDoubleSpinBox
24 CPositionSpinBox(CGotoPositionDialog
* pParent
)
25 : QDoubleSpinBox(pParent
)
27 setAlignment(Qt::AlignRight
| Qt::AlignTrailing
| Qt::AlignVCenter
);
28 setRange(-64000.0, 64000.0);
34 class CRotationSpinBox
: public QDoubleSpinBox
37 CRotationSpinBox(CGotoPositionDialog
* pParent
)
38 : QDoubleSpinBox(pParent
)
40 setAlignment(Qt::AlignRight
| Qt::AlignTrailing
| Qt::AlignVCenter
);
41 setRange(-360.0, 360.0);
47 class CSegmentSpinBox
: public QSpinBox
50 CSegmentSpinBox(CGotoPositionDialog
* pParent
, int32 rangeMin
, int32 rangeMax
, int32 initValue
)
53 setAlignment(Qt::AlignRight
| Qt::AlignTrailing
| Qt::AlignVCenter
);
54 setRange(rangeMin
, rangeMax
);
60 CGotoPositionDialog::CGotoPositionDialog()
61 : CEditorDialog("Go to position")
63 setWindowTitle(tr("Go to position"));
65 QVBoxLayout
* pDialogLayout
= new QVBoxLayout(this);
67 QFormLayout
* pFormLayout
= new QFormLayout();
68 pDialogLayout
->addLayout(pFormLayout
);
70 QLabel
* pDescLine
= new QLabel(tr("Enter position here:"));
71 pFormLayout
->addRow(pDescLine
);
75 CViewport
* pViewport
= GetIEditorImpl()->GetViewManager()->GetSelectedViewport();
76 if (pViewport
&& pViewport
->IsRenderViewport() && pViewport
->GetType() == ET_ViewportCamera
)
78 CRenderViewport
* pRenderViewport
= static_cast<CRenderViewport
*>(pViewport
);
79 Matrix34 transform
= pRenderViewport
->GetViewTM();
80 position
= transform
.GetTranslation();
81 rotation
= Vec3(RAD2DEG(Ang3::GetAnglesXYZ(transform
)));
84 m_pPositionString
= new QLineEdit(this);
85 m_pPositionString
->setText(QString("%1, %2, %3, %4, %5, %6").arg(position
.x
).arg(position
.y
).arg(position
.z
).arg(rotation
.x
).arg(rotation
.y
).arg(rotation
.z
));
86 pFormLayout
->addRow(m_pPositionString
);
87 m_pPositionString
->setFocus();
88 m_pPositionString
->selectAll();
90 connect(m_pPositionString
, &QLineEdit::editingFinished
, this, &CGotoPositionDialog::OnPositionStringChanged
);
91 QGridLayout
* pGridLayout
= new QGridLayout(this);
92 pDialogLayout
->addLayout(pGridLayout
);
94 QLabel
* pPosColumnHeader
= new QLabel(tr("Position"));
95 QLabel
* pRotColumnHeader
= new QLabel(tr("Rotation"));
97 pGridLayout
->addWidget(pPosColumnHeader
, 0, 0);
98 pGridLayout
->addWidget(pRotColumnHeader
, 0, 1);
100 m_pPositionBoxes
[0] = new CPositionSpinBox(this);
101 m_pPositionBoxes
[1] = new CPositionSpinBox(this);
102 m_pPositionBoxes
[2] = new CPositionSpinBox(this);
104 m_pPositionBoxes
[0]->setValue(position
.x
);
105 m_pPositionBoxes
[1]->setValue(position
.y
);
106 m_pPositionBoxes
[2]->setValue(position
.z
);
108 m_pRotationBoxes
[0] = new CRotationSpinBox(this);
109 m_pRotationBoxes
[1] = new CRotationSpinBox(this);
110 m_pRotationBoxes
[2] = new CRotationSpinBox(this);
112 m_pRotationBoxes
[0]->setValue(rotation
.x
);
113 m_pRotationBoxes
[1]->setValue(rotation
.y
);
114 m_pRotationBoxes
[2]->setValue(rotation
.z
);
116 pGridLayout
->addWidget(m_pPositionBoxes
[0], 1, 0);
117 pGridLayout
->addWidget(m_pPositionBoxes
[1], 2, 0);
118 pGridLayout
->addWidget(m_pPositionBoxes
[2], 3, 0);
119 pGridLayout
->addWidget(m_pRotationBoxes
[0], 1, 1);
120 pGridLayout
->addWidget(m_pRotationBoxes
[1], 2, 1);
121 pGridLayout
->addWidget(m_pRotationBoxes
[2], 3, 1);
123 connect(m_pPositionBoxes
[0], static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged
), this, &CGotoPositionDialog::OnValueChanged
);
124 connect(m_pPositionBoxes
[1], static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged
), this, &CGotoPositionDialog::OnValueChanged
);
125 connect(m_pPositionBoxes
[2], static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged
), this, &CGotoPositionDialog::OnValueChanged
);
126 connect(m_pRotationBoxes
[0], static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged
), this, &CGotoPositionDialog::OnValueChanged
);
127 connect(m_pRotationBoxes
[1], static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged
), this, &CGotoPositionDialog::OnValueChanged
);
128 connect(m_pRotationBoxes
[2], static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged
), this, &CGotoPositionDialog::OnValueChanged
);
130 QSpacerItem
* pSpacer
= new QSpacerItem(20, 0, QSizePolicy::Minimum
, QSizePolicy::Expanding
);
131 pDialogLayout
->addSpacerItem(pSpacer
);
133 QDialogButtonBox
* pButtonBox
= new QDialogButtonBox(this);
134 pButtonBox
->setStandardButtons(QDialogButtonBox::Ok
| QDialogButtonBox::Cancel
);
135 pDialogLayout
->addWidget(pButtonBox
);
136 connect(pButtonBox
, &QDialogButtonBox::rejected
, this, &QDialog::reject
);
137 connect(pButtonBox
, &QDialogButtonBox::accepted
, this, &CGotoPositionDialog::GotoPosition
);
140 CGotoPositionDialog::~CGotoPositionDialog()
145 void CGotoPositionDialog::OnPositionStringChanged()
147 if (!m_pPositionString
->text().isEmpty())
149 const QByteArray byteArray
= m_pPositionString
->text().toUtf8();
150 const char* pPosition
= byteArray
.data();
151 const size_t numValues
= 6; // Position XYZ and Rotation XYZ
153 float value
[numValues
] = { 0 };
156 for (size_t i
= 0; i
< numValues
&& c
!= 0; ++i
)
158 // Note: VS 2015 produces wrong code when using a for loop which but a while loop works.
159 //for(c = *pPosition; c != 0 && (c < '0' || c > '9'); ++pPosition);
161 // Search number begin ...
162 while (c
= *pPosition
, c
!= 0 && c
!= '-' && (c
<'0' || c
> '9'))
167 sscanf(pPosition
, "%f", &value
[i
]);
169 // ... and now for the number end.
170 while (c
= *pPosition
++, (c
>= '0' && c
<= '9') || c
== '.' || c
== '-');
173 m_pPositionBoxes
[0]->setValue(value
[0]);
174 m_pPositionBoxes
[1]->setValue(value
[1]);
175 m_pPositionBoxes
[2]->setValue(value
[2]);
177 m_pRotationBoxes
[0]->setValue(value
[3]);
178 m_pRotationBoxes
[1]->setValue(value
[4]);
179 m_pRotationBoxes
[2]->setValue(value
[5]);
183 void CGotoPositionDialog::OnValueChanged()
185 stack_string positionString
;
186 positionString
.Format(
187 "%.2f, %.2f, %.2f, %.2f, %.2f, %.2f",
188 float(m_pPositionBoxes
[0]->value()),
189 float(m_pPositionBoxes
[1]->value()),
190 float(m_pPositionBoxes
[2]->value()),
191 float(m_pRotationBoxes
[0]->value()),
192 float(m_pRotationBoxes
[1]->value()),
193 float(m_pRotationBoxes
[2]->value())
196 m_pPositionString
->setText(positionString
.c_str());
199 void CGotoPositionDialog::GotoPosition()
201 stack_string command
;
203 "general.set_current_view_position %f %f %f",
204 float(m_pPositionBoxes
[0]->value()),
205 float(m_pPositionBoxes
[1]->value()),
206 float(m_pPositionBoxes
[2]->value())
208 GetIEditorImpl()->GetCommandManager()->Execute(command
.c_str());
211 "general.set_current_view_rotation %f %f %f",
212 float(m_pRotationBoxes
[0]->value()),
213 float(m_pRotationBoxes
[1]->value()),
214 float(m_pRotationBoxes
[2]->value())
216 GetIEditorImpl()->GetCommandManager()->Execute(command
.c_str());
221 namespace Private_GoToPositionCommands
225 CGotoPositionDialog dlg
;
230 REGISTER_EDITOR_AND_SCRIPT_COMMAND(Private_GoToPositionCommands::GoToPosition
, level
, go_to_position
,
231 CCommandDescription("Opens go to position dialog"))
232 REGISTER_EDITOR_UI_COMMAND_DESC(level
, go_to_position
, "Go to Position...", "", "icons:Tools/Go_To_Position.ico", false)
233 REGISTER_COMMAND_REMAPPING(ui_action
, actionGoto_Position
, level
, go_to_position
)