- Enhancement: Optimization for drawing scrollbars.
This commit is contained in:
parent
0e77ed10c7
commit
383031bc5d
1
NEWS.md
1
NEWS.md
|
@ -85,6 +85,7 @@ Red Panda C++ Version 2.26
|
|||
- Fix: Function list is not correctly retrived for full-scoped functions.
|
||||
- Enhancement: Improved Raw string support
|
||||
- Enhancement: New option for compiler set "Don't localize gcc output messages"
|
||||
- Enhancement: Optimization for drawing scrollbars.
|
||||
|
||||
Red Panda C++ Version 2.25
|
||||
|
||||
|
|
|
@ -91,7 +91,9 @@ int Document::lineWidth(int line)
|
|||
{
|
||||
QMutexLocker locker(&mMutex);
|
||||
if (line>=0 && line < mLines.size()) {
|
||||
return mLines[line]->width();
|
||||
int width = mLines[line]->width();
|
||||
//updateLongestLineWidth(width);
|
||||
return width;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
@ -139,17 +141,14 @@ int Document::blockEnded(int line)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int Document::longestLineWidth() {
|
||||
int Document::maxLineWidth() {
|
||||
QMutexLocker locker(&mMutex);
|
||||
if (mIndexOfLongestLine < 0) {
|
||||
int MaxLen = -1;
|
||||
mIndexOfLongestLine = -1;
|
||||
if (mLines.count() > 0 ) {
|
||||
for (int i=0;i<mLines.size();i++) {
|
||||
int len = mLines[i]->width();
|
||||
//Just estimate it.
|
||||
if (len<0)
|
||||
len = mCharWidth * mLines[i]->lineText().length();
|
||||
int len = mLines[i]->mWidth;
|
||||
if (len > MaxLen) {
|
||||
MaxLen = len;
|
||||
mIndexOfLongestLine = i;
|
||||
|
@ -471,9 +470,9 @@ void Document::putLine(int index, const QString &s, bool notify) {
|
|||
listIndexOutOfBounds(index);
|
||||
}
|
||||
beginUpdate();
|
||||
int oldColumns = mLines[index]->width();
|
||||
int oldWidth = mLines[index]->width();
|
||||
mLines[index]->setLineText( s );
|
||||
if (mIndexOfLongestLine == index && oldColumns>mLines[index]->width() )
|
||||
if (mIndexOfLongestLine == index && oldWidth>mLines[index]->width() )
|
||||
mIndexOfLongestLine = -1;
|
||||
else if (mIndexOfLongestLine>=0
|
||||
&& mIndexOfLongestLine<mLines.count()
|
||||
|
@ -1171,9 +1170,21 @@ void Document::setLineWidth(int line, const QString &lineText, int newWidth, con
|
|||
return;
|
||||
mLines[line]->mWidth = newWidth;
|
||||
mLines[line]->mGlyphStartPositionList = glyphStartPositionList;
|
||||
updateLongestLineWidth(line , newWidth);
|
||||
Q_ASSERT(mLines[line]->mGlyphStartPositionList.length() == mLines[line]->mGlyphStartCharList.length());
|
||||
}
|
||||
|
||||
void Document::updateLongestLineWidth(int line, int width)
|
||||
{
|
||||
if (mIndexOfLongestLine<0) {
|
||||
mIndexOfLongestLine = line;
|
||||
emit maxLineWidthChanged(width);
|
||||
} else if (mLines[mIndexOfLongestLine]->mWidth < width) {
|
||||
mIndexOfLongestLine = line;
|
||||
emit maxLineWidthChanged(width);
|
||||
}
|
||||
}
|
||||
|
||||
QList<int> Document::calcGlyphPositionList(const QString &lineText, const QList<int> &glyphStartCharList, int left, int &right) const
|
||||
{
|
||||
return calcGlyphPositionList(lineText, glyphStartCharList,
|
||||
|
|
|
@ -300,7 +300,7 @@ public:
|
|||
*
|
||||
* @return
|
||||
*/
|
||||
int longestLineWidth();
|
||||
int maxLineWidth();
|
||||
|
||||
/**
|
||||
* @brief get line break of the current document
|
||||
|
@ -567,6 +567,7 @@ signals:
|
|||
void deleted(int startLine, int count);
|
||||
void inserted(int startLine, int count);
|
||||
void putted(int line);
|
||||
void maxLineWidthChanged(int newWidth);
|
||||
protected:
|
||||
QString getTextStr() const;
|
||||
void setUpdateState(bool Updating);
|
||||
|
@ -576,6 +577,7 @@ protected:
|
|||
void internalClear();
|
||||
private:
|
||||
void setLineWidth(int line, const QString& lineText, int newWidth, const QList<int> glyphStartPositionList);
|
||||
void updateLongestLineWidth(int line, int width);
|
||||
|
||||
int glyphWidth(const QString& glyph, int left,
|
||||
const QFontMetrics &fontMetrics,
|
||||
|
|
|
@ -60,6 +60,10 @@ QSynEdit::QSynEdit(QWidget *parent) : QAbstractScrollArea(parent),
|
|||
mFontDummy = QFont("monospace",14);
|
||||
mFontDummy.setStyleStrategy(QFont::PreferAntialias);
|
||||
mDocument = std::make_shared<Document>(mFontDummy, this);
|
||||
|
||||
connect(mDocument.get(), &Document::maxLineWidthChanged,
|
||||
this, &QSynEdit::updateHScrollbar);
|
||||
|
||||
//fPlugins := TList.Create;
|
||||
mMouseMoved = false;
|
||||
mMouseOrigin = QPoint(0,0);
|
||||
|
@ -70,6 +74,11 @@ QSynEdit::QSynEdit(QWidget *parent) : QAbstractScrollArea(parent),
|
|||
mDocument->connect(mDocument.get(), &Document::deleted, this, &QSynEdit::onLinesDeleted);
|
||||
mDocument->connect(mDocument.get(), &Document::inserted, this, &QSynEdit::onLinesInserted);
|
||||
mDocument->connect(mDocument.get(), &Document::putted, this, &QSynEdit::onLinesPutted);
|
||||
connect(mDocument.get(), &Document::maxLineWidthChanged,
|
||||
this, &QSynEdit::updateHScrollbar);
|
||||
mDocument->connect(mDocument.get(), &Document::cleared, this, &QSynEdit::updateVScrollbar);
|
||||
mDocument->connect(mDocument.get(), &Document::deleted, this, &QSynEdit::updateVScrollbar);
|
||||
mDocument->connect(mDocument.get(), &Document::inserted, this, &QSynEdit::updateVScrollbar);
|
||||
|
||||
mGutterWidth = 0;
|
||||
mScrollBars = ScrollStyle::ssBoth;
|
||||
|
@ -237,6 +246,7 @@ void QSynEdit::setCaretXYEx(bool CallEnsureCursorPosVisible, BufferCoord value)
|
|||
if (mCaretX != value.ch) {
|
||||
mCaretX = value.ch;
|
||||
mStatusChanges.setFlag(StatusChange::scCaretX);
|
||||
mStateFlags.setFlag(StateFlag::sfHScrollbarChanged);
|
||||
invalidateLine(mCaretY);
|
||||
}
|
||||
if (mCaretY != value.line) {
|
||||
|
@ -247,6 +257,7 @@ void QSynEdit::setCaretXYEx(bool CallEnsureCursorPosVisible, BufferCoord value)
|
|||
invalidateLine(oldCaretY);
|
||||
invalidateGutterLine(oldCaretY);
|
||||
mStatusChanges.setFlag(StatusChange::scCaretY);
|
||||
mStateFlags.setFlag(StateFlag::sfVScrollbarChanged);
|
||||
}
|
||||
// Call UpdateLastCaretX before DecPaintLock because the event handler it
|
||||
// calls could raise an exception, and we don't want fLastCaretX to be
|
||||
|
@ -254,8 +265,6 @@ void QSynEdit::setCaretXYEx(bool CallEnsureCursorPosVisible, BufferCoord value)
|
|||
updateLastCaretX();
|
||||
if (CallEnsureCursorPosVisible)
|
||||
ensureCursorPosVisible();
|
||||
mStateFlags.setFlag(StateFlag::sfCaretChanged);
|
||||
mStateFlags.setFlag(StateFlag::sfScrollbarChanged);
|
||||
} else {
|
||||
// Also call UpdateLastCaretX if the caret didn't move. Apps don't know
|
||||
// anything about fLastCaretX and they shouldn't need to. So, to avoid any
|
||||
|
@ -327,7 +336,7 @@ bool QSynEdit::canRedo() const
|
|||
|
||||
int QSynEdit::maxScrollWidth() const
|
||||
{
|
||||
int maxWidth = mDocument->longestLineWidth();
|
||||
int maxWidth = mDocument->maxLineWidth();
|
||||
if (useCodeFolding())
|
||||
maxWidth += stringWidth(syntaxer()->foldString(""),maxWidth);
|
||||
if (mOptions.testFlag(eoScrollPastEol))
|
||||
|
@ -2969,8 +2978,16 @@ void QSynEdit::decPaintLock()
|
|||
Q_ASSERT(mPaintLock > 0);
|
||||
mPaintLock--;
|
||||
if (mPaintLock == 0 ) {
|
||||
if (mStateFlags.testFlag(StateFlag::sfScrollbarChanged)) {
|
||||
updateScrollbars();
|
||||
bool scrollbarUpdated = false;
|
||||
if (mStateFlags.testFlag(StateFlag::sfHScrollbarChanged)) {
|
||||
updateHScrollbar();
|
||||
scrollbarUpdated = true;
|
||||
}
|
||||
if (mStateFlags.testFlag(StateFlag::sfVScrollbarChanged)) {
|
||||
updateVScrollbar();
|
||||
scrollbarUpdated = true;
|
||||
}
|
||||
if (scrollbarUpdated) {
|
||||
ensureCursorPosVisible();
|
||||
}
|
||||
if (mStateFlags.testFlag(StateFlag::sfCaretChanged))
|
||||
|
@ -3117,21 +3134,19 @@ void QSynEdit::doOnStatusChange(StatusChanges)
|
|||
mStatusChanges = StatusChange::scNone;
|
||||
}
|
||||
|
||||
void QSynEdit::updateScrollbars()
|
||||
void QSynEdit::updateHScrollbar()
|
||||
{
|
||||
int nMaxScroll;
|
||||
int nMin,nMax,nPage,nPos;
|
||||
if (mPaintLock!=0) {
|
||||
mStateFlags.setFlag(StateFlag::sfScrollbarChanged);
|
||||
mStateFlags.setFlag(StateFlag::sfHScrollbarChanged);
|
||||
} else {
|
||||
mStateFlags.setFlag(StateFlag::sfScrollbarChanged,false);
|
||||
mStateFlags.setFlag(StateFlag::sfHScrollbarChanged,false);
|
||||
if (mScrollBars != ScrollStyle::ssNone) {
|
||||
if (mOptions.testFlag(eoHideShowScrollbars)) {
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded);
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded);
|
||||
} else {
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOn);
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOn);
|
||||
}
|
||||
if (mScrollBars == ScrollStyle::ssBoth || mScrollBars == ScrollStyle::ssHorizontal) {
|
||||
nMaxScroll = maxScrollWidth();
|
||||
|
@ -3146,6 +3161,26 @@ void QSynEdit::updateScrollbars()
|
|||
horizontalScrollBar()->setSingleStep(1);
|
||||
} else
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOn);
|
||||
} else {
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QSynEdit::updateVScrollbar()
|
||||
{
|
||||
int nMaxScroll;
|
||||
int nMin,nMax,nPage,nPos;
|
||||
if (mPaintLock!=0) {
|
||||
mStateFlags.setFlag(StateFlag::sfVScrollbarChanged);
|
||||
} else {
|
||||
mStateFlags.setFlag(StateFlag::sfVScrollbarChanged,false);
|
||||
if (mScrollBars != ScrollStyle::ssNone) {
|
||||
if (mOptions.testFlag(eoHideShowScrollbars)) {
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded);
|
||||
} else {
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOn);
|
||||
}
|
||||
|
||||
if (mScrollBars == ScrollStyle::ssBoth || mScrollBars == ScrollStyle::ssVertical) {
|
||||
nMaxScroll = maxScrollHeight();
|
||||
|
@ -3161,12 +3196,12 @@ void QSynEdit::updateScrollbars()
|
|||
} else
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff);
|
||||
} else {
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff);
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void QSynEdit::updateCaret()
|
||||
{
|
||||
mStateFlags.setFlag(StateFlag::sfCaretChanged,false);
|
||||
|
@ -3363,7 +3398,8 @@ void QSynEdit::uncollapse(PCodeFoldingRange FoldRange)
|
|||
|
||||
// Redraw fold mark
|
||||
invalidateGutterLines(FoldRange->fromLine, INT_MAX);
|
||||
updateScrollbars();
|
||||
updateVScrollbar();
|
||||
updateHScrollbar();
|
||||
}
|
||||
|
||||
void QSynEdit::collapse(PCodeFoldingRange FoldRange)
|
||||
|
@ -3383,7 +3419,8 @@ void QSynEdit::collapse(PCodeFoldingRange FoldRange)
|
|||
// Redraw fold mark
|
||||
invalidateGutterLines(FoldRange->fromLine, INT_MAX);
|
||||
|
||||
updateScrollbars();
|
||||
updateHScrollbar();
|
||||
updateVScrollbar();
|
||||
}
|
||||
|
||||
void QSynEdit::foldOnLinesInserted(int Line, int Count)
|
||||
|
@ -3771,17 +3808,17 @@ void QSynEdit::onSizeOrFontChanged(bool bFont)
|
|||
{
|
||||
if (mCharWidth != 0) {
|
||||
mLinesInWindow = clientHeight() / mTextHeight;
|
||||
bool scrollBarChangedSettings = mStateFlags.testFlag(StateFlag::sfScrollbarChanged);
|
||||
if (bFont) {
|
||||
if (mGutter.showLineNumbers())
|
||||
onGutterChanged();
|
||||
else
|
||||
updateScrollbars();
|
||||
else {
|
||||
updateHScrollbar();
|
||||
}
|
||||
mStateFlags.setFlag(StateFlag::sfCaretChanged,false);
|
||||
invalidate();
|
||||
} else
|
||||
updateScrollbars();
|
||||
mStateFlags.setFlag(StateFlag::sfScrollbarChanged,scrollBarChangedSettings);
|
||||
} else {
|
||||
updateHScrollbar();
|
||||
}
|
||||
//if (!mOptions.testFlag(SynEditorOption::eoScrollPastEol))
|
||||
setLeftPos(mLeftPos);
|
||||
//if (!mOptions.testFlag(SynEditorOption::eoScrollPastEof))
|
||||
|
@ -4084,7 +4121,8 @@ void QSynEdit::setOptions(const EditorOptions &Value)
|
|||
setBlockBegin(vTempBlockBegin);
|
||||
setBlockEnd(vTempBlockEnd);
|
||||
}
|
||||
updateScrollbars();
|
||||
updateHScrollbar();
|
||||
updateVScrollbar();
|
||||
if (bUpdateAll)
|
||||
invalidate();
|
||||
decPaintLock();
|
||||
|
@ -6577,7 +6615,6 @@ void QSynEdit::onLinesChanged()
|
|||
SelectionMode vOldMode;
|
||||
mStateFlags.setFlag(StateFlag::sfLinesChanging, false);
|
||||
|
||||
updateScrollbars();
|
||||
if (mActiveSelectionMode == SelectionMode::Column) {
|
||||
BufferCoord oldBlockStart = blockBegin();
|
||||
BufferCoord oldBlockEnd = blockEnd();
|
||||
|
@ -6741,7 +6778,7 @@ void QSynEdit::setBlockEnd(BufferCoord value)
|
|||
else
|
||||
value.ch = 1;
|
||||
} else {
|
||||
int maxLen = mDocument->longestLineWidth();
|
||||
int maxLen = mDocument->maxLineWidth();
|
||||
if (useCodeFolding())
|
||||
maxLen += stringWidth(mSyntaxer->foldString(""),maxLen);
|
||||
value.ch = minMax(value.ch, 1, maxLen+1);
|
||||
|
@ -6848,7 +6885,7 @@ void QSynEdit::setBlockBegin(BufferCoord value)
|
|||
else
|
||||
value.ch = 1;
|
||||
} else {
|
||||
int maxLen = mDocument->longestLineWidth();
|
||||
int maxLen = mDocument->maxLineWidth();
|
||||
if (useCodeFolding())
|
||||
maxLen += stringWidth(mSyntaxer->foldString(""),maxLen);
|
||||
value.ch = minMax(value.ch, 1, maxLen+1);
|
||||
|
|
|
@ -62,14 +62,15 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(StatusChanges)
|
|||
|
||||
enum class StateFlag {
|
||||
sfCaretChanged = 0x0001,
|
||||
sfScrollbarChanged = 0x0002,
|
||||
sfLinesChanging = 0x0004,
|
||||
sfIgnoreNextChar = 0x0008,
|
||||
sfCaretVisible = 0x0010,
|
||||
sfDblClicked = 0x0020,
|
||||
sfWaitForDragging = 0x0040,
|
||||
sfRedrawNeeded = 0x0080,
|
||||
sfGutterRedrawNeeded = 0x0100,
|
||||
sfHScrollbarChanged = 0x0002,
|
||||
sfVScrollbarChanged = 0x0004,
|
||||
sfLinesChanging = 0x0008,
|
||||
sfIgnoreNextChar = 0x0010,
|
||||
sfCaretVisible = 0x0020,
|
||||
sfDblClicked = 0x0040,
|
||||
sfWaitForDragging = 0x0080,
|
||||
sfRedrawNeeded = 0x0100,
|
||||
sfGutterRedrawNeeded = 0x0200,
|
||||
};
|
||||
|
||||
Q_DECLARE_FLAGS(StateFlags,StateFlag)
|
||||
|
@ -533,7 +534,8 @@ private:
|
|||
void internalSetCaretY(int Value);
|
||||
void setStatusChanged(StatusChanges changes);
|
||||
void doOnStatusChange(StatusChanges changes);
|
||||
void updateScrollbars();
|
||||
void updateHScrollbar();
|
||||
void updateVScrollbar();
|
||||
void updateCaret();
|
||||
void recalcCharExtent();
|
||||
QString expandAtWideGlyphs(const QString& S);
|
||||
|
|
Loading…
Reference in New Issue