Commit dabac1f4 authored by Thomas Surrel's avatar Thomas Surrel

Highlight lines coming into view

Add a profile option that would, when enabled, highlight the lines that are
coming into view. A thin blue line on the left of the terminal will highlight
the new lines in the following situations:
- scrolling with the mouse
- using the scroll bar
- using the keyboard to move up/down
- new lines resulting from the output of a command
parent fd5c853a
......@@ -1587,6 +1587,12 @@ void EditProfileDialog::setupScrollingPage(const Profile::Ptr &profile)
setupRadio(pageamounts, scrollFullPage);
const auto options = QVector<BooleanOption>{
{_scrollingUi->highlightScrolledLinesButton, Profile::HighlightScrolledLines, SLOT(toggleHighlightScrolledLines(bool))}
};
setupCheckBoxes(options, profile);
// signals and slots
connect(_scrollingUi->historySizeWidget, &Konsole::HistorySizeWidget::historySizeChanged, this,
&Konsole::EditProfileDialog::historySizeChanged);
......@@ -1612,6 +1618,11 @@ void EditProfileDialog::scrollHalfPage()
updateTempProfileProperty(Profile::ScrollFullPage, Enum::ScrollPageHalf);
}
void EditProfileDialog::toggleHighlightScrolledLines(bool enable)
{
updateTempProfileProperty(Profile::HighlightScrolledLines, enable);
}
void EditProfileDialog::setupMousePage(const Profile::Ptr &profile)
{
const auto options = QVector<BooleanOption>{
......
......@@ -176,6 +176,7 @@ private Q_SLOTS:
void scrollFullPage();
void scrollHalfPage();
void toggleHighlightScrolledLines(bool enable);
// keyboard page
void editKeyBinding();
......
......@@ -189,6 +189,45 @@
</attribute>
</widget>
</item>
<item row="8" column="1">
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>16</height>
</size>
</property>
</spacer>
</item>
<item row="9" column="0" alignment="Qt::AlignRight|Qt::AlignVCenter">
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Highlighting:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QCheckBox" name="highlightScrolledLinesButton">
<property name="text">
<string>Highlight the lines coming into view</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
......
......@@ -93,6 +93,7 @@ const Profile::PropertyInfo Profile::DefaultPropertyNames[] = {
, { HistorySize , "HistorySize" , SCROLLING_GROUP , QVariant::Int }
, { ScrollBarPosition , "ScrollBarPosition" , SCROLLING_GROUP , QVariant::Int }
, { ScrollFullPage , "ScrollFullPage" , SCROLLING_GROUP , QVariant::Bool }
, { HighlightScrolledLines , "HighlightScrolledLines" , SCROLLING_GROUP , QVariant::Bool }
// Terminal Features
, { UrlHintsModifiers , "UrlHintsModifiers" , TERMINAL_GROUP , QVariant::Int }
......@@ -188,6 +189,7 @@ void Profile::useFallback()
setProperty(HistorySize, 1000);
setProperty(ScrollBarPosition, Enum::ScrollBarRight);
setProperty(ScrollFullPage, false);
setProperty(HighlightScrolledLines, true);
setProperty(FlowControlEnabled, true);
setProperty(UrlHintsModifiers, 0);
......
......@@ -152,6 +152,10 @@ public:
* height or half height.
*/
ScrollFullPage,
/** (bool) Specifies whether the the lines that are scrolled into view
* should be highlighted.
*/
HighlightScrolledLines,
/** (bool) Specifies whether the terminal will enable Bidirectional
* text display
*/
......
......@@ -1264,8 +1264,11 @@ void TerminalDisplay::updateImage()
dirtyRegion |= QRect(0, _contentRect.top() + (_screenWindow->currentResultLine() - _screenWindow->currentLine()) * _fontHeight,
_columns * _fontWidth, _fontHeight);
}
_screenWindow->resetScrollCount();
if (_highlightScrolledLinesControl.enabled) {
dirtyRegion |= highlightScrolledLinesRegion();
}
_screenWindow->resetScrollCount();
// update the parts of the display which have changed
update(dirtyRegion);
......@@ -1333,6 +1336,7 @@ void TerminalDisplay::paintEvent(QPaintEvent* pe)
drawContents(paint, rect);
}
drawCurrentResultRect(paint);
highlightScrolledLines(paint);
drawInputMethodPreeditString(paint, preeditRect());
paintFilters(paint);
......@@ -1767,6 +1771,75 @@ void TerminalDisplay::drawCurrentResultRect(QPainter& painter)
painter.fillRect(_searchResultRect, QColor(0, 0, 255, 80));
}
void TerminalDisplay::highlightScrolledLines(QPainter& painter)
{
if (!_highlightScrolledLinesControl.enabled) {
return;
}
QColor color = QColor(_colorTable[Color4Index]);
color.setAlpha(_highlightScrolledLinesControl.timer->isActive() ? 255 : 150);
painter.fillRect(_highlightScrolledLinesControl.rect, color);
}
QRect TerminalDisplay::highlightScrolledLinesRegion()
{
QRect result;
if (_scrollBar->maximum() == 0) {
// De-highlight when entering something like 'vim'
if (!_highlightScrolledLinesControl.rect.isEmpty()) {
result = _highlightScrolledLinesControl.rect;
_highlightScrolledLinesControl.rect.setRect(0, 0, 0, 0);
}
} else {
const int highlightLeftPosition = _scrollbarLocation == Enum::ScrollBarLeft ? _scrollBar->width() : 0;
if (_highlightScrolledLinesControl.previousScrollCount != 0) {
// De-highlight previously scrolled lines
if (_screenWindow->scrollCount() == 0 && _scrollBar->value() == _scrollBar->maximum()) {
// Nothing has moved, we can reuse _highlightScrolledLinesControl.rect to clear
result = _highlightScrolledLinesControl.rect;
_highlightScrolledLinesControl.rect.setRect(0, 0, 0, 0);
} else {
int start = 0;
const int nb_lines = abs(_highlightScrolledLinesControl.previousScrollCount);
if (_screenWindow->scrollCount() * _highlightScrolledLinesControl.previousScrollCount > 0) {
start = _screenWindow->scrollCount() < 0 ? abs(_screenWindow->scrollCount()) :
_screenWindow->windowLines() - _screenWindow->scrollCount() - _highlightScrolledLinesControl.previousScrollCount;
} else {
start = _highlightScrolledLinesControl.previousScrollCount > 0 ? _screenWindow->windowLines() - _highlightScrolledLinesControl.previousScrollCount : 0;
}
result = QRect(highlightLeftPosition, _contentRect.top() + start * _fontHeight, HIGHLIGHT_SCROLLED_LINES_WIDTH, nb_lines * _fontHeight);
}
}
// Highlight the new lines coming into view
int nb_lines = abs(_screenWindow->scrollCount());
if (nb_lines > 0) {
if (_highlightScrolledLinesControl.timer->isActive() && (_screenWindow->scrollCount() * _highlightScrolledLinesControl.previousScrollCount > 0)) {
nb_lines += abs(_highlightScrolledLinesControl.previousScrollCount);
nb_lines = std::min(nb_lines, _screenWindow->windowLines());
_highlightScrolledLinesControl.previousScrollCount += _screenWindow->scrollCount();
} else {
_highlightScrolledLinesControl.previousScrollCount = _screenWindow->scrollCount();
}
const int start = _screenWindow->scrollCount() > 0 ? std::max(_screenWindow->windowLines() - nb_lines, 0) : 0;
_highlightScrolledLinesControl.rect.setRect(highlightLeftPosition, _contentRect.top() + start * _fontHeight,
HIGHLIGHT_SCROLLED_LINES_WIDTH, nb_lines * _fontHeight);
result |= _highlightScrolledLinesControl.rect;
_highlightScrolledLinesControl.timer->start();
}
}
return result;
}
void TerminalDisplay::highlightScrolledLinesEvent()
{
update(_highlightScrolledLinesControl.rect);
}
QRect TerminalDisplay::imageToWidget(const QRect& imageArea) const
{
QRect result;
......@@ -2002,7 +2075,8 @@ void TerminalDisplay::calcGeometry()
contentsRect().height() - headerHeight // height
);
_contentRect = contentsRect().adjusted(_margin, _margin, -_margin, -_margin);
_contentRect = contentsRect().adjusted(_margin + (_highlightScrolledLinesControl.enabled ? HIGHLIGHT_SCROLLED_LINES_WIDTH : 0), _margin,
-_margin - (_highlightScrolledLinesControl.enabled ? HIGHLIGHT_SCROLLED_LINES_WIDTH : 0), -_margin);
switch (_scrollbarLocation) {
case Enum::ScrollBarHidden :
......@@ -2161,6 +2235,19 @@ bool TerminalDisplay::scrollFullPage() const
return _scrollFullPage;
}
void TerminalDisplay::setHighlightScrolledLines(bool highlight)
{
_highlightScrolledLinesControl.enabled = highlight;
if (_highlightScrolledLinesControl.enabled && _highlightScrolledLinesControl.timer == nullptr) {
// setup timer for diming the highlight on scrolled lines
_highlightScrolledLinesControl.timer = new QTimer(this);
_highlightScrolledLinesControl.timer->setSingleShot(true);
_highlightScrolledLinesControl.timer->setInterval(250);
connect(_highlightScrolledLinesControl.timer, &QTimer::timeout, this, &Konsole::TerminalDisplay::highlightScrolledLinesEvent);
}
}
/* ------------------------------------------------------------------------- */
/* */
/* Mouse */
......@@ -4064,6 +4151,9 @@ void TerminalDisplay::applyProfile(const Profile::Ptr &profile)
setMiddleClickPasteMode(Enum::MiddleClickPasteModeEnum(profile->property<int>(Profile::MiddleClickPasteMode)));
setCopyTextAsHTML(profile->property<bool>(Profile::CopyTextAsHTML));
// highlight lines scrolled into view (must be applied before margin/center)
setHighlightScrolledLines(profile->property<bool>(Profile::HighlightScrolledLines));
// margin/center
setMargin(profile->property<int>(Profile::TerminalMargin));
setCenterContents(profile->property<bool>(Profile::TerminalCenter));
......
......@@ -117,6 +117,8 @@ public:
void setScrollFullPage(bool fullPage);
bool scrollFullPage() const;
void setHighlightScrolledLines(bool highlight);
/**
* Returns the display's filter chain. When the image for the display is updated,
* the text is passed through each filter in the chain. Each filter can define
......@@ -614,6 +616,7 @@ protected Q_SLOTS:
void scrollBarPositionChanged(int value);
void blinkTextEvent();
void blinkCursorEvent();
void highlightScrolledLinesEvent();
private Q_SLOTS:
......@@ -634,6 +637,11 @@ private:
void drawContents(QPainter &painter, const QRect &rect);
// draw a transparent rectangle over the line of the current match
void drawCurrentResultRect(QPainter &painter);
// draw a thin highlight on the left of the screen for lines that have been scrolled into view
void highlightScrolledLines(QPainter& painter);
// compute which region need to be repainted for scrolled lines highlight
QRect highlightScrolledLinesRegion(void);
// draws a section of text, all the text in this section
// has a common color and style
void drawTextFragment(QPainter &painter, const QRect &rect, const QString &text,
......@@ -891,6 +899,14 @@ private:
bool _drawOverlay;
Qt::Edge _overlayEdge;
struct {
bool enabled = false;
QRect rect;
int previousScrollCount = 0;
QTimer *timer = nullptr;
} _highlightScrolledLinesControl;
static const int HIGHLIGHT_SCROLLED_LINES_WIDTH = 3;
bool _hasCompositeFocus;
QSharedPointer<Filter::HotSpot> _currentlyHoveredHotspot;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment