source: tags/ms_r16q4/SL/TREEDISP/TreeDisplay.hxx

Last change on this file was 15374, checked in by westram, 7 years ago
  • reintegrates 'tree' into 'trunk'
    • implements #578
    • tree display
      • new options: triangle, attach points
      • optimized placement: folded group names, bootstrap values
      • split config window (too big)
  • adds: log:branches/tree@15347:15373
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.7 KB
Line 
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 AWT_CANVAS_HXX
18#include <awt_canvas.hxx>
19#endif
20#ifndef _GLIBCXX_VECTOR
21#include <vector>
22#endif
23#ifndef _GLIBCXX_MAP
24#include <map>
25#endif
26
27
28#define td_assert(cond) arb_assert(cond)
29
30#define AWAR_DTREE_BASELINEWIDTH   "awt/dtree/baselinewidth"
31#define AWAR_DTREE_VERICAL_DIST    "awt/dtree/verticaldist"
32#define AWAR_DTREE_BRANCH_STYLE    "awt/dtree/branch_style"
33#define AWAR_DTREE_ATTACH_SIZE     "awt/dtree/attach_size"
34#define AWAR_DTREE_ATTACH_LEN      "awt/dtree/attach_len"
35#define AWAR_DTREE_ATTACH_GROUP    "awt/dtree/attach_group"
36#define AWAR_DTREE_GROUP_DOWNSCALE "awt/dtree/downscaling"
37#define AWAR_DTREE_GROUP_SCALE     "awt/dtree/groupscaling"
38#define AWAR_DTREE_AUTO_JUMP       "awt/dtree/autojump"
39#define AWAR_DTREE_AUTO_JUMP_TREE  "awt/dtree/autojump_tree"
40#define AWAR_DTREE_SHOW_CIRCLE     "awt/dtree/show_circle"
41#define AWAR_DTREE_SHOW_BRACKETS   "awt/dtree/show_brackets"
42#define AWAR_DTREE_CIRCLE_ZOOM     "awt/dtree/circle_zoom"
43#define AWAR_DTREE_CIRCLE_MAX_SIZE "awt/dtree/max_size"
44#define AWAR_DTREE_USE_ELLIPSE     "awt/dtree/ellipse"
45#define AWAR_DTREE_GROUP_STYLE     "awt/dtree/groupstyle"
46#define AWAR_DTREE_GROUP_ORIENT    "awt/dtree/grouporient"
47#define AWAR_DTREE_GREY_LEVEL      "awt/dtree/greylevel"
48#define AWAR_DTREE_GROUPCOUNTMODE  "awt/dtree/groupcountmode"
49#define AWAR_DTREE_GROUPINFOPOS    "awt/dtree/groupinfopos"
50#define AWAR_DTREE_BOOTSTRAP_MIN   "awt/dtree/bootstrap/inner/min"
51
52#define AWAR_DTREE_RADIAL_ZOOM_TEXT "awt/dtree/radial/zoomtext"
53#define AWAR_DTREE_RADIAL_XPAD      "awt/dtree/radial/xpadding"
54
55#define AWAR_DTREE_DENDRO_ZOOM_TEXT "awt/dtree/dendro/zoomtext"
56#define AWAR_DTREE_DENDRO_XPAD      "awt/dtree/dendro/xpadding"
57
58#define AWAR_DTREE_GROUP_MARKED_THRESHOLD           "awt/dtree/markers/group_marked_threshold"
59#define AWAR_DTREE_GROUP_PARTIALLY_MARKED_THRESHOLD "awt/dtree/markers/group_partially_marked_threshold"
60#define AWAR_DTREE_MARKER_WIDTH                     "awt/dtree/markers/marker_width"
61#define AWAR_DTREE_PARTIAL_GREYLEVEL                "awt/dtree/markers/partial_greylevel"
62
63#define NT_BOX_WIDTH      7   // pixel
64#define NT_DIAMOND_RADIUS 5
65#define NT_ROOT_WIDTH     9
66#define NT_SELECTED_WIDTH 11
67
68#define AWT_TREE(ntw) DOWNCAST(AWT_graphic_tree*, (ntw)->gfx)
69
70
71enum AP_tree_display_style {
72    AP_TREE_NORMAL, // normal tree display (dendrogram)
73    AP_TREE_RADIAL, // radial tree display
74    AP_TREE_IRS, // like AP_TREE_NORMAL, with folding line
75    AP_LIST_NDS,
76    AP_LIST_SIMPLE // simple display only showing name (used at startup to avoid NDS error messages)
77};
78
79enum AP_tree_jump_type { // bit-values
80    AP_JUMP_KEEP_VISIBLE  = 1,  // automatically make selected node visible (on changes)
81    AP_JUMP_UNFOLD_GROUPS = 2,  //
82    AP_JUMP_FORCE_VCENTER = 4,  // force vertical centering (even if visible)
83    AP_JUMP_ALLOW_HCENTER = 8,  // force horizontal centering (if vertically centered); only works together with AP_JUMP_FORCE_VCENTER
84    AP_JUMP_FORCE_HCENTER = 16, // force horizontal centering
85    AP_JUMP_BE_VERBOOSE   = 32, // tell why nothing happened etc.
86
87    // convenience defs:
88    AP_DONT_JUMP         = 0,
89    AP_JUMP_SMART_CENTER = AP_JUMP_FORCE_VCENTER|AP_JUMP_ALLOW_HCENTER,
90    AP_JUMP_FORCE_CENTER = AP_JUMP_FORCE_VCENTER|AP_JUMP_FORCE_HCENTER,
91
92    AP_JUMP_BY_BUTTON = AP_JUMP_SMART_CENTER|AP_JUMP_UNFOLD_GROUPS|AP_JUMP_BE_VERBOOSE,
93};
94
95enum ClickedType {
96    CL_NODE = 1,
97    CL_SPECIES,
98    CL_RULER,
99    CL_FLAG,
100    CL_BRANCH,
101};
102
103inline bool is_list_style(AP_tree_display_style style) { return style == AP_LIST_NDS || style == AP_LIST_SIMPLE; }
104inline bool is_tree_style(AP_tree_display_style style) { return !is_list_style(style); }
105
106
107class AWT_graphic_tree_group_state;
108
109struct AWT_scaled_font_limits {
110    double ascent;
111    double descent;
112    double height;
113    double width;
114
115    void init(const AW_font_limits& font_limits, double factor) {
116        ascent  = font_limits.ascent*factor;
117        descent = font_limits.descent*factor;
118        height  = font_limits.get_height()*factor;
119        width   = font_limits.width*factor;
120    }
121};
122
123enum AD_MAP_VIEWER_TYPE {
124    ADMVT_NONE = 0,
125    ADMVT_INFO,
126    ADMVT_WWW,
127    ADMVT_SELECT
128};
129
130typedef void (*AD_map_viewer_cb)(GBDATA *gbd, AD_MAP_VIEWER_TYPE type);
131
132struct DendroSubtreeLimits {
133    double y_branch;                                // ypos of branch to subtree
134    double y_top;                                   // top ypos of whole subtree
135    double y_bot;                                   // bottom ypos of whole subtree
136    double x_right;                                 // rightmost xpos of whole subtree
137
138    void combine(const DendroSubtreeLimits& other) {
139        y_top   = std::min(y_top, other.y_top);
140        y_bot   = std::max(y_bot, other.y_bot);
141        x_right = std::max(x_right, other.x_right);
142    }
143};
144
145struct AWT_command_data {
146    /*! any kind of data which has to be stored between different events (e.g. to support drag&drop)
147     * Purpose of this class is to allow to delete such data w/o knowing anything else.
148     */
149    virtual ~AWT_command_data() {}
150};
151
152enum CollapseMode {
153    COLLAPSE_ALL      = 0,
154    EXPAND_MARKED     = 1,  // do not collapse groups containing marked species
155    COLLAPSE_TERMINAL = 2,  // do not collapse groups with subgroups
156    EXPAND_ALL        = 4,
157    EXPAND_COLOR      = 8,  // do not collapse groups containing species with color == parameter 'color_group' (or any color if 'color_group' is -1)
158    EXPAND_ZOMBIES    = 16, // do not collapse groups containing zombies
159};
160
161class NodeMarkers {
162    // represents markers at a node (species or group)
163
164    int              nodeSize; // number of species in group (or 1)
165    std::vector<int> mark;     // how often each marker is set in group
166public:
167    NodeMarkers() {} // default for cache
168    explicit NodeMarkers(int numMarks)
169        : nodeSize(0),
170          mark(numMarks, 0)
171    {}
172
173    void incMarker(size_t markerIdx) {
174        td_assert(markerIdx<mark.size());
175        mark[markerIdx]++;
176    }
177    int markerCount(size_t markerIdx) const {
178        td_assert(markerIdx<mark.size());
179        return mark[markerIdx];
180    }
181
182    void incNodeSize() { nodeSize++; }
183    int getNodeSize() const { return nodeSize; }
184
185    double getMarkRate(size_t markerIdx) const { return markerCount(markerIdx) / double(getNodeSize()); }
186
187    void add(const NodeMarkers& other) {
188        size_t size = mark.size();
189        td_assert(size == other.mark.size());
190        for (size_t i = 0; i<size; ++i) {
191            mark[i] += other.mark[i];
192        }
193        nodeSize += other.nodeSize;
194    }
195};
196
197class MarkerDisplay {
198    // defines which markers shall be displayed
199
200    typedef std::map<const AP_tree*,NodeMarkers> GroupMarkerCache;
201
202    GroupMarkerCache cache;
203    int              numMarkers;
204
205public:
206    MarkerDisplay(int numMarkers_)
207        : numMarkers(numMarkers_)
208    {
209        td_assert(numMarkers>0);
210    }
211    virtual ~MarkerDisplay() {}
212
213    virtual const char *get_marker_name(int markerIdx) const                                      = 0;
214    virtual void retrieve_marker_state(const char *speciesName, NodeMarkers& matches)             = 0;
215    virtual void handle_click(int markerIdx, AW_MouseButton button, AWT_graphic_exports& exports) = 0;
216
217    const NodeMarkers *read_cache(const AP_tree *at) const {
218        GroupMarkerCache::const_iterator found = cache.find(at);
219        return found == cache.end() ? NULL : &found->second;
220    }
221    void write_cache(const AP_tree *at, const NodeMarkers& markers) { cache[at] = markers; }
222    void flush_cache() { cache.erase(cache.begin(), cache.end()); }
223
224    int size() const { return numMarkers; }
225};
226
227struct GroupInfo {
228    const char *name;
229    const char *count;
230    unsigned    name_len;
231    unsigned    count_len;
232};
233
234enum GroupInfoMode {
235    GI_COMBINED,             // only sets GroupInfo::name (will contain "name (count)" or only "name" if counters disabled)
236    GI_SEPARATED,            // set GroupInfo::name and GroupInfo::count (to "name" and "count")
237    GI_SEPARATED_PARENTIZED, // like GI_SEPARATED, but GroupInfo::count will be "(count)"
238};
239
240enum GroupInfoPosition {
241    GIP_SEPARATED, // name attached, count overlayed             (=old hardcoded default for AP_TREE_NORMAL and AP_TREE_IRS)
242    GIP_ATTACHED,  // "name (count)" attached "next to" group    (=old hardcoded default for AP_TREE_RADIAL)
243    GIP_OVERLAYED, // "name (count)" overlayed with group polygon
244};
245
246enum GroupCountMode {
247    GCM_NONE,    // do not show group count         (=old hardcoded default for AP_TREE_RADIAL)
248    GCM_MEMBERS, // show number of group members    (=old hardcoded default for AP_TREE_NORMAL and AP_TREE_IRS)
249    GCM_MARKED,  // show number of marked group members (show nothing if none marked)
250    GCM_BOTH,    // show "marked/members" (or "members" if none marked)
251    GCM_PERCENT, // show percent of marked group members (show nothing if none marked)
252    GCM_BOTH_PC, // show "percent/members" (or "members" if none marked)
253};
254
255enum BranchStyle {
256    BS_RECTANGULAR, // traditional rectangular branches
257    BS_DIAGONAL,    // diagonal branches (directly from fathers to sons attach point)
258};
259
260enum GroupStyle {
261    GS_TRAPEZE,
262    GS_TRIANGLE,
263};
264
265enum GroupOrientation {
266    GO_TOP,      // long clade side at top
267    GO_BOTTOM,   // long clade side at bottom
268    GO_INTERIOR, // long clade side towards center of subtree
269    GO_EXTERIOR, // long clade side towards margin of subtree
270};
271
272class AWT_graphic_tree;
273DECLARE_CBTYPE_FVV_AND_BUILDERS(GraphicTreeCallback, void, AWT_graphic_tree*); // generates makeGraphicTreeCallback
274
275class AWT_graphic_tree : public AWT_graphic, virtual Noncopyable {
276    char         *species_name;
277    AW::Position  cursor;
278
279    int   baselinewidth;
280    float circle_zoom_factor;
281    float circle_max_size;
282    int   bootstrap_min;
283
284    int zombies;    // # of zombies during last load()
285    int duplicates; // # of duplicates during last load()
286
287    AP_tree * tree_proto;
288
289    bool show_brackets;
290    bool show_circle;
291    bool use_ellipse;
292    bool link_to_database; // link on load?
293
294    GroupStyle       group_style;
295    GroupOrientation group_orientation;
296
297    double list_tree_ruler_y;
298    double irs_tree_ruler_scale_factor;
299    double attach_size;   // 1.0 = at bigger subtree ; 0.0 = centered;         -1.0 = at smaller subtree (trad.)
300    double attach_len;    // 1.0 = at longer branch;   0.0 = centered (trad.); -1.0 = at shorter branch
301    double attach_group;  // 1.0 = at longer side;     0.5 = centered (trad.);  0.0 = at shorter side (of group polygon)
302
303    AWT_scaled_font_limits scaled_font;
304
305    double        scaled_branch_distance; // vertical distance between branches (may be extra-scaled in options)
306    group_scaling groupScale;             // scaling for folded groups
307    double        scaled_remark_ascend;
308
309    AW_grey_level group_greylevel;
310    AW_grey_level marker_greylevel;
311
312    AW_device *disp_device; // device for recursive functions
313
314    const AW_bitset line_filter, vert_line_filter, mark_filter, group_bracket_filter, bs_circle_filter;
315    const AW_bitset leaf_text_filter, group_text_filter, remark_text_filter, other_text_filter;
316    const AW_bitset ruler_filter, root_filter, marker_filter;
317
318    bool nds_only_marked;
319
320    GroupInfoPosition group_info_pos;
321    GroupCountMode    group_count_mode;
322    BranchStyle       branch_style;
323
324    MarkerDisplay *display_markers;
325    struct {
326        double marked;
327        double partiallyMarked;
328    } groupThreshold;
329
330    AD_map_viewer_cb  map_viewer_cb;
331    AWT_command_data *cmd_data;
332
333    AP_tree_root *tree_static;
334    AP_tree      *displayed_root; // root node of shown (sub-)tree; differs from real root if tree is zoomed logically
335
336    GraphicTreeCallback tree_changed_cb;
337
338    AW_root *aw_root;
339    GBDATA  *gb_main;
340
341    AP_tree_display_style tree_style;
342
343    AW_pos paint_irs_sub_tree(AP_tree *node, AW_pos x_offset); // returns y pos
344    void   unload();
345
346    // functions to compute displayinformation
347
348    void show_dendrogram(AP_tree *at, AW::Position& pen, DendroSubtreeLimits& limits);
349    void show_radial_tree(AP_tree *at, const AW::Position& base, const AW::Position& tip, const AW::Angle& orientation, const double tree_spread);
350    void show_nds_list(GBDATA * gb_main, bool use_nds);
351    void show_irs_tree(AP_tree *at, double height);
352
353    void summarizeGroupMarkers(AP_tree *at, NodeMarkers& markers);
354    void drawMarker(const class MarkerPosition& marker, const bool partial, const int midx);
355    void detectAndDrawMarkers(AP_tree *at, double y1, double y2);
356    void drawMarkerNames(AW::Position& Pen);
357
358    void pixel_box(int gc, const AW::Position& pos, int pixel_width, AW::FillStyle filled);
359
360    const GroupInfo& get_group_info(AP_tree *at, GroupInfoMode mode, bool swap = false) const;
361
362    void handle_key(AW_device *device, AWT_graphic_event& event);
363
364protected:
365    void store_command_data(AWT_command_data *new_cmd_data) {
366        delete cmd_data;
367        cmd_data = new_cmd_data;
368    }
369    AWT_command_data *get_command_data() { return cmd_data; }
370
371public:
372    AWT_graphic_tree(AW_root *aw_root, GBDATA *gb_main, AD_map_viewer_cb map_viewer_cb);
373    ~AWT_graphic_tree() OVERRIDE;
374
375    void filled_box(int gc, const AW::Position& pos, int pixel_width) { pixel_box(gc, pos, pixel_width, AW::FillStyle::SOLID); }
376    void empty_box(int gc, const AW::Position& pos, int pixel_width) { pixel_box(gc, pos, pixel_width, AW::FillStyle::EMPTY); }
377    void diamond(int gc, const AW::Position& pos, int pixel_radius);
378
379    const char *ruler_awar(const char *name);
380
381    void set_line_attributes_for(AP_tree *at) const {
382        disp_device->set_line_attributes(at->gr.gc, at->get_linewidth()+baselinewidth, AW_SOLID);
383    }
384
385    virtual void read_tree_settings();
386    void update_structure() {
387        AP_tree *root = get_root_node();
388        if (root) root->compute_tree();
389    }
390    void apply_zoom_settings_for_treetype(AWT_canvas *ntw);
391
392    int draw_branch_line(int gc, const AW::Position& root, const AW::Position& leaf, AW_bitset filter) {
393        const AW_click_cd *old = disp_device->get_click_cd();
394        td_assert(old && old->get_cd1() && old->get_cd2() == CL_NODE); // cd1 should be the node
395
396        AW_click_cd branch(disp_device, old->get_cd1(), CL_BRANCH);
397        return disp_device->line(gc, root, leaf, filter);
398    }
399
400    bool warn_inappropriate_mode(AWT_COMMAND_MODE mode);
401
402    virtual AP_tree_root *create_tree_root(AliView *aliview, AP_sequence *seq_prototype, bool insert_delete_cbs);
403
404    AW_root *get_root() const { return aw_root; }
405    GBDATA *get_gbmain() const { return gb_main; }
406
407    AP_tree_root *get_tree_root() { return tree_static; }
408
409    AP_tree       *get_root_node()       { return tree_static ? tree_static->get_root_node() : NULL; }
410    const AP_tree *get_root_node() const { return const_cast<AWT_graphic_tree*>(this)->get_root_node(); }
411
412    AP_tree       *get_logical_root()       { return displayed_root; }
413    const AP_tree *get_logical_root() const { return displayed_root; }
414
415    bool is_logically_zoomed() { return displayed_root != get_root_node(); }
416    void set_logical_root_to(AP_tree *node) {
417        displayed_root = node;
418        tree_changed_cb(this);
419    }
420
421    void init(AliView *aliview, AP_sequence *seq_prototype, bool link_to_database_, bool insert_delete_cbs);
422    AW_gc_manager *init_devices(AW_window *, AW_device *, AWT_canvas *ntw) OVERRIDE;
423
424    void show(AW_device *device) OVERRIDE;
425    const AW::Position& get_cursor() const { return cursor; }
426
427    void handle_command(AW_device *device, AWT_graphic_event& event) OVERRIDE;
428
429    void mark_species_in_tree(AP_tree *at, int mark);
430    void mark_species_in_tree_that(AP_tree *at, int mark, int (*condition)(GBDATA*, void*), void *cd);
431
432    void mark_species_in_rest_of_tree(AP_tree *at, int mark);
433    void mark_species_in_rest_of_tree_that(AP_tree *at, int mark, int (*condition)(GBDATA*, void*), void *cd);
434
435    bool tree_has_marks(AP_tree *at);
436    bool rest_tree_has_marks(AP_tree *at);
437
438    void detect_group_state(AP_tree *at, AWT_graphic_tree_group_state *state, AP_tree *skip_this_son);
439
440    bool     group_tree(AP_tree *at, CollapseMode mode, int color_group);
441    void     group_rest_tree(AP_tree *at, CollapseMode mode, int color_group);
442    void     reorder_tree(TreeOrder mode);
443    GB_ERROR create_group(AP_tree * at) __ATTR__USERESULT;
444    void     toggle_group(AP_tree * at);
445    GB_ERROR load(GBDATA *gb_main, const char *name) OVERRIDE __ATTR__USERESULT;
446    GB_ERROR save(GBDATA *gb_main, const char *name) OVERRIDE __ATTR__USERESULT;
447    int      check_update(GBDATA *gb_main) OVERRIDE;         // reload tree if needed
448    void     update(GBDATA *gb_main) OVERRIDE;
449
450    void set_tree_style(AP_tree_display_style style, AWT_canvas *ntw);
451    AP_tree_display_style get_tree_style() const { return tree_style; }
452
453    double get_irs_tree_ruler_scale_factor() const { return irs_tree_ruler_scale_factor; }
454    void show_ruler(AW_device *device, int gc);
455    void get_zombies_and_duplicates(int& zomb, int& dups) const { zomb = zombies; dups = duplicates; }
456
457    void hide_marker_display() {
458        delete display_markers;
459        display_markers = NULL;
460    }
461    void set_marker_display(MarkerDisplay *display) { // takes ownership of 'display'
462        hide_marker_display();
463        display_markers = display;
464    }
465    MarkerDisplay *get_marker_display() { return display_markers; }
466
467    void install_tree_changed_callback(const GraphicTreeCallback& gtcb);
468    void uninstall_tree_changed_callback();
469
470#if defined(UNIT_TESTS) // UT_DIFF
471    friend class fake_AWT_graphic_tree;
472#endif
473};
474
475class ClickedTarget {
476    /*! Represents any target corresponding to some (mouse-)position in the tree display.
477     *
478     * The target is e.g. used as target for keystrokes or mouse clicks.
479     *
480     * For AP_LIST_NDS, this only represents the species (w/o any tree information).
481     * For other tree display modes, this represents a specific tree node.
482     *
483     * The space outside the tree does represent the whole tree (aka the root-node).
484     * (the necessary distance to the tree-structure/-text is defined by AWT_CATCH)
485     */
486
487    AP_tree *tree_node;
488    GBDATA  *gb_species;
489
490    bool ruler;
491    bool branch;
492    int  markerflag; // = markerindex + 1
493
494    const AW_clicked_element *elem;
495
496    void init() {
497        tree_node  = NULL;
498        gb_species = NULL;
499        ruler      = false;
500        branch     = false;
501        markerflag  = 0;
502    }
503
504    void identify(AWT_graphic_tree *agt) {
505        init();
506        if (elem && elem->does_exist()) {
507            ClickedType what = (ClickedType)elem->cd2();
508
509            switch (what) {
510                case CL_SPECIES:
511                    gb_species = (GBDATA*)elem->cd1();
512                    td_assert(gb_species);
513                    break;
514
515                case CL_RULER:
516                    ruler = !elem->cd1();
517                    break;
518
519                case CL_FLAG:
520                    markerflag = elem->cd1()+1;
521                    break;
522
523                case CL_BRANCH:
524                    branch = true;
525                    // fall-through!
526                case CL_NODE:
527                    tree_node = (AP_tree*)elem->cd1();
528                    break;
529
530#if defined(DEBUG)
531                default:
532                    td_assert(0); // unknown element type
533#endif
534            }
535        }
536        else { // use whole tree if mouse does not point to a subtree
537            tree_node = agt ? agt->get_root_node() : NULL;
538        }
539        td_assert(implicated(branch, tree_node));
540    }
541
542public:
543
544    ClickedTarget(AWT_graphic_tree *agt, const AW_clicked_element *clicked) : elem(clicked) {
545        // uses root of tree as target, when a position outside of the tree is selected
546        // (e.g. used for key-commands)
547        identify(agt);
548    }
549    ClickedTarget(const AW_clicked_element *clicked) : elem(clicked) {
550        // accept only normal branches as targets
551        identify(NULL);
552    }
553
554    const AW_clicked_element *element() const { return elem; }
555    AP_tree *node() const { return tree_node; }
556    GBDATA *species() const { return gb_species; }
557    int get_markerindex() const { return markerflag-1; }
558
559    bool is_text() const { return elem && elem->is_text(); }
560    bool is_line() const { return elem && elem->is_line(); }
561    bool is_branch() const { return branch; }
562    bool is_ruler() const { return ruler; }
563    bool is_marker() const { return markerflag; }
564
565    double get_rel_attach() const {
566        // return [0..1] according to exact position where element is dropped
567        if (is_line() && (is_branch() || ruler)) return elem->get_rel_pos();
568        return 0.5; // act like "drop on branch-center"
569    }
570};
571
572void       TREE_create_awars(AW_root *aw_root, AW_default db);
573void       TREE_install_update_callbacks(TREE_canvas *ntw);
574void       TREE_insert_jump_option_menu(AW_window *aws, const char *label, const char *awar_name);
575AW_window *TREE_create_settings_window(AW_root *aw_root);
576AW_window *TREE_create_marker_settings_window(AW_root *root);
577
578AWT_graphic_tree *NT_generate_tree(AW_root *root, GBDATA *gb_main, AD_map_viewer_cb map_viewer_cb);
579
580bool TREE_show_branch_remark(AW_device *device, const char *remark_branch, bool is_leaf, const AW::Position& pos, AW_pos alignment, AW_bitset filteri, int bootstrap_min);
581
582#else
583#error TreeDisplay.hxx included twice
584#endif // TREEDISPLAY_HXX
Note: See TracBrowser for help on using the repository browser.