Wt examples: /home/koen/project/wt/public-git/wt/examples/treelist/DemoTreeList.C Source File

Wt examples 3.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

/home/koen/project/wt/public-git/wt/examples/treelist/DemoTreeList.C
Go to the documentation of this file.

    00001 /*
    00002  * Copyright (C) 2008 Emweb bvba, Kessel-Lo, Belgium.
    00003  *
    00004  * See the LICENSE file for terms of use.
    00005  */
    00006 #include <boost/lexical_cast.hpp>
    00007
    00008 #include <Wt/WApplication>
    00009 #include <Wt/WText>
    00010 #include <Wt/WImage>
    00011 #include <Wt/WPushButton>
    00012
    00013 #include "DemoTreeList.h"
    00014 #include "TreeNode.h"
    00015 #include "IconPair.h"
    00016
    00017 using namespace Wt;
    00018 using std::rand;
    00019
    00020 DemoTreeList::DemoTreeList(WContainerWidget *parent)
    00021   : WContainerWidget(parent),
    00022     testCount_(0)
    00023 {
    00024   addWidget
    00025     (new WText("<h2>Wt Tree List example</h2>"
    00026                "<p>This is a simple demo of a treelist, implemented using"
    00027                " <a href='http://witty.sourceforge.net/'>Wt</a>.</p>"
    00028                "<p>The leafs of the tree contain the source code of the "
    00029                "tree-list in the classes <b>TreeNode</b> and "
    00030                "<b>IconPair</b>, as well as the implementation of this "
    00031                "demo itself in the class <b>DemoTreeList</b>.</p>"));
    00032
    00033   tree_ = makeTreeMap("Examples", 0);
    00034   addWidget(tree_);
    00035
    00036   TreeNode *treelist = makeTreeMap("Tree List", tree_);
    00037   TreeNode *wstateicon = makeTreeMap("class IconPair", treelist);
    00038   makeTreeFile("<a href=\"IconPair.h\">IconPair.h</a>", wstateicon);
    00039   makeTreeFile("<a href=\"IconPair.C\">IconPair.C</a>", wstateicon);
    00040   TreeNode *wtreenode = makeTreeMap("class TreeNode", treelist);
    00041   makeTreeFile("<a href=\"TreeNode.h\">TreeNode.h</a>", wtreenode);
    00042   makeTreeFile("<a href=\"TreeNode.C\">TreeNode.C</a>", wtreenode);
    00043   TreeNode *demotreelist = makeTreeMap("class DemoTreeList", treelist);
    00044   makeTreeFile("<a href=\"DemoTreeList.h\">DemoTreeList.h</a>", demotreelist);
    00045   makeTreeFile("<a href=\"DemoTreeList.C\">DemoTreeList.C</a>", demotreelist);
    00046
    00047   testMap_ = makeTreeMap("Test map", tree_);
    00048
    00049   /*
    00050    * Buttons to dynamically demonstrate changing the tree contents.
    00051    */
    00052   addWidget
    00053     (new WText("<p>Use the following buttons to change the tree "
    00054                "contents:</p>"));
    00055
    00056   addMapButton_
    00057     = new WPushButton("Add map", this);
    00058   addMapButton_->clicked().connect(this, &DemoTreeList::addMap);
    00059
    00060   removeMapButton_
    00061     = new WPushButton("Remove map", this);
    00062   removeMapButton_->clicked().connect(this, &DemoTreeList::removeMap);
    00063   removeMapButton_->disable();
    00064
    00065   addWidget
    00066     (new WText("<p>Remarks:"
    00067                "<ul>"
    00068                "<li><p>This is not the instantiation of a pre-defined "
    00069                "tree list component, but the full implementation of such "
    00070                "a component, in about 350 lines of C++ code !</p> "
    00071                "<p>In comparison, the <a href='http://myfaces.apache.org'> "
    00072                "Apache MyFaces</a> JSF implementation of tree2, with similar "
    00073                "functionality, uses about 2400 lines of Java, and 140 lines "
    00074                "of JavaScript code.</p></li>"
    00075                "<li><p>Once loaded, the tree list does not require any "
    00076                "interaction with the server for handling the click events on "
    00077                "the <img src='icons/nav-plus-line-middle.gif' /> and "
    00078                "<img src='icons/nav-minus-line-middle.gif' /> icons, "
    00079                "because these events have been connected to slots using "
    00080                "STATIC connections. Such connections are converted to the "
    00081                "appropriate JavaScript code that is inserted into the page. "
    00082                "Still, the events are signaled to the server to update the "
    00083                "application state.</p></li>"
    00084                "<li><p>In contrast, the buttons for manipulating the tree "
    00085                "contents use DYNAMIC connections, and thus the update "
    00086                "is computed at server-side, and communicated back to the "
    00087                "browser (by default using AJAX).</p></li>"
    00088                "<li><p>When loading a page, only visible widgets (that are not "
    00089                "<b>setHidden(true)</b>) are transmitted. "
    00090                "The remaining widgets are loaded in the background after "
    00091                "rendering the page. "
    00092                "As a result the application is loaded as fast as possible.</p>"
    00093                "</li>"
    00094                "<li><p>The browser reload button is supported and behaves as "
    00095                "expected: the page is reloaded from the server. Again, "
    00096                "only visible widgets are transmitted immediately.</p> "
    00097                "<p>(For the curious, this is the way to see the actual "
    00098                "HTML/JavaScript code !)</p></li>"
    00099                "</ul></p>"));
    00100 }
    00101
    00102 void DemoTreeList::addMap()
    00103 {
    00104   TreeNode *node
    00105     = makeTreeMap("Map " + boost::lexical_cast<std::string>(++testCount_),
    00106                   testMap_);
    00107   makeTreeFile("File " + boost::lexical_cast<std::string>(testCount_),
    00108                node);
    00109
    00110   removeMapButton_->enable();
    00111 }
    00112
    00113 void DemoTreeList::removeMap()
    00114 {
    00115   int numMaps = testMap_->childNodes().size();
    00116
    00117   if (numMaps > 0) {
    00118     int c = rand() % numMaps;
    00119
    00120     TreeNode *child = testMap_->childNodes()[c];
    00121     testMap_->removeChildNode(child);
    00122     delete child;
    00123
    00124     if (numMaps == 1)
    00125       removeMapButton_->disable();
    00126   }
    00127 }
    00128
    00129 TreeNode *DemoTreeList::makeTreeMap(const std::string name, TreeNode *parent)
    00130 {
    00131   IconPair *labelIcon
    00132     = new IconPair("icons/yellow-folder-closed.png",
    00133                    "icons/yellow-folder-open.png",
    00134                    false);
    00135
    00136   TreeNode *node = new TreeNode(name, PlainText, labelIcon, 0);
    00137   if (parent)
    00138     parent->addChildNode(node);
    00139
    00140   return node;
    00141 }
    00142
    00143 TreeNode *DemoTreeList::makeTreeFile(const std::string name,
    00144                                       TreeNode *parent)
    00145 {
    00146   IconPair *labelIcon
    00147     = new IconPair("icons/document.png", "icons/yellow-folder-open.png",
    00148                    false);
    00149
    00150   TreeNode *node = new TreeNode(name, XHTMLText, labelIcon, 0);
    00151   if (parent)
    00152     parent->addChildNode(node);
    00153
    00154   return node;
    00155 }
    00156
    00157 WApplication *createApplication(const WEnvironment& env)
    00158 {
    00159   WApplication *app = new WApplication(env);
    00160   new DemoTreeList(app->root());
    00161
    00162   /*
    00163    * The look & feel of the tree node is configured using a CSS style sheet.
    00164    * If you are not familiar with CSS, you can use the WCssDecorationStyle
    00165    * class ...
    00166    */
    00167   WCssDecorationStyle treeNodeLabelStyle;
    00168   treeNodeLabelStyle.font().setFamily(WFont::Serif, "Helvetica");
    00169   app->styleSheet().addRule(".treenodelabel", treeNodeLabelStyle);
    00170
    00171   /*
    00172    * ... or if you speak CSS fluently, you can add verbatim rules.
    00173    */
    00174   app->styleSheet().addRule(".treenodechildcount",
    00175                             "color:blue; font-family:Helvetica,serif;");
    00176
    00177   return app;
    00178 }
    00179
    00180 int main(int argc, char **argv)
    00181 {
    00182    return WRun(argc, argv, &createApplication);
    00183 }
    00184