source: tags/ms_r18q1/PHYLO/PH_display.cxx

Last change on this file was 16766, checked in by westram, 6 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.5 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : PH_display.cxx                                    //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include <arbdb.h>
12#include "phylo.hxx"
13#include "phwin.hxx"
14#include "PH_display.hxx"
15#include <aw_awar.hxx>
16#include <aw_msg.hxx>
17#include <aw_root.hxx>
18
19static void vertical_change_cb(AW_window *aww) {
20    PH_display::ph_display->monitor_vertical_scroll_cb(aww);
21}
22
23static void horizontal_change_cb(AW_window *aww) {
24    PH_display::ph_display->monitor_horizontal_scroll_cb(aww);
25}
26
27void ph_view_species_cb() {
28    AW_window *main_win = PH_used_windows::windowList->phylo_main_window;
29
30    PH_display::ph_display->initialize_display(DISP_SPECIES);
31    PH_display::ph_display->display();
32    main_win->set_vertical_change_callback(makeWindowCallback(vertical_change_cb));
33    main_win->set_horizontal_change_callback(makeWindowCallback(horizontal_change_cb));
34
35    // trigger automatic calculation on startup (if autocalc-toggle was saved as checked)
36    main_win->get_root()->awar(AWAR_PHYLO_FILTER_AUTOCALC)->touch();
37}
38
39GB_ERROR ph_check_initialized() {
40    if (!PHDATA::ROOT) return "Please select alignment and press DONE";
41    return NULp;
42}
43
44void ph_calc_filter_cb() {
45    GB_ERROR err = ph_check_initialized();
46    if (err) {
47        aw_message(err);
48    }
49    else {
50        AW_window *main_win  = PH_used_windows::windowList->phylo_main_window;
51        PH_filter *ph_filter = new PH_filter;
52
53        ph_filter->init(PHDATA::ROOT->get_seq_len());
54        PHDATA::ROOT->markerline=ph_filter->calculate_column_homology();
55        PH_display::ph_display->initialize_display(DISP_FILTER);
56        PH_display::ph_display->display();
57        main_win->set_vertical_change_callback(makeWindowCallback(vertical_change_cb));
58        main_win->set_horizontal_change_callback(makeWindowCallback(horizontal_change_cb));
59    }
60}
61
62
63PH_display::PH_display() {
64    memset((char *) this, 0, sizeof(PH_display));
65    this->display_what = DISP_NONE;
66}
67
68
69void PH_display::initialize_display(display_type dpyt) {
70    display_what = dpyt;
71    device=PH_used_windows::windowList->phylo_main_window->get_device(AW_MIDDLE_AREA);
72    if (!device) {
73        aw_message("could not get device !!");
74        return;
75    }
76    const AW_font_limits& lim = device->get_font_limits(0, 0);
77    switch (display_what) {
78        case DISP_NONE:
79            return;
80
81        case DISP_SPECIES:
82        case DISP_FILTER:
83            cell_width  = lim.width;
84            cell_height = lim.get_height()+5;
85            cell_offset = 3;
86
87            off_dx = SPECIES_NAME_LEN*lim.width+20;
88            off_dy = cell_height*3;
89
90            total_cells_vert  = PHDATA::ROOT->nentries;
91            set_scrollbar_steps(PH_used_windows::windowList->phylo_main_window, cell_width, cell_height, 50, 50);
92            break;
93    }
94    resized();  // initialize window_size dependent parameters
95}
96
97
98void PH_display::resized() {
99    const AW_screen_area& squ = PH_used_windows::windowList->phylo_main_window->get_device(AW_MIDDLE_AREA)-> get_area_size();
100    screen_width              = squ.r-squ.l;
101    screen_height             = squ.b-squ.t;
102
103    AW_screen_area rect =  { 0, 0, 0, 0 };
104    long         horiz_paint_size, vert_paint_size;
105    switch (display_what) {
106        case DISP_NONE:
107            return;
108
109        case DISP_SPECIES:
110            horiz_paint_size = (squ.r-off_dx)/cell_width;
111            vert_paint_size  = (squ.b-off_dy)/cell_height;
112            horiz_page_size  = (PHDATA::ROOT->get_seq_len() > horiz_paint_size) ? horiz_paint_size : PHDATA::ROOT->get_seq_len();
113            vert_page_size   = (long(PHDATA::ROOT->nentries) > vert_paint_size) ? vert_paint_size : PHDATA::ROOT->nentries;
114            rect.l           = 0;
115            rect.t           = 0;
116            rect.r           = (int) ((PHDATA::ROOT->get_seq_len()-horiz_page_size)*cell_width+squ.r);
117            rect.b           = (int) ((PHDATA::ROOT->nentries-vert_page_size)*cell_height+squ.b);
118            break;
119
120        case DISP_FILTER:
121            horiz_paint_size  = (squ.r-off_dx)/cell_width;
122            vert_paint_size   = (squ.b-off_dy)/cell_height;
123            vert_paint_size  -= (3/8)/cell_height + 2;
124            horiz_page_size   = (PHDATA::ROOT->get_seq_len() > horiz_paint_size) ? horiz_paint_size : PHDATA::ROOT->get_seq_len();
125            vert_page_size    = (long(PHDATA::ROOT->nentries) > vert_paint_size) ? vert_paint_size : PHDATA::ROOT->nentries;
126            rect.l            = 0;
127            rect.t            = 0;
128            rect.r            = (int) ((PHDATA::ROOT->get_seq_len()-horiz_page_size)*cell_width+squ.r);
129            rect.b            = (int) ((PHDATA::ROOT->nentries-vert_page_size)*cell_height+squ.b);
130            break;
131    }
132
133    horiz_page_start = 0; horiz_last_view_start = 0;
134    vert_page_start  = 0; vert_last_view_start  = 0;
135
136    device->reset();            // clip_size == device_size
137    device->clear(-1);
138    device->set_right_clip_border((int)(off_dx+cell_width*horiz_page_size));
139    device->reset();            // reset shift_x and shift_y
140
141    AW_window *pmw = PH_used_windows::windowList->phylo_main_window;
142    pmw->set_vertical_scrollbar_position(0);
143    pmw->set_horizontal_scrollbar_position(0);
144    pmw->tell_scrolled_picture_size(rect);
145    pmw->calculate_scrollbars();
146}
147
148
149
150void PH_display::display() { // draw area
151    char buf[50], cbuf[2];
152    long x, y, xpos, ypos;
153    AW_window *main_win = PH_used_windows::windowList->phylo_main_window;
154    long minhom;
155    long maxhom;
156    long startcol, stopcol;
157
158    if (!PHDATA::ROOT) return; // not correctly initialized yet
159
160    float *markerline = PHDATA::ROOT->markerline;
161
162    if (!device) return;
163
164    GB_transaction ta(PHDATA::ROOT->get_gb_main());
165    // be careful: text origin is lower left
166    if (display_what != DISP_NONE) {
167        device->shift(AW::Vector(off_dx, off_dy));
168        ypos      = 0;
169        long ymax = std::min(vert_page_start+vert_page_size, total_cells_vert);
170        for (y=vert_page_start; y<ymax; y++) {
171            // species names
172            device->text(PH_GC_SEQUENCE, PHDATA::ROOT->hash_elements[y]->name, -off_dx, ypos*cell_height-cell_offset);
173
174            // alignment
175            GBDATA     *gb_seq_data = PHDATA::ROOT->hash_elements[y]->gb_species_data_ptr;
176            const char *seq_data    = GB_read_char_pntr(gb_seq_data);
177            long        seq_len     = GB_read_count(gb_seq_data);
178
179            device->text(PH_GC_SEQUENCE, (horiz_page_start >= seq_len) ? "" : (seq_data+horiz_page_start), 0, ypos*cell_height-cell_offset);
180            ypos++;
181        }
182
183        if (display_what == DISP_FILTER) {
184            xpos    = 0;
185            cbuf[0] = '\0';
186            cbuf[1] = '\0';
187
188            const AW_font_limits& lim = device->get_font_limits(0, 0);
189
190            minhom   = main_win->get_root()->awar(AWAR_PHYLO_FILTER_MINHOM)->read_int();
191            maxhom   = main_win->get_root()->awar(AWAR_PHYLO_FILTER_MAXHOM)->read_int();
192            startcol = main_win->get_root()->awar(AWAR_PHYLO_FILTER_STARTCOL)->read_int();
193            stopcol  = main_win->get_root()->awar(AWAR_PHYLO_FILTER_STOPCOL)->read_int();
194
195            for (x = horiz_page_start; x < horiz_page_start + horiz_page_size; x++) {
196                int   gc = PH_GC_MARKER;
197                float ml = markerline[x];
198
199                if (x < startcol || x>stopcol) {
200                    gc = PH_GC_NOT_MARKER;
201                }
202                if (markerline[x] >= 0.0) {
203                    if (ml < minhom || ml > maxhom) {
204                        gc = PH_GC_NOT_MARKER;
205                    }
206                    sprintf(buf, "%3.0f", ml);
207                }
208                else {
209                    gc = PH_GC_NOT_MARKER;
210                    sprintf(buf, "XXX");
211                }
212
213                for (y = 0; y < 3; y++) {
214                    strncpy(cbuf, buf + y, 1);
215                    device->text(gc, cbuf, xpos * cell_width + 1, vert_page_size * cell_height + y * lim.get_height());
216                }
217                xpos++;
218            }
219        }
220        device->shift(-AW::Vector(off_dx, off_dy));
221    }
222}
223
224
225void PH_display::set_scrollbar_steps(AW_window *aww, long width_h, long width_v, long page_h, long page_v) {
226    aww->window_local_awar("scroll_width_horizontal")  ->write_int(width_h);
227    aww->window_local_awar("scroll_width_vertical")    ->write_int(width_v);
228    aww->window_local_awar("horizontal_page_increment")->write_int(page_h);
229    aww->window_local_awar("vertical_page_increment")  ->write_int(page_v);
230}
231
232
233void PH_display::monitor_vertical_scroll_cb(AW_window *aww) { // draw area
234    long diff;
235
236    if (!device) return;
237    if (vert_last_view_start==aww->slider_pos_vertical) return;
238
239    diff = (aww->slider_pos_vertical-vert_last_view_start)/cell_height;
240    // fast scroll: be careful: no transformation in move_region
241    if (diff==1) { // scroll one position up (== \/ arrow pressed)
242        device->move_region(0, off_dy, screen_width, vert_page_size*cell_height, 0, off_dy-cell_height);
243        device->clear_part(0, off_dy-cell_height+(vert_page_size-1)*cell_height+1, screen_width, cell_height, -1);
244        device->push_clip_scale();
245        device->set_top_clip_border((int)(off_dy+(vert_page_size-2)*cell_height));
246    }
247    else if (diff==-1) { // scroll one position down (== /\ arrow pressed)
248        device->move_region(0, off_dy-cell_height, screen_width, (vert_page_size-1)*cell_height+1, 0, off_dy);
249        device->clear_part(0, off_dy-cell_height, screen_width, cell_height, -1);
250        device->push_clip_scale();
251        device->set_bottom_clip_border((int)off_dy);
252    }
253    else  device->clear(-1);
254
255    vert_last_view_start = aww->slider_pos_vertical;
256    vert_page_start      = aww->slider_pos_vertical/cell_height;
257
258    display();
259    if ((diff==1) || (diff==-1)) device->pop_clip_scale();
260}
261
262void PH_display::monitor_horizontal_scroll_cb(AW_window *aww) { // draw area
263    long diff;
264
265    if (!device) return;
266    if (horiz_last_view_start==aww->slider_pos_horizontal) return;
267    diff=(aww->slider_pos_horizontal- horiz_last_view_start)/cell_width;
268    // fast scroll
269    if (diff==1) { // scroll one position left ( > arrow pressed)
270        device->move_region(off_dx+cell_width, 0, horiz_page_size*cell_width, screen_height, off_dx, 0);
271        device->clear_part(off_dx+(horiz_page_size-1)*cell_width, 0, cell_width, screen_height, -1);
272        device->push_clip_scale();
273        device->set_left_clip_border((int)((horiz_page_size-1)*cell_width));
274    }
275    else if (diff==-1) { // scroll one position right ( < arrow pressed)
276        device->move_region(off_dx, 0, (horiz_page_size-1)*cell_width, screen_height, off_dx+cell_width, 0);
277        device->clear_part(off_dx, 0, cell_width, screen_height, -1);
278        device->push_clip_scale();
279        device->set_right_clip_border((int)(off_dx+cell_width));
280    }
281    else device->clear(-1);
282
283    horiz_last_view_start=aww->slider_pos_horizontal;
284    horiz_page_start=aww->slider_pos_horizontal/cell_width;
285    display();
286    if ((diff==1) || (diff==-1)) device->pop_clip_scale();
287}
288
289PH_display_status::PH_display_status(AW_device *awd) {
290    device = awd;
291    if (!device) return;
292
293    const AW_font_limits& lim = device->get_font_limits(0, 0);
294
295    font_width  = lim.width;
296    font_height = lim.get_height();
297
298    device->reset();
299
300    const AW_screen_area& rect = device->get_area_size();
301
302    device->set_foreground_color(0, AW_WINDOW_FG);
303    max_x   = (rect.r-rect.l)/font_width;
304    max_y   = (rect.b-rect.t)/font_height;
305    x_pos   = 0.0;
306    y_pos   = 0.0;
307    tab_pos = x_pos;
308}
309
310void PH_display_status::write(const char *text) {
311    device->text(PH_GC_BOTTOM_TEXT, text, x_pos*font_width, y_pos*font_height);
312    x_pos+=strlen(text);
313}
314
315void PH_display_status::writePadded(const char *text, size_t len) {
316    device->text(PH_GC_BOTTOM_TEXT, text, x_pos*font_width, y_pos*font_height);
317    x_pos += len;
318}
319
320void PH_display_status::write(long numl) {
321    char buf[20];
322
323    sprintf(buf, "%ld", numl);
324    write(buf);
325}
326
327void PH_display_status::clear() {
328    device->clear(-1);
329}
330
331void display_status_cb() {
332    // bottom area
333    if (!PH_display::ph_display) return;
334    if (!PH_used_windows::windowList) return;
335
336    AW_root *aw_root = AW_root::SINGLETON;
337
338    {
339        static PH_display_status phds(PH_used_windows::windowList->phylo_main_window->get_device (AW_BOTTOM_AREA));
340        phds.clear();
341
342        const int LABEL_LEN = 21;
343
344        switch (PH_display::ph_display->displayed()) {
345            case DISP_NONE:
346                break;
347
348            case DISP_FILTER:
349            case DISP_SPECIES:
350                phds.set_origin();
351                phds.set_cursor(0, 0);
352                phds.write("FILTER STATUS REPORT:");
353                phds.newline();
354
355                phds.writePadded("Start at column:", LABEL_LEN);
356                phds.write((long)aw_root->awar(AWAR_PHYLO_FILTER_STARTCOL)->read_int());
357                phds.move_x(15);
358                phds.set_tab();
359                phds.writePadded("Stop at column:", LABEL_LEN);
360                phds.write((long)aw_root->awar(AWAR_PHYLO_FILTER_STOPCOL)->read_int());
361                phds.newline();
362
363                phds.writePadded("Minimal similarity:", LABEL_LEN);
364                phds.write((long)aw_root->awar(AWAR_PHYLO_FILTER_MINHOM)->read_int());
365                phds.set_cursor_x(phds.get_tab());
366                phds.writePadded("Maximal similarity:", LABEL_LEN);
367                phds.write((long)aw_root->awar(AWAR_PHYLO_FILTER_MAXHOM)->read_int());
368                phds.newline();
369                phds.newline();
370
371                phds.writePadded("'.':", LABEL_LEN);
372                phds.write(filter_text[aw_root->awar(AWAR_PHYLO_FILTER_DOT)->read_int()]);
373                phds.newline();
374
375                phds.writePadded("'-':", LABEL_LEN);
376                phds.write(filter_text[aw_root->awar(AWAR_PHYLO_FILTER_MINUS)->read_int()]);
377                phds.newline();
378
379                phds.writePadded("ambiguity codes:", LABEL_LEN);
380                phds.write(filter_text[aw_root->awar(AWAR_PHYLO_FILTER_AMBIG)->read_int()]);
381                phds.newline();
382
383                phds.writePadded("lowercase chars:", LABEL_LEN);
384                phds.write(filter_text[aw_root->awar(AWAR_PHYLO_FILTER_LOWER)->read_int()]);
385                break;
386        }
387    }
388}
389
Note: See TracBrowser for help on using the repository browser.