source: tags/arb_5.0/SECEDIT/SEC_root.hxx

Last change on this file was 6017, checked in by westram, 15 years ago
  • do not insert \n into error (\n will not display in secedit main window)
  • rename (SEC_root) get_helix → get_helixDef (get_helix is duplicated in SEC_helix_strand)
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 32.4 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : SEC_root.hxx                                      //
4//   Purpose   : secondary structure representation                //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#ifndef SEC_ROOT_HXX
12#define SEC_ROOT_HXX
13
14#ifndef _CPP_IOSFWD
15#include <iosfwd>
16#endif
17
18#ifndef AW_FONT_GROUP_HXX
19#include <aw_font_group.hxx>
20#endif
21
22#ifndef SEC_ABSPOS_HXX
23#include "SEC_abspos.hxx"
24#endif
25#ifndef SEC_GC_HXX
26#include "SEC_gc.hxx"
27#endif
28#ifndef SEC_DB_HXX
29#include "SEC_db.hxx"
30#endif
31
32
33using namespace AW;
34
35#define DATA_VERSION 3
36
37// ------------------
38//      Debugging
39// ------------------
40
41#if defined(DEBUG)
42
43#define CHECK_INTEGRITY         // check structure integrity after changes
44#define PAINT_ABSOLUTE_POSITION // paint some positions near center (range = 0..len-1)
45
46#endif // DEBUG
47
48#ifdef CHECK_INTEGRITY
49enum SEC_CHECK_TYPE {
50    CHECK_STRUCTURE = 1,
51    CHECK_SIZE      = 2,
52    CHECK_POSITIONS = 4,
53    CHECK_ALL       = CHECK_STRUCTURE|CHECK_SIZE|CHECK_POSITIONS, 
54};
55#endif
56
57// -------------------
58//      SEC_region
59// -------------------
60
61class SEC_root;
62
63class SEC_region {
64private:
65    /* non redundant values */
66    int sequence_start, sequence_end; // sequence_end is exclusive
67
68    /* cached values */
69    int baseCount;             // number of real bases (-1 = uninitialized)
70
71    int * abspos_array;
72#if defined(DEBUG)
73    int   abspos_array_size;
74#endif                          // DEBUG
75
76    void create_abspos_array(const int *static_array);
77
78    void set_base_count(int bc) {
79        sec_assert(bc>0);
80        baseCount = bc;
81    }
82
83    void count_bases(SEC_root *root); // updates abspos_array
84   
85public:
86    SEC_region(int start, int end);
87    virtual ~SEC_region();
88
89    //methods
90    void save(std::ostream & out, int indent, const XString& x_string);
91    GB_ERROR read(std::istream & in, SEC_root *root, int version);
92
93    void update_base_count(SEC_root *root) { if (baseCount == -1) count_bases(root); }
94    void invalidate_base_count();
95
96    //selector-methods
97    int get_sequence_start() const { return sequence_start; }
98    int get_sequence_end() const { return sequence_end; }
99   
100    int get_base_count() const { sec_assert(baseCount != -1); return baseCount; }
101
102    bool contains_seq_position(int pos) const {
103        if (sequence_end<sequence_start) {
104            return pos<sequence_end || sequence_start <= pos;
105        }
106        return sequence_start <= pos && pos < sequence_end;
107    }
108
109    void set_sequence_portion(int start, int end) {
110        sequence_start = start;
111        sequence_end = end;
112        invalidate_base_count();
113    }
114    void generate_x_string(XString& x_string);
115    void align_helix_strands(SEC_root *root, SEC_region *other_region);
116
117    int getBasePos(int basenr) const {
118        // some helix positions do not have an absolute position
119        // in that case getBasePos() returns a neighbour position
120        int pos;
121
122        if (basenr >= 0 && basenr<get_base_count()) {
123            sec_assert(basenr >= 0);
124            sec_assert(abspos_array);
125            sec_assert(basenr<abspos_array_size);
126            pos = abspos_array[basenr];
127        }
128        else { // special case for empty strands
129            sec_assert(get_base_count() == 0);
130            sec_assert(basenr <= 0); // 0 or -1
131           
132            pos = (basenr == 0) ? get_sequence_start() : get_sequence_end();
133        }
134        return pos;
135    }
136
137#if defined(CHECK_INTEGRITY)
138    void check_integrity(const SEC_root *root, SEC_CHECK_TYPE what) const;
139#endif // CHECK_INTEGRITY
140};
141
142// -------------------------
143//      SEC_constrainted
144// -------------------------
145
146class SEC_constrainted {
147    double sSize;               // standard size
148    double dSize;               // constrainted size ( = drawn size)
149    double Min, Max;            // limits for dSize (0 means : do not limitate)
150
151    void refreshDrawnSize() { dSize = (sSize<Min && Min>0) ? Min : ((sSize>Max && Max>0) ? Max : sSize); }
152
153public:
154    SEC_constrainted() : sSize(0), dSize(0), Min(0), Max(0) {}
155
156    double drawnSize() const { return dSize; } // constrainted size
157    double standardSize() const { return sSize; } // // unconstrainted size
158
159    double minSize() const { return Min; } // constraints
160    double maxSize() const { return Max; }
161
162    void setDrawnSize(double size) { // calculate constraints as needed
163        if (sSize < size) {
164            Min = size;
165            if (Min>Max) Max = 0;
166            refreshDrawnSize();
167        }
168        else if (sSize > size) {
169            Max = size;
170            if (Max<Min) Min = 0;
171            refreshDrawnSize();
172        }
173
174#if defined(DEBUG) && 0
175        printf("setDrawnSize(%.2f) -> sSize=%.2f dSize=%.2f Min=%.2f Max=%.2f\n", size, sSize, dSize, Min, Max);
176#endif // DEBUG
177    }
178
179    void setStandardSize(double size) { // set standard size (calculated from base counts)
180        sSize = size;
181        refreshDrawnSize();
182    }
183
184    void setConstraints(double low, double high) {
185        Min = low;
186        Max = high;
187        refreshDrawnSize();
188    }
189};
190
191// ---------------------
192//      SEC_oriented
193// ---------------------
194
195class SEC_base;
196
197class SEC_oriented {
198    Angle rel_angle;
199   
200    mutable Angle abs_angle;
201    mutable bool  abs_angle_valid;
202
203    const Angle& calc_abs_angle() const;
204    const Angle& calc_rel_angle();
205
206    virtual SEC_base *get_parent() = 0;
207public:
208    SEC_oriented() : abs_angle_valid(false) {}
209    virtual ~SEC_oriented() {}
210
211    virtual void invalidate_sub_angles() = 0;
212    void invalidate(); // invalidates cached abs_angle of this and substructure
213
214    const Angle& get_abs_angle() const { return abs_angle_valid ? abs_angle : calc_abs_angle(); }
215    const Angle& get_rel_angle() const { return rel_angle; }
216
217    void set_rel_angle(const Angle& rel) {
218        rel_angle = rel;
219        abs_angle_valid = false;
220        invalidate_sub_angles();
221    }
222    void set_abs_angle(const Angle& abs) {
223        if (abs_angle_valid) {
224            Angle diff  = abs-get_abs_angle();
225            sec_assert(rel_angle.normal().is_normalized());
226            rel_angle  += diff;
227            abs_angle   = abs;
228        }
229        else {
230            abs_angle = abs;
231            calc_rel_angle();
232        }
233        invalidate_sub_angles();
234    }
235    void mark_angle_absolute() { abs_angle = rel_angle; abs_angle_valid = true; } // used for root-loop (rel == abs!!)
236
237    SEC_base *parent() { return get_parent(); }
238    const SEC_base *parent() const { return const_cast<SEC_oriented*>(this)->get_parent(); }
239};
240
241
242// ----------------------
243//      SEC_BASE_TYPE
244// ----------------------
245
246enum SEC_BASE_TYPE {
247    SEC_NO_TYPE  = 0, 
248    SEC_LOOP     = 1,
249    SEC_HELIX    = 2,
250    SEC_ANY_TYPE = SEC_LOOP|SEC_HELIX,
251};
252
253// -----------------
254//      SEC_base
255// -----------------
256
257class SEC_base : public SEC_constrainted, public SEC_oriented, Noncopyable { // loop or helix
258    SEC_root *root;
259   
260    virtual SEC_base *get_parent() = 0;
261public:
262    SEC_base(SEC_root *Root) : root(Root) {}
263    virtual ~SEC_base() {}
264
265    virtual SEC_BASE_TYPE getType() const        = 0;
266    virtual const Position& get_fixpoint() const = 0;
267    virtual void reset_angles()                  = 0; // resets all strand-loop angles (of substructure)
268
269    virtual void orientationChanged() = 0; // recalc coordinates
270    virtual void sizeChanged() = 0; // recalc size and coordinates
271
272    AW_CL self() const { return (AW_CL)this; }
273    SEC_root *get_root() const { return root; }
274};
275
276class SEC_base_part : Noncopyable { // segment or strand
277    SEC_region region;
278
279    virtual SEC_base *get_parent()    = 0;
280    virtual SEC_base_part *get_next() = 0;
281public:
282    SEC_base_part() : region(-1, -1) {}
283    virtual ~SEC_base_part() {}
284
285    SEC_base *parent() { return get_parent(); }
286    const SEC_base *parent() const { return const_cast<SEC_base_part*>(this)->get_parent(); }
287   
288    AW_CL self() const { return parent()->self(); }
289    SEC_root *get_root() const { return parent()->get_root(); }
290
291    SEC_base_part *next() { return get_next(); } // iterates through whole structure
292    const SEC_base_part *next() const { return const_cast<SEC_base_part*>(this)->get_next();}
293
294    const SEC_region *get_region() const { return &region; }
295    SEC_region *get_region() { return &region; }
296
297    void set_sequence_portion(int start, int end) { get_region()->set_sequence_portion(start, end); }
298    size_t getNextAbspos() const;
299};
300
301
302// ------------------
303//      SEC_helix
304// ------------------
305
306class SEC_helix_strand;
307class SEC_loop;
308
309class SEC_helix : public SEC_base {
310   
311    SEC_helix_strand *strand_to_root;
312    size_t base_length; // max. # of bases in any strand
313
314    SEC_base *get_parent();
315public:
316
317    SEC_helix(SEC_root *root, SEC_helix_strand *to_root, SEC_helix_strand *from_root);
318    virtual ~SEC_helix() {}
319
320    void calculate_helix_size();
321    void calculate_helix_coordinates(); // assumes root-side loop has correct coordinates
322
323    void save(std::ostream & out, int indent, const XString& x_string);
324    GB_ERROR read(std::istream & in, int version, double& old_angle_in);
325
326    size_t get_base_length()            { return base_length; }
327
328    SEC_helix_strand *strandToRoot() const { return strand_to_root; } // strand pointing to root
329    SEC_helix_strand *strandToOutside() const; // strand pointing away from root
330   
331    SEC_helix_strand *strandAwayFrom(const SEC_loop *loop) const; // strand pointing away from loop
332    SEC_helix_strand *strandTowards(const SEC_loop *loop) const; // strand pointing to loop
333
334    SEC_loop *otherLoop(const SEC_loop *loop) const; // returns the other loop
335    SEC_loop *rootsideLoop() const;
336    SEC_loop *outsideLoop() const;
337
338    bool hasLoop(SEC_loop *loop) const { return loop == rootsideLoop() || loop == outsideLoop(); }
339
340    void setFixpoints(const Position& rootside, const Position& outside);
341
342    void flip();
343
344    void fixAngleBugs(int version);
345
346#if defined(CHECK_INTEGRITY)
347    void check_integrity(SEC_CHECK_TYPE what) const;
348#endif // CHECK_INTEGRITY
349
350    // SEC_oriented interface:
351    void invalidate_sub_angles();
352
353    // SEC_base interface :
354    SEC_BASE_TYPE getType() const { return SEC_HELIX; }
355    void reset_angles();
356    const Position& get_fixpoint() const;
357   
358    void orientationChanged(); // recalc coordinates
359    void sizeChanged(); // recalc size and coordinates
360};
361
362// -------------------------
363//      SEC_helix_strand
364// -------------------------
365
366class SEC_segment;
367
368class SEC_helix_strand : public SEC_base_part {
369    friend class SEC_helix;
370   
371    SEC_loop         *origin_loop;     // Pointer to loop where strand comes from
372    SEC_helix_strand *other_strand;
373    SEC_helix        *helix_info; // used by both strands
374    SEC_segment      *next_segment; // next segment in origin_loop
375
376    //redundant values
377
378    Position fixpoint;
379    Position rightAttach, leftAttach; // rightAttach was ap1, leftAttach was ap2
380
381    void set_helix_info(SEC_helix *helix_info_)            { helix_info = helix_info_; }
382    void set_other_strand(SEC_helix_strand *other_strand_) { other_strand = other_strand_; }
383
384    // SEC_base_part interface
385    SEC_base *get_parent() { return helix_info; }
386    SEC_base_part *get_next();
387   
388public:
389
390    SEC_helix_strand();
391    virtual ~SEC_helix_strand();
392
393    GB_ERROR read(SEC_loop *loop_, std::istream & in, int version);
394
395    void paint(AW_device *device);
396    void unlink(bool fromOtherStrandAsWell);
397   
398    void paint_strands(AW_device *device, const Vector& strand_dir, const double& strand_length);
399    void paint_constraints(AW_device *device);
400   
401    const SEC_root *get_root() const { return helix_info->get_root(); }
402    SEC_root *get_root() { return helix_info->get_root(); }
403
404    const SEC_helix *get_helix() const { return helix_info; }
405    SEC_helix *get_helix() { return helix_info; }
406   
407    const SEC_helix_strand *get_other_strand() const { return other_strand; }
408    SEC_helix_strand *get_other_strand() { return other_strand; }
409
410    // fix- and attach points
411
412    const Position& get_fixpoint() const { return fixpoint; }
413    bool isRootsideFixpoint() const { return helix_info->strandToOutside() == this; }
414
415    bool pointsToRoot() const { return !isRootsideFixpoint(); }
416    bool pointsToOutside() const { return isRootsideFixpoint(); }
417   
418    bool is3end() const { return get_region()->get_sequence_start() > other_strand->get_region()->get_sequence_start(); }
419
420    // Attach point (left/right when looking towards the strand from its origin loop)
421    const Position& rightAttachPoint() const { return rightAttach; }
422    const Position& leftAttachPoint() const { return leftAttach; }
423   
424    const Position& startAttachPoint() const { return leftAttach; }
425    const Position& endAttachPoint() const { return other_strand->rightAttach; }
426
427    int rightAttachAbspos() const {
428        const SEC_region *reg   = get_other_strand()->get_region();
429        int               count = reg->get_base_count();
430       
431        return reg->getBasePos(count ? count-1 : 0);
432    }
433    int leftAttachAbspos() const { return get_region()->getBasePos(0); }
434
435    int startAttachAbspos() const { return leftAttachAbspos(); }
436    int endAttachAbspos() const { return other_strand->rightAttachAbspos(); }
437
438    void setFixpoint(const Position& p) { fixpoint = p; }
439    void setAttachPoints(const Position& left, const Position& right) { rightAttach = right; leftAttach = left; }
440
441    // interator methods
442
443    const SEC_segment *get_next_segment() const { return next_segment; }
444    SEC_segment *get_next_segment() { return next_segment; }
445    SEC_segment * get_previous_segment(); // expensive!
446
447    const SEC_loop *get_origin_loop() const { return origin_loop; }
448    SEC_loop *get_origin_loop() { return origin_loop; }
449    SEC_loop *get_destination_loop() { return get_other_strand()->get_origin_loop(); }
450   
451    SEC_loop *get_rootside_loop() { return isRootsideFixpoint() ? get_origin_loop() : get_destination_loop(); }
452
453    void set_origin_loop(SEC_loop *loop_)                       { origin_loop = loop_; }
454    void set_next_segment(SEC_segment *next_segment_)           { next_segment=next_segment_; }
455
456#if defined(CHECK_INTEGRITY)
457    void check_integrity(SEC_CHECK_TYPE what) const;
458#endif // CHECK_INTEGRITY
459};
460
461
462// --------------------
463//      SEC_segment
464// --------------------
465
466class SEC_segment : public SEC_base_part {
467private:
468    double   alpha;             // angle of segment (i.e. how much of the loop is used by this segment)
469    Position center1, center2; // segments are not circles, they are ellipsoids
470    // center1 is used for rightAttach (of previous helix)
471    // center2 is used for leftAttach (of next helix)
472
473    SEC_helix_strand *next_helix_strand; // next helix strand after segment (pointing away from segments loop)
474    SEC_loop *loop; // the loop containing 'this'
475   
476    // SEC_base_part interface
477    SEC_base *get_parent();
478    SEC_base_part *get_next() { return get_next_strand(); }
479   
480public:
481
482    SEC_segment();
483    virtual ~SEC_segment();
484
485    void save(std::ostream & out, int indent, const XString& x_string);
486    GB_ERROR read(SEC_loop *loop_,std::istream & in, int version);
487
488    void calculate_segment_size();
489    void calculate_segment_coordinates(const Position& start, const Position& end);
490
491    void paint(AW_device *device, SEC_helix_strand *previous_strand_pointer);
492    void unlink();
493   
494    void prepare_paint(SEC_helix_strand *previous_strand_pointer, double &gamma, double &eta, double &radius, int &base_count, double &angle_step);
495
496    void mergeWith(SEC_segment *other, SEC_loop *target_loop);
497    SEC_helix_strand *split(size_t start, size_t end, SEC_segment **new_segment);
498   
499
500    int is_endings_segment() {
501        int seq_start = get_region()->get_sequence_start();
502        int seq_end = get_region()->get_sequence_end();
503
504        return seq_start>seq_end; 
505    }
506
507    void delete_pointer_2(SEC_helix_strand *strand) {
508        SEC_segment *segment = this;
509        while (1) {
510            SEC_helix_strand *next_strand = segment->next_helix_strand;
511
512            if (!next_strand) break;
513            if (next_strand == strand) { segment->next_helix_strand = NULL; break; }
514           
515            segment = next_strand->get_next_segment();
516            if (!segment || segment==this) {
517#if defined(DEBUG)
518                printf("SEC_segment %p did not contain pointer to SEC_helix_strand %p\n", this, strand);
519#endif // DEBUG
520                break;
521            }
522        }
523    }
524
525    SEC_helix_strand *get_previous_strand();
526
527    const SEC_helix_strand *get_next_strand() const { return next_helix_strand; }
528    SEC_helix_strand *get_next_strand() { return next_helix_strand; }
529   
530    const SEC_loop *get_loop() const { return loop; }
531    SEC_loop *get_loop() { return loop; }
532
533    double get_alpha() { return alpha; }
534
535    void set_next_strand(SEC_helix_strand *strand) { next_helix_strand = strand; }
536    void set_loop(SEC_loop *loop_) { loop = loop_; }
537   
538#if defined(CHECK_INTEGRITY)
539    void check_integrity(SEC_CHECK_TYPE what) const;
540#endif // CHECK_INTEGRITY
541};
542
543// -----------------
544//      SEC_loop
545// -----------------
546
547class SEC_loop : public SEC_base {
548    double   Circumferance;     // unit is in "segment-base-distances"
549    Position center;            // center point of loop
550    SEC_helix_strand *primary_strand; // primary strand of loop
551    // loop orientation points towards that strand
552    // for non-root-loops, this strand points towards root
553   
554    void compute_circumferance();
555    void compute_radius();
556
557    SEC_base *get_parent() { return is_root_loop() ? 0 : get_rootside_helix(); }
558
559public:
560
561    SEC_loop(SEC_root *root_);
562    virtual ~SEC_loop();
563   
564    void save(std::ostream & out, int indent, const XString& x_string);
565    GB_ERROR read(SEC_helix_strand *rootside_strand, std::istream & in, int version, double loop_angle);
566   
567    void calculate_loop_size();
568    void calculate_loop_coordinates();
569
570    void paint(AW_device *device);
571    void paint_constraints(AW_device *device);
572
573    const Position& get_center() const { return center; }
574    const double& get_circumferance() const { return Circumferance; } 
575
576    bool is_root_loop() const;
577
578    SEC_helix_strand *get_rootside_strand() const { return is_root_loop() ? 0 : primary_strand; }
579    SEC_helix *get_rootside_helix() const { return is_root_loop() ? 0 : primary_strand->get_helix(); }
580    SEC_helix_strand *get_fixpoint_strand() const { return primary_strand; }
581    SEC_helix *get_fixpoint_helix() const { return primary_strand->get_helix(); }
582
583    void set_fixpoint_strand(SEC_helix_strand *strand) { primary_strand = strand; }
584
585    // void flip_rootside_helices(SEC_helix_strand *new_fixpoint_strand, const Angle& new_rel_angle);
586    void toggle_root(SEC_loop *root_loop);
587
588    void set_center(const Position& p) { center = p; }
589
590    void fixAngleBugs(int version);
591
592#if defined(CHECK_INTEGRITY)
593    void check_integrity(SEC_CHECK_TYPE what) const;
594#endif // CHECK_INTEGRITY
595
596    // SEC_oriented interface:
597    void invalidate_sub_angles();
598
599    // SEC_base interface :
600    SEC_BASE_TYPE getType() const { return SEC_LOOP; }
601    void reset_angles();
602   
603    const Position& get_fixpoint() const {
604        // Note: does not return center for root-loop.
605        SEC_helix *helix = get_fixpoint_helix();
606        return helix->strandAwayFrom(this)->get_fixpoint();
607    }
608
609    void orientationChanged();  // recalc coordinates
610    void sizeChanged(); // recalc size and coordinates
611};
612
613// --------------------------
614//      SEC_displayParams
615// --------------------------
616
617enum ShowBonds {
618    SHOW_NO_BONDS     = 0,
619    SHOW_HELIX_BONDS  = 1,
620    SHOW_NHELIX_BONDS = 2, 
621};
622
623enum ShowCursorPos {
624    SHOW_NO_CURPOS    = 0,
625    SHOW_ABS_CURPOS   = 1,
626    SHOW_ECOLI_CURPOS = 2,
627    SHOW_BASE_CURPOS  = 3,
628};
629
630struct SEC_displayParams {
631    bool   show_helixNrs;       // display helix number information?
632    double distance_between_strands; // distance between strands (1.0 => strand distance == normal distance of bases in loop)
633
634    ShowBonds show_bonds;       // which bonds to show
635    int       bond_thickness;   // linewidth for bonds
636
637    bool hide_bases;            // hide bases?
638
639    ShowCursorPos show_curpos;  // which position to show at cursor
640    bool          show_ecoli_pos; // show ecoli positions?
641   
642    bool display_search;        // show search results
643    bool display_sai;           // visualize SAIs
644
645    bool show_strSkeleton;      // display the skeleton?
646    int  skeleton_thickness;
647   
648    bool edit_direction;        // true = 5'->3', false = 5'<-3'
649
650#if defined(DEBUG)
651    bool show_debug;            // show debug info in structure display
652#endif // DEBUG
653   
654    void reread(AW_root *aw_root);
655};
656
657
658// -----------------
659//      SEC_root
660// -----------------
661
662class AWT_canvas;
663class SEC_drawn_positions;
664class SEC_db_interface;
665class SEC_graphic;
666
667enum SEC_bgpaint_mode {
668    BG_PAINT_NONE   = 0, 
669    BG_PAINT_FIRST  = 1,
670    BG_PAINT_SECOND = 2,
671    BG_PAINT_BOTH   = BG_PAINT_FIRST | BG_PAINT_SECOND,
672};
673
674class SEC_root {
675    SEC_loop *root_loop;
676    int       cursorAbsPos;     // cursor position (-1 == unset)
677    XString  *xString;
678
679    bool constructing; // whether structure is under construction or a complete ring-structure
680
681    SEC_displayParams  displayParams;
682    SEC_db_interface  *db;
683
684    // -----------------------------
685    //      updated before paint
686    // -----------------------------
687   
688    AW_font_group font_group;
689
690    double char_radius[SEC_GC_DATA_COUNT]; // radius and..
691    double bg_linewidth[SEC_GC_DATA_COUNT]; // ..linewidth for drawing background (index = gc)
692    Vector center_char[SEC_GC_FONT_COUNT]; // correction vector to center the base character at its position (world coordinates)
693
694    char *bg_color;       // only valid after paint (contains EDIT4 GCs), may be NULL
695
696    Vector   *autoscroll;       // if non-zero, scroll canvas before next paint
697    int       nailedAbsPos;     // if not -1, auto-scroll such that position does not move
698    Position  drawnAbsPos;      // position where nailedAbsPos was drawn before
699
700    // --------------------------
701    //      valid after paint
702    // --------------------------
703
704    SEC_drawn_positions *drawnPositions; // after paint this contains draw positions for every absolute position
705    LineVector           cursor_line; // main line of the cursor
706
707    SEC_BASE_TYPE show_constraints; 
708
709   
710    void paintHelixNumbers(AW_device *device);
711    void paintEcoliPositions(AW_device *device);
712#if defined(PAINT_ABSOLUTE_POSITION)
713    void showSomeAbsolutePositions(AW_device *device);
714#endif
715    void fixStructureBugs(int version);
716   
717    void cacheBackgroundColor();
718
719    static bool hasBase(int pos, const char *seq, int len) {
720        sec_assert(pos<len);
721        if (pos<len) {
722            char c = seq[pos];
723            return c != '-' && c != '.';
724        }
725        return false;
726    }
727
728    void delete_root_loop() { SEC_loop *old_root_loop = root_loop; root_loop = 0; delete old_root_loop; }
729    void delete_announced_positions();
730
731public:
732
733    SEC_root();
734    ~SEC_root();
735
736    void init(SEC_graphic *gfx, AWT_canvas *ntw);
737
738    bool under_construction() const { return constructing; }
739    void set_under_construction(bool construct) { constructing = construct; }
740
741    const SEC_db_interface *get_db() const { return db; }
742    bool canDisplay() const { return db && db->canDisplay(); }
743    const BI_helix *get_helixDef() const { sec_assert(db); return db->helix(); }
744    BI_PAIR_TYPE getBondtype(int abspos) { const BI_helix *h = get_helixDef(); return h ? h->pairtype(abspos) : HELIX_NONE; }
745    const char *helixNrAt(int abspos) const { return get_helixDef()->helixNr(abspos); }
746
747    const size_t *getHelixPositions(const char *helixNr) const;
748    const double& get_char_radius(int gc) const { return char_radius[gc]; }
749
750    void reread_display_params(AW_root *aw_root) { displayParams.reread(aw_root); }
751    const SEC_displayParams& display_params() const { return displayParams; }
752
753    bool has_xString() const { return xString; }
754    const XString& get_xString() const {
755        sec_assert(xString);
756        return *xString;
757    }
758
759#if defined(CHECK_INTEGRITY)
760    void check_integrity(SEC_CHECK_TYPE what) const;
761#endif // CHECK_INTEGRITY
762
763    // ------------------------------
764
765    void paintBackgroundColor(AW_device *device, SEC_bgpaint_mode mode, const Position& p1, int color1, int gc1, const Position& p2, int color2, int gc2, int skel_gc, AW_CL cd1, AW_CL cd2);
766    void paintSearchPatternStrings(AW_device *device, int clickedPos,  AW_pos xPos,  AW_pos yPos);
767
768    char *buildStructureString();
769    GB_ERROR read_data(const char *input_string, const char *x_string_in);
770
771    void add_autoscroll(const Vector& scroll);
772    void nail_position(size_t absPos); // re-position on absPos
773    void nail_cursor(); // re-position on cursor
774    void position_cursor(bool toCenter, bool evenIfVisible); // scroll/center cursor (screen-only)
775    void set_cursor(int abspos, bool performRefresh); // sets new cursor position
776
777    bool perform_autoscroll();
778
779private: 
780    void calculate_size();
781    void calculate_coordinates();
782public:
783
784#if defined(CHECK_INTEGRITY)
785    void recalc() {                     check_integrity(static_cast<SEC_CHECK_TYPE>(CHECK_STRUCTURE|CHECK_SIZE));
786        calculate_coordinates();        check_integrity(CHECK_POSITIONS);
787    }
788    void relayout() {                   check_integrity(CHECK_STRUCTURE);
789        calculate_size();               check_integrity(CHECK_SIZE);
790        calculate_coordinates();        check_integrity(CHECK_POSITIONS);
791    }
792#else
793    void recalc() {
794        calculate_coordinates();
795    }
796    void relayout() {
797        calculate_size();
798        calculate_coordinates();
799    }
800#endif
801
802    GB_ERROR split_loop(int start1, int end1, int start2, int end2);
803
804    GB_ERROR paint(AW_device *device);
805    GB_ERROR unsplit_loop(SEC_helix_strand *delete_strand);
806    void     set_root(SEC_loop *loop);
807    void     create_default_bone();
808    void     generate_x_string();
809
810    void update_shown_positions();
811    bool shallDisplayPosition(int abspos) const { return db->shallDisplayPosition(abspos); }
812    void invalidate_base_positions(); // force base counts of all regions to be refreshed
813
814    int getBackgroundColor(int abspos) { return bg_color ? bg_color[abspos] : 0; }
815    const Vector& get_center_char_vector(int gc) {
816        sec_assert(gc >= SEC_GC_FIRST_FONT && gc <= SEC_GC_LAST_FONT);
817        return center_char[gc];
818    }
819
820    size_t max_index() {
821        size_t len = db->length();
822        sec_assert(len); // zero len -> no index exists
823        return len-1;
824    }
825   
826    int get_cursor() const { return cursorAbsPos; }
827
828    SEC_loop *get_root_loop() const { return root_loop; }
829    void set_root_loop(SEC_loop *loop) { root_loop = loop; }
830
831    SEC_BASE_TYPE get_show_constraints() { return show_constraints; }
832    void set_show_constraints(SEC_BASE_TYPE show) { show_constraints = show; }
833
834    void set_last_drawed_cursor_position(const LineVector& line) { cursor_line = line; }
835    const LineVector& get_last_drawed_cursor_position() const { return cursor_line; }
836    void clear_last_drawed_cursor_position() { set_last_drawed_cursor_position(LineVector()); } // invalidate cursor_line
837
838    SEC_base_part *find(int pos); // find part containing position pos
839   
840    void announce_base_position(int base_pos, const Position& draw_pos);
841    void clear_announced_positions();
842
843    const AW_font_group& get_font_group() const { return font_group; }
844
845
846    // draw annotation to explicit coordinates (annotation is drawn "above" line left->right)
847    void paintAnnotation(AW_device *device, int gc,
848                         const Position& annotate, const Position& left, const Position& right,
849                         double noteDistance, const char *text,
850                         bool lineToAnnotated, bool linesToLeftRight, bool boxText,
851                         AW_CL cd1, AW_CL cd2);
852
853    // draw a annotation next to a base (only works after paint())
854    void paintPosAnnotation(AW_device *device, int gc, size_t absPos, const char *text, bool lineToBase, bool boxText); 
855};
856
857
858// --------------------------------------------------------------------------------
859// inlines:
860// --------------------------------------------------------------------------------
861
862inline void SEC_helix::flip() {
863    strand_to_root = strand_to_root->get_other_strand();
864}
865
866inline SEC_helix_strand *SEC_helix::strandToOutside() const { // strand pointing away from root
867    return strandToRoot()->get_other_strand();
868}
869
870inline SEC_helix_strand *SEC_helix::strandAwayFrom(const SEC_loop *loop) const { // strand pointing away from loop
871    if (strandToRoot()->get_origin_loop() == loop) {
872        return strandToRoot();
873    }
874    sec_assert(strandToOutside()->get_origin_loop() == loop);
875    return strandToOutside();
876}
877
878inline SEC_helix_strand *SEC_helix::strandTowards(const SEC_loop *loop) const { // strand pointing to loop
879    return strandAwayFrom(loop)->get_other_strand();
880}
881
882inline SEC_loop *SEC_helix::otherLoop(const SEC_loop *loop) const { // returns loop on other side of strand
883    return strandTowards(loop)->get_origin_loop();
884}
885
886inline SEC_loop *SEC_helix::rootsideLoop() const { return strandToOutside()->get_origin_loop(); }
887inline SEC_loop *SEC_helix::outsideLoop() const { return strandToRoot()->get_origin_loop(); }
888
889inline const Position& SEC_helix::get_fixpoint() const { return strandToOutside()->get_fixpoint(); }
890
891inline void SEC_helix::setFixpoints(const Position& rootside, const Position& outside) {
892    strandToRoot()->setFixpoint(outside);
893    strandToOutside()->setFixpoint(rootside);
894}
895
896inline void SEC_helix::orientationChanged() { // recalc coordinates
897    // we need to recalculate the rootside loop, cause changing the
898    // helix-orientation affects the attached loop segments.
899
900    SEC_loop *loop = rootsideLoop();
901
902    if (loop->is_root_loop()) {
903        // at root-loop do a complete recalc
904        // (fixpoint-strand is not relayouted otherwise)
905        get_root()->recalc();
906    }
907    else {
908#if defined(CHECK_INTEGRITY)
909        loop->check_integrity(CHECK_STRUCTURE);
910        loop->check_integrity(CHECK_SIZE);
911#endif // CHECK_INTEGRITY
912        loop->calculate_loop_coordinates();
913#if defined(CHECK_INTEGRITY)
914        loop->check_integrity(CHECK_POSITIONS);
915#endif // CHECK_INTEGRITY
916    }
917}
918inline void SEC_helix::sizeChanged() { // recalc size and coordinates
919#if defined(CHECK_INTEGRITY)
920    check_integrity(CHECK_STRUCTURE);
921#endif // CHECK_INTEGRITY
922    calculate_helix_size();
923#if defined(CHECK_INTEGRITY)
924    check_integrity(CHECK_SIZE);
925#endif // CHECK_INTEGRITY
926    calculate_helix_coordinates();
927#if defined(CHECK_INTEGRITY)
928    check_integrity(CHECK_POSITIONS);
929#endif // CHECK_INTEGRITY
930}
931
932inline SEC_base *SEC_helix::get_parent() { return rootsideLoop(); }
933
934// --------------------
935
936inline SEC_base_part *SEC_helix_strand::get_next() { return get_other_strand()->get_next_segment(); }
937
938// --------------------
939
940inline bool SEC_loop::is_root_loop() const { return get_root()->get_root_loop() == this; }
941
942inline void SEC_loop::orientationChanged() { // recalc coordinates
943    if (is_root_loop()) {
944        get_root()->recalc();
945    }
946    else {
947        // loop center is calculated by helix, that is why we recalc the helix here
948       
949        SEC_helix *helix = get_fixpoint_helix();
950#if defined(CHECK_INTEGRITY)
951        helix->check_integrity(CHECK_STRUCTURE);
952        helix->check_integrity(CHECK_SIZE);
953#endif // CHECK_INTEGRITY
954        helix->calculate_helix_coordinates();
955#if defined(CHECK_INTEGRITY)
956        helix->check_integrity(CHECK_POSITIONS);
957#endif // CHECK_INTEGRITY
958    }
959}
960inline void SEC_loop::sizeChanged() { // recalc size and coordinates
961    if (is_root_loop()) {
962        get_root()->relayout();
963    }
964    else {
965        SEC_helix *helix = get_fixpoint_helix();
966#if defined(CHECK_INTEGRITY)
967        helix->check_integrity(CHECK_STRUCTURE);
968#endif // CHECK_INTEGRITY
969        helix->calculate_helix_size();
970#if defined(CHECK_INTEGRITY)
971        helix->check_integrity(CHECK_SIZE);
972#endif // CHECK_INTEGRITY
973        helix->calculate_helix_coordinates();
974#if defined(CHECK_INTEGRITY)
975        helix->check_integrity(CHECK_POSITIONS);
976#endif // CHECK_INTEGRITY
977    }
978}
979
980// --------------------
981
982inline SEC_base *SEC_segment::get_parent() { return loop; }
983
984// --------------------
985
986inline bool are_adjacent_regions(const SEC_region *reg1, const SEC_region *reg2) {
987    int end1   = reg1->get_sequence_end();
988    int start2 = reg2->get_sequence_start();
989
990    if (end1 == start2) return true;
991
992    return start2 == 0;
993}
994
995
996#else
997#error SEC_root.hxx included twice
998#endif
999
Note: See TracBrowser for help on using the repository browser.