/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2010 University of Bonn. All rights reserved. * Please see the LICENSE file or "Copyright notice" in builder.cpp for details. */ /* * TranslateAction.cpp * * Created on: May 10, 2010 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "Helpers/MemDebug.hpp" #include "Actions/AtomAction/TranslateAction.hpp" #include "Actions/ActionRegistry.hpp" #include "Helpers/Log.hpp" #include "atom.hpp" #include "LinearAlgebra/Vector.hpp" #include "Helpers/Verbose.hpp" #include "World.hpp" #include #include #include using namespace std; #include "UIElements/UIFactory.hpp" #include "UIElements/Dialog.hpp" #include "Actions/ValueStorage.hpp" /****** AtomTranslateAction *****/ // memento to remember the state when undoing class AtomTranslateState : public ActionState { public: AtomTranslateState(const std::vector &_selectedAtoms, const Vector &_v, const bool _periodic) : selectedAtoms(_selectedAtoms), v(_v), periodic(_periodic) {} std::vector selectedAtoms; Vector v; bool periodic; }; const char AtomTranslateAction::NAME[] = "translate-atoms"; AtomTranslateAction::AtomTranslateAction() : Action(NAME) {} AtomTranslateAction::~AtomTranslateAction() {} void AtomTranslate(Vector &x, bool periodic = false) { ValueStorage::getInstance().setCurrentValue(AtomTranslateAction::NAME, x); ValueStorage::getInstance().setCurrentValue("periodic", periodic); ActionRegistry::getInstance().getActionByName(AtomTranslateAction::NAME)->call(Action::NonInteractive); }; Dialog* AtomTranslateAction::fillDialog(Dialog *dialog) { ASSERT(dialog,"No Dialog given when filling action dialog"); dialog->queryVector(NAME, false, ValueStorage::getInstance().getDescription(NAME)); dialog->queryBoolean("periodic", ValueStorage::getInstance().getDescription("periodic")); return dialog; } Action::state_ptr AtomTranslateAction::performCall() { Vector v; bool periodic = false; Box &domain = World::getInstance().getDomain(); std::vector selectedAtoms = World::getInstance().getSelectedAtoms(); ValueStorage::getInstance().queryCurrentValue(NAME, v); if (!ValueStorage::getInstance().queryCurrentValue("periodic", periodic, true)) periodic = false; // TODO: use AtomSet::translate for (std::vector::iterator iter = selectedAtoms.begin(); iter != selectedAtoms.end(); ++iter) { *(*iter) += v; if (periodic) (*iter)->setPosition(domain.WrapPeriodically((*iter)->getPosition())); } return Action::state_ptr(new AtomTranslateState(selectedAtoms, v, periodic)); } Action::state_ptr AtomTranslateAction::performUndo(Action::state_ptr _state) { AtomTranslateState *state = assert_cast(_state.get()); Box &domain = World::getInstance().getDomain(); for (std::vector::iterator iter = state->selectedAtoms.begin(); iter != state->selectedAtoms.end(); ++iter) { *(*iter) -= state->v; if (state->periodic) (*iter)->setPosition(domain.WrapPeriodically((*iter)->getPosition())); } return Action::state_ptr(_state); } Action::state_ptr AtomTranslateAction::performRedo(Action::state_ptr _state){ AtomTranslateState *state = assert_cast(_state.get()); Box &domain = World::getInstance().getDomain(); for (std::vector::iterator iter = state->selectedAtoms.begin(); iter != state->selectedAtoms.end(); ++iter) { *(*iter) += state->v; if (state->periodic) (*iter)->setPosition(domain.WrapPeriodically((*iter)->getPosition())); } return Action::state_ptr(_state); } bool AtomTranslateAction::canUndo() { return true; } bool AtomTranslateAction::shouldUndo() { return true; } const string AtomTranslateAction::getName() { return NAME; }