source: branches/profile/GENOM/GEN_graphic.cxx

Last change on this file was 11464, checked in by westram, 10 years ago
  • un-dummy-fied transaction (renames only)
  • 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    PAINT_NORMAL = PAINT_MIN,
145    PAINT_COLORED,
146    PAINT_MARKED,
147    PAINT_SELECTED,
148    PAINT_MAX    = PAINT_SELECTED,
149};
150
151inline bool getDrawGcs(GEN_iterator& gene, PaintWhat what, const string& curr_gene_name, int& draw_gc, int& text_gc) {
152    bool draw = false;
153    if (curr_gene_name == gene->Name()) { // current gene
154        draw_gc = text_gc = GEN_GC_CURSOR;
155        draw    = (what == PAINT_SELECTED);
156    }
157    else {
158        GBDATA *gb_gene = (GBDATA*)gene->GbGene();
159
160        if (GB_read_flag(gb_gene)) { // marked genes
161            draw_gc = text_gc = GEN_GC_MARKED;
162            draw    = (what == PAINT_MARKED);
163        }
164        else {
165            int color_group = AWT_gene_get_dominant_color(gb_gene);
166
167            if (color_group) {
168                draw_gc = text_gc = GEN_GC_FIRST_COLOR_GROUP+color_group-1;
169                draw    = (what == PAINT_COLORED);
170            }
171            else {
172                draw_gc = GEN_GC_GENE;
173                text_gc = GEN_GC_DEFAULT; // see show_all_nds in GEN_root::paint if you change this!!!
174                draw    = (what == PAINT_NORMAL);
175            }
176        }
177    }
178    return draw;
179}
180
181void GEN_root::paint(AW_device *device) {
182    if (error_reason.length()) {
183        device->text(GEN_GC_DEFAULT, error_reason.c_str(), 0, 0);
184        return;
185    }
186
187    clear_selected_range();
188
189    AW_root *aw_root      = gen_graphic->get_aw_root();
190    int      arrow_size   = aw_root->awar(AWAR_GENMAP_ARROW_SIZE)->read_int();
191    int      show_all_nds = aw_root->awar(AWAR_GENMAP_SHOW_ALL_NDS)->read_int();
192
193    for (PaintWhat paint_what = PAINT_MIN; paint_what <= PAINT_MAX; paint_what = PaintWhat((int(paint_what)+1))) {
194        switch (gen_graphic->get_display_style()) {
195            case GEN_DISPLAY_STYLE_RADIAL: {
196                double w0      = 2.0*M_PI/double(length);
197                double mp2     = M_PI/2;
198                double inside  = aw_root->awar(AWAR_GENMAP_RADIAL_INSIDE)->read_float()*1000;
199                double outside = aw_root->awar(AWAR_GENMAP_RADIAL_OUTSIDE)->read_float();
200
201                GEN_iterator curr = gene_set.begin();
202                GEN_iterator end  = gene_set.end();
203
204                while (curr != end) {
205                    int draw_gc, text_gc;
206                    if (getDrawGcs(curr, paint_what, gene_name, draw_gc, text_gc)) {
207                        double w    = w0*curr->StartPos()-mp2;
208                        double sinw = sin(w);
209                        double cosw = cos(w);
210                        int    len  = curr->Length();
211
212                        int xi = int(cosw*inside+0.5);
213                        int yi = int(sinw*inside+0.5);
214                        int xo = xi+int(cosw*outside*len+0.5);
215                        int yo = yi+int(sinw*outside*len+0.5);
216
217                        AW_click_cd cd(device, (AW_CL)&*curr);
218                        if (show_all_nds || text_gc != GEN_GC_DEFAULT) {
219                            smart_text(device, text_gc, curr->NodeInfo().c_str(), xo+20, yo);
220                        }
221                        smart_line(device, draw_gc, xi, yi, xo, yo);
222
223                        int sa = int(sinw*arrow_size+0.5);
224                        int ca = int(cosw*arrow_size+0.5);
225
226                        if (curr->Complement()) {
227                            int xa = xi-sa+ca;
228                            int ya = yi+ca+sa;
229                            smart_line(device, draw_gc, xi, yi, xa, ya);
230                        }
231                        else {
232                            int xa = xo+sa-ca;
233                            int ya = yo-ca-sa;
234                            smart_line(device, draw_gc, xo, yo, xa, ya);
235                        }
236                    }
237                    ++curr;
238                }
239                break;
240            }
241            case GEN_DISPLAY_STYLE_VERTICAL: {
242                double factor_x = aw_root->awar(AWAR_GENMAP_VERTICAL_FACTOR_X)->read_float();
243                double factor_y = aw_root->awar(AWAR_GENMAP_VERTICAL_FACTOR_Y)->read_float();
244                int    arrow_x  = int(factor_x*arrow_size);
245                int    arrow_y  = int(factor_y*arrow_size);
246
247                GEN_iterator curr = gene_set.begin();
248                GEN_iterator end  = gene_set.end();
249
250                while (curr != end) {
251                    int draw_gc, text_gc;
252                    if (getDrawGcs(curr, paint_what, gene_name, draw_gc, text_gc)) {
253                        int y         = int(curr->StartPos()*factor_y+0.5);
254                        int x2        = int(curr->Length()*factor_x+0.5);
255
256                        AW_click_cd cd(device, (AW_CL)&*curr);
257                        if (show_all_nds || text_gc != GEN_GC_DEFAULT) {
258                            smart_text(device, text_gc, curr->NodeInfo().c_str(), x2+20, y);
259                        }
260                        smart_line(device, draw_gc, 0, y, x2, y);
261                        if (curr->Complement()) {
262                            smart_line(device, draw_gc, 0, y, arrow_x, y-arrow_y);
263                        }
264                        else {
265                            smart_line(device, draw_gc, x2, y, x2-arrow_x, y-arrow_y);
266                        }
267                    }
268                    ++curr;
269                }
270                break;
271            }
272            case GEN_DISPLAY_STYLE_BOOK: {
273                int    display_width  = aw_root->awar(AWAR_GENMAP_BOOK_BASES_PER_LINE)->read_int();
274                double width_factor   = aw_root->awar(AWAR_GENMAP_BOOK_WIDTH_FACTOR)->read_float();
275                int    line_height    = aw_root->awar(AWAR_GENMAP_BOOK_LINE_HEIGHT)->read_int();
276                int    line_space     = aw_root->awar(AWAR_GENMAP_BOOK_LINE_SPACE)->read_int();
277                int    height_of_line = line_height+line_space;
278                int    xLeft          = 0;
279                int    xRight         = int(display_width*width_factor+0.5);
280                int    arrowMid       = line_height/2;
281
282                GEN_iterator curr = gene_set.begin();
283                GEN_iterator end  = gene_set.end();
284
285                while (curr != end) {
286                    int draw_gc, text_gc;
287                    if (getDrawGcs(curr, paint_what, gene_name, draw_gc, text_gc)) {
288                        int line1 = curr->StartPos()/display_width;
289                        int line2 = curr->EndPos()  / display_width;
290                        int x1    = int((curr->StartPos()-line1*display_width)*width_factor+0.5);
291                        int x2    = int((curr->EndPos()  -line2*display_width)*width_factor+0.5);
292                        int y1    = line1*height_of_line;
293                        int y1o   = y1-line_height;
294
295                        AW_click_cd cd(device, (AW_CL)&*curr);
296                        if (line1 == line2) { // whole gene in one book-line
297                            smart_line(device, draw_gc, x1, y1,  x1, y1o);
298                            smart_line(device, draw_gc, x2, y1,  x2, y1o);
299                            smart_line(device, draw_gc, x1, y1,  x2, y1);
300                            smart_line(device, draw_gc, x1, y1o, x2, y1o);
301                            if (show_all_nds || text_gc != GEN_GC_DEFAULT) smart_text(device, text_gc, curr->NodeInfo().c_str(), x1+2, y1-2);
302
303                            if (curr->Complement()) {
304                                smart_line(device, draw_gc, x2, y1o, x2-arrowMid, y1o+arrowMid);
305                                smart_line(device, draw_gc, x2, y1,  x2-arrowMid, y1o+arrowMid);
306                            }
307                            else {
308                                smart_line(device, draw_gc, x1, y1o,  x1+arrowMid, y1o+arrowMid);
309                                smart_line(device, draw_gc, x1, y1,   x1+arrowMid, y1o+arrowMid);
310                            }
311                        }
312                        else {
313                            int y2  = line2*height_of_line;
314                            int y2o = y2-line_height;
315
316                            // upper line (don't draw right border)
317                            smart_line(device, draw_gc, x1, y1,  x1,     y1o);
318                            smart_line(device, draw_gc, x1, y1,  xRight, y1);
319                            smart_line(device, draw_gc, x1, y1o, xRight, y1o);
320                            if (show_all_nds || text_gc != GEN_GC_DEFAULT) smart_text(device, text_gc, curr->NodeInfo().c_str(), x1+2, y1-2);
321
322                            // lower line (don't draw left border)
323                            smart_line(device, draw_gc, x2,    y2,  x2, y2o);
324                            smart_line(device, draw_gc, xLeft, y2,  x2, y2);
325                            smart_line(device, draw_gc, xLeft, y2o, x2, y2o);
326                            if (show_all_nds || text_gc != GEN_GC_DEFAULT) smart_text(device, text_gc, curr->NodeInfo().c_str(), xLeft+2, y2-2);
327
328                            if (curr->Complement()) {
329                                smart_line(device, draw_gc, x2, y2o, x2-arrowMid, y2o+arrowMid);
330                                smart_line(device, draw_gc, x2, y2,  x2-arrowMid, y2o+arrowMid);
331                            }
332                            else {
333                                smart_line(device, draw_gc, x1, y1o, x1+arrowMid, y1o+arrowMid);
334                                smart_line(device, draw_gc, x1, y1,  x1+arrowMid, y1o+arrowMid);
335                            }
336                        }
337                    }
338                    ++curr;
339                }
340                break;
341            }
342        }
343    }
344}
345
346void GEN_graphic::delete_gen_root(AWT_canvas *scr) {
347    callback_installer(false, scr, this);
348    delete gen_root;
349    gen_root = 0;
350}
351
352void GEN_graphic::reinit_gen_root(AWT_canvas *scr, bool force_reinit) {
353    char *organism_name = aw_root->awar(AWAR_LOCAL_ORGANISM_NAME(window_nr))->read_string();
354    char *gene_name     = aw_root->awar(AWAR_LOCAL_GENE_NAME(window_nr))->read_string();
355
356    if (gen_root) {
357        if (force_reinit || (gen_root->OrganismName() != string(organism_name))) {
358            if (gen_root->OrganismName().length() == 0) {
359                want_zoom_reset = true; // no organism was displayed before
360            }
361            delete_gen_root(scr);
362        }
363        if (gen_root && gen_root->GeneName() != string(gene_name)) {
364            gen_root->set_GeneName(gene_name);
365        }
366    }
367
368    if (!gen_root) {
369        gen_root = new GEN_root(organism_name, gene_name, gb_main, aw_root, this);
370        callback_installer(true, scr, this);
371    }
372
373    free(organism_name);
374    free(gene_name);
375}
376
377void GEN_graphic::set_display_style(GEN_DisplayStyle type) {
378    style = type;
379   
380    switch (style) {
381        case GEN_DISPLAY_STYLE_RADIAL:
382            exports.fit_mode = AWT_FIT_LARGER;
383            break;
384
385        case GEN_DISPLAY_STYLE_VERTICAL:
386        case GEN_DISPLAY_STYLE_BOOK:
387            exports.fit_mode = AWT_FIT_SMALLER;
388            break;
389    }
390
391    exports.zoom_mode = AWT_ZOOM_BOTH;
392    want_zoom_reset   = true;
393}
394
395
Note: See TracBrowser for help on using the repository browser.