In this tutorial, you will learn how to program an Editor that pushes atoms in the viewport. Our editor will be a sphere, that when active pushes atoms.
The source code for an Element created in this tutorial can be found at https://github.com/1A-OneAngstrom/SAMSON-Developer-Tutorials.
We will start by creating a new SAMSON Element called AtomPusher thanks to the SAMSON Element generator (please, refer to the SAMSON Element generator tutorial for a reminder on how to use it):
SEAtomPusherEditor
);The SAMSON Element generator generates an editor class (derived from the SBGEditor class) and a property widget class for the editor.
Open the header file of the editor descriptor (file: SEAtomPusherEditorDescriptor.hpp) and modify the class description:
Modify the getName
function for both the editor class (file: SEAtomPusherEditor.cpp) and the editor GUI class (file: SEAtomPusherEditorGUI.cpp) to have a user-friendly description of the editor inside SAMSON:
Add the getDescription
function in the editor class (file: SEAtomPusherEditor.hpp)
And implement it as follows to have a user-friendly description of the editor in the menu:
Modify the getToolTip
function in the editor class (file: SEAtomPusherEditor.cpp) to have a user-friendly description of what the editor does:
Now, try building the SAMSON Element and when you launch SAMSON you should be able to find it in the App menu or in the toolbar. For now, it has no interface and does nothing, but we will now add functionality to it.
The SAMSON Element generator provides a GUI class (a property widget) for an editor which can be invoked by double-clicking on the editor's icon in the toolbar.
If your editor does not require GUI, you can disable it by simply commenting the creation and destruction of the property widget in the constructor and in the destructor of the editor class, respectively.
Since our editor is a sphere which can be in two states (active or not), we add the following variables in the editor class (file: SEAtomPusherEditor.hpp):
And we initialize them in the constructor of the editor class:
Let's now create a visual representation of our editor, the sphere. For that we implement the display
function in the editor class (file: SEAtomPusherEditor.cpp):
Here, we fill in arrays for position of the sphere, its radius, and color, which we send to the SAMSON::displaySpheres function that will render the sphere in SAMSON's viewport.
If you want your editor to cast shadows, you can implement the displayForShadow
function as well by just invoking the display
function in it (see Casting shadows for more information):
In the display
function we used the sphere's position, to know this position we need to implement the mouseMoveEvent
function in the editor class (file: SEAtomPusherEditorGUI.cpp):
Here, we set the shpere's position from the cursor position in the viewport.
Now, try building the Element and when you launch SAMSON you should be able to find it in the Edit > Editor menu or in the editor toolbar. For now, it has no editing functionality, but you should be able to see the editor's sphere in the SAMSON's viewport once select the editor and move the mouse in the viewport.
SAMSON redirects Qt events to the active editor (see the Editors section for more information). The editor class provides a number of possibilities to handle the GUI interactions:
mousePressEvent
- handles mouse press event;mouseReleaseEvent
- handles mouse release event;mouseMoveEvent
- handles mouse move event;mouseDoubleClickEvent
- handles mouse double click event;wheelEvent
- handles wheel event;keyPressEvent
- handles key press event;keyReleaseEvent
- handles key release event.Since our sphere will be pushing atoms only when it is active. We assume that our editor is active when the mouse button is pressed. For that, we implement mousePressEvent
and mouseReleaseEvent
functions as follows:
Add a function in the editor class (file: SEAtomPusherEditor.hpp) to push atoms
And implement it as follows:
First, we check whether the sphere is active (the sphere pushes atoms only in the active state). We get a node indexer of all atoms in the active documents. Then we get the position of an atom and check whether it is touched by the sphere, if so we push it in the direction from the sphere.
Before, we implemented the mouseMoveEvent
function in the editor class to update the sphere's position when the cursor moves. Let's now re-implement this function to handle the mouse movement for pushing atoms:
First, we update the sphere's position and then me invoke the pushAtoms
function.
We also make it possible to change the sphere's radius through the wheel event by implementing the according function in the editor class:
Note, that by invoking the pushAtoms
function in the end we also take into account that the sphere might be at the same time in the active state pushing atoms.
Now, you have a working editor for pushing atoms. Build the Element, launch SAMSON, load or create any molecule, and choose the developed editor either from the editor's toolbar or from the Edit > Editors menu. Try moving the editor around, activating it, pushing atoms, and changing the sphere's radius.