source: tags/svn.1.5.4/SECEDIT/SEC_root.hxx

Last change on this file was 7811, checked in by westram, 14 years ago

merge from dev [7748] [7749] [7750]

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