Tutorial 5 - Scrolling

This tutorial introduces custom scrolling widgets with the "Scrolling" program. The program consists of a window containing a custom scrolling widget that is made up of two rectangles. It is made up of five files - the source and header for the object that contains the window, the source and header for the custom widget and the source that contains the function main.

The ScrollingWidget object - ScrollingWidget.cc and ScrollingWidget.h

The custom scrolling widget object is called ScrollingWidget and is derived from JXScrollableWidget

ScrollingWidget source file:

/******************************************************************************
 ScrollingWidget.cc

    Wdigets often need a larger drawing area than what is available
    in the window.  In order to do this, the widget must be able to
    scroll.  Such widgets must be derived from JXScrollableWidget
    and must be placed inside a JXScrollbarSet, as shown in
    ScrollingWidgetDir.

    We didn't need to mention it in the Widget example, but drawing
    is always done in the Bounds coordinate frame.  These coordinates
    are independent of scrolling, so Draw() can always do the same
    thing, no matter where the scrollbars are.

    JXScrollableWidget automatically provides a border, so we do
    not need to implement DrawBorder().

    BASE CLASS = JXWindowDirector

    Written by Glenn Bach - 1997.

 ******************************************************************************/

#include "ScrollingWidget.h"
#include <JXWidget.h>
#include <JXWindowPainter.h>
#include <JXColormap.h>
#include <jAssert.h>

/******************************************************************************
 Constructor

 ******************************************************************************/

ScrollingWidget::ScrollingWidget
    (
    JXScrollbarSet* scrollbarSet,
    JXContainer* enclosure,
    const HSizingOption hSizing,
    const VSizingOption vSizing,
    const JCoordinate x,
    const JCoordinate y,
    const JCoordinate w,
    const JCoordinate h
    )
    :
    JXScrollableWidget(scrollbarSet, enclosure, hSizing, vSizing, x, y, w, h)
{
    // This changes our Bounds, independent of what part of us
    // is visible (our Frame).
    SetBounds(500, 400);
}

/******************************************************************************
 Destructor

 ******************************************************************************/

ScrollingWidget::~ScrollingWidget()
{
}

/******************************************************************************
 Draw

    This gets called by the event loop every time the Widget needs to
    be redrawn.

 ******************************************************************************/

void
ScrollingWidget::Draw
    (
    JXWindowPainter& p,
    const JRect& rect
    )
{
    JXColormap* cmap = GetColormap();

    // Drawing goes here
    // See JPainter.h for available functions

    p.SetPenColor(cmap->GetGreenColor());
    p.Rect(10, 10, 50, 50);

    p.SetFilling(kTrue);
    p.SetPenColor(cmap->GetBlueColor());
    p.Rect(10, 70, 50, 50);
}

ScrollingWidget header file:

/******************************************************************************
 ScrollingWidget.h

    Interface for the ScrollingWidget class

    Written by Glenn Bach - 1997.

 ******************************************************************************/

#ifndef _H_ScrollingWidget
#define _H_ScrollingWidget

#include <JXScrollableWidget.h>

class ScrollingWidget : public JXScrollableWidget
{
public:

    ScrollingWidget(JXScrollbarSet* scrollbarSet, JXContainer* enclosure,
                    const HSizingOption hSizing, const VSizingOption vSizing,
                    const JCoordinate x, const JCoordinate y,
                    const JCoordinate w, const JCoordinate h);

    virtual ~ScrollingWidget();

protected:

    virtual void    Draw(JXWindowPainter& p, const JRect& rect);

private:

    // not allowed

    ScrollingWidget(const ScrollingWidget& source);
    const ScrollingWidget& operator=(const ScrollingWidget& source);
};
 

#endif

The ScrollingWidgetDir object - ScrollingWidgetDir .cc and

ScrollingWidgetDir .h

The object that holds the window is a ScrollingWidgetDir object which is derived from JXWindowDirector.

ScrollingWidgetDir source file:

/******************************************************************************
 ScrollingWidgetDir.cc

    BASE CLASS = JXWindowDirector

    Written by Glenn Bach - 1997.

 ******************************************************************************/

#include "ScrollingWidgetDir.h"
#include "ScrollingWidget.h"
#include <JXWindow.h>
#include <JXScrollbarSet.h>
#include <jAssert.h>

/******************************************************************************
 Constructor

 ******************************************************************************/

ScrollingWidgetDir::ScrollingWidgetDir
    (
    JXDirector* supervisor
    )
    :
    JXWindowDirector(supervisor)
{
    BuildWindow();
}

/******************************************************************************
 Destructor

 ******************************************************************************/

ScrollingWidgetDir::~ScrollingWidgetDir()
{
}

/******************************************************************************
 BuildWindow

    This is a convenient and organized way of putting all of the initial
    elements into a window. This will keep the constructor less cluttered.

 ******************************************************************************/

void
ScrollingWidgetDir::BuildWindow()
{
    // Create the window
    JXWindow* window = new JXWindow(this, 300,200, "Scrolling Program");
    assert( window != NULL );

    // Give the window to the director
    SetWindow(window);

    // Set window sizing
    window->SetMinSize(300,200);
    window->SetMaxSize(800,600);

    // Create the scrollbar set to hold the custom widget
    JXScrollbarSet* scrollbarSet =
        new JXScrollbarSet(window,
            JXWidget::kHElastic, JXWidget::kVElastic, 0,0, 300,200);
    assert( scrollbarSet != NULL );

    // Create our custom widget.  It must be placed inside the
    // special widget that JXScrollbarSet creates.  We get a
    // pointer to this special widget by calling GetScrollEnclosure().
    ScrollingWidget* widget =
        new ScrollingWidget(scrollbarSet, scrollbarSet->GetScrollEnclosure(),
            JXWidget::kHElastic, JXWidget::kVElastic,
            0, 0, 10, 10);
    assert( widget != NULL );

    // Adjust the widget to fit into the scrollbarset
    widget->FitToEnclosure(kTrue, kTrue);
}

ScrollingWidget header file:

/******************************************************************************
 ScrollingWidgetDir.h

    Interface for the ScrollingWidgetDir class

    Written by Glenn Bach - 1997.

 ******************************************************************************/

#ifndef _H_ScrollingWidgetDir
#define _H_ScrollingWidgetDir

#include <JXWindowDirector.h>

class ScrollingWidgetDir : public JXWindowDirector
{
public:

    ScrollingWidgetDir(JXDirector* supervisor);

    virtual ~ScrollingWidgetDir();

private:

    void BuildWindow();

    // not allowed

    ScrollingWidgetDir(const ScrollingWidgetDir& source);
    const ScrollingWidgetDir& operator=(const ScrollingWidgetDir& source);
};
 

#endif

The function main - scrolling.cc

/******************************************************************************
 scrolling.cc
 
 Written by Glenn Bach - 1997.

 ******************************************************************************/

#include "ScrollingWidgetDir.h"
#include <JXApplication.h>
#include <jAssert.h>

/******************************************************************************
 main

 ******************************************************************************/

int
main
    (
    int        argc,
    char*    argv[]
    )
{
    // Create the application
    JXApplication* app = new JXApplication(&argc, argv);
    assert( app != NULL );

    // Create the window director
    ScrollingWidgetDir* mainDir = new ScrollingWidgetDir(app);
    assert( mainDir != NULL );

    // Activate the director
    mainDir->Activate();
 
    // Start the event loop
    app->Run();
    return 0;
}