source: tags/cvs_2_svn/GENOM/GEN_graphic.cxx

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