You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
292 lines
10 KiB
C++
292 lines
10 KiB
C++
/*
|
|
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
*
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#if !defined(Q_MOC_RUN)
|
|
#include "Include/EditorCoreAPI.h"
|
|
#include <QtViewPane.h>
|
|
#include "Resource.h"
|
|
#include <AzToolsFramework/API/ViewPaneOptions.h>
|
|
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
|
#include <AzQtComponents/Components/DockTabWidget.h>
|
|
#include <AzQtComponents/Components/StyledDockWidget.h>
|
|
#include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h>
|
|
#include <AzToolsFramework/ComponentMode/EditorComponentModeBus.h>
|
|
#include <AzToolsFramework/API/EditorWindowRequestBus.h>
|
|
|
|
#include <QObject>
|
|
#include <QVector>
|
|
#include <QPointer>
|
|
#include <QSettings>
|
|
#include <QAction>
|
|
#include <QByteArray>
|
|
#include <QList>
|
|
|
|
#include <LyViewPaneNames.h>
|
|
|
|
#include <AzCore/std/functional.h>
|
|
#endif
|
|
|
|
class QMainWindow;
|
|
struct ViewLayoutState;
|
|
|
|
namespace AzQtComponents
|
|
{
|
|
class DockMainWindow;
|
|
class StyledDockWidget;
|
|
class FancyDocking;
|
|
|
|
} // namespace AzQtComponents
|
|
|
|
typedef AZStd::function<QWidget*(QWidget*)> ViewPaneFactory;
|
|
|
|
class DockWidget
|
|
: public AzQtComponents::StyledDockWidget
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
explicit DockWidget(QWidget* widget, QtViewPane* pane, QSettings* settings, QMainWindow* parent, AzQtComponents::FancyDocking* advancedDockManager);
|
|
|
|
QString PaneName() const;
|
|
void RestoreState(bool forceDefault = false);
|
|
|
|
/**
|
|
* Gets the setting name for a given pane.
|
|
*/
|
|
static QString settingsKey(const QString& paneName);
|
|
|
|
protected:
|
|
bool event(QEvent* qtEvent) override;
|
|
private:
|
|
void reparentToMainWindowFix();
|
|
QRect ProperGeometry() const;
|
|
QString settingsKey() const;
|
|
QSettings* const m_settings;
|
|
QMainWindow* const m_mainWindow;
|
|
QtViewPane* const m_pane;
|
|
AzQtComponents::FancyDocking* m_advancedDockManager;
|
|
};
|
|
|
|
struct QtViewPane
|
|
{
|
|
enum class OpenMode
|
|
{
|
|
None = 0x0,
|
|
UseDefaultState = 0x1, // Use default geometry and docking position when opening
|
|
MultiplePanes = 0x2,
|
|
RestoreLayout = 0x4,
|
|
OnlyOpen = 0x8,
|
|
};
|
|
Q_DECLARE_FLAGS(OpenModes, OpenMode)
|
|
|
|
enum class CloseMode
|
|
{
|
|
None = 0x0,
|
|
Destroy = 0x1, // Destroy window when closing it
|
|
Force = 0x2 // Force the dialog to close instead of querying the view if we can close
|
|
};
|
|
Q_DECLARE_FLAGS(CloseModes, CloseMode)
|
|
|
|
int m_id; // between ID_VIEW_OPENPANE_FIRST and ID_VIEW_OPENPANE_LAST
|
|
QString m_name;
|
|
QString m_category;
|
|
ViewPaneFactory m_factoryFunc;
|
|
QPointer<DockWidget> m_dockWidget;
|
|
AzToolsFramework::ViewPaneOptions m_options;
|
|
QList<DockWidget*> m_dockWidgetInstances;
|
|
|
|
bool IsValid() const
|
|
{
|
|
return m_id >= ID_VIEW_OPENPANE_FIRST && m_id <= ID_VIEW_OPENPANE_LAST && !m_name.isEmpty();
|
|
}
|
|
|
|
bool IsVisible() const
|
|
{
|
|
return m_dockWidget && m_dockWidget->isVisible();
|
|
}
|
|
|
|
bool IsConstructed() const
|
|
{
|
|
return m_dockWidget != nullptr;
|
|
}
|
|
|
|
QWidget* Widget() const
|
|
{
|
|
return IsConstructed() ? m_dockWidget->widget() : nullptr;
|
|
}
|
|
|
|
bool IsViewportPane() const
|
|
{
|
|
return m_category == QLatin1String("Viewport") && m_options.viewportType != -1;
|
|
}
|
|
|
|
bool IsPreview() const
|
|
{
|
|
return m_options.isPreview;
|
|
}
|
|
|
|
QWidget* CreateWidget();
|
|
bool Close(CloseModes = CloseMode::Destroy);
|
|
bool CloseInstance(QDockWidget* dockWidget, CloseModes closeModes = CloseMode::Destroy);
|
|
};
|
|
|
|
typedef QVector<QtViewPane> QtViewPanes;
|
|
|
|
class EDITOR_CORE_API QtViewPaneManager
|
|
: public QObject
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
explicit QtViewPaneManager(QObject* parent = nullptr);
|
|
~QtViewPaneManager();
|
|
void SetMainWindow(AzQtComponents::DockMainWindow*, QSettings* settings, const QByteArray& lastMainWindowState);
|
|
void RegisterPane(const QString &name, const QString &category, ViewPaneFactory, const AzToolsFramework::ViewPaneOptions& = {});
|
|
void UnregisterPane(const QString& name);
|
|
QtViewPane* GetPane(int id);
|
|
QtViewPane* GetPane(const QString& name);
|
|
QtViewPane* GetViewportPane(int viewportType);
|
|
QDockWidget* GetView(const QString& name);
|
|
bool IsVisible(const QString& name);
|
|
bool IsPaneRegistered(const QString& name) const;
|
|
|
|
/**
|
|
* Constructs and shows a view pane.
|
|
* The pane is a QDockWidget who's widget was created with QtViewPane::m_factoryFunc.
|
|
* If useDefaultState is true, the default docking area and geometry are used, not the last one.
|
|
*
|
|
* Returns the view on success, nullptr otherwise
|
|
*/
|
|
const QtViewPane* OpenPane(const QString& name, QtViewPane::OpenModes = QtViewPane::OpenMode::None);
|
|
QDockWidget* InstancePane(const QString& name);
|
|
bool ClosePane(const QString& name, QtViewPane::CloseModes = QtViewPane::CloseMode::None);
|
|
bool ClosePaneInstance(const QString& name, QDockWidget* dockPanel, QtViewPane::CloseModes = QtViewPane::CloseMode::None);
|
|
|
|
/**
|
|
* If the pane is not visible, it will be opened and made visible.
|
|
* If the pane is visible, it will be closed.
|
|
*/
|
|
void TogglePane(const QString& name);
|
|
bool CloseAllPanes();
|
|
|
|
/**
|
|
* Closes all non standard panes. Standard panes are for example rollup and console.
|
|
*/
|
|
void CloseAllNonStandardPanes();
|
|
|
|
/**
|
|
* Creates and returns a widget by calling QtViewPane::m_factoryFunc() for the view pane with name paneName.
|
|
* This is similar to OpenPane(), except that there's no dock widget involved. The widget will be used in a
|
|
* CLayoutViewPane (the embedded viewports).
|
|
*
|
|
* Returns nullptr if the specified pane name is not registered.
|
|
*/
|
|
QWidget* CreateWidget(const QString& paneName);
|
|
|
|
void RestoreLayout(bool restoreDefaults);
|
|
bool RestoreLayout(QString name);
|
|
void RestoreDefaultLayout(bool resetSettings = false);
|
|
void SaveLayout();
|
|
void SaveLayout(QString name);
|
|
void RenameLayout(QString name, QString newName);
|
|
void RemoveLayout(QString name);
|
|
bool HasLayout(const QString& name) const;
|
|
QStringList LayoutNames(bool userLayoutsOnly = true) const;
|
|
|
|
void SerializeLayout(XmlNodeRef& parentNode) const;
|
|
bool DeserializeLayout(const XmlNodeRef& parentNode);
|
|
|
|
static QtViewPaneManager* instance();
|
|
static bool exists();
|
|
|
|
/**
|
|
* Returns the known view panes (regardless of them being open or not).
|
|
* If viewPaneMenuOnly is true, only those appearing in "View->Open View Pane" will be show,
|
|
* meaning panes such as the rollup bar or console aren't returned.
|
|
*/
|
|
QtViewPanes GetRegisteredPanes(bool viewPaneMenuOnly = true) const;
|
|
QtViewPanes GetRegisteredMultiInstancePanes(bool viewPaneMenuOnly = true) const;
|
|
QtViewPanes GetRegisteredViewportPanes() const; // only returns the Top/Bottom/Left etc. ones
|
|
|
|
//! Attempts to closes everything not in the input list. Returns false if any failed, and restores all previously opened windows if it does. Returns true otherwise
|
|
bool ClosePanesWithRollback(const QVector<QString>& panesToKeepOpen);
|
|
|
|
signals:
|
|
void savedLayoutsChanged();
|
|
void layoutReset();
|
|
void viewPaneCreated(const QtViewPane* pane);
|
|
void registeredPanesChanged();
|
|
|
|
private:
|
|
friend class DockWidget;
|
|
ViewLayoutState GetLayout() const;
|
|
bool RestoreLayout(const ViewLayoutState& state);
|
|
void SaveStateToLayout(const ViewLayoutState& state, const QString& layoutName);
|
|
|
|
#if AZ_TRAIT_OS_PLATFORM_APPLE
|
|
QDockWidget* ShowFakeNonDockableDockWidget(AzQtComponents::StyledDockWidget* dockWidget, QtViewPane* pane);
|
|
#endif
|
|
|
|
bool ClosePane(QtViewPane* pane, QtViewPane::CloseModes closeModes = QtViewPane::CloseMode::None);
|
|
int NextAvailableId();
|
|
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
|
QtViewPanes m_registeredPanes;
|
|
QByteArray m_defaultMainWindowState;
|
|
QByteArray m_loadedMainWindowState;
|
|
QMainWindow* m_mainWindow;
|
|
QSettings* m_settings;
|
|
QList<int> m_knownIdsSet; // Semantically a set, but QList is faster for small collections than QSet
|
|
bool m_restoreInProgress;
|
|
QMap<QString, QRect> m_fakeDockWidgetGeometries;
|
|
|
|
QPointer<AzQtComponents::FancyDocking> m_advancedDockManager;
|
|
|
|
using EditorComponentModeNotificationBusImpl = AzToolsFramework::ComponentModeFramework::EditorComponentModeNotificationBusImpl;
|
|
EditorComponentModeNotificationBusImpl m_componentModeNotifications; //!< Helper for EditorComponentModeNotificationBus so
|
|
//!< QtViewPaneManager does not need to inherit directly from it. */
|
|
|
|
using EditorWindowRequestBusImpl = AzToolsFramework::EditorWindowRequestBusImpl;
|
|
EditorWindowRequestBusImpl m_windowRequest; //!< Helper for EditorWindowRequestBus so
|
|
//!< QtViewPaneManager does not need to inherit directly from it. */
|
|
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
|
};
|
|
|
|
template<class TWidget>
|
|
bool RegisterQtViewPane([[maybe_unused]] IEditor* editor, const QString& name, const QString& category, const AzToolsFramework::ViewPaneOptions& options = {})
|
|
{
|
|
QtViewPaneManager::instance()->RegisterPane(name, category, [](QWidget* parent = nullptr) { return new TWidget(parent); }, options);
|
|
return true;
|
|
}
|
|
|
|
template<class TWidget>
|
|
bool RegisterQtViewPaneWithName([[maybe_unused]] IEditor* editor, const QString& name, const QString& category, const AzToolsFramework::ViewPaneOptions& options = {})
|
|
{
|
|
QtViewPaneManager::instance()->RegisterPane(name, category, [name](QWidget* parent = nullptr) { return new TWidget(name, parent); }, options);
|
|
return true;
|
|
}
|
|
|
|
template<class TWidget>
|
|
void UnregisterQtViewPane()
|
|
{
|
|
// always close any views that the pane is responsible for before you remove it!
|
|
GetIEditor()->CloseView(CQtViewClass<TWidget>::GetClassID());
|
|
GetIEditor()->GetClassFactory()->UnregisterClass(CQtViewClass<TWidget>::GetClassID());
|
|
}
|
|
|
|
template<typename TWidget>
|
|
TWidget* FindViewPane(const QString& name)
|
|
{
|
|
QtViewPane* pane = QtViewPaneManager::exists() ? QtViewPaneManager::instance()->GetPane(name) : nullptr;
|
|
return pane ? qobject_cast<TWidget*>(pane->Widget()) : nullptr;
|
|
}
|
|
|
|
Q_DECLARE_OPERATORS_FOR_FLAGS(QtViewPane::OpenModes)
|
|
Q_DECLARE_OPERATORS_FOR_FLAGS(QtViewPane::CloseModes)
|
|
|
|
|