Develop a Presenter Extension

Developing a Presenter extension certainly is a more advanced task than developing a Type extensions as a more detailed understanding of the system is required as for example navigations have to be handled.

As a basis for this walk-through on how to develop a Presenter extension we will take the default Presenter of Black Fennec called the column-based-presenter. To read this section it might make sense to open the projects repository located at here. This allows you to individually explore the code lying behind the column-based-presenter while reading through the following explanations.

../../_images/0d8bf952105c7bd79d2e2f91d40bf7f75bd7bd181e6417dd35eb9ae364711e87.svg

Hint

The structure that is present in this presenter is how Black Fennec recommends an extension should be structured. But as previously mentioned this is up to the developer of the extension.

We will now step by step explain the individual Class required to create a Presenter Extension.

Defining the Extension Entrypoint

A valid extension is required to provide an entrypoint. Currently this means that the extension must provide a special functions called create which takes a single parameter of type Extension Api. This function is called when the extension is loaded.

Based on the entrypoint described as in Extension Development we can now implement the register_presenters function. This function is called when the extension is loaded and is responsible for registering the presenters that are provided by this extension.

 1def register_presenters(self):
 2    column_based_presenter = ColumnBasedPresenterViewFactory(
 3        self._api.interpretation_service,
 4        self._api.view_factory,
 5    )
 6    self._api.presenter_registry.register_presenter(
 7        column_based_presenter,
 8    )
 9    self.presenters.append(column_based_presenter)
10
11def deregister_presenters(self):
12    for presenter in self.presenters:
13        self._api.presenter_registry.deregister_presenter(type(presenter))

As you can see the extension_api that is received upon initialization of the extension, can be used to register the presenter and instantiate our presenter factory that we will implement in the next step.

Hint

The Extension API is a special object that is provided to the extension upon initialization. It provides access to the services that are provided by the core of Black Fennec.

The Interpretation Service is a service that is also provided by the core of Black Fennec and is responsible for interpreting the data that is provided by a document.

Writing a Presenter Factory

The Presenter Factory is a simple factory used to create the presenter view model and inject it into the view. The simple factory is instantiated with all arguments that are later on required by the view model to be able to navigate and interpret information. It is a must that the class, in our case the view factory, that is registered in the presenter registry contains a ‘create’ function that receives a instance of the navigation_service and a history service.

Hint

The Navigation Service. is a service that is provided by the core of Black Fennec and is responsible for navigating between different views.

The History Service is a service that is provided by the core of Black Fennec and is responsible for keeping track of the change history of a document.

 1class ColumnBasedPresenterViewFactory:
 2    """Creator or the ColumnBasedPresenterView"""
 3
 4    def __init__(self, interpretation_service, view_factory):
 5        self._interpretation_service = interpretation_service
 6        self._view_factory = view_factory
 7
 8    def create(self, navigation_service, history) -> ColumnBasedPresenterView:
 9        """Create column based presenter view
10
11        Returns:
12            ColumnBasedPresenterView: The column based presenter view.
13                Can be used as presenter in the main UI.
14        """
15        view_model = ColumnBasedPresenterViewModel(
16            self._interpretation_service,
17            navigation_service,
18            history
19        )
20        return ColumnBasedPresenterView(view_model, self._view_factory)

As visible in the code example above, the expected return of the create function is the view of our presenter.

Creating a Presenter View

The Presenter View is something, that is in the responsibility of the extension developer. He may inspire himself by looking at the code of the column-based-presenter - implementation-detail - which thus not relevant for this walk-through.

Hint

One speciality of black-fennecs implementation of MVVM is the utility class Observable, which is a helper class to implement the Observer pattern. With the method call ‘bind’, which is bound via a named-parameter, that is passed a function and will respond to notify events with the event-name that corresponds to the named-parameter, to the view model which inherits of Observable.

The Presenter View Model

The presenter that is currently active in Black Fennec gets notified by a Black Fennec component via the ‘show’ function. This function gets passed which interpretation has triggered the show event, and which part of the structure should now be displayed. This structure can be interpreted with the interpretation_service in order for types beyond the core_types to be shown.

Hint

It is the responsibility of the presenter of setting the navigation service on the interpretation he created. Otherwise, navigational requests that happen in the interpretation would not reach the presenter.

Presenter Extension

The presenter extension (a.k.a Structure Presenter Extension) is responsible for displaying and positioning all Structure Views as described in Develop a Type Extension as well as making Actions <definition_action> available to the user. Presenters have few restrictions and will be given a rectangular area for rendering.

../../_images/0f0b2c540160d7bafbe395aa2f3ad0780d5e1e62b7f594ea70c71b31d1dfa488.svg../../_images/9175cf319ced0671703db034b6867d2ad754f83e99c6c2cf9355173ead9be2be.svg

Displaying Structure Views

Structure Views are placed and positioned by the presenter. They ought to expect a rectangular region in which they are allowed to render information. The presenter has full control over size and position of these regions and is free to arrange and decorate them. It is not the responsibility of the presenter to ensure the usability of the Structure View. However, we might define a soft limit to the minimum width or height that a Structure View ought to get.

Disclaimer

At this point we do NOT plan on implementing more than one presenter. This means that there exists no selection possibility for the user. The presenter that is used is the one that is registered in the presenter registry first.