source: branches/port5/GENOM/GEN_graphic.cxx

Last change on this file was 5942, checked in by westram, 16 years ago
  • added AW_window::activate (activates window using show() and sending _NET_ACTIVE_WINDOW to WM)
  • use activate in
    • standard popups (all menu/button popups using AW_POPUP)
    • special popup functions that don't bind window to menu/button
    • small requesters (aw_input, aw_question, …)
    • in popup-functions of information windows. But not if info-window is minimized and user just selects a new result in search window.
    • popup message window on each new message
  • no-exit-shells now popdown when X-Button is pressed (e.g. MESSAGE BOX)
  • fixed several special popup functions
  • renamed AW_window::get_show() → is_shown()
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.3 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 = false;
54    rot_cl.exists = 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                            GEN_create_gene_window(aw_root)->activate();
131                        }
132                    }
133                }
134                break;
135            }
136            default: {
137                gen_assert(0);
138                break;
139            }
140        }
141    }
142}
143
144inline void clear_selected_range(AW_world& selected_range) {
145    selected_range.r = selected_range.b = INT_MIN;
146    selected_range.l = selected_range.t = INT_MAX;
147}
148inline void increase_selected_range(AW_world& selected_range, AW_pos x, AW_pos y) {
149    if (x<selected_range.l) selected_range.l = x;
150    else if (x>selected_range.r) selected_range.r = x;
151    if (y<selected_range.t) selected_range.t = y;
152    else if (y>selected_range.b) selected_range.b = y;
153}
154inline void increase_selected_range(AW_world& selected_range, AW_pos x1, AW_pos y1, AW_pos x2, AW_pos y2) {
155    increase_selected_range(selected_range, x1, y1);
156    increase_selected_range(selected_range, x2, y2);
157}
158inline 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) {
159    int res = device->text(gc, str, x, y, alignment, filteri, cd1, cd2, opt_strlen);
160    if (gc == GEN_GC_CURSOR) {
161#if defined(DEVEL_RALF)
162#warning implementation missing
163#endif // DEVEL_RALF
164        // @@@ FIXME: detect text size and increase_selected_range
165    }
166    return res;
167}
168inline 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) {
169    int res = device->line(gc, x0, y0, x1, y1, filteri, cd1, cd2);
170    if (gc == GEN_GC_CURSOR) increase_selected_range(selected_range, x0, y0, x1, y1);
171    return res;
172}
173
174enum PaintWhat {
175    PAINT_MIN,
176    PAINT_NORMAL = PAINT_MIN,
177    PAINT_COLORED,
178    PAINT_MARKED,
179    PAINT_SELECTED,
180    PAINT_MAX    = PAINT_SELECTED,
181};
182
183inline bool getDrawGcs(GEN_iterator& gene, PaintWhat what, const string& curr_gene_name, int& draw_gc, int& text_gc) {
184    bool draw = false;
185    if (curr_gene_name == gene->Name()) { // current gene
186        draw_gc = text_gc = GEN_GC_CURSOR;
187        draw    = (what == PAINT_SELECTED);
188    }
189    else {
190        GBDATA *gb_gene = (GBDATA*)gene->GbGene();
191
192        if (GB_read_flag(gb_gene)) { // marked genes
193            draw_gc = text_gc = GEN_GC_MARKED;
194            draw    = (what == PAINT_MARKED);
195        }
196        else {
197            int color_group = AWT_gene_get_dominant_color(gb_gene);
198            // int color_group = AW_find_color_group(gb_gene);
199
200            if (color_group) {
201                draw_gc = text_gc = GEN_GC_FIRST_COLOR_GROUP+color_group-1;
202                draw    = (what == PAINT_COLORED);
203            }
204            else {
205                draw_gc = GEN_GC_GENE;
206                text_gc = GEN_GC_DEFAULT; // see show_all_nds in GEN_root::paint if you change this!!!
207                draw    = (what == PAINT_NORMAL);
208            }
209        }
210    }
211    return draw;
212}
213
214void GEN_root::paint(AW_device *device) {
215    if (error_reason.length()) {
216        device->text(GEN_GC_DEFAULT, error_reason.c_str(), 0, 0, 0.0, -1, 0, 0, 0);
217        return;
218    }
219
220    clear_selected_range(selected_range);
221
222    AW_root *aw_root      = gen_graphic->get_aw_root();
223    int      arrow_size   = aw_root->awar(AWAR_GENMAP_ARROW_SIZE)->read_int();
224    int      show_all_nds = aw_root->awar(AWAR_GENMAP_SHOW_ALL_NDS)->read_int();
225
226    for (PaintWhat paint_what = PAINT_MIN; paint_what <= PAINT_MAX; paint_what = PaintWhat((int(paint_what)+1))) {
227        switch (gen_graphic->get_display_style()) {
228            case GEN_DISPLAY_STYLE_RADIAL: {
229                double w0      = 2.0*M_PI/double(length);
230                double mp2     = M_PI/2;
231                double inside  = aw_root->awar(AWAR_GENMAP_RADIAL_INSIDE)->read_float()*1000;
232                double outside = aw_root->awar(AWAR_GENMAP_RADIAL_OUTSIDE)->read_float();
233
234                GEN_iterator curr = gene_set.begin();
235                GEN_iterator end  = gene_set.end();
236
237                while (curr != end) {
238                    int draw_gc, text_gc;
239                    if (getDrawGcs(curr, paint_what, gene_name, draw_gc, text_gc)) {
240                    // if (paint_what || text_gc != GEN_GC_DEFAULT) {
241                        double w    = w0*curr->StartPos()-mp2;
242                        double sinw = sin(w);
243                        double cosw = cos(w);
244                        int    len  = curr->Length();
245
246                        int xi = int(cosw*inside+0.5);
247                        int yi = int(sinw*inside+0.5);
248                        int xo = xi+int(cosw*outside*len+0.5);
249                        int yo = yi+int(sinw*outside*len+0.5);
250
251                        if (show_all_nds || text_gc != GEN_GC_DEFAULT) {
252                            smart_text(selected_range, device, text_gc, curr->NodeInfo().c_str(), xo+20, yo, 0.0, -1, (AW_CL)(&*curr), 0, 0);
253                        }
254                        smart_line(selected_range, device, draw_gc, xi, yi, xo, yo, -1, (AW_CL)(&*curr), 0);
255
256                        int sa = int(sinw*arrow_size+0.5);
257                        int ca = int(cosw*arrow_size+0.5);
258
259                        if (curr->Complement()) {
260                            int xa = xi-sa+ca;
261                            int ya = yi+ca+sa;
262                            smart_line(selected_range, device, draw_gc, xi, yi, xa, ya, -1, (AW_CL)(&*curr), 0);
263                        }
264                        else {
265                            int xa = xo+sa-ca;
266                            int ya = yo-ca-sa;
267                            smart_line(selected_range, device, draw_gc, xo, yo, xa, ya, -1, (AW_CL)(&*curr), 0);
268                        }
269                    }
270                    ++curr;
271                }
272                break;
273            }
274            case GEN_DISPLAY_STYLE_VERTICAL: {
275                double factor_x = aw_root->awar(AWAR_GENMAP_VERTICAL_FACTOR_X)->read_float();
276                double factor_y = aw_root->awar(AWAR_GENMAP_VERTICAL_FACTOR_Y)->read_float();
277                int    arrow_x  = int(factor_x*arrow_size);
278                int    arrow_y  = int(factor_y*arrow_size);
279
280                GEN_iterator curr = gene_set.begin();
281                GEN_iterator end  = gene_set.end();
282               
283                while (curr != end) {
284                    int draw_gc, text_gc;
285                    if (getDrawGcs(curr, paint_what, gene_name, draw_gc, text_gc)) {
286                        int y         = int(curr->StartPos()*factor_y+0.5);
287                        int x2        = int(curr->Length()*factor_x+0.5);
288
289                        if (show_all_nds || text_gc != GEN_GC_DEFAULT) {
290                            smart_text(selected_range, device, text_gc, curr->NodeInfo().c_str(), x2+20, y, 0.0, -1, (AW_CL)(&*curr), 0, 0);
291                        }
292                        smart_line(selected_range, device, draw_gc, 0, y, x2, y, -1, (AW_CL)(&*curr), 0);
293                        if (curr->Complement()) {
294                            smart_line(selected_range, device, draw_gc, 0, y, arrow_x, y-arrow_y, -1, (AW_CL)(&*curr), 0);
295                        }
296                        else {
297                            smart_line(selected_range, device, draw_gc, x2, y, x2-arrow_x, y-arrow_y, -1, (AW_CL)(&*curr), 0);
298                        }
299                    }
300                    ++curr;
301                }
302                break;
303            }
304            case GEN_DISPLAY_STYLE_BOOK: {
305                int    display_width  = aw_root->awar(AWAR_GENMAP_BOOK_BASES_PER_LINE)->read_int();
306                double width_factor   = aw_root->awar(AWAR_GENMAP_BOOK_WIDTH_FACTOR)->read_float();
307                int    line_height    = aw_root->awar(AWAR_GENMAP_BOOK_LINE_HEIGHT)->read_int();
308                int    line_space     = aw_root->awar(AWAR_GENMAP_BOOK_LINE_SPACE)->read_int();
309                int    height_of_line = line_height+line_space;
310                int    xLeft          = 0;
311                int    xRight         = int(display_width*width_factor+0.5);
312                int    arrowMid       = line_height/2;
313
314                GEN_iterator curr = gene_set.begin();
315                GEN_iterator end  = gene_set.end();
316               
317                while (curr != end) {
318                    int draw_gc, text_gc;
319                    if (getDrawGcs(curr, paint_what, gene_name, draw_gc, text_gc)) {
320                        int line1 = curr->StartPos()/display_width;
321                        int line2 = curr->EndPos()  /display_width;
322                        int x1    = int((curr->StartPos()-line1*display_width)*width_factor+0.5);
323                        int x2    = int((curr->EndPos()  -line2*display_width)*width_factor+0.5);
324                        int y1    = line1*height_of_line;
325                        int y1o   = y1-line_height;
326
327                        if (line1 == line2) { // whole gene in one book-line
328                            smart_line(selected_range, device, draw_gc, x1, y1,  x1, y1o, -1, (AW_CL)(&*curr), 0);
329                            smart_line(selected_range, device, draw_gc, x2, y1,  x2, y1o, -1, (AW_CL)(&*curr), 0);
330                            smart_line(selected_range, device, draw_gc, x1, y1,  x2, y1,  -1, (AW_CL)(&*curr), 0);
331                            smart_line(selected_range, device, draw_gc, x1, y1o, x2, y1o, -1, (AW_CL)(&*curr), 0);
332                            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);
333
334                            if (curr->Complement()) {
335                                smart_line(selected_range, device, draw_gc, x2, y1o, x2-arrowMid, y1o+arrowMid, -1, (AW_CL)(&*curr), 0);
336                                smart_line(selected_range, device, draw_gc, x2, y1,  x2-arrowMid, y1o+arrowMid, -1, (AW_CL)(&*curr), 0);
337                            }
338                            else {
339                                smart_line(selected_range, device, draw_gc, x1, y1o,  x1+arrowMid, y1o+arrowMid, -1, (AW_CL)(&*curr), 0);
340                                smart_line(selected_range, device, draw_gc, x1, y1,   x1+arrowMid, y1o+arrowMid, -1, (AW_CL)(&*curr), 0);
341                            }
342                        }
343                        else {
344                            int y2  = line2*height_of_line;
345                            int y2o = y2-line_height;
346
347                            // upper line (don't draw right border)
348                            smart_line(selected_range, device, draw_gc, x1, y1,  x1,     y1o, -1, (AW_CL)(&*curr), 0);
349                            smart_line(selected_range, device, draw_gc, x1, y1,  xRight, y1,  -1, (AW_CL)(&*curr), 0);
350                            smart_line(selected_range, device, draw_gc, x1, y1o, xRight, y1o, -1, (AW_CL)(&*curr), 0);
351                            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);
352
353                            // lower line (don't draw left border)
354                            smart_line(selected_range, device, draw_gc, x2,    y2,  x2, y2o, -1, (AW_CL)(&*curr), 0);
355                            smart_line(selected_range, device, draw_gc, xLeft, y2,  x2, y2,  -1, (AW_CL)(&*curr), 0);
356                            smart_line(selected_range, device, draw_gc, xLeft, y2o, x2, y2o, -1, (AW_CL)(&*curr), 0);
357                            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);
358
359                            if (curr->Complement()) {
360                                smart_line(selected_range, device, draw_gc, x2, y2o, x2-arrowMid, y2o+arrowMid, -1, (AW_CL)(&*curr), 0);
361                                smart_line(selected_range, device, draw_gc, x2, y2,  x2-arrowMid, y2o+arrowMid, -1, (AW_CL)(&*curr), 0);
362                            }
363                            else {
364                                smart_line(selected_range, device, draw_gc, x1, y1o, x1+arrowMid, y1o+arrowMid, -1, (AW_CL)(&*curr), 0);
365                                smart_line(selected_range, device, draw_gc, x1, y1,  x1+arrowMid, y1o+arrowMid, -1, (AW_CL)(&*curr), 0);
366                            }
367                        }
368                    }
369                    ++curr;
370                }
371                break;
372            }
373            default: {
374                gen_assert(0);
375                break;
376            }
377        }
378    }
379}
380
381void GEN_graphic::delete_gen_root(AWT_canvas *ntw) {
382    callback_installer(false, ntw, this);
383    delete gen_root;
384    gen_root = 0;
385}
386
387void GEN_graphic::reinit_gen_root(AWT_canvas *ntw, bool force_reinit) {
388    char *organism_name = aw_root->awar(AWAR_LOCAL_ORGANISM_NAME(window_nr))->read_string();
389    char *gene_name     = aw_root->awar(AWAR_LOCAL_GENE_NAME(window_nr))->read_string();
390
391    if (gen_root) {
392        if (force_reinit || (gen_root->OrganismName() != string(organism_name))) {
393            if (gen_root->OrganismName().length() == 0) {
394                want_zoom_reset = true; // no organism was displayed before
395            }
396            delete_gen_root(ntw);
397        }
398        if (gen_root && gen_root->GeneName() != string(gene_name)) {
399            gen_root->set_GeneName(gene_name);
400        }
401    }
402
403    if (!gen_root) {
404        gen_root = new GEN_root(organism_name, gene_name, gb_main, aw_root, this);
405        callback_installer(true, ntw, this);
406    }
407
408    free(organism_name);
409    free(gene_name);
410}
411
412void GEN_graphic::set_display_style(GEN_DisplayStyle type) {
413    style = type;
414
415    switch (style) {
416        case GEN_DISPLAY_STYLE_RADIAL: {
417            exports.dont_fit_x      = 0;
418            exports.dont_fit_y      = 0;
419            exports.dont_fit_larger = 0;
420            break;
421        }
422        case GEN_DISPLAY_STYLE_VERTICAL: {
423            exports.dont_fit_x      = 0;
424            exports.dont_fit_y      = 1;
425            exports.dont_fit_larger = 0;
426            break;
427        }
428        case GEN_DISPLAY_STYLE_BOOK: {
429            exports.dont_fit_x      = 0;
430            exports.dont_fit_y      = 1;
431            exports.dont_fit_larger = 0;
432            break;
433        }
434        default: {
435            gen_assert(0);
436            break;
437        }
438    }
439
440    want_zoom_reset = true;
441}
442
Note: See TracBrowser for help on using the repository browser.