Wt examples 3.1.10
/build/buildd/witty-3.1.10/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 
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()->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 } //

Generated on Mon Nov 14 2011 for the C++ Web Toolkit (Wt) by doxygen 1.7.4