highlightingRules;
+ QRegularExpression isLattice1, isLattice2, isLattice3;
+ QRegularExpression isOutput1, isOutput2, isRead;
+ QTextCharFormat formatOutput, formatRead, formatLattice, formatSetup;
+ QRegularExpression isStyle, isForce, isDefine, isUndo;
+ QRegularExpression isParticle, isSetup, isRun;
+ QTextCharFormat formatParticle, formatRun, formatDefine;
+ QRegularExpression isVariable, isReference;
+ QTextCharFormat formatVariable;
+ QRegularExpression isNumber1, isNumber2, isNumber3, isNumber4;
+ QTextCharFormat formatNumber;
+ QRegularExpression isSpecial, isContinue;
+ QTextCharFormat formatSpecial;
+ QRegularExpression isComment;
+ QRegularExpression isQuotedComment;
+ QTextCharFormat formatComment;
+ QRegularExpression isTriple;
+ QRegularExpression isString;
+ QTextCharFormat formatString;
- QTextCharFormat outputFormat;
- QTextCharFormat readFormat;
- QTextCharFormat latticeFormat;
- QTextCharFormat particleFormat;
- QTextCharFormat setupFormat;
- QTextCharFormat runFormat;
- QTextCharFormat defineFormat;
-
- QTextCharFormat numberFormat;
- QTextCharFormat stringFormat;
- QTextCharFormat commentFormat;
+ int in_triple;
+ int startIndex;
};
#endif
// Local Variables:
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/imageviewer.cpp b/tools/lammps-gui/imageviewer.cpp
index 5afb02e5b1..139d73cb38 100644
--- a/tools/lammps-gui/imageviewer.cpp
+++ b/tools/lammps-gui/imageviewer.cpp
@@ -103,8 +103,10 @@ ImageViewer::ImageViewer(const QString &fileName, LammpsWrapper *_lammps, QWidge
connect(xval, &QAbstractSpinBox::editingFinished, this, &ImageViewer::edit_size);
connect(yval, &QAbstractSpinBox::editingFinished, this, &ImageViewer::edit_size);
+ // workaround for incorrect highlight bug on macOS
auto *dummy = new QPushButton(QIcon(), "");
dummy->hide();
+
auto *dossao = new QPushButton(QIcon(":/hd-img.png"), "");
dossao->setCheckable(true);
dossao->setToolTip("Toggle SSAO rendering");
@@ -190,6 +192,7 @@ ImageViewer::ImageViewer(const QString &fileName, LammpsWrapper *_lammps, QWidge
mainLayout->addLayout(menuLayout);
mainLayout->addWidget(scrollArea);
mainLayout->addWidget(buttonBox);
+ setWindowIcon(QIcon(":/lammps-icon-128x128.png"));
setWindowTitle(QString("Image Viewer: ") + QFileInfo(fileName).fileName());
createActions();
@@ -207,9 +210,7 @@ ImageViewer::ImageViewer(const QString &fileName, LammpsWrapper *_lammps, QWidge
resize(image.width() + 20, image.height() + 50);
scrollArea->setVisible(true);
- fitToWindowAct->setEnabled(true);
updateActions();
- if (!fitToWindowAct->isChecked()) imageLabel->adjustSize();
setLayout(mainLayout);
}
@@ -464,30 +465,6 @@ void ImageViewer::saveAs()
void ImageViewer::copy() {}
-void ImageViewer::zoomIn()
-{
- scaleImage(1.25);
-}
-
-void ImageViewer::zoomOut()
-{
- scaleImage(0.8);
-}
-
-void ImageViewer::normalSize()
-{
- imageLabel->adjustSize();
- scaleFactor = 1.0;
-}
-
-void ImageViewer::fitToWindow()
-{
- bool fitToWindow = fitToWindowAct->isChecked();
- scrollArea->setWidgetResizable(fitToWindow);
- if (!fitToWindow) normalSize();
- updateActions();
-}
-
void ImageViewer::saveFile(const QString &fileName)
{
if (!fileName.isEmpty()) image.save(fileName);
@@ -509,39 +486,12 @@ void ImageViewer::createActions()
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, &ImageViewer::zoomIn);
- zoomInAct->setShortcut(QKeySequence::ZoomIn);
- zoomInAct->setIcon(QIcon(":/gtk-zoom-in.png"));
- zoomInAct->setEnabled(false);
-
- zoomOutAct = viewMenu->addAction("Image Zoom &Out (25%)", this, &ImageViewer::zoomOut);
- zoomOutAct->setShortcut(QKeySequence::ZoomOut);
- zoomOutAct->setIcon(QIcon(":/gtk-zoom-out.png"));
- zoomOutAct->setEnabled(false);
-
- normalSizeAct = viewMenu->addAction("&Reset Image Size", this, &ImageViewer::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, &ImageViewer::fitToWindow);
- fitToWindowAct->setEnabled(false);
- fitToWindowAct->setCheckable(true);
- fitToWindowAct->setShortcut(QKeySequence::fromString("Ctrl+="));
}
void ImageViewer::updateActions()
{
saveAsAct->setEnabled(!image.isNull());
copyAct->setEnabled(!image.isNull());
- zoomInAct->setEnabled(!fitToWindowAct->isChecked());
- zoomOutAct->setEnabled(!fitToWindowAct->isChecked());
- normalSizeAct->setEnabled(!fitToWindowAct->isChecked());
}
void ImageViewer::scaleImage(double factor)
@@ -555,8 +505,6 @@ void ImageViewer::scaleImage(double factor)
adjustScrollBar(scrollArea->horizontalScrollBar(), factor);
adjustScrollBar(scrollArea->verticalScrollBar(), factor);
- zoomInAct->setEnabled(scaleFactor < 3.0);
- zoomOutAct->setEnabled(scaleFactor > 0.333);
}
void ImageViewer::adjustScrollBar(QScrollBar *scrollBar, double factor)
diff --git a/tools/lammps-gui/imageviewer.h b/tools/lammps-gui/imageviewer.h
index 3dbf3df324..013a90249f 100644
--- a/tools/lammps-gui/imageviewer.h
+++ b/tools/lammps-gui/imageviewer.h
@@ -40,10 +40,6 @@ public:
private slots:
void saveAs();
void copy();
- void zoomIn();
- void zoomOut();
- void normalSize();
- void fitToWindow();
void edit_size();
void reset_view();
diff --git a/tools/lammps-gui/lammpsgui.cpp b/tools/lammps-gui/lammpsgui.cpp
index d5fe1d043a..7966db61af 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);
@@ -307,6 +309,7 @@ LammpsGui::~LammpsGui()
delete chartwindow;
delete dirstatus;
delete varwindow;
+ delete slideshow;
}
void LammpsGui::new_document()
@@ -545,6 +548,10 @@ void LammpsGui::open_file(const QString &fileName)
dirstatus->setText(QString(" Directory: ") + current_dir);
status->setText("Ready.");
+ if (slideshow) {
+ delete slideshow;
+ slideshow = nullptr;
+ }
update_variables();
}
@@ -710,20 +717,25 @@ void LammpsGui::logupdate()
}
}
+ // get timestep
+ int step = 0;
+ void *ptr = lammps.last_thermo("step", 0);
+ if (ptr) {
+ if (lammps.extract_setting("bigint") == 4)
+ step = *(int *)ptr;
+ else
+ step = (int)*(int64_t *)ptr;
+ }
+
// extract cached thermo data
if (chartwindow) {
// thermo data is not yet valid during setup
void *ptr = lammps.last_thermo("setup", 0);
if (ptr && *(int *)ptr) return;
- ptr = lammps.last_thermo("step", 0);
+ ptr = lammps.last_thermo("num", 0);
if (ptr) {
- int step = 0;
- if (lammps.extract_setting("bigint") == 4)
- step = *(int *)ptr;
- else
- step = (int)*(int64_t *)ptr;
- int ncols = *(int *)lammps.last_thermo("num", 0);
+ int ncols = *(int *)ptr;
// check if the column assignment has changed
// if yes, delete charts and start over
@@ -768,6 +780,22 @@ void LammpsGui::logupdate()
}
}
}
+
+ // update list of available image file names
+
+ QString imagefile = (const char *)lammps.last_thermo("imagename", 0);
+ if (!imagefile.isEmpty()) {
+ if (!slideshow) {
+ slideshow = new SlideShow(current_file);
+ if (QSettings().value("viewslide", true).toBool())
+ slideshow->show();
+ else
+ slideshow->hide();
+ } else {
+ slideshow->setWindowTitle(QString("LAMMPS-GUI - Slide Show: ") + current_file);
+ }
+ slideshow->add_image(imagefile);
+ }
}
void LammpsGui::modified()
@@ -956,6 +984,12 @@ void LammpsGui::do_run(bool use_buffer)
else
chartwindow->hide();
+ if (slideshow) {
+ slideshow->setWindowTitle("LAMMPS-GUI - Slide Show");
+ slideshow->clear();
+ slideshow->hide();
+ }
+
logupdater = new QTimer(this);
connect(logupdater, &QTimer::timeout, this, &LammpsGui::logupdate);
logupdater->start(100);
@@ -982,6 +1016,15 @@ void LammpsGui::render_image()
imagewindow->show();
}
+void LammpsGui::view_slides()
+{
+ if (!slideshow) slideshow = new SlideShow(current_file);
+ if (slideshow->isVisible())
+ slideshow->hide();
+ else
+ slideshow->show();
+}
+
void LammpsGui::view_chart()
{
QSettings settings;
@@ -1068,6 +1111,7 @@ void LammpsGui::about()
QMessageBox msg;
msg.setWindowTitle("About LAMMPS");
+ msg.setWindowIcon(QIcon(":/lammps-icon-128x128.png"));
msg.setText(version.c_str());
msg.setInformativeText(info.c_str());
msg.setIconPixmap(QPixmap(":/lammps-icon-128x128.png").scaled(64, 64));
@@ -1087,6 +1131,7 @@ void LammpsGui::help()
{
QMessageBox msg;
msg.setWindowTitle("LAMMPS-GUI Quick Help");
+ msg.setWindowIcon(QIcon(":/lammps-icon-128x128.png"));
msg.setText("This is LAMMPS-GUI version " LAMMPS_GUI_VERSION "
");
msg.setInformativeText("LAMMPS GUI is a graphical text editor that is linked to the LAMMPS "
"library and thus can run LAMMPS directly using the contents of the "
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..a27d6abbea 100644
--- a/tools/lammps-gui/lammpsgui.qrc
+++ b/tools/lammps-gui/lammpsgui.qrc
@@ -1,49 +1,57 @@
+
-
- lammps-icon-128x128.png
- antialias.png
- application-calc.png
- application-exit.png
- application-plot.png
- axes-img.png
- document-new.png
- document-open-recent.png
- document-open.png
- document-revert.png
- document-save-as.png
- document-save.png
- edit-copy.png
- edit-cut.png
- edit-delete.png
- edit-paste.png
- edit-redo.png
- edit-undo.png
- emblem-photos.png
- gtk-go-down.png
- gtk-go-up.png
- gtk-zoom-fit.png
- gtk-zoom-in.png
- gtk-zoom-out.png
- hd-img.png
- help-about.png
- help-browser.png
- help-faq.png
- help_index.table
- object-rotate-left.png
- object-rotate-right.png
- ovito.png
- preferences-desktop-font.png
- preferences-desktop-personal.png
- preferences-desktop.png
- process-stop.png
- run-file.png
- system-box.png
- system-help.png
- system-run.png
- utilities-terminal.png
- vdw-style.png
- vmd.png
- window-close.png
- x-office-drawing.png
-
+
+ lammps-icon-128x128.png
+ antialias.png
+ application-calc.png
+ application-exit.png
+ application-plot.png
+ axes-img.png
+ document-new.png
+ document-open-recent.png
+ document-open.png
+ document-revert.png
+ document-save-as.png
+ document-save.png
+ edit-copy.png
+ edit-cut.png
+ edit-delete.png
+ edit-paste.png
+ edit-redo.png
+ edit-undo.png
+ emblem-photos.png
+ go-first.png
+ go-last.png
+ go-next-2.png
+ go-previous-2.png
+ gtk-go-down.png
+ gtk-go-up.png
+ gtk-zoom-fit.png
+ gtk-zoom-in.png
+ gtk-zoom-out.png
+ hd-img.png
+ help-about.png
+ help-browser.png
+ help-faq.png
+ help_index.table
+ image-x-generic.png
+ media-playback-start-2.png
+ media-playlist-repeat.png
+ object-rotate-left.png
+ object-rotate-right.png
+ ovito.png
+ preferences-desktop-font.png
+ preferences-desktop-personal.png
+ preferences-desktop.png
+ process-stop.png
+ run-file.png
+ system-box.png
+ system-help.png
+ system-run.png
+ utilities-terminal.png
+ vdw-style.png
+ vmd.png
+ window-close.png
+ x-office-drawing.png
+
diff --git a/tools/lammps-gui/lammpsgui.ui b/tools/lammps-gui/lammpsgui.ui
index 9ef6525f9b..77257b23c2 100644
--- a/tools/lammps-gui/lammpsgui.ui
+++ b/tools/lammps-gui/lammpsgui.ui
@@ -93,6 +93,7 @@
+
@@ -250,7 +251,7 @@
- View &Image
+ Create &Image
Ctrl+I
@@ -352,6 +353,17 @@
Ctrl+Shift+C
+
+
+
+
+
+ &Slide Show Window
+
+
+ Ctrl+L
+
+
diff --git a/tools/lammps-gui/media-playback-start-2.png b/tools/lammps-gui/media-playback-start-2.png
new file mode 100644
index 0000000000..82bfaea9a4
Binary files /dev/null and b/tools/lammps-gui/media-playback-start-2.png differ
diff --git a/tools/lammps-gui/media-playlist-repeat.png b/tools/lammps-gui/media-playlist-repeat.png
new file mode 100644
index 0000000000..8845699912
Binary files /dev/null and b/tools/lammps-gui/media-playlist-repeat.png differ
diff --git a/tools/lammps-gui/preferences.cpp b/tools/lammps-gui/preferences.cpp
index bdb7d39dbf..e4fc276912 100644
--- a/tools/lammps-gui/preferences.cpp
+++ b/tools/lammps-gui/preferences.cpp
@@ -78,6 +78,7 @@ Preferences::Preferences(LammpsWrapper *_lammps, QWidget *parent) :
layout->addWidget(tabWidget);
layout->addWidget(buttonBox);
setLayout(layout);
+ setWindowIcon(QIcon(":/lammps-icon-128x128.png"));
setWindowTitle("LAMMPS-GUI - Preferences");
resize(500, 400);
}
@@ -161,6 +162,8 @@ void Preferences::accept()
if (box) settings->setValue("viewlog", box->isChecked());
box = tabWidget->findChild("viewchart");
if (box) settings->setValue("viewchart", box->isChecked());
+ box = tabWidget->findChild("viewslide");
+ if (box) settings->setValue("viewslide", box->isChecked());
if (need_relaunch) {
QMessageBox msg(QMessageBox::Information, QString("Relaunching LAMMPS-GUI"),
@@ -192,6 +195,9 @@ GeneralTab::GeneralTab(QSettings *_settings, LammpsWrapper *_lammps, QWidget *pa
auto *pltv = new QCheckBox("Show chart window by default");
pltv->setObjectName("viewchart");
pltv->setCheckState(settings->value("viewchart", true).toBool() ? Qt::Checked : Qt::Unchecked);
+ auto *sldv = new QCheckBox("Show slide show window by default");
+ sldv->setObjectName("viewslide");
+ sldv->setCheckState(settings->value("viewslide", true).toBool() ? Qt::Checked : Qt::Unchecked);
auto *logr = new QCheckBox("Replace log window on new run");
logr->setObjectName("logreplace");
logr->setCheckState(settings->value("logreplace", false).toBool() ? Qt::Checked
@@ -232,6 +238,7 @@ GeneralTab::GeneralTab(QSettings *_settings, LammpsWrapper *_lammps, QWidget *pa
layout->addWidget(cite);
layout->addWidget(logv);
layout->addWidget(pltv);
+ layout->addWidget(sldv);
layout->addWidget(logr);
layout->addWidget(pltr);
layout->addWidget(imgr);
diff --git a/tools/lammps-gui/setvariables.cpp b/tools/lammps-gui/setvariables.cpp
index a63832fc57..fbbacb70bd 100644
--- a/tools/lammps-gui/setvariables.cpp
+++ b/tools/lammps-gui/setvariables.cpp
@@ -55,6 +55,7 @@ SetVariables::SetVariables(QList> &_vars, QWidget *paren
layout->addWidget(buttonBox);
setLayout(layout);
+ setWindowIcon(QIcon(":/lammps-icon-128x128.png"));
setWindowTitle("LAMMPS-GUI - Set Variables");
resize(300, 200);
}
diff --git a/tools/lammps-gui/slideshow.cpp b/tools/lammps-gui/slideshow.cpp
new file mode 100644
index 0000000000..a42a67f8a2
--- /dev/null
+++ b/tools/lammps-gui/slideshow.cpp
@@ -0,0 +1,280 @@
+/* ----------------------------------------------------------------------
+ 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
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+SlideShow::SlideShow(const QString &fileName, QWidget *parent) :
+ QDialog(parent), playtimer(nullptr), imageLabel(new QLabel), imageName(new QLabel("(none)")),
+ do_loop(true)
+{
+ imageLabel->setBackgroundRole(QPalette::Base);
+ imageLabel->setScaledContents(false);
+ imageLabel->setMinimumSize(100, 100);
+
+ imageName->setFrameStyle(QFrame::Raised);
+ imageName->setFrameShape(QFrame::Panel);
+ imageName->setAlignment(Qt::AlignCenter);
+ imageName->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+ auto *shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_W), this);
+ QObject::connect(shortcut, &QShortcut::activated, this, &SlideShow::close);
+
+ buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
+
+ connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
+ connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
+
+ auto *mainLayout = new QVBoxLayout;
+ auto *navLayout = new QHBoxLayout;
+ auto *botLayout = new QHBoxLayout;
+
+ // workaround for incorrect highlight bug on macOS
+ auto *dummy = new QPushButton(QIcon(), "");
+ dummy->hide();
+
+ auto *gofirst = new QPushButton(QIcon(":/go-first.png"), "");
+ gofirst->setToolTip("Go to first Image");
+ auto *goprev = new QPushButton(QIcon(":/go-previous-2.png"), "");
+ goprev->setToolTip("Go to previous Image");
+ auto *goplay = new QPushButton(QIcon(":/media-playback-start-2.png"), "");
+ goplay->setToolTip("Play animation");
+ goplay->setCheckable(true);
+ goplay->setChecked(playtimer);
+ goplay->setObjectName("play");
+ auto *gonext = new QPushButton(QIcon(":/go-next-2.png"), "");
+ gonext->setToolTip("Go to next Image");
+ auto *golast = new QPushButton(QIcon(":/go-last.png"), "");
+ golast->setToolTip("Go to last Image");
+ auto *goloop = new QPushButton(QIcon(":/media-playlist-repeat.png"), "");
+ goloop->setToolTip("Loop animation");
+ goloop->setCheckable(true);
+ goloop->setChecked(do_loop);
+
+ auto *zoomin = new QPushButton(QIcon(":/gtk-zoom-in.png"), "");
+ zoomin->setToolTip("Zoom in by 10 percent");
+ auto *zoomout = new QPushButton(QIcon(":/gtk-zoom-out.png"), "");
+ zoomout->setToolTip("Zoom out by 10 percent");
+ auto *normal = new QPushButton(QIcon(":/gtk-zoom-fit.png"), "");
+ normal->setToolTip("Reset zoom to normal");
+
+ connect(gofirst, &QPushButton::released, this, &SlideShow::first);
+ connect(goprev, &QPushButton::released, this, &SlideShow::prev);
+ connect(goplay, &QPushButton::released, this, &SlideShow::play);
+ connect(gonext, &QPushButton::released, this, &SlideShow::next);
+ connect(golast, &QPushButton::released, this, &SlideShow::last);
+ connect(goloop, &QPushButton::released, this, &SlideShow::loop);
+ connect(zoomin, &QPushButton::released, this, &SlideShow::zoomIn);
+ connect(zoomout, &QPushButton::released, this, &SlideShow::zoomOut);
+ connect(gofirst, &QPushButton::released, this, &SlideShow::first);
+ connect(normal, &QPushButton::released, this, &SlideShow::normalSize);
+
+ navLayout->addSpacerItem(new QSpacerItem(10, 10, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ navLayout->addWidget(dummy);
+ navLayout->addWidget(gofirst);
+ navLayout->addWidget(goprev);
+ navLayout->addWidget(goplay);
+ navLayout->addWidget(gonext);
+ navLayout->addWidget(golast);
+ navLayout->addWidget(goloop);
+
+ navLayout->addWidget(zoomin);
+ navLayout->addWidget(zoomout);
+ navLayout->addWidget(normal);
+
+ mainLayout->addWidget(imageLabel);
+ mainLayout->addLayout(navLayout);
+
+ botLayout->addWidget(imageName);
+ botLayout->addWidget(buttonBox);
+ botLayout->setStretch(0, 3);
+ mainLayout->addLayout(botLayout);
+
+ setWindowIcon(QIcon(":/lammps-icon-128x128.png"));
+ setWindowTitle(QString("LAMMPS-GUI - Slide Show: ") + QFileInfo(fileName).fileName());
+
+ imagefiles.clear();
+ scaleFactor = 1.0;
+ current = 0;
+
+ auto maxsize = QGuiApplication::primaryScreen()->availableSize() * 4 / 5;
+ maxheight = maxsize.height();
+ maxwidth = maxsize.width();
+
+ setLayout(mainLayout);
+}
+
+void SlideShow::add_image(const QString &filename)
+{
+ if (!imagefiles.contains(filename)) {
+ int lastidx = imagefiles.size();
+ imagefiles.append(filename);
+ loadImage(lastidx);
+ }
+}
+
+void SlideShow::clear()
+{
+ imagefiles.clear();
+ image.fill(Qt::black);
+ imageLabel->setPixmap(QPixmap::fromImage(image));
+ imageLabel->adjustSize();
+ imageName->setText("(none)");
+ repaint();
+}
+
+void SlideShow::loadImage(int idx)
+{
+ if ((idx < 0) || (idx >= imagefiles.size())) return;
+
+ do {
+ QImageReader reader(imagefiles[idx]);
+ reader.setAutoTransform(true);
+ const QImage newImage = reader.read();
+
+ // There was an error reading the image file. Try reading the previous image instead.
+ if (newImage.isNull()) {
+ --idx;
+ } else {
+ int newheight = (int)newImage.height() * scaleFactor;
+ int newwidth = (int)newImage.width() * scaleFactor;
+ image = newImage.scaled(newwidth, newheight, Qt::IgnoreAspectRatio,
+ Qt::SmoothTransformation);
+ imageLabel->setPixmap(QPixmap::fromImage(image));
+ imageLabel->setMinimumSize(newwidth, newheight);
+ imageName->setText(QString(" Image %1 / %2 : %3 ")
+ .arg(idx + 1)
+ .arg(imagefiles.size())
+ .arg(imagefiles[idx]));
+ adjustSize();
+ current = idx;
+ break;
+ }
+ } while (idx >= 0);
+}
+
+void SlideShow::first()
+{
+ current = 0;
+ loadImage(current);
+}
+
+void SlideShow::last()
+{
+ current = imagefiles.size() - 1;
+ loadImage(current);
+}
+
+void SlideShow::play()
+{
+ // if we do not loop, start animation from beginning
+ if (!do_loop) current = 0;
+
+ if (playtimer) {
+ playtimer->stop();
+ delete playtimer;
+ playtimer = nullptr;
+ } else {
+ playtimer = new QTimer(this);
+ connect(playtimer, &QTimer::timeout, this, &SlideShow::next);
+ playtimer->start(100);
+ }
+
+ // reset push button state. use findChild() if not triggered from button.
+ QPushButton *button = qobject_cast(sender());
+ if (!button) button = findChild("play");
+ if (button) button->setChecked(playtimer);
+}
+
+void SlideShow::next()
+{
+ ++current;
+ if (current >= imagefiles.size()) {
+ if (do_loop) {
+ current = 0;
+ } else {
+ // stop animation
+ if (playtimer) play();
+ --current;
+ }
+ }
+ loadImage(current);
+}
+
+void SlideShow::prev()
+{
+ --current;
+ if (current < 0) {
+ if (do_loop)
+ current = imagefiles.size() - 1;
+ else
+ current = 0;
+ }
+ loadImage(current);
+}
+
+void SlideShow::loop()
+{
+ QPushButton *button = qobject_cast(sender());
+ do_loop = !do_loop;
+ button->setChecked(do_loop);
+}
+
+void SlideShow::zoomIn()
+{
+ scaleImage(1.1);
+}
+
+void SlideShow::zoomOut()
+{
+ scaleImage(0.9);
+}
+
+void SlideShow::normalSize()
+{
+ scaleFactor = 1.0;
+ scaleImage(1.0);
+}
+
+void SlideShow::scaleImage(double factor)
+{
+ // compute maxfactor so the image is not scaled beyond 80 of width or height of screen
+ double maxfactor = 10.0;
+ maxfactor = qMin((double)maxheight / (double)image.height(), maxfactor);
+ maxfactor = qMin((double)maxwidth / (double)image.width(), maxfactor);
+
+ if (factor > maxfactor) factor = maxfactor;
+ scaleFactor *= factor;
+ if (scaleFactor < 0.25) scaleFactor = 0.25;
+
+ loadImage(current);
+}
+
+// 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..fe357ec564
--- /dev/null
+++ b/tools/lammps-gui/slideshow.h
@@ -0,0 +1,65 @@
+/* -*- 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 QDialogButtonBox;
+class QLabel;
+class QTimer;
+
+class SlideShow : public QDialog {
+ Q_OBJECT
+
+public:
+ explicit SlideShow(const QString &fileName, QWidget *parent = nullptr);
+ void add_image(const QString &filename);
+ void clear();
+
+private slots:
+ void first();
+ void last();
+ void next();
+ void prev();
+ void play();
+ void loop();
+ void zoomIn();
+ void zoomOut();
+ void normalSize();
+
+private:
+ void scaleImage(double factor);
+ void loadImage(int idx);
+
+private:
+ QImage image;
+ QTimer *playtimer;
+ QLabel *imageLabel, *imageName;
+ QDialogButtonBox *buttonBox;
+ double scaleFactor = 1.0;
+
+ int current;
+ int maxwidth, maxheight;
+ bool do_loop;
+ QStringList imagefiles;
+};
+#endif
+
+// Local Variables:
+// c-basic-offset: 4
+// End:
diff --git a/unittest/formats/test_atom_styles.cpp b/unittest/formats/test_atom_styles.cpp
index 689a9f4735..4ad571f9fa 100644
--- a/unittest/formats/test_atom_styles.cpp
+++ b/unittest/formats/test_atom_styles.cpp
@@ -533,7 +533,7 @@ TEST_F(AtomStyleTest, atomic)
ASSERT_NE(lmp->atom->mass_setflag, nullptr);
ASSERT_NE(lmp->atom->sametag, nullptr);
ASSERT_EQ(lmp->atom->map_style, Atom::MAP_HASH);
- ASSERT_EQ(lmp->atom->map_user, 2);
+ ASSERT_EQ(lmp->atom->map_user, Atom::MAP_HASH);
ASSERT_EQ(lmp->atom->map_tag_max, 4);
BEGIN_HIDE_OUTPUT();
command("pair_coeff * *");
@@ -587,7 +587,7 @@ TEST_F(AtomStyleTest, atomic)
ASSERT_EQ(lmp->atom->mass_setflag[1], 1);
ASSERT_EQ(lmp->atom->mass_setflag[2], 1);
ASSERT_EQ(lmp->atom->map_style, Atom::MAP_ARRAY);
- ASSERT_EQ(lmp->atom->map_user, 1);
+ ASSERT_EQ(lmp->atom->map_user, Atom::MAP_ARRAY);
ASSERT_EQ(lmp->atom->map_tag_max, 4);
ASSERT_EQ(lmp->atom->tag_consecutive(), 1);
@@ -597,6 +597,7 @@ TEST_F(AtomStyleTest, atomic)
command("delete_atoms group two compress no");
command("write_restart test_atom_styles.restart");
command("clear");
+ command("atom_modify map hash");
command("read_restart test_atom_styles.restart");
END_HIDE_OUTPUT();
ASSERT_THAT(std::string(lmp->atom->atom_style), Eq("atomic"));
@@ -629,8 +630,8 @@ TEST_F(AtomStyleTest, atomic)
EXPECT_NEAR(lmp->atom->mass[2], 2.4, EPSILON);
ASSERT_EQ(lmp->atom->mass_setflag[1], 1);
ASSERT_EQ(lmp->atom->mass_setflag[2], 1);
- ASSERT_EQ(lmp->atom->map_style, Atom::MAP_ARRAY);
- ASSERT_EQ(lmp->atom->map_user, 1);
+ ASSERT_EQ(lmp->atom->map_style, Atom::MAP_HASH);
+ ASSERT_EQ(lmp->atom->map_user, Atom::MAP_HASH);
ASSERT_EQ(lmp->atom->map_tag_max, 3);
BEGIN_HIDE_OUTPUT();
command("reset_atom_ids");
@@ -4561,8 +4562,8 @@ TEST_F(AtomStyleTest, property_atom)
expected.atom_style = "atomic";
expected.molecular = Atom::ATOMIC;
expected.tag_enable = 1;
- expected.map_style = 1;
- expected.map_user = 1;
+ expected.map_style = Atom::MAP_ARRAY;
+ expected.map_user = Atom::MAP_ARRAY;
expected.has_type = true;
expected.has_image = true;
expected.has_mask = true;
@@ -4663,7 +4664,7 @@ TEST_F(AtomStyleTest, property_atom)
ASSERT_NE(lmp->atom->sametag, nullptr);
ASSERT_EQ(lmp->atom->tag_consecutive(), 1);
ASSERT_EQ(lmp->atom->map_style, Atom::MAP_ARRAY);
- ASSERT_EQ(lmp->atom->map_user, 1);
+ ASSERT_EQ(lmp->atom->map_user, Atom::MAP_ARRAY);
ASSERT_EQ(lmp->atom->map_tag_max, 4);
auto x = lmp->atom->x;
@@ -4751,6 +4752,7 @@ TEST_F(AtomStyleTest, property_atom)
expected.has_ianame = true;
expected.has_daname = true;
expected.nextra_store = 12;
+ expected.map_user = Atom::MAP_NONE;
ASSERT_ATOM_STATE_EQ(lmp->atom, expected);
ASSERT_NE(lmp->atom->avec, nullptr);