VTextEdit: support block cursor

This commit is contained in:
Le Tan 2017-11-30 21:25:43 +08:00
parent 72946d0e15
commit b2a435297d
4 changed files with 104 additions and 8 deletions

View File

@ -31,7 +31,11 @@ VTextDocumentLayout::VTextDocumentLayout(QTextDocument *p_doc,
m_imageMgr(p_imageMgr),
m_blockImageEnabled(false),
m_imageWidthConstrainted(false),
m_imageLineColor("#9575CD")
m_imageLineColor("#9575CD"),
m_cursorBlockMode(false),
m_virtualCursorBlockWidth(8),
m_cursorBlockFg("#EEEEEE"),
m_cursorBlockBg("#222222")
{
}
@ -221,6 +225,25 @@ void VTextDocumentLayout::draw(QPainter *p_painter, const PaintContext &p_contex
auto selections = formatRangeFromSelection(block, p_context.selections);
// Draw the cursor.
int blpos = block.position();
int bllen = block.length();
bool drawCursor = p_context.cursorPosition >= blpos
&& p_context.cursorPosition < blpos + bllen;
bool drawCursorAsBlock = drawCursor && m_cursorBlockMode;
if (drawCursorAsBlock) {
if (p_context.cursorPosition == blpos + bllen - 1) {
drawCursorAsBlock = false;
} else {
QTextLayout::FormatRange o;
o.start = p_context.cursorPosition - blpos;
o.length = 1;
o.format.setForeground(m_cursorBlockFg);
o.format.setBackground(m_cursorBlockBg);
selections.append(o);
}
}
layout->draw(p_painter,
offset,
selections,
@ -230,12 +253,7 @@ void VTextDocumentLayout::draw(QPainter *p_painter, const PaintContext &p_contex
drawMarkers(p_painter, block, offset);
// Draw the cursor.
int blpos = block.position();
int bllen = block.length();
bool drawCursor = p_context.cursorPosition >= blpos
&& p_context.cursorPosition < blpos + bllen;
if (drawCursor
if ((drawCursor && !drawCursorAsBlock)
|| (p_context.cursorPosition < -1
&& !layout->preeditAreaText().isEmpty())) {
int cpos = p_context.cursorPosition;
@ -245,7 +263,11 @@ void VTextDocumentLayout::draw(QPainter *p_painter, const PaintContext &p_contex
cpos -= blpos;
}
layout->drawCursor(p_painter, offset, cpos, m_cursorWidth);
layout->drawCursor(p_painter,
offset,
cpos,
m_cursorBlockMode ? m_virtualCursorBlockWidth
: m_cursorWidth);
}
offset.ry() += rect.height();

View File

@ -54,6 +54,12 @@ public:
void setImageLineColor(const QColor &p_color);
void setCursorBlockMode(bool p_enabled);
void setCursorBlockFg(const QColor &p_color);
void setCursorBlockBg(const QColor &p_color);
protected:
void documentChanged(int p_from, int p_charsRemoved, int p_charsAdded) Q_DECL_OVERRIDE;
@ -264,6 +270,18 @@ private:
// Color of the image line.
QColor m_imageLineColor;
// Draw cursor as block.
bool m_cursorBlockMode;
// Virtual cursor block: cursor block on no character.
int m_virtualCursorBlockWidth;
// Foreground of cursor block.
QColor m_cursorBlockFg;
// Background of cursor block.
QColor m_cursorBlockBg;
};
inline qreal VTextDocumentLayout::getLineLeading() const
@ -282,4 +300,20 @@ inline void VTextDocumentLayout::scaleSize(QSize &p_size, int p_width, int p_hei
p_size.scale(p_width, p_height, Qt::KeepAspectRatio);
}
}
inline void VTextDocumentLayout::setCursorBlockMode(bool p_enabled)
{
m_cursorBlockMode = p_enabled;
}
inline void VTextDocumentLayout::setCursorBlockFg(const QColor &p_color)
{
m_cursorBlockFg = p_color;
}
inline void VTextDocumentLayout::setCursorBlockBg(const QColor &p_color)
{
m_cursorBlockBg = p_color;
}
#endif // VTEXTDOCUMENTLAYOUT_H

View File

@ -48,6 +48,8 @@ void VTextEdit::init()
m_blockImageEnabled = false;
m_cursorBlockMode = false;
m_imageMgr = new VImageResourceManager2();
QTextDocument *doc = document();
@ -84,6 +86,10 @@ void VTextEdit::resizeEvent(QResizeEvent *p_event)
{
QTextEdit::resizeEvent(p_event);
if (m_cursorBlockMode) {
setCursorWidth(p_event->size().width());
}
if (m_lineNumberType != LineNumberType::None) {
QRect rect = contentsRect();
m_lineNumberArea->setGeometry(QRect(rect.left(),
@ -332,3 +338,29 @@ void VTextEdit::setImageLineColor(const QColor &p_color)
{
getLayout()->setImageLineColor(p_color);
}
void VTextEdit::setCursorBlockMode(bool p_enabled)
{
if (p_enabled != m_cursorBlockMode) {
m_cursorBlockMode = p_enabled;
getLayout()->setCursorBlockMode(m_cursorBlockMode);
if (p_enabled) {
// Will set cursor width according to the viewport.
setCursorWidth(viewport()->width());
} else {
// Restore cursor width.
setCursorWidth(1);
}
}
}
void VTextEdit::setCursorBlockFg(const QColor &p_color)
{
getLayout()->setCursorBlockFg(p_color);
}
void VTextEdit::setCursorBlockBg(const QColor &p_color)
{
getLayout()->setCursorBlockBg(p_color);
}

View File

@ -56,6 +56,12 @@ public:
void relayout(const QSet<int> &p_blocks);
void setCursorBlockMode(bool p_enabled);
void setCursorBlockFg(const QColor &p_color);
void setCursorBlockBg(const QColor &p_color);
protected:
void resizeEvent(QResizeEvent *p_event) Q_DECL_OVERRIDE;
@ -78,6 +84,8 @@ private:
VImageResourceManager2 *m_imageMgr;
bool m_blockImageEnabled;
bool m_cursorBlockMode;
};
inline void VTextEdit::setLineNumberType(LineNumberType p_type)