ARB
TreeDisplay.hxx
Go to the documentation of this file.
1 // =============================================================== //
2 // //
3 // File : TreeDisplay.hxx //
4 // Purpose : //
5 // //
6 // Institute of Microbiology (Technical University Munich) //
7 // http://www.arb-home.de/ //
8 // //
9 // =============================================================== //
10 
11 #ifndef TREEDISPLAY_HXX
12 #define TREEDISPLAY_HXX
13 
14 #ifndef AP_TREE_HXX
15 #include <AP_Tree.hxx>
16 #endif
17 #ifndef GROUP_HXX
18 #include <Group.hxx>
19 #endif
20 #ifndef AWT_CANVAS_HXX
21 #include <awt_canvas.hxx>
22 #endif
23 #ifndef _GLIBCXX_VECTOR
24 #include <vector>
25 #endif
26 #ifndef _GLIBCXX_MAP
27 #include <map>
28 #endif
29 
30 // Increase stacklimit to 20Mb (before was ~8Mb on my system).
31 // This was done to fix #824 (crash on display of huge trees).
32 #define TREEDISP_STACKSIZE (1024L*1024L*20) // stacksize required for tree-display
33 
34 // the possible MAX_TREEDISP_RECURSION_DEPTH corresponds with the TREEDISP_STACKSIZE:
35 #define MAX_TREEDISP_RECURSION_DEPTH 20000
36 #define TREEDISP_TRUNCATION_MESSAGE "Warning: depth limit reached => subtree not shown (use logical zoom to workaround)"
37 
38 
39 #define td_assert(cond) arb_assert(cond)
40 
41 #define AWAR_DTREE_BASELINEWIDTH "awt/dtree/baselinewidth"
42 #define AWAR_DTREE_VERICAL_DIST "awt/dtree/verticaldist"
43 #define AWAR_DTREE_BRANCH_STYLE "awt/dtree/branch_style"
44 #define AWAR_DTREE_ATTACH_SIZE "awt/dtree/attach_size"
45 #define AWAR_DTREE_ATTACH_LEN "awt/dtree/attach_len"
46 #define AWAR_DTREE_ATTACH_GROUP "awt/dtree/attach_group"
47 #define AWAR_DTREE_GROUP_DOWNSCALE "awt/dtree/downscaling"
48 #define AWAR_DTREE_GROUP_SCALE "awt/dtree/groupscaling"
49 #define AWAR_DTREE_AUTO_JUMP "awt/dtree/autojump"
50 #define AWAR_DTREE_AUTO_JUMP_TREE "awt/dtree/autojump_tree"
51 #define AWAR_DTREE_AUTO_UNFOLD "awt/dtree/auto_unfold"
52 #define AWAR_DTREE_SHOW_BRACKETS "awt/dtree/show_brackets"
53 #define AWAR_DTREE_GROUP_STYLE "awt/dtree/groupstyle"
54 #define AWAR_DTREE_GROUP_ORIENT "awt/dtree/grouporient"
55 #define AWAR_DTREE_GREY_LEVEL "awt/dtree/greylevel"
56 #define AWAR_DTREE_GROUPCOUNTMODE "awt/dtree/groupcountmode"
57 #define AWAR_DTREE_GROUPINFOPOS "awt/dtree/groupinfopos"
58 
59 #define AWAR_DTREE_BOOTSTRAP_MIN "awt/dtree/bootstrap/min"
60 #define AWAR_DTREE_BOOTSTRAP_MAX "awt/dtree/bootstrap/max"
61 #define AWAR_DTREE_BOOTSTRAP_SHOW "awt/dtree/bootstrap/show"
62 #define AWAR_DTREE_BOOTSTRAP_STYLE "awt/dtree/bootstrap/style"
63 #define AWAR_DTREE_CIRCLE_SHOW "awt/dtree/bootstrap/circle/show"
64 #define AWAR_DTREE_CIRCLE_FILL "awt/dtree/bootstrap/circle/fill"
65 #define AWAR_DTREE_CIRCLE_ELLIPSE "awt/dtree/bootstrap/circle/ellipse"
66 #define AWAR_DTREE_CIRCLE_ZOOM "awt/dtree/bootstrap/circle/zoom"
67 #define AWAR_DTREE_CIRCLE_LIMIT "awt/dtree/bootstrap/circle/limit"
68 
69 #define AWAR_DTREE_RADIAL_ZOOM_TEXT "awt/dtree/radial/zoomtext"
70 #define AWAR_DTREE_RADIAL_XPAD "awt/dtree/radial/xpadding"
71 
72 #define AWAR_DTREE_DENDRO_ZOOM_TEXT "awt/dtree/dendro/zoomtext"
73 #define AWAR_DTREE_DENDRO_XPAD "awt/dtree/dendro/xpadding"
74 
75 #define AWAR_DTREE_GROUP_MARKED_THRESHOLD "awt/dtree/markers/group_marked_threshold"
76 #define AWAR_DTREE_GROUP_PARTIALLY_MARKED_THRESHOLD "awt/dtree/markers/group_partially_marked_threshold"
77 #define AWAR_DTREE_MARKER_WIDTH "awt/dtree/markers/marker_width"
78 #define AWAR_DTREE_PARTIAL_GREYLEVEL "awt/dtree/markers/partial_greylevel"
79 
80 #define NT_BOX_WIDTH 7 // pixel
81 #define NT_DIAMOND_RADIUS 5
82 #define NT_ROOT_WIDTH 9
83 #define NT_SELECTED_WIDTH 11
84 
85 #define AWT_TREE(ntw) (ntw)->get_graphic_tree()
86 
88  AP_TREE_NORMAL, // normal tree display (dendrogram)
89  AP_TREE_RADIAL, // radial tree display
90  AP_TREE_IRS, // like AP_TREE_NORMAL, with folding line
92  AP_LIST_SIMPLE // simple display only showing name (used at startup to avoid NDS error messages)
93 };
94 
95 enum AP_tree_jump_type { // bit-values
96  AP_JUMP_KEEP_VISIBLE = 1, // automatically make selected node visible (on changes) [VALUE STORED IN AWAR!]
97  AP_JUMP_LOGICAL_UNZOOM = 2, // adapts logical zoom (if target is outside zoomed subtree)
98  AP_JUMP_FORCE_VCENTER = 4, // force vertical centering (even if visible)
99  AP_JUMP_ALLOW_HCENTER = 8, // force horizontal centering (if vertically centered); only works together with AP_JUMP_FORCE_VCENTER
100  AP_JUMP_FORCE_HCENTER = 16, // force horizontal centering
101  AP_JUMP_BE_VERBOOSE = 32, // tell why nothing happened etc.
102  AP_JUMP_AUTO_UNFOLD = 64, // temporarily auto-unfold folded target node
103 
104  // convenience defs:
105  AP_DONT_JUMP = 0, // [VALUE STORED IN AWAR!]
108 
110 };
111 
117 };
118 
120  CL_NODE = 1,
126 };
127 
128 inline bool is_list_style(AP_tree_display_style style) { return style == AP_LIST_NDS || style == AP_LIST_SIMPLE; }
129 inline bool is_tree_style(AP_tree_display_style style) { return !is_list_style(style); }
130 
131 class NDS_Labeler;
133 
135  double ascent;
136  double descent;
137  double height;
138  double width;
139 
140  void init(const AW_font_limits& font_limits, double factor) {
141  ascent = font_limits.ascent*factor;
142  descent = font_limits.descent*factor;
143  height = font_limits.get_height()*factor;
144  width = font_limits.width*factor;
145  }
146 };
147 
153 };
154 
156 
158  double y_branch; // ypos of branch to subtree
159  double y_top; // top ypos of whole subtree
160  double y_bot; // bottom ypos of whole subtree
161  double x_right; // rightmost xpos of whole subtree
162 
163  void combine(const DendroSubtreeLimits& other) {
164  y_top = std::min(y_top, other.y_top);
165  y_bot = std::max(y_bot, other.y_bot);
166  x_right = std::max(x_right, other.x_right);
167  }
168 };
169 
174  virtual ~AWT_command_data() {}
175 };
176 
179  EXPAND_MARKED = 1, // do not collapse groups containing marked species
180  COLLAPSE_TERMINAL = 2, // do not collapse groups with subgroups
182  EXPAND_COLOR = 8, // do not collapse groups containing species with color == parameter 'color_group' (or any color if 'color_group' is -1)
183  EXPAND_ZOMBIES = 16, // do not collapse groups containing zombies
184  EXPAND_UNMARKED = 32, // do not collapse groups containing unmarked species
185 };
186 
187 class NodeMarkers {
188  // represents markers at a node (species or group)
189 
190  int nodeSize; // number of species in group (or 1)
191  std::vector<int> mark; // how often each marker is set in group
192 public:
193  NodeMarkers() {} // default for cache
194  explicit NodeMarkers(int numMarks)
195  : nodeSize(0),
196  mark(numMarks, 0)
197  {}
198 
199  void incMarker(size_t markerIdx) {
200  td_assert(markerIdx<mark.size());
201  mark[markerIdx]++;
202  }
203  int markerCount(size_t markerIdx) const {
204  td_assert(markerIdx<mark.size());
205  return mark[markerIdx];
206  }
207 
208  void incNodeSize() { nodeSize++; }
209  int getNodeSize() const { return nodeSize; }
210 
211  double getMarkRate(size_t markerIdx) const { return markerCount(markerIdx) / double(getNodeSize()); }
212 
213  void add(const NodeMarkers& other) {
214  size_t size = mark.size();
215  td_assert(size == other.mark.size());
216  for (size_t i = 0; i<size; ++i) {
217  mark[i] += other.mark[i];
218  }
219  nodeSize += other.nodeSize;
220  }
221 };
222 
224  // defines which markers shall be displayed
225 
226  typedef std::map<const AP_tree*,NodeMarkers> GroupMarkerCache;
227 
228  GroupMarkerCache cache;
229  int numMarkers;
230 
231 public:
232  MarkerDisplay(int numMarkers_)
233  : numMarkers(numMarkers_)
234  {
235  td_assert(numMarkers>0);
236  }
237  virtual ~MarkerDisplay() {}
238 
239  virtual const char *get_marker_name(int markerIdx) const = 0;
240  virtual void retrieve_marker_state(const char *speciesName, NodeMarkers& matches) = 0;
241  virtual void handle_click(int markerIdx, AW_MouseButton button, AWT_graphic_exports& exports) = 0;
242 
243  const NodeMarkers *read_cache(const AP_tree *at) const {
244  GroupMarkerCache::const_iterator found = cache.find(at);
245  return found == cache.end() ? NULp : &found->second;
246  }
247  void write_cache(const AP_tree *at, const NodeMarkers& markers) { cache[at] = markers; }
248  void flush_cache() { cache.erase(cache.begin(), cache.end()); }
249 #if defined(ASSERTION_USED)
250  bool cache_is_flushed() const { return cache.empty(); }
251 #endif
252 
253  int size() const { return numMarkers; }
254 };
255 
256 struct GroupInfo {
257  const char *name;
258  const char *count;
259  unsigned name_len;
260  unsigned count_len;
261 };
262 
264  GI_COMBINED, // only sets GroupInfo::name (will contain "name (count)" or only "name" if counters disabled)
265  GI_SEPARATED, // set GroupInfo::name and GroupInfo::count (to "name" and "count")
266  GI_SEPARATED_PARENTIZED, // like GI_SEPARATED, but GroupInfo::count will be "(count)"
267 };
268 
270  GIP_SEPARATED, // name attached, count overlayed (=old hardcoded default for AP_TREE_NORMAL and AP_TREE_IRS)
271  GIP_ATTACHED, // "name (count)" attached "next to" group (=old hardcoded default for AP_TREE_RADIAL)
272  GIP_OVERLAYED, // "name (count)" overlayed with group polygon
273 };
274 
276  GCM_NONE, // do not show group count (=old hardcoded default for AP_TREE_RADIAL)
277  GCM_MEMBERS, // show number of group members (=old hardcoded default for AP_TREE_NORMAL and AP_TREE_IRS)
278  GCM_MARKED, // show number of marked group members (show nothing if none marked)
279  GCM_BOTH, // show "marked/members" (or "members" if none marked)
280  GCM_PERCENT, // show percent of marked group members (show nothing if none marked)
281  GCM_BOTH_PC, // show "percent/members" (or "members" if none marked)
282 };
283 
285  BS_RECTANGULAR, // traditional rectangular branches
286  BS_DIAGONAL, // diagonal branches (directly from fathers to sons attach point)
287 };
288 
290  GS_TRAPEZE, // traditional style
292 };
293 
295  GO_TOP, // long clade side at top
296  GO_BOTTOM, // long clade side at bottom
297  GO_INTERIOR, // long clade side towards center of subtree
298  GO_EXTERIOR, // long clade side towards margin of subtree
299 };
300 
301 class AWT_graphic_tree;
302 DECLARE_CBTYPE_FVV_AND_BUILDERS(GraphicTreeCallback, void, AWT_graphic_tree*); // generates makeGraphicTreeCallback
303 
304 class PaintedNode {
305  AW::Position pos;
306  AP_tree *node;
307 public:
308  PaintedNode() : pos(AW::Origin), node(NULp) {}
309  PaintedNode(const PaintedNode& other) : pos(other.pos), node(other.node) {}
310  PaintedNode(const AW::Position& p, AP_tree *n) : pos(p), node(n) {}
313 
314  bool was_displayed() const { return node || are_distinct(AW::Origin, pos); }
315 
316  const AW::Position& get_pos() const { return pos; }
317  AP_tree *get_node() const { return node; } // NULp in list-mode or if got no tree
318 };
319 
324 };
325 
329 
330  int bootstrap_min; // minimum shown bootstrap (lower values are hidden)
331  int bootstrap_max; // maximum shown bootstrap (higher values are hidden)
332 
334 
337  float fill_level;
338  bool elipsoid;
339 
340  bool show_100_if_empty; // automatically add 100% at branches w/o bootstraps (last loaded state contains bootstraps!)
341 
342  float zoom_factor;
343  float max_radius;
344 
346 
347  BootstrapConfig();
348 
349  void display_remark(AW_device *device, const char *remark, const AW::Position& center, double blen, double bdist, const AW::Position& textpos, AW_pos alignment) const;
350  void display_node_remark(AW_device *device, const AP_tree *at, const AW::Position& center, double blen, double bdist, AW::RoughDirection textArea) const;
351 
353  show_100_if_empty = troot->has_bootstrap();
354  }
355 
356  bool shall_show_remark_for(const TreeNode *node) const {
357  return !node->is_leaf() && (show_100_if_empty || node->get_remark_ptr().isSet());
358  }
359 };
360 
361 class AWT_graphic_tree : public AWT_graphic, virtual Noncopyable {
362  char *species_name;
363  Group selected_group;
364 
365  PaintedNode selSpec; // is set while tree display gets refreshed
366  PaintedNode selGroup; // is set while tree display gets refreshed // @@@ no need to store node; store rectangle area instead of position
367 
368  int baselinewidth;
369 
370  BootstrapConfig bconf;
371 
372  int zombies; // # of zombies during last load()
373  int duplicates; // # of duplicates during last load()
374 
375  AP_tree *tree_proto;
376 
377  bool show_brackets;
378 
379  bool link_to_database; // link on load?
380 
381  GroupStyle group_style;
382  GroupOrientation group_orientation;
383 
384  double list_tree_ruler_y;
385  double irs_tree_ruler_scale_factor;
386  double attach_size; // 1.0 = at bigger subtree ; 0.0 = centered; -1.0 = at smaller subtree (trad.)
387  double attach_len; // 1.0 = at longer branch; 0.0 = centered (trad.); -1.0 = at shorter branch
388  double attach_group; // 1.0 = at longer side; 0.5 = centered (trad.); 0.0 = at shorter side (of group polygon)
389 
390  AWT_scaled_font_limits scaled_font;
391 
392  double scaled_branch_distance; // vertical distance between branches (may be extra-scaled in options)
393 
394  AW_grey_level group_greylevel;
395  AW_grey_level marker_greylevel;
396 
397  AW_device *disp_device; // device for recursive functions
398 
399  const AW_bitset line_filter, vert_line_filter, mark_filter, group_bracket_filter;
400  const AW_bitset leaf_text_filter, group_text_filter, other_text_filter;
401  const AW_bitset ruler_filter, root_filter, marker_filter;
402 
403  GroupInfoPosition group_info_pos;
404  GroupCountMode group_count_mode;
405  BranchStyle branch_style;
406 
407  MarkerDisplay *display_markers;
408  struct {
409  double marked;
411  } groupThreshold;
412 
413  AD_map_viewer_cb map_viewer_cb;
414  AWT_command_data *cmd_data;
415 
416  AP_tree_root *tree_static;
417  AP_tree *displayed_root; // root node of shown (sub-)tree; differs from real root if tree is zoomed logically
418 
419  GraphicTreeCallback tree_changed_cb;
420  static GraphicTreeCallback group_changed_cb;
421 
422  class AP_tree_folding *autoUnfolded;
423 
424  AW_root *aw_root;
425  GBDATA *gb_main;
426 
427  AP_tree_display_style tree_style;
428  bool nds_only_marked; // true -> display only marked species (only for list-styles)
429 
430  AW_pos paint_irs_sub_tree(AP_tree *node, AW_pos x_offset, const NDS_Labeler& labeler); // returns y pos
431  void unload();
432 
433  // functions to compute displayinformation
434 
435  void show_dendrogram(AP_tree *at, AW::Position& pen, DendroSubtreeLimits& limits, const NDS_Labeler& labeler);
436  void show_radial_tree(AP_tree *at, const AW::Position& base, const AW::Position& tip, const AW::Angle& orientation, const double tree_spread, const NDS_Labeler& labeler);
437  void show_nds_list(GBDATA * gb_main, bool use_nds, const NDS_Labeler& labeler);
438  void show_irs_tree(AP_tree *at, double height, const NDS_Labeler& labeler);
439 
440  void summarizeGroupMarkers(AP_tree *at, NodeMarkers& markers);
441  void drawMarker(const class MarkerPosition& marker, const bool partial, const int midx);
442  void detectAndDrawMarkers(AP_tree *at, double y1, double y2);
443  void drawMarkerNames(AW::Position& Pen);
444 
445  void pixel_box(int gc, const AW::Position& pos, int pixel_width, AW::FillStyle filled);
446 
447  AP_tree *find_selected_node() const;
448  AP_tree *find_selected_group();
449 
450  void toggle_folding_at(AP_tree *at, bool force_jump);
451 
452  const GroupInfo& get_group_info(AP_tree *at, GroupInfoMode mode, bool swap, const NDS_Labeler& labeler) const;
453 
454  bool handle_cursor(AW_key_code kcode, AW_key_mod mod);
455  void handle_key(AW_device *device, AWT_graphic_event& event);
456 
457  GB_ERROR create_group(AP_tree * at) __ATTR__USERESULT;
458 
459 protected:
460  group_scaling groupScale; // scaling for folded groups
461 
462  void store_command_data(AWT_command_data *new_cmd_data) {
463  delete cmd_data;
464  cmd_data = new_cmd_data;
465  }
466  AWT_command_data *get_command_data() { return cmd_data; }
467 
468 public:
469  AWT_graphic_tree(AW_root *aw_root, GBDATA *gb_main, AD_map_viewer_cb map_viewer_cb);
471 
472  void filled_box(int gc, const AW::Position& pos, int pixel_width) { pixel_box(gc, pos, pixel_width, AW::FillStyle::SOLID); }
473  void empty_box(int gc, const AW::Position& pos, int pixel_width) { pixel_box(gc, pos, pixel_width, AW::FillStyle::EMPTY); }
474  void diamond(int gc, const AW::Position& pos, int pixel_radius);
475 
476  const char *ruler_awar(const char *name);
477 
479  disp_device->set_line_attributes(at->gr.gc, at->get_linewidth()+baselinewidth, AW_SOLID);
480  }
481 
482  virtual void read_tree_settings();
484  AP_tree *root = get_root_node();
485  if (root) {
487  root->compute_tree();
488  }
489  }
491 
492  int draw_branch_line(int gc, const AW::Position& root, const AW::Position& leaf, AW_bitset filter) {
493  const AW_click_cd *old = disp_device->get_click_cd();
494  td_assert(old && old->get_cd1() && old->get_cd2() == CL_NODE); // cd1 should be the node
495 
496  AW_click_cd branch(disp_device, old->get_cd1(), CL_BRANCH);
497  return disp_device->line(gc, root, leaf, filter);
498  }
499 
501 
502  virtual AP_tree_root *create_tree_root(AliView *aliview, AP_sequence *seq_prototype, bool insert_delete_cbs);
503 
504  AW_root *get_root() const { return aw_root; }
505  GBDATA *get_gbmain() const { return gb_main; }
506 
507  AP_tree_root *get_tree_root() { return tree_static; }
508 
509  AP_tree *get_root_node() { return tree_static ? tree_static->get_root_node() : NULp; }
510  const AP_tree *get_root_node() const { return const_cast<AWT_graphic_tree*>(this)->get_root_node(); }
511 
512  AP_tree *get_logical_root() { return displayed_root; }
513  const AP_tree *get_logical_root() const { return displayed_root; }
514 
515  bool is_logically_zoomed() { return displayed_root != get_root_node(); }
517  displayed_root = node;
518  tree_changed_cb(this);
519  }
520 
521  void init(AliView *aliview, AP_sequence *seq_prototype, bool link_to_database_, bool insert_delete_cbs);
523 
524  void show(AW_device *device) OVERRIDE;
525  const AW::Position& get_cursor() const { return selSpec.get_pos(); }
526  const AW::Position& get_group_cursor() const { return selGroup.get_pos(); }
527 
528  void handle_command(AW_device *device, AWT_graphic_event& event) OVERRIDE;
529 
530  long mark_species_in_tree(AP_tree *at, int mark);
531  long mark_species_in_tree_that(AP_tree *at, int mark, bool (*condition)(GBDATA*, void*), void *cd);
532 
533  void mark_species_in_rest_of_tree(AP_tree *at, int mark);
534 
535  bool tree_has_marks(AP_tree *at);
536  bool rest_tree_has_marks(AP_tree *at);
537 
538  void detect_group_state(AP_tree *at, AWT_graphic_tree_group_state *state, AP_tree *skip_this_son);
539 
540  bool group_tree(AP_tree *at, CollapseMode mode, int color_group);
541  void group_rest_tree(AP_tree *at, CollapseMode mode, int color_group);
542  void reorderTree(TreeOrder mode);
543  void toggle_group(AP_tree * at);
544 
545  GB_ERROR load_from_DB(GBDATA *gb_main, const char *name) FINAL_OVERRIDE __ATTR__USERESULT;
546  GB_ERROR save_to_DB(GBDATA *gb_main, const char *name) FINAL_OVERRIDE __ATTR__USERESULT;
549 
550  void fast_sync_changed_folding(AP_tree *parent_of_all_changes); // use carefully
551 
553  AP_tree_display_style get_tree_style() const { return tree_style; }
554 
555  double get_irs_tree_ruler_scale_factor() const { return irs_tree_ruler_scale_factor; }
556  void show_ruler(AW_device *device, int gc);
557  void get_zombies_and_duplicates(int& zomb, int& dups) const { zomb = zombies; dups = duplicates; }
558 
560  delete display_markers;
561  display_markers = NULp;
562  }
563  void set_marker_display(MarkerDisplay *display) { // takes ownership of 'display'
565  display_markers = display;
566  }
567  MarkerDisplay *get_marker_display() { return display_markers; }
568 
569  void install_tree_changed_callback(const GraphicTreeCallback& gtcb);
571 
572  static void install_group_changed_callback(const GraphicTreeCallback& gccb) {
573  group_changed_cb = gccb;
574  }
575 
576  void auto_unfold(AP_tree *want_visible);
577  void forget_auto_unfolded();
578 
579 private:
580  void select_group(const Group& group) {
581  if (selected_group != group) {
582  selected_group = group;
583  group_changed_cb(this);
584  }
585  }
586 public:
587  void select_group(AP_tree *node) { // select + locate
588  td_assert(node && node->is_clade());
589  select_group(Group(node));
590  }
591  void select_group(GBDATA *gb_group) { // unlocated select (or deselect if called with NULp)
592  select_group(gb_group ? Group(gb_group) : Group());
593  }
594  void deselect_group() {
595  select_group(Group());
596  }
597  const Group& get_selected_group() const {
598  return selected_group;
599  }
601  AP_tree *node = NULp;
602  if (selected_group.is_valid()) {
603  if (selected_group.locate(in_subtree)) {
604  node = selected_group.get_node();
605  }
606  }
607  return node;
608  }
610  // has to be called whenever the keeled-state of a group may change
611  selected_group.dislocate();
612  }
613 
614 #if defined(UNIT_TESTS) // UT_DIFF
615  friend class fake_AWT_graphic_tree;
616 #endif
618 };
621 
634  AP_tree *tree_node;
635  GBDATA *gb_species;
636 
637  bool ruler;
638  bool branch;
639  int markerflag; // = markerindex + 1
640 
641  const AW_clicked_element *elem;
642 
643  void init() {
644  tree_node = NULp;
645  gb_species = NULp;
646  ruler = false;
647  branch = false;
648  markerflag = 0;
649  }
650 
651  void identify(AWT_graphic_tree *agt) {
652  init();
653  if (elem && elem->does_exist()) {
654  ClickedType what = (ClickedType)elem->cd2();
655 
656  switch (what) {
657  case CL_SPECIES:
658  gb_species = (GBDATA*)elem->cd1();
659  td_assert(gb_species);
660  break;
661 
662  case CL_RULER:
663  ruler = !elem->cd1();
664  break;
665 
666  case CL_FLAG:
667  markerflag = elem->cd1()+1;
668  break;
669 
670  case CL_BRANCH:
671  branch = true;
672  // fall-through!
673  case CL_NODE:
674  tree_node = (AP_tree*)elem->cd1();
675  break;
676 
677  case CL_ROOTNODE:
678  if (agt) tree_node = agt->get_root_node();
679  break;
680 
681 #if defined(DEBUG)
682  default:
683  td_assert(0); // unknown element type
684 #endif
685  }
686  }
687  else { // use whole tree if mouse does not point to a subtree
688  tree_node = agt ? agt->get_root_node() : NULp;
689  }
690  td_assert(implicated(branch, tree_node));
691  }
692 
693 public:
694 
695  ClickedTarget(AWT_graphic_tree *agt, const AW_clicked_element *clicked) : elem(clicked) {
696  // uses root of tree as target, when a position outside of the tree is selected
697  // (e.g. used for key-commands)
698  identify(agt);
699  }
700  ClickedTarget(const AW_clicked_element *clicked) : elem(clicked) {
701  // accept only normal branches as targets
702  identify(NULp);
703  }
704 
705  const AW_clicked_element *element() const { return elem; }
706  AP_tree *node() const { return tree_node; }
707  GBDATA *species() const { return gb_species; }
708  int get_markerindex() const { return markerflag-1; }
709 
710  bool is_text() const { return elem && elem->is_text(); }
711  bool is_line() const { return elem && elem->is_line(); }
712  bool is_branch() const { return branch; }
713  bool is_ruler() const { return ruler; }
714  bool is_marker() const { return markerflag; }
715 
716  double get_rel_attach() const {
717  // return [0..1] according to exact position where element is dropped
718  if (is_line() && (is_branch() || ruler)) return elem->get_rel_pos();
719  return 0.5; // act like "drop on branch-center"
720  }
721 };
722 
723 class TREE_canvas : public AWT_canvas { // derived from Noncopyable
724  AW_awar *awar_tree; // awar containing name of displayed tree
725  int index; // unique index [0..MAX_NT_WINDOWS-1]
726 
727  static int count;
728 
729 public:
730  TREE_canvas(GBDATA *gb_main_, AW_window *aww_, const char *gc_base_name_, AWT_graphic *gfx_, AW_awar *awar_tree_) :
731  AWT_canvas(gb_main_, aww_, gc_base_name_, gfx_),
732  awar_tree(awar_tree_),
733  index(count++)
734  {}
735 
738 
740  user_data = cd;
741  }
742 
744  AW_awar *get_awar_tree() const { return awar_tree; }
745  int get_index() const { return index; }
746 };
747 
748 
749 void TREE_create_awars(AW_root *aw_root, AW_default db);
753 
754 AWT_graphic_tree *NT_generate_tree(AW_root *root, GBDATA *gb_main, AD_map_viewer_cb map_viewer_cb);
755 
756 #else
757 #error TreeDisplay.hxx included twice
758 #endif // TREEDISPLAY_HXX
AP_tree * get_node() const
Definition: Group.hxx:54
void reorderTree(TreeOrder mode)
bool does_exist() const
AWT_graphic_tree * get_graphic_tree() const
void combine(const DendroSubtreeLimits &other)
const char * GB_ERROR
Definition: arb_core.h:25
void set_marker_display(MarkerDisplay *display)
AWT_graphic_tree * NT_generate_tree(AW_root *root, GBDATA *gb_main, AD_map_viewer_cb map_viewer_cb)
long AW_bitset
Definition: aw_base.hxx:44
int getNodeSize() const
int get_markerindex() const
GB_TYPES type
AP_tree * node() const
AP_tree * get_logical_root()
bool warn_inappropriate_mode(AWT_COMMAND_MODE mode)
MarkerDisplay(int numMarkers_)
AP_tree_root * get_tree_root()
virtual AP_tree_root * create_tree_root(AliView *aliview, AP_sequence *seq_prototype, bool insert_delete_cbs)
AWT_COMMAND_MODE
Definition: awt_canvas.hxx:25
GB_ERROR load_from_DB(GBDATA *gb_main, const char *name) FINAL_OVERRIDE __ATTR__USERESULT
short get_height() const
#define implicated(hypothesis, conclusion)
Definition: arb_assert.h:289
AP_tree_jump_reason
void group_rest_tree(AP_tree *at, CollapseMode mode, int color_group)
void set_logical_root_to(AP_tree *node)
void check_for_DB_update(GBDATA *gb_main) FINAL_OVERRIDE
void set_line_attributes(int gc, short width, AW_linestyle style)
Definition: AW_device.cxx:465
AP_tree_jump_type
Definition: TreeDisplay.hxx:95
const AW_bitset circle_filter
void detect_group_state(AP_tree *at, AWT_graphic_tree_group_state *state, AP_tree *skip_this_son)
const char * name
void store_command_data(AWT_command_data *new_cmd_data)
ClickedType
double get_irs_tree_ruler_scale_factor() const
void select_group(AP_tree *node)
bool is_clade() const
Definition: TreeNode.h:480
long mark_species_in_tree_that(AP_tree *at, int mark, bool(*condition)(GBDATA *, void *), void *cd)
GB_ERROR save_to_DB(GBDATA *gb_main, const char *name) FINAL_OVERRIDE __ATTR__USERESULT
DECLARE_ASSIGNMENT_OPERATOR(PaintedNode)
void notify_synchronized(GBDATA *gb_main) FINAL_OVERRIDE
AP_tree * get_node() const
AD_MAP_VIEWER_TYPE
virtual ~AWT_command_data()
void forget_auto_unfolded()
AP_tree_members gr
Definition: AP_Tree.hxx:214
void dislocate_selected_group()
long mark_species_in_tree(AP_tree *at, int mark)
bool tree_has_marks(AP_tree *at)
GBDATA * get_gbmain() const
bool is_logically_zoomed()
double getMarkRate(size_t markerIdx) const
const AP_tree * get_root_node() const
const char * count
void add(const NodeMarkers &other)
bool is_valid() const
Definition: Group.hxx:48
ClickedTarget(AWT_graphic_tree *agt, const AW_clicked_element *clicked)
DECLARE_CBTYPE_FVV_AND_BUILDERS(GraphicTreeCallback, void, AWT_graphic_tree *)
void(* screen_update_callback)(AWT_canvas *, AW_CL cd)
Definition: awt_canvas.hxx:296
AW_gc_manager * init_devices(AW_window *, AW_device *, AWT_canvas *ntw) OVERRIDE
Definition: TreeDisplay.cxx:71
void dislocate() const
Definition: Group.hxx:64
GroupOrientation
#define cb(action)
void incMarker(size_t markerIdx)
#define DOWNCAST(totype, expr)
Definition: downcast.h:141
#define FINAL_OVERRIDE
Definition: cxxforward.h:114
BootstrapStyle style
RoughDirection
void diamond(int gc, const AW::Position &pos, int pixel_radius)
void flush_cache()
void(* AD_map_viewer_cb)(GBDATA *gbd, AD_MAP_VIEWER_TYPE type)
bool is_line() const
const AW::Position & get_pos() const
const NodeMarkers * read_cache(const AP_tree *at) const
void set_tree_style(AP_tree_display_style style, AWT_canvas *ntw)
void auto_unfold(AP_tree *want_visible)
MARK_NONFINAL_FUNCTION(AWT_graphic_tree, AP_tree_root *, create_tree_root,(AliView *, AP_sequence *, bool), NULp)
NodeMarkers(int numMarks)
bool is_marker() const
static void install_group_changed_callback(const GraphicTreeCallback &gccb)
double AW_pos
Definition: aw_base.hxx:29
virtual void read_tree_settings()
void compute_tree() FINAL_OVERRIDE
Definition: AP_Tree.cxx:876
virtual const char * get_marker_name(int markerIdx) const =0
PaintedNode(const AW::Position &p, AP_tree *n)
int get_linewidth() const
Definition: AP_Tree.hxx:326
TREE_canvas(GBDATA *gb_main_, AW_window *aww_, const char *gc_base_name_, AWT_graphic *gfx_, AW_awar *awar_tree_)
AW_MouseButton
Definition: aw_window.hxx:70
AW_root * get_root() const
unsigned name_len
void get_zombies_and_duplicates(int &zomb, int &dups) const
void hide_marker_display()
MARK_NONFINAL_CLASS(AWT_graphic_tree)
void incNodeSize()
virtual ~MarkerDisplay()
static int group[MAXN+1]
Definition: ClustalV.cxx:65
MarkerDisplay * get_marker_display()
AW_CL cd1() const
AW_CL get_cd1() const
Definition: aw_device.hxx:347
bool are_distinct(const Position &p1, const Position &p2)
bool line(int gc, const AW::LineVector &Line, AW_bitset filteri=AW_ALL_DEVICES_SCALED)
Definition: aw_device.hxx:430
AW_CL get_cd2() const
Definition: aw_device.hxx:348
bool rest_tree_has_marks(AP_tree *at)
void at_screen_update_call(screen_update_callback cb, AW_CL cd)
CONSTEXPR_INLINE_Cxx14 void swap(unsigned char &c1, unsigned char &c2)
Definition: ad_io_inline.h:19
screen_update_callback announce_update_cb
Definition: awt_canvas.hxx:304
double scaled_remark_ascend
group_scaling groupScale
CollapseMode
void handle_command(AW_device *device, AWT_graphic_event &event) OVERRIDE
~AWT_graphic_tree() OVERRIDE
AWT_command_data * get_command_data()
AW_window * TREE_create_settings_window(AW_root *aw_root)
int size() const
AP_tree_display_style get_tree_style() const
void uninstall_tree_changed_callback()
void fast_sync_changed_folding(AP_tree *parent_of_all_changes)
AW_window * TREE_create_marker_settings_window(AW_root *root)
virtual void retrieve_marker_state(const char *speciesName, NodeMarkers &matches)=0
GBDATA * species() const
void toggle_group(AP_tree *at)
float AW_grey_level
Definition: aw_base.hxx:46
void show_ruler(AW_device *device, int gc)
ClickedTarget(const AW_clicked_element *clicked)
int draw_branch_line(int gc, const AW::Position &root, const AW::Position &leaf, AW_bitset filter)
bool is_ruler() const
bool is_list_style(AP_tree_display_style style)
int get_index() const
bool group_tree(AP_tree *at, CollapseMode mode, int color_group)
#define td_assert(cond)
Definition: TreeDisplay.hxx:39
AW_CL user_data
Definition: awt_canvas.hxx:305
void write_cache(const AP_tree *at, const NodeMarkers &markers)
void display_node_remark(AW_device *device, const AP_tree *at, const AW::Position &center, double blen, double bdist, AW::RoughDirection textArea) const
bool has_bootstrap() const
Definition: TreeNode.h:101
AWT_graphic * gfx
Definition: awt_canvas.hxx:339
const AW::Position & get_group_cursor() const
const Group & get_selected_group() const
bool locate(AP_tree *subtree) const
Definition: Group.cxx:29
bool is_leaf() const
Definition: TreeNode.h:211
BootstrapStyle
AW_CL cd2() const
void display_remark(AW_device *device, const char *remark, const AW::Position &center, double blen, double bdist, const AW::Position &textpos, AW_pos alignment) const
long AW_CL
Definition: cb.h:21
int markerCount(size_t markerIdx) const
double get_rel_pos() const
BranchStyle
AW_key_code
Definition: aw_keysym.hxx:14
void TREE_create_awars(AW_root *aw_root, AW_default db)
GroupInfoMode
#define OVERRIDE
Definition: cxxforward.h:112
void select_group(GBDATA *gb_group)
GroupStyle
unsigned count_len
AP_tree_display_style
Definition: TreeDisplay.hxx:87
#define __ATTR__USERESULT
Definition: attributes.h:58
void TREE_install_update_callbacks(TREE_canvas *ntw)
double get_rel_attach() const
void filled_box(int gc, const AW::Position &pos, int pixel_width)
AP_tree * locate_selected_group(AP_tree *in_subtree)
bool is_text() const
const AW::Position & get_cursor() const
void set_line_attributes_for(AP_tree *at) const
AP_tree * get_root_node()
static void tree_changed_cb(AW_root *, BranchWindow *bw)
TreeOrder
Definition: TreeNode.h:35
const AW_bitset text_filter
PaintedNode(const PaintedNode &other)
const char * ruler_awar(const char *name)
bool was_displayed() const
#define NULp
Definition: cxxforward.h:116
AWT_graphic_tree(AW_root *aw_root, GBDATA *gb_main, AD_map_viewer_cb map_viewer_cb)
AW_key_mod
Definition: aw_keysym.hxx:46
GroupCountMode
GroupInfoPosition
virtual void handle_click(int markerIdx, AW_MouseButton button, AWT_graphic_exports &exports)=0
bool is_tree_style(AP_tree_display_style style)
void init(AliView *aliview, AP_sequence *seq_prototype, bool link_to_database_, bool insert_delete_cbs)
bool is_branch() const
void install_tree_changed_callback(const GraphicTreeCallback &gtcb)
bool shall_show_remark_for(const TreeNode *node) const
void update_empty_branch_behavior(const TreeRoot *troot)
GBDATA * gb_main
Definition: adname.cxx:32
const AP_tree * get_logical_root() const
void empty_box(int gc, const AW::Position &pos, int pixel_width)
void update_structure() FINAL_OVERRIDE
const SmartCharPtr & get_remark_ptr() const
Definition: TreeNode.h:311
#define min(a, b)
Definition: f2c.h:153
PREPARE_MARK_NONFINAL_CLASS(AWT_graphic_tree)
const Position Origin
uint32_t gc
Definition: AP_Tree.hxx:152
const AW_clicked_element * element() const
AW_awar * get_awar_tree() const
bool cache_is_flushed() const
const AW_click_cd * get_click_cd() const
Definition: aw_device.hxx:382
void show(AW_device *device) OVERRIDE
Definition: Group.hxx:20
void init(const AW_font_limits &font_limits, double factor)
void mark_species_in_rest_of_tree(AP_tree *at, int mark)
Definition: cache.h:31
void apply_zoom_settings_for_treetype(AWT_canvas *ntw)
#define max(a, b)
Definition: f2c.h:154