/* 現在位置の単語選択 */ bool CViewCommander::Command_SELECTWORD( CLayoutPoint* pptCaretPos ) { CLayoutRange sRange; CLogicInt nIdx; if( m_pCommanderView->GetSelectionInfo().IsTextSelected() ){ /* テキストが選択されているか */ /* 現在の選択範囲を非選択状態に戻す */ m_pCommanderView->GetSelectionInfo().DisableSelectArea( true ); } CLayoutPoint ptCaretPos = (NULL == pptCaretPos ? GetCaret().GetCaretLayoutPos() : *pptCaretPos); const CLayout* pcLayout = GetDocument()->m_cLayoutMgr.SearchLineByLayoutY( ptCaretPos.GetY2() ); if( NULL == pcLayout ){ return false; // 単語選択に失敗 } /* 指定された桁に対応する行のデータ内の位置を調べる */ nIdx = m_pCommanderView->LineColumnToIndex( pcLayout, ptCaretPos.GetX2() ); /* 現在位置の単語の範囲を調べる */ if( GetDocument()->m_cLayoutMgr.WhereCurrentWord( ptCaretPos.GetY2(), nIdx, &sRange, NULL, NULL ) ){ // 指定された行のデータ内の位置に対応する桁の位置を調べる // 2007.10.15 kobake 既にレイアウト単位なので変換は不要 /* pcLayout = GetDocument()->m_cLayoutMgr.SearchLineByLayoutY( sRange.GetFrom().GetY2() ); sRange.SetFromX( m_pCommanderView->LineIndexToColumn( pcLayout, sRange.GetFrom().x ) ); pcLayout = GetDocument()->m_cLayoutMgr.SearchLineByLayoutY( sRange.GetTo().GetY2() ); sRange.SetToX( m_pCommanderView->LineIndexToColumn( pcLayout, sRange.GetTo().x ) ); */ /* 選択範囲の変更 */ // 2005.06.24 Moca m_pCommanderView->GetSelectionInfo().SetSelectArea( sRange ); /* 選択領域描画 */ m_pCommanderView->GetSelectionInfo().DrawSelectArea(); /* 単語の先頭にカーソルを移動 */ GetCaret().MoveCursor( sRange.GetTo(), true ); GetCaret().m_nCaretPosX_Prev = GetCaret().GetCaretLayoutPos().GetX2(); return true; // 単語選択に成功。 } else { return false; // 単語選択に失敗 } }
/*! 対括弧の強調表示 @date 2002/09/18 ai @date 2003/02/18 ai 再描画対応の為大改造 */ void CEditView::DrawBracketPair( bool bDraw ) { // 03/03/06 ai すべて置換、すべて置換後のUndo&Redoがかなり遅い問題に対応 if( m_bDoing_UndoRedo || !GetDrawSwitch() ){ return; } if( !m_pTypeData->m_ColorInfoArr[COLORIDX_BRACKET_PAIR].m_bDisp ){ return; } // 括弧の強調表示位置が未登録の場合は終了 if( m_ptBracketPairPos_PHY.HasNegative() || m_ptBracketCaretPos_PHY.HasNegative() ){ return; } // 描画指定(bDraw=true) かつ // ( テキストが選択されている 又は // 選択範囲を描画している 又は // フォーカスを持っていない 又は // アクティブなペインではない ) 場合は終了 if( bDraw &&( GetSelectionInfo().IsTextSelected() || GetSelectionInfo().m_bDrawSelectArea || !m_bDrawBracketPairFlag || ( m_pcEditWnd->GetActivePane() != m_nMyIndex ) ) ){ return; } CGraphics gr; gr.Init(::GetDC(GetHwnd())); bool bCaretChange = false; gr.SetTextBackTransparent(true); for( int i = 0; i < 2; i++ ) { // i=0:対括弧,i=1:カーソル位置の括弧 // 2011.11.23 ryoji 対括弧 -> カーソル位置の括弧 の順に処理順序を変更 // # { と } が異なる行にある場合に { を BS で消すと } の強調表示が解除されない問題(Wiki BugReport/89)の対策 // # この順序変更によりカーソル位置が括弧でなくなっていても対括弧があれば対括弧側の強調表示は解除される CLayoutPoint ptColLine; if( i == 0 ){ m_pcEditDoc->m_cLayoutMgr.LogicToLayout( m_ptBracketPairPos_PHY, &ptColLine ); }else{ m_pcEditDoc->m_cLayoutMgr.LogicToLayout( m_ptBracketCaretPos_PHY, &ptColLine ); } if ( ( ptColLine.x >= GetTextArea().GetViewLeftCol() ) && ( ptColLine.x <= GetTextArea().GetRightCol() ) && ( ptColLine.y >= GetTextArea().GetViewTopLine() ) && ( ptColLine.y <= GetTextArea().GetBottomLine() ) ) { // 表示領域内の場合 if( !bDraw && GetSelectionInfo().m_bDrawSelectArea && ( 0 == IsCurrentPositionSelected( ptColLine ) ) ) { // 選択範囲描画済みで消去対象の括弧が選択範囲内の場合 continue; } const CLayout* pcLayout; CLogicInt nLineLen; const wchar_t* pLine = m_pcEditDoc->m_cLayoutMgr.GetLineStr( ptColLine.GetY2(), &nLineLen, &pcLayout ); if( pLine ) { EColorIndexType nColorIndex; CLogicInt OutputX = LineColumnToIndex( pcLayout, ptColLine.GetX2() ); if( bDraw ) { nColorIndex = COLORIDX_BRACKET_PAIR; } else{ if( IsBracket( pLine, OutputX, CLogicInt(1) ) ){ DispPos _sPos(0,0); // 注意:この値はダミー。CheckChangeColorでの参照位置は不正確 SColorStrategyInfo _sInfo; SColorStrategyInfo* pInfo = &_sInfo; pInfo->m_pDispPos = &_sPos; pInfo->m_pcView = this; // 03/10/24 ai 折り返し行のColorIndexが正しく取得できない問題に対応 // 2009.02.07 ryoji GetColorIndex に渡すインデックスの仕様変更(元はこっちの仕様だった模様) CColor3Setting cColor = GetColorIndex( pcLayout, ptColLine.GetY2(), OutputX, pInfo ); nColorIndex = cColor.eColorIndex2; } else{ SetBracketPairPos( false ); break; } } CTypeSupport cCuretLineBg(this,COLORIDX_CARETLINEBG); EColorIndexType nColorIndexBg = (cCuretLineBg.IsDisp() && ptColLine.GetY2() == GetCaret().GetCaretLayoutPos().GetY2() ? COLORIDX_CARETLINEBG : CTypeSupport(this,COLORIDX_EVENLINEBG).IsDisp() && ptColLine.GetY2() % 2 == 1 ? COLORIDX_EVENLINEBG : COLORIDX_TEXT); // 03/03/03 ai カーソルの左に括弧があり括弧が強調表示されている状態でShift+←で選択開始すると // 選択範囲内に反転表示されない部分がある問題の修正 CLayoutInt caretX = GetCaret().GetCaretLayoutPos().GetX2(); bool bCaretHide = (!bCaretChange && (ptColLine.x == caretX || ptColLine.x + 1 == caretX) && GetCaret().GetCaretShowFlag()); if( bCaretHide ){ bCaretChange = true; GetCaret().HideCaret_( GetHwnd() ); // キャレットが一瞬消えるのを防止 } { int nWidth = GetTextMetrics().GetHankakuDx(); int nHeight = GetTextMetrics().GetHankakuDy(); int nLeft = (GetTextArea().GetDocumentLeftClientPointX()) + GetTextMetrics().GetCharPxWidth(ptColLine.x); int nTop = (Int)( ptColLine.GetY2() - GetTextArea().GetViewTopLine() ) * nHeight + GetTextArea().GetAreaTop(); CLayoutXInt charsWidth = m_pcEditDoc->m_cLayoutMgr.GetLayoutXOfChar(pLine, nLineLen, OutputX); //色設定 CTypeSupport cTextType(this,COLORIDX_TEXT); cTextType.SetGraphicsState_WhileThisObj(gr); // 2013.05.24 背景色がテキストの背景色と同じならカーソル行の背景色を適用 CTypeSupport cColorIndexType(this,nColorIndex); CTypeSupport cColorIndexBgType(this,nColorIndexBg); CTypeSupport* pcColorBack = &cColorIndexType; if( cColorIndexType.GetBackColor() == cTextType.GetBackColor() && nColorIndexBg != COLORIDX_TEXT ){ pcColorBack = &cColorIndexBgType; } SetCurrentColor( gr, nColorIndex, nColorIndex, nColorIndexBg ); bool bTrans = false; // DEBUG_TRACE( _T("DrawBracket %d %d ") , ptColLine.y, ptColLine.x ); if( IsBkBitmap() && cTextType.GetBackColor() == pcColorBack->GetBackColor() ){ bTrans = true; RECT rcChar; rcChar.left = nLeft; rcChar.top = nTop; rcChar.right = nLeft + GetTextMetrics().GetCharPxWidth(charsWidth); rcChar.bottom = nTop + nHeight; HDC hdcBgImg = ::CreateCompatibleDC(gr); HBITMAP hBmpOld = (HBITMAP)::SelectObject(hdcBgImg, m_pcEditDoc->m_hBackImg); DrawBackImage(gr, rcChar, hdcBgImg); ::SelectObject(hdcBgImg, hBmpOld); ::DeleteDC(hdcBgImg); } DispPos sPos(nWidth, nHeight); sPos.InitDrawPos(CMyPoint(nLeft, nTop)); GetTextDrawer().DispText(gr, &sPos, 0, &pLine[OutputX], 1, bTrans); GetTextDrawer().DispNoteLine(gr, nTop, nTop + nHeight, nLeft, nLeft + (Int)charsWidth * nWidth); // 2006.04.30 Moca 対括弧の縦線対応 GetTextDrawer().DispVerticalLines(gr, nTop, nTop + nHeight, ptColLine.x, ptColLine.x + charsWidth); //※括弧が全角幅である場合を考慮 cTextType.RewindGraphicsState(gr); } if( ( m_pcEditWnd->GetActivePane() == m_nMyIndex ) && ( ( ptColLine.y == GetCaret().GetCaretLayoutPos().GetY() ) || ( ptColLine.y - 1 == GetCaret().GetCaretLayoutPos().GetY() ) ) ){ // 03/02/27 ai 行の間隔が"0"の時にアンダーラインが欠ける事がある為修正 GetCaret().m_cUnderLine.CaretUnderLineON( true, false ); } } } } if( bCaretChange ){ GetCaret().ShowCaret_( GetHwnd() ); // キャレットが一瞬消えるのを防止 } ::ReleaseDC( GetHwnd(), gr ); }
// トグル用のフラグに変更 20060201 aroka BOOL CViewCommander::Command_FUNCLIST( int nAction, int _nOutlineType = OUTLINE_DEFAULT ) { static bool bIsProcessing = false; //アウトライン解析処理中フラグ //アウトラインプラグイン内でのEditor.Outline呼び出しによる再入を禁止する if( bIsProcessing )return FALSE; bIsProcessing = true; // 自プロセスが前面にいるかどうか調べる DWORD dwPid1, dwPid2; dwPid1 = ::GetCurrentProcessId(); ::GetWindowThreadProcessId( ::GetForegroundWindow(), &dwPid2 ); bool bForeground = (dwPid1 == dwPid2); EOutlineType nOutlineType = (EOutlineType)_nOutlineType; //2007.11.29 kobake // if( bCheckOnly ){ // return TRUE; // } static CFuncInfoArr cFuncInfoArr; // int nLine; // int nListType; std::tstring sTitleOverride; //プラグインによるダイアログタイトル上書き // 2001.12.03 hor & 2002.3.13 YAZAKI if( nOutlineType == OUTLINE_DEFAULT ){ /* タイプ別に設定されたアウトライン解析方法 */ nOutlineType = m_pCommanderView->m_pTypeData->m_eDefaultOutline; if( nOutlineType == OUTLINE_CPP ){ if( CheckEXT( GetDocument()->m_cDocFile.GetFilePath(), _T("c") ) ){ nOutlineType = OUTLINE_C; /* これでC関数一覧リストビューになる */ } } } if( NULL != GetEditWindow()->m_cDlgFuncList.GetHwnd() && nAction != SHOW_RELOAD ){ switch(nAction ){ case SHOW_NORMAL: // アクティブにする // 開いているものと種別が同じならActiveにするだけ.異なれば再解析 GetEditWindow()->m_cDlgFuncList.SyncColor(); if( GetEditWindow()->m_cDlgFuncList.CheckListType( nOutlineType )){ if( bForeground ){ ::SetFocus( GetEditWindow()->m_cDlgFuncList.GetHwnd() ); } bIsProcessing = false; return TRUE; } break; case SHOW_TOGGLE: // 閉じる // 開いているものと種別が同じなら閉じる.異なれば再解析 if( GetEditWindow()->m_cDlgFuncList.CheckListType( nOutlineType )){ if( GetEditWindow()->m_cDlgFuncList.IsDocking() ) ::DestroyWindow( GetEditWindow()->m_cDlgFuncList.GetHwnd() ); else ::SendMessageAny( GetEditWindow()->m_cDlgFuncList.GetHwnd(), WM_CLOSE, 0, 0 ); bIsProcessing = false; return TRUE; } break; default: break; } } /* 解析結果データを空にする */ cFuncInfoArr.Empty(); int nListType = nOutlineType; //2011.06.25 syat switch( nOutlineType ){ case OUTLINE_C: // C/C++ は MakeFuncList_C case OUTLINE_CPP: GetDocument()->m_cDocOutline.MakeFuncList_C( &cFuncInfoArr );break; case OUTLINE_PLSQL: GetDocument()->m_cDocOutline.MakeFuncList_PLSQL( &cFuncInfoArr );break; case OUTLINE_JAVA: GetDocument()->m_cDocOutline.MakeFuncList_Java( &cFuncInfoArr );break; case OUTLINE_COBOL: GetDocument()->m_cDocOutline.MakeTopicList_cobol( &cFuncInfoArr );break; case OUTLINE_ASM: GetDocument()->m_cDocOutline.MakeTopicList_asm( &cFuncInfoArr );break; case OUTLINE_PERL: GetDocument()->m_cDocOutline.MakeFuncList_Perl( &cFuncInfoArr );break; // Sep. 8, 2000 genta case OUTLINE_VB: GetDocument()->m_cDocOutline.MakeFuncList_VisualBasic( &cFuncInfoArr );break; // June 23, 2001 N.Nakatani case OUTLINE_WZTXT: GetDocument()->m_cDocOutline.MakeTopicList_wztxt(&cFuncInfoArr);break; // 2003.05.20 zenryaku 階層付テキスト アウトライン解析 case OUTLINE_HTML: GetDocument()->m_cDocOutline.MakeTopicList_html(&cFuncInfoArr, false);break; // 2003.05.20 zenryaku HTML アウトライン解析 case OUTLINE_TEX: GetDocument()->m_cDocOutline.MakeTopicList_tex(&cFuncInfoArr);break; // 2003.07.20 naoh TeX アウトライン解析 case OUTLINE_BOOKMARK: GetDocument()->m_cDocOutline.MakeFuncList_BookMark( &cFuncInfoArr );break; // 2001.12.03 hor case OUTLINE_FILE: GetDocument()->m_cDocOutline.MakeFuncList_RuleFile( &cFuncInfoArr, sTitleOverride );break; // 2002.04.01 YAZAKI アウトライン解析にルールファイルを導入 // case OUTLINE_UNKNOWN: //Jul. 08, 2001 JEPRO 使わないように変更 case OUTLINE_PYTHON: GetDocument()->m_cDocOutline.MakeFuncList_python(&cFuncInfoArr);break; // 2007.02.08 genta case OUTLINE_ERLANG: GetDocument()->m_cDocOutline.MakeFuncList_Erlang(&cFuncInfoArr);break; // 2009.08.10 genta case OUTLINE_XML: GetDocument()->m_cDocOutline.MakeTopicList_html(&cFuncInfoArr, true);break; // 2014.12.25 Moca case OUTLINE_FILETREE: /* 特に何もしない*/ ;break; // 2013.12.08 Moca case OUTLINE_TEXT: // fall though // ここには何も入れてはいけない 2007.02.28 genta 注意書き default: //プラグインから検索する { CPlug::Array plugs; CJackManager::getInstance()->GetUsablePlug( PP_OUTLINE, nOutlineType, &plugs ); if( plugs.size() > 0 ){ assert_warning( 1 == plugs.size() ); //インタフェースオブジェクト準備 CWSHIfObj::List params; COutlineIfObj* objOutline = new COutlineIfObj( cFuncInfoArr ); objOutline->AddRef(); params.push_back( objOutline ); //プラグイン呼び出し ( *plugs.begin() )->Invoke( m_pCommanderView, params ); nListType = objOutline->m_nListType; //ダイアログの表示方法をを上書き sTitleOverride = objOutline->m_sOutlineTitle; //ダイアログタイトルを上書き objOutline->Release(); break; } } //それ以外 GetDocument()->m_cDocOutline.MakeTopicList_txt( &cFuncInfoArr ); break; } /* 解析対象ファイル名 */ _tcscpy( cFuncInfoArr.m_szFilePath, GetDocument()->m_cDocFile.GetFilePath() ); /* アウトライン ダイアログの表示 */ CLayoutPoint poCaret = GetCaret().GetCaretLayoutPos(); if( NULL == GetEditWindow()->m_cDlgFuncList.GetHwnd() ){ GetEditWindow()->m_cDlgFuncList.DoModeless( G_AppInstance(), m_pCommanderView->GetHwnd(), (LPARAM)m_pCommanderView, &cFuncInfoArr, poCaret.GetY2() + CLayoutInt(1), poCaret.GetX2() + CLayoutInt(1), nOutlineType, nListType, m_pCommanderView->m_pTypeData->m_bLineNumIsCRLF /* 行番号の表示 false=折り返し単位/true=改行単位 */ ); }else{ /* アクティブにする */ GetEditWindow()->m_cDlgFuncList.Redraw( nOutlineType, nListType, &cFuncInfoArr, poCaret.GetY2() + 1, poCaret.GetX2() + 1 ); if( bForeground ){ ::SetFocus( GetEditWindow()->m_cDlgFuncList.GetHwnd() ); } } // ダイアログタイトルを上書き if( ! sTitleOverride.empty() ){ GetEditWindow()->m_cDlgFuncList.SetWindowText( sTitleOverride.c_str() ); } // 解析結果を折りたたみに反映する if (m_pCommanderView->m_pTypeData->m_ColorInfoArr[COLORIDX_FOLDING].m_bDisp && nOutlineType != OUTLINE_BOOKMARK && nOutlineType != OUTLINE_FILETREE) { CDocFoldMgr::getInstance()->RefreshFromOutline(&cFuncInfoArr, m_pCommanderView->GetDocument()->m_cDocLineMgr); if (m_pCommanderView->m_pTypeData->m_ColorInfoArr[COLORIDX_FOLDING].m_bDisp) { m_pCommanderView->m_pcEditDoc->OnChangeSetting(); } } bIsProcessing = false; return TRUE; }
/*! @brief 行桁指定によるカーソル移動 必要に応じて縦/横スクロールもする. 垂直スクロールをした場合はその行数を返す(正/負). @return 縦スクロール行数(負:上スクロール/正:下スクロール) @note 不正な位置が指定された場合には適切な座標値に 移動するため,引数で与えた座標と移動後の座標は 必ずしも一致しない. @note bScrollがfalseの場合にはカーソル位置のみ移動する. trueの場合にはスクロール位置があわせて変更される @note 同じ行の左右移動はアンダーラインを一度消す必要が無いので bUnderlineDoNotOFFを指定すると高速化できる. 同様に同じ桁の上下移動はbVertLineDoNotOFFを指定すると カーソル位置縦線の消去を省いて高速化できる. @date 2001.10.20 deleted by novice AdjustScrollBar()を呼ぶ位置を変更 @date 2004.04.02 Moca 行だけ有効な座標に修正するのを厳密に処理する @date 2004.09.11 genta bDrawスイッチは動作と名称が一致していないので 再描画スイッチ→画面位置調整スイッチと名称変更 @date 2009.08.28 nasukoji テキスト折り返しの「折り返さない」対応 @date 2010.11.27 syat アンダーライン、縦線を消去しないフラグを追加 */ CLayoutInt CCaret::MoveCursor( CLayoutPoint ptWk_CaretPos, //!< [in] 移動先レイアウト位置 bool bScroll, //!< [in] true: 画面位置調整有り false: 画面位置調整無し int nCaretMarginRate, //!< [in] 縦スクロール開始位置を決める値 bool bUnderLineDoNotOFF, //!< [in] アンダーラインを消去しない bool bVertLineDoNotOFF //!< [in] カーソル位置縦線を消去しない ) { CTextArea& area = m_pEditView->GetTextArea(); // スクロール処理 CLayoutInt nScrollRowNum = CLayoutInt(0); CLayoutInt nScrollColNum = CLayoutInt(0); int nCaretMarginY; CLayoutInt nScrollMarginRight; CLayoutInt nScrollMarginLeft; if( 0 >= m_pEditView->GetTextArea().m_nViewColNum ){ return CLayoutInt(0); } if( m_pEditView->GetSelectionInfo().IsMouseSelecting() ){ // 範囲選択中 nCaretMarginY = 0; } else{ // 2001/10/20 novice nCaretMarginY = (Int)m_pEditView->GetTextArea().m_nViewRowNum / nCaretMarginRate; if( 1 > nCaretMarginY ){ nCaretMarginY = 1; } } // 2004.04.02 Moca 行だけ有効な座標に修正するのを厳密に処理する GetAdjustCursorPos( &ptWk_CaretPos ); m_pEditDoc->m_cLayoutMgr.LayoutToLogic( ptWk_CaretPos, &m_ptCaretPos_Logic //カーソル位置。ロジック単位。 ); /* キャレット移動 */ SetCaretLayoutPos(ptWk_CaretPos); // カーソル行アンダーラインのOFF bool bDrawPaint = ptWk_CaretPos.GetY2() != m_pEditView->m_nOldUnderLineYBg; m_cUnderLine.SetUnderLineDoNotOFF( bUnderLineDoNotOFF ); m_cUnderLine.SetVertLineDoNotOFF( bVertLineDoNotOFF ); m_cUnderLine.CaretUnderLineOFF( bScroll, bDrawPaint ); // YAZAKI m_cUnderLine.SetUnderLineDoNotOFF( false ); m_cUnderLine.SetVertLineDoNotOFF( false ); // 水平スクロール量(文字数)の算出 nScrollColNum = CLayoutInt(0); nScrollMarginRight = m_pEditView->GetTextMetrics().GetLayoutXDefault(CKetaXInt(SCROLLMARGIN_RIGHT)); nScrollMarginLeft = m_pEditView->GetTextMetrics().GetLayoutXDefault(CKetaXInt(SCROLLMARGIN_LEFT)); // 2010.08.24 Moca 幅が狭い場合のマージンの調整 { // カーソルが真ん中にあるときに左右にぶれないように CLayoutInt nNoMove = m_pEditView->GetTextMetrics().GetLayoutXDefault(CKetaXInt(SCROLLMARGIN_NOMOVE)); CLayoutInt Keta2Width = m_pEditView->GetTextMetrics().GetLayoutXDefault(CKetaXInt(2)); CLayoutInt a = ((m_pEditView->GetTextArea().m_nViewColNum) - nNoMove) / 2; CLayoutInt nMin = (Keta2Width <= a ? a : CLayoutInt(0)); // 1だと全角移動に支障があるので2以上 nScrollMarginRight = t_min(nScrollMarginRight, nMin); nScrollMarginLeft = t_min(nScrollMarginLeft, nMin); } // Aug. 14, 2005 genta 折り返し幅をLayoutMgrから取得するように if( m_pEditDoc->m_cLayoutMgr.GetMaxLineLayout() > area.m_nViewColNum && ptWk_CaretPos.GetX() >area.GetViewLeftCol() + area.m_nViewColNum - nScrollMarginRight ){ nScrollColNum = ( area.GetViewLeftCol() + area.m_nViewColNum - nScrollMarginRight ) - ptWk_CaretPos.GetX2(); } else if( 0 < area.GetViewLeftCol() && ptWk_CaretPos.GetX() < area.GetViewLeftCol() + nScrollMarginLeft ){ nScrollColNum = area.GetViewLeftCol() + nScrollMarginLeft - ptWk_CaretPos.GetX2(); if( 0 > area.GetViewLeftCol() - nScrollColNum ){ nScrollColNum = area.GetViewLeftCol(); } } // 2013.12.30 bScrollがOFFのときは横スクロールしない if( bScroll ){ m_pEditView->GetTextArea().SetViewLeftCol(m_pEditView->GetTextArea().GetViewLeftCol() - nScrollColNum); }else{ nScrollColNum = 0; } // From Here 2007.07.28 じゅうじ : 表示行数が3行以下の場合の動作改善 /* 垂直スクロール量(行数)の算出 */ // 画面が3行以下 if( m_pEditView->GetTextArea().m_nViewRowNum <= 3 ){ // 移動先は、画面のスクロールラインより上か?(up キー) if( ptWk_CaretPos.y - m_pEditView->GetTextArea().GetViewTopLine() < nCaretMarginY ){ if( ptWk_CaretPos.y < nCaretMarginY ){ //1行目に移動 nScrollRowNum = m_pEditView->GetTextArea().GetViewTopLine(); } else if( m_pEditView->GetTextArea().m_nViewRowNum <= 1 ){ // 画面が1行 nScrollRowNum = m_pEditView->GetTextArea().GetViewTopLine() - ptWk_CaretPos.y; } #if !(0) // COMMENTにすると、上下の空きを死守しない為、縦移動はgoodだが、横移動の場合上下にぶれる else if( m_pEditView->GetTextArea().m_nViewRowNum <= 2 ){ // 画面が2行 nScrollRowNum = m_pEditView->GetTextArea().GetViewTopLine() - ptWk_CaretPos.y; } #endif else { // 画面が3行 nScrollRowNum = m_pEditView->GetTextArea().GetViewTopLine() - ptWk_CaretPos.y + 1; } }else // 移動先は、画面の最大行数-2より下か?(down キー) if( ptWk_CaretPos.y - m_pEditView->GetTextArea().GetViewTopLine() >= (m_pEditView->GetTextArea().m_nViewRowNum - nCaretMarginY - 2) ){ CLayoutInt ii = m_pEditDoc->m_cLayoutMgr.GetLineCount(); if( ii - ptWk_CaretPos.y < nCaretMarginY + 1 && ii - m_pEditView->GetTextArea().GetViewTopLine() < m_pEditView->GetTextArea().m_nViewRowNum ) { } else if( m_pEditView->GetTextArea().m_nViewRowNum <= 2 ){ // 画面が2行、1行 nScrollRowNum = m_pEditView->GetTextArea().GetViewTopLine() - ptWk_CaretPos.y; }else{ // 画面が3行 nScrollRowNum = m_pEditView->GetTextArea().GetViewTopLine() - ptWk_CaretPos.y + 1; } } } // 移動先は、画面のスクロールラインより上か?(up キー) else if( ptWk_CaretPos.y - m_pEditView->GetTextArea().GetViewTopLine() < nCaretMarginY ){ if( ptWk_CaretPos.y < nCaretMarginY ){ //1行目に移動 nScrollRowNum = m_pEditView->GetTextArea().GetViewTopLine(); }else{ nScrollRowNum = -(ptWk_CaretPos.y - m_pEditView->GetTextArea().GetViewTopLine()) + nCaretMarginY; } } // 移動先は、画面の最大行数-2より下か?(down キー) else if( ptWk_CaretPos.y - m_pEditView->GetTextArea().GetViewTopLine() >= m_pEditView->GetTextArea().m_nViewRowNum - nCaretMarginY - 2 ){ CLayoutInt ii = m_pEditDoc->m_cLayoutMgr.GetLineCount(); if( ii - ptWk_CaretPos.y < nCaretMarginY + 1 && ii - m_pEditView->GetTextArea().GetViewTopLine() < m_pEditView->GetTextArea().m_nViewRowNum ) { } else{ nScrollRowNum = -(ptWk_CaretPos.y - m_pEditView->GetTextArea().GetViewTopLine()) + (m_pEditView->GetTextArea().m_nViewRowNum - nCaretMarginY - 2); } } // To Here 2007.07.28 じゅうじ if( bScroll ){ /* スクロール */ if( t_abs( nScrollColNum ) >= m_pEditView->GetTextArea().m_nViewColNum || t_abs( nScrollRowNum ) >= m_pEditView->GetTextArea().m_nViewRowNum ){ m_pEditView->GetTextArea().OffsetViewTopLine(-nScrollRowNum); if( m_pEditView->GetDrawSwitch() ){ m_pEditView->InvalidateRect( NULL ); if( m_pEditView->m_pcEditWnd->GetMiniMap().GetHwnd() ){ m_pEditView->MiniMapRedraw(true); } } } else if( nScrollRowNum != 0 || nScrollColNum != 0 ){ RECT rcClip; RECT rcClip2; RECT rcScroll; m_pEditView->GetTextArea().GenerateTextAreaRect(&rcScroll); if( nScrollRowNum > 0 ){ rcScroll.bottom = m_pEditView->GetTextArea().GetAreaBottom() - (Int)nScrollRowNum * m_pEditView->GetTextMetrics().GetHankakuDy(); m_pEditView->GetTextArea().OffsetViewTopLine(-nScrollRowNum); m_pEditView->GetTextArea().GenerateTopRect(&rcClip,nScrollRowNum); } else if( nScrollRowNum < 0 ){ rcScroll.top = m_pEditView->GetTextArea().GetAreaTop() - (Int)nScrollRowNum * m_pEditView->GetTextMetrics().GetHankakuDy(); m_pEditView->GetTextArea().OffsetViewTopLine(-nScrollRowNum); m_pEditView->GetTextArea().GenerateBottomRect(&rcClip,-nScrollRowNum); } int nScrollColPx = m_pEditView->GetTextMetrics().GetCharPxWidth(nScrollColNum); if( nScrollColNum > 0 ){ rcScroll.left = m_pEditView->GetTextArea().GetAreaLeft(); rcScroll.right = m_pEditView->GetTextArea().GetAreaRight() - nScrollColPx; m_pEditView->GetTextArea().GenerateLeftRect(&rcClip2, nScrollColNum); } else if( nScrollColNum < 0 ){ rcScroll.left = m_pEditView->GetTextArea().GetAreaLeft() - nScrollColPx; m_pEditView->GetTextArea().GenerateRightRect(&rcClip2, -nScrollColNum); } if( m_pEditView->GetDrawSwitch() ){ m_pEditView->ScrollDraw(nScrollRowNum, nScrollColNum, rcScroll, rcClip, rcClip2); if( m_pEditView->m_pcEditWnd->GetMiniMap().GetHwnd() ){ m_pEditView->MiniMapRedraw(false); } } } /* スクロールバーの状態を更新する */ m_pEditView->AdjustScrollBars(); // 2001/10/20 novice } // 横スクロールが発生したら、ルーラー全体を再描画 2002.02.25 Add By KK if (nScrollColNum != 0 ){ //次回DispRuler呼び出し時に再描画。(bDraw=falseのケースを考慮した。) m_pEditView->GetRuler().SetRedrawFlag(); } /* カーソル行アンダーラインのON */ //CaretUnderLineON( bDraw ); //2002.02.27 Del By KK アンダーラインのちらつきを低減 if( bScroll ){ /* キャレットの表示・更新 */ ShowEditCaret(); /* ルーラの再描画 */ HDC hdc = m_pEditView->GetDC(); m_pEditView->GetRuler().DispRuler( hdc ); m_pEditView->ReleaseDC( hdc ); /* アンダーラインの再描画 */ m_cUnderLine.CaretUnderLineON(true, bDrawPaint); /* キャレットの行桁位置を表示する */ ShowCaretPosInfo(); // Sep. 11, 2004 genta 同期スクロールの関数化 // bScroll == FALSEの時にはスクロールしないので,実行しない m_pEditView->SyncScrollV( -nScrollRowNum ); // 方向が逆なので符号反転が必要 m_pEditView->SyncScrollH( -nScrollColNum ); // 方向が逆なので符号反転が必要 } // 02/09/18 対括弧の強調表示 ai Start 03/02/18 ai mod S m_pEditView->DrawBracketPair( false ); m_pEditView->SetBracketPairPos( true ); m_pEditView->DrawBracketPair( true ); // 02/09/18 対括弧の強調表示 ai End 03/02/18 ai mod E return nScrollRowNum; }
/*! 行桁指定によるカーソル移動(座標調整付き) @return 縦スクロール行数(負:上スクロール/正:下スクロール) @note マウス等による移動で不適切な位置に行かないよう座標調整してカーソル移動する @date 2007.08.23 ryoji 関数化(MoveCursorToPoint()から処理を抜き出し) @date 2007.09.26 ryoji 半角文字でも中央で左右にカーソルを振り分ける @date 2007.10.23 kobake 引数説明の誤りを修正 ([in,out]→[in]) @date 2009.02.17 ryoji レイアウト行末以後のカラム位置指定なら末尾文字の前ではなく末尾文字の後に移動する */ CLayoutInt CCaret::MoveCursorProperly( CLayoutPoint ptNewXY, //!< [in] カーソルのレイアウト座標X bool bScroll, //!< [in] true: 画面位置調整有り/ false: 画面位置調整有り無し bool test, //!< [in] true: カーソル移動はしない CLayoutPoint* ptNewXYNew, //!< [out] 新しいレイアウト座標 int nCaretMarginRate, //!< [in] 縦スクロール開始位置を決める値 int dx //!< [in] ptNewXY.xとマウスカーソル位置との誤差(カラム幅未満のドット数) ) { CLogicInt nLineLen; const CLayout* pcLayout; if( 0 > ptNewXY.y ){ ptNewXY.y = CLayoutInt(0); } // 2011.12.26 EOF以下の行だった場合で矩形のときは、最終レイアウト行へ移動する if( ptNewXY.y >= m_pEditDoc->m_cLayoutMgr.GetLineCount() && (m_pEditView->GetSelectionInfo().IsMouseSelecting() && m_pEditView->GetSelectionInfo().IsBoxSelecting()) ){ const CLayout* layoutEnd = m_pEditDoc->m_cLayoutMgr.GetBottomLayout(); bool bEofOnly = (layoutEnd && layoutEnd->GetLayoutEol() != EOL_NONE) || NULL == layoutEnd; // 2012.01.09 ぴったり[EOF]位置にある場合は位置を維持(1つ上の行にしない) if( bEofOnly && ptNewXY.y == m_pEditDoc->m_cLayoutMgr.GetLineCount() && ptNewXY.x == 0 ){ }else{ ptNewXY.y = t_max(CLayoutInt(0), m_pEditDoc->m_cLayoutMgr.GetLineCount() - 1); } } /* カーソルがテキスト最下端行にあるか */ if( ptNewXY.y >= m_pEditDoc->m_cLayoutMgr.GetLineCount() ){ // 2004.04.03 Moca EOFより後ろの座標調整は、MoveCursor内でやってもらうので、削除 } /* カーソルがテキスト最上端行にあるか */ else if( ptNewXY.y < 0 ){ ptNewXY.Set(CLayoutInt(0), CLayoutInt(0)); } else{ /* 移動先の行のデータを取得 */ m_pEditDoc->m_cLayoutMgr.GetLineStr( ptNewXY.GetY2(), &nLineLen, &pcLayout ); int nColWidth = m_pEditView->GetTextMetrics().GetCharPxWidth(); CLayoutInt nPosX = CLayoutInt(0); int i = 0; CMemoryIterator it = m_pEditDoc->m_cLayoutMgr.CreateCMemoryIterator(pcLayout); while( !it.end() ){ it.scanNext(); if ( it.getIndex() + it.getIndexDelta() > CLogicInt(pcLayout->GetLengthWithoutEOL()) ){ i = nLineLen; break; } if( it.getColumn() + it.getColumnDelta() > ptNewXY.GetX2() ){ if (ptNewXY.GetX2() >= (pcLayout ? pcLayout->GetIndent() : CLayoutInt(0)) && ((ptNewXY.GetX2() - it.getColumn()) * nColWidth + dx) * 2 >= it.getColumnDelta() * nColWidth){ //if (ptNewXY.GetX2() >= (pcLayout ? pcLayout->GetIndent() : CLayoutInt(0)) && (it.getColumnDelta() > CLayoutInt(1)) && ((it.getColumn() + it.getColumnDelta() - ptNewXY.GetX2()) <= it.getColumnDelta() / 2)){ nPosX += it.getColumnDelta(); } //} i = it.getIndex(); break; } it.addDelta(); } nPosX += it.getColumn(); if ( it.end() ){ i = it.getIndex(); //nPosX -= it.getColumnDelta(); // 2009.02.17 ryoji コメントアウト(末尾文字の後に移動する) } if( i >= nLineLen ){ // 2011.12.26 フリーカーソル/矩形でデータ付きEOFの右側へ移動できるように /* フリーカーソルモードか */ if( GetDllShareData().m_Common.m_sGeneral.m_bIsFreeCursorMode || ( m_pEditView->GetSelectionInfo().IsMouseSelecting() && m_pEditView->GetSelectionInfo().IsBoxSelecting() ) /* マウス範囲選択中 && 矩形範囲選択中 */ || ( m_pEditView->m_bDragMode && m_pEditView->m_bDragBoxData ) /* OLE DropTarget && 矩形データ */ ){ // 折り返し幅とレイアウト行桁数(ぶら下げを含む)のどちらか大きいほうまでカーソル移動可能 // Aug. 14, 2005 genta 折り返し幅をLayoutMgrから取得するように CLayoutInt nMaxX = t_max(nPosX, m_pEditDoc->m_cLayoutMgr.GetMaxLineLayout()); nPosX = ptNewXY.GetX2(); if( nPosX < CLayoutInt(0) ){ nPosX = CLayoutInt(0); } else if( nPosX > nMaxX ){ nPosX = nMaxX; } } } ptNewXY.SetX( nPosX ); } if( ptNewXYNew ){ *ptNewXYNew = ptNewXY; GetAdjustCursorPos( ptNewXYNew ); } if( test ){ return CLayoutInt(0); } return MoveCursor( ptNewXY, bScroll, nCaretMarginRate ); }