| 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 | |
|---|
| 36 | int ED4_consensus_sequence_terminal::get_length() const { |
|---|
| 37 | return get_char_table().size(); |
|---|
| 38 | } |
|---|
| 39 | |
|---|
| 40 | inline 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 | |
|---|
| 51 | ED4_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 | |
|---|
| 115 | struct ShowHelix_cd { |
|---|
| 116 | AW_helix *helix; |
|---|
| 117 | int real_sequence_length; |
|---|
| 118 | }; |
|---|
| 119 | |
|---|
| 120 | static 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 | 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 | |
|---|
| 147 | static 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 global_protstruct |
|---|
| 155 | * \param[in] global_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 | |
|---|
| 182 | ED4_returncode 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 | const char *no_data = "No sequence data"; |
|---|
| 210 | size_t len = strlen(no_data); |
|---|
| 211 | |
|---|
| 212 | device->text(ED4_G_STANDARD, no_data, text_x, text_y, 0, AW_SCREEN, len); |
|---|
| 213 | return ED4_R_OK; |
|---|
| 214 | } |
|---|
| 215 | |
|---|
| 216 | if (index_range.end() >= len_of_colored_strings) { |
|---|
| 217 | len_of_colored_strings = index_range.end() + 256; |
|---|
| 218 | if (!colored_strings) { |
|---|
| 219 | colored_strings = (char **)GB_calloc(sizeof(char *), ED4_G_DRAG); |
|---|
| 220 | } |
|---|
| 221 | int i; |
|---|
| 222 | for (i=0; i<ED4_G_DRAG; i++) { |
|---|
| 223 | freeset(colored_strings[i], (char *)malloc(sizeof(char) * (len_of_colored_strings+1))); |
|---|
| 224 | memset(colored_strings[i], ' ', len_of_colored_strings); |
|---|
| 225 | colored_strings[i][len_of_colored_strings] = 0; |
|---|
| 226 | } |
|---|
| 227 | } |
|---|
| 228 | |
|---|
| 229 | int seq_end = rm->screen_to_sequence(index_range.end()); |
|---|
| 230 | |
|---|
| 231 | // mark all strings as unused |
|---|
| 232 | memset(color_is_used, 0, sizeof(color_is_used)); |
|---|
| 233 | |
|---|
| 234 | int iDisplayMode = ED4_ROOT->aw_root->awar(AWAR_PROTVIEW_DISPLAY_OPTIONS)->read_int(); |
|---|
| 235 | { |
|---|
| 236 | const unsigned char *aaSequence_u = (const unsigned char *)aaSequence; |
|---|
| 237 | const unsigned char *aaColor_u = (const unsigned char *)aaColor; |
|---|
| 238 | |
|---|
| 239 | if (iDisplayMode == PV_AA_NAME || iDisplayMode == PV_AA_CODE) { |
|---|
| 240 | // transform strings, compress if needed |
|---|
| 241 | AWT_reference *ref = ED4_ROOT->reference; |
|---|
| 242 | ref->expand_to_length(seq_end); |
|---|
| 243 | |
|---|
| 244 | char *char_2_char = ED4_ROOT->sequence_colors->char_2_char_aa; |
|---|
| 245 | char *char_2_gc = ED4_ROOT->sequence_colors->char_2_gc_aa; |
|---|
| 246 | |
|---|
| 247 | if (iDisplayMode == PV_AA_NAME) { |
|---|
| 248 | for (int scr_pos=index_range.start(); scr_pos <= index_range.end(); scr_pos++) { |
|---|
| 249 | int seq_pos = rm->screen_to_sequence(scr_pos); |
|---|
| 250 | unsigned char c = aaSequence_u[seq_pos]; |
|---|
| 251 | unsigned char cc = aaColor_u[seq_pos]; |
|---|
| 252 | int gc = char_2_gc[safeCharIndex(cc)]; |
|---|
| 253 | |
|---|
| 254 | color_is_used[gc] = scr_pos+1; |
|---|
| 255 | colored_strings[gc][scr_pos] = char_2_char[safeCharIndex(c)]; |
|---|
| 256 | } |
|---|
| 257 | } |
|---|
| 258 | else { |
|---|
| 259 | for (int scr_pos=index_range.start(); scr_pos <= index_range.end(); scr_pos++) { |
|---|
| 260 | int seq_pos = rm->screen_to_sequence(scr_pos); |
|---|
| 261 | char c = aaSequence_u[seq_pos]; |
|---|
| 262 | int gc = char_2_gc[safeCharIndex(c)]; |
|---|
| 263 | |
|---|
| 264 | color_is_used[gc] = scr_pos+1; |
|---|
| 265 | colored_strings[gc][scr_pos] = char_2_char[safeCharIndex(c)]; |
|---|
| 266 | } |
|---|
| 267 | } |
|---|
| 268 | } |
|---|
| 269 | |
|---|
| 270 | // paint background |
|---|
| 271 | if ((iDisplayMode == PV_AA_CODE) || (iDisplayMode == PV_AA_BOX)) { |
|---|
| 272 | AW_pos width = ED4_ROOT->font_group.get_width(ED4_G_HELIX); |
|---|
| 273 | const int real_left = index_range.start(); |
|---|
| 274 | const int real_right = index_range.end(); |
|---|
| 275 | AW_pos x2 = text_x + width*real_left; |
|---|
| 276 | AW_pos x1 = x2; |
|---|
| 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 | 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, true, 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, false, center_x, y1, rad_x, rad_y, 0, DRAW_DEG); |
|---|
| 305 | device->arc(ED4_G_SEQUENCES, false, 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 | return (ED4_R_OK); |
|---|
| 326 | } |
|---|
| 327 | |
|---|
| 328 | ED4_returncode ED4_sequence_terminal::draw() { |
|---|
| 329 | static int color_is_used[ED4_G_DRAG]; |
|---|
| 330 | static char **colored_strings = 0; |
|---|
| 331 | static int len_of_colored_strings = 0; |
|---|
| 332 | |
|---|
| 333 | #if defined(TRACE_REFRESH) |
|---|
| 334 | fprintf(stderr, "ED4_sequence_terminal::draw for id='%s'\n", id); fflush(stderr); |
|---|
| 335 | #endif |
|---|
| 336 | |
|---|
| 337 | AW_device *device = current_device(); |
|---|
| 338 | |
|---|
| 339 | int max_seq_len; |
|---|
| 340 | resolve_pointer_to_char_pntr(&max_seq_len); |
|---|
| 341 | e4_assert(max_seq_len>0); |
|---|
| 342 | |
|---|
| 343 | AW_pos world_x, world_y; |
|---|
| 344 | calc_world_coords(&world_x, &world_y); |
|---|
| 345 | current_ed4w()->world_to_win_coords(&world_x, &world_y); |
|---|
| 346 | |
|---|
| 347 | AW_pos text_x = world_x + CHARACTEROFFSET; // don't change |
|---|
| 348 | AW_pos text_y = world_y + SEQ_TERM_TEXT_YOFFSET; |
|---|
| 349 | |
|---|
| 350 | const ED4_remap *rm = ED4_ROOT->root_group_man->remap(); |
|---|
| 351 | |
|---|
| 352 | ExplicitRange index_range = rm->clip_screen_range(calc_update_interval()); |
|---|
| 353 | if (index_range.is_empty()) return ED4_R_OK; |
|---|
| 354 | |
|---|
| 355 | int left = index_range.start(); // @@@ do similar to ED4_orf_terminal::draw here |
|---|
| 356 | int right = index_range.end(); |
|---|
| 357 | |
|---|
| 358 | { |
|---|
| 359 | int max_seq_pos = rm->sequence_to_screen(max_seq_len-1); |
|---|
| 360 | |
|---|
| 361 | if (right>max_seq_len) right = max_seq_pos; |
|---|
| 362 | if (left>right) { |
|---|
| 363 | const char *no_data = "No sequence data"; |
|---|
| 364 | size_t len = strlen(no_data); |
|---|
| 365 | |
|---|
| 366 | device->text(ED4_G_STANDARD, no_data, text_x, text_y, 0, AW_SCREEN, len); |
|---|
| 367 | return ED4_R_OK; |
|---|
| 368 | } |
|---|
| 369 | } |
|---|
| 370 | |
|---|
| 371 | if (right >= len_of_colored_strings) { |
|---|
| 372 | len_of_colored_strings = right + 256; |
|---|
| 373 | if (!colored_strings) { |
|---|
| 374 | colored_strings = (char **)GB_calloc(sizeof(char *), ED4_G_DRAG); |
|---|
| 375 | } |
|---|
| 376 | int i; |
|---|
| 377 | for (i=0; i<ED4_G_DRAG; i++) { |
|---|
| 378 | freeset(colored_strings[i], (char *)malloc(sizeof(char) * (len_of_colored_strings+1))); |
|---|
| 379 | memset(colored_strings[i], ' ', len_of_colored_strings); |
|---|
| 380 | colored_strings[i][len_of_colored_strings] = 0; |
|---|
| 381 | } |
|---|
| 382 | } |
|---|
| 383 | |
|---|
| 384 | int seq_start = rm->screen_to_sequence(left); // real start of sequence |
|---|
| 385 | int seq_end = rm->screen_to_sequence(right); |
|---|
| 386 | |
|---|
| 387 | // mark all strings as unused |
|---|
| 388 | memset(color_is_used, 0, sizeof(color_is_used)); |
|---|
| 389 | |
|---|
| 390 | // transform strings, compress if needed |
|---|
| 391 | { |
|---|
| 392 | AWT_reference *ref = ED4_ROOT->reference; |
|---|
| 393 | unsigned char *db_pointer = (unsigned char *)resolve_pointer_to_string_copy(); |
|---|
| 394 | |
|---|
| 395 | ref->expand_to_length(seq_end); |
|---|
| 396 | |
|---|
| 397 | GB_alignment_type aliType = GetAliType(); |
|---|
| 398 | char *char_2_char = (aliType && (aliType==GB_AT_AA)) ? ED4_ROOT->sequence_colors->char_2_char_aa : ED4_ROOT->sequence_colors->char_2_char; |
|---|
| 399 | char *char_2_gc = (aliType && (aliType==GB_AT_AA)) ? ED4_ROOT->sequence_colors->char_2_gc_aa : ED4_ROOT->sequence_colors->char_2_gc; |
|---|
| 400 | |
|---|
| 401 | int scr_pos; |
|---|
| 402 | int is_ref = ref->reference_species_is(species_name); |
|---|
| 403 | |
|---|
| 404 | for (scr_pos=left; scr_pos <= right; scr_pos++) { |
|---|
| 405 | int seq_pos = rm->screen_to_sequence(scr_pos); |
|---|
| 406 | int c = db_pointer[seq_pos]; |
|---|
| 407 | int gc = char_2_gc[c]; |
|---|
| 408 | |
|---|
| 409 | color_is_used[gc] = scr_pos+1; |
|---|
| 410 | colored_strings[gc][scr_pos] = char_2_char[is_ref ? c : ref->convert(c, seq_pos)]; |
|---|
| 411 | } |
|---|
| 412 | |
|---|
| 413 | free(db_pointer); |
|---|
| 414 | } |
|---|
| 415 | |
|---|
| 416 | // Set background |
|---|
| 417 | |
|---|
| 418 | { |
|---|
| 419 | GB_transaction dummy(GLOBAL_gb_main); |
|---|
| 420 | ST_ML_Color *colors = 0; |
|---|
| 421 | char *searchColors = results().buildColorString(this, seq_start, seq_end); // defined in ED4_SearchResults class : ED4_search.cxx |
|---|
| 422 | ED4_species_manager *spec_man = get_parent(ED4_L_SPECIES)->to_species_manager(); |
|---|
| 423 | int color_group = AWT_species_get_dominant_color(spec_man->get_species_pointer()); |
|---|
| 424 | |
|---|
| 425 | PosRange selection; |
|---|
| 426 | int is_selected = ED4_get_selected_range(this, selection); |
|---|
| 427 | int is_marked = GB_read_flag(spec_man->get_species_pointer()); |
|---|
| 428 | |
|---|
| 429 | if (species_name && |
|---|
| 430 | ED4_ROOT->column_stat_activated && |
|---|
| 431 | (st_ml_node || (st_ml_node = STAT_find_node_by_name(ED4_ROOT->st_ml, this->species_name)))) |
|---|
| 432 | { |
|---|
| 433 | colors = STAT_get_color_string(ED4_ROOT->st_ml, 0, st_ml_node, seq_start, seq_end); |
|---|
| 434 | } |
|---|
| 435 | |
|---|
| 436 | const char *saiColors = 0; |
|---|
| 437 | |
|---|
| 438 | if (species_name && |
|---|
| 439 | ED4_ROOT->visualizeSAI && |
|---|
| 440 | spec_man->get_type() != ED4_SP_SAI && |
|---|
| 441 | (is_marked || ED4_ROOT->visualizeSAI_allSpecies)) |
|---|
| 442 | { |
|---|
| 443 | saiColors = ED4_getSaiColorString(ED4_ROOT->aw_root, seq_start, seq_end); |
|---|
| 444 | } |
|---|
| 445 | |
|---|
| 446 | if (colors || searchColors || is_marked || is_selected || color_group || saiColors) { |
|---|
| 447 | int i; |
|---|
| 448 | AW_pos width = ED4_ROOT->font_group.get_width(ED4_G_HELIX); |
|---|
| 449 | int real_left = left; |
|---|
| 450 | int real_right = right; |
|---|
| 451 | AW_pos x2 = text_x + width*real_left; |
|---|
| 452 | AW_pos old_x = x2; |
|---|
| 453 | AW_pos y1 = world_y; |
|---|
| 454 | AW_pos y2 = text_y+1; |
|---|
| 455 | AW_pos height = y2-y1+1; |
|---|
| 456 | int old_color = ED4_G_STANDARD; |
|---|
| 457 | int color = ED4_G_STANDARD; |
|---|
| 458 | |
|---|
| 459 | if (is_selected && selection.is_unlimited()) { |
|---|
| 460 | selection = ExplicitRange(selection, rm->screen_to_sequence(real_right)); |
|---|
| 461 | } |
|---|
| 462 | |
|---|
| 463 | for (i = real_left; i <= real_right; i++, x2 += width) { |
|---|
| 464 | int new_pos = rm->screen_to_sequence(i); // getting the real position of the base in the sequence |
|---|
| 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 (colors) { |
|---|
| 473 | color = colors[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, true, 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, true, 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(ED4_L_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 | return (ED4_R_OK); |
|---|
| 556 | } |
|---|
| 557 | |
|---|
| 558 | |
|---|
| 559 | ED4_returncode ED4_sequence_info_terminal::draw() { |
|---|
| 560 | AW_pos x, y; |
|---|
| 561 | calc_world_coords(&x, &y); |
|---|
| 562 | current_ed4w()->world_to_win_coords(&x, &y); |
|---|
| 563 | |
|---|
| 564 | AW_pos text_x = x + CHARACTEROFFSET; // don't change |
|---|
| 565 | AW_pos text_y = y+INFO_TERM_TEXT_YOFFSET; |
|---|
| 566 | |
|---|
| 567 | char buffer[10]; |
|---|
| 568 | GBDATA *gbdata = data(); |
|---|
| 569 | |
|---|
| 570 | if (gbdata) { |
|---|
| 571 | GB_push_transaction(gbdata); |
|---|
| 572 | buffer[0] = '0' + GB_read_security_write(gbdata); |
|---|
| 573 | GB_pop_transaction(gbdata); |
|---|
| 574 | } |
|---|
| 575 | else { |
|---|
| 576 | buffer[0] = ' '; |
|---|
| 577 | } |
|---|
| 578 | strncpy(&buffer[1], this->id, 8); |
|---|
| 579 | buffer[9] = 0; |
|---|
| 580 | |
|---|
| 581 | if (containing_species_manager()->is_selected()) { |
|---|
| 582 | current_device()->box(ED4_G_SELECTED, true, x, y, extension.size[WIDTH], text_y-y+1); |
|---|
| 583 | } |
|---|
| 584 | |
|---|
| 585 | current_device()->set_vertical_font_overlap(true); |
|---|
| 586 | current_device()->text(ED4_G_STANDARD, buffer, text_x, text_y, 0, AW_SCREEN, 0); |
|---|
| 587 | current_device()->set_vertical_font_overlap(false); |
|---|
| 588 | |
|---|
| 589 | return (ED4_R_OK); |
|---|
| 590 | |
|---|
| 591 | } |
|---|
| 592 | |
|---|
| 593 | // --------------------------- |
|---|
| 594 | // ED4_text_terminal |
|---|
| 595 | |
|---|
| 596 | ED4_returncode ED4_text_terminal::Show(int IF_ASSERTION_USED(refresh_all), int is_cleared) |
|---|
| 597 | { |
|---|
| 598 | e4_assert(update_info.refresh || refresh_all); |
|---|
| 599 | current_device()->push_clip_scale(); |
|---|
| 600 | if (adjust_clipping_rectangle()) { |
|---|
| 601 | if (update_info.clear_at_refresh && !is_cleared) { |
|---|
| 602 | clear_background(); |
|---|
| 603 | } |
|---|
| 604 | draw(); |
|---|
| 605 | } |
|---|
| 606 | current_device()->pop_clip_scale(); |
|---|
| 607 | |
|---|
| 608 | return ED4_R_OK; |
|---|
| 609 | } |
|---|
| 610 | |
|---|
| 611 | ED4_returncode ED4_text_terminal::draw() { |
|---|
| 612 | AW_pos x, y; |
|---|
| 613 | calc_world_coords(&x, &y); |
|---|
| 614 | current_ed4w()->world_to_win_coords(&x, &y); |
|---|
| 615 | |
|---|
| 616 | AW_pos text_x = x + CHARACTEROFFSET; // don't change |
|---|
| 617 | AW_pos text_y = y + INFO_TERM_TEXT_YOFFSET; |
|---|
| 618 | |
|---|
| 619 | current_device()->set_vertical_font_overlap(true); |
|---|
| 620 | |
|---|
| 621 | if (is_species_name_terminal()) { |
|---|
| 622 | GB_CSTR real_name = to_species_name_terminal()->get_displayed_text(); |
|---|
| 623 | int width_of_char; |
|---|
| 624 | int height_of_char = -1; |
|---|
| 625 | bool paint_box = inside_species_seq_manager(); |
|---|
| 626 | bool is_marked = false; |
|---|
| 627 | |
|---|
| 628 | if (paint_box) { |
|---|
| 629 | ED4_species_manager *species_man = get_parent(ED4_L_SPECIES)->to_species_manager(); |
|---|
| 630 | GBDATA *gbd = species_man->get_species_pointer(); |
|---|
| 631 | |
|---|
| 632 | if (gbd) { |
|---|
| 633 | GB_transaction ta(gbd); |
|---|
| 634 | is_marked = GB_read_flag(gbd); |
|---|
| 635 | } |
|---|
| 636 | |
|---|
| 637 | width_of_char = ED4_ROOT->font_group.get_width(ED4_G_STANDARD); |
|---|
| 638 | height_of_char = ED4_ROOT->font_group.get_height(ED4_G_STANDARD); |
|---|
| 639 | #define MIN_MARK_BOX_SIZE 8 |
|---|
| 640 | if (width_of_char<MIN_MARK_BOX_SIZE) width_of_char = MIN_MARK_BOX_SIZE; |
|---|
| 641 | if (height_of_char<MIN_MARK_BOX_SIZE) height_of_char = MIN_MARK_BOX_SIZE; |
|---|
| 642 | #undef MIN_MARK_BOX_SIZE |
|---|
| 643 | } |
|---|
| 644 | else { |
|---|
| 645 | width_of_char = 0; |
|---|
| 646 | } |
|---|
| 647 | |
|---|
| 648 | if (containing_species_manager()->is_selected()) { |
|---|
| 649 | current_device()->box(ED4_G_SELECTED, true, x, y, extension.size[WIDTH], text_y-y+1); |
|---|
| 650 | } |
|---|
| 651 | current_device()->text(ED4_G_STANDARD, real_name, text_x+width_of_char, text_y, 0, AW_SCREEN, 0); |
|---|
| 652 | |
|---|
| 653 | if (paint_box) { |
|---|
| 654 | int xsize = (width_of_char*6)/10; |
|---|
| 655 | int ysize = (height_of_char*6)/10; |
|---|
| 656 | int xoff = xsize>>1; |
|---|
| 657 | int yoff = 0; |
|---|
| 658 | int bx = int(text_x+xoff); |
|---|
| 659 | int by = int(text_y-(yoff+ysize)); |
|---|
| 660 | |
|---|
| 661 | current_device()->box(ED4_G_STANDARD, true, bx, by, xsize, ysize); |
|---|
| 662 | if (!is_marked && xsize>2 && ysize>2) { |
|---|
| 663 | current_device()->clear_part(bx+1, by+1, xsize-2, ysize-2, AW_ALL_DEVICES); |
|---|
| 664 | } |
|---|
| 665 | } |
|---|
| 666 | } |
|---|
| 667 | else { |
|---|
| 668 | char *db_pointer = resolve_pointer_to_string_copy(); |
|---|
| 669 | |
|---|
| 670 | if (is_sequence_info_terminal()) { |
|---|
| 671 | current_device()->text(ED4_G_STANDARD, db_pointer, text_x, text_y, 0, AW_SCREEN, 4); |
|---|
| 672 | } |
|---|
| 673 | else if (is_pure_text_terminal()) { // normal text (i.e. remark) |
|---|
| 674 | text_y += (SEQ_TERM_TEXT_YOFFSET-INFO_TERM_TEXT_YOFFSET); |
|---|
| 675 | current_device()->text(ED4_G_SEQUENCES, db_pointer, text_x, text_y, 0, AW_SCREEN, 0); |
|---|
| 676 | } |
|---|
| 677 | else { |
|---|
| 678 | e4_assert(0); // unknown terminal type |
|---|
| 679 | } |
|---|
| 680 | |
|---|
| 681 | free(db_pointer); |
|---|
| 682 | } |
|---|
| 683 | current_device()->set_vertical_font_overlap(false); |
|---|
| 684 | |
|---|
| 685 | return (ED4_R_OK); |
|---|
| 686 | } |
|---|
| 687 | |
|---|
| 688 | ED4_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) : |
|---|
| 689 | ED4_terminal(spec_, temp_id, x, y, width, height, temp_parent) |
|---|
| 690 | { |
|---|
| 691 | } |
|---|