diff --git a/Modules/Core/include/mitkAbstractAnnotationRenderer.h b/Modules/Core/include/mitkAbstractAnnotationRenderer.h index 5b87e78229..a448cd4707 100644 --- a/Modules/Core/include/mitkAbstractAnnotationRenderer.h +++ b/Modules/Core/include/mitkAbstractAnnotationRenderer.h @@ -1,87 +1,88 @@ /*=================================================================== * 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 ABSTRACTANNOTATIONRENDERER_H #define ABSTRACTANNOTATIONRENDERER_H #include "mitkOverlay.h" #include "mitkServiceInterface.h" #include "usGetModuleContext.h" #include "usServiceTracker.h" #include #include namespace mitk { class BaseRenderer; /** @brief Baseclass of Overlay layouters */ /** *A AbstractAnnotationRenderer can be implemented to control a set of Overlays by means of position and size. *AbstractAnnotationRenderer::PrepareLayout() should be implemented with a routine to set the position of the internal *m_ManagedOverlays List. *A layouter is always connected to one BaseRenderer, so there is one instance of the layouter for each BaseRenderer. *One type of layouter should always have a unique identifier. *@ingroup Overlays */ class MITKCORE_EXPORT AbstractAnnotationRenderer : public us::ServiceTracker { public: typedef us::ServiceTracker Superclass; AbstractAnnotationRenderer(const std::string &rendererID, const std::string &arID); /** \brief virtual destructor in order to derive from this class */ virtual ~AbstractAnnotationRenderer(); const std::string GetID() const; const std::string GetRendererID() const; void CurrentBaseRendererChanged(); + virtual void OnRenderWindowModified() {} void RemoveAllOverlays(); void Update(); static const std::string US_INTERFACE_NAME; static const std::string US_PROPKEY_ID; static const std::string US_PROPKEY_RENDERER_ID; protected: BaseRenderer *GetCurrentBaseRenderer(); private: /** \brief copy constructor */ AbstractAnnotationRenderer(const AbstractAnnotationRenderer &); /** \brief assignment operator */ AbstractAnnotationRenderer &operator=(const AbstractAnnotationRenderer &); TrackedType AddingService(const ServiceReferenceType &reference) override; void ModifiedService(const ServiceReferenceType & /*reference*/, TrackedType tracked) override; void RemovedService(const ServiceReferenceType & /*reference*/, TrackedType tracked) override; virtual void OnAnnotationRenderersChanged() {} const std::string m_RendererID; const std::string m_ID; }; } // namespace mitk MITK_DECLARE_SERVICE_INTERFACE(mitk::AbstractAnnotationRenderer, "org.mitk.services.AbstractAnnotationRenderer") #endif // ABSTRACTANNOTATIONRENDERER_H diff --git a/Modules/Core/include/mitkAnnotationService.h b/Modules/Core/include/mitkAnnotationService.h index e4974fda44..ff765d313c 100644 --- a/Modules/Core/include/mitkAnnotationService.h +++ b/Modules/Core/include/mitkAnnotationService.h @@ -1,55 +1,60 @@ /*=================================================================== 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 mitkAnnotationService_h #define mitkAnnotationService_h #include #include #include +class vtkObject; + namespace mitk { class AbstractAnnotationRenderer; class Overlay; + class BaseRenderer; class MITKCORE_EXPORT AnnotationService { public: typedef std::vector> AnnotationRendererServices; AnnotationService(); ~AnnotationService(); static AbstractAnnotationRenderer *GetAnnotationRenderer(const std::string &arTypeID, const std::string &rendererID); static void RegisterAnnotationRenderer(AbstractAnnotationRenderer *annotationRenderer); static std::vector GetAnnotationRenderer(const std::string &rendererID); static void UpdateAnnotationRenderer(const std::string &rendererID); - static void BaseRendererChanged(const std::string &rendererID); + static void BaseRendererChanged(BaseRenderer *renderer); static mitk::Overlay *GetOverlay(const std::string &overlayID); private: AnnotationService(const AnnotationService &); AnnotationService &operator=(const AnnotationService &); + + static void RenderWindowCallback(vtkObject *caller, unsigned long, void *, void *); }; } #endif diff --git a/Modules/Core/include/mitkOverlay.h b/Modules/Core/include/mitkOverlay.h index 75cb1d2f15..9cbc19d901 100644 --- a/Modules/Core/include/mitkOverlay.h +++ b/Modules/Core/include/mitkOverlay.h @@ -1,461 +1,457 @@ /*=================================================================== 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 OVERLAY_H #define OVERLAY_H #include "mitkServiceInterface.h" #include "usServiceRegistration.h" #include #include #include namespace mitk { class AbstractOverlayLayouter; /** \brief Base class for all overlays */ /** This class is to be implemented in order to create overlays which are managed by the OverlayManager and can be placed by a AbstractOverlayLayouter. This class contains an internal Propertylist, and another PropertyList for each BaseRenderer. A property that is specified for a specific renderer always overrides the general internal property of the same name. AddOverlay, RemoveOverlay and UpdateOverlay methods have to be implemented.*/ class MITKCORE_EXPORT Overlay : public itk::Object { friend class AbstractOverlayLayouter; public: /** \brief Container for position and size on the display.*/ struct Bounds { itk::Point Position; itk::Point Size; }; /** \brief Base class for mapper specific rendering ressources. */ class MITKCORE_EXPORT BaseLocalStorage { public: bool IsGenerateDataRequired(mitk::BaseRenderer *renderer, mitk::Overlay *overlay); inline void UpdateGenerateDataTime() { m_LastGenerateDataTime.Modified(); } inline itk::TimeStamp &GetLastGenerateDataTime() { return m_LastGenerateDataTime; } protected: /** \brief timestamp of last update of stored data */ itk::TimeStamp m_LastGenerateDataTime; }; /** * @brief Set the property (instance of BaseProperty) with key @a propertyKey in the PropertyList * of the @a renderer (if NULL, use BaseRenderer-independent PropertyList). This is set-by-value. * * @warning Change in semantics since Aug 25th 2006. Check your usage of this method if you do * more with properties than just call SetProperty( "key", new SomeProperty("value") ). * * @sa GetProperty * @sa m_PropertyList * @sa m_MapOfPropertyLists */ void SetProperty(const std::string &propertyKey, const BaseProperty::Pointer &property); /** * @brief Replace the property (instance of BaseProperty) with key @a propertyKey in the PropertyList * of the @a renderer (if NULL, use BaseRenderer-independent PropertyList). This is set-by-reference. * * If @a renderer is @a NULL the property is set in the BaseRenderer-independent * PropertyList of this Overlay. * @sa GetProperty * @sa m_PropertyList * @sa m_MapOfPropertyLists */ void ReplaceProperty(const std::string &propertyKey, const BaseProperty::Pointer &property); /** * @brief Add the property (instance of BaseProperty) if it does * not exist (or always if \a overwrite is \a true) * with key @a propertyKey in the PropertyList * of the @a renderer (if NULL, use BaseRenderer-independent * PropertyList). This is set-by-value. * * For \a overwrite == \a false the property is \em not changed * if it already exists. For \a overwrite == \a true the method * is identical to SetProperty. * * @sa SetProperty * @sa GetProperty * @sa m_PropertyList * @sa m_MapOfPropertyLists */ void AddProperty(const std::string &propertyKey, const BaseProperty::Pointer &property, bool overwrite = false); /** * @brief Add values from another PropertyList. * * Overwrites values in m_PropertyList only when possible (i.e. when types are compatible). * If you want to allow for object type changes (replacing a "visible":BoolProperty with "visible":IntProperty, * set the @param replace. * * @param replace true: if @param pList contains a property "visible" of type ColorProperty and our m_PropertyList * also has a "visible" property of a different type (e.g. BoolProperty), change the type, i.e. replace the objects * behind the pointer. * * @sa SetProperty * @sa ReplaceProperty * @sa m_PropertyList */ void ConcatenatePropertyList(PropertyList *pList, bool replace = false); /** * @brief Get the property (instance of BaseProperty) with key @a propertyKey from the PropertyList * of the @a renderer, if available there, otherwise use the BaseRenderer-independent PropertyList. * * If @a renderer is @a NULL or the @a propertyKey cannot be found * in the PropertyList specific to @a renderer or is disabled there, the BaseRenderer-independent * PropertyList of this Overlay is queried. * @sa GetPropertyList * @sa m_PropertyList * @sa m_MapOfPropertyLists */ mitk::BaseProperty *GetProperty(const std::string &propertyKey) const; /** * @brief Get the property of type T with key @a propertyKey from the PropertyList * of the @a renderer, if available there, otherwise use the BaseRenderer-independent PropertyList. * * If @a renderer is @a NULL or the @a propertyKey cannot be found * in the PropertyList specific to @a renderer or is disabled there, the BaseRenderer-independent * PropertyList of this Overlay is queried. * @sa GetPropertyList * @sa m_PropertyList * @sa m_MapOfPropertyLists */ template bool GetProperty(itk::SmartPointer &property, const std::string &propertyKey) const { property = dynamic_cast(GetProperty(propertyKey)); return property.IsNotNull(); } /** * @brief Get the property of type T with key @a propertyKey from the PropertyList * of the @a renderer, if available there, otherwise use the BaseRenderer-independent PropertyList. * * If @a renderer is @a NULL or the @a propertyKey cannot be found * in the PropertyList specific to @a renderer or is disabled there, the BaseRenderer-independent * PropertyList of this Overlay is queried. * @sa GetPropertyList * @sa m_PropertyList * @sa m_MapOfPropertyLists */ template bool GetProperty(T *&property, const std::string &propertyKey) const { property = dynamic_cast(GetProperty(propertyKey)); return property != nullptr; } /** * @brief Convenience access method for GenericProperty properties * (T being the type of the second parameter) * @return @a true property was found */ template bool GetPropertyValue(const std::string &propertyKey, T &value) const { GenericProperty *gp = dynamic_cast *>(GetProperty(propertyKey)); if (gp != nullptr) { value = gp->GetValue(); return true; } return false; } /** * @brief Convenience access method for bool properties (instances of * BoolProperty) * @return @a true property was found */ bool GetBoolProperty(const std::string &propertyKey, bool &boolValue) const; /** * @brief Convenience access method for int properties (instances of * IntProperty) * @return @a true property was found */ bool GetIntProperty(const std::string &propertyKey, int &intValue) const; /** * @brief Convenience access method for float properties (instances of * FloatProperty) * @return @a true property was found */ bool GetFloatProperty(const std::string &propertyKey, float &floatValue) const; /** * @brief Convenience access method for string properties (instances of * StringProperty) * @return @a true property was found */ bool GetStringProperty(const std::string &propertyKey, std::string &string) const; /** * @brief Convenience method for setting int properties (instances of * IntProperty) */ void SetIntProperty(const std::string &propertyKey, int intValue); /** * @brief Convenience method for setting int properties (instances of * IntProperty) */ void SetBoolProperty(const std::string &propertyKey, bool boolValue); /** * @brief Convenience method for setting int properties (instances of * IntProperty) */ void SetFloatProperty(const std::string &propertyKey, float floatValue); /** * @brief Convenience method for setting int properties (instances of * IntProperty) */ void SetStringProperty(const std::string &propertyKey, const std::string &string); /** * @brief Convenience access method for boolean properties (instances * of BoolProperty). Return value is the value of the property. If the property is * not found, the value of @a defaultIsOn is returned. * * Thus, the return value has a different meaning than in the * GetBoolProperty method! * @sa GetBoolProperty */ bool IsOn(const std::string &propertyKey, bool defaultIsOn = true) const { GetBoolProperty(propertyKey, defaultIsOn); return defaultIsOn; } /** * @brief Convenience access method for accessing the name of an object (instance of * StringProperty with property-key "name") * @return @a true property was found */ bool GetName(std::string &nodeName, const std::string &propertyKey = "name") const; /** * @brief Extra convenience access method for accessing the name of an object (instance of * StringProperty with property-key "name"). * * This method does not take the renderer specific * propertylists into account, because the name of an object should never be renderer specific. * @returns a std::string with the name of the object (content of "name" Property). * If there is no "name" Property, an empty string will be returned. */ virtual std::string GetName() const; /** * @brief Extra convenience access method to set the name of an object. * * The name will be stored in the non-renderer-specific PropertyList in a StringProperty named "name". */ virtual void SetName(const std::string &name); /** * @brief Convenience access method for color properties (instances of * ColorProperty) * @return @a true property was found */ bool GetColor(float rgb[], const std::string &propertyKey = "color") const; /** * @brief Convenience method for setting color properties (instances of * ColorProperty) */ void SetColor(const mitk::Color &color, const std::string &propertyKey = "color"); /** * @brief Convenience method for setting color properties (instances of * ColorProperty) */ void SetColor(float red, float green, float blue, const std::string &propertyKey = "color"); /** * @brief Convenience method for setting color properties (instances of * ColorProperty) */ void SetColor(const float rgb[], const std::string &propertyKey = "color"); /** * @brief Convenience access method for opacity properties (instances of * FloatProperty) * @return @a true property was found */ bool GetOpacity(float &opacity, const std::string &propertyKey = "opacity") const; /** * @brief Convenience method for setting opacity properties (instances of * FloatProperty) */ void SetOpacity(float opacity, const std::string &propertyKey = "opacity"); void SetText(std::string text); std::string GetText() const; void SetFontSize(int fontSize); int GetFontSize() const; /** * @brief Convenience access method for visibility properties (instances * of BoolProperty with property-key "visible") * @return @a true property was found * @sa IsVisible */ bool GetVisibility(bool &visible, const std::string &propertyKey = "visible") const; /** * @brief Convenience access method for visibility properties (instances * of BoolProperty). Return value is the visibility. Default is * visible==true, i.e., true is returned even if the property (@a * propertyKey) is not found. * * Thus, the return value has a different meaning than in the * GetVisibility method! * @sa GetVisibility * @sa IsOn */ bool IsVisible(const std::string &propertyKey = "visible", bool defaultIsOn = true) const; /** * @brief Convenience method for setting visibility properties (instances * of BoolProperty) * @param visible If set to true, the data will be rendered. If false, the render will skip this data. * @param renderer Specify a renderer if the visibility shall be specific to a renderer * @param propertykey Can be used to specify a user defined name of the visibility propery. */ void SetVisibility(bool visible, const std::string &propertyKey = "visible"); /** \brief Adds the overlay to the specified renderer. Update Overlay should be called soon in order to apply all * properties*/ virtual void AddToBaseRenderer(BaseRenderer *renderer) = 0; /** \brief Adds the overlay to the specified renderer. Update Overlay should be called soon in order to apply all * properties*/ virtual void AddToRenderer(BaseRenderer *renderer, vtkRenderer *vtkrenderer) = 0; /** \brief Removes the overlay from the specified renderer. It is not visible anymore then.*/ virtual void RemoveFromBaseRenderer(BaseRenderer *renderer) = 0; /** \brief Removes the overlay from the specified renderer. It is not visible anymore then.*/ virtual void RemoveFromRenderer(BaseRenderer *renderer, vtkRenderer *vtkrenderer) = 0; /** \brief Applies all properties and should be called before the rendering procedure.*/ virtual void Update(BaseRenderer *renderer) = 0; /** \brief Returns position and size of the overlay on the display.*/ virtual Bounds GetBoundsOnDisplay(BaseRenderer *renderer) const; /** \brief Sets position and size of the overlay on the display.*/ virtual void SetBoundsOnDisplay(BaseRenderer *renderer, const Bounds &); void SetForceInForeground(bool forceForeground); bool IsForceInForeground() const; PropertyList *GetPropertyList() const; /** *\brief Returns the id that this device is registered with. The id will only be valid, if the * Overlay has been registered using RegisterAsMicroservice(). */ std::string GetMicroserviceID(); /** *\brief These Constants are used in conjunction with Microservices */ static const std::string US_INTERFACE_NAME; static const std::string US_PROPKEY_OVERLAYNAME; static const std::string US_PROPKEY_ID; static const std::string US_PROPKEY_MODIFIED; static const std::string US_PROPKEY_RENDERER_ID; static const std::string US_PROPKEY_AR_ID; /** *\brief Registers this object as a Microservice, making it available to every module and/or plugin. * To unregister, call UnregisterMicroservice(). */ virtual void RegisterAsMicroservice(us::ServiceProperties props); /** *\brief Registers this object as a Microservice, making it available to every module and/or plugin. */ virtual void UnRegisterMicroservice(); void OverlayModified(); mitkClassMacroItkParent(Overlay, itk::Object); - void SetMargin2D(const Point2D &OffsetVector); - - mitk::Point2D GetMargin2D() const; - protected: /** \brief explicit constructor which disallows implicit conversions */ Overlay(); /** \brief virtual destructor in order to derive from this class */ virtual ~Overlay(); /** * @brief BaseRenderer-independent PropertyList * * Properties herein can be overwritten specifically for each BaseRenderer * by the BaseRenderer-specific properties defined in m_MapOfPropertyLists. */ PropertyList::Pointer m_PropertyList; /** * @brief Timestamp of the last change of m_Data */ itk::TimeStamp m_DataReferenceChangedTime; void SetUSProperty(const std::string &propertyKey, us::Any value); private: /** \brief render this overlay on a foreground renderer */ bool m_ForceInForeground; /** \brief copy constructor */ Overlay(const Overlay &); /** \brief assignment operator */ Overlay &operator=(const Overlay &); /** \brief Reference to the layouter in which this overlay is managed. */ AbstractOverlayLayouter *m_LayoutedBy; private: us::ServiceRegistration m_ServiceRegistration; unsigned long m_PropertyListModifiedObserverTag; void PropertyListModified(const itk::Object *, const itk::EventObject &); }; } // namespace mitk MITK_DECLARE_SERVICE_INTERFACE(mitk::Overlay, "org.mitk.services.Overlay") #endif // OVERLAY_H diff --git a/Modules/Core/src/Rendering/mitkAbstractAnnotationRenderer.cpp b/Modules/Core/src/Rendering/mitkAbstractAnnotationRenderer.cpp index f855729ddf..ca021c23d3 100644 --- a/Modules/Core/src/Rendering/mitkAbstractAnnotationRenderer.cpp +++ b/Modules/Core/src/Rendering/mitkAbstractAnnotationRenderer.cpp @@ -1,108 +1,111 @@ /*=================================================================== 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 "mitkAbstractAnnotationRenderer.h" #include "mitkBaseRenderer.h" #include "mitkRenderingManager.h" #include "usGetModuleContext.h" #include namespace mitk { const std::string AbstractAnnotationRenderer::US_INTERFACE_NAME = "org.mitk.services.AbstractAnnotationRenderer"; const std::string AbstractAnnotationRenderer::US_PROPKEY_ID = US_INTERFACE_NAME + ".id"; const std::string AbstractAnnotationRenderer::US_PROPKEY_RENDERER_ID = US_INTERFACE_NAME + ".rendererId"; AbstractAnnotationRenderer::AbstractAnnotationRenderer(const std::string &rendererID, const std::string &arID) : Superclass(us::GetModuleContext(), us::LDAPFilter("(&(" + Overlay::US_PROPKEY_RENDERER_ID + "=" + rendererID + ")(" + Overlay::US_PROPKEY_AR_ID + "=" + arID + "))")), m_RendererID(rendererID), m_ID(arID) { this->Open(); } AbstractAnnotationRenderer::~AbstractAnnotationRenderer() {} const std::string AbstractAnnotationRenderer::GetRendererID() const { return m_RendererID; } void AbstractAnnotationRenderer::CurrentBaseRendererChanged() { BaseRenderer *renderer = GetCurrentBaseRenderer(); if (renderer) { for (Overlay *o : this->GetServices()) { o->AddToBaseRenderer(renderer); } } } void AbstractAnnotationRenderer::RemoveAllOverlays() { BaseRenderer *renderer = GetCurrentBaseRenderer(); if (renderer) { for (Overlay *o : this->GetServices()) { o->RemoveFromBaseRenderer(renderer); } } } void AbstractAnnotationRenderer::Update() { BaseRenderer *renderer = GetCurrentBaseRenderer(); if (renderer) { for (Overlay *o : this->GetServices()) { o->Update(renderer); } } } const std::string AbstractAnnotationRenderer::GetID() const { return m_ID; } AbstractAnnotationRenderer::TrackedType AbstractAnnotationRenderer::AddingService( const AbstractAnnotationRenderer::ServiceReferenceType &reference) { Overlay *overlay = Superclass::AddingService(reference); BaseRenderer *renderer = GetCurrentBaseRenderer(); if (overlay && renderer) { overlay->AddToBaseRenderer(renderer); } + OnAnnotationRenderersChanged(); return overlay; } void AbstractAnnotationRenderer::ModifiedService(const AbstractAnnotationRenderer::ServiceReferenceType &, AbstractAnnotationRenderer::TrackedType tracked) { BaseRenderer *renderer = GetCurrentBaseRenderer(); if (tracked && renderer) { tracked->Update(renderer); } + OnAnnotationRenderersChanged(); } void AbstractAnnotationRenderer::RemovedService(const AbstractAnnotationRenderer::ServiceReferenceType &, AbstractAnnotationRenderer::TrackedType /*tracked*/) { + OnAnnotationRenderersChanged(); } BaseRenderer *AbstractAnnotationRenderer::GetCurrentBaseRenderer() { return BaseRenderer::GetByName(this->GetRendererID()); } } diff --git a/Modules/Core/src/Rendering/mitkAnnotationService.cpp b/Modules/Core/src/Rendering/mitkAnnotationService.cpp index 90b35945a2..0479494b5f 100644 --- a/Modules/Core/src/Rendering/mitkAnnotationService.cpp +++ b/Modules/Core/src/Rendering/mitkAnnotationService.cpp @@ -1,108 +1,126 @@ /*=================================================================== 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 "mitkAnnotationService.h" #include "mitkOverlay.h" +#include "vtkCallbackCommand.h" +#include "vtkCommand.h" #include namespace mitk { AnnotationService::AnnotationService() {} AnnotationService::~AnnotationService() {} AbstractAnnotationRenderer *AnnotationService::GetAnnotationRenderer(const std::string &arTypeID, const std::string &rendererID) { // get the context us::ModuleContext *context = us::GetModuleContext(); // specify a filter that defines the requested type std::string filter = "(&(" + AbstractAnnotationRenderer::US_PROPKEY_ID + "=" + arTypeID + ")(" + AbstractAnnotationRenderer::US_PROPKEY_RENDERER_ID + "=" + rendererID + "))"; // find the fitting service std::vector serviceReferences = context->GetServiceReferences(AbstractAnnotationRenderer::US_INTERFACE_NAME, filter); // check if a service reference was found. It is also possible that several // services were found. This is not checked here, just the first one is taken. AbstractAnnotationRenderer *ar = nullptr; if (serviceReferences.size()) { ar = context->GetService(serviceReferences.front()); } // no service reference was found or found service reference has no valid source return ar; } void AnnotationService::RegisterAnnotationRenderer(AbstractAnnotationRenderer *annotationRenderer) { static AnnotationRendererServices AnnotationRendererServices; // Define ServiceProps us::ServiceProperties props; props[AbstractAnnotationRenderer::US_PROPKEY_RENDERER_ID] = annotationRenderer->GetRendererID(); props[AbstractAnnotationRenderer::US_PROPKEY_ID] = annotationRenderer->GetID(); us::GetModuleContext()->RegisterService(annotationRenderer, props); AnnotationRendererServices.push_back(std::unique_ptr(annotationRenderer)); } void AnnotationService::UpdateAnnotationRenderer(const std::string &rendererID) { for (AbstractAnnotationRenderer *annotationRenderer : GetAnnotationRenderer(rendererID)) { annotationRenderer->Update(); } } - void AnnotationService::BaseRendererChanged(const std::string &rendererID) + void AnnotationService::BaseRendererChanged(BaseRenderer *renderer) { - for (AbstractAnnotationRenderer *annotationRenderer : GetAnnotationRenderer(rendererID)) + for (AbstractAnnotationRenderer *annotationRenderer : GetAnnotationRenderer(renderer->GetName())) { annotationRenderer->CurrentBaseRendererChanged(); } + vtkCallbackCommand *renderCallbackCommand = vtkCallbackCommand::New(); + renderCallbackCommand->SetCallback(AnnotationService::RenderWindowCallback); + renderer->GetRenderWindow()->AddObserver(vtkCommand::ModifiedEvent, renderCallbackCommand); + renderCallbackCommand->Delete(); + } + + void AnnotationService::RenderWindowCallback(vtkObject *caller, unsigned long, void *, void *) + { + vtkRenderWindow *renderWindow = dynamic_cast(caller); + if (!renderWindow) + return; + BaseRenderer *renderer = BaseRenderer::GetInstance(renderWindow); + for (AbstractAnnotationRenderer *annotationRenderer : GetAnnotationRenderer(renderer->GetName())) + { + annotationRenderer->OnRenderWindowModified(); + } } Overlay *AnnotationService::GetOverlay(const std::string &overlayID) { std::string ldapFilter = "(" + Overlay::US_PROPKEY_ID + "=" + overlayID + ")"; us::ModuleContext *context = us::GetModuleContext(); std::vector> overlays = context->GetServiceReferences(ldapFilter); Overlay *overlay = nullptr; if (!overlays.empty()) { overlay = us::GetModuleContext()->GetService(overlays.front()); } return overlay; } std::vector AnnotationService::GetAnnotationRenderer(const std::string &rendererID) { us::ModuleContext *context = us::GetModuleContext(); // specify a filter that defines the requested type std::string filter = "(&(" + AbstractAnnotationRenderer::US_PROPKEY_ID + "=*)(" + AbstractAnnotationRenderer::US_PROPKEY_RENDERER_ID + "=" + rendererID + "))"; // find the fitting service std::vector serviceReferences = context->GetServiceReferences(AbstractAnnotationRenderer::US_INTERFACE_NAME, filter); std::vector arList; for (us::ServiceReferenceU service : serviceReferences) { arList.push_back(context->GetService(service)); } return arList; } } diff --git a/Modules/Core/src/Rendering/mitkOverlay.cpp b/Modules/Core/src/Rendering/mitkOverlay.cpp index 4820a5bb09..671bcec7c6 100644 --- a/Modules/Core/src/Rendering/mitkOverlay.cpp +++ b/Modules/Core/src/Rendering/mitkOverlay.cpp @@ -1,358 +1,344 @@ /*=================================================================== 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 "mitkOverlay.h" #include "usGetModuleContext.h" const std::string mitk::Overlay::US_INTERFACE_NAME = "org.mitk.services.Overlay"; const std::string mitk::Overlay::US_PROPKEY_OVERLAYNAME = US_INTERFACE_NAME + ".name"; const std::string mitk::Overlay::US_PROPKEY_ID = US_INTERFACE_NAME + ".id"; const std::string mitk::Overlay::US_PROPKEY_MODIFIED = US_INTERFACE_NAME + ".modified"; const std::string mitk::Overlay::US_PROPKEY_RENDERER_ID = US_INTERFACE_NAME + ".rendererId"; const std::string mitk::Overlay::US_PROPKEY_AR_ID = US_INTERFACE_NAME + ".arId"; mitk::Overlay::Overlay() : m_LayoutedBy(nullptr), m_PropertyListModifiedObserverTag(0) { m_PropertyList = mitk::PropertyList::New(); itk::MemberCommand::Pointer _PropertyListModifiedCommand = itk::MemberCommand::New(); _PropertyListModifiedCommand->SetCallbackFunction(this, &mitk::Overlay::PropertyListModified); m_PropertyListModifiedObserverTag = m_PropertyList->AddObserver(itk::ModifiedEvent(), _PropertyListModifiedCommand); this->SetName(this->GetNameOfClass()); this->SetVisibility(true); this->SetOpacity(1.0); } void mitk::Overlay::PropertyListModified(const itk::Object * /*caller*/, const itk::EventObject &) { OverlayModified(); } mitk::Overlay::~Overlay() { this->UnRegisterMicroservice(); } void mitk::Overlay::SetUSProperty(const std::string &propertyKey, us::Any value) { if (this->m_ServiceRegistration) { us::ServiceProperties props; std::vector propertyKeys; m_ServiceRegistration.GetReference().GetPropertyKeys(propertyKeys); for (std::string key : propertyKeys) { props[key] = m_ServiceRegistration.GetReference().GetProperty(key); } props[propertyKey] = value; m_ServiceRegistration.SetProperties(props); } } void mitk::Overlay::SetProperty(const std::string &propertyKey, const BaseProperty::Pointer &propertyValue) { this->m_PropertyList->SetProperty(propertyKey, propertyValue); } void mitk::Overlay::ReplaceProperty(const std::string &propertyKey, const BaseProperty::Pointer &propertyValue) { this->m_PropertyList->ReplaceProperty(propertyKey, propertyValue); } void mitk::Overlay::AddProperty(const std::string &propertyKey, const BaseProperty::Pointer &propertyValue, bool overwrite) { if ((overwrite) || (GetProperty(propertyKey) == NULL)) { SetProperty(propertyKey, propertyValue); } } void mitk::Overlay::ConcatenatePropertyList(PropertyList *pList, bool replace) { m_PropertyList->ConcatenatePropertyList(pList, replace); } mitk::BaseProperty *mitk::Overlay::GetProperty(const std::string &propertyKey) const { mitk::BaseProperty::Pointer property = m_PropertyList->GetProperty(propertyKey); if (property.IsNotNull()) return property; // only to satisfy compiler! return NULL; } bool mitk::Overlay::GetBoolProperty(const std::string &propertyKey, bool &boolValue) const { mitk::BoolProperty::Pointer boolprop = dynamic_cast(GetProperty(propertyKey)); if (boolprop.IsNull()) return false; boolValue = boolprop->GetValue(); return true; } bool mitk::Overlay::GetIntProperty(const std::string &propertyKey, int &intValue) const { mitk::IntProperty::Pointer intprop = dynamic_cast(GetProperty(propertyKey)); if (intprop.IsNull()) return false; intValue = intprop->GetValue(); return true; } bool mitk::Overlay::GetFloatProperty(const std::string &propertyKey, float &floatValue) const { mitk::FloatProperty::Pointer floatprop = dynamic_cast(GetProperty(propertyKey)); if (floatprop.IsNull()) return false; floatValue = floatprop->GetValue(); return true; } bool mitk::Overlay::GetStringProperty(const std::string &propertyKey, std::string &string) const { mitk::StringProperty::Pointer stringProp = dynamic_cast(GetProperty(propertyKey)); if (stringProp.IsNull()) { return false; } else { // memcpy((void*)string, stringProp->GetValue(), strlen(stringProp->GetValue()) + 1 ); // looks dangerous string = stringProp->GetValue(); return true; } } void mitk::Overlay::SetIntProperty(const std::string &propertyKey, int intValue) { this->m_PropertyList->SetProperty(propertyKey, mitk::IntProperty::New(intValue)); Modified(); } void mitk::Overlay::SetBoolProperty(const std::string &propertyKey, bool boolValue) { this->m_PropertyList->SetProperty(propertyKey, mitk::BoolProperty::New(boolValue)); Modified(); } void mitk::Overlay::SetFloatProperty(const std::string &propertyKey, float floatValue) { this->m_PropertyList->SetProperty(propertyKey, mitk::FloatProperty::New(floatValue)); Modified(); } void mitk::Overlay::SetStringProperty(const std::string &propertyKey, const std::string &stringValue) { this->m_PropertyList->SetProperty(propertyKey, mitk::StringProperty::New(stringValue)); Modified(); } std::string mitk::Overlay::GetName() const { mitk::StringProperty *sp = dynamic_cast(this->GetProperty("name")); if (sp == NULL) return ""; return sp->GetValue(); } void mitk::Overlay::SetName(const std::string &name) { this->SetStringProperty("name", name); } bool mitk::Overlay::GetName(std::string &nodeName, const std::string &propertyKey) const { return GetStringProperty(propertyKey, nodeName); } void mitk::Overlay::SetText(std::string text) { SetStringProperty("Text", text.c_str()); } std::string mitk::Overlay::GetText() const { std::string text; GetStringProperty("Text", text); return text; } void mitk::Overlay::SetFontSize(int fontSize) { SetIntProperty("FontSize", fontSize); } int mitk::Overlay::GetFontSize() const { int fontSize = 1; GetIntProperty("FontSize", fontSize); return fontSize; } -void mitk::Overlay::SetMargin2D(const Point2D &OffsetVector) -{ - mitk::Point2dProperty::Pointer OffsetVectorProperty = mitk::Point2dProperty::New(OffsetVector); - SetProperty("Margin2D", OffsetVectorProperty.GetPointer()); -} - -mitk::Point2D mitk::Overlay::GetMargin2D() const -{ - mitk::Point2D OffsetVector; - OffsetVector.Fill(0); - GetPropertyValue("Margin2D", OffsetVector); - return OffsetVector; -} - bool mitk::Overlay::GetVisibility(bool &visible, const std::string &propertyKey) const { return GetBoolProperty(propertyKey, visible); } bool mitk::Overlay::IsVisible(const std::string &propertyKey, bool defaultIsOn) const { return IsOn(propertyKey, defaultIsOn); } bool mitk::Overlay::GetColor(float rgb[], const std::string &propertyKey) const { mitk::ColorProperty::Pointer colorprop = dynamic_cast(GetProperty(propertyKey)); if (colorprop.IsNull()) return false; memcpy(rgb, colorprop->GetColor().GetDataPointer(), 3 * sizeof(float)); return true; } void mitk::Overlay::SetColor(const mitk::Color &color, const std::string &propertyKey) { mitk::ColorProperty::Pointer prop; prop = mitk::ColorProperty::New(color); this->m_PropertyList->SetProperty(propertyKey, prop); } void mitk::Overlay::SetColor(float red, float green, float blue, const std::string &propertyKey) { float color[3]; color[0] = red; color[1] = green; color[2] = blue; SetColor(color, propertyKey); } void mitk::Overlay::SetColor(const float rgb[], const std::string &propertyKey) { mitk::ColorProperty::Pointer prop; prop = mitk::ColorProperty::New(rgb); this->m_PropertyList->SetProperty(propertyKey, prop); } bool mitk::Overlay::GetOpacity(float &opacity, const std::string &propertyKey) const { mitk::FloatProperty::Pointer opacityprop = dynamic_cast(GetProperty(propertyKey)); if (opacityprop.IsNull()) return false; opacity = opacityprop->GetValue(); return true; } void mitk::Overlay::SetOpacity(float opacity, const std::string &propertyKey) { mitk::FloatProperty::Pointer prop; prop = mitk::FloatProperty::New(opacity); this->m_PropertyList->SetProperty(propertyKey, prop); } void mitk::Overlay::SetVisibility(bool visible, const std::string &propertyKey) { mitk::BoolProperty::Pointer prop; prop = mitk::BoolProperty::New(visible); this->m_PropertyList->SetProperty(propertyKey, prop); Modified(); } bool mitk::Overlay::BaseLocalStorage::IsGenerateDataRequired(mitk::BaseRenderer *renderer, mitk::Overlay *overlay) { if (m_LastGenerateDataTime < overlay->GetMTime()) return true; if (m_LastGenerateDataTime < overlay->GetPropertyList()->GetMTime()) return true; if (renderer && m_LastGenerateDataTime < renderer->GetTimeStepUpdateTime()) return true; return false; } mitk::Overlay::Bounds mitk::Overlay::GetBoundsOnDisplay(mitk::BaseRenderer *) const { mitk::Overlay::Bounds bounds; bounds.Position[0] = bounds.Position[1] = bounds.Size[0] = bounds.Size[1] = 0; return bounds; } void mitk::Overlay::SetBoundsOnDisplay(mitk::BaseRenderer *, const mitk::Overlay::Bounds &) { } void mitk::Overlay::SetForceInForeground(bool forceForeground) { m_ForceInForeground = forceForeground; } bool mitk::Overlay::IsForceInForeground() const { return m_ForceInForeground; } mitk::PropertyList *mitk::Overlay::GetPropertyList() const { return m_PropertyList; } std::string mitk::Overlay::GetMicroserviceID() { return this->m_ServiceRegistration.GetReference().GetProperty(US_PROPKEY_ID).ToString(); } void mitk::Overlay::RegisterAsMicroservice(us::ServiceProperties props) { if (m_ServiceRegistration != NULL) m_ServiceRegistration.Unregister(); us::ModuleContext *context = us::GetModuleContext(); // Define ServiceProps mitk::UIDGenerator uidGen = mitk::UIDGenerator("org.mitk.services.Overlay.id_", 16); props[US_PROPKEY_ID] = uidGen.GetUID(); m_ServiceRegistration = context->RegisterService(this, props); } void mitk::Overlay::UnRegisterMicroservice() { if (m_ServiceRegistration != NULL) m_ServiceRegistration.Unregister(); m_ServiceRegistration = 0; } void mitk::Overlay::OverlayModified() { Modified(); this->SetUSProperty(US_PROPKEY_MODIFIED, this->GetMTime()); } diff --git a/Modules/Core/src/Rendering/mitkRenderWindowBase.cpp b/Modules/Core/src/Rendering/mitkRenderWindowBase.cpp index 9ef7ed0a25..fdc4f18d0f 100644 --- a/Modules/Core/src/Rendering/mitkRenderWindowBase.cpp +++ b/Modules/Core/src/Rendering/mitkRenderWindowBase.cpp @@ -1,121 +1,121 @@ /*=================================================================== 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 "mitkRenderWindowBase.h" #include "mitkRenderingManager.h" #include "mitkVtkLayerController.h" #include "vtkRenderer.h" #include "mitkAnnotationService.h" mitk::RenderWindowBase::RenderWindowBase() : m_RenderProp(NULL), m_InResize(false) { } /* * "Member functions, including virtual functions (10.3), can be called during construction or destruction (12.6.2). When a * virtual function is called directly or indirectly from a constructor (including from the mem-initializer for a data member) or from * a destructor, and the object to which the call applies is the object under construction or destruction, the function called is * the one defined in the constructor or destructor's own class or in one of its bases, but not a function overriding it in a class * derived from the constructor or destructor's class, or overriding it in one of the other base classes of the most derived object[..]" * or short: within constructors and destructors classes are not polymorph. */ void mitk::RenderWindowBase::Initialize(mitk::RenderingManager *renderingManager, const char *name, mitk::BaseRenderer::RenderingMode::Type renderingMode) { if (renderingManager == NULL) { renderingManager = mitk::RenderingManager::GetInstance(); } if (m_Renderer.IsNull()) { m_Renderer = mitk::VtkPropRenderer::New(name, GetVtkRenderWindow(), renderingManager, renderingMode); } m_Renderer->InitRenderer(this->GetVtkRenderWindow()); mitk::BaseRenderer::AddInstance(GetVtkRenderWindow(), m_Renderer); renderingManager->AddRenderWindow(GetVtkRenderWindow()); // Add previously created overlays to new BaseRenderer - mitk::AnnotationService::BaseRendererChanged(m_Renderer->GetName()); + mitk::AnnotationService::BaseRendererChanged(m_Renderer); m_RenderProp = vtkMitkRenderProp::New(); m_RenderProp->SetPropRenderer(m_Renderer); m_Renderer->GetVtkRenderer()->AddViewProp(m_RenderProp); if ((this->GetVtkRenderWindow()->GetSize()[0] > 10) && (this->GetVtkRenderWindow()->GetSize()[1] > 10)) m_Renderer->InitSize(this->GetVtkRenderWindow()->GetSize()[0], this->GetVtkRenderWindow()->GetSize()[1]); m_InResize = false; } bool mitk::RenderWindowBase::HandleEvent(InteractionEvent *interactionEvent) { return m_Renderer->GetDispatcher()->ProcessEvent(interactionEvent); } void mitk::RenderWindowBase::Destroy() { m_Renderer->GetRenderingManager()->RemoveRenderWindow(GetVtkRenderWindow()); mitk::BaseRenderer::RemoveInstance(GetVtkRenderWindow()); m_Renderer->GetVtkRenderer()->RemoveViewProp(m_RenderProp); m_RenderProp->Delete(); } mitk::RenderWindowBase::~RenderWindowBase() { } mitk::SliceNavigationController *mitk::RenderWindowBase::GetSliceNavigationController() { return mitk::BaseRenderer::GetInstance(this->GetVtkRenderWindow())->GetSliceNavigationController(); } mitk::CameraRotationController *mitk::RenderWindowBase::GetCameraRotationController() { return mitk::BaseRenderer::GetInstance(this->GetVtkRenderWindow())->GetCameraRotationController(); } mitk::BaseController *mitk::RenderWindowBase::GetController() { mitk::BaseRenderer *renderer = mitk::BaseRenderer::GetInstance(GetVtkRenderWindow()); switch (renderer->GetMapperID()) { case mitk::BaseRenderer::Standard2D: return GetSliceNavigationController(); case mitk::BaseRenderer::Standard3D: return GetCameraRotationController(); default: return GetSliceNavigationController(); } } mitk::VtkPropRenderer *mitk::RenderWindowBase::GetRenderer() { return m_Renderer; } diff --git a/Modules/Overlays/include/mitkOverlayLayouter2D.h b/Modules/Overlays/include/mitkOverlayLayouter2D.h index 20828703ba..f887dc5c46 100644 --- a/Modules/Overlays/include/mitkOverlayLayouter2D.h +++ b/Modules/Overlays/include/mitkOverlayLayouter2D.h @@ -1,91 +1,103 @@ /*=================================================================== 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 OVERLAYLAYOUTER2D_H #define OVERLAYLAYOUTER2D_H #include "MitkOverlaysExports.h" #include "mitkAbstractAnnotationRenderer.h" namespace mitk { class BaseRenderer; /** \brief The OverlayLayouter2D updates and manages Overlays and the respective Layouters. */ /** An Instance of the OverlayLayouter2D can be registered to several BaseRenderer instances in order to * call the update method of each Overlay during the rendering phase of the renderer. * See \ref OverlaysPage for more info. */ class MITKOVERLAYS_EXPORT OverlayLayouter2D : public AbstractAnnotationRenderer { public: static const std::string PROP_LAYOUT; static const std::string PROP_LAYOUT_PRIORITY; static const std::string PROP_LAYOUT_ALIGNMENT; + static const std::string PROP_LAYOUT_MARGIN; enum Alignment { TopLeft, Top, TopRight, BottomLeft, Bottom, BottomRight, Left, Right }; typedef std::vector OverlayVector; typedef std::map OverlayLayouterContainerMap; /** \brief virtual destructor in order to derive from this class */ virtual ~OverlayLayouter2D(); const std::string GetID() const; static OverlayLayouter2D *GetAnnotationRenderer(const std::string &rendererID); + void OnRenderWindowModified(); + static void AddOverlay(Overlay *overlay, const std::string &rendererID, Alignment alignment = TopLeft, + double marginX = 5, + double marginY = 5, int priority = -1); - static void AddOverlay(Overlay *overlay, BaseRenderer *renderer, Alignment alignment = TopLeft, int priority = -1); + static void AddOverlay(Overlay *overlay, + BaseRenderer *renderer, + Alignment alignment = TopLeft, + double marginX = 5, + double marginY = 5, + int priority = -1); void PrepareLayout(); private: OverlayLayouter2D(const std::string &rendererId); - static void AddAlignmentProperty(Overlay *overlay, Alignment activeAlignment, int priority); + static void AddAlignmentProperty(Overlay *overlay, Alignment activeAlignment, Point2D margin, int priority); void PrepareTopLeftLayout(int *displaySize); void PrepareTopLayout(int *displaySize); void PrepareTopRightLayout(int *displaySize); void PrepareBottomLeftLayout(int *displaySize); void PrepareBottomLayout(int *displaySize); void PrepareBottomRightLayout(int *displaySize); void PrepareLeftLayout(int *displaySize); void PrepareRightLayout(int *displaySize); static double GetHeight(OverlayVector &overlays, BaseRenderer *renderer); virtual void OnAnnotationRenderersChanged(); static const std::string ANNOTATIONRENDERER_ID; OverlayLayouterContainerMap m_OverlayContainerMap; + static void SetMargin2D(Overlay *overlay, const Point2D &OffsetVector); + static Point2D GetMargin2D(Overlay *overlay); }; } // namespace mitk #endif // OVERLAYLAYOUTER2D_H diff --git a/Modules/Overlays/src/mitkOverlayLayouter2D.cpp b/Modules/Overlays/src/mitkOverlayLayouter2D.cpp index 19bd20be7c..66ff2a0c3f 100644 --- a/Modules/Overlays/src/mitkOverlayLayouter2D.cpp +++ b/Modules/Overlays/src/mitkOverlayLayouter2D.cpp @@ -1,295 +1,330 @@ /*=================================================================== 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 "mitkOverlayLayouter2D.h" #include "mitkBaseRenderer.h" #include "mitkAnnotationService.h" #include "mitkEnumerationProperty.h" #include "mitkOverlay2DLayouter.h" #include namespace mitk { const std::string OverlayLayouter2D::ANNOTATIONRENDERER_ID = "OverlayLayouter2D"; const std::string OverlayLayouter2D::PROP_LAYOUT = "Layout"; const std::string OverlayLayouter2D::PROP_LAYOUT_PRIORITY = PROP_LAYOUT + ".priority"; const std::string OverlayLayouter2D::PROP_LAYOUT_ALIGNMENT = PROP_LAYOUT + ".alignment"; + const std::string OverlayLayouter2D::PROP_LAYOUT_MARGIN = PROP_LAYOUT + ".margin"; + + void OverlayLayouter2D::SetMargin2D(Overlay *overlay, const Point2D &OffsetVector) + { + mitk::Point2dProperty::Pointer OffsetVectorProperty = mitk::Point2dProperty::New(OffsetVector); + overlay->SetProperty(PROP_LAYOUT_MARGIN, OffsetVectorProperty.GetPointer()); + } + + Point2D OverlayLayouter2D::GetMargin2D(Overlay *overlay) + { + mitk::Point2D OffsetVector; + OffsetVector.Fill(0); + overlay->GetPropertyValue(PROP_LAYOUT_MARGIN, OffsetVector); + return OffsetVector; + } OverlayLayouter2D::OverlayLayouter2D(const std::string &rendererId) : AbstractAnnotationRenderer(rendererId, OverlayLayouter2D::ANNOTATIONRENDERER_ID) { } - void OverlayLayouter2D::AddAlignmentProperty(Overlay *overlay, Alignment activeAlignment, int priority) + void OverlayLayouter2D::AddAlignmentProperty(Overlay *overlay, + Alignment activeAlignment, + Point2D margin, + int priority) { EnumerationProperty::Pointer alignmentProperty(mitk::EnumerationProperty::New()); alignmentProperty->AddEnum("TopLeft", TopLeft); alignmentProperty->AddEnum("Top", Top); alignmentProperty->AddEnum("TopRight", TopRight); alignmentProperty->AddEnum("BottomLeft ", BottomLeft); alignmentProperty->AddEnum("Bottom", Bottom); alignmentProperty->AddEnum("BottomRight", BottomRight); alignmentProperty->AddEnum("Left", Left); alignmentProperty->AddEnum("Right", Right); alignmentProperty->SetValue(activeAlignment); overlay->AddProperty(PROP_LAYOUT_ALIGNMENT, alignmentProperty.GetPointer()); overlay->SetIntProperty(PROP_LAYOUT_PRIORITY, priority); + SetMargin2D(overlay, margin); } void OverlayLayouter2D::OnAnnotationRenderersChanged() { + if (!this->GetCurrentBaseRenderer()) + return; m_OverlayContainerMap.clear(); for (Overlay *overlay : this->GetServices()) { + if (!overlay) + continue; BaseProperty *prop = overlay->GetProperty(PROP_LAYOUT_ALIGNMENT); EnumerationProperty *enumProb = dynamic_cast(prop); Alignment currentAlignment = TopLeft; + Point2D margin; + margin.Fill(5); int priority = -1; overlay->GetIntProperty(PROP_LAYOUT_PRIORITY, priority); if (!enumProb) { - AddAlignmentProperty(overlay, currentAlignment, priority); + AddAlignmentProperty(overlay, currentAlignment, margin, priority); } else { currentAlignment = static_cast(enumProb->GetValueAsId()); } OverlayVector &overlayVec = m_OverlayContainerMap[currentAlignment]; if (!overlayVec.empty() && priority >= 0) { for (auto it = overlayVec.begin(); it != overlayVec.end(); ++it) { int listPrio = -1; (*it)->GetIntProperty(PROP_LAYOUT_PRIORITY, listPrio); if (listPrio >= priority) { overlayVec.insert(it + 1, overlay); } } } overlayVec.push_back(overlay); } + this->PrepareLayout(); } OverlayLayouter2D::~OverlayLayouter2D() {} const std::string OverlayLayouter2D::GetID() const { return ANNOTATIONRENDERER_ID; } OverlayLayouter2D *OverlayLayouter2D::GetAnnotationRenderer(const std::string &rendererID) { OverlayLayouter2D *result = nullptr; AbstractAnnotationRenderer *registeredService = AnnotationService::GetAnnotationRenderer(ANNOTATIONRENDERER_ID, rendererID); if (registeredService) result = dynamic_cast(registeredService); if (!result) { result = new OverlayLayouter2D(rendererID); AnnotationService::RegisterAnnotationRenderer(result); } return result; } - void OverlayLayouter2D::AddOverlay(Overlay *overlay, const std::string &rendererID, Alignment alignment, int priority) + void OverlayLayouter2D::OnRenderWindowModified() { PrepareLayout(); } + void OverlayLayouter2D::AddOverlay( + Overlay *overlay, const std::string &rendererID, Alignment alignment, double marginX, double marginY, int priority) { GetAnnotationRenderer(rendererID); us::ServiceProperties props; props[Overlay::US_PROPKEY_AR_ID] = ANNOTATIONRENDERER_ID; props[Overlay::US_PROPKEY_RENDERER_ID] = rendererID; overlay->RegisterAsMicroservice(props); - AddAlignmentProperty(overlay, alignment, priority); + Point2D margin; + margin[0] = marginX; + margin[1] = marginY; + AddAlignmentProperty(overlay, alignment, margin, priority); } - void OverlayLayouter2D::AddOverlay(Overlay *overlay, BaseRenderer *renderer, Alignment alignment, int priority) + void OverlayLayouter2D::AddOverlay( + Overlay *overlay, BaseRenderer *renderer, Alignment alignment, double marginX, double marginY, int priority) { - AddOverlay(overlay, renderer->GetName(), alignment, priority); + AddOverlay(overlay, renderer->GetName(), alignment, marginX, marginY, priority); } void OverlayLayouter2D::PrepareLayout() { - // std::vector managedOverlays = this->GetServices(); - // std::list::iterator it; - // mitk::Overlay::Bounds bounds; - // int *size = this->GetCurrentBaseRenderer()->GetVtkRenderer()->GetSize(); - - // The alignment enum defines the type of this layouter + if (!this->GetCurrentBaseRenderer()) + return; + int *size = this->GetCurrentBaseRenderer()->GetVtkRenderer()->GetSize(); + PrepareTopLeftLayout(size); + PrepareTopLayout(size); + PrepareTopRightLayout(size); + PrepareBottomLeftLayout(size); + PrepareBottomLayout(size); + PrepareBottomRightLayout(size); + PrepareLeftLayout(size); + PrepareRightLayout(size); } - void OverlayLayouter2D::PrepareTopLeftLayout(int *displaySize) { double posX, posY; Point2D margin; posX = 0; posY = displaySize[1]; mitk::Overlay::Bounds bounds; for (mitk::Overlay *overlay : m_OverlayContainerMap[TopLeft]) { - margin = overlay->GetMargin2D(); + margin = GetMargin2D(overlay); bounds = overlay->GetBoundsOnDisplay(this->GetCurrentBaseRenderer()); - posX += margin[0]; posY -= bounds.Size[1] + margin[1]; - bounds.Position[0] = posX; + bounds.Position[0] = posX + margin[0]; bounds.Position[1] = posY; overlay->SetBoundsOnDisplay(this->GetCurrentBaseRenderer(), bounds); } } void OverlayLayouter2D::PrepareTopLayout(int *displaySize) { double posX, posY; Point2D margin; posX = 0; posY = displaySize[1]; mitk::Overlay::Bounds bounds; for (mitk::Overlay *overlay : m_OverlayContainerMap[Top]) { - margin = overlay->GetMargin2D(); + margin = GetMargin2D(overlay); bounds = overlay->GetBoundsOnDisplay(this->GetCurrentBaseRenderer()); posX = displaySize[0] / 2 - bounds.Size[0] / 2; posY -= bounds.Size[1] + margin[1]; bounds.Position[0] = posX; bounds.Position[1] = posY; overlay->SetBoundsOnDisplay(this->GetCurrentBaseRenderer(), bounds); } } void OverlayLayouter2D::PrepareTopRightLayout(int *displaySize) { double posX, posY; Point2D margin; posX = 0; posY = displaySize[1]; mitk::Overlay::Bounds bounds; for (mitk::Overlay *overlay : m_OverlayContainerMap[TopRight]) { - margin = overlay->GetMargin2D(); + margin = GetMargin2D(overlay); bounds = overlay->GetBoundsOnDisplay(this->GetCurrentBaseRenderer()); posX = displaySize[0] - (bounds.Size[0] + margin[0]); posY -= bounds.Size[1] + margin[1]; bounds.Position[0] = posX; bounds.Position[1] = posY; overlay->SetBoundsOnDisplay(this->GetCurrentBaseRenderer(), bounds); } } - void OverlayLayouter2D::PrepareBottomLeftLayout(int * /*displaySize*/) + + void OverlayLayouter2D::PrepareRightLayout(int *displaySize) { - double posX, posY; + double posY; Point2D margin; - posX = 0; - posY = 0; + double height = GetHeight(m_OverlayContainerMap[Right], GetCurrentBaseRenderer()); + posY = (height / 2.0 + displaySize[1]) / 2.0; mitk::Overlay::Bounds bounds; - for (mitk::Overlay *overlay : m_OverlayContainerMap[BottomLeft]) + for (mitk::Overlay *overlay : m_OverlayContainerMap[Right]) { - margin = overlay->GetMargin2D(); + margin = GetMargin2D(overlay); bounds = overlay->GetBoundsOnDisplay(this->GetCurrentBaseRenderer()); - bounds.Position[0] = posX + margin[0]; + posY -= bounds.Size[1] + margin[1]; + bounds.Position[0] = displaySize[0] - (bounds.Size[0] + margin[0]); bounds.Position[1] = posY + margin[1]; overlay->SetBoundsOnDisplay(this->GetCurrentBaseRenderer(), bounds); - posY += bounds.Size[1] + margin[1]; } } - void OverlayLayouter2D::PrepareBottomLayout(int *displaySize) + + void OverlayLayouter2D::PrepareLeftLayout(int *displaySize) { - double posX, posY; + double posY; Point2D margin; - posX = 0; - posY = 0; + double height = GetHeight(m_OverlayContainerMap[Left], GetCurrentBaseRenderer()); + posY = (height / 2.0 + displaySize[1]) / 2.0; mitk::Overlay::Bounds bounds; - for (mitk::Overlay *overlay : m_OverlayContainerMap[Bottom]) + for (mitk::Overlay *overlay : m_OverlayContainerMap[Left]) { - margin = overlay->GetMargin2D(); + margin = GetMargin2D(overlay); bounds = overlay->GetBoundsOnDisplay(this->GetCurrentBaseRenderer()); - posX = displaySize[0] / 2 - bounds.Size[0] / 2; - bounds.Position[0] = posX; - bounds.Position[1] = posY + margin[1]; + posY -= bounds.Size[1] + margin[1]; + bounds.Position[0] = margin[0]; + bounds.Position[1] = posY; overlay->SetBoundsOnDisplay(this->GetCurrentBaseRenderer(), bounds); - posY += bounds.Size[1] + margin[1]; } } - void OverlayLayouter2D::PrepareBottomRightLayout(int *displaySize) + + void OverlayLayouter2D::PrepareBottomLeftLayout(int * /*displaySize*/) { double posX, posY; Point2D margin; posX = 0; posY = 0; mitk::Overlay::Bounds bounds; - for (mitk::Overlay *overlay : m_OverlayContainerMap[BottomRight]) + for (mitk::Overlay *overlay : m_OverlayContainerMap[BottomLeft]) { - margin = overlay->GetMargin2D(); + margin = GetMargin2D(overlay); bounds = overlay->GetBoundsOnDisplay(this->GetCurrentBaseRenderer()); - posX = displaySize[0] - (bounds.Size[0] + margin[0]); - bounds.Position[0] = posX; + bounds.Position[0] = posX + margin[0]; bounds.Position[1] = posY + margin[1]; overlay->SetBoundsOnDisplay(this->GetCurrentBaseRenderer(), bounds); posY += bounds.Size[1] + margin[1]; } } - void OverlayLayouter2D::PrepareLeftLayout(int *displaySize) + void OverlayLayouter2D::PrepareBottomLayout(int *displaySize) { double posX, posY; Point2D margin; - posX = displaySize[0]; - posY = displaySize[1] / 2.0; + posX = 0; + posY = 0; mitk::Overlay::Bounds bounds; - for (mitk::Overlay *overlay : m_OverlayContainerMap[Left]) + for (mitk::Overlay *overlay : m_OverlayContainerMap[Bottom]) { - margin = overlay->GetMargin2D(); + margin = GetMargin2D(overlay); bounds = overlay->GetBoundsOnDisplay(this->GetCurrentBaseRenderer()); - posY = (displaySize[1] - bounds.Size[1]) / 2.0; - posX = displaySize[0] - (bounds.Size[0] + margin[0]); + posX = displaySize[0] / 2 - bounds.Size[0] / 2; bounds.Position[0] = posX; bounds.Position[1] = posY + margin[1]; overlay->SetBoundsOnDisplay(this->GetCurrentBaseRenderer(), bounds); - posY += bounds.Size[1]; + posY += bounds.Size[1] + margin[1]; } } - void OverlayLayouter2D::PrepareRightLayout(int *displaySize) + void OverlayLayouter2D::PrepareBottomRightLayout(int *displaySize) { double posX, posY; Point2D margin; posX = 0; - posY = displaySize[1] / 2.0; + posY = 0; mitk::Overlay::Bounds bounds; - for (mitk::Overlay *overlay : m_OverlayContainerMap[Right]) + for (mitk::Overlay *overlay : m_OverlayContainerMap[BottomRight]) { - margin = overlay->GetMargin2D(); + margin = GetMargin2D(overlay); bounds = overlay->GetBoundsOnDisplay(this->GetCurrentBaseRenderer()); - posY = (displaySize[1] - bounds.Size[1]) / 2.0; - bounds.Position[0] = posX + margin[0]; - bounds.Position[1] = posY; + posX = displaySize[0] - (bounds.Size[0] + margin[0]); + bounds.Position[0] = posX; + bounds.Position[1] = posY + margin[1]; overlay->SetBoundsOnDisplay(this->GetCurrentBaseRenderer(), bounds); posY += bounds.Size[1] + margin[1]; } } double OverlayLayouter2D::GetHeight(OverlayVector &overlays, BaseRenderer *renderer) { double height = 0; for (auto overlay : overlays) { Overlay::Bounds bounds = overlay->GetBoundsOnDisplay(renderer); height += bounds.Size[0]; - height += overlay->GetMargin2D()[0]; + height += GetMargin2D(overlay)[0]; } return height; } } diff --git a/Plugins/org.mitk.gui.qt.overlaymanager/src/internal/QmitkOverlayManagerView.cpp b/Plugins/org.mitk.gui.qt.overlaymanager/src/internal/QmitkOverlayManagerView.cpp index 4abbdf82a5..98d24e6514 100644 --- a/Plugins/org.mitk.gui.qt.overlaymanager/src/internal/QmitkOverlayManagerView.cpp +++ b/Plugins/org.mitk.gui.qt.overlaymanager/src/internal/QmitkOverlayManagerView.cpp @@ -1,537 +1,539 @@ /*=================================================================== 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 // Blueberry #include #include #include // Qmitk #include "QmitkAddNewPropertyDialog.h" #include "QmitkOverlayManagerView.h" #include "QmitkPropertyItemDelegate.h" #include "QmitkPropertyItemModel.h" #include // Qt #include #include #include #include "internal/org_mitk_gui_qt_overlaymanager_Activator.h" #include "mitkAnnotationPlacer.h" #include "mitkAnnotationService.h" #include "mitkGetPropertyService.h" +#include "mitkOverlayLayouter2D.h" #include "mitkOverlayManager.h" #include "mitkRenderingManager.h" #include #include #include #include #include #include #include #include #include const std::string QmitkOverlayManagerView::VIEW_ID = "org.mitk.views.overlaymanager"; QmitkOverlayManagerView::QmitkOverlayManagerView() : m_Parent(nullptr), m_PropertyNameChangedTag(0), m_OverlayManagerObserverTag(0), m_PropertyAliases(nullptr), m_PropertyDescriptions(nullptr), m_PropertyPersistence(nullptr), m_ProxyModel(nullptr), m_Model(nullptr), m_Delegate(nullptr), m_Renderer(nullptr), m_AddOverlayMenu(nullptr) { } QmitkOverlayManagerView::~QmitkOverlayManagerView() { } void QmitkOverlayManagerView::SetFocus() { } void QmitkOverlayManagerView::CreateQtPartControl(QWidget *parent) { // create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi(parent); m_Controls.m_OverlayList->clear(); mitk::IRenderWindowPart *renderWindowPart = this->GetRenderWindowPart(); if (renderWindowPart != NULL) { QHash renderWindows = renderWindowPart->GetQmitkRenderWindows(); Q_FOREACH (QString renderWindow, renderWindows.keys()) { if (!m_Renderer) m_Renderer = renderWindows[renderWindow]->GetRenderer(); m_Controls.m_RendererCB->addItem(renderWindow); } } InitializeAddOverlayMenu(); m_ProxyModel = new QSortFilterProxyModel(m_Controls.m_PropertyTree); m_Model = new QmitkPropertyItemModel(m_ProxyModel); m_ProxyModel->setSourceModel(m_Model); m_ProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); m_ProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); m_ProxyModel->setDynamicSortFilter(true); m_Delegate = new QmitkPropertyItemDelegate(m_Controls.m_PropertyTree); m_Controls.m_PropertyTree->setItemDelegateForColumn(1, m_Delegate); m_Controls.m_PropertyTree->setModel(m_ProxyModel); m_Controls.m_PropertyTree->setColumnWidth(0, 160); m_Controls.m_PropertyTree->sortByColumn(0, Qt::AscendingOrder); m_Controls.m_PropertyTree->setSelectionBehavior(QAbstractItemView::SelectRows); m_Controls.m_PropertyTree->setSelectionMode(QAbstractItemView::SingleSelection); m_Controls.m_PropertyTree->setEditTriggers(QAbstractItemView::SelectedClicked | QAbstractItemView::DoubleClicked); connect(m_Controls.m_RendererCB, SIGNAL(currentIndexChanged(int)), this, SLOT(OnPropertyListChanged(int))); connect(m_Controls.newButton, SIGNAL(clicked()), this, SLOT(OnAddNewProperty())); connect(m_Controls.m_PropertyTree->selectionModel(), SIGNAL(currentRowChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(OnCurrentRowChanged(const QModelIndex &, const QModelIndex &))); connect(m_Controls.m_OverlayList, SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)), this, SLOT(OnOverlaySelectionChanged(QListWidgetItem *, QListWidgetItem *))); connect(m_Controls.m_DeleteOverlay, SIGNAL(clicked()), this, SLOT(OnDelete())); connect(m_Controls.m_AddOverlay, SIGNAL(clicked()), this, SLOT(OnAddOverlay())); itk::MemberCommand::Pointer command = itk::MemberCommand::New(); command->SetCallbackFunction(this, &QmitkOverlayManagerView::OnFocusChanged); m_RenderWindowFocusObserverTag = mitk::RenderingManager::GetInstance()->AddObserver(mitk::FocusChangedEvent(), command); } void QmitkOverlayManagerView::OnFocusChanged(itk::Object * /*caller*/, const itk::EventObject &event) { const mitk::FocusChangedEvent *focusEvent = dynamic_cast(&event); if (focusEvent) { QHash renderWindows = this->GetRenderWindowPart()->GetQmitkRenderWindows(); m_Controls.m_RendererCB->clear(); Q_FOREACH (QString renderWindow, renderWindows.keys()) { m_Controls.m_RendererCB->addItem(renderWindow); if (renderWindows[renderWindow]->GetVtkRenderWindow() == mitk::RenderingManager::GetInstance()->GetFocusedRenderWindow()) { m_Controls.m_RendererCB->setCurrentText(renderWindow); } } this->OnActivateOverlayList(); } } QString QmitkOverlayManagerView::GetPropertyNameOrAlias(const QModelIndex &index) { QString propertyName; if (index.isValid()) { QModelIndex current = index; while (current.isValid()) { QString name = m_ProxyModel->data(m_ProxyModel->index(current.row(), 0, current.parent())).toString(); propertyName.prepend(propertyName.isEmpty() ? name : name.append('.')); current = current.parent(); } } return propertyName; } void QmitkOverlayManagerView::OnCurrentRowChanged(const QModelIndex ¤t, const QModelIndex &) { if (m_PropertyDescriptions != nullptr && current.isValid()) { QString name = this->GetPropertyNameOrAlias(current); if (!name.isEmpty()) { QString alias; bool isTrueName = true; if (m_PropertyAliases != nullptr) { std::string trueName = m_PropertyAliases->GetPropertyName(name.toStdString()); if (trueName.empty() && !m_SelectionClassName.empty()) trueName = m_PropertyAliases->GetPropertyName(name.toStdString(), m_SelectionClassName); if (!trueName.empty()) { alias = name; name = QString::fromStdString(trueName); isTrueName = false; } } QString description = QString::fromStdString(m_PropertyDescriptions->GetDescription(name.toStdString())); std::vector aliases; if (!isTrueName && m_PropertyAliases != nullptr) { aliases = m_PropertyAliases->GetAliases(name.toStdString(), m_SelectionClassName); if (aliases.empty() && !m_SelectionClassName.empty()) aliases = m_PropertyAliases->GetAliases(name.toStdString()); } bool isPersistent = false; // QString persistenceKey; if (m_PropertyPersistence != nullptr) { isPersistent = m_PropertyPersistence->HasInfo(name.toStdString()); /*if (isPersistent) { persistenceKey = QString::fromStdString(m_PropertyPersistence->GetInfo(name.toStdString())->GetKey()); if (persistenceKey.isEmpty()) persistenceKey = name; }*/ } if (!description.isEmpty() || !aliases.empty() || isPersistent) { QString customizedDescription; if (!description.isEmpty()) customizedDescription += "

" + description + "

"; if (!aliases.empty() || isPersistent) { customizedDescription += "
"; if (!aliases.empty()) { customizedDescription += aliases.size() > 1 ? "" : ""; } if (isPersistent) customizedDescription += ""; customizedDescription += "
"; } return; } } } } void QmitkOverlayManagerView::OnPropertyNameChanged(const itk::EventObject &) { mitk::PropertyList *propertyList = m_Model->GetPropertyList(); if (propertyList != NULL) { mitk::BaseProperty *nameProperty = propertyList->GetProperty("name"); if (nameProperty != NULL) { QString partName = "Properties ("; partName.append(QString::fromStdString(nameProperty->GetValueAsString())).append(')'); this->SetPartName(partName); } } } void QmitkOverlayManagerView::OnSelectionChanged(berry::IWorkbenchPart::Pointer, const QList &nodes) { } void QmitkOverlayManagerView::InitializeAddOverlayMenu() { m_AddOverlayMenu = new QMenu(m_Controls.m_AddOverlay); m_AddOverlayMenu->addAction("TextOverlay2D"); m_AddOverlayMenu->addAction("TextOverlay3D"); m_AddOverlayMenu->addAction("LabelOverlay"); m_AddOverlayMenu->addAction("ColorBarOverlay"); m_AddOverlayMenu->addAction("ScaleLegendOverlay"); m_AddOverlayMenu->addAction("LogoOverlay"); } void QmitkOverlayManagerView::Activated() { // this->OnActivateOverlayList(); } void QmitkOverlayManagerView::Deactivated() { } void QmitkOverlayManagerView::Visible() { this->OnActivateOverlayList(); } void QmitkOverlayManagerView::Hidden() { } void QmitkOverlayManagerView::OnPropertyListChanged(int index) { if (index == -1) return; QString renderer = m_Controls.m_RendererCB->itemText(index); QmitkRenderWindow *renwin = this->GetRenderWindowPart()->GetQmitkRenderWindow(renderer); m_Renderer = renwin ? renwin->GetRenderer() : nullptr; this->OnOverlaySelectionChanged(m_Controls.m_OverlayList->currentItem(), nullptr); this->OnActivateOverlayList(); } void QmitkOverlayManagerView::OnAddNewProperty() { std::unique_ptr dialog( new QmitkAddNewPropertyDialog(m_SelectedOverlay, m_Renderer, m_Parent)); if (dialog->exec() == QDialog::Accepted) this->m_Model->Update(); } void QmitkOverlayManagerView::OnActivateOverlayList() { if (!m_Renderer) return; std::vector arList = mitk::AnnotationService::GetAnnotationRenderer(m_Renderer->GetName()); m_Controls.m_OverlayList->clear(); for (auto ar : arList) { for (auto overlay : ar->GetServices()) { QListWidgetItem *item = new QListWidgetItem(); item->setData(Qt::UserRole, QVariant(overlay->GetMicroserviceID().c_str())); QString text(overlay->GetName().c_str()); if (text.length() > 0) { text.append(" : "); } text.append(overlay->GetNameOfClass()); item->setText(text); m_Controls.m_OverlayList->addItem(item); } } } void QmitkOverlayManagerView::OnOverlaySelectionChanged(QListWidgetItem *current, QListWidgetItem *) { mitk::PropertyList *propertyList = m_Model->GetPropertyList(); if (propertyList != NULL) { mitk::BaseProperty *nameProperty = propertyList->GetProperty("name"); if (nameProperty != NULL) nameProperty->RemoveObserver(m_PropertyNameChangedTag); m_PropertyNameChangedTag = 0; } mitk::Overlay *overlay = nullptr; QString oID; if (current) { oID = current->data(Qt::UserRole).toString(); OverlayMapType::iterator it = m_OverlayMap.find(oID.toStdString()); if (it != m_OverlayMap.end()) overlay = it->second; else { overlay = mitk::AnnotationService::GetOverlay(oID.toStdString()); } } if (!overlay) { m_SelectedOverlay = NULL; this->SetPartName("Overlay Properties"); m_Model->SetPropertyList(NULL); m_Delegate->SetPropertyList(NULL); m_Controls.newButton->setEnabled(false); } else { m_SelectedOverlay = overlay; QString selectionClassName = m_SelectedOverlay->GetNameOfClass(); m_SelectionClassName = selectionClassName.toStdString(); mitk::PropertyList::Pointer propertyList = overlay->GetPropertyList(); m_Model->SetPropertyList(propertyList, selectionClassName); m_Delegate->SetPropertyList(propertyList); OnPropertyNameChanged(itk::ModifiedEvent()); mitk::BaseProperty *nameProperty = m_SelectedOverlay->GetProperty("name"); if (nameProperty != NULL) { itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction(this, &QmitkOverlayManagerView::OnPropertyNameChanged); m_PropertyNameChangedTag = nameProperty->AddObserver(itk::ModifiedEvent(), command); } m_Controls.newButton->setEnabled(true); } if (!m_ProxyModel->filterRegExp().isEmpty()) m_Controls.m_PropertyTree->expandAll(); } void QmitkOverlayManagerView::OnDelete() { auto items = m_Controls.m_OverlayList->selectedItems(); if (items.count() < 1) return; mitk::Overlay *overlay = nullptr; QListWidgetItem *item = items[0]; if (item) overlay = reinterpret_cast(item->data(Qt::UserRole).value()); mitk::OverlayManager::GetInstance()->RemoveOverlay(overlay); } void QmitkOverlayManagerView::OnAddOverlay() { QAction *action = m_AddOverlayMenu->exec(QCursor::pos()); mitk::Overlay::Pointer overlay; if (action != NULL) { const QString widgetKey = action->text(); if (widgetKey == "TextOverlay2D") overlay = CreateTextOverlay2D(); else if (widgetKey == "TextOverlay3D") overlay = CreateTextOverlay3D(); else if (widgetKey == "LabelOverlay") overlay = CreateLabelOverlay(); else if (widgetKey == "ColorBarOverlay") overlay = CreateColorBarOverlay(); else if (widgetKey == "ScaleLegendOverlay") overlay = CreateScaleLegendOverlay(); else if (widgetKey == "LogoOverlay") overlay = CreateLogoOverlay(); mitk::BaseRenderer *renderer = this->GetRenderWindowPart()->GetQmitkRenderWindow(m_Controls.m_RendererCB->currentText())->GetRenderer(); - mitk::AnnotationPlacer::AddOverlay(overlay, renderer); + mitk::OverlayLayouter2D::AddOverlay(overlay, renderer); m_OverlayMap[overlay->GetMicroserviceID()] = overlay; } OnActivateOverlayList(); } mitk::Overlay::Pointer QmitkOverlayManagerView::CreateTextOverlay2D() { mitk::TextOverlay2D::Pointer to = mitk::TextOverlay2D::New(); + to->SetText("Test"); return to.GetPointer(); } mitk::Overlay::Pointer QmitkOverlayManagerView::CreateTextOverlay3D() { mitk::TextOverlay3D::Pointer to = mitk::TextOverlay3D::New(); return to.GetPointer(); } mitk::Overlay::Pointer QmitkOverlayManagerView::CreateLabelOverlay() { mitk::LabelOverlay3D::Pointer to = mitk::LabelOverlay3D::New(); return to.GetPointer(); } mitk::Overlay::Pointer QmitkOverlayManagerView::CreateColorBarOverlay() { mitk::ColorBarOverlay::Pointer to = mitk::ColorBarOverlay::New(); return to.GetPointer(); } mitk::Overlay::Pointer QmitkOverlayManagerView::CreateScaleLegendOverlay() { mitk::ScaleLegendOverlay::Pointer to = mitk::ScaleLegendOverlay::New(); return to.GetPointer(); } mitk::Overlay::Pointer QmitkOverlayManagerView::CreateLogoOverlay() { mitk::LogoOverlay::Pointer to = mitk::LogoOverlay::New(); return to.GetPointer(); } void QmitkOverlayManagerView::RenderWindowPartActivated(mitk::IRenderWindowPart * /*renderWindowPart*/) { if (m_Controls.m_RendererCB->count() == 0) { QHash renderWindows = this->GetRenderWindowPart()->GetQmitkRenderWindows(); Q_FOREACH (QString renderWindow, renderWindows.keys()) { m_Controls.m_RendererCB->addItem(renderWindow); } } OnActivateOverlayList(); } void QmitkOverlayManagerView::RenderWindowPartDeactivated(mitk::IRenderWindowPart *) { if (m_Controls.m_RendererCB->count() > 0) { m_Controls.m_RendererCB->clear(); } m_Controls.m_OverlayList->clear(); }