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/WTable> 00009 #include <Wt/WTableCell> 00010 #include <Wt/WImage> 00011 #include <Wt/WText> 00012 #include <Wt/WCssDecorationStyle> 00013 00014 #include "TreeNode.h" 00015 #include "IconPair.h" 00016 00017 using std::find; 00018 00019 std::string TreeNode::imageLine_[] = { "icons/line-middle.gif", 00020 "icons/line-last.gif" }; 00021 std::string TreeNode::imagePlus_[] = { "icons/nav-plus-line-middle.gif", 00022 "icons/nav-plus-line-last.gif" }; 00023 std::string TreeNode::imageMin_[] = { "icons/nav-minus-line-middle.gif", 00024 "icons/nav-minus-line-last.gif" }; 00025 00026 TreeNode::TreeNode(const std::string labelText, 00027 Wt::TextFormat labelFormat, 00028 IconPair *labelIcon, 00029 Wt::WContainerWidget *parent) 00030 : Wt::WCompositeWidget(parent), 00031 parentNode_(0), 00032 labelIcon_(labelIcon) 00033 { 00034 // pre-learned stateless implementations ... 00035 implementStateless(&TreeNode::expand, &TreeNode::undoExpand); 00036 implementStateless(&TreeNode::collapse, &TreeNode::undoCollapse); 00037 00038 // ... or auto-learned stateless implementations 00039 // which do not need undo functions 00040 //implementStateless(&TreeNode::expand); 00041 //implementStateless(&TreeNode::collapse); 00042 00043 setImplementation(layout_ = new Wt::WTable()); 00044 00045 expandIcon_ = new IconPair(imagePlus_[Last], imageMin_[Last]); 00046 expandIcon_->hide(); 00047 noExpandIcon_ = new Wt::WImage(imageLine_[Last]); 00048 00049 expandedContent_ = new Wt::WContainerWidget(); 00050 expandedContent_->hide(); 00051 00052 labelText_ = new Wt::WText(labelText); 00053 labelText_->setTextFormat(labelFormat); 00054 labelText_->setStyleClass("treenodelabel"); 00055 childCountLabel_ = new Wt::WText(); 00056 childCountLabel_->setMargin(7, Wt::Left); 00057 childCountLabel_->setStyleClass("treenodechildcount"); 00058 00059 layout_->elementAt(0, 0)->addWidget(expandIcon_); 00060 layout_->elementAt(0, 0)->addWidget(noExpandIcon_); 00061 00062 if (labelIcon_) { 00063 layout_->elementAt(0, 1)->addWidget(labelIcon_); 00064 labelIcon_->setVerticalAlignment(Wt::AlignMiddle); 00065 } 00066 layout_->elementAt(0, 1)->addWidget(labelText_); 00067 layout_->elementAt(0, 1)->addWidget(childCountLabel_); 00068 00069 layout_->elementAt(1, 1)->addWidget(expandedContent_); 00070 00071 layout_->elementAt(0, 0)->setContentAlignment(Wt::AlignTop); 00072 layout_->elementAt(0, 1)->setContentAlignment(Wt::AlignMiddle); 00073 00074 expandIcon_->icon1Clicked.connect(this, &TreeNode::expand); 00075 expandIcon_->icon2Clicked.connect(this, &TreeNode::collapse); 00076 } // 00077 00078 bool TreeNode::isLastChildNode() const 00079 { 00080 if (parentNode_) { 00081 return parentNode_->childNodes_.back() == this; 00082 } else 00083 return true; 00084 } 00085 00086 void TreeNode::addChildNode(TreeNode *node) 00087 { 00088 childNodes_.push_back(node); 00089 node->parentNode_ = this; 00090 00091 expandedContent_->addWidget(node); 00092 00093 childNodesChanged(); 00094 } 00095 00096 void TreeNode::removeChildNode(TreeNode *node) 00097 { 00098 childNodes_.erase(std::find(childNodes_.begin(), childNodes_.end(), node)); 00099 00100 node->parentNode_ = 0; 00101 00102 expandedContent_->removeWidget(node); 00103 00104 childNodesChanged(); 00105 } // 00106 00107 void TreeNode::childNodesChanged() 00108 { 00109 for (unsigned i = 0; i < childNodes_.size(); ++i) 00110 childNodes_[i]->adjustExpandIcon(); 00111 00112 adjustExpandIcon(); 00113 00114 if (childNodes_.size()) 00115 childCountLabel_ 00116 ->setText("(" + boost::lexical_cast<std::string>(childNodes_.size()) 00117 + ")"); 00118 else 00119 childCountLabel_->setText(""); 00120 00121 resetLearnedSlots(); 00122 } // 00123 00124 void TreeNode::collapse() 00125 { 00126 wasCollapsed_ = expandedContent_->isHidden(); 00127 00128 expandIcon_->setState(0); 00129 expandedContent_->hide(); 00130 if (labelIcon_) 00131 labelIcon_->setState(0); 00132 } // 00133 00134 void TreeNode::expand() 00135 { 00136 wasCollapsed_ = expandedContent_->isHidden(); 00137 00138 expandIcon_->setState(1); 00139 expandedContent_->show(); 00140 if (labelIcon_) 00141 labelIcon_->setState(1); 00142 00143 /* 00144 * collapse all children 00145 */ 00146 for (unsigned i = 0; i < childNodes_.size(); ++i) 00147 childNodes_[i]->collapse(); 00148 } // 00149 00150 void TreeNode::undoCollapse() 00151 { 00152 if (!wasCollapsed_) { 00153 // re-expand 00154 expandIcon_->setState(1); 00155 expandedContent_->show(); 00156 if (labelIcon_) 00157 labelIcon_->setState(1); 00158 } 00159 } 00160 00161 void TreeNode::undoExpand() 00162 { 00163 if (wasCollapsed_) { 00164 // re-collapse 00165 expandIcon_->setState(0); 00166 expandedContent_->hide(); 00167 if (labelIcon_) 00168 labelIcon_->setState(0); 00169 } 00170 00171 /* 00172 * undo collapse of children 00173 */ 00174 for (unsigned i = 0; i < childNodes_.size(); ++i) 00175 childNodes_[i]->undoCollapse(); 00176 } // 00177 00178 void TreeNode::adjustExpandIcon() 00179 { 00180 ImageIndex index = isLastChildNode() ? Last : Middle; 00181 00182 if (expandIcon_->icon1()->imageLink().url() != imagePlus_[index]) 00183 expandIcon_->icon1()->setImageLink(imagePlus_[index]); 00184 if (expandIcon_->icon2()->imageLink().url() != imageMin_[index]) 00185 expandIcon_->icon2()->setImageLink(imageMin_[index]); 00186 if (noExpandIcon_->imageLink().url() != imageLine_[index]) 00187 noExpandIcon_->setImageLink(imageLine_[index]); 00188 00189 if (index == Last) { 00190 layout_->elementAt(0, 0) 00191 ->decorationStyle().setBackgroundImage(""); 00192 layout_->elementAt(1, 0) 00193 ->decorationStyle().setBackgroundImage(""); 00194 } else { 00195 layout_->elementAt(0, 0) 00196 ->decorationStyle().setBackgroundImage("icons/line-trunk.gif", 00197 Wt::WCssDecorationStyle::RepeatY); 00198 layout_->elementAt(1, 0) 00199 ->decorationStyle().setBackgroundImage("icons/line-trunk.gif", 00200 Wt::WCssDecorationStyle::RepeatY); 00201 } // 00202 00203 if (childNodes_.empty()) { 00204 if (noExpandIcon_->isHidden()) { 00205 noExpandIcon_->show(); 00206 expandIcon_->hide(); 00207 } 00208 } else { 00209 if (expandIcon_->isHidden()) { 00210 noExpandIcon_->hide(); 00211 expandIcon_->show(); 00212 } 00213 } 00214 } //