Using HIViews

HIView is Carbon's object-orientated view system, which allows developers to organize and manipulate the contents of a window.

HIViews can be nested, scrolled, and can automatically adjust their layout based on changes in the size or location of other views. Unlike Cocoa's NSView class, sibling HIViews can also be overlapped to support efficient compositing.

For more information on HIViews, see Apple's HIView Programming Guide.

NHIView

In Nano, an HIViewRef object is represented by the NHIView class. This class exposes basic functionality common to all views, such as manipulating the size or location of the view.

An NHIView sub-class has been provided for every standard system view, to allows those views to be manipulated using the NHIView interface.

View Properties

Interface Builder can attach a tagged list of properties to views, which can be manipulated through NHIView.

Many of Nano's view classes support properties that can be used to customize their behaviour, or to expose functionality not supported by Interface Builder.

For example, NDataBrowser supports a kTagDrawRowStripes property that can be used to adjust the kDataBrowserAttributeListViewAlternatingRowColors attribute of the view.

Even though Interface Builder does not expose this attribute, by assigning a property within the nib the attribute can be applied at run-time without any additional code.

Supported properties can be identified by searching for kPropertyNano.

System Views

System views are typically placed in a .nib using Interface Builder, and communicated with through one of Nano's view classes.

This is achieved with the NIB_VIEW macro, which allows you to connect a member variable to a view with one line of code:

    MyDocument.h
    class MyDocument : public NDocument {
    ...
    protected:
        OSStatus InitializeSelf(void);

    private:
        NIB_VIEW('wavh', NSlider, WaveHeight);
    };


    MyDocument.cpp
    OSStatus MyDocument::InitializeSelf(void)
    {
        // Configure the view
        mWaveHeight->SetCurrentValue(23);
        mWaveHeight->SetMaximumValue(42);

        return(noErr);
    }

The NIB_VIEW macro will define a private constant named kViewWaveHeight (whose value is 'wavh'), instantiate an NSlider view named mWaveHeight, and connect mWaveHeight to the kViewWaveHeight view in the window.

NIB_VIEW declarations are executed prior to InitializeSelf being called, ensuring that an object's member variables are automatically created and connected to the corresponding view as part of window initialisation.

Custom Views

To create a custom view with Nano, sub-class NHIView and declare the view as a sub-class of the appropriate HIView class.

For example:

    MyView.h
    class MyView : public NHIView {
                 DECLARE_HIVIEW_SUBCLASS(MyView);

    protected:
        void     InitializeView(void);
    };


    MyView.cpp
    DEFINE_HIVIEW_SUBCLASS(MyView, "com.mysoftware.myview", kHIViewClassID);
    
    void MyView::InitializeView(void)
    {
        // Initialize the view
    }

The DECLARE_ and DEFINE_ macros declare the MyView class as a sub-class of the root HIView class. This allows this view to be instantiated within Interface Builder, simply by creating a view with a class ID of "com.mysoftware.myview".

When this view is instantiated, the InitializeView method will be called to initialize the view. Typically a view would initialize itself by assigning its default state, registering for events, and then implementing handlers for those events.

If the view also supports properties, it could then override its default state with any additional values assigned in the .nib file.

Several custom views can be found in Library/Source/HIToolbox/Custom, and can be seen in the NanoDemo example.

Scrollable Views

NScrollableView is an a NHIView sub-class that can itself be sub-classed to implement a custom view that displays scrollable content.

This view also supports zooming, and will automatically adjust the scrollable area in order to reflect the current zoom level.

Views with scrollable content can simply sub-class this view, assign their content size to the view, and then draw their content when required.