Add some helper wrappers for custom emoji.

This commit is contained in:
John Preston 2022-08-26 23:51:49 +04:00
parent 29ce965e61
commit f876d15eed
8 changed files with 152 additions and 35 deletions

View file

@ -153,6 +153,8 @@ PRIVATE
ui/text/text.h ui/text/text.h
ui/text/text_block.cpp ui/text/text_block.cpp
ui/text/text_block.h ui/text/text_block.h
ui/text/text_custom_emoji.cpp
ui/text/text_custom_emoji.h
ui/text/text_entity.cpp ui/text/text_entity.cpp
ui/text/text_entity.h ui/text/text_entity.h
ui/text/text_isolated_emoji.h ui/text/text_isolated_emoji.h

View file

@ -103,6 +103,7 @@ ImageSubrect RoundAreaWithShadow::validateOverlayMask(
p.setCompositionMode(QPainter::CompositionMode_Source); p.setCompositionMode(QPainter::CompositionMode_Source);
p.fillRect(QRect(position, maskSize), Qt::transparent); p.fillRect(QRect(position, maskSize), Qt::transparent);
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
auto hq = PainterHighQualityEnabler(p); auto hq = PainterHighQualityEnabler(p);
const auto inner = QRect(position + _inner.topLeft(), innerSize); const auto inner = QRect(position + _inner.topLeft(), innerSize);
p.setPen(Qt::NoPen); p.setPen(Qt::NoPen);
@ -198,10 +199,13 @@ void RoundAreaWithShadow::overlayExpandedBorder(
QPainter &p, QPainter &p,
QSize size, QSize size,
float64 expandRatio, float64 expandRatio,
float64 radius, float64 radiusFrom,
float64 radiusTill,
float64 scale) { float64 scale) {
const auto progress = expandRatio; const auto progress = expandRatio;
const auto frame = int(base::SafeRound(progress * (kFramesCount - 1))); const auto frame = int(base::SafeRound(progress * (kFramesCount - 1)));
const auto cacheRatio = frame / float64(kFramesCount - 1);
const auto radius = radiusFrom + (radiusTill - radiusFrom) * cacheRatio;
const auto twiceRadius = int(base::SafeRound(radius * 2)); const auto twiceRadius = int(base::SafeRound(radius * 2));
const auto innerSize = QSize( const auto innerSize = QSize(
std::max(_inner.width(), twiceRadius), std::max(_inner.width(), twiceRadius),

View file

@ -59,7 +59,8 @@ public:
QPainter &p, QPainter &p,
QSize size, QSize size,
float64 expandRatio, float64 expandRatio,
float64 radius, float64 radiusFrom,
float64 radiusTill,
float64 scale); float64 scale);
private: private:

View file

@ -498,10 +498,6 @@ CustomEmojiBlock::CustomEmojiBlock(
} }
} }
int AdjustCustomEmojiSize(int emojiSize) {
return base::SafeRound(emojiSize * 1.12);
}
NewlineBlock::NewlineBlock( NewlineBlock::NewlineBlock(
const style::font &font, const style::font &font,
const QString &str, const QString &str,

View file

@ -6,6 +6,7 @@
// //
#pragma once #pragma once
#include "ui/text/text_custom_emoji.h"
#include "ui/style/style_core.h" #include "ui/style/style_core.h"
#include "ui/emoji_config.h" #include "ui/emoji_config.h"
@ -166,29 +167,6 @@ private:
}; };
struct CustomEmojiPaintContext {
QColor preview;
QSize size; // Required only when scaled = true, for path scaling.
crl::time now = 0;
float64 scale = 0.;
QPoint position;
bool paused = false;
bool scaled = false;
};
class CustomEmoji {
public:
virtual ~CustomEmoji() = default;
[[nodiscard]] virtual QString entityData() = 0;
using Context = CustomEmojiPaintContext;
virtual void paint(QPainter &p, const Context &context) = 0;
virtual void unload() = 0;
[[nodiscard]] virtual bool ready() = 0;
};
class CustomEmojiBlock final : public AbstractBlock { class CustomEmojiBlock final : public AbstractBlock {
public: public:
CustomEmojiBlock( CustomEmojiBlock(
@ -210,8 +188,6 @@ private:
}; };
[[nodiscard]] int AdjustCustomEmojiSize(int emojiSize);
class SkipBlock final : public AbstractBlock { class SkipBlock final : public AbstractBlock {
public: public:
SkipBlock( SkipBlock(

View file

@ -0,0 +1,62 @@
// 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
//
#include "ui/text/text_custom_emoji.h"
namespace Ui::Text {
int AdjustCustomEmojiSize(int emojiSize) {
return base::SafeRound(emojiSize * 1.12);
}
ShiftedEmoji::ShiftedEmoji(
std::unique_ptr<Ui::Text::CustomEmoji> wrapped,
QPoint shift)
: _wrapped(std::move(wrapped))
, _shift(shift) {
}
QString ShiftedEmoji::entityData() {
return _wrapped->entityData();
}
void ShiftedEmoji::paint(QPainter &p, const Context &context) {
auto copy = context;
copy.position += _shift;
_wrapped->paint(p, copy);
}
void ShiftedEmoji::unload() {
_wrapped->unload();
}
bool ShiftedEmoji::ready() {
return _wrapped->ready();
}
FirstFrameEmoji::FirstFrameEmoji(std::unique_ptr<CustomEmoji> wrapped)
: _wrapped(std::move(wrapped)) {
}
QString FirstFrameEmoji::entityData() {
return _wrapped->entityData();
}
void FirstFrameEmoji::paint(QPainter &p, const Context &context) {
auto copy = context;
copy.firstFrameOnly = true;
_wrapped->paint(p, copy);
}
void FirstFrameEmoji::unload() {
_wrapped->unload();
}
bool FirstFrameEmoji::ready() {
return _wrapped->ready();
}
} // namespace Ui::Text

View file

@ -0,0 +1,78 @@
// 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
#include <QtGui/QColor>
#include <QtCore/QSize>
#include <QtCore/QPoint>
#include <crl/crl_time.h>
class QPainter;
namespace Ui::Text {
[[nodiscard]] int AdjustCustomEmojiSize(int emojiSize);
struct CustomEmojiPaintContext {
QColor preview;
QSize size; // Required only when scaled = true, for path scaling.
crl::time now = 0;
float64 scale = 0.;
QPoint position;
bool firstFrameOnly = false;
bool paused = false;
bool scaled = false;
};
class CustomEmoji {
public:
virtual ~CustomEmoji() = default;
[[nodiscard]] virtual QString entityData() = 0;
using Context = CustomEmojiPaintContext;
virtual void paint(QPainter &p, const Context &context) = 0;
virtual void unload() = 0;
[[nodiscard]] virtual bool ready() = 0;
};
using CustomEmojiFactory = Fn<std::unique_ptr<CustomEmoji>(
QStringView,
Fn<void()>)>;
class ShiftedEmoji final : public CustomEmoji {
public:
ShiftedEmoji(std::unique_ptr<CustomEmoji> wrapped, QPoint shift);
QString entityData() override;
void paint(QPainter &p, const Context &context) override;
void unload() override;
bool ready() override;
private:
const std::unique_ptr<Ui::Text::CustomEmoji> _wrapped;
const QPoint _shift;
};
class FirstFrameEmoji final : public CustomEmoji {
public:
explicit FirstFrameEmoji(std::unique_ptr<CustomEmoji> wrapped);
QString entityData() override;
void paint(QPainter &p, const Context &context) override;
void unload() override;
bool ready() override;
private:
const std::unique_ptr<Ui::Text::CustomEmoji> _wrapped;
};
} // namespace Ui::Text

View file

@ -10,6 +10,7 @@
#include "ui/rp_widget.h" #include "ui/rp_widget.h"
#include "ui/effects/animations.h" #include "ui/effects/animations.h"
#include "ui/text/text_entity.h" #include "ui/text/text_entity.h"
#include "ui/text/text_custom_emoji.h"
#include "styles/style_widgets.h" #include "styles/style_widgets.h"
#include <QContextMenuEvent> #include <QContextMenuEvent>
@ -35,10 +36,6 @@ const auto kMonospaceSequence = QKeySequence("ctrl+shift+m");
const auto kEditLinkSequence = QKeySequence("ctrl+k"); const auto kEditLinkSequence = QKeySequence("ctrl+k");
const auto kSpoilerSequence = QKeySequence("ctrl+shift+p"); const auto kSpoilerSequence = QKeySequence("ctrl+shift+p");
using CustomEmojiFactory = Fn<std::unique_ptr<Text::CustomEmoji>(
QStringView,
Fn<void()>)>;
class PopupMenu; class PopupMenu;
void InsertEmojiAtCursor(QTextCursor cursor, EmojiPtr emoji); void InsertEmojiAtCursor(QTextCursor cursor, EmojiPtr emoji);
@ -199,6 +196,7 @@ public:
MultiLine, MultiLine,
}; };
using TagList = TextWithTags::Tags; using TagList = TextWithTags::Tags;
using CustomEmojiFactory = Text::CustomEmojiFactory;
struct MarkdownTag { struct MarkdownTag {
// With each emoji being QChar::ObjectReplacementCharacter. // With each emoji being QChar::ObjectReplacementCharacter.