Skip to content

Commit

Permalink
Merge pull request #1320 from ghutchis/add-plugin-script-points
Browse files Browse the repository at this point in the history
Add extension and tool register / handle commands for scripts
  • Loading branch information
ghutchis authored Jul 26, 2023
2 parents b13a324 + a0211c2 commit d523fba
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 58 deletions.
30 changes: 13 additions & 17 deletions avogadro/qtgui/extensionplugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,34 @@

namespace Avogadro::QtGui {

ExtensionPlugin::ExtensionPlugin(QObject* parent_) : QObject(parent_)
{
}
ExtensionPlugin::ExtensionPlugin(QObject* parent_) : QObject(parent_) {}

ExtensionPlugin::~ExtensionPlugin()
{
}
ExtensionPlugin::~ExtensionPlugin() {}

QList<Io::FileFormat*> ExtensionPlugin::fileFormats() const
{
return QList<Io::FileFormat*>();
}

ExtensionPluginFactory::~ExtensionPluginFactory()
{
}
ExtensionPluginFactory::~ExtensionPluginFactory() {}

bool ExtensionPlugin::readMolecule(Molecule&)
{
return false;
}

void ExtensionPlugin::setScene(Rendering::Scene*)
{
}
void ExtensionPlugin::setScene(Rendering::Scene*) {}

void ExtensionPlugin::setCamera(Rendering::Camera* camera)
{
}
void ExtensionPlugin::setCamera(Rendering::Camera* camera) {}

void ExtensionPlugin::setActiveWidget(QWidget* widget) {}

void ExtensionPlugin::setActiveWidget(QWidget* widget)
bool ExtensionPlugin::handleCommand(const QString& command,
const QVariantMap& options)
{
Q_UNUSED(command);
Q_UNUSED(options);
return false;
}

} // End Avogadro namespace
} // namespace Avogadro::QtGui
29 changes: 26 additions & 3 deletions avogadro/qtgui/extensionplugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class Molecule;
namespace Rendering {
class Camera;
class Scene;
}
} // namespace Rendering

namespace Io {
class FileFormat;
Expand Down Expand Up @@ -103,6 +103,18 @@ public slots:
*/
virtual void setActiveWidget(QWidget* widget);

/**
* Called by the app to handle a command registered by the extension.
* (e.g., "renderMovie" or "generateSurface", etc.)
*
* The app will turn the command into a string and pass it to the extension.
* and any options will go from a JSON dictionary to a QVariantMap.
*
* @return true if the command was handled, false otherwise.
*/
virtual bool handleCommand(const QString& command,
const QVariantMap& options);

signals:
/**
* Signal that the extension has a new molecule that is ready to be loaded.
Expand Down Expand Up @@ -131,6 +143,17 @@ public slots:
* would be most readily viewed with a specialized view.
*/
void requestActiveDisplayTypes(QStringList displayTypes);

/**
* Register a new command with the application. The command will be available
* through scripting (e.g., "renderMovie" or "generateSurface", etc.)
*
* @param command The name of the command to register.
* @param description A description of the command.
*
* @sa handleCommand
*/
void registerCommand(QString command, QString description);
};

/**
Expand All @@ -146,8 +169,8 @@ class AVOGADROQTGUI_EXPORT ExtensionPluginFactory
~ExtensionPluginFactory() override;
};

} // End QtGui namespace
} // End Avogadro namespace
} // namespace QtGui
} // namespace Avogadro

Q_DECLARE_INTERFACE(Avogadro::QtGui::ExtensionPluginFactory,
"org.openchemistry.avogadro.ExtensionPluginFactory")
Expand Down
22 changes: 11 additions & 11 deletions avogadro/qtgui/toolplugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,9 @@

namespace Avogadro::QtGui {

ToolPlugin::ToolPlugin(QObject* parent_) : QObject(parent_)
{
}
ToolPlugin::ToolPlugin(QObject* parent_) : QObject(parent_) {}

ToolPlugin::~ToolPlugin()
{
}
ToolPlugin::~ToolPlugin() {}

QUndoCommand* ToolPlugin::mousePressEvent(QMouseEvent*)
{
Expand Down Expand Up @@ -50,12 +46,16 @@ QUndoCommand* ToolPlugin::keyReleaseEvent(QKeyEvent*)
return nullptr;
}

void ToolPlugin::draw(Rendering::GroupNode&)
{
}
void ToolPlugin::draw(Rendering::GroupNode&) {}

ToolPluginFactory::~ToolPluginFactory()
bool ToolPlugin::handleCommand(const QString& command,
const QVariantMap& options)
{
Q_UNUSED(command);
Q_UNUSED(options);
return false;
}

} // End Avogadro namespace
ToolPluginFactory::~ToolPluginFactory() {}

} // namespace Avogadro::QtGui
31 changes: 27 additions & 4 deletions avogadro/qtgui/toolplugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ namespace Avogadro {
namespace Rendering {
class GroupNode;
class GLRenderer;
}
} // namespace Rendering

namespace QtOpenGL {
class GLWidget;
Expand Down Expand Up @@ -91,6 +91,18 @@ class AVOGADROQTGUI_EXPORT ToolPlugin : public QObject
*/
virtual void draw(Rendering::GroupNode& node);

/**
* Called by the app to handle a command registered by the plugin.
* (e.g., "renderMovie" or "drawAtom", etc.)
*
* The app will turn the command into a string and pass it to the tool.
* and any options will go from a JSON dictionary to a QVariantMap.
*
* @return true if the command was handled, false otherwise.
*/
virtual bool handleCommand(const QString& command,
const QVariantMap& options);

signals:
/**
* Emitted when draw() needs to be called again due to updates.
Expand All @@ -103,6 +115,17 @@ class AVOGADROQTGUI_EXPORT ToolPlugin : public QObject
*/
void updateRequested();

/**
* Register a new command with the application. The command will be available
* through scripting (e.g., "renderMovie" or "generateSurface", etc.)
*
* @param command The name of the command to register.
* @param description A description of the command.
*
* @sa handleCommand
*/
void registerCommand(QString command, QString description);

public slots:
/**
* Called when the current molecule changes.
Expand Down Expand Up @@ -137,12 +160,12 @@ class AVOGADROQTGUI_EXPORT ToolPluginFactory
public:
virtual ~ToolPluginFactory();

virtual ToolPlugin* createInstance(QObject *parent = nullptr) = 0;
virtual ToolPlugin* createInstance(QObject* parent = nullptr) = 0;
virtual QString identifier() const = 0;
};

} // End QtGui namespace
} // End Avogadro namespace
} // namespace QtGui
} // namespace Avogadro

Q_DECLARE_INTERFACE(Avogadro::QtGui::ToolPluginFactory,
"org.openchemistry.avogadro.ToolPluginFactory")
Expand Down
89 changes: 68 additions & 21 deletions avogadro/qtplugins/spectra/spectra.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
#include <avogadro/core/array.h>
#include <avogadro/core/variant.h>
#include <avogadro/core/vector.h>
#include <avogadro/qtgui/molecule.h>

#include <QtCore/QTimer>
#include <QAction>
#include <QDebug>
#include <QtCore/QTimer>
#include <QtWidgets/QFileDialog>
#include <avogadro/qtgui/molecule.h>

namespace Avogadro::QtPlugins {

Expand All @@ -26,12 +27,20 @@ Spectra::Spectra(QObject* p)
action->setText(tr("Vibrational Modes…"));
connect(action, SIGNAL(triggered()), SLOT(openDialog()));
m_actions.push_back(action);
}

Spectra::~Spectra()
{
emit registerCommand("showVibrations",
tr("Show the vibrational modes dialog."));
emit registerCommand("setVibrationalMode", tr("Set the vibrational mode."));
emit registerCommand("setVibrationalAmplitude",
tr("Set the vibrational amplitude."));
emit registerCommand("startVibrationAnimation",
tr("Start the vibrational animation."));
emit registerCommand("stopVibrationAnimation",
tr("Stop the vibrational animation."));
}

Spectra::~Spectra() {}

QList<QAction*> Spectra::actions() const
{
return m_actions;
Expand All @@ -54,6 +63,37 @@ void Spectra::setMolecule(QtGui::Molecule* mol)
m_molecule = mol;
if (m_dialog)
m_dialog->setMolecule(mol);

if (isVibrational)
openDialog();
}

bool Spectra::handleCommand(const QString& command, const QVariantMap& options)
{
if (m_molecule == nullptr)
return false; // No molecule to handle the command.

if (command == "showVibrations") {
openDialog();
return true;
} else if (command == "setVibrationalMode") {
if (options.contains("mode")) {
setMode(options["mode"].toInt());
return true;
}
} else if (command == "setVibrationalAmplitude") {
if (options.contains("amplitude")) {
setAmplitude(options["amplitude"].toInt());
return true;
}
} else if (command == "startVibrationAnimation") {
startVibrationAnimation();
return true;
} else if (command == "stopVibrationAnimation") {
stopVibrationAnimation();
return true;
}
return false;
}

void Spectra::setMode(int mode)
Expand All @@ -66,50 +106,57 @@ void Spectra::setMode(int mode)
m_molecule->setCoordinate3d(0);
Core::Array<Vector3> atomPositions = m_molecule->atomPositions3d();
Core::Array<Vector3> atomDisplacements = m_molecule->vibrationLx(mode);
// TODO: needs an option (show forces or not)
double factor = 0.01 * m_amplitude;
Index atom = 0;
for (Vector3& v : atomDisplacements) {
v *= 10.0 * factor;
m_molecule->setForceVector(atom, v);
++atom;
}
m_molecule->emitChanged(QtGui::Molecule::Atoms | QtGui::Molecule::Added);

int frames = 5;
int frames = 5; // TODO: needs an option
int frameCounter = 0;
m_molecule->setCoordinate3d(atomPositions, frameCounter++);

double factor = 0.01 * m_amplitude;

// Current coords + displacement.
for (int i = 1; i <= frames; ++i) {
Core::Array<Vector3> framePositions;
for (Index atom = 0; atom < m_molecule->atomCount(); ++atom) {
framePositions.push_back(atomPositions[atom] +
atomDisplacements[atom] * factor *
(double(i) / frames));
framePositions.push_back(atomPositions[atom] + atomDisplacements[atom] *
factor *
(double(i) / frames));
}
m_molecule->setCoordinate3d(framePositions, frameCounter++);
}
// + displacement back to original.
for (int i = frames - 1; i >= 0; --i) {
Core::Array<Vector3> framePositions;
for (Index atom = 0; atom < m_molecule->atomCount(); ++atom) {
framePositions.push_back(atomPositions[atom] +
atomDisplacements[atom] * factor *
(double(i) / frames));
framePositions.push_back(atomPositions[atom] + atomDisplacements[atom] *
factor *
(double(i) / frames));
}
m_molecule->setCoordinate3d(framePositions, frameCounter++);
}
// Current coords - displacement.
for (int i = 1; i <= frames; ++i) {
Core::Array<Vector3> framePositions;
for (Index atom = 0; atom < m_molecule->atomCount(); ++atom) {
framePositions.push_back(atomPositions[atom] -
atomDisplacements[atom] * factor *
(double(i) / frames));
framePositions.push_back(atomPositions[atom] - atomDisplacements[atom] *
factor *
(double(i) / frames));
}
m_molecule->setCoordinate3d(framePositions, frameCounter++);
}
// - displacement back to original.
for (int i = frames - 1; i >= 0; --i) {
Core::Array<Vector3> framePositions;
for (Index atom = 0; atom < m_molecule->atomCount(); ++atom) {
framePositions.push_back(atomPositions[atom] -
atomDisplacements[atom] * factor *
(double(i) / frames));
framePositions.push_back(atomPositions[atom] - atomDisplacements[atom] *
factor *
(double(i) / frames));
}
m_molecule->setCoordinate3d(framePositions, frameCounter++);
}
Expand Down Expand Up @@ -169,4 +216,4 @@ void Spectra::advanceFrame()
m_molecule->setCoordinate3d(m_currentFrame);
m_molecule->emitChanged(QtGui::Molecule::Atoms | QtGui::Molecule::Added);
}
}
} // namespace Avogadro::QtPlugins
7 changes: 5 additions & 2 deletions avogadro/qtplugins/spectra/spectra.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ class Spectra : public QtGui::ExtensionPlugin

void setMolecule(QtGui::Molecule* mol) override;

bool handleCommand(const QString& command,
const QVariantMap& options) override;

public slots:
void setMode(int mode);
void setAmplitude(int amplitude);
Expand All @@ -66,7 +69,7 @@ private slots:
int m_mode;
int m_amplitude;
};
}
}
} // namespace QtPlugins
} // namespace Avogadro

#endif // AVOGADRO_QTPLUGINS_Spectra_H

0 comments on commit d523fba

Please sign in to comment.