MultiWidget Abstraction

From mitk.org
Jump to navigation Jump to search

This is a design document draft for Bug #10963


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.

<syntaxhighlight lang="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;

}; </syntaxhighlight >


Interface ILinkedRenderWindowPart

The second interface extends IRenderWindowPart by adding API for controlling linked render windows (synchronized by slicing planes)

<syntaxhighlight lang="cpp"> struct ILinkedRenderWindowPart : public virtual IRenderWindowPart {

 mitk::SlicesRotator* GetSlicesRotator() const;
 mitk::SlicesSwiveller* GetSlicesSwiveller() const;
 void EnableSlicingPlanes(bool enable);
 bool IsSlicingPlanesEnabled() const;

}; </syntaxhighlight>


Handling multiple rendering editors

One of the mentioned goals is the correct handling of zero, one, ore more registered "rendering editors". First, we will outline how to register such an editor.

Registering a rendering editor

  1. As usual, the editor implementation must be contributed by providing an extension to the extension-point org.blueberry.ui.editors. The extensions XML attribute should contain a *.mitk entry. The default attribute can be set to true.
  2. The editor implementation must implement IRenderWindowPart or ILinkedRenderWindowPart and the editor input type must be IDataStorageEditorInput.

The default editor can be set at runtime by using berry::IEditorRegistry::SetDefaultEditor(...).

The new QmitkView class (super class of MITK Views, replacing QmitkFunctionality) will provide convenience methods to retrieve the current rendering editor or to open the default editor for *.mitk inputs.


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

  1. Create the interfaces inside the org.mitk.gui.qt.common plug-in
  2. Move the QmitkStdMultiWidgetEditor into a new plug-in (org.mitk.gui.qt.stdmultiwidgeteditor) and implement the interfaces
  3. Create a new org.mitk.gui.qt.common.legacy plug-in and copy QmitkFunctionality and related classes to it. This plug-in will have a direct dependency on org.mitk.gui.qt.stdmultiwidgeteditor
  4. Rename QmitkFunctionality to QmitkView and remove the QmitkStdMultiWidget dependencies in org.mitk.gui.qt.common
  5. Adapt the MITK-ProjectTemplate and Plugin Generator
  6. Gradually modify MITK Views to use QmitkView as the base class, instead of QmitkFunctionality. See the ViewsWithoutMultiWidget document.

Remarks:

  • The QmitkStdMultiWidget class will not be modified
  • All current MITK views will be functional at all time