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

Generated on Fri Jul 25 17:05:59 2008 for Wt by doxygen 1.5.3