Improved style of selected text with spoilers.
This commit is contained in:
parent
6c9d832ad8
commit
af2cfca307
2 changed files with 51 additions and 9 deletions
|
|
@ -17,6 +17,7 @@ TextPalette {
|
||||||
linkAlwaysActive: int;
|
linkAlwaysActive: int;
|
||||||
spoilerBg: color;
|
spoilerBg: color;
|
||||||
spoilerActiveBg: color;
|
spoilerActiveBg: color;
|
||||||
|
spoilerActiveFg: color;
|
||||||
}
|
}
|
||||||
|
|
||||||
TextStyle {
|
TextStyle {
|
||||||
|
|
@ -48,6 +49,7 @@ defaultTextPalette: TextPalette {
|
||||||
selectOverlay: msgSelectOverlay;
|
selectOverlay: msgSelectOverlay;
|
||||||
spoilerBg: msgInDateFg;
|
spoilerBg: msgInDateFg;
|
||||||
spoilerActiveBg: msgInDateFg;
|
spoilerActiveBg: msgInDateFg;
|
||||||
|
spoilerActiveFg: msgInBg;
|
||||||
}
|
}
|
||||||
defaultTextStyle: TextStyle {
|
defaultTextStyle: TextStyle {
|
||||||
font: normalFont;
|
font: normalFont;
|
||||||
|
|
@ -145,6 +147,7 @@ inTextPalette: TextPalette(defaultTextPalette) {
|
||||||
selectOverlay: msgSelectOverlay;
|
selectOverlay: msgSelectOverlay;
|
||||||
spoilerBg: msgInDateFg;
|
spoilerBg: msgInDateFg;
|
||||||
spoilerActiveBg: msgInDateFg;
|
spoilerActiveBg: msgInDateFg;
|
||||||
|
spoilerActiveFg: msgInBg;
|
||||||
}
|
}
|
||||||
inTextPaletteSelected: TextPalette(inTextPalette) {
|
inTextPaletteSelected: TextPalette(inTextPalette) {
|
||||||
linkFg: historyLinkInFgSelected;
|
linkFg: historyLinkInFgSelected;
|
||||||
|
|
@ -160,6 +163,7 @@ outTextPalette: TextPalette(defaultTextPalette) {
|
||||||
selectOverlay: msgSelectOverlay;
|
selectOverlay: msgSelectOverlay;
|
||||||
spoilerBg: msgOutDateFg;
|
spoilerBg: msgOutDateFg;
|
||||||
spoilerActiveBg: msgOutDateFg;
|
spoilerActiveBg: msgOutDateFg;
|
||||||
|
spoilerActiveFg: msgOutBg;
|
||||||
}
|
}
|
||||||
outTextPaletteSelected: TextPalette(outTextPalette) {
|
outTextPaletteSelected: TextPalette(outTextPalette) {
|
||||||
linkFg: historyLinkOutFgSelected;
|
linkFg: historyLinkOutFgSelected;
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ namespace {
|
||||||
|
|
||||||
constexpr auto kStringLinkIndexShift = uint16(0x8000);
|
constexpr auto kStringLinkIndexShift = uint16(0x8000);
|
||||||
constexpr auto kMaxDiacAfterSymbol = 2;
|
constexpr auto kMaxDiacAfterSymbol = 2;
|
||||||
|
constexpr auto kSelectedSpoilerOpacity = 0.5;
|
||||||
|
|
||||||
Qt::LayoutDirection StringDirection(
|
Qt::LayoutDirection StringDirection(
|
||||||
const QString &str,
|
const QString &str,
|
||||||
|
|
@ -1762,20 +1763,28 @@ private:
|
||||||
if (rtl) {
|
if (rtl) {
|
||||||
glyphX += spacesWidth;
|
glyphX += spacesWidth;
|
||||||
}
|
}
|
||||||
|
struct {
|
||||||
|
QFixed from;
|
||||||
|
QFixed to;
|
||||||
|
} fillSelect;
|
||||||
|
struct {
|
||||||
|
QFixed from;
|
||||||
|
QFixed width;
|
||||||
|
} fillSpoiler;
|
||||||
if (_localFrom + si.position < _selection.to) {
|
if (_localFrom + si.position < _selection.to) {
|
||||||
auto chFrom = _str + currentBlock->from();
|
auto chFrom = _str + currentBlock->from();
|
||||||
auto chTo = chFrom + ((nextBlock ? nextBlock->from() : _t->_text.size()) - currentBlock->from());
|
auto chTo = chFrom + ((nextBlock ? nextBlock->from() : _t->_text.size()) - currentBlock->from());
|
||||||
if (_localFrom + si.position >= _selection.from) { // could be without space
|
if (_localFrom + si.position >= _selection.from) { // could be without space
|
||||||
if (chTo == chFrom || (chTo - 1)->unicode() != QChar::Space || _selection.to >= (chTo - _str)) {
|
if (chTo == chFrom || (chTo - 1)->unicode() != QChar::Space || _selection.to >= (chTo - _str)) {
|
||||||
fillSelectRange(x, x + si.width);
|
fillSelect = { x, x + si.width };
|
||||||
} else { // or with space
|
} else { // or with space
|
||||||
fillSelectRange(glyphX, glyphX + currentBlock->f_width());
|
fillSelect = { glyphX, glyphX + currentBlock->f_width() };
|
||||||
}
|
}
|
||||||
} else if (chTo > chFrom && (chTo - 1)->unicode() == QChar::Space && (chTo - 1 - _str) >= _selection.from) {
|
} else if (chTo > chFrom && (chTo - 1)->unicode() == QChar::Space && (chTo - 1 - _str) >= _selection.from) {
|
||||||
if (rtl) { // rtl space only
|
if (rtl) { // rtl space only
|
||||||
fillSelectRange(x, glyphX);
|
fillSelect = { x, glyphX };
|
||||||
} else { // ltr space only
|
} else { // ltr space only
|
||||||
fillSelectRange(x + currentBlock->f_width(), x + si.width);
|
fillSelect = { x + currentBlock->f_width(), x + si.width };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1787,19 +1796,32 @@ private:
|
||||||
auto chTo = chFrom + ((nextBlock ? nextBlock->from() : _t->_text.size()) - currentBlock->from());
|
auto chTo = chFrom + ((nextBlock ? nextBlock->from() : _t->_text.size()) - currentBlock->from());
|
||||||
if (_localFrom + si.position >= from) { // could be without space
|
if (_localFrom + si.position >= from) { // could be without space
|
||||||
if (chTo == chFrom || (chTo - 1)->unicode() != QChar::Space || to >= (chTo - _str)) {
|
if (chTo == chFrom || (chTo - 1)->unicode() != QChar::Space || to >= (chTo - _str)) {
|
||||||
fillSpoilerRange(x, si.width, blockIndex);
|
fillSpoiler = { x, si.width };
|
||||||
} else { // or with space
|
} else { // or with space
|
||||||
fillSpoilerRange(glyphX, currentBlock->f_width(), blockIndex);
|
fillSpoiler = { glyphX, currentBlock->f_width() };
|
||||||
}
|
}
|
||||||
} else if (chTo > chFrom && (chTo - 1)->unicode() == QChar::Space && (chTo - 1 - _str) >= from) {
|
} else if (chTo > chFrom && (chTo - 1)->unicode() == QChar::Space && (chTo - 1 - _str) >= from) {
|
||||||
if (rtl) { // rtl space only
|
if (rtl) { // rtl space only
|
||||||
fillSpoilerRange(x, glyphX - x, blockIndex);
|
fillSpoiler = { x, glyphX - x };
|
||||||
} else { // ltr space only
|
} else { // ltr space only
|
||||||
fillSpoilerRange(x + currentBlock->f_width(), si.width, blockIndex);
|
fillSpoiler = { x + currentBlock->f_width(), si.width };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const auto hasSpoiler = fillSpoiler.width != QFixed();
|
||||||
|
const auto hasSelect = fillSelect.to != QFixed();
|
||||||
|
if (hasSpoiler && !_background.inFront) {
|
||||||
|
fillSpoilerRange(fillSpoiler.from, fillSpoiler.width, blockIndex);
|
||||||
|
}
|
||||||
|
if (hasSelect) {
|
||||||
|
const auto opacity = _p->opacity();
|
||||||
|
if (hasSpoiler && !_background.inFront) {
|
||||||
|
_p->setOpacity(kSelectedSpoilerOpacity);
|
||||||
|
}
|
||||||
|
fillSelectRange(fillSelect.from, fillSelect.to);
|
||||||
|
_p->setOpacity(opacity);
|
||||||
|
}
|
||||||
if (!_background.inFront) {
|
if (!_background.inFront) {
|
||||||
Emoji::Draw(
|
Emoji::Draw(
|
||||||
*_p,
|
*_p,
|
||||||
|
|
@ -1808,6 +1830,9 @@ private:
|
||||||
(glyphX + st::emojiPadding).toInt(),
|
(glyphX + st::emojiPadding).toInt(),
|
||||||
_y + _yDelta + emojiY);
|
_y + _yDelta + emojiY);
|
||||||
}
|
}
|
||||||
|
if (hasSpoiler && _background.inFront) {
|
||||||
|
fillSpoilerRange(fillSpoiler.from, fillSpoiler.width, blockIndex);
|
||||||
|
}
|
||||||
// } else if (_p && currentBlock->type() == TextBlockSkip) { // debug
|
// } else if (_p && currentBlock->type() == TextBlockSkip) { // debug
|
||||||
// _p->fillRect(QRect(x.toInt(), _y, currentBlock->width(), static_cast<SkipBlock*>(currentBlock)->height()), QColor(0, 0, 0, 32));
|
// _p->fillRect(QRect(x.toInt(), _y, currentBlock->width(), static_cast<SkipBlock*>(currentBlock)->height()), QColor(0, 0, 0, 32));
|
||||||
}
|
}
|
||||||
|
|
@ -1896,7 +1921,9 @@ private:
|
||||||
gf.justified = false;
|
gf.justified = false;
|
||||||
gf.initWithScriptItem(si);
|
gf.initWithScriptItem(si);
|
||||||
|
|
||||||
if (!_background.inFront) {
|
const auto hasBackground = !_background.inFront
|
||||||
|
&& _background.color;
|
||||||
|
if (hasBackground) {
|
||||||
fillSpoilerRange(x, si.width, blockIndex);
|
fillSpoilerRange(x, si.width, blockIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1904,6 +1931,11 @@ private:
|
||||||
auto hasNotSelected = true;
|
auto hasNotSelected = true;
|
||||||
auto selectedRect = QRect();
|
auto selectedRect = QRect();
|
||||||
if (_localFrom + itemStart < _selection.to && _localFrom + itemEnd > _selection.from) {
|
if (_localFrom + itemStart < _selection.to && _localFrom + itemEnd > _selection.from) {
|
||||||
|
const auto opacity = _p->opacity();
|
||||||
|
if (hasBackground) {
|
||||||
|
_p->setOpacity(kSelectedSpoilerOpacity);
|
||||||
|
}
|
||||||
|
|
||||||
hasSelected = true;
|
hasSelected = true;
|
||||||
auto selX = x;
|
auto selX = x;
|
||||||
auto selWidth = itemWidth;
|
auto selWidth = itemWidth;
|
||||||
|
|
@ -1946,6 +1978,7 @@ private:
|
||||||
if (rtl) selX = x + itemWidth - (selX - x) - selWidth;
|
if (rtl) selX = x + itemWidth - (selX - x) - selWidth;
|
||||||
selectedRect = QRect(selX.toInt(), _y + _yDelta, (selX + selWidth).toInt() - selX.toInt(), _fontHeight);
|
selectedRect = QRect(selX.toInt(), _y + _yDelta, (selX + selWidth).toInt() - selX.toInt(), _fontHeight);
|
||||||
fillSelectRange(selX, selX + selWidth);
|
fillSelectRange(selX, selX + selWidth);
|
||||||
|
_p->setOpacity(opacity);
|
||||||
}
|
}
|
||||||
if (Q_UNLIKELY(hasSelected)) {
|
if (Q_UNLIKELY(hasSelected)) {
|
||||||
if (Q_UNLIKELY(hasNotSelected)) {
|
if (Q_UNLIKELY(hasNotSelected)) {
|
||||||
|
|
@ -2843,6 +2876,11 @@ private:
|
||||||
*_background.color);
|
*_background.color);
|
||||||
mutableCache.color = (*_background.color)->c;
|
mutableCache.color = (*_background.color)->c;
|
||||||
}
|
}
|
||||||
|
if (inBack) {
|
||||||
|
_currentPen = &_textPalette->spoilerActiveFg->p;
|
||||||
|
_currentPenSelected = &_textPalette->spoilerActiveFg->p;
|
||||||
|
return;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
_background = {};
|
_background = {};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue