[Home]  [Prev]  [Next]    A guide, a tutorial for developing well-designed cross-platform applications

7. Documentation

Documentation of an application may be provided as either a manual or as a help. A help has the advantage that it might be context sensitive while a manual is easier as a tutorial.

Another type of documentation is the "About ..." box which shows the essential information, e.g. the environment an application is running. This is rather handy in case of a bug report.


7.1 Help

Not much has to be said about help, it's simply a necessity. While on most platform the help is located next to the application executable, on Linux the location of the help isn't well standardized. In this case it's best if the help file location is configured in the prefs (application directory) and located via g_appDirectory (see also the Application location description).

Sample code

#include <wx/fs_zip.h>   // ZIP filesystem support
#include <wx/html/helpctrl.h> // html help support
#include "wx/localize.h"   // localize support
...

//! global help provider
wxHtmlHelpController *g_help = NULL;

class AppFrame: public wxFrame {
    ...
    void OnHelp (wxCommandEvent &event);
    ...
    wxHtmlHelpController& GetHelpController() {return *g_help; }
    ...
}

bool App::OnInit () {
    ...

    wxString appPath = g_appDirectory; // gets the configured application directory
    if (appPath.IsEmpty()) appPath = wxFileName(argv[0]).GetPath (wxPATH_GET_VOLUME);
    wxString appName = wxFileName(argv[0]).GetName();
#ifdef __WXMAC__
    appPath += wxFileName::GetPathSeparator() + appName + _T(".app/Contents/SharedSupport"));
#endif

    ...
    wxFileSystem::AddHandler (new wxZipFSHandler);
    g_help = new wxHtmlHelpController;
    wxString helpfile = wxLocalize (appPath, appName + _T(".htb"));
    if (wxFileExists (helpfile)) {
        g_help->AddBook (helpfile);
    }
    ...
}

int App::OnExit () {
    ...

    // delete help
    if (g_help) delete g_help;

    ...
}

void AppFrame::OnHelp (wxCommandEvent &WXUNUSED(event)) {
    wxWindow *active = wxGetActiveWindow();
    wxString helptext;
    while (active && helptext.IsEmpty()) {
        helptext = active->GetHelpText();
        active = GetParent();
    }
    g_help->DisplayContents();
}

Don't forget to add the localize sources to your project, they aren't currently part of wxWidgets but from wxCode.

Note: The application directory (g_appDirectory) can be configured in the preferences, the code can looked up in the demo application.


7.2 About box

The "About ..." box is the signature of an application and gives the first impression. Depending of the kind of the application this might be a fancy multimedia process or just a practical display of the essential information.

The essential information an "About ..." box should show are:

Of course additional information might be nice as well, e.g. framework version, important library versions, additional developers, etc.

It should also contain a small description what this application is for and a reference to where to get more information. A clickable link to the web site (if any) would be nice. For OpenSource project its common practice to list the contributors.

An application may show the "About ..." box during program start. If it does it should either provide a disable feature right in the box or remove the box after a certain state is reached or at least a certain amount of time is over. It's very annoying for a user to have to close the box during daily work.

Sample code

#include "app.xpm"          // app icon bitmap
#include "wx/hyperlink.h"   // hyperlink support
...
const wxString APP_NAME = _T("wyoGuide-Demo");
const wxString APP_VENDOR = _T("wyoGuide");
const wxString APP_VERSION = _T("1.3.3");
const wxString APP_MAINT = _T("Otto Wyss");
const wxString APP_LICENCE = _T("wxWindows");
const wxString APP_COPYRIGTH = _T("(C) 2005 Otto Wyss");
const wxString APP_WEBSITE = _T("http://wyoguide.sourceforge.net/");
const wxString APP_WEBSITE_EXACT = _T("index.php?page=demo.html");
const wxString APP_MAIL = _T("mailto:wyoguide-users@lists.sourceforge.net");
...

static wxString g_appname;

class AppFrame: public wxFrame {
    friend class AppAbout;
    ...
    void OnAbout (wxCommandEvent &event);
    ...
};

class AppAbout: public wxDialog {

public:
    AppAbout (wxWindow *parent, long style = 0);

};

void AppFrame::OnAbout (wxCommandEvent &WXUNUSED(event)) {
    AppAbout (this);
}

AppAbout::AppAbout (wxWindow *parent,
                    long style)
        : wxDialog (parent, -1, _("About ..."),
                    wxDefaultPosition, wxDefaultSize,
                    wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) {

    // sets the application icon
    SetTitle (_("About ..."));

    // about info
    wxGridSizer *aboutinfo = new wxGridSizer (2, 3, 3);
    aboutinfo->Add (new wxStaticText(this, -1, _("Version: ")));
    aboutinfo->Add (new wxStaticText(this, -1, APP_VERSION));
    aboutinfo->Add (new wxStaticText(this, -1, _("Written by: ")));
    aboutinfo->Add (new wxStaticText(this, -1, APP_MAINT));
    aboutinfo->Add (new wxStaticText(this, -1, _("Licence type: ")));
    aboutinfo->Add (new wxStaticText(this, -1, APP_LICENCE));
    aboutinfo->Add (new wxStaticText(this, -1, _("wxWidgets: ")));
    aboutinfo->Add (new wxStaticText(this, -1, wxVERSION_STRING));
    aboutinfo->Add (new wxStaticText(this, -1, _("Copyright: ")));
    aboutinfo->Add (new wxStaticText(this, -1, APP_COPYRIGTH));

    // about icontitle//info
    wxBoxSizer *aboutpane = new wxBoxSizer (wxHORIZONTAL);
    aboutpane->Add (new wxStaticBitmap (this, -1, wxBitmap (app_xpm)),
                    0, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 40);
    aboutpane->Add (aboutinfo, 1, wxEXPAND);
    aboutpane->Add (60, 0);

    // about complete
    wxBoxSizer *totalpane = new wxBoxSizer (wxVERTICAL);
    totalpane->Add (0, 20);
    wxStaticText *appname = new wxStaticText (this, -1, g_appname);
    appname->SetFont (wxFont (24, wxDEFAULT, wxNORMAL, wxBOLD));
    abouttext->Add (appname, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, 40);
    abouttext->Add (0, 10);
    totalpane->Add (aboutpane, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT | wxBOTTOM, 10);
    totalpane->Add (new wxStaticText(this, -1, wxGetTranslation(APP_SYNOPSIS)),
                    0, wxALIGN_LEFT | wxLEFT | wxRIGHT | wxBOTTOM, 10);
    myHyperLink *website = new myHyperLink (this, -1, APP_WEBSITE);
    wxString url = APP_WEBSITE;
    url.Append (APP_WEBSITE_EXACT);
    website->SetURL (url);
    totalpane->Add (website, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT | wxBOTTOM, 10);
    ...
    wxButton *okButton = new wxButton (this, wxID_OK, _("OK"));
    okButton->SetDefault();
    totalpane->Add (okButton, 0, wxALIGN_CENTER | wxALL, 10);

    SetSizerAndFit (totalpane);

    CentreOnParent();
    ShowModal();
}

Don't forget to add the hyperlink sources to your project, they aren't currently part of wxWidgets but from wxCode.


7.3 Naming of objects

Someone said once, all the programming art is choosing good names, the rest is just plain work. This is certainly true but it's almost impossible to make good rules.