[ Lit Window Library at SourceForge[ Lit Window Productions Homepage ]  [ wxWidgets Tips&Tricks ]  [  wxVisualSetup ]

Main Page | Modules | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

RSS Reader Tutorial Step 2: Adding data structures, defining data adapters

This step shows you how to add data structures to the program and define data adapters, so that RapidUI can use your data structures.

Data Structures

Let's flesh out the prototype we have so far.

Declare the data structures.

First define the neccessary data types.

Create a new file data.h with the following content:

/* 
 * Copyright 2004, Hajo Kirchhoff - Lit Window Productions, http://www.litwindow.com
 * This file is part of the Lit Window Library. All use of this material - copying
 * in full or part, including in other works, using in non-profit or for-profit work
 * and other uses - is governed by the licence contained in the Lit Window Library 
 * distribution, file LICENCE.TXT
 * $Id: data.h,v 1.1.1.1 2004/10/04 06:41:13 hajokirchhoff Exp $
 */
#pragma once

#include <vector>
#include "wx/datetime.h"

using namespace std;

struct Headline
{
    wxString    m_title;        // the headline title
    wxString    m_body;         // the news in html
    wxDateTime  m_published;    // date/time when this headline was published
    string      m_url;          // an associated URL
};

struct Channel
{
    string              m_webAddress;   // url of the channel
    wxString            m_title;        // the title of this channel
    wxTimeSpan          m_cacheExpires; // timespan between two refreshes
    vector<Headline>    m_headlines;    // the list of headlines
    wxDateTime          m_lastRead;     // date/time when this channel was last read
};

struct RssReaderData
{
    vector<Channel> m_channels;         // store all channels
    wxTimeSpan      m_refreshAfter;     // timespan between two refreshes
    wxDateTime      m_nextRefresh;      // time of next refresh
};

extern RssReaderData g_data;

Create a global RssReaderData variable.

The application needs some place to store the channels, headlines and settings. The easiest way is to use a global variable g_data.

Add the following lines to the main source file simple_rssreader_app.cpp

#include "data.h"
...
RssReaderData g_data;

Init the vector with a test entry.

Since we haven't coded a way to let the user add channels, lets add some channels directly for testing purposes. Add these lines to SimpleRssReader::OnInit().
bool SimpleRssReader::OnInit()
{
    wx_redirect.insert(lw_log());
    // add a test channel and a test headline
    Headline firstHeadline;
    firstHeadline.m_title="The 1st headline";
    firstHeadline.m_body="<p>This is some news!</p>";
    Channel testChannel;
    testChannel.m_webAddress="http://www.litwindow.com/rss.xml";
    testChannel.m_title="Testtitle";
    testChannel.m_headlines.push_back(firstHeadline);
    g_data.m_channels.push_back(testChannel);
This adds a headline with some text to a channel, then adds the channel to the global vector.

Defining the data adapters

Now it gets interesting. This is the first time we'll actually use something from the Lit Window Library. The RapidUI mechanism doesn't know anything about the struct we have just defined. We need an adapter between the data structures and the RapidUI mechanism. These adapter definitions can go into any source file of your project. Put them into simple_rssreader_app.cpp for this tutorial.

Defining adapters for struct datatypes

Include the neccessary header file.
#include <litwindow/dataadapter.h>
Add the data adapter definition.
BEGIN_ADAPTER(Headline)
    PROP(m_title)
    PROP(m_body)
    PROP(m_published)
    PROP(m_url)
END_ADAPTER()

BEGIN_ADAPTER(Channel)
    PROP(m_webAddress)
    PROP(m_title)
    PROP(m_cacheExpires)
    PROP(m_headlines)
    PROP(m_lastRead)
END_ADAPTER()

BEGIN_ADAPTER(RssReaderData)
    PROP(m_channels)
    PROP(m_refreshAfter)
    PROP(m_nextRefresh)
END_ADAPTER()

The adapter definition is just a very simple repetition of the struct declaration. BEGIN_ADAPTER(name) / END_ADAPTER encloses the list of the struct properties. To add a struct member to the adapter, simply add PROP(name) to the adapter.

Defining adapters for the container

Two adapters are still missing. The Channel datatype uses a vector<Headline> to store all headlines for a channel and the global variable g_channels uses a vector<Channel> to store all channels. RapidUI does not know anything about these containers, so we need to add another adapter.
IMPLEMENT_ADAPTER_CONTAINER(vector<Headline>)
IMPLEMENT_ADAPTER_CONTAINER(vector<Channel>)

These data adapter definitions are the price you have to pay to be able to use the RapidUI mechanism. But its worth it, as you'll see in the next step.

Lit Window Library project settings

Before you can build and run the project, you must make the neccessary settings for the Lit Window Library.

  1. Add the path to the Lit Window Libary include directory to the C++ preprocessor settings.
    Example: c:\litwindow\include.
  2. If you are using the DLL version you must define the USING_DLL preprocessor macro.
  3. Enable "RunTime Type Information" RTTI in C++|Language.
  4. Enable "C++ Exceptions" in C++|Code Generation.
  5. Add the Lit Window Library path to the linker input settings
    Example: c:\litwindow\lib

Build the project.

Step 2 Summary

Define Headline, Channel and RssData.
struct Headline
{
    wxString    m_title;        // the headline title
    wxString    m_body;         // the news in html
    wxDateTime  m_published;    // date/time when this headline was published
    string      m_url;          // an associated URL
};

struct Channel
{
    string              m_webAddress;   // url of the channel
    wxString            m_title;        // the title of this channel
    wxTimeSpan          m_cacheExpires; // timespan between two refreshes
    vector<Headline>    m_headlines;    // the list of headlines
    wxDateTime          m_lastRead;     // date/time when this channel was last read
};

struct RssReaderData
{
    vector<Channel> m_channels;         // store all channels
    wxTimeSpan      m_refreshAfter;     // timespan between two refreshes
    wxDateTime      m_nextRefresh;      // time of next refresh
};

extern RssReaderData g_data;

Add data adapters for struct Headline, struct Channel and struct RssData:

BEGIN_ADAPTER(Headline)
    PROP(m_title)
    PROP(m_body)
    PROP(m_published)
    PROP(m_url)
END_ADAPTER()

BEGIN_ADAPTER(Channel)
    PROP(m_webAddress)
    PROP(m_title)
    PROP(m_cacheExpires)
    PROP(m_headlines)
    PROP(m_lastRead)
END_ADAPTER()

BEGIN_ADAPTER(RssReaderData)
    PROP(m_channels)
    PROP(m_refreshAfter)
    PROP(m_nextRefresh)
END_ADAPTER()

Continue with RSS Reader Tutorial Step 3: Adding RapidUI


Copyright 2004, Hajo Kirchhoff, Lit Window Productions