diff --git a/Core/Code/Interactions/mitkEventFactory.cpp b/Core/Code/Interactions/mitkEventFactory.cpp index 762bf34974..26f46502b8 100755 --- a/Core/Code/Interactions/mitkEventFactory.cpp +++ b/Core/Code/Interactions/mitkEventFactory.cpp @@ -1,230 +1,479 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkEventFactory.h" #include #include #include #include #include #include #include #include #include #include #include #include namespace { - std::vector &split(const std::string &s, char delim, std::vector &elems) +std::vector &split(const std::string &s, char delim, std::vector &elems) +{ + std::stringstream ss(s); + std::string item; + while (std::getline(ss, item, delim)) { - std::stringstream ss(s); - std::string item; - while (std::getline(ss, item, delim)) - { - elems.push_back(item); - } - return elems; + elems.push_back(item); } + return elems; +} - std::vector split(const std::string &s, char delim) - { - std::vector < std::string > elems; - return split(s, delim, elems); - } +std::vector split(const std::string &s, char delim) +{ + std::vector < std::string > elems; + return split(s, delim, elems); +} } mitk::InteractionEvent::Pointer mitk::EventFactory::CreateEvent(PropertyList::Pointer list) { -// + // std::string eventClass, eventVariant; list->GetStringProperty(InteractionEventConst::xmlParameterEventClass().c_str(), eventClass); list->GetStringProperty(InteractionEventConst::xmlParameterEventVariant().c_str(), eventVariant); -// Query all possible attributes, if they are not present, set their default values. -// Position Events & Key Events + // Query all possible attributes, if they are not present, set their default values. + // Position Events & Key Events std::string strModifiers; InteractionEvent::ModifierKeys modifiers = InteractionEvent::NoKey; std::string strEventButton; InteractionEvent::MouseButtons eventButton = InteractionEvent::NoButton; std::string strButtonState; InteractionEvent::MouseButtons buttonState = InteractionEvent::NoButton; std::string strKey; std::string key; std::string strWheelDelta; int wheelDelta; std::string strSignalName = ""; Point2D pos; pos.Fill(0); -// Parse modifier information + // Parse modifier information if (list->GetStringProperty(InteractionEventConst::xmlEventPropertyModifier().c_str(), strModifiers)) { std::vector mods = split(strModifiers, ','); for (std::vector::iterator it = mods.begin(); it != mods.end(); ++it) { std::transform((*it).begin(), (*it).end(), (*it).begin(), ::toupper); if (*it == "CTRL") { modifiers = modifiers | InteractionEvent::ControlKey; } else if (*it == "ALT") { modifiers = modifiers | InteractionEvent::AltKey; } else if (*it == "SHIFT") { modifiers = modifiers | InteractionEvent::ShiftKey; } else { MITK_WARN<< "mitkEventFactory: Invalid event modifier in config file :" << (*it); } } } -// Set EventButton + // Set EventButton if (list->GetStringProperty(InteractionEventConst::xmlEventPropertyEventButton().c_str(), strEventButton)) { std::transform(strEventButton.begin(), strEventButton.end(), strEventButton.begin(), ::toupper); if (strEventButton == "MIDDLEMOUSEBUTTON") { eventButton = InteractionEvent::MiddleMouseButton; } else if (strEventButton == "LEFTMOUSEBUTTON") { eventButton = InteractionEvent::LeftMouseButton; } else if (strEventButton == "RIGHTMOUSEBUTTON") { eventButton = InteractionEvent::RightMouseButton; } else { MITK_WARN<< "mitkEventFactory: Invalid event button in config file: " << strEventButton; } } -// Parse ButtonStates + // Parse ButtonStates if (list->GetStringProperty(InteractionEventConst::xmlEventPropertyButtonState().c_str(), strButtonState)) { std::vector mods = split(strButtonState, ','); for (std::vector::iterator it = mods.begin(); it != mods.end(); ++it) { std::transform((*it).begin(), (*it).end(), (*it).begin(), ::toupper); if (*it == "MIDDLEMOUSEBUTTON") { buttonState = buttonState | InteractionEvent::MiddleMouseButton; } else if (*it == "LEFTMOUSEBUTTON") { buttonState = buttonState | InteractionEvent::LeftMouseButton; } else if (*it == "RIGHTMOUSEBUTTON") { buttonState = buttonState | InteractionEvent::RightMouseButton; } else { MITK_WARN<< "mitkEventFactory: Invalid event buttonstate in config file:" << (*it); } } } -// Key + // Key if (!list->GetStringProperty(InteractionEventConst::xmlEventPropertyKey().c_str(), strKey)) { key = ""; } else { key = strKey; } -// WheelDelta + // WheelDelta if (!list->GetStringProperty(InteractionEventConst::xmlEventPropertyScrollDirection().c_str(), strWheelDelta)) { wheelDelta = 0; } else { std::transform(strWheelDelta.begin(), strWheelDelta.end(), strWheelDelta.begin(), ::toupper); if (strWheelDelta == "DOWN") { wheelDelta = -1; } else { wheelDelta = 1; } } -// Internal Signals Name + // Internal Signals Name list->GetStringProperty(InteractionEventConst::xmlEventPropertySignalName().c_str(), strSignalName); /* * Here the objects are created */ mitk::InteractionEvent::Pointer event; std::transform(eventClass.begin(), eventClass.end(), eventClass.begin(), ::toupper); if (eventClass == "MOUSEPRESSEVENT") { // buttonstates incorporate the event button (as in Qt) buttonState = buttonState | eventButton; event = MousePressEvent::New(NULL, pos, buttonState, modifiers, eventButton); } else if (eventClass == "MOUSEDOUBLECLICKEVENT") { buttonState = buttonState | eventButton; event = MouseDoubleClickEvent::New(NULL, pos, buttonState, modifiers, eventButton); } else if (eventClass == "MOUSEMOVEEVENT") { event = MouseMoveEvent::New(NULL, pos, buttonState, modifiers); } else if (eventClass == "MOUSERELEASEEVENT") { event = MouseReleaseEvent::New(NULL, pos, buttonState, modifiers, eventButton); } else if (eventClass == "INTERACTIONKEYEVENT") { event = InteractionKeyEvent::New(NULL, key, modifiers); } else if (eventClass == "MOUSEWHEELEVENT") { event = MouseWheelEvent::New(NULL, pos, buttonState, modifiers, wheelDelta); } else if (eventClass == "INTERACTIONPOSITIONEVENT") { event = InteractionPositionEvent::New(NULL, pos); } else if (eventClass == "INTERNALEVENT") { event = InternalEvent::New(NULL, NULL, strSignalName); } else if (eventClass == "INTERACTIONEVENT") { event = InteractionEvent::New(NULL); } if (event.IsNull()) { MITK_WARN<< "Event couldn't be constructed. Please check your StateMachine patterns and config files\n for the following event class, which is not valid: " << eventClass; return NULL; } return event; } + +std::string mitk::EventFactory::EventToXML(mitk::InteractionEvent *event) +{ + + std::string eventClass = event->GetNameOfClass(); + std::string eventXML = "<" + InteractionEventConst::xmlTagEventVariant() + " " + InteractionEventConst::xmlParameterEventClass() + "=\""; + + std::transform(eventClass.begin(), eventClass.end(), eventClass.begin(), ::toupper); + + eventXML += eventClass + "\" >\n"; + // here follow event specific attributes + if (eventClass == "MOUSEPRESSEVENT" || eventClass == "MOUSERELEASEEVENT" || eventClass == "MOUSEDOUBLECLICKEVENT" || eventClass == "MOUSEMOVEEVENT" || eventClass == "MOUSEWHEELEVENT") + { + if (!(eventClass == "MOUSEMOVEEVENT") && !(eventClass == "MOUSEWHEELEVENT")) + { + // EventButton + eventXML += " <" + InteractionEventConst::xmlTagAttribute() +" " + InteractionEventConst::xmlParameterName() + "=\"" + InteractionEventConst::xmlEventPropertyEventButton() + "\" "; + eventXML += InteractionEventConst::xmlParameterValue() + "\""; + eventXML += GetEventButton(event); + eventXML += "\"/>\n"; + } + // ButtonState + if (GetButtonState(event) != "") + { + eventXML += " <" + InteractionEventConst::xmlTagAttribute() +" " + InteractionEventConst::xmlParameterName() + "=\"" + InteractionEventConst::xmlEventPropertyButtonState() + "\" "; + eventXML += InteractionEventConst::xmlParameterValue() + "\""; + eventXML += GetButtonState(event); + eventXML += "\"/>\n"; + } + + // Modifiers + if (GetModifierState(event) != "") + { + eventXML += " <" + InteractionEventConst::xmlTagAttribute() +" " + InteractionEventConst::xmlParameterName() + "=\"" + InteractionEventConst::xmlEventPropertyModifier() + "\" "; + eventXML += InteractionEventConst::xmlParameterValue() + "\""; + eventXML += GetModifierState(event); + eventXML += "\"/>\n"; + } + + // Position on Screen + eventXML += " <" + InteractionEventConst::xmlTagAttribute() +" " + InteractionEventConst::xmlParameterName() + "=\"" + InteractionEventConst::xmlEventPropertyPositionOnScreen() + "\" "; + eventXML += InteractionEventConst::xmlParameterValue() + "\""; + eventXML += GetPositionInWorld(event); + eventXML += "\"/>\n"; + + // Position in World + eventXML += " <" + InteractionEventConst::xmlTagAttribute() +" " + InteractionEventConst::xmlParameterName() + "=\"" + InteractionEventConst::xmlEventPropertyPositionInWorld() + "\" "; + eventXML += InteractionEventConst::xmlParameterValue() + "\""; + eventXML += GetPositionOnScreen(event); + eventXML += "\"/>\n"; + } + // TODO Implement Key Events!! + // else if (eventClass == "INTERACTIONKEYEVENT") + // { + // event = InteractionKeyEvent::New(NULL, key, modifiers); + // } + else if (eventClass == "MOUSEWHEELEVENT") + { + MouseWheelEvent* we = dynamic_cast (event); + int delta = we->GetWheelDelta(); + + std::stringstream ss; + ss << delta; + + eventXML += " <" + InteractionEventConst::xmlTagAttribute() +" " + InteractionEventConst::xmlParameterName() + "=\"" + InteractionEventConst::xmlEventPropertyWheelDelta() + "\" "; + eventXML += InteractionEventConst::xmlParameterValue() + "\""; + eventXML += ss.str(); + eventXML += "\"/>\n"; + } + else + { + MITK_WARN << "Event not recognized, discarding event of type " << event->GetNameOfClass(); + } + // closing tag: + eventXML += ""; + return eventXML; +} + +std::string mitk::EventFactory::GetButtonState(mitk::InteractionEvent *event) +{ + InteractionEvent::MouseButtons buttonState = InteractionEvent::NoButton; + std::string eventClass = event->GetNameOfClass(); + std::transform(eventClass.begin(), eventClass.end(), eventClass.begin(), ::toupper); + + MITK_INFO << eventClass; + std::string strButtonState = ""; + if (eventClass == "MOUSEPRESSEVENT") + { + MousePressEvent* mme = dynamic_cast (event); + buttonState = mme->GetButtonStates(); + } + if (eventClass == "MOUSERELEASEEVENT") + { + MouseReleaseEvent* mme = dynamic_cast (event); + buttonState = mme->GetButtonStates(); + } + if (eventClass == "MOUSEDOUBLECLICKEVENT") + { + MouseDoubleClickEvent* mme = dynamic_cast (event); + buttonState = mme->GetButtonStates(); + } + if (eventClass == "MOUSEMOVEEVENT") + { + MouseMoveEvent* mme = dynamic_cast (event); + buttonState = mme->GetButtonStates(); + } + if (eventClass == "MOUSEWHEELEVENT") + { + MouseWheelEvent* mme = dynamic_cast (event); + buttonState = mme->GetButtonStates(); + } + + if (buttonState & InteractionEvent::LeftMouseButton ) + { + strButtonState = "LeftMouseButton"; + } + if (buttonState & InteractionEvent::RightMouseButton ) + { + if (strButtonState != "") + strButtonState += ","; + + strButtonState += "RightMouseButton"; + } + if (buttonState & InteractionEvent::MiddleMouseButton ) + { + if (strButtonState != "") + strButtonState += ","; + + strButtonState += "MiddleMouseButton"; + } + return strButtonState; +} + +std::string mitk::EventFactory::GetModifierState(mitk::InteractionEvent *event) +{ + InteractionEvent::ModifierKeys modifierKeys = InteractionEvent::NoKey; + std::string eventClass = event->GetNameOfClass(); + std::transform(eventClass.begin(), eventClass.end(), eventClass.begin(), ::toupper); + std::string strModKeys = ""; + // TODO Add InteractionKey + if (eventClass == "MOUSEPRESSEVENT") + { + MousePressEvent* mme = dynamic_cast (event); + modifierKeys = mme->GetModifiers(); + } + if (eventClass == "MOUSERELEASEEVENT") + { + MouseReleaseEvent* mme = dynamic_cast (event); + modifierKeys = mme->GetModifiers(); + } + if (eventClass == "MOUSEDOUBLECLICKEVENT") + { + MouseDoubleClickEvent* mme = dynamic_cast (event); + modifierKeys = mme->GetModifiers(); + } + if (eventClass == "MOUSEMOVEEVENT") + { + MouseMoveEvent* mme = dynamic_cast (event); + modifierKeys = mme->GetModifiers(); + } + if (eventClass == "MOUSEWHEELEVENT") + { + MouseWheelEvent* mme = dynamic_cast (event); + modifierKeys = mme->GetModifiers(); + } + + if (modifierKeys & InteractionEvent::ShiftKey ) + { + strModKeys = "SHIFT"; + } + if (modifierKeys & InteractionEvent::ControlKey ) + { + if (strModKeys != "") + strModKeys += ","; + + strModKeys += "CTRL"; + } + if (modifierKeys & InteractionEvent::AltKey ) + { + if (strModKeys != "") + strModKeys += ","; + + strModKeys += "ALT"; + } + return strModKeys; +} + +std::string mitk::EventFactory::GetEventButton(mitk::InteractionEvent *event) +{ + InteractionEvent::MouseButtons button = InteractionEvent::NoButton; + std::string eventClass = event->GetNameOfClass(); + std::transform(eventClass.begin(), eventClass.end(), eventClass.begin(), ::toupper); + std::string stdButton = ""; + // TODO Add InteractionKey + if (eventClass == "MOUSEPRESSEVENT") + { + MousePressEvent* mme = dynamic_cast (event); + button = mme->GetEventButton(); + } + if (eventClass == "MOUSERELEASEEVENT") + { + MouseReleaseEvent* mme = dynamic_cast (event); + button = mme->GetEventButton(); + } + if (eventClass == "MOUSEDOUBLECLICKEVENT") + { + MouseDoubleClickEvent* mme = dynamic_cast (event); + button = mme->GetEventButton(); + } + + if (button & InteractionEvent::LeftMouseButton ) + { + stdButton = "LeftMouseButton"; + } + if (button & InteractionEvent::RightMouseButton ) + { + stdButton = "RightMouseButton"; + } + if (button & InteractionEvent::MiddleMouseButton ) + { + stdButton = "MiddleMouseButton"; + } + return stdButton; + +} + +std::string mitk::EventFactory::GetPositionInWorld(mitk::InteractionEvent *event) +{ + std::stringstream ss; + InteractionPositionEvent* pe = dynamic_cast (event); + if (pe != NULL) + { + Point3D p = pe->GetPositionInWorld(); + ss << p[0] << "," << p[1] << "," << p[2]; + } + return ss.str(); +} + +std::string mitk::EventFactory::GetPositionOnScreen(mitk::InteractionEvent *event) +{ + std::stringstream ss; + InteractionPositionEvent* pe = dynamic_cast (event); + if (pe != NULL) + { + Point2D p = pe->GetPointerPositionOnScreen(); + ss << p[0] << "," << p[1]; + } + return ss.str(); +} diff --git a/Core/Code/Interactions/mitkEventFactory.h b/Core/Code/Interactions/mitkEventFactory.h index 3b4efe2504..ff01287825 100755 --- a/Core/Code/Interactions/mitkEventFactory.h +++ b/Core/Code/Interactions/mitkEventFactory.h @@ -1,47 +1,91 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef mitkEventFactory_h #define mitkEventFactory_h #include "mitkCommon.h" #include "mitkInteractionEvent.h" #include "mitkPropertyList.h" #include namespace mitk { /** * \class EventFactory * \brief Generates InteractionEvent-Objects which are described by a PropertyList. * This class is used by the EventConfig object to parse configuration files and create Events based on the xml description. * * \ingroup Interaction */ class MITK_CORE_EXPORT EventFactory { public: /** * Parses PropertyList and queries all possible Information. * If an attribute is not present the default value is used. * Finally the Event-Type is chosen by the ClassName property and the object is created using the collected information. */ static InteractionEvent::Pointer CreateEvent(PropertyList::Pointer eventDescription); + + /** + * @brief EventToXML Transforms an event into a XML tag describing it. + * @param event + * @return Event block specifying event class and attributes of that event. + */ + static std::string EventToXML(InteractionEvent* event); + + + /** + * @brief GetEventButton Return EventButton as String + * @param event + * @return + */ + static std::string GetButtonState(InteractionEvent* event); + + /** + * @brief GetModifierState Return ModifierState as String + * @param event + * @return + */ + static std::string GetModifierState(InteractionEvent* event); + + /** + * @brief GetEventButton Return EventButton as String + * @param event + * @return + */ + static std::string GetEventButton(InteractionEvent* event); + + /** + * @brief GetPosition Return World Position as String + * @param event + * @return + */ + static std::string GetPositionInWorld(InteractionEvent* event); + + /** + * @brief GetPositionOnScreen Return PositionOnScreen as String + * @param event + * @return + */ + static std::string GetPositionOnScreen(InteractionEvent* event); + }; } #endif /* mitkEventFactory_h */