forked from qt-creator/qt-creator
QmlDesigner: Add preset layout options for 3D View
Task-number: QDS-14907 Change-Id: I0937a64dc1820727178372663e2913f2c2239f10 Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
@@ -16,7 +16,7 @@ public:
|
|||||||
Edit3DToolState,
|
Edit3DToolState,
|
||||||
Render3DView,
|
Render3DView,
|
||||||
ActiveSceneChanged,
|
ActiveSceneChanged,
|
||||||
ActiveSplitChanged,
|
ActiveViewportChanged,
|
||||||
RenderModelNodePreviewImage,
|
RenderModelNodePreviewImage,
|
||||||
Import3DPreviewIcon,
|
Import3DPreviewIcon,
|
||||||
Import3DPreviewImage,
|
Import3DPreviewImage,
|
||||||
|
@@ -51,10 +51,11 @@ enum class View3DActionType {
|
|||||||
ParticlesRestart,
|
ParticlesRestart,
|
||||||
ParticlesSeek,
|
ParticlesSeek,
|
||||||
SyncEnvBackground,
|
SyncEnvBackground,
|
||||||
|
ViewportPreset,
|
||||||
GetNodeAtPos,
|
GetNodeAtPos,
|
||||||
GetNodeAtMainScenePos,
|
GetNodeAtMainScenePos,
|
||||||
SetBakeLightsView3D,
|
SetBakeLightsView3D,
|
||||||
SplitViewToggle,
|
ViewportViewToggle,
|
||||||
MaterialOverride,
|
MaterialOverride,
|
||||||
ShowWireframe,
|
ShowWireframe,
|
||||||
FlyModeToggle,
|
FlyModeToggle,
|
||||||
|
@@ -98,11 +98,11 @@ void Edit3DCanvas::setFlyMode(bool enabled, const QPoint &pos)
|
|||||||
m_flyModeStartCursorPos = pos;
|
m_flyModeStartCursorPos = pos;
|
||||||
m_flyModeFirstUpdate = true;
|
m_flyModeFirstUpdate = true;
|
||||||
|
|
||||||
// Hide cursor on the middle of the active split to make the wheel work during flight mode.
|
// Hide cursor on the middle of the active viewport to make the wheel work during flight mode.
|
||||||
// We can't rely on current activeSplit value, as mouse press to enter flight mode can change the
|
// We can't rely on current activeViewport value, as mouse press to enter flight mode can change the
|
||||||
// active split, so hide the cursor based on its current location.
|
// active viewport, so hide the cursor based on its current location.
|
||||||
QPoint center = mapToGlobal(QPoint(width() / 2, height() / 2));
|
QPoint center = mapToGlobal(QPoint(width() / 2, height() / 2));
|
||||||
if (m_parent->view()->isSplitView()) {
|
if (m_parent->view()->isMultiViewportView()) {
|
||||||
if (pos.x() <= center.x()) {
|
if (pos.x() <= center.x()) {
|
||||||
if (pos.y() <= center.y())
|
if (pos.y() <= center.y())
|
||||||
m_hiddenCursorPos = mapToGlobal(QPoint(width() / 4, height() / 4));
|
m_hiddenCursorPos = mapToGlobal(QPoint(width() / 4, height() / 4));
|
||||||
@@ -192,7 +192,7 @@ void Edit3DCanvas::mouseMoveEvent(QMouseEvent *e)
|
|||||||
if (!m_flyModeFirstUpdate) {
|
if (!m_flyModeFirstUpdate) {
|
||||||
// We notify explicit camera rotation needs for QML Puppet rather than relying on mouse events,
|
// We notify explicit camera rotation needs for QML Puppet rather than relying on mouse events,
|
||||||
// as mouse isn't grabbed on QML Puppet side and can't handle fast movements that go out of
|
// as mouse isn't grabbed on QML Puppet side and can't handle fast movements that go out of
|
||||||
// edit camera mouse area. This also simplifies split view handling.
|
// edit camera mouse area. This also simplifies viewport view handling.
|
||||||
QPointF diff = m_isQDSTrusted ? (m_hiddenCursorPos - globalPos)
|
QPointF diff = m_isQDSTrusted ? (m_hiddenCursorPos - globalPos)
|
||||||
: (m_lastCursorPos - e->globalPosition().toPoint());
|
: (m_lastCursorPos - e->globalPosition().toPoint());
|
||||||
|
|
||||||
|
@@ -73,7 +73,7 @@ Edit3DView::Edit3DView(ExternalDependenciesInterface &externalDependencies)
|
|||||||
connect(&m_compressionTimer, &QTimer::timeout, this, &Edit3DView::handleEntriesChanged);
|
connect(&m_compressionTimer, &QTimer::timeout, this, &Edit3DView::handleEntriesChanged);
|
||||||
|
|
||||||
for (int i = 0; i < 4; ++i)
|
for (int i = 0; i < 4; ++i)
|
||||||
m_splitToolStates.append({0, false, i == 0});
|
m_viewportToolStates.append({0, false, i == 0});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Edit3DView::createEdit3DWidget()
|
void Edit3DView::createEdit3DWidget()
|
||||||
@@ -120,15 +120,15 @@ void Edit3DView::renderImage3DChanged(const QImage &img)
|
|||||||
|
|
||||||
void Edit3DView::updateActiveScene3D(const QVariantMap &sceneState)
|
void Edit3DView::updateActiveScene3D(const QVariantMap &sceneState)
|
||||||
{
|
{
|
||||||
const QString activeSplitKey = QStringLiteral("activeSplit");
|
const QString activeViewportKey = QStringLiteral("activeViewport");
|
||||||
if (sceneState.contains(activeSplitKey)) {
|
if (sceneState.contains(activeViewportKey)) {
|
||||||
setActiveSplit(sceneState[activeSplitKey].toInt());
|
setActiveViewport(sceneState[activeViewportKey].toInt());
|
||||||
// If the sceneState contained just activeSplit key, then this is simply an active split
|
// If the sceneState contained just activeViewport key, then this is simply an active Viewport
|
||||||
// change rather than entire active scene change, and we don't need to process further.
|
// change rather than entire active scene change, and we don't need to process further.
|
||||||
if (sceneState.size() == 1)
|
if (sceneState.size() == 1)
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
setActiveSplit(0);
|
setActiveViewport(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString sceneKey = QStringLiteral("sceneInstanceId");
|
const QString sceneKey = QStringLiteral("sceneInstanceId");
|
||||||
@@ -146,7 +146,7 @@ void Edit3DView::updateActiveScene3D(const QVariantMap &sceneState)
|
|||||||
const QString particleEmitterKey = QStringLiteral("showParticleEmitter");
|
const QString particleEmitterKey = QStringLiteral("showParticleEmitter");
|
||||||
const QString particlesPlayKey = QStringLiteral("particlePlay");
|
const QString particlesPlayKey = QStringLiteral("particlePlay");
|
||||||
const QString syncEnvBgKey = QStringLiteral("syncEnvBackground");
|
const QString syncEnvBgKey = QStringLiteral("syncEnvBackground");
|
||||||
const QString splitViewKey = QStringLiteral("splitView");
|
const QString activePresetKey = QStringLiteral("activePreset");
|
||||||
const QString matOverrideKey = QStringLiteral("matOverride");
|
const QString matOverrideKey = QStringLiteral("matOverride");
|
||||||
const QString showWireframeKey = QStringLiteral("showWireframe");
|
const QString showWireframeKey = QStringLiteral("showWireframe");
|
||||||
|
|
||||||
@@ -177,10 +177,10 @@ void Edit3DView::updateActiveScene3D(const QVariantMap &sceneState)
|
|||||||
if (sceneState.contains(perspectiveKey)) {
|
if (sceneState.contains(perspectiveKey)) {
|
||||||
const QVariantList showList = sceneState[perspectiveKey].toList();
|
const QVariantList showList = sceneState[perspectiveKey].toList();
|
||||||
for (int i = 0; i < 4; ++i)
|
for (int i = 0; i < 4; ++i)
|
||||||
m_splitToolStates[i].isPerspective = i < showList.size() ? showList[i].toBool() : i == 0;
|
m_viewportToolStates[i].isPerspective = i < showList.size() ? showList[i].toBool() : i == 0;
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
SplitToolState &state = m_splitToolStates[i];
|
ViewportToolState &state = m_viewportToolStates[i];
|
||||||
state.isPerspective = i == 0;
|
state.isPerspective = i == 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,26 +235,21 @@ void Edit3DView::updateActiveScene3D(const QVariantMap &sceneState)
|
|||||||
else
|
else
|
||||||
m_particlesPlayAction->action()->setChecked(true);
|
m_particlesPlayAction->action()->setChecked(true);
|
||||||
|
|
||||||
if (sceneState.contains(splitViewKey))
|
|
||||||
m_splitViewAction->action()->setChecked(sceneState[splitViewKey].toBool());
|
|
||||||
else
|
|
||||||
m_splitViewAction->action()->setChecked(false);
|
|
||||||
|
|
||||||
if (sceneState.contains(matOverrideKey)) {
|
if (sceneState.contains(matOverrideKey)) {
|
||||||
const QVariantList overrides = sceneState[matOverrideKey].toList();
|
const QVariantList overrides = sceneState[matOverrideKey].toList();
|
||||||
for (int i = 0; i < 4; ++i)
|
for (int i = 0; i < 4; ++i)
|
||||||
m_splitToolStates[i].matOverride = i < overrides.size() ? overrides[i].toInt() : 0;
|
m_viewportToolStates[i].matOverride = i < overrides.size() ? overrides[i].toInt() : 0;
|
||||||
} else {
|
} else {
|
||||||
for (SplitToolState &state : m_splitToolStates)
|
for (ViewportToolState &state : m_viewportToolStates)
|
||||||
state.matOverride = 0;
|
state.matOverride = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sceneState.contains(showWireframeKey)) {
|
if (sceneState.contains(showWireframeKey)) {
|
||||||
const QVariantList showList = sceneState[showWireframeKey].toList();
|
const QVariantList showList = sceneState[showWireframeKey].toList();
|
||||||
for (int i = 0; i < 4; ++i)
|
for (int i = 0; i < 4; ++i)
|
||||||
m_splitToolStates[i].showWireframe = i < showList.size() ? showList[i].toBool() : false;
|
m_viewportToolStates[i].showWireframe = i < showList.size() ? showList[i].toBool() : false;
|
||||||
} else {
|
} else {
|
||||||
for (SplitToolState &state : m_splitToolStates)
|
for (ViewportToolState &state : m_viewportToolStates)
|
||||||
state.showWireframe = false;
|
state.showWireframe = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,10 +269,10 @@ void Edit3DView::updateActiveScene3D(const QVariantMap &sceneState)
|
|||||||
storeCurrentSceneEnvironment();
|
storeCurrentSceneEnvironment();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Edit3DView::setActiveSplit(int split)
|
void Edit3DView::setActiveViewport(int viewport)
|
||||||
{
|
{
|
||||||
m_activeSplit = split;
|
m_activeViewport = viewport;
|
||||||
m_cameraModeAction->action()->setChecked(m_splitToolStates[m_activeSplit].isPerspective);
|
m_cameraModeAction->action()->setChecked(m_viewportToolStates[m_activeViewport].isPerspective);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Edit3DView::modelAttached(Model *model)
|
void Edit3DView::modelAttached(Model *model)
|
||||||
@@ -709,6 +704,45 @@ void Edit3DView::createSyncEnvBackgroundAction()
|
|||||||
tooltip);
|
tooltip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Edit3DView::createViewportPresetActions()
|
||||||
|
{
|
||||||
|
auto createViewportPresetAction = [this](std::unique_ptr<Edit3DAction> &targetAction,
|
||||||
|
const QByteArray &id,
|
||||||
|
const QString &label,
|
||||||
|
bool isChecked) {
|
||||||
|
auto operation = [this, &targetAction, label](const SelectionContext &) {
|
||||||
|
for (Edit3DAction *action : std::as_const(m_viewportPresetActions)) {
|
||||||
|
if (action->menuId() != targetAction->menuId())
|
||||||
|
action->action()->setChecked(false);
|
||||||
|
}
|
||||||
|
emitView3DAction(View3DActionType::ViewportPreset, label);
|
||||||
|
};
|
||||||
|
|
||||||
|
targetAction = std::make_unique<Edit3DAction>(
|
||||||
|
id,
|
||||||
|
View3DActionType::Empty,
|
||||||
|
label,
|
||||||
|
QKeySequence(),
|
||||||
|
true,
|
||||||
|
isChecked,
|
||||||
|
QIcon(),
|
||||||
|
this,
|
||||||
|
operation);
|
||||||
|
};
|
||||||
|
|
||||||
|
createViewportPresetAction(m_viewportPresetSingleAction, Constants::EDIT3D_PRESET_SINGLE, "Single", true);
|
||||||
|
createViewportPresetAction(m_viewportPresetQuadAction, Constants::EDIT3D_PRESET_QUAD, "Quad", false);
|
||||||
|
createViewportPresetAction(m_viewportPreset3Left1RightAction, Constants::EDIT3D_PRESET_3LEFT1RIGHT, "3Left1Right", false);
|
||||||
|
createViewportPresetAction(m_viewportPreset2HorizontalAction, Constants::EDIT3D_PRESET_2HORIZONTAL, "2Horizontal", false);
|
||||||
|
createViewportPresetAction(m_viewportPreset2VerticalAction, Constants::EDIT3D_PRESET_2VERTICAL, "2Vertical", false);
|
||||||
|
|
||||||
|
m_viewportPresetActions << m_viewportPresetSingleAction.get();
|
||||||
|
m_viewportPresetActions << m_viewportPresetQuadAction.get();
|
||||||
|
m_viewportPresetActions << m_viewportPreset3Left1RightAction.get();
|
||||||
|
m_viewportPresetActions << m_viewportPreset2HorizontalAction.get();
|
||||||
|
m_viewportPresetActions << m_viewportPreset2VerticalAction.get();
|
||||||
|
}
|
||||||
|
|
||||||
void Edit3DView::createSeekerSliderAction()
|
void Edit3DView::createSeekerSliderAction()
|
||||||
{
|
{
|
||||||
m_seekerAction = std::make_unique<Edit3DParticleSeekerAction>(
|
m_seekerAction = std::make_unique<Edit3DParticleSeekerAction>(
|
||||||
@@ -930,27 +964,27 @@ void Edit3DView::storeCurrentSceneEnvironment()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const QList<Edit3DView::SplitToolState> &Edit3DView::splitToolStates() const
|
const QList<Edit3DView::ViewportToolState> &Edit3DView::viewportToolStates() const
|
||||||
{
|
{
|
||||||
return m_splitToolStates;
|
return m_viewportToolStates;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Edit3DView::setSplitToolState(int splitIndex, const SplitToolState &state)
|
void Edit3DView::setViewportToolState(int viewportIndex, const ViewportToolState &state)
|
||||||
{
|
{
|
||||||
if (splitIndex >= m_splitToolStates.size())
|
if (viewportIndex >= m_viewportToolStates.size())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_splitToolStates[splitIndex] = state;
|
m_viewportToolStates[viewportIndex] = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Edit3DView::activeSplit() const
|
int Edit3DView::activeViewport() const
|
||||||
{
|
{
|
||||||
return m_activeSplit;
|
return m_activeViewport;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Edit3DView::isSplitView() const
|
bool Edit3DView::isMultiViewportView() const
|
||||||
{
|
{
|
||||||
return m_splitViewAction->action()->isChecked();
|
return m_viewportPresetsMenuAction->action()->isChecked();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Edit3DView::createEdit3DActions()
|
void Edit3DView::createEdit3DActions()
|
||||||
@@ -1022,12 +1056,12 @@ void Edit3DView::createEdit3DActions()
|
|||||||
|
|
||||||
SelectionContextOperation cameraModeTrigger = [this](const SelectionContext &) {
|
SelectionContextOperation cameraModeTrigger = [this](const SelectionContext &) {
|
||||||
QVariantList list;
|
QVariantList list;
|
||||||
for (int i = 0; i < m_splitToolStates.size(); ++i) {
|
for (int i = 0; i < m_viewportToolStates.size(); ++i) {
|
||||||
Edit3DView::SplitToolState state = m_splitToolStates[i];
|
Edit3DView::ViewportToolState state = m_viewportToolStates[i];
|
||||||
if (i == m_activeSplit) {
|
if (i == m_activeViewport) {
|
||||||
bool isChecked = m_cameraModeAction->action()->isChecked();
|
bool isChecked = m_cameraModeAction->action()->isChecked();
|
||||||
state.isPerspective = isChecked;
|
state.isPerspective = isChecked;
|
||||||
setSplitToolState(i, state);
|
setViewportToolState(i, state);
|
||||||
list.append(isChecked);
|
list.append(isChecked);
|
||||||
} else {
|
} else {
|
||||||
list.append(state.isPerspective);
|
list.append(state.isPerspective);
|
||||||
@@ -1315,14 +1349,24 @@ void Edit3DView::createEdit3DActions()
|
|||||||
this,
|
this,
|
||||||
snapConfigTrigger);
|
snapConfigTrigger);
|
||||||
|
|
||||||
m_splitViewAction = std::make_unique<Edit3DAction>(QmlDesigner::Constants::EDIT3D_SPLIT_VIEW,
|
SelectionContextOperation viewportPresetsActionTrigger = [this](const SelectionContext &) {
|
||||||
View3DActionType::SplitViewToggle,
|
if (!edit3DWidget()->viewportPresetsMenu())
|
||||||
Tr::tr("Toggle Split View On/Off"),
|
return;
|
||||||
QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_Q),
|
|
||||||
true,
|
edit3DWidget()->showViewportPresetsMenu(
|
||||||
|
!edit3DWidget()->viewportPresetsMenu()->isVisible(),
|
||||||
|
resolveToolbarPopupPos(m_viewportPresetsMenuAction.get()));
|
||||||
|
};
|
||||||
|
|
||||||
|
m_viewportPresetsMenuAction = std::make_unique<Edit3DAction>(QmlDesigner::Constants::EDIT3D_PRESETS,
|
||||||
|
View3DActionType::Empty,
|
||||||
|
Tr::tr("Show Viewport Modes"),
|
||||||
|
QKeySequence(),
|
||||||
|
false,
|
||||||
false,
|
false,
|
||||||
toolbarIcon(DesignerIcons::SplitViewIcon),
|
toolbarIcon(DesignerIcons::SplitViewIcon),
|
||||||
this);
|
this,
|
||||||
|
viewportPresetsActionTrigger);
|
||||||
|
|
||||||
SelectionContextOperation cameraSpeedConfigTrigger = [this](const SelectionContext &) {
|
SelectionContextOperation cameraSpeedConfigTrigger = [this](const SelectionContext &) {
|
||||||
if (!m_cameraSpeedConfiguration) {
|
if (!m_cameraSpeedConfiguration) {
|
||||||
@@ -1372,7 +1416,7 @@ void Edit3DView::createEdit3DActions()
|
|||||||
m_leftActions << nullptr;
|
m_leftActions << nullptr;
|
||||||
m_leftActions << m_visibilityTogglesAction.get();
|
m_leftActions << m_visibilityTogglesAction.get();
|
||||||
m_leftActions << m_backgroundColorMenuAction.get();
|
m_leftActions << m_backgroundColorMenuAction.get();
|
||||||
m_leftActions << m_splitViewAction.get();
|
m_leftActions << m_viewportPresetsMenuAction.get();
|
||||||
|
|
||||||
m_rightActions << m_particleViewModeAction.get();
|
m_rightActions << m_particleViewModeAction.get();
|
||||||
m_rightActions << m_particlesPlayAction.get();
|
m_rightActions << m_particlesPlayAction.get();
|
||||||
@@ -1400,6 +1444,8 @@ void Edit3DView::createEdit3DActions()
|
|||||||
m_backgroundColorActions << m_selectGridColorAction.get();
|
m_backgroundColorActions << m_selectGridColorAction.get();
|
||||||
m_backgroundColorActions << m_syncEnvBackgroundAction.get();
|
m_backgroundColorActions << m_syncEnvBackgroundAction.get();
|
||||||
m_backgroundColorActions << m_resetColorAction.get();
|
m_backgroundColorActions << m_resetColorAction.get();
|
||||||
|
|
||||||
|
createViewportPresetActions();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<Edit3DAction *> Edit3DView::leftActions() const
|
QVector<Edit3DAction *> Edit3DView::leftActions() const
|
||||||
@@ -1422,6 +1468,10 @@ QVector<Edit3DAction *> Edit3DView::backgroundColorActions() const
|
|||||||
return m_backgroundColorActions;
|
return m_backgroundColorActions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVector<Edit3DAction *> Edit3DView::viewportPresetActions() const
|
||||||
|
{
|
||||||
|
return m_viewportPresetActions;
|
||||||
|
}
|
||||||
|
|
||||||
Edit3DAction *Edit3DView::edit3DAction(View3DActionType type) const
|
Edit3DAction *Edit3DView::edit3DAction(View3DActionType type) const
|
||||||
{
|
{
|
||||||
|
@@ -39,7 +39,7 @@ class QMLDESIGNERCOMPONENTS_EXPORT Edit3DView : public AbstractView
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct SplitToolState
|
struct ViewportToolState
|
||||||
{
|
{
|
||||||
int matOverride = 0;
|
int matOverride = 0;
|
||||||
bool showWireframe = false;
|
bool showWireframe = false;
|
||||||
@@ -92,6 +92,7 @@ public:
|
|||||||
QVector<Edit3DAction *> rightActions() const;
|
QVector<Edit3DAction *> rightActions() const;
|
||||||
QVector<Edit3DAction *> visibilityToggleActions() const;
|
QVector<Edit3DAction *> visibilityToggleActions() const;
|
||||||
QVector<Edit3DAction *> backgroundColorActions() const;
|
QVector<Edit3DAction *> backgroundColorActions() const;
|
||||||
|
QVector<Edit3DAction *> viewportPresetActions() const;
|
||||||
Edit3DAction *edit3DAction(View3DActionType type) const;
|
Edit3DAction *edit3DAction(View3DActionType type) const;
|
||||||
Edit3DBakeLightsAction *bakeLightsAction() const;
|
Edit3DBakeLightsAction *bakeLightsAction() const;
|
||||||
|
|
||||||
@@ -110,11 +111,11 @@ public:
|
|||||||
void setCameraSpeedAuxData(double speed, double multiplier);
|
void setCameraSpeedAuxData(double speed, double multiplier);
|
||||||
void getCameraSpeedAuxData(double &speed, double &multiplier);
|
void getCameraSpeedAuxData(double &speed, double &multiplier);
|
||||||
|
|
||||||
const QList<SplitToolState> &splitToolStates() const;
|
const QList<ViewportToolState> &viewportToolStates() const;
|
||||||
void setSplitToolState(int splitIndex, const SplitToolState &state);
|
void setViewportToolState(int viewportIndex, const ViewportToolState &state);
|
||||||
|
|
||||||
int activeSplit() const;
|
int activeViewport() const;
|
||||||
bool isSplitView() const;
|
bool isMultiViewportView() const;
|
||||||
void setFlyMode(bool enabled);
|
void setFlyMode(bool enabled);
|
||||||
void emitView3DAction(View3DActionType type, const QVariant &value);
|
void emitView3DAction(View3DActionType type, const QVariant &value);
|
||||||
|
|
||||||
@@ -147,12 +148,13 @@ private:
|
|||||||
void createGridColorSelectionAction();
|
void createGridColorSelectionAction();
|
||||||
void createResetColorAction(QAction *syncEnvBackgroundAction);
|
void createResetColorAction(QAction *syncEnvBackgroundAction);
|
||||||
void createSyncEnvBackgroundAction();
|
void createSyncEnvBackgroundAction();
|
||||||
|
void createViewportPresetActions();
|
||||||
void createSeekerSliderAction();
|
void createSeekerSliderAction();
|
||||||
void syncCameraSpeedToNewView();
|
void syncCameraSpeedToNewView();
|
||||||
QmlObjectNode currentSceneEnv();
|
QmlObjectNode currentSceneEnv();
|
||||||
void storeCurrentSceneEnvironment();
|
void storeCurrentSceneEnvironment();
|
||||||
|
|
||||||
void setActiveSplit(int split);
|
void setActiveViewport(int viewportIndex);
|
||||||
|
|
||||||
QPoint resolveToolbarPopupPos(Edit3DAction *action) const;
|
QPoint resolveToolbarPopupPos(Edit3DAction *action) const;
|
||||||
|
|
||||||
@@ -164,6 +166,7 @@ private:
|
|||||||
QVector<Edit3DAction *> m_rightActions;
|
QVector<Edit3DAction *> m_rightActions;
|
||||||
QVector<Edit3DAction *> m_visibilityToggleActions;
|
QVector<Edit3DAction *> m_visibilityToggleActions;
|
||||||
QVector<Edit3DAction *> m_backgroundColorActions;
|
QVector<Edit3DAction *> m_backgroundColorActions;
|
||||||
|
QVector<Edit3DAction *> m_viewportPresetActions;
|
||||||
|
|
||||||
QMap<View3DActionType, Edit3DAction *> m_edit3DActions;
|
QMap<View3DActionType, Edit3DAction *> m_edit3DActions;
|
||||||
std::unique_ptr<Edit3DAction> m_selectionModeAction;
|
std::unique_ptr<Edit3DAction> m_selectionModeAction;
|
||||||
@@ -191,7 +194,14 @@ private:
|
|||||||
std::unique_ptr<Edit3DAction> m_selectBackgroundColorAction;
|
std::unique_ptr<Edit3DAction> m_selectBackgroundColorAction;
|
||||||
std::unique_ptr<Edit3DAction> m_selectGridColorAction;
|
std::unique_ptr<Edit3DAction> m_selectGridColorAction;
|
||||||
std::unique_ptr<Edit3DAction> m_resetColorAction;
|
std::unique_ptr<Edit3DAction> m_resetColorAction;
|
||||||
std::unique_ptr<Edit3DAction> m_splitViewAction;
|
|
||||||
|
// Viewport presets actions
|
||||||
|
std::unique_ptr<Edit3DAction> m_viewportPresetSingleAction;
|
||||||
|
std::unique_ptr<Edit3DAction> m_viewportPresetQuadAction;
|
||||||
|
std::unique_ptr<Edit3DAction> m_viewportPreset3Left1RightAction;
|
||||||
|
std::unique_ptr<Edit3DAction> m_viewportPreset2HorizontalAction;
|
||||||
|
std::unique_ptr<Edit3DAction> m_viewportPreset2VerticalAction;
|
||||||
|
std::unique_ptr<Edit3DAction> m_viewportPresetsMenuAction;
|
||||||
|
|
||||||
// View3DActionType::Empty actions
|
// View3DActionType::Empty actions
|
||||||
std::unique_ptr<Edit3DAction> m_resetAction;
|
std::unique_ptr<Edit3DAction> m_resetAction;
|
||||||
@@ -216,9 +226,9 @@ private:
|
|||||||
bool m_isBakingLightsSupported = false;
|
bool m_isBakingLightsSupported = false;
|
||||||
QPointer<SnapConfiguration> m_snapConfiguration;
|
QPointer<SnapConfiguration> m_snapConfiguration;
|
||||||
QPointer<CameraSpeedConfiguration> m_cameraSpeedConfiguration;
|
QPointer<CameraSpeedConfiguration> m_cameraSpeedConfiguration;
|
||||||
int m_activeSplit = 0;
|
int m_activeViewport = 0;
|
||||||
|
|
||||||
QList<SplitToolState> m_splitToolStates;
|
QList<ViewportToolState> m_viewportToolStates;
|
||||||
ModelNode m_contextMenuPendingNode;
|
ModelNode m_contextMenuPendingNode;
|
||||||
ModelNode m_pickView3dNode;
|
ModelNode m_pickView3dNode;
|
||||||
|
|
||||||
|
@@ -179,6 +179,10 @@ Edit3DWidget::Edit3DWidget(Edit3DView *view)
|
|||||||
|
|
||||||
handleActions(view->backgroundColorActions(), m_backgroundColorMenu, false);
|
handleActions(view->backgroundColorActions(), m_backgroundColorMenu, false);
|
||||||
|
|
||||||
|
m_viewportPresetsMenu = new QMenu(this);
|
||||||
|
m_viewportPresetsMenu->setToolTipsVisible(true);
|
||||||
|
handleActions(view->viewportPresetActions(), m_viewportPresetsMenu, false);
|
||||||
|
|
||||||
createContextMenu();
|
createContextMenu();
|
||||||
|
|
||||||
// Onboarding label contains instructions for new users how to get 3D content into the project
|
// Onboarding label contains instructions for new users how to get 3D content into the project
|
||||||
@@ -568,11 +572,11 @@ void Edit3DWidget::onMatOverrideAction(QAction *action)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
QVariantList list;
|
QVariantList list;
|
||||||
for (int i = 0; i < m_view->splitToolStates().size(); ++i) {
|
for (int i = 0; i < m_view->viewportToolStates().size(); ++i) {
|
||||||
Edit3DView::SplitToolState state = m_view->splitToolStates()[i];
|
Edit3DView::ViewportToolState state = m_view->viewportToolStates()[i];
|
||||||
if (i == m_view->activeSplit()) {
|
if (i == m_view->activeViewport()) {
|
||||||
state.matOverride = action->data().toInt();
|
state.matOverride = action->data().toInt();
|
||||||
m_view->setSplitToolState(i, state);
|
m_view->setViewportToolState(i, state);
|
||||||
list.append(action->data());
|
list.append(action->data());
|
||||||
} else {
|
} else {
|
||||||
list.append(state.matOverride);
|
list.append(state.matOverride);
|
||||||
@@ -588,11 +592,11 @@ void Edit3DWidget::onWireframeAction()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
QVariantList list;
|
QVariantList list;
|
||||||
for (int i = 0; i < m_view->splitToolStates().size(); ++i) {
|
for (int i = 0; i < m_view->viewportToolStates().size(); ++i) {
|
||||||
Edit3DView::SplitToolState state = m_view->splitToolStates()[i];
|
Edit3DView::ViewportToolState state = m_view->viewportToolStates()[i];
|
||||||
if (i == m_view->activeSplit()) {
|
if (i == m_view->activeViewport()) {
|
||||||
state.showWireframe = m_wireFrameAction->isChecked();
|
state.showWireframe = m_wireFrameAction->isChecked();
|
||||||
m_view->setSplitToolState(i, state);
|
m_view->setViewportToolState(i, state);
|
||||||
list.append(m_wireFrameAction->isChecked());
|
list.append(m_wireFrameAction->isChecked());
|
||||||
} else {
|
} else {
|
||||||
list.append(state.showWireframe);
|
list.append(state.showWireframe);
|
||||||
@@ -610,11 +614,11 @@ void Edit3DWidget::onResetAllOverridesAction()
|
|||||||
QVariantList wList;
|
QVariantList wList;
|
||||||
QVariantList mList;
|
QVariantList mList;
|
||||||
|
|
||||||
for (int i = 0; i < m_view->splitToolStates().size(); ++i) {
|
for (int i = 0; i < m_view->viewportToolStates().size(); ++i) {
|
||||||
Edit3DView::SplitToolState state;
|
Edit3DView::ViewportToolState state;
|
||||||
state.showWireframe = false;
|
state.showWireframe = false;
|
||||||
state.matOverride = 0;
|
state.matOverride = 0;
|
||||||
m_view->setSplitToolState(i, state);
|
m_view->setViewportToolState(i, state);
|
||||||
wList.append(state.showWireframe);
|
wList.append(state.showWireframe);
|
||||||
mList.append(state.matOverride);
|
mList.append(state.matOverride);
|
||||||
}
|
}
|
||||||
@@ -675,6 +679,21 @@ void Edit3DWidget::showBackgroundColorMenu(bool show, const QPoint &pos)
|
|||||||
m_backgroundColorMenu->close();
|
m_backgroundColorMenu->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QMenu *Edit3DWidget::viewportPresetsMenu() const
|
||||||
|
{
|
||||||
|
return m_viewportPresetsMenu.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Edit3DWidget::showViewportPresetsMenu(bool show, const QPoint &pos)
|
||||||
|
{
|
||||||
|
if (m_viewportPresetsMenu.isNull())
|
||||||
|
return;
|
||||||
|
if (show)
|
||||||
|
m_viewportPresetsMenu->popup(pos);
|
||||||
|
else
|
||||||
|
m_viewportPresetsMenu->close();
|
||||||
|
}
|
||||||
|
|
||||||
void Edit3DWidget::showContextMenu(const QPoint &pos, const ModelNode &modelNode, const QVector3D &pos3d)
|
void Edit3DWidget::showContextMenu(const QPoint &pos, const ModelNode &modelNode, const QVector3D &pos3d)
|
||||||
{
|
{
|
||||||
auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils();
|
auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils();
|
||||||
@@ -711,11 +730,11 @@ void Edit3DWidget::showContextMenu(const QPoint &pos, const ModelNode &modelNode
|
|||||||
m_materialsAction->updateMenu(view()->selectedModelNodes());
|
m_materialsAction->updateMenu(view()->selectedModelNodes());
|
||||||
|
|
||||||
if (m_view) {
|
if (m_view) {
|
||||||
int idx = m_view->activeSplit();
|
int idx = m_view->activeViewport();
|
||||||
m_wireFrameAction->setChecked(m_view->splitToolStates()[idx].showWireframe);
|
m_wireFrameAction->setChecked(m_view->viewportToolStates()[idx].showWireframe);
|
||||||
for (QAction *a : std::as_const(m_matOverrideActions))
|
for (QAction *a : std::as_const(m_matOverrideActions))
|
||||||
a->setChecked(false);
|
a->setChecked(false);
|
||||||
int type = m_view->splitToolStates()[idx].matOverride;
|
int type = m_view->viewportToolStates()[idx].matOverride;
|
||||||
m_matOverrideActions[type]->setChecked(true);
|
m_matOverrideActions[type]->setChecked(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -58,6 +58,9 @@ public:
|
|||||||
QMenu *backgroundColorMenu() const;
|
QMenu *backgroundColorMenu() const;
|
||||||
void showBackgroundColorMenu(bool show, const QPoint &pos);
|
void showBackgroundColorMenu(bool show, const QPoint &pos);
|
||||||
|
|
||||||
|
QMenu *viewportPresetsMenu() const;
|
||||||
|
void showViewportPresetsMenu(bool show, const QPoint &pos);
|
||||||
|
|
||||||
void showContextMenu(const QPoint &pos, const ModelNode &modelNode, const QVector3D &pos3d);
|
void showContextMenu(const QPoint &pos, const ModelNode &modelNode, const QVector3D &pos3d);
|
||||||
void updateCreateSubMenu(const QList<ItemLibraryDetails> &entriesList);
|
void updateCreateSubMenu(const QList<ItemLibraryDetails> &entriesList);
|
||||||
|
|
||||||
@@ -91,6 +94,7 @@ private:
|
|||||||
Core::IContext *m_context = nullptr;
|
Core::IContext *m_context = nullptr;
|
||||||
QPointer<QMenu> m_visibilityTogglesMenu;
|
QPointer<QMenu> m_visibilityTogglesMenu;
|
||||||
QPointer<QMenu> m_backgroundColorMenu;
|
QPointer<QMenu> m_backgroundColorMenu;
|
||||||
|
QPointer<QMenu> m_viewportPresetsMenu;
|
||||||
QPointer<QMenu> m_contextMenu;
|
QPointer<QMenu> m_contextMenu;
|
||||||
QPointer<QAction> m_bakeLightsAction;
|
QPointer<QAction> m_bakeLightsAction;
|
||||||
QPointer<QAction> m_editComponentAction;
|
QPointer<QAction> m_editComponentAction;
|
||||||
|
@@ -1811,12 +1811,12 @@ void NodeInstanceView::handlePuppetToCreatorCommand(const PuppetToCreatorCommand
|
|||||||
const auto sceneState = qvariant_cast<QVariantMap>(command.data());
|
const auto sceneState = qvariant_cast<QVariantMap>(command.data());
|
||||||
if (isAttached())
|
if (isAttached())
|
||||||
model()->emitUpdateActiveScene3D(this, sceneState);
|
model()->emitUpdateActiveScene3D(this, sceneState);
|
||||||
} else if (command.type() == PuppetToCreatorCommand::ActiveSplitChanged) {
|
} else if (command.type() == PuppetToCreatorCommand::ActiveViewportChanged) {
|
||||||
// Active split change is a special case of active scene change
|
// Active viewport change is a special case of active scene change
|
||||||
QVariantMap splitState;
|
QVariantMap viewportState;
|
||||||
splitState.insert("activeSplit", command.data());
|
viewportState.insert("activeViewport", command.data());
|
||||||
if (isAttached())
|
if (isAttached())
|
||||||
model()->emitUpdateActiveScene3D(this, splitState);
|
model()->emitUpdateActiveScene3D(this, viewportState);
|
||||||
} else if (command.type() == PuppetToCreatorCommand::RenderModelNodePreviewImage) {
|
} else if (command.type() == PuppetToCreatorCommand::RenderModelNodePreviewImage) {
|
||||||
ImageContainer container = qvariant_cast<ImageContainer>(command.data());
|
ImageContainer container = qvariant_cast<ImageContainer>(command.data());
|
||||||
QImage image = container.image();
|
QImage image = container.image();
|
||||||
|
@@ -44,6 +44,14 @@ inline constexpr char EDIT3D_EDIT_SHOW_CAMERA_FRUSTUM[]
|
|||||||
= "QmlDesigner.Editor3D.ToggleCameraFrustum";
|
= "QmlDesigner.Editor3D.ToggleCameraFrustum";
|
||||||
inline constexpr char EDIT3D_EDIT_SHOW_PARTICLE_EMITTER[]
|
inline constexpr char EDIT3D_EDIT_SHOW_PARTICLE_EMITTER[]
|
||||||
= "QmlDesigner.Editor3D.ToggleParticleEmitter";
|
= "QmlDesigner.Editor3D.ToggleParticleEmitter";
|
||||||
|
|
||||||
|
inline constexpr char EDIT3D_PRESETS[] = "QmlDesigner.Editor3D.Presets";
|
||||||
|
inline constexpr char EDIT3D_PRESET_SINGLE[] = "QmlDesigner.Editor3D.Single";
|
||||||
|
inline constexpr char EDIT3D_PRESET_QUAD[] = "QmlDesigner.Editor3D.Quad";
|
||||||
|
inline constexpr char EDIT3D_PRESET_3LEFT1RIGHT[] = "QmlDesigner.Editor3D.3Left1Right";
|
||||||
|
inline constexpr char EDIT3D_PRESET_2HORIZONTAL[] = "QmlDesigner.Editor3D.2Horizontal";
|
||||||
|
inline constexpr char EDIT3D_PRESET_2VERTICAL[] = "QmlDesigner.Editor3D.2Vertical";
|
||||||
|
|
||||||
inline constexpr char EDIT3D_RESET_VIEW[] = "QmlDesigner.Editor3D.ResetView";
|
inline constexpr char EDIT3D_RESET_VIEW[] = "QmlDesigner.Editor3D.ResetView";
|
||||||
inline constexpr char EDIT3D_PARTICLE_MODE[] = "QmlDesigner.Editor3D.ParticleViewModeToggle";
|
inline constexpr char EDIT3D_PARTICLE_MODE[] = "QmlDesigner.Editor3D.ParticleViewModeToggle";
|
||||||
inline constexpr char EDIT3D_PARTICLES_PLAY[] = "QmlDesigner.Editor3D.ParticlesPlay";
|
inline constexpr char EDIT3D_PARTICLES_PLAY[] = "QmlDesigner.Editor3D.ParticlesPlay";
|
||||||
|
@@ -8,9 +8,9 @@ Item {
|
|||||||
id: cameraCtrl
|
id: cameraCtrl
|
||||||
|
|
||||||
property var viewRoot: null
|
property var viewRoot: null
|
||||||
property int splitId: -1
|
property int viewportId: -1
|
||||||
property Camera camera: view3d ? view3d.camera : null
|
property Camera camera: view3d ? view3d.camera : null
|
||||||
property View3D view3d: viewRoot.editViews[splitId]
|
property View3D view3d: viewRoot.editViews[viewportId]
|
||||||
property string sceneId: viewRoot.sceneId
|
property string sceneId: viewRoot.sceneId
|
||||||
property vector3d _lookAtPoint
|
property vector3d _lookAtPoint
|
||||||
property vector3d _pressPoint
|
property vector3d _pressPoint
|
||||||
@@ -55,11 +55,11 @@ Item {
|
|||||||
_lookAtPoint = Qt.vector3d(0, 0, 0);
|
_lookAtPoint = Qt.vector3d(0, 0, 0);
|
||||||
_zoomFactor = 1;
|
_zoomFactor = 1;
|
||||||
|
|
||||||
if (splitId === 1) {
|
if (viewportId === 1) {
|
||||||
jumpToRotation(originGizmo.quaternionForAxis(OriginGizmo.PositiveZ));
|
jumpToRotation(originGizmo.quaternionForAxis(OriginGizmo.PositiveZ));
|
||||||
} else if (splitId === 2) {
|
} else if (viewportId === 2) {
|
||||||
jumpToRotation(originGizmo.quaternionForAxis(OriginGizmo.NegativeY));
|
jumpToRotation(originGizmo.quaternionForAxis(OriginGizmo.NegativeY));
|
||||||
} else if (splitId === 3) {
|
} else if (viewportId === 3) {
|
||||||
jumpToRotation(originGizmo.quaternionForAxis(OriginGizmo.NegativeX));
|
jumpToRotation(originGizmo.quaternionForAxis(OriginGizmo.NegativeX));
|
||||||
} else {
|
} else {
|
||||||
camera.position = _defaultCameraPosition;
|
camera.position = _defaultCameraPosition;
|
||||||
@@ -79,7 +79,7 @@ Item {
|
|||||||
cameraState[1] = _zoomFactor;
|
cameraState[1] = _zoomFactor;
|
||||||
cameraState[2] = camera.position;
|
cameraState[2] = camera.position;
|
||||||
cameraState[3] = camera.rotation;
|
cameraState[3] = camera.rotation;
|
||||||
_generalHelper.storeToolState(sceneId, "editCamState" + splitId, cameraState, delay);
|
_generalHelper.storeToolState(sceneId, "editCamState" + viewportId, cameraState, delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
function focusObject(targetNodes, rotation, updateZoom, closeUp)
|
function focusObject(targetNodes, rotation, updateZoom, closeUp)
|
||||||
@@ -254,12 +254,12 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
on_LookAtPointChanged: {
|
on_LookAtPointChanged: {
|
||||||
viewRoot.overlayViews[splitId].lookAtGizmo.position = _lookAtPoint;
|
viewRoot.overlayViews[viewportId].lookAtGizmo.position = _lookAtPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: _generalHelper
|
target: _generalHelper
|
||||||
enabled: viewRoot.activeSplit === cameraCtrl.splitId
|
enabled: viewRoot.activeViewport === cameraCtrl.viewportId
|
||||||
|
|
||||||
function onRequestCameraMove(camera, moveVec) {
|
function onRequestCameraMove(camera, moveVec) {
|
||||||
if (camera === cameraCtrl.camera) {
|
if (camera === cameraCtrl.camera) {
|
||||||
@@ -272,7 +272,7 @@ Item {
|
|||||||
Image {
|
Image {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
source: "qrc:///qtquickplugin/mockfiles/images/crosshair.png"
|
source: "qrc:///qtquickplugin/mockfiles/images/crosshair.png"
|
||||||
visible: cameraCtrl.showCrosshairs && viewRoot.activeSplit === cameraCtrl.splitId
|
visible: cameraCtrl.showCrosshairs && viewRoot.activeViewport === cameraCtrl.viewportId
|
||||||
opacity: 0.7
|
opacity: 0.7
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,7 +303,7 @@ Item {
|
|||||||
onPressed: (mouse) => {
|
onPressed: (mouse) => {
|
||||||
if (cameraCtrl.flyMode)
|
if (cameraCtrl.flyMode)
|
||||||
return;
|
return;
|
||||||
viewRoot.activeSplit = cameraCtrl.splitId
|
viewRoot.activeViewport = cameraCtrl.viewportId
|
||||||
if (cameraCtrl.camera && (mouse.modifiers & (Qt.AltModifier | Qt.ShiftModifier))) {
|
if (cameraCtrl.camera && (mouse.modifiers & (Qt.AltModifier | Qt.ShiftModifier))) {
|
||||||
cameraCtrl._dragging = true;
|
cameraCtrl._dragging = true;
|
||||||
cameraCtrl._startRotation = cameraCtrl.camera.eulerRotation;
|
cameraCtrl._startRotation = cameraCtrl.camera.eulerRotation;
|
||||||
@@ -328,9 +328,9 @@ Item {
|
|||||||
onCanceled: handleRelease()
|
onCanceled: handleRelease()
|
||||||
|
|
||||||
onWheel: (wheel) => {
|
onWheel: (wheel) => {
|
||||||
if (cameraCtrl.flyMode && cameraCtrl.splitId !== viewRoot.activeSplit)
|
if (cameraCtrl.flyMode && cameraCtrl.viewportId !== viewRoot.activeViewport)
|
||||||
return;
|
return;
|
||||||
viewRoot.activeSplit = cameraCtrl.splitId;
|
viewRoot.activeViewport = cameraCtrl.viewportId;
|
||||||
if (cameraCtrl.camera) {
|
if (cameraCtrl.camera) {
|
||||||
// Empirically determined divisor for nice zoom
|
// Empirically determined divisor for nice zoom
|
||||||
cameraCtrl.zoomRelative(wheel.angleDelta.y / -40);
|
cameraCtrl.zoomRelative(wheel.angleDelta.y / -40);
|
||||||
@@ -373,7 +373,7 @@ Item {
|
|||||||
targetNode: cameraCtrl.camera
|
targetNode: cameraCtrl.camera
|
||||||
|
|
||||||
onAxisClicked: (axis) => {
|
onAxisClicked: (axis) => {
|
||||||
viewRoot.activeSplit = cameraCtrl.splitId
|
viewRoot.activeViewport = cameraCtrl.viewportId
|
||||||
cameraCtrl.jumpToRotation(quaternionForAxis(axis));
|
cameraCtrl.jumpToRotation(quaternionForAxis(axis));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -12,7 +12,7 @@ Item {
|
|||||||
visible: true
|
visible: true
|
||||||
|
|
||||||
property Node activeScene: null
|
property Node activeScene: null
|
||||||
property int activeSplit: 0
|
property int activeViewport: 0
|
||||||
property var editViews: [null, null, null, null]
|
property var editViews: [null, null, null, null]
|
||||||
property var usePerspective: [true, false, false, false]
|
property var usePerspective: [true, false, false, false]
|
||||||
property var overlayViews: [overlayView0, overlayView1, overlayView2, overlayView3]
|
property var overlayViews: [overlayView0, overlayView1, overlayView2, overlayView3]
|
||||||
@@ -21,8 +21,8 @@ Item {
|
|||||||
property var materialOverrides:
|
property var materialOverrides:
|
||||||
[DebugSettings.None, DebugSettings.None, DebugSettings.None, DebugSettings.None]
|
[DebugSettings.None, DebugSettings.None, DebugSettings.None, DebugSettings.None]
|
||||||
property var showWireframes: [false, false, false, false]
|
property var showWireframes: [false, false, false, false]
|
||||||
property var activeEditView: editViews[activeSplit]
|
property var activeEditView: editViews[activeViewport]
|
||||||
property var activeOverlayView: overlayViews[activeSplit]
|
property var activeOverlayView: overlayViews[activeViewport]
|
||||||
property string sceneId
|
property string sceneId
|
||||||
|
|
||||||
property bool showEditLight: false
|
property bool showEditLight: false
|
||||||
@@ -37,12 +37,56 @@ Item {
|
|||||||
property color backgroundGradientColorStart: "#222222"
|
property color backgroundGradientColorStart: "#222222"
|
||||||
property color backgroundGradientColorEnd: "#999999"
|
property color backgroundGradientColorEnd: "#999999"
|
||||||
property color gridColor: "#cccccc"
|
property color gridColor: "#cccccc"
|
||||||
|
property color viewportBorderColor: "#aaaaaaaa"
|
||||||
property bool syncEnvBackground: true
|
property bool syncEnvBackground: true
|
||||||
property bool splitView: false
|
property string activePreset: "Single"
|
||||||
property bool flyMode: false
|
property bool flyMode: false
|
||||||
property bool showCameraSpeed: false
|
property bool showCameraSpeed: false
|
||||||
property string cameraViewMode
|
property string cameraViewMode
|
||||||
|
|
||||||
|
// The presets used to customize the display of the viewports
|
||||||
|
property var viewportPresets: {
|
||||||
|
"Single": {
|
||||||
|
numViewports: 1,
|
||||||
|
viewRects: [
|
||||||
|
{ x: 0.0, y: 0.0, width: 1.0, height: 1.0 }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Quad": {
|
||||||
|
numViewports: 4,
|
||||||
|
viewRects: [
|
||||||
|
{ x: 0.0, y: 0.0, width: 0.5, height: 0.5 },
|
||||||
|
{ x: 0.5, y: 0.0, width: 0.5, height: 0.5 },
|
||||||
|
{ x: 0.0, y: 0.5, width: 0.5, height: 0.5 },
|
||||||
|
{ x: 0.5, y: 0.5, width: 0.5, height: 0.5 }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"3Left1Right": {
|
||||||
|
numViewports: 4,
|
||||||
|
viewRects: [
|
||||||
|
{ x: 0.0, y: 0.0, width: 0.25, height: 0.33 },
|
||||||
|
{ x: 0.0, y: 0.33, width: 0.25, height: 0.34 },
|
||||||
|
{ x: 0.0, y: 0.67, width: 0.25, height: 0.33 },
|
||||||
|
{ x: 0.25, y: 0.0, width: 0.75, height: 1.0 }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"2Horizontal": {
|
||||||
|
numViewports: 2,
|
||||||
|
viewRects: [
|
||||||
|
{ x: 0.0, y: 0.0, width: 1.0, height: 0.5 },
|
||||||
|
{ x: 0.0, y: 0.5, width: 1.0, height: 0.5 }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"2Vertical": {
|
||||||
|
numViewports: 2,
|
||||||
|
viewRects: [
|
||||||
|
{ x: 0.0, y: 0.0, width: 0.5, height: 1.0 },
|
||||||
|
{ x: 0.5, y: 0.0, width: 0.5, height: 1.0 }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
//TODO: reset of presets
|
||||||
|
};
|
||||||
|
|
||||||
enum SelectionMode { Item, Group }
|
enum SelectionMode { Item, Group }
|
||||||
enum TransformMode { Move, Rotate, Scale }
|
enum TransformMode { Move, Rotate, Scale }
|
||||||
|
|
||||||
@@ -64,7 +108,7 @@ Item {
|
|||||||
signal commitObjectProperty(var objects, var propNames)
|
signal commitObjectProperty(var objects, var propNames)
|
||||||
signal changeObjectProperty(var objects, var propNames)
|
signal changeObjectProperty(var objects, var propNames)
|
||||||
signal notifyActiveSceneChange()
|
signal notifyActiveSceneChange()
|
||||||
signal notifyActiveSplitChange(int index)
|
signal notifyActiveViewportChange(int index)
|
||||||
|
|
||||||
onUsePerspectiveChanged: _generalHelper.storeToolState(sceneId, "usePerspective", usePerspective)
|
onUsePerspectiveChanged: _generalHelper.storeToolState(sceneId, "usePerspective", usePerspective)
|
||||||
onShowEditLightChanged: _generalHelper.storeToolState(sceneId, "showEditLight", showEditLight)
|
onShowEditLightChanged: _generalHelper.storeToolState(sceneId, "showEditLight", showEditLight)
|
||||||
@@ -81,14 +125,14 @@ Item {
|
|||||||
onTransformModeChanged: _generalHelper.storeToolState(sceneId, "transformMode", transformMode);
|
onTransformModeChanged: _generalHelper.storeToolState(sceneId, "transformMode", transformMode);
|
||||||
onMaterialOverridesChanged: _generalHelper.storeToolState(sceneId, "matOverride", materialOverrides);
|
onMaterialOverridesChanged: _generalHelper.storeToolState(sceneId, "matOverride", materialOverrides);
|
||||||
onShowWireframesChanged: _generalHelper.storeToolState(sceneId, "showWireframe", showWireframes);
|
onShowWireframesChanged: _generalHelper.storeToolState(sceneId, "showWireframe", showWireframes);
|
||||||
onSplitViewChanged: {
|
onActivePresetChanged: {
|
||||||
_generalHelper.storeToolState(sceneId, "splitView", splitView);
|
_generalHelper.storeToolState(sceneId, "activePreset", activePreset);
|
||||||
_generalHelper.requestOverlayUpdate();
|
_generalHelper.requestOverlayUpdate();
|
||||||
}
|
}
|
||||||
onActiveSplitChanged: {
|
onActiveViewportChanged: {
|
||||||
_generalHelper.storeToolState(sceneId, "activeSplit", activeSplit);
|
_generalHelper.storeToolState(sceneId, "activeViewport", activeViewport);
|
||||||
cameraControls[activeSplit].forceActiveFocus();
|
cameraControls[activeViewport].forceActiveFocus();
|
||||||
notifyActiveSplitChange(activeSplit);
|
notifyActiveViewportChange(activeViewport);
|
||||||
}
|
}
|
||||||
|
|
||||||
onActiveSceneChanged: updateActiveScene()
|
onActiveSceneChanged: updateActiveScene()
|
||||||
@@ -141,7 +185,7 @@ Item {
|
|||||||
|
|
||||||
selectionBoxCount = 0;
|
selectionBoxCount = 0;
|
||||||
editViewsChanged();
|
editViewsChanged();
|
||||||
cameraControls[activeSplit].forceActiveFocus();
|
cameraControls[activeViewport].forceActiveFocus();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -234,7 +278,7 @@ Item {
|
|||||||
} else if (selectedNodes.length > 0 && selectionBoxCount > 0) {
|
} else if (selectedNodes.length > 0 && selectionBoxCount > 0) {
|
||||||
boxModels.push(activeEditView.selectionBoxes[0].model);
|
boxModels.push(activeEditView.selectionBoxes[0].model);
|
||||||
}
|
}
|
||||||
cameraControls[activeSplit].focusObject(
|
cameraControls[activeViewport].focusObject(
|
||||||
boxModels, activeEditView.camera.eulerRotation, true, false);
|
boxModels, activeEditView.camera.eulerRotation, true, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -242,7 +286,7 @@ Item {
|
|||||||
function alignCamerasToView(cameraNodes)
|
function alignCamerasToView(cameraNodes)
|
||||||
{
|
{
|
||||||
if (activeEditView) {
|
if (activeEditView) {
|
||||||
cameraControls[activeSplit].alignCameras(cameraNodes);
|
cameraControls[activeViewport].alignCameras(cameraNodes);
|
||||||
var propertyNames = ["position", "eulerRotation"];
|
var propertyNames = ["position", "eulerRotation"];
|
||||||
viewRoot.changeObjectProperty(cameraNodes, propertyNames);
|
viewRoot.changeObjectProperty(cameraNodes, propertyNames);
|
||||||
viewRoot.commitObjectProperty(cameraNodes, propertyNames);
|
viewRoot.commitObjectProperty(cameraNodes, propertyNames);
|
||||||
@@ -252,7 +296,7 @@ Item {
|
|||||||
function alignViewToCamera(cameraNodes)
|
function alignViewToCamera(cameraNodes)
|
||||||
{
|
{
|
||||||
if (activeEditView)
|
if (activeEditView)
|
||||||
cameraControls[activeSplit].alignView(cameraNodes);
|
cameraControls[activeViewport].alignView(cameraNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateBackgroundColors(colors)
|
function updateBackgroundColors(colors)
|
||||||
@@ -388,15 +432,16 @@ Item {
|
|||||||
viewRoot.showCameraSpeed = false;
|
viewRoot.showCameraSpeed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("splitView" in toolStates)
|
if ("activePreset" in toolStates)
|
||||||
splitView = toolStates.splitView;
|
activePreset = toolStates.activePreset;
|
||||||
else if (resetToDefault)
|
else if (resetToDefault)
|
||||||
splitView = false;
|
activePreset = "Quad";
|
||||||
|
applyViewportPreset(activePreset)
|
||||||
|
|
||||||
if ("activeSplit" in toolStates)
|
if ("activeViewport" in toolStates)
|
||||||
activeSplit = toolStates.activeSplit;
|
activeViewport = toolStates.activeViewport;
|
||||||
else if (resetToDefault)
|
else if (resetToDefault)
|
||||||
activeSplit = 0;
|
activeViewport = 0;
|
||||||
|
|
||||||
if ("showWireframe" in toolStates)
|
if ("showWireframe" in toolStates)
|
||||||
showWireframes = toolStates.showWireframe;
|
showWireframes = toolStates.showWireframe;
|
||||||
@@ -424,8 +469,8 @@ Item {
|
|||||||
_generalHelper.storeToolState(sceneId, "globalOrientation", globalOrientation)
|
_generalHelper.storeToolState(sceneId, "globalOrientation", globalOrientation)
|
||||||
_generalHelper.storeToolState(sceneId, "selectionMode", selectionMode);
|
_generalHelper.storeToolState(sceneId, "selectionMode", selectionMode);
|
||||||
_generalHelper.storeToolState(sceneId, "transformMode", transformMode);
|
_generalHelper.storeToolState(sceneId, "transformMode", transformMode);
|
||||||
_generalHelper.storeToolState(sceneId, "splitView", splitView)
|
_generalHelper.storeToolState(sceneId, "activePreset", activePreset)
|
||||||
_generalHelper.storeToolState(sceneId, "activeSplit", activeSplit)
|
_generalHelper.storeToolState(sceneId, "activeViewport", activeViewport)
|
||||||
_generalHelper.storeToolState(sceneId, "showWireframe", showWireframes)
|
_generalHelper.storeToolState(sceneId, "showWireframe", showWireframes)
|
||||||
_generalHelper.storeToolState(sceneId, "matOverride", materialOverrides)
|
_generalHelper.storeToolState(sceneId, "matOverride", materialOverrides)
|
||||||
|
|
||||||
@@ -527,6 +572,7 @@ Item {
|
|||||||
selectionChanged(newSelection);
|
selectionChanged(newSelection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: only update the active viewport views
|
||||||
function addLightGizmo(scene, obj)
|
function addLightGizmo(scene, obj)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < 4; ++i)
|
for (var i = 0; i < 4; ++i)
|
||||||
@@ -617,64 +663,95 @@ Item {
|
|||||||
overlayViews[i].updateReflectionProbeGizmoScene(scene, obj);
|
overlayViews[i].updateReflectionProbeGizmoScene(scene, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveSplitPoint(x, y)
|
function resolveViewportPoint(x, y)
|
||||||
{
|
{
|
||||||
if (!splitView || activeSplit === 0)
|
let rect = viewRects[activeViewport];
|
||||||
|
// Check invisible or out or range, then fallback to original origin
|
||||||
|
if (!rect || !rect.visible)
|
||||||
return Qt.point(x, y);
|
return Qt.point(x, y);
|
||||||
|
|
||||||
if (activeSplit === 1)
|
// Transform topleft of the active viewport to be the origin
|
||||||
return Qt.point(x - viewContainer.width / 2, y);
|
return Qt.point(x - rect.x, y - rect.y);
|
||||||
else if (activeSplit === 2)
|
|
||||||
return Qt.point(x, y - viewContainer.height / 2);
|
|
||||||
else
|
|
||||||
return Qt.point(x - viewContainer.width / 2, y - viewContainer.height / 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateActiveSplit(x, y)
|
function updateActiveViewport(x, y)
|
||||||
{
|
{
|
||||||
if (splitView) {
|
for (let i = 0; i < 4; ++i) {
|
||||||
if (x <= viewContainer.width / 2) {
|
let rect = viewRects[i];
|
||||||
if (y <= viewContainer.height / 2)
|
if (!rect.visible)
|
||||||
activeSplit = 0;
|
continue;
|
||||||
else
|
|
||||||
activeSplit = 2;
|
if (x >= rect.x && x <= rect.x + rect.width
|
||||||
} else {
|
&& y >= rect.y && y <= rect.y + rect.height) {
|
||||||
if (y <= viewContainer.height / 2)
|
activeViewport = i;
|
||||||
activeSplit = 1;
|
return;
|
||||||
else
|
|
||||||
activeSplit = 3;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: if click outside all visible viewRects, do nothing
|
||||||
|
// or reset to e.g. activeVireport = -1 or 0
|
||||||
}
|
}
|
||||||
|
|
||||||
function gizmoAt(x, y)
|
function gizmoAt(x, y)
|
||||||
{
|
{
|
||||||
updateActiveSplit(x, y);
|
updateActiveViewport(x, y);
|
||||||
let splitPoint = resolveSplitPoint(x, y);
|
let viewportPoint = resolveViewportPoint(x, y);
|
||||||
|
|
||||||
return activeOverlayView.gizmoAt(splitPoint.x, splitPoint.y);
|
return activeOverlayView.gizmoAt(viewportPoint.x, viewportPoint.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
function rotateEditCamera(angles)
|
function rotateEditCamera(angles)
|
||||||
{
|
{
|
||||||
cameraControls[activeSplit].rotateCamera(angles);
|
cameraControls[activeViewport].rotateCamera(angles);
|
||||||
}
|
}
|
||||||
|
|
||||||
function moveEditCamera(amounts)
|
function moveEditCamera(amounts)
|
||||||
{
|
{
|
||||||
cameraControls[activeSplit].moveCamera(amounts);
|
cameraControls[activeViewport].moveCamera(amounts);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update viewports based on selected preset
|
||||||
|
function applyViewportPreset(presetName)
|
||||||
|
{
|
||||||
|
let preset = viewportPresets[presetName];
|
||||||
|
if (!preset)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let count = preset.numViewports;
|
||||||
|
|
||||||
|
for (let i = 0; i < 4; ++i) {
|
||||||
|
if (i < count) {
|
||||||
|
viewRects[i].visible = true;
|
||||||
|
viewRects[i].x = preset.viewRects[i].x * viewContainer.width;
|
||||||
|
viewRects[i].y = preset.viewRects[i].y * viewContainer.height;
|
||||||
|
viewRects[i].width = preset.viewRects[i].width * viewContainer.width;
|
||||||
|
viewRects[i].height = preset.viewRects[i].height * viewContainer.height;
|
||||||
|
} else {
|
||||||
|
viewRects[i].visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Do we need this here?
|
||||||
|
cameraView.updateSnapping();
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
createEditViews();
|
createEditViews();
|
||||||
selectObjects([]);
|
selectObjects([]);
|
||||||
|
applyViewportPreset(activePreset)
|
||||||
// Work-around the fact that the projection matrix for the camera is not calculated until
|
// Work-around the fact that the projection matrix for the camera is not calculated until
|
||||||
// the first frame is rendered, so any initial calls to mapFrom3DScene() will fail.
|
// the first frame is rendered, so any initial calls to mapFrom3DScene() will fail.
|
||||||
_generalHelper.requestOverlayUpdate();
|
_generalHelper.requestOverlayUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
onWidthChanged: _generalHelper.requestOverlayUpdate()
|
onWidthChanged: {
|
||||||
onHeightChanged: _generalHelper.requestOverlayUpdate()
|
applyViewportPreset(activePreset)
|
||||||
|
_generalHelper.requestOverlayUpdate()
|
||||||
|
}
|
||||||
|
onHeightChanged: {
|
||||||
|
applyViewportPreset(activePreset)
|
||||||
|
_generalHelper.requestOverlayUpdate()
|
||||||
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: _generalHelper
|
target: _generalHelper
|
||||||
@@ -715,9 +792,9 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Shared nodes of the overlay, set as importScene on all overlay views.
|
// Shared nodes of the overlay, set as importScene on all overlay views.
|
||||||
// Content here can be used as is on all splits.
|
// Content here can be used as is on all viewports.
|
||||||
// Nodes that utilize autoscaling or otherwise need to have different appearance on each split
|
// Nodes that utilize autoscaling or otherwise need to have different appearance on each viewport
|
||||||
// need to have separate copy on each split.
|
// need to have separate copy on each viewport.
|
||||||
Node {
|
Node {
|
||||||
id: overlayScene
|
id: overlayScene
|
||||||
|
|
||||||
@@ -743,12 +820,9 @@ Item {
|
|||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: viewRect0
|
id: viewRect0
|
||||||
width: viewRoot.splitView ? parent.width / 2 : parent.width
|
|
||||||
height: viewRoot.splitView ? parent.height / 2 : parent.height
|
|
||||||
x: 0
|
|
||||||
y: 0
|
|
||||||
visible: viewRoot.splitView || viewRoot.activeSplit == 0
|
|
||||||
gradient: bgGradient
|
gradient: bgGradient
|
||||||
|
border.width: 1
|
||||||
|
border.color: viewportBorderColor
|
||||||
OverlayView3D {
|
OverlayView3D {
|
||||||
id: overlayView0
|
id: overlayView0
|
||||||
editView: viewRoot.editViews[0]
|
editView: viewRoot.editViews[0]
|
||||||
@@ -765,18 +839,15 @@ Item {
|
|||||||
EditCameraController {
|
EditCameraController {
|
||||||
id: cameraControl0
|
id: cameraControl0
|
||||||
viewRoot: viewRoot
|
viewRoot: viewRoot
|
||||||
splitId: 0
|
viewportId: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: viewRect1
|
id: viewRect1
|
||||||
width: viewRoot.splitView ? parent.width / 2 : parent.width
|
|
||||||
height: viewRoot.splitView ? parent.height / 2 : parent.height
|
|
||||||
x: viewRoot.splitView ? parent.width / 2 : 0
|
|
||||||
y: 0
|
|
||||||
visible: viewRoot.splitView || viewRoot.activeSplit == 1
|
|
||||||
gradient: bgGradient
|
gradient: bgGradient
|
||||||
|
border.width: 1
|
||||||
|
border.color: viewportBorderColor
|
||||||
OverlayView3D {
|
OverlayView3D {
|
||||||
id: overlayView1
|
id: overlayView1
|
||||||
editView: viewRoot.editViews[1]
|
editView: viewRoot.editViews[1]
|
||||||
@@ -793,18 +864,15 @@ Item {
|
|||||||
EditCameraController {
|
EditCameraController {
|
||||||
id: cameraControl1
|
id: cameraControl1
|
||||||
viewRoot: viewRoot
|
viewRoot: viewRoot
|
||||||
splitId: 1
|
viewportId: 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: viewRect2
|
id: viewRect2
|
||||||
width: viewRoot.splitView ? parent.width / 2 : parent.width
|
|
||||||
height: viewRoot.splitView ? parent.height / 2 : parent.height
|
|
||||||
x: 0
|
|
||||||
y: viewRoot.splitView ? parent.height / 2 : 0
|
|
||||||
visible: viewRoot.splitView || viewRoot.activeSplit == 2
|
|
||||||
gradient: bgGradient
|
gradient: bgGradient
|
||||||
|
border.width: 1
|
||||||
|
border.color: viewportBorderColor
|
||||||
OverlayView3D {
|
OverlayView3D {
|
||||||
id: overlayView2
|
id: overlayView2
|
||||||
editView: viewRoot.editViews[2]
|
editView: viewRoot.editViews[2]
|
||||||
@@ -821,18 +889,15 @@ Item {
|
|||||||
EditCameraController {
|
EditCameraController {
|
||||||
id: cameraControl2
|
id: cameraControl2
|
||||||
viewRoot: viewRoot
|
viewRoot: viewRoot
|
||||||
splitId: 2
|
viewportId: 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: viewRect3
|
id: viewRect3
|
||||||
width: viewRoot.splitView ? parent.width / 2 : parent.width
|
|
||||||
height: viewRoot.splitView ? parent.height / 2 : parent.height
|
|
||||||
x: viewRoot.splitView ? parent.width / 2 : 0
|
|
||||||
y: viewRoot.splitView ? parent.height / 2 : 0
|
|
||||||
visible: viewRoot.splitView || viewRoot.activeSplit == 3
|
|
||||||
gradient: bgGradient
|
gradient: bgGradient
|
||||||
|
border.width: 1
|
||||||
|
border.color: viewportBorderColor
|
||||||
OverlayView3D {
|
OverlayView3D {
|
||||||
id: overlayView3
|
id: overlayView3
|
||||||
editView: viewRoot.editViews[3]
|
editView: viewRoot.editViews[3]
|
||||||
@@ -849,44 +914,21 @@ Item {
|
|||||||
EditCameraController {
|
EditCameraController {
|
||||||
id: cameraControl3
|
id: cameraControl3
|
||||||
viewRoot: viewRoot
|
viewRoot: viewRoot
|
||||||
splitId: 3
|
viewportId: 3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Active viewport highlight
|
||||||
Rectangle {
|
Rectangle {
|
||||||
// Vertical border between splits
|
visible: activePreset !== "Single" && viewRects[viewRoot.activeViewport].visible
|
||||||
visible: viewRoot.splitView
|
x: viewRects[viewRoot.activeViewport].x
|
||||||
x: parent.width / 2
|
y: viewRects[viewRoot.activeViewport].y
|
||||||
y: 0
|
width: viewRects[viewRoot.activeViewport].width
|
||||||
width: 1
|
height: viewRects[viewRoot.activeViewport].height
|
||||||
height: parent.height
|
|
||||||
border.width: 1
|
|
||||||
border.color: "#aaaaaa"
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
// Horizontal border between splits
|
|
||||||
visible: viewRoot.splitView
|
|
||||||
x: 0
|
|
||||||
y: parent.height / 2
|
|
||||||
height: 1
|
|
||||||
width: parent.width
|
|
||||||
border.width: 1
|
|
||||||
border.color: "#aaaaaa"
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
// Active split highlight
|
|
||||||
visible: viewRoot.splitView
|
|
||||||
x: viewRects[viewRoot.activeSplit].x
|
|
||||||
y: viewRects[viewRoot.activeSplit].y
|
|
||||||
height: viewRects[viewRoot.activeSplit].height
|
|
||||||
+ (viewRoot.activeSplit === 0 || viewRoot.activeSplit === 1 ? 1 : 0)
|
|
||||||
width: viewRects[viewRoot.activeSplit].width
|
|
||||||
+ (viewRoot.activeSplit === 0 || viewRoot.activeSplit === 2 ? 1 : 0)
|
|
||||||
border.width: 2
|
border.width: 2
|
||||||
border.color: "#57B9FC"
|
border.color: "#57B9FC"
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
z: 1000 // Edge case to make sure selection rect drawn over everything
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
@@ -903,20 +945,20 @@ Item {
|
|||||||
if (viewRoot.flyMode)
|
if (viewRoot.flyMode)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
viewRoot.updateActiveSplit(mouse.x, mouse.y);
|
viewRoot.updateActiveViewport(mouse.x, mouse.y);
|
||||||
|
|
||||||
let splitPoint = viewRoot.resolveSplitPoint(mouse.x, mouse.y);
|
let viewportPoint = viewRoot.resolveViewportPoint(mouse.x, mouse.y);
|
||||||
|
|
||||||
if (viewRoot.activeEditView) {
|
if (viewRoot.activeEditView) {
|
||||||
// First pick overlay to check for hits there
|
// First pick overlay to check for hits there
|
||||||
var pickResult = _generalHelper.pickViewAt(activeOverlayView,
|
var pickResult = _generalHelper.pickViewAt(activeOverlayView,
|
||||||
splitPoint.x, splitPoint.y);
|
viewportPoint.x, viewportPoint.y);
|
||||||
var resolvedResult = _generalHelper.resolvePick(pickResult.objectHit);
|
var resolvedResult = _generalHelper.resolvePick(pickResult.objectHit);
|
||||||
|
|
||||||
if (!resolvedResult) {
|
if (!resolvedResult) {
|
||||||
// No hits from overlay view, pick the main scene
|
// No hits from overlay view, pick the main scene
|
||||||
pickResult = _generalHelper.pickViewAt(viewRoot.activeEditView,
|
pickResult = _generalHelper.pickViewAt(viewRoot.activeEditView,
|
||||||
splitPoint.x, splitPoint.y);
|
viewportPoint.x, viewportPoint.y);
|
||||||
resolvedResult = _generalHelper.resolvePick(pickResult.objectHit);
|
resolvedResult = _generalHelper.resolvePick(pickResult.objectHit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -940,17 +982,17 @@ Item {
|
|||||||
}
|
}
|
||||||
onPositionChanged: (mouse) => {
|
onPositionChanged: (mouse) => {
|
||||||
if (freeDraggerArea) {
|
if (freeDraggerArea) {
|
||||||
let splitPoint = viewRoot.resolveSplitPoint(mouse.x, mouse.y);
|
let viewportPoint = viewRoot.resolveViewportPoint(mouse.x, mouse.y);
|
||||||
let splitPress = viewRoot.resolveSplitPoint(pressPoint.x, pressPoint.y);
|
let viewportPress = viewRoot.resolveViewportPoint(pressPoint.x, pressPoint.y);
|
||||||
if (initialMoveBlock && Math.abs(splitPress.x - splitPoint.x)
|
if (initialMoveBlock && Math.abs(viewportPress.x - viewportPoint.x)
|
||||||
+ Math.abs(splitPress.y - splitPoint.y) > 10) {
|
+ Math.abs(viewportPress.y - viewportPoint.y) > 10) {
|
||||||
// Don't force press event at actual press, as that puts the gizmo
|
// Don't force press event at actual press, as that puts the gizmo
|
||||||
// in free-dragging state, which is bad UX if drag is not actually done
|
// in free-dragging state, which is bad UX if drag is not actually done
|
||||||
freeDraggerArea.forcePressEvent(splitPress.x, splitPress.y);
|
freeDraggerArea.forcePressEvent(viewportPress.x, viewportPress.y);
|
||||||
freeDraggerArea.forceMoveEvent(splitPoint.x, splitPoint.y);
|
freeDraggerArea.forceMoveEvent(viewportPoint.x, viewportPoint.y);
|
||||||
initialMoveBlock = false;
|
initialMoveBlock = false;
|
||||||
} else {
|
} else {
|
||||||
freeDraggerArea.forceMoveEvent(splitPoint.x, splitPoint.y);
|
freeDraggerArea.forceMoveEvent(viewportPoint.x, viewportPoint.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -959,11 +1001,11 @@ Item {
|
|||||||
{
|
{
|
||||||
if (freeDraggerArea) {
|
if (freeDraggerArea) {
|
||||||
if (initialMoveBlock) {
|
if (initialMoveBlock) {
|
||||||
let splitPress = viewRoot.resolveSplitPoint(pressPoint.x, pressPoint.y);
|
let viewportPress = viewRoot.resolveViewportPoint(pressPoint.x, pressPoint.y);
|
||||||
freeDraggerArea.forceReleaseEvent(splitPress.x, splitPress.y);
|
freeDraggerArea.forceReleaseEvent(viewportPress.x, viewportPress.y);
|
||||||
} else {
|
} else {
|
||||||
let splitPoint = viewRoot.resolveSplitPoint(mouse.x, mouse.y);
|
let viewportPoint = viewRoot.resolveViewportPoint(mouse.x, mouse.y);
|
||||||
freeDraggerArea.forceReleaseEvent(splitPoint.x, splitPoint.y);
|
freeDraggerArea.forceReleaseEvent(viewportPoint.x, viewportPoint.y);
|
||||||
}
|
}
|
||||||
freeDraggerArea = null;
|
freeDraggerArea = null;
|
||||||
}
|
}
|
||||||
@@ -1107,19 +1149,17 @@ Item {
|
|||||||
viewPortSize: Qt.size(viewRoot.viewPortRect.width, viewRoot.viewPortRect.height)
|
viewPortSize: Qt.size(viewRoot.viewPortRect.width, viewRoot.viewPortRect.height)
|
||||||
|
|
||||||
function updateSnapping() {
|
function updateSnapping() {
|
||||||
if (!viewRoot.splitView)
|
const rect = viewRoot.viewRects[viewRoot.activeViewport];
|
||||||
cameraView.snapLeft = true
|
if (!rect || !rect.visible)
|
||||||
else if (viewRoot.activeSplit === 2)
|
return;
|
||||||
cameraView.snapLeft = false
|
|
||||||
else if (viewRoot.activeSplit === 3)
|
const centerX = rect.x + rect.width / 2;
|
||||||
cameraView.snapLeft = true
|
cameraView.snapLeft = centerX < viewContainer.width / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: viewRoot
|
target: viewRoot
|
||||||
|
onActiveViewportChanged: cameraView.updateSnapping()
|
||||||
onSplitViewChanged: cameraView.updateSnapping()
|
|
||||||
onActiveSplitChanged: cameraView.updateSnapping()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,7 +16,7 @@ View3D {
|
|||||||
|
|
||||||
property var viewRoot: null
|
property var viewRoot: null
|
||||||
property View3D editView: null
|
property View3D editView: null
|
||||||
property bool isActive: viewRoot.overlayViews[viewRoot.activeSplit] === overlayView
|
property bool isActive: viewRoot.overlayViews[viewRoot.activeViewport] === overlayView
|
||||||
|
|
||||||
property var lightIconGizmos: []
|
property var lightIconGizmos: []
|
||||||
property var cameraGizmos: []
|
property var cameraGizmos: []
|
||||||
@@ -629,7 +629,7 @@ View3D {
|
|||||||
scale: lookAtAutoScale.getScale(Qt.vector3d(10, 10, 10))
|
scale: lookAtAutoScale.getScale(Qt.vector3d(10, 10, 10))
|
||||||
visible: overlayView.viewRoot.showLookAt
|
visible: overlayView.viewRoot.showLookAt
|
||||||
&& overlayView.isActive
|
&& overlayView.isActive
|
||||||
&& !overlayView.viewRoot.cameraControls[viewRoot.activeSplit].showCrosshairs
|
&& !overlayView.viewRoot.cameraControls[viewRoot.activeViewport].showCrosshairs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -956,9 +956,9 @@ void Qt5InformationNodeInstanceServer::handleActiveSceneChange()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Qt5InformationNodeInstanceServer::handleActiveSplitChange(int index)
|
void Qt5InformationNodeInstanceServer::handleActiveViewportChange(int index)
|
||||||
{
|
{
|
||||||
nodeInstanceClient()->handlePuppetToCreatorCommand({PuppetToCreatorCommand::ActiveSplitChanged,
|
nodeInstanceClient()->handlePuppetToCreatorCommand({PuppetToCreatorCommand::ActiveViewportChanged,
|
||||||
index});
|
index});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1966,8 +1966,8 @@ void Qt5InformationNodeInstanceServer::setup3DEditView(
|
|||||||
this, SLOT(handleObjectPropertyChange(QVariant, QVariant)));
|
this, SLOT(handleObjectPropertyChange(QVariant, QVariant)));
|
||||||
QObject::connect(m_editView3DData.rootItem, SIGNAL(notifyActiveSceneChange()),
|
QObject::connect(m_editView3DData.rootItem, SIGNAL(notifyActiveSceneChange()),
|
||||||
this, SLOT(handleActiveSceneChange()));
|
this, SLOT(handleActiveSceneChange()));
|
||||||
QObject::connect(m_editView3DData.rootItem, SIGNAL(notifyActiveSplitChange(int)),
|
QObject::connect(m_editView3DData.rootItem, SIGNAL(notifyActiveViewportChange(int)),
|
||||||
this, SLOT(handleActiveSplitChange(int)));
|
this, SLOT(handleActiveViewportChange(int)));
|
||||||
QObject::connect(&m_propertyChangeTimer, &QTimer::timeout,
|
QObject::connect(&m_propertyChangeTimer, &QTimer::timeout,
|
||||||
this, &Qt5InformationNodeInstanceServer::handleObjectPropertyChangeTimeout);
|
this, &Qt5InformationNodeInstanceServer::handleObjectPropertyChangeTimeout);
|
||||||
QObject::connect(&m_selectionChangeTimer, &QTimer::timeout,
|
QObject::connect(&m_selectionChangeTimer, &QTimer::timeout,
|
||||||
@@ -2599,6 +2599,9 @@ void Qt5InformationNodeInstanceServer::view3DAction([[maybe_unused]] const View3
|
|||||||
case View3DActionType::SyncEnvBackground:
|
case View3DActionType::SyncEnvBackground:
|
||||||
updatedToolState.insert("syncEnvBackground", command.isEnabled());
|
updatedToolState.insert("syncEnvBackground", command.isEnabled());
|
||||||
break;
|
break;
|
||||||
|
case View3DActionType::ViewportPreset:
|
||||||
|
updatedToolState.insert("activePreset", command.value());
|
||||||
|
break;
|
||||||
#ifdef QUICK3D_PARTICLES_MODULE
|
#ifdef QUICK3D_PARTICLES_MODULE
|
||||||
case View3DActionType::ShowParticleEmitter:
|
case View3DActionType::ShowParticleEmitter:
|
||||||
updatedToolState.insert("showParticleEmitter", command.isEnabled());
|
updatedToolState.insert("showParticleEmitter", command.isEnabled());
|
||||||
@@ -2637,8 +2640,8 @@ void Qt5InformationNodeInstanceServer::view3DAction([[maybe_unused]] const View3
|
|||||||
getNodeAtMainScenePos(data[0].toPointF(), qint32(data[1].toInt()));
|
getNodeAtMainScenePos(data[0].toPointF(), qint32(data[1].toInt()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case View3DActionType::SplitViewToggle:
|
case View3DActionType::ViewportViewToggle:
|
||||||
updatedToolState.insert("splitView", command.isEnabled());
|
updatedToolState.insert("viewportView", command.isEnabled());
|
||||||
break;
|
break;
|
||||||
case View3DActionType::FlyModeToggle:
|
case View3DActionType::FlyModeToggle:
|
||||||
updatedToolState.insert("flyMode", command.isEnabled());
|
updatedToolState.insert("flyMode", command.isEnabled());
|
||||||
|
@@ -66,7 +66,7 @@ private slots:
|
|||||||
void handleObjectPropertyCommit(const QVariant &objects, const QVariant &propNames);
|
void handleObjectPropertyCommit(const QVariant &objects, const QVariant &propNames);
|
||||||
void handleObjectPropertyChange(const QVariant &objects, const QVariant &propNames);
|
void handleObjectPropertyChange(const QVariant &objects, const QVariant &propNames);
|
||||||
void handleActiveSceneChange();
|
void handleActiveSceneChange();
|
||||||
void handleActiveSplitChange(int index);
|
void handleActiveViewportChange(int index);
|
||||||
void handleToolStateChanged(const QString &sceneId, const QString &tool,
|
void handleToolStateChanged(const QString &sceneId, const QString &tool,
|
||||||
const QVariant &toolState);
|
const QVariant &toolState);
|
||||||
void handleView3DSizeChange();
|
void handleView3DSizeChange();
|
||||||
|
Reference in New Issue
Block a user