source: tags/testbuild/GENOM/GEN_graphic.cxx

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