From 1cc74a41c4d1c3fe9824e4bf47c23e3bcd1759e6 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Tue, 16 Aug 2022 18:50:45 +0300 Subject: [PATCH] Moved out spoiler data from Ui::Text::String to separate structure. --- CMakeLists.txt | 1 + ui/text/text.cpp | 77 ++++++++++++++++++++++--------------- ui/text/text.h | 8 +--- ui/text/text_spoiler_data.h | 22 +++++++++++ 4 files changed, 70 insertions(+), 38 deletions(-) create mode 100644 ui/text/text_spoiler_data.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 9dbebcb..5268434 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -154,6 +154,7 @@ PRIVATE ui/text/text_entity.cpp ui/text/text_entity.h ui/text/text_isolated_emoji.h + ui/text/text_spoiler_data.h ui/text/text_utilities.cpp ui/text/text_utilities.h ui/text/text_variant.cpp diff --git a/ui/text/text.cpp b/ui/text/text.cpp index 20fa292..1877de5 100644 --- a/ui/text/text.cpp +++ b/ui/text/text.cpp @@ -9,6 +9,7 @@ #include "ui/basic_click_handlers.h" #include "ui/text/text_block.h" #include "ui/text/text_isolated_emoji.h" +#include "ui/text/text_spoiler_data.h" #include "ui/emoji_config.h" #include "ui/integration.h" #include "ui/round_rect.h" @@ -861,12 +862,17 @@ void Parser::finalize(const TextParseOptions &options) { } } const auto spoilerIndex = block->spoilerIndex(); - if (spoilerIndex && (_t->_spoilers.size() < spoilerIndex)) { - _t->_spoilers.resize(spoilerIndex); - const auto handler = (options.flags & TextParseLinks) - ? std::make_shared() - : nullptr; - _t->setSpoiler(spoilerIndex, std::move(handler)); + if (spoilerIndex) { + if (!_t->_spoiler) { + _t->_spoiler = std::make_shared(); + } + if (_t->_spoiler->links.size() < spoilerIndex) { + _t->_spoiler->links.resize(spoilerIndex); + const auto handler = (options.flags & TextParseLinks) + ? std::make_shared() + : nullptr; + _t->setSpoiler(spoilerIndex, std::move(handler)); + } } const auto shiftedIndex = block->lnkIndex(); auto useCustomIndex = false; @@ -925,14 +931,16 @@ void Parser::finalize(const TextParseOptions &options) { } lastHandlerIndex.lnk = realIndex; } - if (!_t->_hasCustomEmoji || !_t->_spoilers.empty()) { + if (!_t->_hasCustomEmoji || _t->_spoiler) { _t->_isOnlyCustomEmoji = false; } - if (_t->_blocks.empty() || !_t->_spoilers.empty()) { + if (_t->_blocks.empty() || _t->_spoiler) { _t->_isIsolatedEmoji = false; } _t->_links.squeeze(); - _t->_spoilers.squeeze(); + if (_t->_spoiler) { + _t->_spoiler->links.squeeze(); + } _t->_blocks.shrink_to_fit(); _t->_text.squeeze(); } @@ -1961,8 +1969,9 @@ private: } const auto progress = float64(_now - _background.startMs) / st::fadeWrapDuration; - if ((progress > 1.) && _background.spoilerIndex) { - const auto link = _t->_spoilers.at(_background.spoilerIndex - 1); + if ((progress > 1.) && _background.spoilerIndex && _t->_spoiler) { + const auto link = _t->_spoiler->links.at( + _background.spoilerIndex - 1); if (link) { link->setStartMs(0); } @@ -1979,6 +1988,9 @@ private: if (!_background.color) { return; } + if (!_t->_spoiler) { + return; + } const auto elideOffset = (_indexOfElidedBlock == currentBlockIndex) ? (_elideRemoveFromEnd + _f->elidew) : 0; @@ -2011,8 +2023,8 @@ private: const auto hasRight = (parts & RectPart::Right) != 0; const auto &cache = _background.inFront - ? _t->_spoilerCache - : _t->_spoilerShownCache; + ? _t->_spoiler->spoilerCache + : _t->_spoiler->spoilerShownCache; const auto cornerWidth = cache.corners[0].width() / style::DevicePixelRatio(); const auto useWidth = ((x + width).toInt() - x.toInt()) - elideOffset; @@ -2833,9 +2845,9 @@ private: if (_p) { const auto isMono = IsMono(block->flags()); _background = {}; - if (block->spoilerIndex()) { + if (block->spoilerIndex() && _t->_spoiler) { const auto handler - = _t->_spoilers.at(block->spoilerIndex() - 1); + = _t->_spoiler->links.at(block->spoilerIndex() - 1); const auto inBack = (handler && handler->shown()); _background.inFront = !inBack; _background.color = inBack @@ -2844,14 +2856,15 @@ private: _background.startMs = handler ? handler->startMs() : 0; _background.spoilerIndex = block->spoilerIndex(); + Assert(_t->_spoiler != nullptr); const auto &cache = _background.inFront - ? _t->_spoilerCache - : _t->_spoilerShownCache; + ? _t->_spoiler->spoilerCache + : _t->_spoiler->spoilerShownCache; if (cache.color != (*_background.color)->c) { auto mutableText = const_cast(_t); auto &mutableCache = _background.inFront - ? mutableText->_spoilerCache - : mutableText->_spoilerShownCache; + ? mutableText->_spoiler->spoilerCache + : mutableText->_spoiler->spoilerShownCache; mutableCache.corners = Images::PrepareCorners( ImageRoundRadius::Small, *_background.color); @@ -3134,19 +3147,20 @@ void String::setLink(uint16 lnkIndex, const ClickHandlerPtr &lnk) { void String::setSpoiler( uint16 lnkIndex, const std::shared_ptr &lnk) { - if (!lnkIndex || lnkIndex > _spoilers.size()) { + if (!lnkIndex || !_spoiler || lnkIndex > _spoiler->links.size()) { return; } - _spoilers[lnkIndex - 1] = lnk; + _spoiler->links[lnkIndex - 1] = lnk; } void String::setSpoilerShown(uint16 lnkIndex, bool shown) { if (!lnkIndex - || (lnkIndex > _spoilers.size()) - || !_spoilers[lnkIndex - 1]) { + || !_spoiler + || (lnkIndex > _spoiler->links.size()) + || !_spoiler->links[lnkIndex - 1]) { return; } - _spoilers[lnkIndex - 1]->setShown(shown); + _spoiler->links[lnkIndex - 1]->setShown(shown); } bool String::hasLinks() const { @@ -3154,7 +3168,7 @@ bool String::hasLinks() const { } int String::spoilersCount() const { - return _spoilers.size(); + return !_spoiler ? 0 : int(_spoiler->links.size()); } bool String::hasSkipBlock() const { @@ -3528,9 +3542,9 @@ void String::enumerateText( if (rangeTo > rangeFrom) { // handle click handler const auto r = base::StringViewMid(_text, rangeFrom, rangeTo - rangeFrom); // Ignore links that are partially copied. - const auto handler = (spoilerFrom != rangeFrom || blockFrom != rangeTo) + const auto handler = (spoilerFrom != rangeFrom || blockFrom != rangeTo || !_spoiler) ? nullptr - : _spoilers.at(spoilerIndex - 1); + : _spoiler->links.at(spoilerIndex - 1); const auto type = EntityType::Spoiler; clickHandlerFinishCallback(r, handler, type); } @@ -3784,8 +3798,7 @@ IsolatedEmoji String::toIsolatedEmoji() const { auto result = IsolatedEmoji(); const auto skip = (_blocks.empty() || _blocks.back()->type() != TextBlockTSkip) ? 0 : 1; - if ((_blocks.size() > kIsolatedEmojiLimit + skip) - || !_spoilers.empty()) { + if ((_blocks.size() > kIsolatedEmojiLimit + skip) || _spoiler) { return {}; } auto index = 0; @@ -3813,14 +3826,14 @@ void String::clear() { void String::clearFields() { _blocks.clear(); _links.clear(); - _spoilers.clear(); + _spoiler = nullptr; _maxWidth = _minHeight = 0; _startDir = Qt::LayoutDirectionAuto; } ClickHandlerPtr String::spoilerLink(uint16 spoilerIndex) const { - if (spoilerIndex) { - const auto &handler = _spoilers.at(spoilerIndex - 1); + if (spoilerIndex && _spoiler) { + const auto &handler = _spoiler->links.at(spoilerIndex - 1); return (handler && !handler->shown()) ? handler : nullptr; } return nullptr; diff --git a/ui/text/text.h b/ui/text/text.h index 6f810ad..2b3e86d 100644 --- a/ui/text/text.h +++ b/ui/text/text.h @@ -64,6 +64,7 @@ namespace Ui::Text { struct IsolatedEmoji; struct OnlyCustomEmoji; +struct SpoilerData; struct StateRequest { enum class Flag { @@ -226,14 +227,9 @@ private: TextBlocks _blocks; TextLinks _links; - QVector> _spoilers; - Qt::LayoutDirection _startDir = Qt::LayoutDirectionAuto; - struct { - std::array corners; - QColor color; - } _spoilerCache, _spoilerShownCache; + std::shared_ptr _spoiler; friend class Parser; friend class Renderer; diff --git a/ui/text/text_spoiler_data.h b/ui/text/text_spoiler_data.h new file mode 100644 index 0000000..fd68360 --- /dev/null +++ b/ui/text/text_spoiler_data.h @@ -0,0 +1,22 @@ +// This file is part of Desktop App Toolkit, +// a set of libraries for developing nice desktop applications. +// +// For license and copyright information please follow this link: +// https://github.com/desktop-app/legal/blob/master/LEGAL +// +#pragma once + +class SpoilerClickHandler; + +namespace Ui::Text { + +struct SpoilerData { + struct { + std::array corners; + QColor color; + } spoilerCache, spoilerShownCache; + + QVector> links; +}; + +} // namespace Ui::Text