mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-10 05:32:18 -06:00
Merging master in to sync with new release
This commit is contained in:
@@ -9,7 +9,3 @@ charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
insert_final_newline = true
|
||||
|
||||
# overwrite default settings here, for instance like this:
|
||||
# [*.cpp]
|
||||
# indent_style = tabs
|
||||
|
||||
@@ -29,7 +29,7 @@ project(OpenSpace)
|
||||
set(OPENSPACE_VERSION_MAJOR 0)
|
||||
set(OPENSPACE_VERSION_MINOR 18)
|
||||
set(OPENSPACE_VERSION_PATCH 0)
|
||||
set(OPENSPACE_VERSION_STRING "Beta-11 (RC1)")
|
||||
set(OPENSPACE_VERSION_STRING "Beta-11")
|
||||
|
||||
set(OPENSPACE_BASE_DIR "${PROJECT_SOURCE_DIR}")
|
||||
set(OPENSPACE_CMAKE_EXT_DIR "${OPENSPACE_BASE_DIR}/support/cmake")
|
||||
|
||||
@@ -45,10 +45,9 @@ set(HEADER_FILES
|
||||
include/profile/profileedit.h
|
||||
include/profile/propertiesdialog.h
|
||||
include/sgctedit/displaywindowunion.h
|
||||
include/sgctedit/filesupport.h
|
||||
include/sgctedit/monitorbox.h
|
||||
include/sgctedit/orientation.h
|
||||
include/sgctedit/orientationdialog.h
|
||||
include/sgctedit/settingswidget.h
|
||||
include/sgctedit/sgctedit.h
|
||||
include/sgctedit/windowcontrol.h
|
||||
)
|
||||
@@ -75,39 +74,12 @@ set(SOURCE_FILES
|
||||
src/profile/propertiesdialog.cpp
|
||||
src/sgctedit/sgctedit.cpp
|
||||
src/sgctedit/displaywindowunion.cpp
|
||||
src/sgctedit/filesupport.cpp
|
||||
src/sgctedit/monitorbox.cpp
|
||||
src/sgctedit/orientation.cpp
|
||||
src/sgctedit/orientationdialog.cpp
|
||||
src/sgctedit/settingswidget.cpp
|
||||
src/sgctedit/windowcontrol.cpp
|
||||
)
|
||||
|
||||
set(HEADER_SOURCE
|
||||
include/launcherwindow.h
|
||||
include/profile/actiondialog.h
|
||||
include/profile/additionalscriptsdialog.h
|
||||
include/profile/assetsdialog.h
|
||||
include/profile/assetedit.h
|
||||
include/profile/assettreemodel.h
|
||||
include/profile/cameradialog.h
|
||||
include/profile/deltatimesdialog.h
|
||||
include/profile/horizonsdialog.h
|
||||
include/profile/scriptlogdialog.h
|
||||
include/profile/marknodesdialog.h
|
||||
include/profile/metadialog.h
|
||||
include/profile/modulesdialog.h
|
||||
include/profile/timedialog.h
|
||||
include/profile/profileedit.h
|
||||
include/profile/propertiesdialog.h
|
||||
include/sgctedit/displaywindowunion.h
|
||||
include/sgctedit/filesupport.h
|
||||
include/sgctedit/monitorbox.h
|
||||
include/sgctedit/orientation.h
|
||||
include/sgctedit/orientationdialog.h
|
||||
include/sgctedit/sgctedit.h
|
||||
include/sgctedit/windowcontrol.h
|
||||
)
|
||||
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Widgets Network REQUIRED)
|
||||
set(MOC_FILES "")
|
||||
set(RESOURCE_FILES "")
|
||||
@@ -117,7 +89,7 @@ if (${QT_VERSION_MAJOR} EQUAL 5)
|
||||
find_package(Qt5 COMPONENTS Core Widgets Network)
|
||||
qt5_wrap_cpp(
|
||||
MOC_FILES
|
||||
${HEADER_SOURCE}
|
||||
${HEADER_FILES}
|
||||
)
|
||||
qt5_add_resources(RESOURCE_FILES resources/resources.qrc)
|
||||
set(LIBRARIES )
|
||||
@@ -126,7 +98,7 @@ elseif (${QT_VERSION_MAJOR} EQUAL 6)
|
||||
|
||||
qt6_wrap_cpp(
|
||||
MOC_FILES
|
||||
${HEADER_SOURCE}
|
||||
${HEADER_FILES}
|
||||
)
|
||||
qt6_add_resources(RESOURCE_FILES resources/resources.qrc)
|
||||
elseif (NOT DEFINED QT_VERSION_MAJOR)
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace openspace::configuration { struct Configuration; }
|
||||
class QComboBox;
|
||||
class QLabel;
|
||||
|
||||
class LauncherWindow : public QMainWindow {
|
||||
class LauncherWindow final : public QMainWindow {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
|
||||
@@ -41,8 +41,7 @@ class QTextEdit;
|
||||
class ActionDialog final : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ActionDialog(QWidget* parent,
|
||||
std::vector<openspace::Profile::Action>* actions,
|
||||
ActionDialog(QWidget* parent, std::vector<openspace::Profile::Action>* actions,
|
||||
std::vector<openspace::Profile::Keybinding>* keybindings);
|
||||
|
||||
private:
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_UI_LAUNCHER___ADDITIONALSCRIPTS___H__
|
||||
#define __OPENSPACE_UI_LAUNCHER___ADDITIONALSCRIPTS___H__
|
||||
#ifndef __OPENSPACE_UI_LAUNCHER___ADDITIONALSCRIPTSDIALOG___H__
|
||||
#define __OPENSPACE_UI_LAUNCHER___ADDITIONALSCRIPTSDIALOG___H__
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
@@ -41,7 +41,9 @@ public:
|
||||
*/
|
||||
AdditionalScriptsDialog(QWidget* parent, std::vector<std::string>* scripts);
|
||||
|
||||
private slots:
|
||||
private:
|
||||
void createWidgets();
|
||||
|
||||
void parseScript();
|
||||
void chooseScripts();
|
||||
|
||||
@@ -52,13 +54,10 @@ private slots:
|
||||
*/
|
||||
void appendScriptsToTextfield(std::string scripts);
|
||||
|
||||
private:
|
||||
void createWidgets();
|
||||
|
||||
std::vector<std::string>* _scripts = nullptr;
|
||||
std::vector<std::string> _scriptsData;
|
||||
QTextEdit* _textScripts = nullptr;
|
||||
QPushButton* _chooseScriptsButton = nullptr;
|
||||
};
|
||||
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___ADDITIONALSCRIPTS___H__
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___ADDITIONALSCRIPTSDIALOG___H__
|
||||
|
||||
@@ -26,8 +26,6 @@
|
||||
#define __OPENSPACE_UI_LAUNCHER___ASSETEDIT___H__
|
||||
|
||||
#include <QDialog>
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
|
||||
namespace openspace { class Asset; }
|
||||
|
||||
@@ -37,39 +35,21 @@ class QLabel;
|
||||
class QLineEdit;
|
||||
class QWidget;
|
||||
|
||||
class AssetEdit : public QDialog {
|
||||
class AssetEdit final : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Constructor for AssetEdit class
|
||||
*/
|
||||
AssetEdit(QWidget* parent);
|
||||
|
||||
private slots:
|
||||
//void openComponent();
|
||||
|
||||
//void openHorizonsFile();
|
||||
void openHorizons();
|
||||
|
||||
void approved();
|
||||
|
||||
private:
|
||||
void createWidgets();
|
||||
|
||||
void openHorizons();
|
||||
void approved();
|
||||
|
||||
QBoxLayout* _layout = nullptr;
|
||||
QLineEdit* _nameEdit = nullptr;
|
||||
//QComboBox* _components = nullptr;
|
||||
|
||||
//std::filesystem::path _horizonsFile;
|
||||
//QLineEdit* _horizonsFileEdit = nullptr;
|
||||
|
||||
QLabel* _errorMsg = nullptr;
|
||||
|
||||
// List of all the supported components
|
||||
/*QStringList _supportedComponents = {
|
||||
"Choose Component",
|
||||
"Horizons Translation"
|
||||
};*/
|
||||
};
|
||||
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___ASSETEDIT___H__
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_UI_LAUNCHER___ASSETS___H__
|
||||
#define __OPENSPACE_UI_LAUNCHER___ASSETS___H__
|
||||
#ifndef __OPENSPACE_UI_LAUNCHER___ASSETSDIALOG___H__
|
||||
#define __OPENSPACE_UI_LAUNCHER___ASSETSDIALOG___H__
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
@@ -48,17 +48,13 @@ public:
|
||||
AssetsDialog(QWidget* parent, openspace::Profile* profile,
|
||||
const std::string& assetBasePath, const std::string& userAssetBasePath);
|
||||
|
||||
private slots:
|
||||
private:
|
||||
void createWidgets();
|
||||
|
||||
void parseSelections();
|
||||
void selected(const QModelIndex&);
|
||||
|
||||
private:
|
||||
void createWidgets();
|
||||
/**
|
||||
* Creates a text summary of all assets and their paths
|
||||
*
|
||||
* \return the #std::string summary
|
||||
*/
|
||||
/// Creates a text summary of all assets and their paths
|
||||
QString createTextSummary();
|
||||
void openAssetEditor();
|
||||
|
||||
@@ -68,4 +64,4 @@ private:
|
||||
QTextEdit* _summary = nullptr;
|
||||
};
|
||||
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___ASSETS___H__
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___ASSETSDIALOG___H__
|
||||
|
||||
@@ -30,20 +30,19 @@
|
||||
|
||||
class AssetTreeItem {
|
||||
public:
|
||||
static constexpr const int CheckboxColumn = 1;
|
||||
static constexpr int CheckboxColumn = 1;
|
||||
|
||||
/**
|
||||
* Constructor for assetTreeItem class
|
||||
* Constructor for assetTreeItem class.
|
||||
*
|
||||
* \param data QVector containing the data contained in this tree view item
|
||||
* \param parentItem The parent that contains this (and possibly other) children
|
||||
* in the tree structure (optional).
|
||||
*/
|
||||
explicit AssetTreeItem(const std::vector<QVariant>& data,
|
||||
AssetTreeItem* parentItem = nullptr);
|
||||
AssetTreeItem(std::vector<QVariant> data, AssetTreeItem* parentItem = nullptr);
|
||||
|
||||
/**
|
||||
* Destructor for assetTreeItem class
|
||||
* Destructor for assetTreeItem class.
|
||||
*/
|
||||
~AssetTreeItem();
|
||||
|
||||
@@ -51,28 +50,25 @@ public:
|
||||
* Returns pointer to this tree item's child at position \p row.
|
||||
*
|
||||
* \param row int of the row number of the child to get pointer
|
||||
* \param parentItem The parent that contains this (and possibly other) children
|
||||
* in the tree structure (optional).
|
||||
* \return pointer to the child #assetTreeItem
|
||||
*/
|
||||
AssetTreeItem* child(int row);
|
||||
AssetTreeItem* child(int row) const;
|
||||
|
||||
/**
|
||||
* Returns the number of children this item has
|
||||
* Returns the number of children this item has.
|
||||
*
|
||||
* \return The number of children
|
||||
*/
|
||||
int childCount() const;
|
||||
|
||||
/**
|
||||
* Returns the number of data columns of this item
|
||||
* Returns the number of data columns of this item.
|
||||
*
|
||||
* \return The number of data columns
|
||||
*/
|
||||
int columnCount() const;
|
||||
|
||||
/**
|
||||
* Returns the data at column \p column of this item
|
||||
* Returns the data at column \p column of this item.
|
||||
*
|
||||
* \param column Column number from which to retrieve data
|
||||
* \return The data contained in the column
|
||||
@@ -80,7 +76,7 @@ public:
|
||||
QVariant data(int column) const;
|
||||
|
||||
/**
|
||||
* Inserts children item(s) to the current item
|
||||
* Inserts children item(s) to the current item.
|
||||
*
|
||||
* \param position where in this item's children to insert new children
|
||||
* \param count number of children to insert
|
||||
@@ -91,7 +87,7 @@ public:
|
||||
bool insertChildren(int position, int count, int columns);
|
||||
|
||||
/**
|
||||
* Inserts data column(s) in the current item
|
||||
* Inserts data column(s) in the current item.
|
||||
*
|
||||
* \param position column number at which to insert column(s)
|
||||
* \param columns number of columns to insert
|
||||
@@ -100,21 +96,21 @@ public:
|
||||
bool insertColumns(int position, int columns);
|
||||
|
||||
/**
|
||||
* Returns a pointer to the current item's parent
|
||||
* Returns a pointer to the current item's parent.
|
||||
*
|
||||
* \return pointer to the \p assetTreeItem parent
|
||||
*/
|
||||
AssetTreeItem* parent();
|
||||
|
||||
/**
|
||||
* Returns the row number / child number of this item's parent
|
||||
* Returns the row number / child number of this item's parent.
|
||||
*
|
||||
* \return The row number of this item's parent
|
||||
*/
|
||||
int row() const;
|
||||
|
||||
/**
|
||||
* Returns the data at column \p column of this item
|
||||
* Returns the data at column \p column of this item.
|
||||
*
|
||||
* \param position The position of the child(ren) to remove from the current
|
||||
* item (which is parent)
|
||||
@@ -124,13 +120,13 @@ public:
|
||||
bool removeChildren(int position, int count);
|
||||
|
||||
/**
|
||||
* Set data at column \p column
|
||||
* Set data at column \p column.
|
||||
*
|
||||
* \param column The data column number to set
|
||||
* \param value The #QVariant data element to store at column \p column
|
||||
* \return true if the data set was successful
|
||||
*/
|
||||
bool setData(int column, const QVariant &value);
|
||||
bool setData(int column, const QVariant& value);
|
||||
|
||||
/**
|
||||
* Returns the checked state of this item. If an asset is selected to be included
|
||||
@@ -141,7 +137,7 @@ public:
|
||||
bool isChecked() const;
|
||||
|
||||
/**
|
||||
* Sets the checked state of this item (whether or not it is selected for a profile)
|
||||
* Sets the checked state of this item (whether or not it is selected for a profile).
|
||||
*
|
||||
* \param set bool for whether or not this is checked
|
||||
*/
|
||||
@@ -164,23 +160,23 @@ public:
|
||||
bool isCategory() const;
|
||||
|
||||
/**
|
||||
* Sets status of whether or not the asset exists in the current filesystem.
|
||||
* It is possible that an imported profile lists an asset from another system
|
||||
* that is not included on the current filesystem.
|
||||
* Sets status of whether or not the asset exists in the current filesystem. It is
|
||||
* possible that an imported profile lists an asset from another system that is not
|
||||
* included on the current filesystem.
|
||||
*
|
||||
* \param set to true if the asset file exists in the current filesystem
|
||||
*/
|
||||
void setExistsInFilesystem(bool fileExists);
|
||||
|
||||
/**
|
||||
* Returns bool for whether or not the asset exists in the current filesystem
|
||||
* Returns bool for whether or not the asset exists in the current filesystem.
|
||||
*
|
||||
* \return true if the asset exists in the current filesystem
|
||||
*/
|
||||
bool doesExistInFilesystem() const;
|
||||
|
||||
/**
|
||||
* Returns the asset name of the current item
|
||||
* Returns the asset name of the current item.
|
||||
*
|
||||
* \return The asset name
|
||||
*/
|
||||
|
||||
@@ -33,12 +33,11 @@
|
||||
|
||||
class AssetTreeModel final : public QAbstractItemModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AssetTreeModel(QObject* parent = nullptr);
|
||||
|
||||
/**
|
||||
* Returns the data contained at an index
|
||||
* Returns the data contained at an index.
|
||||
*
|
||||
* \param index that defines where the item is located in the tree model
|
||||
* \param role Qt-defined role that describes the reason Qt is calling the
|
||||
@@ -48,7 +47,7 @@ public:
|
||||
QVariant data(const QModelIndex& index, int role) const final;
|
||||
|
||||
/**
|
||||
* Returns the header data of the tree view
|
||||
* Returns the header data of the tree view.
|
||||
*
|
||||
* \param section of data to be obtained from header
|
||||
* \param orientation of the query (e.g. Qt::horizontal)
|
||||
@@ -60,7 +59,7 @@ public:
|
||||
int role = Qt::DisplayRole) const final;
|
||||
|
||||
/**
|
||||
* Returns the index of item in #QModelIndex object form
|
||||
* Returns the index of item in #QModelIndex object form.
|
||||
*
|
||||
* \param row the row number
|
||||
* \param column the column number
|
||||
@@ -71,7 +70,7 @@ public:
|
||||
const QModelIndex& parent = QModelIndex()) const final;
|
||||
|
||||
/**
|
||||
* Returns the index of the parent of the item specified by input param
|
||||
* Returns the index of the parent of the item specified by input param.
|
||||
*
|
||||
* \param index of item that is a child of the parent
|
||||
* \return #QModelIndex index of the parent
|
||||
@@ -79,7 +78,7 @@ public:
|
||||
QModelIndex parent(const QModelIndex& index) const final;
|
||||
|
||||
/**
|
||||
* Returns the index of the parent of the item specified by the input params
|
||||
* Returns the index of the parent of the item specified by the input params.
|
||||
*
|
||||
* \param row the row number
|
||||
* \param column the column number
|
||||
@@ -90,7 +89,7 @@ public:
|
||||
const QModelIndex& parent = QModelIndex()) const;
|
||||
|
||||
/**
|
||||
* Returns asset item at specified index
|
||||
* Returns asset item at specified index.
|
||||
*
|
||||
* \param index of item that is a child of the parent
|
||||
* \return #assetTreeItem pointer to the item at the provided index
|
||||
@@ -98,7 +97,7 @@ public:
|
||||
AssetTreeItem* assetItem(const QModelIndex& index);
|
||||
|
||||
/**
|
||||
* Returns number of children/rows of the parent
|
||||
* Returns number of children/rows of the parent.
|
||||
*
|
||||
* \param parent #QModelIndex of the parent item
|
||||
* \return number of children/rows of this parent
|
||||
@@ -106,7 +105,7 @@ public:
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const final;
|
||||
|
||||
/**
|
||||
* Returns the number of columns of data in each item of the tree
|
||||
* Returns the number of columns of data in each item of the tree.
|
||||
*
|
||||
* \param parent specified by the #QModelIndex index
|
||||
* \return the number of data columns
|
||||
@@ -115,7 +114,7 @@ public:
|
||||
|
||||
/**
|
||||
* Return the Qt flags of the item specified by index, which can include
|
||||
* Qt::ItemIsEnabled, Qt::ItemIsSelectable
|
||||
* Qt::ItemIsEnabled, Qt::ItemIsSelectable.
|
||||
*
|
||||
* \param index specified by the #QModelIndex index
|
||||
* \return the Qt flags
|
||||
@@ -123,7 +122,7 @@ public:
|
||||
Qt::ItemFlags flags(const QModelIndex& index) const final;
|
||||
|
||||
/**
|
||||
* Set data at index \p index
|
||||
* Set data at index \p index.
|
||||
*
|
||||
* \param index location of the item to set
|
||||
* \param value The #QVariant data element to store at column \p column
|
||||
@@ -134,12 +133,11 @@ public:
|
||||
int role = Qt::EditRole) final;
|
||||
|
||||
/**
|
||||
* Returns a vector of all #Assets selected in the tree view
|
||||
* Returns a vector of all #Assets selected in the tree view.
|
||||
*
|
||||
* \param outputPaths vector of #openspace::Profile::Asset objects,
|
||||
* each of which are selected
|
||||
* \param outputItems vector of #assetTreeItem * objects,
|
||||
* each of which are selected
|
||||
* \param outputPaths vector of #openspace::Profile::Asset objects, each of which are
|
||||
* selected
|
||||
* \param outputItems vector of #assetTreeItem * objects, each of which are selected
|
||||
*/
|
||||
void getSelectedAssets(std::vector<std::string>& outputPaths,
|
||||
std::vector<AssetTreeItem*>& outputItems);
|
||||
@@ -154,7 +152,7 @@ public:
|
||||
const std::string& userAssetBasePath);
|
||||
|
||||
/**
|
||||
* Returns bool for if item is checked/selected
|
||||
* Returns bool for if item is checked/selected.
|
||||
*
|
||||
* \param index location of the item to set
|
||||
* \return true if the item is checked
|
||||
@@ -162,7 +160,7 @@ public:
|
||||
bool isChecked(QModelIndex& index) const;
|
||||
|
||||
/**
|
||||
* Answers query about whether or not item is an asset
|
||||
* Answers query about whether or not item is an asset.
|
||||
*
|
||||
* \param index location of the item to query
|
||||
* \return true if the item is an asset (and not a directory)
|
||||
@@ -170,7 +168,7 @@ public:
|
||||
bool isAsset(QModelIndex& index) const;
|
||||
|
||||
/**
|
||||
* Answers query about whether or not item is in the current filesystem
|
||||
* Answers query about whether or not item is in the current filesystem.
|
||||
*
|
||||
* \param index location of the item to query
|
||||
* \return true if the data is in the filesystem
|
||||
@@ -178,7 +176,7 @@ public:
|
||||
bool inFilesystem(QModelIndex& index) const;
|
||||
|
||||
/**
|
||||
* Returns number of child items of referenced item
|
||||
* Returns number of child items of referenced item.
|
||||
*
|
||||
* \param index location of the item to query
|
||||
* \return number of child items
|
||||
@@ -186,7 +184,7 @@ public:
|
||||
int childCount(QModelIndex& index) const;
|
||||
|
||||
/**
|
||||
* Returns a pointer to a child item of the current item
|
||||
* Returns a pointer to a child item of the current item.
|
||||
*
|
||||
* \param row the child number of the current item
|
||||
* \return assetTreeItem pointer to the child
|
||||
@@ -194,7 +192,7 @@ public:
|
||||
AssetTreeItem* child(int row) const;
|
||||
|
||||
/**
|
||||
* Returns the asset name of the specified item
|
||||
* Returns the asset name of the specified item.
|
||||
*
|
||||
* \param index location of the item to query
|
||||
* \return the asset name of the item
|
||||
@@ -202,7 +200,7 @@ public:
|
||||
QString name(QModelIndex& index) const;
|
||||
|
||||
/**
|
||||
* Set asset name at specified index
|
||||
* Set asset name at specified index.
|
||||
*
|
||||
* \param index location of the item to set
|
||||
* \param name the asset name to set
|
||||
@@ -210,7 +208,7 @@ public:
|
||||
void setName(QModelIndex& index, QString name);
|
||||
|
||||
/**
|
||||
* Set state of checked/selected of an item
|
||||
* Set state of checked/selected of an item.
|
||||
*
|
||||
* \param index location of the item to set
|
||||
* \param checked true if item is checked/selected
|
||||
@@ -218,7 +216,7 @@ public:
|
||||
void setChecked(QModelIndex& index, bool checked);
|
||||
|
||||
/**
|
||||
* Set state of whether or not asset exists in filesystem
|
||||
* Set state of whether or not asset exists in filesystem.
|
||||
*
|
||||
* \param index location of the item to set
|
||||
* \param fileExists true if asset exists in filesystem
|
||||
@@ -226,7 +224,7 @@ public:
|
||||
void setExistenceInFilesystem(QModelIndex& index, bool fileExists);
|
||||
|
||||
private:
|
||||
AssetTreeItem* getItem(const QModelIndex& index) const;
|
||||
AssetTreeItem* item(const QModelIndex& index) const;
|
||||
|
||||
std::unique_ptr<AssetTreeItem> _rootItem;
|
||||
};
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_UI_LAUNCHER___DELTATIMES___H__
|
||||
#define __OPENSPACE_UI_LAUNCHER___DELTATIMES___H__
|
||||
#ifndef __OPENSPACE_UI_LAUNCHER___DELTATIMESDIALOG___H__
|
||||
#define __OPENSPACE_UI_LAUNCHER___DELTATIMESDIALOG___H__
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
@@ -61,8 +61,9 @@ public:
|
||||
*/
|
||||
virtual void keyPressEvent(QKeyEvent* evt) override;
|
||||
|
||||
|
||||
private slots:
|
||||
private:
|
||||
void createWidgets();
|
||||
|
||||
void listItemSelected();
|
||||
void valueChanged(const QString& text);
|
||||
void saveDeltaTimeValue();
|
||||
@@ -71,9 +72,6 @@ private slots:
|
||||
void removeDeltaTimeValue();
|
||||
void parseSelections();
|
||||
|
||||
private:
|
||||
void createWidgets();
|
||||
|
||||
/**
|
||||
* Called to transition to editing a particular dt value (gui settings)
|
||||
*
|
||||
@@ -103,4 +101,4 @@ private:
|
||||
QLabel* _errorMsg = nullptr;
|
||||
};
|
||||
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___DELTATIMES___H__
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___DELTATIMESDIALOG___H__
|
||||
|
||||
@@ -22,11 +22,12 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_UI_LAUNCHER___HORIZONS___H__
|
||||
#define __OPENSPACE_UI_LAUNCHER___HORIZONS___H__
|
||||
#ifndef __OPENSPACE_UI_LAUNCHER___HORIZONSDIALOG___H__
|
||||
#define __OPENSPACE_UI_LAUNCHER___HORIZONSDIALOG___H__
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include <openspace/json.h>
|
||||
#include <QDialog>
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
|
||||
@@ -43,27 +44,12 @@ class QNetworkReply;
|
||||
class QPlainTextEdit;
|
||||
class QProgressBar;
|
||||
|
||||
class HorizonsDialog : public QDialog {
|
||||
class HorizonsDialog final : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Constructor for HorizonsDialog class
|
||||
*/
|
||||
HorizonsDialog(QWidget* parent);
|
||||
explicit HorizonsDialog(QWidget* parent);
|
||||
|
||||
#ifdef OPENSPACE_MODULE_SPACE_ENABLED
|
||||
std::filesystem::path file() const;
|
||||
#endif // OPENSPACE_MODULE_SPACE_ENABLED
|
||||
|
||||
private slots:
|
||||
void openSaveAs();
|
||||
void typeOnChange(int index);
|
||||
void downloadProgress(qint64 ist, qint64 max);
|
||||
void importTimeRange();
|
||||
|
||||
#ifdef OPENSPACE_MODULE_SPACE_ENABLED
|
||||
void approved();
|
||||
#endif // OPENSPACE_MODULE_SPACE_ENABLED
|
||||
|
||||
private:
|
||||
enum class LogLevel {
|
||||
@@ -82,8 +68,14 @@ private:
|
||||
};
|
||||
|
||||
void createWidgets();
|
||||
void cleanAllWidgets();
|
||||
void styleLabel(QLabel* label, bool isDirty);
|
||||
|
||||
void openSaveAs();
|
||||
void typeOnChange(int index);
|
||||
void downloadProgress(int value, int max);
|
||||
void importTimeRange();
|
||||
|
||||
void approved();
|
||||
|
||||
bool isValidInput();
|
||||
nlohmann::json sendRequest(const std::string& url);
|
||||
nlohmann::json handleReply(QNetworkReply* reply);
|
||||
@@ -133,4 +125,4 @@ private:
|
||||
std::string _latestHorizonsError;
|
||||
};
|
||||
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___HORIZONS___H__
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___HORIZONSDIALOG___H__
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#include <QFrame>
|
||||
|
||||
class Line : public QFrame {
|
||||
class Line final : public QFrame {
|
||||
public:
|
||||
Line();
|
||||
};
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_UI_LAUNCHER___MARKNODES___H__
|
||||
#define __OPENSPACE_UI_LAUNCHER___MARKNODES___H__
|
||||
#ifndef __OPENSPACE_UI_LAUNCHER___MARKNODESDIALOG___H__
|
||||
#define __OPENSPACE_UI_LAUNCHER___MARKNODESDIALOG___H__
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
@@ -51,15 +51,13 @@ public:
|
||||
*/
|
||||
void keyPressEvent(QKeyEvent* evt) override;
|
||||
|
||||
private slots:
|
||||
void listItemSelected();
|
||||
private:
|
||||
void createWidgets();
|
||||
|
||||
void listItemAdded();
|
||||
void listItemRemove();
|
||||
void parseSelections();
|
||||
|
||||
private:
|
||||
void createWidgets();
|
||||
|
||||
std::vector<QListWidgetItem*> _markedNodesListItems;
|
||||
std::vector<std::string>* _markedNodes;
|
||||
std::vector<std::string> _markedNodesData;
|
||||
@@ -67,7 +65,6 @@ private:
|
||||
QListWidget* _list = nullptr;
|
||||
QPushButton* _removeButton = nullptr;
|
||||
QLineEdit* _newNode = nullptr;
|
||||
|
||||
};
|
||||
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___MARKNODES___H__
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___MARKNODESDIALOG___H__
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_UI_LAUNCHER___META___H__
|
||||
#define __OPENSPACE_UI_LAUNCHER___META___H__
|
||||
#ifndef __OPENSPACE_UI_LAUNCHER___METADIALOG___H__
|
||||
#define __OPENSPACE_UI_LAUNCHER___METADIALOG___H__
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
@@ -37,7 +37,7 @@ class MetaDialog final : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Constructor for meta class
|
||||
* Constructor for meta class.
|
||||
*
|
||||
* \param profile The #openspace::Profile object containing all data of the
|
||||
* new or imported profile.
|
||||
@@ -45,12 +45,11 @@ public:
|
||||
*/
|
||||
MetaDialog(QWidget* parent, std::optional<openspace::Profile::Meta>* meta);
|
||||
|
||||
private slots:
|
||||
void save();
|
||||
|
||||
private:
|
||||
void createWidgets();
|
||||
|
||||
void save();
|
||||
|
||||
std::optional<openspace::Profile::Meta>* _meta = nullptr;
|
||||
|
||||
QLineEdit* _nameEdit = nullptr;
|
||||
@@ -61,4 +60,4 @@ private:
|
||||
QLineEdit* _licenseEdit = nullptr;
|
||||
};
|
||||
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___META___H__
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___METADIALOG___H__
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_UI_LAUNCHER___MODULES___H__
|
||||
#define __OPENSPACE_UI_LAUNCHER___MODULES___H__
|
||||
#ifndef __OPENSPACE_UI_LAUNCHER___MODULESDIALOG___H__
|
||||
#define __OPENSPACE_UI_LAUNCHER___MODULESDIALOG___H__
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
@@ -54,7 +54,9 @@ public:
|
||||
*/
|
||||
virtual void keyPressEvent(QKeyEvent* evt) override;
|
||||
|
||||
private slots:
|
||||
private:
|
||||
void createWidgets();
|
||||
|
||||
void listItemSelected();
|
||||
void listItemAdded();
|
||||
void listItemRemove();
|
||||
@@ -63,9 +65,6 @@ private slots:
|
||||
void transitionToEditMode();
|
||||
void parseSelections();
|
||||
|
||||
private:
|
||||
void createWidgets();
|
||||
|
||||
QString createOneLineSummary(openspace::Profile::Module m);
|
||||
void transitionFromEditMode();
|
||||
void editBoxDisabled(bool disabled);
|
||||
@@ -92,4 +91,4 @@ private:
|
||||
QLabel* _errorMsg = nullptr;
|
||||
};
|
||||
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___MODULES___H__
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___MODULESDIALOG___H__
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_UI_LAUNCHER___PROPERTIES___H__
|
||||
#define __OPENSPACE_UI_LAUNCHER___PROPERTIES___H__
|
||||
#ifndef __OPENSPACE_UI_LAUNCHER___PROPERTIESDIALOG___H__
|
||||
#define __OPENSPACE_UI_LAUNCHER___PROPERTIESDIALOG___H__
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
@@ -56,7 +56,9 @@ public:
|
||||
*/
|
||||
virtual void keyPressEvent(QKeyEvent* evt) override;
|
||||
|
||||
private slots:
|
||||
private:
|
||||
void createWidgets();
|
||||
|
||||
void listItemSelected();
|
||||
void listItemAdded();
|
||||
void listItemRemove();
|
||||
@@ -67,9 +69,6 @@ private slots:
|
||||
|
||||
void selectLineFromScriptLog();
|
||||
|
||||
private:
|
||||
void createWidgets();
|
||||
|
||||
QString createOneLineSummary(openspace::Profile::Property p);
|
||||
void transitionFromEditMode();
|
||||
void editBoxDisabled(bool disabled);
|
||||
@@ -98,4 +97,4 @@ private:
|
||||
QLabel* _errorMsg = nullptr;
|
||||
};
|
||||
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___PROPERTIES___H__
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___PROPERTIESDIALOG___H__
|
||||
|
||||
@@ -22,32 +22,35 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_UI_LAUNCHER___SCRIPTLOG___H__
|
||||
#define __OPENSPACE_UI_LAUNCHER___SCRIPTLOG___H__
|
||||
#ifndef __OPENSPACE_UI_LAUNCHER___SCRIPTLOGDIALOG___H__
|
||||
#define __OPENSPACE_UI_LAUNCHER___SCRIPTLOGDIALOG___H__
|
||||
|
||||
#include <QDialog>
|
||||
#include <QListWidget>
|
||||
|
||||
class QLineEdit;
|
||||
class QListWidget;
|
||||
class QPushButton;
|
||||
|
||||
class ScriptlogDialog final : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Constructor for ScriptlogDialog class
|
||||
*
|
||||
* \param parent Pointer to parent Qt widget
|
||||
*/
|
||||
ScriptlogDialog(QWidget* parent);
|
||||
|
||||
signals:
|
||||
void scriptsSelected(std::string script);
|
||||
|
||||
private slots:
|
||||
void saveChosenScripts();
|
||||
|
||||
private:
|
||||
void createWidgets();
|
||||
|
||||
void loadScriptFile();
|
||||
void saveChosenScripts();
|
||||
|
||||
void updateScriptList();
|
||||
|
||||
QListWidget* _scriptlogList = nullptr;
|
||||
QLineEdit* _filter = nullptr;
|
||||
QPushButton* _reloadFile = nullptr;
|
||||
std::vector<std::string> _scripts;
|
||||
};
|
||||
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___SCRIPTLOG___H__
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___SCRIPTLOGDIALOG___H__
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_UI_LAUNCHER___OSTIME___H__
|
||||
#define __OPENSPACE_UI_LAUNCHER___OSTIME___H__
|
||||
#ifndef __OPENSPACE_UI_LAUNCHER___TIMEDIALOG___H__
|
||||
#define __OPENSPACE_UI_LAUNCHER___TIMEDIALOG___H__
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
@@ -65,4 +65,4 @@ private:
|
||||
QLineEdit* _relativeEdit = nullptr;
|
||||
};
|
||||
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___OSTIME___H__
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___TIMEDIALOG___H__
|
||||
|
||||
@@ -21,36 +21,26 @@
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_UI_LAUNCHER___DISPLAYWINDOWUNION___H__
|
||||
#define __OPENSPACE_UI_LAUNCHER___DISPLAYWINDOWUNION___H__
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "windowcontrol.h"
|
||||
#include "monitorbox.h"
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QIntValidator>
|
||||
#include <QLabel>
|
||||
#include <QLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
#include <QPoint>
|
||||
#include <QPushButton>
|
||||
#include <QTextBrowser>
|
||||
#include <QVector>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
class DisplayWindowUnion : public QWidget {
|
||||
class QFrame;
|
||||
class QPushButton;
|
||||
class QVBoxLayout;
|
||||
class WindowControl;
|
||||
|
||||
class DisplayWindowUnion final : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Constructor for DisplayWindowUnion class, which manages the overall control layout
|
||||
* including monitorBox, multiple WindowControl columns, and additional controls
|
||||
*
|
||||
* \param monitorRenderBox pointer to the MonitorBox object
|
||||
* \param monitorSizeList A vector containing QRect objects containing pixel dims
|
||||
* of each monitor
|
||||
* \param nMaxWindows The maximum number of windows allowed (depends on the number
|
||||
@@ -58,45 +48,59 @@ public:
|
||||
* \param winColors An array of QColor objects for window colors. The indexing of
|
||||
* this array matches the window indexing used elsewhere in the
|
||||
* class. This allows for a unique color for each window.
|
||||
*/
|
||||
DisplayWindowUnion(std::shared_ptr<MonitorBox> monitorRenderBox,
|
||||
std::vector<QRect>& monitorSizeList, unsigned int nMaxWindows,
|
||||
const std::array<QColor, 4>& winColors);
|
||||
* \param parent The parent to which this widget belongs
|
||||
*/
|
||||
DisplayWindowUnion(const std::vector<QRect>& monitorSizeList,
|
||||
int nMaxWindows, const std::array<QColor, 4>& windowColors,
|
||||
QWidget* parent = nullptr);
|
||||
|
||||
/**
|
||||
* Returns a vector of pointers to all WindowControl objects for all windows
|
||||
* Returns a vector of pointers to the WindowControl objects for all visible windows.
|
||||
*
|
||||
* \return vector of pointers of WindowControl objects
|
||||
*/
|
||||
std::vector<std::shared_ptr<WindowControl>> windowControls() const;
|
||||
/**
|
||||
* Returns the current number of windows
|
||||
*
|
||||
* \return the currently-selected number of windows in unsigned int
|
||||
*/
|
||||
unsigned int nWindows() const;
|
||||
*/
|
||||
std::vector<WindowControl*> windowControls() const;
|
||||
|
||||
private slots:
|
||||
/**
|
||||
* When called will add a new window to the set of windows, which will, in turn, send
|
||||
* out all of the corresponding signals described below.
|
||||
*/
|
||||
void addWindow();
|
||||
|
||||
/**
|
||||
* When called will remove the last window from the set of windows, which will, in
|
||||
* turn, send out all of the corresponding signals described below.
|
||||
*/
|
||||
void removeWindow();
|
||||
|
||||
signals:
|
||||
/**
|
||||
* This signal is emitted when a windowhas changed.
|
||||
*
|
||||
* \param monitorIndex The 0-based index of the monitor to which the window belongs to
|
||||
* \param windowIndex The 0-based index of the window that was changed
|
||||
* \param newDimensions The pixel sizes of the window after the change
|
||||
*/
|
||||
void windowChanged(int monitorIndex, int windowIndex, const QRectF& newDimensions);
|
||||
|
||||
/**
|
||||
* This signal is emitted when the total number of windows has changed.
|
||||
*
|
||||
* \param newCount The new total number of windows
|
||||
*/
|
||||
void nWindowsChanged(int newCount);
|
||||
|
||||
private:
|
||||
void initializeWindowControl();
|
||||
void initializeLayout();
|
||||
void createWidgets(int nMaxWindows, std::vector<QRect> monitorResolutions,
|
||||
std::array<QColor, 4> windowColors);
|
||||
void showWindows();
|
||||
std::shared_ptr<MonitorBox> _monBox;
|
||||
std::vector<QRect>& _monitorResolutions;
|
||||
unsigned int _nWindowsAllocated = 0;
|
||||
|
||||
unsigned int _nWindowsDisplayed = 0;
|
||||
unsigned int _nMaxWindows = 3;
|
||||
const std::array<QColor, 4>& _winColors;
|
||||
std::vector<std::shared_ptr<WindowControl>> _windowControl;
|
||||
|
||||
std::vector<WindowControl*> _windowControl;
|
||||
QPushButton* _addWindowButton = nullptr;
|
||||
QPushButton* _removeWindowButton = nullptr;
|
||||
unsigned int _monitorIdx = 0;
|
||||
std::vector<QVBoxLayout*> _winCtrlLayouts;
|
||||
std::vector<QWidget*> _layoutWindowWrappers;
|
||||
std::vector<QFrame*> _frameBorderLines;
|
||||
QFrame* _borderFrame = nullptr;
|
||||
};
|
||||
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___DISPLAYWINDOWUNION___H__
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2022 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_UI_LAUNCHER___FILESUPPORT___H__
|
||||
#define __OPENSPACE_UI_LAUNCHER___FILESUPPORT___H__
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <sgctedit/displaywindowunion.h>
|
||||
#include <sgctedit/orientation.h>
|
||||
#include <sgct/config.h>
|
||||
#include <QFileDialog>
|
||||
#include <QFrame>
|
||||
#include <QLabel>
|
||||
#include <QLayout>
|
||||
#include <QPushButton>
|
||||
#include <QVector>
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
using ProjectionOptions = std::variant<
|
||||
sgct::config::NoProjection,
|
||||
sgct::config::CylindricalProjection,
|
||||
sgct::config::EquirectangularProjection,
|
||||
sgct::config::FisheyeProjection,
|
||||
sgct::config::PlanarProjection,
|
||||
sgct::config::ProjectionPlane,
|
||||
sgct::config::SphericalMirrorProjection,
|
||||
sgct::config::SpoutOutputProjection,
|
||||
sgct::config::SpoutFlatProjection
|
||||
>;
|
||||
|
||||
struct SgctConfigElements {
|
||||
std::vector<sgct::config::Window>& windowList;
|
||||
sgct::config::Cluster& cluster;
|
||||
};
|
||||
|
||||
struct UserConfigurationElements {
|
||||
std::vector<QRect>& monitorList;
|
||||
std::shared_ptr<DisplayWindowUnion> display;
|
||||
Orientation* orientation;
|
||||
const std::string configSavePath;
|
||||
};
|
||||
|
||||
class FileSupport : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Constructor for FileSupport class, which saves the window configuration settings
|
||||
* into the SGCT json structure according to the sgct code
|
||||
*
|
||||
* \param parentLayout Qt vertical (QVBoxLayout) layout where controls are added
|
||||
* \param cfgElements struct of elements needed to read user settings from GUI
|
||||
* \param sgctElements struct of the window and cluster objects needed for saving
|
||||
* \param finishedCallback function to be called when user has selected to either
|
||||
* save changes to file, apply and run without saving, or cancel
|
||||
*/
|
||||
FileSupport(QVBoxLayout* parentLayout, UserConfigurationElements& cfgElements,
|
||||
SgctConfigElements& sgctElements, std::function<void(bool)> finishedCallback);
|
||||
std::string saveFilename();
|
||||
|
||||
private slots:
|
||||
void cancel();
|
||||
void save();
|
||||
void apply();
|
||||
|
||||
private:
|
||||
bool isWindowFullscreen(unsigned int monitorIdx, sgct::ivec2 wDims);
|
||||
std::optional<unsigned int> findGuiWindow();
|
||||
void saveConfigToSgctFormat();
|
||||
void saveCluster();
|
||||
void saveWindows();
|
||||
void saveUser();
|
||||
ProjectionOptions saveProjectionInformation(
|
||||
std::shared_ptr<WindowControl> winControl);
|
||||
ProjectionOptions saveProjectionSpout(std::shared_ptr<WindowControl> winControl);
|
||||
ProjectionOptions saveProjectionNoSpout(std::shared_ptr<WindowControl> winControl);
|
||||
sgct::config::Viewport generateViewport();
|
||||
sgct::config::Window saveWindowsDimensions(std::shared_ptr<WindowControl> wCtrl);
|
||||
void saveWindowsWebGui(unsigned int wIdx, sgct::config::Window& win);
|
||||
|
||||
QHBoxLayout* _layoutButtonBox = nullptr;
|
||||
QPushButton* _saveButton = nullptr;
|
||||
QPushButton* _cancelButton = nullptr;
|
||||
QPushButton* _applyButton = nullptr;
|
||||
std::shared_ptr<DisplayWindowUnion> _displayWidget;
|
||||
Orientation* _orientationWidget;
|
||||
std::vector<QRect>& _monitors;
|
||||
sgct::config::Cluster& _cluster;
|
||||
std::vector<sgct::config::Window>& _windowList;
|
||||
std::function<void(bool)> _finishedCallback;
|
||||
const std::string _userConfigPath;
|
||||
std::string _saveTarget;
|
||||
};
|
||||
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___FILESUPPORT___H__
|
||||
@@ -27,20 +27,11 @@
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "windowcontrol.h"
|
||||
#include <QColor>
|
||||
#include <QIntValidator>
|
||||
#include <QLineEdit>
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
#include <QPoint>
|
||||
#include <QVector>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
class MonitorBox : public QWidget {
|
||||
class MonitorBox final : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
@@ -54,73 +45,50 @@ public:
|
||||
* \param winColors An array of QColor objects for window colors. The indexing of
|
||||
* this array matches the window indexing used elsewhere in the
|
||||
* class. This allows for a unique color for each window.
|
||||
*/
|
||||
MonitorBox(QRect widgetDims, std::vector<QRect> monitorResolution,
|
||||
unsigned int nWindows, const std::array<QColor, 4>& winColors);
|
||||
* \param parent The parent which to which this MonitorBox belongs
|
||||
*/
|
||||
MonitorBox(QRect widgetDims, const std::vector<QRect>& monitorResolutions,
|
||||
unsigned int nWindows, const std::array<QColor, 4>& windowColors,
|
||||
QWidget* parent = nullptr);
|
||||
|
||||
/**
|
||||
* Maps window resolution into the scaled resolution of the display widget
|
||||
*
|
||||
* \param mIdx The zero-based monitor index (primary monitor is 0)
|
||||
* \param wIdx The zero-based window index
|
||||
* \param winDimensions Dimensions (pixels) of window to be mapped in QRect
|
||||
*/
|
||||
void mapWindowResolutionToWidgetCoordinates(unsigned int mIdx, unsigned int wIdx,
|
||||
const QRectF& winDimensions);
|
||||
/**
|
||||
* Sets the number of windows to be displayed
|
||||
*
|
||||
* \param nWindows Number of windows to be displayed
|
||||
*/
|
||||
void setNumWindowsDisplayed(unsigned int nWindows);
|
||||
/**
|
||||
* Called when window dimensions or monitor location have changed, requiring redraw
|
||||
* Called when window dimensions or monitor location have changed, requiring redraw.
|
||||
* This will also map the window resolution into the scaled resolution of the display
|
||||
* widget.
|
||||
*
|
||||
* \param mIdx The zero-based monitor index (primary monitor is 0)
|
||||
* \param wIdx The zero-based window index
|
||||
* \param newDimensions Dimensions (pixels) of window to be mapped in QRect
|
||||
*/
|
||||
*/
|
||||
void windowDimensionsChanged(unsigned int mIdx, unsigned int wIdx,
|
||||
const QRectF& newDimensions);
|
||||
const QRectF& newDimensions);
|
||||
|
||||
/**
|
||||
* Called when the number of windows that should be displayed changes.
|
||||
*
|
||||
* \param newCount The new number of windows included
|
||||
*/
|
||||
void nWindowsDisplayedChanged(int newCount);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent* event) override;
|
||||
|
||||
private:
|
||||
void determineMonitorArrangement();
|
||||
void mapMonitorResolutionToWidgetCoordinates();
|
||||
void paintWidgetBorder(QPainter& painter, int width, int height);
|
||||
void paintMonitorBackgrounds(QPainter& painter);
|
||||
void paintWindow(QPainter& painter, size_t winIdx);
|
||||
void paintWindowBeyondBounds(QPainter& painter, unsigned int winIdx);
|
||||
void paintWindowNumber(QPainter& painter, unsigned int winIdx);
|
||||
void setPenSpecificToWindow(QPainter& painter, unsigned int windowIdx,
|
||||
bool visibleBorder);
|
||||
void computeScaledResolutionLandscape(float aspectRatio, float maxWidth);
|
||||
void computeScaledResolutionPortrait(float aspectRatio, float maxHeight);
|
||||
std::vector<QSizeF> computeScaledResolutionLandscape(QRectF arrangement,
|
||||
const std::vector<QRect>& resolutions);
|
||||
std::vector<QSizeF> computeScaledResolutionPortrait(QRectF arrangement,
|
||||
const std::vector<QRect>& resolutions);
|
||||
|
||||
unsigned int _maxNumMonitors = 2;
|
||||
QRectF _monitorWidgetSize;
|
||||
QRectF _monitorBoundaryRect;
|
||||
unsigned int _nMonitors = 1;
|
||||
float _monitorArrangementAspectRatio = 1.f;
|
||||
QSizeF _monitorArrangementDimensions = { 0.0, 0.0 };
|
||||
std::vector<QRect> _monitorResolution;
|
||||
std::vector<QRectF> _monitorDimensionsScaled;
|
||||
QRectF _negativeCorrectionOffsets = {0.f, 0.f, 0.f, 0.f};
|
||||
std::vector<QRectF> _windowResolutions;
|
||||
std::vector<QRectF> _windowRendering = {
|
||||
{0.f, 0.f, 0.f, 0.f},
|
||||
{0.f, 0.f, 0.f, 0.f},
|
||||
{0.f, 0.f, 0.f, 0.f},
|
||||
{0.f, 0.f, 0.f, 0.f}
|
||||
std::array<QRectF, 4> _windowRendering = {
|
||||
QRectF{ 0.f, 0.f, 0.f, 0.f },
|
||||
QRectF{ 0.f, 0.f, 0.f, 0.f },
|
||||
QRectF{ 0.f, 0.f, 0.f, 0.f },
|
||||
QRectF{ 0.f, 0.f, 0.f, 0.f }
|
||||
};
|
||||
unsigned int _nWindows = 1;
|
||||
int _nWindows = 1;
|
||||
const std::array<QColor, 4> _colorsForWindows;
|
||||
int _alphaWindowOpacity = 170;
|
||||
float _monitorScaleFactor = 1.0;
|
||||
bool _showLabel = false;
|
||||
float _marginWidget = 5.0;
|
||||
std::vector<QSizeF> _monitorOffsets;
|
||||
};
|
||||
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___MONITORBOX___H__
|
||||
|
||||
@@ -27,13 +27,12 @@
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include <sgct/config.h>
|
||||
#include <QLineEdit>
|
||||
#include <glm/gtc/constants.hpp>
|
||||
#include <sgct/math.h>
|
||||
|
||||
class QLineEdit;
|
||||
class QWidget;
|
||||
|
||||
class OrientationDialog : public QDialog {
|
||||
class OrientationDialog final : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
@@ -42,14 +41,12 @@ public:
|
||||
*
|
||||
* \param orientation x,y,z angles in degrees contained in sgct::quat object
|
||||
* \param parent pointer to Qt QWidget parent object
|
||||
*/
|
||||
*/
|
||||
OrientationDialog(sgct::quat& orientation, QWidget* parent);
|
||||
|
||||
private slots:
|
||||
void cancel();
|
||||
void ok();
|
||||
|
||||
private:
|
||||
void ok();
|
||||
|
||||
QLineEdit* _linePitch = nullptr;
|
||||
QLineEdit* _lineRoll = nullptr;
|
||||
QLineEdit* _lineYaw = nullptr;
|
||||
|
||||
@@ -22,62 +22,50 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_UI_LAUNCHER___ORIENTATION___H__
|
||||
#define __OPENSPACE_UI_LAUNCHER___ORIENTATION___H__
|
||||
#ifndef __OPENSPACE_UI_LAUNCHER___SETTINGSWIDGET___H__
|
||||
#define __OPENSPACE_UI_LAUNCHER___SETTINGSWIDGET___H__
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include <sgctedit/orientationdialog.h>
|
||||
#include <sgct/config.h>
|
||||
#include <sgct/math.h>
|
||||
#include <QCheckBox>
|
||||
#include <QLayout>
|
||||
#include <QPushButton>
|
||||
|
||||
class Orientation : public QWidget {
|
||||
class QCheckBox;
|
||||
class QLabel;
|
||||
|
||||
class SettingsWidget final : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Constructor for Orientation class, which manages the overall control layout
|
||||
* including monitorBox, multiple WindowControl columns, and additional controls
|
||||
*
|
||||
* \param monitorRenderBox pointer to the MonitorBox object
|
||||
* \param monitorSizeList A vector containing QRect objects containing pixel dims
|
||||
* of each monitor
|
||||
* \param nMaxWindows The maximum number of windows allowed (depends on the number
|
||||
* of monitors in the system)
|
||||
* \param winColors An array of QColor objects for window colors. The indexing of
|
||||
* this array matches the window indexing used elsewhere in the
|
||||
* class. This allows for a unique color for each window.
|
||||
*/
|
||||
Orientation();
|
||||
/**
|
||||
* Add Orientation controls to the parent layout
|
||||
*
|
||||
* \param parentLayout the layout to which the Orientation's controls will be added
|
||||
*/
|
||||
void addControlsToParentLayout(QVBoxLayout* parentLayout);
|
||||
*/
|
||||
SettingsWidget(sgct::quat orientation, QWidget* parent = nullptr);
|
||||
|
||||
/**
|
||||
* Gets the user-provided x,y,z orientation values (degrees)
|
||||
*
|
||||
* \return the orientation angles provided in sgct::quat object
|
||||
*/
|
||||
sgct::quat orientationValue() const;
|
||||
*/
|
||||
sgct::quat orientation() const;
|
||||
|
||||
/**
|
||||
* Gets the value for if VSync is enabled
|
||||
*
|
||||
* \return true if the VSync option is checked/enabled
|
||||
*/
|
||||
bool vsyncValue() const;
|
||||
*/
|
||||
bool vsync() const;
|
||||
|
||||
private slots:
|
||||
void orientationDialog();
|
||||
/**
|
||||
* Gets whether the UI should be restricted to the first window
|
||||
*
|
||||
* \return true if the UI should only be on the first window
|
||||
*/
|
||||
bool showUiOnFirstWindow() const;
|
||||
|
||||
private:
|
||||
sgct::quat _orientationValue = {0.f, 0.f, 0.f, 0.f};
|
||||
OrientationDialog _orientationDialog;
|
||||
QHBoxLayout* _layoutOrientationFull = nullptr;
|
||||
sgct::quat _orientationValue = { 0.f, 0.f, 0.f, 0.f };
|
||||
QCheckBox* _checkBoxVsync = nullptr;
|
||||
QCheckBox* _showUiOnFirstWindow = nullptr;
|
||||
};
|
||||
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___ORIENTATION___H__
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___SETTINGSWIDGET___H__
|
||||
@@ -27,18 +27,15 @@
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include <sgctedit/displaywindowunion.h>
|
||||
#include <sgctedit/filesupport.h>
|
||||
#include <sgctedit/monitorbox.h>
|
||||
#include <sgctedit/orientation.h>
|
||||
#include <QApplication>
|
||||
#include <sgct/config.h>
|
||||
#include <QColor>
|
||||
#include <QLayout>
|
||||
#include <QScreen>
|
||||
#include <memory>
|
||||
#include <array>
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class DisplayWindowUnion;
|
||||
class SettingsWidget;
|
||||
class QBoxLayout;
|
||||
class QWidget;
|
||||
|
||||
class SgctEdit final : public QDialog {
|
||||
@@ -49,57 +46,48 @@ public:
|
||||
* configuration editor
|
||||
*
|
||||
* \param parent The Qt QWidget parent object
|
||||
* \param windowList vector of sgct::config::Window objects which will be modified
|
||||
* by the user settings, and then used for writing to file in
|
||||
* the launcher code
|
||||
* \param cluster reference to sgct::config::Cluster object that contains sgct
|
||||
* objects that will be modified by the window configuration settings
|
||||
* \param screenList A QList containing a QScreen object for each monitor in the
|
||||
* system
|
||||
* \param userConfigPath A string containing the file path of the user config
|
||||
* directory where all window configs are stored
|
||||
*/
|
||||
SgctEdit(QWidget* parent, std::vector<sgct::config::Window>& windowList,
|
||||
sgct::config::Cluster& cluster, const QList<QScreen*>& screenList,
|
||||
const std::string userConfigPath);
|
||||
~SgctEdit();
|
||||
/**
|
||||
* Used to determine if the window configuration was saved to file, or canceled
|
||||
*
|
||||
* \return true if configuration was saved to file
|
||||
*/
|
||||
bool wasSaved() const;
|
||||
*/
|
||||
SgctEdit(QWidget* parent, std::string userConfigPath);
|
||||
|
||||
/**
|
||||
* Returns the saved filename
|
||||
*
|
||||
* \return saved filename in std::string
|
||||
*/
|
||||
std::string saveFilename();
|
||||
*/
|
||||
std::filesystem::path saveFilename() const;
|
||||
|
||||
/**
|
||||
* Returns the generated Cluster object.
|
||||
*
|
||||
* \return The generated Cluster object
|
||||
*/
|
||||
sgct::config::Cluster cluster() const;
|
||||
|
||||
private:
|
||||
void addDisplayLayout(QHBoxLayout* layout);
|
||||
void createWidgets();
|
||||
void systemMonitorConfiguration(const QList<QScreen*>& screenList);
|
||||
void createWidgets(const std::vector<QRect>& monitorSizes);
|
||||
sgct::config::Cluster generateConfiguration() const;
|
||||
|
||||
std::shared_ptr<MonitorBox> _monBox = nullptr;
|
||||
std::vector<QRect> _monitorSizeList;
|
||||
QVBoxLayout* _displayLayout = nullptr;
|
||||
QFrame* _displayFrame = nullptr;
|
||||
std::shared_ptr<DisplayWindowUnion> _displayWidget = nullptr;
|
||||
QRect _monitorWidgetSize = {0, 0, 500, 500};
|
||||
FileSupport* _fileSupportWidget = nullptr;
|
||||
Orientation* _orientationWidget = nullptr;
|
||||
sgct::config::Cluster& _cluster;
|
||||
std::vector<sgct::config::Window>& _windowList;
|
||||
void save();
|
||||
void apply();
|
||||
|
||||
DisplayWindowUnion* _displayWidget = nullptr;
|
||||
SettingsWidget* _settingsWidget = nullptr;
|
||||
sgct::config::Cluster _cluster;
|
||||
const std::string _userConfigPath;
|
||||
bool _saveSelected = false;
|
||||
unsigned int _nMaxWindows = 3;
|
||||
const std::array<QColor, 4> _colorsForWindows = {
|
||||
QColor(0x2B, 0x9E, 0xC3),
|
||||
QColor(0xFC, 0xAB, 0x10),
|
||||
QColor(0x44, 0xAF, 0x69),
|
||||
QColor(0xF8, 0x33, 0x3C)
|
||||
};
|
||||
|
||||
QBoxLayout* _layoutButtonBox = nullptr;
|
||||
QPushButton* _saveButton = nullptr;
|
||||
QPushButton* _cancelButton = nullptr;
|
||||
QPushButton* _applyButton = nullptr;
|
||||
std::string _saveTarget;
|
||||
};
|
||||
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___SGCTEDIT___H__
|
||||
|
||||
@@ -21,21 +21,24 @@
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_UI_LAUNCHER___WINDOWCONTROL___H__
|
||||
#define __OPENSPACE_UI_LAUNCHER___WINDOWCONTROL___H__
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include <sgct/config.h>
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QLabel>
|
||||
#include <QLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QIcon>
|
||||
#include <vector>
|
||||
|
||||
class WindowControl : public QWidget {
|
||||
class QCheckBox;
|
||||
class QComboBox;
|
||||
class QDoubleSpinBox;
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QSpinBox;
|
||||
|
||||
class WindowControl final : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
@@ -46,206 +49,107 @@ public:
|
||||
* resides in
|
||||
* \param windowIndex The zero-based window index
|
||||
* \param monitorDims Vector of monitor dimensions in QRect form
|
||||
* \param winColor A QColor object for this window's unique color
|
||||
*/
|
||||
WindowControl(unsigned int monitorIndex, unsigned int windowIndex,
|
||||
std::vector<QRect>& monitorDims, const QColor& winColor,
|
||||
QWidget *parent);
|
||||
~WindowControl();
|
||||
/**
|
||||
* Sets callback function to be invoked when a window's setting changes
|
||||
*
|
||||
* \param cb Callback function that accepts the listed arg types, in order of
|
||||
* monitorIndex, windowIndex, and windowDims (that were just changed)
|
||||
* \param winColor A QColor object for this window's unique color
|
||||
*/
|
||||
void setWindowChangeCallback(std::function<void(int, int, const QRectF&)> cb);
|
||||
/**
|
||||
* Sets callback function to be invoked when a window gets its GUI checkbox selected
|
||||
*
|
||||
* \param cb Callback function that accepts the index of the window that has its
|
||||
* WebGUI option selected
|
||||
*/
|
||||
void setWebGuiChangeCallback(std::function<void(unsigned int)> cb);
|
||||
WindowControl(int monitorIndex, int windowIndex,
|
||||
const std::vector<QRect>& monitorDims, const QColor& winColor, QWidget* parent);
|
||||
|
||||
/**
|
||||
* Makes the window label at top of a window control column visible
|
||||
*
|
||||
* \param bool Shows the window label if true
|
||||
*/
|
||||
void showWindowLabel(bool show);
|
||||
|
||||
/**
|
||||
* Initializes the layout of a window controls column, returning the Qt layout object
|
||||
*
|
||||
* \return the QVBoxLayout object that contains the entire windows control column
|
||||
* Resets all controls for this window to default settings
|
||||
*/
|
||||
QVBoxLayout* initializeLayout();
|
||||
/**
|
||||
* Returns the dimensions of the window
|
||||
*
|
||||
* \return the QRectF object that contains the windows dimensions
|
||||
*/
|
||||
QRectF& dimensions();
|
||||
/**
|
||||
* Returns the title name of the window
|
||||
*
|
||||
* \return the std::string of the window name
|
||||
*/
|
||||
std::string windowName() const;
|
||||
/**
|
||||
* Returns the user-entered window size width, height from the text line objects
|
||||
*
|
||||
* \return the user-entered window size in sgct::ivec2 object
|
||||
*/
|
||||
sgct::ivec2 windowSize() const;
|
||||
/**
|
||||
* Returns the user-entered window position in x,y pixles from the text line objects
|
||||
*
|
||||
* \return the user-entered window position in sgct::ivec2 object
|
||||
*/
|
||||
sgct::ivec2 windowPos() const;
|
||||
/**
|
||||
* Returns bool for if the window control checkbox is set to be decorated
|
||||
*
|
||||
* \return bool for if window decoration is enabled
|
||||
*/
|
||||
bool isDecorated() const;
|
||||
/**
|
||||
* Returns bool for if the window control checkbox spout selection is enabled
|
||||
*
|
||||
* \return bool for if window has spout enabled
|
||||
*/
|
||||
bool isSpoutSelected() const;
|
||||
/**
|
||||
* Returns bool for if the window control checkbox for WebGUI is enabled
|
||||
*
|
||||
* \return bool for if window has WebGUI enabled
|
||||
*/
|
||||
bool isGuiWindow() const;
|
||||
/**
|
||||
* Function called in order to disable/uncheck the WebGUI checkbox option
|
||||
*/
|
||||
void uncheckWebGuiOption();
|
||||
/**
|
||||
* Returns index number of the selected window quality value. This is an index into
|
||||
* the QualityValues array
|
||||
*
|
||||
* \return index int into the QualityValues array
|
||||
*/
|
||||
int qualitySelectedValue() const;
|
||||
/**
|
||||
* Returns index number of the monitor that this window is assigned to
|
||||
*
|
||||
* \return int index of monitor
|
||||
*/
|
||||
unsigned int monitorNum() const;
|
||||
/**
|
||||
* Returns the user-entered horizontal field-of-view (planar projection only)
|
||||
*
|
||||
* \return float value of horizontal FOV
|
||||
*/
|
||||
float fovH() const;
|
||||
/**
|
||||
* Returns the user-entered vertical field-of-view (planar projection only)
|
||||
*
|
||||
* \return float value of vertical FOV
|
||||
*/
|
||||
float fovV() const;
|
||||
/**
|
||||
* Returns the user-entered height offset (cylindrical projection only)
|
||||
*
|
||||
* \return float value of height offset
|
||||
*/
|
||||
float heightOffset() const;
|
||||
enum class ProjectionIndeces {
|
||||
void resetToDefaults();
|
||||
|
||||
sgct::config::Window generateWindowInformation() const;
|
||||
|
||||
signals:
|
||||
void windowChanged(int monitorIndex, int windowIndex, const QRectF& newDimensions);
|
||||
|
||||
private:
|
||||
enum class ProjectionIndices {
|
||||
Planar = 0,
|
||||
Fisheye,
|
||||
SphericalMirror,
|
||||
Cylindrical,
|
||||
Equirectangular
|
||||
};
|
||||
/**
|
||||
* Returns the user-selected window projection type
|
||||
*
|
||||
* \return ProjectionIndeces enum of the projection type
|
||||
*/
|
||||
ProjectionIndeces projectionSelectedIndex() const;
|
||||
/**
|
||||
* Resets all controls for this window to default settings
|
||||
*/
|
||||
void resetToDefaults();
|
||||
|
||||
private slots:
|
||||
void onSizeXChanged(const QString& newText);
|
||||
void onSizeYChanged(const QString& newText);
|
||||
void onOffsetXChanged(const QString& newText);
|
||||
void onOffsetYChanged(const QString& newText);
|
||||
void onMonitorChanged(int newSelection);
|
||||
void createWidgets(const QColor& windowColor);
|
||||
QWidget* createPlanarWidget();
|
||||
QWidget* createFisheyeWidget();
|
||||
QWidget* createSphericalMirrorWidget();
|
||||
QWidget* createCylindricalWidget();
|
||||
QWidget* createEquirectangularWidget();
|
||||
|
||||
void onSizeXChanged(int newValue);
|
||||
void onSizeYChanged(int newValue);
|
||||
void onOffsetXChanged(int newValue);
|
||||
void onOffsetYChanged(int newValue);
|
||||
void onProjectionChanged(int newSelection);
|
||||
void onFullscreenClicked();
|
||||
void onSpoutSelection(int selectionState);
|
||||
void onWebGuiSelection(int selectionState);
|
||||
void onAspectRatioLockClicked();
|
||||
void onFovLockClicked();
|
||||
|
||||
private:
|
||||
void createWidgets(QWidget* parent);
|
||||
void determineIdealWindowSize();
|
||||
QString resolutionLabelText(QRect resolution);
|
||||
sgct::config::Projections generateProjectionInformation() const;
|
||||
void updatePlanarLockedFov();
|
||||
void updateScaledWindowDimensions();
|
||||
std::function<void(int, int, const QRectF&)> _windowChangeCallback;
|
||||
std::function<void(unsigned int)> _windowGuiCheckCallback;
|
||||
QRectF defaultWindowSizes[4] = {
|
||||
{50.f, 50.f, 1280.f, 720.f},
|
||||
{150.f, 150.f, 1280.f, 720.f},
|
||||
{50.f, 50.f, 1280.f, 720.f},
|
||||
{150.f, 150.f, 1280.f, 720.f}
|
||||
};
|
||||
QList<QString> _monitorNames = { "Primary", "Secondary" };
|
||||
int QualityValues[10] = { 256, 512, 1024, 1536, 2048, 4096, 8192, 16384,
|
||||
32768, 65536 };
|
||||
int _lineEditWidthFixedWinSize = 50;
|
||||
int _lineEditWidthFixedFov = 80;
|
||||
const float _idealAspectRatio = 16.f / 9.f;
|
||||
float _aspectRatioSize = _idealAspectRatio;
|
||||
float _marginFractionOfWidgetSize = 0.025f;
|
||||
float _defaultFovH = 80.f;
|
||||
float _defaultFovV = 50.534f;
|
||||
float _defaultHeightOffset = 0.f;
|
||||
unsigned int _nMonitors = 1;
|
||||
unsigned int _monIndex = 0;
|
||||
unsigned int _monIndexDefault = 0;
|
||||
unsigned int _index = 0;
|
||||
|
||||
static constexpr float IdealAspectRatio = 16.f / 9.f;
|
||||
float _aspectRatioSize = IdealAspectRatio;
|
||||
|
||||
const int _monitorIndexDefault = 0;
|
||||
int _windowIndex = 0;
|
||||
bool _aspectRatioLocked = false;
|
||||
bool _FovLocked = true;
|
||||
std::vector<QRect>& _monitorResolutions;
|
||||
int _maxWindowSizePixels = 10000;
|
||||
const QColor& _colorForWindow;
|
||||
QVBoxLayout* _layoutFullWindow = nullptr;
|
||||
QLabel* _labelWinNum = nullptr;
|
||||
QLineEdit* _sizeX = nullptr;
|
||||
QLineEdit* _sizeY = nullptr;
|
||||
QLineEdit* _offsetX = nullptr;
|
||||
QLineEdit* _offsetY = nullptr;
|
||||
QPushButton* _buttonLockAspectRatio = nullptr;
|
||||
QPushButton* _buttonLockFov = nullptr;
|
||||
QRectF _windowDims;
|
||||
QPushButton* _fullscreenButton = nullptr;
|
||||
QCheckBox* _checkBoxWindowDecor = nullptr;
|
||||
QCheckBox* _checkBoxWebGui = nullptr;
|
||||
QCheckBox* _checkBoxSpoutOutput = nullptr;
|
||||
QComboBox* _comboMonitorSelect = nullptr;
|
||||
QComboBox* _comboProjection = nullptr;
|
||||
QComboBox* _comboQuality = nullptr;
|
||||
QLabel* _labelQuality = nullptr;
|
||||
QLabel* _labelFovH = nullptr;
|
||||
QLineEdit* _lineFovH = nullptr;
|
||||
QLabel* _labelFovV = nullptr;
|
||||
QLineEdit* _lineFovV = nullptr;
|
||||
QLabel* _labelHeightOffset = nullptr;
|
||||
QLineEdit* _lineHeightOffset = nullptr;
|
||||
bool _fovLocked = true;
|
||||
std::vector<QRect> _monitorResolutions;
|
||||
QRectF _windowDimensions;
|
||||
|
||||
QLabel* _windowNumber = nullptr;
|
||||
QLineEdit* _windowName = nullptr;
|
||||
QIcon _lockIcon;
|
||||
QIcon _unlockIcon;
|
||||
QComboBox* _monitor = nullptr;
|
||||
QSpinBox* _sizeX = nullptr;
|
||||
QSpinBox* _sizeY = nullptr;
|
||||
QSpinBox* _offsetX = nullptr;
|
||||
QSpinBox* _offsetY = nullptr;
|
||||
QCheckBox* _windowDecoration = nullptr;
|
||||
QComboBox* _projectionType = nullptr;
|
||||
|
||||
struct {
|
||||
QWidget* widget = nullptr;
|
||||
QDoubleSpinBox* fovH = nullptr;
|
||||
QDoubleSpinBox* fovV = nullptr;
|
||||
} _planar;
|
||||
|
||||
struct {
|
||||
QWidget* widget = nullptr;
|
||||
QComboBox* quality = nullptr;
|
||||
QCheckBox* spoutOutput = nullptr;
|
||||
} _fisheye;
|
||||
|
||||
struct {
|
||||
QWidget* widget = nullptr;
|
||||
QComboBox* quality = nullptr;
|
||||
} _sphericalMirror;
|
||||
|
||||
struct {
|
||||
QWidget* widget = nullptr;
|
||||
QComboBox* quality = nullptr;
|
||||
QDoubleSpinBox* heightOffset = nullptr;
|
||||
} _cylindrical;
|
||||
|
||||
struct {
|
||||
QWidget* widget = nullptr;
|
||||
QComboBox* quality = nullptr;
|
||||
QCheckBox* spoutOutput = nullptr;
|
||||
} _equirectangular;
|
||||
|
||||
const QIcon _lockIcon;
|
||||
const QIcon _unlockIcon;
|
||||
};
|
||||
|
||||
#endif // __OPENSPACE_UI_LAUNCHER___WINDOWCONTROL___H__
|
||||
|
||||
@@ -149,25 +149,41 @@ CameraDialog QLabel#error-message {
|
||||
min-width: 10em;
|
||||
}
|
||||
|
||||
/*
|
||||
* ScriptlogDialog
|
||||
*/
|
||||
ScriptlogDialog QListWidget {
|
||||
min-width: 60em;
|
||||
}
|
||||
|
||||
/*
|
||||
* Horizons dialog
|
||||
*/
|
||||
QPlainTextEdit#log {
|
||||
HorizonsDialog QPlainTextEdit#log {
|
||||
font-family: Courier;
|
||||
}
|
||||
|
||||
QComboBox#mono {
|
||||
HorizonsDialog QComboBox#mono {
|
||||
font-family: Courier;
|
||||
}
|
||||
|
||||
QLabel#thin {
|
||||
HorizonsDialog QLabel#thin {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
QLabel#error {
|
||||
HorizonsDialog QLabel#error {
|
||||
color: rgb(221, 17, 17);
|
||||
}
|
||||
|
||||
QLabel#normal {
|
||||
HorizonsDialog QLabel#normal {
|
||||
color: rgb(0, 0, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* SGCT
|
||||
*/
|
||||
WindowControl QLabel#info {
|
||||
font-style: italic;
|
||||
font-weight: normal;
|
||||
font-size: 8pt;
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
void saveWindowConfig(QWidget* parent, const std::string& path,
|
||||
void saveWindowConfig(QWidget* parent, const std::filesystem::path& path,
|
||||
sgct::config::Cluster& cluster)
|
||||
{
|
||||
std::ofstream outFile;
|
||||
@@ -395,7 +395,9 @@ void LauncherWindow::populateProfilesList(std::string preset) {
|
||||
}
|
||||
|
||||
_profileBox->addItem(QString::fromStdString("--- User Profiles ---"));
|
||||
const QStandardItemModel* model = qobject_cast<const QStandardItemModel*>(_profileBox->model());
|
||||
const QStandardItemModel* model = qobject_cast<const QStandardItemModel*>(
|
||||
_profileBox->model()
|
||||
);
|
||||
model->item(_userAssetCount)->setEnabled(false);
|
||||
++_userAssetCount;
|
||||
|
||||
@@ -410,7 +412,10 @@ void LauncherWindow::populateProfilesList(std::string preset) {
|
||||
}
|
||||
std::sort(profiles.begin(), profiles.end());
|
||||
for (const fs::directory_entry& p : profiles) {
|
||||
_profileBox->addItem(QString::fromStdString(p.path().stem().string()));
|
||||
_profileBox->addItem(
|
||||
QString::fromStdString(p.path().stem().string()),
|
||||
QString::fromStdString(p.path().string())
|
||||
);
|
||||
}
|
||||
|
||||
_profileBox->addItem(QString::fromStdString("--- OpenSpace Profiles ---"));
|
||||
@@ -427,16 +432,33 @@ void LauncherWindow::populateProfilesList(std::string preset) {
|
||||
profiles.push_back(path);
|
||||
}
|
||||
std::sort(profiles.begin(), profiles.end());
|
||||
//add sorted items to list
|
||||
|
||||
// Add sorted items to list
|
||||
for (const fs::directory_entry& profile : profiles) {
|
||||
_profileBox->addItem(QString::fromStdString(profile.path().stem().string()));
|
||||
std::string abc = profile.path().string();
|
||||
_profileBox->addItem(
|
||||
QString::fromStdString(profile.path().stem().string()),
|
||||
QString::fromStdString(profile.path().string())
|
||||
);
|
||||
}
|
||||
|
||||
// Try to find the requested profile and set it as the current one
|
||||
const int idx = _profileBox->findText(QString::fromStdString(std::move(preset)));
|
||||
if (idx != -1) {
|
||||
_profileBox->setCurrentIndex(idx);
|
||||
int idx = _profileBox->findText(QString::fromStdString(preset));
|
||||
if (idx == -1) {
|
||||
// We didn't find the preset, so the user probably specified a path in the
|
||||
// configuration file that doesn't match any value in the list
|
||||
_profileBox->addItem(QString::fromStdString("--- Configuration File ---"));
|
||||
model = qobject_cast<const QStandardItemModel*>(_profileBox->model());
|
||||
model->item(_profileBox->count() - 1)->setEnabled(false);
|
||||
|
||||
_profileBox->addItem(
|
||||
QString::fromStdString(preset),
|
||||
QString::fromStdString(preset)
|
||||
);
|
||||
idx = _profileBox->count() - 1;
|
||||
}
|
||||
|
||||
_profileBox->setCurrentIndex(idx);
|
||||
}
|
||||
|
||||
// Returns 'true' if the file was a configuration file, 'false' otherwise
|
||||
@@ -471,7 +493,7 @@ void LauncherWindow::populateWindowConfigsList(std::string preset) {
|
||||
|
||||
bool hasXmlConfig = false;
|
||||
|
||||
//sort files
|
||||
// Sort files
|
||||
std::vector<fs::directory_entry> files;
|
||||
for (const fs::directory_entry& p : fs::directory_iterator(_userConfigPath)) {
|
||||
files.push_back(p);
|
||||
@@ -492,7 +514,7 @@ void LauncherWindow::populateWindowConfigsList(std::string preset) {
|
||||
model->item(_userConfigCount)->setEnabled(false);
|
||||
|
||||
if (std::filesystem::exists(_configPath)) {
|
||||
//sort files
|
||||
// Sort files
|
||||
files.clear();
|
||||
for (const fs::directory_entry& p : fs::directory_iterator(_configPath)) {
|
||||
files.push_back(p);
|
||||
@@ -522,7 +544,7 @@ void LauncherWindow::populateWindowConfigsList(std::string preset) {
|
||||
);
|
||||
}
|
||||
|
||||
//Always add the .cfg sgct default as first item
|
||||
// Always add the .cfg sgct default as first item
|
||||
_windowConfigBox->insertItem(0, QString::fromStdString(_sgctConfigName));
|
||||
// Try to find the requested configuration file and set it as the current one. As we
|
||||
// have support for function-generated configuration files that will not be in the
|
||||
@@ -534,8 +556,8 @@ void LauncherWindow::populateWindowConfigsList(std::string preset) {
|
||||
else {
|
||||
// Add the requested preset at the top
|
||||
_windowConfigBox->insertItem(1, QString::fromStdString(preset));
|
||||
//Increment the user config count because there is an additional option added
|
||||
//before the user config options
|
||||
// Increment the user config count because there is an additional option added
|
||||
// before the user config options
|
||||
_userConfigCount++;
|
||||
_windowConfigBox->setCurrentIndex(1);
|
||||
}
|
||||
@@ -546,7 +568,6 @@ void LauncherWindow::openProfileEditor(const std::string& profile, bool isUserPr
|
||||
std::string saveProfilePath = isUserProfile ? _userProfilePath : _profilePath;
|
||||
if (profile.empty()) {
|
||||
// If the requested profile is the empty string, then we want to create a new one
|
||||
|
||||
p = Profile();
|
||||
}
|
||||
else {
|
||||
@@ -559,13 +580,21 @@ void LauncherWindow::openProfileEditor(const std::string& profile, bool isUserPr
|
||||
}
|
||||
}
|
||||
|
||||
ProfileEdit editor(*p, profile, _assetPath, _userAssetPath, saveProfilePath, _readOnlyProfiles, this);
|
||||
ProfileEdit editor(
|
||||
*p,
|
||||
profile,
|
||||
_assetPath,
|
||||
_userAssetPath,
|
||||
saveProfilePath,
|
||||
_readOnlyProfiles,
|
||||
this
|
||||
);
|
||||
editor.exec();
|
||||
if (editor.wasSaved()) {
|
||||
if (editor.specifiedFilename() != profile) {
|
||||
saveProfilePath = _userProfilePath;
|
||||
}
|
||||
const std::string path = saveProfilePath + editor.specifiedFilename() + ".profile";
|
||||
std::string path = saveProfilePath + editor.specifiedFilename() + ".profile";
|
||||
saveProfile(this, path, *p);
|
||||
populateProfilesList(editor.specifiedFilename());
|
||||
}
|
||||
@@ -576,40 +605,16 @@ void LauncherWindow::openProfileEditor(const std::string& profile, bool isUserPr
|
||||
}
|
||||
|
||||
void LauncherWindow::openWindowEditor() {
|
||||
QList<QScreen*> screenList = qApp->screens();
|
||||
if (screenList.length() == 0) {
|
||||
LERRORC(
|
||||
"LauncherWindow",
|
||||
"Error: Qt reports no screens/monitors available"
|
||||
);
|
||||
return;
|
||||
}
|
||||
sgct::config::Cluster cluster;
|
||||
std::vector<sgct::config::Window> windowList;
|
||||
SgctEdit editor(this, windowList, cluster, screenList, _userConfigPath);
|
||||
editor.exec();
|
||||
if (editor.wasSaved()) {
|
||||
std::string ext = ".json";
|
||||
std::string savePath = editor.saveFilename();
|
||||
if (savePath.size() >= ext.size()
|
||||
&& !(savePath.substr(savePath.size() - ext.size()).compare(ext) == 0))
|
||||
{
|
||||
savePath += ext;
|
||||
}
|
||||
if (cluster.nodes.size() == 0) {
|
||||
cluster.nodes.push_back(sgct::config::Node());
|
||||
}
|
||||
for (auto w : windowList) {
|
||||
cluster.nodes[0].windows.push_back(w);
|
||||
}
|
||||
SgctEdit editor(this, _userConfigPath);
|
||||
int ret = editor.exec();
|
||||
if (ret == QDialog::DialogCode::Accepted) {
|
||||
sgct::config::Cluster cluster = editor.cluster();
|
||||
|
||||
std::filesystem::path savePath = editor.saveFilename();
|
||||
saveWindowConfig(this, savePath, cluster);
|
||||
//Truncate path to convert this back to path relative to _userConfigPath
|
||||
savePath = savePath.substr(_userConfigPath.size());
|
||||
populateWindowConfigsList(savePath);
|
||||
}
|
||||
else {
|
||||
const std::string current = _windowConfigBox->currentText().toStdString();
|
||||
populateWindowConfigsList(current);
|
||||
// Truncate path to convert this back to path relative to _userConfigPath
|
||||
std::string p = savePath.string().substr(_userConfigPath.size());
|
||||
populateWindowConfigsList(p);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -618,14 +623,16 @@ bool LauncherWindow::wasLaunchSelected() const {
|
||||
}
|
||||
|
||||
std::string LauncherWindow::selectedProfile() const {
|
||||
return _profileBox->currentText().toStdString();
|
||||
// The user data stores the full path to the profile
|
||||
return _profileBox->currentData().toString().toStdString();
|
||||
}
|
||||
|
||||
std::string LauncherWindow::selectedWindowConfig() const {
|
||||
int idx = _windowConfigBox->currentIndex();
|
||||
if (idx == 0) {
|
||||
return _sgctConfigName;
|
||||
} else if (idx > _userConfigCount) {
|
||||
}
|
||||
else if (idx > _userConfigCount) {
|
||||
return "${CONFIG}/" + _windowConfigBox->currentText().toStdString();
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -85,7 +85,7 @@ void ActionDialog::createWidgets() {
|
||||
// | | Is Local | [] [choosescr] | Row 5
|
||||
// | | Script | [oooooooooooo] | Row 6
|
||||
// *----------------------*---------------*----------------*
|
||||
// | [+] [-] | | [Save] [Cancel]| Row 7
|
||||
// | [+] [-] | | <Save> <Cancel>| Row 7
|
||||
// *----------------------*---------------*----------------*
|
||||
// |=======================================================| Row 8
|
||||
// | Keybindings | Row 9
|
||||
@@ -95,11 +95,11 @@ void ActionDialog::createWidgets() {
|
||||
// | | Add actions | DDDDDDDDDDDD> | Row 12
|
||||
// | | Action | [oooooooooooo] | Row 13
|
||||
// *----------------------*---------------*----------------*
|
||||
// | [+] [-] | | [Save] [Cancel]| Row 14
|
||||
// | [+] [-] | | <Save> <Cancel>| Row 14
|
||||
// *----------------------*---------------*----------------*
|
||||
// |=======================================================| Row 14
|
||||
// *----------------------*---------------*----------------*
|
||||
// | | [Save] [Cancel]| Row 15
|
||||
// | | <Save> <Cancel>| Row 15
|
||||
// *----------------------*---------------*----------------*
|
||||
|
||||
QGridLayout* layout = new QGridLayout(this);
|
||||
@@ -485,9 +485,15 @@ void ActionDialog::actionRemove() {
|
||||
|
||||
for (size_t i = 0; i < _actionData.size(); ++i) {
|
||||
if (_actionData[i].identifier == action->identifier) {
|
||||
clearActionFields();
|
||||
_actionData.erase(_actionData.begin() + i);
|
||||
delete _actionWidgets.list->takeItem(static_cast<int>(i));
|
||||
clearActionFields();
|
||||
|
||||
_keybindingWidgets.action->clear();
|
||||
for (const Profile::Action& a : _actionData) {
|
||||
_keybindingWidgets.action->addItem(QString::fromStdString(a.identifier));
|
||||
}
|
||||
clearKeybindingFields();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -587,6 +593,13 @@ void ActionDialog::actionSaved() {
|
||||
action->script = _actionWidgets.script->toPlainText().toStdString();
|
||||
|
||||
updateListItem(_actionWidgets.list->currentItem(), *action);
|
||||
|
||||
// Update the list of actions available in the action chooser
|
||||
_keybindingWidgets.action->clear();
|
||||
for (const Profile::Action& a : _actionData) {
|
||||
_keybindingWidgets.action->addItem(QString::fromStdString(a.identifier));
|
||||
}
|
||||
clearKeybindingFields();
|
||||
clearActionFields();
|
||||
}
|
||||
|
||||
@@ -648,9 +661,9 @@ void ActionDialog::keybindingRemove() {
|
||||
if (_keybindingsData[i].key == keybinding->key &&
|
||||
_keybindingsData[i].action == keybinding->action)
|
||||
{
|
||||
clearKeybindingFields();
|
||||
_keybindingsData.erase(_keybindingsData.begin() + i);
|
||||
delete _keybindingWidgets.list->takeItem(static_cast<int>(i));
|
||||
clearKeybindingFields();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,7 +102,10 @@ void AdditionalScriptsDialog::parseScript() {
|
||||
|
||||
void AdditionalScriptsDialog::chooseScripts() {
|
||||
ScriptlogDialog d(this);
|
||||
connect(&d, &ScriptlogDialog::scriptsSelected, this, &AdditionalScriptsDialog::appendScriptsToTextfield);
|
||||
connect(
|
||||
&d, &ScriptlogDialog::scriptsSelected,
|
||||
this, &AdditionalScriptsDialog::appendScriptsToTextfield
|
||||
);
|
||||
d.exec();
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
|
||||
AssetEdit::AssetEdit(QWidget* parent)
|
||||
: QDialog(parent)
|
||||
@@ -46,18 +48,15 @@ AssetEdit::AssetEdit(QWidget* parent)
|
||||
void AssetEdit::createWidgets() {
|
||||
_layout = new QVBoxLayout(this);
|
||||
{
|
||||
QLabel* heading =
|
||||
new QLabel("The Asset Editor is coming soon in a future release", this);
|
||||
QLabel* heading = new QLabel("The Asset Editor is coming in a future release");
|
||||
heading->setObjectName("heading");
|
||||
_layout->addWidget(heading);
|
||||
}
|
||||
{
|
||||
QPushButton* generateButton = new QPushButton("Generate Horizons File", this);
|
||||
QPushButton* generateButton = new QPushButton("Generate Horizons File");
|
||||
connect(
|
||||
generateButton,
|
||||
&QPushButton::released,
|
||||
this,
|
||||
&AssetEdit::openHorizons
|
||||
generateButton, &QPushButton::released,
|
||||
this, &AssetEdit::openHorizons
|
||||
);
|
||||
generateButton->setDefault(false);
|
||||
|
||||
@@ -73,32 +72,32 @@ void AssetEdit::createWidgets() {
|
||||
|
||||
_layout->addWidget(generateButton);
|
||||
}
|
||||
/*{
|
||||
QBoxLayout* container = new QHBoxLayout(this);
|
||||
QLabel* assetLabel = new QLabel("Asset Name:");
|
||||
assetLabel->setObjectName("profile");
|
||||
container->addWidget(assetLabel);
|
||||
//{
|
||||
// QBoxLayout* container = new QHBoxLayout(this);
|
||||
// QLabel* assetLabel = new QLabel("Asset Name:");
|
||||
// assetLabel->setObjectName("profile");
|
||||
// container->addWidget(assetLabel);
|
||||
|
||||
_nameEdit = new QLineEdit();
|
||||
container->addWidget(_nameEdit);
|
||||
// _nameEdit = new QLineEdit();
|
||||
// container->addWidget(_nameEdit);
|
||||
|
||||
_layout->addLayout(container);
|
||||
}
|
||||
_layout->addWidget(new Line);
|
||||
{
|
||||
QBoxLayout* container = new QHBoxLayout(this);
|
||||
_components = new QComboBox(this);
|
||||
_components->addItems(_supportedComponents);
|
||||
_components->setCurrentIndex(0);
|
||||
container->addWidget(_components);
|
||||
// _layout->addLayout(container);
|
||||
//}
|
||||
//_layout->addWidget(new Line);
|
||||
//{
|
||||
// QBoxLayout* container = new QHBoxLayout(this);
|
||||
// _components = new QComboBox(this);
|
||||
// _components->addItems(_supportedComponents);
|
||||
// _components->setCurrentIndex(0);
|
||||
// container->addWidget(_components);
|
||||
|
||||
QPushButton* addButton = new QPushButton("Add", this);
|
||||
connect(addButton, &QPushButton::clicked, this, &AssetEdit::openComponent);
|
||||
addButton->setCursor(Qt::PointingHandCursor);
|
||||
container->addWidget(addButton);
|
||||
// QPushButton* addButton = new QPushButton("Add", this);
|
||||
// connect(addButton, &QPushButton::clicked, this, &AssetEdit::openComponent);
|
||||
// addButton->setCursor(Qt::PointingHandCursor);
|
||||
// container->addWidget(addButton);
|
||||
|
||||
_layout->addLayout(container);
|
||||
}*/
|
||||
// _layout->addLayout(container);
|
||||
//}
|
||||
_layout->addWidget(new Line);
|
||||
{
|
||||
QBoxLayout* footer = new QHBoxLayout;
|
||||
@@ -116,77 +115,77 @@ void AssetEdit::createWidgets() {
|
||||
}
|
||||
}
|
||||
|
||||
/*void AssetEdit::openComponent() {
|
||||
switch (_components->currentIndex()) {
|
||||
case 0:
|
||||
_errorMsg->setText("Choose a component to add to the asset");
|
||||
break;
|
||||
case 1: {
|
||||
QBoxLayout* horizonsLayout = new QVBoxLayout(this);
|
||||
{
|
||||
QLabel* label = new QLabel("Horizons Translation:", this);
|
||||
label->setObjectName("heading");
|
||||
horizonsLayout->addWidget(label);
|
||||
}
|
||||
{
|
||||
QBoxLayout* container = new QHBoxLayout(this);
|
||||
QLabel* fileLabel = new QLabel("File path:", this);
|
||||
container->addWidget(fileLabel);
|
||||
|
||||
_horizonsFileEdit = new QLineEdit(this);
|
||||
container->addWidget(_horizonsFileEdit);
|
||||
|
||||
QPushButton* fileButton = new QPushButton("Browse", this);
|
||||
connect(
|
||||
fileButton,
|
||||
&QPushButton::released,
|
||||
this,
|
||||
&AssetEdit::openHorizonsFile
|
||||
);
|
||||
fileButton->setCursor(Qt::PointingHandCursor);
|
||||
container->addWidget(fileButton);
|
||||
|
||||
QPushButton* generateButton = new QPushButton("Generate", this);
|
||||
connect(
|
||||
generateButton,
|
||||
&QPushButton::released,
|
||||
this,
|
||||
&AssetEdit::openHorizons
|
||||
);
|
||||
|
||||
// In order to generate a Horizons File the Space module is required
|
||||
#ifndef OPENSPACE_MODULE_SPACE_ENABLED
|
||||
generateButton->setEnabled(false);
|
||||
generateButton->setToolTip(
|
||||
"Connot generate Horizons file without the space module enabled"
|
||||
);
|
||||
#else
|
||||
generateButton->setCursor(Qt::PointingHandCursor);
|
||||
#endif // OPENSPACE_MODULE_SPACE_ENABLED
|
||||
|
||||
container->addWidget(generateButton);
|
||||
horizonsLayout->addLayout(container);
|
||||
}
|
||||
horizonsLayout->addWidget(new Line);
|
||||
_layout->insertLayout(_layout->count() - 3, horizonsLayout);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
_errorMsg->setText("Unkown component");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void AssetEdit::openHorizonsFile() {
|
||||
std::string filePath = QFileDialog::getOpenFileName(
|
||||
this,
|
||||
tr("Open Horizons file"),
|
||||
"",
|
||||
tr("Horiozons file (*.dat)")
|
||||
).toStdString();
|
||||
_horizonsFile = std::filesystem::absolute(filePath);
|
||||
_horizonsFileEdit->setText(QString(_horizonsFile.string().c_str()));
|
||||
}*/
|
||||
//void AssetEdit::openComponent() {
|
||||
// switch (_components->currentIndex()) {
|
||||
// case 0:
|
||||
// _errorMsg->setText("Choose a component to add to the asset");
|
||||
// break;
|
||||
// case 1: {
|
||||
// QBoxLayout* horizonsLayout = new QVBoxLayout(this);
|
||||
// {
|
||||
// QLabel* label = new QLabel("Horizons Translation:", this);
|
||||
// label->setObjectName("heading");
|
||||
// horizonsLayout->addWidget(label);
|
||||
// }
|
||||
// {
|
||||
// QBoxLayout* container = new QHBoxLayout(this);
|
||||
// QLabel* fileLabel = new QLabel("File path:", this);
|
||||
// container->addWidget(fileLabel);
|
||||
//
|
||||
// _horizonsFileEdit = new QLineEdit(this);
|
||||
// container->addWidget(_horizonsFileEdit);
|
||||
//
|
||||
// QPushButton* fileButton = new QPushButton("Browse", this);
|
||||
// connect(
|
||||
// fileButton,
|
||||
// &QPushButton::released,
|
||||
// this,
|
||||
// &AssetEdit::openHorizonsFile
|
||||
// );
|
||||
// fileButton->setCursor(Qt::PointingHandCursor);
|
||||
// container->addWidget(fileButton);
|
||||
//
|
||||
// QPushButton* generateButton = new QPushButton("Generate", this);
|
||||
// connect(
|
||||
// generateButton,
|
||||
// &QPushButton::released,
|
||||
// this,
|
||||
// &AssetEdit::openHorizons
|
||||
// );
|
||||
//
|
||||
// // In order to generate a Horizons File the Space module is required
|
||||
// #ifndef OPENSPACE_MODULE_SPACE_ENABLED
|
||||
// generateButton->setEnabled(false);
|
||||
// generateButton->setToolTip(
|
||||
// "Connot generate Horizons file without the space module enabled"
|
||||
// );
|
||||
// #else
|
||||
// generateButton->setCursor(Qt::PointingHandCursor);
|
||||
// #endif // OPENSPACE_MODULE_SPACE_ENABLED
|
||||
//
|
||||
// container->addWidget(generateButton);
|
||||
// horizonsLayout->addLayout(container);
|
||||
// }
|
||||
// horizonsLayout->addWidget(new Line);
|
||||
// _layout->insertLayout(_layout->count() - 3, horizonsLayout);
|
||||
// break;
|
||||
// }
|
||||
// default:
|
||||
// _errorMsg->setText("Unkown component");
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void AssetEdit::openHorizonsFile() {
|
||||
// std::string filePath = QFileDialog::getOpenFileName(
|
||||
// this,
|
||||
// tr("Open Horizons file"),
|
||||
// "",
|
||||
// tr("Horiozons file (*.dat)")
|
||||
// ).toStdString();
|
||||
// _horizonsFile = std::filesystem::absolute(filePath);
|
||||
// _horizonsFileEdit->setText(QString(_horizonsFile.string().c_str()));
|
||||
//}
|
||||
|
||||
void AssetEdit::openHorizons() {
|
||||
_errorMsg->clear();
|
||||
@@ -199,10 +198,10 @@ void AssetEdit::openHorizons() {
|
||||
}
|
||||
|
||||
void AssetEdit::approved() {
|
||||
/*std::string assetName = _nameEdit->text().toStdString();
|
||||
if (assetName.empty()) {
|
||||
_errorMsg->setText("Asset name must be specified");
|
||||
return;
|
||||
}*/
|
||||
// std::string assetName = _nameEdit->text().toStdString();
|
||||
// if (assetName.empty()) {
|
||||
// _errorMsg->setText("Asset name must be specified");
|
||||
// return;
|
||||
// }
|
||||
accept();
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include "profile/assetsdialog.h"
|
||||
|
||||
#include "profile/assetedit.h"
|
||||
|
||||
#include "profile/line.h"
|
||||
#include <openspace/scene/profile.h>
|
||||
#include <ghoul/fmt.h>
|
||||
@@ -38,8 +37,8 @@
|
||||
#include <QTreeView>
|
||||
|
||||
namespace {
|
||||
bool traverseToExpandSelectedItems(QTreeView& tree, AssetTreeModel& model,
|
||||
int rows, QModelIndex parent)
|
||||
bool traverseToExpandSelectedItems(QTreeView& tree, AssetTreeModel& model, int rows,
|
||||
QModelIndex parent)
|
||||
{
|
||||
bool isExpanded = false;
|
||||
|
||||
@@ -144,7 +143,7 @@ AssetsDialog::AssetsDialog(QWidget* parent, openspace::Profile* profile,
|
||||
heading->setObjectName("heading");
|
||||
container->addWidget(heading, 0, 0);
|
||||
|
||||
QPushButton* newAssetButton = new QPushButton("New Asset", this);
|
||||
QPushButton* newAssetButton = new QPushButton("New Asset");
|
||||
connect(
|
||||
newAssetButton, &QPushButton::released,
|
||||
this, &AssetsDialog::openAssetEditor
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
|
||||
#include "profile/assettreeitem.h"
|
||||
|
||||
AssetTreeItem::AssetTreeItem(const std::vector<QVariant>& data, AssetTreeItem* parentItem)
|
||||
: _itemData(data)
|
||||
AssetTreeItem::AssetTreeItem(std::vector<QVariant> data, AssetTreeItem* parentItem)
|
||||
: _itemData(std::move(data))
|
||||
, _parentItem(parentItem)
|
||||
{}
|
||||
|
||||
@@ -35,12 +35,12 @@ AssetTreeItem::~AssetTreeItem() {
|
||||
}
|
||||
}
|
||||
|
||||
AssetTreeItem* AssetTreeItem::child(int row) {
|
||||
if (row < 0 || row >= static_cast<int>(_childItems.size())) {
|
||||
return nullptr;
|
||||
AssetTreeItem* AssetTreeItem::child(int row) const {
|
||||
if (row >= 0 && row < static_cast<int>(_childItems.size())) {
|
||||
return _childItems.at(row);
|
||||
}
|
||||
else {
|
||||
return _childItems.at(row);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,11 +67,11 @@ int AssetTreeItem::columnCount() const {
|
||||
}
|
||||
|
||||
QVariant AssetTreeItem::data(int column) const {
|
||||
if (column < 0 || column >= static_cast<int>(_itemData.size())) {
|
||||
return QVariant();
|
||||
if (column >= 0 && column < static_cast<int>(_itemData.size())) {
|
||||
return _itemData.at(column);
|
||||
}
|
||||
else {
|
||||
return _itemData.at(column);
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,11 +96,11 @@ void AssetTreeItem::setChecked(bool set) {
|
||||
}
|
||||
|
||||
bool AssetTreeItem::isAsset() const {
|
||||
return (childCount() == 0);
|
||||
return childCount() == 0;
|
||||
}
|
||||
|
||||
bool AssetTreeItem::isCategory() const {
|
||||
return (childCount() > 0);
|
||||
return childCount() > 0;
|
||||
}
|
||||
|
||||
void AssetTreeItem::setExistsInFilesystem(bool fileExists) {
|
||||
|
||||
@@ -139,8 +139,9 @@ AssetTreeModel::AssetTreeModel(QObject* parent)
|
||||
: QAbstractItemModel(parent)
|
||||
{
|
||||
_rootItem = std::make_unique<AssetTreeItem>(
|
||||
std::vector<QVariant>{
|
||||
QString::fromStdString(Header1), QString::fromStdString(Header2)
|
||||
std::vector<QVariant> {
|
||||
QString::fromStdString(Header1),
|
||||
QString::fromStdString(Header2)
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -162,7 +163,7 @@ void AssetTreeModel::importModelData(const std::string& assetBasePath,
|
||||
}
|
||||
}
|
||||
|
||||
AssetTreeItem* AssetTreeModel::getItem(const QModelIndex& index) const {
|
||||
AssetTreeItem* AssetTreeModel::item(const QModelIndex& index) const {
|
||||
if (index.isValid()) {
|
||||
AssetTreeItem* item = static_cast<AssetTreeItem*>(index.internalPointer());
|
||||
if (item) {
|
||||
@@ -173,46 +174,46 @@ AssetTreeItem* AssetTreeModel::getItem(const QModelIndex& index) const {
|
||||
}
|
||||
|
||||
bool AssetTreeModel::isChecked(QModelIndex& index) const {
|
||||
AssetTreeItem* item = getItem(index);
|
||||
const int isChecked = item->data(1).toInt();
|
||||
AssetTreeItem* i = item(index);
|
||||
const int isChecked = i->data(1).toInt();
|
||||
return isChecked == Qt::Checked;
|
||||
}
|
||||
|
||||
bool AssetTreeModel::isAsset(QModelIndex& index) const {
|
||||
AssetTreeItem* item = getItem(index);
|
||||
return item->isAsset();
|
||||
AssetTreeItem* i = item(index);
|
||||
return i->isAsset();
|
||||
}
|
||||
|
||||
bool AssetTreeModel::inFilesystem(QModelIndex& index) const {
|
||||
AssetTreeItem* item = getItem(index);
|
||||
return item->doesExistInFilesystem();
|
||||
AssetTreeItem* i = item(index);
|
||||
return i->doesExistInFilesystem();
|
||||
}
|
||||
|
||||
int AssetTreeModel::childCount(QModelIndex& index) const {
|
||||
return getItem(index)->childCount();
|
||||
return item(index)->childCount();
|
||||
}
|
||||
|
||||
QString AssetTreeModel::name(QModelIndex& index) const {
|
||||
return getItem(index)->name();
|
||||
return item(index)->name();
|
||||
}
|
||||
|
||||
void AssetTreeModel::setName(QModelIndex& index, QString name) {
|
||||
getItem(index)->setData(0, name);
|
||||
item(index)->setData(0, name);
|
||||
}
|
||||
|
||||
void AssetTreeModel::setChecked(QModelIndex& index, bool checked) {
|
||||
getItem(index)->setData(1, checked ? Qt::Checked : Qt::Unchecked);
|
||||
item(index)->setData(1, checked ? Qt::Checked : Qt::Unchecked);
|
||||
}
|
||||
|
||||
void AssetTreeModel::setExistenceInFilesystem(QModelIndex& index, bool fileExists) {
|
||||
getItem(index)->setExistsInFilesystem(fileExists);
|
||||
item(index)->setExistsInFilesystem(fileExists);
|
||||
}
|
||||
|
||||
AssetTreeItem* AssetTreeModel::child(int row) const {
|
||||
QModelIndex i = index(row, 0);
|
||||
int nKids = childCount(i);
|
||||
if (row < nKids) {
|
||||
return getItem(i)->child(row);
|
||||
const int nChildren = childCount(i);
|
||||
if (row < nChildren) {
|
||||
return item(i)->child(row);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -224,7 +225,7 @@ QModelIndex AssetTreeModel::index(int row, int column, const QModelIndex& parent
|
||||
if (!hasIndex(row, column, parent)) {
|
||||
return QModelIndex();
|
||||
}
|
||||
AssetTreeItem* parentItem = getItem(parent);
|
||||
AssetTreeItem* parentItem = item(parent);
|
||||
if (!parentItem) {
|
||||
return QModelIndex();
|
||||
}
|
||||
@@ -250,7 +251,7 @@ QModelIndex AssetTreeModel::parent(const QModelIndex& index) const {
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
AssetTreeItem* childItem = getItem(index);
|
||||
AssetTreeItem* childItem = item(index);
|
||||
AssetTreeItem* parentItem = childItem ? childItem->parent() : nullptr;
|
||||
if (parentItem == _rootItem.get() || !parentItem) {
|
||||
return QModelIndex();
|
||||
@@ -260,11 +261,11 @@ QModelIndex AssetTreeModel::parent(const QModelIndex& index) const {
|
||||
}
|
||||
|
||||
AssetTreeItem* AssetTreeModel::assetItem(const QModelIndex& index) {
|
||||
return getItem(index);
|
||||
return item(index);
|
||||
}
|
||||
|
||||
int AssetTreeModel::rowCount(const QModelIndex& parent) const {
|
||||
const AssetTreeItem* parentItem = getItem(parent);
|
||||
const AssetTreeItem* parentItem = item(parent);
|
||||
return parentItem ? parentItem->childCount() : 0;
|
||||
}
|
||||
|
||||
@@ -289,12 +290,7 @@ QVariant AssetTreeModel::data(const QModelIndex& index, int role) const {
|
||||
}
|
||||
|
||||
if (role == Qt::ForegroundRole) {
|
||||
if (item->doesExistInFilesystem()) {
|
||||
return QVariant(QColor(Qt::black));
|
||||
}
|
||||
else {
|
||||
return QVariant(QColor(Qt::red));
|
||||
}
|
||||
return item->doesExistInFilesystem() ? QColor(Qt::black) : QColor(Qt::red);
|
||||
}
|
||||
else if (role == Qt::DisplayRole) {
|
||||
return item->data(index.column());
|
||||
@@ -345,7 +341,7 @@ QVariant AssetTreeModel::headerData(int section, Qt::Orientation orientation,
|
||||
}
|
||||
|
||||
void AssetTreeModel::getSelectedAssets(std::vector<std::string>& outputPaths,
|
||||
std::vector<AssetTreeItem*>& outputItems)
|
||||
std::vector<AssetTreeItem*>& outputItems)
|
||||
{
|
||||
parseChildrenForSelected(_rootItem.get(), outputPaths, outputItems, "");
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace {
|
||||
constexpr const int CameraTypeGeo = 1;
|
||||
|
||||
template <class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
|
||||
template <class... Ts> overloaded(Ts...)->overloaded<Ts...>;
|
||||
template <class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
|
||||
|
||||
bool inNumericalRange(QLineEdit* le, float min, float max) {
|
||||
QString s = le->text();
|
||||
|
||||
@@ -41,14 +41,14 @@
|
||||
#include <iostream>
|
||||
|
||||
namespace {
|
||||
constexpr const int MaxNumberOfKeys = 30;
|
||||
constexpr int MaxNumberOfKeys = 30;
|
||||
|
||||
struct TimeInterval {
|
||||
uint64_t secondsPerInterval;
|
||||
std::string intervalName;
|
||||
};
|
||||
|
||||
std::array<TimeInterval, 7> TimeIntervals = {
|
||||
const std::array<TimeInterval, 7> TimeIntervals = {
|
||||
TimeInterval{ 31536000, "year" },
|
||||
TimeInterval{ 18144000, "month" },
|
||||
TimeInterval{ 604800, "week" },
|
||||
@@ -98,17 +98,16 @@ DeltaTimesDialog::DeltaTimesDialog(QWidget* parent, std::vector<double>* deltaTi
|
||||
|
||||
void DeltaTimesDialog::createWidgets() {
|
||||
QBoxLayout* layout = new QVBoxLayout(this);
|
||||
{
|
||||
_listWidget = new QListWidget;
|
||||
connect(
|
||||
_listWidget, &QListWidget::itemSelectionChanged,
|
||||
this, &DeltaTimesDialog::listItemSelected
|
||||
);
|
||||
_listWidget->setAutoScroll(true);
|
||||
_listWidget->setLayoutMode(QListView::SinglePass);
|
||||
layout->addWidget(_listWidget);
|
||||
}
|
||||
|
||||
_listWidget = new QListWidget;
|
||||
connect(
|
||||
_listWidget, &QListWidget::itemSelectionChanged,
|
||||
this, &DeltaTimesDialog::listItemSelected
|
||||
);
|
||||
_listWidget->setAutoScroll(true);
|
||||
_listWidget->setLayoutMode(QListView::SinglePass);
|
||||
layout->addWidget(_listWidget);
|
||||
|
||||
{
|
||||
QBoxLayout* buttonLayout = new QHBoxLayout;
|
||||
_addButton = new QPushButton("Add Entry");
|
||||
@@ -128,10 +127,10 @@ void DeltaTimesDialog::createWidgets() {
|
||||
buttonLayout->addStretch();
|
||||
layout->addLayout(buttonLayout);
|
||||
}
|
||||
{
|
||||
_adjustLabel = new QLabel("Set Simulation Time Increment for key");
|
||||
layout->addWidget(_adjustLabel);
|
||||
}
|
||||
|
||||
_adjustLabel = new QLabel("Set Simulation Time Increment for key");
|
||||
layout->addWidget(_adjustLabel);
|
||||
|
||||
{
|
||||
QBoxLayout* box = new QHBoxLayout;
|
||||
_seconds = new QLineEdit;
|
||||
@@ -184,7 +183,7 @@ void DeltaTimesDialog::createWidgets() {
|
||||
}
|
||||
|
||||
std::string DeltaTimesDialog::createSummaryForDeltaTime(size_t idx, bool forListView) {
|
||||
int k = (idx%10 == 9) ? 0 : idx%10 + 1;
|
||||
int k = (idx % 10 == 9) ? 0 : idx % 10 + 1;
|
||||
k = (idx == 0) ? 1 : k;
|
||||
std::string key = std::to_string(k);
|
||||
|
||||
@@ -204,9 +203,7 @@ std::string DeltaTimesDialog::createSummaryForDeltaTime(size_t idx, bool forList
|
||||
|
||||
if (forListView) {
|
||||
s += fmt::format(
|
||||
"\t{}\t{}",
|
||||
std::to_string(_deltaTimesData.at(idx)),
|
||||
timeDescription(_deltaTimesData.at(idx))
|
||||
"\t{}\t{}", _deltaTimesData.at(idx), timeDescription(_deltaTimesData.at(idx))
|
||||
);
|
||||
}
|
||||
return s;
|
||||
@@ -252,9 +249,7 @@ void DeltaTimesDialog::valueChanged(const QString& text) {
|
||||
else {
|
||||
int value = text.toDouble();
|
||||
if (value != 0) {
|
||||
_value->setText(QString::fromStdString(
|
||||
timeDescription(text.toDouble()))
|
||||
);
|
||||
_value->setText(QString::fromStdString(timeDescription(text.toDouble())));
|
||||
_errorMsg->setText("");
|
||||
}
|
||||
}
|
||||
@@ -296,15 +291,13 @@ void DeltaTimesDialog::addDeltaTimeValue() {
|
||||
|
||||
void DeltaTimesDialog::saveDeltaTimeValue() {
|
||||
QListWidgetItem* item = _listWidget->currentItem();
|
||||
if (item != nullptr) {
|
||||
if (item && !_deltaTimesData.empty()) {
|
||||
int index = _listWidget->row(item);
|
||||
if (_deltaTimesData.size() > 0) {
|
||||
_deltaTimesData.at(index) = _seconds->text().toDouble();
|
||||
std::string summary = createSummaryForDeltaTime(index, true);
|
||||
_listWidget->item(index)->setText(QString::fromStdString(summary));
|
||||
transitionEditMode(index, false);
|
||||
_editModeNewItem = false;
|
||||
}
|
||||
_deltaTimesData.at(index) = _seconds->text().toDouble();
|
||||
std::string summary = createSummaryForDeltaTime(index, true);
|
||||
_listWidget->item(index)->setText(QString::fromStdString(summary));
|
||||
transitionEditMode(index, false);
|
||||
_editModeNewItem = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,29 +28,37 @@
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/fmt.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/boolean.h>
|
||||
#include <QComboBox>
|
||||
#include <QDateTimeEdit>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QDir>
|
||||
#include <QEventLoop>
|
||||
#include <QFileDialog>
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QMessageBox>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkRequest>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QProgressBar>
|
||||
#include <QPushButton>
|
||||
#include <QScrollBar>
|
||||
#include <QVBoxLayout>
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <QStyle>
|
||||
#include <sstream>
|
||||
|
||||
using json = nlohmann::json;
|
||||
using namespace openspace;
|
||||
|
||||
namespace {
|
||||
BooleanType(IsDirty);
|
||||
void styleLabel(QLabel* label, IsDirty isDirty) {
|
||||
std::string newStyle = isDirty ? "error" : "normal";
|
||||
label->setObjectName(QString::fromStdString(newStyle));
|
||||
label->style()->unpolish(label);
|
||||
label->style()->polish(label);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
constexpr std::string_view _loggerCat = "HorizonsDialog";
|
||||
@@ -85,20 +93,23 @@ HorizonsDialog::HorizonsDialog(QWidget* parent)
|
||||
#endif // OPENSPACE_MODULE_SPACE_ENABLED
|
||||
}
|
||||
|
||||
#ifdef OPENSPACE_MODULE_SPACE_ENABLED
|
||||
std::filesystem::path HorizonsDialog::file() const {
|
||||
#ifdef OPENSPACE_MODULE_SPACE_ENABLED
|
||||
return _horizonsFile.file();
|
||||
}
|
||||
#else // OPENSPACE_MODULE_SPACE_ENABLED
|
||||
return std::filesystem::path();
|
||||
#endif // OPENSPACE_MODULE_SPACE_ENABLED
|
||||
}
|
||||
|
||||
void HorizonsDialog::openSaveAs() {
|
||||
QString filename = QFileDialog::getSaveFileName(
|
||||
this,
|
||||
"Choose a file path where the generated Horizons file will be saved",
|
||||
QString::fromStdString(absPath("${USER}").string()),
|
||||
"Horizons data file (*.hrz);;(*.hrz)",
|
||||
"Horizons data file (*.hrz)",
|
||||
nullptr
|
||||
#ifdef __linux__
|
||||
// Linux in Qt5 and Qt6 crashes when trying to access the native dialog here
|
||||
, QFileDialog::DontUseNativeDialog
|
||||
#endif
|
||||
);
|
||||
@@ -116,49 +127,34 @@ void HorizonsDialog::typeOnChange(int index) {
|
||||
}
|
||||
else {
|
||||
_errorMsg->setText("Invalid Horizons type");
|
||||
styleLabel(_typeLabel, true);
|
||||
styleLabel(_typeLabel, IsDirty::Yes);
|
||||
}
|
||||
}
|
||||
|
||||
void HorizonsDialog::downloadProgress(qint64 value, qint64 total) {
|
||||
void HorizonsDialog::downloadProgress(int value, int total) {
|
||||
if (total < 0) {
|
||||
_downloadProgress->setRange(0, 0);
|
||||
return;
|
||||
}
|
||||
_downloadProgress->setRange(0, total);
|
||||
_downloadProgress->setValue(value);
|
||||
else {
|
||||
_downloadProgress->setRange(0, total);
|
||||
_downloadProgress->setValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
void HorizonsDialog::importTimeRange() {
|
||||
QDateTime start, end;
|
||||
start = QDateTime::fromString(
|
||||
QString::fromStdString(_validTimeRange.first),
|
||||
"yyyy-MMM-dd T hh:mm"
|
||||
);
|
||||
end = QDateTime::fromString(
|
||||
QString::fromStdString(_validTimeRange.second),
|
||||
"yyyy-MMM-dd T hh:mm"
|
||||
);
|
||||
QString startStr = QString::fromStdString(_validTimeRange.first);
|
||||
QString endStr = QString::fromStdString(_validTimeRange.second);
|
||||
|
||||
QDateTime start = QDateTime::fromString(startStr, "yyyy-MMM-dd T hh:mm");
|
||||
QDateTime end = QDateTime::fromString(endStr, "yyyy-MMM-dd T hh:mm");
|
||||
|
||||
if (!start.isValid() || !end.isValid()) {
|
||||
start = QDateTime::fromString(
|
||||
QString::fromStdString(_validTimeRange.first),
|
||||
"yyyy-MMM-dd T hh:mm:ss"
|
||||
);
|
||||
end = QDateTime::fromString(
|
||||
QString::fromStdString(_validTimeRange.second),
|
||||
"yyyy-MMM-dd T hh:mm:ss"
|
||||
);
|
||||
start = QDateTime::fromString(startStr, "yyyy-MMM-dd T hh:mm:ss");
|
||||
end = QDateTime::fromString(endStr, "yyyy-MMM-dd T hh:mm:ss");
|
||||
|
||||
if (!start.isValid() || !end.isValid()) {
|
||||
QDate startDate = QDate::fromString(
|
||||
QString::fromStdString(_validTimeRange.first),
|
||||
"yyyy-MMM-dd"
|
||||
);
|
||||
QDate endDate = QDate::fromString(
|
||||
QString::fromStdString(_validTimeRange.second),
|
||||
"yyyy-MMM-dd"
|
||||
);
|
||||
QDate startDate = QDate::fromString(startStr, "yyyy-MMM-dd");
|
||||
QDate endDate = QDate::fromString(endStr, "yyyy-MMM-dd");
|
||||
|
||||
if (startDate.isValid() && endDate.isValid()) {
|
||||
_startEdit->setDate(startDate);
|
||||
@@ -170,8 +166,8 @@ void HorizonsDialog::importTimeRange() {
|
||||
|
||||
_errorMsg->setText("Could not import time range");
|
||||
std::string msg = fmt::format(
|
||||
"Could not import time range '{}' to '{}'", _validTimeRange.first,
|
||||
_validTimeRange.second
|
||||
"Could not import time range '{}' to '{}'",
|
||||
_validTimeRange.first, _validTimeRange.second
|
||||
);
|
||||
appendLog(msg, LogLevel::Error);
|
||||
return;
|
||||
@@ -183,17 +179,17 @@ void HorizonsDialog::importTimeRange() {
|
||||
_validTimeRange = std::pair<std::string, std::string>();
|
||||
}
|
||||
|
||||
#ifdef OPENSPACE_MODULE_SPACE_ENABLED
|
||||
// When the user presses the 'Save' button
|
||||
void HorizonsDialog::approved() {
|
||||
#ifdef OPENSPACE_MODULE_SPACE_ENABLED
|
||||
_downloadLabel->show();
|
||||
bool result = handleRequest();
|
||||
_downloadLabel->hide();
|
||||
if (result && std::filesystem::is_regular_file(_horizonsFile.file())) {
|
||||
accept();
|
||||
}
|
||||
}
|
||||
#endif // OPENSPACE_MODULE_SPACE_ENABLED
|
||||
}
|
||||
|
||||
void HorizonsDialog::createWidgets() {
|
||||
QGridLayout* layout = new QGridLayout(this);
|
||||
@@ -203,10 +199,10 @@ void HorizonsDialog::createWidgets() {
|
||||
generateLabel->setObjectName("heading");
|
||||
layout->addWidget(generateLabel, 0, 0, 1, 3);
|
||||
|
||||
QLabel* infoLabel = new QLabel("<p>For more information about the Horizons "
|
||||
"system please visit: <a href=\"https://ssd.jpl.nasa.gov/horizons/\">"
|
||||
"https://ssd.jpl.nasa.gov/horizons/</a></p>",
|
||||
this
|
||||
QLabel* infoLabel = new QLabel(
|
||||
"<p>For more information about the Horizons system please visit: "
|
||||
"<a href=\"https://ssd.jpl.nasa.gov/horizons/\">"
|
||||
"https://ssd.jpl.nasa.gov/horizons/</a></p>"
|
||||
);
|
||||
infoLabel->setWordWrap(true);
|
||||
infoLabel->setObjectName("thin");
|
||||
@@ -214,11 +210,11 @@ void HorizonsDialog::createWidgets() {
|
||||
layout->addWidget(infoLabel, 1, 0, 1, 3);
|
||||
}
|
||||
{
|
||||
_typeLabel = new QLabel("Horizons data type:", this);
|
||||
_typeLabel = new QLabel("Horizons data type:");
|
||||
_typeLabel->setToolTip("Choose Horizons data type");
|
||||
layout->addWidget(_typeLabel, 2, 0, 1, 2);
|
||||
|
||||
_typeCombo = new QComboBox(this);
|
||||
_typeCombo = new QComboBox;
|
||||
_typeCombo->setToolTip("Choose Horizons data type");
|
||||
QStringList types = {
|
||||
"Vector table",
|
||||
@@ -226,24 +222,26 @@ void HorizonsDialog::createWidgets() {
|
||||
};
|
||||
_typeCombo->addItems(types);
|
||||
_typeCombo->setCurrentIndex(0);
|
||||
connect(_typeCombo, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
connect(
|
||||
_typeCombo, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, &HorizonsDialog::typeOnChange
|
||||
);
|
||||
layout->addWidget(_typeCombo, 2, 2);
|
||||
}
|
||||
{
|
||||
_fileLabel = new QLabel("File Path:", this);
|
||||
_fileLabel = new QLabel("File Path:");
|
||||
_fileLabel->setToolTip("Where the generated Horizons file is saved");
|
||||
layout->addWidget(_fileLabel, 3, 0);
|
||||
|
||||
QBoxLayout* container = new QHBoxLayout(this);
|
||||
QBoxLayout* container = new QHBoxLayout;
|
||||
_fileEdit = new QLineEdit(this);
|
||||
_fileEdit->setToolTip("Where the generated Horizons file is saved");
|
||||
container->addWidget(_fileEdit);
|
||||
|
||||
QPushButton* browseButton = new QPushButton("Browse", this);
|
||||
QPushButton* browseButton = new QPushButton("Browse");
|
||||
browseButton->setDefault(false);
|
||||
connect(browseButton, &QPushButton::released, this,
|
||||
connect(
|
||||
browseButton, &QPushButton::released, this,
|
||||
&HorizonsDialog::openSaveAs
|
||||
);
|
||||
browseButton->setCursor(Qt::PointingHandCursor);
|
||||
@@ -255,20 +253,19 @@ void HorizonsDialog::createWidgets() {
|
||||
layout->addLayout(container, 3, 1, 1, 2);
|
||||
}
|
||||
{
|
||||
_targetLabel = new QLabel("Target Body:", this);
|
||||
_targetLabel = new QLabel("Target Body:");
|
||||
_targetLabel->setToolTip(
|
||||
"Which target or body would you like Horizons trajectery data for?"
|
||||
);
|
||||
layout->addWidget(_targetLabel, 4, 0);
|
||||
|
||||
_targetEdit =
|
||||
new QLineEdit("Tesla", this);
|
||||
_targetEdit = new QLineEdit("Tesla");
|
||||
_targetEdit->setToolTip(
|
||||
"Which target or body would you like Horizons trajectery data for?"
|
||||
);
|
||||
layout->addWidget(_targetEdit, 4, 1, 1, 2);
|
||||
|
||||
_chooseTargetCombo = new QComboBox(this);
|
||||
_chooseTargetCombo = new QComboBox;
|
||||
_chooseTargetCombo->setObjectName("mono");
|
||||
_chooseTargetCombo->hide();
|
||||
_chooseTargetCombo->setToolTip(
|
||||
@@ -277,15 +274,15 @@ void HorizonsDialog::createWidgets() {
|
||||
layout->addWidget(_chooseTargetCombo, 5, 1, 1, 2);
|
||||
}
|
||||
{
|
||||
_centerLabel = new QLabel("Observer Location:", this);
|
||||
_centerLabel = new QLabel("Observer Location:");
|
||||
_centerLabel->setToolTip("In which reference frame do you want the data in?");
|
||||
layout->addWidget(_centerLabel, 6, 0);
|
||||
|
||||
_centerEdit = new QLineEdit(QString::fromStdString("@ssb"), this);
|
||||
_centerEdit = new QLineEdit(QString::fromStdString("@ssb"));
|
||||
_centerEdit->setToolTip("In which reference frame do you want the data in?");
|
||||
layout->addWidget(_centerEdit, 6, 1, 1, 2);
|
||||
|
||||
_chooseObserverCombo = new QComboBox(this);
|
||||
_chooseObserverCombo = new QComboBox;
|
||||
_chooseObserverCombo->setObjectName("mono");
|
||||
_chooseObserverCombo->hide();
|
||||
_chooseObserverCombo->setToolTip(
|
||||
@@ -294,17 +291,17 @@ void HorizonsDialog::createWidgets() {
|
||||
layout->addWidget(_chooseObserverCombo, 7, 1, 1, 2);
|
||||
}
|
||||
{
|
||||
_startLabel = new QLabel("Start Time:", this);
|
||||
_startLabel = new QLabel("Start Time:");
|
||||
_startLabel->setToolTip("Enter the start date and time for the data");
|
||||
layout->addWidget(_startLabel, 8, 0, 1, 2);
|
||||
_startEdit = new QDateTimeEdit(this);
|
||||
_startEdit = new QDateTimeEdit;
|
||||
_startEdit->setDisplayFormat("yyyy-MM-dd T hh:mm:ss");
|
||||
_startEdit->setDate(QDate::currentDate().addYears(-1));
|
||||
_startEdit->setToolTip("Enter the start date and time for the data");
|
||||
layout->addWidget(_startEdit, 8, 2);
|
||||
}
|
||||
{
|
||||
_endLabel = new QLabel("End Time:", this);
|
||||
_endLabel = new QLabel("End Time:");
|
||||
_endLabel->setToolTip("Enter the end date and time for the data");
|
||||
layout->addWidget(_endLabel, 9, 0, 1, 2);
|
||||
_endEdit = new QDateTimeEdit(this);
|
||||
@@ -314,30 +311,29 @@ void HorizonsDialog::createWidgets() {
|
||||
layout->addWidget(_endEdit, 9, 2);
|
||||
}
|
||||
{
|
||||
_importTimeButton = new QPushButton("Import timerange", this);
|
||||
_importTimeButton = new QPushButton("Import timerange");
|
||||
_importTimeButton->setDefault(false);
|
||||
connect(_importTimeButton, &QPushButton::released, this,
|
||||
&HorizonsDialog::importTimeRange
|
||||
connect(
|
||||
_importTimeButton, &QPushButton::released,
|
||||
this, &HorizonsDialog::importTimeRange
|
||||
);
|
||||
_importTimeButton->setCursor(Qt::PointingHandCursor);
|
||||
_importTimeButton->setToolTip(
|
||||
"Import parsed timerange for full data coverage"
|
||||
);
|
||||
_importTimeButton->setToolTip("Import parsed timerange for full data coverage");
|
||||
_importTimeButton->hide();
|
||||
layout->addWidget(_importTimeButton, 10, 2);
|
||||
}
|
||||
{
|
||||
_stepLabel = new QLabel("Step Size:", this);
|
||||
_stepLabel = new QLabel("Step Size:");
|
||||
_stepLabel->setToolTip("Enter the step size for the data");
|
||||
layout->addWidget(_stepLabel, 11, 0);
|
||||
|
||||
_stepEdit = new QLineEdit(this);
|
||||
_stepEdit = new QLineEdit;
|
||||
_stepEdit->setValidator(new QIntValidator(this));
|
||||
_stepEdit->setText(QString::number(1));
|
||||
_stepEdit->setToolTip("Enter the step size for the data");
|
||||
layout->addWidget(_stepEdit, 11, 1);
|
||||
|
||||
_timeTypeCombo = new QComboBox(this);
|
||||
_timeTypeCombo = new QComboBox;
|
||||
_timeTypeCombo->setToolTip("Choose unit of the step size");
|
||||
QStringList timeTypes = {
|
||||
Minutes.data(),
|
||||
@@ -353,7 +349,7 @@ void HorizonsDialog::createWidgets() {
|
||||
}
|
||||
layout->addWidget(new Line, 12, 0, 1, 3);
|
||||
{
|
||||
_log = new QPlainTextEdit(this);
|
||||
_log = new QPlainTextEdit;
|
||||
_log->setReadOnly(true);
|
||||
_log->setObjectName("log");
|
||||
|
||||
@@ -369,55 +365,36 @@ void HorizonsDialog::createWidgets() {
|
||||
}
|
||||
layout->addWidget(new Line, 14, 0, 1, 3);
|
||||
{
|
||||
_downloadLabel = new QLabel("Downloading file...", this);
|
||||
_downloadLabel = new QLabel("Downloading file...");
|
||||
_downloadLabel->setObjectName("thin");
|
||||
_downloadLabel->hide();
|
||||
layout->addWidget(_downloadLabel, 15, 0);
|
||||
|
||||
_downloadProgress = new QProgressBar(this);
|
||||
_downloadProgress = new QProgressBar;
|
||||
_downloadProgress->hide();
|
||||
layout->addWidget(_downloadProgress, 15, 1, 1, 2);
|
||||
}
|
||||
{
|
||||
QBoxLayout* footer = new QHBoxLayout(this);
|
||||
_errorMsg = new QLabel(this);
|
||||
QBoxLayout* footer = new QHBoxLayout;
|
||||
_errorMsg = new QLabel;
|
||||
_errorMsg->setObjectName("error-message");
|
||||
_errorMsg->setWordWrap(true);
|
||||
footer->addWidget(_errorMsg);
|
||||
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox(this);
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox;
|
||||
buttons->setStandardButtons(QDialogButtonBox::Save | QDialogButtonBox::Cancel);
|
||||
#ifdef OPENSPACE_MODULE_SPACE_ENABLED
|
||||
connect(buttons, &QDialogButtonBox::accepted, this, &HorizonsDialog::approved);
|
||||
#endif // OPENSPACE_MODULE_SPACE_ENABLED
|
||||
connect(buttons, &QDialogButtonBox::rejected, this, &HorizonsDialog::reject);
|
||||
footer->addWidget(buttons);
|
||||
layout->addLayout(footer, 16, 0, 1, 3);
|
||||
}
|
||||
}
|
||||
|
||||
void HorizonsDialog::cleanAllWidgets() {
|
||||
styleLabel(_typeLabel, false);
|
||||
styleLabel(_fileLabel, false);
|
||||
styleLabel(_targetLabel, false);
|
||||
styleLabel(_centerLabel, false);
|
||||
styleLabel(_startLabel, false);
|
||||
styleLabel(_endLabel, false);
|
||||
styleLabel(_stepLabel, false);
|
||||
}
|
||||
|
||||
void HorizonsDialog::styleLabel(QLabel* label, bool isDirty) {
|
||||
std::string newStyle = isDirty ? "error" : "normal";
|
||||
label->setObjectName(QString::fromStdString(newStyle));
|
||||
label->style()->unpolish(label);
|
||||
label->style()->polish(label);
|
||||
}
|
||||
|
||||
bool HorizonsDialog::isValidInput() {
|
||||
// File
|
||||
if (_fileEdit->text().isEmpty()) {
|
||||
_errorMsg->setText("File path not selected");
|
||||
styleLabel(_fileLabel, true);
|
||||
styleLabel(_fileLabel, IsDirty::Yes);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -426,13 +403,13 @@ bool HorizonsDialog::isValidInput() {
|
||||
_chooseTargetCombo->currentIndex() == 0) || _chooseTargetCombo->count() == 0))
|
||||
{
|
||||
_errorMsg->setText("Target not selected");
|
||||
styleLabel(_targetLabel, true);
|
||||
styleLabel(_targetLabel, IsDirty::Yes);
|
||||
return false;
|
||||
}
|
||||
if (_targetEdit->text().toStdString().find_first_of("¤<>§£´¨€") != std::string::npos)
|
||||
{
|
||||
_errorMsg->setText("Target includes illegal characters");
|
||||
styleLabel(_targetLabel, true);
|
||||
styleLabel(_targetLabel, IsDirty::Yes);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -441,13 +418,13 @@ bool HorizonsDialog::isValidInput() {
|
||||
_chooseObserverCombo->currentIndex() == 0) || _chooseObserverCombo->count() == 0))
|
||||
{
|
||||
_errorMsg->setText("Observer not selected");
|
||||
styleLabel(_centerLabel, true);
|
||||
styleLabel(_centerLabel, IsDirty::Yes);
|
||||
return false;
|
||||
}
|
||||
if (_centerEdit->text().toStdString().find_first_of("¤<>§£´¨€") != std::string::npos)
|
||||
{
|
||||
_errorMsg->setText("Observer includes illegal characters");
|
||||
styleLabel(_centerLabel, true);
|
||||
styleLabel(_centerLabel, IsDirty::Yes);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -455,7 +432,7 @@ bool HorizonsDialog::isValidInput() {
|
||||
// Empty
|
||||
if (_stepEdit->text().isEmpty()) {
|
||||
_errorMsg->setText("Step size not selected");
|
||||
styleLabel(_stepLabel, true);
|
||||
styleLabel(_stepLabel, IsDirty::Yes);
|
||||
return false;
|
||||
}
|
||||
// Numerical
|
||||
@@ -464,29 +441,29 @@ bool HorizonsDialog::isValidInput() {
|
||||
if (!couldConvert) {
|
||||
_errorMsg->setText(QString::fromStdString(fmt::format(
|
||||
"Step size needs to be a number in range 1 to {}",
|
||||
std::to_string(std::numeric_limits<int32_t>::max())
|
||||
std::numeric_limits<int32_t>::max()
|
||||
)));
|
||||
styleLabel(_stepLabel, true);
|
||||
styleLabel(_stepLabel, IsDirty::Yes);
|
||||
return false;
|
||||
}
|
||||
// In the case of arcseconds range is different
|
||||
if (_timeTypeCombo->currentText().toStdString() == TimeVarying) {
|
||||
if (step < 60 || step > 3600) {
|
||||
_errorMsg->setText("Angular step size needs to be in range 60 to 3600");
|
||||
styleLabel(_stepLabel, true);
|
||||
styleLabel(_stepLabel, IsDirty::Yes);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Range 1 to 2147483647 (max of 32 bit int).
|
||||
// Horizons read the step size into a 32 bit int, but verifies the input on their
|
||||
// website as a uint32_t. If step size over 32 bit int is sent, this error
|
||||
// message is recived: Cannot read numeric value -- re-enter
|
||||
// website as a uint32_t. If step size over 32 bit int is sent, this error message is
|
||||
// recived: Cannot read numeric value -- re-enter
|
||||
if (step < 1 || step > std::numeric_limits<int32_t>::max()) {
|
||||
_errorMsg->setText(QString::fromStdString(fmt::format(
|
||||
"Step size is outside valid range 1 to '{}'",
|
||||
std::to_string(std::numeric_limits<int32_t>::max())
|
||||
std::numeric_limits<int32_t>::max()
|
||||
)));
|
||||
styleLabel(_stepLabel, true);
|
||||
styleLabel(_stepLabel, IsDirty::Yes);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -499,20 +476,20 @@ json HorizonsDialog::sendRequest(const std::string& url) {
|
||||
request.setUrl(QUrl(QString::fromStdString(url)));
|
||||
|
||||
QNetworkReply* reply = _manager->get(request);
|
||||
connect(reply, &QNetworkReply::downloadProgress, this,
|
||||
&HorizonsDialog::downloadProgress
|
||||
connect(
|
||||
reply, &QNetworkReply::downloadProgress,
|
||||
this, &HorizonsDialog::downloadProgress
|
||||
);
|
||||
_downloadProgress->reset();
|
||||
_downloadProgress->show();
|
||||
|
||||
QEventLoop loop;
|
||||
QMetaObject::Connection status =
|
||||
QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
|
||||
QMetaObject::Connection status = connect(
|
||||
reply, &QNetworkReply::finished,
|
||||
&loop, &QEventLoop::quit
|
||||
);
|
||||
if (!status) {
|
||||
appendLog(
|
||||
"Could not connect to Horizons API",
|
||||
HorizonsDialog::LogLevel::Error
|
||||
);
|
||||
appendLog("Could not connect to Horizons API", HorizonsDialog::LogLevel::Error);
|
||||
return json();
|
||||
}
|
||||
|
||||
@@ -570,21 +547,22 @@ bool HorizonsDialog::checkHttpStatus(const QVariant& statusCode) {
|
||||
statusCode.toInt() != static_cast<int>(HorizonsDialog::HTTPCodes::Ok))
|
||||
{
|
||||
std::string message;
|
||||
int code = statusCode.toInt();
|
||||
HorizonsDialog::HTTPCodes code =
|
||||
static_cast<HorizonsDialog::HTTPCodes>(statusCode.toInt());
|
||||
|
||||
switch (code) {
|
||||
case static_cast<int>(HorizonsDialog::HTTPCodes::BadRequest):
|
||||
case HorizonsDialog::HTTPCodes::BadRequest:
|
||||
message = "The request contained invalid keywords and/or used "
|
||||
"a method other than GET or POST";
|
||||
break;
|
||||
case static_cast<int>(HorizonsDialog::HTTPCodes::MethodNotAllowed):
|
||||
case HorizonsDialog::HTTPCodes::MethodNotAllowed:
|
||||
message = "The request used an incorrect method";
|
||||
break;
|
||||
case static_cast<int>(HorizonsDialog::HTTPCodes::InternalServerError):
|
||||
case HorizonsDialog::HTTPCodes::InternalServerError:
|
||||
message = "The database is currently not available, try again at a "
|
||||
"later time";
|
||||
break;
|
||||
case static_cast<int>(HorizonsDialog::HTTPCodes::ServiceUnavailable):
|
||||
case HorizonsDialog::HTTPCodes::ServiceUnavailable:
|
||||
message = "The server is currently unable to handle the request due to a "
|
||||
"temporary overloading or maintenance of the server, try again at a "
|
||||
"later time";
|
||||
@@ -714,7 +692,17 @@ bool HorizonsDialog::handleRequest() {
|
||||
|
||||
// Reset
|
||||
_errorMsg->clear();
|
||||
cleanAllWidgets();
|
||||
|
||||
//
|
||||
// Clean all widgets
|
||||
styleLabel(_typeLabel, IsDirty::No);
|
||||
styleLabel(_fileLabel, IsDirty::No);
|
||||
styleLabel(_targetLabel, IsDirty::No);
|
||||
styleLabel(_centerLabel, IsDirty::No);
|
||||
styleLabel(_startLabel, IsDirty::No);
|
||||
styleLabel(_endLabel, IsDirty::No);
|
||||
styleLabel(_stepLabel, IsDirty::No);
|
||||
|
||||
_importTimeButton->hide();
|
||||
_validTimeRange = std::pair<std::string, std::string>();
|
||||
_latestHorizonsError.clear();
|
||||
@@ -732,14 +720,13 @@ bool HorizonsDialog::handleRequest() {
|
||||
return false;
|
||||
}
|
||||
|
||||
openspace::HorizonsFile file = handleAnswer(answer);
|
||||
HorizonsFile file = handleAnswer(answer);
|
||||
if (!file.hasFile()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_horizonsFile = std::move(file);
|
||||
openspace::HorizonsResultCode result =
|
||||
openspace::isValidHorizonsFile(_horizonsFile.file());
|
||||
HorizonsResultCode result = isValidHorizonsFile(_horizonsFile.file());
|
||||
|
||||
bool isValid = handleResult(result);
|
||||
|
||||
@@ -764,23 +751,23 @@ bool HorizonsDialog::handleRequest() {
|
||||
|
||||
std::string HorizonsDialog::constructUrl() {
|
||||
// Construct url for request
|
||||
openspace::HorizonsType type;
|
||||
HorizonsType type;
|
||||
if (_typeCombo->currentIndex() == 0) {
|
||||
type = openspace::HorizonsType::Vector;
|
||||
type = HorizonsType::Vector;
|
||||
}
|
||||
else if (_typeCombo->currentIndex() == 1) {
|
||||
type = openspace::HorizonsType::Observer;
|
||||
type = HorizonsType::Observer;
|
||||
}
|
||||
else {
|
||||
_errorMsg->setText("Invalid Horizons type");
|
||||
styleLabel(_typeLabel, true);
|
||||
styleLabel(_typeLabel, IsDirty::Yes);
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string command;
|
||||
if (_chooseTargetCombo->count() > 0 && _chooseTargetCombo->currentIndex() != 0) {
|
||||
QVariant target = _chooseTargetCombo->itemData(_chooseTargetCombo->currentIndex());
|
||||
command = target.toString().toStdString();
|
||||
QVariant t = _chooseTargetCombo->itemData(_chooseTargetCombo->currentIndex());
|
||||
command = t.toString().toStdString();
|
||||
_targetName = _chooseTargetCombo->currentText().toStdString();
|
||||
_targetEdit->setText(QString::fromStdString(command));
|
||||
}
|
||||
@@ -839,11 +826,11 @@ std::string HorizonsDialog::constructUrl() {
|
||||
}
|
||||
else {
|
||||
_errorMsg->setText("Invalid time unit type");
|
||||
styleLabel(_stepLabel, true);
|
||||
styleLabel(_stepLabel, IsDirty::Yes);
|
||||
return "";
|
||||
}
|
||||
|
||||
return openspace::constructHorizonsUrl(
|
||||
return constructHorizonsUrl(
|
||||
type,
|
||||
command,
|
||||
center,
|
||||
@@ -860,11 +847,10 @@ openspace::HorizonsFile HorizonsDialog::handleAnswer(json& answer) {
|
||||
_latestHorizonsError = *it;
|
||||
}
|
||||
|
||||
openspace::HorizonsResultCode isValid =
|
||||
openspace::isValidHorizonsAnswer(answer);
|
||||
if (isValid != openspace::HorizonsResultCode::Valid &&
|
||||
isValid != openspace::HorizonsResultCode::MultipleObserverStations &&
|
||||
isValid != openspace::HorizonsResultCode::ErrorTimeRange)
|
||||
HorizonsResultCode isValid = isValidHorizonsAnswer(answer);
|
||||
if (isValid != HorizonsResultCode::Valid &&
|
||||
isValid != HorizonsResultCode::MultipleObserverStations &&
|
||||
isValid != HorizonsResultCode::ErrorTimeRange)
|
||||
{
|
||||
// Special case with MultipleObserverStations since it is detected as an error
|
||||
// but could be fixed by parsing the matches and let user choose
|
||||
@@ -901,11 +887,11 @@ openspace::HorizonsFile HorizonsDialog::handleAnswer(json& answer) {
|
||||
case QMessageBox::No:
|
||||
case QMessageBox::Cancel:
|
||||
_errorMsg->setText("File already exist, try another file path");
|
||||
styleLabel(_fileLabel, true);
|
||||
styleLabel(_fileLabel, IsDirty::Yes);
|
||||
return openspace::HorizonsFile();
|
||||
default:
|
||||
_errorMsg->setText("Invalid answer");
|
||||
styleLabel(_fileLabel, true);
|
||||
styleLabel(_fileLabel, IsDirty::Yes);
|
||||
return openspace::HorizonsFile();
|
||||
}
|
||||
}
|
||||
@@ -916,7 +902,7 @@ openspace::HorizonsFile HorizonsDialog::handleAnswer(json& answer) {
|
||||
|
||||
bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
|
||||
switch (result) {
|
||||
case openspace::HorizonsResultCode::Valid: {
|
||||
case HorizonsResultCode::Valid: {
|
||||
// If the request worked then delete the corresponding error file if it exist
|
||||
std::filesystem::path validFile(_horizonsFile.file());
|
||||
|
||||
@@ -930,7 +916,7 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case openspace::HorizonsResultCode::Empty: {
|
||||
case HorizonsResultCode::Empty: {
|
||||
_errorMsg->setText("The horizons file is empty");
|
||||
if (!_latestHorizonsError.empty()) {
|
||||
std::string msg = fmt::format(
|
||||
@@ -942,7 +928,7 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
|
||||
std::filesystem::remove(_horizonsFile.file());
|
||||
break;
|
||||
}
|
||||
case openspace::HorizonsResultCode::ErrorSize: {
|
||||
case HorizonsResultCode::ErrorSize: {
|
||||
std::string msg = fmt::format(
|
||||
"Time range '{}' to '{}' with step size '{} {}' is too big, try to "
|
||||
"increase the step size and/or decrease the time range",
|
||||
@@ -950,29 +936,29 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
|
||||
_timeTypeCombo->currentText().toStdString()
|
||||
);
|
||||
appendLog(msg, HorizonsDialog::LogLevel::Error);
|
||||
styleLabel(_startLabel, true);
|
||||
styleLabel(_endLabel, true);
|
||||
styleLabel(_stepLabel, true);
|
||||
styleLabel(_startLabel, IsDirty::Yes);
|
||||
styleLabel(_endLabel, IsDirty::Yes);
|
||||
styleLabel(_stepLabel, IsDirty::Yes);
|
||||
|
||||
std::filesystem::remove(_horizonsFile.file());
|
||||
break;
|
||||
}
|
||||
case openspace::HorizonsResultCode::ErrorSpan:
|
||||
case HorizonsResultCode::ErrorSpan:
|
||||
appendLog(
|
||||
"Step size is too big, exceeds available time span for target",
|
||||
HorizonsDialog::LogLevel::Error
|
||||
);
|
||||
styleLabel(_stepLabel, true);
|
||||
styleLabel(_stepLabel, IsDirty::Yes);
|
||||
|
||||
std::filesystem::remove(_horizonsFile.file());
|
||||
break;
|
||||
case openspace::HorizonsResultCode::ErrorTimeRange: {
|
||||
case HorizonsResultCode::ErrorTimeRange: {
|
||||
std::string msg = fmt::format(
|
||||
"Time range is outside the valid range for target '{}'", _targetName
|
||||
);
|
||||
appendLog(msg, HorizonsDialog::LogLevel::Error);
|
||||
styleLabel(_startLabel, true);
|
||||
styleLabel(_endLabel, true);
|
||||
styleLabel(_startLabel, IsDirty::Yes);
|
||||
styleLabel(_endLabel, IsDirty::Yes);
|
||||
|
||||
_validTimeRange = readTimeRange();
|
||||
if (_validTimeRange.first.empty() || _validTimeRange.second.empty()) {
|
||||
@@ -993,7 +979,7 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
|
||||
std::filesystem::remove(_horizonsFile.file());
|
||||
break;
|
||||
}
|
||||
case openspace::HorizonsResultCode::ErrorNoObserver: {
|
||||
case HorizonsResultCode::ErrorNoObserver: {
|
||||
std::string msg = fmt::format(
|
||||
"No match was found for observer '{}'", _observerName
|
||||
);
|
||||
@@ -1004,24 +990,24 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
|
||||
_observerName
|
||||
);
|
||||
appendLog(msg, HorizonsDialog::LogLevel::Info);
|
||||
styleLabel(_centerLabel, true);
|
||||
styleLabel(_centerLabel, IsDirty::Yes);
|
||||
|
||||
std::filesystem::remove(_horizonsFile.file());
|
||||
break;
|
||||
}
|
||||
case openspace::HorizonsResultCode::ErrorObserverTargetSame: {
|
||||
case HorizonsResultCode::ErrorObserverTargetSame: {
|
||||
std::string msg = fmt::format(
|
||||
"The observer '{}' and target '{}' are the same. Please use another "
|
||||
"observer for the current target.", _observerName, _targetName
|
||||
);
|
||||
appendLog(msg, HorizonsDialog::LogLevel::Error);
|
||||
styleLabel(_targetLabel, true);
|
||||
styleLabel(_centerLabel, true);
|
||||
styleLabel(_targetLabel, IsDirty::Yes);
|
||||
styleLabel(_centerLabel, IsDirty::Yes);
|
||||
|
||||
std::filesystem::remove(_horizonsFile.file());
|
||||
break;
|
||||
}
|
||||
case openspace::HorizonsResultCode::ErrorNoData: {
|
||||
case HorizonsResultCode::ErrorNoData: {
|
||||
std::string msg = fmt::format(
|
||||
"There is not enough data to compute the state of target '{}' in "
|
||||
"relation to the observer '{}' for the time range '{}' to '{}'. Try to "
|
||||
@@ -1033,7 +1019,7 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
|
||||
std::filesystem::remove(_horizonsFile.file());
|
||||
break;
|
||||
}
|
||||
case openspace::HorizonsResultCode::MultipleObserverStations: {
|
||||
case HorizonsResultCode::MultipleObserverStations: {
|
||||
std::string msg = fmt::format(
|
||||
"Multiple matching observer stations were found for observer '{}'. ",
|
||||
_observerName
|
||||
@@ -1045,7 +1031,7 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
|
||||
"for alternatives.", _observerName
|
||||
);
|
||||
appendLog(msg, HorizonsDialog::LogLevel::Info);
|
||||
styleLabel(_centerLabel, true);
|
||||
styleLabel(_centerLabel, IsDirty::Yes);
|
||||
|
||||
std::vector<std::string> matchingstations =
|
||||
_horizonsFile.parseMatches(
|
||||
@@ -1076,12 +1062,12 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
|
||||
std::filesystem::remove(_horizonsFile.file());
|
||||
break;
|
||||
}
|
||||
case openspace::HorizonsResultCode::MultipleObserver: {
|
||||
case HorizonsResultCode::MultipleObserver: {
|
||||
std::string msg = fmt::format(
|
||||
"Multiple matches were found for observer '{}'", _observerName
|
||||
);
|
||||
appendLog(msg, HorizonsDialog::LogLevel::Warning);
|
||||
styleLabel(_centerLabel, true);
|
||||
styleLabel(_centerLabel, IsDirty::Yes);
|
||||
|
||||
std::vector<std::string> matchingObservers =
|
||||
_horizonsFile.parseMatches("Name", "matches", ">MATCH NAME<");
|
||||
@@ -1111,7 +1097,7 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
|
||||
std::filesystem::remove(_horizonsFile.file());
|
||||
break;
|
||||
}
|
||||
case openspace::HorizonsResultCode::ErrorNoTarget: {
|
||||
case HorizonsResultCode::ErrorNoTarget: {
|
||||
std::string msg = fmt::format(
|
||||
"No match was found for target '{}'", _targetName
|
||||
);
|
||||
@@ -1122,12 +1108,12 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
|
||||
_targetName
|
||||
);
|
||||
appendLog(msg, HorizonsDialog::LogLevel::Info);
|
||||
styleLabel(_targetLabel, true);
|
||||
styleLabel(_targetLabel, IsDirty::Yes);
|
||||
|
||||
std::filesystem::remove(_horizonsFile.file());
|
||||
break;
|
||||
}
|
||||
case openspace::HorizonsResultCode::MultipleTarget: {
|
||||
case HorizonsResultCode::MultipleTarget: {
|
||||
// Case Small Bodies:
|
||||
// Line before data: Matching small-bodies
|
||||
// Format: Record #, Epoch-yr, >MATCH DESIG<, Primary Desig, Name
|
||||
@@ -1143,7 +1129,7 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
|
||||
"Multiple matches were found for target '{}'", _targetName
|
||||
);
|
||||
appendLog(msg, HorizonsDialog::LogLevel::Warning);
|
||||
styleLabel(_targetLabel, true);
|
||||
styleLabel(_targetLabel, IsDirty::Yes);
|
||||
|
||||
std::vector<std::string> matchingTargets =
|
||||
_horizonsFile.parseMatches("Name", "matches", ">MATCH NAME<");
|
||||
@@ -1171,7 +1157,7 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
|
||||
std::filesystem::remove(_horizonsFile.file());
|
||||
break;
|
||||
}
|
||||
case openspace::HorizonsResultCode::UnknownError: {
|
||||
case HorizonsResultCode::UnknownError: {
|
||||
appendLog("Unknown error", LogLevel::Error);
|
||||
if (!_latestHorizonsError.empty()) {
|
||||
std::string msg = fmt::format(
|
||||
@@ -1193,6 +1179,6 @@ bool HorizonsDialog::handleResult(openspace::HorizonsResultCode& result) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result == openspace::HorizonsResultCode::Valid;
|
||||
return result == HorizonsResultCode::Valid;
|
||||
}
|
||||
#endif // OPENSPACE_MODULE_SPACE_ENABLED
|
||||
|
||||
@@ -49,7 +49,9 @@ void MarkNodesDialog::createWidgets() {
|
||||
_list = new QListWidget;
|
||||
connect(
|
||||
_list, &QListWidget::itemSelectionChanged,
|
||||
this, &MarkNodesDialog::listItemSelected
|
||||
[this]() {
|
||||
_removeButton->setEnabled(true);
|
||||
}
|
||||
);
|
||||
_list->setAlternatingRowColors(true);
|
||||
_list->setMovement(QListView::Free);
|
||||
@@ -77,10 +79,7 @@ void MarkNodesDialog::createWidgets() {
|
||||
box->addWidget(_newNode);
|
||||
|
||||
QPushButton* addButton = new QPushButton("Add new");
|
||||
connect(
|
||||
addButton, &QPushButton::clicked,
|
||||
this, &MarkNodesDialog::listItemAdded
|
||||
);
|
||||
connect(addButton, &QPushButton::clicked, this, &MarkNodesDialog::listItemAdded);
|
||||
box->addWidget(addButton);
|
||||
layout->addLayout(box);
|
||||
}
|
||||
@@ -88,22 +87,15 @@ void MarkNodesDialog::createWidgets() {
|
||||
{
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox;
|
||||
buttons->setStandardButtons(QDialogButtonBox::Save | QDialogButtonBox::Cancel);
|
||||
QObject::connect(
|
||||
connect(
|
||||
buttons, &QDialogButtonBox::accepted,
|
||||
this, &MarkNodesDialog::parseSelections
|
||||
);
|
||||
QObject::connect(
|
||||
buttons, &QDialogButtonBox::rejected,
|
||||
this, &MarkNodesDialog::reject
|
||||
);
|
||||
connect(buttons, &QDialogButtonBox::rejected, this, &MarkNodesDialog::reject);
|
||||
layout->addWidget(buttons);
|
||||
}
|
||||
}
|
||||
|
||||
void MarkNodesDialog::listItemSelected() {
|
||||
_removeButton->setEnabled(true);
|
||||
}
|
||||
|
||||
void MarkNodesDialog::listItemAdded() {
|
||||
if (_newNode->text().isEmpty()) {
|
||||
return;
|
||||
@@ -151,12 +143,11 @@ void MarkNodesDialog::parseSelections() {
|
||||
}
|
||||
|
||||
void MarkNodesDialog::keyPressEvent(QKeyEvent* evt) {
|
||||
if (evt->key() == Qt::Key_Enter || evt->key() == Qt::Key_Return) {
|
||||
if (_newNode->text().length() > 0 && _newNode->hasFocus()) {
|
||||
listItemAdded();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ((evt->key() == Qt::Key_Enter || evt->key() == Qt::Key_Return) &&
|
||||
(!_newNode->text().isEmpty() && _newNode->hasFocus()))
|
||||
{
|
||||
listItemAdded();
|
||||
return;
|
||||
}
|
||||
QDialog::keyPressEvent(evt);
|
||||
}
|
||||
|
||||
|
||||
@@ -54,21 +54,21 @@ ModulesDialog::ModulesDialog(QWidget* parent,
|
||||
|
||||
void ModulesDialog::createWidgets() {
|
||||
QBoxLayout* layout = new QVBoxLayout(this);
|
||||
{
|
||||
_list = new QListWidget;
|
||||
connect(
|
||||
_list, &QListWidget::itemSelectionChanged,
|
||||
this, &ModulesDialog::listItemSelected
|
||||
);
|
||||
_list->setAlternatingRowColors(true);
|
||||
_list->setMovement(QListView::Free);
|
||||
_list->setResizeMode(QListView::Adjust);
|
||||
|
||||
for (const Profile::Module& m : _moduleData) {
|
||||
_list->addItem(new QListWidgetItem(createOneLineSummary(m)));
|
||||
}
|
||||
layout->addWidget(_list);
|
||||
_list = new QListWidget;
|
||||
connect(
|
||||
_list, &QListWidget::itemSelectionChanged,
|
||||
this, &ModulesDialog::listItemSelected
|
||||
);
|
||||
_list->setAlternatingRowColors(true);
|
||||
_list->setMovement(QListView::Free);
|
||||
_list->setResizeMode(QListView::Adjust);
|
||||
|
||||
for (const Profile::Module& m : _moduleData) {
|
||||
_list->addItem(new QListWidgetItem(createOneLineSummary(m)));
|
||||
}
|
||||
layout->addWidget(_list);
|
||||
|
||||
{
|
||||
QBoxLayout* box = new QHBoxLayout;
|
||||
_buttonAdd = new QPushButton("Add new");
|
||||
@@ -89,12 +89,14 @@ void ModulesDialog::createWidgets() {
|
||||
{
|
||||
_moduleLabel = new QLabel("Module");
|
||||
layout->addWidget(_moduleLabel);
|
||||
|
||||
_moduleEdit = new QLineEdit;
|
||||
_moduleEdit->setToolTip("Name of OpenSpace module related to this profile");
|
||||
layout->addWidget(_moduleEdit);
|
||||
|
||||
_loadedLabel = new QLabel("Command if Module is Loaded");
|
||||
layout->addWidget(_loadedLabel);
|
||||
|
||||
_loadedEdit = new QLineEdit;
|
||||
_loadedEdit->setToolTip(
|
||||
"Lua command(s) to execute if OpenSpace has been compiled with the module"
|
||||
@@ -103,6 +105,7 @@ void ModulesDialog::createWidgets() {
|
||||
|
||||
_notLoadedLabel = new QLabel("Command if Module is NOT Loaded");
|
||||
layout->addWidget(_notLoadedLabel);
|
||||
|
||||
_notLoadedEdit = new QLineEdit;
|
||||
_notLoadedEdit->setToolTip(
|
||||
"Lua command(s) to execute if the module is not present in the OpenSpace "
|
||||
@@ -155,8 +158,8 @@ void ModulesDialog::createWidgets() {
|
||||
|
||||
QString ModulesDialog::createOneLineSummary(Profile::Module m) {
|
||||
QString summary = QString::fromStdString(m.name);
|
||||
bool hasCommandForLoaded = (m.loadedInstruction->length() > 0);
|
||||
bool hasCommandForNotLoaded = (m.notLoadedInstruction->length() > 0);
|
||||
bool hasCommandForLoaded = !m.loadedInstruction->empty();
|
||||
bool hasCommandForNotLoaded = !m.notLoadedInstruction->empty();
|
||||
|
||||
if (hasCommandForLoaded && hasCommandForNotLoaded) {
|
||||
summary += " (commands set for both loaded & not-loaded conditions)";
|
||||
@@ -186,6 +189,7 @@ void ModulesDialog::listItemSelected() {
|
||||
else {
|
||||
_loadedEdit->clear();
|
||||
}
|
||||
|
||||
if (m.notLoadedInstruction.has_value()) {
|
||||
_notLoadedEdit->setText(QString::fromStdString(*m.notLoadedInstruction));
|
||||
}
|
||||
@@ -197,14 +201,9 @@ void ModulesDialog::listItemSelected() {
|
||||
}
|
||||
|
||||
bool ModulesDialog::isLineEmpty(int index) const {
|
||||
bool isEmpty = true;
|
||||
if (!_list->item(index)->text().isEmpty()) {
|
||||
isEmpty = false;
|
||||
}
|
||||
if (!_moduleData.empty() && !_moduleData.at(0).name.empty()) {
|
||||
isEmpty = false;
|
||||
}
|
||||
return isEmpty;
|
||||
return
|
||||
_list->item(index)->text().isEmpty() &&
|
||||
_moduleData.empty() && !_moduleData.at(0).name.empty();
|
||||
}
|
||||
|
||||
void ModulesDialog::listItemAdded() {
|
||||
@@ -258,7 +257,7 @@ void ModulesDialog::listItemSave() {
|
||||
QListWidgetItem* item = _list->currentItem();
|
||||
int index = _list->row(item);
|
||||
|
||||
if (_moduleData.size() > 0) {
|
||||
if (!_moduleData.empty()) {
|
||||
_moduleData[index].name = _moduleEdit->text().toStdString();
|
||||
_moduleData[index].loadedInstruction = _loadedEdit->text().toStdString();
|
||||
_moduleData[index].notLoadedInstruction = _notLoadedEdit->text().toStdString();
|
||||
@@ -277,21 +276,21 @@ void ModulesDialog::listItemCancelSave() {
|
||||
}
|
||||
|
||||
void ModulesDialog::listItemRemove() {
|
||||
if (_list->count() > 0) {
|
||||
if (_list->currentRow() >= 0 && _list->currentRow() < _list->count()) {
|
||||
if (_list->count() == 1) {
|
||||
// Special case where last remaining item is being removed (QListWidget
|
||||
// doesn't like the final item being removed so instead clear it)
|
||||
_moduleData.at(0) = Blank;
|
||||
_list->item(0)->setText("");
|
||||
}
|
||||
else {
|
||||
int index = _list->currentRow();
|
||||
if (index >= 0 && index < _list->count()) {
|
||||
delete _list->takeItem(index);
|
||||
if (!_moduleData.empty()) {
|
||||
_moduleData.erase(_moduleData.begin() + index);
|
||||
}
|
||||
if (_list->count() > 0 &&
|
||||
_list->currentRow() >= 0 && _list->currentRow() < _list->count())
|
||||
{
|
||||
if (_list->count() == 1) {
|
||||
// Special case where last remaining item is being removed (QListWidget
|
||||
// doesn't like the final item being removed so instead clear it)
|
||||
_moduleData.at(0) = Blank;
|
||||
_list->item(0)->setText("");
|
||||
}
|
||||
else {
|
||||
int index = _list->currentRow();
|
||||
if (index >= 0 && index < _list->count()) {
|
||||
delete _list->takeItem(index);
|
||||
if (!_moduleData.empty()) {
|
||||
_moduleData.erase(_moduleData.begin() + index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -361,4 +360,3 @@ void ModulesDialog::keyPressEvent(QKeyEvent* evt) {
|
||||
}
|
||||
QDialog::keyPressEvent(evt);
|
||||
}
|
||||
|
||||
|
||||
@@ -183,7 +183,7 @@ void PropertiesDialog::listItemSelected() {
|
||||
QListWidgetItem* item = _list->currentItem();
|
||||
int index = _list->row(item);
|
||||
|
||||
if (_propertyData.size() > 0) {
|
||||
if (!_propertyData.empty()) {
|
||||
Profile::Property& p = _propertyData[index];
|
||||
if (p.setType == Profile::Property::SetType::SetPropertyValueSingle) {
|
||||
_commandCombo->setCurrentIndex(0);
|
||||
@@ -211,21 +211,21 @@ bool PropertiesDialog::isLineEmpty(int index) {
|
||||
void PropertiesDialog::listItemAdded() {
|
||||
int currentListSize = _list->count();
|
||||
|
||||
if ((currentListSize == 1) && (isLineEmpty(0))) {
|
||||
// Special case where list is "empty" but really has one line that is blank.
|
||||
// This is done because QListWidget does not seem to like having its sole
|
||||
// remaining item being removed.
|
||||
_propertyData.at(0) = Blank;
|
||||
_list->item(0)->setText(" (Enter details below & click 'Save')");
|
||||
_list->setCurrentRow(0);
|
||||
transitionToEditMode();
|
||||
}
|
||||
else {
|
||||
_propertyData.push_back(Blank);
|
||||
_list->addItem(new QListWidgetItem(" (Enter details below & click 'Save')"));
|
||||
//Scroll down to that blank line highlighted
|
||||
_list->setCurrentRow(_list->count() - 1);
|
||||
}
|
||||
if ((currentListSize == 1) && (isLineEmpty(0))) {
|
||||
// Special case where list is "empty" but really has one line that is blank.
|
||||
// This is done because QListWidget does not seem to like having its sole
|
||||
// remaining item being removed.
|
||||
_propertyData.at(0) = Blank;
|
||||
_list->item(0)->setText(" (Enter details below & click 'Save')");
|
||||
_list->setCurrentRow(0);
|
||||
transitionToEditMode();
|
||||
}
|
||||
else {
|
||||
_propertyData.push_back(Blank);
|
||||
_list->addItem(new QListWidgetItem(" (Enter details below & click 'Save')"));
|
||||
//Scroll down to that blank line highlighted
|
||||
_list->setCurrentRow(_list->count() - 1);
|
||||
}
|
||||
|
||||
// Blank-out the 2 text fields, set combo box to index 0
|
||||
_commandCombo->setCurrentIndex(0);
|
||||
@@ -243,7 +243,7 @@ void PropertiesDialog::listItemSave() {
|
||||
QListWidgetItem* item = _list->currentItem();
|
||||
int index = _list->row(item);
|
||||
|
||||
if (_propertyData.size() > 0) {
|
||||
if (!_propertyData.empty()) {
|
||||
if (_commandCombo->currentIndex() == 0) {
|
||||
_propertyData[index].setType =
|
||||
Profile::Property::SetType::SetPropertyValueSingle;
|
||||
@@ -262,12 +262,12 @@ void PropertiesDialog::listItemSave() {
|
||||
bool PropertiesDialog::areRequiredFormsFilled() {
|
||||
bool requiredFormsFilled = true;
|
||||
QString errors;
|
||||
if (_propertyEdit->text().length() == 0) {
|
||||
if (_propertyEdit->text().isEmpty()) {
|
||||
errors += "Missing property name";
|
||||
requiredFormsFilled = false;
|
||||
}
|
||||
if (_valueEdit->text().length() == 0) {
|
||||
if (errors.length() > 0) {
|
||||
if (_valueEdit->text().isEmpty()) {
|
||||
if (!errors.isEmpty()) {
|
||||
errors += ", ";
|
||||
}
|
||||
errors += "Missing value";
|
||||
@@ -280,34 +280,30 @@ bool PropertiesDialog::areRequiredFormsFilled() {
|
||||
void PropertiesDialog::listItemCancelSave() {
|
||||
listItemSelected();
|
||||
transitionFromEditMode();
|
||||
if (_editModeNewItem) {
|
||||
if (_propertyData.size() > 0) {
|
||||
if (_propertyData.back().name.length() == 0 ||
|
||||
_propertyData.back().value.length() == 0)
|
||||
{
|
||||
listItemRemove();
|
||||
}
|
||||
}
|
||||
if (_editModeNewItem && !_propertyData.empty() &&
|
||||
(_propertyData.back().name.empty() || _propertyData.back().value.empty()))
|
||||
{
|
||||
listItemRemove();
|
||||
}
|
||||
_editModeNewItem = false;
|
||||
}
|
||||
|
||||
void PropertiesDialog::listItemRemove() {
|
||||
if (_list->count() > 0) {
|
||||
if (_list->currentRow() >= 0 && _list->currentRow() < _list->count()) {
|
||||
if (_list->count() == 1) {
|
||||
//Special case where last remaining item is being removed (QListWidget
|
||||
// doesn't like the final item being removed so instead clear it)
|
||||
_propertyData.at(0) = Blank;
|
||||
_list->item(0)->setText("");
|
||||
}
|
||||
else {
|
||||
int index = _list->currentRow();
|
||||
if (index >= 0 && index < _list->count()) {
|
||||
delete _list->takeItem(index);
|
||||
if (_propertyData.size() > 0) {
|
||||
_propertyData.erase(_propertyData.begin() + index);
|
||||
}
|
||||
if (_list->count() > 0 &&
|
||||
(_list->currentRow() >= 0 && _list->currentRow() < _list->count()))
|
||||
{
|
||||
if (_list->count() == 1) {
|
||||
// Special case where last remaining item is being removed (QListWidget
|
||||
// doesn't like the final item being removed so instead clear it)
|
||||
_propertyData.at(0) = Blank;
|
||||
_list->item(0)->setText("");
|
||||
}
|
||||
else {
|
||||
int index = _list->currentRow();
|
||||
if (index >= 0 && index < _list->count()) {
|
||||
delete _list->takeItem(index);
|
||||
if (_propertyData.size() > 0) {
|
||||
_propertyData.erase(_propertyData.begin() + index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -370,11 +366,9 @@ void PropertiesDialog::keyPressEvent(QKeyEvent* evt) {
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (evt->key() == Qt::Key_Escape) {
|
||||
if (_editModeNewItem) {
|
||||
listItemCancelSave();
|
||||
return;
|
||||
}
|
||||
else if (evt->key() == Qt::Key_Escape && _editModeNewItem) {
|
||||
listItemCancelSave();
|
||||
return;
|
||||
}
|
||||
QDialog::keyPressEvent(evt);
|
||||
}
|
||||
@@ -405,49 +399,52 @@ void PropertiesDialog::selectLineFromScriptLog() {
|
||||
|
||||
QDialog dialog;
|
||||
|
||||
connect(&dialog, &QDialog::finished, [this, comboBox](int result) {
|
||||
if (result == QDialog::Rejected) {
|
||||
return;
|
||||
connect(
|
||||
&dialog, &QDialog::finished,
|
||||
[this, comboBox](int result) {
|
||||
if (result == QDialog::Rejected) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString text = comboBox->currentText();
|
||||
if (!text.startsWith("openspace.setPropertyValue")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We have a string that is of the form:
|
||||
// openspace.setPropertyValue('prop', value);
|
||||
|
||||
if (text.startsWith("openspace.setPropertyValueSingle")) {
|
||||
_commandCombo->setCurrentIndex(0);
|
||||
std::string_view prefix = "openspace.setPropertyValueSingle";
|
||||
text = text.mid(static_cast<int>(prefix.size()) + 1); // +1 for (
|
||||
}
|
||||
else {
|
||||
// command == "openspace.setPropertyValue"
|
||||
_commandCombo->setCurrentIndex(1);
|
||||
std::string_view prefix = "openspace.setPropertyValue";
|
||||
text = text.mid(static_cast<int>(prefix.size()) + 1); // +1 for (
|
||||
}
|
||||
|
||||
// Remove everything past the closing brace
|
||||
text = text.left(text.indexOf(")"));
|
||||
QStringList textList = text.split(",");
|
||||
|
||||
if (textList.size() < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the string markers around the property
|
||||
QString property = textList[0].mid(1, textList[0].size() - 2);
|
||||
|
||||
textList.removeFirst();
|
||||
QString value = textList.join(",");
|
||||
|
||||
|
||||
_propertyEdit->setText(property.trimmed());
|
||||
_valueEdit->setText(value.trimmed());
|
||||
}
|
||||
|
||||
QString text = comboBox->currentText();
|
||||
if (!text.startsWith("openspace.setPropertyValue")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We have a string that is of the form:
|
||||
// openspace.setPropertyValue('prop', value);
|
||||
|
||||
if (text.startsWith("openspace.setPropertyValueSingle")) {
|
||||
_commandCombo->setCurrentIndex(0);
|
||||
std::string_view prefix = "openspace.setPropertyValueSingle";
|
||||
text = text.mid(static_cast<int>(prefix.size()) + 1); // +1 for (
|
||||
}
|
||||
else {
|
||||
// command == "openspace.setPropertyValue"
|
||||
_commandCombo->setCurrentIndex(1);
|
||||
std::string_view prefix = "openspace.setPropertyValue";
|
||||
text = text.mid(static_cast<int>(prefix.size()) + 1); // +1 for (
|
||||
}
|
||||
|
||||
// Remove everything past the closing brace
|
||||
text = text.left(text.indexOf(")"));
|
||||
QStringList textList = text.split(",");
|
||||
|
||||
if (textList.size() < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the string markers around the property
|
||||
QString property = textList[0].mid(1, textList[0].size() - 2);
|
||||
|
||||
textList.removeFirst();
|
||||
QString value = textList.join(",");
|
||||
|
||||
|
||||
_propertyEdit->setText(property.trimmed());
|
||||
_valueEdit->setText(value.trimmed());
|
||||
});
|
||||
);
|
||||
|
||||
QLayout* layout = new QVBoxLayout;
|
||||
QLabel* label = new QLabel("Select a line from the Script Log to add");
|
||||
|
||||
@@ -23,15 +23,21 @@
|
||||
****************************************************************************************/
|
||||
|
||||
#include "profile/scriptlogdialog.h"
|
||||
|
||||
#include "profile/line.h"
|
||||
#include <openspace/engine/configuration.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/scene/profile.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/fmt.h>
|
||||
#include <QGridLayout>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QListWidget>
|
||||
#include <QFile>
|
||||
#include <QPushButton>
|
||||
#include <QTextStream>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
ScriptlogDialog::ScriptlogDialog(QWidget* parent)
|
||||
: QDialog(parent)
|
||||
@@ -39,32 +45,43 @@ ScriptlogDialog::ScriptlogDialog(QWidget* parent)
|
||||
setWindowTitle("Scriptlog");
|
||||
createWidgets();
|
||||
|
||||
QFile file(QString::fromStdString(absPath("${LOGS}/scriptLog.txt").string()));
|
||||
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
QTextStream in(&file);
|
||||
while (!in.atEnd()) {
|
||||
QString line = in.readLine();
|
||||
// removing return from a few statments
|
||||
// these are usually generated by gui panels
|
||||
line.remove(QRegularExpression("^return "));
|
||||
if (!line.isEmpty()) {
|
||||
_scriptlogList->addItem(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
loadScriptFile();
|
||||
}
|
||||
|
||||
void ScriptlogDialog::createWidgets() {
|
||||
QBoxLayout* layout = new QVBoxLayout(this);
|
||||
// Column 0 Column 1
|
||||
// *-------------------------*------------*
|
||||
// | Title |
|
||||
// *--------------------------------------*
|
||||
// | Filter scripts * Reload |
|
||||
// *--------------------------------------*
|
||||
// | Script list |
|
||||
// *--------------------------------------*
|
||||
// * Save Cancel *
|
||||
// *-------------------------*------------*
|
||||
|
||||
QGridLayout* layout = new QGridLayout(this);
|
||||
{
|
||||
QLabel* heading = new QLabel("Choose commands from log/scriptLog.txt");
|
||||
QLabel* heading = new QLabel(QString::fromStdString(fmt::format(
|
||||
"Choose commands from \"{}\"", openspace::global::configuration->scriptLog
|
||||
)));
|
||||
heading->setObjectName("heading");
|
||||
layout->addWidget(heading);
|
||||
layout->addWidget(heading, 0, 0, 1, 2);
|
||||
}
|
||||
|
||||
_filter = new QLineEdit;
|
||||
_filter->setPlaceholderText("Filter the list of scripts");
|
||||
connect(_filter, &QLineEdit::textEdited, this, &ScriptlogDialog::updateScriptList);
|
||||
layout->addWidget(_filter, 1, 0);
|
||||
|
||||
_reloadFile = new QPushButton("Reload");
|
||||
_reloadFile->setToolTip("Reload the script log file");
|
||||
connect(_reloadFile, &QPushButton::clicked, this, &ScriptlogDialog::loadScriptFile);
|
||||
layout->addWidget(_reloadFile, 1, 1);
|
||||
|
||||
_scriptlogList = new QListWidget;
|
||||
_scriptlogList->setSelectionMode(QAbstractItemView::SelectionMode::MultiSelection);
|
||||
layout->addWidget(_scriptlogList);
|
||||
layout->addWidget(_scriptlogList, 2, 0, 1, 2);
|
||||
|
||||
layout->addWidget(new Line);
|
||||
{
|
||||
@@ -78,10 +95,47 @@ void ScriptlogDialog::createWidgets() {
|
||||
buttons, &QDialogButtonBox::rejected,
|
||||
this, &ScriptlogDialog::reject
|
||||
);
|
||||
layout->addWidget(buttons);
|
||||
layout->addWidget(buttons, 3, 0, 1, 2);
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptlogDialog::loadScriptFile() {
|
||||
std::string log = absPath(openspace::global::configuration->scriptLog).string();
|
||||
QFile file(QString::fromStdString(log));
|
||||
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
QTextStream in(&file);
|
||||
while (!in.atEnd()) {
|
||||
QString line = in.readLine();
|
||||
// removing return from statements which are usually generated by gui panels
|
||||
line.remove(QRegularExpression("^return "));
|
||||
if (!line.isEmpty()) {
|
||||
_scripts.push_back(line.toStdString());
|
||||
}
|
||||
}
|
||||
}
|
||||
updateScriptList();
|
||||
}
|
||||
|
||||
void ScriptlogDialog::updateScriptList() {
|
||||
std::string filter = _filter->text().toStdString();
|
||||
QListWidgetItem* curr = _scriptlogList->currentItem();
|
||||
std::string selection;
|
||||
if (curr) {
|
||||
selection = curr->text().toStdString();
|
||||
}
|
||||
int index = -1;
|
||||
_scriptlogList->clear();
|
||||
for (const std::string& script : _scripts) {
|
||||
if (script.find(filter) != std::string::npos) {
|
||||
if (script == selection && index == -1) {
|
||||
index = _scriptlogList->count();
|
||||
}
|
||||
_scriptlogList->addItem(QString::fromStdString(script));
|
||||
}
|
||||
}
|
||||
_scriptlogList->setCurrentRow(index != -1 ? index : 0);
|
||||
}
|
||||
|
||||
void ScriptlogDialog::saveChosenScripts() {
|
||||
std::string chosenScripts;
|
||||
QList<QListWidgetItem*> itemList = _scriptlogList->selectedItems();
|
||||
|
||||
@@ -49,7 +49,7 @@ TimeDialog::TimeDialog(QWidget* parent, std::optional<openspace::Profile::Time>*
|
||||
if (_time->has_value()) {
|
||||
_timeData = **_time;
|
||||
if (_timeData.type == Profile::Time::Type::Relative) {
|
||||
if (_timeData.value == "") {
|
||||
if (_timeData.value.empty()) {
|
||||
_timeData.value = "0d";
|
||||
}
|
||||
_relativeEdit->setSelection(0, _relativeEdit->text().length());
|
||||
@@ -81,6 +81,7 @@ void TimeDialog::createWidgets() {
|
||||
{
|
||||
_absoluteLabel = new QLabel("Absolute UTC:");
|
||||
layout->addWidget(_absoluteLabel);
|
||||
|
||||
_absoluteEdit = new QDateTimeEdit;
|
||||
_absoluteEdit->setDisplayFormat("yyyy-MM-dd T hh:mm:ss");
|
||||
_absoluteEdit->setDateTime(QDateTime::currentDateTime());
|
||||
@@ -89,6 +90,7 @@ void TimeDialog::createWidgets() {
|
||||
{
|
||||
_relativeLabel = new QLabel("Relative Time:");
|
||||
layout->addWidget(_relativeLabel);
|
||||
|
||||
_relativeEdit = new QLineEdit;
|
||||
_relativeEdit->setToolTip(
|
||||
"String for relative time to actual (e.g. \"-1d\" for back 1 day)"
|
||||
|
||||
@@ -24,93 +24,112 @@
|
||||
|
||||
#include "sgctedit/displaywindowunion.h"
|
||||
|
||||
#include <ghoul/fmt.h>
|
||||
#include "sgctedit/monitorbox.h"
|
||||
#include "sgctedit/windowcontrol.h"
|
||||
#include <QApplication>
|
||||
#include <QMainWindow>
|
||||
#include <QScreen>
|
||||
#include <ghoul/fmt.h>
|
||||
#include <QColor>
|
||||
#include <QFrame>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
DisplayWindowUnion::DisplayWindowUnion(std::shared_ptr<MonitorBox> monitorRenderBox,
|
||||
std::vector<QRect>& monitorSizeList, unsigned int nMaxWindows,
|
||||
const std::array<QColor, 4>& winColors)
|
||||
: _monBox(monitorRenderBox)
|
||||
, _monitorResolutions(monitorSizeList)
|
||||
, _nMaxWindows(nMaxWindows)
|
||||
, _winColors(winColors)
|
||||
DisplayWindowUnion::DisplayWindowUnion(const std::vector<QRect>& monitorSizeList,
|
||||
int nMaxWindows,
|
||||
const std::array<QColor, 4>& windowColors,
|
||||
QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
_addWindowButton = new QPushButton("Add Window");
|
||||
_removeWindowButton = new QPushButton("Remove Window");
|
||||
//Add all window controls (some will be hidden from GUI initially)
|
||||
for (unsigned int i = 0; i < _nMaxWindows; ++i) {
|
||||
initializeWindowControl();
|
||||
}
|
||||
connect(
|
||||
_addWindowButton,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&DisplayWindowUnion::addWindow
|
||||
);
|
||||
connect(
|
||||
_removeWindowButton,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&DisplayWindowUnion::removeWindow
|
||||
);
|
||||
initializeLayout();
|
||||
createWidgets(nMaxWindows, monitorSizeList, windowColors);
|
||||
showWindows();
|
||||
}
|
||||
|
||||
void DisplayWindowUnion::initializeLayout() {
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
void DisplayWindowUnion::createWidgets(int nMaxWindows,
|
||||
std::vector<QRect> monitorResolutions,
|
||||
std::array<QColor, 4> windowColors)
|
||||
{
|
||||
// Add all window controls (some will be hidden from GUI initially)
|
||||
for (unsigned int i = 0; i < nMaxWindows; ++i) {
|
||||
const unsigned int monitorNumForThisWindow = (nMaxWindows > 3 && i >= 2) ? 1 : 0;
|
||||
|
||||
WindowControl* ctrl = new WindowControl(
|
||||
monitorNumForThisWindow,
|
||||
i,
|
||||
monitorResolutions,
|
||||
windowColors[i],
|
||||
this
|
||||
);
|
||||
_windowControl.push_back(ctrl);
|
||||
|
||||
connect(
|
||||
ctrl, &WindowControl::windowChanged,
|
||||
this, &DisplayWindowUnion::windowChanged
|
||||
);
|
||||
}
|
||||
|
||||
QBoxLayout* layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->setSizeConstraint(QLayout::SizeConstraint::SetMinimumSize);
|
||||
|
||||
{
|
||||
QHBoxLayout* layoutMonButton = new QHBoxLayout;
|
||||
QBoxLayout* layoutMonButton = new QHBoxLayout;
|
||||
_removeWindowButton = new QPushButton("Remove Window");
|
||||
_removeWindowButton->setFocusPolicy(Qt::NoFocus);
|
||||
_removeWindowButton->setToolTip(
|
||||
"Remove window from the configuration (at least one window is required)"
|
||||
);
|
||||
std::string addTip = fmt::format(
|
||||
"Add a window to the configuration (up to {} windows allowed)", _nMaxWindows
|
||||
connect(
|
||||
_removeWindowButton, &QPushButton::clicked,
|
||||
this, &DisplayWindowUnion::removeWindow
|
||||
);
|
||||
_addWindowButton->setToolTip(QString::fromStdString(addTip));
|
||||
_addWindowButton->setFocusPolicy(Qt::NoFocus);
|
||||
_removeWindowButton->setFocusPolicy(Qt::NoFocus);
|
||||
layoutMonButton->addWidget(_removeWindowButton);
|
||||
|
||||
layoutMonButton->addStretch(1);
|
||||
|
||||
_addWindowButton = new QPushButton("Add Window");
|
||||
_addWindowButton->setToolTip(QString::fromStdString(fmt::format(
|
||||
"Add a window to the configuration (up to {} windows allowed)", nMaxWindows
|
||||
)));
|
||||
_addWindowButton->setFocusPolicy(Qt::NoFocus);
|
||||
connect(
|
||||
_addWindowButton, &QPushButton::clicked,
|
||||
this, &DisplayWindowUnion::addWindow
|
||||
);
|
||||
layoutMonButton->addWidget(_addWindowButton);
|
||||
layout->addLayout(layoutMonButton);
|
||||
}
|
||||
QHBoxLayout* layoutWindows = new QHBoxLayout;
|
||||
layout->addStretch();
|
||||
|
||||
for (unsigned int i = 0; i < _nMaxWindows; ++i) {
|
||||
QVBoxLayout* layoutForNextWindow = _windowControl[i]->initializeLayout();
|
||||
_winCtrlLayouts.push_back(layoutForNextWindow);
|
||||
QWidget* layoutWrapper = new QWidget();
|
||||
layoutWrapper->setLayout(layoutForNextWindow);
|
||||
_layoutWindowWrappers.push_back(layoutWrapper);
|
||||
layoutWindows->addWidget(layoutWrapper);
|
||||
if (i < (_nMaxWindows - 1)) {
|
||||
QFrame* frameForNextWindow = new QFrame();
|
||||
QFrame* line = new QFrame;
|
||||
line->setFrameShape(QFrame::HLine);
|
||||
line->setFrameShadow(QFrame::Sunken);
|
||||
layout->addWidget(line);
|
||||
|
||||
QBoxLayout* layoutWindows = new QHBoxLayout;
|
||||
layoutWindows->setContentsMargins(0, 0, 0, 0);
|
||||
layoutWindows->setSpacing(0);
|
||||
for (int i = 0; i < nMaxWindows; ++i) {
|
||||
layoutWindows->addWidget(_windowControl[i]);
|
||||
if (i < (nMaxWindows - 1)) {
|
||||
QFrame* frameForNextWindow = new QFrame;
|
||||
frameForNextWindow->setFrameShape(QFrame::VLine);
|
||||
_frameBorderLines.push_back(frameForNextWindow);
|
||||
layoutWindows->addWidget(frameForNextWindow);
|
||||
}
|
||||
}
|
||||
_nWindowsDisplayed = 1;
|
||||
showWindows();
|
||||
layout->addLayout(layoutWindows);
|
||||
layout->addStretch();
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<WindowControl>> DisplayWindowUnion::windowControls() const {
|
||||
return _windowControl;
|
||||
}
|
||||
|
||||
unsigned int DisplayWindowUnion::nWindows() const {
|
||||
return _nWindowsDisplayed;
|
||||
std::vector<WindowControl*> DisplayWindowUnion::windowControls() const {
|
||||
std::vector<WindowControl*> res;
|
||||
res.reserve(_nWindowsDisplayed);
|
||||
for (unsigned int i = 0; i < _nWindowsDisplayed; ++i) {
|
||||
res.push_back(_windowControl[i]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void DisplayWindowUnion::addWindow() {
|
||||
if (_nWindowsDisplayed < _nMaxWindows) {
|
||||
if (_nWindowsDisplayed < _windowControl.size()) {
|
||||
_windowControl[_nWindowsDisplayed]->resetToDefaults();
|
||||
_nWindowsDisplayed++;
|
||||
showWindows();
|
||||
@@ -125,55 +144,16 @@ void DisplayWindowUnion::removeWindow() {
|
||||
}
|
||||
|
||||
void DisplayWindowUnion::showWindows() {
|
||||
for (size_t i = 0; i < _layoutWindowWrappers.size(); ++i) {
|
||||
_layoutWindowWrappers[i]->setVisible(i < _nWindowsDisplayed);
|
||||
for (size_t i = 0; i < _windowControl.size(); ++i) {
|
||||
_windowControl[i]->setVisible(i < _nWindowsDisplayed);
|
||||
}
|
||||
for (size_t i = 0; i < _frameBorderLines.size(); ++i) {
|
||||
_frameBorderLines[i]->setVisible(i < (_nWindowsDisplayed - 1));
|
||||
}
|
||||
_removeWindowButton->setEnabled(_nWindowsDisplayed > 1);
|
||||
_addWindowButton->setEnabled(_nWindowsDisplayed != _nMaxWindows);
|
||||
for (std::shared_ptr<WindowControl> w : _windowControl) {
|
||||
_addWindowButton->setEnabled(_nWindowsDisplayed != _windowControl.size());
|
||||
for (WindowControl* w : _windowControl) {
|
||||
w->showWindowLabel(_nWindowsDisplayed > 1);
|
||||
}
|
||||
_monBox->setNumWindowsDisplayed(_nWindowsDisplayed);
|
||||
emit nWindowsChanged(_nWindowsDisplayed);
|
||||
}
|
||||
|
||||
void DisplayWindowUnion::initializeWindowControl() {
|
||||
if (_nWindowsAllocated < _nMaxWindows) {
|
||||
unsigned int monitorNumForThisWindow = 0;
|
||||
if (_nMaxWindows > 3 && _nWindowsAllocated >= 2) {
|
||||
monitorNumForThisWindow = 1;
|
||||
}
|
||||
_windowControl.push_back(
|
||||
std::make_shared<WindowControl>(
|
||||
monitorNumForThisWindow,
|
||||
_nWindowsAllocated,
|
||||
_monitorResolutions,
|
||||
_winColors[_nWindowsAllocated],
|
||||
this
|
||||
)
|
||||
);
|
||||
_windowControl.back()->setWindowChangeCallback(
|
||||
[this](int monIndex, int winIndex, const QRectF& newDims) {
|
||||
_monBox->windowDimensionsChanged(monIndex, winIndex, newDims);
|
||||
}
|
||||
);
|
||||
_windowControl.back()->setWebGuiChangeCallback(
|
||||
[this](unsigned int winIndex) {
|
||||
for (unsigned int w = 0; w < _nMaxWindows; ++w) {
|
||||
if (w != winIndex) {
|
||||
_windowControl[w]->uncheckWebGuiOption();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
_monBox->mapWindowResolutionToWidgetCoordinates(
|
||||
monitorNumForThisWindow,
|
||||
_nWindowsAllocated,
|
||||
_windowControl.back()->dimensions()
|
||||
);
|
||||
_nWindowsAllocated++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,291 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2022 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include "sgctedit/filesupport.h"
|
||||
|
||||
FileSupport::FileSupport(QVBoxLayout* parentLayout,
|
||||
UserConfigurationElements& cfgElements,
|
||||
SgctConfigElements& sgctElements,
|
||||
std::function<void(bool)> finishedCallback)
|
||||
: _displayWidget(cfgElements.display)
|
||||
, _orientationWidget(cfgElements.orientation)
|
||||
, _monitors(cfgElements.monitorList)
|
||||
, _cluster(sgctElements.cluster)
|
||||
, _windowList(sgctElements.windowList)
|
||||
, _finishedCallback(finishedCallback)
|
||||
, _userConfigPath(cfgElements.configSavePath)
|
||||
{
|
||||
QVBoxLayout* layoutFullVertical = new QVBoxLayout;
|
||||
_saveButton = new QPushButton("Save As");
|
||||
_saveButton->setToolTip("Save configuration changes (opens file chooser dialog)");
|
||||
_saveButton->setFocusPolicy(Qt::NoFocus);
|
||||
connect(_saveButton, &QPushButton::released, this, &FileSupport::save);
|
||||
_cancelButton = new QPushButton("Cancel");
|
||||
_cancelButton->setToolTip("Cancel changes");
|
||||
_cancelButton->setFocusPolicy(Qt::NoFocus);
|
||||
connect(_cancelButton, &QPushButton::released, this, &FileSupport::cancel);
|
||||
_applyButton = new QPushButton("Apply Without Saving");
|
||||
_applyButton->setToolTip("Apply configuration changes without saving to file");
|
||||
_applyButton->setFocusPolicy(Qt::NoFocus);
|
||||
connect(_applyButton, &QPushButton::released, this, &FileSupport::apply);
|
||||
{
|
||||
QHBoxLayout* layoutButtonBox = new QHBoxLayout;
|
||||
layoutButtonBox->addStretch(1);
|
||||
layoutButtonBox->addWidget(_cancelButton);
|
||||
layoutButtonBox->addWidget(_saveButton);
|
||||
layoutButtonBox->addWidget(_applyButton);
|
||||
layoutFullVertical->addLayout(layoutButtonBox);
|
||||
}
|
||||
parentLayout->addLayout(layoutFullVertical);
|
||||
}
|
||||
|
||||
void FileSupport::saveCluster() {
|
||||
if (_orientationWidget) {
|
||||
sgct::config::Scene initScene;
|
||||
initScene.orientation = _orientationWidget->orientationValue();
|
||||
_cluster.nodes.clear();
|
||||
sgct::config::Node tmpNode;
|
||||
tmpNode.address = "localhost";
|
||||
tmpNode.port = 20401;
|
||||
_cluster.nodes.push_back(tmpNode);
|
||||
_cluster.masterAddress = "localhost";
|
||||
_cluster.scene = std::move(initScene);
|
||||
_cluster.firmSync = _orientationWidget->vsyncValue();
|
||||
}
|
||||
}
|
||||
|
||||
void FileSupport::saveUser() {
|
||||
if (_orientationWidget) {
|
||||
sgct::config::User user;
|
||||
user.eyeSeparation = 0.065f;
|
||||
user.position = {0.0f, 0.0f, 4.0f};
|
||||
_cluster.users.push_back(user);
|
||||
}
|
||||
}
|
||||
|
||||
bool FileSupport::isWindowFullscreen(unsigned int monitorIdx, sgct::ivec2 wDims) {
|
||||
return (_monitors[monitorIdx].width() == wDims.x &&
|
||||
_monitors[monitorIdx].height() == wDims.y);
|
||||
}
|
||||
|
||||
std::optional<unsigned int> FileSupport::findGuiWindow() {
|
||||
unsigned int windowIndex = 0;
|
||||
for (unsigned int w = 0; w < _displayWidget->nWindows(); ++w) {
|
||||
if (_displayWidget->windowControls()[w]->isGuiWindow()) {
|
||||
return std::optional<unsigned int>(windowIndex);
|
||||
}
|
||||
windowIndex++;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void FileSupport::saveWindows() {
|
||||
unsigned int windowIndex = 0;
|
||||
for (unsigned int w = 0; w < _displayWidget->nWindows(); ++w) {
|
||||
std::shared_ptr<WindowControl> wCtrl = _displayWidget->windowControls()[w];
|
||||
sgct::config::Window tmpWindow = saveWindowsDimensions(wCtrl);
|
||||
tmpWindow.viewports.push_back(generateViewport());
|
||||
tmpWindow.viewports.back().projection = saveProjectionInformation(wCtrl);
|
||||
tmpWindow.isDecorated = wCtrl->isDecorated();
|
||||
tmpWindow.isFullScreen = isWindowFullscreen(
|
||||
wCtrl->monitorNum(),
|
||||
wCtrl->windowSize()
|
||||
);
|
||||
if (tmpWindow.isFullScreen) {
|
||||
tmpWindow.monitor = wCtrl->monitorNum();
|
||||
}
|
||||
saveWindowsWebGui(windowIndex, tmpWindow);
|
||||
if (!wCtrl->windowName().empty()) {
|
||||
tmpWindow.name = wCtrl->windowName();
|
||||
}
|
||||
tmpWindow.id = windowIndex++;
|
||||
_windowList.push_back(tmpWindow);
|
||||
}
|
||||
}
|
||||
|
||||
sgct::config::Viewport FileSupport::generateViewport() {
|
||||
sgct::config::Viewport vp;
|
||||
vp.isTracked = true;
|
||||
vp.position = {0.f, 0.f};
|
||||
vp.size = {1.f, 1.f};
|
||||
return vp;
|
||||
}
|
||||
|
||||
sgct::config::Window FileSupport::saveWindowsDimensions(
|
||||
std::shared_ptr<WindowControl> wCtrl)
|
||||
{
|
||||
sgct::config::Window tmpWindow;
|
||||
tmpWindow.size = wCtrl->windowSize();
|
||||
tmpWindow.pos = {
|
||||
_monitors[wCtrl->monitorNum()].x() + wCtrl->windowPos().x,
|
||||
_monitors[wCtrl->monitorNum()].y() + wCtrl->windowPos().y,
|
||||
};
|
||||
return tmpWindow;
|
||||
}
|
||||
|
||||
void FileSupport::saveWindowsWebGui(unsigned int wIdx, sgct::config::Window& win) {
|
||||
win.viewports.back().isTracked = true;
|
||||
std::optional<unsigned int> webGuiWindowIndex = findGuiWindow();
|
||||
bool isOneOfWindowsSetAsWebGui = webGuiWindowIndex.has_value();
|
||||
if (isOneOfWindowsSetAsWebGui) {
|
||||
if (wIdx == webGuiWindowIndex.value()) {
|
||||
win.viewports.back().isTracked = false;
|
||||
win.tags.push_back("GUI");
|
||||
}
|
||||
win.draw2D = (wIdx == webGuiWindowIndex.value());
|
||||
win.draw3D = !(win.draw2D.value());
|
||||
}
|
||||
}
|
||||
|
||||
ProjectionOptions FileSupport::saveProjectionInformation(
|
||||
std::shared_ptr<WindowControl> winControl)
|
||||
{
|
||||
if (winControl->isSpoutSelected()) {
|
||||
return saveProjectionSpout(winControl);
|
||||
}
|
||||
else {
|
||||
return saveProjectionNoSpout(winControl);
|
||||
}
|
||||
}
|
||||
|
||||
ProjectionOptions FileSupport::saveProjectionSpout(
|
||||
std::shared_ptr<WindowControl> winControl)
|
||||
{
|
||||
sgct::config::SpoutOutputProjection projection;
|
||||
switch(winControl->projectionSelectedIndex()) {
|
||||
case WindowControl::ProjectionIndeces::Fisheye:
|
||||
projection.mapping
|
||||
= sgct::config::SpoutOutputProjection::Mapping::Fisheye;
|
||||
break;
|
||||
|
||||
case WindowControl::ProjectionIndeces::Equirectangular:
|
||||
default:
|
||||
projection.mapping
|
||||
= sgct::config::SpoutOutputProjection::Mapping::Equirectangular;
|
||||
break;
|
||||
}
|
||||
projection.quality = winControl->qualitySelectedValue();
|
||||
projection.mappingSpoutName = "OpenSpace";
|
||||
return projection;
|
||||
}
|
||||
|
||||
ProjectionOptions FileSupport::saveProjectionNoSpout(
|
||||
std::shared_ptr<WindowControl> winControl)
|
||||
{
|
||||
switch(winControl->projectionSelectedIndex()) {
|
||||
case WindowControl::ProjectionIndeces::Fisheye:
|
||||
{
|
||||
sgct::config::FisheyeProjection projection;
|
||||
projection.quality = winControl->qualitySelectedValue();
|
||||
projection.fov = 180.f;
|
||||
projection.tilt = 0.f;
|
||||
return projection;
|
||||
}
|
||||
break;
|
||||
|
||||
case WindowControl::ProjectionIndeces::SphericalMirror:
|
||||
{
|
||||
sgct::config::SphericalMirrorProjection projection;
|
||||
projection.quality = winControl->qualitySelectedValue();
|
||||
return projection;
|
||||
}
|
||||
break;
|
||||
|
||||
case WindowControl::ProjectionIndeces::Cylindrical:
|
||||
{
|
||||
sgct::config::CylindricalProjection projection;
|
||||
projection.quality = winControl->qualitySelectedValue();
|
||||
projection.heightOffset = winControl->heightOffset();
|
||||
return projection;
|
||||
}
|
||||
break;
|
||||
|
||||
case WindowControl::ProjectionIndeces::Equirectangular:
|
||||
{
|
||||
sgct::config::EquirectangularProjection projection;
|
||||
projection.quality = winControl->qualitySelectedValue();
|
||||
return projection;
|
||||
}
|
||||
break;
|
||||
|
||||
case WindowControl::ProjectionIndeces::Planar:
|
||||
default:
|
||||
{
|
||||
// The negative values for left & down are according to sgct's convention
|
||||
sgct::config::PlanarProjection projection;
|
||||
projection.fov.right = winControl->fovH() / 2.0;
|
||||
projection.fov.left = -projection.fov.right;
|
||||
projection.fov.up = winControl->fovV() / 2.0;
|
||||
projection.fov.down = -projection.fov.up;
|
||||
return projection;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string FileSupport::saveFilename() {
|
||||
return _saveTarget;
|
||||
}
|
||||
|
||||
void FileSupport::save() {
|
||||
QString fileName = QFileDialog::getSaveFileName(
|
||||
this,
|
||||
"Save Window Configuration File",
|
||||
QString::fromStdString(_userConfigPath),
|
||||
"Window Configuration (*.json);;(*.json)",
|
||||
nullptr
|
||||
#ifdef __linux__
|
||||
, QFileDialog::DontUseNativeDialog
|
||||
#endif
|
||||
);
|
||||
if (fileName.length() != 0) {
|
||||
_saveTarget = fileName.toStdString();
|
||||
saveConfigToSgctFormat();
|
||||
_finishedCallback(true);
|
||||
}
|
||||
}
|
||||
|
||||
void FileSupport::cancel() {
|
||||
_finishedCallback(false);
|
||||
}
|
||||
|
||||
void FileSupport::apply() {
|
||||
std::string userCfgTempDir = _userConfigPath;
|
||||
if (userCfgTempDir.back() != '/') {
|
||||
userCfgTempDir += "/";
|
||||
}
|
||||
userCfgTempDir += "temp";
|
||||
if (!std::filesystem::is_directory(userCfgTempDir)) {
|
||||
std::filesystem::create_directories(absPath(userCfgTempDir));
|
||||
}
|
||||
_saveTarget = userCfgTempDir + "/" + "apply-without-saving.json";
|
||||
saveConfigToSgctFormat();
|
||||
_finishedCallback(true);
|
||||
}
|
||||
|
||||
void FileSupport::saveConfigToSgctFormat() {
|
||||
saveCluster();
|
||||
saveWindows();
|
||||
saveUser();
|
||||
}
|
||||
@@ -24,232 +24,183 @@
|
||||
|
||||
#include "sgctedit/monitorbox.h"
|
||||
|
||||
constexpr float MarginFractionOfWidgetSize = 0.05f;
|
||||
#include <QPainter>
|
||||
|
||||
MonitorBox::MonitorBox(QRect widgetDims, std::vector<QRect> monitorResolution,
|
||||
unsigned int nWindows, const std::array<QColor, 4>& winColors)
|
||||
: _monitorWidgetSize(widgetDims)
|
||||
, _monitorResolution(monitorResolution)
|
||||
namespace {
|
||||
constexpr float MarginFractionOfWidgetSize = 0.05f;
|
||||
constexpr int WindowOpacity = 170;
|
||||
|
||||
QRectF computeUnion(const std::vector<QRect>& monitorResolutions) {
|
||||
QRectF res = { 0.f, 0.f, 0.f, 0.f };
|
||||
for (const QRect& m : monitorResolutions) {
|
||||
res |= m;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
MonitorBox::MonitorBox(QRect widgetDims, const std::vector<QRect>& monitorResolutions,
|
||||
unsigned int nWindows, const std::array<QColor, 4>& windowColors,
|
||||
QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, _nWindows(nWindows)
|
||||
, _colorsForWindows(winColors)
|
||||
, _colorsForWindows(windowColors)
|
||||
{
|
||||
_nMonitors = static_cast<unsigned int>(monitorResolution.size());
|
||||
_showLabel = (_nMonitors > 1);
|
||||
determineMonitorArrangement();
|
||||
this->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
float borderMargin = MarginFractionOfWidgetSize * 2.f;
|
||||
if (_monitorArrangementAspectRatio > 1.0) {
|
||||
borderMargin *= _monitorWidgetSize.width();
|
||||
_monitorWidgetSize.setHeight(_monitorWidgetSize.width()
|
||||
/ _monitorArrangementAspectRatio + borderMargin);
|
||||
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
|
||||
QRectF monitorArrangement = computeUnion(monitorResolutions);
|
||||
|
||||
const float aspectRatio = monitorArrangement.width() / monitorArrangement.height();
|
||||
if (aspectRatio > 1.0) {
|
||||
float borderMargin = 2.f * MarginFractionOfWidgetSize * widgetDims.width();
|
||||
widgetDims.setHeight(widgetDims.width() / aspectRatio + borderMargin);
|
||||
}
|
||||
else {
|
||||
borderMargin *= _monitorWidgetSize.height();
|
||||
_monitorWidgetSize.setWidth(_monitorWidgetSize.height()
|
||||
* _monitorArrangementAspectRatio + borderMargin);
|
||||
float borderMargin = 2.f * MarginFractionOfWidgetSize * widgetDims.height();
|
||||
widgetDims.setWidth(widgetDims.height() * aspectRatio + borderMargin);
|
||||
}
|
||||
setFixedSize(widgetDims.width(), widgetDims.height());
|
||||
|
||||
//
|
||||
// Map monitor resolution to widget coordinates
|
||||
std::vector<QSizeF> offsets =
|
||||
aspectRatio >= 1.f ?
|
||||
computeScaledResolutionLandscape(monitorArrangement, monitorResolutions) :
|
||||
computeScaledResolutionPortrait(monitorArrangement, monitorResolutions);
|
||||
|
||||
for (size_t i = 0; i < monitorResolutions.size(); ++i) {
|
||||
_monitorDimensionsScaled.emplace_back(
|
||||
offsets[i].width(),
|
||||
offsets[i].height(),
|
||||
monitorResolutions[i].width() * _monitorScaleFactor,
|
||||
monitorResolutions[i].height() * _monitorScaleFactor
|
||||
);
|
||||
}
|
||||
this->setFixedSize(_monitorWidgetSize.width(), _monitorWidgetSize.height());
|
||||
mapMonitorResolutionToWidgetCoordinates();
|
||||
}
|
||||
|
||||
void MonitorBox::paintEvent(QPaintEvent* event) {
|
||||
Q_UNUSED(event)
|
||||
void MonitorBox::paintEvent(QPaintEvent*) {
|
||||
QPainter painter(this);
|
||||
QPen pen = painter.pen();
|
||||
painter.setPen(pen);
|
||||
paintWidgetBorder(painter, width(), height());
|
||||
//Draw window out-of-bounds region(s) first
|
||||
for (unsigned int i = 0; i < _nWindows; ++i) {
|
||||
paintWindowBeyondBounds(painter, i);
|
||||
}
|
||||
//Draw & fill monitors over the out-of-bounds regions
|
||||
paintMonitorBackgrounds(painter);
|
||||
//Draw window number(s) first for darker contrast, then window(s) over both
|
||||
//out-of-bounds and monitors
|
||||
for (unsigned int i = 0; i < _nWindows; ++i) {
|
||||
paintWindowNumber(painter, i);
|
||||
}
|
||||
for (unsigned int i = 0; i < _nWindows; ++i) {
|
||||
paintWindow(painter, i);
|
||||
}
|
||||
}
|
||||
|
||||
void MonitorBox::paintWidgetBorder(QPainter& painter, int width, int height) {
|
||||
//
|
||||
// Draw widget border
|
||||
constexpr int Radius = 10;
|
||||
painter.setPen(QPen(Qt::gray, 4));
|
||||
painter.drawRoundedRect(0, 0, width - 1, height - 1, Radius, Radius);
|
||||
}
|
||||
painter.drawRoundedRect(0, 0, width() - 1, height() - 1, Radius, Radius);
|
||||
|
||||
void MonitorBox::paintMonitorBackgrounds(QPainter& painter) {
|
||||
//
|
||||
// Draw window out-of-bounds region(s) first
|
||||
for (int i = 0; i < _nWindows; ++i) {
|
||||
painter.setBrush(Qt::BDiagPattern);
|
||||
painter.setPen(QPen(_colorsForWindows[i], 0));
|
||||
painter.drawRect(_windowRendering[i]);
|
||||
}
|
||||
|
||||
// Draw & fill monitors over the out-of-bounds regions
|
||||
painter.setPen(QPen(Qt::black, 2));
|
||||
QFont f("Arial");
|
||||
f.setPixelSize(24);
|
||||
painter.setFont(f);
|
||||
for (unsigned int i = 0; i < _nMonitors; ++i) {
|
||||
if (i <= _monitorDimensionsScaled.size()) {
|
||||
painter.drawRect(_monitorDimensionsScaled[i]);
|
||||
QColor fillColor("#DDDDDD");
|
||||
QBrush brush(fillColor);
|
||||
brush.setStyle(Qt::SolidPattern);
|
||||
painter.fillRect(_monitorDimensionsScaled[i], brush);
|
||||
if (_showLabel) {
|
||||
QPointF textPos = QPointF(
|
||||
_monitorDimensionsScaled[i].left() + 4,
|
||||
_monitorDimensionsScaled[i].top() + 24
|
||||
);
|
||||
if (i == 0) {
|
||||
painter.drawText(textPos, "Primary");
|
||||
}
|
||||
}
|
||||
painter.setBrush(Qt::NoBrush);
|
||||
|
||||
for (size_t i = 0; i < _monitorDimensionsScaled.size(); ++i) {
|
||||
const QColor Grey = QColor(0xDD, 0xDD, 0xDD);
|
||||
|
||||
painter.drawRect(_monitorDimensionsScaled[i]);
|
||||
painter.fillRect(_monitorDimensionsScaled[i], QBrush(Grey, Qt::SolidPattern));
|
||||
|
||||
if (_monitorDimensionsScaled.size() > 1 && i == 0) {
|
||||
// We only want to render the "Primary" if there are multiple windows
|
||||
QPointF textPos = QPointF(
|
||||
_monitorDimensionsScaled[i].left() + 4.0,
|
||||
_monitorDimensionsScaled[i].top() + 24.0
|
||||
);
|
||||
QFont f("Arial");
|
||||
f.setPixelSize(24);
|
||||
painter.setFont(f);
|
||||
painter.drawText(textPos, "Primary");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MonitorBox::paintWindowBeyondBounds(QPainter& painter, unsigned int winIdx) {
|
||||
painter.setBrush(Qt::BDiagPattern);
|
||||
setPenSpecificToWindow(painter, winIdx, false);
|
||||
if (winIdx <= _windowRendering.size()) {
|
||||
painter.drawRect(_windowRendering[winIdx]);
|
||||
// Draw window number(s) first for darker contrast, then window(s) over both
|
||||
// out-of-bounds and monitors
|
||||
for (int i = 0; i < _nWindows; ++i) {
|
||||
QPointF p = QPointF(
|
||||
_windowRendering[i].left() + 5.0,
|
||||
_windowRendering[i].bottom() - 5.0
|
||||
);
|
||||
p.setX(std::clamp(p.x(), 0.0, static_cast<double>(size().width()) - 10.0));
|
||||
p.setY(std::clamp(p.y(), 20.0, static_cast<double>(size().height())));
|
||||
painter.drawText(p, QString::number(i + 1));
|
||||
}
|
||||
setPenSpecificToWindow(painter, winIdx, true);
|
||||
painter.setBrush(Qt::NoBrush);
|
||||
}
|
||||
|
||||
void MonitorBox::paintWindow(QPainter& painter, size_t winIdx) {
|
||||
setPenSpecificToWindow(painter, static_cast<unsigned int>(winIdx), true);
|
||||
if (winIdx <= _windowRendering.size()) {
|
||||
painter.drawRect(_windowRendering[winIdx]);
|
||||
QColor fillColor = _colorsForWindows[winIdx];
|
||||
fillColor.setAlpha(_alphaWindowOpacity);
|
||||
QBrush brush(fillColor);
|
||||
brush.setStyle(Qt::SolidPattern);
|
||||
painter.fillRect(_windowRendering[winIdx], brush);
|
||||
//
|
||||
// Paint window
|
||||
for (int i = 0; i < _nWindows; ++i) {
|
||||
painter.setPen(QPen(_colorsForWindows[i], 1));
|
||||
painter.drawRect(_windowRendering[i]);
|
||||
|
||||
QColor fillColor = _colorsForWindows[i];
|
||||
fillColor.setAlpha(WindowOpacity);
|
||||
painter.fillRect(_windowRendering[i], QBrush(fillColor, Qt::SolidPattern));
|
||||
}
|
||||
}
|
||||
|
||||
void MonitorBox::paintWindowNumber(QPainter& painter, unsigned int winIdx) {
|
||||
QPointF textPos = QPointF(_windowRendering[winIdx].left() + 5,
|
||||
_windowRendering[winIdx].bottom() - 5);
|
||||
textPos.setX(std::clamp(textPos.x(), 0.0, _monitorWidgetSize.width() - 10));
|
||||
textPos.setY(std::clamp(textPos.y(), 20.0, _monitorWidgetSize.height()));
|
||||
painter.drawText(textPos, QString::fromStdString(std::to_string(winIdx + 1)));
|
||||
}
|
||||
|
||||
void MonitorBox::setPenSpecificToWindow(QPainter& painter, unsigned int windowIdx,
|
||||
bool visibleBorder)
|
||||
{
|
||||
int penWidth = (visibleBorder) ? 1 : -1;
|
||||
painter.setPen(QPen(_colorsForWindows[windowIdx], penWidth));
|
||||
}
|
||||
|
||||
void MonitorBox::windowDimensionsChanged(unsigned int mIdx, unsigned int wIdx,
|
||||
const QRectF& newDimensions)
|
||||
{
|
||||
mapWindowResolutionToWidgetCoordinates(mIdx, wIdx, newDimensions);
|
||||
}
|
||||
|
||||
void MonitorBox::determineMonitorArrangement() {
|
||||
for (const QRect& m : _monitorResolution) {
|
||||
if (m.x() < _negativeCorrectionOffsets.x()) {
|
||||
_negativeCorrectionOffsets.setX(m.x());
|
||||
}
|
||||
if (m.y() < _negativeCorrectionOffsets.y()) {
|
||||
_negativeCorrectionOffsets.setY(m.y());
|
||||
}
|
||||
}
|
||||
for (const QRect& m : _monitorResolution) {
|
||||
if ((m.x() + m.width() - _negativeCorrectionOffsets.x())
|
||||
> _monitorArrangementDimensions.width())
|
||||
{
|
||||
_monitorArrangementDimensions.setWidth(
|
||||
m.x() + m.width() - _negativeCorrectionOffsets.x());
|
||||
}
|
||||
if ((m.y() + m.height() - _negativeCorrectionOffsets.y())
|
||||
> _monitorArrangementDimensions.height())
|
||||
{
|
||||
_monitorArrangementDimensions.setHeight(
|
||||
m.y() + m.height() - _negativeCorrectionOffsets.y());
|
||||
}
|
||||
}
|
||||
_monitorArrangementAspectRatio = _monitorArrangementDimensions.width()
|
||||
/ _monitorArrangementDimensions.height();
|
||||
}
|
||||
|
||||
void MonitorBox::mapMonitorResolutionToWidgetCoordinates() {
|
||||
if (_monitorArrangementAspectRatio >= 1.0) {
|
||||
computeScaledResolutionLandscape(
|
||||
_monitorArrangementAspectRatio,
|
||||
_monitorArrangementDimensions.width()
|
||||
);
|
||||
}
|
||||
else {
|
||||
computeScaledResolutionPortrait(
|
||||
_monitorArrangementAspectRatio,
|
||||
_monitorArrangementDimensions.height()
|
||||
);
|
||||
}
|
||||
for (size_t m = 0; m < _monitorResolution.size(); ++m) {
|
||||
_monitorDimensionsScaled.push_back({
|
||||
_monitorOffsets[m].width(),
|
||||
_monitorOffsets[m].height(),
|
||||
_monitorResolution[m].width() * _monitorScaleFactor,
|
||||
_monitorResolution[m].height() * _monitorScaleFactor,
|
||||
});
|
||||
}
|
||||
_windowRendering[wIdx] = {
|
||||
_monitorDimensionsScaled[mIdx].x() + newDimensions.left() * _monitorScaleFactor,
|
||||
_monitorDimensionsScaled[mIdx].y() + newDimensions.top() * _monitorScaleFactor,
|
||||
newDimensions.width() * _monitorScaleFactor,
|
||||
newDimensions.height() * _monitorScaleFactor
|
||||
};
|
||||
update();
|
||||
}
|
||||
|
||||
void MonitorBox::computeScaledResolutionLandscape(float aspectRatio, float maxWidth) {
|
||||
_marginWidget = _monitorWidgetSize.width() * MarginFractionOfWidgetSize;
|
||||
float virtualWidth = _monitorWidgetSize.width()
|
||||
* (1.0 - MarginFractionOfWidgetSize * 2.0);
|
||||
_monitorScaleFactor = virtualWidth / maxWidth;
|
||||
float newHeight = virtualWidth / aspectRatio;
|
||||
for (size_t m = 0; m < _monitorResolution.size(); ++m) {
|
||||
_monitorOffsets.push_back({
|
||||
_marginWidget + (_monitorResolution[m].x() - _negativeCorrectionOffsets.x())
|
||||
* _monitorScaleFactor,
|
||||
_marginWidget + (_monitorWidgetSize.height() - newHeight - _marginWidget) / 4.0
|
||||
+ (_monitorResolution[m].y() - _negativeCorrectionOffsets.y())
|
||||
* _monitorScaleFactor
|
||||
});
|
||||
std::vector<QSizeF> MonitorBox::computeScaledResolutionLandscape(QRectF arrangement,
|
||||
const std::vector<QRect>& resolutions)
|
||||
{
|
||||
std::vector<QSizeF> offsets;
|
||||
|
||||
float marginWidget = size().width() * MarginFractionOfWidgetSize;
|
||||
float virtualWidth = size().width() * (1.f - MarginFractionOfWidgetSize * 2.f);
|
||||
_monitorScaleFactor = virtualWidth / arrangement.width();
|
||||
|
||||
const float aspectRatio = arrangement.width() / arrangement.height();
|
||||
const float newHeight = virtualWidth / aspectRatio;
|
||||
|
||||
for (const QRect& res : resolutions) {
|
||||
float x = marginWidget + (res.x() - arrangement.x()) * _monitorScaleFactor;
|
||||
float y = marginWidget + (size().height() - newHeight - marginWidget) / 4.f +
|
||||
(res.y() - arrangement.y()) * _monitorScaleFactor;
|
||||
offsets.emplace_back(x, y);
|
||||
}
|
||||
|
||||
return offsets;
|
||||
}
|
||||
|
||||
void MonitorBox::computeScaledResolutionPortrait(float aspectRatio, float maxHeight) {
|
||||
_marginWidget = _monitorWidgetSize.height() * MarginFractionOfWidgetSize;
|
||||
float virtualHeight = _monitorWidgetSize.height()
|
||||
* (1.0 - MarginFractionOfWidgetSize * 2.0);
|
||||
_monitorScaleFactor = virtualHeight / maxHeight;
|
||||
float newWidth = virtualHeight * aspectRatio;
|
||||
for (size_t m = 0; m < _monitorResolution.size(); ++m) {
|
||||
_monitorOffsets.push_back({
|
||||
_marginWidget + (_monitorWidgetSize.width() - newWidth - _marginWidget) / 4.0
|
||||
+ (_monitorResolution[m].x() - _negativeCorrectionOffsets.x())
|
||||
* _monitorScaleFactor,
|
||||
_marginWidget + (_monitorResolution[m].y() - _negativeCorrectionOffsets.y())
|
||||
* _monitorScaleFactor
|
||||
});
|
||||
std::vector<QSizeF> MonitorBox::computeScaledResolutionPortrait(QRectF arrangement,
|
||||
const std::vector<QRect>& resolutions)
|
||||
{
|
||||
std::vector<QSizeF> offsets;
|
||||
|
||||
float marginWidget = size().height() * MarginFractionOfWidgetSize;
|
||||
float virtualHeight = size().height() * (1.f - MarginFractionOfWidgetSize * 2.f);
|
||||
_monitorScaleFactor = virtualHeight / arrangement.height();
|
||||
|
||||
const float aspectRatio = arrangement.width() / arrangement.height();
|
||||
const float newWidth = virtualHeight * aspectRatio;
|
||||
|
||||
for (const QRect& res : resolutions) {
|
||||
float x = marginWidget + (size().width() - newWidth - marginWidget) / 4.f +
|
||||
(res.x() - arrangement.x()) * _monitorScaleFactor;
|
||||
float y = marginWidget + (res.y() - arrangement.y()) * _monitorScaleFactor;
|
||||
offsets.emplace_back(x, y);
|
||||
}
|
||||
|
||||
return offsets;
|
||||
}
|
||||
|
||||
void MonitorBox::setNumWindowsDisplayed(unsigned int nWindows) {
|
||||
void MonitorBox::nWindowsDisplayedChanged(int nWindows) {
|
||||
if (_nWindows != nWindows) {
|
||||
_nWindows = nWindows;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void MonitorBox::mapWindowResolutionToWidgetCoordinates(unsigned int mIdx,
|
||||
unsigned int wIdx,
|
||||
const QRectF& winDimensions)
|
||||
{
|
||||
QRectF wF = winDimensions;
|
||||
_windowRendering[wIdx] = {
|
||||
_monitorDimensionsScaled[mIdx].x() + wF.left() * _monitorScaleFactor,
|
||||
_monitorDimensionsScaled[mIdx].y() + wF.top() * _monitorScaleFactor,
|
||||
wF.width() * _monitorScaleFactor,
|
||||
wF.height() * _monitorScaleFactor
|
||||
};
|
||||
update();
|
||||
}
|
||||
|
||||
@@ -24,96 +24,86 @@
|
||||
|
||||
#include "sgctedit/orientationdialog.h"
|
||||
|
||||
#include "sgctedit/displaywindowunion.h"
|
||||
#include <QDialogButtonBox>
|
||||
#include <QDoubleValidator>
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <ghoul/glm.h>
|
||||
|
||||
OrientationDialog::OrientationDialog(sgct::quat& orientation, QWidget* parent)
|
||||
: QDialog(parent)
|
||||
, _orientationValue(orientation)
|
||||
{
|
||||
setWindowTitle("Global Orientation");
|
||||
QVBoxLayout* layoutWindow = new QVBoxLayout(this);
|
||||
QGridLayout* layoutWindow = new QGridLayout(this);
|
||||
|
||||
_linePitch = new QLineEdit;
|
||||
_lineRoll = new QLineEdit;
|
||||
_lineYaw = new QLineEdit;
|
||||
_linePitch->setText(QString::number(_orientationValue.x));
|
||||
_lineRoll->setText(QString::number(_orientationValue.z));
|
||||
_lineYaw->setText(QString::number(_orientationValue.y));
|
||||
{
|
||||
QDoubleValidator* validatorPitch = new QDoubleValidator(-90.0, 90.0, 15);
|
||||
QDoubleValidator* validatorRoll = new QDoubleValidator(-360.0, 360.0, 15);
|
||||
QDoubleValidator* validatorYaw = new QDoubleValidator(-180.0, 180.0, 15);
|
||||
validatorPitch->setNotation(QDoubleValidator::StandardNotation);
|
||||
validatorRoll->setNotation(QDoubleValidator::StandardNotation);
|
||||
validatorYaw->setNotation(QDoubleValidator::StandardNotation);
|
||||
_linePitch->setValidator(validatorPitch);
|
||||
_lineRoll->setValidator(validatorRoll);
|
||||
_lineYaw->setValidator(validatorYaw);
|
||||
}
|
||||
{
|
||||
QLabel* labelPitch = new QLabel;
|
||||
labelPitch->setText("Pitch: ");
|
||||
QHBoxLayout* layoutPitch = new QHBoxLayout;
|
||||
layoutPitch->addStretch(1);
|
||||
QString pitchTip = "Pitch or elevation: negative numbers tilt the camera "
|
||||
"downwards; positive numbers tilt upwards.\nThe allowed range is [-90, 90]. "
|
||||
"Internally, this corresponds to the x value in the quaternion.";
|
||||
|
||||
QLabel* labelPitch = new QLabel("Pitch");
|
||||
labelPitch->setToolTip(pitchTip);
|
||||
layoutWindow->addWidget(labelPitch, 0, 0);
|
||||
|
||||
_linePitch = new QLineEdit;
|
||||
_linePitch->setText(QString::number(glm::degrees(_orientationValue.x)));
|
||||
_linePitch->setToolTip(pitchTip);
|
||||
layoutPitch->addWidget(labelPitch);
|
||||
layoutPitch->addWidget(_linePitch);
|
||||
layoutWindow->addLayout(layoutPitch);
|
||||
QLabel* labelRoll = new QLabel;
|
||||
labelRoll ->setText("Roll: ");
|
||||
QHBoxLayout* layoutRoll = new QHBoxLayout;
|
||||
layoutRoll->addStretch(1);
|
||||
QDoubleValidator* validatorPitch = new QDoubleValidator(-90.0, 90.0, 15);
|
||||
validatorPitch->setNotation(QDoubleValidator::StandardNotation);
|
||||
_linePitch->setValidator(validatorPitch);
|
||||
layoutWindow->addWidget(_linePitch, 0, 1);
|
||||
}
|
||||
{
|
||||
QString rollTip = "Roll or bank: negative numbers rotate the camera counter-"
|
||||
"clockwise; positive numbers clockwise.\nThe allowed range is [-180, 180]. "
|
||||
"Internally, this corresponds to the z value in the quaternion.";
|
||||
|
||||
QLabel* labelRoll = new QLabel("Roll");
|
||||
labelRoll->setToolTip(rollTip);
|
||||
layoutWindow->addWidget(labelRoll, 1, 0);
|
||||
|
||||
_lineRoll = new QLineEdit;
|
||||
_lineRoll->setText(QString::number(glm::degrees(_orientationValue.z)));
|
||||
_lineRoll->setToolTip(rollTip);
|
||||
layoutRoll->addWidget(labelRoll);
|
||||
layoutRoll->addWidget(_lineRoll);
|
||||
layoutWindow->addLayout(layoutRoll);
|
||||
QLabel* labelYaw = new QLabel;
|
||||
labelYaw ->setText("Yaw: ");
|
||||
QHBoxLayout* layoutYaw = new QHBoxLayout;
|
||||
layoutYaw->addStretch(1);
|
||||
QDoubleValidator* validatorRoll = new QDoubleValidator(-360.0, 360.0, 15);
|
||||
validatorRoll->setNotation(QDoubleValidator::StandardNotation);
|
||||
_lineRoll->setValidator(validatorRoll);
|
||||
layoutWindow->addWidget(_lineRoll, 1, 1);
|
||||
}
|
||||
{
|
||||
QString yawTip = "Yaw, heading, or azimuth: negative numbers pan the camera "
|
||||
"to the left; positive numbers pan to the\nright. The allowed range is "
|
||||
"[-360, 360]. Internally, this corresponds to the y value in the quaternion.";
|
||||
|
||||
QLabel* labelYaw = new QLabel;
|
||||
labelYaw ->setText("Yaw");
|
||||
labelYaw->setToolTip(yawTip);
|
||||
layoutWindow->addWidget(labelYaw, 2, 0);
|
||||
|
||||
_lineYaw = new QLineEdit;
|
||||
_lineYaw->setText(QString::number(glm::degrees(_orientationValue.y)));
|
||||
_lineYaw->setToolTip(yawTip);
|
||||
layoutYaw->addWidget(labelYaw);
|
||||
layoutYaw->addWidget(_lineYaw);
|
||||
layoutWindow->addLayout(layoutYaw);
|
||||
QDoubleValidator* validatorYaw = new QDoubleValidator(-180.0, 180.0, 15, this);
|
||||
validatorYaw->setNotation(QDoubleValidator::StandardNotation);
|
||||
_lineYaw->setValidator(validatorYaw);
|
||||
layoutWindow->addWidget(_lineYaw, 2, 1);
|
||||
}
|
||||
{
|
||||
QHBoxLayout* layoutButtonBox = new QHBoxLayout;
|
||||
QPushButton* buttonSave = new QPushButton("OK");
|
||||
buttonSave->setToolTip("Save global orientation changes");
|
||||
buttonSave->setFocusPolicy(Qt::NoFocus);
|
||||
layoutButtonBox->addStretch(1);
|
||||
layoutButtonBox->addWidget(buttonSave);
|
||||
QPushButton* buttonCancel = new QPushButton("Cancel");
|
||||
buttonCancel->setToolTip("Cancel global orientation changes");
|
||||
buttonCancel->setFocusPolicy(Qt::NoFocus);
|
||||
layoutButtonBox->addWidget(buttonCancel);
|
||||
layoutButtonBox->addStretch(1);
|
||||
connect(buttonSave, &QPushButton::released, this, &OrientationDialog::ok);
|
||||
connect(buttonCancel, &QPushButton::released, this, &OrientationDialog::cancel);
|
||||
layoutWindow->addLayout(layoutButtonBox);
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox(
|
||||
QDialogButtonBox::Ok | QDialogButtonBox::Cancel
|
||||
);
|
||||
connect(buttons, &QDialogButtonBox::accepted, this, &OrientationDialog::ok);
|
||||
connect(buttons, &QDialogButtonBox::rejected, this, &OrientationDialog::reject);
|
||||
layoutWindow->addWidget(buttons, 3, 0, 1, 2);
|
||||
}
|
||||
}
|
||||
|
||||
void OrientationDialog::ok() {
|
||||
_orientationValue.x = _linePitch->text().toFloat() / 180.0 * glm::pi<float>();
|
||||
_orientationValue.y = _lineYaw->text().toFloat() / 180.0 * glm::pi<float>();
|
||||
_orientationValue.z = _lineRoll->text().toFloat() / 180.0 * glm::pi<float>();
|
||||
_orientationValue.x = glm::radians(_linePitch->text().toFloat());
|
||||
_orientationValue.y = glm::radians(_lineYaw->text().toFloat());
|
||||
_orientationValue.z = glm::radians(_lineRoll->text().toFloat());
|
||||
_orientationValue.w = 1.0;
|
||||
accept();
|
||||
}
|
||||
|
||||
void OrientationDialog::cancel() {
|
||||
reject();
|
||||
}
|
||||
|
||||
82
apps/OpenSpace/ext/launcher/src/sgctedit/settingswidget.cpp
Normal file
82
apps/OpenSpace/ext/launcher/src/sgctedit/settingswidget.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2022 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include "sgctedit/settingswidget.h"
|
||||
|
||||
#include "sgctedit/orientationdialog.h"
|
||||
#include <QCheckBox>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
SettingsWidget::SettingsWidget(sgct::quat orientation, QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, _orientationValue(std::move(orientation))
|
||||
{
|
||||
QBoxLayout* layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
_showUiOnFirstWindow = new QCheckBox("Show only user interface on the first window");
|
||||
_showUiOnFirstWindow->setChecked(false);
|
||||
_showUiOnFirstWindow->setToolTip(
|
||||
"If enabled the first window is marked as a GUI window resulting in the user "
|
||||
"interface only being shown on that window and the rendering is suppressed on "
|
||||
"this first window. The remaining windows will render normally but they will not "
|
||||
"show the user interface"
|
||||
);
|
||||
layout->addWidget(_showUiOnFirstWindow);
|
||||
|
||||
|
||||
_checkBoxVsync = new QCheckBox("Enable VSync");
|
||||
_checkBoxVsync->setToolTip(
|
||||
"If enabled the framerate will be locked to the refresh rate of the monitor"
|
||||
);
|
||||
layout->addWidget(_checkBoxVsync);
|
||||
|
||||
QPushButton* orientationButton = new QPushButton("Global Orientation");
|
||||
orientationButton->setToolTip(
|
||||
"Opens a separate dialog for setting the pitch, yaw, and roll of the camera\n"
|
||||
"(the orientation applies to all viewports)"
|
||||
);
|
||||
orientationButton->setFocusPolicy(Qt::NoFocus);
|
||||
layout->addWidget(orientationButton);
|
||||
connect(
|
||||
orientationButton, &QPushButton::released,
|
||||
[this]() {
|
||||
OrientationDialog _orientationDialog(_orientationValue, this);
|
||||
_orientationDialog.exec();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sgct::quat SettingsWidget::orientation() const {
|
||||
return _orientationValue;
|
||||
}
|
||||
|
||||
bool SettingsWidget::vsync() const {
|
||||
return _checkBoxVsync->isChecked();
|
||||
}
|
||||
|
||||
bool SettingsWidget::showUiOnFirstWindow() const {
|
||||
return _showUiOnFirstWindow->isChecked();
|
||||
}
|
||||
@@ -23,117 +23,272 @@
|
||||
****************************************************************************************/
|
||||
|
||||
#include "sgctedit/sgctedit.h"
|
||||
|
||||
#include <sgctedit/displaywindowunion.h>
|
||||
#include <sgctedit/monitorbox.h>
|
||||
#include <sgctedit/settingswidget.h>
|
||||
#include <sgctedit/windowcontrol.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <QApplication>
|
||||
#include <QFileDialog>
|
||||
#include <QFrame>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QScreen>
|
||||
#include <QVBoxLayout>
|
||||
#include <filesystem>
|
||||
|
||||
SgctEdit::SgctEdit(QWidget* parent, std::vector<sgct::config::Window>& windowList,
|
||||
sgct::config::Cluster& cluster, const QList<QScreen*>& screenList,
|
||||
const std::string userConfigPath)
|
||||
: QDialog(parent)
|
||||
, _cluster(cluster)
|
||||
, _windowList(windowList)
|
||||
, _userConfigPath(userConfigPath)
|
||||
{
|
||||
systemMonitorConfiguration(screenList);
|
||||
setWindowTitle("Window Configuration Editor");
|
||||
createWidgets();
|
||||
}
|
||||
namespace {
|
||||
constexpr QRect MonitorWidgetSize = { 0, 0, 500, 500 };
|
||||
constexpr int MaxNumberWindows = 4;
|
||||
|
||||
void SgctEdit::systemMonitorConfiguration(const QList<QScreen*>& screenList) {
|
||||
size_t nScreensManaged = std::min(static_cast<int>(screenList.length()), 2);
|
||||
for (unsigned int s = 0; s < static_cast<unsigned int>(nScreensManaged); ++s) {
|
||||
int actualWidth = std::max(
|
||||
screenList[s]->size().width(),
|
||||
screenList[s]->availableGeometry().width()
|
||||
);
|
||||
int actualHeight = std::max(
|
||||
screenList[s]->size().height(),
|
||||
screenList[s]->availableGeometry().height()
|
||||
);
|
||||
_monitorSizeList.push_back({
|
||||
screenList[s]->availableGeometry().x(),
|
||||
screenList[s]->availableGeometry().y(),
|
||||
actualWidth,
|
||||
actualHeight
|
||||
});
|
||||
}
|
||||
_nMaxWindows = (_monitorSizeList.size() == 1) ? 3 : 4;
|
||||
}
|
||||
|
||||
void SgctEdit::createWidgets() {
|
||||
QVBoxLayout* layoutMainV = new QVBoxLayout(this);
|
||||
QHBoxLayout* layoutMainH = new QHBoxLayout;
|
||||
_orientationWidget = new Orientation();
|
||||
{
|
||||
_monBox = std::make_shared<MonitorBox>(
|
||||
_monitorWidgetSize,
|
||||
_monitorSizeList,
|
||||
_nMaxWindows,
|
||||
_colorsForWindows
|
||||
);
|
||||
QHBoxLayout* layoutMonBox = new QHBoxLayout;
|
||||
layoutMonBox->addStretch(1);
|
||||
layoutMonBox->addWidget(_monBox.get());
|
||||
layoutMonBox->addStretch(1);
|
||||
layoutMainV->addLayout(layoutMonBox);
|
||||
addDisplayLayout(layoutMainH);
|
||||
}
|
||||
{
|
||||
layoutMainV->addLayout(layoutMainH);
|
||||
_orientationWidget->addControlsToParentLayout(layoutMainV);
|
||||
|
||||
QFrame* bottomBorder = new QFrame();
|
||||
bottomBorder->setFrameShape(QFrame::HLine);
|
||||
layoutMainV->addWidget(bottomBorder);
|
||||
|
||||
SgctConfigElements sgctCfg = {_windowList, _cluster};
|
||||
UserConfigurationElements userCfg = {
|
||||
_monitorSizeList,
|
||||
_displayWidget,
|
||||
_orientationWidget,
|
||||
_userConfigPath
|
||||
// Returns true if the windows are not ordered correctly. 'Correct' in this means that
|
||||
// there is a smaller window defined before a bigger one
|
||||
// This check is only necessary until
|
||||
// https://github.com/OpenSpace/OpenSpace/issues/507
|
||||
// is fixed
|
||||
bool hasWindowIssues(const sgct::config::Cluster& cluster) {
|
||||
sgct::ivec2 size = {
|
||||
std::numeric_limits<int>::max(),
|
||||
std::numeric_limits<int>::max()
|
||||
};
|
||||
_fileSupportWidget = new FileSupport(
|
||||
layoutMainV,
|
||||
userCfg,
|
||||
sgctCfg,
|
||||
[this](bool accepted) {
|
||||
if (accepted) {
|
||||
_saveSelected = true;
|
||||
accept();
|
||||
}
|
||||
else {
|
||||
reject();
|
||||
}
|
||||
for (const sgct::config::Window& window : cluster.nodes.front().windows) {
|
||||
if (window.size.x <= size.x && window.size.y <= size.y) {
|
||||
size = window.size;
|
||||
}
|
||||
else {
|
||||
// The window size is bigger than a previous one, so we gotta bail
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// We got to the end without running into any problems, so we are golden
|
||||
return false;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
SgctEdit::SgctEdit(QWidget* parent, std::string userConfigPath)
|
||||
: QDialog(parent)
|
||||
, _userConfigPath(std::move(userConfigPath))
|
||||
{
|
||||
QList<QScreen*> screens = qApp->screens();
|
||||
setWindowTitle("Window Configuration Editor");
|
||||
|
||||
int nScreensManaged = std::min(static_cast<int>(screens.length()), 4);
|
||||
std::vector<QRect> monitorSizes;
|
||||
for (int s = 0; s < nScreensManaged; ++s) {
|
||||
QSize size = screens[s]->size();
|
||||
QRect geometry = screens[s]->availableGeometry();
|
||||
int actualWidth = std::max(size.width(), geometry.width());
|
||||
int actualHeight = std::max(size.height(), geometry.height());
|
||||
monitorSizes.emplace_back(
|
||||
geometry.x(),
|
||||
geometry.y(),
|
||||
static_cast<int>(actualWidth * screens[s]->devicePixelRatio()),
|
||||
static_cast<int>(actualHeight * screens[s]->devicePixelRatio())
|
||||
);
|
||||
}
|
||||
|
||||
createWidgets(monitorSizes);
|
||||
}
|
||||
|
||||
void SgctEdit::createWidgets(const std::vector<QRect>& monitorSizes) {
|
||||
QBoxLayout* layout = new QVBoxLayout(this);
|
||||
layout->setSizeConstraint(QLayout::SetFixedSize);
|
||||
|
||||
sgct::quat orientation = { 0.f, 0.f, 0.f, 0.f };
|
||||
if (_cluster.scene.has_value() && _cluster.scene->orientation.has_value()) {
|
||||
orientation = *_cluster.scene->orientation;
|
||||
}
|
||||
{
|
||||
MonitorBox* monitorBox = new MonitorBox(
|
||||
MonitorWidgetSize,
|
||||
monitorSizes,
|
||||
MaxNumberWindows,
|
||||
_colorsForWindows,
|
||||
this
|
||||
);
|
||||
layout->addWidget(monitorBox, 0, Qt::AlignCenter);
|
||||
|
||||
QFrame* displayFrame = new QFrame;
|
||||
displayFrame->setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
|
||||
|
||||
QBoxLayout* displayLayout = new QVBoxLayout(displayFrame);
|
||||
_displayWidget = new DisplayWindowUnion(
|
||||
monitorSizes,
|
||||
MaxNumberWindows,
|
||||
_colorsForWindows,
|
||||
this
|
||||
);
|
||||
connect(
|
||||
_displayWidget, &DisplayWindowUnion::windowChanged,
|
||||
monitorBox, &MonitorBox::windowDimensionsChanged
|
||||
);
|
||||
connect(
|
||||
_displayWidget, &DisplayWindowUnion::nWindowsChanged,
|
||||
monitorBox, &MonitorBox::nWindowsDisplayedChanged
|
||||
);
|
||||
_displayWidget->addWindow();
|
||||
|
||||
displayLayout->addWidget(_displayWidget);
|
||||
|
||||
layout->addWidget(displayFrame);
|
||||
}
|
||||
|
||||
_settingsWidget = new SettingsWidget(orientation, this);
|
||||
layout->addWidget(_settingsWidget);
|
||||
|
||||
{
|
||||
QHBoxLayout* layoutButtonBox = new QHBoxLayout;
|
||||
layoutButtonBox->addStretch(1);
|
||||
|
||||
QFrame* bottomBorder = new QFrame;
|
||||
bottomBorder->setFrameShape(QFrame::HLine);
|
||||
layout->addWidget(bottomBorder);
|
||||
|
||||
_cancelButton = new QPushButton("Cancel");
|
||||
_cancelButton->setToolTip("Cancel changes.");
|
||||
_cancelButton->setFocusPolicy(Qt::NoFocus);
|
||||
connect(_cancelButton, &QPushButton::released, this, &SgctEdit::reject);
|
||||
layoutButtonBox->addWidget(_cancelButton);
|
||||
|
||||
_saveButton = new QPushButton("Save As");
|
||||
_saveButton->setToolTip("Save configuration changes.");
|
||||
_saveButton->setFocusPolicy(Qt::NoFocus);
|
||||
connect(_saveButton, &QPushButton::released, this, &SgctEdit::save);
|
||||
layoutButtonBox->addWidget(_saveButton);
|
||||
|
||||
_applyButton = new QPushButton("Apply Without Saving");
|
||||
_applyButton->setToolTip("Apply configuration changes without saving to file.");
|
||||
_applyButton->setFocusPolicy(Qt::NoFocus);
|
||||
connect(_applyButton, &QPushButton::released, this, &SgctEdit::apply);
|
||||
layoutButtonBox->addWidget(_applyButton);
|
||||
|
||||
layout->addLayout(layoutButtonBox);
|
||||
}
|
||||
}
|
||||
|
||||
void SgctEdit::addDisplayLayout(QHBoxLayout* layout) {
|
||||
_displayLayout = new QVBoxLayout;
|
||||
_displayWidget = std::make_shared<DisplayWindowUnion>(
|
||||
_monBox,
|
||||
_monitorSizeList,
|
||||
_nMaxWindows,
|
||||
_colorsForWindows
|
||||
std::filesystem::path SgctEdit::saveFilename() const {
|
||||
return _saveTarget;
|
||||
}
|
||||
|
||||
void SgctEdit::save() {
|
||||
sgct::config::Cluster cluster = generateConfiguration();
|
||||
if (hasWindowIssues(cluster)) {
|
||||
int ret = QMessageBox::warning(
|
||||
this,
|
||||
"Window Sizes Incompatible",
|
||||
"Window sizes for multiple windows have to be strictly ordered, meaning that "
|
||||
"the size of window 1 has to be bigger in each dimension than window 2, "
|
||||
"window 2 has to be bigger than window 3 (if it exists), and window 3 has to "
|
||||
"be bigger than window 4.\nOtherwise, rendering errors might occur.\n\nAre "
|
||||
"you sure you want to continue?",
|
||||
QMessageBox::StandardButtons(QMessageBox::Yes || QMessageBox::No)
|
||||
);
|
||||
if (ret == QMessageBox::No) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QString fileName = QFileDialog::getSaveFileName(
|
||||
this,
|
||||
"Save Window Configuration File",
|
||||
QString::fromStdString(_userConfigPath),
|
||||
"Window Configuration (*.json)",
|
||||
nullptr
|
||||
#ifdef __linux__
|
||||
// Linux in Qt5 and Qt6 crashes when trying to access the native dialog here
|
||||
, QFileDialog::DontUseNativeDialog
|
||||
#endif
|
||||
);
|
||||
_displayFrame = new QFrame;
|
||||
_displayLayout->addWidget(_displayWidget.get());
|
||||
_displayFrame->setLayout(_displayLayout);
|
||||
_displayFrame->setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
|
||||
layout->addWidget(_displayFrame);
|
||||
if (!fileName.isEmpty()) {
|
||||
_saveTarget = fileName.toStdString();
|
||||
_cluster = std::move(cluster);
|
||||
accept();
|
||||
}
|
||||
}
|
||||
|
||||
bool SgctEdit::wasSaved() const {
|
||||
return _saveSelected;
|
||||
void SgctEdit::apply() {
|
||||
sgct::config::Cluster cluster = generateConfiguration();
|
||||
if (hasWindowIssues(cluster)) {
|
||||
int ret = QMessageBox::warning(
|
||||
this,
|
||||
"Window Sizes Incompatible",
|
||||
"Window sizes for multiple windows have to be strictly ordered, meaning that "
|
||||
"the size of window 1 has to be bigger in each dimension than window 2, "
|
||||
"window 2 has to be bigger than window 3 (if it exists), and window 3 has to "
|
||||
"be bigger than window 4.\nOtherwise, rendering errors might occur.\n\nAre "
|
||||
"you sure you want to continue?",
|
||||
QMessageBox::Yes | QMessageBox::No
|
||||
);
|
||||
if (ret == QMessageBox::No) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::string userCfgTempDir = _userConfigPath;
|
||||
if (userCfgTempDir.back() != '/') {
|
||||
userCfgTempDir += '/';
|
||||
}
|
||||
userCfgTempDir += "temp";
|
||||
if (!std::filesystem::is_directory(absPath(userCfgTempDir))) {
|
||||
std::filesystem::create_directories(absPath(userCfgTempDir));
|
||||
}
|
||||
_saveTarget = userCfgTempDir + "/apply-without-saving.json";
|
||||
_cluster = std::move(cluster);
|
||||
accept();
|
||||
}
|
||||
|
||||
std::string SgctEdit::saveFilename() {
|
||||
return _fileSupportWidget->saveFilename();
|
||||
sgct::config::Cluster SgctEdit::generateConfiguration() const {
|
||||
sgct::config::Cluster cluster;
|
||||
|
||||
sgct::config::Scene scene;
|
||||
scene.orientation = _settingsWidget->orientation();
|
||||
cluster.scene = std::move(scene);
|
||||
|
||||
cluster.masterAddress = "localhost";
|
||||
|
||||
if (_settingsWidget->vsync()) {
|
||||
sgct::config::Settings::Display display;
|
||||
display.swapInterval = 1;
|
||||
|
||||
sgct::config::Settings settings;
|
||||
settings.display = display;
|
||||
|
||||
cluster.settings = settings;
|
||||
}
|
||||
|
||||
sgct::config::Node node;
|
||||
node.address = "localhost";
|
||||
node.port = 20401;
|
||||
|
||||
// Save Windows
|
||||
unsigned int windowIndex = 0;
|
||||
for (WindowControl* wCtrl : _displayWidget->windowControls()) {
|
||||
sgct::config::Window window = wCtrl->generateWindowInformation();
|
||||
|
||||
window.id = windowIndex++;
|
||||
node.windows.push_back(std::move(window));
|
||||
}
|
||||
|
||||
if (_settingsWidget->showUiOnFirstWindow()) {
|
||||
sgct::config::Window& window = node.windows.front();
|
||||
window.viewports.back().isTracked = false;
|
||||
window.tags.push_back("GUI");
|
||||
window.draw2D = true;
|
||||
window.draw3D = false;
|
||||
}
|
||||
|
||||
cluster.nodes.push_back(node);
|
||||
|
||||
sgct::config::User user;
|
||||
user.eyeSeparation = 0.065f;
|
||||
user.position = { 0.f, 0.f, 4.f };
|
||||
cluster.users = { user };
|
||||
|
||||
return cluster;
|
||||
}
|
||||
|
||||
SgctEdit::~SgctEdit() {
|
||||
delete _orientationWidget;
|
||||
delete _fileSupportWidget;
|
||||
delete _displayLayout;
|
||||
sgct::config::Cluster SgctEdit::cluster() const {
|
||||
return _cluster;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Submodule apps/OpenSpace/ext/sgct updated: 0dec32d871...5cd9a45cd1
@@ -207,6 +207,71 @@ LONG WINAPI generateMiniDump(EXCEPTION_POINTERS* exceptionPointers) {
|
||||
}
|
||||
#endif // WIN32
|
||||
|
||||
void checkJoystickStatus() {
|
||||
using namespace interaction;
|
||||
|
||||
for (int i = GLFW_JOYSTICK_1; i <= GLFW_JOYSTICK_LAST; ++i) {
|
||||
ZoneScopedN("Joystick state");
|
||||
|
||||
JoystickInputState& state = global::joystickInputStates->at(i);
|
||||
|
||||
int present = glfwJoystickPresent(i);
|
||||
if (present == GLFW_FALSE) {
|
||||
state.isConnected = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!state.isConnected) {
|
||||
// Joystick was added
|
||||
state.isConnected = true;
|
||||
state.name = glfwGetJoystickName(i);
|
||||
|
||||
std::fill(state.axes.begin(), state.axes.end(), 0.f);
|
||||
std::fill(state.buttons.begin(), state.buttons.end(), JoystickAction::Idle);
|
||||
|
||||
// Check axes and buttons
|
||||
glfwGetJoystickAxes(i, &state.nAxes);
|
||||
glfwGetJoystickButtons(i, &state.nButtons);
|
||||
}
|
||||
|
||||
const float* axes = glfwGetJoystickAxes(i, &state.nAxes);
|
||||
state.axes.resize(state.nAxes);
|
||||
std::memcpy(state.axes.data(), axes, state.nAxes * sizeof(float));
|
||||
|
||||
const unsigned char* buttons = glfwGetJoystickButtons(i, &state.nButtons);
|
||||
state.buttons.resize(state.nButtons);
|
||||
|
||||
for (int j = 0; j < state.nButtons; ++j) {
|
||||
const bool currentlyPressed = buttons[j] == GLFW_PRESS;
|
||||
|
||||
if (currentlyPressed) {
|
||||
switch (state.buttons[j]) {
|
||||
case JoystickAction::Idle:
|
||||
case JoystickAction::Release:
|
||||
state.buttons[j] = JoystickAction::Press;
|
||||
break;
|
||||
case JoystickAction::Press:
|
||||
case JoystickAction::Repeat:
|
||||
state.buttons[j] = JoystickAction::Repeat;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (state.buttons[j]) {
|
||||
case JoystickAction::Idle:
|
||||
case JoystickAction::Release:
|
||||
state.buttons[j] = JoystickAction::Idle;
|
||||
break;
|
||||
case JoystickAction::Press:
|
||||
case JoystickAction::Repeat:
|
||||
state.buttons[j] = JoystickAction::Release;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Init function
|
||||
//
|
||||
@@ -319,6 +384,9 @@ void mainInitFunc(GLFWwindow*) {
|
||||
#endif // OPENSPACE_HAS_SPOUT
|
||||
}
|
||||
|
||||
// Query joystick status, those connected before start up
|
||||
checkJoystickStatus();
|
||||
|
||||
LTRACE("main::mainInitFunc(end)");
|
||||
}
|
||||
|
||||
@@ -336,87 +404,8 @@ void mainPreSyncFunc() {
|
||||
Engine::instance().terminate();
|
||||
}
|
||||
|
||||
// Query joystick status
|
||||
using namespace interaction;
|
||||
|
||||
for (int i = GLFW_JOYSTICK_1; i <= GLFW_JOYSTICK_LAST; ++i) {
|
||||
ZoneScopedN("Joystick state");
|
||||
|
||||
JoystickInputState& state = global::joystickInputStates->at(i);
|
||||
|
||||
int present = glfwJoystickPresent(i);
|
||||
if (present == GLFW_FALSE) {
|
||||
state.isConnected = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!state.isConnected) {
|
||||
// Joystick was added
|
||||
state.isConnected = true;
|
||||
state.name = glfwGetJoystickName(i);
|
||||
|
||||
std::fill(state.axes.begin(), state.axes.end(), 0.f);
|
||||
std::fill(state.buttons.begin(), state.buttons.end(), JoystickAction::Idle);
|
||||
|
||||
// Check axes and buttons
|
||||
glfwGetJoystickAxes(i, &state.nAxes);
|
||||
if (state.nAxes > JoystickInputState::MaxAxes) {
|
||||
LWARNING(fmt::format(
|
||||
"Joystick/Gamepad {} has {} axes, but only {} axes are supported. "
|
||||
"All excess axes are ignored",
|
||||
state.name, state.nAxes, JoystickInputState::MaxAxes
|
||||
));
|
||||
}
|
||||
glfwGetJoystickButtons(i, &state.nButtons);
|
||||
if (state.nButtons > JoystickInputState::MaxButtons) {
|
||||
LWARNING(fmt::format(
|
||||
"Joystick/Gamepad {} has {} buttons, but only {} buttons are "
|
||||
"supported. All excess buttons are ignored",
|
||||
state.name, state.nButtons, JoystickInputState::MaxButtons
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
const float* axes = glfwGetJoystickAxes(i, &state.nAxes);
|
||||
if (state.nAxes > JoystickInputState::MaxAxes) {
|
||||
state.nAxes = JoystickInputState::MaxAxes;
|
||||
}
|
||||
std::memcpy(state.axes.data(), axes, state.nAxes * sizeof(float));
|
||||
|
||||
const unsigned char* buttons = glfwGetJoystickButtons(i, &state.nButtons);
|
||||
if (state.nButtons > JoystickInputState::MaxButtons) {
|
||||
state.nButtons = JoystickInputState::MaxButtons;
|
||||
}
|
||||
|
||||
for (int j = 0; j < state.nButtons; ++j) {
|
||||
const bool currentlyPressed = buttons[j] == GLFW_PRESS;
|
||||
|
||||
if (currentlyPressed) {
|
||||
switch (state.buttons[j]) {
|
||||
case JoystickAction::Idle:
|
||||
case JoystickAction::Release:
|
||||
state.buttons[j] = JoystickAction::Press;
|
||||
break;
|
||||
case JoystickAction::Press:
|
||||
case JoystickAction::Repeat:
|
||||
state.buttons[j] = JoystickAction::Repeat;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (state.buttons[j]) {
|
||||
case JoystickAction::Idle:
|
||||
case JoystickAction::Release:
|
||||
state.buttons[j] = JoystickAction::Idle;
|
||||
break;
|
||||
case JoystickAction::Press:
|
||||
case JoystickAction::Repeat:
|
||||
state.buttons[j] = JoystickAction::Release;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Query joystick status, those connected at run time
|
||||
checkJoystickStatus();
|
||||
|
||||
LTRACE("main::mainPreSyncFunc(end)");
|
||||
}
|
||||
|
||||
@@ -12,6 +12,22 @@
|
||||
"address": "localhost",
|
||||
"port": 20401,
|
||||
"windows": [
|
||||
{
|
||||
"fullscreen": false,
|
||||
"border": false,
|
||||
"name": "GUI",
|
||||
"tags": [ "GUI" ],
|
||||
"draw3d": false,
|
||||
"stereo": "none",
|
||||
"pos": { "x": 0, "y": 0 },
|
||||
"size": { "x": 1920, "y": 1080 },
|
||||
"viewports": [
|
||||
{
|
||||
"pos": { "x": 0.0, "y": 0.0 },
|
||||
"size": { "x": 1.0, "y": 1.0 }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"fullscreen": true,
|
||||
"monitor": 1,
|
||||
@@ -35,22 +51,6 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"fullscreen": false,
|
||||
"border": false,
|
||||
"name": "GUI",
|
||||
"tags": [ "GUI" ],
|
||||
"draw3d": false,
|
||||
"stereo": "none",
|
||||
"pos": { "x": 0, "y": 0 },
|
||||
"size": { "x": 1920, "y": 1080 },
|
||||
"viewports": [
|
||||
{
|
||||
"pos": { "x": 0.0, "y": 0.0 },
|
||||
"size": { "x": 1.0, "y": 1.0 }
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,26 +6,6 @@
|
||||
"address": "localhost",
|
||||
"port": 20401,
|
||||
"windows": [
|
||||
{
|
||||
"name": "OpenSpace",
|
||||
"fullscreen": false,
|
||||
"draw2d": false,
|
||||
"stereo": "none",
|
||||
"size": { "x": 1024, "y": 1024 },
|
||||
"viewports": [
|
||||
{
|
||||
"pos": { "x": 0.0, "y": 0.0 },
|
||||
"size": { "x": 1.0, "y": 1.0 },
|
||||
"projection": {
|
||||
"type": "FisheyeProjection",
|
||||
"fov": 180.0,
|
||||
"quality": "1k",
|
||||
"tilt": 27.0,
|
||||
"background": { "r": 0.1, "g": 0.1, "b": 0.1, "a": 1.0 }
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "GUI",
|
||||
"tags": [ "GUI" ],
|
||||
@@ -48,6 +28,26 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "OpenSpace",
|
||||
"fullscreen": false,
|
||||
"draw2d": false,
|
||||
"stereo": "none",
|
||||
"size": { "x": 1024, "y": 1024 },
|
||||
"viewports": [
|
||||
{
|
||||
"pos": { "x": 0.0, "y": 0.0 },
|
||||
"size": { "x": 1.0, "y": 1.0 },
|
||||
"projection": {
|
||||
"type": "FisheyeProjection",
|
||||
"fov": 180.0,
|
||||
"quality": "1k",
|
||||
"tilt": 27.0,
|
||||
"background": { "r": 0.1, "g": 0.1, "b": 0.1, "a": 1.0 }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -13,15 +13,15 @@
|
||||
"port": 20401,
|
||||
"windows": [
|
||||
{
|
||||
"name": "OpenSpace",
|
||||
"name": "GUI",
|
||||
"tags": [ "GUI" ],
|
||||
"fullscreen": false,
|
||||
"draw2d": false,
|
||||
"draw3d": false,
|
||||
"stereo": "none",
|
||||
"pos": { "x": 50, "y": 50 },
|
||||
"size": { "x": 1280, "y": 720 },
|
||||
"viewports": [
|
||||
{
|
||||
"tracked": true,
|
||||
"pos": { "x": 0.0, "y": 0.0 },
|
||||
"size": { "x": 1.0, "y": 1.0 },
|
||||
"projection": {
|
||||
@@ -36,15 +36,15 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "GUI",
|
||||
"tags": [ "GUI" ],
|
||||
"name": "OpenSpace",
|
||||
"fullscreen": false,
|
||||
"draw3d": false,
|
||||
"draw2d": false,
|
||||
"stereo": "none",
|
||||
"pos": { "x": 50, "y": 50 },
|
||||
"size": { "x": 1280, "y": 720 },
|
||||
"viewports": [
|
||||
{
|
||||
"tracked": true,
|
||||
"pos": { "x": 0.0, "y": 0.0 },
|
||||
"size": { "x": 1.0, "y": 1.0 },
|
||||
"projection": {
|
||||
|
||||
@@ -12,6 +12,27 @@
|
||||
"address": "localhost",
|
||||
"port": 20401,
|
||||
"windows": [
|
||||
{
|
||||
"name": "GUI",
|
||||
"pos": { "x": 50, "y": 50 },
|
||||
"size": { "x": 1280, "y": 720 },
|
||||
"stereo": "none",
|
||||
"tags": [ "GUI" ],
|
||||
"viewports": [
|
||||
{
|
||||
"pos": { "x": 0.0, "y": 0.0 },
|
||||
"size": { "x": 1.0, "y": 1.0 },
|
||||
"projection": {
|
||||
"type": "PlanarProjection",
|
||||
"fov": {
|
||||
"hfov": 80.0,
|
||||
"vfov": 50.53401565551758
|
||||
},
|
||||
"orientation": { "yaw": 0.0, "pitch": 0.0, "roll": 0.0 }
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "OpenSpace",
|
||||
"pos": { "x": 50, "y": 50 },
|
||||
@@ -33,27 +54,6 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "GUI",
|
||||
"pos": { "x": 50, "y": 50 },
|
||||
"size": { "x": 1280, "y": 720 },
|
||||
"stereo": "none",
|
||||
"tags": [ "GUI" ],
|
||||
"viewports": [
|
||||
{
|
||||
"pos": { "x": 0.0, "y": 0.0 },
|
||||
"size": { "x": 1.0, "y": 1.0 },
|
||||
"projection": {
|
||||
"type": "PlanarProjection",
|
||||
"fov": {
|
||||
"hfov": 80.0,
|
||||
"vfov": 50.53401565551758
|
||||
},
|
||||
"orientation": { "yaw": 0.0, "pitch": 0.0, "roll": 0.0 }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,29 +6,6 @@
|
||||
"address": "127.0.0.1",
|
||||
"port": 20401,
|
||||
"windows": [
|
||||
{
|
||||
"fullscreen": false,
|
||||
"name": "Spherical Projection",
|
||||
"stereo": "none",
|
||||
"draw2d": false,
|
||||
"pos": { "x": 0, "y": 100 },
|
||||
"size": { "x": 1280, "y": 720 },
|
||||
"res": { "x": 2048, "y": 2048 },
|
||||
"viewports": [
|
||||
{
|
||||
"mesh": "mesh/standard_16x9.data",
|
||||
"pos": { "x": 0.0, "y": 0.0 },
|
||||
"size": { "x": 1.0, "y": 1.0 },
|
||||
"projection": {
|
||||
"type": "FisheyeProjection",
|
||||
"fov": 180.0,
|
||||
"quality": "2k",
|
||||
"tilt": 30.0,
|
||||
"background": { "r": 0.1, "g": 0.1, "b": 0.1, "a": 1.0 }
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"fullscreen": false,
|
||||
"name": "GUI",
|
||||
@@ -52,6 +29,29 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"fullscreen": false,
|
||||
"name": "Spherical Projection",
|
||||
"stereo": "none",
|
||||
"draw2d": false,
|
||||
"pos": { "x": 0, "y": 100 },
|
||||
"size": { "x": 1280, "y": 720 },
|
||||
"res": { "x": 2048, "y": 2048 },
|
||||
"viewports": [
|
||||
{
|
||||
"mesh": "mesh/standard_16x9.data",
|
||||
"pos": { "x": 0.0, "y": 0.0 },
|
||||
"size": { "x": 1.0, "y": 1.0 },
|
||||
"projection": {
|
||||
"type": "FisheyeProjection",
|
||||
"fov": 180.0,
|
||||
"quality": "2k",
|
||||
"tilt": 30.0,
|
||||
"background": { "r": 0.1, "g": 0.1, "b": 0.1, "a": 1.0 }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
89
data/assets/actions/planets/mars_layers.asset
Normal file
89
data/assets/actions/planets/mars_layers.asset
Normal file
@@ -0,0 +1,89 @@
|
||||
local ctx_enable_action = {
|
||||
Identifier = "os.mars.ctx.fadein",
|
||||
Name = "Fade in CTX",
|
||||
Command = [[
|
||||
openspace.setPropertyValueSingle("Scene.Mars.Renderable.Layers.ColorLayers.CTX_blended_01.Enabled", true)
|
||||
openspace.setPropertyValueSingle("Scene.Mars.Renderable.Layers.ColorLayers.CTX_blended_01.Settings.Opacity", 0)
|
||||
openspace.setPropertyValueSingle("Scene.Mars.Renderable.Layers.ColorLayers.CTX_blended_01.Settings.Opacity", 1, 2.0)]],
|
||||
Documentation = "Enables and fades in CTX layer for Mars",
|
||||
GuiPath = "/Solar System/Mars",
|
||||
IsLocal = true
|
||||
}
|
||||
asset.export("ctx_enable_action", ctx_enable_action.Identifier)
|
||||
|
||||
local ctx_disable_action = {
|
||||
Identifier = "os.mars.ctx.fadedout",
|
||||
Name = "Fade out CTX Layer",
|
||||
Command = [[openspace.setPropertyValueSingle("Scene.Mars.Renderable.Layers.ColorLayers.CTX_blended_01.Settings.Opacity", 0, 2.0)]],
|
||||
Documentation = "Fade out CTX",
|
||||
GuiPath = "/Solar System/Mars",
|
||||
IsLocal = true
|
||||
}
|
||||
asset.export("ctx_disable_action", ctx_disable_action.Identifier)
|
||||
|
||||
local hirise_enable_action = {
|
||||
Identifier = "os.mars.hirise.fadein",
|
||||
Name = "Fade in HiRISE",
|
||||
Command = [[
|
||||
openspace.setPropertyValueSingle("Scene.Mars.Renderable.Layers.ColorLayers.HiRISE-PSP.Enabled", true)
|
||||
openspace.setPropertyValueSingle("Scene.Mars.Renderable.Layers.ColorLayers.HiRISE-PSP.Settings.Opacity", 0)
|
||||
openspace.setPropertyValueSingle("Scene.Mars.Renderable.Layers.ColorLayers.HiRISE-PSP.Settings.Opacity", 1, 2.0)]],
|
||||
Documentation = "Enables and fades in HiRise layer for Mars",
|
||||
GuiPath = "/Solar System/Mars",
|
||||
IsLocal = true
|
||||
}
|
||||
asset.export("hirise_enable_action", hirise_enable_action.Identifier)
|
||||
|
||||
local hirise_disable_action = {
|
||||
Identifier = "os.mars.hirise.fadedout",
|
||||
Name = "Fade out HiRISE",
|
||||
Command = [[openspace.setPropertyValueSingle("Scene.Mars.Renderable.Layers.ColorLayers.HiRISE-PSP.Settings.Opacity", 0, 2.0)]],
|
||||
Documentation = "Fade out HiRISE layer for Mars",
|
||||
GuiPath = "/Solar System/Mars",
|
||||
IsLocal = true
|
||||
}
|
||||
asset.export("hirise_disable_action", hirise_disable_action.Identifier)
|
||||
|
||||
local lshirise_enable_action = {
|
||||
Identifier = "os.mars.lshirise.fadein",
|
||||
Name = "Fade in HiRISE Local Set",
|
||||
Command = [[
|
||||
openspace.setPropertyValueSingle("Scene.Mars.Renderable.Layers.ColorLayers.HiRISE-LS.Enabled", true)
|
||||
openspace.setPropertyValueSingle("Scene.Mars.Renderable.Layers.HeightLayers.HiRISE-LS-DEM.Enabled", true)
|
||||
openspace.setPropertyValueSingle("Scene.Mars.Renderable.Layers.ColorLayers.HiRISE-LS.Settings.Opacity", 0)
|
||||
openspace.setPropertyValueSingle("Scene.Mars.Renderable.Layers.ColorLayers.HiRISE-LS.Settings.Opacity", 1, 2.0)]],
|
||||
Documentation = "Enables and fades in HiRise local set layers for Mars (including height)",
|
||||
GuiPath = "/Solar System/Mars",
|
||||
IsLocal = true
|
||||
}
|
||||
asset.export("lshirise_enable_action", lshirise_enable_action.Identifier)
|
||||
|
||||
local lshirise_disable_action = {
|
||||
Identifier = "os.mars.lshirise.fadedout",
|
||||
Name = "Fade out HiRISE Local Set",
|
||||
Command = [[openspace.setPropertyValueSingle("Scene.Mars.Renderable.Layers.ColorLayers.HiRISE-LS.Settings.Opacity", 0, 2.0)
|
||||
openspace.setPropertyValueSingle("Scene.Mars.Renderable.Layers.HeightLayers.HiRISE-LS-DEM.Enabled", false)]],
|
||||
Documentation = "Fade out HiRISE local set layer for Mars",
|
||||
GuiPath = "/Solar System/Mars",
|
||||
IsLocal = true
|
||||
}
|
||||
asset.export("lshirise_disable_action", lshirise_disable_action.Identifier)
|
||||
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.action.registerAction(ctx_enable_action)
|
||||
openspace.action.registerAction(ctx_disable_action)
|
||||
openspace.action.registerAction(hirise_enable_action)
|
||||
openspace.action.registerAction(hirise_disable_action)
|
||||
openspace.action.registerAction(lshirise_enable_action)
|
||||
openspace.action.registerAction(lshirise_disable_action)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.action.removeAction(lshirise_disable_action)
|
||||
openspace.action.removeAction(lshirise_enable_action)
|
||||
openspace.action.removeAction(hirise_disable_action)
|
||||
openspace.action.removeAction(hirise_enable_action)
|
||||
openspace.action.removeAction(ctx_disable_action)
|
||||
openspace.action.removeAction(ctx_enable_action)
|
||||
end)
|
||||
126
data/assets/actions/planets/planet_lighting.asset
Normal file
126
data/assets/actions/planets/planet_lighting.asset
Normal file
@@ -0,0 +1,126 @@
|
||||
local function getIlluminationCommand(node, global)
|
||||
local commandString = "local node = \"" .. node .. "\"\n"
|
||||
if (node == "Current Focus") then
|
||||
commandString = "local node = openspace.navigation.getNavigationState().Anchor\n"
|
||||
end
|
||||
if (global) then
|
||||
commandString = commandString .. [[
|
||||
if (openspace.hasProperty("Scene."..node..".Renderable.UseAccurateNormals")) then
|
||||
local list = openspace.getProperty("Scene." .. node .. ".Renderable.Layers.NightLayers.*.Enabled")
|
||||
if (#list > 0) then
|
||||
openspace.setPropertyValue("Scene." .. node .. ".Renderable.Layers.NightLayers.*.Enabled", false)
|
||||
else
|
||||
openspace.setPropertyValueSingle("Scene." .. node .. ".Renderable.PerformShading", false)
|
||||
end
|
||||
if openspace.hasSceneGraphNode(node .. "Atmosphere") then
|
||||
openspace.setPropertyValueSingle("Scene." .. node .. "Atmosphere.Renderable.SunFollowingCamera", true)
|
||||
end
|
||||
if openspace.hasProperty("Scene." .. node .. ".Renderable.ShadowsComponent.DistanceFraction") then
|
||||
openspace.setPropertyValueSingle("Scene." .. node .. ".Renderable.ShadowsComponent.DistanceFraction", 3000)
|
||||
end
|
||||
else
|
||||
openspace.printWarning("Illumination action only available for globes")
|
||||
end]]
|
||||
else
|
||||
--todo @micahnyc this 40 wont do once we have more rings
|
||||
commandString = commandString .. [[if (openspace.hasProperty("Scene."..node..".Renderable.UseAccurateNormals")) then
|
||||
local list = openspace.getProperty("Scene." .. node .. ".Renderable.Layers.NightLayers.*.Enabled")
|
||||
if (#list > 0) then
|
||||
openspace.setPropertyValue(list[1], true)
|
||||
else
|
||||
openspace.setPropertyValueSingle("Scene." .. node .. ".Renderable.PerformShading", true)
|
||||
end
|
||||
if openspace.hasSceneGraphNode(node .. "Atmosphere") then
|
||||
openspace.setPropertyValueSingle("Scene." .. node .. "Atmosphere.Renderable.SunFollowingCamera", false)
|
||||
end
|
||||
if openspace.hasProperty("Scene." .. node .. ".Renderable.ShadowsComponent.DistanceFraction") then
|
||||
openspace.setPropertyValueSingle("Scene." .. node .. ".Renderable.ShadowsComponent.DistanceFraction", 40)
|
||||
end
|
||||
else
|
||||
openspace.printWarning("Illumination action only available for globes")
|
||||
end]]
|
||||
end
|
||||
return commandString
|
||||
end
|
||||
|
||||
local function getIlluminationAction(node, node_lower, global)
|
||||
local actionString = "_standard_illumination"
|
||||
local actionName = "Standard Illumination"
|
||||
local actionCommand = getIlluminationCommand(node, global)
|
||||
if (global) then
|
||||
actionString = "_global_illumination"
|
||||
actionName = "Global Illumination"
|
||||
actionCommand = getIlluminationCommand(node, global)
|
||||
end
|
||||
|
||||
local action = {
|
||||
Identifier = "os." .. string.gsub(node_lower, "%s+", "") .. actionString,
|
||||
Name = node .. " " .. actionName,
|
||||
Command = actionCommand,
|
||||
Documentation = "Enables " .. string.lower(actionName) .. " for" .. node,
|
||||
GuiPath = "/Solar System/" .. node,
|
||||
IsLocal = true
|
||||
}
|
||||
return action
|
||||
end
|
||||
|
||||
local current_focus_global = getIlluminationAction("Current Focus", "current_focus", true)
|
||||
asset.export("current_focus_global", current_focus_global.Identifier)
|
||||
local current_focus_standard = getIlluminationAction("Current Focus", "current_focus", false)
|
||||
asset.export("current_focus_standard", current_focus_standard.Identifier)
|
||||
|
||||
local earth_global = getIlluminationAction("Earth", "earth", true)
|
||||
asset.export("earth_global", earth_global.Identifier)
|
||||
local earth_standard = getIlluminationAction("Earth", "earth", false)
|
||||
asset.export("earth_standard", earth_standard.Identifier)
|
||||
|
||||
local mars_global = getIlluminationAction("Mars", "mars", true)
|
||||
asset.export("mars_global", mars_global.Identifier)
|
||||
local mars_standard = getIlluminationAction("Mars", "mars", false)
|
||||
asset.export("mars_standard", mars_standard.Identifier)
|
||||
|
||||
local venus_global = getIlluminationAction("Venus", "venus", true)
|
||||
asset.export("venus_global", venus_global.Identifier)
|
||||
local venus_standard = getIlluminationAction("Venus", "venus", false)
|
||||
asset.export("venus_standard", venus_standard.Identifier)
|
||||
|
||||
local titan_global = getIlluminationAction("Titan", "titan", true)
|
||||
asset.export("titan_global", titan_global.Identifier)
|
||||
local titan_standard = getIlluminationAction("Titan", "titan", false)
|
||||
asset.export("titan_standard", titan_standard.Identifier)
|
||||
|
||||
local saturn_global = getIlluminationAction("Saturn", "saturn", true)
|
||||
asset.export("saturn_global", saturn_global.Identifier)
|
||||
local saturn_standard = getIlluminationAction("Saturn", "saturn", false)
|
||||
asset.export("titan_standard", saturn_standard.Identifier)
|
||||
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.action.registerAction(current_focus_global)
|
||||
openspace.action.registerAction(current_focus_standard)
|
||||
openspace.action.registerAction(earth_global)
|
||||
openspace.action.registerAction(earth_standard)
|
||||
openspace.action.registerAction(mars_global)
|
||||
openspace.action.registerAction(mars_standard)
|
||||
openspace.action.registerAction(venus_global)
|
||||
openspace.action.registerAction(venus_standard)
|
||||
openspace.action.registerAction(titan_global)
|
||||
openspace.action.registerAction(titan_standard)
|
||||
openspace.action.registerAction(saturn_global)
|
||||
openspace.action.registerAction(saturn_standard)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.action.removeAction(saturn_standard)
|
||||
openspace.action.removeAction(saturn_global)
|
||||
openspace.action.removeAction(titan_standard)
|
||||
openspace.action.removeAction(titan_global)
|
||||
openspace.action.removeAction(venus_standard)
|
||||
openspace.action.removeAction(venus_global)
|
||||
openspace.action.removeAction(mars_standard)
|
||||
openspace.action.removeAction(mars_global)
|
||||
openspace.action.removeAction(earth_standard)
|
||||
openspace.action.removeAction(earth_global)
|
||||
openspace.action.removeAction(current_focus_standard)
|
||||
openspace.action.removeAction(current_focus_global)
|
||||
end)
|
||||
127
data/assets/actions/planets/scale_planets_and_moons.asset
Normal file
127
data/assets/actions/planets/scale_planets_and_moons.asset
Normal file
@@ -0,0 +1,127 @@
|
||||
local function getScaleCommand(identifier, scale, speed)
|
||||
local command = 'openspace.setPropertyValue("' .. identifier .. '.Scale.Scale", '
|
||||
command = command .. scale .. ", " .. speed
|
||||
if (scale == 1) then
|
||||
command = command .. ")"
|
||||
else
|
||||
command = command .. ', "CubicEaseOut")'
|
||||
end
|
||||
return command
|
||||
end
|
||||
|
||||
local function getScaleAction(identifier, scale, name, speed)
|
||||
local actionString = "Grow"
|
||||
if (scale == 1) then
|
||||
actionString = "Shrink"
|
||||
end
|
||||
local action = {
|
||||
Identifier = "os." .. actionString .. "_" .. identifier,
|
||||
Name = actionString .. " " .. name,
|
||||
Command = getScaleCommand(identifier, scale, speed),
|
||||
Documentation = "Scales " .. name .. " to " .. scale .. "x",
|
||||
GuiPath = "/Solar System/Scale",
|
||||
IsLocal = true
|
||||
}
|
||||
return action
|
||||
end
|
||||
|
||||
local function getToggleScaleAction(identifier, scale, name, speedup, speedown)
|
||||
local action = {
|
||||
Identifier = "os.toggle_" .. string.gsub(name, "%s+", "") .. "_scale",
|
||||
Name = "Toggle " .. name .. " Scale",
|
||||
Command = [[
|
||||
local list = openspace.getProperty("]] .. identifier .. [[.Scale.Scale");
|
||||
if #list == 0 then
|
||||
openspace.printWarning("No planets to resize");
|
||||
else
|
||||
local prop = list[1];
|
||||
local currentScale = openspace.getPropertyValue(prop);
|
||||
local newScale = 1;
|
||||
if (currentScale == 1) then
|
||||
]] .. getScaleCommand(identifier, scale, speedup) .. [[
|
||||
else
|
||||
]] .. getScaleCommand(identifier, 1, speedown) .. [[
|
||||
end
|
||||
end
|
||||
]],
|
||||
GuiPath = "/Solar System/Scale",
|
||||
Documentation = "Toggle the scale of " .. name,
|
||||
IsLocal = true
|
||||
}
|
||||
return action
|
||||
end
|
||||
|
||||
local grow_planets = getScaleAction("{planet_solarSystem}", 3400, "Planets", 3)
|
||||
asset.export("grow_planets", grow_planets.Identifier)
|
||||
local shrink_planets = getScaleAction("{planet_solarSystem}", 1, "Planets", 2)
|
||||
asset.export("shrink_planets", shrink_planets.Identifier)
|
||||
local toggle_planet_scale = getToggleScaleAction("{planet_solarSystem}", 3400, "Planets", 3, 2)
|
||||
asset.export("toggle_planet_scale", toggle_planet_scale.Identifier)
|
||||
|
||||
local grow_inner_planets = getScaleAction("{planet_terrestrial}", 3400, "Inner Planets", 3)
|
||||
asset.export("grow_inner_planets", grow_inner_planets.Identifier)
|
||||
local shrink_inner_planets = getScaleAction("{planet_terrestrial}", 1, "Inner Planets", 2)
|
||||
asset.export("shrink_inner_planets", shrink_inner_planets.Identifier)
|
||||
local toggle_inner_planet_scale = getToggleScaleAction("{planet_terrestrial}", 3400, "Inner Planets", 3, 2)
|
||||
asset.export("toggle_inner_planet_scale", toggle_inner_planet_scale.Identifier)
|
||||
|
||||
local grow_outter_planets = getScaleAction("{planet_giants}", 3400, "Outter Planets", 3)
|
||||
asset.export("grow_outter_planets", grow_outter_planets.Identifier)
|
||||
local shrink_outter_planets = getScaleAction("{planet_giants}", 1, "Outter Planets", 2)
|
||||
asset.export("shrink_outter_planets", shrink_outter_planets.Identifier)
|
||||
local toggle_outter_planet_scale = getToggleScaleAction("{planet_giants}", 3400, "Outter Planets", 3, 2)
|
||||
asset.export("toggle_outter_planet_scale", toggle_outter_planet_scale.Identifier)
|
||||
|
||||
local grow_jupiter_moons = getScaleAction("{moon_jupiter}", 50, "Jupiter Moons", 3)
|
||||
asset.export("grow_jupiter_moons", grow_jupiter_moons.Identifier)
|
||||
local shrink_jupiter_moons = getScaleAction("{moon_jupiter}", 1, "Jupiter Moons", 2)
|
||||
asset.export("shrink_jupiter_moons", shrink_jupiter_moons.Identifier)
|
||||
local toggle_jupiter_moon_scales = getToggleScaleAction("{moon_jupiter}", 50, "Jupiter Moons", 3, 2)
|
||||
asset.export("toggle_jupiter_moon_scales", toggle_jupiter_moon_scales.Identifier)
|
||||
|
||||
local grow_moon = getScaleAction("Scene.Moon", 25, "Moon", 3)
|
||||
asset.export("grow_moon", grow_moon.Identifier)
|
||||
local shrink_moon = getScaleAction("Scene.Moon", 1, "Moon", 2)
|
||||
asset.export("shrink_moon", shrink_moon.Identifier)
|
||||
local toggle_moon_scale = getToggleScaleAction("Scene.Moon", 25, "Moon", 3, 2)
|
||||
asset.export("toggle_moon_scale", toggle_moon_scale.Identifier)
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.action.registerAction(grow_planets)
|
||||
openspace.action.registerAction(shrink_planets)
|
||||
openspace.action.registerAction(toggle_planet_scale)
|
||||
|
||||
openspace.action.registerAction(grow_inner_planets)
|
||||
openspace.action.registerAction(shrink_inner_planets)
|
||||
openspace.action.registerAction(toggle_inner_planet_scale)
|
||||
|
||||
openspace.action.registerAction(grow_outter_planets)
|
||||
openspace.action.registerAction(shrink_outter_planets)
|
||||
openspace.action.registerAction(toggle_outter_planet_scale)
|
||||
|
||||
openspace.action.registerAction(grow_jupiter_moons)
|
||||
openspace.action.registerAction(shrink_jupiter_moons)
|
||||
openspace.action.registerAction(toggle_jupiter_moon_scales)
|
||||
|
||||
openspace.action.registerAction(grow_moon)
|
||||
openspace.action.registerAction(shrink_moon)
|
||||
openspace.action.registerAction(toggle_moon_scale)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.action.removeAction(toggle_moon_scale)
|
||||
openspace.action.removeAction(shrink_moon)
|
||||
openspace.action.removeAction(grow_moon)
|
||||
|
||||
openspace.action.removeAction(toggle_outter_planet_scale)
|
||||
openspace.action.removeAction(shrink_outter_planets)
|
||||
openspace.action.removeAction(grow_outter_planets)
|
||||
|
||||
openspace.action.removeAction(toggle_inner_planet_scale)
|
||||
openspace.action.removeAction(shrink_inner_planets)
|
||||
openspace.action.removeAction(grow_inner_planets)
|
||||
|
||||
openspace.action.removeAction(toggle_planet_scale)
|
||||
openspace.action.removeAction(shrink_planets)
|
||||
openspace.action.removeAction(grow_planets)
|
||||
end)
|
||||
29
data/assets/actions/system/undo_event_fades.asset
Normal file
29
data/assets/actions/system/undo_event_fades.asset
Normal file
@@ -0,0 +1,29 @@
|
||||
local undo_event_fade = {
|
||||
Identifier = "os.undo_event_fade",
|
||||
Name = "Undo All Event Fading",
|
||||
Command = [[
|
||||
openspace.setPropertyValue("Scene.*.Renderable.Fade", 1.0, 0.5);
|
||||
]],
|
||||
Documentation = [[Sets the 'Fade' value of all renderables to 1. This internval values is managed by events.]],
|
||||
GuiPath = "/System/Rendering",
|
||||
IsLocal = true
|
||||
}
|
||||
asset.export("undo_event_fade", undo_event_fade.Identifier)
|
||||
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.action.registerAction(undo_event_fade)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.action.removeAction(undo_event_fade)
|
||||
end)
|
||||
|
||||
asset.meta = {
|
||||
Name = "Actions - Undo All Event Fading",
|
||||
Version = "1.0",
|
||||
Description = [[ Asset providing debug ability to undo all event fading.]],
|
||||
Author = "OpenSpace Team",
|
||||
URL = "http://openspaceproject.com",
|
||||
License = "MIT license"
|
||||
}
|
||||
67
data/assets/actions/trails/toggle_all_trails.asset
Normal file
67
data/assets/actions/trails/toggle_all_trails.asset
Normal file
@@ -0,0 +1,67 @@
|
||||
local fade_up_trails = {
|
||||
Identifier = "os.fade_up_trails",
|
||||
Name = "Show All Trails",
|
||||
Command = [[
|
||||
openspace.setPropertyValue("Scene.*Trail.Renderable.Fade", 1, 2);
|
||||
openspace.setPropertyValue("Scene.*trail.Renderable.Fade", 1, 2);
|
||||
]],
|
||||
Documentation = "Fade up all enabled trails in the Scene",
|
||||
GuiPath = "/Trails",
|
||||
IsLocal = true
|
||||
}
|
||||
asset.export("fade_up_trails", fade_up_trails.Identifier)
|
||||
|
||||
local fade_down_trails = {
|
||||
Identifier = "os.fade_down_trails",
|
||||
Name = "Hide All Trails",
|
||||
Command = [[
|
||||
openspace.setPropertyValue("Scene.*Trail.Renderable.Fade", 0, 2);
|
||||
openspace.setPropertyValue("Scene.*trail.Renderable.Fade", 0, 2);
|
||||
]],
|
||||
Documentation = "Fade down all enabled trails in the Scene",
|
||||
GuiPath = "/Trails",
|
||||
IsLocal = true
|
||||
}
|
||||
asset.export("fade_down_trails", fade_down_trails.Identifier)
|
||||
|
||||
local toggle_trails = {
|
||||
Identifier = "os.toggle_trails",
|
||||
Name = "Toggle All Trails",
|
||||
Command = [[
|
||||
local capList = openspace.getProperty("*Trail.Renderable.Fade");
|
||||
local list = openspace.getProperty("*trail.Renderable.Fade");
|
||||
if (#capList == 0) and (#list == 0) then
|
||||
openspace.printWarning("No trails to toggle");
|
||||
else
|
||||
local prop;
|
||||
if #capList > 0 then
|
||||
prop = capList[1];
|
||||
else
|
||||
prop = list[1];
|
||||
end
|
||||
local currentFade = openspace.getPropertyValue(prop);
|
||||
local newFade = 0;
|
||||
if currentFade < 1 then
|
||||
newFade = 1;
|
||||
end
|
||||
openspace.setPropertyValue("Scene.*Trail.Renderable.Fade", newFade, 2);
|
||||
openspace.setPropertyValue("Scene.*trail.Renderable.Fade", newFade, 2);
|
||||
end
|
||||
]],
|
||||
Documentation = "Toggle fade for all trails in the Scene",
|
||||
GuiPath = "/Trails",
|
||||
IsLocal = true
|
||||
}
|
||||
asset.export("toggle_trails", toggle_trails.Identifier)
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.action.registerAction(fade_up_trails)
|
||||
openspace.action.registerAction(fade_down_trails)
|
||||
openspace.action.registerAction(toggle_trails)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.action.removeAction(toggle_trails)
|
||||
openspace.action.removeAction(fade_down_trails)
|
||||
openspace.action.removeAction(fade_up_trails)
|
||||
end)
|
||||
@@ -0,0 +1,24 @@
|
||||
local toggle_trails = {
|
||||
Identifier = "os_default.toggle_trails",
|
||||
Name = "Toggle Planet and Moon Trails (Instant)",
|
||||
Command = [[
|
||||
local list = openspace.getProperty("{planetTrail_solarSystem}.Renderable.Enabled");
|
||||
for _,v in pairs(list) do openspace.setPropertyValueSingle(v, not openspace.getPropertyValue(v)) end
|
||||
|
||||
local moonlist = openspace.getProperty("{moonTrail_solarSystem}.Renderable.Enabled");
|
||||
for _,v in pairs(moonlist) do openspace.setPropertyValueSingle(v, not openspace.getPropertyValue(v)) end
|
||||
]],
|
||||
Documentation = "Toggles the visibility of planet and moon trails",
|
||||
GuiPath = "/Solar System",
|
||||
IsLocal = false,
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.action.registerAction(toggle_trails)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.action.removeAction(toggle_trails)
|
||||
end)
|
||||
|
||||
asset.export(toggle_trails)
|
||||
67
data/assets/actions/trails/toggle_trails_planets_moons.asset
Normal file
67
data/assets/actions/trails/toggle_trails_planets_moons.asset
Normal file
@@ -0,0 +1,67 @@
|
||||
local fade_up_trails = {
|
||||
Identifier = "os.fade_up_trails_planets_moon",
|
||||
Name = "Show Planet and Moon Trails",
|
||||
Command = [[
|
||||
openspace.setPropertyValue("{planetTrail_solarSystem}.Renderable.Fade", 1, 2);
|
||||
openspace.setPropertyValue("{moonTrail_solarSystem}.Renderable.Fade", 1, 2);
|
||||
]],
|
||||
Documentation = "Fade up all planet and moon trails in the Scene",
|
||||
GuiPath = "/Trails",
|
||||
IsLocal = true
|
||||
}
|
||||
asset.export("fade_up_trails", fade_up_trails.Identifier)
|
||||
|
||||
local fade_down_trails = {
|
||||
Identifier = "os.fade_down_trails_planets_moon",
|
||||
Name = "Hide Planet and Moon Trails",
|
||||
Command = [[
|
||||
openspace.setPropertyValue("{planetTrail_solarSystem}.Renderable.Fade", 0, 2);
|
||||
openspace.setPropertyValue("{moonTrail_solarSystem}.Renderable.Fade", 0, 2);
|
||||
]],
|
||||
Documentation = "Fade down all planet and moon trails in the Scene",
|
||||
GuiPath = "/Trails",
|
||||
IsLocal = true
|
||||
}
|
||||
asset.export("fade_down_trails", fade_down_trails.Identifier)
|
||||
|
||||
local toggle_trails = {
|
||||
Identifier = "os.toggle_trails_planets_moon",
|
||||
Name = "Toggle Planet and Moon Trails",
|
||||
Command = [[
|
||||
local capList = openspace.getProperty("{planetTrail_solarSystem}.Renderable.Fade");
|
||||
local list = openspace.getProperty("{moonTrail_solarSystem}.Renderable.Fade");
|
||||
if (#capList == 0) and (#list == 0) then
|
||||
openspace.printWarning("No trails to toggle");
|
||||
else
|
||||
local prop;
|
||||
if (#capList > 0) then
|
||||
prop = capList[1];
|
||||
else
|
||||
prop = list[1];
|
||||
end
|
||||
local currentFade = openspace.getPropertyValue(prop);
|
||||
local newFade = 0;
|
||||
if currentFade < 1 then
|
||||
newFade = 1;
|
||||
end
|
||||
openspace.setPropertyValue("{planetTrail_solarSystem}.Renderable.Fade", newFade, 2);
|
||||
openspace.setPropertyValue("{moonTrail_solarSystem}.Renderable.Fade", newFade, 2);
|
||||
end
|
||||
]],
|
||||
Documentation = "Toggle fade for planet and moon trails in the Scene",
|
||||
GuiPath = "/Trails",
|
||||
IsLocal = true
|
||||
}
|
||||
asset.export("toggle_trails", toggle_trails)
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.action.registerAction(fade_up_trails)
|
||||
openspace.action.registerAction(fade_down_trails)
|
||||
openspace.action.registerAction(toggle_trails)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.action.removeAction(toggle_trails)
|
||||
openspace.action.removeAction(fade_down_trails)
|
||||
openspace.action.removeAction(fade_up_trails)
|
||||
end)
|
||||
163
data/assets/actions/trails/trail_appearance.asset
Normal file
163
data/assets/actions/trails/trail_appearance.asset
Normal file
@@ -0,0 +1,163 @@
|
||||
local enable_trail_fading = {
|
||||
Identifier = "os.enable_trail_fading",
|
||||
Name = "Enable Trail Fading",
|
||||
Command = [[
|
||||
openspace.setPropertyValue("Scene.*Trail.Renderable.Appearance.EnableFade", true);
|
||||
openspace.setPropertyValue("Scene.*trail.Renderable.Appearance.EnableFade", true);
|
||||
]],
|
||||
Documentation = "Set orbits to fade out towards the end",
|
||||
GuiPath = "/Trails/Appearance",
|
||||
IsLocal = true
|
||||
}
|
||||
asset.export("enable_trail_fading", enable_trail_fading.Identifier)
|
||||
|
||||
local disable_trail_fading = {
|
||||
Identifier = "os.disable_trail_fading",
|
||||
Name = "Disable Trail Fading",
|
||||
Command = [[
|
||||
openspace.setPropertyValue("Scene.*Trail.Renderable.Appearance.EnableFade", false);
|
||||
openspace.setPropertyValue("Scene.*trail.Renderable.Appearance.EnableFade", false);
|
||||
]],
|
||||
Documentation = "Sets trails not to fade out torwards end",
|
||||
GuiPath = "/Trails/Appearance",
|
||||
IsLocal = true
|
||||
}
|
||||
asset.export("disable_trail_fading", disable_trail_fading.Identifier)
|
||||
|
||||
local toggle_trail_fading = {
|
||||
Identifier = "os.toggle_trail_fading",
|
||||
Name = "Toggle Trail Fading",
|
||||
Command = [[
|
||||
local capList = openspace.getProperty("*Trail.Renderable.Appearance.EnableFade")
|
||||
local list = openspace.getProperty("*trail.Renderable.Appearance.EnableFade")
|
||||
if (#capList == 0) and (#list == 0) then
|
||||
openspace.printWarning("No trails to toggle");
|
||||
else
|
||||
local prop;
|
||||
if #capList > 0 then
|
||||
prop = capList[1];
|
||||
else
|
||||
prop = list[1];
|
||||
end
|
||||
local currentFade = openspace.getPropertyValue(prop);
|
||||
local newFade = not currentFade;
|
||||
openspace.setPropertyValue("Scene.*Trail.Renderable.Appearance.EnableFade", newFade);
|
||||
openspace.setPropertyValue("Scene.*trail.Renderable.Appearance.EnableFade", newFade);
|
||||
end
|
||||
]],
|
||||
Documentation = "Toggle trails to fade out towards the end for all trails in the Scene",
|
||||
GuiPath = "/Trails/Appearance",
|
||||
IsLocal = true
|
||||
}
|
||||
asset.export("toggle_trail_fading", toggle_trail_fading.Identifier)
|
||||
|
||||
local function getHightlightCommand(identifierString, value)
|
||||
local easeFunction = "QuinticEaseOut"
|
||||
if value > 1 then
|
||||
easeFunction = "QuinticEaseIn"
|
||||
end
|
||||
local command = 'openspace.setPropertyValue("'
|
||||
command = command .. identifierString .. '.Renderable.Appearance.Fade", '
|
||||
command = command .. value .. ', 2, "' .. easeFunction .. '")'
|
||||
return command;
|
||||
end
|
||||
|
||||
local function getHighlightAction(identifierString, value, nameString)
|
||||
local actionString = 'Dehighlight'
|
||||
if value > 1 then
|
||||
actionString = 'Highlight'
|
||||
end
|
||||
local action = {
|
||||
Identifier = "os." .. actionString .. identifierString .. "_trail",
|
||||
Name = actionString .. " " .. nameString .. " Trail",
|
||||
Command = getHightlightCommand(identifierString, value),
|
||||
Documentation = "Animates the trail fade of " .. nameString .. "'s Trail",
|
||||
GuiPath = "/Trails/Appearance",
|
||||
IsLocal = true
|
||||
}
|
||||
return action
|
||||
end
|
||||
|
||||
local function getToggleHighlightAction(identifierString, value, nameString)
|
||||
local action = {
|
||||
Identifier = "os.toggle_" .. identifierString .. "_trail_highlight",
|
||||
Name = "Toggle " .. nameString .. " Trail Highlight",
|
||||
Command = [[
|
||||
local list = openspace.getProperty("]] .. identifierString .. [[.Renderable.Appearance.Fade");
|
||||
if #list == 0 then
|
||||
openspace.printWarning("No planets to resize");
|
||||
else
|
||||
local prop = list[1];
|
||||
local fadeValue = openspace.getPropertyValue(prop)
|
||||
if fadeValue > 1 then
|
||||
]] .. getHightlightCommand(identifierString, 1, nameString) .. "\n" .. [[
|
||||
else
|
||||
]] .. getHightlightCommand(identifierString, value, nameString) .. "\n" .. [[
|
||||
end
|
||||
end]],
|
||||
Documentation = "Animates the trail fade of " .. nameString .. "'s trail",
|
||||
GuiPath = "/Trails/Appearance",
|
||||
IsLocal = true
|
||||
}
|
||||
return action
|
||||
end
|
||||
|
||||
local earthTrailIdentifer = "Scene.EarthTrail"
|
||||
|
||||
local highlight_earth_trail = getHighlightAction(earthTrailIdentifer, 10, "Earth")
|
||||
asset.export("highlight_earth_trail", highlight_earth_trail.Identifier)
|
||||
local dehighlight_earth_trail = getHighlightAction(earthTrailIdentifer, 1, "Earth")
|
||||
asset.export("dehighlight_earth_trail", dehighlight_earth_trail.Identifier)
|
||||
local toggle_earth_trail_highlight = getToggleHighlightAction(earthTrailIdentifer, 10, "Earth")
|
||||
asset.export("toggle_earth_trail_highlight", toggle_earth_trail_highlight.Identifier)
|
||||
|
||||
local highlight_inner_trails = getHighlightAction("{planetTrail_terrestrial}", 50, "Inner Planet")
|
||||
asset.export("highlight_inner_trails", highlight_inner_trails.Identifier)
|
||||
local dehighlight_inner_trails = getHighlightAction("{planetTrail_terrestrial}", 1, "Inner Planet")
|
||||
asset.export("dehighlight_inner_trails", dehighlight_inner_trails.Identifier)
|
||||
local toggle_inner_trail_highlight = getToggleHighlightAction("{planetTrail_terrestrial}", 50, "Inner Planet")
|
||||
asset.export("toggle_inner_trail_highlight", toggle_inner_trail_highlight.Identifier)
|
||||
|
||||
local highlight_outter_trails = getHighlightAction("{planetTrail_giants}", 100, "Outter Planet")
|
||||
asset.export("highlight_outter_trails", highlight_outter_trails.Identifier)
|
||||
local dehighlight_outter_trails = getHighlightAction("{planetTrail_giants}", 1, "Outter Planet")
|
||||
asset.export("dehighlight_outter_trails", dehighlight_outter_trails.Identifier)
|
||||
local toggle_outter_trail_highlight = getToggleHighlightAction("{planetTrail_giants}", 100, "Outter Planet")
|
||||
asset.export("toggle_outter_trail_highlight", toggle_outter_trail_highlight.Identifier)
|
||||
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.action.registerAction(enable_trail_fading)
|
||||
openspace.action.registerAction(disable_trail_fading)
|
||||
openspace.action.registerAction(toggle_trail_fading)
|
||||
|
||||
openspace.action.registerAction(highlight_earth_trail)
|
||||
openspace.action.registerAction(dehighlight_earth_trail)
|
||||
openspace.action.registerAction(toggle_earth_trail_highlight)
|
||||
|
||||
openspace.action.registerAction(highlight_inner_trails)
|
||||
openspace.action.registerAction(dehighlight_inner_trails)
|
||||
openspace.action.registerAction(toggle_inner_trail_highlight)
|
||||
|
||||
openspace.action.registerAction(highlight_outter_trails)
|
||||
openspace.action.registerAction(dehighlight_outter_trails)
|
||||
openspace.action.registerAction(toggle_outter_trail_highlight)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.action.removeAction(toggle_outter_trail_highlight)
|
||||
openspace.action.removeAction(dehighlight_outter_trails)
|
||||
openspace.action.removeAction(highlight_outter_trails)
|
||||
|
||||
openspace.action.removeAction(highlight_inner_trails)
|
||||
openspace.action.removeAction(dehighlight_inner_trails)
|
||||
openspace.action.removeAction(toggle_inner_trail_highlight)
|
||||
|
||||
openspace.action.removeAction(highlight_earth_trail)
|
||||
openspace.action.removeAction(dehighlight_earth_trail)
|
||||
openspace.action.removeAction(toggle_earth_trail_highlight)
|
||||
|
||||
openspace.action.removeAction(toggle_trail_fading)
|
||||
openspace.action.removeAction(disable_trail_fading)
|
||||
openspace.action.removeAction(enable_trail_fading)
|
||||
end)
|
||||
@@ -4,6 +4,10 @@
|
||||
|
||||
asset.require("./base_blank")
|
||||
|
||||
-- Modules and component settings
|
||||
asset.require("modules/exoplanets/exoplanets")
|
||||
asset.require("modules/skybrowser/skybrowser")
|
||||
|
||||
-- Specifying which other assets should be loaded in this scene
|
||||
asset.require("scene/solarsystem/sun/sun")
|
||||
asset.require("scene/solarsystem/sun/glare")
|
||||
@@ -17,12 +21,6 @@ asset.require("scene/solarsystem/dwarf_planets/pluto/charon/default_layers")
|
||||
asset.require("scene/milkyway/milkyway/volume")
|
||||
asset.require("scene/milkyway/constellations/constellation_art")
|
||||
asset.require("scene/milkyway/constellations/constellation_keybinds")
|
||||
asset.require("scene/milkyway/objects/orionnebula/orionnebula")
|
||||
asset.require("util/launcher_images")
|
||||
|
||||
-- For exoplanet system visualizations
|
||||
asset.require("scene/milkyway/exoplanets/exoplanets_data")
|
||||
asset.require("scene/milkyway/exoplanets/exoplanets_textures")
|
||||
|
||||
asset.require("scene/digitaluniverse/2dF")
|
||||
asset.require("scene/digitaluniverse/2mass")
|
||||
@@ -60,11 +58,56 @@ asset.require("scene/digitaluniverse/supernovaremnants")
|
||||
asset.require("scene/digitaluniverse/tully")
|
||||
asset.require("scene/digitaluniverse/voids")
|
||||
|
||||
|
||||
asset.require("customization/globebrowsing")
|
||||
asset.require("util/default_actions")
|
||||
|
||||
local toggle_trails = {
|
||||
Identifier = "os_default.toggle_trails",
|
||||
Name = "Toggle Trails",
|
||||
Command = [[
|
||||
local list = openspace.getProperty("{planetTrail_solarSystem}.Renderable.Enabled");
|
||||
for _,v in pairs(list) do openspace.setPropertyValueSingle(v, not openspace.getPropertyValue(v)) end
|
||||
|
||||
local moonlist = openspace.getProperty("{moonTrail_solarSystem}.Renderable.Enabled");
|
||||
for _,v in pairs(moonlist) do openspace.setPropertyValueSingle(v, not openspace.getPropertyValue(v)) end
|
||||
]],
|
||||
Documentation = "Toggles the visibility of planet and moon trails",
|
||||
GuiPath = "/Rendering",
|
||||
IsLocal = false,
|
||||
|
||||
Key = "h"
|
||||
}
|
||||
|
||||
local toggle_planet_labels = {
|
||||
Identifier = "os_default.toggle_planet_labels",
|
||||
Name = "Toggle planet labels",
|
||||
Command = [[
|
||||
local list = openspace.getProperty("{solarsystem_labels}.Renderable.Enabled");
|
||||
for _,v in pairs(list) do openspace.setPropertyValueSingle(v, not openspace.getPropertyValue(v)) end
|
||||
]],
|
||||
Documentation = "Turns on visibility for all solar system labels",
|
||||
GuiPath = "/Rendering",
|
||||
IsLocal = false,
|
||||
|
||||
Key = "l"
|
||||
}
|
||||
|
||||
local trailAction = asset.require("actions/trails/toggle_trails_planets_moons").toggle_trails
|
||||
|
||||
asset.onInitialize(function ()
|
||||
openspace.bindKey("h", trailAction.Identifier)
|
||||
|
||||
openspace.action.registerAction(toggle_planet_labels)
|
||||
openspace.bindKey(toggle_planet_labels.Key, toggle_planet_labels.Identifier)
|
||||
|
||||
openspace.globebrowsing.loadWMSServersFromFile(
|
||||
openspace.absPath("${DATA}/globebrowsing_servers.lua")
|
||||
)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function ()
|
||||
openspace.clearKey(toggle_trails.Key)
|
||||
|
||||
openspace.action.removeAction(toggle_planet_labels)
|
||||
openspace.clearKey(toggle_planet_labels.Key)
|
||||
end)
|
||||
|
||||
@@ -15,55 +15,11 @@ local webGui = asset.require("util/webgui")
|
||||
-- Scale the different UI components based on the operating system's DPI scaling value
|
||||
asset.require("util/dpiscaling")
|
||||
|
||||
local toggle_trails = {
|
||||
Identifier = "os_default.toggle_trails",
|
||||
Name = "Toggle Trails",
|
||||
Command = [[
|
||||
local list = openspace.getProperty("{planetTrail_solarSystem}.Renderable.Enabled");
|
||||
for _,v in pairs(list) do openspace.setPropertyValueSingle(v, not openspace.getPropertyValue(v)) end
|
||||
|
||||
local moonlist = openspace.getProperty("{moonTrail_solarSystem}.Renderable.Enabled");
|
||||
for _,v in pairs(moonlist) do openspace.setPropertyValueSingle(v, not openspace.getPropertyValue(v)) end
|
||||
]],
|
||||
Documentation = "Toggles the visibility of planet and moon trails",
|
||||
GuiPath = "/Rendering",
|
||||
IsLocal = false,
|
||||
|
||||
Key = "h"
|
||||
}
|
||||
|
||||
local toggle_planet_labels = {
|
||||
Identifier = "os_default.toggle_planet_labels",
|
||||
Name = "Toggle planet labels",
|
||||
Command = [[
|
||||
local list = openspace.getProperty("{solarsystem_labels}.Renderable.Enabled");
|
||||
for _,v in pairs(list) do openspace.setPropertyValueSingle(v, not openspace.getPropertyValue(v)) end
|
||||
]],
|
||||
Documentation = "Turns on visibility for all solar system labels",
|
||||
GuiPath = "/Rendering",
|
||||
IsLocal = false,
|
||||
|
||||
Key = "l"
|
||||
}
|
||||
-- Load the images required for the launcher to show up
|
||||
asset.require("util/launcher_images")
|
||||
|
||||
asset.onInitialize(function ()
|
||||
webGui.setCefRoute("onscreen")
|
||||
|
||||
openspace.action.registerAction(toggle_trails)
|
||||
openspace.bindKey(toggle_trails.Key, toggle_trails.Identifier)
|
||||
|
||||
openspace.action.registerAction(toggle_planet_labels)
|
||||
openspace.bindKey(toggle_planet_labels.Key, toggle_planet_labels.Identifier)
|
||||
|
||||
openspace.setDefaultGuiSorting()
|
||||
|
||||
openspace.setPropertyValueSingle("RenderEngine.VerticalLogOffset", 0.100000)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function ()
|
||||
openspace.action.removeAction(toggle_trails)
|
||||
openspace.clearKey(toggle_trails.Key)
|
||||
|
||||
openspace.action.removeAction(toggle_planet_labels)
|
||||
openspace.clearKey(toggle_planet_labels.Key)
|
||||
end)
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 18 KiB |
@@ -1,8 +1,8 @@
|
||||
local item = {
|
||||
Type = "DashboardItemVelocity",
|
||||
Identifier = "GlobeLocation",
|
||||
Identifier = "CameraVelocity",
|
||||
Simplification = true,
|
||||
GuiName = "Velocity"
|
||||
GuiName = "Camera Velocity"
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
|
||||
27
data/assets/events/toggle_all_trails.asset
Normal file
27
data/assets/events/toggle_all_trails.asset
Normal file
@@ -0,0 +1,27 @@
|
||||
local action = asset.require("actions/trails/toggle_all_trails")
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.event.registerEventAction(
|
||||
"CameraFocusTransition",
|
||||
action.fade_up_trails,
|
||||
{ Transition = "Exiting" }
|
||||
)
|
||||
openspace.event.registerEventAction(
|
||||
"CameraFocusTransition",
|
||||
action.fade_down_trails,
|
||||
{ Transition = "Approaching" }
|
||||
)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.event.unregisterEventAction(
|
||||
"CameraFocusTransition",
|
||||
action.fade_up_trails,
|
||||
{ Transition = "Exiting" }
|
||||
)
|
||||
openspace.event.unregisterEventAction(
|
||||
"CameraFocusTransition",
|
||||
action.fade_down_trails,
|
||||
{ Transition = "Approaching" }
|
||||
)
|
||||
end)
|
||||
@@ -22,7 +22,7 @@ local toggle_sun = {
|
||||
Documentation = [[Toggles the visibility of the Sun glare and the Sun globe when the
|
||||
camera is approaching either so that from far away the Sun Glare is rendered and when
|
||||
close up, the globe is rendered instead.]],
|
||||
GuiPath = "/Sun",
|
||||
GuiPath = "/Solar System/Sun",
|
||||
IsLocal = false
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
local action = asset.require("actions/toggle_trail")
|
||||
local action = asset.require("actions/trails/toggle_trail")
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.event.registerEventAction(
|
||||
|
||||
27
data/assets/events/toggle_trails_planets_moons.asset
Normal file
27
data/assets/events/toggle_trails_planets_moons.asset
Normal file
@@ -0,0 +1,27 @@
|
||||
local action = asset.require("actions/trails/toggle_trails_planets_moons")
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.event.registerEventAction(
|
||||
"CameraFocusTransition",
|
||||
action.fade_up_trails,
|
||||
{ Transition = "Exiting" }
|
||||
)
|
||||
openspace.event.registerEventAction(
|
||||
"CameraFocusTransition",
|
||||
action.fade_down_trails,
|
||||
{ Transition = "Approaching" }
|
||||
)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.event.unregisterEventAction(
|
||||
"CameraFocusTransition",
|
||||
action.fade_up_trails,
|
||||
{ Transition = "Exiting" }
|
||||
)
|
||||
openspace.event.unregisterEventAction(
|
||||
"CameraFocusTransition",
|
||||
action.fade_down_trails,
|
||||
{ Transition = "Approaching" }
|
||||
)
|
||||
end)
|
||||
@@ -25,8 +25,8 @@
|
||||
-- First - Name of the joystick that should be bound
|
||||
-- Second - Which axis should be bound of this joystick
|
||||
-- Third - The property uri
|
||||
-- Fourth - (optional) The smallest value that you wnat to allow this property on the joystick
|
||||
-- Fifth - (optional) The largest value that you wnat to allow this property on the joystick
|
||||
-- Fourth - (optional) The smallest value that you want to allow this property on the joystick
|
||||
-- Fifth - (optional) The largest value that you want to allow this property on the joystick
|
||||
-- Sixth - (optional) Determines whether the axis should be inverted
|
||||
-- Seventh - (optional) Should this property change be sent to other connected remote sessions
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ local layer_folder = {
|
||||
Type = "TemporalTileLayer",
|
||||
Mode = "Folder",
|
||||
Folder = {
|
||||
Folder = "C:/Development/sync/http/earth_textures_climate/1",
|
||||
Folder = path,
|
||||
Format = "%Y-%m-%d-land.png"
|
||||
},
|
||||
Interpolation = true,
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
-- This asset requires OpenSpace to be built with the OPENSPACE_MODULE_SPOUT enabled
|
||||
|
||||
local transforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
|
||||
local circle = {
|
||||
Identifier = "hoverCircle",
|
||||
Parent = transforms.SolarSystemBarycenter.Identifier,
|
||||
Renderable = {
|
||||
Type = "RenderablePlaneImageLocal",
|
||||
Size = 3.0E15,
|
||||
Origin = "Center",
|
||||
Billboard = true,
|
||||
Texture = "${ASSETS}/circle.png"
|
||||
},
|
||||
GUI = {
|
||||
Path = "/SkyBrowser"
|
||||
}
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addSceneGraphNode(circle)
|
||||
openspace.skybrowser.setHoverCircle('hoverCircle')
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeSceneGraphNode(circle)
|
||||
end)
|
||||
|
||||
asset.export(circle)
|
||||
16
data/assets/modules/exoplanets/default_settings.asset
Normal file
16
data/assets/modules/exoplanets/default_settings.asset
Normal file
@@ -0,0 +1,16 @@
|
||||
asset.onInitialize(function ()
|
||||
openspace.setPropertyValueSingle("Modules.Exoplanets.Enabled", true)
|
||||
openspace.setPropertyValueSingle("Modules.Exoplanets.ShowComparisonCircle", false)
|
||||
openspace.setPropertyValueSingle("Modules.Exoplanets.ShowHabitableZone", true)
|
||||
openspace.setPropertyValueSingle("Modules.Exoplanets.UseOptimisticZone", true)
|
||||
openspace.setPropertyValueSingle("Modules.Exoplanets.HabitableZoneOpacity", 0.1)
|
||||
end)
|
||||
|
||||
asset.meta = {
|
||||
Name = "Exoplanet Default Settings",
|
||||
Version = "1.0",
|
||||
Description = [[ Some default settings related to the exoplanet module ]],
|
||||
Author = "OpenSpace Team",
|
||||
URL = "http://openspaceproject.com",
|
||||
License = "MIT license"
|
||||
}
|
||||
3
data/assets/modules/exoplanets/exoplanets.asset
Normal file
3
data/assets/modules/exoplanets/exoplanets.asset
Normal file
@@ -0,0 +1,3 @@
|
||||
asset.require("./default_settings")
|
||||
asset.require("./exoplanets_data")
|
||||
asset.require("./exoplanets_textures")
|
||||
@@ -2,17 +2,19 @@ local DataPath = asset.syncedResource({
|
||||
Name = "Exoplanet Data Files",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "exoplanets_data",
|
||||
Version = 2
|
||||
Version = 3
|
||||
})
|
||||
|
||||
local colormaps = asset.syncedResource({
|
||||
Name = "Stars Color Table",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "stars_colormap",
|
||||
Version = 2
|
||||
Version = 3
|
||||
})
|
||||
|
||||
asset.onInitialize(function ()
|
||||
-- Set the default data files used for the exoplanet system creation
|
||||
-- (Check if already set, to not override value set in another file)
|
||||
local p = "Modules.Exoplanets.DataFolder";
|
||||
if (openspace.getPropertyValue(p) == "") then
|
||||
openspace.setPropertyValueSingle(p, DataPath)
|
||||
@@ -28,7 +30,7 @@ asset.export("DataPath", DataPath)
|
||||
|
||||
asset.meta = {
|
||||
Name = "Exoplanet Data",
|
||||
Version = "2.0",
|
||||
Version = "3.0",
|
||||
Description = [[ The data that is used for the exoplanet systems. The data has been
|
||||
derived from the 'Planetary Systems Composite Data' dataset from the NASA Exoplanet
|
||||
Archive]],
|
||||
@@ -1,5 +1,6 @@
|
||||
local habitableZoneTextures =
|
||||
asset.require("../habitable_zones/habitable_zone_textures").TexturesPath
|
||||
local habitableZoneTextures = asset.require(
|
||||
"scene/milkyway/habitable_zones/habitable_zone_textures"
|
||||
).TexturesPath
|
||||
|
||||
local sunTextures = asset.syncedResource({
|
||||
Type = "HttpSynchronization",
|
||||
@@ -25,7 +26,7 @@ asset.onInitialize(function ()
|
||||
local hzTexture = habitableZoneTextures .. "hot_to_cold_faded.png"
|
||||
|
||||
-- Set the default textures used for the exoplanet system creation
|
||||
-- (Check if already set, to not override value in config file)
|
||||
-- (Check if already set, to not override value set in another file)
|
||||
local p = "Modules.Exoplanets.StarTexture";
|
||||
if (openspace.getPropertyValue(p) == "") then
|
||||
openspace.setPropertyValueSingle(p, starTexture)
|
||||
14
data/assets/modules/skybrowser/default_settings.asset
Normal file
14
data/assets/modules/skybrowser/default_settings.asset
Normal file
@@ -0,0 +1,14 @@
|
||||
asset.onInitialize(function ()
|
||||
openspace.setPropertyValueSingle("Modules.SkyBrowser.Enabled", true)
|
||||
openspace.setPropertyValueSingle("Modules.SkyBrowser.ShowTitleInGuiBrowser", false)
|
||||
-- More settings are available, but for now using the default values
|
||||
end)
|
||||
|
||||
asset.meta = {
|
||||
Name = "SkyBrowser Module Default Settings",
|
||||
Version = "1.0",
|
||||
Description = [[ Some default settings related to the SkyBrowser module ]],
|
||||
Author = "OpenSpace Team",
|
||||
URL = "http://openspaceproject.com",
|
||||
License = "MIT license"
|
||||
}
|
||||
50
data/assets/modules/skybrowser/hoverCircle.asset
Normal file
50
data/assets/modules/skybrowser/hoverCircle.asset
Normal file
@@ -0,0 +1,50 @@
|
||||
-- This asset requires OpenSpace to be built with the OPENSPACE_MODULE_SPOUT enabled
|
||||
|
||||
local transforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
|
||||
local imageFolder = asset.syncedResource({
|
||||
Name = "Hover Circle Image",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "misc_ring_image",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
local circle = {
|
||||
Identifier = "hoverCircle",
|
||||
Parent = transforms.SolarSystemBarycenter.Identifier,
|
||||
Renderable = {
|
||||
Type = "RenderablePlaneImageLocal",
|
||||
Size = 3.0E15,
|
||||
Origin = "Center",
|
||||
Billboard = true,
|
||||
Texture = imageFolder .. "ring.png"
|
||||
},
|
||||
GUI = {
|
||||
Name = "Hover Circle",
|
||||
Description = [[A circular marker that shows the position on the night sky
|
||||
of the object hovered in the sky browser UI. The circle will hide/show up
|
||||
dynamically, depending on the interaction with the items in the UI. ]],
|
||||
Path = "/SkyBrowser"
|
||||
}
|
||||
}
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addSceneGraphNode(circle)
|
||||
openspace.skybrowser.setHoverCircle('hoverCircle')
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeSceneGraphNode(circle)
|
||||
end)
|
||||
|
||||
asset.export(circle)
|
||||
|
||||
asset.meta = {
|
||||
Name = "SkyBrowser Hover Circle",
|
||||
Version = "1.0",
|
||||
Description = [[Includes a circular marker that shows the position on the night sky
|
||||
of the object hovered in the sky browser UI. ]],
|
||||
Author = "OpenSpace Team",
|
||||
URL = "http://openspaceproject.com",
|
||||
License = "MIT license"
|
||||
}
|
||||
2
data/assets/modules/skybrowser/skybrowser.asset
Normal file
2
data/assets/modules/skybrowser/skybrowser.asset
Normal file
@@ -0,0 +1,2 @@
|
||||
asset.require("./default_settings")
|
||||
asset.require("./hoverCircle")
|
||||
@@ -12,6 +12,13 @@ local speck = asset.syncedResource({
|
||||
Version = 2
|
||||
})
|
||||
|
||||
local colormaps = asset.syncedResource({
|
||||
Name = "Quasars Colormap",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "digitaluniverse_quasars_colormap",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
local object = {
|
||||
Identifier = "Quasars",
|
||||
Renderable = {
|
||||
@@ -25,7 +32,11 @@ local object = {
|
||||
ScaleFactor = 540.9,
|
||||
FadeInDistances = { 1000.0, 10000.0 }, -- Fade in value in the same unit as "Unit"
|
||||
BillboardMinMaxSize = { 0.0, 11.1 },
|
||||
EnablePixelSizeControl = true
|
||||
EnablePixelSizeControl = true,
|
||||
ColorMap = colormaps .. "viridis.cmap",
|
||||
ColorOption = { "redshift", "Tlookback", "distMpc" },
|
||||
ColorRange = { { 0.102, 7.085 }, { 1.4, 13.0 }, { 440.5, 8852.099609 } },
|
||||
UseColorMap = false
|
||||
},
|
||||
GUI = {
|
||||
Name = "Quasars",
|
||||
|
||||
@@ -16,7 +16,7 @@ local colormaps = asset.syncedResource({
|
||||
Name = "Stars Color Table",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "stars_colormap",
|
||||
Version = 2
|
||||
Version = 3
|
||||
})
|
||||
|
||||
local textures = asset.syncedResource({
|
||||
|
||||
@@ -62,11 +62,11 @@ local createConstellations = function (baseIdentifier, guiPath, constellationfil
|
||||
BlendMode = "Additive",
|
||||
Opacity = 0.1
|
||||
},
|
||||
Tag = { "ConstellationArtImage", group },
|
||||
Tag = { "ImageConstellation", group },
|
||||
GUI = {
|
||||
Name = name .. " Image",
|
||||
Path = "/Milky Way/" .. guiPath,
|
||||
Description = name .. " Constellation Image"
|
||||
Description = name .. " Image"
|
||||
}
|
||||
}
|
||||
table.insert(genConstellations, aconstellation);
|
||||
@@ -83,9 +83,9 @@ local show_art = {
|
||||
Identifier = "constellation_art.show_art",
|
||||
Name = "Show Constellation Art",
|
||||
Command = [[
|
||||
openspace.setPropertyValue("Scene.ConstellationArt*.Renderable.Opacity", 0);
|
||||
openspace.setPropertyValue("Scene.ConstellationArt*.Renderable.Enabled", true);
|
||||
openspace.setPropertyValue("Scene.ConstellationArt*.Renderable.Opacity", 0.2, 2);
|
||||
openspace.setPropertyValue("Scene.ImageConstellation*.Renderable.Opacity", 0);
|
||||
openspace.setPropertyValue("Scene.ImageConstellation*.Renderable.Enabled", true);
|
||||
openspace.setPropertyValue("Scene.ImageConstellation*.Renderable.Opacity", 0.2, 2);
|
||||
]],
|
||||
Documentation = "Enables and fades up constellation art work",
|
||||
GuiPath = "/Rendering",
|
||||
@@ -96,7 +96,7 @@ asset.export("ShowArtAction", show_art)
|
||||
local hide_art = {
|
||||
Identifier = "constellation_art.hide_art",
|
||||
Name = "Hide Constellation Art",
|
||||
Command = [[openspace.setPropertyValue("Scene.ConstellationArt*.Renderable.Opacity", 0, 2)]],
|
||||
Command = [[openspace.setPropertyValue("Scene.ImageConstellation*.Renderable.Opacity", 0, 2)]],
|
||||
Documentation = "Fades out constellation artwork",
|
||||
GuiPath = "/Rendering",
|
||||
IsLocal = false
|
||||
@@ -106,7 +106,7 @@ asset.export("HideArtAction", hide_art)
|
||||
local disable_art = {
|
||||
Identifier = "constellation_art.disable_art",
|
||||
Name = "Disable Constellation Art",
|
||||
Command = [[openspace.setPropertyValue("Scene.ConstellationArt*.Renderable.Enabled", false)]],
|
||||
Command = [[openspace.setPropertyValue("Scene.ImageConstellation*.Renderable.Enabled", false)]],
|
||||
Documentation = "Disable constellation artwork",
|
||||
GuiPath = "/Rendering",
|
||||
IsLocal = false
|
||||
@@ -117,7 +117,7 @@ local show_zodiac_art = {
|
||||
Identifier = "constellation_art.show_zodiac_art",
|
||||
Name = "Show Zodiac Art",
|
||||
Command = [[
|
||||
openspace.setPropertyValue("Scene.ConstellationArt*.Renderable.Opacity", 0);
|
||||
openspace.setPropertyValue("Scene.ImageConstellation*.Renderable.Opacity", 0);
|
||||
openspace.setPropertyValue("{zodiac}.Renderable.Enabled",true);
|
||||
openspace.setPropertyValue("{zodiac}.Renderable.Opacity", 1, 2);
|
||||
]],
|
||||
@@ -142,7 +142,7 @@ local nodes = {}
|
||||
asset.onInitialize(function ()
|
||||
local constellationsCSV = images .. "constellation_data.csv"
|
||||
|
||||
nodes = createConstellations("ConstellationArt", "Constellation Art", constellationsCSV)
|
||||
nodes = createConstellations("ImageConstellation", "Constellation Art", constellationsCSV)
|
||||
for _, n in ipairs(nodes) do
|
||||
openspace.addSceneGraphNode(n);
|
||||
end
|
||||
|
||||
@@ -9,7 +9,7 @@ local colormaps = asset.syncedResource({
|
||||
Name = "Stars Color Table",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "stars_colormap",
|
||||
Version = 2
|
||||
Version = 3
|
||||
})
|
||||
|
||||
local textures = asset.syncedResource({
|
||||
@@ -27,13 +27,14 @@ local gaia_abundance_apogee = {
|
||||
File = speck .. "GaiaAbundApogee.speck",
|
||||
ColorOption = "Other Data",
|
||||
OtherData = "FeH",
|
||||
MagnitudeExponent = 6.2,
|
||||
MagnitudeExponent = 7.25,
|
||||
SizeComposition = "Distance Modulus",
|
||||
RenderMethod = "Texture Based",
|
||||
Texture = textures .. "halo.png",
|
||||
ColorRange = { { -0.8, 0.6 } },
|
||||
-- ShapeTexture = textures .. "disc.png",
|
||||
ColorMap = colormaps .. "colorbv.cmap",
|
||||
OtherDataColorMap = colormaps .. "viridis.cmap",
|
||||
OtherDataColorMap = colormaps .. "RainbowGradient.cmap",
|
||||
StaticFilter = -9999,
|
||||
StaticFilterReplacement = 0.0,
|
||||
DataMapping = {
|
||||
|
||||
@@ -16,7 +16,7 @@ local colormaps = asset.syncedResource({
|
||||
Name = "Stars Color Table",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "stars_colormap",
|
||||
Version = 2
|
||||
Version = 3
|
||||
})
|
||||
|
||||
local textures = asset.syncedResource({
|
||||
@@ -32,7 +32,7 @@ local GaiaStars = {
|
||||
Type = "RenderableGaiaStars",
|
||||
File = starsFolder,
|
||||
FileReaderOption = "StreamOctree",
|
||||
RenderOption = "Motion",
|
||||
RenderMode = "Motion",
|
||||
ShaderOption = "Point_SSBO",
|
||||
Texture = textures .. "halo.png",
|
||||
ColorMap = colormaps .. "colorbv.cmap",
|
||||
|
||||
@@ -9,7 +9,7 @@ local colormaps = asset.syncedResource({
|
||||
Name = "Stars Color Table",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "stars_colormap",
|
||||
Version = 2
|
||||
Version = 3
|
||||
})
|
||||
|
||||
local textures = asset.syncedResource({
|
||||
@@ -27,13 +27,14 @@ local gaia_abundance_galah = {
|
||||
File = speck .. "GaiaAbundGalah.speck",
|
||||
Texture = textures .. "halo.png",
|
||||
-- ShapeTexture = textures .. "disc.png",
|
||||
MagnitudeExponent = 6.2,
|
||||
MagnitudeExponent = 7.25,
|
||||
SizeComposition = "Distance Modulus",
|
||||
RenderMethod = "Texture Based",
|
||||
ColorOption = "Other Data",
|
||||
OtherData = "FeH",
|
||||
ColorMap = colormaps .. "colorbv.cmap",
|
||||
OtherDataColorMap = colormaps .. "viridis.cmap",
|
||||
OtherDataColorMap = colormaps .. "RainbowGradient.cmap",
|
||||
ColorRange = { { -0.8, 0.6 } },
|
||||
StaticFilter = -9999,
|
||||
StaticFilterReplacement = 0.0,
|
||||
DataMapping = {
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
local resetLoopAction = {
|
||||
Documentation = "Reset button. Sets time to start of dataset. No loop",
|
||||
GuiPath = "2012July",
|
||||
Identifier = "2012july.reset_loop",
|
||||
IsLocal = false,
|
||||
Name = "Reset button",
|
||||
Command = "openspace.time.setTime('2012-JUL-01 07:00:00.00');\nopenspace.time.setDeltaTime(1400);\nopenspace.scriptScheduler.clear();"
|
||||
}
|
||||
|
||||
asset.export(resetLoopAction)
|
||||
|
||||
asset.onInitialize(function ()
|
||||
openspace.action.registerAction(resetLoopAction)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function ()
|
||||
openspace.asction.removeAction(resetLoopAction)
|
||||
end)
|
||||
@@ -0,0 +1,3 @@
|
||||
asset.require("./sun_earth_2012_fieldlines_enlil")
|
||||
asset.require("./sun_earth_2012_fieldlines_batsrus")
|
||||
asset.require("./sun_earth_2012_fieldlines_pfss")
|
||||
@@ -0,0 +1,168 @@
|
||||
local transforms = asset.require('scene/solarsystem/planets/earth/magnetosphere/transforms_magnetosphere.asset')
|
||||
asset.require('scene/solarsystem/heliosphere/2012/reset_loop_action.asset')
|
||||
|
||||
local transferFunctions = asset.syncedResource({
|
||||
Name = "Fieldlines Transfer Functions",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "sun_earth_event_july_2012-fieldlines_transferfunctions",
|
||||
Version = 2
|
||||
})
|
||||
|
||||
local fieldlineData = asset.syncedResource({
|
||||
Name = "Fieldlines Data BATSRUS",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "sun_earth_event_july_2012-batsrus",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
local loop = {
|
||||
Documentation = "Sets time to start of data, sets higher delta time and loops back from start, when at end of data.",
|
||||
GuiPath = "2012July",
|
||||
Identifier = "2012july.loop_batsrus",
|
||||
IsLocal = false,
|
||||
Name = "Loop BATSRUS",
|
||||
Command = "openspace.scriptScheduler.clear();\nopenspace.time.setDeltaTime(1400);\nopenspace.time.setTime('2012-JUL-14 06:00:00.00');\nlocal StarttimescriptBatsrusLoop = \"openspace.time.setTime('2012 JUL 14 06:00:00')\";\nopenspace.scriptScheduler.loadScheduledScript('2012 JUL 16 07:30:00', StarttimescriptBatsrusLoop);"
|
||||
}
|
||||
|
||||
local batsrusTemperatureColorTable = transferFunctions .. "batsrus_temperature.txt"
|
||||
local batsrusDensityColorTable = transferFunctions .. "batsrus_density.txt"
|
||||
local batsrusCurrentColorTable = transferFunctions .. "batsrus_current2.txt"
|
||||
local batsrusVelocityColorTable = transferFunctions .. "batsrus_velocity.txt"
|
||||
local batsrusTopologyColorTable = transferFunctions .. "batsrus_topology.txt"
|
||||
|
||||
local unzippedDataDestination = {
|
||||
openClosed = fieldlineData .. "magnetic_fieldlines-open_closed",
|
||||
velocityFlow = fieldlineData .. "velocity_flowlines-upstream",
|
||||
asherStatic = fieldlineData .. "ashers_static_seeds"
|
||||
}
|
||||
|
||||
local colorRanges = {
|
||||
{ 0, 100000000 },
|
||||
{ 0, 60 },
|
||||
{ -0.015, 0.015 },
|
||||
{ 150, 900 },
|
||||
{ 0, 3 },
|
||||
}
|
||||
|
||||
local interactionSphere = 6380000 -- A value slightly bigger than earth radius
|
||||
|
||||
----------------------LUTZ's JULY TRACES-------------------------
|
||||
local BatsrusJ12OpenClosed = {
|
||||
Identifier = "FL_BATSRUS_J12_OpenClosed",
|
||||
Parent = transforms.GSMReferenceFrame.Identifier,
|
||||
InteractionSphere = interactionSphere,
|
||||
Renderable = {
|
||||
Type = "RenderableFieldlinesSequence",
|
||||
SourceFolder = unzippedDataDestination.openClosed,
|
||||
InputFileType = "Osfls",
|
||||
Color = { 0.7, 0.4, 0.0, 0.6 }, -- Default color
|
||||
ColorMethod = "By Quantity", -- Color by Quantity
|
||||
ColorQuantity = 0, -- Temperature
|
||||
ColorTablePaths = {
|
||||
batsrusTemperatureColorTable,
|
||||
batsrusDensityColorTable,
|
||||
batsrusCurrentColorTable,
|
||||
batsrusVelocityColorTable,
|
||||
batsrusTopologyColorTable,
|
||||
},
|
||||
ColorTableRanges = colorRanges,
|
||||
MaskingEnabled = true,
|
||||
MaskingQuantity = 4, -- Topology
|
||||
MaskingRanges = { {2.5, 3.0} } -- Corresponds to closed fieldlines only
|
||||
},
|
||||
GUI = {
|
||||
Name = "Fieldlines BATSRUS J12 Open/Closed",
|
||||
Path = "/Solar System/Heliosphere"
|
||||
}
|
||||
}
|
||||
|
||||
--------------------- VELOCITY FLOWLINES ------------------------
|
||||
local BatsrusJ12FlowLines = {
|
||||
Identifier = "FL_BATSRUS_J12_FlowLines",
|
||||
Parent = transforms.GSMReferenceFrame.Identifier,
|
||||
InteractionSphere = interactionSphere,
|
||||
Renderable = {
|
||||
Type = "RenderableFieldlinesSequence",
|
||||
SourceFolder = unzippedDataDestination.velocityFlow,
|
||||
InputFileType = "Osfls",
|
||||
ColorMethod = "By Quantity", -- Color by Quantity
|
||||
ColorQuantity = 3, -- Velocity
|
||||
Color = { 0.7, 0.4, 0.0, 0.12 }, -- Default color
|
||||
ColorTablePaths = {
|
||||
batsrusTemperatureColorTable,
|
||||
batsrusDensityColorTable,
|
||||
batsrusCurrentColorTable,
|
||||
batsrusVelocityColorTable,
|
||||
batsrusTopologyColorTable,
|
||||
},
|
||||
ColorTableRanges = colorRanges
|
||||
},
|
||||
GUI = {
|
||||
Name = "Fieldlines BATSRUS J12 Flowlines",
|
||||
Path = "/Solar System/Heliosphere"
|
||||
}
|
||||
}
|
||||
|
||||
--------------------- Ashers seedpoints ------------------------
|
||||
local BatsrusAsherStaticSeedsFlowLines = {
|
||||
Identifier = "FL_BATSRUS_ASHER_STATIC_SSEDS_FlowLines",
|
||||
Parent = transforms.GSMReferenceFrame.Identifier,
|
||||
InteractionSphere = interactionSphere,
|
||||
Renderable = {
|
||||
Type = "RenderableFieldlinesSequence",
|
||||
SourceFolder = unzippedDataDestination.asherStatic,
|
||||
Enabled = false,
|
||||
InputFileType = "Osfls",
|
||||
ColorTablePaths = {
|
||||
batsrusTemperatureColorTable,
|
||||
batsrusDensityColorTable,
|
||||
batsrusCurrentColorTable,
|
||||
batsrusVelocityColorTable,
|
||||
batsrusTopologyColorTable,
|
||||
},
|
||||
ColorTableRanges = colorRanges
|
||||
},
|
||||
GUI = {
|
||||
Name = "Fieldlines BATSRUS Asher Static",
|
||||
Path = "/Solar System/Heliosphere"
|
||||
}
|
||||
}
|
||||
|
||||
asset.onInitialize(function ()
|
||||
openspace.action.registerAction(loop)
|
||||
|
||||
if not openspace.directoryExists(unzippedDataDestination.openClosed) then
|
||||
openspace.printInfo("Extracting " .. "Fieldlines from Batsrus model of 2012 event")
|
||||
openspace.unzipFile(fieldlineData .. "magnetic_fieldlines-open_closed.zip", unzippedDataDestination.openClosed, true)
|
||||
end
|
||||
if not openspace.directoryExists(unzippedDataDestination.velocityFlow) then
|
||||
openspace.printInfo("Extracting " .. "Fieldlines from Batsrus model of 2012 event")
|
||||
openspace.unzipFile(fieldlineData .. "velocity_flowlines-upstream.zip", unzippedDataDestination.velocityFlow, true)
|
||||
end
|
||||
if not openspace.directoryExists(unzippedDataDestination.asherStatic) then
|
||||
openspace.printInfo("Extracting " .. "Fieldlines from Batsrus model of 2012 event")
|
||||
openspace.unzipFile(fieldlineData .. "ashers_static_seeds.zip", unzippedDataDestination.asherStatic, true)
|
||||
end
|
||||
|
||||
openspace.addSceneGraphNode(BatsrusJ12OpenClosed)
|
||||
openspace.addSceneGraphNode(BatsrusJ12FlowLines)
|
||||
openspace.addSceneGraphNode(BatsrusAsherStaticSeedsFlowLines)
|
||||
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function ()
|
||||
openspace.removeSceneGraphNode(BatsrusAsherStaticSeedsFlowLines)
|
||||
openspace.removeSceneGraphNode(BatsrusJ12FlowLines)
|
||||
openspace.removeSceneGraphNode(BatsrusJ12OpenClosed)
|
||||
|
||||
openspace.action.removeAction(loop)
|
||||
end)
|
||||
|
||||
asset.meta = {
|
||||
Name = "Fieldlines from Batsrus model of 2012 event",
|
||||
Version = "1.0",
|
||||
Description = "Magnetic fieldlines from Batsrus model for a 2012 CME event",
|
||||
Author = "CCMC",
|
||||
URL = "",
|
||||
License = "CC-BY"
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
local transforms = asset.require('scene/solarsystem/sun/transforms_heliosphere.asset')
|
||||
asset.require('scene/solarsystem/heliosphere/2012/reset_loop_action.asset')
|
||||
|
||||
local transferFunctions = asset.syncedResource({
|
||||
Name = "Fieldlines Transfer Functions",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "sun_earth_event_july_2012-fieldlines_transferfunctions",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
local fieldlineData = asset.syncedResource({
|
||||
Name = "Fieldlines Data ENLIL",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "sun_earth_event_july_2012-enlil",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
local loop = {
|
||||
Documentation = "Sets time to start of data, sets high delta time and loops back from start when at end of data",
|
||||
GuiPath = "2012July",
|
||||
Identifier = "2012july.loop_enlil",
|
||||
IsLocal = false,
|
||||
Name = "Loop ENLIL",
|
||||
Command = "openspace.scriptScheduler.clear();\nopenspace.time.setDeltaTime(43200);\nopenspace.time.setTime('2012-JUL-01 07:00:00.00');\nlocal StarttimescriptENLILLoop = \"openspace.time.setTime('2012 JUL 01 07:00:00')\";\nopenspace.scriptScheduler.loadScheduledScript('2012 AUG 01 06:58:00', StarttimescriptENLILLoop);"
|
||||
}
|
||||
|
||||
local enlilDensityColorTable = transferFunctions .. "enlil_density.txt"
|
||||
local enlilVelocityColorTable = transferFunctions .. "kroyw.txt"
|
||||
|
||||
local unzippedDataDestination = {
|
||||
EqPlane011AU1 = fieldlineData .. "011AU_eq_plane_1/",
|
||||
EqPlane011AU2 = fieldlineData .. "011AU_eq_plane_2/",
|
||||
Lat4011AU1 = fieldlineData .. "011AU_lat4_1/",
|
||||
Lat4011AU2 = fieldlineData .. "011AU_lat4_2/",
|
||||
Earth = fieldlineData .. "earth/",
|
||||
StereoA = fieldlineData .. "stereoa/"
|
||||
}
|
||||
|
||||
local colorRanges = {
|
||||
{ 0, 1000000 },
|
||||
{ 100, 2000 }
|
||||
}
|
||||
|
||||
local interactionSphere = 695700000
|
||||
|
||||
local ENLILSliceEqPlane11AU1 = {
|
||||
Identifier = "FL_ENLIL_slice_eqPlane_011AU_1",
|
||||
Parent = transforms.HEEQ180ReferenceFrame.Identifier,
|
||||
InteractionSphere = interactionSphere,
|
||||
Renderable = {
|
||||
Type = "RenderableFieldlinesSequence",
|
||||
SourceFolder = unzippedDataDestination.EqPlane011AU1,
|
||||
InputFileType = "Osfls",
|
||||
Color = { 0.4, 0.15, 0.4, 0.6 },
|
||||
ColorMethod = "By Quantity", -- Color by Quantity
|
||||
ColorQuantity = 1, -- Velocity
|
||||
ColorTablePaths = {
|
||||
enlilDensityColorTable,
|
||||
enlilVelocityColorTable,
|
||||
},
|
||||
ColorTableRanges = colorRanges
|
||||
},
|
||||
GUI = {
|
||||
Name = "Fieldlines ENLIL Slice Equatorial Plane 0.11 AU 1",
|
||||
Path = "/Solar System/Heliosphere"
|
||||
}
|
||||
}
|
||||
|
||||
local ENLILSliceEqPlane11AU2 = {
|
||||
Identifier = "FL_ENLIL_slice_eqPlane_011AU_2",
|
||||
Parent = transforms.HEEQ180ReferenceFrame.Identifier,
|
||||
InteractionSphere = interactionSphere,
|
||||
Renderable = {
|
||||
Type = "RenderableFieldlinesSequence",
|
||||
SourceFolder = unzippedDataDestination.EqPlane011AU2,
|
||||
InputFileType = "Osfls",
|
||||
Color = { 0.4, 0.15, 0.4, 0.6 },
|
||||
ColorMethod = "By Quantity", -- Color by Quantity
|
||||
ColorQuantity = 1, -- Velocity
|
||||
ColorTablePaths = {
|
||||
enlilDensityColorTable,
|
||||
enlilVelocityColorTable,
|
||||
},
|
||||
ColorTableRanges = colorRanges
|
||||
},
|
||||
GUI = {
|
||||
Name = "Fieldlines ENLIL Slice Equatorial Plane 0.11 AU 2",
|
||||
Path = "/Solar System/Heliosphere"
|
||||
}
|
||||
}
|
||||
|
||||
local ENLILSliceLat411AU1 = {
|
||||
Identifier = "FL_ENLIL_slice_lat4_011AU_1",
|
||||
Parent = transforms.HEEQ180ReferenceFrame.Identifier,
|
||||
InteractionSphere = interactionSphere,
|
||||
Renderable = {
|
||||
Type = "RenderableFieldlinesSequence",
|
||||
SourceFolder = unzippedDataDestination.Lat4011AU1,
|
||||
InputFileType = "Osfls",
|
||||
|
||||
Color = { 0.4, 0.15, 0.4, 0.6 },
|
||||
ColorMethod = "By Quantity", -- Color by Quantity
|
||||
ColorQuantity = 1, -- Velocity
|
||||
ColorTablePaths = {
|
||||
enlilDensityColorTable,
|
||||
enlilVelocityColorTable,
|
||||
},
|
||||
ColorTableRanges = colorRanges
|
||||
},
|
||||
GUI = {
|
||||
Name = "Fieldlines ENLIL Slice Latitude 4 0.11 AU 1",
|
||||
Path = "/Solar System/Heliosphere"
|
||||
}
|
||||
}
|
||||
|
||||
local ENLILSliceLat411AU2 = {
|
||||
Identifier = "FL_ENLIL_slice_lat4_011AU_2",
|
||||
Parent = transforms.HEEQ180ReferenceFrame.Identifier,
|
||||
InteractionSphere = interactionSphere,
|
||||
Renderable = {
|
||||
Type = "RenderableFieldlinesSequence",
|
||||
SourceFolder = unzippedDataDestination.Lat4011AU2,
|
||||
InputFileType = "Osfls",
|
||||
|
||||
Color = { 0.4, 0.15, 0.4, 0.6 },
|
||||
ColorMethod = "By Quantity", -- Color by Quantity
|
||||
ColorQuantity = 1, -- Velocity
|
||||
ColorTablePaths = {
|
||||
enlilDensityColorTable,
|
||||
enlilVelocityColorTable,
|
||||
},
|
||||
ColorTableRanges = colorRanges
|
||||
},
|
||||
GUI = {
|
||||
Name = "Fieldlines ENLIL Slice Latitude 4 0.11 AU 2",
|
||||
Path = "/Solar System/Heliosphere"
|
||||
}
|
||||
}
|
||||
|
||||
local ENLILEarth = {
|
||||
Identifier = "FL_ENLIL_earth",
|
||||
Parent = transforms.HEEQ180ReferenceFrame.Identifier,
|
||||
InteractionSphere = interactionSphere,
|
||||
Renderable = {
|
||||
Type = "RenderableFieldlinesSequence",
|
||||
SourceFolder = unzippedDataDestination.Earth,
|
||||
InputFileType = "Osfls",
|
||||
Color = { 1.0, 1.0, 1.0, 0.6 },
|
||||
ColorTablePaths = {
|
||||
enlilDensityColorTable,
|
||||
enlilVelocityColorTable,
|
||||
},
|
||||
ColorTableRanges = colorRanges
|
||||
},
|
||||
GUI = {
|
||||
Name = "Fieldlines ENLIL Earth",
|
||||
Path = "/Solar System/Heliosphere"
|
||||
}
|
||||
}
|
||||
|
||||
local ENLILStereoA = {
|
||||
Identifier = "FL_ENLIL_stereoa",
|
||||
Parent = transforms.HEEQ180ReferenceFrame.Identifier,
|
||||
InteractionSphere = interactionSphere,
|
||||
Renderable = {
|
||||
Type = "RenderableFieldlinesSequence",
|
||||
SourceFolder = unzippedDataDestination.StereoA,
|
||||
InputFileType = "Osfls",
|
||||
Color = { 1.0, 1.0, 1.0, 0.6 },
|
||||
ColorTablePaths = {
|
||||
enlilDensityColorTable,
|
||||
enlilVelocityColorTable,
|
||||
},
|
||||
ColorTableRanges = colorRanges,
|
||||
FlowEnabled = true,
|
||||
ReversedFlow = true,
|
||||
ParticleSize = 5,
|
||||
ParticleSpacing = 25,
|
||||
FlowSpeed = 25
|
||||
},
|
||||
GUI = {
|
||||
Name = "Fieldlines ENLIL STEREO A",
|
||||
Path = "/Solar System/Heliosphere"
|
||||
}
|
||||
}
|
||||
|
||||
asset.onInitialize(function ()
|
||||
openspace.action.registerAction(loop)
|
||||
|
||||
if not openspace.directoryExists(unzippedDataDestination.EqPlane011AU1) then
|
||||
openspace.printInfo("Extracting " .. "Fieldlines from ENLIL model of 2012 event")
|
||||
openspace.unzipFile(fieldlineData .. "011AU_eq_plane_1.zip", unzippedDataDestination.EqPlane011AU1, true)
|
||||
end
|
||||
if not openspace.directoryExists(unzippedDataDestination.EqPlane011AU2) then
|
||||
openspace.printInfo("Extracting " .. "Fieldlines from ENLIL model of 2012 event")
|
||||
openspace.unzipFile(fieldlineData .. "011AU_eq_plane_2.zip", unzippedDataDestination.EqPlane011AU2, true)
|
||||
end
|
||||
if not openspace.directoryExists(unzippedDataDestination.Lat4011AU1) then
|
||||
openspace.printInfo("Extracting " .. "Fieldlines from ENLIL model of 2012 event")
|
||||
openspace.unzipFile(fieldlineData .. "011AU_lat4_1.zip", unzippedDataDestination.Lat4011AU1, true)
|
||||
end
|
||||
if not openspace.directoryExists(unzippedDataDestination.Lat4011AU2) then
|
||||
openspace.printInfo("Extracting " .. "Fieldlines from ENLIL model of 2012 event")
|
||||
openspace.unzipFile(fieldlineData .. "011AU_lat4_2.zip", unzippedDataDestination.Lat4011AU2, true)
|
||||
end
|
||||
if not openspace.directoryExists(unzippedDataDestination.Earth) then
|
||||
openspace.printInfo("Extracting " .. "Fieldlines from ENLIL model of 2012 event")
|
||||
openspace.unzipFile(fieldlineData .. "earth.zip", unzippedDataDestination.Earth, true)
|
||||
end
|
||||
if not openspace.directoryExists(unzippedDataDestination.StereoA) then
|
||||
openspace.printInfo("Extracting " .. "Fieldlines from ENLIL model of 2012 event")
|
||||
openspace.unzipFile(fieldlineData .. "stereoa.zip", unzippedDataDestination.StereoA, true)
|
||||
end
|
||||
|
||||
openspace.addSceneGraphNode(ENLILSliceEqPlane11AU1)
|
||||
openspace.addSceneGraphNode(ENLILSliceEqPlane11AU2)
|
||||
openspace.addSceneGraphNode(ENLILSliceLat411AU1)
|
||||
openspace.addSceneGraphNode(ENLILSliceLat411AU2)
|
||||
openspace.addSceneGraphNode(ENLILEarth)
|
||||
openspace.addSceneGraphNode(ENLILStereoA)
|
||||
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function ()
|
||||
openspace.removeSceneGraphNode(ENLILStereoA)
|
||||
openspace.removeSceneGraphNode(ENLILEarth)
|
||||
openspace.removeSceneGraphNode(ENLILSliceLat411AU2)
|
||||
openspace.removeSceneGraphNode(ENLILSliceLat411AU1)
|
||||
openspace.removeSceneGraphNode(ENLILSliceEqPlane11AU2)
|
||||
openspace.removeSceneGraphNode(ENLILSliceEqPlane11AU1)
|
||||
|
||||
openspace.action.removeAction(loop)
|
||||
end)
|
||||
|
||||
asset.meta = {
|
||||
Name = "Fieldlines from ENLIL model of 2012 event",
|
||||
Version = "1.0",
|
||||
Description = "Magnetic fieldlines from ENLIL model for a 2012 CME event",
|
||||
Author = "CCMC",
|
||||
URL = "",
|
||||
License = "CC-BY"
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
local transforms = asset.require('scene/solarsystem/sun/transforms_heliosphere.asset')
|
||||
|
||||
local transferFunctions = asset.syncedResource({
|
||||
Name = "Fieldlines Transfer Functions",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "sun_earth_event_july_2012-fieldlines_transferfunctions",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
local fieldlineData = asset.syncedResource({
|
||||
Name = "Fieldlines Data PFSS",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "sun_earth_event_july_2012-pfss",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
local darkenSun = {
|
||||
Documentation = "Makes the Sun turn black",
|
||||
GuiPath = "2012July",
|
||||
Identifier = "2012july.dark_sun",
|
||||
IsLocal = false,
|
||||
Name = "Dark sun",
|
||||
Command = "local textureMultiplier = openspace.getPropertyValue(\"Scene.Sun.Renderable.Layers.ColorLayers.Texture.Settings.Multiplier\");\nif(textureMultiplier < 0.01) then\nopenspace.setPropertyValueSingle(\"Scene.Sun.Renderable.Layers.ColorLayers.Texture.Settings.Multiplier\", 1.0, 1);\nelse\nopenspace.setPropertyValueSingle(\"Scene.Sun.Renderable.Layers.ColorLayers.Texture.Settings.Multiplier\", 0.0, 1)\nend"
|
||||
}
|
||||
|
||||
local pfssTransitionColorTable = transferFunctions .. "pfss_transition.txt"
|
||||
local pfssTopologyColorTable = transferFunctions .. "pfss_topology.txt"
|
||||
local pfssBsignColorTable = transferFunctions .. "pfss_bsign.txt"
|
||||
|
||||
local PFSSPaths = {
|
||||
SolarSoft = fieldlineData .. "leilas_solar_soft/"
|
||||
}
|
||||
|
||||
local PFSS = {
|
||||
Identifier = "FL_PFSS",
|
||||
Parent = transforms.HEEQ180ReferenceFrame.Identifier,
|
||||
InteractionSphere = 695700000,
|
||||
Renderable = {
|
||||
Type = "RenderableFieldlinesSequence",
|
||||
SourceFolder = PFSSPaths.SolarSoft,
|
||||
InputFileType = "Osfls",
|
||||
Color = {0.35, 0.51, 0.875, 0.22},
|
||||
FlowEnabled = true,
|
||||
ReversedFlow = true,
|
||||
FlowColor = { 1, 0.9, 1, 0.74 },
|
||||
ParticleSize = 5,
|
||||
ParticleSpacing = 250,
|
||||
FlowSpeed = 75,
|
||||
ColorTablePaths = {
|
||||
pfssTopologyColorTable,
|
||||
pfssBsignColorTable,
|
||||
},
|
||||
ColorTableRanges = {
|
||||
{ 0, 2 },
|
||||
{ -1, 1 },
|
||||
},
|
||||
},
|
||||
GUI = {
|
||||
Name = "Fieldlines PFSS",
|
||||
Path = "/Solar System/Heliosphere"
|
||||
}
|
||||
}
|
||||
|
||||
asset.onInitialize(function ()
|
||||
openspace.action.registerAction(darkenSun)
|
||||
|
||||
if not openspace.directoryExists(PFSSPaths.SolarSoft) then
|
||||
openspace.printInfo("Extracting " .. "Fieldlines from PFSS model of 2012 event")
|
||||
openspace.unzipFile(fieldlineData .. "leilas_solar_soft.zip", PFSSPaths.SolarSoft, true)
|
||||
end
|
||||
|
||||
openspace.addSceneGraphNode(PFSS)
|
||||
|
||||
-- openspace.setPropertyValueSingle("Scene.FL_PFSS.Renderable.FlowEnabled", true)
|
||||
-- openspace.setPropertyValueSingle("Scene.FL_PFSS.Renderable.Flow.Reversed", true)
|
||||
--openspace.setPropertyValueSingle("Scene.FL_PFSS.Renderable.Flow.particleSize", 5)
|
||||
--openspace.setPropertyValueSingle("Scene.FL_PFSS.Renderable.Flow.particleSpacing", 250)
|
||||
--openspace.setPropertyValueSingle("Scene.FL_PFSS.Renderable.Flow.speed", 75.0)
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function ()
|
||||
openspace.removeSceneGraphNode(PFSS)
|
||||
openspace.action.removeAction(darkenSun)
|
||||
|
||||
end)
|
||||
|
||||
asset.meta = {
|
||||
Name = "Fieldlines from PFSS model of 2012 event",
|
||||
Version = "1.0",
|
||||
Description = "Magnetic fieldlines from PFSS model for a 2012 CME event",
|
||||
Author = "CCMC",
|
||||
URL = "",
|
||||
License = "CC-BY"
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
local propertyHelper = asset.require("util/property_helper")
|
||||
local sunTransforms = asset.require("scene/solarsystem/sun/transforms")
|
||||
local sunAsset = asset.require("scene/solarsystem/sun/sun")
|
||||
|
||||
local densityDirectory = asset.syncedResource({
|
||||
Name = "Bastille Day MAS Density",
|
||||
@@ -12,6 +13,9 @@ local sunRadius = 6.957E8
|
||||
|
||||
local densityVolume = {
|
||||
Identifier = "MAS-MHD-Density-bastille-day-2000",
|
||||
-- TODO Elon: 21 April 2022. Interaction sphere should not depend on the transform scale.
|
||||
-- InteractionSphere = sunAsset.Sun.Renderable.Radii[1] * 1.05,
|
||||
InteractionSphere = 1/695700000,
|
||||
Parent = sunTransforms.SunIAU.Identifier,
|
||||
Transform = {
|
||||
Scale = {
|
||||
@@ -28,7 +32,7 @@ local densityVolume = {
|
||||
Renderable = {
|
||||
Type = "RenderableTimeVaryingVolume",
|
||||
StepSize = 0.004,
|
||||
Opacity = 0.3,
|
||||
Brightness = 0.3,
|
||||
TransferFunction = asset.localResource("transferfunctions/mas-mhd-r-squared-old.txt"),
|
||||
SourceDirectory = densityDirectory,
|
||||
GridType = "Spherical",
|
||||
|
||||
@@ -15,6 +15,9 @@ local sunRadius = 6.957E8
|
||||
local fieldlines = {
|
||||
Identifier = "MAS-MHD-Fieldlines-bastille-day-2000",
|
||||
Parent = heliosphereTransforms.HEEQ180ReferenceFrame.Identifier,
|
||||
-- TODO Elon: 21 April 2022. Interaction sphere should not depend on the transform scale.
|
||||
-- InteractionSphere = sunAsset.Sun.Renderable.Radii[1] * 1.05,
|
||||
InteractionSphere = 1/695700000,
|
||||
Transform = {
|
||||
Scale = {
|
||||
Type = "StaticScale",
|
||||
@@ -31,14 +34,11 @@ local fieldlines = {
|
||||
asset.localResource("transferfunctions/density-fieldlines.txt"),
|
||||
asset.localResource("transferfunctions/velocity-fieldlines.txt")
|
||||
},
|
||||
ColorTableMinMax = {
|
||||
ColorTableRanges = {
|
||||
{ 0, 1000000 },
|
||||
{ 100, 2000 }
|
||||
},
|
||||
SimulationModel = "mas",
|
||||
Color = {
|
||||
Uniform = { 0.0, 0.725, 0.75, 1.0 }
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Path = "/Solar System/Heliosphere/Bastille Day 2000",
|
||||
@@ -68,7 +68,6 @@ end)
|
||||
|
||||
asset.export(fieldlines)
|
||||
|
||||
|
||||
asset.meta = {
|
||||
Name = "Predictive Science Inc. Fieldlines Bastille Day",
|
||||
Version = "1.0",
|
||||
|
||||
@@ -13,6 +13,9 @@ local fluxNodesBinaries = asset.syncedResource({
|
||||
local fluxNodes = {
|
||||
Identifier = "MAS-MHD-FluxNodes-bastille-day-2000",
|
||||
Parent = heliosphereTransforms.HEEQ180ReferenceFrame.Identifier,
|
||||
-- TODO Elon: 21 April 2022. Interaction sphere should not depend on the transform scale.
|
||||
-- InteractionSphere = sunAsset.Sun.Renderable.Radii[1] * 1.05,
|
||||
InteractionSphere = 695700000.0,
|
||||
Transform = {
|
||||
Rotation = rot.CarringtonLongitudeToHEEQ180Rotation
|
||||
},
|
||||
|
||||
@@ -19,6 +19,9 @@ local TexturesPathMeridial = asset.syncedResource({
|
||||
local EquatorialCutplane = {
|
||||
Identifier = "EquatorialCutplane-bastille-day-2000",
|
||||
Parent = transforms.HEEQ180ReferenceFrame.Identifier,
|
||||
-- TODO Elon: 21 April 2022. Interaction sphere should not depend on the transform scale.
|
||||
-- InteractionSphere = sunAsset.Sun.Renderable.Radii[1] * 1.05,
|
||||
InteractionSphere = 695700000.0,
|
||||
Transform = {
|
||||
Rotation = rot.CarringtonLongitudeToHEEQ180Rotation
|
||||
},
|
||||
@@ -41,6 +44,9 @@ local EquatorialCutplane = {
|
||||
local MeridialCutplane = {
|
||||
Identifier = "MeridialCutplane-bastille-day-2000",
|
||||
Parent = transforms.HEEQ180ReferenceFrame.Identifier,
|
||||
-- TODO Elon: 21 April 2022. Interaction sphere should not depend on the transform scale.
|
||||
-- InteractionSphere = sunAsset.Sun.Renderable.Radii[1] * 1.05,
|
||||
InteractionSphere = 695700000,
|
||||
Transform = {
|
||||
Rotation = {
|
||||
Type = "StaticRotation",
|
||||
|
||||
@@ -5,6 +5,9 @@ local travelSpeedIndicator = {
|
||||
Identifier = "TravelSpeedIndicator-2000",
|
||||
--SunIAU adds an extra rotation. Using barycenter, then offsetting to SunIAU
|
||||
Parent = sunTransforms.SolarSystemBarycenter.Identifier,
|
||||
-- TODO Elon: 21 April 2022. Interaction sphere should not depend on the transform scale.
|
||||
-- InteractionSphere = sunAsset.Sun.Renderable.Radii[1] * 1.05,
|
||||
InteractionSphere = 695700000.0,
|
||||
Transform = {
|
||||
Translation = {
|
||||
Type = "SpiceTranslation",
|
||||
|
||||
@@ -151,7 +151,7 @@ local RotationKeyframes = {
|
||||
|
||||
local InsightParent = {
|
||||
Identifier = "InsightParent",
|
||||
Parent = mars.Identifier,
|
||||
Parent = mars.Mars.Identifier,
|
||||
Transform = {
|
||||
Translation ={
|
||||
Type = "TimelineTranslation",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user