/* 指定された桁に対応する行のデータ内の位置を調べる Ver1 @@@ 2002.09.28 YAZAKI CLayoutが必要になりました。 */ CLogicInt CViewCalc::LineColumnToIndex( const CLayout* pcLayout, CLayoutInt nColumn ) const { CLogicInt i2 = CLogicInt(0); CMemoryIterator it = m_pOwner->m_pcEditDoc->m_cLayoutMgr.CreateCMemoryIterator(pcLayout); while( !it.end() ){ it.scanNext(); if ( it.getColumn() + it.getColumnDelta() > nColumn ){ break; } it.addDelta(); } i2 += it.getIndex(); return i2; }
/* || 指定された行のデータ内の位置に対応する桁の位置を調べる || || @@@ 2002.09.28 YAZAKI CLayoutが必要になりました。 */ CLayoutInt CViewCalc::LineIndexToColumn( const CLayout* pcLayout, CLogicInt nIndex ) const { // 以下、iterator版 CLayoutInt nPosX2 = CLayoutInt(0); CMemoryIterator it = m_pOwner->m_pcEditDoc->m_cLayoutMgr.CreateCMemoryIterator(pcLayout); while( !it.end() ){ it.scanNext(); if ( it.getIndex() + it.getIndexDelta() > nIndex ){ break; } it.addDelta(); } nPosX2 += it.getColumn(); return nPosX2; }
/* それ以外の場合はpnLineAllColLenに0をセットする @@@ 2002.09.28 YAZAKI CLayoutが必要になりました。 */ CLogicInt CViewCalc::LineColumnToIndex2( const CLayout* pcLayout, CLayoutInt nColumn, CLayoutInt* pnLineAllColLen ) const { *pnLineAllColLen = CLayoutInt(0); CLogicInt i2 = CLogicInt(0); CLayoutInt nPosX2 = CLayoutInt(0); CMemoryIterator it = m_pOwner->m_pcEditDoc->m_cLayoutMgr.CreateCMemoryIterator(pcLayout); while( !it.end() ){ it.scanNext(); if ( it.getColumn() + it.getColumnDelta() > nColumn ){ break; } it.addDelta(); } i2 += it.getIndex(); if( i2 >= pcLayout->GetLengthWithEOL() ){ nPosX2 += it.getColumn(); *pnLineAllColLen = nPosX2; } return i2; }
/* カーソル上下移動処理 */ CLayoutInt CCaret::Cursor_UPDOWN( CLayoutInt nMoveLines, bool bSelect ) { //必要なインターフェース const CLayoutMgr* const pLayoutMgr = &m_pEditDoc->m_cLayoutMgr; const CommonSetting* const pCommon = &GetDllShareData().m_Common; const CLayoutPoint ptCaret = GetCaretLayoutPos(); bool bVertLineDoNotOFF = true; // カーソル位置縦線を消去しない if( bSelect ){ bVertLineDoNotOFF = false; //選択状態ならカーソル位置縦線消去を行う } // 現在のキャレットY座標 + nMoveLinesが正しいレイアウト行の範囲内に収まるように nMoveLinesを調整する。 if( nMoveLines > 0 ) { // 下移動。 const bool existsEOFOnlyLine = pLayoutMgr->GetBottomLayout() && pLayoutMgr->GetBottomLayout()->GetLayoutEol() != EOL_NONE || pLayoutMgr->GetLineCount() == 0; const CLayoutInt maxLayoutLine = pLayoutMgr->GetLineCount() + (existsEOFOnlyLine ? 1 : 0 ) - 1; // 移動先が EOFのみの行を含めたレイアウト行数未満になるように移動量を規正する。 nMoveLines = t_min( nMoveLines, maxLayoutLine - ptCaret.y ); if( ptCaret.y + nMoveLines == maxLayoutLine && existsEOFOnlyLine // 移動先が EOFのみの行 && m_pEditView->GetSelectionInfo().IsBoxSelecting() && 0 != ptCaret.x // かつ矩形選択中なら、 ) { // EOFのみの行には移動しない。下移動でキャレットの X座標を動かしたくないので。 nMoveLines = t_max( CLayoutInt(0), nMoveLines - 1 ); // うっかり上移動しないように 0以上を守る。 } } else { // 上移動。 // 移動先が 0行目より小さくならないように移動量を規制。 nMoveLines = t_max( nMoveLines, - GetCaretLayoutPos().GetY() ); } if( bSelect && ! m_pEditView->GetSelectionInfo().IsTextSelected() ) { /* 現在のカーソル位置から選択を開始する */ m_pEditView->GetSelectionInfo().BeginSelectArea(); } if( ! bSelect ){ if( m_pEditView->GetSelectionInfo().IsTextSelected() ) { /* 現在の選択範囲を非選択状態に戻す */ m_pEditView->GetSelectionInfo().DisableSelectArea(true); }else if( m_pEditView->GetSelectionInfo().IsBoxSelecting() ){ m_pEditView->GetSelectionInfo().SetBoxSelect(false); } } // (これから求める)キャレットの移動先。 CLayoutPoint ptTo( CLayoutInt(0), ptCaret.y + nMoveLines ); /* 移動先の行のデータを取得 */ const CLayout* const pLayout = pLayoutMgr->SearchLineByLayoutY( ptTo.y ); const CLogicInt nLineLen = pLayout ? pLayout->GetLengthWithEOL() : CLogicInt(0); int i = 0; ///< 何? if( pLayout ) { CMemoryIterator it = pLayoutMgr->CreateCMemoryIterator(pLayout); while( ! it.end() ){ it.scanNext(); if ( it.getIndex() + it.getIndexDelta() > pLayout->GetLengthWithoutEOL() ){ i = nLineLen; break; } if( it.getColumn() + it.getColumnDelta() > m_nCaretPosX_Prev ){ i = it.getIndex(); break; } it.addDelta(); } ptTo.x += it.getColumn(); if( it.end() ) { i = it.getIndex(); } } if( i >= nLineLen ) { /* フリーカーソルモードと矩形選択中は、キャレットの位置を改行や EOFの前に制限しない */ if( pCommon->m_sGeneral.m_bIsFreeCursorMode || m_pEditView->GetSelectionInfo().IsBoxSelecting() ) { ptTo.x = m_nCaretPosX_Prev; } } if( ptTo.x != GetCaretLayoutPos().GetX() ){ bVertLineDoNotOFF = false; } GetAdjustCursorPos( &ptTo ); if( bSelect ) { /* 現在のカーソル位置によって選択範囲を変更 */ m_pEditView->GetSelectionInfo().ChangeSelectAreaByCurrentCursor( ptTo ); } const CLayoutInt nScrollLines = MoveCursor( ptTo, m_pEditView->GetDrawSwitch() /* TRUE */, _CARETMARGINRATE, false, bVertLineDoNotOFF ); return nScrollLines; }
/*! 行桁指定によるカーソル移動(座標調整付き) @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 ); }