Developer Guide

Table of Contents 

  1. Overview
  2. Reference
  3. Samples
  4. Customizing Platform

* ... work in progress


Overview 

This section gives an overview of the library concepts.

Display/Strategy/Model (DSM)

The core concept of the library is Display/Strategy/Model (DSM). 

The DSM components are template parameters combined into a single entity by notus::view.

template<
      typename Display
    , typename Strategy
    , typename Model
> struct view;

view makes sure that the Display and Model events get sent to appropriate strategies. Strategies is in fact a tuple, so many strategies can be specified in one view as tuple members (for more information about tuples, see Boost). For example.

typedef TUP::tuple< mouse_event_strategy, paint_strategy > my_strategy;
typedef view< window, my_strategy, some_data > my_dsm_view;

The strategies can be nested.

typedef TUP::tuple< keyboard_event_strategy, my_strategy > my_extended_strategy;

For the list of available displays, see notus::displays. You can always implement your own display or derive it from an existing one.

All application intelligence resides in strategies. Strategies define event handlers. The view sends events to these handlers. The view also sends a reference to itself. Using this reference, the strategies can access the view model and display objects.

Model is an active object in notus. If the application updates the model data, a data update event is generated. If the user defines a strategy for this event type, the view calls this strategy. A typical scenario may look like this.

Managers

The managers namespace is intended for building high-level GUI constructs that represent typical usage cases. The main building blocks are notus::view's and other managers. A manager is a concrete design for a particular usage case or family of cases.

Event Handling

The traditional GUI applications are typically event driven. The events are generated by the GUI widgets and the developer implements appropriate event handlers. The same is basically true in Notus. The Displays can be considered as widgets that generate events. The developer implements Strategies to process these events. The view class template is responsible for dispatching the display events to the appropriate strategies. For more details about Notus events, see the Events section in Reference.

Displays are not the only entities that can generate events in Notus. Models generate the notus::events::model_update events whenever the model data is modified.

Strategies

An application can define different strategies for different event types. One strategy can handle multiple event types. Here is how to define a strategy that will be called for mouse events.

struct my_strategy : handle_event< events::mouse >
{
    template< typename View >
    bool on_event( View& v, events::mouse& event );
};

The handle_event<...> type indicates what events are handled by this strategy. One strategy type can process multiple event types. The View parameter is view that generated this event.

struct my_strategy :
       handle_event< events::mouse >
     , handle_event< events::model_update >
{
    template< typename View >
    bool on_event( View& v, events::mouse& event );


    template< typename View >
    bool on_event( View& v, events::model_update& event );
};

As described in Display/Strategy/Model (DSM) , strategies must be supplied to view's as tuple members. The strategy tuples can be nested.

Object Lifetime

What about object life-times? The issue at stake is how the life-time of the physical GUI objects such as HWND in Win32 or wxWindow in wxWindows is related to the life-time of notus class instances.

Notus uses the following set of rules:

Platform

Notus defines an abstraction layer for the physical platform. The abstraction is declared in the notus::impl namespace. Everything above the notus::impl namespace in Notus is in header files. No libraries is required. The impl namespace interfaces are mostly static methods. These methods use the Traits template parameter to access constants and other specific information about the platform. Below is an example of the abstraction interfaces for a window.

namespace notus
{
namespace impl
{
template< typename Traits >
struct window
{
    typedef Traits traits;
    typedef typename traits::point point;
    typedef typename traits::rect rect;
    typedef typename traits::size size;
    typedef typename traits::window::hnd hnd;
    typedef typename traits::string string;

    static void destroy( hnd h );

    static void set_title( hnd h, const string& txt );

    static size get_clientsize( hnd h );
    static void set_position( hnd h, const point& p );

    static void repaint( hnd h, bool erase ); //clear window
    static void repaint( hnd h, const rect&r, bool erase ); //clear rectangle

    static void show( hnd h );
    static void hide( hnd h );
};
};
};

to access some fundamental types such as point, the window methods use Tratis. This technique allows a direct use of the native platform types. For example the traits for Win32 can define point as the native Win32 POINT while the traits for wxWindow, as wxPoint. The notus::impl interfaces are instantiated in libs\src\platform\win32\notus_traits\generator.cpp.

In general, to port Notus to another platform, all that is needed is to implement the notus::impl namespace.

It is a very flexible approach that supports easy porting or customization of an existing platform.

You can customize the standard Win32 platform by deriving your own traits from the standard ones and instantiating the notus::impl methods for you custom traits. For instance you can customize it so that all windows will have an elliptical shape an the rest of the library won't know about the change.

Reference

Notus Namespaces

* ... work in progress

Events

* ... work in progress


Copyright Eugene Gladyshev, 2004

SourceForge.net Logo