source: tags/ms_r16q3/EDIT4/ED4_text_terminals.cxx

Last change on this file was 15288, checked in by westram, 8 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 26.5 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : ED4_text_terminals.cxx                            //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include <ed4_extern.hxx>
12
13#include "ed4_class.hxx"
14#include "ed4_awars.hxx"
15#include "ed4_edit_string.hxx"
16#include "ed4_block.hxx"
17#include "ed4_nds.hxx"
18#include "ed4_visualizeSAI.hxx"
19#include "ed4_ProteinViewer.hxx"
20#include "ed4_protein_2nd_structure.hxx"
21#include "ed4_seq_colors.hxx"
22
23#include <aw_preset.hxx>
24#include <aw_awar.hxx>
25
26#include <AW_helix.hxx>
27#include <aw_msg.hxx>
28#include <aw_root.hxx>
29
30#include <st_window.hxx>
31#include <arbdbt.h>
32#include <ad_colorset.h>
33
34#include <iostream>
35
36inline void ensure_buffer(char*& buffer, size_t& buffer_size, size_t needed) {
37    if (needed>buffer_size) {
38        delete [] buffer;
39        buffer_size = needed+10;
40        buffer      = new char[buffer_size];
41
42        memset(buffer, ' ', buffer_size-1);
43        buffer[buffer_size-1] = 0;
44    }
45}
46
47void ED4_consensus_sequence_terminal::draw() {
48    static char   *buffer      = 0;
49    static size_t  buffer_size = 0;
50
51    AW_pos x, y;
52    calc_world_coords(&x, &y);
53    current_ed4w()->world_to_win_coords(&x, &y);
54
55    PosRange index_range = calc_update_interval();
56    if (index_range.is_empty()) return; // nothing to draw
57
58    AW_pos text_x = x + CHARACTEROFFSET; // don't change
59    AW_pos text_y = y + SEQ_TERM_TEXT_YOFFSET;
60
61    buffer_size = 0;
62
63    if (index_range.is_unlimited()) {
64        e4_assert(MAXSEQUENCECHARACTERLENGTH == 0); // allow missing update interval when no seqdata is present (yet)
65
66        const char *no_data = "No consensus data";
67        size_t      len     = strlen(no_data);
68        ensure_buffer(buffer, buffer_size, len+1);
69        memcpy(buffer, no_data, len);
70
71        index_range = ExplicitRange(index_range, buffer_size-1);
72    }
73    else {
74        const ED4_remap *rm = ED4_ROOT->root_group_man->remap();
75       
76        index_range = rm->clip_screen_range(index_range);
77        if (index_range.is_empty()) return; // nothing to draw
78
79        ExplicitRange seq_range = ExplicitRange(rm->screen_to_sequence(index_range), MAXSEQUENCECHARACTERLENGTH);
80        index_range             = rm->sequence_to_screen(seq_range);
81
82        char *cons = 0;
83        if (!seq_range.is_empty()) {
84            cons = GB_give_buffer(seq_range.size()+1);
85            get_char_table().build_consensus_string_to(cons, seq_range, ED4_ROOT->get_consensus_params());
86        }
87
88        ensure_buffer(buffer, buffer_size, index_range.end()+1);
89
90        ED4_reference *ref            = ED4_ROOT->reference;
91        bool           only_show_diff = ref->only_show_diff_for(this);
92
93        for (int pos = index_range.start(); pos <= index_range.end(); ++pos) {
94            int seq_pos = rm->screen_to_sequence(pos);
95            if (seq_pos<0) {
96                buffer[pos] = ' ';
97            }
98            else {
99                char c      = cons[seq_pos-seq_range.start()];
100                buffer[pos] = only_show_diff ? ref->convert(c, seq_pos) : c;
101                e4_assert(buffer[pos]);
102            }
103        }
104    }
105
106    if (buffer_size) {
107        current_device()->set_vertical_font_overlap(true);
108        current_device()->text(ED4_G_SEQUENCES, buffer, text_x, text_y, 0, AW_SCREEN, index_range.end()+1);
109        current_device()->set_vertical_font_overlap(false);
110    }
111}
112
113struct ShowHelix_cd {
114    AW_helix *helix;
115    int       real_sequence_length;
116};
117
118static bool ED4_show_helix_on_device(AW_device *device, int gc, const char *opt_string, size_t /*opt_string_size*/, size_t start, size_t size,
119                                     AW_pos x, AW_pos y, AW_pos /*opt_ascent*/, AW_pos /*opt_descent*/,
120                                     AW_CL cduser) // , AW_CL real_sequence_length, AW_CL cd2)
121{
122    ShowHelix_cd    *cd     = (ShowHelix_cd*)cduser;
123    AW_helix        *helix  = cd->helix;
124    const ED4_remap *rm     = ED4_ROOT->root_group_man->remap();
125    char            *buffer = GB_give_buffer(size+1);
126    long             i, j, k;
127
128    size = std::min(rm->get_max_screen_pos(), size);
129
130    for (k=0; size_t(k)<size; k++) {
131        i = rm->screen_to_sequence(k+start);
132
133        BI_PAIR_TYPE pairType = helix->pairtype(i);
134        if (pairType == HELIX_NONE) {
135            buffer[k] = ' ';
136        }
137        else {
138            j             = helix->opposite_position(i);
139            char pairchar = j<cd->real_sequence_length ? opt_string[j] : '.';
140            buffer[k]     = helix->get_symbol(opt_string[i], pairchar, pairType);
141        }
142    }
143    buffer[size] = 0;
144    return device->text(gc, buffer, x, y);
145}
146
147static bool ED4_show_protein_match_on_device(AW_device *device, int gc, const char *protstruct, size_t /* protstruct_len */, size_t start, size_t size,
148                                             AW_pos x, AW_pos y, AW_pos /* opt_ascent */, AW_pos /* opt_descent */,
149                                             AW_CL cl_protstruct) // , AW_CL /* real_sequence_length */, AW_CL cd2)
150{
151    /*! \brief Calls ED4_pfold_calculate_secstruct_match() for the visible area in the
152     *         editor to compute the protein secondary structure match and outputs the
153     *         result to the device.
154     *  \param[in] protstruct    The protein structure (primary or secondary) that should be compared to \a cl_protstruct
155     *  \param[in] cl_protstruct The reference protein secondary structure SAI
156     */
157
158    GB_ERROR error = 0;
159    // TODO: proper use of ED4_remap?
160    const ED4_remap *rm = ED4_ROOT->root_group_man->remap();
161    char *buffer = GB_give_buffer(size+1);
162    if (!buffer) {
163        error = GB_export_error("Out of memory.");
164    }
165    else {
166        error = ED4_pfold_calculate_secstruct_match((const unsigned char *)cl_protstruct,
167                                                    (const unsigned char *)protstruct,
168                                                    rm->screen_to_sequence(start),
169                                                    rm->screen_to_sequence(start + size),
170                                                    buffer,
171                                                    (PFOLD_MATCH_METHOD)ED4_ROOT->aw_root->awar(PFOLD_AWAR_MATCH_METHOD)->read_int());
172    }
173    if (error) {
174        aw_message(error);
175        return false;
176    }
177   
178    buffer[size] = 0;
179    return device->text(gc, buffer, x, y);
180}
181
182void ED4_orf_terminal::draw() {
183    // draw aminoacid ORFs below the DNA sequence
184
185    static int    color_is_used[ED4_G_DRAG];
186    static char **colored_strings        = 0;
187    static int    len_of_colored_strings = 0;
188
189    AW_device *device = current_device();
190
191    // @@@ DRY calculation of index-range to-be-updated (done in several draw functions)
192    AW_pos world_x, world_y;
193    calc_world_coords(&world_x, &world_y);
194    current_ed4w()->world_to_win_coords(&world_x, &world_y);
195
196    AW_pos text_x = world_x + CHARACTEROFFSET; // don't change
197    AW_pos text_y = world_y + SEQ_TERM_TEXT_YOFFSET;
198
199    const ED4_remap *rm = ED4_ROOT->root_group_man->remap();
200
201    ExplicitRange index_range = rm->clip_screen_range(calc_update_interval());
202    {
203        int max_seq_len = aaSeqLen;
204        int max_seq_pos = rm->sequence_to_screen(max_seq_len-1);
205        index_range     = ExplicitRange(PosRange(index_range), max_seq_pos);
206    }
207
208    if (index_range.is_empty()) {
209        // @@@ looks wrong (index_range is empty depending on updated area!)
210        // compare to .@DRAW_WRONG_MESSAGE
211
212        const char *no_data = "No sequence data";
213        size_t      len     = strlen(no_data);
214
215        device->text(ED4_G_STANDARD, no_data, text_x, text_y, 0, AW_SCREEN, len);
216        return; // nothing to draw
217    }
218
219    if (index_range.end() >= len_of_colored_strings) {
220        len_of_colored_strings = index_range.end() + 256;
221        if (!colored_strings) ARB_calloc(colored_strings, ED4_G_DRAG);
222
223        for (int i=0; i<ED4_G_DRAG; i++) {
224            freeset(colored_strings[i], ARB_alloc<char>(len_of_colored_strings+1));
225            memset(colored_strings[i], ' ', len_of_colored_strings);
226            colored_strings[i][len_of_colored_strings] = 0;
227        }
228    }
229
230    int seq_end = rm->screen_to_sequence(index_range.end());
231
232    // mark all strings as unused
233    memset(color_is_used, 0, sizeof(color_is_used));
234
235    int iDisplayMode = ED4_ROOT->aw_root->awar(AWAR_PROTVIEW_DISPLAY_OPTIONS)->read_int();
236    {
237        const unsigned char *aaSequence_u = (const unsigned char *)aaSequence;
238        const unsigned char *aaColor_u    = (const unsigned char *)aaColor;
239
240        if (iDisplayMode == PV_AA_NAME || iDisplayMode == PV_AA_CODE) {
241            // transform strings, compress if needed
242            ED4_reference *ref = ED4_ROOT->reference;
243            ref->expand_to_length(seq_end);
244
245            char *char_2_char = ED4_ROOT->sequence_colors->char_2_char_aa;
246            char *char_2_gc   = ED4_ROOT->sequence_colors->char_2_gc_aa;
247
248            if (iDisplayMode == PV_AA_NAME) {
249                for (int scr_pos=index_range.start(); scr_pos <= index_range.end(); scr_pos++) {
250                    int           seq_pos = rm->screen_to_sequence(scr_pos);
251                    unsigned char c       = aaSequence_u[seq_pos];
252                    unsigned char cc      = aaColor_u[seq_pos];
253                    int           gc      = char_2_gc[safeCharIndex(cc)];
254
255                    color_is_used[gc] = scr_pos+1;
256                    colored_strings[gc][scr_pos] = char_2_char[safeCharIndex(c)];
257                }
258            }
259            else {
260                for (int scr_pos=index_range.start(); scr_pos <= index_range.end(); scr_pos++) {
261                    int  seq_pos = rm->screen_to_sequence(scr_pos);
262                    char c       = aaSequence_u[seq_pos];
263                    int  gc      = char_2_gc[safeCharIndex(c)];
264
265                    color_is_used[gc] = scr_pos+1;
266                    colored_strings[gc][scr_pos] = char_2_char[safeCharIndex(c)];
267                }
268            }
269        }
270
271        // paint background
272        if ((iDisplayMode == PV_AA_CODE) || (iDisplayMode == PV_AA_BOX)) {
273            AW_pos     width        = ED4_ROOT->font_group.get_width(ED4_G_SEQUENCES);
274            const int  real_left    = index_range.start();
275            const int  real_right   = index_range.end();
276            AW_pos     x2           = text_x + width*real_left;
277            AW_pos     y1           = world_y;
278            AW_pos     y2           = text_y+1;
279            AW_pos     height       = y2-y1+1;
280            int        color        = ED4_G_STANDARD;
281            char      *char_2_gc_aa = ED4_ROOT->sequence_colors->char_2_gc_aa;
282
283            for (int i = real_left; i <= real_right; i++, x2 += width) {
284                int  new_pos = rm->screen_to_sequence(i); // getting the real position of the base in the sequence
285                char base    = aaSequence_u[new_pos];
286
287                if (isupper(base) || (base=='*')) {
288                    AW_pos x1  = x2-width; // store current x pos to x1
289                    x2 += width*2; // add 2 char width to x2
290                    i  += 2; // jump two pos
291
292                    int gcChar =  char_2_gc_aa[safeCharIndex(base)];
293                    if ((gcChar>=0) && (gcChar<ED4_G_DRAG)) {
294                        color = gcChar;
295                        if (iDisplayMode == PV_AA_BOX) {
296                            device->box(color, AW::FillStyle::SOLID, x1, y1, width*3, height);
297                        }
298                        else {
299                            double    rad_x    = width*1.5;
300                            double    rad_y    = height*0.7;
301                            double    center_x = x1+rad_x;
302                            const int DRAW_DEG = 62;
303
304                            device->arc(ED4_G_SEQUENCES, AW::FillStyle::EMPTY, center_x, y1, rad_x, rad_y,   0,  DRAW_DEG);
305                            device->arc(ED4_G_SEQUENCES, AW::FillStyle::EMPTY, center_x, y1, rad_x, rad_y, 180, -DRAW_DEG);
306                        }
307                    }
308                }
309            }
310        }
311    }
312
313    if ((iDisplayMode == PV_AA_NAME) || (iDisplayMode == PV_AA_CODE)) {
314        device->set_vertical_font_overlap(true);
315        // output strings
316        for (int gc = 0; gc < ED4_G_DRAG; gc++) {
317            if (color_is_used[gc] && (int)strlen(colored_strings[gc]) >= color_is_used[gc]) {
318                device->text(gc, colored_strings[gc], text_x, text_y, 0, AW_SCREEN, color_is_used [gc]);
319                memset(colored_strings[gc] + index_range.start(), ' ', index_range.size()); // clear string
320            }
321        }
322        device->set_vertical_font_overlap(false);
323    }
324}
325
326void ED4_sequence_terminal::draw() {
327    static int    color_is_used[ED4_G_DRAG];
328    static char **colored_strings        = 0;
329    static int    len_of_colored_strings = 0;
330
331#if defined(TRACE_REFRESH)
332    fprintf(stderr, "ED4_sequence_terminal::draw for id='%s'\n", id); fflush(stderr);
333#endif
334
335    AW_device *device = current_device();
336
337    int max_seq_len;
338    resolve_pointer_to_char_pntr(&max_seq_len);
339    e4_assert(max_seq_len>0);
340
341    AW_pos world_x, world_y;
342    calc_world_coords(&world_x, &world_y);
343    current_ed4w()->world_to_win_coords(&world_x, &world_y);
344
345    AW_pos text_x = world_x + CHARACTEROFFSET;    // don't change
346    AW_pos text_y = world_y + SEQ_TERM_TEXT_YOFFSET;
347
348    const ED4_remap *rm = ED4_ROOT->root_group_man->remap();
349
350    ExplicitRange index_range = rm->clip_screen_range(calc_update_interval());
351    if (index_range.is_empty()) return; // nothing to draw
352
353    int left  = index_range.start(); // @@@ do similar to ED4_orf_terminal::draw here
354    int right = index_range.end();
355
356    {
357        int max_seq_pos = rm->sequence_to_screen(max_seq_len-1);
358
359        if (right>max_seq_len) right = max_seq_pos;
360        if (left>right) {
361            // @@@ may be correct here
362            // compare to .@DRAW_WRONG_MESSAGE
363
364            const char *no_data = "No sequence data";
365            size_t      len     = strlen(no_data);
366
367            device->text(ED4_G_STANDARD, no_data, text_x, text_y, 0, AW_SCREEN, len);
368            return; // nothing to draw
369        }
370    }
371
372    if (right >= len_of_colored_strings) {
373        len_of_colored_strings = right + 256;
374        if (!colored_strings) ARB_calloc(colored_strings, ED4_G_DRAG);
375
376        for (int i=0; i<ED4_G_DRAG; i++) {
377            freeset(colored_strings[i], (char *)malloc(sizeof(char) * (len_of_colored_strings+1)));
378            memset(colored_strings[i], ' ', len_of_colored_strings);
379            colored_strings[i][len_of_colored_strings] = 0;
380        }
381    }
382
383    int seq_start = rm->screen_to_sequence(left); // real start of sequence
384    int seq_end = rm->screen_to_sequence(right);
385
386    // mark all strings as unused
387    memset(color_is_used, 0, sizeof(color_is_used));
388
389    // transform strings, compress if needed
390    {
391        ED4_reference *ref        = ED4_ROOT->reference;
392        unsigned char *db_pointer = (unsigned char *)resolve_pointer_to_string_copy();
393
394        ref->expand_to_length(seq_end);
395
396        GB_alignment_type aliType = GetAliType();
397        char *char_2_char = (aliType && (aliType==GB_AT_AA)) ? ED4_ROOT->sequence_colors->char_2_char_aa : ED4_ROOT->sequence_colors->char_2_char;
398        char *char_2_gc   = (aliType && (aliType==GB_AT_AA)) ? ED4_ROOT->sequence_colors->char_2_gc_aa : ED4_ROOT->sequence_colors->char_2_gc;
399
400        bool only_show_diff = ref->only_show_diff_for(this);
401        for (int scr_pos=left; scr_pos <= right; scr_pos++) {
402            int seq_pos = rm->screen_to_sequence(scr_pos);
403            int c = db_pointer[seq_pos];
404            int gc = char_2_gc[c];
405
406            color_is_used[gc] = scr_pos+1;
407            colored_strings[gc][scr_pos] = char_2_char[only_show_diff ? ref->convert(c, seq_pos) : c];
408        }
409
410        free(db_pointer);
411    }
412
413    // Set background
414
415    {
416        GB_transaction       ta(GLOBAL_gb_main);
417        ST_ML_Color         *statColors   = 0;
418        char                *searchColors = results().buildColorString(this, seq_start, seq_end); // defined in ED4_SearchResults class : ED4_search.cxx
419        ED4_species_manager *spec_man     = get_parent(LEV_SPECIES)->to_species_manager();
420        int                  color_group  = AW_color_groups_active() ? GBT_get_color_group(spec_man->get_species_pointer()) : 0;
421
422        PosRange selection;
423        int      is_selected = ED4_get_selected_range(this, selection);
424        int      is_marked   = GB_read_flag(spec_man->get_species_pointer());
425
426        if (species_name &&
427            ED4_ROOT->column_stat_activated &&
428            (st_ml_node || (st_ml_node = STAT_find_node_by_name(ED4_ROOT->st_ml, this->species_name))))
429            {
430                statColors = STAT_get_color_string(ED4_ROOT->st_ml, 0, st_ml_node, seq_start, seq_end);
431            }
432
433        const char *saiColors = 0;
434
435        if (species_name                       &&
436            ED4_ROOT->visualizeSAI             &&
437            spec_man->get_type() != ED4_SP_SAI &&
438            (is_marked || ED4_ROOT->visualizeSAI_allSpecies))
439        {
440            saiColors = ED4_getSaiColorString(ED4_ROOT->aw_root, seq_start, seq_end);
441        }
442
443        if (statColors || searchColors || is_marked || is_selected || color_group || saiColors) {
444            int    i;
445            AW_pos width      = ED4_ROOT->font_group.get_width(ED4_G_SEQUENCES);
446            int    real_left  = left;
447            int    real_right = right;
448            AW_pos x2         = text_x + width*real_left;
449            AW_pos old_x      = x2;
450            AW_pos y1         = world_y;
451            AW_pos y2         = text_y+1;
452            AW_pos height     = y2-y1+1;
453            int    old_color  = ED4_G_STANDARD;
454            int    color      = ED4_G_STANDARD;
455
456            if (is_selected && selection.is_unlimited()) {
457                selection = ExplicitRange(selection, rm->screen_to_sequence(real_right));
458            }
459
460            for (i = real_left; i <= real_right; i++, x2 += width) {
461                int new_pos = rm->screen_to_sequence(i);  // getting the real position of the base in the sequence
462
463                // Note: if you change background color priorities,
464                // please update help in ../HELP_SOURCE/oldhelp/e4_background_priority.hlp@COLOR_PRIORITY
465
466                if (searchColors && searchColors[new_pos]) {
467                    color = searchColors[new_pos];
468                }
469                else if (is_selected && selection.contains(new_pos)) {
470                    color = ED4_G_SELECTED;
471                }
472                else if (statColors) {
473                    color = statColors[new_pos] + ED4_G_CBACK_0;
474                    if (color > ED4_G_CBACK_9) color = ED4_G_CBACK_9;
475                }
476                else if (saiColors) {
477                    color = saiColors[new_pos];
478                    if (color < ED4_G_CBACK_0 || color > ED4_G_CBACK_9)  color = ED4_G_STANDARD;
479                }
480                else if (is_marked) {
481                    color = ED4_G_MARKED;
482                }
483                else if (color_group) {
484                    color = ED4_G_FIRST_COLOR_GROUP+color_group-1;
485                }
486                else {
487                    color = ED4_G_STANDARD;
488                }
489
490                if (color != old_color) {   // draw till oldcolor
491                    if (x2>old_x) {
492                        if (old_color!=ED4_G_STANDARD) {
493                            device->box(old_color, AW::FillStyle::SOLID, old_x, y1, x2-old_x, height); // paints the search pattern background
494                        }
495                    }
496                    old_x = x2;
497                    old_color = color;
498                }
499            }
500
501            if (x2>old_x) {
502                if (color!=ED4_G_STANDARD) {
503                    device->box(color, AW::FillStyle::SOLID, old_x, y1, x2-old_x, height);
504                }
505            }
506        }
507    }
508
509    device->set_vertical_font_overlap(true);
510
511    if (shall_display_secstruct_info) {
512        if (ED4_ROOT->helix->is_enabled()) {
513            // output helix
514            int   db_len;
515            char *db_pointer = resolve_pointer_to_string_copy(&db_len);
516
517            e4_assert(size_t(db_len) == ED4_ROOT->helix->size());
518            ShowHelix_cd  cd         = { ED4_ROOT->helix, max_seq_len };
519            device->text_overlay(ED4_G_HELIX,
520                                 (char *)db_pointer, db_len,
521                                 AW::Position(text_x,  text_y + ED4_ROOT->helix_spacing), 0.0,  AW_ALL_DEVICES_UNSCALED,
522                                 (AW_CL)&cd, 1.0, 1.0, ED4_show_helix_on_device);
523            free(db_pointer);
524        }
525
526        if (ED4_ROOT->protstruct) {
527            // output protein structure match
528            ED4_species_manager *spec_man = get_parent(LEV_SPECIES)->to_species_manager();
529            if (spec_man->get_type() != ED4_SP_SAI && ED4_ROOT->aw_root->awar(PFOLD_AWAR_ENABLE)->read_int()) {  // should do a remap
530                int   db_len;
531                char *protstruct = resolve_pointer_to_string_copy(&db_len);
532               
533                if (protstruct) {
534                    device->text_overlay(ED4_G_HELIX,
535                                         protstruct, db_len,
536                                         AW::Position(text_x,  text_y + ED4_ROOT->helix_spacing),  0.0,  AW_ALL_DEVICES_UNSCALED,
537                                         (AW_CL)ED4_ROOT->protstruct, 1.0, 1.0, ED4_show_protein_match_on_device);
538                    free(protstruct);
539                }
540            }
541        }
542    }
543    // output strings
544    {
545        int gc;
546        for (gc = 0; gc < ED4_G_DRAG; gc++) {
547            if (!color_is_used[gc]) continue;
548            device->text(gc, colored_strings[gc], text_x, text_y, 0, AW_SCREEN, color_is_used[gc]);
549            memset(colored_strings[gc] + left, ' ', right-left+1); // clear string
550        }
551    }
552
553    device->set_vertical_font_overlap(false);
554}
555
556
557void ED4_sequence_info_terminal::draw() {
558    AW_pos x, y;
559    calc_world_coords(&x, &y);
560    current_ed4w()->world_to_win_coords(&x, &y);
561
562    AW_pos text_x = x + CHARACTEROFFSET; // don't change
563    AW_pos text_y = y+INFO_TERM_TEXT_YOFFSET;
564
565    char    buffer[10];
566    GBDATA *gbdata = data();
567
568    if (gbdata) {
569        GB_push_transaction(gbdata);
570        buffer[0] = '0' + GB_read_security_write(gbdata);
571        GB_pop_transaction(gbdata);
572    }
573    else {
574        buffer[0] = ' ';
575    }
576    strncpy(&buffer[1], this->id, 8);
577    buffer[9] = 0;
578
579    if (containing_species_manager()->is_selected()) {
580        current_device()->box(ED4_G_SELECTED, AW::FillStyle::SOLID, x, y, extension.size[WIDTH], text_y-y+1);
581    }
582
583    current_device()->set_vertical_font_overlap(true);
584    current_device()->text(ED4_G_STANDARD, buffer, text_x, text_y, 0, AW_SCREEN, 0);
585    current_device()->set_vertical_font_overlap(false);
586}
587
588// ---------------------------
589//      ED4_text_terminal
590
591void ED4_text_terminal::draw() {
592    AW_pos x, y;
593    calc_world_coords(&x, &y);
594    current_ed4w()->world_to_win_coords(&x, &y);
595
596    AW_pos text_x = x + CHARACTEROFFSET; // don't change
597    AW_pos text_y = y + INFO_TERM_TEXT_YOFFSET;
598
599    current_device()->set_vertical_font_overlap(true);
600
601    if (is_species_name_terminal()) { // @@@ handle by virtual method (eg. draw_text())
602        GB_CSTR real_name      = to_species_name_terminal()->get_displayed_text();
603        int     width_of_char;
604        int     height_of_char = -1;
605        bool    paint_box      = inside_species_seq_manager();
606        bool    is_marked      = false;
607
608        if (paint_box) {
609            ED4_species_manager *species_man = get_parent(LEV_SPECIES)->to_species_manager();
610            GBDATA *gbd = species_man->get_species_pointer();
611
612            if (gbd) {
613                GB_transaction ta(gbd);
614                is_marked = GB_read_flag(gbd);
615            }
616
617            width_of_char = ED4_ROOT->font_group.get_width(ED4_G_STANDARD);
618            height_of_char = ED4_ROOT->font_group.get_height(ED4_G_STANDARD);
619#define MIN_MARK_BOX_SIZE 8
620            if (width_of_char<MIN_MARK_BOX_SIZE) width_of_char = MIN_MARK_BOX_SIZE;
621            if (height_of_char<MIN_MARK_BOX_SIZE) height_of_char = MIN_MARK_BOX_SIZE;
622#undef MIN_MARK_BOX_SIZE
623        }
624        else {
625            width_of_char = 0;
626        }
627
628        if (containing_species_manager()->is_selected()) {
629            current_device()->box(ED4_G_SELECTED, AW::FillStyle::SOLID, x, y, extension.size[WIDTH], text_y-y+1);
630        }
631        current_device()->text(ED4_G_STANDARD, real_name, text_x+width_of_char, text_y, 0, AW_SCREEN, 0);
632
633        if (paint_box) {
634            int xsize = (width_of_char*6)/10;
635            int ysize = (height_of_char*6)/10;
636            int xoff  = xsize>>1;
637            int yoff  = 0;
638            int bx    = int(text_x+xoff);
639            int by    = int(text_y-(yoff+ysize));
640
641            current_device()->box(ED4_G_STANDARD, AW::FillStyle::SOLID, bx, by, xsize, ysize);
642            if (!is_marked && xsize>2 && ysize>2) {
643                current_device()->clear_part(bx+1, by+1, xsize-2, ysize-2, AW_ALL_DEVICES);
644            }
645        }
646    }
647    else if (is_flag_header_terminal()) { // @@@ handle by virtual method (eg. draw_text())
648        ED4_flag_header_terminal *header_term = to_flag_header_terminal();
649        const char               *header_text = header_term->get_displayed_text();
650
651        text_y += (SEQ_TERM_TEXT_YOFFSET-INFO_TERM_TEXT_YOFFSET); // @@@ wrong vertical shift? (change fontsize to examine)
652        current_device()->text(ED4_G_FLAG_INFO, header_text, text_x, text_y, 0, AW_SCREEN, header_term->get_length());
653    }
654    else {
655        char *db_pointer = resolve_pointer_to_string_copy();
656
657        if (is_sequence_info_terminal()) {
658            current_device()->text(ED4_G_STANDARD, db_pointer, text_x, text_y, 0, AW_SCREEN, 4);
659            e4_assert(0); // @@@ does this ever happen? ED4_sequence_info_terminal::draw() is overloaded as well. DRY!
660        }
661        else if (is_pure_text_terminal()) { // normal text (i.e. remark)
662            text_y += (SEQ_TERM_TEXT_YOFFSET-INFO_TERM_TEXT_YOFFSET);
663            current_device()->text(ED4_G_SEQUENCES, db_pointer, text_x, text_y, 0, AW_SCREEN, 0);
664        }
665        else {
666            e4_assert(0); // unhandled terminal type
667        }
668
669        free(db_pointer);
670    }
671    current_device()->set_vertical_font_overlap(false);
672}
673
674ED4_text_terminal::ED4_text_terminal(const ED4_objspec& spec_, GB_CSTR temp_id, AW_pos width, AW_pos height, ED4_manager *temp_parent) :
675    ED4_terminal(spec_, temp_id, width, height, temp_parent)
676{
677}
678
Note: See TracBrowser for help on using the repository browser.