/***************************************************************************** # 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. # #*****************************************************************************/ #ifndef GUITEDWIN_INCLUDED #define GUITEDWIN_INCLUDED #include #include #include #include "rwtvalorderedvector.h" #include "sysdepend.h" #include "numutil.h" #include "guiapp.h" #include "motifutils.h" #include "infobutton.h" #include "textfield.h" #include "teditor_types.h" #include "guiapp.h" // // some default initial values for the class // static const int nPixelMarginAboveNumbers = 0; static const int nPixelMarginBelowScaleMarks = 0; static const int nPixelMarginBelowConsensusBases = 0; static const int nPixelMarginAboveConsensusBases = 1; static const int nPixelMarginAboveConsensusScaleNumbers = 0; static const int nPixelMarginBelowConsensusScaleNumbers = 0; static const double dPixelsPerPointInit = 5.0; static const int nHorizontalScaleInit = 30; static const int nOffsetFromLabels = 2; static const int nBottomTextMargin = 0; static const int nFragmentBaseTopMargin = 0; static const int nConsensusTopMargin = 2; static const int nCalledBasesTopMargin = 0; static const int nINVALID_CONS_POS = -99; enum eScaleType { eFragmentPosition, eConsensusPosition }; // forward declarations of objects class Teditor; class TedWin; class GuiTeditor; class GuiTedWin { public: GuiTedWin(TedWin* pTedWin, const int nPositionOnTeditor, const bool bAddToScrollingWindow, const bool bShowABICalledBasesLine, const bool bShowPhredCalledBasesLine, const bool bShowConsensusLine, const bool bShowEditableReadLine, const bool bShowConsensusPositions, const bool bShowScrollbar ); // dtor does nothing. pointers should already be dead, motif // stuff destroyed by GuiTeditor ~GuiTedWin(); // for rogue wave. can only equal self. bool operator == (const GuiTedWin& rGTW) const { return (this == &rGTW); } // return pointer to companion tedwin TedWin* pTedWinGet() { return pTedWin_; } // pointer to parent GuiTeditor is actually obtained from // the Teditor GuiTeditor* pGuiTeditorGet(); Teditor* pGetTeditor(); // get highest level widget of GuiTedWin, the form it is built // upon Widget widGet() { return widFrame_; } // set the read sense arrow pixmap for the trace void setReadSenseForward(); void setReadSenseReverse(); // activate (i.e. make pressable) the undo button void activateUndoButton(); // deactivate (i.e. make not pressable) the undo button void deactivateUndoButton(); int nGetTraceWindowPointsWide(); void guiClearWindow( eTeditorType eTeditorTypee ); void guiDrawBaseAtPeakPosition( eTeditorType eTeditorTypee, int nPointLocation, char cBase, GuiColorText* pGuiColorText, const bool bLeftMostBase); void guiDrawBaseAtSavedPixelPosition( eTeditorType eTeditorTypee, int nConsPos, char cBase, GuiColorText* pGuiColorText ); void guiDrawHalfCharacterTagAtSavedPixelPosition( const eTeditorType eTeditorTypee, int nConsPos, GuiColorText* pGuiColorTextForTag ); void guiDrawBaseWithoutBackgroundAtSavedPixelPosition( const eTeditorType eTeditorTypee, int nConsPos, char cBase, GuiColorText* pGuiColorText ); static GuiColorText* pGetGuiColorTextA() { return( pGuiColorTextA_); } static GuiColorText* pGetGuiColorTextC() { return( pGuiColorTextC_); } static GuiColorText* pGetGuiColorTextG() { return( pGuiColorTextG_); } static GuiColorText* pGetGuiColorTextT() { return( pGuiColorTextT_); } static GuiColorText* pGetGuiColorTextN() { return( pGuiColorTextN_); } static GuiColorText* pGetGuiColorTextPad() { return( pGuiColorTextPad_); } static GuiColorText* pGetGuiColorTextHighlightedA() { return( pGuiColorTextHighlightedA_); } static GuiColorText* pGetGuiColorTextHighlightedC() { return( pGuiColorTextHighlightedC_); } static GuiColorText* pGetGuiColorTextHighlightedG() { return( pGuiColorTextHighlightedG_); } static GuiColorText* pGetGuiColorTextHighlightedT() { return( pGuiColorTextHighlightedT_); } static GuiColorText* pGetGuiColorTextHighlightedN() { return( pGuiColorTextHighlightedN_); } static GuiColorText* pGetGuiColorTextHighlightedX() { return( pGuiColorTextHighlightedX_); } static GuiColorText* pGetGuiColorTextHighlightedPad() { return( pGuiColorTextHighlightedPad_); } static GuiColorText* pGetGuiColorTextHighlightBackground() { return( pGuiColorTextHighlightBackground_); } static GuiColorText* pGetGuiColorTextForScale() { return( pGuiColorTextForScale_ ); } static GuiColorText* pGetGuiColorTextForConsensusCursor() { return( pGuiColorTextForConsCursor_ ); } static GuiColorText* pGetGuiColorTextForScaleNumbers() { return( pGuiColorTextForScaleNumbers_ ); } // returns the left edge position of the window as point index int nGetLeftEdgePointPosition() const { return(nLeftEdgePointPosition_); } // returns the right edge position of the window as point index int nGetRightEdgePointPosition() { return( nLeftEdgePointPosition_ + nGetTraceWindowPointsWide() - 1); } void setLeftEdgePointPosition( const int nNewLeftEdgePointPosition ) { nLeftEdgePointPosition_ = nNewLeftEdgePointPosition; } // returns the widget of the drawing area depending on which // type of base. these include the three lines of (text) // bases and the widget used for drawing the positions and tickmarks Widget widGetWidgetFromBaseType( eTeditorType eTeditorTypee ); // returns height of trace window in pixels int nGetTraceWindowHeight(); int nGetTraceWindowPixelWidth(); // returns graphics context to draw trace determined by // single char argument of base type ('A', 'C', etc.) GC GCForTrace( const char c ); // draw the trace of passed type void drawTrace( const char c ); // clear the trace drawing area window void clearTracesWindow(); int nGetTraceHeightFactor(); float fGetScaleFactorToAutomaticallyScaleTraces(); // passed position in points, sets scrollbar resources to that // position and saves new current pos in member data void setScrollBarPosition( const int nNewScrollBarPosition ); // used when changing horizontal magnification and scrolling under program // control at the same time void setScrollBarPositionAndResizeSlider(); void guiTedWinResetSlider(const int nCurrentPosition, const int nMin, const int nMax, const int nUnitsDisplayed ); void resizeSlider(); void guiStartHighlight( int nX ); void guiContinueHighlight( int nX ); void guiHighlightBackground( const int nLeftPoint, const int nRightPoint ); void guiHighlightFinished(); void handleMovingMouseOffOrBackIntoWindow( const int nPixelX ); void stopAutomaticScrollingIfNecessary(); void resetScrollingTimer(); // handles mouse event in frag window to set cursor void guiSetFragCursor(const int nX); // handles mouse event in consensus window to set cursor void guiSetConsCursor(const int nX); // these two draw the unpadded consensus position and tickmark in // the scale drawing area. not all tickmarks always get numbers. // if the window gets packed too tight, only every 5th one // gets a number void guiDrawScaleNumber(const int nNumberToDraw, const int nConsPos, const eScaleType eScaleTypee, const bool bDrawInShowAllTracesConsensusWindow ); void guiDrawScaleTick(const int nConsPos, const bool bDrawBigTick, const bool bDrawInShowAllTracesConsensusWindow ); // draws the line below numbers and above tickmarks void guiDrawScaleLine( const bool bDrawInShowAllTracesConsensusWindow ); // draw the line that separates the consensus bases from // fragment bases. void guiDrawConsSepLine(); // used whenever an event occurs (e.g., scrolling) that changes // the pixel locations void clearBasePixelPositions(); void setLeftMostConsPos( const int nConsPosMin ) { nLeftMostConsPos_ = nConsPosMin; } void guiSetBasePixelPosition( const int nConsPos, const int nPointPosition ); // used to draw bases and scale int nPixelXFromConsPos( const int nConsPos ); // used to set cursor int nConsPosFromPixelX( const int nPixelX ); // should probably only be used internally to GuiTedWin int nZeroBasedBaseIndexFromPixelX( const int nPixelX ); // used to highlight characters--finds left pixel boundary of // highlighted region int nLeftPixelXFromConsPos( const int nConsPos ); // same as above, but finds the right boundary int nRightPixelXFromConsPos( const int nConsPos ); // refers to the bases whose pixel positions are saved void getSavedRangeOfConsensusPositions( int& nConsPosMin, int& nConsPosMax ); // differs slightly from above in that it returns the range of // bases whose peaks fall within the range of points--useful // for aligning traces void getSavedRangeOfConsensusPositionsOnScreen( int& nConsPosMin, int& nConsPosMax, bool& bPartOfTraceWithoutBases ); int nPixelXOfTick( const int nConsPos ); // kludge determines how much drawing area width required for // passed number, returned value in pixels so // we can determine if there's enough room to draw the // consensus/fragment position over every tickmark int nGetPixelsRequiredForString(const int nCharactersWide); bool bGuiTedWinsScrollTogether(); void changeGuiTedWinsScrollTogetherButtons( const bool bScrollTogether ); // int nGetApproxPixelsPerBase(); void getWindowInMasterAboutCursor( int& nConsPosToAlign, int& nConsPosLeft, int& nConsPosRight, bool& bInPartOfTraceWithoutBases ); void alignTraceToMaster(); void setScrollBarAtMax(); void screenBlackAndScrollBarAtFarRight(); void screenBlackAndScrollBarAtFarLeft(); void setHorizontalMagnification( const double dPixelsPerPoint ); void setHorizontalMagnificationSlider(); GuiTedWin* pGetGuiTedWinScrollMaster(); void guiDrawVerticalLineThroughTraces( const int nPointPos ); void alignScrollingWindowConsensusToThisTrace(); //////////////////////////////////////////////////////////////////// // // these member data are used to position within // the base numbers widget // //////////////////////////////////////////////////////////////////// int nScaleNumbersBaseline( const eScaleType eScaleTypee) const { if ( eScaleTypee == eConsensusPosition ) return( nPixelMarginAboveNumbers + GuiApp::pGetGuiApp()->nGetFontHeight() ); else if (eScaleTypee == eFragmentPosition) { if ( bShowConsensusPositionsLine_ ) return( nScaleNumbersBaseline( eConsensusPosition ) + nPixelMarginAboveNumbers + GuiApp::pGetGuiApp()->nGetFontHeight() ); else return( nPixelMarginAboveNumbers + GuiApp::pGetGuiApp()->nGetFontHeight() ); } else assert( false ); } inline int nScaleLinePixelY() const { return (int) (nScaleNumbersBaseline( eFragmentPosition ) + .5 * GuiApp::pGetGuiApp()->nGetFontAscent()); } static inline int nScaleMarksHeight() { return (int) (.5 * GuiApp::pGetGuiApp()->nGetFontHeight() ); } inline int nGetScaleWidgetHeight() { return (nScaleLinePixelY() + nScaleMarksHeight() + nPixelMarginBelowScaleMarks ); } static inline int nShowAllTracesScaleNumbersBaseline() { return( nPixelMarginAboveConsensusScaleNumbers + GuiApp::pGetGuiApp()->nGetFontAscent() ); } static inline int nGetShowAllTracesScaleLinePixelY() { // the +1 is because the scale line must start at // least on the pixel below the bottom pixel of the numbers return ( nShowAllTracesScaleNumbersBaseline() + 1 + nPixelMarginBelowConsensusScaleNumbers ); } static inline int nGetShowAllTracesConsensusScaleHeight() { return( nGetShowAllTracesScaleLinePixelY() + nScaleMarksHeight() + nPixelMarginBelowScaleMarks ); } static inline int nGetShowAllTracesConsensusWindowHeight() { int nHeight = GuiApp::pGetGuiApp()->nGetFontHeight() + nPixelMarginBelowConsensusBases + nPixelMarginAboveConsensusBases; return( nHeight ); } static void allocateColors(); // create them static void maybeChangeTracesDashedOrNot( const bool bDashed ); void grabInputFocus(); public: // pointer to companion TedWin object TedWin *pTedWin_; // Teditor is available through TedWin. // not inlined to avoid circular includes Teditor* pTeditorGet(); // this is the highest level contained within the GuiTedWin // which is assumed to be attached to some larger form on // a dialog box or application shell widget Widget widFrame_; Widget widForm_; // child of frame // all these are positioned on widForm_ Widget widScale_; Widget widShowAllTracesConsensusScale_; Widget widConsensus_; Widget widFragmentBases_; Widget widPhredCalledBases_; Widget widABICalledBases_; Widget widTraces_; Widget widHorizontalScale_; Widget widVerticalScale_; Widget widScrollBar_; Widget widReadSenseLabel_; Widget widConsensusScaleLabel_; Widget widReadScaleLabel_; Widget widConsensusLabel_; Widget widFragmentBasesLabel_; Widget widPhredCalledBasesLabel_; Widget widABICalledBasesLabel_; Widget widYes_; Widget widNo_; Widget widSequenceName_; bool bShowABICalledBases_; bool bShowPhredCalledBasesLine_; bool bShowConsensusLine_; bool bShowEditableReadLine_; bool bShowConsensusPositionsLine_; bool bShowScrollbar_; // this button destroys the GuiTedWin. if the last one in // the guiteditor, it gets destroyed too InfoButton ibRemove_; // this button implements global undo edit Widget widUndoButton_; Widget widSelectButton_; static GuiColorText* pGuiColorTextA_; static GuiColorText* pGuiColorTextC_; static GuiColorText* pGuiColorTextG_; static GuiColorText* pGuiColorTextT_; static GuiColorText* pGuiColorTextN_; static GuiColorText* pGuiColorTextPad_; static GuiColorText* pGuiColorTextHighlightedA_; static GuiColorText* pGuiColorTextHighlightedC_; static GuiColorText* pGuiColorTextHighlightedG_; static GuiColorText* pGuiColorTextHighlightedT_; static GuiColorText* pGuiColorTextHighlightedN_; static GuiColorText* pGuiColorTextHighlightedX_; static GuiColorText* pGuiColorTextHighlightedPad_; static GuiColorText* pGuiColorTextHighlightBackground_; static GuiColorText* pGuiColorTextForScale_; static GuiColorText* pGuiColorTextForConsCursor_; static GuiColorText* pGuiColorTextForScaleNumbers_; static bool bTracesGCSetToDashed_; // the pixmaps for read sense (triangle pointing left or right) // are shared by all members of the class, and created only // once, the first time through the ctor static bool bPixmapsCreated_; // indicates whether created yet static Pixmap pixSenseForward_; // points right static Pixmap pixSenseReverse_; // points left // similarly the colors are allocated once for the entire class static bool bColorsAllocated_; // indicates whether created yet double dPixelsPerPoint_; int nLeftEdgePointPosition_; int nVerticalScaleValue_; // method of keeping all bases visible and moving to the right // in order of consensus position int nPixelXPreviousBase_; // Information about the pixel positions of the displayed bases // This includes the consensus bases and the editable read bases. // The phred called bases are positioned according to their point // positions, with a little shove over if they get too close (or // reverse their order). RWTValOrderedVector aBasePixelPositions_; int nLeftMostConsPos_; // Used to prevent resize event from being processed during the // construction of the widgets bool bGuiTedWinCtorFinished_; bool bMouseIsOnWindow_; bool bAutomaticallyScrollLeftNotRight_; bool bAutomaticScrollingInProgress_; XtIntervalId xtidTimerForAutomaticScrolling_; private: // // friend functions allow xt callbacks access to private // member data // friend void guiTedWinResizeXtCb(Widget, GuiTedWin*, XmDrawingAreaCallbackStruct*); friend void guiTedWinExposureXtCb( Widget, GuiTedWin*, XmDrawingAreaCallbackStruct*); friend void guiTedWinScaleExposureXtCb(Widget, GuiTedWin*, XmDrawingAreaCallbackStruct*); friend void guiTedWinSameAsContigWinExposureXtCb(Widget wid, GuiTedWin*, XmDrawingAreaCallbackStruct*); friend void guiTedWinConsensusExposureXtCb(Widget, GuiTedWin*, XmDrawingAreaCallbackStruct*); friend void guiTedWinABICalledBasesXtCb(Widget, GuiTedWin*, XmDrawingAreaCallbackStruct*); friend void guiTedWinPhredCalledBasesXtCb(Widget, GuiTedWin*, XmDrawingAreaCallbackStruct*); friend void guiTedWinTracesExposureXtCb(Widget, GuiTedWin*, XmDrawingAreaCallbackStruct*); friend void guiTedWinScrollBarXtCb(Widget, GuiTedWin*, XmScrollBarCallbackStruct*); friend void guiTedWinHorizontalMagXtCb(Widget, GuiTedWin*, XmScaleCallbackStruct*); friend void guiTedWinVerticalMagXtCb(Widget, GuiTedWin*, XmScaleCallbackStruct*); friend void guiTedWinResizeXtCb(Widget, GuiTedWin*, XmDrawingAreaCallbackStruct*); friend void cbScrollTogetherRadioBox( Widget wid, GuiTedWin* pGuiTedWin, XmToggleButtonCallbackStruct *pXmToggleButtonCallbackStruct ); void createReadSensePixmaps(); // create them int nPixelXFromPoint( const int nPointLocation ); int nPointFromPixelX( const int nPixelX ); int nGetTextBaseline( eTeditorType eTeditorTypee); int nGetTextTopPixel( eTeditorType eTeditorTypee) { return( nGetTextBaseline( eTeditorTypee ) - GuiApp::pGetGuiApp()->nGetFontAscent() ); } int nGetTextWindowHeight( eTeditorType eTeditorTypee); Widget widMakeLabel( const eTeditorType eTeditorTypee, const int nPositionY = 0 ); int nGetMaxWidthOfLabels(); int nGetTextWindowMidlineInRootCoords( eTeditorType eTeditorTypee ); void positionLabel( eTeditorType eTeditorTypee ); int nRootYCoordsToFormYCoords( const int nRootYCoord ); inline Widget widGetScaleWidget( const bool bDrawInShowAllTracesConsensusWindow ) { return( (bDrawInShowAllTracesConsensusWindow ? widShowAllTracesConsensusScale_ : widScale_ ) ); } }; // class GuiTedWin void guiTedWinResizeXtCb(Widget, GuiTedWin*, XmDrawingAreaCallbackStruct*); void guiTedWinExposureXtCb( Widget, GuiTedWin*, XmDrawingAreaCallbackStruct*); void guiTedWinScaleExposureXtCb(Widget, GuiTedWin*, XmDrawingAreaCallbackStruct*); void guiTedWinSameAsContigWinExposureXtCb(Widget wid, GuiTedWin*, XmDrawingAreaCallbackStruct*); void guiTedWinConsensusExposureXtCb(Widget, GuiTedWin*, XmDrawingAreaCallbackStruct*); void guiTedWinABICalledBasesXtCb(Widget, GuiTedWin*, XmDrawingAreaCallbackStruct*); void guiTedWinPhredCalledBasesXtCb(Widget, GuiTedWin*, XmDrawingAreaCallbackStruct*); void guiTedWinTracesExposureXtCb(Widget, GuiTedWin*, XmDrawingAreaCallbackStruct*); void guiTedWinScrollBarXtCb(Widget, GuiTedWin*, XmScrollBarCallbackStruct*); void guiTedWinHorizontalMagXtCb(Widget, GuiTedWin*, XmScaleCallbackStruct*); void guiTedWinVerticalMagXtCb(Widget, GuiTedWin*, XmScaleCallbackStruct*); void guiTedWinResizeXtCb(Widget, GuiTedWin*, XmDrawingAreaCallbackStruct*); void cbScrollTogetherRadioBox( Widget wid, GuiTedWin* pGuiTedWin, XmToggleButtonCallbackStruct *pXmToggleButtonCallbackStruct ); #endif