source: tags/ms_r16q2/GENOM/GEN_graphic.cxx

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