forked from qt-creator/qt-creator
fix find scope scelection, special case empty overlay selections
This commit is contained in:
@@ -2097,6 +2097,7 @@ void BaseTextEditor::paintEvent(QPaintEvent *e)
|
|||||||
TextEditorOverlay *overlay = new TextEditorOverlay(this);
|
TextEditorOverlay *overlay = new TextEditorOverlay(this);
|
||||||
overlay->addOverlaySelection(d->m_findScope, d->m_searchScopeFormat.background().color().darker(120),
|
overlay->addOverlaySelection(d->m_findScope, d->m_searchScopeFormat.background().color().darker(120),
|
||||||
d->m_searchScopeFormat.background().color());
|
d->m_searchScopeFormat.background().color());
|
||||||
|
overlay->setAlpha(false);
|
||||||
overlay->paint(&painter, e->rect());
|
overlay->paint(&painter, e->rect());
|
||||||
delete overlay;
|
delete overlay;
|
||||||
}
|
}
|
||||||
|
@@ -42,6 +42,7 @@ TextEditorOverlay::TextEditorOverlay(BaseTextEditor *editor)
|
|||||||
m_borderWidth = 1;
|
m_borderWidth = 1;
|
||||||
m_dropShadowWidth = 2;
|
m_dropShadowWidth = 2;
|
||||||
m_editor = editor;
|
m_editor = editor;
|
||||||
|
m_alpha = true;
|
||||||
m_viewport = editor->viewport();
|
m_viewport = editor->viewport();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +119,6 @@ QPainterPath TextEditorOverlay::createSelectionPath(const QTextCursor &begin, co
|
|||||||
if (begin.isNull() || end.isNull() || begin.position() > end.position())
|
if (begin.isNull() || end.isNull() || begin.position() > end.position())
|
||||||
return QPainterPath();
|
return QPainterPath();
|
||||||
|
|
||||||
|
|
||||||
QPointF offset = m_editor->contentOffset();
|
QPointF offset = m_editor->contentOffset();
|
||||||
QRect viewportRect = rect();
|
QRect viewportRect = rect();
|
||||||
QTextDocument *document = m_editor->document();
|
QTextDocument *document = m_editor->document();
|
||||||
@@ -134,65 +134,78 @@ QPainterPath TextEditorOverlay::createSelectionPath(const QTextCursor &begin, co
|
|||||||
|
|
||||||
QVector<QRectF> selection;
|
QVector<QRectF> selection;
|
||||||
|
|
||||||
for (; block.isValid() && block.blockNumber() <= end.blockNumber(); block = block.next()) {
|
if (begin.position() == end.position()) {
|
||||||
if (! block.isVisible())
|
// special case empty selections
|
||||||
continue;
|
|
||||||
|
|
||||||
const QRectF blockGeometry = m_editor->blockBoundingGeometry(block);
|
const QRectF blockGeometry = m_editor->blockBoundingGeometry(block);
|
||||||
QTextLayout *blockLayout = block.layout();
|
QTextLayout *blockLayout = block.layout();
|
||||||
|
int pos = begin.position() - begin.block().position();
|
||||||
QTextLine line = blockLayout->lineAt(0);
|
QTextLine line = blockLayout->lineForTextPosition(pos);
|
||||||
|
|
||||||
int beginChar = 0;
|
|
||||||
if (!inSelection) {
|
|
||||||
beginChar = begin.position() - begin.block().position();
|
|
||||||
line = blockLayout->lineForTextPosition(beginChar);
|
|
||||||
inSelection = true;
|
|
||||||
} else {
|
|
||||||
while (beginChar < block.length() && document->characterAt(block.position() + beginChar).isSpace())
|
|
||||||
++beginChar;
|
|
||||||
if (beginChar == block.length())
|
|
||||||
beginChar = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lastLine = blockLayout->lineCount()-1;
|
|
||||||
int endChar = -1;
|
|
||||||
if (block == end.block()) {
|
|
||||||
endChar = end.position() - end.block().position();
|
|
||||||
lastLine = blockLayout->lineForTextPosition(endChar).lineNumber();
|
|
||||||
inSelection = false;
|
|
||||||
} else {
|
|
||||||
endChar = block.length();
|
|
||||||
while (endChar > beginChar && document->characterAt(block.position() + endChar - 1).isSpace())
|
|
||||||
--endChar;
|
|
||||||
}
|
|
||||||
|
|
||||||
QRectF lineRect = line.naturalTextRect();
|
QRectF lineRect = line.naturalTextRect();
|
||||||
if (beginChar < endChar) {
|
int x = line.cursorToX(pos);
|
||||||
lineRect.setLeft(line.cursorToX(beginChar));
|
lineRect.setLeft(x - m_borderWidth);
|
||||||
if (line.lineNumber() == lastLine)
|
lineRect.setRight(x + m_borderWidth);
|
||||||
lineRect.setRight(line.cursorToX(endChar));
|
selection += lineRect.translated(blockGeometry.topLeft());
|
||||||
selection += lineRect.translated(blockGeometry.topLeft());
|
} else {
|
||||||
|
for (; block.isValid() && block.blockNumber() <= end.blockNumber(); block = block.next()) {
|
||||||
|
if (! block.isVisible())
|
||||||
|
continue;
|
||||||
|
|
||||||
for (int lineIndex = line.lineNumber()+1; lineIndex <= lastLine; ++lineIndex) {
|
const QRectF blockGeometry = m_editor->blockBoundingGeometry(block);
|
||||||
line = blockLayout->lineAt(lineIndex);
|
QTextLayout *blockLayout = block.layout();
|
||||||
lineRect = line.naturalTextRect();
|
|
||||||
if (lineIndex == lastLine)
|
QTextLine line = blockLayout->lineAt(0);
|
||||||
|
|
||||||
|
int beginChar = 0;
|
||||||
|
if (!inSelection) {
|
||||||
|
beginChar = begin.position() - begin.block().position();
|
||||||
|
line = blockLayout->lineForTextPosition(beginChar);
|
||||||
|
inSelection = true;
|
||||||
|
} else {
|
||||||
|
while (beginChar < block.length() && document->characterAt(block.position() + beginChar).isSpace())
|
||||||
|
++beginChar;
|
||||||
|
if (beginChar == block.length())
|
||||||
|
beginChar = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lastLine = blockLayout->lineCount()-1;
|
||||||
|
int endChar = -1;
|
||||||
|
if (block == end.block()) {
|
||||||
|
endChar = end.position() - end.block().position();
|
||||||
|
lastLine = blockLayout->lineForTextPosition(endChar).lineNumber();
|
||||||
|
inSelection = false;
|
||||||
|
} else {
|
||||||
|
endChar = block.length();
|
||||||
|
while (endChar > beginChar && document->characterAt(block.position() + endChar - 1).isSpace())
|
||||||
|
--endChar;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF lineRect = line.naturalTextRect();
|
||||||
|
if (beginChar < endChar) {
|
||||||
|
lineRect.setLeft(line.cursorToX(beginChar));
|
||||||
|
if (line.lineNumber() == lastLine)
|
||||||
lineRect.setRight(line.cursorToX(endChar));
|
lineRect.setRight(line.cursorToX(endChar));
|
||||||
selection += lineRect.translated(blockGeometry.topLeft());
|
selection += lineRect.translated(blockGeometry.topLeft());
|
||||||
|
|
||||||
|
for (int lineIndex = line.lineNumber()+1; lineIndex <= lastLine; ++lineIndex) {
|
||||||
|
line = blockLayout->lineAt(lineIndex);
|
||||||
|
lineRect = line.naturalTextRect();
|
||||||
|
if (lineIndex == lastLine)
|
||||||
|
lineRect.setRight(line.cursorToX(endChar));
|
||||||
|
selection += lineRect.translated(blockGeometry.topLeft());
|
||||||
|
}
|
||||||
|
} else { // empty lines
|
||||||
|
if (!selection.isEmpty())
|
||||||
|
lineRect.setLeft(selection.last().left());
|
||||||
|
lineRect.setRight(lineRect.left() + 16);
|
||||||
|
selection += lineRect.translated(blockGeometry.topLeft());
|
||||||
}
|
}
|
||||||
} else { // empty lines
|
|
||||||
if (!selection.isEmpty())
|
if (!inSelection)
|
||||||
lineRect.setLeft(selection.last().left());
|
break;
|
||||||
lineRect.setRight(lineRect.left() + 16);
|
|
||||||
selection += lineRect.translated(blockGeometry.topLeft());
|
if (blockGeometry.translated(offset).y() > 2*viewportRect.height())
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!inSelection)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (blockGeometry.translated(offset).y() > 2*viewportRect.height())
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -288,21 +301,30 @@ void TextEditorOverlay::paintSelection(QPainter *painter,
|
|||||||
|
|
||||||
painter->save();
|
painter->save();
|
||||||
QColor penColor = fg;
|
QColor penColor = fg;
|
||||||
penColor.setAlpha(220);
|
if (m_alpha)
|
||||||
|
penColor.setAlpha(220);
|
||||||
QPen pen(penColor, m_borderWidth);
|
QPen pen(penColor, m_borderWidth);
|
||||||
painter->translate(-.5, -.5);
|
painter->translate(-.5, -.5);
|
||||||
|
|
||||||
QRectF pathRect = path.controlPointRect();
|
QRectF pathRect = path.controlPointRect();
|
||||||
|
|
||||||
if (bg.isValid()) {
|
if (bg.isValid()) {
|
||||||
QLinearGradient linearGrad(pathRect.topLeft(), pathRect.bottomLeft());
|
if (!m_alpha || begin.blockNumber() != end.blockNumber()) {
|
||||||
QColor col1 = fg.lighter(150);
|
// gradients are too slow for larger selections :(
|
||||||
col1.setAlpha(20);
|
QColor col = bg;
|
||||||
QColor col2 = fg;
|
if (m_alpha)
|
||||||
col2.setAlpha(80);
|
col.setAlpha(50);
|
||||||
linearGrad.setColorAt(0, col1);
|
painter->setBrush(col);
|
||||||
linearGrad.setColorAt(1, col2);
|
} else {
|
||||||
painter->setBrush(QBrush(linearGrad));
|
QLinearGradient linearGrad(pathRect.topLeft(), pathRect.bottomLeft());
|
||||||
|
QColor col1 = fg.lighter(150);
|
||||||
|
col1.setAlpha(20);
|
||||||
|
QColor col2 = fg;
|
||||||
|
col2.setAlpha(80);
|
||||||
|
linearGrad.setColorAt(0, col1);
|
||||||
|
linearGrad.setColorAt(1, col2);
|
||||||
|
painter->setBrush(QBrush(linearGrad));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
painter->setBrush(QBrush());
|
painter->setBrush(QBrush());
|
||||||
}
|
}
|
||||||
@@ -311,12 +333,10 @@ void TextEditorOverlay::paintSelection(QPainter *painter,
|
|||||||
|
|
||||||
if (selection.m_dropShadow) {
|
if (selection.m_dropShadow) {
|
||||||
painter->save();
|
painter->save();
|
||||||
painter->translate(m_dropShadowWidth, m_dropShadowWidth);
|
QPainterPath shadow = path;
|
||||||
|
shadow.translate(m_dropShadowWidth, m_dropShadowWidth);
|
||||||
QPainterPath clip = path;
|
painter->setClipPath(shadow.intersected(path));
|
||||||
clip.translate(-m_dropShadowWidth, -m_dropShadowWidth);
|
painter->fillPath(shadow, QColor(0, 0, 0, 100));
|
||||||
painter->setClipPath(clip.intersected(path));
|
|
||||||
painter->fillPath(path, QColor(0, 0, 0, 100));
|
|
||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -59,6 +59,7 @@ private:
|
|||||||
bool m_visible;
|
bool m_visible;
|
||||||
int m_borderWidth;
|
int m_borderWidth;
|
||||||
int m_dropShadowWidth;
|
int m_dropShadowWidth;
|
||||||
|
bool m_alpha;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TextEditorOverlay(BaseTextEditor *editor);
|
TextEditorOverlay(BaseTextEditor *editor);
|
||||||
@@ -74,6 +75,8 @@ public:
|
|||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
|
void setAlpha(bool enabled) { m_alpha = enabled; }
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
void addOverlaySelection(const QTextCursor &cursor, const QColor &fg, const QColor &bg, bool lockSize = false);
|
void addOverlaySelection(const QTextCursor &cursor, const QColor &fg, const QColor &bg, bool lockSize = false);
|
||||||
void addOverlaySelection(int begin, int end, const QColor &fg, const QColor &bg, bool lockSize = false, bool dropShadow = false);
|
void addOverlaySelection(int begin, int end, const QColor &fg, const QColor &bg, bool lockSize = false, bool dropShadow = false);
|
||||||
|
Reference in New Issue
Block a user