MultiWidget Abstraction
Goals
- MITK Views should be as independent of a specific "Rendering Editor" (e.g. QmitkStdMultiWidgetEditor) as possible.
- Define a useful common API for rendering editors
- Make it possible to call the rendering editor API without a direct coupling from the caller to the specific editor implementation.
- Correctly handle the presence or zero, one or more rendering editors.
Two main problems can be identified, which are related to the possibility of having multiple registered rendering editors:
- If the user starts the application and loads the first file, the data storage contents should be rendered in a (newly opened) rendering editor automatically. The decision which editor to open should be made by means of the BlueBerry Workbench support for handling different editors. The application designer will be responsible for eventually providing a mechanism to end-users to choose a specific rendering editor (this will probably be a rare requirement).
- If multiple renedering editors are open, actions triggered by MITK Views should affect only the currently active editor. MITK Views should not keep any state information about active editors.
Current QmitkStdMultiWidget dependencies
MITK Views frequently call one of the following methods on a QmitkStdMultiWidget instances (provided by the QmitkFunctionality super class):
- GetTimeNavigationController()
- GetRenderWindow[X]()
- GetCrossPosition()
- MoveCrossToPosition()
- GetSlicesRotator()
- GetSlicesSwiveller()
- SetWidgetPlanesVisibility(bool)
- SetWidgetPlaneModeToSlicing()
- SetWidgetPlaneModeToRotation()
- RequestUpdate()
- ForceImmediateUpdate()
- DisableColoredRectangles()
- DisableDepartmentLogo()
- DisableGradientBackground()
Rendering editor interfaces
Based on the current API usage in MITK Views, it looks like two interfaces can be extracted. The proposed interfaces should be implemented by the editor directly.
Interface IRenderWindowPart
This interface represents a Workbench part (editor or view) which provides one or more QmitkRenderWindow instances.
#!highlight cpp struct IRenderWindowPart { /** Get the currently active (focused) render window. * Focus handling is implementation specific. */ QmitkRenderWindow* GetActiveRenderWindow() const; /** Get all render windows with their ids. */ QHash<QString,QmitkRenderWindow*> GetRenderWindows() const; /** Get a render window with a specific id. */ QmitkRenderWindow* GetRenderWindow(const QString& id) const; /** Request an update of all render windows */ void RequestUpdate(); /** Force an immediate update of all render windows */ void ForceImmediateUpdate(); /** Get the selected position in the render window with ''id'' * or in the active render window if ''id'' is NULL. */ mitk::Point3D GetSelectedPosition(const QString& id = QString()) const; /** Set the selected position in the render window with 'id' * or in the active render window if 'id' is NULL. */ void SetSelectedPosition(const mitk::Point3D& pos, const QString& id = QString()); /** Enable ''decorations'' like colored borders, menu widgets, * logos, text annotations, etc. */ void EnableDecorations(bool enable, const QStringList& decorations = QStringList()); /** Return if a specific decoration is enabled */ bool IsDecorationEnabled(const QString& decoration) const; /** Get a list of supported decorations. Standardized decoration * ids are ''border'', ''menu'', ''background'', and ''logo''. */ QStringList GetDecorations() const; };
Interface ILinkedRenderWindowPart
The second interface extends IRenderWindowPart by adding API for controlling linked render windows (synchronized by slicing planes)
#!highlight cpp struct ILinkedRenderWindowPart : public virtual IRenderWindowPart { mitk::SlicesRotator* GetSlicesRotator() const; mitk::SlicesSwiveller* GetSlicesSwiveller() const; void EnableSlicingPlanes(bool enable); bool IsSlicingPlanesEnabled() const; };
API Mapping
The following table maps the QmitkStdMultiWidget API usage to the new interfaces.
QmitkStdMultiWidget | IRenderWindowPart | ILinkedRenderWindowPart |
GetTimeNavigationController() | x | x |
GetRenderWindow[X]() | GetRenderWindow(id) | |
GetCrossPosition() | GetSelectedPosition() | |
MoveCrossToPosition() | SetSelectedPosition() | |
GetSlicesRotator() | GetSlicesRotator() | |
GetSlicesSwiveller() | GetSlicesSwiveller() | |
SetWidgetPlanesVisibility(bool) | EnableSlicingPlanes(bool) | |
SetWidgetPlaneModeToSlicing() | x | x |
SetWidgetPlaneModeToRotation() | x | x |
RequestUpdate() | RequestUpdate() | |
ForceImmediateUpdate() | ForceImmediateUpdate() | |
DisableColoredRectangles() | EnableDecorations(false,"border") | |
DisableDepartmentLogo() | EnableDecorations(false,"logo") | |
DisableGradientBackground() | EnableDecorations(false,"background") |
Remarks:
- Calls to the method GetTimeNavigationController() should be replaced by calling IRenderWindowPart::GetActiveRenderWindow()::GetSliceNavigationController().
- SetWidgetPlaneModeToSlicing() and SetWidgetPlaneModeToRotation() will not be available through the interfaces.
Migration Plan
- Create the interfaces inside the org.mitk.gui.qt.common plug-in
- Move the QmitkStdMultiWidgetEditor into a new plug-in (org.mitk.gui.qt.stdmultiwidgeteditor) and implement the interfaces
- Copy QmitkFunctionality to QmitkView and remove the QmitkStdMultiWidget dependencies.
- Gradually modify MITK Views to use QmitkView as the base class, instead of QmitkFunctionality.
Remarks:
- The QmitkStdMultiWidget class will not be modified
- All current MITK views will be functional at all time