/***************************************************************************** # Copyright (C) 1994-2008 by David Gordon. # All rights reserved. # # This software is part of a beta-test version of the Consed/Autofinish # package. It should not be redistributed or # used for any commercial purpose, including commercially funded # sequencing, without written permission from the author and the # University of Washington. # # This software is provided ``AS IS'' and any express or implied # warranties, including, but not limited to, the implied warranties of # merchantability and fitness for a particular purpose, are disclaimed. # In no event shall the authors or the University of Washington be # liable for any direct, indirect, incidental, special, exemplary, or # consequential damages (including, but not limited to, procurement of # substitute goods or services; loss of use, data, or profits; or # business interruption) however caused and on any theory of liability, # whether in contract, strict liability, or tort (including negligence # or otherwise) arising in any way out of the use of this software, even # if advised of the possibility of such damage. # # Building Consed from source is error prone and not simple which is # why I provide executables. Due to time limitations I cannot # provide any assistance in building Consed. Even if you do not # modify the source, you may introduce errors due to using a # different version of the compiler, a different version of motif, # different versions of other libraries than I used, etc. For this # reason, if you discover Consed bugs, I can only offer help with # those bugs if you first reproduce those bugs with an executable # provided by me--not an executable you have built. # # Modifying Consed is also difficult. Although Consed is modular, # some modules are used by many other modules. Thus making a change # in one place can have unforeseen effects on many other features. # It may takes months for you to notice these other side-effects # which may not seen connected at all. It is not feasable for me to # provide help with modifying Consed sources because of the # potentially huge amount of time involved. # #*****************************************************************************/ // // EditCursor.h // // The EditCursor Object stores the location and status of an "edit" // cursor. It's called an EditCursor instead of a Cursor to distinguish // it from the X cursor. The edit cursor is equivalent to the cursor // in a text editor (such as emacs) showing where characters typed by // the user will be inserted/overstricken into the text. It appears // in either ContigWin or TedWin as a single character drawn with // foreground and background colors different from those of the surrounding // characters, e.g. reversed. // // An edit cursor appears only on characters, never on a trace. // // In it's current implementation, each ContigWin can have its own // cursor, and the location of a cursor in a TedWin corresponds exactly to // the location of the cursor in the corresponding ContigWin. This means // that the cursor can only appear in TedWin's whose LocatedFragment // currently has the cursor in the ContigWin. All ContigWins can have // cursors (though they might not) but not all TedWins can have cursors // at any given time. // // NOTE: // in some circumstances (startup, new window, etc.) the cursor may be // invalid because it is uninitialized. member functions to return // fragment or contig pointers WILL THROW AN EXCEPTION if the cursor // is invalid, so have the refresh routine call bCursorValid() before // trying to use the pointers or consensus index. // #ifndef EDITCURSOR_DEFINED #define EDITCURSOR_DEFINED #ifdef SCCS_ID static const char* editCursorSccsId = "@(#)EditCursor.h 1.7 05/13/98 14:27:20"; #endif #include "sysdepend.h" #include "assert.h" // // these forward declarations avoid circular include(s) // class Contig; class ContigView; class LocatedFragment; class ContigWin; class EditCursor { public: EditCursor() : pContig_(0), pLocFrag_(0), nConsPos_(0) {} ~EditCursor() {} // // two different ctors with initialization impose the same // rule: "either consensus or fragment but not both" // EditCursor(Contig* pContig, int nConsPos) : pLocFrag_(0), pContig_(pContig), nConsPos_(nConsPos) { validate(); // throws exception if fails } EditCursor(LocatedFragment* pLocFrag, int nConsPos) : pLocFrag_(pLocFrag), pContig_(0), nConsPos_(nConsPos) { validate(); // throws exception if fails } // // convenience functions return bool indicating // whether cursor is valid (used), in consensus or fragment // // CALL THIS FIRST before using member data to refresh // does NOT throw exception, just returns bool indicating // if it's safe to use the cursor. There may not _be_ // a current cursor position. bool bCursorValid() const { return (pContig_ || pLocFrag_); } bool bCursorOnCons() const { return ( pContig_ != 0 ); } bool bCursorOnFrag() const { return ( pLocFrag_ != 0 ); } // // public read-only access to data members. validation // is bug insurance against using member data from // uninitialized EditCursor object, side effects of editing // Contig* pGetContig() { validate(); return pContig_; } Contig* pGetContigEvenIfCursorIsOnRead(); LocatedFragment* pLocFragGet() { validate(); return pLocFrag_; } int nConsPosGet() const { validate(); return nConsPos_; } // // these set the cursor on either a fragment or consensus // note that you can't have it both ways. either will // throw exception if position invalid. // // note that blinking is started the first time that ANY // cursor is set to a valid position // void setCursorOnFrag(LocatedFragment* pLocFrag, int nConsPos) { pLocFrag_ = pLocFrag; pContig_ = 0; nConsPos_ = nConsPos; validate(); } void setCursorOnCons(Contig* pContig, int nConsPos) { pLocFrag_ = 0; pContig_ = pContig; nConsPos_ = nConsPos; validate(); } void advanceCursorAlongRead(); // called when the current cursor position is no longer // valid (fragment has been removed, whatever). void unsetCursor() { pLocFrag_ = 0; pContig_ = 0; nConsPos_ = 0; } // called by the ContigWin when it refreshes the display // after the Contig is complemented void complementPosition(); // this function is called for the purpose of refreshing // the cursor on a ContigWin. throws exception if cursor // invalid. // passed a ContigView as arg, returns boolean indicating // whether the cursor is in that view (and presumably can // be refreshed). sets bOnFrag, boolean, screen line, x // coord of cursor // // if true (in view) // nScreenChar is set to 0 based x coord of char on screen; // bOnFrag is set to true if cursor on fragment; // if bOnFrag (on fragment), // nFragLine is set to the screen line (0 based) of the // fragment, pLocFrag to fragment // else // nFragLine is set to -1; // else (returns false i.e. not in view) // args cleared (-1, null, false); // bool bGetViewPos(ContigWin*, int& nScreenChar, bool& bOnFrag, int& nFragLine) const; bool bGetBlinkState() const { return GuiApp::pGetGuiApp()->bBlinkState_; } private: // throws exception if object is not longer valid - // either the contig or fragment pointer must be non-nil // but not both. the consensus position must be // legal in valid range, and if on a fragment, the // fragment must be aligned at that position void validate() const; Contig* pContig_; LocatedFragment* pLocFrag_; int nConsPos_; // consensus relative position }; #endif // EDITCURSOR_DEFINED