Add some helper wrappers for custom emoji.
This commit is contained in:
parent
29ce965e61
commit
f876d15eed
8 changed files with 152 additions and 35 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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),
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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(
|
||||||
|
|
|
||||||
62
ui/text/text_custom_emoji.cpp
Normal file
62
ui/text/text_custom_emoji.cpp
Normal 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
|
||||||
78
ui/text/text_custom_emoji.h
Normal file
78
ui/text/text_custom_emoji.h
Normal 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
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue