Move some more widgets and effects.

This commit is contained in:
John Preston 2019-09-17 10:51:02 +03:00
parent 673072ea5b
commit 3b0bf7cb1e
36 changed files with 336 additions and 260 deletions

View file

@ -7,8 +7,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "base/unixtime.h"
#include "logs.h"
#include <QDateTime>
#include <QReadWriteLock>
@ -125,19 +123,15 @@ TimeId now() {
void update(TimeId now, bool force) {
if (force) {
DEBUG_LOG(("MTP Info: forcing client unixtime to %1"
).arg(now));
ValueUpdated = true;
} else {
auto expected = false;
if (!ValueUpdated.compare_exchange_strong(expected, true)) {
return;
}
DEBUG_LOG(("MTP Info: setting client unixtime to %1").arg(now));
}
const auto shift = now + 1 - local();
ValueShift = shift;
DEBUG_LOG(("MTP Info: now unixtimeDelta is %1").arg(shift));
HttpValueShift = 0;
HttpValueValid = false;

View file

@ -10,11 +10,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "platform/platform_launcher.h"
#include "platform/platform_specific.h"
#include "platform/platform_info.h"
#include "ui/main_queue_processor.h"
#include "core/crash_reports.h"
#include "core/main_queue_processor.h"
#include "core/update_checker.h"
#include "core/sandbox.h"
#include "base/concurrent_timer.h"
#include "facades.h"
namespace Core {
namespace {
@ -453,7 +454,7 @@ void Launcher::processArguments() {
int Launcher::executeApplication() {
FilteredCommandLineArguments arguments(_argc, _argv);
Sandbox sandbox(this, arguments.count(), arguments.values());
MainQueueProcessor processor;
Ui::MainQueueProcessor processor;
base::ConcurrentTimerEnvironment environment;
return sandbox.start();
}

View file

@ -83,6 +83,11 @@ Sandbox::Sandbox(
char **argv)
: QApplication(argc, argv)
, _mainThreadId(QThread::currentThreadId())
, _handleObservables([=] {
Expects(_application != nullptr);
_application->call_handleObservables();
})
, _launcher(launcher) {
}
@ -152,6 +157,10 @@ void Sandbox::launchApplication() {
}
setupScreenScale();
base::InitObservables([] {
Instance()._handleObservables.call();
});
_application = std::make_unique<Application>(_launcher);
// Ideally this should go to constructor.

View file

@ -105,6 +105,7 @@ private:
int _loopNestingLevel = 0;
std::vector<int> _previousLoopNestingLevels;
std::vector<PostponedCall> _postponedCalls;
SingleQueuedInvokation _handleObservables;
not_null<Launcher*> _launcher;
std::unique_ptr<Application> _application;

View file

@ -294,7 +294,6 @@ namespace internal {
struct Data {
SingleQueuedInvokation HandleUnreadCounterUpdate = { [] { Core::App().call_handleUnreadCounterUpdate(); } };
SingleQueuedInvokation HandleDelayedPeerUpdates = { [] { Core::App().call_handleDelayedPeerUpdates(); } };
SingleQueuedInvokation HandleObservables = { [] { Core::App().call_handleObservables(); } };
Adaptive::WindowLayout AdaptiveWindowLayout = Adaptive::WindowLayout::Normal;
Adaptive::ChatLayout AdaptiveChatLayout = Adaptive::ChatLayout::Normal;
@ -425,7 +424,6 @@ void finish() {
DefineRefVar(Global, SingleQueuedInvokation, HandleUnreadCounterUpdate);
DefineRefVar(Global, SingleQueuedInvokation, HandleDelayedPeerUpdates);
DefineRefVar(Global, SingleQueuedInvokation, HandleObservables);
DefineVar(Global, Adaptive::WindowLayout, AdaptiveWindowLayout);
DefineVar(Global, Adaptive::ChatLayout, AdaptiveChatLayout);

View file

@ -168,7 +168,6 @@ void finish();
DeclareRefVar(SingleQueuedInvokation, HandleUnreadCounterUpdate);
DeclareRefVar(SingleQueuedInvokation, HandleDelayedPeerUpdates);
DeclareRefVar(SingleQueuedInvokation, HandleObservables);
DeclareVar(Adaptive::WindowLayout, AdaptiveWindowLayout);
DeclareVar(Adaptive::ChatLayout, AdaptiveChatLayout);

View file

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <rpl/never.h>
#include <rpl/merge.h>
#include "lang/lang_keys.h"
#include "lang/lang_numbers_animation.h"
#include "info/info_wrap_widget.h"
#include "info/info_controller.h"
#include "info/profile/info_profile_values.h"

View file

@ -8,8 +8,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "intro/introwidget.h"
#include "lang/lang_keys.h"
#include "storage/localstorage.h"
#include "lang/lang_file_parser.h"
#include "storage/localstorage.h"
#include "intro/introstart.h"
#include "intro/introphone.h"
#include "intro/introcode.h"

View file

@ -8,6 +8,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_cloud_manager.h"
#include "lang/lang_instance.h"
#include "lang/lang_file_parser.h"
#include "lang/lang_text_entity.h"
#include "mtproto/mtp_instance.h"
#include "storage/localstorage.h"
#include "core/application.h"
@ -17,7 +19,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/wrap/padding_wrap.h"
#include "ui/widgets/labels.h"
#include "ui/text/text_utilities.h"
#include "lang/lang_file_parser.h"
#include "core/file_utilities.h"
#include "core/click_handler_types.h"
#include "app.h"

View file

@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_instance.h"
#include "lang/lang_hardcoded.h"
#include "lang/lang_text_entity.h"
QString langDayOfMonth(const QDate &date);
QString langDayOfMonthFull(const QDate &date);

View file

@ -0,0 +1,30 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "lang/lang_numbers_animation.h"
#include "lang/lang_tag.h"
namespace Lang {
Ui::StringWithNumbers ReplaceTag<Ui::StringWithNumbers>::Call(
Ui::StringWithNumbers &&original,
ushort tag,
const Ui::StringWithNumbers &replacement) {
original.offset = FindTagReplacementPosition(original.text, tag);
if (original.offset < 0) {
return std::move(original);
}
original.text = ReplaceTag<QString>::Call(
std::move(original.text),
tag,
replacement.text);
original.length = replacement.text.size();
return std::move(original);
}
} // namespace Lang

View file

@ -0,0 +1,35 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "ui/effects/numbers_animation.h"
namespace Lang {
template <typename ResultString>
struct StartReplacements;
template <>
struct StartReplacements<Ui::StringWithNumbers> {
static inline Ui::StringWithNumbers Call(QString &&langString) {
return { std::move(langString) };
}
};
template <typename ResultString>
struct ReplaceTag;
template <>
struct ReplaceTag<Ui::StringWithNumbers> {
static Ui::StringWithNumbers Call(
Ui::StringWithNumbers &&original,
ushort tag,
const Ui::StringWithNumbers &replacement);
};
} // namespace Lang

View file

@ -0,0 +1,72 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "lang/lang_text_entity.h"
#include "lang/lang_tag.h"
namespace Lang {
TextWithEntities ReplaceTag<TextWithEntities>::Call(TextWithEntities &&original, ushort tag, const TextWithEntities &replacement) {
auto replacementPosition = FindTagReplacementPosition(original.text, tag);
if (replacementPosition < 0) {
return std::move(original);
}
auto result = TextWithEntities();
result.text = ReplaceTag<QString>::Replace(std::move(original.text), replacement.text, replacementPosition);
auto originalEntitiesCount = original.entities.size();
auto replacementEntitiesCount = replacement.entities.size();
if (originalEntitiesCount != 0 || replacementEntitiesCount != 0) {
result.entities.reserve(originalEntitiesCount + replacementEntitiesCount);
auto replacementEnd = replacementPosition + replacement.text.size();
auto replacementEntity = replacement.entities.cbegin();
auto addReplacementEntitiesUntil = [&replacementEntity, &replacement, &result, replacementPosition, replacementEnd](int untilPosition) {
while (replacementEntity != replacement.entities.cend()) {
auto newOffset = replacementPosition + replacementEntity->offset();
if (newOffset >= untilPosition) {
return;
}
auto newEnd = newOffset + replacementEntity->length();
newOffset = std::clamp(newOffset, replacementPosition, replacementEnd);
newEnd = std::clamp(newEnd, replacementPosition, replacementEnd);
if (auto newLength = newEnd - newOffset) {
result.entities.push_back({ replacementEntity->type(), newOffset, newLength, replacementEntity->data() });
}
++replacementEntity;
}
};
for (const auto &entity : std::as_const(original.entities)) {
// Transform the entity by the replacement.
auto offset = entity.offset();
auto end = offset + entity.length();
if (offset > replacementPosition) {
offset = offset + replacement.text.size() - kTagReplacementSize;
}
if (end > replacementPosition) {
end = end + replacement.text.size() - kTagReplacementSize;
}
offset = std::clamp(offset, 0, result.text.size());
end = std::clamp(end, 0, result.text.size());
// Add all replacement entities that start before the current original entity.
addReplacementEntitiesUntil(offset);
// Add a modified original entity.
if (auto length = end - offset) {
result.entities.push_back({ entity.type(), offset, length, entity.data() });
}
}
// Add the remaining replacement entities.
addReplacementEntitiesUntil(result.text.size());
}
return result;
}
} // namespace Lang

View file

@ -0,0 +1,33 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "ui/text/text_entity.h"
namespace Lang {
template <typename ResultString>
struct StartReplacements;
template <>
struct StartReplacements<TextWithEntities> {
static inline TextWithEntities Call(QString &&langString) {
return { std::move(langString), EntitiesInText() };
}
};
template <typename ResultString>
struct ReplaceTag;
template <>
struct ReplaceTag<TextWithEntities> {
static TextWithEntities Call(TextWithEntities &&original, ushort tag, const TextWithEntities &replacement);
};
} // namespace Lang

View file

@ -29,10 +29,6 @@ inline std::optional<crl::time> LastUserInputTime() {
inline void IgnoreApplicationActivationRightNow() {
}
inline constexpr bool UseMainQueueGeneric() {
return true;
}
} // namespace Platform
inline QString psServerPrefix() {

View file

@ -20,10 +20,6 @@ QString CurrentExecutablePath(int argc, char *argv[]);
void RemoveQuarantine(const QString &path);
inline constexpr bool UseMainQueueGeneric() {
return false;
}
namespace ThirdParty {
inline void start() {

View file

@ -34,10 +34,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <mach-o/dyld.h>
#include <AVFoundation/AVFoundation.h>
extern "C" {
void _dispatch_main_queue_callback_4CF(mach_msg_header_t *msg);
} // extern "C"
namespace {
QStringList _initLogs;
@ -132,10 +128,6 @@ void RemoveQuarantine(const QString &path) {
removexattr(local.data(), kQuarantineAttribute, 0);
}
void DrainMainQueue() {
_dispatch_main_queue_callback_4CF(nullptr);
}
void RegisterCustomScheme() {
#ifndef TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
OSStatus result = LSSetDefaultHandlerForURLScheme(CFSTR("tg"), (CFStringRef)[[NSBundle mainBundle] bundleIdentifier]);
@ -261,7 +253,7 @@ std::optional<crl::time> LastUserInputTime() {
void IgnoreApplicationActivationRightNow() {
objc_ignoreApplicationActivationRightNow();
}
} // namespace Platform
void psNewVersion() {

View file

@ -40,9 +40,6 @@ bool OpenSystemSettings(SystemSettingsType type);
}
void IgnoreApplicationActivationRightNow();
[[nodiscard]] constexpr bool UseMainQueueGeneric();
void DrainMainQueue(); // Needed only if UseMainQueueGeneric() is false.
namespace ThirdParty {

View file

@ -24,10 +24,6 @@ QString CurrentExecutablePath(int argc, char *argv[]);
inline void IgnoreApplicationActivationRightNow() {
}
inline constexpr bool UseMainQueueGeneric() {
return true;
}
namespace ThirdParty {
void start();

View file

@ -10,11 +10,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/effects/animation_value.h"
#include "ui/painter.h"
#include <QtCore/QtMath>
namespace Ui {
namespace {
constexpr auto kPointCount = 12;
constexpr auto kStaticLoadingValue = float64(-666);
constexpr auto kFullArcLength = 360 * 16;
//
// 1 3
@ -141,12 +145,12 @@ void CrossAnimation::paint(
auto pathDeleteSize = kPointCount;
const auto staticLoading = (loading == kStaticLoadingValue);
auto loadingArcLength = staticLoading ? FullArcLength : 0;
auto loadingArcLength = staticLoading ? kFullArcLength : 0;
if (loading > 0.) {
transformLoadingCross(loading, pathDelete, pathDeleteSize);
auto loadingArc = (loading >= 0.5) ? (loading - 1.) : loading;
loadingArcLength = qRound(-loadingArc * 2 * FullArcLength);
loadingArcLength = qRound(-loadingArc * 2 * kFullArcLength);
}
if (!staticLoading) {
@ -177,9 +181,9 @@ void CrossAnimation::paint(
if (staticLoading) {
anim::DrawStaticLoading(p, roundPart, st.stroke, color);
} else {
auto loadingArcStart = FullArcLength / 8;
auto loadingArcStart = kFullArcLength / 8;
if (shown < 1.) {
loadingArcStart -= qRound(-(shown - 1.) * FullArcLength / 4.);
loadingArcStart -= qRound(-(shown - 1.) * kFullArcLength / 4.);
}
if (loadingArcLength < 0) {
loadingArcStart += loadingArcLength;

View file

@ -7,9 +7,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "ui/effects/numbers_animation.h"
#include "lang/lang_tag.h"
#include "ui/painter.h"
#include "styles/style_widgets.h"
#include <QtGui/QPainter>
namespace Ui {
NumbersAnimation::NumbersAnimation(
@ -107,7 +109,7 @@ void NumbersAnimation::finishAnimating() {
}
}
void NumbersAnimation::paint(Painter &p, int x, int y, int outerWidth) {
void NumbersAnimation::paint(QPainter &p, int x, int y, int outerWidth) {
auto digitsCount = _digits.size();
if (!digitsCount) return;
@ -115,7 +117,7 @@ void NumbersAnimation::paint(Painter &p, int x, int y, int outerWidth) {
auto width = anim::interpolate(_fromWidth, _toWidth, progress);
QString singleChar('0');
if (rtl()) x = outerWidth - x - width;
if (style::RightToLeft()) x = outerWidth - x - width;
x += width - _digits.size() * _digitWidth;
auto fromTop = anim::interpolate(0, _font->height, progress) * (_growing ? 1 : -1);
auto toTop = anim::interpolate(_font->height, 0, progress) * (_growing ? -1 : 1);
@ -233,23 +235,3 @@ void LabelWithNumbers::paintEvent(QPaintEvent *e) {
}
} // namespace Ui
namespace Lang {
Ui::StringWithNumbers ReplaceTag<Ui::StringWithNumbers>::Call(
Ui::StringWithNumbers &&original,
ushort tag,
const Ui::StringWithNumbers &replacement) {
original.offset = FindTagReplacementPosition(original.text, tag);
if (original.offset < 0) {
return std::move(original);
}
original.text = ReplaceTag<QString>::Call(
std::move(original.text),
tag,
replacement.text);
original.length = replacement.text.size();
return std::move(original);
}
} // namespace Lang

View file

@ -28,7 +28,7 @@ public:
void setText(const QString &text, int value);
void finishAnimating();
void paint(Painter &p, int x, int y, int outerWidth);
void paint(QPainter &p, int x, int y, int outerWidth);
int countWidth() const;
int maxWidth() const;
@ -108,28 +108,3 @@ private:
};
} // namespace Ui
namespace Lang {
template <typename ResultString>
struct StartReplacements;
template <>
struct StartReplacements<Ui::StringWithNumbers> {
static inline Ui::StringWithNumbers Call(QString &&langString) {
return { std::move(langString) };
}
};
template <typename ResultString>
struct ReplaceTag;
template <>
struct ReplaceTag<Ui::StringWithNumbers> {
static Ui::StringWithNumbers Call(
Ui::StringWithNumbers &&original,
ushort tag,
const Ui::StringWithNumbers &replacement);
};
} // namespace Lang

View file

@ -8,12 +8,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/effects/panel_animation.h"
#include "ui/effects/animation_value.h"
#include "app.h"
#include "ui/ui_utility.h"
#include <QtGui/QPainter>
namespace Ui {
void RoundShadowAnimation::start(int frameWidth, int frameHeight, float64 devicePixelRatio) {
Assert(!started());
Expects(!started());
_frameWidth = frameWidth;
_frameHeight = frameHeight;
_frame = QImage(_frameWidth, _frameHeight, QImage::Format_ARGB32_Premultiplied);
@ -27,7 +30,7 @@ void RoundShadowAnimation::start(int frameWidth, int frameHeight, float64 device
}
void RoundShadowAnimation::setShadow(const style::Shadow &st) {
_shadow.extend = st.extend * cIntRetinaFactor();
_shadow.extend = st.extend * style::DevicePixelRatio();
_shadow.left = cloneImage(st.left);
if (_shadow.valid()) {
_shadow.topLeft = cloneImage(st.topLeft);
@ -64,7 +67,8 @@ void RoundShadowAnimation::setCornerMasks(
}
void RoundShadowAnimation::setCornerMask(Corner &corner, const QImage &image) {
Assert(!started());
Expects(!started());
corner.image = image;
if (corner.valid()) {
corner.width = corner.image.width();
@ -82,11 +86,13 @@ void RoundShadowAnimation::setCornerMask(Corner &corner, const QImage &image) {
QImage RoundShadowAnimation::cloneImage(const style::icon &source) {
if (source.empty()) return QImage();
auto result = QImage(source.size() * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
result.setDevicePixelRatio(cRetinaFactor());
auto result = QImage(
source.size() * style::DevicePixelRatio(),
QImage::Format_ARGB32_Premultiplied);
result.setDevicePixelRatio(style::DevicePixelRatio());
result.fill(Qt::transparent);
{
Painter p(&result);
QPainter p(&result);
source.paint(p, 0, 0, source.width());
}
return result;
@ -218,22 +224,26 @@ void RoundShadowAnimation::paintShadowHorizontal(int left, int right, int top, c
}
void PanelAnimation::setFinalImage(QImage &&finalImage, QRect inner) {
Assert(!started());
_finalImage = App::pixmapFromImageInPlace(std::move(finalImage).convertToFormat(QImage::Format_ARGB32_Premultiplied));
Expects(!started());
const auto pixelRatio = style::DevicePixelRatio();
_finalImage = PixmapFromImage(
std::move(finalImage).convertToFormat(
QImage::Format_ARGB32_Premultiplied));
Assert(!_finalImage.isNull());
_finalWidth = _finalImage.width();
_finalHeight = _finalImage.height();
Assert(!(_finalWidth % cIntRetinaFactor()));
Assert(!(_finalHeight % cIntRetinaFactor()));
Assert(!(_finalWidth % pixelRatio));
Assert(!(_finalHeight % pixelRatio));
_finalInnerLeft = inner.x();
_finalInnerTop = inner.y();
_finalInnerWidth = inner.width();
_finalInnerHeight = inner.height();
Assert(!(_finalInnerLeft % cIntRetinaFactor()));
Assert(!(_finalInnerTop % cIntRetinaFactor()));
Assert(!(_finalInnerWidth % cIntRetinaFactor()));
Assert(!(_finalInnerHeight % cIntRetinaFactor()));
Assert(!(_finalInnerLeft % pixelRatio));
Assert(!(_finalInnerTop % pixelRatio));
Assert(!(_finalInnerWidth % pixelRatio));
Assert(!(_finalInnerHeight % pixelRatio));
_finalInnerRight = _finalInnerLeft + _finalInnerWidth;
_finalInnerBottom = _finalInnerTop + _finalInnerHeight;
Assert(QRect(0, 0, _finalWidth, _finalHeight).contains(inner));
@ -285,14 +295,14 @@ void PanelAnimation::setStartFadeTop() {
void PanelAnimation::createFadeMask() {
auto resultHeight = qRound(_finalImage.height() * _st.fadeHeight);
if (auto remove = (resultHeight % cIntRetinaFactor())) {
if (auto remove = (resultHeight % style::DevicePixelRatio())) {
resultHeight -= remove;
}
auto finalAlpha = qRound(_st.fadeOpacity * 255);
Assert(finalAlpha >= 0 && finalAlpha < 256);
auto result = QImage(cIntRetinaFactor(), resultHeight, QImage::Format_ARGB32_Premultiplied);
auto result = QImage(style::DevicePixelRatio(), resultHeight, QImage::Format_ARGB32_Premultiplied);
auto ints = reinterpret_cast<uint32*>(result.bits());
auto intsPerLineAdded = (result.bytesPerLine() >> 2) - cIntRetinaFactor();
auto intsPerLineAdded = (result.bytesPerLine() >> 2) - style::DevicePixelRatio();
auto up = (_origin == PanelAnimation::Origin::BottomLeft || _origin == PanelAnimation::Origin::BottomRight);
auto from = up ? resultHeight : 0, to = resultHeight - from, delta = up ? -1 : 1;
auto fadeFirstAlpha = up ? (finalAlpha + 1) : 1;
@ -302,12 +312,12 @@ void PanelAnimation::createFadeMask() {
for (auto y = from; y != to; y += delta) {
auto alpha = static_cast<uint32>(finalAlpha * y) / resultHeight;
auto value = (0xFFU << 24) | (alpha << 16) | (alpha << 8) | alpha;
for (auto x = 0; x != cIntRetinaFactor(); ++x) {
for (auto x = 0; x != style::DevicePixelRatio(); ++x) {
*ints++ = value;
}
ints += intsPerLineAdded;
}
_fadeMask = App::pixmapFromImageInPlace(style::colorizeImage(result, _st.fadeBg));
_fadeMask = PixmapFromImage(style::colorizeImage(result, _st.fadeBg));
_fadeHeight = _fadeMask.height();
}
@ -356,16 +366,18 @@ void PanelAnimation::paintFrame(QPainter &p, int x, int y, int outerWidth, float
Assert(started());
Assert(dt >= 0.);
const auto pixelRatio = style::DevicePixelRatio();
auto &transition = anim::easeOutCirc;
if (dt < _alphaDuration) opacity *= transition(1., dt / _alphaDuration);
_frameAlpha = anim::interpolate(1, 256, opacity);
auto frameWidth = (_startWidth < 0 || dt >= _widthDuration) ? _finalInnerWidth : anim::interpolate(_startWidth, _finalInnerWidth, transition(1., dt / _widthDuration));
auto frameHeight = (_startHeight < 0 || dt >= _heightDuration) ? _finalInnerHeight : anim::interpolate(_startHeight, _finalInnerHeight, transition(1., dt / _heightDuration));
if (auto decrease = (frameWidth % cIntRetinaFactor())) {
if (auto decrease = (frameWidth % pixelRatio)) {
frameWidth -= decrease;
}
if (auto decrease = (frameHeight % cIntRetinaFactor())) {
if (auto decrease = (frameHeight % pixelRatio)) {
frameHeight -= decrease;
}
auto frameLeft = (_origin == Origin::TopLeft || _origin == Origin::BottomLeft) ? _finalInnerLeft : (_finalInnerRight - frameWidth);
@ -373,11 +385,11 @@ void PanelAnimation::paintFrame(QPainter &p, int x, int y, int outerWidth, float
auto frameRight = frameLeft + frameWidth;
auto frameBottom = frameTop + frameHeight;
auto fadeTop = (_fadeHeight > 0) ? snap(anim::interpolate(_startFadeTop, _finalInnerHeight, transition(1., dt)), 0, frameHeight) : frameHeight;
if (auto decrease = (fadeTop % cIntRetinaFactor())) {
auto fadeTop = (_fadeHeight > 0) ? std::clamp(anim::interpolate(_startFadeTop, _finalInnerHeight, transition(1., dt)), 0, frameHeight) : frameHeight;
if (auto decrease = (fadeTop % pixelRatio)) {
fadeTop -= decrease;
}
auto fadeBottom = (fadeTop < frameHeight) ? qMin(fadeTop + _fadeHeight, frameHeight) : frameHeight;
auto fadeBottom = (fadeTop < frameHeight) ? std::min(fadeTop + _fadeHeight, frameHeight) : frameHeight;
auto fadeSkipLines = 0;
if (_origin == Origin::BottomLeft || _origin == Origin::BottomRight) {
fadeTop = frameHeight - fadeTop;
@ -392,21 +404,21 @@ void PanelAnimation::paintFrame(QPainter &p, int x, int y, int outerWidth, float
_frame.fill(Qt::transparent);
}
{
Painter p(&_frame);
QPainter p(&_frame);
p.setOpacity(opacity);
auto painterFrameLeft = frameLeft / cIntRetinaFactor();
auto painterFrameTop = frameTop / cIntRetinaFactor();
auto painterFadeBottom = fadeBottom / cIntRetinaFactor();
auto painterFrameLeft = frameLeft / pixelRatio;
auto painterFrameTop = frameTop / pixelRatio;
auto painterFadeBottom = fadeBottom / pixelRatio;
p.drawPixmap(painterFrameLeft, painterFrameTop, _finalImage, frameLeft, frameTop, frameWidth, frameHeight);
if (_fadeHeight) {
if (frameTop != fadeTop) {
p.fillRect(painterFrameLeft, painterFrameTop, frameWidth, fadeTop - frameTop, _fadeFirst);
}
if (fadeTop != fadeBottom) {
auto painterFadeTop = fadeTop / cIntRetinaFactor();
auto painterFrameWidth = frameWidth / cIntRetinaFactor();
auto painterFrameHeight = frameHeight / cIntRetinaFactor();
p.drawPixmap(painterFrameLeft, painterFadeTop, painterFrameWidth, painterFadeBottom - painterFadeTop, _fadeMask, 0, fadeSkipLines, cIntRetinaFactor(), fadeBottom - fadeTop);
auto painterFadeTop = fadeTop / pixelRatio;
auto painterFrameWidth = frameWidth / pixelRatio;
auto painterFrameHeight = frameHeight / pixelRatio;
p.drawPixmap(painterFrameLeft, painterFadeTop, painterFrameWidth, painterFadeBottom - painterFadeTop, _fadeMask, 0, fadeSkipLines, pixelRatio, fadeBottom - fadeTop);
}
if (fadeBottom != frameBottom) {
p.fillRect(painterFrameLeft, painterFadeBottom, frameWidth, frameBottom - fadeBottom, _fadeLast);
@ -433,18 +445,18 @@ void PanelAnimation::paintFrame(QPainter &p, int x, int y, int outerWidth, float
outerRight += _shadow.extend.right();
outerBottom += _shadow.extend.bottom();
}
if (cIntRetinaFactor() > 1) {
if (auto skipLeft = (outerLeft % cIntRetinaFactor())) {
if (pixelRatio > 1) {
if (auto skipLeft = (outerLeft % pixelRatio)) {
outerLeft -= skipLeft;
}
if (auto skipTop = (outerTop % cIntRetinaFactor())) {
if (auto skipTop = (outerTop % pixelRatio)) {
outerTop -= skipTop;
}
if (auto skipRight = (outerRight % cIntRetinaFactor())) {
outerRight += (cIntRetinaFactor() - skipRight);
if (auto skipRight = (outerRight % pixelRatio)) {
outerRight += (pixelRatio - skipRight);
}
if (auto skipBottom = (outerBottom % cIntRetinaFactor())) {
outerBottom += (cIntRetinaFactor() - skipBottom);
if (auto skipBottom = (outerBottom % pixelRatio)) {
outerBottom += (pixelRatio - skipBottom);
}
}
@ -494,7 +506,7 @@ void PanelAnimation::paintFrame(QPainter &p, int x, int y, int outerWidth, float
// frameInts += _frameIntsPerLineAdded;
//}
p.drawImage(style::rtlpoint(x + (outerLeft / cIntRetinaFactor()), y + (outerTop / cIntRetinaFactor()), outerWidth), _frame, QRect(outerLeft, outerTop, outerRight - outerLeft, outerBottom - outerTop));
p.drawImage(style::rtlpoint(x + (outerLeft / pixelRatio), y + (outerTop / pixelRatio), outerWidth), _frame, QRect(outerLeft, outerTop, outerRight - outerLeft, outerBottom - outerTop));
}
} // namespace Ui

View file

@ -8,7 +8,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/effects/ripple_animation.h"
#include "ui/effects/animations.h"
#include "app.h"
#include "ui/painter.h"
#include "ui/ui_utility.h"
namespace Ui {
@ -51,11 +52,12 @@ RippleAnimation::Ripple::Ripple(const style::RippleAnimation &st, QPoint origin,
, _frame(mask.size(), QImage::Format_ARGB32_Premultiplied) {
_frame.setDevicePixelRatio(mask.devicePixelRatio());
const auto pixelRatio = style::DevicePixelRatio();
QPoint points[] = {
{ 0, 0 },
{ _frame.width() / cIntRetinaFactor(), 0 },
{ _frame.width() / cIntRetinaFactor(), _frame.height() / cIntRetinaFactor() },
{ 0, _frame.height() / cIntRetinaFactor() },
{ _frame.width() / pixelRatio, 0 },
{ _frame.width() / pixelRatio, _frame.height() / pixelRatio },
{ 0, _frame.height() / pixelRatio },
};
for (auto point : points) {
accumulate_max(_radiusTo, style::point::dotProduct(_origin - point, _origin - point));
@ -68,7 +70,9 @@ RippleAnimation::Ripple::Ripple(const style::RippleAnimation &st, QPoint origin,
RippleAnimation::Ripple::Ripple(const style::RippleAnimation &st, const QPixmap &mask, Fn<void()> update)
: _st(st)
, _update(update)
, _origin(mask.width() / (2 * cIntRetinaFactor()), mask.height() / (2 * cIntRetinaFactor()))
, _origin(
mask.width() / (2 * style::DevicePixelRatio()),
mask.height() / (2 * style::DevicePixelRatio()))
, _radiusFrom(mask.width() + mask.height())
, _frame(mask.size(), QImage::Format_ARGB32_Premultiplied) {
_frame.setDevicePixelRatio(mask.devicePixelRatio());
@ -86,7 +90,7 @@ void RippleAnimation::Ripple::paint(QPainter &p, const QPixmap &mask, const QCol
auto radius = anim::interpolate(_radiusFrom, _radiusTo, _show.value(1.));
_frame.fill(Qt::transparent);
{
Painter p(&_frame);
QPainter p(&_frame);
p.setPen(Qt::NoPen);
if (colorOverride) {
p.setBrush(*colorOverride);
@ -101,7 +105,7 @@ void RippleAnimation::Ripple::paint(QPainter &p, const QPixmap &mask, const QCol
p.drawPixmap(0, 0, mask);
}
if (radius == _radiusTo && colorOverride == nullptr) {
_cache = App::pixmapFromImageInPlace(std::move(_frame));
_cache = PixmapFromImage(std::move(_frame));
}
}
auto saved = p.opacity();
@ -142,7 +146,7 @@ void RippleAnimation::Ripple::clearCache() {
RippleAnimation::RippleAnimation(const style::RippleAnimation &st, QImage mask, Fn<void()> callback)
: _st(st)
, _mask(App::pixmapFromImageInPlace(std::move(mask)))
, _mask(PixmapFromImage(std::move(mask)))
, _update(callback) {
}
@ -189,7 +193,9 @@ void RippleAnimation::paint(QPainter &p, int x, int y, int outerWidth, const QCo
return;
}
if (rtl()) x = outerWidth - x - (_mask.width() / cIntRetinaFactor());
if (style::RightToLeft()) {
x = outerWidth - x - (_mask.width() / style::DevicePixelRatio());
}
p.translate(x, y);
for (const auto &ripple : _ripples) {
ripple->paint(p, _mask, colorOverride);
@ -199,8 +205,8 @@ void RippleAnimation::paint(QPainter &p, int x, int y, int outerWidth, const QCo
}
QImage RippleAnimation::maskByDrawer(QSize size, bool filled, Fn<void(QPainter &p)> drawer) {
auto result = QImage(size * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
result.setDevicePixelRatio(cRetinaFactor());
auto result = QImage(size * style::DevicePixelRatio(), QImage::Format_ARGB32_Premultiplied);
result.setDevicePixelRatio(style::DevicePixelRatio());
result.fill(filled ? QColor(255, 255, 255) : Qt::transparent);
if (drawer) {
Painter p(&result);

View file

@ -5,13 +5,18 @@ the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "core/main_queue_processor.h"
#include "ui/main_queue_processor.h"
#include "core/sandbox.h"
#include "platform/platform_specific.h"
#include "facades.h"
#include "base/base_integration.h"
#include "ui/platform/ui_platform_utility.h"
namespace Core {
#include <QtCore/QMutex>
#include <QtCore/QCoreApplication>
#include <QtGui/QtEvents>
#include <crl/crl_on_main.h>
namespace Ui {
namespace {
constexpr auto kProcessorEvent = QEvent::Type(QEvent::User + 1);
@ -47,7 +52,7 @@ void PushToMainQueueGeneric(void (*callable)(void*), void *argument) {
QMutexLocker lock(&ProcessorMutex);
if (ProcessorInstance) {
QApplication::postEvent(ProcessorInstance, event.release());
QCoreApplication::postEvent(ProcessorInstance, event.release());
}
}
@ -72,13 +77,13 @@ MainQueueProcessor::MainQueueProcessor() {
crl::init_main_queue(PushToMainQueueGeneric);
} else {
crl::wrap_main_queue([](void (*callable)(void*), void *argument) {
Sandbox::Instance().customEnterFromEventLoop([&] {
base::EnterFromEventLoop([&] {
callable(argument);
});
});
}
Core::Sandbox::Instance().widgetUpdateRequests(
crl::on_main_update_requests(
) | rpl::start_with_next([] {
if constexpr (Platform::UseMainQueueGeneric()) {
DrainMainQueueGeneric();
@ -86,10 +91,6 @@ MainQueueProcessor::MainQueueProcessor() {
Platform::DrainMainQueue();
}
}, _lifetime);
base::InitObservables([] {
Global::RefHandleObservables().call();
});
}
bool MainQueueProcessor::event(QEvent *event) {
@ -124,4 +125,4 @@ MainQueueProcessor::~MainQueueProcessor() {
}
}
} // namespace
} // namespace Ui

View file

@ -7,7 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
namespace Core {
namespace Ui {
class MainQueueProcessor : public QObject {
public:
@ -25,4 +25,4 @@ private:
};
} // namespace Core
} // namespace Ui

View file

@ -34,5 +34,9 @@ inline void ShowOverAll(not_null<QWidget*> widget, bool canFocus) {
inline void BringToBack(not_null<QWidget*> widget) {
}
inline constexpr bool UseMainQueueGeneric() {
return true;
}
} // namespace Platform
} // namespace Ui

View file

@ -19,5 +19,9 @@ inline bool TranslucentWindowsSupported(QPoint globalPosition) {
inline void UpdateOverlayed(not_null<QWidget*> widget) {
}
inline constexpr bool UseMainQueueGeneric() {
return false;
}
} // namespace Platform
} // namespace Ui

View file

@ -15,6 +15,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <Cocoa/Cocoa.h>
extern "C" {
void _dispatch_main_queue_callback_4CF(mach_msg_header_t *msg);
} // extern "C"
namespace Ui {
namespace Platform {
@ -84,5 +88,9 @@ void BringToBack(not_null<QWidget*> widget) {
[wnd setLevel:NSModalPanelWindowLevel];
}
void DrainMainQueue() {
_dispatch_main_queue_callback_4CF(nullptr);
}
} // namespace Platform
} // namespace Ui

View file

@ -27,6 +27,9 @@ void UpdateOverlayed(not_null<QWidget*> widget);
void ShowOverAll(not_null<QWidget*> widget, bool canFocus = true);
void BringToBack(not_null<QWidget*> widget);
[[nodiscard]] constexpr bool UseMainQueueGeneric();
void DrainMainQueue(); // Needed only if UseMainQueueGeneric() is false.
} // namespace Platform
} // namespace Ui

View file

@ -37,5 +37,9 @@ inline void ShowOverAll(not_null<QWidget*> widget, bool canFocus) {
inline void BringToBack(not_null<QWidget*> widget) {
}
inline constexpr bool UseMainQueueGeneric() {
return true;
}
} // namespace Platform
} // namespace Ui

View file

@ -7,7 +7,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "ui/text/text_entity.h"
#include "lang/lang_tag.h"
#include "base/qthelp_url.h"
#include "base/qthelp_regex.h"
#include "base/crc32hash.h"
@ -2112,65 +2111,3 @@ int EntityInText::FirstMonospaceOffset(
&EntityInText::offset);
return (i == monospace.end()) ? textLength : i->offset();
}
namespace Lang {
TextWithEntities ReplaceTag<TextWithEntities>::Call(TextWithEntities &&original, ushort tag, const TextWithEntities &replacement) {
auto replacementPosition = FindTagReplacementPosition(original.text, tag);
if (replacementPosition < 0) {
return std::move(original);
}
auto result = TextWithEntities();
result.text = ReplaceTag<QString>::Replace(std::move(original.text), replacement.text, replacementPosition);
auto originalEntitiesCount = original.entities.size();
auto replacementEntitiesCount = replacement.entities.size();
if (originalEntitiesCount != 0 || replacementEntitiesCount != 0) {
result.entities.reserve(originalEntitiesCount + replacementEntitiesCount);
auto replacementEnd = replacementPosition + replacement.text.size();
auto replacementEntity = replacement.entities.cbegin();
auto addReplacementEntitiesUntil = [&replacementEntity, &replacement, &result, replacementPosition, replacementEnd](int untilPosition) {
while (replacementEntity != replacement.entities.cend()) {
auto newOffset = replacementPosition + replacementEntity->offset();
if (newOffset >= untilPosition) {
return;
}
auto newEnd = newOffset + replacementEntity->length();
newOffset = std::clamp(newOffset, replacementPosition, replacementEnd);
newEnd = std::clamp(newEnd, replacementPosition, replacementEnd);
if (auto newLength = newEnd - newOffset) {
result.entities.push_back({ replacementEntity->type(), newOffset, newLength, replacementEntity->data() });
}
++replacementEntity;
}
};
for (const auto &entity : std::as_const(original.entities)) {
// Transform the entity by the replacement.
auto offset = entity.offset();
auto end = offset + entity.length();
if (offset > replacementPosition) {
offset = offset + replacement.text.size() - kTagReplacementSize;
}
if (end > replacementPosition) {
end = end + replacement.text.size() - kTagReplacementSize;
}
offset = std::clamp(offset, 0, result.text.size());
end = std::clamp(end, 0, result.text.size());
// Add all replacement entities that start before the current original entity.
addReplacementEntitiesUntil(offset);
// Add a modified original entity.
if (auto length = end - offset) {
result.entities.push_back({ entity.type(), offset, length, entity.data() });
}
}
// Add the remaining replacement entities.
addReplacementEntitiesUntil(result.text.size());
}
return result;
}
} // namespace Lang

View file

@ -353,26 +353,3 @@ void SetClipboardText(
QClipboard::Mode mode = QClipboard::Clipboard);
} // namespace TextUtilities
namespace Lang {
template <typename ResultString>
struct StartReplacements;
template <>
struct StartReplacements<TextWithEntities> {
static inline TextWithEntities Call(QString &&langString) {
return { std::move(langString), EntitiesInText() };
}
};
template <typename ResultString>
struct ReplaceTag;
template <>
struct ReplaceTag<TextWithEntities> {
static TextWithEntities Call(TextWithEntities &&original, ushort tag, const TextWithEntities &replacement);
};
} // namespace Lang

View file

@ -7,9 +7,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "ui/widgets/checkbox.h"
#include "lang/lang_keys.h"
#include "ui/effects/ripple_animation.h"
#include "app.h"
#include "ui/ui_utility.h"
#include <QtGui/QtEvents>
namespace Ui {
namespace {
@ -624,14 +625,16 @@ void Checkbox::paintEvent(QPaintEvent *e) {
QPixmap Checkbox::grabCheckCache() const {
auto checkSize = _check->getSize();
auto image = QImage(checkSize * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
auto image = QImage(
checkSize * style::DevicePixelRatio(),
QImage::Format_ARGB32_Premultiplied);
image.fill(Qt::transparent);
image.setDevicePixelRatio(cRetinaFactor());
image.setDevicePixelRatio(style::DevicePixelRatio());
{
Painter p(&image);
_check->paint(p, 0, 0, checkSize.width());
}
return App::pixmapFromImageInPlace(std::move(image));
return PixmapFromImage(std::move(image));
}
void Checkbox::onStateChanged(State was, StateChangeSource source) {

View file

@ -2,6 +2,14 @@
<(src_loc)/ui/effects/animation_value.h
<(src_loc)/ui/effects/animations.cpp
<(src_loc)/ui/effects/animations.h
<(src_loc)/ui/effects/cross_animation.cpp
<(src_loc)/ui/effects/cross_animation.h
<(src_loc)/ui/effects/numbers_animation.cpp
<(src_loc)/ui/effects/numbers_animation.h
<(src_loc)/ui/effects/panel_animation.cpp
<(src_loc)/ui/effects/panel_animation.h
<(src_loc)/ui/effects/ripple_animation.cpp
<(src_loc)/ui/effects/ripple_animation.h
<(src_loc)/ui/image/image_prepare.cpp
<(src_loc)/ui/image/image_prepare.h
<(src_loc)/ui/platform/ui_platform_utility.h
@ -36,6 +44,8 @@
<(src_loc)/ui/text/text_utilities.h
<(src_loc)/ui/widgets/buttons.cpp
<(src_loc)/ui/widgets/buttons.h
<(src_loc)/ui/widgets/checkbox.cpp
<(src_loc)/ui/widgets/checkbox.h
<(src_loc)/ui/widgets/dropdown_menu.cpp
<(src_loc)/ui/widgets/dropdown_menu.h
<(src_loc)/ui/widgets/inner_dropdown.cpp
@ -76,6 +86,8 @@
<(src_loc)/ui/focus_persister.h
<(src_loc)/ui/inactive_press.cpp
<(src_loc)/ui/inactive_press.h
<(src_loc)/ui/main_queue_processor.cpp
<(src_loc)/ui/main_queue_processor.h
<(src_loc)/ui/painter.h
<(src_loc)/ui/round_rect.cpp
<(src_loc)/ui/round_rect.h

View file

@ -161,8 +161,6 @@
<(src_loc)/core/launcher.h
<(src_loc)/core/local_url_handlers.cpp
<(src_loc)/core/local_url_handlers.h
<(src_loc)/core/main_queue_processor.cpp
<(src_loc)/core/main_queue_processor.h
<(src_loc)/core/media_active_cache.h
<(src_loc)/core/mime_type.cpp
<(src_loc)/core/mime_type.h
@ -460,8 +458,12 @@
<(src_loc)/lang/lang_instance.h
<(src_loc)/lang/lang_keys.cpp
<(src_loc)/lang/lang_keys.h
<(src_loc)/lang/lang_numbers_animation.cpp
<(src_loc)/lang/lang_numbers_animation.h
<(src_loc)/lang/lang_tag.cpp
<(src_loc)/lang/lang_tag.h
<(src_loc)/lang/lang_text_entity.cpp
<(src_loc)/lang/lang_text_entity.h
<(src_loc)/lang/lang_translator.cpp
<(src_loc)/lang/lang_translator.h
<(src_loc)/lang/lang_values.cpp
@ -737,18 +739,10 @@
<(src_loc)/support/support_helper.h
<(src_loc)/support/support_templates.cpp
<(src_loc)/support/support_templates.h
<(src_loc)/ui/effects/cross_animation.cpp
<(src_loc)/ui/effects/cross_animation.h
<(src_loc)/ui/effects/fade_animation.cpp
<(src_loc)/ui/effects/fade_animation.h
<(src_loc)/ui/effects/numbers_animation.cpp
<(src_loc)/ui/effects/numbers_animation.h
<(src_loc)/ui/effects/panel_animation.cpp
<(src_loc)/ui/effects/panel_animation.h
<(src_loc)/ui/effects/radial_animation.cpp
<(src_loc)/ui/effects/radial_animation.h
<(src_loc)/ui/effects/ripple_animation.cpp
<(src_loc)/ui/effects/ripple_animation.h
<(src_loc)/ui/effects/round_checkbox.cpp
<(src_loc)/ui/effects/round_checkbox.h
<(src_loc)/ui/effects/send_action_animations.cpp
@ -767,8 +761,6 @@
<(src_loc)/ui/toast/toast_manager.h
<(src_loc)/ui/toast/toast_widget.cpp
<(src_loc)/ui/toast/toast_widget.h
<(src_loc)/ui/widgets/checkbox.cpp
<(src_loc)/ui/widgets/checkbox.h
<(src_loc)/ui/widgets/continuous_sliders.cpp
<(src_loc)/ui/widgets/continuous_sliders.h
<(src_loc)/ui/widgets/discrete_sliders.cpp