diff --git a/tools/lammps-gui/CMakeLists.txt b/tools/lammps-gui/CMakeLists.txt index 10ac72783f..0cd15bd753 100644 --- a/tools/lammps-gui/CMakeLists.txt +++ b/tools/lammps-gui/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.16) -project(lammps-gui VERSION 1.3.1 LANGUAGES CXX) +project(lammps-gui VERSION 1.4.0 LANGUAGES CXX) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOMOC ON) @@ -72,17 +72,17 @@ find_package(Qt5 5.12 REQUIRED COMPONENTS Widgets Charts) set(PROJECT_SOURCES main.cpp + lammpsgui.cpp + lammpsgui.h + lammpsgui.ui + chartviewer.cpp + chartviewer.h codeeditor.cpp codeeditor.h highlighter.cpp highlighter.h imageviewer.cpp imageviewer.h - chartviewer.cpp - chartviewer.h - lammpsgui.cpp - lammpsgui.h - lammpsgui.ui lammpsrunner.h lammpswrapper.cpp lammpswrapper.h @@ -93,6 +93,8 @@ set(PROJECT_SOURCES preferences.h setvariables.cpp setvariables.h + slideshow.h + slideshow.cpp stdcapture.cpp ${PLUGIN_LOADER_SRC} ${ICON_RC_FILE} diff --git a/tools/lammps-gui/image-x-generic.png b/tools/lammps-gui/image-x-generic.png new file mode 100644 index 0000000000..1fe112632a Binary files /dev/null and b/tools/lammps-gui/image-x-generic.png differ diff --git a/tools/lammps-gui/lammpsgui.cpp b/tools/lammps-gui/lammpsgui.cpp index d5fe1d043a..b340ab766d 100644 --- a/tools/lammps-gui/lammpsgui.cpp +++ b/tools/lammps-gui/lammpsgui.cpp @@ -20,6 +20,7 @@ #include "logwindow.h" #include "preferences.h" #include "setvariables.h" +#include "slideshow.h" #include "stdcapture.h" #include "ui_lammpsgui.h" @@ -96,8 +97,8 @@ static bool has_exe(const QString &exe) LammpsGui::LammpsGui(QWidget *parent, const char *filename) : QMainWindow(parent), ui(new Ui::LammpsGui), highlighter(nullptr), capturer(nullptr), status(nullptr), logwindow(nullptr), imagewindow(nullptr), chartwindow(nullptr), - logupdater(nullptr), dirstatus(nullptr), progress(nullptr), prefdialog(nullptr), - lammpsstatus(nullptr), varwindow(nullptr) + slideshow(nullptr), logupdater(nullptr), dirstatus(nullptr), progress(nullptr), + prefdialog(nullptr), lammpsstatus(nullptr), varwindow(nullptr) { // enforce using the plain ASCII C locale within the GUI. QLocale::setDefault(QLocale("C")); @@ -239,6 +240,7 @@ LammpsGui::LammpsGui(QWidget *parent, const char *filename) : connect(ui->actionView_Log_Window, &QAction::triggered, this, &LammpsGui::view_log); connect(ui->actionView_Graph_Window, &QAction::triggered, this, &LammpsGui::view_chart); connect(ui->actionView_Image_Window, &QAction::triggered, this, &LammpsGui::view_image); + connect(ui->actionView_Slide_Show, &QAction::triggered, this, &LammpsGui::view_slides); connect(ui->actionView_Variable_Window, &QAction::triggered, this, &LammpsGui::view_variables); connect(ui->action_1, &QAction::triggered, this, &LammpsGui::open_recent); connect(ui->action_2, &QAction::triggered, this, &LammpsGui::open_recent); @@ -265,15 +267,19 @@ LammpsGui::LammpsGui(QWidget *parent, const char *filename) : auto *lammpsrun = new QPushButton(QIcon(":/system-run.png"), ""); auto *lammpsstop = new QPushButton(QIcon(":/process-stop.png"), ""); auto *lammpsimage = new QPushButton(QIcon(":/emblem-photos.png"), ""); + auto *lammpsslide = new QPushButton(QIcon(":/image-x-generic.png"), ""); lammpsrun->setToolTip("Run LAMMPS on input"); lammpsstop->setToolTip("Stop LAMMPS"); lammpsimage->setToolTip("Create snapshot image"); + lammpsslide->setToolTip("View Slide Show"); ui->statusbar->addWidget(lammpsrun); ui->statusbar->addWidget(lammpsstop); ui->statusbar->addWidget(lammpsimage); + ui->statusbar->addWidget(lammpsslide); connect(lammpsrun, &QPushButton::released, this, &LammpsGui::run_buffer); connect(lammpsstop, &QPushButton::released, this, &LammpsGui::stop_run); connect(lammpsimage, &QPushButton::released, this, &LammpsGui::render_image); + connect(lammpsslide, &QPushButton::released, this, &LammpsGui::view_slides); status = new QLabel("Ready."); status->setFixedWidth(300); @@ -307,6 +313,7 @@ LammpsGui::~LammpsGui() delete chartwindow; delete dirstatus; delete varwindow; + delete slideshow; } void LammpsGui::new_document() @@ -982,6 +989,15 @@ void LammpsGui::render_image() imagewindow->show(); } +void LammpsGui::view_slides() +{ + if (!slideshow) slideshow = new SlideShow(current_file, &lammps); + if (slideshow->isVisible()) + slideshow->hide(); + else + slideshow->show(); +} + void LammpsGui::view_chart() { QSettings settings; diff --git a/tools/lammps-gui/lammpsgui.h b/tools/lammps-gui/lammpsgui.h index aeda618443..6d80b0aee6 100644 --- a/tools/lammps-gui/lammpsgui.h +++ b/tools/lammps-gui/lammpsgui.h @@ -45,6 +45,7 @@ class StdCapture; class Preferences; class ImageViewer; class ChartWindow; +class SlideShow; class LammpsGui : public QMainWindow { Q_OBJECT @@ -84,6 +85,7 @@ private slots: void stop_run(); void edit_variables(); void render_image(); + void view_slides(); void view_image(); void view_chart(); void view_log(); @@ -107,6 +109,7 @@ private: LogWindow *logwindow; ImageViewer *imagewindow; ChartWindow *chartwindow; + SlideShow *slideshow; QTimer *logupdater; QLabel *dirstatus; QProgressBar *progress; diff --git a/tools/lammps-gui/lammpsgui.qrc b/tools/lammps-gui/lammpsgui.qrc index 31f997f05e..15ff13da4b 100644 --- a/tools/lammps-gui/lammpsgui.qrc +++ b/tools/lammps-gui/lammpsgui.qrc @@ -29,6 +29,7 @@ help-browser.png help-faq.png help_index.table + image-x-generic.png object-rotate-left.png object-rotate-right.png ovito.png diff --git a/tools/lammps-gui/lammpsgui.ui b/tools/lammps-gui/lammpsgui.ui index 9ef6525f9b..d6264e48e4 100644 --- a/tools/lammps-gui/lammpsgui.ui +++ b/tools/lammps-gui/lammpsgui.ui @@ -93,6 +93,7 @@ + @@ -352,6 +353,17 @@ Ctrl+Shift+C + + + + + + &Slide Show Window + + + Ctrl+Shift+W + + diff --git a/tools/lammps-gui/slideshow.cpp b/tools/lammps-gui/slideshow.cpp new file mode 100644 index 0000000000..cc8c57d4f0 --- /dev/null +++ b/tools/lammps-gui/slideshow.cpp @@ -0,0 +1,190 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "slideshow.h" +#include "lammpswrapper.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static const QString blank(" "); + +SlideShow::SlideShow(const QString &fileName, LammpsWrapper *_lammps, QWidget *parent) : + QDialog(parent), imageLabel(new QLabel), scrollArea(new QScrollArea), menuBar(new QMenuBar), + lammps(_lammps) +{ + imageLabel->setBackgroundRole(QPalette::Base); + imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); + imageLabel->setScaledContents(true); + imageLabel->minimumSizeHint(); + + scrollArea->setBackgroundRole(QPalette::Dark); + scrollArea->setWidget(imageLabel); + scrollArea->setVisible(false); + + buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); + + connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); + + QVBoxLayout *mainLayout = new QVBoxLayout; + QSettings settings; + + mainLayout->addWidget(scrollArea); + mainLayout->addWidget(buttonBox); + setWindowTitle(QString("Slide Show: ") + QFileInfo(fileName).fileName()); + createActions(); + + scaleFactor = 1.0; + resize(image.width() + 20, image.height() + 50); + + scrollArea->setVisible(true); + fitToWindowAct->setEnabled(true); + updateActions(); + if (!fitToWindowAct->isChecked()) imageLabel->adjustSize(); + setLayout(mainLayout); +} + +void SlideShow::saveAs() +{ + QString fileName = QFileDialog::getSaveFileName(this, "Save Image File As", QString(), + "Image Files (*.jpg *.png *.bmp *.ppm)"); + saveFile(fileName); +} + +void SlideShow::copy() {} + +void SlideShow::zoomIn() +{ + scaleImage(1.25); +} + +void SlideShow::zoomOut() +{ + scaleImage(0.8); +} + +void SlideShow::normalSize() +{ + imageLabel->adjustSize(); + scaleFactor = 1.0; +} + +void SlideShow::fitToWindow() +{ + bool fitToWindow = fitToWindowAct->isChecked(); + scrollArea->setWidgetResizable(fitToWindow); + if (!fitToWindow) normalSize(); + updateActions(); +} + +void SlideShow::saveFile(const QString &fileName) +{ + if (!fileName.isEmpty()) image.save(fileName); +} + +void SlideShow::createActions() +{ + QMenu *fileMenu = menuBar->addMenu("&File"); + + saveAsAct = fileMenu->addAction("&Save As...", this, &SlideShow::saveAs); + saveAsAct->setIcon(QIcon(":/document-save-as.png")); + saveAsAct->setEnabled(false); + fileMenu->addSeparator(); + copyAct = fileMenu->addAction("&Copy", this, &SlideShow::copy); + copyAct->setIcon(QIcon(":/edit-copy.png")); + copyAct->setShortcut(QKeySequence::Copy); + copyAct->setEnabled(false); + fileMenu->addSeparator(); + QAction *exitAct = fileMenu->addAction("&Close", this, &QWidget::close); + exitAct->setIcon(QIcon(":/window-close.png")); + exitAct->setShortcut(QKeySequence::fromString("Ctrl+W")); + + QMenu *viewMenu = menuBar->addMenu("&View"); + + zoomInAct = viewMenu->addAction("Image Zoom &In (25%)", this, &SlideShow::zoomIn); + zoomInAct->setShortcut(QKeySequence::ZoomIn); + zoomInAct->setIcon(QIcon(":/gtk-zoom-in.png")); + zoomInAct->setEnabled(false); + + zoomOutAct = viewMenu->addAction("Image Zoom &Out (25%)", this, &SlideShow::zoomOut); + zoomOutAct->setShortcut(QKeySequence::ZoomOut); + zoomOutAct->setIcon(QIcon(":/gtk-zoom-out.png")); + zoomOutAct->setEnabled(false); + + normalSizeAct = viewMenu->addAction("&Reset Image Size", this, &SlideShow::normalSize); + normalSizeAct->setShortcut(QKeySequence::fromString("Ctrl+0")); + normalSizeAct->setIcon(QIcon(":/gtk-zoom-fit.png")); + normalSizeAct->setEnabled(false); + + viewMenu->addSeparator(); + + fitToWindowAct = viewMenu->addAction("&Fit to Window", this, &SlideShow::fitToWindow); + fitToWindowAct->setEnabled(false); + fitToWindowAct->setCheckable(true); + fitToWindowAct->setShortcut(QKeySequence::fromString("Ctrl+=")); +} + +void SlideShow::updateActions() +{ + saveAsAct->setEnabled(!image.isNull()); + copyAct->setEnabled(!image.isNull()); + zoomInAct->setEnabled(!fitToWindowAct->isChecked()); + zoomOutAct->setEnabled(!fitToWindowAct->isChecked()); + normalSizeAct->setEnabled(!fitToWindowAct->isChecked()); +} + +void SlideShow::scaleImage(double factor) +{ + scaleFactor *= factor; +#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) + imageLabel->resize(scaleFactor * imageLabel->pixmap()->size()); +#else + imageLabel->resize(scaleFactor * imageLabel->pixmap(Qt::ReturnByValue).size()); +#endif + + adjustScrollBar(scrollArea->horizontalScrollBar(), factor); + adjustScrollBar(scrollArea->verticalScrollBar(), factor); + zoomInAct->setEnabled(scaleFactor < 3.0); + zoomOutAct->setEnabled(scaleFactor > 0.333); +} + +void SlideShow::adjustScrollBar(QScrollBar *scrollBar, double factor) +{ + scrollBar->setValue( + int(factor * scrollBar->value() + ((factor - 1) * scrollBar->pageStep() / 2))); +} + +// Local Variables: +// c-basic-offset: 4 +// End: diff --git a/tools/lammps-gui/slideshow.h b/tools/lammps-gui/slideshow.h new file mode 100644 index 0000000000..bde011e905 --- /dev/null +++ b/tools/lammps-gui/slideshow.h @@ -0,0 +1,76 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifndef SLIDESHOW_H +#define SLIDESHOW_H + +#include +#include +#include +#include + +class QAction; +class QMenuBar; +class QDialogButtonBox; +class QLabel; +class QObject; +class QScrollArea; +class QScrollBar; +class QStatusBar; +class LammpsWrapper; +class QComboBox; + +class SlideShow : public QDialog { + Q_OBJECT + +public: + explicit SlideShow(const QString &fileName, LammpsWrapper *_lammps, + QWidget *parent = nullptr); + +private slots: + void saveAs(); + void copy(); + void zoomIn(); + void zoomOut(); + void normalSize(); + void fitToWindow(); + +private: + void createActions(); + void updateActions(); + void saveFile(const QString &fileName); + void scaleImage(double factor); + void adjustScrollBar(QScrollBar *scrollBar, double factor); + +private: + QImage image; + QMenuBar *menuBar; + QLabel *imageLabel; + QScrollArea *scrollArea; + QDialogButtonBox *buttonBox; + double scaleFactor = 1.0; + + QAction *saveAsAct; + QAction *copyAct; + QAction *zoomInAct; + QAction *zoomOutAct; + QAction *normalSizeAct; + QAction *fitToWindowAct; + + LammpsWrapper *lammps; +}; +#endif + +// Local Variables: +// c-basic-offset: 4 +// End: