[ 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 4: Filling in the rules

RapidUI is ready to spring into action.

Fill the channels listbox.

Let's fill the listbox with the list of channels.

Assigning the vector<Channels> to the listbox

RapidUI lets you assign the vector<Channels> to the listbox. RapidUI's parser for text-based rules is not finished yet, so we have to use the C++ form.
ASSIGN("m_channelsList.Items", "m_channels")

Add this rule to the rules section.

BEGIN_RULES(g_rules)
    RULE("m_channelsList.Items", make_expr<accessor>("m_channels"))         // listbox uses elements from m_channels
END_RULES()

Choosing the element to display

Build and run the application. This simple rule fills the listbox with all elements from the channels list. But the list displays the URL instead of the title. The data adapter definition for a Channel reads:
BEGIN_ADAPTER(Channel)
    PROP(m_webAddress)
    PROP(m_title)
    PROP(m_cacheExpires)
    PROP(m_headlines)
    PROP(m_lastRead)
END_ADAPTER()

By default the listbox will choose the first member variable of the data adapter, the member variable m_webAddress, and display it for all elements. The listbox property Column allows you to select a different member variable. Add the following rule:

    RULE("m_channelsList.Column", make_const(string("m_title")))            // listbox displays "Channel::m_title"

Build and run the application. The listbox will now show the title instead of the URL.

Linking the headlines and the channels listbox together.

Now it gets interesting. The next rule we are going to add links the headlines listbox to the selection of the channels listbox. When a user selects a channel, the headlines listbox shall display all available headlines for that channel. Everytime the user selects a different channel, the contents of the headlines listbox change.

link_channels_headlines.png

Current channel and list of headlines linked together

The requirement in plain english reads
The headlines listbox shall always contain the list of headlines for the currently selected channel.
A slightly more technical version is
The "Items" property of the headlines listbox shall always contain the list of headlines for the currently selected channel, i.e. the "Current" property of the channels listbox.
or as a rule
m_headlinesList.Items = m_channels.Current.m_headlines

"Filling the headlines listbox" written in C++

In traditional GUI coding you have to write a function for the 'channel selection has changed' event. This function must then clear the headlines listbox and fill it with new values.
void MyFrame::OnChannelsChanged(wxCommandEvent &evt)
{
    m_headlinesList.Clear();
    int selectedChannelIndex=m_channelsList.GetSelection();
    if (selectedChannelIndex>=0) {
        Channel &current=g_data.m_channels[selectedChannelIndex];
        size_t i;
        for (i=0; i<current.m_headlines.size(); ++i) {
            m_headlinesList.Append(current.m_headlines[i].m_title);
        }
    }
}

"Filling the headlines listbox" written with RapidUI

With RapidUI you need exactly one line of code.
    RULE("m_headlinesList.Items", make_expr<accessor>("m_channelsList.Current.m_headlines"))

This is a very good (and working!) example of why I hope to reduce coding time by a factor of 10.

Showing the news article for the selected headline.

Another 'linking' requirement.
Requirement
The news htmlWindow shall always contain the body of the currently selected headline.
More technical version
The "Page" property (wxHtmlWindow::SetPage) shall always contain the m_body member of the currently selected headline, i.e. the "Current" property of the headlines listbox.
link_headline_news.png

Current headline and html window linked together

As a rule
m_newsItem.Page = m_headlinesList.Current.m_body

"Showing the news" written in C++

Like above you have to write a function for the 'headline selection has changed' event. This function copies the m_body member of the currently selected headline and calls wxHtmlWindow::SetPage.
void MyFrame::OnHeadlinesChanged(wxCommandEvent &evt)
{
    int channelIndex=m_channelsList.GetSelection();
    int headlineIndex=m_headlinesList.GetSelection();
    m_newsItem.SetPage((channelIndex>=0 && headlineIndex>=0) ? g_data.m_channels[channelIndex].m_headlines[headlineIndex].m_body);
}

"Showing the news" written with RapidUI

Again, only one line of code (one rule to rule the news).
    RULE("m_newsItem.Page", make_expr<wxString>("m_headlinesList.Current.m_body"))

Displaying the title of the headline in the titlebar of the frame window

Finally, to show that rules can handle expressions, lets implement the following requirement.
Requirement
The titlebar of the frame window shall display the title of the currently selected headline prepended by the word 'Headline: '
Technical version
The "Title" property of the frame window shall always contain the result of the following expression: "Headline: "+m_headlinesList.Current.m_title
As a rule
ID_FRAME.Title = wxString("Headline: ")+m_headlinesList.Current.m_title

"Setting the title bar" written in C++

Since we've already got an event function OnHeadlinesChanged, we can use it and add the following line to it:
    this->SetTitle(wxString("Headline: ")+g_data.m_channels[channelIndex].m_headlines[headlineIndex].m_title);
Except for one thing: When the program starts for the first time, OnHeadlinesChanged will not get called and the title bar will not be set. We must initialise the titlebar to the proper value "Headlines: ", if desired.

"Setting the title bar" written in C++

The RapidUI rules can handle more than simple assignments. Here is the rule:
    RULE("ID_FRAME.Title", make_const<wxString>("Headline: ")+make_expr<wxString>("m_channelsList.Current.m_title"))
Note:
ID_FRAME is the (XRC) name of the frame window.

Step 4 Summary

RapidUI saves time and code, because writing rules is usually a lot faster and shorter than coding the appropriate 'OnSomethingHappened' event handler. These rules

Copyright 2004, Hajo Kirchhoff, Lit Window Productions