source: branches/profile/EDIT4/ED4_text_terminals.cxx

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