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