bpp-phyl3  3.0.0
AbstractTreeDrawing.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
5 #ifndef BPP_PHYL_GRAPHICS_ABSTRACTTREEDRAWING_H
6 #define BPP_PHYL_GRAPHICS_ABSTRACTTREEDRAWING_H
7 
8 
9 #include "../Tree/NodeTemplate.h"
10 #include "../Tree/TreeTemplate.h"
11 #include "TreeDrawing.h"
12 #include "TreeDrawingListener.h"
13 
14 // From the STL:
15 #include <vector>
16 #include <string>
17 #include <memory>
18 
19 namespace bpp
20 {
22 {
23 private:
25  bool collapsed_;
26 
27 public:
29  virtual ~TreeDrawingNodeInfo() {}
30 
31 public:
32  const Point2D<double>& getPosition() const { return pos_; }
34  void setPosition(const Point2D<double>& position) { pos_ = position; }
35  double getX() const { return pos_.getX(); }
36  double getY() const { return pos_.getY(); }
37  void setX(double x) { pos_.setX(x); }
38  void setY(double y) { pos_.setY(y); }
39  void collapse(bool yn) { collapsed_ = yn; }
40  bool isCollapsed() const { return collapsed_; }
41 };
42 
44 
45 
50  public DrawNodeEvent
51 {
52 private:
53  const INode* node_;
54 
55 public:
56  DrawINodeEvent(const TreeDrawing* source, GraphicDevice* gd, const INode* node, const Cursor& cursor) :
57  DrawNodeEvent(source, gd, node->getId(), cursor),
58  node_(node)
59  {}
60 
62  DrawNodeEvent(dne), node_(dne.node_)
63  {}
64 
66  {
68  node_ = dne.node_;
69  return *this;
70  }
71 
72 public:
73  const INode* getINode() const { return node_; }
74 };
75 
76 
81  public DrawBranchEvent
82 {
83 private:
84  const INode* node_;
85 
86 public:
87  DrawIBranchEvent(const TreeDrawing* source, GraphicDevice* gd, const INode* node, const Cursor& cursor) :
88  DrawBranchEvent(source, gd, node->getId(), cursor),
89  node_(node)
90  {}
91 
93  DrawBranchEvent(dne), node_(dne.node_)
94  {}
95 
97  {
99  node_ = dne.node_;
100  return *this;
101  }
102 
103 public:
104  const INode* getINode() const { return node_; }
105 };
106 
107 
116  public virtual TreeDrawing
117 {
118 private:
119  std::unique_ptr<TreeTemplate<INode>> tree_;
120  double xUnit_;
121  double yUnit_;
123  std::vector<TreeDrawingListener*> listeners_;
124 
125 public:
127 
129  tree_(atd.tree_.get() ? dynamic_cast<TreeTemplate<INode>*>(atd.tree_->clone()) : 0),
130  xUnit_(atd.xUnit_),
131  yUnit_(atd.yUnit_),
132  settings_(atd.settings_),
133  listeners_(atd.listeners_.size())
134  {
135  for (unsigned int i = 0; i < listeners_.size(); ++i)
136  {
137  if (atd.listeners_[i]->isAutonomous())
138  listeners_[i] = atd.listeners_[i];
139  else
140  listeners_[i] = dynamic_cast<TreeDrawingListener*>(atd.listeners_[i]->clone());
141  }
142  }
143 
145  {
146  if (atd.tree_.get())
147  tree_.reset(dynamic_cast<TreeTemplate<INode>*>(atd.tree_->clone()));
148  else tree_.reset();
149  xUnit_ = atd.xUnit_;
150  yUnit_ = atd.yUnit_;
151  settings_ = atd.settings_;
152  listeners_.resize(atd.listeners_.size());
153  for (unsigned int i = 0; i < listeners_.size(); ++i)
154  {
155  if (atd.listeners_[i]->isAutonomous())
156  listeners_[i] = atd.listeners_[i];
157  else
158  listeners_[i] = dynamic_cast<TreeDrawingListener*>(atd.listeners_[i]->clone());
159  }
160  return *this;
161  }
162 
164  {
165  for (unsigned int i = 0; i < listeners_.size(); i++)
166  {
167  if (!listeners_[i]->isAutonomous())
168  delete listeners_[i];
169  }
170  }
171 
172 public:
173  bool hasTree() const { return tree_.get() != 0; }
174 
175  const TreeTemplate<INode>* getTree() const { return tree_.get(); }
176 
177  void setTree(const Tree* tree)
178  {
179  if (tree_.get())
180  tree_.reset();
181  if (!tree) tree_.reset();
182  else
183  {
184  tree_.reset(new TreeTemplate<INode>(*tree)); // We copy the tree
185  }
186  treeHasChanged();
187  }
188 
189  Point2D<double> getNodePosition(int nodeId) const;
190 
191  int getNodeAt(const Point2D<double>& position) const;
192 
202  bool belongsTo(const Point2D<double>& p1, const Point2D<double>& p2) const;
203 
216  virtual void drawAtNode(GraphicDevice& gDevice, const INode& node, const std::string& text,
217  double xOffset = 0, double yOffset = 0,
218  short hpos = GraphicDevice::TEXT_HORIZONTAL_LEFT, short vpos = GraphicDevice::TEXT_VERTICAL_CENTER, double angle = 0) const;
219 
232  virtual void drawAtBranch(GraphicDevice& gDevice, const INode& node, const std::string& text, double xOffset = 0, double yOffset = 0, short hpos = GraphicDevice::TEXT_HORIZONTAL_LEFT, short vpos = GraphicDevice::TEXT_VERTICAL_CENTER, double angle = 0) const;
233 
235  {
236  if (!tds)
237  throw NullPointerException("AbstractTreeDrawing::setDisplaySettings. Null pointer provided.");
238  settings_ = tds;
239  }
241 
242  double getXUnit() const { return xUnit_; }
243 
244  double getYUnit() const { return yUnit_; }
245 
246  void setXUnit(double xu) { xUnit_ = xu; }
247 
248  void setYUnit(double yu) { yUnit_ = yu; }
249 
250  void collapseNode(int nodeId, bool yn)
251  {
252  if (!tree_.get()) throw Exception("AbstractTreeDrawing::collapseNode. No tree is associated to the drawing.");
253  tree_->getNode(nodeId)->getInfos().collapse(yn);
254  }
255 
256  bool isNodeCollapsed(int nodeId) const
257  {
258  if (!tree_.get()) throw Exception("AbstractTreeDrawing::isNodeCollapsed. No tree is associated to the drawing.");
259  return tree_->getNode(nodeId)->getInfos().isCollapsed();
260  }
261 
263  {
264  if (find(listeners_.begin(), listeners_.end(), listener) != listeners_.end())
265  throw Exception("AbstractTreeDrawing::addTreeDrawingListener. Listener is already associated to this drawing.");
266  listeners_.push_back(listener);
267  }
268 
270  {
271  std::vector<TreeDrawingListener*>::iterator it = std::find(listeners_.begin(), listeners_.end(), listener);
272  if (it == listeners_.end())
273  throw Exception("AbstractTreeDrawing::addTreeDrawingListener. Listener is not associated to this drawing, and therefore can't be removed.");
274  listeners_.erase(it);
275  if (!listener->isAutonomous())
276  delete listener;
277  }
278 
282  virtual void treeHasChanged() = 0;
283 
284 protected:
285  TreeTemplate<INode>* getTree_() { return tree_.get(); }
286  const TreeTemplate<INode>* getTree_() const { return tree_.get(); }
287 
288  void fireBeforeTreeEvent_(const DrawTreeEvent& event) const
289  {
290  for (unsigned int i = 0; i < listeners_.size(); i++)
291  {
292  if (listeners_[i]->isEnabled())
293  listeners_[i]->beforeDrawTree(event);
294  }
295  }
296 
297  void fireAfterTreeEvent_(const DrawTreeEvent& event) const
298  {
299  for (unsigned int i = 0; i < listeners_.size(); i++)
300  {
301  if (listeners_[i]->isEnabled())
302  listeners_[i]->afterDrawTree(event);
303  }
304  }
305 
306  void fireBeforeNodeEvent_(const DrawINodeEvent& event) const
307  {
308  for (unsigned int i = 0; i < listeners_.size(); i++)
309  {
310  if (listeners_[i]->isEnabled())
311  listeners_[i]->beforeDrawNode(event);
312  }
313  }
314 
315  void fireAfterNodeEvent_(const DrawINodeEvent& event) const
316  {
317  for (unsigned int i = 0; i < listeners_.size(); i++)
318  {
319  if (listeners_[i]->isEnabled())
320  listeners_[i]->afterDrawNode(event);
321  }
322  }
323 
324  void fireBeforeBranchEvent_(const DrawIBranchEvent& event) const
325  {
326  for (unsigned int i = 0; i < listeners_.size(); i++)
327  {
328  if (listeners_[i]->isEnabled())
329  listeners_[i]->beforeDrawBranch(event);
330  }
331  }
332 
333  void fireAfterBranchEvent_(const DrawIBranchEvent& event) const
334  {
335  for (unsigned int i = 0; i < listeners_.size(); i++)
336  {
337  if (listeners_[i]->isEnabled())
338  listeners_[i]->afterDrawBranch(event);
339  }
340  }
341 
342 public:
344 };
345 } // end of namespace bpp.
346 #endif // BPP_PHYL_GRAPHICS_ABSTRACTTREEDRAWING_H
Partial implementation of the TreeDrawing interface.
const TreeTemplate< INode > * getTree() const
void addTreeDrawingListener(TreeDrawingListener *listener)
Add a drawing listener to this instance.
void fireBeforeBranchEvent_(const DrawIBranchEvent &event) const
TreeTemplate< INode > * getTree_()
std::vector< TreeDrawingListener * > listeners_
Point2D< double > getNodePosition(int nodeId) const
Get the position of a node.
const TreeDrawingSettings & getDisplaySettings() const
AbstractTreeDrawing(const AbstractTreeDrawing &atd)
void setDisplaySettings(const TreeDrawingSettings *tds)
Global drawing settings.
bool isNodeCollapsed(int nodeId) const
void collapseNode(int nodeId, bool yn)
Properties to draw.
bool belongsTo(const Point2D< double > &p1, const Point2D< double > &p2) const
Utilitary function, telling if a point belongs to a specified area.
void setYUnit(double yu)
Set the 'vertical' expansion unit.
int getNodeAt(const Point2D< double > &position) const
Get the node corresponding to a position on the device.
const TreeDrawingSettings * settings_
std::unique_ptr< TreeTemplate< INode > > tree_
virtual void drawAtBranch(GraphicDevice &gDevice, const INode &node, const std::string &text, double xOffset=0, double yOffset=0, short hpos=GraphicDevice::TEXT_HORIZONTAL_LEFT, short vpos=GraphicDevice::TEXT_VERTICAL_CENTER, double angle=0) const
Draw some text at a particular branch position.
const TreeTemplate< INode > * getTree_() const
void fireAfterTreeEvent_(const DrawTreeEvent &event) const
void fireBeforeNodeEvent_(const DrawINodeEvent &event) const
void setTree(const Tree *tree)
virtual void drawAtNode(GraphicDevice &gDevice, const INode &node, const std::string &text, double xOffset=0, double yOffset=0, short hpos=GraphicDevice::TEXT_HORIZONTAL_LEFT, short vpos=GraphicDevice::TEXT_VERTICAL_CENTER, double angle=0) const
Draw some text at a particular node position.
virtual void treeHasChanged()=0
Method to implement to deal with redrawing when the underlying tree has been modified.
void removeTreeDrawingListener(TreeDrawingListener *listener)
Remove a drawing listener from this instance.
void fireAfterNodeEvent_(const DrawINodeEvent &event) const
static const TreeDrawingSettings DEFAULT_SETTINGS
AbstractTreeDrawing & operator=(const AbstractTreeDrawing &atd)
void fireBeforeTreeEvent_(const DrawTreeEvent &event) const
void setXUnit(double xu)
Set the 'horizontal' expansion unit.
void fireAfterBranchEvent_(const DrawIBranchEvent &event) const
Data structure describing a plotting direction.
Definition: TreeDrawing.h:53
Event class used by TreeDrawing classes.
Definition: TreeDrawing.h:127
DrawBranchEvent & operator=(const DrawBranchEvent &dne)
Definition: TreeDrawing.h:143
Event class that uses INode object (more efficient than relying on nodes id, but less generic).
const INode * getINode() const
DrawIBranchEvent(const TreeDrawing *source, GraphicDevice *gd, const INode *node, const Cursor &cursor)
DrawIBranchEvent & operator=(const DrawIBranchEvent &dne)
DrawIBranchEvent(const DrawIBranchEvent &dne)
Event class that uses INode object (more efficient than relying on nodes id, but less generic).
DrawINodeEvent & operator=(const DrawINodeEvent &dne)
DrawINodeEvent(const TreeDrawing *source, GraphicDevice *gd, const INode *node, const Cursor &cursor)
const INode * getINode() const
DrawINodeEvent(const DrawINodeEvent &dne)
Event class used by TreeDrawing classes.
Definition: TreeDrawing.h:88
DrawNodeEvent & operator=(const DrawNodeEvent &dne)
Definition: TreeDrawing.h:104
Event class used by TreeDrawing classes.
Definition: TreeDrawing.h:171
static short TEXT_HORIZONTAL_LEFT
static short TEXT_VERTICAL_CENTER
The NodeTemplate class.
Definition: NodeTemplate.h:39
void setY(const T y)
const T & getY() const
void setX(const T x)
const T & getX() const
Interface allowing to capture drawing events.
virtual bool isAutonomous() const =0
Tells if the listener is autonomous. If so, it will never be hard-copied or deleted.
Point2D< double > & getPosition()
void setPosition(const Point2D< double > &position)
const Point2D< double > & getPosition() const
A set of options to tune the display of a TreeDrawing object.
Definition: TreeDrawing.h:27
Basal interface for tree drawing classes.
Definition: TreeDrawing.h:223
TreeDrawing * clone() const =0
The phylogenetic tree class.
Definition: TreeTemplate.h:59
Interface for phylogenetic tree objects.
Definition: Tree.h:115
Defines the basic types of data flow nodes.
NodeTemplate< TreeDrawingNodeInfo > INode