/***************************************************************************** # 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. # #*****************************************************************************/ // // guiteditor.cpp // // gordon 17-April-1995 // #include "guiteditor.h" #include "guitedwin.h" #include "tedwin.h" #include "teditor.h" #include "rwcstring.h" #include "contigwin.h" #include "guiapp.h" #include #include #include #include "infobutton.h" #include "guicontigwin.h" #include "handleWindowManagerDelete.h" #include "popupInfoMessage.h" #include #include "consedParameters.h" #include #include "hp_exception_kludge.h" #include #include #include #include #include "waitUntilDialogIsVisible.h" // // some local defaults // // these are the (user strechable) initial dimensions of an individual // GuiTedWin. behavior note: the height of each GuiTedWin in the // GuiTeditor will snap back to this default when one is added or // removed and the GuiTeditor gets resized (and the GuiTedwins // repositioned on the form). The width stays the same (so as not // to mess with a user choice unneccessarily). // // for reasons I still don't understand, the resizing must be done // to the GuiTeditor and not to individual GuiTedWins. The parent // form just isn't resizing in response to its children. The reverse // is true however: by resizing the parent form, all attached // GuiTedWins resize correctly. go figure. // const int nDefaultTedWinHeight = 200; const int nDefaultTedWinWidth = 800; const int nMarginAboveGuiTedWins = 0; const int nMarginBelowGuiTedWins = 25; void cbDismissGuiTeditor( Widget wid, XtPointer pClientData, XtPointer pCallData ); void cbHelpInsert( Widget wid, XtPointer pClientData, XtPointer pCallData ); void cbHelpDelete( Widget wid, XtPointer pClientData, XtPointer pCallData ); static void cbResizeWorkArea( Widget wid, XtPointer pClientData, XtPointer pCallData ) { GuiTeditor* pGuiTeditor = (GuiTeditor*) pClientData; TRY_CATCH_WRAPPER( pGuiTeditor->resizeScrollingTraces() ); } static void cbShowPrevTraces( Widget wid, XtPointer pClientData, XtPointer pCallData ) { GuiTeditor* pGuiTeditor = (GuiTeditor*) pClientData; TRY_CATCH_WRAPPER( pGuiTeditor->pTeditor_->showNextPrevTraces( Teditor::cPrevTraces ) ); } static void cbShowNextTraces( Widget wid, XtPointer pClientData, XtPointer pCallData ) { GuiTeditor* pGuiTeditor = (GuiTeditor*) pClientData; TRY_CATCH_WRAPPER( pGuiTeditor->pTeditor_->showNextPrevTraces( Teditor::cNextTraces ) ); } static void cbUserPushedShowAllSomeTracesButton( Widget wid, XtPointer pClientData, XtPointer pCallData ) { GuiTeditor* pGuiTeditor = (GuiTeditor*) pClientData; TRY_CATCH_WRAPPER( pGuiTeditor->userPushedShowSomeAllTracesButton() ); } static void cbGuiTeditorConsensusExposure( Widget wid, XtPointer pClientData, XtPointer pCallData ) { GuiTeditor* pGuiTeditor = (GuiTeditor*) pClientData; // if the teditor has just been created, the scroll master may // not have been selected yet--avoid segmentation fault if ( ! pGuiTeditor->pTeditor_->pGuiTedWinScrollMaster_ ) return; TRY_CATCH_WRAPPER( pGuiTeditor->pTeditor_->pGuiTedWinScrollMaster_->pTedWinGet()->drawConsensusBases() ); } static void cbGuiTeditorConsensusScaleExposure( Widget wid, XtPointer pClientData, XtPointer pCallData ) { GuiTeditor* pGuiTeditor = (GuiTeditor*) pClientData; // if the teditor has just been created, the scroll master may // not have been selected yet--avoid segmentation fault if ( ! pGuiTeditor->pTeditor_->pGuiTedWinScrollMaster_ ) return; TRY_CATCH_WRAPPER( pGuiTeditor->pTeditor_->pGuiTedWinScrollMaster_->pTedWinGet()->drawScale( true, // bDrawInShowAllTracesConsensusWindow true ) // bDrawConsensusPositions ); } static void cbNavigateToPreviousItem( Widget wid, XtPointer pClientData, XtPointer pCallData ) { TRY_CATCH_WRAPPER( GuiTeditor* pGuiTeditor = (GuiTeditor*) pClientData; pGuiTeditor->pTeditor_->pContigWin_->navigateToNextOrPreviousItem( false ); ); } static void cbNavigateToNextItem( Widget wid, XtPointer pClientData, XtPointer pCallData ) { TRY_CATCH_WRAPPER( GuiTeditor* pGuiTeditor = (GuiTeditor*) pClientData; pGuiTeditor->pTeditor_->pContigWin_->navigateToNextOrPreviousItem( true ); ); } // the ctor for the gui teditor does not need any widgets, etc. // that are not already created, hence there is no initialize() // routine GuiTeditor::GuiTeditor(Teditor* pTeditor, const int nStartWithThisManyTraces, const bool bShowTracesInScrollingWindow ) : pTeditor_(pTeditor), bShowTracesInScrollingWindow_( bShowTracesInScrollingWindow ) { // position the teditor so it doesn't obstruct the alignment window Widget widGuiContigWin = pContigWinGet()->pGcw_->widGetGuiContigWinTopLevel(); Dimension nHeight; Dimension nWidth; Position nY; Position nX; XtVaGetValues( widGuiContigWin, XmNheight, &nHeight, XmNwidth, &nWidth, XmNy, &nY, XmNx, &nX, NULL ); Arg aArg[30]; int nArgs; // the dibox title RWCString soDiboxTitle("Trace Window: "); // append contig name soDiboxTitle.append(pContigWinGet()->pGetContig()->soGetName()); widShell_ = XtVaCreatePopupShell( "consed", topLevelShellWidgetClass, GuiApp::pGetGuiApp()->widGetTopLevel(), XmNtitle, (char *)soDiboxTitle.data(), XmNiconName, (char *)soDiboxTitle.data(), XmNy, nY + nHeight, XmNx, nX, XmNdeleteResponse, XmDO_NOTHING, NULL ); handleWindowManagerDelete( widShell_ ); // the immediate child of the application shell is a // main window // widMainWin_ = // XtVaCreateManagedWidget("mainwin", // xmMainWindowWidgetClass, widShell_, // XmNancestorSensitive, True, // // XtNwidth, nDefaultTedWinWidth, // NULL ); Widget widGuiTeditorTopForm = XtVaCreateManagedWidget("form", xmFormWidgetClass, widShell_, XmNshadowThickness,0, XmNborderWidth,0, XmNancestorSensitive,True, NULL ); if ( bShowTracesInScrollingWindow ) { XtVaSetValues( widGuiTeditorTopForm, XmNfractionBase, 100, NULL ); } else { XtVaSetValues( widGuiTeditorTopForm, XmNfractionBase, 24, NULL ); } int nDismissLeftPosition; int nDismissRightPosition; int nHelpInsertLeftPosition; int nHelpInsertRightPosition; int nPrevLeftPosition; int nPrevRightPosition; int nNextLeftPosition; int nNextRightPosition; int nHelpDeleteLeftPosition; int nHelpDeleteRightPosition; int nNext50TracesLeftPosition; int nNext50TracesRightPosition; int nPrev50TracesLeftPosition; int nPrev50TracesRightPosition; int nDismissTopLeftPosition; int nDismissTopRightPosition; if ( bShowTracesInScrollingWindow ) { nHelpInsertLeftPosition = 2; nHelpInsertRightPosition = 14; nPrev50TracesLeftPosition = 15; nPrev50TracesRightPosition = 29; nPrevLeftPosition = 30; nPrevRightPosition = 42; nDismissLeftPosition = 44; nDismissRightPosition = 56; nNextLeftPosition = 58; nNextRightPosition = 70; nNext50TracesLeftPosition = 71; nNext50TracesRightPosition = 85; nHelpDeleteLeftPosition = 86; nHelpDeleteRightPosition = 98; nDismissTopLeftPosition = 41; nDismissTopRightPosition = 59; } else { nHelpInsertLeftPosition = 0; nHelpInsertRightPosition = 4; nPrevLeftPosition = 5; nPrevRightPosition = 9; nDismissLeftPosition = 10; nDismissRightPosition = 14; nNextLeftPosition = 15; nNextRightPosition = 19; nHelpDeleteLeftPosition = 20; nHelpDeleteRightPosition = 24; nDismissTopLeftPosition = 10; nDismissTopRightPosition = 14; } widDismissTop_ = XtVaCreateManagedWidget( "Dismiss", xmPushButtonWidgetClass, widGuiTeditorTopForm, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, nDismissTopLeftPosition, XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, nDismissTopRightPosition, XmNalignment, XmALIGNMENT_CENTER, XmNtraversalOn, False, NULL ); XtAddCallback(widDismissTop_, XmNactivateCallback, (XtCallbackProc )cbDismissGuiTeditor, this); // // dismiss button at middle bottom // widDismissBottom_ = XtVaCreateManagedWidget( "Dismiss", xmPushButtonWidgetClass, widGuiTeditorTopForm, XmNtopAttachment, XmATTACH_NONE, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, 1, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, nDismissLeftPosition, XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, nDismissRightPosition, XmNalignment, XmALIGNMENT_CENTER, NULL ); XtAddCallback( widDismissBottom_, XmNactivateCallback, (XtCallbackProc) cbDismissGuiTeditor, this ); nArgs = 0; nArgs = 0; XtSetArg(aArg[nArgs], XmNtopAttachment, XmATTACH_NONE); nArgs++; XtSetArg(aArg[nArgs], XmNbottomAttachment, XmATTACH_FORM); nArgs++; XtSetArg(aArg[nArgs], XmNbottomOffset, 1 ); nArgs++; XtSetArg(aArg[nArgs], XmNleftAttachment, XmATTACH_POSITION); nArgs++; XtSetArg(aArg[nArgs], XmNleftPosition, nHelpInsertLeftPosition ); nArgs++; XtSetArg(aArg[nArgs], XmNrightAttachment, XmATTACH_POSITION); nArgs++; XtSetArg(aArg[nArgs], XmNrightPosition, nHelpInsertRightPosition ); nArgs++; XtSetArg(aArg[nArgs], XmNalignment, XmALIGNMENT_CENTER); nArgs++; XtSetArg(aArg[nArgs], XmNtraversalOn, False); nArgs++; widHelpInsertButton_ = XmCreatePushButton(widGuiTeditorTopForm, "Help Insert", aArg, nArgs); XtAddCallback(widHelpInsertButton_, XmNactivateCallback, (XtCallbackProc )cbHelpInsert, this); XtManageChild(widHelpInsertButton_); widPrev_ = XtVaCreateManagedWidget( "prev", xmPushButtonWidgetClass, widGuiTeditorTopForm, XmNtopAttachment, XmATTACH_NONE, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, 1, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, nPrevLeftPosition, XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, nPrevRightPosition, XmNalignment, XmALIGNMENT_CENTER, XmNtraversalOn, False, NULL ); XtAddCallback( widPrev_, XmNactivateCallback, cbNavigateToPreviousItem, this ); widNext_ = XtVaCreateManagedWidget( "next", xmPushButtonWidgetClass, widGuiTeditorTopForm, XmNtopAttachment, XmATTACH_NONE, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, 1, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, nNextLeftPosition, XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, nNextRightPosition, XmNalignment, XmALIGNMENT_CENTER, XmNtraversalOn, False, NULL ); XtAddCallback( widNext_, XmNactivateCallback, cbNavigateToNextItem, this ); nArgs = 0; XtSetArg(aArg[nArgs], XmNtopAttachment, XmATTACH_NONE); nArgs++; XtSetArg(aArg[nArgs], XmNbottomAttachment, XmATTACH_FORM); nArgs++; XtSetArg(aArg[nArgs], XmNbottomOffset, 1 ); nArgs++; XtSetArg(aArg[nArgs], XmNleftAttachment, XmATTACH_POSITION); nArgs++; XtSetArg(aArg[nArgs], XmNleftPosition, nHelpDeleteLeftPosition ); nArgs++; XtSetArg(aArg[nArgs], XmNrightAttachment, XmATTACH_POSITION); nArgs++; XtSetArg(aArg[nArgs], XmNrightPosition, nHelpDeleteRightPosition ); nArgs++; XtSetArg(aArg[nArgs], XmNalignment, XmALIGNMENT_CENTER); nArgs++; XtSetArg(aArg[nArgs], XmNtraversalOn, False); nArgs++; widHelpDeleteButton_ = XmCreatePushButton(widGuiTeditorTopForm, "Help Delete", aArg, nArgs); XtAddCallback(widHelpDeleteButton_, XmNactivateCallback, (XtCallbackProc )cbHelpDelete, this); XtManageChild(widHelpDeleteButton_); if ( bShowTracesInScrollingWindow_ ) { RWCString soLabel = "prev "; soLabel += RWCString( (long) pCP->nShowAllTracesMaxNumberOfTracesToShowAtOnce_ ); soLabel += " traces"; widPrevTraces_ = XtVaCreateManagedWidget( soLabel.data(), xmPushButtonWidgetClass, widGuiTeditorTopForm, XmNtopAttachment, XmATTACH_NONE, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, 1, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, nPrev50TracesLeftPosition, XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, nPrev50TracesRightPosition, XmNalignment, XmALIGNMENT_CENTER, XmNtraversalOn, False, NULL ); XtAddCallback( widPrevTraces_, XmNactivateCallback, cbShowPrevTraces, this ); soLabel = "next "; soLabel += RWCString( (long) pCP->nShowAllTracesMaxNumberOfTracesToShowAtOnce_ ); soLabel += " traces"; widNextTraces_ = XtVaCreateManagedWidget( soLabel.data(), xmPushButtonWidgetClass, widGuiTeditorTopForm, XmNtopAttachment, XmATTACH_NONE, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, 1, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, nNext50TracesLeftPosition, XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, nNext50TracesRightPosition, XmNalignment, XmALIGNMENT_CENTER, XmNtraversalOn, False, NULL ); XtAddCallback( widNextTraces_, XmNactivateCallback, cbShowNextTraces, this ); widShowAllSomeTracesButton_ = XtVaCreateManagedWidget( "????", // depends on .consedrc xmPushButtonWidgetClass, widGuiTeditorTopForm, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 5, XmNtraversalOn, False, NULL ); setShowAllTracesJustShowGoodTracesButton(); XtAddCallback( widShowAllSomeTracesButton_, XmNactivateCallback, cbUserPushedShowAllSomeTracesButton, this ); widStatusText_ = XtVaCreateManagedWidget( "status", xmTextFieldWidgetClass, widGuiTeditorTopForm, XmNtopAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, widDismissTop_, XmNtraversalOn, False, XmNeditable, False, XmNcursorPositionVisible, False, NULL ); } Widget widAboveTraces; Widget widBelowTraces; if ( bShowTracesInScrollingWindow_ ) { // first put on a frame so that the scale and consensus line up // with the bases in the trace windows Widget widFrame = XtVaCreateManagedWidget( "frameForConsensusScaleAndBases", xmFrameWidgetClass, widGuiTeditorTopForm, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, widStatusText_, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNtopOffset, 0, XmNbottomOffset, 0, XmNleftOffset, 0, XmNrightOffset, 0, XmNshadowType, XmSHADOW_IN, NULL ); Widget widForm = XtVaCreateManagedWidget( "formInFrame", xmFormWidgetClass, widFrame, XmNancestorSensitive, True, XmNshadowThickness, 0, XmNborderWidth, 0, NULL ); ////////////////////////////////////////////////////////////////////// // // create the scale drawing area widget // ////////////////////////////////////////////////////////////////////// widConsensusScale_ = XtVaCreateManagedWidget( "scaleDrawingArea", xmDrawingAreaWidgetClass, widForm, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNtopOffset, 0, XmNbottomOffset, 0, XmNleftOffset, 0, XmNrightOffset, 0, XmNshadowThickness, 0, XmNborderWidth, 0, XtNheight, (Dimension) GuiTedWin::nGetShowAllTracesConsensusScaleHeight(), NULL ); XtAddCallback( widConsensusScale_, XmNexposeCallback, (XtCallbackProc ) cbGuiTeditorConsensusScaleExposure, this ); widConsensus_ = XtVaCreateManagedWidget( "consensusDrawingArea", xmDrawingAreaWidgetClass, widForm, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, widConsensusScale_, XmNbottomAttachment, XmATTACH_FORM, XmNtopOffset, 0, XmNbottomOffset, 0, XmNleftOffset, 0, XmNrightOffset, 0, XmNshadowThickness, 0, XmNborderWidth, 0, XtNheight, GuiTedWin::nGetShowAllTracesConsensusWindowHeight(), NULL ); XtAddCallback( widConsensus_, XmNexposeCallback, (XtCallbackProc ) cbGuiTeditorConsensusExposure, this ); widAboveTraces = widFrame; // const int nAmountToScrollWhenArrowIsPushed = 10; // widHorizontalScrollBar_ = XtVaCreateManagedWidget( // "scrollbar", // xmScrollBarWidgetClass, // widGuiTeditorTopForm, // XmNorientation, XmHORIZONTAL, // XmNleftAttachment, XmATTACH_FORM, // XmNrightAttachment, XmATTACH_FORM, // XmNbottomAttachment, XmATTACH_WIDGET, // XmNbottomWidget, widDismissBottom_, // XmNincrement, nAmountToScrollWhenArrowIsPushed, // NULL ); // when enable scrollbar, restore this // widBelowTraces = widHorizontalScrollBar_; widBelowTraces = widDismissBottom_; // XtAddCallback( widHorizontalScrollBar_, // XmNvalueChangedCallback, // (XtCallbackProc ) cbGuiTeditorHorizontalScrollBar, // this); // XtAddCallback(widHorizontalScrollBar_, // XmNdragCallback, // (XtCallbackProc ) cbGuiTeditorHorizontalScrollBar, // this); } else { widAboveTraces = widDismissTop_; widBelowTraces = widDismissBottom_; } widForm_= XtVaCreateManagedWidget("form", xmFormWidgetClass, widGuiTeditorTopForm, XmNancestorSensitive,True, // changed from XtNwidth and XtNheight XmNwidth, (Dimension) consedParameters::pGetConsedParameters()->nTracesWindowInitialPixelWidth_, // nDefaultTedWinWidth, XmNheight, nDefaultTedWinHeight * nStartWithThisManyTraces, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, widAboveTraces, XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomWidget, widBelowTraces, // XmNbottomOffset, nMarginBelowGuiTedWins, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNfractionBase, nStartWithThisManyTraces, NULL ); XtManageChild(widForm_); // and there's nothing in the form of GuiTedWins. these // get added by addGuiTedWin(). presumably the first one // gets added by default. XtPopup( widShell_, XtGrabNone ); } // TedWin's are added dynamically, and their ctor tells the // parent GuiTeditor that they exist and causes it to position // the new one on its widForm_ void GuiTeditor::addGuiTedWinToTop(GuiTedWin* pGuiTedWin) { assert (pGuiTedWin); // pTeditor_->deleteTedWinsIfTooMany( 1 ); // how many are there on the GuiTeditor? // (add 1 because we must include the GuiTedWin we are creating) int nGuiTedWins = nNumberOfGuiTedWins() + 1; int nNewHeight = nGuiTedWins * nDefaultTedWinHeight + nMarginAboveGuiTedWins + nMarginBelowGuiTedWins; XtVaSetValues( widShell_, XmNheight, nNewHeight, NULL ); XtVaSetValues( widForm_, XmNfractionBase, nGuiTedWins, NULL ); // divide up the form and squish them all in. // let the user resize if need be // all GuiTedWins, new or old, get re-attached Widget widTopGuiTedWin = pGuiTedWin->widGet(); for (int n = 0; n <= nGuiTedWins - 1; n++) { Widget widGuiTedWin; if ( n == (nGuiTedWins - 1) ) widGuiTedWin = widTopGuiTedWin; else widGuiTedWin = pGetGuiTedWin( n )->widGet(); XtVaSetValues( widGuiTedWin, XmNbottomAttachment, XmATTACH_POSITION, XmNbottomPosition, (nGuiTedWins - n), NULL ); XtVaSetValues( widGuiTedWin, XmNtopAttachment, XmATTACH_POSITION, XmNtopPosition, (nGuiTedWins - n - 1), NULL ); } } void GuiTeditor :: moveDownExistingTraces( const int nAmountToMoveDown ) { int nGuiTedWins = nNumberOfGuiTedWins(); for (int n = 0; n <= nGuiTedWins - 1; n++) { Widget widGuiTedWin = pGetGuiTedWin( n )->widGet(); int nTopPosition; int nBottomPosition; XtVaGetValues( widGuiTedWin, XmNtopPosition, &nTopPosition, XmNbottomPosition, &nBottomPosition, NULL ); XtVaSetValues( widGuiTedWin, XmNbottomAttachment, XmATTACH_POSITION, NULL ); XtVaSetValues( widGuiTedWin, XmNbottomPosition, nBottomPosition + nAmountToMoveDown, NULL ); XtVaSetValues( widGuiTedWin, XmNtopAttachment, XmATTACH_POSITION, XmNtopPosition, nTopPosition + nAmountToMoveDown, NULL ); } } // nPosition runs from 0 to the maximum value - 1 void GuiTeditor::addGuiTedWinToSpecificLocation(GuiTedWin* pGuiTedWin, const int nPosition ) { assert (pGuiTedWin); Widget widGuiTedWin = pGuiTedWin->widGet(); XtVaSetValues( widGuiTedWin, XmNtopAttachment, XmATTACH_POSITION, XmNtopPosition, nPosition, XmNbottomAttachment, XmATTACH_POSITION, XmNbottomPosition, nPosition + 1, NULL ); } void GuiTeditor :: fixArrangementOfGuiTedWins() { int nNewNumberOfGuiTedWins = nNumberOfGuiTedWins(); for (int n = 0; n <= nNewNumberOfGuiTedWins - 1; n++) { Widget widGuiTedWin = pGetGuiTedWin( n )->widGet(); XtVaSetValues( widGuiTedWin, XmNtopAttachment, XmATTACH_POSITION, XmNtopPosition, (nNewNumberOfGuiTedWins - n - 1), NULL ); XtVaSetValues( widGuiTedWin, XmNbottomAttachment, XmATTACH_POSITION, XmNbottomPosition, (nNewNumberOfGuiTedWins - n), NULL ); } XtVaSetValues( widForm_, XmNfractionBase, nNewNumberOfGuiTedWins, NULL ); int nNewHeight = nNewNumberOfGuiTedWins * nDefaultTedWinHeight + nMarginAboveGuiTedWins + nMarginBelowGuiTedWins; XtVaSetValues( widShell_, XmNheight, nNewHeight, NULL ); } void GuiTeditor :: removeGuiTedWinByUser( GuiTedWin* pGuiTedWin ) { removeGuiTedWin( pGuiTedWin ); if (nNumberOfGuiTedWins() == 0 ) { Teditor* pTeditor = pTeditorGet(); delete pTeditor; // suicide by any other name } else { fixArrangementOfGuiTedWins(); } } void GuiTeditor :: removeGuiTedWin(GuiTedWin* pGuiTedWin) { assert (pGuiTedWin); // if the tedwins are scrolling together, make sure the one // that is being deleted isn't the master if (pTeditor_->bTedWinsScrollTogether() ) { if ( pTeditor_->pGetGuiTedWinScrollMaster() == pGuiTedWin ) { // oh, oh. Everyone else is going to be pointing to this one // so make a different tedwin the master pTeditor_->changeToADifferentScrollMaster(); } } TedWin* pTedWin = pGuiTedWin->pTedWinGet(); pTeditor_->removeTedWinFromTeditorList( pTedWin ); // for some reason, deleting the widget at this point will give lots of // 'bailed out' errors when we change the fractal value. So unmanage // for now, and then delete later. XtUnmanageChild( pGuiTedWin->widGet() ); delete pTedWin; } // not inlined to avoid circular include ContigWin* GuiTeditor::pContigWinGet() { return pTeditor_->pContigWinGet(); } GuiTeditor :: ~GuiTeditor() { // no! no! no! The GuiTedWins are ALREADY destroyed by the // ~Teditor -> ~TedWin -> ~GuiTedWin // We may want, when we stack, to not have ~Teditor -> ~TedWin, but // that is the way it is now. (DG) // delete all GuiTedWins // dapGuiTedWin_.clearAndDestroy(); // for some reason, the shell doesn't seem to really ever be destroyed // (it stays up), so use XtPopdown to get it off the screen // Note: this is EVEN true if you sync, process all events in the // event queue, both before and after the XtDestroyWidget. // Also: if you run it in the debugger, the problem goes away. XtPopdown( widShell_ ); XtDestroyWidget(widShell_); } int GuiTeditor :: nNumberOfGuiTedWins() { return( pTeditor_->nNumberOfTedWins() ); } GuiTedWin* GuiTeditor :: pGetGuiTedWin( const int nTedWinIndex ) { return( pTeditor_->pGetTedWin( nTedWinIndex )->pGetGuiTedWin() ); } // callback for "Dismiss" button destroys self, Teditor object // and motif shell void cbDismissGuiTeditor( Widget wid, XtPointer pClientData, XtPointer pCallData ) { TRY_CATCH_WRAPPER( GuiTeditor* pGuiTeditor = (GuiTeditor* )pClientData; Teditor* pTeditor = pGuiTeditor->pTeditorGet(); delete pTeditor; // suicide by any other name ); } void cbHelpInsert( Widget wid, XtPointer pClientData, XtPointer pCallData ) { TRY_CATCH_WRAPPER( GuiTeditor* pGuiTeditor = (GuiTeditor* )pClientData; popupInfoMessage( pGuiTeditor->widGetGuiTeditorShell(), "To insert a base, put cursor just after where you want to add a base. Push the space bar, which will add a column of pads (*'s). Then overstrike the pad with a base." ); ); } void cbHelpDelete( Widget wid, XtPointer pClientData, XtPointer pCallData ) { TRY_CATCH_WRAPPER( GuiTeditor* pGuiTeditor = (GuiTeditor* )pClientData; popupInfoMessage( pGuiTeditor->widGetGuiTeditorShell(), "To delete a base, put cursor on the base and type \'*\'. This removes the base, but leaves a record of it." ); ); } GuiTedWin* GuiTedWin :: pGetGuiTedWinScrollMaster() { return( pTeditorGet()->pGetGuiTedWinScrollMaster() ); } void GuiTeditor :: enlargeTeditor( const int nHowManyMoreTedWins ) { // how many are there on the GuiTeditor? // (add 1 because we must include the GuiTedWin we are creating) int nGuiTedWins = nNumberOfGuiTedWins() + nHowManyMoreTedWins; int nNewHeight = nGuiTedWins * nDefaultTedWinHeight + nMarginAboveGuiTedWins + nMarginBelowGuiTedWins; XtVaSetValues( widShell_, XmNheight, nNewHeight, NULL ); XtVaSetValues( widForm_, XmNheight, nNewHeight, NULL ); Dimension nRecHeight = 0; XtVaGetValues( widShell_, XmNheight, &nRecHeight, NULL ); XEvent event; XtAppContext cxt = GuiApp::pGetGuiApp()->ctxGetAppContext(); for( int n = 0; (n < 5000 ) && ( nRecHeight != nNewHeight); ++n ) { if( XtAppPending( cxt ) && XtIMXEvent ) { XtAppNextEvent(cxt, &event); XtDispatchEvent(&event); } XtVaGetValues( widShell_, XmNheight, &nRecHeight, NULL ); } } void GuiTeditor :: repartitionTraceWindow( const int nHowManyMoreTraces ) { int nNewNumberOfTraces = nNumberOfGuiTedWins() + nHowManyMoreTraces; XtVaSetValues( widForm_, XmNfractionBase, nNewNumberOfTraces, NULL ); } void GuiTeditor :: raiseTracesWindow() { XtPopup( widShell_, XtGrabNone ); } void GuiTeditor :: createScrollingWindowForTraces() { widScrolledWindow_ = XtVaCreateManagedWidget( "scrolled", xmScrolledWindowWidgetClass, widForm_, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNscrollingPolicy, XmAUTOMATIC, XmNscrollBarDisplayPolicy, XmSTATIC, NULL ); // get rid of the bottom scrollbar--we are going to create our own // which will be application defined Widget widHorizontalScrollBar; XtVaGetValues( widScrolledWindow_, XmNhorizontalScrollBar, &widHorizontalScrollBar, NULL ); // changed March 2003 from XtDestroyWidget which // caused a segmentation fault with Motif 2.1 when the user // tried to scroll down or resize the window XtUnmanageChild( widHorizontalScrollBar ); widRowCol_ = XtVaCreateManagedWidget( "rowcol", xmRowColumnWidgetClass, widScrolledWindow_, XmNorientation, XmVERTICAL, XmNnumColumns, 1, XmNpacking, XmPACK_COLUMN, XmNwidth, (Dimension) consedParameters::pGetConsedParameters()->nTracesWindowInitialPixelWidth_, XmNborderWidth, 0, XmNshadowThickness, 0, XmNmarginWidth, 0, NULL ); XmScrolledWindowSetAreas( widScrolledWindow_, (Widget) NULL, (Widget) NULL, widRowCol_ ); // prepare for resizing the window XtVaGetValues( widScrolledWindow_, XmNclipWindow, &widClipWindow_, NULL ); XtAddCallback(widClipWindow_, XmNresizeCallback, (XtCallbackProc )cbResizeWorkArea, this ); // initial size of traces dimClipWindowWidth_ = (Dimension) consedParameters::pGetConsedParameters()->nTracesWindowInitialPixelWidth_; } void GuiTeditor :: resizeScrollingTraces() { XtVaGetValues( widClipWindow_, XmNwidth, &dimClipWindowWidth_, NULL ); XtVaSetValues( widRowCol_, XmNwidth, dimClipWindowWidth_, NULL ); for (int nTw = 0; nTw < pTeditor_->dapTedWin_.length(); nTw++) { GuiTedWin* pGuiTedWin = pTeditor_->dapTedWin_[nTw]->pGuiTedWin_; XtVaSetValues( pGuiTedWin->widFrame_, XmNwidth, dimClipWindowWidth_, NULL ); } int nNumberOfTraces = nNumberOfGuiTedWins(); setVerticalScrollBarIncrement( nNumberOfTraces ); } void GuiTeditor :: prepareToDie() { // if we don't do this, then when the trace window is dismissed, // there is a segmentation fault. I think this is because the // resize callback is called after the guitedwin's have already // been destroyed. if ( bShowTracesInScrollingWindow_ ) { XtRemoveCallback(widClipWindow_, XmNresizeCallback, cbResizeWorkArea, this ); } } void GuiTeditor :: scrollScrollingWindow( const int nReadIndex, const int nNumberOfReadsDisplayed ) { // there is nothing to scroll if there is no scrolling window if ( !bShowTracesInScrollingWindow_ ) return; Widget widVerticalScrollBar; XtVaGetValues( widScrolledWindow_, XmNverticalScrollBar, &widVerticalScrollBar, NULL ); int nValue; int nSliderSize; int nIncrement; int nPageIncrement; int nMaximum; int nMinimum; XmScrollBarGetValues( widVerticalScrollBar, &nValue, &nSliderSize, &nIncrement, &nPageIncrement ); XtVaGetValues( widVerticalScrollBar, XmNmaximum, &nMaximum, XmNminimum, &nMinimum, XmNvalue, &nValue, NULL ); // let's check if our desired trace is visible int nSizeOfATrace = nMaximum / nNumberOfReadsDisplayed; int nTopOfOurTrace = nReadIndex * nSizeOfATrace; int nBottomOfOurTrace = ( nReadIndex + 1 ) * nSizeOfATrace; int nBottomOfViewPort = nValue + nSliderSize - 1; if ( nValue <= nTopOfOurTrace && nBottomOfOurTrace <= nBottomOfViewPort ) { // the trace is totally visible, so do nothing return; } else if ( nTopOfOurTrace < nValue ) { // at least part of the trace is above the viewport // Scroll up. Make this trace at the bottom. // want nBottomOfViewPort == nBottomOfOurTrace, // so nValue + nSliderSize - 1 == nBottomOfOurTrace, // so nValue == nBottomOfOurTrace - nSliderSize + 1 int nNewValue = nBottomOfOurTrace - nSliderSize + 1; if ( nNewValue < nMinimum ) nNewValue = nMinimum; XmScrollBarSetValues( widVerticalScrollBar, nNewValue, nSliderSize, nIncrement, nPageIncrement, True ); } else if ( nBottomOfOurTrace > nBottomOfViewPort ) { int nNewValue = nTopOfOurTrace; if ( nNewValue > ( nMaximum - nSliderSize ) ) nNewValue = nMaximum - nSliderSize; XmScrollBarSetValues( widVerticalScrollBar, nNewValue, nSliderSize, nIncrement, nPageIncrement, True ); } } void GuiTeditor :: displayStatusMessage( const RWCString& soMessage ) { XmTextFieldSetString( widStatusText_, soMessage.data() ); } void GuiTeditor :: userPushedShowSomeAllTracesButton() { pCP->bShowAllTracesJustShowGoodTraces_ = !pCP->bShowAllTracesJustShowGoodTraces_; setShowAllTracesJustShowGoodTracesButton(); popupInfoMessage( widShell_, "Please dismiss traces and then bring them up again for this feature to take effect" ); } void GuiTeditor :: setShowAllTracesJustShowGoodTracesButton() { RWCString soButtonLabel; if ( pCP->bShowAllTracesJustShowGoodTraces_ ) soButtonLabel = "Show All Traces"; else soButtonLabel = "Show Just Good Traces"; XmString xms = XmStringCreateLocalized( soButtonLabel.data() ); XtVaSetValues( widShowAllSomeTracesButton_, XmNlabelString, xms, NULL ); XmStringFree( xms ); } void GuiTeditor :: setVerticalScrollBarIncrement( const int nNumberOfTraces ) { Widget widVerticalScrollBar; XtVaGetValues( widScrolledWindow_, XmNverticalScrollBar, &widVerticalScrollBar, NULL ); int nScrollBarMaximum; XtVaGetValues( widVerticalScrollBar, XmNmaximum, &nScrollBarMaximum, NULL ); int nSizeOfATrace = 10; if ( nNumberOfTraces > 0 ) nSizeOfATrace = nScrollBarMaximum / nNumberOfTraces; XtVaSetValues( widVerticalScrollBar, XmNincrement, nSizeOfATrace, NULL ); }