Introduction

BakeryExtras extends the basic features provided by the Bakery library.

Purpose

Navigator / Target views

You may use the Navigator extension when the document is a set of records, and you need a view to display one record (the Target view) and a view displaying many records (the Navigator view) ; the Navigator view should give end-users the capability to select a particular record to display in the Target view.

For instance, in the GEDCOM Viewer application, the main screen and the list browser plays respectively the role of Target and Navigator views.

Navigator view
Navigator view : List browser

Target view
Target view : Individual record

Subscriber / Linked views

You may use the Linked view extension when the document is a set of records and you need a view to display one record (the Subscriber view) and a view displaying information concerning the subscriber record (the Linked view). When the record displayed in the Subscriber view changes, the Linked view is reloaded.

For instance, in the GEDCOM Viewer main screen, the Individual Record view is a subscriber view for the ChildToFamilyLinks, SpouseToFamilyLinks (and others) views.

Subscriber view
Subscriber view : Individual Record

Linked view
Linked view : ChildToFamilyLinks

Linked view
Linked view : SpouseToFamilyLinks

Linked view
Linked view : IndividualEvents

And more...

Often Navigator / Target and Subscriber / Linked extensions are both used. For instance in the GEDCOM Viewer application the List Browser reflects the current displayed record in the main view : the List Browser is a Navigator and a Linked view for the IndividualRecord view, and reciprocally the IndividualRecord view is a Target and Subscriber view for the List Browser.

Design

Navigator / Target class diagram
Navigator / Target class diagram

View_Navigator and View_Target are two class templates derived from the Bakery::View template.
A Navigator may have only one Target.

The View_Navigator provides two publics methods :
- setTarget is used to associate a View_Navigator object with a View_Target object.
- Navigate is used to execute the effective navigation (i.e. display the wanted record in the View_Target object). It calls the Goto () method on the target of the Navigator.

The View_Target provides one public method :
- Goto is used to load the wanted record in the view

The Navigation / Target templates relies on the existence of a key in the record set which identify each record. The class of the key may be defined on the instanciation of the class templates : it is the KeyType template parameter.



Subscriber / Linked class diagram
Subscriber / Linked class diagram
View_Subscriber and View_Linked are two class templates derived from the Bakery::View template.
A View_Subscriber is linked with one or more View_Linked. (The implementation of the association is View_Subscriber <-> Bakery::View to reduce dependencies, but subscribees MUST be View_Linked based objects).

The View_Subscriber provides the following public methods :
- subscribe_view, unsubscribe_view, delete_subscribed_views are used to add / remove (one or all) subscribees
- notify_subscribees() notifies the subscribees about a change in the Subscriber view
- set_entity() sets the subscriber record

The View_Linked provides the following public methods :
- set_parent_entity() sets the subscriber entity. This method calls the load_from_document() method which should rely on the subscriber entity.
- parent_change_before_callback and parent_change_after_callback are two virtual method which are called respectively before and after the load_from_document() methods. You may overload them to extend the default behaviour without overload the set_parent_entity method.

Make your App use those templates

First of all, your app should use the Bakery framework ! You should read explanations here.

Navigator / Target

Create the Navigator view

    class ViewExampleNavigator :
      public BakeryExtras::View_Navigator < DocumentExample, KeyTypeExample >         
      {
        public:
        // standard overrides (Bakery::View)
       
virtual void load_from_document();
        // declare and implement a method which
        // call Navigate() on response of a user event
      };
 

Create the Target view

    class ViewExampleTarget :
        public BakeryExtras::View_Target< DocumentExample, KeyTypeExample >
        {
        public:
            ViewExampleTarget(void);
            ~ViewExampleTarget(void);
            // overrides
            virtual void load_from_document();
            virtual void Goto(KeyTypeExample const &key);
        };

Make your app use the Navigator / Target views

The main view connected to your app should link together Navigator and Target views (for instance in the constructor) :
    class View : public MMI,
        public Bakery::View<DocumentExample>
       {
       public:
         View() :
        _view_target_example(0),
        _view_navigator_example(0)
        {
            _view_target_example = new ViewExampleTarget();
            _view_navigator_example = new ViewExampleNavigator();
            _view_navigator_example->setTarget(_view_target_example);
        };
         virtual ~View();
       private:
           ViewExampleTarget * _view_target_example;       
           ViewExampleNavigator * _view_navigator_example;
        };

Subscriber / Linked

Create the Subscriber view

    class ViewExampleSubscriber :
      public BakeryExtras::View_Subscriber < DocumentExample, EntityExample >         
      {
        public:
        // standard overrides (Bakery::View)
       
virtual void load_from_document(); // the load_from_document must call the notify_subscribees() method
      };

Create the Linked view

    class ViewExampleLinked :
      public BakeryExtras::View_Linked < DocumentExample, EntityExample >         
      {
        public:
        // standard overrides (Bakery::View)
       
virtual void load_from_document(); // the load_from_document must relies on the _parent_entity attribute to display its data
      };

Make your app use the Subscriber / Linked views

The main view connected to your app should link together Navigator and Target views (for instance in the constructor) :
    class View : public MMI,
        public Bakery::View<DocumentExample>
       {
       public:
         View() :
        _view_subscriber_example(0),
        _view_linked_example(0)
        {
            _view_subscriber_example = new ViewExampleSubscriber();
            _view_linked_example = new ViewExampleLinked();
            _view_subscriber_example->subscribe_view(_view_linked_example);
        };
         virtual ~View();
       private:
           ViewExampleSubscriber * _view_subscriber_example;       
           ViewExampleLinked * _view_linked_example;
        };