source: tags/svn.1.5.4/GENOM/GEN_graphic.cxx

Last change on this file was 7916, checked in by westram, 14 years ago
  • removed AWAR_DTREE_REFRESH (→ AWAR_TREE_REFRESH)
  • DRYed AWAR_TREE_REFRESH
  • loosened coupling between aw_awar.hxx and aw_awar_defs.hxx (former aw_awars.hxx)
    • aw_awars.hxx now includes both
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.6 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : GEN_graphic.cxx                                   //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Coded by Ralf Westram (coder@reallysoft.de) in 2001           //
7//   Institute of Microbiology (Technical University Munich)       //
8//   http://www.arb-home.de/                                       //
9//                                                                 //
10// =============================================================== //
11
12#include "GEN_local.hxx"
13#include "GEN_gene.hxx"
14#include "GEN_graphic.hxx"
15
16#include <arbdbt.h>
17#include <aw_awar.hxx>
18#include <aw_preset.hxx>
19#include <awt_attributes.hxx>
20#include <aw_msg.hxx>
21#include <aw_root.hxx>
22
23#include <climits>
24
25using namespace std;
26using namespace AW;
27
28//  -------------------
29//      GEN_graphic
30//  -------------------
31
32GEN_graphic::GEN_graphic(AW_root *aw_root_, GBDATA *gb_main_, GEN_graphic_cb_installer callback_installer_, int window_nr_)
33    : aw_root(aw_root_)
34    , gb_main(gb_main_)
35    , callback_installer(callback_installer_)
36    , window_nr(window_nr_)
37    , gen_root(0)
38    , want_zoom_reset(false)
39{
40    exports.dont_fit_x  = 0;
41    exports.dont_fit_y  = 0;
42    exports.dont_scroll = 0;
43    exports.set_standard_default_padding();
44
45    rot_ct.exists = false;
46    rot_cl.exists = false;
47
48    set_display_style(GEN_DisplayStyle(aw_root->awar(AWAR_GENMAP_DISPLAY_TYPE(window_nr))->read_int()));
49}
50
51GEN_graphic::~GEN_graphic() {
52}
53
54AW_gc_manager GEN_graphic::init_devices(AW_window *aww, AW_device *device, AWT_canvas *ntw, AW_CL cd2) {
55    disp_device                 = device;
56    AW_gc_manager preset_window = AW_manage_GC(aww, device,
57                                               GEN_GC_FIRST_FONT, GEN_GC_MAX, AW_GCM_DATA_AREA,
58                                               (AW_CB)AWT_resize_cb, (AW_CL)ntw, cd2,
59                                               true, // define color groups
60                                               "#55C0AA",
61                                               "Default$#5555ff",
62                                               "Gene$#000000",
63                                               "Marked$#ffff00",
64                                               "Cursor$#ff0000",
65                                               NULL);
66    return preset_window;
67}
68
69void GEN_graphic::show(AW_device *device) {
70    if (gen_root) {
71#if defined(DEBUG) && 0
72        fprintf(stderr, "GEN_graphic::show\n");
73#endif // DEBUG
74
75        gen_root->paint(device);
76    }
77    else {
78        device->line(GEN_GC_DEFAULT, -100, -100, 100, 100);
79        device->line(GEN_GC_DEFAULT, -100, 100, 100, -100);
80    }
81}
82
83int GEN_graphic::check_update(GBDATA *) {
84    // if check_update returns >0 -> zoom_reset is done
85    int do_zoom_reset = want_zoom_reset;
86    want_zoom_reset   = false;
87    return do_zoom_reset;
88}
89
90void GEN_graphic::info(AW_device */*device*/, AW_pos /*x*/, AW_pos /*y*/, AW_clicked_line */*cl*/, AW_clicked_text */*ct*/) {
91    aw_message("INFO MESSAGE");
92}
93
94void GEN_graphic::command(AW_device *device, AWT_COMMAND_MODE cmd, int button, AW_key_mod /* key_modifier */, AW_key_code /* key_code */, char /* key_char */, AW_event_type type,
95                          AW_pos screen_x, AW_pos screen_y, AW_clicked_line *cl, AW_clicked_text *ct) {
96    AW_pos world_x;
97    AW_pos world_y;
98    device->rtransform(screen_x, screen_y, world_x, world_y);
99
100    if (type == AW_Mouse_Press) {
101        switch (cmd) {
102            case AWT_MODE_ZOOM: {
103                break;
104            }
105            case AWT_MODE_SELECT:
106            case AWT_MODE_EDIT: {
107                if (button==AWT_M_LEFT) {
108                    GEN_gene *gene = 0;
109                    if (ct) gene   = (GEN_gene*)ct->client_data1;
110                    if (cl) gene   = (GEN_gene*)cl->client_data1;
111
112                    if (gene) {
113                        GB_transaction dummy(gb_main);
114                        aw_root->awar(AWAR_LOCAL_GENE_NAME(window_nr))->write_string(gene->Name().c_str());
115
116                        if (cmd == AWT_MODE_EDIT) {
117                            GEN_create_gene_window(aw_root, (AW_CL)gb_main)->activate();
118                        }
119                    }
120                }
121                break;
122            }
123            default: {
124                gen_assert(0);
125                break;
126            }
127        }
128    }
129}
130
131inline int GEN_root::smart_text(AW_device *device, int gc, const char *str, AW_pos x, AW_pos y) {
132    int slen = strlen(str);
133    int res  = device->text(gc, str, x, y, 0.0, AW_ALL_DEVICES_UNSCALED, slen);
134    if (gc == GEN_GC_CURSOR) {
135        int                   xsize = device->get_string_size(gc, str, slen);
136        const AW_font_limits& lim   = device->get_font_limits(gc, 0);
137
138        Position  stext = device->transform(Position(x, y));
139        Rectangle srect(stext.xpos(), stext.ypos()-lim.ascent, stext.xpos()+xsize, stext.ypos()+lim.descent);
140        Rectangle wrect = device->rtransform(srect);
141        increase_selected_range(wrect);
142    }
143    return res;
144}
145
146inline int GEN_root::smart_line(AW_device *device, int gc, AW_pos x0, AW_pos y0, AW_pos x1, AW_pos y1) {
147    int res = device->line(gc, x0, y0, x1, y1);
148    if (gc == GEN_GC_CURSOR) increase_selected_range(Rectangle(x0, y0, x1, y1));
149    return res;
150}
151
152enum PaintWhat {
153    PAINT_MIN,
154    PAINT_NORMAL = PAINT_MIN,
155    PAINT_COLORED,
156    PAINT_MARKED,
157    PAINT_SELECTED,
158    PAINT_MAX    = PAINT_SELECTED,
159};
160
161inline bool getDrawGcs(GEN_iterator& gene, PaintWhat what, const string& curr_gene_name, int& draw_gc, int& text_gc) {
162    bool draw = false;
163    if (curr_gene_name == gene->Name()) { // current gene
164        draw_gc = text_gc = GEN_GC_CURSOR;
165        draw    = (what == PAINT_SELECTED);
166    }
167    else {
168        GBDATA *gb_gene = (GBDATA*)gene->GbGene();
169
170        if (GB_read_flag(gb_gene)) { // marked genes
171            draw_gc = text_gc = GEN_GC_MARKED;
172            draw    = (what == PAINT_MARKED);
173        }
174        else {
175            int color_group = AWT_gene_get_dominant_color(gb_gene);
176
177            if (color_group) {
178                draw_gc = text_gc = GEN_GC_FIRST_COLOR_GROUP+color_group-1;
179                draw    = (what == PAINT_COLORED);
180            }
181            else {
182                draw_gc = GEN_GC_GENE;
183                text_gc = GEN_GC_DEFAULT; // see show_all_nds in GEN_root::paint if you change this!!!
184                draw    = (what == PAINT_NORMAL);
185            }
186        }
187    }
188    return draw;
189}
190
191void GEN_root::paint(AW_device *device) {
192    if (error_reason.length()) {
193        device->text(GEN_GC_DEFAULT, error_reason.c_str(), 0, 0);
194        return;
195    }
196
197    clear_selected_range();
198
199    AW_root *aw_root      = gen_graphic->get_aw_root();
200    int      arrow_size   = aw_root->awar(AWAR_GENMAP_ARROW_SIZE)->read_int();
201    int      show_all_nds = aw_root->awar(AWAR_GENMAP_SHOW_ALL_NDS)->read_int();
202
203    for (PaintWhat paint_what = PAINT_MIN; paint_what <= PAINT_MAX; paint_what = PaintWhat((int(paint_what)+1))) {
204        switch (gen_graphic->get_display_style()) {
205            case GEN_DISPLAY_STYLE_RADIAL: {
206                double w0      = 2.0*M_PI/double(length);
207                double mp2     = M_PI/2;
208                double inside  = aw_root->awar(AWAR_GENMAP_RADIAL_INSIDE)->read_float()*1000;
209                double outside = aw_root->awar(AWAR_GENMAP_RADIAL_OUTSIDE)->read_float();
210
211                GEN_iterator curr = gene_set.begin();
212                GEN_iterator end  = gene_set.end();
213
214                while (curr != end) {
215                    int draw_gc, text_gc;
216                    if (getDrawGcs(curr, paint_what, gene_name, draw_gc, text_gc)) {
217                        double w    = w0*curr->StartPos()-mp2;
218                        double sinw = sin(w);
219                        double cosw = cos(w);
220                        int    len  = curr->Length();
221
222                        int xi = int(cosw*inside+0.5);
223                        int yi = int(sinw*inside+0.5);
224                        int xo = xi+int(cosw*outside*len+0.5);
225                        int yo = yi+int(sinw*outside*len+0.5);
226
227                        AW_click_cd cd(device, (AW_CL)&*curr);
228                        if (show_all_nds || text_gc != GEN_GC_DEFAULT) {
229                            smart_text(device, text_gc, curr->NodeInfo().c_str(), xo+20, yo);
230                        }
231                        smart_line(device, draw_gc, xi, yi, xo, yo);
232
233                        int sa = int(sinw*arrow_size+0.5);
234                        int ca = int(cosw*arrow_size+0.5);
235
236                        if (curr->Complement()) {
237                            int xa = xi-sa+ca;
238                            int ya = yi+ca+sa;
239                            smart_line(device, draw_gc, xi, yi, xa, ya);
240                        }
241                        else {
242                            int xa = xo+sa-ca;
243                            int ya = yo-ca-sa;
244                            smart_line(device, draw_gc, xo, yo, xa, ya);
245                        }
246                    }
247                    ++curr;
248                }
249                break;
250            }
251            case GEN_DISPLAY_STYLE_VERTICAL: {
252                double factor_x = aw_root->awar(AWAR_GENMAP_VERTICAL_FACTOR_X)->read_float();
253                double factor_y = aw_root->awar(AWAR_GENMAP_VERTICAL_FACTOR_Y)->read_float();
254                int    arrow_x  = int(factor_x*arrow_size);
255                int    arrow_y  = int(factor_y*arrow_size);
256
257                GEN_iterator curr = gene_set.begin();
258                GEN_iterator end  = gene_set.end();
259
260                while (curr != end) {
261                    int draw_gc, text_gc;
262                    if (getDrawGcs(curr, paint_what, gene_name, draw_gc, text_gc)) {
263                        int y         = int(curr->StartPos()*factor_y+0.5);
264                        int x2        = int(curr->Length()*factor_x+0.5);
265
266                        AW_click_cd cd(device, (AW_CL)&*curr);
267                        if (show_all_nds || text_gc != GEN_GC_DEFAULT) {
268                            smart_text(device, text_gc, curr->NodeInfo().c_str(), x2+20, y);
269                        }
270                        smart_line(device, draw_gc, 0, y, x2, y);
271                        if (curr->Complement()) {
272                            smart_line(device, draw_gc, 0, y, arrow_x, y-arrow_y);
273                        }
274                        else {
275                            smart_line(device, draw_gc, x2, y, x2-arrow_x, y-arrow_y);
276                        }
277                    }
278                    ++curr;
279                }
280                break;
281            }
282            case GEN_DISPLAY_STYLE_BOOK: {
283                int    display_width  = aw_root->awar(AWAR_GENMAP_BOOK_BASES_PER_LINE)->read_int();
284                double width_factor   = aw_root->awar(AWAR_GENMAP_BOOK_WIDTH_FACTOR)->read_float();
285                int    line_height    = aw_root->awar(AWAR_GENMAP_BOOK_LINE_HEIGHT)->read_int();
286                int    line_space     = aw_root->awar(AWAR_GENMAP_BOOK_LINE_SPACE)->read_int();
287                int    height_of_line = line_height+line_space;
288                int    xLeft          = 0;
289                int    xRight         = int(display_width*width_factor+0.5);
290                int    arrowMid       = line_height/2;
291
292                GEN_iterator curr = gene_set.begin();
293                GEN_iterator end  = gene_set.end();
294
295                while (curr != end) {
296                    int draw_gc, text_gc;
297                    if (getDrawGcs(curr, paint_what, gene_name, draw_gc, text_gc)) {
298                        int line1 = curr->StartPos()/display_width;
299                        int line2 = curr->EndPos()  / display_width;
300                        int x1    = int((curr->StartPos()-line1*display_width)*width_factor+0.5);
301                        int x2    = int((curr->EndPos()  -line2*display_width)*width_factor+0.5);
302                        int y1    = line1*height_of_line;
303                        int y1o   = y1-line_height;
304
305                        AW_click_cd cd(device, (AW_CL)&*curr);
306                        if (line1 == line2) { // whole gene in one book-line
307                            smart_line(device, draw_gc, x1, y1,  x1, y1o);
308                            smart_line(device, draw_gc, x2, y1,  x2, y1o);
309                            smart_line(device, draw_gc, x1, y1,  x2, y1);
310                            smart_line(device, draw_gc, x1, y1o, x2, y1o);
311                            if (show_all_nds || text_gc != GEN_GC_DEFAULT) smart_text(device, text_gc, curr->NodeInfo().c_str(), x1+2, y1-2);
312
313                            if (curr->Complement()) {
314                                smart_line(device, draw_gc, x2, y1o, x2-arrowMid, y1o+arrowMid);
315                                smart_line(device, draw_gc, x2, y1,  x2-arrowMid, y1o+arrowMid);
316                            }
317                            else {
318                                smart_line(device, draw_gc, x1, y1o,  x1+arrowMid, y1o+arrowMid);
319                                smart_line(device, draw_gc, x1, y1,   x1+arrowMid, y1o+arrowMid);
320                            }
321                        }
322                        else {
323                            int y2  = line2*height_of_line;
324                            int y2o = y2-line_height;
325
326                            // upper line (don't draw right border)
327                            smart_line(device, draw_gc, x1, y1,  x1,     y1o);
328                            smart_line(device, draw_gc, x1, y1,  xRight, y1);
329                            smart_line(device, draw_gc, x1, y1o, xRight, y1o);
330                            if (show_all_nds || text_gc != GEN_GC_DEFAULT) smart_text(device, text_gc, curr->NodeInfo().c_str(), x1+2, y1-2);
331
332                            // lower line (don't draw left border)
333                            smart_line(device, draw_gc, x2,    y2,  x2, y2o);
334                            smart_line(device, draw_gc, xLeft, y2,  x2, y2);
335                            smart_line(device, draw_gc, xLeft, y2o, x2, y2o);
336                            if (show_all_nds || text_gc != GEN_GC_DEFAULT) smart_text(device, text_gc, curr->NodeInfo().c_str(), xLeft+2, y2-2);
337
338                            if (curr->Complement()) {
339                                smart_line(device, draw_gc, x2, y2o, x2-arrowMid, y2o+arrowMid);
340                                smart_line(device, draw_gc, x2, y2,  x2-arrowMid, y2o+arrowMid);
341                            }
342                            else {
343                                smart_line(device, draw_gc, x1, y1o, x1+arrowMid, y1o+arrowMid);
344                                smart_line(device, draw_gc, x1, y1,  x1+arrowMid, y1o+arrowMid);
345                            }
346                        }
347                    }
348                    ++curr;
349                }
350                break;
351            }
352            default: {
353                gen_assert(0);
354                break;
355            }
356        }
357    }
358}
359
360void GEN_graphic::delete_gen_root(AWT_canvas *ntw) {
361    callback_installer(false, ntw, this);
362    delete gen_root;
363    gen_root = 0;
364}
365
366void GEN_graphic::reinit_gen_root(AWT_canvas *ntw, bool force_reinit) {
367    char *organism_name = aw_root->awar(AWAR_LOCAL_ORGANISM_NAME(window_nr))->read_string();
368    char *gene_name     = aw_root->awar(AWAR_LOCAL_GENE_NAME(window_nr))->read_string();
369
370    if (gen_root) {
371        if (force_reinit || (gen_root->OrganismName() != string(organism_name))) {
372            if (gen_root->OrganismName().length() == 0) {
373                want_zoom_reset = true; // no organism was displayed before
374            }
375            delete_gen_root(ntw);
376        }
377        if (gen_root && gen_root->GeneName() != string(gene_name)) {
378            gen_root->set_GeneName(gene_name);
379        }
380    }
381
382    if (!gen_root) {
383        gen_root = new GEN_root(organism_name, gene_name, gb_main, aw_root, this);
384        callback_installer(true, ntw, this);
385    }
386
387    free(organism_name);
388    free(gene_name);
389}
390
391void GEN_graphic::set_display_style(GEN_DisplayStyle type) {
392    style = type;
393
394    switch (style) {
395        case GEN_DISPLAY_STYLE_RADIAL: {
396            exports.dont_fit_x      = 0;
397            exports.dont_fit_y      = 0;
398            exports.dont_fit_larger = 0;
399            break;
400        }
401        case GEN_DISPLAY_STYLE_VERTICAL: {
402            exports.dont_fit_x      = 0;
403            exports.dont_fit_y      = 1;
404            exports.dont_fit_larger = 0;
405            break;
406        }
407        case GEN_DISPLAY_STYLE_BOOK: {
408            exports.dont_fit_x      = 0;
409            exports.dont_fit_y      = 1;
410            exports.dont_fit_larger = 0;
411            break;
412        }
413        default: {
414            gen_assert(0);
415            break;
416        }
417    }
418
419    want_zoom_reset = true;
420}
421
Note: See TracBrowser for help on using the repository browser.