diff options
| author | Bryan Galdrikian <[email protected]> | 2017-02-24 09:32:20 -0800 |
|---|---|---|
| committer | Bryan Galdrikian <[email protected]> | 2017-02-24 09:32:20 -0800 |
| commit | e1bf674c16e3c8472b29574159c789cd3f0c64e0 (patch) | |
| tree | 9f0cfce09c71a2c27ff19589fcad6cd83504477c /tools/ArtistTools/source/CoreLib/Window | |
| parent | first commit (diff) | |
| download | blast-e1bf674c16e3c8472b29574159c789cd3f0c64e0.tar.xz blast-e1bf674c16e3c8472b29574159c789cd3f0c64e0.zip | |
Updating to [email protected] and [email protected] with a new directory structure.
NvBlast folder is gone, files have been moved to top level directory. README is changed to reflect this.
Diffstat (limited to 'tools/ArtistTools/source/CoreLib/Window')
24 files changed, 4406 insertions, 0 deletions
diff --git a/tools/ArtistTools/source/CoreLib/Window/AppMainWindow.cpp b/tools/ArtistTools/source/CoreLib/Window/AppMainWindow.cpp new file mode 100644 index 0000000..3a85d8b --- /dev/null +++ b/tools/ArtistTools/source/CoreLib/Window/AppMainWindow.cpp @@ -0,0 +1,1448 @@ +#include <QtWidgets/QShortcut> +#include <QtWidgets/QAction> +#include <QtWidgets/QMenu> +#include <QtWidgets/QFileDialog> +#include <QtWidgets/QMessageBox> +#include <QtGui/QDesktopServices> +#include <QtWidgets/QScrollBar> +#include <QtWidgets/QGraphicsEllipseItem> +#include <QtWidgets/QGraphicsView> +#include <QtWidgets/QProgressDialog> + +#include <Windows.h> + +#include "AppMainWindow.h" +#include "ExpandablePanel.h" + +#include "D3DWidget.h" + +#include "DisplayMeshesPanel.h" + +#include "DisplayPreferencesPanel.h" +#include "DisplayScenePanel.h" +#include "DisplayLightPanel.h" +#include "ui_DisplayPreferencesPanel.h" +#include "ui_DisplayScenePanel.h" +#include "ui_DisplayLightPanel.h" +#include "CameraBookmarksDialog.h" + +#include "SimpleScene.h" +#include "GlobalSettings.h" + +#include "ViewerOutput.h" +#include "Gamepad.h" +#if USE_CURVE_EDITOR +#include "CurveEditorMainWindow.h" +#endif +#ifndef NV_ARTISTTOOLS +#include "ui_AppMainToolbar.h" +#include "ui_AssetControlPanel.h" +#include "ui_GeneralAttributesPanel.h" +#include "ui_PhysicalMaterialsPanel.h" +#include "ui_StyleMaterialsPanel.h" +#include "ui_GraphicalMaterialsPanel.h" +#include "BlastToolbar.h" +#include "AssetControlPanel.h" +#include "GraphicalMaterialPanel.h" +#include "PhysicalMaterialPanel.h" +#include "StyleMaterialPanel.h" +#include "GeneralAttributePanel.h" +#include "MaterialSetPanel.h" +#include "LodPanel.h" +#include "DisplayVisualizersPanel.h" +#include "ui_DisplayVisualizersPanel.h" +#include "DisplayMeshMaterialsPanel.h" +#include "FurCharacter.h" +#include "HairParams.h" +#include "AboutDialog.h" +#else +#endif // NV_ARTISTTOOLS + +class MsgPrinter : public FrontPrinter +{ +public: + MsgPrinter(QTextBrowser* browser):_browser(browser) + { + + } + + void print(const char* txt, unsigned long color /* = 0 */, Effect e /* = NONE */) + { + if(color == 0 && e == FrontPrinter::NONE) + { + _browser->insertPlainText(QString(txt)+"\n"); + } + else + { + // output html text + QString surfix; + QString postfix; + surfix.reserve(64); + postfix.reserve(64); + if(e & FrontPrinter::BOLD) + { + surfix = surfix + "<b>"; + postfix= postfix + "</b>"; + } + else if(e & FrontPrinter::UNDERLINE) + { + surfix = surfix + "<u>"; + postfix= QString("</u>") + postfix; + } + else if(e & FrontPrinter::ITALIC) + { + surfix = surfix + "<i>"; + postfix= QString("</i>") + postfix; + } + + if(color != 0) + { + int r = GetRValue(color); + int g = GetGValue(color); + int b = GetBValue(color); + + surfix = QString("<div style=\"color:rgb(%1,%2,%3);\">").arg(r).arg(g).arg(b) + surfix; + postfix= postfix + QString("</div><br />"); + } + + QString html = surfix + QString(txt) + postfix; + _browser->insertHtml(html); + } + // auto scroll to the bottom + QScrollBar *sb = _browser->verticalScrollBar(); + if (sb) sb->setValue(sb->maximum()); + } + +private: + QTextBrowser* _browser; +}; + +int AppMainWindow::_connectionMode = 0; +bool AppMainWindow::_expertMode = false; +AppMainWindow* gAppMainWindow = NV_NULL; + +void CreateAppMainWindow() +{ + gAppMainWindow = new AppMainWindow; +} + +void ReleaseAppMainWindow() +{ + delete gAppMainWindow; + gAppMainWindow = NV_NULL; +} + +AppMainWindow& AppMainWindow::Inst() +{ + return *gAppMainWindow; +} + +AppMainWindow::AppMainWindow(QWidget *parent, Qt::WindowFlags flags) + : QMainWindow(parent, flags) + , _bookmarksMenu(0) + ,_displayMeshesPanel(0) + , _displayPreferencesPanel(0) + , _displayScenePanel(0) + ,_displayLightPanel(0) +#if USE_CURVE_EDITOR + ,_curveEditorInitizlized(false) + , _curveEditorMainWindow(nullptr) +#endif + ,_bookmarkActionGroup(0) + ,_actionAddBookmark(0) + ,_actionEditBookmarks(0) +{ + setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea); + setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); + + ui.setupUi(this); + //ui.dockOutputWindow->hide(); + +#ifndef NV_ARTISTTOOLS + _mainToolbar = 0; + _physicalMaterialPanel = 0; + _styleMaterialPanel = 0; + _graphicalMaterialPanel = 0; + _displayFurVisualizersPanel = 0; + _assetControlPanel = 0; + _generalAttributePanel = 0; + _lodPanel = 0; + _displayMeshMaterialsPanel; +#if USE_MATERIAL_SET + _materialSetPanel = 0; +#endif +#else + CoreLib::Inst()->AppMainWindow_AppMainWindow(); +#endif // NV_ARTISTTOOLS + + _progressDialog.close(); // prevent show one empty progress dialog when it runs. + + m_bGizmoWithLocal = false; +} + +void AppMainWindow::InitUI() +{ + _d3dWidget = new D3DWidget(this); + _d3dWidget->setMinimumSize(200, 200); + ui.renderLayout->addWidget(_d3dWidget); + + InitShortCuts(); + InitMenuItems(); + InitToolbar(); + InitPluginTab(); + InitMainTab(); + + InitMouseSchemes(); + + updateUI(); + + if (_connectionMode == 1) // master mode + ui.sideBarTab->removeTab(1); + + if (_connectionMode == 2) + ui.sideBarTab->removeTab(0); + + + QString defFilePath; + + QString appDir = qApp->applicationDirPath(); + QDir dir(appDir); + if (dir.cd("../../media")) + defFilePath = dir.absolutePath(); + + _lastFilePath = defFilePath; + + _navigationStyle = 0; + + // initialize the message printer + _printer = new MsgPrinter(this->ui.outputWindow); + ViewerOutput::Inst().RegisterPrinter(_printer); + +#ifndef NV_ARTISTTOOLS + + viewer_info( + "<a href=\"https://developer.nvidia.com/hairworks\" style=\"color:rgb(118,180,0);\">NVIDIA Blast Version v" + NV_HAIR_RELEASE_VERSION_STRING + "</a>"); + +#else + CoreLib::Inst()->AppMainWindow_InitUI(); +#endif // NV_ARTISTTOOLS +} + +AppMainWindow::~AppMainWindow() +{ +} + +void AppMainWindow::setConnectionMode(int m) +{ + _connectionMode = m; +} + +void AppMainWindow::startProgress() +{ + _progressDialog.setWindowModality(Qt::WindowModal); + _progressDialog.show(); +} + +void AppMainWindow::setProgress(const char* label, int progress) +{ + _progressDialog.setLabelText(label); + if (progress >= 0) + _progressDialog.setValue(progress); + + _progressDialog.update(); +} + +void AppMainWindow::endProgress() +{ + _progressDialog.close(); +} + +void AppMainWindow::quit() +{ + emit aboutToQuit(); +} + +void AppMainWindow::setProgressMaximum(int m) +{ + _progressDialog.setMaximum(m); +} + +void AppMainWindow::InitMenuItems() +{ + QMenuBar* menu = ui.menuBar; + QAction* act = NV_NULL; + + // file sub-menu + QMenu* fileMenu = menu->addMenu("&File"); + + if (_connectionMode != 1) + { + act = new QAction("Clear scene", this); + act->setShortcut(QKeySequence::New); + connect(act, SIGNAL(triggered()), this, SLOT(menu_clearScene())); + fileMenu->addAction(act); + + fileMenu->addSeparator(); + + act = new QAction("Open fbx file", this); + connect(act, SIGNAL(triggered()), this, SLOT(menu_openfbx())); + fileMenu->addAction(act); + + fileMenu->addSeparator(); + +#ifndef NV_ARTISTTOOLS + fileMenu->addSeparator(); + act = new QAction("Open project file", this); + act->setShortcut(QKeySequence::Open); + connect(act, SIGNAL(triggered()), this, SLOT(menu_openProject())); + fileMenu->addAction(act); + + act = new QAction("Save project file", this); + act->setShortcut(QKeySequence::Save); + connect(act, SIGNAL(triggered()), this, SLOT(menu_saveProject())); + fileMenu->addAction(act); + + act = new QAction("Save project file as...", this); + connect(act, SIGNAL(triggered()), this, SLOT(menu_saveProjectAs())); + fileMenu->addAction(act); + + fileMenu->addSeparator(); + + act = new QAction("&Open hair file", this); + connect(act, SIGNAL(triggered()), this, SLOT(menu_openHair())); + fileMenu->addAction(act); + + act = new QAction("&Save hair file", this); + connect(act, SIGNAL(triggered()), this, SLOT(menu_saveHair())); + fileMenu->addAction(act); + + act = new QAction("Save hair file as...", this); + act->setShortcut(QKeySequence::SaveAs); + connect(act, SIGNAL(triggered()), this, SLOT(menu_saveHairAs())); + fileMenu->addAction(act); + + act = new QAction("Save all hairs...", this); + connect(act, SIGNAL(triggered()), this, SLOT(menu_saveAllHairs())); + fileMenu->addAction(act); + + fileMenu->addSeparator(); +#else + CoreLib::Inst()->AppMainWindow_InitMenuItems(ui.menuBar); +#endif // NV_ARTISTTOOLS + } + + act = new QAction("E&xit", this); + act->setShortcut(QKeySequence::Quit); + connect(act, SIGNAL(triggered()), this, SLOT(close())); + fileMenu->addAction(act); + + // view submenu + QMenu* viewMenu = menu->addMenu("&View"); + act = new QAction("Bookmarks", this); + //connect(act, SIGNAL(triggered()), this, SLOT(menu_showOutput())); + viewMenu->addAction(act); + _bookmarksMenu = new QMenu("Bookmarks", this); + connect(_bookmarksMenu, SIGNAL(triggered(QAction*)), this, SLOT(menu_bookmarkTriggered(QAction*))); + act->setMenu(_bookmarksMenu); + act = new QAction("Add Bookmark", this); + connect(act, SIGNAL(triggered()), this, SLOT(menu_addBookmark())); + _bookmarksMenu->addAction(act); + _actionAddBookmark = act; + act = new QAction("Edit Bookmarks", this); + connect(act, SIGNAL(triggered()), this, SLOT(menu_editBookmarks())); + _bookmarksMenu->addAction(act); + _actionEditBookmarks = act; + _bookmarksMenu->addSeparator(); + _bookmarkActionGroup = new QActionGroup(this); + + // window submenu + QMenu* windowMenu = menu->addMenu("&Window"); + act = new QAction("Output", this); + connect(act, SIGNAL(triggered()), this, SLOT(menu_showOutput())); + windowMenu->addAction(act); + + act = new QAction("Attribute Editor", this); + connect(act, SIGNAL(triggered()), this, SLOT(menu_showAttributeEditor())); + windowMenu->addAction(act); + +#if USE_CURVE_EDITOR + act = new QAction("Curve Editor", this); + connect(act, SIGNAL(triggered()), this, SLOT(menu_showCurveEditor())); + windowMenu->addAction(act); +#endif + + // help submenu + QMenu* helpMenu = menu->addMenu("&Help"); + + act = new QAction("Documentation", this); + connect(act, SIGNAL(triggered()), this, SLOT(menu_opendoc())); + helpMenu->addAction(act); + + act = new QAction("&About", this); + connect(act, SIGNAL(triggered()), this, SLOT(menu_about())); + helpMenu->addAction(act); +} + +void AppMainWindow::InitToolbar() +{ + if (_connectionMode != 1) + { +#ifndef NV_ARTISTTOOLS + _mainToolbar = new BlastToolbar(ui.centralWidget); + ui.verticalLayout->insertWidget(0, _mainToolbar); + connect(_mainToolbar->getUI().btnFileOpen, SIGNAL(clicked()), this, SLOT(menu_openProject())); +#else + CoreLib::Inst()->AppMainWindow_InitToolbar(ui.centralWidget, ui.verticalLayout); +#endif // NV_ARTISTTOOLS + } +} + +void AppMainWindow::InitPluginTab() +{ +#ifndef NV_ARTISTTOOLS + QWidget *tabFur; + QGridLayout *gridLayout; + QFrame *furMaterialEditorArea; + QVBoxLayout *furMaterialEditorAreaLayout; + QScrollArea *furScrollArea; + QWidget *furScrollAreaContents; + QVBoxLayout *furScrollAreaLayout; + QSpacerItem *verticalSpacer; + + tabFur = new QWidget(); + tabFur->setObjectName(QStringLiteral("tabFur")); + gridLayout = new QGridLayout(tabFur); + gridLayout->setSpacing(6); + gridLayout->setContentsMargins(11, 11, 11, 11); + gridLayout->setObjectName(QStringLiteral("gridLayout")); + gridLayout->setContentsMargins(0, 0, 0, 0); + furMaterialEditorArea = new QFrame(tabFur); + furMaterialEditorArea->setObjectName(QStringLiteral("furMaterialEditorArea")); + furMaterialEditorAreaLayout = new QVBoxLayout(furMaterialEditorArea); + furMaterialEditorAreaLayout->setSpacing(6); + furMaterialEditorAreaLayout->setContentsMargins(11, 11, 11, 11); + furMaterialEditorAreaLayout->setObjectName(QStringLiteral("furMaterialEditorAreaLayout")); + furMaterialEditorAreaLayout->setContentsMargins(2, 2, 2, 2); + + gridLayout->addWidget(furMaterialEditorArea, 1, 0, 1, 1); + + furScrollArea = new QScrollArea(tabFur); + furScrollArea->setObjectName(QStringLiteral("furScrollArea")); + furScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); + furScrollArea->setWidgetResizable(true); + furScrollAreaContents = new QWidget(); + furScrollAreaContents->setObjectName(QStringLiteral("furScrollAreaContents")); + furScrollAreaContents->setGeometry(QRect(0, 0, 359, 481)); + furScrollAreaLayout = new QVBoxLayout(furScrollAreaContents); + furScrollAreaLayout->setSpacing(3); + furScrollAreaLayout->setContentsMargins(11, 11, 11, 11); + furScrollAreaLayout->setObjectName(QStringLiteral("furScrollAreaLayout")); + furScrollAreaLayout->setContentsMargins(2, 2, 2, 2); + verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding); + + furScrollAreaLayout->addItem(verticalSpacer); + + furScrollArea->setWidget(furScrollAreaContents); + + gridLayout->addWidget(furScrollArea, 0, 0, 1, 1); + + ui.sideBarTab->addTab(tabFur, QString()); + + ui.sideBarTab->setTabText(ui.sideBarTab->indexOf(tabFur), QApplication::translate("AppMainWindowClass", "Hair", 0)); + + ExpandablePanel* panel = 0; + int pannelCnt = 0; + + if (_connectionMode == 0) + { + panel = new ExpandablePanel(furScrollAreaContents, false); + _generalAttributePanel = new GeneralAttributePanel(panel); + panel->AddContent(_generalAttributePanel); + furScrollAreaLayout->insertWidget(pannelCnt++, panel); + panel->SetTitle("Asset Selection"); + + panel = new ExpandablePanel(furScrollAreaContents, false); + _assetControlPanel = new AssetControlPanel(panel); + panel->AddContent(_assetControlPanel); + furScrollAreaLayout->insertWidget(pannelCnt++, panel); + panel->SetTitle("General Settings"); + + } + + panel = new ExpandablePanel(furScrollAreaContents); + _displayFurVisualizersPanel = new DisplayFurVisualizersPanel(panel); + panel->AddContent(_displayFurVisualizersPanel); + furScrollAreaLayout->insertWidget(pannelCnt++, panel); + panel->SetTitle("Visualization"); + + panel = new ExpandablePanel(furScrollAreaContents); + _physicalMaterialPanel = new PhysicalMaterialPanel(panel); + panel->AddContent(_physicalMaterialPanel); + furScrollAreaLayout->insertWidget(pannelCnt++, panel); + panel->SetTitle("Physical"); + + panel = new ExpandablePanel(furScrollAreaContents); + _styleMaterialPanel = new StyleMaterialPanel(panel); + panel->AddContent(_styleMaterialPanel); + furScrollAreaLayout->insertWidget(pannelCnt++, panel); + panel->SetTitle("Style"); + + panel = new ExpandablePanel(furScrollAreaContents); + _graphicalMaterialPanel = new GraphicalMaterialPanel(panel); + panel->AddContent(_graphicalMaterialPanel); + furScrollAreaLayout->insertWidget(pannelCnt++, panel); + panel->SetTitle("Graphics"); + + panel = new ExpandablePanel(furScrollAreaContents); + _lodPanel = new LodPanel(panel); + panel->AddContent(_lodPanel); + furScrollAreaLayout->insertWidget(pannelCnt++, panel); + panel->SetTitle("Level Of Detail"); + +#if USE_MATERIAL_SET + panel = new ExpandablePanel(furScrollAreaContents); + _materialSetPanel = new MaterialSetPanel(panel); + panel->AddContent(_materialSetPanel); + furScrollAreaLayout->insertWidget(pannelCnt++, panel); + panel->SetTitle("Control Texture Channels"); + //_materialSetPanel->hide(); + //panel->SetCollapsed(true); +#else + ui.furMaterialEditorAreaLayout->setEnabled(false); +#endif +#else + CoreLib::Inst()->AppMainWindow_InitPluginTab(ui.sideBarTab); +#endif // NV_ARTISTTOOLS + +#if USE_CURVE_EDITOR + _curveEditorMainWindow = new nvidia::CurveEditor::CurveEditorMainWindow( this);//nullptr); + _curveEditorMainWindow->setResampleEnabled(false); + ui.dockWidgetCurveEditor->setWidget(_curveEditorMainWindow); + ui.dockWidgetCurveEditor->setWindowTitle(tr("Curve Editor")); + + connect(_curveEditorMainWindow, SIGNAL(CurveAttributeChanged(nvidia::CurveEditor::CurveAttribute*)), this, SLOT(onCurveAttributeChanged(nvidia::CurveEditor::CurveAttribute*))); + connect(_curveEditorMainWindow, SIGNAL(ColorAttributeChanged(nvidia::CurveEditor::ColorAttribute*)), this, SLOT(onColorAttributeChanged(nvidia::CurveEditor::ColorAttribute*))); + connect(_curveEditorMainWindow, SIGNAL(ReloadColorAttributeTexture(nvidia::CurveEditor::ColorAttribute*, bool, int)), this, SLOT(onReloadColorAttributeTexture(nvidia::CurveEditor::ColorAttribute*, bool, int))); +//#else +// ui.furCurveEditorAreaLayout->setEnabled(false); +#endif +} + +void AppMainWindow::InitMainTab() +{ + int idx = 0; + + if (_connectionMode != 1) + { + ExpandablePanel* panel = new ExpandablePanel(ui.displayScrollAreaContents); + _displayPreferencesPanel = new DisplayPreferencesPanel(panel); + panel->AddContent(_displayPreferencesPanel); + ui.displayScrollAreaLayout->insertWidget(idx++, panel); + panel->SetTitle("Preferences"); + + panel = new ExpandablePanel(ui.displayScrollAreaContents); + _displayScenePanel = new DisplayScenePanel(panel); + panel->AddContent(_displayScenePanel); + ui.displayScrollAreaLayout->insertWidget(idx++, panel); + panel->SetTitle("Scene"); + + panel = new ExpandablePanel(ui.displayScrollAreaContents); + _displayLightPanel = new DisplayLightPanel(panel); + panel->AddContent(_displayLightPanel); + ui.displayScrollAreaLayout->insertWidget(idx++, panel); + panel->SetTitle("Light"); + + panel = new ExpandablePanel(ui.displayScrollAreaContents); + _displayMeshesPanel = new DisplayMeshesPanel(panel); + panel->AddContent(_displayMeshesPanel); + ui.displayScrollAreaLayout->insertWidget(idx++, panel); + panel->SetTitle("Display Meshes"); + } + + if (_connectionMode != 1) + { +#ifndef NV_ARTISTTOOLS + ExpandablePanel* panel = new ExpandablePanel(ui.displayScrollAreaContents); + _displayMeshMaterialsPanel = new DisplayMeshMaterialsPanel(panel); + panel->AddContent(_displayMeshMaterialsPanel); + ui.displayScrollAreaLayout->insertWidget(idx++, panel); + panel->SetTitle("Display Mesh Materials"); +#else + CoreLib::Inst()->AppMainWindow_InitMainTab(ui.displayScrollAreaContents, ui.displayScrollAreaLayout, idx); +#endif // NV_ARTISTTOOLS + } +} + +void AppMainWindow::InitShortCuts() +{ + QShortcut* shortCut; + shortCut = new QShortcut(QKeySequence(Qt::Key_F), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_frameall())); + + shortCut = new QShortcut(QKeySequence(Qt::Key_H), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_hud())); + + shortCut = new QShortcut(QKeySequence(Qt::Key_G), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_statistics())); + + shortCut = new QShortcut(QKeySequence(Qt::Key_Space), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_pause())); + + shortCut = new QShortcut(QKeySequence(Qt::Key_B), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_reset())); + + shortCut = new QShortcut(QKeySequence(Qt::Key_Escape), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_escape())); + + shortCut = new QShortcut(QKeySequence(Qt::Key_V), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_expert())); + + shortCut = new QShortcut(QKeySequence("Ctrl+X"), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_expert())); + + shortCut = new QShortcut(QKeySequence(Qt::Key_D), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(demo_next())); + + shortCut = new QShortcut(QKeySequence(Qt::Key_Right), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(demo_next())); + + shortCut = new QShortcut(QKeySequence(Qt::Key_A), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(demo_prev())); + + shortCut = new QShortcut(QKeySequence(Qt::Key_Left), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(demo_prev())); + + shortCut = new QShortcut(QKeySequence(Qt::Key_F2), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_output())); + + shortCut = new QShortcut(QKeySequence("Ctrl+F"), this); + connect(shortCut, SIGNAL(activated()), this, SLOT(shortcut_fitcamera())); +} + +////////////////////////////////////////////////////////////////////////// +void AppMainWindow::updateBookmarkMenu() +{ + // clear old menu items of camera bookmarks + while (_bookmarkActionGroup->actions().size() > 0) + { + QAction* act = _bookmarkActionGroup->actions()[0]; + _bookmarkActionGroup->removeAction(act); + delete act; + } + _bookmarksMenu->clear(); + _bookmarksMenu->addAction(_actionAddBookmark); + _bookmarksMenu->addAction(_actionEditBookmarks); + _bookmarksMenu->addSeparator(); + + QList<QString> bookmarks = SimpleScene::Inst()->getBookmarkNames(); + int numBookmarks = bookmarks.size(); + for (int i = 0; i < numBookmarks; ++i) + { + QString bookmark = bookmarks[i]; + + QAction* act = new QAction(bookmark, this); + act->setCheckable(true); + _bookmarksMenu->addAction(act); + _bookmarkActionGroup->addAction(act); + } + +} + +////////////////////////////////////////////////////////////////////////// +void AppMainWindow::updateUI() +{ + if (_bookmarksMenu && _bookmarkActionGroup) + { + updateBookmarkMenu(); + } + +#ifndef NV_ARTISTTOOLS + if (_mainToolbar) + _mainToolbar->updateValues(); + + if (_graphicalMaterialPanel) + _graphicalMaterialPanel->updateValues(); + + if (_physicalMaterialPanel) + _physicalMaterialPanel->updateValues(); + + if (_styleMaterialPanel) + _styleMaterialPanel->updateValues(); + + if (_displayFurVisualizersPanel) + _displayFurVisualizersPanel->updateValues(); + + if (_lodPanel) + _lodPanel->updateValues(); + + if (_generalAttributePanel) + _generalAttributePanel->updateValues(); + + if (_assetControlPanel) + _assetControlPanel->updateValues(); + + if (_displayMeshMaterialsPanel) + _displayMeshMaterialsPanel->updateValues(); + +#if USE_MATERIAL_SET + if (_materialSetPanel) + _materialSetPanel->updateValues(); +#endif +#else + CoreLib::Inst()->AppMainWindow_updateUI(); +#endif // NV_ARTISTTOOLS + + if (_displayPreferencesPanel) + _displayPreferencesPanel->updateValues(); + + if (_displayScenePanel) + _displayScenePanel->updateValues(); + + if (_displayLightPanel) + _displayLightPanel->updateValues(); + + if (_displayMeshesPanel) + _displayMeshesPanel->updateValues(); + +#if USE_CURVE_EDITOR + if (_curveEditorMainWindow) + UpdateCurveEditor(); +#endif +} + +////////////////////////////////////////////////////////////////////////// +void AppMainWindow::updatePluginUI() +{ + SimpleScene::Inst()->setIsUpdatingUI(true); + +#ifndef NV_ARTISTTOOLS + if (_graphicalMaterialPanel) + _graphicalMaterialPanel->updateValues(); + + if (_physicalMaterialPanel) + _physicalMaterialPanel->updateValues(); + + if (_styleMaterialPanel) + _styleMaterialPanel->updateValues(); + + if (_lodPanel) + _lodPanel->updateValues(); + + if (_displayFurVisualizersPanel) + _displayFurVisualizersPanel->updateValues(); + + if (_generalAttributePanel) + _generalAttributePanel->updateValues(); + + if (_assetControlPanel) + _assetControlPanel->updateValues(); + +#if USE_MATERIAL_SET + if (_materialSetPanel) + _materialSetPanel->updateValues(); +#endif +#else + CoreLib::Inst()->AppMainWindow_updatePluginUI(); +#endif // NV_ARTISTTOOLS + +#if USE_CURVE_EDITOR + if (_curveEditorMainWindow) + UpdateCurveEditor(); +#endif + + SimpleScene::Inst()->setIsUpdatingUI(false); +} + + +////////////////////////////////////////////////////////////////////////// +// event handlers + + +////////////////////////////////////////////////////////////////////////// +// event handlers +bool AppMainWindow::openProject(QString fileName) +{ + if (!fileName.isEmpty()) + { + QFileInfo fileInfo(fileName); + QByteArray dir = QDir::toNativeSeparators(fileInfo.absoluteDir().absolutePath()).toLocal8Bit(); + QByteArray file= fileInfo.fileName().toLocal8Bit(); + + if (SimpleScene::Inst()->LoadProject(dir, file) == false) + { + QMessageBox messageBox; + messageBox.critical(0,"Error","File open error!"); + messageBox.setFixedSize(500,200); + + AppMainWindow::Inst().endProgress(); + char message[1024]; + sprintf(message, "Failed to open project file(\"%s\")", (const char*)file); + viewer_err(message); + return false; + } + + AppMainWindow::Inst().endProgress(); + _lastFilePath = fileInfo.absoluteDir().absolutePath(); + + updateUI(); + return true; + } + return false; +} + +void AppMainWindow::processDragAndDrop(QString fname) +{ + openProject(fname); +} + +void AppMainWindow::removeBookmark(const QString& name) +{ + QList<QAction*> bookmarks = _bookmarkActionGroup->actions(); + int bookmarkCount = bookmarks.size(); + for (int i = 0; i < bookmarkCount; ++i) + { + QAction* act = bookmarks.at(i); + if (act->text() == name) + { + _bookmarkActionGroup->removeAction(act); + _bookmarksMenu->removeAction(act); + delete act; + } + } +} + +void AppMainWindow::renameBookmark(const QString& oldName, const QString& newName) +{ + QList<QAction*> bookmarks = _bookmarkActionGroup->actions(); + int bookmarkCount = bookmarks.size(); + for (int i = 0; i < bookmarkCount; ++i) + { + QAction* act = bookmarks.at(i); + if (act->text() == oldName) + { + act->setText(newName); + } + } +} + +#if USE_CURVE_EDITOR +void AppMainWindow::UpdateCurveEditor() +{ +#ifndef NV_ARTISTTOOLS + _curveEditorMainWindow->setCurveAttributes(SimpleScene::Inst()->GetFurCharacter().GetCurveAttributes()); + _curveEditorMainWindow->setColorCurveAttributes(SimpleScene::Inst()->GetFurCharacter().GetColorAttributes()); +#else + CoreLib::Inst()->AppMainWindow_UpdateCurveEditor(); +#endif // NV_ARTISTTOOLS + + _curveEditorMainWindow->update(); +} + +void AppMainWindow::ShowCurveEditor(int paramId) +{ +#ifndef NV_ARTISTTOOLS + _curveEditorMainWindow->setCurveAttributes(SimpleScene::Inst()->GetFurCharacter().GetCurveAttributes()); + _curveEditorMainWindow->setColorCurveAttributes(SimpleScene::Inst()->GetFurCharacter().GetColorAttributes()); + if (HAIR_PARAMS_ROOT_COLOR == paramId || HAIR_PARAMS_TIP_COLOR == paramId) + { + std::vector<nvidia::CurveEditor::ColorAttribute*> attributes = SimpleScene::Inst()->GetFurCharacter().GetColorAttributesByParamId(paramId); + _curveEditorMainWindow->setSelectedColorAttribute(attributes.size() > 0 ? attributes[0] : nullptr); + } + else + _curveEditorMainWindow->setSelectedCurveAttributes(SimpleScene::Inst()->GetFurCharacter().GetCurveAttributesByParamId(paramId)); + +#else + CoreLib::Inst()->AppMainWindow_ShowCurveEditor(paramId); +#endif // NV_ARTISTTOOLS + + _curveEditorMainWindow->update(); +} +#endif + +void AppMainWindow::menu_clearScene() +{ + SimpleScene::Inst()->Clear(); + updateUI(); +} + +bool AppMainWindow::menu_openfbx() +{ + /* + QString lastDir = _lastFilePath; + QString fileName = QFileDialog::getOpenFileName(this, "Open FBX File", lastDir, "FBX File (*.fbx)"); + if (!fileName.isEmpty()) + { + QFileInfo fileInfo(fileName); + QByteArray dir = QDir::toNativeSeparators(fileInfo.absoluteDir().absolutePath()).toLocal8Bit(); + QByteArray file= fileInfo.fileName().toLocal8Bit(); + + if (SimpleScene::Inst()->LoadSceneFromFbx(dir, file) == false) + { + QMessageBox messageBox; + messageBox.critical(0,"Error","File open error!"); + messageBox.setFixedSize(500,200); + + AppMainWindow::Inst().endProgress(); + + char message[1024]; + sprintf(message, "Failed to open fbx file(\"%s\")", (const char*)file); + viewer_err(message); + + return false; + } + + AppMainWindow::Inst().endProgress(); + + _lastFilePath = fileInfo.absoluteDir().absolutePath(); + + updateUI(); + + return true; + } + return true; + */ + + // dir and file will get in blast open asset dialog + return SimpleScene::Inst()->LoadSceneFromFbx("", ""); +} + +void AppMainWindow::menu_addBookmark() +{ + QString bookmark = SimpleScene::Inst()->createBookmark(); + + QAction* act = new QAction(bookmark, this); + act->setCheckable(true); + _bookmarksMenu->addAction(act); + _bookmarkActionGroup->addAction(act); + act->setChecked(true); +} + +void AppMainWindow::menu_editBookmarks() +{ + CameraBookmarksDialog dlg(this); + dlg.exec(); +} + +void AppMainWindow::menu_bookmarkTriggered(QAction* act) +{ + if (_actionAddBookmark != act && _actionEditBookmarks != act) + { + SimpleScene::Inst()->activateBookmark(act->text()); + } +} + +void AppMainWindow::menu_showOutput() +{ + bool bVisibal = ui.dockOutputWindow->isVisible(); + ui.dockOutputWindow->setVisible(!bVisibal); +} + +void AppMainWindow::menu_showAttributeEditor() +{ + bool bVisibal = ui.dockWidget->isVisible(); + ui.dockWidget->setVisible(!bVisibal); +} +#if USE_CURVE_EDITOR +void AppMainWindow::menu_showCurveEditor() +{ + bool bVisibal = ui.dockWidgetCurveEditor->isVisible(); + ui.dockWidgetCurveEditor->setVisible(!bVisibal); +} +#endif +void AppMainWindow::menu_about() +{ + qDebug("%s", __FUNCTION__); +#ifndef NV_ARTISTTOOLS + AboutDialog::ShowAboutDialog(); +#else + CoreLib::Inst()->AppMainWindow_menu_about(); +#endif // NV_ARTISTTOOLS +} + +void AppMainWindow::menu_opendoc() +{ + qDebug("%s", __FUNCTION__); + +#ifndef NV_ARTISTTOOLS + QString appDir = QApplication::applicationDirPath(); + QString docsFile = QFileInfo(appDir + "/../../docs/User_Guide/Nvidia Blast.chm").absoluteFilePath(); + + QUrl docsUrl = QUrl::fromLocalFile(docsFile); + QUrl url = QUrl::fromUserInput(QString("http://docs.nvidia.com/gameworks/content/artisttools/hairworks/index.html")); + QDesktopServices::openUrl(url); +#else + CoreLib::Inst()->AppMainWindow_menu_opendoc(); +#endif // NV_ARTISTTOOLS +} + +void AppMainWindow::shortcut_frameall() +{ + qDebug("ShortCut_F: frame all"); +} + +void AppMainWindow::shortcut_hud() +{ + Gamepad::ShowHideHud(); + qDebug("ShortCut_S: statistics on/off"); +} + +void AppMainWindow::shortcut_statistics() +{ + Gamepad::ShowHideStats(); + qDebug("ShortCut_S: statistics on/off"); +} + +void AppMainWindow::shortcut_reset() +{ + Gamepad::ResetAnimation(); +} + +void AppMainWindow::shortcut_pause() +{ + //_mainToolbar->on_btnPlayAnimation_clicked(); // this one has some delay + //qDebug("ShortCut_Space: play/pause simualtion"); + Gamepad::PlayPauseAnimation(); +} + +bool AppMainWindow::IsExpertMode() +{ + return _expertMode; +} + +void AppMainWindow::demo_next() +{ + Gamepad::DemoNext(); +} + +void AppMainWindow::demo_prev() +{ + Gamepad::DemoPrev(); +} + +void AppMainWindow::shortcut_escape() +{ + Gamepad::DemoEscape(); +} + +void AppMainWindow::shortcut_expert() +{ + qDebug("ShortCut_F: expert mode on/off"); + + _expertMode = !_expertMode; + bool mode = !_expertMode; + + ui.menuBar->setVisible(mode); + ui.dockWidget->setVisible(mode); + ui.dockOutputWindow->setVisible(mode); +#if USE_CURVE_EDITOR + ui.dockWidgetCurveEditor->setVisible(mode); +#endif + ui.statusBar->setVisible(mode); + +#ifndef NV_ARTISTTOOLS + if (_mainToolbar) + _mainToolbar->setVisible(mode); +#else + CoreLib::Inst()->AppMainWindow_shortcut_expert(mode); +#endif // NV_ARTISTTOOLS + + //bool bDemoMode = AppMainWindow::IsExpertMode(); + bool bMaxSized = AppMainWindow::Inst().isMaximized(); + if (!bMaxSized) + { + // resize before change to demo mode + AppMainWindow::Inst().showMaximized(); + } + + _d3dWidget->update(); + Gamepad::ShowProjectName(); +} + +void AppMainWindow::shortcut_output() +{ + ui.dockOutputWindow->show(); + _d3dWidget->update(); +} + +void AppMainWindow::shortcut_meshmat() +{ +} + +void AppMainWindow::shortcut_fitcamera() +{ + qDebug("ShortCut_Ctrl+F: fit camera"); + SimpleScene::Inst()->FitCamera(); +} + +#if USE_CURVE_EDITOR +void AppMainWindow::onCurveAttributeChanged(nvidia::CurveEditor::CurveAttribute* attribute) +{ +#ifndef NV_ARTISTTOOLS + SimpleScene::Inst()->GetFurCharacter().updateCurveAttribute(attribute); +#else + CoreLib::Inst()->AppMainWindow_onCurveAttributeChanged(attribute); +#endif // NV_ARTISTTOOLS +} + +void AppMainWindow::onColorAttributeChanged(nvidia::CurveEditor::ColorAttribute* attribute) +{ +#ifndef NV_ARTISTTOOLS + SimpleScene::Inst()->GetFurCharacter().updateColorAttribute(attribute); + _graphicalMaterialPanel->updateValues(); +#else + CoreLib::Inst()->AppMainWindow_onColorAttributeChanged(attribute); +#endif // NV_ARTISTTOOLS +} + +void AppMainWindow::onReloadColorAttributeTexture(nvidia::CurveEditor::ColorAttribute* attribute, bool reloadColorTex, int selectedCtrlPntIndex) +{ +#ifndef NV_ARTISTTOOLS + SimpleScene::Inst()->GetFurCharacter().reloadColorAttributeTexture(attribute, reloadColorTex, selectedCtrlPntIndex); +#else + CoreLib::Inst()->AppMainWindow_onReloadColorAttributeTexture(attribute, reloadColorTex, selectedCtrlPntIndex); +#endif // NV_ARTISTTOOLS +} +#endif + +/* + Maya Scheme: + ALT + LMB -> Rotate + ALT + MMB -> Pan + ALT + RMB -> Zoom + + M-wheel -> Zoom + + 3dsMax Scheme: + ALT + MMB -> Rotate + N/A + MMB -> Pan + ALT + SHFT + MMB -> Zoom + + M-wheel -> Zoom +*/ + +void AppMainWindow::InitMouseSchemes() +{ + ShortCut alt_lmb = qMakePair(Qt::KeyboardModifiers(Qt::AltModifier), Qt::MouseButtons(Qt::LeftButton)); + ShortCut alt_mmb = qMakePair(Qt::KeyboardModifiers(Qt::AltModifier), Qt::MouseButtons(Qt::MiddleButton)); + ShortCut alt_rmb = qMakePair(Qt::KeyboardModifiers(Qt::AltModifier), Qt::MouseButtons(Qt::RightButton)); + ShortCut non_mmb = qMakePair(Qt::KeyboardModifiers(Qt::NoModifier), Qt::MouseButtons(Qt::MiddleButton)); + ShortCut alt_shft_mmb = qMakePair(Qt::KeyboardModifiers(Qt::AltModifier|Qt::ShiftModifier), Qt::MouseButtons(Qt::MiddleButton)); + + _mayaScheme[alt_lmb] = 'R'; + _mayaScheme[alt_mmb] = 'P'; + _mayaScheme[alt_rmb] = 'Z'; + + _maxScheme[alt_mmb] = 'R'; + _maxScheme[non_mmb] = 'P'; + _maxScheme[alt_shft_mmb] = 'Z'; +} + +char AppMainWindow::TestMouseScheme( Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons ) +{ + char op = TestDragCamera(modifiers, buttons); + + if (op != 0) + return op; + + if (modifiers == Qt::KeyboardModifier(Qt::ControlModifier)) + { + if (buttons == Qt::MouseButton(Qt::LeftButton)) + return 'L'; + else if (buttons == Qt::MouseButton(Qt::MiddleButton)) + return 'K'; + } + + if (modifiers == Qt::KeyboardModifier(Qt::ShiftModifier)) + return 'W'; + + return 0; +} + +char AppMainWindow::TestDragCamera( Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons ) +{ + if(modifiers != Qt::NoModifier && modifiers != Qt::AltModifier) return 0; + + ShortCut input = qMakePair(modifiers, buttons); + + int scheme = _navigationStyle; + + // !! MUST MATCH THE ORDER OF ITEMS IN 'cbNavigationStyle' + const int MAYA_SCHEME = 0; + const int MAX_SCHEME = 1; + if(scheme == MAYA_SCHEME) + { + auto itr = _mayaScheme.find(input); + if(itr != _mayaScheme.end()) return itr.value(); + } + else + { + auto itr = _maxScheme.find(input); + if(itr != _maxScheme.end()) return itr.value(); + } + return 0; +} + +QString AppMainWindow::OpenTextureFile(QString title) +{ + QString lastDir = _lastFilePath; + QString titleStr = "Open Texture File"; + if(!title.isEmpty()) + titleStr = title; + + QString fileName = QFileDialog::getOpenFileName(this, titleStr, lastDir, "Images (*.dds *.png *.bmp *.jpg *.tga)"); + if(!fileName.isEmpty()) + { + QFileInfo fileInfo(fileName); + _lastFilePath = fileInfo.absoluteDir().absolutePath(); + } + + return fileName; +} + +void AppMainWindow::closeEvent (QCloseEvent *event) +{ + ViewerOutput::Inst().UnRegisterPrinter(_printer); + + if (1) + { +#if USE_CURVE_EDITOR + _curveEditorMainWindow->setParent(NULL); +#endif + event->accept(); + emit aboutToQuit(); + return; + } + if (SimpleScene::Inst()->IsProjectModified() || SimpleScene::Inst()->IsFurModified()) + { + QMessageBox::StandardButton resBtn = QMessageBox::warning( + this, tr("Blast Viewer"), + tr("Save changes?\n"), + QMessageBox::Cancel | QMessageBox::No | QMessageBox::Yes, + QMessageBox::Yes); + switch (resBtn) + { + case QMessageBox::Yes: +#ifndef NV_ARTISTTOOLS + if (!menu_saveHair()) + { + event->ignore(); + return; + } + if (!menu_saveProject()) + { + event->ignore(); + return; + } +#else + if (!CoreLib::Inst()->AppMainWindow_closeEvent(event)) + { + event->ignore(); + return; + } +#endif // NV_ARTISTTOOLS + break; + case QMessageBox::No: + break; + default: + event->ignore(); + return; + } + } + event->accept(); + emit aboutToQuit(); +} + +void AppMainWindow::updateMainToolbar() +{ +#ifndef NV_ARTISTTOOLS + if (_mainToolbar) + _mainToolbar->updateValues(); +#else + CoreLib::Inst()->AppMainWindow_updateMainToolbar(); +#endif // NV_ARTISTTOOLS +} + +#ifndef NV_ARTISTTOOLS +bool AppMainWindow::menu_openProject() +{ + QString lastDir = _lastFilePath; + QString fileName = QFileDialog::getOpenFileName(this, "Open Hair Project File", lastDir, "Hair Project File (*.furproj)"); + + return openProject(fileName); +} + +bool AppMainWindow::menu_saveProject() +{ + char message[1024]; + + std::string projectFilePath = GlobalSettings::Inst().getAbsoluteFilePath(); + if (projectFilePath != "") + { + if (SimpleScene::Inst()->SaveProject( + GlobalSettings::Inst().m_projectFileDir.c_str(), + GlobalSettings::Inst().m_projectFileName.c_str() + ) == false) + { + QMessageBox messageBox; + + sprintf(message, "Project file %s could not be saved!", (const char*)projectFilePath.c_str()); + messageBox.critical(0, "Error", message); + messageBox.setFixedSize(500, 200); + char message[1024]; + sprintf(message, "Failed to save project file(\"%s\")", (const char*)projectFilePath.c_str()); + viewer_err(message); + return false; + } + + sprintf(message, "Project file %s was saved.", (const char*)projectFilePath.c_str()); + + /* + QMessageBox messageBox; + messageBox.information(0, "Info", message); + messageBox.setFixedSize(500,200); + */ + viewer_msg(message); + return true; + } + else + { + return menu_saveProjectAs(); + } + return false; +} + +bool AppMainWindow::menu_saveProjectAs() +{ + char message[1024]; + + QString lastDir = _lastFilePath; + QString fileName = QFileDialog::getSaveFileName(this, "Save Hair Project File", lastDir, "Hair Project File (*.furproj)"); + if (!fileName.isEmpty()) + { + QFileInfo fileInfo(fileName); + QByteArray dir = QDir::toNativeSeparators(fileInfo.absoluteDir().absolutePath()).toLocal8Bit(); + QByteArray file = fileInfo.fileName().toLocal8Bit(); + + if (SimpleScene::Inst()->SaveProject(dir, file) == false) + { + QMessageBox messageBox; + sprintf(message, "Project file %s could not be saved!", (const char*)file); + messageBox.critical(0, "Error", message); + messageBox.setFixedSize(500, 200); + return false; + } + + sprintf(message, "Project file %s was saved.", (const char*)file); + + /* + QMessageBox messageBox; + messageBox.information(0, "Info", message); + messageBox.setFixedSize(500,200); + */ + + viewer_msg(message); + + _lastFilePath = fileInfo.absoluteDir().absolutePath(); + return true; + } + return false; +} + +bool AppMainWindow::menu_openHair() +{ + AppMainWindow& window = AppMainWindow::Inst(); + QString lastDir = window._lastFilePath; + QString fileName = QFileDialog::getOpenFileName(&window, "Open Hair File", lastDir, "Apex Hair File (*.apx;*.apb)"); + if (!fileName.isEmpty()) + { + QFileInfo fileInfo(fileName); + QByteArray dir = QDir::toNativeSeparators(fileInfo.absoluteDir().absolutePath()).toLocal8Bit(); + QByteArray file = fileInfo.fileName().toLocal8Bit(); + + if (SimpleScene::Inst()->GetFurCharacter().LoadHairAsset(dir, file) == false) + { + QMessageBox messageBox; + messageBox.critical(0, "Error", "File open error!"); + messageBox.setFixedSize(500, 200); + char message[1024]; + sprintf(message, "Failed to open hair file(\"%s\")", (const char*)file); + viewer_err(message); + return false; + } + + window._lastFilePath = fileInfo.absoluteDir().absolutePath(); + + window.updateUI(); + return true; + } + + return false; +} + +////////////////////////////////////////////////////////////////////////// +// event handlers +bool AppMainWindow::menu_importHair() +{ + AppMainWindow& window = AppMainWindow::Inst(); + QString lastDir = window._lastFilePath; + QString fileName = QFileDialog::getOpenFileName(&window, "Import Hair File", lastDir, "Apex Hair File (*.apx;*.apb)"); + if (!fileName.isEmpty()) + { + QFileInfo fileInfo(fileName); + QByteArray dir = QDir::toNativeSeparators(fileInfo.absoluteDir().absolutePath()).toLocal8Bit(); + QByteArray file = fileInfo.fileName().toLocal8Bit(); + + if (SimpleScene::Inst()->GetFurCharacter().ImportSelectedHairAsset(dir, file) == false) + { + QMessageBox messageBox; + messageBox.critical(0, "Error", "File open error!"); + messageBox.setFixedSize(500, 200); + char message[1024]; + sprintf(message, "Failed to import hair file(\"%s\")", (const char*)file); + viewer_err(message); + return false; + } + + window._lastFilePath = fileInfo.absoluteDir().absolutePath(); + + window.updateUI(); + return true; + } + return false; +} + + +bool AppMainWindow::menu_saveHair() +{ + return SimpleScene::Inst()->GetFurCharacter().SaveHairAsset(); +} + +bool AppMainWindow::menu_saveHairAs() +{ + AppMainWindow& window = AppMainWindow::Inst(); + QString lastDir = window._lastFilePath; + QString fileName = QFileDialog::getSaveFileName(&window, "Save as", lastDir, "Apex Hair File (*.apx;*.apb)"); + if (!fileName.isEmpty()) + { + QFileInfo fileInfo(fileName); + QByteArray dir = QDir::toNativeSeparators(fileInfo.absoluteDir().absolutePath()).toLocal8Bit(); + QByteArray file = fileInfo.fileName().toLocal8Bit(); + + if (SimpleScene::Inst()->GetFurCharacter().SaveHairAssetAs(dir, file)) + { + window.updateUI(); + } + + window._lastFilePath = fileInfo.absoluteDir().absolutePath(); + return true; + } + return false; +} + +bool AppMainWindow::menu_saveAllHairs() +{ + return SimpleScene::Inst()->GetFurCharacter().SaveAllHairs(); +} +#endif // NV_ARTISTTOOLS
\ No newline at end of file diff --git a/tools/ArtistTools/source/CoreLib/Window/AppMainWindow.h b/tools/ArtistTools/source/CoreLib/Window/AppMainWindow.h new file mode 100644 index 0000000..4183fc2 --- /dev/null +++ b/tools/ArtistTools/source/CoreLib/Window/AppMainWindow.h @@ -0,0 +1,208 @@ +#ifndef APPMAINWINDOW_H +#define APPMAINWINDOW_H + +#include <QtWidgets/QMainWindow> +#include <QtWidgets/QProgressDialog> + +#include "ui_AppMainWindow.h" +#include "UIGlobal.h" + +class StyleMaterialPanel; +class AssetControlPanel; +class PhysicalMaterialPanel; +class GraphicalMaterialPanel; +class DisplayFurVisualizersPanel; +class GeneralAttributePanel; +class BlastToolbar; +class LodPanel; +class DisplayMeshesPanel; +class DisplayPreferencesPanel; +class DisplayScenePanel; +class DisplayLightPanel; +class DisplayMeshMaterialsPanel; + +#if USE_CURVE_EDITOR +namespace nvidia { +namespace CurveEditor { + +class CurveEditorMainWindow; +class CurveAttribute; +class ColorAttribute; + +} // namespace CurveEditor +} // namespace nvidia +#endif + +#if USE_MATERIAL_SET +class MaterialSetPanel; +#endif + +class D3DWidget; +class MsgPrinter; +class AppMainWindow : public QMainWindow +{ + Q_OBJECT + +public: + AppMainWindow(QWidget *parent = 0, Qt::WindowFlags flags = 0); + ~AppMainWindow(); + + CORELIB_EXPORT static AppMainWindow& Inst(); + + CORELIB_EXPORT void InitUI(); + CORELIB_EXPORT void updateUI(); + CORELIB_EXPORT void updatePluginUI(); + + static bool IsExpertMode(); + + D3DWidget* GetRenderWidget() {return _d3dWidget;} + char TestMouseScheme(Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons); + + CORELIB_EXPORT QString OpenTextureFile(QString title = ""); + + void setNavigationStyle(int index) { _navigationStyle = index; } + int getNavigationStyle() { return _navigationStyle; } + + void closeEvent (QCloseEvent *event); + + CORELIB_EXPORT void startProgress(); + CORELIB_EXPORT void setProgressMaximum(int m); + CORELIB_EXPORT void setProgress(const char* label, int progress = -1); + CORELIB_EXPORT void endProgress(); + CORELIB_EXPORT void quit(); + + CORELIB_EXPORT void updateMainToolbar(); + CORELIB_EXPORT void processDragAndDrop(QString fname); + CORELIB_EXPORT bool openProject(QString fileName); + + CORELIB_EXPORT static void setConnectionMode(int); + + DisplayMeshesPanel* GetDisplayMeshesPanel() { return _displayMeshesPanel; } + DisplayPreferencesPanel* GetDisplayPreferencesPanel() { return _displayPreferencesPanel; } + DisplayScenePanel* GetDisplayScenePanel() { return _displayScenePanel; } + DisplayLightPanel* GetDisplayLightPanel() { return _displayLightPanel; } + + void removeBookmark(const QString& name); + void renameBookmark(const QString& oldName, const QString& newName); + +#if USE_CURVE_EDITOR + CORELIB_EXPORT nvidia::CurveEditor::CurveEditorMainWindow* GetCurveEditorMainWindow() { return _curveEditorMainWindow; } + CORELIB_EXPORT void UpdateCurveEditor(); + CORELIB_EXPORT void ShowCurveEditor(int paramId); +#endif + + inline QString GetFilePath() { return _lastFilePath; } +signals: + void aboutToQuit(); + + public slots: + CORELIB_EXPORT void menu_clearScene(); + CORELIB_EXPORT bool menu_openfbx(); + CORELIB_EXPORT void menu_addBookmark(); + CORELIB_EXPORT void menu_editBookmarks(); + CORELIB_EXPORT void menu_bookmarkTriggered(QAction* act); + CORELIB_EXPORT void menu_showOutput(); + CORELIB_EXPORT void menu_showAttributeEditor(); + CORELIB_EXPORT void menu_about(); + CORELIB_EXPORT void menu_opendoc(); + CORELIB_EXPORT void shortcut_frameall(); + CORELIB_EXPORT void shortcut_hud(); + CORELIB_EXPORT void shortcut_statistics(); + CORELIB_EXPORT void shortcut_pause(); + CORELIB_EXPORT void shortcut_reset(); + CORELIB_EXPORT void shortcut_escape(); + CORELIB_EXPORT void shortcut_expert(); + CORELIB_EXPORT void demo_next(); + CORELIB_EXPORT void demo_prev(); + CORELIB_EXPORT void shortcut_output(); + CORELIB_EXPORT void shortcut_meshmat(); + CORELIB_EXPORT void shortcut_fitcamera(); + +#if USE_CURVE_EDITOR + CORELIB_EXPORT void menu_showCurveEditor(); + CORELIB_EXPORT void onCurveAttributeChanged(nvidia::CurveEditor::CurveAttribute* attribute); + CORELIB_EXPORT void onColorAttributeChanged(nvidia::CurveEditor::ColorAttribute* attribute); + CORELIB_EXPORT void onReloadColorAttributeTexture(nvidia::CurveEditor::ColorAttribute* attribute, bool reloadColorTex, int selectedCtrlPntIndex); +#endif + +private: + char TestDragCamera(Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons); + +public: + void InitMenuItems(); + void InitToolbar(); + void InitPluginTab(); + void InitMainTab(); + void InitMouseSchemes(); + void InitShortCuts(); + void updateBookmarkMenu(); + + Ui::AppMainWindowClass ui; + + D3DWidget* _d3dWidget; + QMenu* _bookmarksMenu; + + DisplayMeshesPanel* _displayMeshesPanel; + DisplayPreferencesPanel* _displayPreferencesPanel; + DisplayScenePanel* _displayScenePanel; + DisplayLightPanel* _displayLightPanel; + + +#if USE_CURVE_EDITOR + bool _curveEditorInitizlized; + nvidia::CurveEditor::CurveEditorMainWindow* _curveEditorMainWindow; +#endif + + typedef QPair<Qt::KeyboardModifiers, Qt::MouseButtons> ShortCut; + QMap<ShortCut, char> _mayaScheme; + QMap<ShortCut, char> _maxScheme; + QActionGroup* _bookmarkActionGroup; + QAction* _actionAddBookmark; + QAction* _actionEditBookmarks; + + QString _lastFilePath; + + int _navigationStyle; + + MsgPrinter* _printer; + + QProgressDialog _progressDialog; + + + static bool _expertMode; + + CORELIB_EXPORT static int _connectionMode; + +#ifndef NV_ARTISTTOOLS + BlastToolbar* GetMainToolbar() { return _mainToolbar; } + DisplayFurVisualizersPanel* GetFurVisualizersPanel() { return _displayFurVisualizersPanel; } + +public slots: + bool menu_openProject(); + bool menu_saveProject(); + bool menu_saveProjectAs(); + bool menu_openHair(); + bool menu_importHair(); + bool menu_saveHair(); + bool menu_saveHairAs(); + bool menu_saveAllHairs(); + +private: + BlastToolbar* _mainToolbar; + AssetControlPanel* _assetControlPanel; + GeneralAttributePanel* _generalAttributePanel; + DisplayFurVisualizersPanel* _displayFurVisualizersPanel; + StyleMaterialPanel* _styleMaterialPanel; + PhysicalMaterialPanel* _physicalMaterialPanel; + GraphicalMaterialPanel* _graphicalMaterialPanel; + LodPanel* _lodPanel; + DisplayMeshMaterialsPanel* _displayMeshMaterialsPanel; +#if USE_MATERIAL_SET + MaterialSetPanel* _materialSetPanel; +#endif +#endif // NV_ARTISTTOOLS + + bool m_bGizmoWithLocal; +}; + +#endif // APPMAINWINDOW_H diff --git a/tools/ArtistTools/source/CoreLib/Window/CameraBookmarksDialog.cpp b/tools/ArtistTools/source/CoreLib/Window/CameraBookmarksDialog.cpp new file mode 100644 index 0000000..445067a --- /dev/null +++ b/tools/ArtistTools/source/CoreLib/Window/CameraBookmarksDialog.cpp @@ -0,0 +1,106 @@ +#include "CameraBookmarksDialog.h" +#include "SimpleScene.h" +#include "AppMainWindow.h" +#include <QtWidgets/QMessageBox> + +CameraBookmarksDialog::CameraBookmarksDialog(QWidget *parent) + : QDialog(parent) +{ + ui.setupUi(this); + + ui.buttonBox->button(QDialogButtonBox::Ok)->setFixedWidth(64); + ui.buttonBox->button(QDialogButtonBox::Cancel)->setFixedWidth(64); + ui.buttonBox->button(QDialogButtonBox::Ok)->setFixedHeight(23); + ui.buttonBox->button(QDialogButtonBox::Cancel)->setFixedHeight(23); + setWindowFlags(windowFlags()&~Qt::WindowContextHelpButtonHint); + + QObject::connect(ui.buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept())); + QObject::connect(ui.buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject())); + + ui.editBookmarkName->setEnabled(false); + ui.btnRename->setEnabled(false); + ui.btnDelete->setEnabled(false); + + _fillListWidget(); +} + +CameraBookmarksDialog::~CameraBookmarksDialog() +{ + +} + +void CameraBookmarksDialog::on_listWidgetBookmarks_itemSelectionChanged() +{ + if (ui.listWidgetBookmarks->selectedItems().size() == 0) + { + ui.editBookmarkName->setEnabled(false); + ui.btnRename->setEnabled(false); + ui.btnDelete->setEnabled(false); + } + else + { + QListWidgetItem* item = ui.listWidgetBookmarks->selectedItems().at(0); + ui.editBookmarkName->setEnabled(true); + ui.btnRename->setEnabled(true); + ui.btnDelete->setEnabled(true); + + ui.editBookmarkName->setText(item->text()); + } +} + +void CameraBookmarksDialog::on_editBookmarkName_textChanged(QString val) +{ + +} + +void CameraBookmarksDialog::on_btnRename_clicked() +{ + if (ui.editBookmarkName->text().isEmpty()) + { + QListWidgetItem* item = ui.listWidgetBookmarks->selectedItems().at(0); + ui.editBookmarkName->setText(item->text()); + } + else + { + if (_isNameConflict(ui.editBookmarkName->text())) + { + QMessageBox::warning(this, tr("Warning"), tr("The new name is conflict with name of other camera bookmark!")); + return; + } + + QListWidgetItem* item = ui.listWidgetBookmarks->selectedItems().at(0); + SimpleScene::Inst()->renameBookmark(item->text(), ui.editBookmarkName->text()); + AppMainWindow::Inst().renameBookmark(item->text(), ui.editBookmarkName->text()); + item->setText(ui.editBookmarkName->text()); + } + +} + +void CameraBookmarksDialog::on_btnDelete_clicked() +{ + QListWidgetItem* item = ui.listWidgetBookmarks->selectedItems().at(0); + SimpleScene::Inst()->removeBookmark(item->text()); + AppMainWindow::Inst().removeBookmark(item->text()); + ui.listWidgetBookmarks->takeItem(ui.listWidgetBookmarks->row(item)); + delete item; + +} + +void CameraBookmarksDialog::_fillListWidget() +{ + QList<QString> bookmarks = SimpleScene::Inst()->getBookmarkNames(); + ui.listWidgetBookmarks->addItems(bookmarks); +} + +bool CameraBookmarksDialog::_isNameConflict(const QString& name) +{ + QList<QString> bookmarks = SimpleScene::Inst()->getBookmarkNames(); + int bookmarkCount = bookmarks.size(); + for (int i = 0; i < bookmarkCount; ++i) + { + if (bookmarks.at(i) == name) + return true; + } + + return false; +}
\ No newline at end of file diff --git a/tools/ArtistTools/source/CoreLib/Window/CameraBookmarksDialog.h b/tools/ArtistTools/source/CoreLib/Window/CameraBookmarksDialog.h new file mode 100644 index 0000000..13caa42 --- /dev/null +++ b/tools/ArtistTools/source/CoreLib/Window/CameraBookmarksDialog.h @@ -0,0 +1,31 @@ +#ifndef CAMERABOOKMARKSDIALOG_H +#define CAMERABOOKMARKSDIALOG_H + +#include <QtWidgets/QDialog> +#include "ui_CameraBookmarksDialog.h" + +#include "corelib_global.h" + +class CameraBookmarksDialog : public QDialog +{ + Q_OBJECT + +public: + CameraBookmarksDialog(QWidget *parent = 0); + ~CameraBookmarksDialog(); + +private slots: +CORELIB_EXPORT void on_listWidgetBookmarks_itemSelectionChanged(); +CORELIB_EXPORT void on_editBookmarkName_textChanged(QString val); +CORELIB_EXPORT void on_btnRename_clicked(); +CORELIB_EXPORT void on_btnDelete_clicked(); + +private: + void _fillListWidget(); + bool _isNameConflict(const QString& name); + +private: + Ui::CameraBookmarksDialog ui; +}; + +#endif // CAMERABOOKMARKSDIALOG_H diff --git a/tools/ArtistTools/source/CoreLib/Window/D3DWidget.cpp b/tools/ArtistTools/source/CoreLib/Window/D3DWidget.cpp new file mode 100644 index 0000000..69be706 --- /dev/null +++ b/tools/ArtistTools/source/CoreLib/Window/D3DWidget.cpp @@ -0,0 +1,151 @@ +#include <QtGui/QResizeEvent> +#include <QtGui/QMouseEvent> +#include <QtCore/QTimer> +#include <QtCore/QMimeData> + +#include "D3DWidget.h" +#include "AppMainWindow.h" +#include "SimpleScene.h" + +D3DWidget::D3DWidget( QWidget* parent ) + : QWidget(parent, Qt::MSWindowsOwnDC) // Same settings as used in Qt's QGLWidget +{ + // same settings as used in QGLWidget to avoid 'white flickering' + setAttribute(Qt::WA_PaintOnScreen); + setAttribute(Qt::WA_NoSystemBackground); + + // to get rid of 'black flickering' + setAttribute(Qt::WA_OpaquePaintEvent, true); + + QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + setSizePolicy(sizePolicy); + + _appWindow = qobject_cast<AppMainWindow*>(parent); + this->setAcceptDrops(true); + + setMouseTracking(true); +} + +void D3DWidget::dragEnterEvent(QDragEnterEvent *e) +{ + CoreLib::Inst()->D3DWidget_dragEnterEvent(e); + e->acceptProposedAction(); +} + +void D3DWidget::dragMoveEvent(QDragMoveEvent *e) +{ + CoreLib::Inst()->D3DWidget_dragMoveEvent(e); + e->acceptProposedAction(); +} + +void D3DWidget::dragLeaveEvent(QDragLeaveEvent *e) +{ + CoreLib::Inst()->D3DWidget_dragLeaveEvent(e); + //e->acceptProposedAction(); +} + +void D3DWidget::dropEvent(QDropEvent *e) +{ + CoreLib::Inst()->D3DWidget_dropEvent(e); + + const QMimeData* data = e->mimeData(); + QString name = data->objectName(); + + bool hasUrls = data->hasUrls(); + if (!hasUrls) + return; + + QList<QUrl> urlList = data->urls(); + QString text; + for (int i = 0; i < urlList.size() && i < 32; ++i) { + QString url = urlList.at(i).toLocalFile(); + text += url; + } + + e->acceptProposedAction(); + + AppMainWindow::Inst().processDragAndDrop(text); +} + +void D3DWidget::paintEvent( QPaintEvent* e ) +{ + CoreLib::Inst()->D3DWidget_paintEvent(e); + + SimpleScene::Inst()->Draw(); +} + +void D3DWidget::Shutdown() +{ + SimpleScene::Inst()->Shutdown(); +} + +void D3DWidget::Timeout() +{ + SimpleScene::Inst()->Timeout(); +} + +void D3DWidget::resizeEvent( QResizeEvent* e ) +{ + int w = e->size().width(); + int h = e->size().height(); + // resize calls D3D11RenderWindow::Resize + SimpleScene::Inst()->Resize(w,h); + // D3DWidget_resizeEvent calls resize in DeviceManager + CoreLib::Inst()->D3DWidget_resizeEvent(e); +} + +void D3DWidget::mouseMoveEvent( QMouseEvent* e ) +{ + CoreLib::Inst()->D3DWidget_mouseMoveEvent(e); + + atcore_float2 pos = gfsdk_makeFloat2(e->x(), e->y()); + SimpleScene::Inst()->onMouseMove(pos); + + Q_ASSERT(_appWindow != NV_NULL); + char mode = _appWindow->TestMouseScheme(e->modifiers(), e->buttons()); + + if(mode == 0) return; + SimpleScene::Inst()->Drag(mode); +} + +void D3DWidget::wheelEvent(QWheelEvent* e) +{ + CoreLib::Inst()->D3DWidget_wheelEvent(e); + + SimpleScene::Inst()->onMouseWheel(e->delta()); + SimpleScene::Inst()->WheelZoom(); +} + +void D3DWidget::mousePressEvent( QMouseEvent* e ) +{ + CoreLib::Inst()->D3DWidget_mousePressEvent(e); + + atcore_float2 pos = gfsdk_makeFloat2(e->x(), e->y()); + SimpleScene::Inst()->onMouseDown(pos); +} + +void D3DWidget::mouseReleaseEvent( QMouseEvent* e ) +{ + CoreLib::Inst()->D3DWidget_mouseReleaseEvent(e); + + atcore_float2 pos = gfsdk_makeFloat2(e->x(), e->y()); + SimpleScene::Inst()->onMouseUp(pos); +} + +void D3DWidget::keyPressEvent( QKeyEvent* e ) +{ + CoreLib::Inst()->D3DWidget_keyPressEvent(e); +} + +void D3DWidget::keyReleaseEvent( QKeyEvent* e ) +{ + CoreLib::Inst()->D3DWidget_keyReleaseEvent(e); +} + +void D3DWidget::contextMenuEvent(QContextMenuEvent *e) +{ + CoreLib::Inst()->D3DWidget_contextMenuEvent(e); +} + diff --git a/tools/ArtistTools/source/CoreLib/Window/D3DWidget.h b/tools/ArtistTools/source/CoreLib/Window/D3DWidget.h new file mode 100644 index 0000000..0de9a1e --- /dev/null +++ b/tools/ArtistTools/source/CoreLib/Window/D3DWidget.h @@ -0,0 +1,51 @@ +#ifndef D3DWidget_h__ +#define D3DWidget_h__ + +#include <QtWidgets/QWidget> +#include "Nv.h" + +#include "corelib_global.h" + +class AppMainWindow; +class D3DWidget : public QWidget +{ + Q_OBJECT + +public: + + D3DWidget(QWidget* parent); + virtual ~D3DWidget(){} + +signals: + void DropSignal(); + +public slots: +CORELIB_EXPORT void Timeout(); +CORELIB_EXPORT void Shutdown(); + +protected: + // return NULL to ignore system painter + virtual QPaintEngine *paintEngine() const { return NV_NULL; } + + // QWidget events + virtual void resizeEvent(QResizeEvent* e); + virtual void paintEvent(QPaintEvent* e); + virtual void mousePressEvent(QMouseEvent* e); + virtual void mouseReleaseEvent(QMouseEvent* e); + virtual void mouseMoveEvent(QMouseEvent* e); + virtual void wheelEvent ( QWheelEvent * e); + virtual void keyPressEvent(QKeyEvent* e); + virtual void keyReleaseEvent(QKeyEvent* e); + + virtual void dragEnterEvent(QDragEnterEvent *e); + virtual void dragMoveEvent(QDragMoveEvent *e); + virtual void dragLeaveEvent(QDragLeaveEvent *e); + virtual void dropEvent(QDropEvent *e); + + virtual void contextMenuEvent(QContextMenuEvent *e); + +private: + AppMainWindow* _appWindow; +}; + +#endif // D3DWidget_h__ diff --git a/tools/ArtistTools/source/CoreLib/Window/DisplayLightPanel.cpp b/tools/ArtistTools/source/CoreLib/Window/DisplayLightPanel.cpp new file mode 100644 index 0000000..ec267a3 --- /dev/null +++ b/tools/ArtistTools/source/CoreLib/Window/DisplayLightPanel.cpp @@ -0,0 +1,263 @@ +#include "AppMainWindow.h" +#include "DisplayLightPanel.h" + +#include "Light.h" +#include "GlobalSettings.h" + +#include <QtWidgets/QColorDialog> +#include <QtCore/QFileInfo> + +DisplayLightPanel::DisplayLightPanel(QWidget* parent) + : + QWidget(parent) +{ + ui.setupUi(this); + _isUpdatingUI = false; + + ConfigSpinBox<SlideSpinBoxF>(ui.spinLightDistance, 0.0, 1000.0, 0.1); + ConfigSpinBox<SlideSpinBoxF>(ui.spinLightIntensity, 0.0, 5.0, 0.01); + + ui.btnLightColorTex->setIcon(QIcon(":/AppMainWindow/images/TextureEnabled_icon.png")); + ui.btnLightColorTex->setIconSize(QSize(12,12)); + ui.btnLightColorTexReload->setIcon(QIcon(":/AppMainWindow/images/Refresh_icon.png")); + ui.btnLightColorTexClear->setIcon(QIcon(":/AppMainWindow/images/Remove_icon.png")); + + connect(ui.listSelectedLight, SIGNAL(itemSelectionChanged()), this, SLOT(onListSelectionChanged())); +} + +void DisplayLightPanel::onListSelectionChanged() +{ + if (_isUpdatingUI) + return; + + int numSelected = ui.listSelectedLight->selectedItems().count(); + + // change selection only when there is something selected + if (numSelected > 0) + { + int numItems = ui.listSelectedLight->count(); + { + for (int i = 0; i < numItems; i++) + { + bool selected = ui.listSelectedLight->item(i)->isSelected(); + Light::GetLight(i)->m_selected = selected; + } + } + } + + updateUI(); +} + +void DisplayLightPanel::on_cbShadowMapResolution_currentIndexChanged( int index ) +{ + for (int i = 0; i < 4; i++) + { + Light* pLight = Light::GetLight(i); + if (!pLight || !pLight->m_selected) + continue; + + pLight->SetShadowMapResolution(index); + } +} + +void DisplayLightPanel::on_btnLightUseShadow_stateChanged(int state) +{ + for (int i = 0; i < 4; i++) + { + Light* pLight = Light::GetLight(i); + if (!pLight || !pLight->m_selected) + continue; + + pLight->m_useShadows = state; + } +} + +void DisplayLightPanel::on_btnVisualizeLight_stateChanged(int state) +{ + for (int i = 0; i < 4; i++) + { + Light* pLight = Light::GetLight(i); + if (!pLight || !pLight->m_selected) + continue; + + pLight->m_visualize = state; + } +} + +void DisplayLightPanel::on_btnLightEnable_stateChanged(int state) +{ + for (int i = 0; i < 4; i++) + { + Light* pLight = Light::GetLight(i); + if (!pLight || !pLight->m_selected) + continue; + + pLight->m_enable = state; + } +} + +void DisplayLightPanel::on_btnLinkLightEnable_stateChanged(int state) +{ + Light::SetLinkLightOption(state != 0 ? true : false); +} + +void DisplayLightPanel::on_spinLightDistance_valueChanged(double v) +{ + for (int i = 0; i < 4; i++) + { + Light* pLight = Light::GetLight(i); + if (!pLight || !pLight->m_selected) + continue; + + pLight->SetDistance(v); + } +} + +void DisplayLightPanel::on_spinLightIntensity_valueChanged(double v) +{ + for (int i = 0; i < 4; i++) + { + Light* pLight = Light::GetLight(i); + if (!pLight || !pLight->m_selected) + continue; + + pLight->m_intensity = v; + } +} + +void DisplayLightPanel::on_btnVisualizeShadowMap_stateChanged(int state) +{ + GlobalSettings::Inst().m_visualizeShadowMap = state; +} + +void DisplayLightPanel::setButtonColor(QPushButton *button, float r, float g, float b) +{ + QColor specColor; + specColor.setRgbF(r,g,b); + QString specBtnStyle = QString("background-color: rgb(%1,%2,%3);") + .arg(specColor.red()) + .arg(specColor.green()) + .arg(specColor.blue()); + button->setStyleSheet(specBtnStyle); +} + + +static bool getNewColor(atcore_float3& color) +{ + QColor currentColor; + currentColor.setRgbF(color.x, color.y, color.z); + + QColor newColor = QColorDialog::getColor(currentColor, NV_NULL); + if(newColor.isValid()) + { + qreal r,g,b; + newColor.getRgbF(&r, &g, &b); + + color.x = r; + color.y = g; + color.z = b; + return true; + } + + return false; +} + +void DisplayLightPanel::on_btnLightColor_clicked() +{ + Light* pLight = Light::GetFirstSelectedLight(); + + atcore_float3 color = pLight->m_color; + + if (getNewColor(color)) + setButtonColor(ui.btnLightColor, color.x, color.y, color.z); + + for (int i = 0; i < 4; i++) + { + Light* pLight = Light::GetLight(i); + if (!pLight || !pLight->m_selected) + continue; + + pLight->m_color = color; + } +} + +inline void SetTextureIcon(QPushButton* pButton, bool enabled) +{ + if (enabled) + pButton->setIcon(QIcon(":/AppMainWindow/images/TextureEnabled_icon.png")); + else + pButton->setIcon(QIcon(":/AppMainWindow/images/TextureIsUsed_icon.png")); +} + +void DisplayLightPanel::on_btnLightColorTex_clicked() +{ + QString texName = AppMainWindow::Inst().OpenTextureFile(); + QFileInfo fileInfo(texName); + QByteArray ba = fileInfo.absoluteFilePath().toLocal8Bit(); + + if (Light::SetEnvTextureFromFilePath((const char*)ba)) + SetTextureIcon(ui.btnLightColorTex, Light::GetEnvTextureFilePath().empty()); +} + +void DisplayLightPanel::on_btnLightColorTexReload_clicked() +{ + std::string path = Light::GetEnvTextureFilePath(); + if (Light::SetEnvTextureFromFilePath(path.c_str())) + SetTextureIcon(ui.btnLightColorTex, Light::GetEnvTextureFilePath().empty()); +} + +void DisplayLightPanel::on_btnLightColorTexClear_clicked() +{ + Light::SetEnvTextureFromFilePath(nullptr); + SetTextureIcon(ui.btnLightColorTex, Light::GetEnvTextureFilePath().empty()); +} + +void DisplayLightPanel::updateUI() +{ + Light* pLight = Light::GetFirstSelectedLight(); + if (!pLight) + return; + + atcore_float3& color = pLight->m_color; + setButtonColor(ui.btnLightColor, color.x, color.y, color.z); + + ui.btnVisualizeLight->setChecked(pLight->m_visualize); + + ui.spinLightDistance->setValue(pLight->GetDistance()); + ui.spinLightIntensity->setValue(pLight->m_intensity); + + ui.btnLightUseShadow->setChecked(pLight->m_useShadows); + ui.btnLightEnable->setChecked(pLight->m_enable); + + ui.btnVisualizeShadowMap->setChecked(GlobalSettings::Inst().m_visualizeShadowMap); + + ui.cbShadowMapResolution->setCurrentIndex(pLight->m_shadowMapResolutionIndex); + + ui.btnLinkLightEnable->setChecked(Light::GetLinkLightOption()); + + SetTextureIcon(ui.btnLightColorTex, Light::GetEnvTextureFilePath().empty()); +} + +void DisplayLightPanel::updateValues() +{ + _isUpdatingUI = true; + + ui.listSelectedLight->clear(); + for (int i = 0; i < 4; i++) + { + Light* pLight = Light::GetLight(i); + if (!pLight) + continue; + + const char* lightName = pLight->m_name.c_str(); + bool selected = pLight->m_selected; + + ui.listSelectedLight->addItem(lightName); + ui.listSelectedLight->item(i)->setSelected(selected); + } + ui.listSelectedLight->setSelectionMode(QAbstractItemView::ExtendedSelection); + + updateUI(); + + _isUpdatingUI = false; +} diff --git a/tools/ArtistTools/source/CoreLib/Window/DisplayLightPanel.h b/tools/ArtistTools/source/CoreLib/Window/DisplayLightPanel.h new file mode 100644 index 0000000..e22eae4 --- /dev/null +++ b/tools/ArtistTools/source/CoreLib/Window/DisplayLightPanel.h @@ -0,0 +1,47 @@ +#ifndef DisplayLightPanel_h__ +#define DisplayLightPanel_h__ + +#include <QtWidgets/QWidget> +#include "ui_DisplayLightPanel.h" + +#include "corelib_global.h" + +class DisplayLightPanel : public QWidget +{ + Q_OBJECT + +public: + DisplayLightPanel(QWidget* parent); + + public: + CORELIB_EXPORT void updateValues(); + + public slots: + CORELIB_EXPORT void onListSelectionChanged(); + + CORELIB_EXPORT void on_spinLightDistance_valueChanged(double v); + CORELIB_EXPORT void on_spinLightIntensity_valueChanged(double v); + + CORELIB_EXPORT void on_btnLightUseShadow_stateChanged(int state); + CORELIB_EXPORT void on_btnVisualizeLight_stateChanged(int state); + CORELIB_EXPORT void on_btnLightEnable_stateChanged(int state); + CORELIB_EXPORT void on_btnLinkLightEnable_stateChanged(int state); + + CORELIB_EXPORT void on_btnLightColor_clicked(); + CORELIB_EXPORT void on_btnLightColorTex_clicked(); + CORELIB_EXPORT void on_btnLightColorTexReload_clicked(); + CORELIB_EXPORT void on_btnLightColorTexClear_clicked(); + + CORELIB_EXPORT void on_btnVisualizeShadowMap_stateChanged(int state); + + CORELIB_EXPORT void on_cbShadowMapResolution_currentIndexChanged(int index); + +private: + Ui::DisplayLightPanel ui; + bool _isUpdatingUI; + void setButtonColor(QPushButton *button, float r, float g, float b); + + void updateUI(); +}; + +#endif diff --git a/tools/ArtistTools/source/CoreLib/Window/DisplayMeshesPanel.cpp b/tools/ArtistTools/source/CoreLib/Window/DisplayMeshesPanel.cpp new file mode 100644 index 0000000..67ca141 --- /dev/null +++ b/tools/ArtistTools/source/CoreLib/Window/DisplayMeshesPanel.cpp @@ -0,0 +1,177 @@ +#include "DisplayMeshesPanel.h" + +#include <QtWidgets/QGridLayout> +#include <QtWidgets/QHBoxLayout> +#include <QtWidgets/QPushButton> + +#include "AppMainWindow.h" + +#include "SimpleScene.h" + +#ifndef NV_ARTISTTOOLS +#include "FurCharacter.h" +#else +#endif // NV_ARTISTTOOLS + +////////////////////////////////////////////////////////////////////////// +// DisplayMeshItem + +StateViewItem::StateViewItem( QWidget* parent, unsigned int id, MeshViewState view /*= VS_VISIABLE*/ ) + : _id(id) +{ + static QIcon iconVisible(":/AppMainWindow/images/visibilityToggle_visible.png"); + static QIcon iconNotVisible(":/AppMainWindow/images/visibilityToggle_notVisible.png"); + + _parent = qobject_cast<DisplayMeshesPanel*>(parent); + + _layout = new QHBoxLayout(this); + _layout->setObjectName(QString::fromUtf8("boxLayout")); + _layout->setMargin(0); + + this->setLayout(_layout); + + _btn = new QPushButton(this); + + _btn->setObjectName(QString::fromUtf8("btnToggleView")); + QSizePolicy sizePolicy1(QSizePolicy::Ignored, QSizePolicy::Fixed); + sizePolicy1.setHorizontalStretch(0); + sizePolicy1.setVerticalStretch(0); + sizePolicy1.setHeightForWidth(_btn->sizePolicy().hasHeightForWidth()); + _btn->setSizePolicy(sizePolicy1); + _btn->setMinimumSize(QSize(16, 16)); + _btn->setMaximumSize(QSize(16, 16)); + _btn->setAutoFillBackground(false); + _btn->setCheckable(true); + _btn->setChecked(view == VS_VISIABLE); + _btn->setIcon( (view == VS_VISIABLE) ? iconVisible : iconNotVisible); + + _layout->addWidget(_btn); + + _spacer = new QSpacerItem(20, 40, QSizePolicy::Expanding, QSizePolicy::Ignored); + _layout->addItem(_spacer); + + QMetaObject::connectSlotsByName(this); +} + +void StateViewItem::on_btnToggleView_clicked() +{ + static QIcon iconVisible(":/AppMainWindow/images/visibilityToggle_visible.png"); + static QIcon iconNotVisible(":/AppMainWindow/images/visibilityToggle_notVisible.png"); + + bool bVis = _btn->isChecked(); + _btn->setIcon(bVis ? iconVisible : iconNotVisible); + + _parent->EmitToggleSignal(_id, bVis); + + qDebug("%s", __FUNCTION__); +} + + +////////////////////////////////////////////////////////////////////////// +DisplayMeshesPanel::DisplayMeshesPanel( QWidget* parent ) + :QFrame(parent) +{ + _layout = new QGridLayout(this); + _layout->setObjectName(QString::fromUtf8("gridLayout")); + + this->setLayout(_layout); + + //QString styleSheet = + // "QPushButton#btnToggleView:checked {border:2px solid gray; background:rgb(118,180,0);} \n" \ + // "QPushButton#btnToggleView:pressed {border:2px solid gray; background:rgb(118,180,0);}"; + //setStyleSheet(styleSheet); +} + +///////////////////////////////////////////////////////////////////////////////////////// +void DisplayMeshesPanel::updateValues() +{ + ClearItems(); + +#ifndef NV_ARTISTTOOLS + FurCharacter& character = SimpleScene::Inst()->GetFurCharacter(); + int nMesh = character.GetMeshCount(); + for (int i = 0; i < nMesh; ++i) + { + bool used = character.GetMeshUsed(i); + if (!used) + continue; + + const char* name = character.GetMeshName(i); + bool visible = character.GetMeshVisible(i); + + StateViewItem::MeshViewState visState = visible ? StateViewItem::VS_VISIABLE : StateViewItem::VS_INVISIBLE; + + AddMeshItem(QString(name), i, visState); + } +#else + CoreLib::Inst()->DisplayMeshesPanel_updateValues(); +#endif // NV_ARTISTTOOLS +} + +///////////////////////////////////////////////////////////////////////////////////////// +void DisplayMeshesPanel::AddMeshItem( QString name, unsigned int id, StateViewItem::MeshViewState view ) +{ + StateViewItem* item; + item = new StateViewItem(this, id, view); + + QSizePolicy sizePolicy1(QSizePolicy::Expanding, QSizePolicy::Fixed); + sizePolicy1.setHorizontalStretch(0); + sizePolicy1.setVerticalStretch(0); + + QLabel* label = new QLabel(name, this); + label->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); + label->setSizePolicy(sizePolicy1); + + int row = _items.size(); + _layout->addWidget(label, row, 0, 1, 1); + + _layout->addWidget(item, row, 1, 1, 1); + + Q_ASSERT(_items.find(id) == _items.end()); + + ItemUI ui; + ui.label = label; + ui.viewItem = item; + _items[id] = ui; +} + +///////////////////////////////////////////////////////////////////////////////////////// +void DisplayMeshesPanel::EmitToggleSignal( unsigned int id, bool visible ) +{ + emit MeshViewSignal(id, visible); + +#ifndef NV_ARTISTTOOLS + FurCharacter& character = SimpleScene::Inst()->GetFurCharacter(); + character.SetMeshVisible(id, visible); +#else + CoreLib::Inst()->DisplayMeshesPanel_EmitToggleSignal(id, visible); +#endif // NV_ARTISTTOOLS +} + +///////////////////////////////////////////////////////////////////////////////////////// +void DisplayMeshesPanel::RemoveMeshItem( unsigned int id ) +{ + if(_items.find(id) != _items.end()) + { + ItemUI ui = _items[id]; + delete ui.label; + delete ui.viewItem; + _items.remove(id); + } + else + { + Q_ASSERT("Mesh item doesn't exist!!"); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// +void DisplayMeshesPanel::ClearItems() +{ + Q_FOREACH(ItemUI ui, _items) + { + delete ui.label; + delete ui.viewItem; + } + + _items.clear(); +} diff --git a/tools/ArtistTools/source/CoreLib/Window/DisplayMeshesPanel.h b/tools/ArtistTools/source/CoreLib/Window/DisplayMeshesPanel.h new file mode 100644 index 0000000..ecc5b49 --- /dev/null +++ b/tools/ArtistTools/source/CoreLib/Window/DisplayMeshesPanel.h @@ -0,0 +1,80 @@ +#ifndef DisplayMeshesPanel_h__ +#define DisplayMeshesPanel_h__ + +#include <QtWidgets/QFrame> +#include <QtCore/QMap> +#ifndef NV_ARTISTTOOLS +#include "ui_LodPanel.h" +#else +#include <QtWidgets/QLabel> +#endif // NV_ARTISTTOOLS + +#include "corelib_global.h" + +class QPushButton; +class QGridLayout; +class QHBoxLayout; +class QSpacerItem; + +class DisplayMeshesPanel; +class StateViewItem : public QWidget +{ + Q_OBJECT + +public: + enum MeshViewState + { + VS_INVISIBLE = 0, + VS_VISIABLE = 1, + }; + + StateViewItem(QWidget* parent, unsigned int id, MeshViewState view = VS_VISIABLE); + + public slots: + CORELIB_EXPORT void on_btnToggleView_clicked(); + +private: + unsigned int _id; + + QHBoxLayout* _layout; + QPushButton* _btn; + QSpacerItem* _spacer; + + DisplayMeshesPanel* _parent; +}; + +class DisplayMeshesPanel : public QFrame +{ + Q_OBJECT + +public: + DisplayMeshesPanel(QWidget* parent); + + void updateValues(); + + // client code should make sure the 'id' is unique! + CORELIB_EXPORT void AddMeshItem(QString name, unsigned int id, StateViewItem::MeshViewState view = StateViewItem::VS_VISIABLE); + CORELIB_EXPORT void RemoveMeshItem(unsigned int id); + CORELIB_EXPORT void ClearItems(); + +signals: + void MeshViewSignal(unsigned int id, bool visible); + +protected: + virtual void EmitToggleSignal(unsigned int id, bool visible); + +private: + QGridLayout* _layout; + + struct ItemUI + { + StateViewItem* viewItem; + QLabel* label; + }; + + QMap<unsigned int, ItemUI> _items; + + friend class StateViewItem; +}; + +#endif // GraphicalMaterialPanel_h__ diff --git a/tools/ArtistTools/source/CoreLib/Window/DisplayPreferencesPanel.cpp b/tools/ArtistTools/source/CoreLib/Window/DisplayPreferencesPanel.cpp new file mode 100644 index 0000000..fe4b808 --- /dev/null +++ b/tools/ArtistTools/source/CoreLib/Window/DisplayPreferencesPanel.cpp @@ -0,0 +1,906 @@ +#include "DisplayPreferencesPanel.h" + +#include "AppMainWindow.h" + +#include "SimpleScene.h" +#include "GlobalSettings.h" +#include <QtWidgets/QInputDialog> +#include <QtWidgets/QMessageBox> +#include <QtWidgets/QFileDialog> + +#include "PlaylistParams.h" +//#include <Nv/Blast/NvHairCommon.h> +#include "NvParameterized.h" +#include "XmlSerializer.h" +#include "NsFileBuffer.h" +#include "NvTraits.h" +#include "NsMemoryBuffer.h" +#include "ViewerOutput.h" +#include "Settings.h" + +#include "Gamepad.h" + +const QString sPlaylistExt = "plist"; +bool bRefreshingComboBox = false; + +DisplayPreferencesPanel::DisplayPreferencesPanel(QWidget* parent) + : + QWidget(parent) + , idxCurrentPlaylist(-1) + , idxCurrentProj(-1) + , playlistProjectsDirty(false) +{ + ui.setupUi(this); + + ui.btnBackgroundTex->setIcon(QIcon(":/AppMainWindow/images/TextureEnabled_icon.png")); + ui.btnBackgroundTex->setIconSize(QSize(12,12)); + ui.btnBackgroundTexClear->setIcon(QIcon(":/AppMainWindow/images/Remove_icon.png")); + + ui.btnPlaylistsRename->setIcon(QIcon(":/AppMainWindow/images/EditWrench.png")); + ui.btnPlaylistsAdd->setIcon(QIcon(":/AppMainWindow/images/Add.png")); + ui.btnPlaylistsReload->setIcon(QIcon(":/AppMainWindow/images/refreshReload.png")); + ui.btnPlaylistsRemove->setIcon(QIcon(":/AppMainWindow/images/Remove_icon.png")); + + ui.btnPlaylistAddProj->setIcon(QIcon(":/AppMainWindow/images/Add.png")); + ui.btnPlaylistRemoveProj->setIcon(QIcon(":/AppMainWindow/images/Remove_icon.png")); + ui.btnPlaylistProjGoUp->setIcon(QIcon(":/AppMainWindow/images/Up.png")); + ui.btnPlaylistProjGoDown->setIcon(QIcon(":/AppMainWindow/images/Down.png")); + + ui.btnPlaylistsPlay->setIcon(QIcon(":/AppMainWindow/images/playlist.png")); + + //QObject::connect(ui.listWidgetPlaylist, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(playlistDoubleClicked(QListWidgetItem*))); + + ConfigSpinBox<SlideSpinBoxF>(ui.spinCameraFOV, 5.0, 180.0, 1.0); +} + +DisplayPreferencesPanel::~DisplayPreferencesPanel() +{ +} + +void DisplayPreferencesPanel::on_spinRenderPlayRateFPS_valueChanged(double v) +{ + GlobalSettings::Inst().setRenderFps((float)v); +} + +void DisplayPreferencesPanel::on_spinSimulationRateFPS_valueChanged(double v) +{ + GlobalSettings::Inst().setSimulationFps((float)v); +} + +void DisplayPreferencesPanel::on_spinCameraFOV_valueChanged(double v) +{ + GlobalSettings::Inst().m_fovAngle = v; +} + +void DisplayPreferencesPanel::on_cbAntialiasing_currentIndexChanged( int index ) +{ + GlobalSettings::Inst().m_msaaOption = index; +} + +void DisplayPreferencesPanel::on_cbUpAxis_currentIndexChanged( int index ) +{ + switch (index) + { + case 0: // y up + SimpleScene::Inst()->ResetUpDir(false); + break; + case 1: // z up + SimpleScene::Inst()->ResetUpDir(true); + break; + } + SimpleScene::Inst()->SetProjectModified(true); +} + +void DisplayPreferencesPanel::on_cbHandedness_currentIndexChanged( int index ) +{ + switch (index) + { + case 0: // rhs + SimpleScene::Inst()->ResetLhs(false); + break; + case 1: // lhs + SimpleScene::Inst()->ResetLhs(true); + break; + } + SimpleScene::Inst()->SetProjectModified(true); +} + +void DisplayPreferencesPanel::on_cbSceneUnit_currentIndexChanged( int index ) +{ + GlobalSettings::Inst().m_sceneUnitIndex = index; +} + +void DisplayPreferencesPanel::on_cbNavigationStyle_currentIndexChanged( int index ) +{ + AppMainWindow::Inst().setNavigationStyle(index); +} + +void DisplayPreferencesPanel::on_btnBackgroundTex_clicked() +{ + if (SimpleScene::Inst()->LoadBackgroundTextureFile()) + ui.btnBackgroundTex->setIcon(QIcon(":/AppMainWindow/images/TextureIsUsed_icon.png")); + else + ui.btnBackgroundTex->setIcon(QIcon(":/AppMainWindow/images/TextureEnabled_icon.png")); + + updateValues(); + SimpleScene::Inst()->SetProjectModified(true); +} + +void DisplayPreferencesPanel::on_btnBackgroundTexClear_clicked() +{ + SimpleScene::Inst()->ClearBackgroundTexture(); + ui.btnBackgroundTex->setIcon(QIcon(":/AppMainWindow/images/TextureEnabled_icon.png")); + updateValues(); +} + +void DisplayPreferencesPanel::updateValues() +{ + GlobalSettings& globalSettings = GlobalSettings::Inst(); + + ui.spinRenderPlayRateFPS->setValue(globalSettings.m_renderFps); + ui.spinSimulationRateFPS->setValue(globalSettings.m_simulationFps); + ui.cbUpAxis->setCurrentIndex(globalSettings.m_zup); + ui.cbHandedness->setCurrentIndex(globalSettings.m_lhs); + ui.spinCameraFOV->setValue(globalSettings.m_fovAngle); + ui.cbSceneUnit->setCurrentIndex(globalSettings.m_sceneUnitIndex); + ui.cbNavigationStyle->setCurrentIndex(AppMainWindow::Inst().getNavigationStyle()); + ui.cbAntialiasing->setCurrentIndex(globalSettings.m_msaaOption); + + savePlaylistProjects(); + reloadComboxBoxPlaylists(); + + //// sync playlist to gamepad + //static bool bOnce = true; + //if (bOnce) + //{ + // bOnce = false; + // assignPlayPlaylistToGamepad(0); + //} +} + +void DisplayPreferencesPanel::reloadComboxBoxPlaylists() +{ + playlistsLoader.loadPlaylistsFromMediaPath(); + // set playlist combo box + //idxCurrentPlaylist = ui.cbPlaylists->currentIndex(); + bRefreshingComboBox = true; + ui.cbPlaylists->clear(); + int count = playlistsLoader.playlists.size(); + for (int i = 0; i < count; ++i) + { + QFileInfo& fi = playlistsLoader.playlists[i]; + std::string fn = fi.fileName().toUtf8().data(); + ui.cbPlaylists->addItem(fi.fileName()); + } + bRefreshingComboBox = false; + if (idxCurrentPlaylist > count || idxCurrentPlaylist < 0) + idxCurrentPlaylist = 0; + + ui.cbPlaylists->setCurrentIndex(idxCurrentPlaylist); + + // refresh project list + reloadListboxPorjectsFromPlayist(); +} + +void DisplayPreferencesPanel::runDemoCommandline() +{ + // run demos if command line asks + static bool once = true; + if (once) + { + once = false; + std::string demoPlaylist = AppSettings::Inst().GetOptionValue("User/FurDemoPlaylist")->Value.String; + if (demoPlaylist.size() > 1) + { + QString demoList = QString(demoPlaylist.c_str()).toUpper(); + int count = playlistsLoader.playlists.size(); + for (int i = 0; i < count; ++i) + { + QFileInfo& fi = playlistsLoader.playlists[i]; + QString fname = fi.fileName().toUpper(); + if (fname == demoList) + { + idxCurrentPlaylist = i; + ui.cbPlaylists->setCurrentIndex(idxCurrentPlaylist); + playPlaylist(idxCurrentPlaylist); + return; + } + } + viewer_msg(QString("Cannot find playlist, " + demoList).toUtf8().data()); + } + } +} + +void DisplayPreferencesPanel::reloadListboxPorjectsFromPlayist() +{ + int count = playlistsLoader.getProjectsInPlaylist(idxCurrentPlaylist, playlistProjects); + refreshListboxPorjects(); +} + +void DisplayPreferencesPanel::savePlaylistProjects() +{ + if (playlistProjectsDirty) + { + playlistsLoader.saveProjectsInPlaylist(idxCurrentPlaylist, playlistProjects); + playlistProjectsDirty = false; + } +} + +void DisplayPreferencesPanel::refreshListboxPorjects() +{ + int count = playlistProjects.size(); + ui.listWidgetPlaylist->clear(); + ui.listWidgetPlaylist->setSortingEnabled(false); + ui.listWidgetPlaylist->setSelectionMode(QAbstractItemView::SingleSelection); + QStringList tips; + for (int i = 0; i < count; ++i) + { + QString fullName = playlistsLoader.convertToAbsoluteFilePath(playlistProjects[i]); + QFileInfo fi(fullName); + tips.append(fi.absoluteFilePath()); + std::string tmp = fi.absoluteFilePath().toUtf8().data(); + ui.listWidgetPlaylist->addItem(fi.fileName()); + } + ui.listWidgetPlaylist->setTips(tips); + if (idxCurrentProj > count || idxCurrentProj < 0) + { + idxCurrentProj = 0; + } + ui.listWidgetPlaylist->setCurrentRow(idxCurrentProj); +} + +void DisplayPreferencesPanel::SelectPlayList(QString& name) +{ + QString newName = name.toUpper(); + int count = playlistsLoader.playlists.size(); + for (int i = 0; i < count; ++i) + { + QFileInfo& fi = playlistsLoader.playlists[i]; + if (fi.baseName().toUpper() == newName) + { + ui.cbPlaylists->setCurrentIndex(i); + break; + } + } +} + +void DisplayPreferencesPanel::on_cbPlaylists_currentIndexChanged(int index) +{ + savePlaylistProjects(); + if (!bRefreshingComboBox) + { + idxCurrentPlaylist = ui.cbPlaylists->currentIndex(); + reloadListboxPorjectsFromPlayist(); + } +} + +void DisplayPreferencesPanel::SelectProject(QString& name) +{ + QString newName = name.toUpper(); + std::string strNew = newName.toUtf8().data(); + int count = playlistProjects.size(); + for (int i = 0; i < count; ++i) + { + QString& str = playlistProjects[i]; + //QFileInfo fi(str); + //std::string stmp = fi.absoluteFilePath().toUtf8().data(); + //if (fi.absoluteFilePath().toUpper() == newName) + if (str.toUpper() == newName) + { + ui.listWidgetPlaylist->setCurrentRow(i); + break; + } + } +} + +void DisplayPreferencesPanel::on_listWidgetPlaylist_itemSelectionChanged() +{ + idxCurrentProj = ui.listWidgetPlaylist->currentRow(); +} + +void DisplayPreferencesPanel::on_listWidgetPlaylist_itemDoubleClicked(QListWidgetItem* pItem) +{ + idxCurrentProj = ui.listWidgetPlaylist->currentRow(); + if (idxCurrentProj < 0) + return; + QString fn = playlistProjects[idxCurrentProj]; + QString fullname = PlaylistsLoader::convertToAbsoluteFilePath(fn); + AppMainWindow::Inst().openProject(fullname); + char msg[1024]; + sprintf(msg, "Blast Viewer - %s", fullname.toUtf8().data()); + AppMainWindow::Inst().setWindowTitle(msg); +} + +void DisplayPreferencesPanel::on_btnPlaylistsRename_clicked() +{ + idxCurrentPlaylist = ui.cbPlaylists->currentIndex(); + if (idxCurrentPlaylist < 0) + return; + + QFileInfo& fi = playlistsLoader.playlists[idxCurrentPlaylist]; + bool isOK = false; + QString newBaseName = QInputDialog::getText(NULL, "Rename Playlist - " + fi.fileName(), + "Input a new name for the playlist, " + fi.fileName(), QLineEdit::Normal, + fi.baseName(), &isOK); + if (isOK) + { + bool ok = playlistsLoader.rename(idxCurrentPlaylist, newBaseName); + if (ok) + { + reloadComboxBoxPlaylists(); + SelectPlayList(newBaseName); + } + else + { + QMessageBox::warning(this, "Fail to rename a playlist", + "Fail to rename a playlist. The failure could relate to name duplication or hardware failure.", + QMessageBox::Close); + } + } +} + +void DisplayPreferencesPanel::on_btnPlaylistsAdd_clicked() +{ + savePlaylistProjects(); + + bool isOK = false; + QString sInput = QInputDialog::getText(NULL, "Create New Playlist", "Input a name for the new playlist.", QLineEdit::Normal, "", &isOK); + if (isOK) + { + QString newName = sInput.trimmed(); + bool ok = playlistsLoader.add(newName); + if (ok) + { + reloadComboxBoxPlaylists(); + // select the new one + SelectPlayList(newName); + } + else + { + QMessageBox::warning(this, "Fail to add new playlist", + "Fail to add new playlist. The failure could relate to name duplication or hardware failure.", + QMessageBox::Close); + } + } +} + +void DisplayPreferencesPanel::on_btnPlaylistsReload_clicked() +{ + savePlaylistProjects(); + reloadComboxBoxPlaylists(); +} + +void DisplayPreferencesPanel::on_btnPlaylistsRemove_clicked() +{ + savePlaylistProjects(); + idxCurrentPlaylist = ui.cbPlaylists->currentIndex(); + if (idxCurrentPlaylist < 0) + return; + + bool ok = playlistsLoader.remove(idxCurrentPlaylist); + if (ok) + { + reloadComboxBoxPlaylists(); + } + else + { + QMessageBox::warning(this, "Fail to remove a playlist", + "Fail to remove a playlist. The failure could relate to hardware.", + QMessageBox::Close); + } +} + +void DisplayPreferencesPanel::on_btnPlaylistAddProj_clicked() +{ + static QString lastPath; + if (lastPath.size() < 1) + { + lastPath = PlaylistsLoader::mediaPath; + } + QString fileNameInput = QFileDialog::getOpenFileName(this, "Open Hair Project File", lastPath, "Hair Project File (*.furproj)"); + if (!QFile::exists(fileNameInput)) + return; + std::string tmp = fileNameInput.toUtf8().data(); + QString fileName = PlaylistsLoader::convertToSaveingFilePath(fileNameInput); + if (fileName.size() < 1) + { + return; + } + lastPath = QFileInfo(fileNameInput).absolutePath(); + std::string tmp2 = fileName.toUtf8().data(); + playlistProjects.append(fileName); + refreshListboxPorjects(); + //QFileInfo fi(fileName); + SelectProject(fileName);// fi.absoluteFilePath()); + playlistProjectsDirty = true; +} + +void DisplayPreferencesPanel::on_btnPlaylistProjGoUp_clicked() +{ + idxCurrentProj = ui.listWidgetPlaylist->currentRow(); + if (idxCurrentProj <= 0) + return; + + QString tmp = playlistProjects[idxCurrentProj]; + playlistProjects[idxCurrentProj] = playlistProjects[idxCurrentProj - 1]; + playlistProjects[idxCurrentProj - 1] = tmp; + + refreshListboxPorjects(); + SelectProject(tmp); + + playlistProjectsDirty = true; +} + +void DisplayPreferencesPanel::on_btnPlaylistProjGoDown_clicked() +{ + int count = playlistProjects.size(); + idxCurrentProj = ui.listWidgetPlaylist->currentRow(); + if (idxCurrentProj < 0 || idxCurrentProj>= count -1) + return; + + QString tmp = playlistProjects[idxCurrentProj]; + playlistProjects[idxCurrentProj] = playlistProjects[idxCurrentProj + 1]; + playlistProjects[idxCurrentProj + 1] = tmp; + + refreshListboxPorjects(); + SelectProject(tmp); + + playlistProjectsDirty = true; +} + +void DisplayPreferencesPanel::on_btnPlaylistRemoveProj_clicked() +{ + int count = playlistProjects.size(); + idxCurrentProj = ui.listWidgetPlaylist->currentRow(); + if (idxCurrentProj < 0 || idxCurrentProj >= count) + { + return; + } + + playlistProjects.removeAt(idxCurrentProj); + + refreshListboxPorjects(); + playlistProjectsDirty = true; +} + +void DisplayPreferencesPanel::assignPlayPlaylistToGamepad(int idx) +{ + if (idx == -1) + idx = idxCurrentPlaylist; + int count = playlistsLoader.getProjectsInPlaylist(idx, playlistProjects); + if (count < 1) + { + viewer_msg("Playlist is empty."); + return; + } + QList<QString> files; + for (int i = 0; i < count; ++i) + { + QString fname = PlaylistsLoader::convertToAbsoluteFilePath(playlistProjects[i]); + if (fname.size() > 0) + { + files.append(fname); + } + } + + Gamepad& theGamepad = Gamepad::Instance(); + theGamepad.SetDemoProjects(files); +} + +void DisplayPreferencesPanel::playPlaylist(int idx) +{ + assignPlayPlaylistToGamepad(idx); + Gamepad& theGamepad = Gamepad::Instance(); + theGamepad.SetDemoMode(true); +} + +void DisplayPreferencesPanel::on_btnPlaylistsPlay_clicked() +{ + savePlaylistProjects(); + + idxCurrentPlaylist = ui.cbPlaylists->currentIndex(); + if (idxCurrentPlaylist < 0) + { + viewer_msg("No available playlists."); + return; + } + playPlaylist(idxCurrentPlaylist); +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////// +using namespace nvidia; +using namespace nvidia::parameterized; + +QString PlaylistsLoader::projectPath; +QString PlaylistsLoader::mediaPath; + +#include "FoundationHolder.h" + +struct PlaylistParamsContext +{ + //nvidia::NvFoundation* mFoundation; + NvParameterized::Traits* mTraits; + PlaylistParamsFactory* mPlaylistParamsFactory; +}; + +PlaylistsLoader::PlaylistsLoader() + :pContext(nullptr) +{ +} + +PlaylistsLoader::~PlaylistsLoader() +{ +} + +void PlaylistsLoader::CreatePlaylistParamsContext() +{ + if (pContext) + return; + + PlaylistParamsContext* context = new PlaylistParamsContext; + //context->mFoundation = FoundationHolder::GetFoundation(); + FoundationHolder::GetFoundation(); + //assert(context->mFoundation != NV_NULL); + + context->mTraits = NvParameterized::createTraits(); + context->mPlaylistParamsFactory = new PlaylistParamsFactory; + context->mTraits->registerFactory(*context->mPlaylistParamsFactory); + pContext = context; +} + +void PlaylistsLoader::ReleasePlaylistParamsContext() +{ + if (pContext) + { + pContext->mTraits->release(); + delete pContext->mPlaylistParamsFactory; + delete pContext; + pContext = nullptr; + } +} + +void PlaylistsLoader::loadPlaylistsFromMediaPath() +{ + if (projectPath.isEmpty()) + { + QString appDir = qApp->applicationDirPath(); + QDir dirTmp(appDir); + if (dirTmp.cd("./media/playlists")) + projectPath = dirTmp.absolutePath(); + else if (dirTmp.cd("../media/playlists")) + projectPath = dirTmp.absolutePath(); + else if (dirTmp.cd("../../media/playlists")) + projectPath = dirTmp.absolutePath(); + else if (dirTmp.cd("../../media")) + { + bool ok = dirTmp.mkdir("playlists"); + if (dirTmp.cd("playlists")) + { + projectPath = dirTmp.absolutePath(); + } + } + if (!projectPath.isEmpty()) + { + if (dirTmp.cd("..")) + { + mediaPath = dirTmp.absolutePath(); + } + else + { + mediaPath = projectPath + "/.."; + } + } + } + if (!projectPath.isEmpty()) + { + playlists.clear(); + + QStringList filters; + filters << (QString("*.") + sPlaylistExt); + QDirIterator dir_iterator(projectPath, filters, QDir::Files | QDir::NoSymLinks, QDirIterator::NoIteratorFlags); //QDirIterator::Subdirectories + while (dir_iterator.hasNext()) + { + dir_iterator.next(); + QFileInfo file_info = dir_iterator.fileInfo(); + std::string absolute_file_path = file_info.absoluteFilePath().toUtf8().data(); + playlists.append(file_info); + } + } +} + +bool PlaylistsLoader::rename(int idx, QString& newBaseName) +{ + int count = playlists.size(); + if (idx >= 0 && idx < count) + { + QFileInfo& finfo = playlists[idx]; + QString fn = finfo.baseName().toUpper(); + QString fnNew = newBaseName.toUpper(); + if (fn != fnNew) + { + QFileInfo nfi(projectPath, newBaseName + "." + sPlaylistExt); + QString fullNewName = nfi.absoluteFilePath(); + std::string fntmp = fullNewName.toUtf8().data(); + bool exist = QFile::exists(fullNewName); + if (exist) + { + return false; + } + bool ok = QFile::rename(finfo.absoluteFilePath(), fullNewName); + if (ok) + { + finfo.setFile(fullNewName); + exist = QFile::exists(fullNewName); + if (!exist) + { + return false; + } + } + return ok; + } + return true; + } + return false; +} + +bool PlaylistsLoader::remove(int idx) +{ + int count = playlists.size(); + if (idx >= 0 && idx < count) + { + QFileInfo& finfo = playlists[idx]; + std::string fn = finfo.fileName().toUtf8().data(); + bool ok = QFile::remove(finfo.absoluteFilePath()); + if (ok) + { + playlists.removeAt(idx); + } + return ok; + } + return false; +} + +bool PlaylistsLoader::saveProjectsInPlaylist(int idx, QList<QString>& projects) +{ + int count = playlists.size(); + if (idx < 0 || idx >= count) + return false; + + CreatePlaylistParamsContext(); + if (!pContext) + return false; + + std::string tempFilePath = playlists[idx].absoluteFilePath().toUtf8().data(); + NvParameterized::XmlSerializer serializer(pContext->mTraits); + NvFileBuf* stream = new NvFileBufferBase(tempFilePath.c_str(), NvFileBuf::OPEN_WRITE_ONLY); + if (!stream || !stream->isOpen()) + { + // file open error + if (stream) stream->release(); + return false; + } + NvParameterized::Traits* traits = pContext->mTraits; + int numObjects = 0; + const int kMaxObjects = 1; + NvParameterized::Interface* objects[kMaxObjects]; + + PlaylistParams* params = new PlaylistParams(traits); + objects[numObjects++] = params; + NvParameterized::Interface* iface = static_cast<NvParameterized::Interface*>(params); + + if (1) + { + nvidia::parameterized::PlaylistParams* params = static_cast<nvidia::parameterized::PlaylistParams*>(iface); + nvidia::parameterized::PlaylistParamsNS::ParametersStruct& targetDesc = params->parameters(); + + NvParameterized::Handle handle(iface); + if (iface->getParameterHandle("furprojFilePaths", handle) == NvParameterized::ERROR_NONE) + { + int num = projects.size(); + + std::vector<std::string> strArray; + const char** strOutput = new const char*[num]; + + for (int i = 0; i < num; i++) + { + std::string proj = projects[i].toUtf8().data(); + strArray.push_back(proj); + strOutput[i] = strArray[i].c_str(); + } + + handle.resizeArray(num); + handle.setParamStringArray(strOutput, num); + + delete[] strOutput; + } + } + + NV_ASSERT(numObjects <= kMaxObjects); + NvParameterized::Serializer::ErrorType serError = NvParameterized::Serializer::ERROR_NONE; + bool isUpdate = false; + serError = serializer.serialize(*stream, (const NvParameterized::Interface**)&objects[0], numObjects, isUpdate); + for (int idx = 0; idx < numObjects; ++idx) + { + delete objects[idx]; + } + stream->release(); + ReleasePlaylistParamsContext(); + return true; +} + +QString PlaylistsLoader::convertToAbsoluteFilePath(QString& filePath) +{ + QString fname; + bool bCanBeRelativePath = false; + bool bAbsPath = (filePath.indexOf(':') >= 0); + if (bAbsPath) + { + if (QFile::exists(filePath)) + { + fname = filePath; + } + else + { + viewer_msg(QString(filePath + " does not exist.").toUtf8().data()); + } + std::string tmp2 = fname.toUtf8().data(); + return fname; + } + else + { + QFileInfo fi(mediaPath + "/" + filePath); + fname = fi.absoluteFilePath(); + if (!QFile::exists(fname)) + { + viewer_msg(QString(filePath + " does not exist.").toUtf8().data()); + fname = ""; + } + std::string tmp2 = fname.toUtf8().data(); + return fname; + } +} + +QString PlaylistsLoader::convertToSaveingFilePath(QString& filePath) +{ + QString fname; + bool bCanBeRelativePath = false; + bool bAbsPath = (filePath.indexOf(':') >= 0); + if (bAbsPath) + { + if (QFile::exists(filePath)) + { + QFileInfo fi(filePath); + int pos = fi.absoluteFilePath().indexOf(mediaPath, Qt::CaseInsensitive); + if (pos >= 0) + { + // convert to relative path + fname = filePath.right(filePath.size() - (pos + mediaPath.size() + 1)); + } + else + { + fname = fi.absoluteFilePath(); + } + } + else + { + fname = ""; + viewer_msg(QString(filePath + " does not exist.").toUtf8().data()); + } + std::string tmp = fname.toUtf8().data(); + return fname; + } + // do more try + QString tag = "media"; + int pos = filePath.indexOf(tag, Qt::CaseInsensitive); + if (pos >= 0) + { + fname = filePath.right(filePath.size() - (pos + tag.size() + 1)); + } + else + { + fname = filePath; + } + QFileInfo fi(mediaPath + "/" + fname); + std::string tmp = fi.absoluteFilePath().toUtf8().data(); + if (!QFile::exists(fi.absoluteFilePath())) + { + viewer_msg(QString(filePath + " does not exist.").toUtf8().data()); + fname = ""; + } + std::string tmp2 = fname.toUtf8().data(); + return fname; +} + +int PlaylistsLoader::getProjectsInPlaylist(int idx, QList<QString>& projects) +{ + projects.clear(); + + int count = playlists.size(); + if (idx < 0 || idx >= count) + return 0; + + CreatePlaylistParamsContext(); + if (!pContext) + return 0; + + std::string tempFilePath = playlists[idx].absoluteFilePath().toUtf8().data(); + NvFileBuf* stream = new NvFileBufferBase(tempFilePath.c_str(), NvFileBuf::OPEN_READ_ONLY); + if (!stream || !stream->isOpen()) + { + // file open error + if (stream) + stream->release(); + return 0; + } + + NvParameterized::Serializer::DeserializedData data; + NvParameterized::Serializer::ErrorType serError = NvParameterized::Serializer::ERROR_NONE; + NvParameterized::XmlSerializer serializer(pContext->mTraits); + bool isUpdated = false; + serError = serializer.deserialize(*stream, data, isUpdated); + if (data.size() < 1) + { + if (stream) + stream->release(); + return 0; + } + + for (int idx = 0; idx < (int)data.size(); ++idx) + { + NvParameterized::Interface* iface = data[idx]; + if (::strcmp(iface->className(), PlaylistParams::staticClassName()) == 0) + { + nvidia::parameterized::PlaylistParams* params = static_cast<nvidia::parameterized::PlaylistParams*>(iface); + nvidia::parameterized::PlaylistParamsNS::ParametersStruct& srcDesc = params->parameters(); + NvParameterized::Handle handle(iface); + if (iface->getParameterHandle("furprojFilePaths", handle) == NvParameterized::ERROR_NONE) + { + int arraySize; + handle.getArraySize(arraySize); + char** strArray = new char*[arraySize]; + handle.getParamStringArray(strArray, arraySize); + for (int idx = 0; idx < arraySize; ++idx) + { + QString fileName = PlaylistsLoader::convertToSaveingFilePath(QString(strArray[idx])); + if (fileName.size() > 0) + { + std::string tmp = fileName.toUtf8().data(); + projects.append(fileName); + } + } + delete[] strArray; + } + } + } + stream->release(); + ReleasePlaylistParamsContext(); + return projects.size(); +} + +bool PlaylistsLoader::add(QString& name) +{ + int count = playlists.size(); + for (int i = 0; i < count; ++i) + { + QFileInfo& fi = playlists[i]; + if (fi.baseName().toUpper() == name.toUpper()) + { + return false; + } + } + QFileInfo nfi(projectPath, name + "." + sPlaylistExt); + QFile newFile(nfi.absoluteFilePath()); + if (newFile.exists()) + { + return false; + } + newFile.open(QIODevice::WriteOnly); + newFile.close(); + bool exist = QFile::exists(nfi.absoluteFilePath()); + if (!exist) + { + return false; + } + playlists.append(nfi); + return true; +}
\ No newline at end of file diff --git a/tools/ArtistTools/source/CoreLib/Window/DisplayPreferencesPanel.h b/tools/ArtistTools/source/CoreLib/Window/DisplayPreferencesPanel.h new file mode 100644 index 0000000..eb57b12 --- /dev/null +++ b/tools/ArtistTools/source/CoreLib/Window/DisplayPreferencesPanel.h @@ -0,0 +1,100 @@ +#ifndef DisplayPreferencesPanel_h__ +#define DisplayPreferencesPanel_h__ + +#include <QtWidgets/QWidget> +#include <QtCore/QDir> +#include <QtCore/QDirIterator> +#include "TipListView.h" +#include "ui_DisplayPreferencesPanel.h" + +#include "corelib_global.h" + +struct PlaylistParamsContext; + +class PlaylistsLoader +{ +public: + PlaylistsLoader(); + ~PlaylistsLoader(); + + void loadPlaylistsFromMediaPath(); + bool rename(int idx, QString& newName); + bool remove(int idx); + bool add(QString& name); + bool saveProjectsInPlaylist(int idx, QList<QString>& projects); + int getProjectsInPlaylist(int idx, QList<QString>& projects); + + static QString convertToSaveingFilePath(QString& filePath); + static QString convertToAbsoluteFilePath(QString& filePath); + + QList<QFileInfo> playlists; + static QString projectPath; + static QString mediaPath; + +private: + void CreatePlaylistParamsContext(); + void ReleasePlaylistParamsContext(); + PlaylistParamsContext* pContext; +}; + +class DisplayPreferencesPanel : public QWidget +{ + Q_OBJECT + +public: + DisplayPreferencesPanel(QWidget* parent); + ~DisplayPreferencesPanel(); + + public: + void updateValues(); + + public slots: + CORELIB_EXPORT void on_spinRenderPlayRateFPS_valueChanged(double v); + CORELIB_EXPORT void on_spinSimulationRateFPS_valueChanged(double v); + CORELIB_EXPORT void on_spinCameraFOV_valueChanged(double v); + + CORELIB_EXPORT void on_cbSceneUnit_currentIndexChanged(int index); + CORELIB_EXPORT void on_cbAntialiasing_currentIndexChanged(int index); + CORELIB_EXPORT void on_cbUpAxis_currentIndexChanged(int index); + CORELIB_EXPORT void on_cbHandedness_currentIndexChanged(int index); + CORELIB_EXPORT void on_cbNavigationStyle_currentIndexChanged(int index); + CORELIB_EXPORT void on_btnBackgroundTex_clicked(); + CORELIB_EXPORT void on_btnBackgroundTexClear_clicked(); + + CORELIB_EXPORT void on_cbPlaylists_currentIndexChanged(int index); + CORELIB_EXPORT void SelectPlayList(QString& name); + CORELIB_EXPORT void on_listWidgetPlaylist_itemSelectionChanged(); + CORELIB_EXPORT void on_listWidgetPlaylist_itemDoubleClicked(QListWidgetItem* pItem); + CORELIB_EXPORT void SelectProject(QString& name); + + CORELIB_EXPORT void on_btnPlaylistsRename_clicked(); + CORELIB_EXPORT void on_btnPlaylistsAdd_clicked(); + CORELIB_EXPORT void on_btnPlaylistsReload_clicked(); + CORELIB_EXPORT void on_btnPlaylistsRemove_clicked(); + + CORELIB_EXPORT void on_btnPlaylistAddProj_clicked(); + CORELIB_EXPORT void on_btnPlaylistProjGoUp_clicked(); + CORELIB_EXPORT void on_btnPlaylistProjGoDown_clicked(); + CORELIB_EXPORT void on_btnPlaylistRemoveProj_clicked(); + + CORELIB_EXPORT void on_btnPlaylistsPlay_clicked(); + CORELIB_EXPORT void assignPlayPlaylistToGamepad(int idx = -1); + CORELIB_EXPORT void playPlaylist(int idx); + + CORELIB_EXPORT void reloadComboxBoxPlaylists(); + CORELIB_EXPORT void refreshListboxPorjects(); + CORELIB_EXPORT void reloadListboxPorjectsFromPlayist(); + CORELIB_EXPORT void savePlaylistProjects(); + + CORELIB_EXPORT void runDemoCommandline(); + +private: + Ui::DisplayPreferencesPanel ui; + PlaylistsLoader playlistsLoader; + QList<QString> playlistProjects; + bool playlistProjectsDirty; + int idxCurrentPlaylist; + int idxCurrentProj; +}; + +#endif // DisplayScene_h__ diff --git a/tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.cpp b/tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.cpp new file mode 100644 index 0000000..b118b6b --- /dev/null +++ b/tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.cpp @@ -0,0 +1,93 @@ +#include "DisplayScenePanel.h" + +#include "AppMainWindow.h" + +#include "SimpleScene.h" +#include "GlobalSettings.h" + +DisplayScenePanel::DisplayScenePanel(QWidget* parent) + : + QWidget(parent) +{ + ui.setupUi(this); +} + +void DisplayScenePanel::on_btnVisualizeWind_stateChanged(int state) +{ + GlobalSettings::Inst().m_visualizeWind = state; +} + +void DisplayScenePanel::on_btnShowGrid_stateChanged(int state) +{ + GlobalSettings::Inst().m_showGrid = state; +} + +void DisplayScenePanel::on_btnShowAxis_stateChanged(int state) +{ + GlobalSettings::Inst().m_showAxis = state; +} + +void DisplayScenePanel::on_btnShowWireframe_stateChanged(int state) +{ + GlobalSettings::Inst().m_showWireframe = state; +} + +void DisplayScenePanel::on_btnUseLighting_stateChanged(int state) +{ + GlobalSettings::Inst().m_useLighting = state; +} + +void DisplayScenePanel::on_cbRenderType_currentIndexChanged(int index) +{ + GlobalSettings::Inst().m_renderStyle = index; +} + +void DisplayScenePanel::on_btnShowHUD_stateChanged(int state) +{ + GlobalSettings::Inst().m_showHUD = state; +} + +void DisplayScenePanel::on_btnComputeStats_stateChanged(int state) +{ + GlobalSettings::Inst().m_computeStatistics = state; +} + +void DisplayScenePanel::on_btnComputeProfile_stateChanged(int state) +{ + GlobalSettings::Inst().m_computeProfile = state; +} + +void DisplayScenePanel::on_btnShowGraphicsMesh_stateChanged(int state) +{ + GlobalSettings::Inst().m_showGraphicsMesh = state; +} + +void DisplayScenePanel::on_btnShowSkinnedOnly_stateChanged(int state) +{ + GlobalSettings::Inst().m_showSkinnedMeshOnly = state; + AppMainWindow::Inst().updateUI(); +} + +void DisplayScenePanel::on_btnSkinningDQ_stateChanged(int state) +{ + GlobalSettings::Inst().m_useDQ = state; +} + +void DisplayScenePanel::on_checkBoxGizmoWithLocal_stateChanged(int state) +{ + AppMainWindow::Inst().m_bGizmoWithLocal = state; +} + +void DisplayScenePanel::updateValues() +{ + GlobalSettings& globalSettings = GlobalSettings::Inst(); + + ui.btnShowGrid->setChecked(globalSettings.m_showGrid); + ui.btnShowAxis->setChecked(globalSettings.m_showAxis); + ui.cbRenderType->setCurrentIndex(globalSettings.m_renderStyle); + ui.btnShowHUD->setChecked(globalSettings.m_showHUD); + ui.btnComputeStats->setChecked(globalSettings.m_computeStatistics); + ui.btnUseLighting->setChecked(globalSettings.m_useLighting); + ui.btnShowGraphicsMesh->setChecked( globalSettings.m_showGraphicsMesh); + ui.btnShowSkinnedOnly->setChecked( globalSettings.m_showSkinnedMeshOnly); +} diff --git a/tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.h b/tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.h new file mode 100644 index 0000000..6614eca --- /dev/null +++ b/tools/ArtistTools/source/CoreLib/Window/DisplayScenePanel.h @@ -0,0 +1,39 @@ +#ifndef DisplayScenePanel_h__ +#define DisplayScenePanel_h__ + +#include <QtWidgets/QWidget> +#include "ui_DisplayScenePanel.h" + +#include "corelib_global.h" + +class DisplayScenePanel : public QWidget +{ + Q_OBJECT + +public: + DisplayScenePanel(QWidget* parent); + + public: + void updateValues(); + + public slots: + CORELIB_EXPORT void on_btnVisualizeWind_stateChanged(int state); + CORELIB_EXPORT void on_btnShowGrid_stateChanged(int state); + CORELIB_EXPORT void on_btnShowAxis_stateChanged(int state); + CORELIB_EXPORT void on_cbRenderType_currentIndexChanged(int index); + CORELIB_EXPORT void on_btnShowWireframe_stateChanged(int state); + CORELIB_EXPORT void on_btnShowHUD_stateChanged(int state); + CORELIB_EXPORT void on_btnComputeStats_stateChanged(int state); + CORELIB_EXPORT void on_btnComputeProfile_stateChanged(int state); + CORELIB_EXPORT void on_btnUseLighting_stateChanged(int state); + CORELIB_EXPORT void on_btnShowGraphicsMesh_stateChanged(int state); + CORELIB_EXPORT void on_btnShowSkinnedOnly_stateChanged(int state); + CORELIB_EXPORT void on_btnSkinningDQ_stateChanged(int state); + CORELIB_EXPORT void on_checkBoxGizmoWithLocal_stateChanged(int state); + + +private: + Ui::DisplayScenePanel ui; +}; + +#endif // DisplayScene_h__ diff --git a/tools/ArtistTools/source/CoreLib/Window/ExpandablePanel.cpp b/tools/ArtistTools/source/CoreLib/Window/ExpandablePanel.cpp new file mode 100644 index 0000000..0fe96d1 --- /dev/null +++ b/tools/ArtistTools/source/CoreLib/Window/ExpandablePanel.cpp @@ -0,0 +1,190 @@ +#include <QtWidgets/QLabel> +#include <QtGui/QImage> +#include <QtWidgets/QVBoxLayout> +#include <QtGui/QMouseEvent> +#include <QtGui/QPaintEvent> +#include <QtGui/QPainter> +#include <QtGui/QPainterPath> +#include "ExpandablePanel.h" +#include "Nv.h" + +static QImage S_TriangleRight; +static QImage S_TriangleDown; + +void InitTriangleResources(int w, int h) +{ + S_TriangleRight = QImage(w, h, QImage::Format_ARGB32); + S_TriangleDown = QImage(w, h, QImage::Format_ARGB32); + + S_TriangleRight.fill(QColor(0, 0, 0, 0)); + S_TriangleDown.fill(QColor(0, 0, 0, 0)); + + QPainter painter(&S_TriangleRight); + painter.setRenderHints(QPainter::Antialiasing,true); + + QPainterPath path; + path.moveTo(0, 0); + path.lineTo(w, h>>1); + path.lineTo(0, h); + path.lineTo(0, 0); + painter.setPen(Qt::NoPen); + painter.fillPath(path, QBrush(QColor(50, 50, 50))); + + // a painter cannot switch device? + QPainter painter2(&S_TriangleDown); + painter2.setRenderHint(QPainter::Antialiasing,true); + path = QPainterPath(); // trick to clear up a path + path.moveTo(0, 0); + path.lineTo(w, 0); + path.lineTo(w>>1, h); + path.lineTo(0, 0); + painter2.setPen(Qt::NoPen); + painter2.fillPath(path, QBrush(QColor(50, 50, 50))); +} + +class TitleLabelImpl : public TitleLabel +{ + enum + { + IMAGE_H = 10, + IMAGE_W = 10, + FIXED_H = 20, + }; + +public: + TitleLabelImpl(QWidget* parent, bool collapsed) + : TitleLabel(parent) + , _collapsed(collapsed) + { + QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(this->sizePolicy().hasHeightForWidth()); + this->setSizePolicy(sizePolicy); + this->setMinimumSize(QSize(0, FIXED_H)); + this->setMaximumSize(QSize(16777215, FIXED_H)); + //this->setStyleSheet(QString::fromUtf8("background:rgb(219,219,219);border:1px solid rgb(185,185,185);")); + this->setFrameShape(QFrame::NoFrame); + this->setFrameShadow(QFrame::Plain); + this->setTextFormat(Qt::AutoText); + this->setScaledContents(false); + this->setAlignment(Qt::AlignCenter); + + if(S_TriangleDown.isNull() || S_TriangleRight.isNull()) + InitTriangleResources(IMAGE_W, IMAGE_H); + } + + void paintEvent(QPaintEvent * e) + { + QLabel::paintEvent(e); + + QPainter painter(this); + painter.setRenderHints(QPainter::Antialiasing,true); + + const int L = 10; + const int T = (FIXED_H - IMAGE_H)/2; + QRect rc(L, T, IMAGE_W, IMAGE_H); + + // [later] transform the painter should also work; + // but i don't get the expected results, so have to use two images + if(_collapsed) + painter.drawImage(rc, S_TriangleRight); + else + painter.drawImage(rc, S_TriangleDown); + + } + + bool Collapsed() {return _collapsed;} + void SetCollapsed(bool b) + { + _collapsed = b; + this->update(); + } + +protected: + virtual void mousePressEvent(QMouseEvent* e) + { + if(e->buttons() == Qt::LeftButton) + { + _collapsed = !_collapsed; + this->update(); + emit LPressSignal(); + } + } + +private: + bool _collapsed; +}; + +ExpandablePanel::ExpandablePanel(QWidget* parent, bool collapsed) + : QFrame(parent) + , _pContent(NV_NULL) +{ + //_pContent = new QWidget(this); + Init(collapsed); +} + +ExpandablePanel::ExpandablePanel( QWidget* content, QWidget* parent /*= 0*/ ) + : QFrame(parent) + , _pContent(content) +{ + Init(); +} + +ExpandablePanel::~ExpandablePanel() +{ + +} + +void ExpandablePanel::SetCollapsed(bool b) +{ + if (_pTitle) + _pTitle->SetCollapsed(b); +} + +void ExpandablePanel::Init(bool collapsed) +{ + setAutoFillBackground(true); + setFrameShape(QFrame::StyledPanel); + setFrameShadow(QFrame::Sunken); + _pMainLayout = new QVBoxLayout(this); + _pMainLayout->setSpacing(2); + _pMainLayout->setContentsMargins(0, 0, 0, 0); + _pMainLayout->setObjectName(QString::fromUtf8("mainLayout")); + + _pTitle = new TitleLabelImpl(this, collapsed); + _pTitle->setText("TitleLabel"); + _pMainLayout->addWidget(_pTitle); + + connect(_pTitle, SIGNAL(LPressSignal()), this, SLOT(TitlePress())); + + if(_pContent) + _pMainLayout->addWidget(_pContent); +} + +void ExpandablePanel::SetTitle( const QString& title ) +{ + _pTitle->setText(title); +} + +void ExpandablePanel::TitlePress() +{ + if(_pTitle->Collapsed()) + { + _pContent->hide(); + } + else // expanded + { + _pContent->show(); + } +} + +void ExpandablePanel::AddContent( QWidget* content ) +{ + // only support one widget as content right now + if (_pContent != NV_NULL) return; + + _pMainLayout->addWidget(content); + _pContent = content; +} + diff --git a/tools/ArtistTools/source/CoreLib/Window/ExpandablePanel.h b/tools/ArtistTools/source/CoreLib/Window/ExpandablePanel.h new file mode 100644 index 0000000..ba3018d --- /dev/null +++ b/tools/ArtistTools/source/CoreLib/Window/ExpandablePanel.h @@ -0,0 +1,51 @@ +#ifndef ExpandablePanel_h__ +#define ExpandablePanel_h__ + +#include <QtWidgets/QWidget> +#include <QtWidgets/QFrame> +#include <QtWidgets/QLabel> + +#include "corelib_global.h" + +class TitleLabelImpl; +class QString; +class QVBoxLayout; + +class TitleLabel : public QLabel +{ + Q_OBJECT + +public: + TitleLabel(QWidget* parent):QLabel(parent){} + +signals: + void LPressSignal(); +}; + +class ExpandablePanel : public QFrame +{ + Q_OBJECT + +public: + CORELIB_EXPORT explicit ExpandablePanel(QWidget* parent, bool collapsed = false); + explicit ExpandablePanel(QWidget* content, QWidget* parent); + virtual ~ExpandablePanel(); + + CORELIB_EXPORT void SetTitle(const QString& title); + void SetCollapsed(bool b); + QWidget* Content() {return _pContent;} + CORELIB_EXPORT void AddContent(QWidget* content); + +public slots: +CORELIB_EXPORT void TitlePress(); + +private: + void Init(bool collapsed = false); + +private: + QVBoxLayout* _pMainLayout; + TitleLabelImpl* _pTitle; + QWidget* _pContent; +}; + +#endif // ExpandablePanel_h__ diff --git a/tools/ArtistTools/source/CoreLib/Window/OutputWindow.cpp b/tools/ArtistTools/source/CoreLib/Window/OutputWindow.cpp new file mode 100644 index 0000000..08867e3 --- /dev/null +++ b/tools/ArtistTools/source/CoreLib/Window/OutputWindow.cpp @@ -0,0 +1,22 @@ +#include "AppMainWindow.h" +#include "OutputWindow.h" + +#include <QtGUI/QContextMenuEvent> + +OutputWindow::OutputWindow(QWidget* parent) + : + QTextBrowser(parent) +{ + ui.setupUi(this); +} + +void OutputWindow::contextMenuEvent(QContextMenuEvent *event) +{ + QMenu *menu = createStandardContextMenu(); + + QAction* act = new QAction("&Clear All", this); + connect(act, SIGNAL(triggered()), this, SLOT(clear())); + menu->addAction(act); + menu->exec(event->globalPos()); + delete menu; +} diff --git a/tools/ArtistTools/source/CoreLib/Window/OutputWindow.h b/tools/ArtistTools/source/CoreLib/Window/OutputWindow.h new file mode 100644 index 0000000..5d19bb6 --- /dev/null +++ b/tools/ArtistTools/source/CoreLib/Window/OutputWindow.h @@ -0,0 +1,22 @@ +#ifndef OutputWindow_h__ +#define OutputWindow_h__ + +#include <QtWidgets/QTextBrowser> +#include "ui_OutputWindow.h" + +#include "UIGlobal.h" + +class CORELIB_EXPORT OutputWindow : public QTextBrowser +{ + Q_OBJECT + +public: + OutputWindow(QWidget* parent); + + void contextMenuEvent(QContextMenuEvent *event); + +private: + Ui::OutputWindow ui; +}; + +#endif // DisplayScene_h__ diff --git a/tools/ArtistTools/source/CoreLib/Window/SlideSpinBox.cpp b/tools/ArtistTools/source/CoreLib/Window/SlideSpinBox.cpp new file mode 100644 index 0000000..b127f1c --- /dev/null +++ b/tools/ArtistTools/source/CoreLib/Window/SlideSpinBox.cpp @@ -0,0 +1,17 @@ +#include "SlideSpinBox.h" + +void SlideSpinBoxSlots::timeout() +{ + //qDebug("%s", __FUNCTION__); + this->_cb->on_timeout(); +} + +void ConfigSpinBoxInt(SlideSpinBoxInt* spinBox, int minv, int maxv, int step) +{ + spinBox->blockSignals(true); + spinBox->setRange(minv, maxv); + spinBox->setSingleStep(step); + spinBox->AutoConfigDragRange(); + spinBox->setKeyboardTracking(false); + spinBox->blockSignals(false); +} diff --git a/tools/ArtistTools/source/CoreLib/Window/SlideSpinBox.h b/tools/ArtistTools/source/CoreLib/Window/SlideSpinBox.h new file mode 100644 index 0000000..eeb7626 --- /dev/null +++ b/tools/ArtistTools/source/CoreLib/Window/SlideSpinBox.h @@ -0,0 +1,284 @@ +#ifndef SlideSpinBox_h__ +#define SlideSpinBox_h__ + +#include <QtWidgets/QStyle> +#include <QtWidgets/QStyleOptionSpinBox> +#include <QtWidgets/QAbstractSpinBox> +#include <QtGui/QMouseEvent> +#include <QtCore/QTimer> +#include <QtWidgets/QDoubleSpinBox> +#include <QtWidgets/QSpinBox> + +#include "corelib_global.h" + +/* + A Lesson: never use a template to sub-class QWidgets! + Qt doesn't moc template widget classes; + So we have to use a specific 'slots-callback' pair to let the moc system work... + */ +class SlideSpinBoxCallback +{ +public: + virtual void on_timeout() = 0; +}; + +class SlideSpinBoxSlots : public QObject +{ + Q_OBJECT + +public: + SlideSpinBoxSlots(SlideSpinBoxCallback* cb) + : _cb (cb) + {} + + public slots: + CORELIB_EXPORT void timeout(); + +private: + SlideSpinBoxCallback* _cb; +}; + +template<typename SpinWidget, typename ValueType> +class SlideSpinBox : public SpinWidget, public SlideSpinBoxCallback +{ + +public: + void on_timeout() + { + //qDebug("%s", __FUNCTION__); + EmitDragValueChanged(); + } + +public: + typedef ValueType value_type; + + SlideSpinBox(QWidget* parent = 0) + : SpinWidget(parent) + , _dragRange(DEFAULT_DRAG_RANGE) + { + setAccelerated(true); + + ResetCustState(); + + _pSlots = new SlideSpinBoxSlots(this); + + _dragTimer.setParent(this); + _dragTimer.setInterval(DRAG_TIMER_INTERVAL); + _dragTimer.setSingleShot(true); + connect(&_dragTimer, SIGNAL(timeout()), _pSlots, SLOT(timeout())); + } + + ~SlideSpinBox() + { + delete _pSlots; + } + + void SetDragRange(int range) + { + if(range < MIN_DRAG_RANGE) + range = MIN_DRAG_RANGE; + else if(range > MAX_DRAG_RANGE) + range = MAX_DRAG_RANGE; + + _dragRange = range; + } + + void AutoConfigDragRange() + { + ValueType minv = this->minimum(); + ValueType maxv = this->maximum(); + + double vrange = maxv - minv; + double step = 1.0; + + if(vrange <= 1.0) + { + step = 0.01; + } + else if(vrange <= 10.0) + { + step = 0.1; + } + + double pixelError = 2.0; + double dragRange = vrange * pixelError / step; + + SetDragRange((int)dragRange); + } + +protected: + void mouseMoveEvent ( QMouseEvent * event ) + { + if(!_dragBegin) + { + QAbstractSpinBox::mouseMoveEvent(event); + return; + } + + if(!_dragging) + { + _dragging = true; + _cursor = this->cursor(); + + this->setCursor(Qt::SizeVerCursor); + } + + //if(_dragging) + //{ + // _dragTimer.start(); // always restart, we only need the timeout event; + //} + + event->accept(); + DragValue(event->pos()); + } + + void mousePressEvent( QMouseEvent * event ) + { + if(event->button() == Qt::LeftButton) + { + SetupCustState(event); + } + + if(_dragging) + blockSignals(true); + QAbstractSpinBox::mousePressEvent(event); + if(_dragging) + blockSignals(false); + } + + void mouseReleaseEvent( QMouseEvent * event ) + { + if(_dragging) + { + setCursor(_cursor); + _dragTimer.stop(); + } + + QAbstractSpinBox::mouseReleaseEvent(event); + //if(_dragBegin) + // EmitDragValueChanged(); + + ResetCustState(); + } + + void timerEvent(QTimerEvent *event) + { + if(_dragging) + { + // stop timer event to disable acceleration/auto-stepping + event->ignore(); + return; + } + + event->accept(); + + if(_dragBegin) blockSignals(true); + QAbstractSpinBox::timerEvent(event); + if(_dragBegin) blockSignals(false); + } + +private: + enum + { + MIN_DRAG_RANGE = 50, + MAX_DRAG_RANGE = 500, + + DEFAULT_DRAG_RANGE = 100, + + DRAG_TIMER_INTERVAL= 30, // in msec + }; + + bool SetupCustState(QMouseEvent* event) + { + QStyleOptionSpinBox opt; + this->initStyleOption(&opt); + QStyle::SubControl hitControl = this->style()->hitTestComplexControl(QStyle::CC_SpinBox, &opt, event->pos()); + if(hitControl != QStyle::SC_SpinBoxUp && hitControl != QStyle::SC_SpinBoxDown) + return false; + + _pressPosition = event->pos(); + _dragging = false; + _dragBegin = true; + _pressValue = this->value(); + _dragValue = this->value(); + + return true; + } + + void ResetCustState() + { + _dragBegin = false; + _dragging = false; + } + + void DragValue(const QPoint& pos) + { + ValueType valueRange = this->maximum() - this->minimum(); + + double dh = (double)(_pressPosition.y() - pos.y()); + double dv = valueRange * dh / (double)_dragRange; + ValueType v = _pressValue + (ValueType)dv; + + //blockSignals(true); + setValue(v); + //blockSignals(false); + } + + void EmitDragValueChanged() + { + //if(this->value() != _pressValue) // value are always bound by qt (and decimal settings) + if(this->value() != _dragValue) + { + _dragValue = this->value(); + emit valueChanged(this->value()); + } + } + + int _dragRange; + + QPoint _pressPosition; + ValueType _pressValue; + ValueType _dragValue; + + bool _dragging; + bool _dragBegin; + QCursor _cursor; + + QTimer _dragTimer; + SlideSpinBoxSlots* _pSlots; +}; + +typedef SlideSpinBox<QDoubleSpinBox, double> SlideSpinBoxF; +typedef SlideSpinBox<QSpinBox, int> SlideSpinBoxInt; + +template<typename CustSpinBox> +class ConfigSpinBox +{ +public: + typedef typename CustSpinBox::value_type ValueType; + + ConfigSpinBox(CustSpinBox* spinBox, ValueType minv, ValueType maxv, ValueType step = (ValueType)1) + { + spinBox->blockSignals(true); + spinBox->setRange(minv, maxv); + spinBox->setSingleStep(step); + spinBox->AutoConfigDragRange(); + spinBox->setKeyboardTracking(false); + SpecificConfig<ValueType>(spinBox); + spinBox->blockSignals(false); + } + + template<typename T> + void SpecificConfig(CustSpinBox* spinBox){} + + template<> + void SpecificConfig<double>(CustSpinBox* spinBox) + { + spinBox->setDecimals(2.0); + } +}; + +#include "corelib_global.h" +CORELIB_EXPORT void ConfigSpinBoxInt(SlideSpinBoxInt* spinBox, int minv, int maxv, int step = (int)1); + +#endif // SlideSpinBox_h__ diff --git a/tools/ArtistTools/source/CoreLib/Window/SlideSpinBoxInt.h b/tools/ArtistTools/source/CoreLib/Window/SlideSpinBoxInt.h new file mode 100644 index 0000000..393adee --- /dev/null +++ b/tools/ArtistTools/source/CoreLib/Window/SlideSpinBoxInt.h @@ -0,0 +1,15 @@ +#ifndef SlideSpinBoxInt_h__ +#define SlideSpinBoxInt_h__ + +#include <QtWidgets/QStyle> +#include <QtWidgets/QStyleOptionSpinBox> +#include <QtWidgets/QAbstractSpinBox> +#include <QtGui/QMouseEvent> +#include <QtCore/QTimer> +#include <QtWidgets/QDoubleSpinBox> +#include <QtWidgets/QSpinBox> +#include <SlideSpinBox.h> + +// use this header as a trick to make moc work right + +#endif // SlideSpinBoxInt_h__ diff --git a/tools/ArtistTools/source/CoreLib/Window/TipListView.cpp b/tools/ArtistTools/source/CoreLib/Window/TipListView.cpp new file mode 100644 index 0000000..b91fd3e --- /dev/null +++ b/tools/ArtistTools/source/CoreLib/Window/TipListView.cpp @@ -0,0 +1,42 @@ +#include "TipListView.h" +#include <QtWidgets/QToolTip> +#include <QtCore/QEvent> +#include <QtGUI/QEvent.h> + + +TipListView::TipListView(QWidget* parent) + :QListWidget(parent) +{ +} + +void TipListView::setTips(QStringList& tips) +{ + mTips = tips; +} + +bool TipListView::event(QEvent *evt) +{ + if (evt->type() == QEvent::ToolTip) + { + if (mTips.size() > 0) + { + QHelpEvent *helpEvent = (QHelpEvent *)(evt); + const QPoint& pos = helpEvent->pos(); + QListWidgetItem* pItem = itemAt(pos); + int index = 0, num = count(); + for (int i = 0; i < num; ++i) + { + QListWidgetItem* pi = item(i); + if (pi == pItem && mTips.size() > i) + { + QToolTip::showText(helpEvent->globalPos(), mTips[i]); + return true; + } + } + } + //QToolTip::hideText(); + //evt->ignore(); + //return true; + } + return QListWidget::event(evt); +} diff --git a/tools/ArtistTools/source/CoreLib/Window/TipListView.h b/tools/ArtistTools/source/CoreLib/Window/TipListView.h new file mode 100644 index 0000000..6913baa --- /dev/null +++ b/tools/ArtistTools/source/CoreLib/Window/TipListView.h @@ -0,0 +1,26 @@ +#ifndef TipListView_h__ +#define TipListView_h__ + +#include <QtWidgets/QWidget> +#include <QtWidgets/QListWidget> +#include <QtCore/QEvent> + +#include "corelib_global.h" + +class TipListView : public QListWidget +{ + Q_OBJECT + +public: + TipListView(QWidget* parent = 0); + + void setTips(QStringList& tips); + +protected: + bool event(QEvent *); +private: + + QStringList mTips; + +}; +#endif // TipListView_h__ diff --git a/tools/ArtistTools/source/CoreLib/Window/UIGlobal.h b/tools/ArtistTools/source/CoreLib/Window/UIGlobal.h new file mode 100644 index 0000000..3d50132 --- /dev/null +++ b/tools/ArtistTools/source/CoreLib/Window/UIGlobal.h @@ -0,0 +1,37 @@ +// This code contains NVIDIA Confidential Information and is disclosed +// under the Mutual Non-Disclosure Agreement. +// +// Notice +// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES +// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless +// expressly authorized by NVIDIA. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2013-2015 NVIDIA Corporation. All rights reserved. +// +// NVIDIA Corporation and its licensors retain all intellectual property and proprietary +// rights in and to this software and related documentation and any modifications thereto. +// Any use, reproduction, disclosure or distribution of this software and related +// documentation without an express license agreement from NVIDIA Corporation is +// strictly prohibited. +// + +#pragma once + +#define USE_MATERIAL_SET 1 +#define USE_CURVE_EDITOR 0 +#define USE_TEXTURE_BRIGHTNESS 0 + +#define USE_INTERNAL_GRAPHICAL_MATERIAL 0 + +#include "corelib_global.h"
\ No newline at end of file |