Tutorial 3 - Dialog Hello

This tutorial introduces dialog boxes with the "Dialog hello" program. The program consists of a window with the words "Hello world" displayed. A dialog box is added to allow the user to change the text of the main window to any arbitrary string. It is made up of five files - the source and header for the object that contains the window, the source and header for the dialog box, and the source that contains the function main.

The DialogHelloDir object - DialogHelloDir.cc and DialogHelloDir.h

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

DialogHelloDir source file:

/******************************************************************************
 DialogHelloDir.cc

 BASE CLASS = JXWindowDirector

 Written by Glenn Bach - 1997.

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

#include "DialogHelloDir.h"
#include "DHStringInputDialog.h"
#include <JXWindow.h>
#include <JXStaticText.h>
#include <JXTextMenu.h>
#include <JXMenuBar.h>
#include <JString.h>
#include <JXApplication.h>
#include <jXGlobals.h>
#include <jAssert.h>

extern JXApplication* gApplication;

// This defines the menu title and menu items
static const JCharacter* kTextMenuTitleStr = "Text";
static const JCharacter* kTextMenuStr =
 "Change Text %k Meta-C %l|Quit %k Meta-Q";

enum
{
    kChangeText = 1,
    kQuit
};

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

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

DialogHelloDir::DialogHelloDir
    (
     JXDirector* supervisor
     )
     :
     JXWindowDirector(supervisor)
{
    BuildWindow();

    // We create the dialog when we need it.
    itsDialog = NULL;
}

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

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

DialogHelloDir::~DialogHelloDir()
{
    // We don't need to delete anything here, since the director deletes the
    // window automatically, and the window will delete anything within it.
}

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

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

void
DialogHelloDir::BuildWindow()
{
    // Create the window and give it to the director.
    JXWindow* window = new JXWindow(this, 200,100, "Hello World Program");
    assert( window != NULL );
    SetWindow(window);

    // This sets the minimum and maximum size to be the
    // current size.
    window->LockCurrentSize();

    // Create the menu bar and make it expand horizontally as the window expands.
    JXMenuBar* menuBar =
     new JXMenuBar(window, JXWidget::kHElastic, JXWidget::kFixedTop,
         0,0, 200,kJXStdMenuBarHeight);
    assert( menuBar != NULL );

    // Create the menu and attach it to the menu bar.
    itsTextMenu = menuBar->AppendTextMenu(kTextMenuTitleStr);

    // Set the menu items.
    itsTextMenu->SetMenuItems(kTextMenuStr);

    // The menu items don't need to be disabled
    itsTextMenu->SetUpdateAction(JXMenu::kDisableNone);

    // Listen for messages from the menu.
    ListenTo(itsTextMenu);

    // Create the object to hold the text.
    itsText =
    new JXStaticText("Hello world!", window,
        JXWidget::kFixedLeft, JXWidget::kFixedTop,
        20, 40, 160, 20);
    assert ( itsText != NULL );
}

/******************************************************************************
 Receive (virtual protected)

 Listen for menu selections and deactivated dialog windows.

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

void
DialogHelloDir::Receive
    (
    JBroadcaster* sender,
    const Message& message
    )
{
    // Check to see if the a menu item was selected.
    if (sender == itsTextMenu && message.Is(JXMenu::kItemSelected))
        {
        // Cast the sender so we can access its functions.
        const JXMenu::ItemSelected* selection =
        dynamic_cast(const JXMenu::ItemSelected*, &message);
        assert( selection != NULL );

        // Handle the menu selection
        HandleTextMenu(selection->GetIndex());
        }

    // Check if the sender is our dialog and that it's been diactivated.
    else if (sender == itsDialog && message.Is(JXDialogDirector::kDeactivated))
        {
        // Cast the sender so we can access its functions.
        const JXDialogDirector::Deactivated* info =
            dynamic_cast(const JXDialogDirector::Deactivated*, &message);
        assert( info != NULL );

        // If the user pressed the cancel button, this will fail.
        if (info->Successful())
            {
            // Get the next text from the dialog.
            GetNewTextFromDialog();
            }

        // The dialog is deleted (not by us) after it broadcasts this message.
        itsDialog = NULL;
        }

    // If we don't handle the message, we need to pass it to the base class
    else
        {
        JXWindowDirector::Receive(sender,message);
        }
}

/******************************************************************************
 HandleTextMenu

 Respond to the selected menu item.

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

void
DialogHelloDir::HandleTextMenu
 (
 const JIndex index
 )
{
    // Respond to the different menu items.
    if (index == kChangeText)
        {
        // Create and activate the input dialog.

        SetupInputDialog();
        }

    else if (index == kQuit)
        {
        // Quit the program. The application object is one of the few global
        // objects that can be accessed from anywhere within the application.

        (JXGetApplication())->Quit();
        }
}

/******************************************************************************
 SetupInputDialog

 Create and activate the input dialog.

 Dialog windows notify you that they have been dismissed by
 broadcasting the message JXDialogDirector::kDeactivated.
 Thus, all we have to do is create it, activate it, and listen
 to it.

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

void
DialogHelloDir::SetupInputDialog()
{
    // Make sure the dialog hasn't already been created.
    assert ( itsDialog == NULL );

    // Create the dialog with text from our static text object.
    itsDialog = new DHStringInputDialog(this, itsText->GetText());
    assert ( itsDialog != NULL );

    // We need to listen for the dialog's deactivation message.
    ListenTo(itsDialog);

    // Activate the dialog.
    itsDialog->BeginDialog();
}

/******************************************************************************
 GetNewTextFromDialog

 Pull the new text out of the dialog.

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

void
DialogHelloDir::GetNewTextFromDialog()
{
    // The dialog must have been created if we're calling this.
    assert ( itsDialog != NULL );

    // Get the text from the dialog and pass it to the static text object.
    const JString str = itsDialog->GetString();
    itsText->SetText(str);
}

DialogHelloDir header file:

/******************************************************************************
 DialogHelloDir.h

 Interface for the DialogHelloDir class

 Written by Glenn Bach - 1997.

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

#ifndef _H_DialogHelloDir
#define _H_DialogHelloDir

#include <JXWindowDirector.h>

class JXStaticText;
class JXTextMenu;
class DHStringInputDialog;

class DialogHelloDir : public JXWindowDirector
{
public:

    DialogHelloDir(JXDirector* supervisor);

    virtual ~DialogHelloDir();

protected:

    virtual void Receive(JBroadcaster* sender, const Message& message);

private:

    JXStaticText* itsText;
    JXTextMenu* itsTextMenu;
    DHStringInputDialog* itsDialog;

private:

    void BuildWindow();
    void HandleTextMenu(const JIndex index);
    void SetupInputDialog();
    void GetNewTextFromDialog();

    // not allowed

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

#endif
 
 

The DHStringInputDialog object - DHStringInputDialog.cc and DHStringInputDialog.h

DHStringInputDialog source file:

/******************************************************************************
 DHStringInputDialog.cc

 BASE CLASS = JXDialogDirector

 Written by Glenn Bach - 1997.

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

#include "DHStringInputDialog.h"
#include <JXWindow.h>
#include <JXTextButton.h>
#include <JXStringInput.h>
#include <JXStaticText.h>
#include <JString.h>
#include <jAssert.h>

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

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

DHStringInputDialog::DHStringInputDialog
    (
    JXWindowDirector* supervisor,
    const JCharacter* str
    )
    :
    JXDialogDirector(supervisor, kTrue)
{
    BuildWindow();

    // Set the initial value of the input string to the value passed in.
    itsText->SetString(str);
}

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

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

DHStringInputDialog::~DHStringInputDialog()
{
    // We don't have anything to delete.
}

/******************************************************************************
 BuildWindow (private)

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

void
DHStringInputDialog::BuildWindow()
{
    // Create the window and pass it to the director.
    JXWindow* window = new JXWindow(this, 280,90, "Change Text");
    assert( window != NULL );
    SetWindow(window);

    // Create the cancel button.
    JXTextButton* cancelButton =
        new JXTextButton("Cancel", window,
                    JXWidget::kHElastic, JXWidget::kVElastic, 70,60, 50,20);
    assert( cancelButton != NULL );

    // Create the OK button.
    JXTextButton* okButton =
        new JXTextButton("OK", window,
                    JXWidget::kHElastic, JXWidget::kVElastic, 150,60, 50,20);
    assert( okButton != NULL );
    okButton->SetShortcuts("^M");

    // Create the string input field.
    itsText =
        new JXStringInput(window,
                    JXWidget::kHElastic, JXWidget::kVElastic, 100,20, 150,20);
    assert( itsText != NULL );

    // Create a label for the input field.
    JXStaticText* obj1 =
        new JXStaticText("New Text:", window,
                    JXWidget::kHElastic, JXWidget::kVElastic, 30,20, 65,20);
    assert( obj1 != NULL );

    // The dialog director needs to know what its cancel and OK buttons are.
    // The OK button must exist. The Cancel button may be NULL.
    SetButtons(okButton, cancelButton);

    // Set it such that the input can only be 30 characters or less.
    itsText->SetMaxLength(30);
}

/******************************************************************************
 GetString

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

JString
DHStringInputDialog::GetString()
    const
{
    // After the dialog has been deactivated, this is how the program will
    // access the new string that was typed into the input field.
    return itsText->GetString();
}

DHStringInputDialog source file:

/******************************************************************************
 DHStringInputDialog.h

 Interface for the DHStringInputDialog class

 Written by Glenn Bach - 1997.

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

#ifndef _H_DHStringInputDialog
#define _H_DHStringInputDialog

#include <JXDialogDirector.h>

class JXStringInput;
class JString;

class DHStringInputDialog : public JXDialogDirector
{
public:

    DHStringInputDialog(JXWindowDirector* supervisor, const JCharacter* str);

    virtual ~DHStringInputDialog();

    JString GetString() const;

private:

    JXStringInput* itsText;

private:

    void BuildWindow();

    // not allowed

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

#endif
 
 

The function main - dialog_hello.cc

/******************************************************************************
 dialog_hello.cc

 Written by Glenn Bach - 1997.

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

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

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

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

int
main
    (
    int  argc,
    char* argv[]
 )
{
    // Create the application object - there should only be one of these
    JXApplication* app = new JXApplication(&argc, argv);
    assert( app != NULL );

    // Create the window director to maintain the Hello World window
    DialogHelloDir* mainDir = new DialogHelloDir(app);
    assert( mainDir != NULL );

    // Show the window and activate it
    mainDir->Activate();

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