source: tags/ms_r16q2/PROBE_DESIGN/SaiProbeVisualization.cxx

Last change on this file was 14952, checked in by westram, 8 years ago
  • fix canvas resize/zoom-reset
    • replaced calls to AWT_expose_cb by AWT_canvas::refresh
    • replaced calls to AWT_resize_cb by AWT_canvas::zoom_reset_and_refresh
    • fixed double refresh in AWT_canvas::scroll
    • fixed recalc_size(true)
      • if canvas is scrolled out at top or left side ⇒ fix resulting scroll-offset according to size-change
    • instead of zoom_reset do recalc_size when
      • jumping to species in folded group (or outside logical subtree)
      • changing vertical branch distance or group scales (in "Tree Settings")
      • changing font(size)
    • never trigger zoom-reset in AWT_graphic_tree::check_update
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 29.5 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : SaiProbeVisualization.cxx                         //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include "SaiProbeVisualization.hxx"
12#include "probe_match_parser.hxx"
13
14#include <nds.h>
15#include <items.h>
16#include <awt_sel_boxes.hxx>
17#include <awt_config_manager.hxx>
18#include <aw_awars.hxx>
19#include <aw_root.hxx>
20#include <aw_preset.hxx>
21#include <aw_msg.hxx>
22#include <arbdbt.h>
23
24#include <iostream>
25#include <arb_global_defs.h>
26#include <item_sel_list.h>
27
28
29using namespace std;
30
31#define PROBE_PREFIX_LENGTH 9
32#define PROBE_SUFFIX_LENGTH 9
33
34static saiProbeData *g_pbdata                    = 0;
35static char         *saiValues                   = 0;
36static bool          in_colorDefChanged_callback = false; // used to avoid colorDef correction
37
38#define BUFSIZE 100
39static const char *getAwarName(int awarNo) {
40    static char buf[BUFSIZE];
41
42    strcpy(buf, AWAR_SPV_SAI_COLOR);
43    (strchr(buf, 0)-1)[0] = '0'+awarNo;
44
45    return buf;
46}
47
48AW_gc_manager *SAI_graphic::init_devices(AW_window *aww, AW_device *device, AWT_canvas *scr) {
49    AW_gc_manager *gc_manager =
50        AW_manage_GC(aww,
51                     scr->get_gc_base_name(),
52                     device,
53                     SAI_GC_HIGHLIGHT,
54                     SAI_GC_MAX,
55                     AW_GCM_DATA_AREA,
56                     makeGcChangedCallback(AWT_GC_changed_cb, scr),
57                     "#005500",
58                     "Selected Probe$#FF0000",
59                     "Foreground$#FFAA00",
60                     "Probe$#FFFF00",
61                     "+-COLOR 0$#FFFFFF", "-COLOR 1$#E0E0E0",
62                     "+-COLOR 2$#C0C0C0", "-COLOR 3$#A0A0A0",
63                     "+-COLOR 4$#909090", "-COLOR 5$#808080",
64                     "+-COLOR 6$#707070", "-COLOR 7$#505050",
65                     "+-COLOR 8$#404040", "-COLOR 9$#303030",
66                     NULL);
67
68    return gc_manager;
69}
70
71SAI_graphic::SAI_graphic(AW_root *aw_rooti, GBDATA *gb_maini) {
72    exports.zoom_mode = AWT_ZOOM_NEVER;
73    exports.fit_mode  = AWT_FIT_NEVER;
74
75    exports.set_standard_default_padding();
76
77    this->aw_root = aw_rooti;
78    this->gb_main = gb_maini;
79}
80
81void SAI_graphic::handle_command(AW_device *, AWT_graphic_event& event) {
82    if (event.type() == AW_Mouse_Press && event.button() != AW_BUTTON_MIDDLE) {
83        const AW_clicked_element *clicked = event.best_click();
84        if (clicked->is_text()) {
85            int         clicked_idx  = (int)clicked->cd1();
86            const char *species_name = g_pbdata->probeSpecies[clicked_idx].c_str();
87
88            aw_root->awar(AWAR_SPECIES_NAME)->write_string(species_name);
89            aw_root->awar(AWAR_SPV_SELECTED_PROBE)->write_string(species_name);
90        }
91    }
92}
93
94SAI_graphic::~SAI_graphic() {}
95
96void SAI_graphic::show(AW_device *device) {
97    paint(device);
98}
99
100static void colorDefChanged_callback(AW_root *awr, int awarNo) {
101    if (!in_colorDefChanged_callback) {
102        LocallyModify<bool> flag(in_colorDefChanged_callback, true);
103        unsigned char charUsed[256]; memset(charUsed, 255, 256);
104        {
105            for (int i=0; i<10;  i++) {
106                char *awarString_next = awr->awar_string(getAwarName(i))->read_string();
107                for (int c=0; awarString_next[c]; ++c) {
108                    charUsed[(unsigned char)awarString_next[c]] = i;
109                }
110                free(awarString_next);
111            }
112            char *awarString = awr->awar_string(getAwarName(awarNo))->read_string();
113
114            for (int c = 0; awarString[c]; ++c) {
115                charUsed[(unsigned char)awarString[c]] = awarNo;
116            }
117            free(awarString);
118
119            typedef unsigned char mystr[256];
120            mystr s[10];
121            for (int i=0; i<10; i++)  s[i][0]=0; // initializing the strings
122
123            for (int i=0; i<256; i++) {
124                int table = charUsed[i];
125                if (table != 255) {
126                    char *eos = strchr((char *)s[table], 0); // get pointer to end of string
127                    eos[0] = char(i);
128                    eos[1] = 0;
129                }
130            }
131
132            for (int i=0; i<10; i++) {
133                awr->awar_string(getAwarName(i))->write_string((char *)s[i]);
134            }
135        }
136    }
137    awr->awar(AWAR_SPV_DISP_SAI)->touch(); // refreshes the display
138}
139
140static void refreshCanvas(AW_root*, AWT_canvas *scr) {
141    // repaints the canvas
142    scr->refresh();
143}
144
145static void createSaiProbeAwars(AW_root *aw_root) {
146    // creating awars specific for the painting routine
147    aw_root->awar_int(AWAR_SPV_DISP_SAI, 0, AW_ROOT_DEFAULT); // to display SAI values
148
149    for (int i = 0; i < 10; i++) {  // initializing 10 color definition string AWARS
150       AW_awar *def_awar = aw_root->awar_string(getAwarName(i), "", AW_ROOT_DEFAULT);
151       def_awar->add_callback(makeRootCallback(colorDefChanged_callback, i));
152    }
153}
154
155static void addCallBacks(AW_root *awr, AWT_canvas *scr) {
156    // add callbacks to the awars (refresh display on change)
157    RootCallback refresh_cb = makeRootCallback(refreshCanvas, scr);
158
159    awr->awar(AWAR_SPV_DISP_SAI)      ->add_callback(refresh_cb);
160    awr->awar(AWAR_SPV_SAI_2_PROBE)   ->add_callback(refresh_cb);
161    awr->awar(AWAR_SPV_DB_FIELD_NAME) ->add_callback(refresh_cb);
162    awr->awar(AWAR_SPV_DB_FIELD_WIDTH)->add_callback(refresh_cb);
163    awr->awar(AWAR_SPV_SELECTED_PROBE)->add_callback(refresh_cb);
164    awr->awar(AWAR_SPV_ACI_COMMAND)   ->add_callback(refresh_cb);
165}
166
167static const char *translateSAItoColors(AW_root *awr, GBDATA *gb_main, int start, int end, int speciesNo) {
168    // translating SAIs to color strings
169    static int   seqBufferSize = 0;
170    static char *saiColors     = 0;
171
172    if (start >= end) return 0;
173
174    int seqSize = (end - start) + 1;
175
176    if (seqSize > seqBufferSize) {
177        free(saiColors);
178        seqBufferSize = seqSize;
179        saiColors = (char*)malloc(seqBufferSize);
180        saiValues = (char*)malloc(seqBufferSize);
181    }
182
183    memset(saiColors, '0'-1, seqSize);
184    memset(saiValues, '0'-1, seqSize);
185
186    char *saiSelected = awr->awar(AWAR_SPV_SAI_2_PROBE)->read_string();
187
188    GB_push_transaction(gb_main);
189    char   *alignment_name = GBT_get_default_alignment(gb_main);
190    GBDATA *gb_extended    = GBT_find_SAI(gb_main, saiSelected);
191    int     positions      = 0;
192
193    if (gb_extended) {
194        GBDATA *gb_ali = GB_entry(gb_extended, alignment_name);
195        if (gb_ali) {
196            const char *saiData      = 0;
197            const char *seqData      = 0;
198            bool        free_saiData = false;
199
200            {
201                GBDATA *saiSequence = GB_entry(gb_ali, "data"); // search "data" entry (normal SAI)
202                if (saiSequence) {
203                    saiData = GB_read_char_pntr(saiSequence); // not allocated
204                }
205                else {
206                    saiSequence = GB_entry(gb_ali, "bits"); // search "bits" entry (binary SAI)
207                    if (saiSequence) {
208                        saiData      = GB_read_as_string(saiSequence); // allocated
209                        free_saiData = true; // free saiData below
210                    }
211                }
212
213                const char *species_name = g_pbdata->probeSpecies[speciesNo].c_str();
214                GBDATA *gb_species       = GBT_find_species(gb_main, species_name);
215                GBDATA *gb_seq_data      = GBT_find_sequence(gb_species, alignment_name);
216                if (gb_seq_data) seqData = GB_read_char_pntr(gb_seq_data);
217            }
218
219            if (saiData) {
220                char trans_table[256];
221                {
222
223                    // @@@ FIXME: build trans_table ONCE for each refresh only (not for each translation)
224
225                    // build the translation table
226                    memset(trans_table, '0'-1, 256);
227                    for (int i = 0; i < SAI_CLR_COUNT; ++i) {
228                        char *def      = awr->awar(getAwarName(i))->read_string();
229                        int   clrRange = i + '0'; // configured values use '0' to '9' (unconfigured use '0'-1)
230
231                        for (const char *d = def; *d; ++d) {
232                            trans_table[(unsigned char)*d] = clrRange;
233                        }
234                        free(def);
235                    }
236                }
237
238                // translate SAI to colors
239                int i, j;
240                for (i = start, j = 0;   i <= end; ++i) {
241                    if ((seqData[i] != '.') && (seqData[i] != '-')) {
242                        saiColors[j] = trans_table[(unsigned char)saiData[i]];
243                        saiValues[j] = saiData[i];
244                        ++j;
245                    }
246                }
247                positions = j;
248            }
249
250            if (free_saiData) {
251                free(const_cast<char*>(saiData)); // in this case saiData is allocated (see above)
252            }
253        }
254    }
255
256    saiColors[positions] = 0;
257    saiValues[positions] = 0;
258
259    free(alignment_name);
260    free(saiSelected);
261    GB_pop_transaction(gb_main);
262
263    return saiColors;
264}
265
266static int calculateEndPosition(GBDATA *gb_main, int startPos, int speciesNo, int mode, int probeLen, GB_ERROR *err) {
267    // returns -2 in case of error
268    // Note: if mode == 'PROBE_PREFIX' the result is 1 in front of last base (and so may be -1)
269
270    int i, endPos, baseCntr;
271    i      = baseCntr = 0;
272    endPos = -2;
273    *err   = 0;
274
275    GB_push_transaction(gb_main);
276    char       *alignment_name = GBT_get_default_alignment(gb_main);
277    const char *species_name   = g_pbdata->probeSpecies[speciesNo].c_str();
278    GBDATA     *gb_species     = GBT_find_species(gb_main, species_name);
279    if (gb_species) {
280        GBDATA *gb_seq_data      = GBT_find_sequence(gb_species, alignment_name);
281        if (gb_seq_data) {
282            const char *seqData = GB_read_char_pntr(gb_seq_data);
283
284            if (seqData) {
285                switch (mode) {
286                    case PROBE:
287                        for (i = startPos; baseCntr < probeLen; ++i) {
288                            if ((seqData[i] != '-') && (seqData[i] != '.'))
289                                baseCntr++;
290                        }
291                        break;
292                    case PROBE_PREFIX:
293                        for (i = startPos; baseCntr < PROBE_PREFIX_LENGTH && i >= 0; --i) {
294                            if ((seqData[i] != '-') && (seqData[i] != '.'))
295                                baseCntr++;
296                        }
297                        break;
298                    case PROBE_SUFFIX:
299                        for (i = startPos; baseCntr < PROBE_SUFFIX_LENGTH && seqData[i]; ++i) {
300                            if ((seqData[i] != '-') && (seqData[i] != '.'))
301                                baseCntr++;
302                        }
303                        break;
304                }
305                endPos = i;
306            }
307            else {
308                *err = "can't read data";
309            }
310        }
311        else {
312            *err = "no data";
313        }
314    }
315    else {
316        *err = "species not found";
317    }
318    free(alignment_name);
319    GB_pop_transaction(gb_main);
320
321    return endPos;
322}
323
324// --------------------------------------------------------------------------------
325// painting routine
326
327static void paintBackgroundAndSAI (AW_device *device, size_t probeRegionLen, AW_pos pbRgX1, AW_pos pbY, AW_pos pbMaxWidth, AW_pos pbMaxHeight,
328                             const char *saiCols, int dispSai)
329{
330    // painting background in translated colors from the chosen SAI values
331    // and also printing the values based on the options set by user
332    for (size_t j = 0; j<probeRegionLen; j++) {
333        if (saiCols[j] >= '0') {
334            device->box(saiCols[j]-'0'+SAI_GC_0, AW::FillStyle::SOLID, pbRgX1+j*pbMaxWidth, pbY-pbMaxHeight+1, pbMaxWidth, pbMaxHeight);
335        }
336        if (dispSai && saiValues[j]) {
337            char saiVal[2];
338            saiVal[0] = saiValues[j];
339            saiVal[1] = 0;
340            device->text(SAI_GC_FOREGROUND, saiVal, (pbRgX1+(j*pbMaxWidth)), pbY+pbMaxHeight, 0, AW_SCREEN, 0);
341        }
342    }
343}
344
345// static void paintProbeInfo(AW_device *device, const char *probe_info, AW_pos x, AW_pos y, AW_pos xoff, AW_pos yoff, AW_pos maxDescent, AW_CL clientdata, int textCOLOR) {
346static void paintProbeInfo(AW_device *device, const char *probe_info, AW_pos x, AW_pos y, AW_pos xoff, AW_pos yoff, AW_pos maxDescent, int textCOLOR) {
347    char probeChar[2];
348    probeChar[1] = 0;
349
350    for (size_t j = 0; probe_info[j]; ++j) {
351        if (probe_info[j] == '=') {
352            AW_pos yl = y-maxDescent-(yoff-maxDescent)/3;
353            AW_pos xl = x+xoff*j;
354            device->line(SAI_GC_PROBE, xl, yl, xl+xoff-1, yl);
355        }
356        else {
357            probeChar[0] = probe_info[j];
358            // device->text(textCOLOR, probeChar, x+j*xoff, y-maxDescent, 0, AW_SCREEN|AW_CLICK, clientdata, 0);
359            device->text(textCOLOR, probeChar, x+j*xoff, y-maxDescent, 0, AW_SCREEN|AW_CLICK);
360        }
361    }
362}
363
364static char *GetDisplayInfo(AW_root *root, GBDATA *gb_main, const char *speciesName, size_t displayWidth, const char *default_tree_name)
365{
366    GB_ERROR        error       = 0;
367    char           *displayInfo = 0;
368    GB_transaction  ta(gb_main);
369    GBDATA         *gb_Species  = GBT_expect_species(gb_main, speciesName);
370
371    if (!gb_Species) error = GB_await_error();
372    else {
373        char *field_content = 0;
374        {
375            const char *dbFieldName = root->awar_string(AWAR_SPV_DB_FIELD_NAME)->read_char_pntr();
376            if (strcmp(dbFieldName, NO_FIELD_SELECTED) == 0) {
377                field_content = strdup("no field, no content");
378            }
379            else {
380                GBDATA *gb_field = GB_search(gb_Species, dbFieldName, GB_FIND);
381                if (gb_field) {
382                    field_content             = GB_read_as_string(gb_field);
383                    if (!field_content) error = GB_await_error();
384                }
385                else {
386                    if (GB_have_error()) {
387                        error = GBS_global_string("Failed to retrieve field '%s' (Reason: %s)", dbFieldName, GB_await_error());
388                    }
389                    else {
390                        error = GBS_global_string("No entry '%s' in species '%s'", dbFieldName, speciesName);
391                    }
392                }
393            }
394        }
395
396        if (!error) {
397            char *aciCommand        = root->awar_string(AWAR_SPV_ACI_COMMAND)->read_string();
398            displayInfo             = GB_command_interpreter(gb_main, field_content, aciCommand, gb_Species, default_tree_name);
399            if (!displayInfo) error = GB_await_error();
400            free(aciCommand);
401        }
402
403        if (displayInfo && strlen(displayInfo)>displayWidth) displayInfo[displayWidth] = 0; // shorten result
404        free(field_content);
405    }
406
407    if (error) freedup(displayInfo, error);                // display the error
408
409    sai_assert(displayInfo);
410    return displayInfo;
411}
412
413void SAI_graphic::paint(AW_device *device) {
414    // Painting routine of the canvas based on the probe match results
415
416    double xStep_info   = 0;
417    double xStep_border = 0;
418    double xStep_target = 0;
419    double yStep        = 0;
420    double maxDescent   = 0;
421    // detect x/y step to use
422    {
423        const AW_font_limits& fgFontLim = device->get_font_limits(SAI_GC_FOREGROUND_FONT, 0);
424        const AW_font_limits& pbFontLim = device->get_font_limits(SAI_GC_PROBE_FONT, 0);
425        const AW_font_limits& hlFontLim = device->get_font_limits(SAI_GC_HIGHLIGHT_FONT, 0);
426
427        AW_font_limits target_font_limits(pbFontLim, hlFontLim);
428        AW_font_limits all_font_limits(fgFontLim, target_font_limits);
429
430        xStep_info   = fgFontLim.width;
431        xStep_border = pbFontLim.width;
432        xStep_target = target_font_limits.width;
433
434        yStep      = all_font_limits.height;
435        maxDescent = all_font_limits.descent;
436    }
437
438    AW_pos fgY = yStep + 10;
439    AW_pos pbY = yStep + 10;
440
441    char *saiSelected  = aw_root->awar(AWAR_SPV_SAI_2_PROBE)->read_string();
442    int   dispSai      = aw_root->awar(AWAR_SPV_DISP_SAI)->read_int();       // to display SAI below probe targets
443    int   displayWidth = aw_root->awar(AWAR_SPV_DB_FIELD_WIDTH)->read_int(); // display column width of the selected database field
444
445    {
446        char buf[1024];
447        if (strcmp(saiSelected, "")==0) sprintf(buf, "Selected SAI = Not Selected!");
448        else sprintf(buf, "Selected SAI = %s", saiSelected);
449        device->text(SAI_GC_PROBE, buf, 100, -30, 0.0, AW_SCREEN);
450    }
451
452    double yLineStep = dispSai ? yStep*2 : yStep;
453
454    if (g_pbdata) {
455        device->text(SAI_GC_PROBE,  "Species INFO", 0, 8, 0.0, AW_SCREEN);
456        if (!g_pbdata->probeSpecies.empty()) {
457            char *default_tree  = aw_root->awar(AWAR_TREE)->read_string();
458            char *selectedProbe = aw_root->awar(AWAR_SPV_SELECTED_PROBE)->read_string();
459
460            for (size_t j = 0; j < g_pbdata->probeSpecies.size(); ++j) {
461                const char *name        = g_pbdata->probeSpecies[j].c_str();
462                char       *displayInfo = GetDisplayInfo(aw_root, gb_main, name, displayWidth, default_tree);
463
464                AW_pos fgX = 0;
465
466                AW_click_cd cd(device, j);
467                if (strcmp(selectedProbe, name) == 0) {
468                    device->box(SAI_GC_FOREGROUND, AW::FillStyle::SOLID, fgX, (fgY - (yStep * 0.9)), (displayWidth * xStep_info), yStep);
469                    device->text(SAI_GC_HIGHLIGHT, displayInfo, fgX, fgY-1, 0, AW_SCREEN|AW_CLICK, 0);
470                }
471                else {
472                    device->text(SAI_GC_FOREGROUND, displayInfo, fgX, fgY, 0, AW_SCREEN|AW_CLICK, 0);
473                }
474                fgY += yLineStep;
475
476                free(displayInfo);
477            }
478
479            free(selectedProbe);
480            free(default_tree);
481        }
482
483        double spacer   = 4.0;
484        AW_pos lineXpos = 0;
485
486        AW_pos pbRgX1 = ((displayWidth+1) * xStep_info);
487        AW_pos pbX    = pbRgX1 + (9 * xStep_border) + spacer;
488        AW_pos pbRgX2 = pbX + (g_pbdata->getProbeTargetLen() * xStep_target) + spacer;
489
490        int  probeLen = g_pbdata->getProbeTargetLen();
491
492        device->box(SAI_GC_FOREGROUND, AW::FillStyle::SOLID, pbX, 10-yStep, (probeLen * xStep_target), yStep);
493        paintProbeInfo(device, g_pbdata->getProbeTarget(), pbX, 10, xStep_target, yStep, maxDescent, SAI_GC_HIGHLIGHT);
494        device->set_line_attributes(SAI_GC_FOREGROUND, 2, AW_SOLID);
495
496
497        ProbeMatchParser parser(g_pbdata->getProbeTarget(), g_pbdata->getHeadline());
498        if (parser.get_error()) {
499            device->text(SAI_GC_PROBE, GBS_global_string("Error: %s", parser.get_error()), pbRgX2, pbY, 0, AW_SCREEN, 0);
500        }
501        else {
502            for (size_t i = 0;  i < g_pbdata->probeSeq.size(); ++i) { // loop over all matches
503                GB_ERROR         error;
504                ParsedProbeMatch parsed(g_pbdata->probeSeq[i].c_str(), parser);
505                AW_click_cd      cd(device, i);
506
507                if ((error = parsed.get_error())) {
508                    device->text(SAI_GC_PROBE, GBS_global_string("Error: %s", error), pbRgX2, pbY, 0, AW_SCREEN, 0);
509                }
510                else {
511                    const char *probeRegion      = parsed.get_probe_region();
512                    sai_assert(probeRegion);
513                    char       *probeRegion_copy = strdup(probeRegion);
514
515                    const char *tok_prefix = strtok(probeRegion_copy, "-");
516                    const char *tok_infix  = tok_prefix ? strtok(0, "-") : 0;
517                    const char *tok_suffix = tok_infix ? strtok(0, "-") : 0;
518
519                    if (!tok_suffix) {
520                        // handle special case where no suffix exists
521                        const char *end = strchr(probeRegion, 0);
522                        if (end>probeRegion && end[-1] == '-') tok_suffix = "";
523                    }
524
525                    const char *err = 0;
526                    if (tok_suffix) {
527                        // --------------------
528                        // pre-probe region - 9 bases
529                        int startPos = parsed.get_position();
530                        if (parsed.get_error()) {
531                            err = GBS_global_string("Could not parse match position (Reason: %s).", parsed.get_error());
532                        }
533                        else {
534                            const char *endErr;
535                            int         endPos = calculateEndPosition(gb_main, startPos-1, i, PROBE_PREFIX, probeLen, &endErr);
536                            if (endPos == -2) {
537                                err = GBS_global_string("Can't handle '%s' (%s)", g_pbdata->probeSpecies[i].c_str(), endErr);
538                            }
539                            else {
540                                sai_assert(!endErr);
541                                sai_assert(endPos >= -1); // note: -1 gets fixed in the next line
542                                endPos++; // calculateEndPosition returns 'one position in front of start'
543                                const char *saiCols = translateSAItoColors(aw_root, gb_main, endPos, startPos-1, i);
544                                if (saiCols) {
545                                    int positions = strlen(saiCols);
546                                    int skipLeft  = PROBE_PREFIX_LENGTH-positions;
547                                    sai_assert(skipLeft >= 0);
548                                    paintBackgroundAndSAI(device, positions, pbRgX1+skipLeft*xStep_border, pbY, xStep_border, yStep, saiCols, dispSai);
549                                }
550                                paintProbeInfo(device, tok_prefix, pbRgX1, pbY, xStep_border, yStep, maxDescent, SAI_GC_PROBE);
551
552                                // --------------------
553                                // probe region
554                                endPos  = calculateEndPosition(gb_main, startPos, i, PROBE, probeLen, &endErr);
555                                sai_assert(endPos >= startPos);
556                                sai_assert(!endErr);
557                                saiCols = translateSAItoColors(aw_root, gb_main, startPos, endPos, i);
558
559                                paintBackgroundAndSAI(device, strlen(tok_infix), pbX, pbY, xStep_target, yStep, saiCols, dispSai);
560                                paintProbeInfo(device, tok_infix, pbX, pbY, xStep_target, yStep, maxDescent, SAI_GC_PROBE);
561
562                                // post-probe region - 9 bases
563                                size_t post_start_pos = endPos;
564
565                                endPos = calculateEndPosition(gb_main, post_start_pos, i, PROBE_SUFFIX, probeLen, &endErr);
566                                sai_assert(endPos >= int(post_start_pos));
567                                sai_assert(!endErr);
568
569                                saiCols = translateSAItoColors(aw_root, gb_main, post_start_pos, endPos, i);
570                                if (saiCols) paintBackgroundAndSAI(device, strlen(tok_suffix), pbRgX2, pbY, xStep_border, yStep, saiCols, dispSai);
571                                paintProbeInfo(device, tok_suffix, pbRgX2, pbY, xStep_border, yStep, maxDescent, SAI_GC_PROBE);
572                            }
573                        }
574                    }
575                    else {
576                        err = GBS_global_string("probe-region '%s' has invalid format", probeRegion);
577                    }
578
579                    if (err) device->text(SAI_GC_PROBE, err, pbRgX2, pbY, 0, AW_SCREEN, 0);
580                    free(probeRegion_copy);
581                }
582                pbY += yLineStep;
583            }
584        }
585        lineXpos = pbRgX2 + (9 * xStep_border);
586        device->set_line_attributes(SAI_GC_FOREGROUND, 1, AW_SOLID);
587
588        device->line(SAI_GC_FOREGROUND, 0, -20, lineXpos, -20);
589        device->line(SAI_GC_FOREGROUND, 0, pbY, lineXpos, pbY);
590
591        {
592            double vert_x1 = pbX-spacer/2;
593            double vert_x2 = pbRgX2-spacer/2;
594            device->line(SAI_GC_FOREGROUND, vert_x1, -20, vert_x1, pbY);
595            device->line(SAI_GC_FOREGROUND, vert_x2, -20, vert_x2, pbY);
596        }
597    }
598}
599
600void transferProbeData(saiProbeData *spd) {
601    // store pointer to currently used probe data
602    g_pbdata = spd;
603
604}
605
606// ---------------------------------- Creating WINDOWS ------------------------------------------------
607
608static AWT_predefined_config predefined_saiColorDefinitions[] = {
609    {
610        "*binary",
611        "Use with SAIs containing binary columns\ne.g. \'markerline\'",
612        "0='-.0=';1='';2='';3='';4='';5='';6='';7='';8='';9='1x'"
613    },
614    {
615        "*column_weights_09",
616        "Use with SAIs containing column weights (0-9)\ne.g. MAX_FREQUENCY",
617        "0='0';1='1';2='2';3='3';4='4';5='5';6='6';7='7';8='8';9='9'"
618    },
619    {
620        "*column_weights_0Z_posvar",
621        "Use with SAIs containing column weights (0-9,A-Z)\ne.g. POS_VAR_BY_PARSIMONY",
622        "0='012';1='345';2='678';3='9AB';4='CDE';5='FGH';6='IJK';7='LMN';8='OPQ';9='RST'"
623    },
624    {
625        "*sequence_data",
626        "Use with SAIs containing nucleotide sequence data",
627        "0='-.';1='';2='';3='A';4='';5='C';6='';7='G';8='';9='TU'"
628    },
629    {
630        "*helix",
631        "Use with SAI:HELIX",
632        "0='';1='';2='';3='<[';4='';5='';6='>]';7='';8='';9=''"
633    },
634    { 0, 0, 0 }
635};
636
637static void setup_saiColorDefs_config(AWT_config_definition& cdef) {
638    for (int i = 0; i < 10; i++) {
639        const char *awarDef = getAwarName(i);
640        cdef.add(awarDef, "",  i);
641    }
642}
643
644static AW_window *create_colorTranslationTable_window(AW_root *aw_root) { // creates color translation table window
645    // window to define color translations of selected SAI
646    static AW_window_simple *aws = 0;
647    if (!aws) {
648        aws = new AW_window_simple;
649        aws->init(aw_root, "SAI_CTT", "Color Translation Table");
650        aws->load_xfig("probeSaiColors.fig");
651
652        char at_name[] = "rangex";
653        char *dig      = strchr(at_name, 0)-1;
654
655        for (int i = 0; i<SAI_CLR_COUNT; ++i) {
656            dig[0] = '0'+i;
657            aws->at(at_name);
658            aws->create_input_field(getAwarName(i), 15);
659        }
660
661        aws->at("config");
662        AWT_insert_config_manager(aws, AW_ROOT_DEFAULT, "saveSaiColorDefs", makeConfigSetupCallback(setup_saiColorDefs_config), NULL, predefined_saiColorDefinitions);
663
664        aws->at("dispSai");
665        aws->create_toggle(AWAR_SPV_DISP_SAI);
666
667        aws->at("close");
668        aws->callback(AW_POPDOWN);
669        aws->create_button("CLOSE", "CLOSE", "C");
670    }
671    return aws;
672}
673
674static AW_window *createDisplayField_window(AW_root *aw_root, GBDATA *gb_main) {
675    // window to select existing species field (simple NDS setup for PROBE/SAI-viewer)
676    static AW_window_simple *aws = 0;
677    if (!aws) {
678        aws = new AW_window_simple;
679        aws->init(aw_root, "SELECT_DISPLAY_FIELD", "Select display field");
680        aws->load_xfig("displayField.fig");
681
682        aws->button_length(10);
683
684        aws->at("close");
685        aws->callback(AW_POPDOWN);
686        aws->create_button("CLOSE", "CLOSE", "C");
687
688        aws->at("help");
689        aws->callback(makeHelpCallback("displayField.hlp"));
690        aws->create_button("HELP", "HELP", "H");
691
692        create_itemfield_selection_button(aws, FieldSelDef(AWAR_SPV_DB_FIELD_NAME, gb_main, SPECIES_get_selector(), FIELD_FILTER_NDS, "display-field"), "dbField");
693
694        aws->at("aciSelect");
695        aws->button_length(12);
696        aws->callback(makeWindowCallback(AWT_popup_select_srtaci_window, AWAR_SPV_ACI_COMMAND));
697        aws->create_button("SELECT_ACI", "Select ACI");
698
699        aws->at("aciCmd");
700        aws->create_input_field(AWAR_SPV_ACI_COMMAND, 40);
701
702        aws->at("width");
703        aws->create_input_field(AWAR_SPV_DB_FIELD_WIDTH, 4);
704
705        aws->window_fit();
706    }
707    return aws;
708}
709
710static AW_window *createSaiColorWindow(AW_root *aw_root, AW_gc_manager *gc_manager) {
711    return AW_create_gc_window_named(aw_root, gc_manager, "SAI_COLOR_DEF", "Probe/SAI Colors and Fonts");
712}
713
714AW_window *createSaiProbeMatchWindow(AW_root *awr, GBDATA *gb_main) {
715    // Main Window - Canvas on which the actual painting is done
716    GB_transaction ta(gb_main);
717
718    createSaiProbeAwars(awr); // creating awars for colors ( 0 to 9)
719
720    AW_window_menu *awm = new AW_window_menu;
721    awm->init(awr, "MATCH_SAI", "PROBE AND SAI", 200, 300);
722
723    SAI_graphic *saiProbeGraphic = new SAI_graphic(awr, gb_main);
724    AWT_canvas  *scr             = new AWT_canvas(gb_main, awm, awm->get_window_id(), saiProbeGraphic, AWAR_TARGET_STRING);
725
726    scr->recalc_size(true);
727
728    awm->insert_help_topic("How to Visualize SAI`s ?", "V", "saiProbe.hlp", AWM_ALL, makeHelpCallback("saiProbe.hlp"));
729
730    awm->create_menu("File", "F", AWM_ALL);
731    awm->insert_menu_topic("close", "Close", "C", "quit.hlp", AWM_ALL, AW_POPDOWN);
732
733    awm->create_menu("Properties", "P", AWM_ALL);
734    awm->insert_menu_topic("selectDispField", "Select display field",      "F", "displayField.hlp", AWM_ALL, makeCreateWindowCallback(createDisplayField_window, gb_main));
735    awm->insert_menu_topic("selectSAI",       "Select SAI",                "S", "saiProbe.hlp",     AWM_ALL, makeWindowCallback(awt_popup_SAI_selection_list, AWAR_SPV_SAI_2_PROBE, gb_main));
736    awm->insert_menu_topic("clrTransTable",   "Define Color Translations", "D", "saiProbe.hlp",     AWM_ALL, create_colorTranslationTable_window);
737    awm->insert_menu_topic("SetColors",       "Set Colors and Fonts",      "t", "color_props.hlp",  AWM_ALL, makeCreateWindowCallback(createSaiColorWindow, scr->gc_manager));
738
739    addCallBacks(awr, scr);
740
741    return awm;
742}
Note: See TracBrowser for help on using the repository browser.