Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add extension and tool register / handle commands for scripts #1320

Merged
merged 3 commits into from
Jul 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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