source: tags/arb_5.0/AWT/AWT_irstree.cxx

Last change on this file was 5901, checked in by westram, 15 years ago
  • AW_BOOL → bool
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.4 KB
Line 
1#include <stdio.h>
2
3#include <math.h>
4#include <string.h>
5#include <arbdb.h>
6#include <arbdbt.h>
7#include <aw_root.hxx>
8#include <aw_device.hxx>
9#include <aw_window.hxx>
10
11#include <awt_canvas.hxx>
12#include <awt_nds.hxx>
13#include "awt_tree.hxx"
14#include "awt_dtree.hxx"
15#include <aw_awars.hxx>
16
17enum AWT_IRS_TREE_TYPES {
18    AWT_IRS_HIDDEN_TREE,
19    AWT_IRS_NORMAL_TREE
20};
21
22
23enum IRS_PRUNE_LEVEL {
24    IRS_NOPRUNE
25};
26
27/* *********************** paint sub tree ************************ */
28
29#define IS_HIDDEN(node) (type == AWT_IRS_HIDDEN_TREE && node->gr.gc>0)
30
31const int MAXSHOWNNODES = 5000;       // Something like max screen height/minimum font size
32const int tipBoxSize    = 4;
33const int nodeBoxWidth  = 5;
34
35static struct {
36    GB_BOOL    ftrst_species;
37    int        y;
38    int        min_y;
39    int        max_y;
40    int        ruler_y;
41    int        min_x;
42    int        max_x;
43    int        step_y;
44    double     x_scale;
45    AW_device *device;
46   
47    int      nodes_xpos[MAXSHOWNNODES];   // needed for Query results drawing
48    int      nodes_ypos[MAXSHOWNNODES];
49    AP_tree *nodes_id[MAXSHOWNNODES];
50    int      nodes_ntip;                  // counts the tips stored in nodes_xx
51    int      nodes_nnnodes;               // counts the inner nodes (reverse counter !!!)
52
53    int                  font_height_2;
54    enum IRS_PRUNE_LEVEL pruneLevel;
55    int                  is_size_device;
56} irs_gl;
57
58void draw_top_seperator(){
59    int gc = AWT_GC_GROUPS;
60    int y;
61    irs_gl.ftrst_species = GB_FALSE;
62    if (!irs_gl.is_size_device){
63        for (y = irs_gl.min_y; y< irs_gl.min_y+4;y++){
64            irs_gl.device->line(gc,-10000,y,10000,y,-1,(AW_CL)0,(AW_CL)0);
65        }
66    }
67}
68
69int AWT_graphic_tree::paint_irs_sub_tree(AP_tree *node, int x_offset, int type){
70
71    int left_y;
72    int left_x;
73    int right_y;
74    int right_x;
75
76
77    // if (irs_gl.y > irs_gl.max_clipped_y) irs_gl.max_clipped_y = irs_gl.max_y; // @@@ ralf
78
79    /* *********************** Check clipping rectangle ************************ */
80    if (!irs_gl.is_size_device){
81        if (irs_gl.y > irs_gl.max_y) {
82            return irs_gl.max_y;
83        }
84        int height_of_subtree = irs_gl.step_y*node->gr.view_sum;
85        if (irs_gl.y + height_of_subtree < irs_gl.min_y) {
86            irs_gl.y+= height_of_subtree;
87            return irs_gl.min_y;
88        }
89    }
90
91
92
93    /* *********************** i'm a leaf ************************ */
94    if (node->is_leaf) {
95        irs_gl.y+=irs_gl.step_y;
96        if (irs_gl.ftrst_species) {
97            draw_top_seperator();
98        }
99        int x = x_offset;
100        int y = irs_gl.y + irs_gl.font_height_2;
101        int gc = node->gr.gc;
102
103
104
105        if (node->name && node->name[0] == this->species_name[0] &&
106            !strcmp(node->name,this->species_name)) {
107            x_cursor = x; y_cursor = irs_gl.y;
108        }
109
110        const char *str = 0;
111        if (!irs_gl.is_size_device){
112            if (node->gb_node && GB_read_flag(node->gb_node)){
113                NT_scalebox(gc,x, irs_gl.y, NT_BOX_WIDTH);
114            }
115            str = make_node_text_nds(gb_main,node->gb_node,0,node->get_gbt_tree(), tree_name);
116            irs_gl.device->text(gc,str, x, y,0.0,-1, (AW_CL)node,0);
117        }
118        return irs_gl.y;
119    }
120
121    /* *********************** i'm a grouped subtree ************************ */
122    int last_y = irs_gl.y;
123    const char *node_string = 0;
124    if (node->gb_node){
125        if (!irs_gl.is_size_device){
126            if (!node->father) { // root node - don't try to get taxonomy
127                node_string = tree_name;
128            }
129            else {
130                node_string = make_node_text_nds(gb_main,node->gb_node,0,node->get_gbt_tree(), tree_name);
131            }
132        }else{
133            node_string = "0123456789";
134        }
135    }
136    if (node->gr.grouped) {             // no recursion here    just a group symbol !!!
137        int vsize = node->gr.view_sum * irs_gl.step_y;
138        int y_center = irs_gl.y + (vsize>>1) + irs_gl.step_y;
139        if ( irs_gl.y >= irs_gl.min_y) {
140            if (irs_gl.ftrst_species) { // A name of a group just under the seperator
141                draw_top_seperator();
142            }
143            int topy = irs_gl.y+irs_gl.step_y - 2;
144            int boty = irs_gl.y+irs_gl.step_y+ vsize + 2;
145            int rx   = x_offset + vsize + vsize;
146            int gc   = AWT_GC_GROUPS;
147
148            // draw group box (unclosed on right hand):
149            irs_gl.device->line(gc, x_offset, topy, rx,       topy, -1, (AW_CL)node, 0);
150            irs_gl.device->line(gc, x_offset, topy, x_offset, boty, -1, (AW_CL)node, 0);
151            irs_gl.device->line(gc, x_offset, boty, rx,       boty, -1, (AW_CL)node, 0);
152
153            irs_gl.device->box(node->gr.gc, true, x_offset - (tipBoxSize>>1), topy - (tipBoxSize>>1), tipBoxSize, tipBoxSize, mark_filter, (AW_CL)node, 0);
154            irs_gl.device->box(node->gr.gc, true, x_offset+2,                 irs_gl.y+irs_gl.step_y, vsize,      vsize,      -1, (AW_CL)node, 0); 
155
156            irs_gl.y += vsize + 2*irs_gl.step_y ;
157            if (node_string) {
158                const char *s = GBS_global_string("%s (%i)",node_string,node->gr.leave_sum);
159                irs_gl.device->text(node->gr.gc,s,x_offset + vsize + 10 + nodeBoxWidth,
160                                    y_center + (irs_gl.step_y>>1),0.0, //  A node name should be displayed
161                                    -1, (AW_CL)node, 0);
162            }
163        }
164        else{
165            irs_gl.y+= vsize;
166            y_center = irs_gl.min_y;
167            if ( irs_gl.y > irs_gl.min_y) {
168                irs_gl.y = irs_gl.min_y;
169            }
170        }
171        return y_center;
172    }
173
174    // ungrouped groups go here
175
176    if ( irs_gl.pruneLevel != IRS_NOPRUNE ){
177        node_string = 0;
178    }
179
180    /* *********************** i'm a labeled node ************************ */
181    /*  If I have only one child + pruneLevel != MAXPRUNE -> no labeling */
182
183    if (node_string != NULL) {          //  A node name should be displayed
184        if (last_y >= irs_gl.min_y) {
185            if (irs_gl.ftrst_species) { // A name of a group just under the seperator
186                draw_top_seperator();
187            }
188            last_y = irs_gl.y + irs_gl.step_y;
189        }else{
190            last_y = irs_gl.min_y;
191            irs_gl.min_y += int(irs_gl.step_y * 1.8);
192        }
193        irs_gl.y+=int(irs_gl.step_y * 1.8);
194        int gc = AWT_GC_GROUPS;
195        irs_gl.device->line(gc,x_offset,last_y,  x_offset+400, last_y, -1, (AW_CL)node,0);
196
197        irs_gl.device->box(node->gr.gc, true, x_offset- (tipBoxSize>>1), last_y- (tipBoxSize>>1), tipBoxSize,tipBoxSize, mark_filter, (AW_CL)node,0);
198        const char *s = GBS_global_string("%s (%i)",node_string,node->gr.leave_sum);
199        irs_gl.device->text(node->gr.gc,s, x_offset + 10 + nodeBoxWidth, last_y + irs_gl.step_y + 1,0.0, -1, (AW_CL)node,0);
200    }
201
202    /* *********************** connect two nodes == draw branches ************************ */
203    int y_center;
204
205    left_x = (int)(x_offset + 0.9 + irs_gl.x_scale * node->leftlen);
206    left_y = paint_irs_sub_tree(node->leftson, left_x, type);
207
208    right_x = int(x_offset + 0.9 + irs_gl.x_scale * node->rightlen);
209    right_y = paint_irs_sub_tree(node->rightson, right_x, type);
210
211
212    /* *********************** draw structure ************************ */
213
214    if (left_y > irs_gl.min_y){
215        if (left_y < irs_gl.max_y){ // clip y on top border
216            if (node->leftson->remark_branch ) {
217                AWT_show_remark_branch(disp_device, node->leftson->remark_branch, node->leftson->is_leaf, left_x, left_y, 1, text_filter, (AW_CL)node->leftson, 0);
218            }
219            irs_gl.device->line(node->leftson->gr.gc,x_offset,left_y,  left_x,   left_y, -1, (AW_CL)node->leftson,0); //  ***
220        }
221    }else{
222        left_y = irs_gl.min_y;
223    }
224
225    y_center = (left_y + right_y) / 2; // clip conter on bottom border
226
227    if (right_y > irs_gl.min_y && right_y < irs_gl.max_y) { // visible right branch in lower part of display
228
229        if (node->rightson->remark_branch ) {
230            AWT_show_remark_branch(disp_device, node->rightson->remark_branch, node->rightson->is_leaf, right_x, right_y, 1, text_filter, (AW_CL)node->rightson, 0);
231        }
232        irs_gl.device->line(node->rightson->gr.gc,x_offset,right_y,  right_x,   right_y, -1, (AW_CL)node->rightson,0);
233    }
234
235    irs_gl.device->line(node->leftson->gr.gc, x_offset,y_center,x_offset, left_y,  -1, (AW_CL)node,0);
236    irs_gl.device->line(node->rightson->gr.gc,x_offset,y_center,x_offset, right_y, -1, (AW_CL)node,0);
237    irs_gl.ruler_y = y_center;
238
239    if (node_string != 0) {             //  A node name should be displayed
240        irs_gl.y+=irs_gl.step_y /2;
241        int gc = AWT_GC_GROUPS;
242        irs_gl.device->line(gc,x_offset-1,irs_gl.y, x_offset+400,  irs_gl.y, -1,(AW_CL)node,0);
243        irs_gl.device->line(gc,x_offset-1,last_y,   x_offset-1,  irs_gl.y, -1,(AW_CL)node,0);
244    }
245    if (0 &&  !irs_gl.is_size_device){
246        if (irs_gl.nodes_nnnodes>irs_gl.nodes_ntip+1){
247            irs_gl.nodes_nnnodes--;
248            irs_gl.nodes_xpos[irs_gl.nodes_nnnodes] = x_offset;
249            irs_gl.nodes_ypos[irs_gl.nodes_nnnodes] = y_center;
250            irs_gl.nodes_id[irs_gl.nodes_nnnodes] = node;
251        }
252    }
253
254    return y_center;
255}
256
257int AWT_graphic_tree::draw_slot(int x_offset, GB_BOOL draw_at_tips){
258    int maxx = x_offset;
259    int i;
260    int no_compress = 0;
261    if (!draw_at_tips) no_compress = 1;
262    for (i=0;i<irs_gl.nodes_ntip;i++){
263        AP_tree *tip = irs_gl.nodes_id[i];
264        const char *str = make_node_text_nds(gb_main,tip->gb_node,no_compress,tip->get_gbt_tree(), tree_name);
265        int len = irs_gl.device->get_string_size(tip->gr.gc,str,0);
266        int x = 0;
267        int y = irs_gl.nodes_ypos[i]+ irs_gl.font_height_2;
268        if (draw_at_tips) {
269            x = x_offset + irs_gl.nodes_xpos[i];
270        }else{
271            irs_gl.device->text(tip->gr.gc,str,x,irs_gl.nodes_ypos[i],0,-1,(AW_CL)tip,0);
272        }
273        if (x + len > maxx) maxx = x+len;
274        irs_gl.device->text(tip->gr.gc,str, x, y,0.0,-1, (AW_CL)tip,0);
275    }
276    return maxx;
277}
278
279
280void AWT_graphic_tree::show_irs_tree(AP_tree *at,AW_device *device, int height){
281    device->push_clip_scale();
282    int x;
283    int y;
284    const AW_font_information *font_info = device->get_font_information(AWT_GC_SELECTED,0);
285    device->rtransform(0,0,x,y); // calculate real world coordinates of left/upper screen border
286    int clipped_l,clipped_t;
287    int clipped_r,clipped_b;
288    device->rtransform(device->clip_rect.l,device->clip_rect.t,clipped_l,clipped_t);
289    device->rtransform(device->clip_rect.r,device->clip_rect.b,clipped_r,clipped_b);
290
291    irs_gl.nodes_nnnodes  = MAXSHOWNNODES;
292    irs_gl.nodes_ntip     = 0;
293    irs_gl.font_height_2  = font_info->max_letter.ascent/2;
294    irs_gl.device         = device;
295    irs_gl.ftrst_species  = GB_TRUE;
296    irs_gl.y              = 0;
297    irs_gl.min_x          = x;
298    irs_gl.max_x          = 100;
299    irs_gl.min_y          = y;
300    irs_gl.max_y          = clipped_b;
301    irs_gl.ruler_y        = 0;
302    irs_gl.step_y         = height;
303    irs_gl.x_scale        = 600.0 / at->gr.tree_depth;
304    irs_gl.is_size_device = 0;
305   
306    if (irs_gl.device->type() == AW_DEVICE_SIZE){
307        irs_gl.is_size_device = 1;
308    }
309
310    paint_irs_sub_tree(at,0,AWT_IRS_NORMAL_TREE );
311
312    // provide some information for ruler :
313    y_pos                       = irs_gl.ruler_y;
314    irs_tree_ruler_scale_factor = irs_gl.x_scale;
315
316    if (irs_gl.is_size_device){
317        irs_gl.device->invisible(0,irs_gl.min_x,irs_gl.y + (irs_gl.min_y-y) + 200,-1,0,0);
318    }
319    device->pop_clip_scale();
320}
Note: See TracBrowser for help on using the repository browser.