mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-05-31 02:26:29 +03:00
Minor refactor.
This commit is contained in:
@@ -73,7 +73,7 @@ class EE_API DocumentView {
|
||||
LineWrapMode mode, bool keepIndentation,
|
||||
Uint32 tabWidth = 4 );
|
||||
|
||||
static Float computeOffsets( const String& string, const FontStyleConfig& fontStyle,
|
||||
static Float computeOffsets( const String::View& string, const FontStyleConfig& fontStyle,
|
||||
Uint32 tabWidth );
|
||||
|
||||
DocumentView( std::shared_ptr<TextDocument> doc, FontStyleConfig fontStyle, Config config );
|
||||
@@ -134,9 +134,9 @@ class EE_API DocumentView {
|
||||
FontStyleConfig mFontStyle;
|
||||
Config mConfig;
|
||||
Float mMaxWidth{ 0 };
|
||||
std::vector<TextPosition> mWrappedLines;
|
||||
std::vector<Float> mWrappedLinesOffset;
|
||||
std::vector<Int64> mWrappedLineToIndex;
|
||||
std::vector<TextPosition> mVisibleLines;
|
||||
std::vector<Float> mVisibleLinesOffset;
|
||||
std::vector<Int64> mDocLineToVisibleIndex;
|
||||
bool mPendingReconstruction{ false };
|
||||
bool mUnderConstruction{ false };
|
||||
};
|
||||
|
||||
@@ -43,12 +43,13 @@ std::string DocumentView::fromLineWrapType( LineWrapType type ) {
|
||||
}
|
||||
}
|
||||
|
||||
Float DocumentView::computeOffsets( const String& string, const FontStyleConfig& fontStyle,
|
||||
Float DocumentView::computeOffsets( const String::View& string, const FontStyleConfig& fontStyle,
|
||||
Uint32 tabWidth ) {
|
||||
|
||||
auto nonIndentPos = string.find_first_not_of( " \t\n\v\f\r" );
|
||||
if ( nonIndentPos != String::InvalidPos )
|
||||
return Text::getTextWidth( string.view().substr( 0, nonIndentPos ), fontStyle, tabWidth );
|
||||
static const String sepSpaces = " \t\n\v\f\r";
|
||||
auto nonIndentPos = string.find_first_not_of( sepSpaces.data() );
|
||||
if ( nonIndentPos != String::View::npos )
|
||||
return Text::getTextWidth( string.substr( 0, nonIndentPos ), fontStyle, tabWidth );
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
@@ -62,13 +63,8 @@ DocumentView::LineWrapInfo DocumentView::computeLineBreaks( const String::View&
|
||||
if ( string.empty() || nullptr == fontStyle.Font || mode == LineWrapMode::NoWrap )
|
||||
return info;
|
||||
|
||||
if ( keepIndentation ) {
|
||||
static const String nofOf = " \t\n\v\f\r";
|
||||
auto nonIndentPos = string.find_first_not_of( nofOf.data() );
|
||||
if ( nonIndentPos != String::InvalidPos )
|
||||
info.paddingStart =
|
||||
Text::getTextWidth( string.substr( 0, nonIndentPos ), fontStyle, tabWidth );
|
||||
}
|
||||
if ( keepIndentation )
|
||||
info.paddingStart = computeOffsets( string, fontStyle, tabWidth );
|
||||
|
||||
Float xoffset = 0.f;
|
||||
Float lastWidth = 0.f;
|
||||
@@ -177,17 +173,17 @@ void DocumentView::setLineWrapMode( LineWrapMode mode ) {
|
||||
}
|
||||
|
||||
TextPosition DocumentView::getVisibleIndexPosition( VisibleIndex visibleIndex ) const {
|
||||
if ( mConfig.mode == LineWrapMode::NoWrap || mWrappedLines.empty() )
|
||||
if ( mConfig.mode == LineWrapMode::NoWrap || mVisibleLines.empty() )
|
||||
return { static_cast<Int64>( visibleIndex ), 0 };
|
||||
return mWrappedLines[eeclamp( static_cast<Int64>( visibleIndex ), 0ll,
|
||||
eemax( static_cast<Int64>( mWrappedLines.size() ) - 1, 0ll ) )];
|
||||
return mVisibleLines[eeclamp( static_cast<Int64>( visibleIndex ), 0ll,
|
||||
eemax( static_cast<Int64>( mVisibleLines.size() ) - 1, 0ll ) )];
|
||||
}
|
||||
|
||||
Float DocumentView::getLinePadding( Int64 docIdx ) const {
|
||||
if ( mConfig.mode == LineWrapMode::NoWrap || mWrappedLinesOffset.empty() )
|
||||
if ( mConfig.mode == LineWrapMode::NoWrap || mVisibleLinesOffset.empty() )
|
||||
return 0;
|
||||
return mWrappedLinesOffset[eeclamp(
|
||||
docIdx, 0ll, eemax( static_cast<Int64>( mWrappedLinesOffset.size() ) - 1, 0ll ) )];
|
||||
return mVisibleLinesOffset[eeclamp(
|
||||
docIdx, 0ll, eemax( static_cast<Int64>( mVisibleLinesOffset.size() ) - 1, 0ll ) )];
|
||||
}
|
||||
|
||||
void DocumentView::setConfig( Config config ) {
|
||||
@@ -208,32 +204,32 @@ void DocumentView::invalidateCache() {
|
||||
|
||||
BoolScopedOp op( mUnderConstruction, true );
|
||||
|
||||
mWrappedLines.clear();
|
||||
mWrappedLineToIndex.clear();
|
||||
mWrappedLinesOffset.clear();
|
||||
mVisibleLines.clear();
|
||||
mDocLineToVisibleIndex.clear();
|
||||
mVisibleLinesOffset.clear();
|
||||
|
||||
if ( mConfig.mode == LineWrapMode::NoWrap )
|
||||
return;
|
||||
|
||||
Int64 linesCount = mDoc->linesCount();
|
||||
mWrappedLines.reserve( linesCount );
|
||||
mWrappedLinesOffset.reserve( linesCount );
|
||||
mVisibleLines.reserve( linesCount );
|
||||
mVisibleLinesOffset.reserve( linesCount );
|
||||
|
||||
for ( auto i = 0; i < linesCount; i++ ) {
|
||||
auto lb = computeLineBreaks( *mDoc, i, mFontStyle, mMaxWidth, mConfig.mode,
|
||||
mConfig.keepIndentation, mConfig.tabWidth );
|
||||
mWrappedLinesOffset.emplace_back( lb.paddingStart );
|
||||
mVisibleLinesOffset.emplace_back( lb.paddingStart );
|
||||
for ( const auto& col : lb.wraps )
|
||||
mWrappedLines.emplace_back( i, col );
|
||||
mVisibleLines.emplace_back( i, col );
|
||||
}
|
||||
|
||||
std::optional<Int64> lastWrap;
|
||||
size_t i = 0;
|
||||
mWrappedLineToIndex.reserve( linesCount );
|
||||
mDocLineToVisibleIndex.reserve( linesCount );
|
||||
|
||||
for ( const auto& wl : mWrappedLines ) {
|
||||
for ( const auto& wl : mVisibleLines ) {
|
||||
if ( !lastWrap || *lastWrap != wl.line() ) {
|
||||
mWrappedLineToIndex.emplace_back( i );
|
||||
mDocLineToVisibleIndex.emplace_back( i );
|
||||
lastWrap = wl.line();
|
||||
}
|
||||
i++;
|
||||
@@ -244,15 +240,15 @@ void DocumentView::invalidateCache() {
|
||||
|
||||
VisibleIndex DocumentView::toVisibleIndex( Int64 docIdx, bool retLast ) const {
|
||||
eeASSERT( isLineVisible( docIdx ) );
|
||||
if ( mConfig.mode == LineWrapMode::NoWrap || mWrappedLineToIndex.empty() )
|
||||
if ( mConfig.mode == LineWrapMode::NoWrap || mDocLineToVisibleIndex.empty() )
|
||||
return static_cast<VisibleIndex>( docIdx );
|
||||
auto idx = mWrappedLineToIndex[eeclamp( docIdx, 0ll,
|
||||
static_cast<Int64>( mWrappedLineToIndex.size() - 1 ) )];
|
||||
auto idx = mDocLineToVisibleIndex[eeclamp(
|
||||
docIdx, 0ll, static_cast<Int64>( mDocLineToVisibleIndex.size() - 1 ) )];
|
||||
if ( retLast ) {
|
||||
Int64 lastOfLine = mWrappedLines[idx].line();
|
||||
Int64 wrappedCount = mWrappedLines.size();
|
||||
for ( auto i = idx + 1; i < wrappedCount; i++ ) {
|
||||
if ( mWrappedLines[i].line() == lastOfLine )
|
||||
Int64 lastOfLine = mVisibleLines[idx].line();
|
||||
Int64 visibleLinesCount = mVisibleLines.size();
|
||||
for ( auto i = idx + 1; i < visibleLinesCount; i++ ) {
|
||||
if ( mVisibleLines[i].line() == lastOfLine )
|
||||
idx = i;
|
||||
else
|
||||
break;
|
||||
@@ -263,9 +259,9 @@ VisibleIndex DocumentView::toVisibleIndex( Int64 docIdx, bool retLast ) const {
|
||||
|
||||
bool DocumentView::isWrappedLine( Int64 docIdx ) const {
|
||||
if ( isWrapEnabled() && mConfig.mode != LineWrapMode::NoWrap ) {
|
||||
Int64 wrappedIndex = static_cast<Int64>( toVisibleIndex( docIdx ) );
|
||||
return wrappedIndex + 1 < static_cast<Int64>( mWrappedLines.size() ) &&
|
||||
mWrappedLines[wrappedIndex].line() == mWrappedLines[wrappedIndex + 1].line();
|
||||
Int64 visibleIndex = static_cast<Int64>( toVisibleIndex( docIdx ) );
|
||||
return visibleIndex + 1 < static_cast<Int64>( mVisibleLines.size() ) &&
|
||||
mVisibleLines[visibleIndex].line() == mVisibleLines[visibleIndex + 1].line();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -282,9 +278,9 @@ DocumentView::VisibleLineInfo DocumentView::getVisibleLineInfo( Int64 docIdx ) c
|
||||
Int64 toIdx = static_cast<Int64>( toVisibleIndex( docIdx, true ) );
|
||||
line.visualLines.reserve( toIdx - fromIdx + 1 );
|
||||
for ( Int64 i = fromIdx; i <= toIdx; i++ )
|
||||
line.visualLines.emplace_back( mWrappedLines[i] );
|
||||
line.visualLines.emplace_back( mVisibleLines[i] );
|
||||
line.visibleIndex = static_cast<VisibleIndex>( fromIdx );
|
||||
line.paddingStart = mWrappedLinesOffset[docIdx];
|
||||
line.paddingStart = mVisibleLinesOffset[docIdx];
|
||||
return line;
|
||||
}
|
||||
|
||||
@@ -300,9 +296,9 @@ DocumentView::VisibleLineRange DocumentView::getVisibleLineRange( const TextPosi
|
||||
Int64 toIdx = static_cast<Int64>( toVisibleIndex( pos.line(), true ) );
|
||||
DocumentView::VisibleLineRange info;
|
||||
for ( Int64 i = fromIdx; i < toIdx; i++ ) {
|
||||
Int64 fromCol = mWrappedLines[i].column();
|
||||
Int64 fromCol = mVisibleLines[i].column();
|
||||
Int64 toCol = i + 1 <= toIdx
|
||||
? mWrappedLines[i + 1].column() - ( allowVisualLineEnd ? 0 : 1 )
|
||||
? mVisibleLines[i + 1].column() - ( allowVisualLineEnd ? 0 : 1 )
|
||||
: mDoc->line( pos.line() ).size();
|
||||
if ( pos.column() >= fromCol && pos.column() <= toCol ) {
|
||||
info.visibleIndex = static_cast<VisibleIndex>( i );
|
||||
@@ -312,7 +308,7 @@ DocumentView::VisibleLineRange DocumentView::getVisibleLineRange( const TextPosi
|
||||
}
|
||||
eeASSERT( toIdx >= 0 );
|
||||
info.visibleIndex = static_cast<VisibleIndex>( toIdx );
|
||||
info.range = { { pos.line(), mWrappedLines[toIdx].column() },
|
||||
info.range = { { pos.line(), mVisibleLines[toIdx].column() },
|
||||
mDoc->endOfLine( { pos.line(), 0ll } ) };
|
||||
return info;
|
||||
}
|
||||
@@ -323,9 +319,9 @@ TextRange DocumentView::getVisibleIndexRange( VisibleIndex visibleIndex ) const
|
||||
Int64 idx = static_cast<Int64>( visibleIndex );
|
||||
auto start = getVisibleIndexPosition( visibleIndex );
|
||||
auto end = start;
|
||||
if ( idx + 1 < static_cast<Int64>( mWrappedLines.size() ) &&
|
||||
mWrappedLines[idx + 1].line() == start.line() ) {
|
||||
end.setColumn( mWrappedLines[idx + 1].column() );
|
||||
if ( idx + 1 < static_cast<Int64>( mVisibleLines.size() ) &&
|
||||
mVisibleLines[idx + 1].line() == start.line() ) {
|
||||
end.setColumn( mVisibleLines[idx + 1].column() );
|
||||
} else {
|
||||
end.setColumn( mDoc->line( start.line() ).size() );
|
||||
}
|
||||
@@ -352,9 +348,9 @@ void DocumentView::setPendingReconstruction( bool pendingReconstruction ) {
|
||||
}
|
||||
|
||||
void DocumentView::clear() {
|
||||
mWrappedLines.clear();
|
||||
mWrappedLineToIndex.clear();
|
||||
mWrappedLinesOffset.clear();
|
||||
mVisibleLines.clear();
|
||||
mDocLineToVisibleIndex.clear();
|
||||
mVisibleLinesOffset.clear();
|
||||
}
|
||||
|
||||
Float DocumentView::getLineYOffset( VisibleIndex visibleIndex, Float lineHeight ) const {
|
||||
@@ -372,22 +368,22 @@ bool DocumentView::isLineVisible( Int64 ) const {
|
||||
void DocumentView::updateCache( Int64 fromLine, Int64 toLine, Int64 numLines ) {
|
||||
if ( mConfig.mode == LineWrapMode::NoWrap )
|
||||
return;
|
||||
// Get affected wrapped range
|
||||
// Get affected visible range
|
||||
Int64 oldIdxFrom = static_cast<Int64>( toVisibleIndex( fromLine, false ) );
|
||||
Int64 oldIdxTo = static_cast<Int64>( toVisibleIndex( toLine, true ) );
|
||||
|
||||
// Remove old wrapped lines
|
||||
mWrappedLines.erase( mWrappedLines.begin() + oldIdxFrom, mWrappedLines.begin() + oldIdxTo + 1 );
|
||||
// Remove old visible lines
|
||||
mVisibleLines.erase( mVisibleLines.begin() + oldIdxFrom, mVisibleLines.begin() + oldIdxTo + 1 );
|
||||
|
||||
// Remove old offsets
|
||||
mWrappedLinesOffset.erase( mWrappedLinesOffset.begin() + fromLine,
|
||||
mWrappedLinesOffset.begin() + toLine + 1 );
|
||||
mVisibleLinesOffset.erase( mVisibleLinesOffset.begin() + fromLine,
|
||||
mVisibleLinesOffset.begin() + toLine + 1 );
|
||||
|
||||
// Shift the line numbers
|
||||
if ( numLines != 0 ) {
|
||||
Int64 wrappedLines = mWrappedLines.size();
|
||||
for ( Int64 i = oldIdxFrom; i < wrappedLines; i++ )
|
||||
mWrappedLines[i].setLine( mWrappedLines[i].line() + numLines );
|
||||
Int64 visibleLinesCount = mVisibleLines.size();
|
||||
for ( Int64 i = oldIdxFrom; i < visibleLinesCount; i++ )
|
||||
mVisibleLines[i].setLine( mVisibleLines[i].line() + numLines );
|
||||
}
|
||||
|
||||
// Recompute line breaks
|
||||
@@ -396,51 +392,40 @@ void DocumentView::updateCache( Int64 fromLine, Int64 toLine, Int64 numLines ) {
|
||||
for ( auto i = fromLine; i <= netLines; i++ ) {
|
||||
auto lb = computeLineBreaks( *mDoc, i, mFontStyle, mMaxWidth, mConfig.mode,
|
||||
mConfig.keepIndentation, mConfig.tabWidth );
|
||||
mWrappedLinesOffset.insert( mWrappedLinesOffset.begin() + i, lb.paddingStart );
|
||||
mVisibleLinesOffset.insert( mVisibleLinesOffset.begin() + i, lb.paddingStart );
|
||||
for ( const auto& col : lb.wraps ) {
|
||||
mWrappedLines.insert( mWrappedLines.begin() + idxOffset, { i, col } );
|
||||
mVisibleLines.insert( mVisibleLines.begin() + idxOffset, { i, col } );
|
||||
idxOffset++;
|
||||
}
|
||||
}
|
||||
|
||||
// Recompute wrapped line to index
|
||||
// Recompute document line to visible index
|
||||
Int64 line = fromLine;
|
||||
Int64 wrappedLinesCount = mWrappedLines.size();
|
||||
mWrappedLineToIndex.resize( mDoc->linesCount() );
|
||||
for ( Int64 wrappedIdx = oldIdxFrom; wrappedIdx < wrappedLinesCount; wrappedIdx++ ) {
|
||||
if ( mWrappedLines[wrappedIdx].column() == 0 ) {
|
||||
mWrappedLineToIndex[line] = wrappedIdx;
|
||||
Int64 visibleLinesCount = mVisibleLines.size();
|
||||
mDocLineToVisibleIndex.resize( mDoc->linesCount() );
|
||||
for ( Int64 visibleIdx = oldIdxFrom; visibleIdx < visibleLinesCount; visibleIdx++ ) {
|
||||
if ( mVisibleLines[visibleIdx].column() == 0 ) {
|
||||
mDocLineToVisibleIndex[line] = visibleIdx;
|
||||
line++;
|
||||
}
|
||||
}
|
||||
mWrappedLineToIndex.resize( mDoc->linesCount() );
|
||||
mDocLineToVisibleIndex.resize( mDoc->linesCount() );
|
||||
|
||||
#ifdef EE_DEBUG
|
||||
if ( mConfig.keepIndentation ) {
|
||||
auto wrappedOffset = mWrappedLinesOffset;
|
||||
|
||||
for ( auto i = fromLine; i <= toLine; i++ ) {
|
||||
mWrappedLinesOffset[i] =
|
||||
computeOffsets( mDoc->line( i ).getText(), mFontStyle, mConfig.tabWidth );
|
||||
}
|
||||
|
||||
eeASSERT( wrappedOffset == mWrappedLinesOffset );
|
||||
}
|
||||
|
||||
auto wrappedLines = mWrappedLines;
|
||||
auto wrappedLinesToIndex = mWrappedLineToIndex;
|
||||
auto wrappedOffset = mWrappedLinesOffset;
|
||||
auto visibleLines = mVisibleLines;
|
||||
auto docLineToVisibleIndex = mDocLineToVisibleIndex;
|
||||
auto visibleLinesOffset = mVisibleLinesOffset;
|
||||
|
||||
invalidateCache();
|
||||
|
||||
eeASSERT( wrappedLines == mWrappedLines );
|
||||
eeASSERT( wrappedLinesToIndex == mWrappedLineToIndex );
|
||||
eeASSERT( wrappedOffset == mWrappedLinesOffset );
|
||||
eeASSERT( visibleLines == mVisibleLines );
|
||||
eeASSERT( docLineToVisibleIndex == mDocLineToVisibleIndex );
|
||||
eeASSERT( visibleLinesOffset == mVisibleLinesOffset );
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t DocumentView::getVisibleLinesCount() const {
|
||||
return mConfig.mode == LineWrapMode::NoWrap ? mDoc->linesCount() : mWrappedLines.size();
|
||||
return mConfig.mode == LineWrapMode::NoWrap ? mDoc->linesCount() : mVisibleLines.size();
|
||||
}
|
||||
|
||||
}}} // namespace EE::UI::Doc
|
||||
|
||||
@@ -1740,7 +1740,7 @@ Float UICodeEditor::getLineWidth( const Int64& docLine ) {
|
||||
}
|
||||
|
||||
void UICodeEditor::updateScrollBar() {
|
||||
int notVisibleLineCount = (int)mDoc->linesCount() - (int)getViewPortLineCount().y;
|
||||
Int64 notVisibleLineCount = (Int64)getTotalVisibleLines() - (Int64)getViewPortLineCount().y;
|
||||
|
||||
mHScrollBar->setEnabled( false );
|
||||
mHScrollBar->setVisible( false );
|
||||
|
||||
Reference in New Issue
Block a user