Wt examples
3.3.0
|
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