/***************************************************************************** # 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. # #*****************************************************************************/ // // guihighlight.cpp // // X-specific part of highlighting bases // // gordon 11-May-1995 // #include #include #include #include #include #include "guiteditor.h" #include "guitedwin.h" #include "tedwin.h" #include "hp_exception_kludge.h" #include "consedParameters.h" #include "consed.h" #include "teditor.h" void guiTedWinConsButtonPressXtEventHandler(Widget, XtPointer client_data, XEvent* pEvent, Boolean* ) { GuiTedWin *pGuiTedWin = (GuiTedWin*) client_data; int nPixelX = pEvent->xbutton.x; int nY = pEvent->xbutton.y; unsigned int uButton = pEvent->xbutton.button; if (pEvent->xbutton.button == Button1) { TRY_CATCH_WRAPPER( pGuiTedWin->guiSetConsCursor(nPixelX)); } } void guiTedWinFragButtonPressXtEventHandler( Widget, XtPointer client_data, XEvent* pEvent, Boolean* ) { GuiTedWin *pGuiTedWin = (GuiTedWin*) client_data; int nPixelX = pEvent->xbutton.x; int nY = pEvent->xbutton.y; unsigned int uButton = pEvent->xbutton.button; // is this button 1 or 2? if (pEvent->xbutton.button == Button2) { TRY_CATCH_WRAPPER(pGuiTedWin->guiStartHighlight( nPixelX )); } else if (pEvent->xbutton.button == Button1) { TRY_CATCH_WRAPPER(pGuiTedWin->guiSetFragCursor(nPixelX)); } else if (pEvent->xbutton.button == Button3) { TRY_CATCH_WRAPPER( pGuiTedWin->pTedWinGet()->popupTags( nPixelX ) ); } } void guiTedWinButtonReleaseXtEventHandler( Widget, XtPointer client_data, XEvent* pEvent, Boolean* ) { int nX = pEvent->xbutton.x; int nY = pEvent->xbutton.y; unsigned int uButton = pEvent->xbutton.button; // if this button 1 ignore if (pEvent->xbutton.button != Button2) { return; } GuiTedWin *pGuiTedWin = (GuiTedWin*) client_data; TRY_CATCH_WRAPPER(pGuiTedWin->guiContinueHighlight( nX );pGuiTedWin->guiHighlightFinished()); } void guiTedWinButtonMotionXtEventHandler(Widget, XtPointer client_data, XEvent* pEvent, Boolean* ) { int nX = pEvent->xmotion.x; int nY = pEvent->xmotion.y; unsigned long ulSerial = pEvent->xmotion.serial; GuiTedWin *pGuiTedWin = (GuiTedWin*) client_data; TRY_CATCH_WRAPPER(pGuiTedWin->guiContinueHighlight( nX )); } void guiTedWinLeaveNotifyXtEventHandler( Widget, XtPointer, XEvent*, Boolean*) { // cerr << "Left window" << endl; } void guiTedWinKeyPressXtEventHandler(Widget, XtPointer client_data, XEvent* pEvent, Boolean*) { // not concerned with anything other than keypress // just in case one made it here by mistake if (pEvent->type != KeyPress) return; // get this pointer to guitedwin from client data GuiTedWin* pGuiTedWin = (GuiTedWin* )client_data; // translate the event const int nBufSize = 20; char szBuf[nBufSize]; KeySym keySym; XComposeStatus xcsStatus ; // unused through R4 sez O'Reilly int nRetLength = XLookupString((XKeyEvent* )pEvent, szBuf, nBufSize, &keySym, &xcsStatus); char c = szBuf[0]; // printf( "keysym = %x\n", keySym ); // cout << "keysym = " << (void*) ks << endl; cout.flush(); // // keysym constants are defined in // note that modifiers are ignored. if we ever want to care // about Shift, Ctrl, etc. the translation has to be done // more carefully. // if ((keySym == XK_Delete)) { TRY_CATCH_WRAPPER(pGuiTedWin->pTedWinGet()->userOverstruckNtide('*')); } else if ( keySym == XK_BackSpace ) { GuiApp::popupErrorMessage( "To delete a base, overstrike with a *" ); return; } else if ((keySym == XK_Shift_L) || (keySym == XK_Shift_R) || (keySym == XK_Control_L) || (keySym == XK_Control_R) ) { // ignore } else if ( (keySym == XK_Left ) || (keySym == XK_Right ) ) { TRY_CATCH_WRAPPER( pGuiTedWin->pTedWinGet()->userPushedArrowKey( keySym == XK_Left ) ); } else if ( keySym == XK_Up || keySym == XK_Down ) { TRY_CATCH_WRAPPER( pGuiTedWin->pTeditorGet()->userPushedUpDownArrowKey( keySym == XK_Up ) ); } else { switch (c) { case 'A': case 'C': case 'G': case 'T': case 'N': case 'X': case 'a': case 'c': case 'g': case 't': case 'n': case 'x': case '*': case 'R': case 'r': case 'Y': case 'y': case 'M': case 'm': case 'K': case 'k': case 'S': case 's': case 'W': case 'w': case 'D': case 'd': case 'H': case 'h': case 'B': case 'b': case 'V': case 'v': // cout << "overstrike with char " << c << endl; // pass the overstrike event to the TedWin. // note that WHICH char to strike is determined // by the current location of the EditCursor TRY_CATCH_WRAPPER(pGuiTedWin->pTedWinGet()->userOverstruckNtide(c)); break; case ' ': // cout << "space bar interpreted as insert *" << endl; TRY_CATCH_WRAPPER(pGuiTedWin->pTedWinGet()->insertColumnOfPads()); break; case '>': TRY_CATCH_WRAPPER(pGuiTedWin->pTedWinGet()->userPressedHotKey( eChangeToNsToRight ) ); break; case '<': TRY_CATCH_WRAPPER(pGuiTedWin->pTedWinGet()->userPressedHotKey( eChangeToNsToLeft ) ); break; case '\x0C': // control-L TRY_CATCH_WRAPPER(pGuiTedWin->pTedWinGet()->userPressedHotKey( eMakeLowQualityToLeft ) ); break; case '\x12': // control-R TRY_CATCH_WRAPPER(pGuiTedWin->pTedWinGet()->userPressedHotKey( eMakeLowQualityToRight ) ); break; case '\x10': // control-P TRY_CATCH_WRAPPER(pGuiTedWin->pTedWinGet()->userPressedHotKey( eAddPolymorphismTag ) ); break; default: TRY_CATCH_WRAPPER( bool bFoundUserDefinedKey = false; for( int n = 0; n < pCP->aUserDefinedKeys_.length(); ++n ) { if ( c == pCP->aUserDefinedKeys_[ n ] ) { RWCString soProgram = pCP->aProgramsForUserDefinedKeys_[ n ]; RWCString soArgument1 = pCP->aArgumentsToPassToUserDefinedPrograms_[ n]; RWCString soTagWithUserDefinedKey = pCP->aTagsToApplyWithUserDefinedKeys_[n]; pGuiTedWin->pTedWinGet()->userPressedUserDefinedKey( soProgram, soArgument1, soTagWithUserDefinedKey ); bFoundUserDefinedKey = true; break; } } if ( bFoundUserDefinedKey ) break; GuiApp::beep(); break; ); } } } // called by motion and button press event handlers void GuiTedWin :: guiContinueHighlight( int nPixelX ) { handleMovingMouseOffOrBackIntoWindow( nPixelX ); int nConsPos = nConsPosFromPixelX( nPixelX ); pTedWinGet()->continueHighlight( nConsPos ); // record case of the user trying to move the point outside of the // window if ( nPixelX <= 0 || nPixelX >= ( nGetTraceWindowPixelWidth() - 1 ) ) { ConsEd::pGetConsEd()->pGetSelection()->bUserMovedPointerToEdgeOfWindow_ = true; } } void GuiTedWin :: guiStartHighlight( int nPixelX ) { int nConsPos = nConsPosFromPixelX( nPixelX ); pTedWinGet()->startHighlight( nConsPos ); } // handles mouse event in frag window to set cursor void GuiTedWin::guiSetFragCursor( const int nPixelX ) { int nConsPos = nConsPosFromPixelX( nPixelX ); pTedWinGet()->setFragCursor( nConsPos ); } // handles mouse event in consensus window to set cursor void GuiTedWin::guiSetConsCursor(const int nPixelX) { int nConsPos = nConsPosFromPixelX( nPixelX ); pTedWinGet()->setConsCursor( nConsPos ); } void GuiTedWin :: guiHighlightBackground( const int nLeftConsPos, const int nRightConsPos ) { int nLeftPixel = nLeftPixelXFromConsPos( nLeftConsPos ); int nRightPixel = nRightPixelXFromConsPos( nRightConsPos ); int nWindowHeight; Arg aArg[20]; int nArgs = 0; XtSetArg( aArg[ nArgs ], XtNheight, &nWindowHeight ); ++nArgs; XtGetValues( widFragmentBases_, aArg, nArgs ); XFillRectangle( XtDisplay( widFragmentBases_ ), XtWindow( widFragmentBases_ ), pGuiColorTextHighlightBackground_->gcGet(), nLeftPixel, // x origin 0, nRightPixel - nLeftPixel + 1, // width nGetTextWindowHeight( eFragmentBase ) ); } void GuiTedWin :: guiHighlightFinished() { stopAutomaticScrollingIfNecessary(); pTedWinGet()->highlightFinished(); } void GuiTedWin :: handleMovingMouseOffOrBackIntoWindow( const int nPixelX ) { bool bIsNowOnWindow = ( 0 <= nPixelX && nPixelX < nGetTraceWindowPixelWidth() ) ? true : false; if ( bIsNowOnWindow && !bMouseIsOnWindow_ ) { // change back to onto window--remove the timer stopAutomaticScrollingIfNecessary(); } else if ( !bIsNowOnWindow && bMouseIsOnWindow_ ) { // just moved off the window--add the timer bAutomaticallyScrollLeftNotRight_ = ( nPixelX < 0 ? true : false ); pTedWin_->automaticallyScroll(); resetScrollingTimer(); } else if ( bIsNowOnWindow && bMouseIsOnWindow_ ) { return; } else if ( !bIsNowOnWindow && !bMouseIsOnWindow_ ) { return; } bMouseIsOnWindow_ = bIsNowOnWindow; } static void cbAutomaticScrollingTimer( XtPointer pClientData, XtIntervalId* pId ) { TedWin* pTedWin = (TedWin*) pClientData; TRY_CATCH_WRAPPER( pTedWin->automaticScrollingTimer(); pTedWin->pGuiTedWin_->resetScrollingTimer(); ); } void GuiTedWin :: resetScrollingTimer() { bAutomaticScrollingInProgress_ = true; xtidTimerForAutomaticScrolling_ = XtAppAddTimeOut( GAPP->ctxGetAppContext(), pCP->nWhenUserScrollsOffWindowMillisecondsBetweenScrolling_, cbAutomaticScrollingTimer, pTedWin_ ); } void GuiTedWin :: stopAutomaticScrollingIfNecessary() { if ( bAutomaticScrollingInProgress_ ) { XtRemoveTimeOut( xtidTimerForAutomaticScrolling_ ); bAutomaticScrollingInProgress_ = false; } }