diff --git a/src/Interface/Modules/Render/CMakeLists.txt b/src/Interface/Modules/Render/CMakeLists.txt index a332093f91..449c718938 100644 --- a/src/Interface/Modules/Render/CMakeLists.txt +++ b/src/Interface/Modules/Render/CMakeLists.txt @@ -43,6 +43,7 @@ SET(Interface_Modules_Render_FORMS Materials.ui ObjectSelection.ui OrientationAxes.ui + Screenshot.ui ScaleBar.ui ClippingPlanes.ui InputControls.ui diff --git a/src/Interface/Modules/Render/InputControls.ui b/src/Interface/Modules/Render/InputControls.ui index 8c828987f3..26f47761af 100644 --- a/src/Interface/Modules/Render/InputControls.ui +++ b/src/Interface/Modules/Render/InputControls.ui @@ -6,14 +6,14 @@ 0 0 - 301 - 210 + 300 + 180 300 - 210 + 180 @@ -120,22 +120,6 @@ - - - - - 50 - false - - - - Save screenshot on geometry update - - - Save screenshot on update - - - diff --git a/src/Interface/Modules/Render/Screenshot.cc b/src/Interface/Modules/Render/Screenshot.cc index 830ec26470..ff3d53b3d5 100644 --- a/src/Interface/Modules/Render/Screenshot.cc +++ b/src/Interface/Modules/Render/Screenshot.cc @@ -38,30 +38,10 @@ using namespace SCIRun::Core::Datatypes; Screenshot::Screenshot(QOpenGLWidget *glwidget, QObject *parent) : QObject(parent), - viewport_(glwidget), - index_(0) + viewport_(glwidget) { } -QString Screenshot::screenshotDirectory() -{ - // static const QString filePath = QDir::homePath() + QLatin1String("/scirun5screenshots"); - QString filePath = QString::fromStdString(Core::Preferences::Instance().screenshotDirectory().string()); - - if (filePath.isEmpty()) - { - filePath = QDir::homePath() + QLatin1String("/scirun5screenshots"); - - QDir dir(filePath); - if (!dir.exists()) - { - dir.mkpath(filePath); - } - } - - return filePath; -} - void Screenshot::takeScreenshot() { screenshot_ = getScreenshot(); @@ -81,42 +61,10 @@ QImage Screenshot::getScreenshot() return image; } -void Screenshot::saveScreenshot() -{ - index_++; - const auto fileName = screenshotFile(); - if (!fileName.isEmpty()) - { - QMessageBox::information(nullptr, "ViewScene Screenshot", "Saving ViewScene screenshot to: " + fileName); - screenshot_.save(fileName); - } -} - -void Screenshot::saveScreenshot(const QString& filename) +void Screenshot::saveScreenshot(const QString& fileName) { - screenshot_.save(filename); -} - -void Screenshot::saveScreenshotFromPath(bool prompt) -{ - index_++; - auto fileName = screenshotFileFromPreferences(); if (!fileName.isEmpty()) - { - if (prompt) - QMessageBox::information(nullptr, "ViewScene Screenshot", "Saving ViewScene screenshot to: " + fileName); screenshot_.save(fileName); - } -} - -QString Screenshot::screenshotFileFromPreferences() const -{ - return screenshotDirectory() + QString("/viewScene_%1_%2.png").arg(QDateTime::currentDateTime().toString("yyyy.MM.dd.HHmmss.zzz")).arg(index_); -} - -QString Screenshot::screenshotFile() const -{ - return QFileDialog::getSaveFileName(viewport_, "Save screenshot...", screenshotDirectory(), "*.png"); } SCIRun::Modules::Render::RGBMatrices Screenshot::toMatrix() const diff --git a/src/Interface/Modules/Render/Screenshot.h b/src/Interface/Modules/Render/Screenshot.h index d472faea50..7e69446e5a 100644 --- a/src/Interface/Modules/Render/Screenshot.h +++ b/src/Interface/Modules/Render/Screenshot.h @@ -47,18 +47,12 @@ namespace SCIRun explicit Screenshot(QOpenGLWidget *glwidget, QObject *parent = nullptr); void takeScreenshot(); QImage getScreenshot(); - void saveScreenshot(); void saveScreenshot(const QString& filename); - void saveScreenshotFromPath(bool prompt); - QString screenshotFileFromPreferences() const; - QString screenshotFile() const; Modules::Render::RGBMatrices toMatrix() const; - static QString screenshotDirectory(); private: QOpenGLWidget* viewport_; QImage screenshot_; - uint index_; }; } } diff --git a/src/Interface/Modules/Render/Screenshot.ui b/src/Interface/Modules/Render/Screenshot.ui new file mode 100644 index 0000000000..bcdc2faee5 --- /dev/null +++ b/src/Interface/Modules/Render/Screenshot.ui @@ -0,0 +1,92 @@ + + + Screenshot + + + + 0 + 0 + 400 + 150 + + + + + 400 + 150 + + + + Orientation Axes + + + + + + Default Screenshot Path + + + + + 15 + 33 + 16 + 16 + + + + + + + + + + 10 + 30 + 361 + 33 + + + + + QLayout::SetDefaultConstraint + + + + + + + + true + + + Set... + + + + + + + + + + + Save Screenshot on Update + + + + + + + true + + + Save Screenshot As... + + + + + + + + diff --git a/src/Interface/Modules/Render/ViewScene.cc b/src/Interface/Modules/Render/ViewScene.cc index 965d0e70dc..afeaa954e0 100644 --- a/src/Interface/Modules/Render/ViewScene.cc +++ b/src/Interface/Modules/Render/ViewScene.cc @@ -169,6 +169,7 @@ namespace Gui { ViewAxisChooserControls* viewAxisChooser_{nullptr}; ObjectSelectionControls* objectSelectionControls_{nullptr}; OrientationAxesControls* orientationAxesControls_{nullptr}; + ScreenshotControls* screenshotControls_{nullptr}; ScaleBarControls* scaleBarControls_{nullptr}; ClippingPlaneControls* clippingPlaneControls_{nullptr}; InputControls* inputControls_{nullptr}; @@ -448,6 +449,8 @@ ViewSceneDialog::ViewSceneDialog(const std::string& name, ModuleStateHandle stat glLayout->addWidget(impl_->toolBar2_, 1, 0); glLayout->update(); + addLineEditManager(impl_->screenshotControls_->defaultScreenshotPath_, Parameters::ScreenshotDirectory); + viewSceneManager.addViewScene(this); } @@ -488,7 +491,6 @@ void ViewSceneDialog::addToolBar() addObjectSelectionButton(); addAutoViewButton(); addScreenshotButton(); - addQuickScreenshotButton(); addAutoRotateButton(); addColorOptionsButton(); addLightButtons(); @@ -684,18 +686,9 @@ void ViewSceneDialog::addScreenshotButton() screenshotButton->setToolTip("Take Screenshot"); screenshotButton->setIcon(QPixmap(":/general/Resources/ViewScene/screenshot.png")); screenshotButton->setShortcut(Qt::Key_F12); - connect(screenshotButton, SIGNAL(clicked(bool)), this, SLOT(screenshotClicked())); - addToolbarButton(screenshotButton, 1); -} - -void ViewSceneDialog::addQuickScreenshotButton() -{ - auto* quickScreenshotButton = new QPushButton(this); - quickScreenshotButton->setToolTip("Take Quick Screenshot"); - quickScreenshotButton->setIcon(QPixmap(":/general/Resources/ViewScene/quickscreenshot.png")); - quickScreenshotButton->setShortcut(Qt::Key_F12); - connect(quickScreenshotButton, &QPushButton::clicked, this, &ViewSceneDialog::quickScreenshotClicked); - addToolbarButton(quickScreenshotButton, 1); + connect(screenshotButton, SIGNAL(clicked(bool)), this, SLOT(quickScreenshotClicked())); + impl_->screenshotControls_ = new ScreenshotControls(this); + addToolbarButton(screenshotButton, 1, impl_->screenshotControls_); } using V = glm::vec3; @@ -1206,7 +1199,7 @@ void ViewSceneDialog::newGeometryValue(bool forceAllObjectsToUpdate, bool clippi } if (impl_->saveScreenshotOnNewGeometry_) - quickScreenshot(false); + autoSaveScreenshot(); } void ViewSceneDialog::lockMutex() @@ -2671,28 +2664,49 @@ void ViewSceneDialog::setTransparencySortTypeLists(bool) updateAllGeometries(); } -void ViewSceneDialog::screenshotClicked() +void ViewSceneDialog::screenshotSaveAs() { - takeScreenshot(); - impl_->screenshotTaker_->saveScreenshot(); + auto fileName = QFileDialog::getSaveFileName(impl_->mGLWidget, "Save screenshot...", QString::fromStdString(state_->getValue(Parameters::ScreenshotDirectory).toString()), "*.png"); + + saveScreenshot(fileName, true); } -void ViewSceneDialog::quickScreenshot(bool prompt) +void ViewSceneDialog::quickScreenshot() { - takeScreenshot(); - impl_->screenshotTaker_->saveScreenshotFromPath(prompt); + auto fileName = QString::fromStdString(state_->getValue(Parameters::ScreenshotDirectory).toString()) + + QString("/%1_%2.png").arg(QString::fromStdString(getName()).replace(':', '-')).arg(QDateTime::currentDateTime().toString("yyyy.MM.dd.HHmmss.zzz")); + + saveScreenshot(fileName, true); +} + +void ViewSceneDialog::setScreenshotDirectory() +{ + auto dir = QFileDialog::getExistingDirectory(this, tr("Choose Screenshot Directory"), QString::fromStdString(state_->getValue(Parameters::ScreenshotDirectory).toString())); + + state_->setValue(Parameters::ScreenshotDirectory, dir.toStdString()); +} + +void ViewSceneDialog::saveScreenshot(QString fileName, bool notify) +{ + if(!fileName.isEmpty()) + { + takeScreenshot(); + if(notify) + QMessageBox::information(nullptr, "ViewScene Screenshot", "Saving ViewScene screenshot to: " + fileName); + + impl_->screenshotTaker_->saveScreenshot(fileName); + } } void ViewSceneDialog::autoSaveScreenshot() { QThread::sleep(1); - takeScreenshot(); - const auto file = Screenshot::screenshotDirectory() + + const auto file = QString::fromStdString(state_->getValue(Parameters::ScreenshotDirectory).toString()) + QString("/%1_%2.png") - .arg(windowTitle().replace(':', '-')) + .arg(QString::fromStdString(getName()).replace(':', '-')) .arg(QTime::currentTime().toString("hh.mm.ss.zzz")); - impl_->screenshotTaker_->saveScreenshot(file); + saveScreenshot(file, false); } void ViewSceneDialog::sendBugReport() @@ -2701,10 +2715,8 @@ void ViewSceneDialog::sendBugReport() const QString gpuVersion = reinterpret_cast(glGetString(GL_RENDERER)); // Temporarily save screenshot so that it can be sent over email - takeScreenshot(); - const QImage image = impl_->screenshotTaker_->getScreenshot(); - QString location = Screenshot::screenshotDirectory() + ("/scirun_bug.png"); - image.save(location); + QString location = QString::fromStdString(state_->getValue(Parameters::ScreenshotDirectory).toString()) + ("/scirun_bug.png"); + saveScreenshot(location, false); // Generate email template const QString askForScreenshot = "\nIMPORTANT: Make sure to attach the screenshot of the ViewScene located at " diff --git a/src/Interface/Modules/Render/ViewScene.h b/src/Interface/Modules/Render/ViewScene.h index fffbda68bc..6fee5b1770 100644 --- a/src/Interface/Modules/Render/ViewScene.h +++ b/src/Interface/Modules/Render/ViewScene.h @@ -184,9 +184,11 @@ namespace SCIRun { void setTransparencySortTypeContinuous(bool index); void setTransparencySortTypeUpdate(bool index); void setTransparencySortTypeLists(bool index); - void screenshotClicked(); - void quickScreenshot(bool prompt); - void quickScreenshotClicked() { quickScreenshot(true); } + void screenshotSaveAs(); + void screenshotSaveAsClicked() { screenshotSaveAs(); }; + void quickScreenshot(); + void quickScreenshotClicked() { quickScreenshot(); } + void setScreenshotDirectory(); void saveNewGeometryChanged(int state); @@ -223,7 +225,6 @@ namespace SCIRun { void setupMaterials(); void addAutoViewButton(); void addScreenshotButton(); - void addQuickScreenshotButton(); void addViewBarButton(); void addControlLockButton(); void addAutoRotateButton(); @@ -283,6 +284,7 @@ namespace SCIRun { //---------------- Misc. --------------------------------------------------------------------- void takeScreenshot(); void sendScreenshotDownstreamForTesting(); + void saveScreenshot(QString directory, bool notify); std::unique_ptr impl_; @@ -293,6 +295,7 @@ namespace SCIRun { friend class MaterialsControls; friend class ObjectSelectionControls; friend class OrientationAxesControls; + friend class ScreenshotControls; friend class ScaleBarControls; friend class LightControls; friend class ClippingPlaneControls; diff --git a/src/Interface/Modules/Render/ViewSceneControlsDock.cc b/src/Interface/Modules/Render/ViewSceneControlsDock.cc index f6ad4831e9..022c085a23 100644 --- a/src/Interface/Modules/Render/ViewSceneControlsDock.cc +++ b/src/Interface/Modules/Render/ViewSceneControlsDock.cc @@ -587,6 +587,15 @@ void OrientationAxesControls::toggleButton() updateToolbarButton("lightGray"); } +ScreenshotControls::ScreenshotControls(ViewSceneDialog* parent) + : QWidget(parent) +{ + setupUi(this); + connect(saveScreenShotOnUpdateCheckBox_, SIGNAL(stateChanged(int)), parent, SLOT(saveNewGeometryChanged(int))); + connect(screenshotSaveAsButton_, SIGNAL(clicked()), parent, SLOT(screenshotSaveAsClicked())); + connect(screenshotPathButton_, SIGNAL(clicked()), parent, SLOT(setScreenshotDirectory())); +} + ScaleBarControls::ScaleBarControls(ViewSceneDialog* parent, QPushButton* toolbarButton) : QWidget(parent), ButtonStylesheetToggler(toolbarButton, [this]() { toggleCheckable(showScaleBarTextGroupBox_); }) { @@ -655,7 +664,6 @@ InputControls::InputControls(ViewSceneDialog* parent) : QWidget(parent) updateZoomOptionVisibility(); - connect(saveScreenShotOnUpdateCheckBox_, SIGNAL(stateChanged(int)), parent, SLOT(saveNewGeometryChanged(int))); connect(mouseControlComboBox_, SIGNAL(currentIndexChanged(int)), parent, SLOT(menuMouseControlChanged(int))); connect(invertZoomCheckBox_, SIGNAL(clicked(bool)), parent, SLOT(invertZoomClicked(bool))); connect(zoomSpeedHorizontalSlider_, SIGNAL(valueChanged(int)), parent, SLOT(adjustZoomSpeed(int))); diff --git a/src/Interface/Modules/Render/ViewSceneControlsDock.h b/src/Interface/Modules/Render/ViewSceneControlsDock.h index 89c18ea03d..bee11ac89f 100644 --- a/src/Interface/Modules/Render/ViewSceneControlsDock.h +++ b/src/Interface/Modules/Render/ViewSceneControlsDock.h @@ -36,6 +36,7 @@ #include "Interface/Modules/Render/ui_Fog.h" #include "Interface/Modules/Render/ui_ObjectSelection.h" #include "Interface/Modules/Render/ui_OrientationAxes.h" +#include "Interface/Modules/Render/ui_Screenshot.h" #include "Interface/Modules/Render/ui_ScaleBar.h" #include "Interface/Modules/Render/ui_ClippingPlanes.h" #include "Interface/Modules/Render/ui_InputControls.h" @@ -174,6 +175,18 @@ namespace SCIRun { void setSliderCenterPos(); }; + class SCISHARE ScreenshotControls : public QWidget, public Ui::Screenshot + { + Q_OBJECT + + public: + explicit ScreenshotControls(ViewSceneDialog* parent); + void setScreenshotDirectory(const QString& dir); + private: + void setSliderDefaultPos(); + void setSliderCenterPos(); + }; + struct SCISHARE ScaleBarData { bool visible; diff --git a/src/Modules/Render/CMakeLists.txt b/src/Modules/Render/CMakeLists.txt index 56964a92a0..c324baf26c 100644 --- a/src/Modules/Render/CMakeLists.txt +++ b/src/Modules/Render/CMakeLists.txt @@ -45,6 +45,7 @@ SCIRUN_ADD_LIBRARY(Modules_Render TARGET_LINK_LIBRARIES(Modules_Render Dataflow_Network Core_Datatypes + Core_Application_Preferences ) IF(BUILD_SHARED_LIBS) diff --git a/src/Modules/Render/ViewScene.cc b/src/Modules/Render/ViewScene.cc index 2061e3c0e9..c8b6fd01a8 100644 --- a/src/Modules/Render/ViewScene.cc +++ b/src/Modules/Render/ViewScene.cc @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -158,6 +159,8 @@ ALGORITHM_PARAMETER_DEF(Render, AxesX); ALGORITHM_PARAMETER_DEF(Render, AxesY); ALGORITHM_PARAMETER_DEF(Render, VisibleItemListState); +ALGORITHM_PARAMETER_DEF(Render, ScreenshotDirectory); + ViewScene::ViewScene() : ModuleWithAsyncDynamicPorts(staticInfo_, true) { RENDERER_LOG_FUNCTION_SCOPE; @@ -254,6 +257,9 @@ void ViewScene::setStateDefaults() state->setValue(Parameters::AxesX, 100); state->setValue(Parameters::AxesY, 100); + state->setValue(Parameters::ScreenshotDirectory, Core::Preferences::Instance().screenshotDirectory().string()); + + get_state()->connectSpecificStateChanged(Parameters::GeometryFeedbackInfo, [this]() { processViewSceneObjectFeedback(); }); get_state()->connectSpecificStateChanged(Parameters::MeshComponentSelection, [this]() { processMeshComponentSelection(); }); } diff --git a/src/Modules/Render/ViewScene.h b/src/Modules/Render/ViewScene.h index 49cf4fc33c..58651cc71e 100644 --- a/src/Modules/Render/ViewScene.h +++ b/src/Modules/Render/ViewScene.h @@ -124,6 +124,8 @@ namespace SCIRun ALGORITHM_PARAMETER_DECL(Light2Inclination); ALGORITHM_PARAMETER_DECL(Light3Inclination); + ALGORITHM_PARAMETER_DECL(ScreenshotDirectory); + // not used--GUI hidden/never implemented //ALGORITHM_PARAMETER_DECL(Lighting); //ALGORITHM_PARAMETER_DECL(ShowBBox);