Go to the documentation of this file.00001
00002
00003
00004
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
00035 implementStateless(&TreeNode::expand, &TreeNode::undoExpand);
00036 implementStateless(&TreeNode::collapse, &TreeNode::undoCollapse);
00037
00038
00039
00040
00041
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
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
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
00165 expandIcon_->setState(0);
00166 expandedContent_->hide();
00167 if (labelIcon_)
00168 labelIcon_->setState(0);
00169 }
00170
00171
00172
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()->imageRef() != imagePlus_[index])
00183 expandIcon_->icon1()->setImageRef(imagePlus_[index]);
00184 if (expandIcon_->icon2()->imageRef() != imageMin_[index])
00185 expandIcon_->icon2()->setImageRef(imageMin_[index]);
00186 if (noExpandIcon_->imageRef() != imageLine_[index])
00187 noExpandIcon_->setImageRef(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 }