mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 06:07:06 +02:00
Move App::roundRect to Ui::FillRoundRect.
This commit is contained in:
parent
b3b11bd9e7
commit
05eb549a3d
66 changed files with 2051 additions and 1847 deletions
|
@ -21,9 +21,6 @@ add_subdirectory(lib_qr)
|
|||
add_subdirectory(lib_webrtc)
|
||||
add_subdirectory(codegen)
|
||||
|
||||
include(lib_ui/cmake/generate_styles.cmake)
|
||||
include(cmake/generate_numbers.cmake)
|
||||
|
||||
get_filename_component(src_loc SourceFiles REALPATH)
|
||||
get_filename_component(res_loc Resources REALPATH)
|
||||
|
||||
|
@ -37,33 +34,6 @@ include(cmake/td_lang.cmake)
|
|||
include(cmake/td_scheme.cmake)
|
||||
include(cmake/td_ui.cmake)
|
||||
|
||||
set(style_files
|
||||
boxes/boxes.style
|
||||
calls/calls.style
|
||||
chat_helpers/chat_helpers.style
|
||||
export/view/export.style
|
||||
info/info.style
|
||||
intro/intro.style
|
||||
media/view/media_view.style
|
||||
media/player/media_player.style
|
||||
overview/overview.style
|
||||
passport/passport.style
|
||||
profile/profile.style
|
||||
settings/settings.style
|
||||
ui/filter_icons.style
|
||||
)
|
||||
|
||||
set(dependent_style_files
|
||||
${submodules_loc}/lib_ui/ui/colors.palette
|
||||
${submodules_loc}/lib_ui/ui/basic.style
|
||||
${submodules_loc}/lib_ui/ui/layers/layers.style
|
||||
${submodules_loc}/lib_ui/ui/widgets/widgets.style
|
||||
${src_loc}/ui/td_common.style
|
||||
)
|
||||
|
||||
generate_styles(Telegram ${src_loc} "${style_files}" "${dependent_style_files}")
|
||||
generate_numbers(Telegram ${res_loc}/numbers.txt)
|
||||
|
||||
set_target_properties(Telegram PROPERTIES AUTOMOC ON AUTORCC ON)
|
||||
|
||||
target_link_libraries(Telegram
|
||||
|
@ -359,8 +329,6 @@ PRIVATE
|
|||
core/launcher.h
|
||||
core/local_url_handlers.cpp
|
||||
core/local_url_handlers.h
|
||||
core/mime_type.cpp
|
||||
core/mime_type.h
|
||||
core/sandbox.cpp
|
||||
core/sandbox.h
|
||||
core/shortcuts.cpp
|
||||
|
@ -1023,8 +991,6 @@ PRIVATE
|
|||
ui/filter_icons.h
|
||||
ui/filter_icon_panel.cpp
|
||||
ui/filter_icon_panel.h
|
||||
ui/grouped_layout.cpp
|
||||
ui/grouped_layout.h
|
||||
ui/item_text_options.cpp
|
||||
ui/item_text_options.h
|
||||
ui/resize_area.h
|
||||
|
|
|
@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/view/history_view_service_message.h"
|
||||
#include "media/audio/media_audio.h"
|
||||
#include "ui/image/image.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "inline_bots/inline_bot_layout_item.h"
|
||||
#include "core/crash_reports.h"
|
||||
#include "core/update_checker.h"
|
||||
|
@ -66,14 +67,6 @@ HistoryView::Element *hoveredItem = nullptr,
|
|||
*pressedLinkItem = nullptr,
|
||||
*mousedItem = nullptr;
|
||||
|
||||
struct CornersPixmaps {
|
||||
QPixmap p[4];
|
||||
};
|
||||
QVector<CornersPixmaps> corners;
|
||||
using CornersMap = QMap<uint32, CornersPixmaps>;
|
||||
CornersMap cornersMap;
|
||||
QImage cornersMaskLarge[4], cornersMaskSmall[4];
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace App {
|
||||
|
@ -104,114 +97,12 @@ namespace App {
|
|||
return result;
|
||||
}
|
||||
|
||||
void prepareCorners(RoundCorners index, int32 radius, const QBrush &brush, const style::color *shadow = nullptr, QImage *cors = nullptr) {
|
||||
Expects(::corners.size() > index);
|
||||
|
||||
int32 r = radius * cIntRetinaFactor(), s = st::msgShadow * cIntRetinaFactor();
|
||||
QImage rect(r * 3, r * 3 + (shadow ? s : 0), QImage::Format_ARGB32_Premultiplied), localCors[4];
|
||||
{
|
||||
Painter p(&rect);
|
||||
PainterHighQualityEnabler hq(p);
|
||||
|
||||
p.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
p.fillRect(QRect(0, 0, rect.width(), rect.height()), Qt::transparent);
|
||||
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||
p.setPen(Qt::NoPen);
|
||||
if (shadow) {
|
||||
p.setBrush((*shadow)->b);
|
||||
p.drawRoundedRect(0, s, r * 3, r * 3, r, r);
|
||||
}
|
||||
p.setBrush(brush);
|
||||
p.drawRoundedRect(0, 0, r * 3, r * 3, r, r);
|
||||
}
|
||||
if (!cors) cors = localCors;
|
||||
cors[0] = rect.copy(0, 0, r, r);
|
||||
cors[1] = rect.copy(r * 2, 0, r, r);
|
||||
cors[2] = rect.copy(0, r * 2, r, r + (shadow ? s : 0));
|
||||
cors[3] = rect.copy(r * 2, r * 2, r, r + (shadow ? s : 0));
|
||||
if (index != SmallMaskCorners && index != LargeMaskCorners) {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
::corners[index].p[i] = pixmapFromImageInPlace(std::move(cors[i]));
|
||||
::corners[index].p[i].setDevicePixelRatio(cRetinaFactor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void createMaskCorners() {
|
||||
QImage mask[4];
|
||||
prepareCorners(SmallMaskCorners, st::buttonRadius, QColor(255, 255, 255), nullptr, mask);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
::cornersMaskSmall[i] = mask[i].convertToFormat(QImage::Format_ARGB32_Premultiplied);
|
||||
::cornersMaskSmall[i].setDevicePixelRatio(cRetinaFactor());
|
||||
}
|
||||
prepareCorners(LargeMaskCorners, st::historyMessageRadius, QColor(255, 255, 255), nullptr, mask);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
::cornersMaskLarge[i] = mask[i].convertToFormat(QImage::Format_ARGB32_Premultiplied);
|
||||
::cornersMaskLarge[i].setDevicePixelRatio(cRetinaFactor());
|
||||
}
|
||||
}
|
||||
|
||||
void createPaletteCorners() {
|
||||
prepareCorners(MenuCorners, st::buttonRadius, st::menuBg);
|
||||
prepareCorners(BoxCorners, st::boxRadius, st::boxBg);
|
||||
prepareCorners(BotKbOverCorners, st::dateRadius, st::msgBotKbOverBgAdd);
|
||||
prepareCorners(StickerCorners, st::dateRadius, st::msgServiceBg);
|
||||
prepareCorners(StickerSelectedCorners, st::dateRadius, st::msgServiceBgSelected);
|
||||
prepareCorners(SelectedOverlaySmallCorners, st::buttonRadius, st::msgSelectOverlay);
|
||||
prepareCorners(SelectedOverlayLargeCorners, st::historyMessageRadius, st::msgSelectOverlay);
|
||||
prepareCorners(DateCorners, st::dateRadius, st::msgDateImgBg);
|
||||
prepareCorners(DateSelectedCorners, st::dateRadius, st::msgDateImgBgSelected);
|
||||
prepareCorners(OverviewVideoCorners, st::overviewVideoStatusRadius, st::msgDateImgBg);
|
||||
prepareCorners(OverviewVideoSelectedCorners, st::overviewVideoStatusRadius, st::msgDateImgBgSelected);
|
||||
prepareCorners(InShadowCorners, st::historyMessageRadius, st::msgInShadow);
|
||||
prepareCorners(InSelectedShadowCorners, st::historyMessageRadius, st::msgInShadowSelected);
|
||||
prepareCorners(ForwardCorners, st::historyMessageRadius, st::historyForwardChooseBg);
|
||||
prepareCorners(MediaviewSaveCorners, st::mediaviewControllerRadius, st::mediaviewSaveMsgBg);
|
||||
prepareCorners(EmojiHoverCorners, st::buttonRadius, st::emojiPanHover);
|
||||
prepareCorners(StickerHoverCorners, st::buttonRadius, st::emojiPanHover);
|
||||
prepareCorners(BotKeyboardCorners, st::buttonRadius, st::botKbBg);
|
||||
prepareCorners(PhotoSelectOverlayCorners, st::buttonRadius, st::overviewPhotoSelectOverlay);
|
||||
|
||||
prepareCorners(Doc1Corners, st::buttonRadius, st::msgFile1Bg);
|
||||
prepareCorners(Doc2Corners, st::buttonRadius, st::msgFile2Bg);
|
||||
prepareCorners(Doc3Corners, st::buttonRadius, st::msgFile3Bg);
|
||||
prepareCorners(Doc4Corners, st::buttonRadius, st::msgFile4Bg);
|
||||
|
||||
prepareCorners(MessageInCorners, st::historyMessageRadius, st::msgInBg, &st::msgInShadow);
|
||||
prepareCorners(MessageInSelectedCorners, st::historyMessageRadius, st::msgInBgSelected, &st::msgInShadowSelected);
|
||||
prepareCorners(MessageOutCorners, st::historyMessageRadius, st::msgOutBg, &st::msgOutShadow);
|
||||
prepareCorners(MessageOutSelectedCorners, st::historyMessageRadius, st::msgOutBgSelected, &st::msgOutShadowSelected);
|
||||
|
||||
prepareCorners(SendFilesBoxAlbumGroupCorners, st::sendBoxAlbumGroupRadius, st::callFingerprintBg);
|
||||
}
|
||||
|
||||
void createCorners() {
|
||||
::corners.resize(RoundCornersCount);
|
||||
createMaskCorners();
|
||||
createPaletteCorners();
|
||||
}
|
||||
|
||||
void clearCorners() {
|
||||
::corners.clear();
|
||||
::cornersMap.clear();
|
||||
}
|
||||
|
||||
void initMedia() {
|
||||
createCorners();
|
||||
Ui::StartCachedCorners();
|
||||
|
||||
using Update = Window::Theme::BackgroundUpdate;
|
||||
static auto subscription = Window::Theme::Background()->add_subscription([](const Update &update) {
|
||||
if (update.paletteChanged()) {
|
||||
createPaletteCorners();
|
||||
|
||||
if (const auto m = App::main()) { // multi good
|
||||
m->updateScrollColors();
|
||||
}
|
||||
HistoryView::serviceColorsUpdated();
|
||||
} else if (update.type == Update::Type::New) {
|
||||
prepareCorners(StickerCorners, st::dateRadius, st::msgServiceBg);
|
||||
prepareCorners(StickerSelectedCorners, st::dateRadius, st::msgServiceBgSelected);
|
||||
|
||||
if (const auto m = App::main()) { // multi good
|
||||
m->updateScrollColors();
|
||||
}
|
||||
|
@ -221,8 +112,7 @@ namespace App {
|
|||
}
|
||||
|
||||
void deinitMedia() {
|
||||
clearCorners();
|
||||
|
||||
Ui::FinishCachedCorners();
|
||||
Data::clearGlobalStructures();
|
||||
}
|
||||
|
||||
|
@ -396,132 +286,4 @@ namespace App {
|
|||
return QPixmap::fromImage(std::move(image), Qt::ColorOnly);
|
||||
}
|
||||
|
||||
void rectWithCorners(Painter &p, QRect rect, const style::color &bg, RoundCorners index, RectParts corners) {
|
||||
auto parts = RectPart::Top
|
||||
| RectPart::NoTopBottom
|
||||
| RectPart::Bottom
|
||||
| corners;
|
||||
roundRect(p, rect, bg, index, nullptr, parts);
|
||||
if ((corners & RectPart::AllCorners) != RectPart::AllCorners) {
|
||||
const auto size = ::corners[index].p[0].width() / cIntRetinaFactor();
|
||||
if (!(corners & RectPart::TopLeft)) {
|
||||
p.fillRect(rect.x(), rect.y(), size, size, bg);
|
||||
}
|
||||
if (!(corners & RectPart::TopRight)) {
|
||||
p.fillRect(rect.x() + rect.width() - size, rect.y(), size, size, bg);
|
||||
}
|
||||
if (!(corners & RectPart::BottomLeft)) {
|
||||
p.fillRect(rect.x(), rect.y() + rect.height() - size, size, size, bg);
|
||||
}
|
||||
if (!(corners & RectPart::BottomRight)) {
|
||||
p.fillRect(rect.x() + rect.width() - size, rect.y() + rect.height() - size, size, size, bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void complexOverlayRect(Painter &p, QRect rect, ImageRoundRadius radius, RectParts corners) {
|
||||
if (radius == ImageRoundRadius::Ellipse) {
|
||||
PainterHighQualityEnabler hq(p);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(p.textPalette().selectOverlay);
|
||||
p.drawEllipse(rect);
|
||||
} else {
|
||||
auto overlayCorners = (radius == ImageRoundRadius::Small)
|
||||
? SelectedOverlaySmallCorners
|
||||
: SelectedOverlayLargeCorners;
|
||||
const auto bg = p.textPalette().selectOverlay;
|
||||
rectWithCorners(p, rect, bg, overlayCorners, corners);
|
||||
}
|
||||
}
|
||||
|
||||
void complexLocationRect(Painter &p, QRect rect, ImageRoundRadius radius, RectParts corners) {
|
||||
rectWithCorners(p, rect, st::msgInBg, MessageInCorners, corners);
|
||||
}
|
||||
|
||||
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, const CornersPixmaps &corner, const style::color *shadow, RectParts parts) {
|
||||
auto cornerWidth = corner.p[0].width() / cIntRetinaFactor();
|
||||
auto cornerHeight = corner.p[0].height() / cIntRetinaFactor();
|
||||
if (w < 2 * cornerWidth || h < 2 * cornerHeight) return;
|
||||
if (w > 2 * cornerWidth) {
|
||||
if (parts & RectPart::Top) {
|
||||
p.fillRect(x + cornerWidth, y, w - 2 * cornerWidth, cornerHeight, bg);
|
||||
}
|
||||
if (parts & RectPart::Bottom) {
|
||||
p.fillRect(x + cornerWidth, y + h - cornerHeight, w - 2 * cornerWidth, cornerHeight, bg);
|
||||
if (shadow) {
|
||||
p.fillRect(x + cornerWidth, y + h, w - 2 * cornerWidth, st::msgShadow, *shadow);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (h > 2 * cornerHeight) {
|
||||
if ((parts & RectPart::NoTopBottom) == RectPart::NoTopBottom) {
|
||||
p.fillRect(x, y + cornerHeight, w, h - 2 * cornerHeight, bg);
|
||||
} else {
|
||||
if (parts & RectPart::Left) {
|
||||
p.fillRect(x, y + cornerHeight, cornerWidth, h - 2 * cornerHeight, bg);
|
||||
}
|
||||
if ((parts & RectPart::Center) && w > 2 * cornerWidth) {
|
||||
p.fillRect(x + cornerWidth, y + cornerHeight, w - 2 * cornerWidth, h - 2 * cornerHeight, bg);
|
||||
}
|
||||
if (parts & RectPart::Right) {
|
||||
p.fillRect(x + w - cornerWidth, y + cornerHeight, cornerWidth, h - 2 * cornerHeight, bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (parts & RectPart::TopLeft) {
|
||||
p.drawPixmap(x, y, corner.p[0]);
|
||||
}
|
||||
if (parts & RectPart::TopRight) {
|
||||
p.drawPixmap(x + w - cornerWidth, y, corner.p[1]);
|
||||
}
|
||||
if (parts & RectPart::BottomLeft) {
|
||||
p.drawPixmap(x, y + h - cornerHeight, corner.p[2]);
|
||||
}
|
||||
if (parts & RectPart::BottomRight) {
|
||||
p.drawPixmap(x + w - cornerWidth, y + h - cornerHeight, corner.p[3]);
|
||||
}
|
||||
}
|
||||
|
||||
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, RoundCorners index, const style::color *shadow, RectParts parts) {
|
||||
roundRect(p, x, y, w, h, bg, ::corners[index], shadow, parts);
|
||||
}
|
||||
|
||||
void roundShadow(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color shadow, RoundCorners index, RectParts parts) {
|
||||
auto &corner = ::corners[index];
|
||||
auto cornerWidth = corner.p[0].width() / cIntRetinaFactor();
|
||||
auto cornerHeight = corner.p[0].height() / cIntRetinaFactor();
|
||||
if (parts & RectPart::Bottom) {
|
||||
p.fillRect(x + cornerWidth, y + h, w - 2 * cornerWidth, st::msgShadow, shadow);
|
||||
}
|
||||
if (parts & RectPart::BottomLeft) {
|
||||
p.fillRect(x, y + h - cornerHeight, cornerWidth, st::msgShadow, shadow);
|
||||
p.drawPixmap(x, y + h - cornerHeight + st::msgShadow, corner.p[2]);
|
||||
}
|
||||
if (parts & RectPart::BottomRight) {
|
||||
p.fillRect(x + w - cornerWidth, y + h - cornerHeight, cornerWidth, st::msgShadow, shadow);
|
||||
p.drawPixmap(x + w - cornerWidth, y + h - cornerHeight + st::msgShadow, corner.p[3]);
|
||||
}
|
||||
}
|
||||
|
||||
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, ImageRoundRadius radius, RectParts parts) {
|
||||
auto colorKey = ((uint32(bg->c.alpha()) & 0xFF) << 24) | ((uint32(bg->c.red()) & 0xFF) << 16) | ((uint32(bg->c.green()) & 0xFF) << 8) | ((uint32(bg->c.blue()) & 0xFF) << 24);
|
||||
auto i = cornersMap.find(colorKey);
|
||||
if (i == cornersMap.cend()) {
|
||||
QImage images[4];
|
||||
switch (radius) {
|
||||
case ImageRoundRadius::Small: prepareCorners(SmallMaskCorners, st::buttonRadius, bg, nullptr, images); break;
|
||||
case ImageRoundRadius::Large: prepareCorners(LargeMaskCorners, st::historyMessageRadius, bg, nullptr, images); break;
|
||||
default: p.fillRect(x, y, w, h, bg); return;
|
||||
}
|
||||
|
||||
CornersPixmaps pixmaps;
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
pixmaps.p[j] = pixmapFromImageInPlace(std::move(images[j]));
|
||||
pixmaps.p[j].setDevicePixelRatio(cRetinaFactor());
|
||||
}
|
||||
i = cornersMap.insert(colorKey, pixmaps);
|
||||
}
|
||||
roundRect(p, x, y, w, h, bg, i.value(), nullptr, parts);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,54 +8,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#pragma once
|
||||
|
||||
#include "data/data_types.h"
|
||||
#include "ui/rect_part.h"
|
||||
|
||||
enum class ImageRoundRadius;
|
||||
|
||||
namespace HistoryView {
|
||||
class Element;
|
||||
} // namespace HistoryView
|
||||
|
||||
enum RoundCorners : int {
|
||||
SmallMaskCorners = 0x00, // for images
|
||||
LargeMaskCorners,
|
||||
|
||||
BoxCorners,
|
||||
MenuCorners,
|
||||
BotKbOverCorners,
|
||||
StickerCorners,
|
||||
StickerSelectedCorners,
|
||||
SelectedOverlaySmallCorners,
|
||||
SelectedOverlayLargeCorners,
|
||||
DateCorners,
|
||||
DateSelectedCorners,
|
||||
OverviewVideoCorners,
|
||||
OverviewVideoSelectedCorners,
|
||||
ForwardCorners,
|
||||
MediaviewSaveCorners,
|
||||
EmojiHoverCorners,
|
||||
StickerHoverCorners,
|
||||
BotKeyboardCorners,
|
||||
PhotoSelectOverlayCorners,
|
||||
|
||||
Doc1Corners,
|
||||
Doc2Corners,
|
||||
Doc3Corners,
|
||||
Doc4Corners,
|
||||
|
||||
InShadowCorners, // for photos without bg
|
||||
InSelectedShadowCorners,
|
||||
|
||||
MessageInCorners, // with shadow
|
||||
MessageInSelectedCorners,
|
||||
MessageOutCorners,
|
||||
MessageOutSelectedCorners,
|
||||
|
||||
SendFilesBoxAlbumGroupCorners,
|
||||
|
||||
RoundCornersCount
|
||||
};
|
||||
|
||||
namespace App {
|
||||
QString formatPhone(QString phone);
|
||||
|
||||
|
@ -90,20 +47,4 @@ namespace App {
|
|||
QImage readImage(const QString &file, QByteArray *format = nullptr, bool opaque = true, bool *animated = nullptr, QByteArray *content = 0);
|
||||
QPixmap pixmapFromImageInPlace(QImage &&image);
|
||||
|
||||
void complexOverlayRect(Painter &p, QRect rect, ImageRoundRadius radius, RectParts corners);
|
||||
void complexLocationRect(Painter &p, QRect rect, ImageRoundRadius radius, RectParts corners);
|
||||
|
||||
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, RoundCorners index, const style::color *shadow = nullptr, RectParts parts = RectPart::Full);
|
||||
inline void roundRect(Painter &p, const QRect &rect, style::color bg, RoundCorners index, const style::color *shadow = nullptr, RectParts parts = RectPart::Full) {
|
||||
return roundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, index, shadow, parts);
|
||||
}
|
||||
void roundShadow(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color shadow, RoundCorners index, RectParts parts = RectPart::Full);
|
||||
inline void roundShadow(Painter &p, const QRect &rect, style::color shadow, RoundCorners index, RectParts parts = RectPart::Full) {
|
||||
return roundShadow(p, rect.x(), rect.y(), rect.width(), rect.height(), shadow, index, parts);
|
||||
}
|
||||
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, ImageRoundRadius radius, RectParts parts = RectPart::Full);
|
||||
inline void roundRect(Painter &p, const QRect &rect, style::color bg, ImageRoundRadius radius, RectParts parts = RectPart::Full) {
|
||||
return roundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, radius, parts);
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -50,11 +50,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/text/text_options.h"
|
||||
#include "ui/chat/attach/attach_prepare.h"
|
||||
#include "ui/controls/emoji_button.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "confirm_box.h"
|
||||
#include "apiwrap.h"
|
||||
#include "app.h" // App::pixmapFromImageInPlace.
|
||||
#include "facades.h" // App::LambdaDelayed.
|
||||
#include "app.h"
|
||||
#include "styles/style_layers.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "styles/style_chat_helpers.h"
|
||||
|
@ -484,7 +485,7 @@ void EditCaptionBox::updateEditPreview() {
|
|||
const auto fileinfo = QFileInfo(file->path);
|
||||
const auto filename = fileinfo.fileName();
|
||||
|
||||
_isImage = fileIsImage(filename, file->mime);
|
||||
_isImage = Core::FileIsImage(filename, file->mime);
|
||||
_isAudio = false;
|
||||
_animated = false;
|
||||
_photo = false;
|
||||
|
@ -516,7 +517,7 @@ void EditCaptionBox::updateEditPreview() {
|
|||
if (shouldAsDoc) {
|
||||
auto nameString = filename;
|
||||
if (const auto song = std::get_if<Info::Song>(fileMedia)) {
|
||||
nameString = DocumentData::ComposeNameString(
|
||||
nameString = Ui::ComposeNameString(
|
||||
filename,
|
||||
song->title,
|
||||
song->performer);
|
||||
|
@ -623,9 +624,10 @@ void EditCaptionBox::createEditMediaButton() {
|
|||
_editMedia.create(this, st::editMediaButton);
|
||||
updateEditMediaButton();
|
||||
_editMedia->setClickedCallback(
|
||||
App::LambdaDelayed(st::historyAttach.ripple.hideDuration, this, [=] {
|
||||
buttonCallback();
|
||||
}));
|
||||
App::LambdaDelayed(
|
||||
st::historyAttach.ripple.hideDuration,
|
||||
this,
|
||||
buttonCallback));
|
||||
}
|
||||
|
||||
void EditCaptionBox::prepare() {
|
||||
|
@ -894,7 +896,7 @@ void EditCaptionBox::paintEvent(QPaintEvent *e) {
|
|||
const auto namewidth = w - nameleft - editButton;
|
||||
const auto x = (width() - w) / 2, y = st::boxPhotoPadding.top();
|
||||
|
||||
// App::roundRect(p, x, y, w, h, st::msgInBg, MessageInCorners, &st::msgInShadow);
|
||||
// Ui::FillRoundCorner(p, x, y, w, h, st::msgInBg, Ui::MessageInCorners, &st::msgInShadow);
|
||||
|
||||
if (_thumbw) {
|
||||
QRect rthumb(style::rtlrect(x + 0, y + 0, st::msgFileThumbSize, st::msgFileThumbSize, width()));
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -35,6 +35,8 @@ class RoundButton;
|
|||
class InputField;
|
||||
struct GroupMediaLayout;
|
||||
class EmojiButton;
|
||||
class AlbumPreview;
|
||||
enum class SendFilesWay;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Window {
|
||||
|
@ -45,12 +47,6 @@ namespace SendMenu {
|
|||
enum class Type;
|
||||
} // namespace SendMenu
|
||||
|
||||
enum class SendFilesWay {
|
||||
Album,
|
||||
Photos,
|
||||
Files,
|
||||
};
|
||||
|
||||
class SendFilesBox : public Ui::BoxContent {
|
||||
public:
|
||||
enum class SendLimit {
|
||||
|
@ -70,7 +66,7 @@ public:
|
|||
void setConfirmedCallback(
|
||||
Fn<void(
|
||||
Ui::PreparedList &&list,
|
||||
SendFilesWay way,
|
||||
Ui::SendFilesWay way,
|
||||
TextWithTags &&caption,
|
||||
Api::SendOptions options,
|
||||
bool ctrlShiftEnter)> callback) {
|
||||
|
@ -91,8 +87,6 @@ protected:
|
|||
void resizeEvent(QResizeEvent *e) override;
|
||||
|
||||
private:
|
||||
class AlbumPreview;
|
||||
|
||||
void initSendWay();
|
||||
void initPreview(rpl::producer<int> desiredPreviewHeight);
|
||||
|
||||
|
@ -101,7 +95,7 @@ private:
|
|||
void setupCaption();
|
||||
void setupShadows(
|
||||
not_null<Ui::ScrollArea*> wrap,
|
||||
not_null<AlbumPreview*> content);
|
||||
not_null<Ui::AlbumPreview*> content);
|
||||
|
||||
void setupEmojiPanel();
|
||||
void updateEmojiPanelGeometry();
|
||||
|
@ -149,7 +143,7 @@ private:
|
|||
|
||||
Fn<void(
|
||||
Ui::PreparedList &&list,
|
||||
SendFilesWay way,
|
||||
Ui::SendFilesWay way,
|
||||
TextWithTags &&caption,
|
||||
Api::SendOptions options,
|
||||
bool ctrlShiftEnter)> _confirmedCallback;
|
||||
|
@ -161,16 +155,16 @@ private:
|
|||
base::unique_qptr<ChatHelpers::TabbedPanel> _emojiPanel;
|
||||
base::unique_qptr<QObject> _emojiFilter;
|
||||
|
||||
object_ptr<Ui::Radioenum<SendFilesWay>> _sendAlbum = { nullptr };
|
||||
object_ptr<Ui::Radioenum<SendFilesWay>> _sendPhotos = { nullptr };
|
||||
object_ptr<Ui::Radioenum<SendFilesWay>> _sendFiles = { nullptr };
|
||||
std::shared_ptr<Ui::RadioenumGroup<SendFilesWay>> _sendWay;
|
||||
object_ptr<Ui::Radioenum<Ui::SendFilesWay>> _sendAlbum = { nullptr };
|
||||
object_ptr<Ui::Radioenum<Ui::SendFilesWay>> _sendPhotos = { nullptr };
|
||||
object_ptr<Ui::Radioenum<Ui::SendFilesWay>> _sendFiles = { nullptr };
|
||||
std::shared_ptr<Ui::RadioenumGroup<Ui::SendFilesWay>> _sendWay;
|
||||
|
||||
rpl::variable<int> _footerHeight = 0;
|
||||
rpl::event_stream<> _albumChanged;
|
||||
|
||||
QWidget *_preview = nullptr;
|
||||
AlbumPreview *_albumPreview = nullptr;
|
||||
Ui::AlbumPreview *_albumPreview = nullptr;
|
||||
int _albumVideosCount = 0;
|
||||
int _albumPhotosCount = 0;
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/emoji_config.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "ui/widgets/popup_menu.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "lottie/lottie_multi_player.h"
|
||||
#include "lottie/lottie_animation.h"
|
||||
#include "chat_helpers/stickers_lottie.h"
|
||||
|
@ -35,7 +36,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "apiwrap.h"
|
||||
#include "mainwidget.h"
|
||||
#include "mainwindow.h"
|
||||
#include "app.h"
|
||||
#include "styles/style_layers.h"
|
||||
#include "styles/style_chat_helpers.h"
|
||||
#include "styles/style_info.h"
|
||||
|
@ -661,7 +661,7 @@ void StickerSetBox::Inner::paintSticker(
|
|||
p.setOpacity(over);
|
||||
auto tl = position;
|
||||
if (rtl()) tl.setX(width() - tl.x() - st::stickersSize.width());
|
||||
App::roundRect(p, QRect(tl, st::stickersSize), st::emojiPanHover, StickerHoverCorners);
|
||||
Ui::FillRoundRect(p, QRect(tl, st::stickersSize), st::emojiPanHover, Ui::StickerHoverCorners);
|
||||
p.setOpacity(1);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,9 +33,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/widgets/discrete_sliders.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "ui/image/image.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "main/main_session.h"
|
||||
#include "app.h"
|
||||
#include "styles/style_layers.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "styles/style_chat_helpers.h"
|
||||
|
@ -1129,7 +1129,7 @@ void StickersBox::Inner::paintRow(Painter &p, not_null<Row*> row, int index) {
|
|||
Ui::Shadow::paint(p, rect, width(), st::boxRoundShadow);
|
||||
p.setOpacity(1);
|
||||
|
||||
App::roundRect(p, rect, st::boxBg, BoxCorners);
|
||||
Ui::FillRoundRect(p, rect, st::boxBg, Ui::BoxCorners);
|
||||
|
||||
p.setOpacity(1. - current);
|
||||
paintFakeButton(p, row, index);
|
||||
|
@ -1318,7 +1318,7 @@ void StickersBox::Inner::paintFakeButton(Painter &p, not_null<Row*> row, int ind
|
|||
auto textWidth = (_section == Section::Installed) ? _undoWidth : _addWidth;
|
||||
auto &text = (_section == Section::Installed) ? _undoText : _addText;
|
||||
auto &textBg = selected ? st.textBgOver : st.textBg;
|
||||
App::roundRect(p, myrtlrect(rect), textBg, ImageRoundRadius::Small);
|
||||
Ui::FillRoundRect(p, myrtlrect(rect), textBg, ImageRoundRadius::Small);
|
||||
if (row->ripple) {
|
||||
row->ripple->paint(p, rect.x(), rect.y(), width());
|
||||
if (row->ripple->empty()) {
|
||||
|
|
|
@ -12,8 +12,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_user.h"
|
||||
#include "data/data_session.h"
|
||||
#include "main/main_session.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "facades.h"
|
||||
#include "app.h"
|
||||
#include "styles/style_widgets.h"
|
||||
#include "styles/style_chat.h"
|
||||
|
||||
|
@ -76,7 +76,7 @@ void Style::paintButtonBg(
|
|||
Painter &p,
|
||||
const QRect &rect,
|
||||
float64 howMuchOver) const {
|
||||
App::roundRect(p, rect, st::botKbBg, BotKeyboardCorners);
|
||||
Ui::FillRoundRect(p, rect, st::botKbBg, Ui::BotKeyboardCorners);
|
||||
}
|
||||
|
||||
void Style::paintButtonIcon(
|
||||
|
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/widgets/shadow.h"
|
||||
#include "ui/emoji_config.h"
|
||||
#include "ui/ui_utility.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "emoji_suggestions_data.h"
|
||||
#include "emoji_suggestions_helper.h"
|
||||
|
@ -20,7 +21,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "core/application.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "facades.h"
|
||||
#include "app.h"
|
||||
#include "styles/style_chat_helpers.h"
|
||||
|
||||
namespace ChatHelpers {
|
||||
|
@ -211,7 +211,7 @@ void EmojiColorPicker::paintEvent(QPaintEvent *e) {
|
|||
return;
|
||||
}
|
||||
Ui::Shadow::paint(p, inner, width(), st::defaultRoundShadow);
|
||||
App::roundRect(p, inner, st::boxBg, BoxCorners);
|
||||
Ui::FillRoundRect(p, inner, st::boxBg, Ui::BoxCorners);
|
||||
|
||||
auto x = st::emojiPanMargins.left() + 2 * st::emojiColorsPadding + _singleSize.width();
|
||||
if (rtl()) x = width() - x - st::emojiColorsSep;
|
||||
|
@ -372,7 +372,7 @@ void EmojiColorPicker::drawVariant(Painter &p, int variant) {
|
|||
if (variant == _selected) {
|
||||
QPoint tl(w);
|
||||
if (rtl()) tl.setX(width() - tl.x() - _singleSize.width());
|
||||
App::roundRect(p, QRect(tl, _singleSize), st::emojiPanHover, StickerHoverCorners);
|
||||
Ui::FillRoundRect(p, QRect(tl, _singleSize), st::emojiPanHover, Ui::StickerHoverCorners);
|
||||
}
|
||||
const auto esize = Ui::Emoji::GetSizeLarge();
|
||||
Ui::Emoji::Draw(
|
||||
|
@ -558,7 +558,7 @@ void EmojiListWidget::paintEvent(QPaintEvent *e) {
|
|||
if (selected) {
|
||||
auto tl = w;
|
||||
if (rtl()) tl.setX(width() - tl.x() - _singleSize.width());
|
||||
App::roundRect(p, QRect(tl, _singleSize), st::emojiPanHover, StickerHoverCorners);
|
||||
Ui::FillRoundRect(p, QRect(tl, _singleSize), st::emojiPanHover, Ui::StickerHoverCorners);
|
||||
}
|
||||
Ui::Emoji::Draw(
|
||||
p,
|
||||
|
|
|
@ -17,11 +17,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/widgets/input_fields.h"
|
||||
#include "ui/emoji_config.h"
|
||||
#include "ui/ui_utility.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "platform/platform_specific.h"
|
||||
#include "core/application.h"
|
||||
#include "base/event_filter.h"
|
||||
#include "main/main_session.h"
|
||||
#include "app.h"
|
||||
#include "styles/style_chat_helpers.h"
|
||||
|
||||
#include <QtWidgets/QApplication>
|
||||
|
@ -218,11 +218,11 @@ void SuggestionsWidget::paintEvent(QPaintEvent *e) {
|
|||
? _pressed
|
||||
: _selectedAnimation.value(_selected);
|
||||
if (selected > -1.) {
|
||||
App::roundRect(
|
||||
Ui::FillRoundRect(
|
||||
p,
|
||||
QRect(selected * _oneWidth, 0, _oneWidth, _oneWidth),
|
||||
st::emojiPanHover,
|
||||
StickerHoverCorners);
|
||||
Ui::StickerHoverCorners);
|
||||
}
|
||||
|
||||
for (auto i = from; i != till; ++i) {
|
||||
|
|
|
@ -29,10 +29,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/widgets/scroll_area.h"
|
||||
#include "ui/image/image.h"
|
||||
#include "ui/ui_utility.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "facades.h"
|
||||
#include "app.h"
|
||||
#include "styles/style_chat.h"
|
||||
#include "styles/style_widgets.h"
|
||||
#include "styles/style_chat_helpers.h"
|
||||
|
@ -686,7 +686,7 @@ void FieldAutocompleteInner::paintEvent(QPaintEvent *e) {
|
|||
if (_sel == index) {
|
||||
QPoint tl(pos);
|
||||
if (rtl()) tl.setX(width() - tl.x() - st::stickerPanSize.width());
|
||||
App::roundRect(p, QRect(tl, st::stickerPanSize), st::emojiPanHover, StickerHoverCorners);
|
||||
Ui::FillRoundRect(p, QRect(tl, st::stickerPanSize), st::emojiPanHover, Ui::StickerHoverCorners);
|
||||
}
|
||||
|
||||
media->checkStickerSmall();
|
||||
|
|
|
@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/effects/animations.h"
|
||||
#include "ui/effects/ripple_animation.h"
|
||||
#include "ui/image/image.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "lottie/lottie_multi_player.h"
|
||||
#include "lottie/lottie_single_player.h"
|
||||
#include "lottie/lottie_animation.h"
|
||||
|
@ -38,7 +39,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "main/main_session_settings.h"
|
||||
#include "apiwrap.h"
|
||||
#include "api/api_toggling_media.h" // Api::ToggleFavedSticker
|
||||
#include "app.h"
|
||||
#include "styles/style_chat_helpers.h"
|
||||
#include "styles/style_window.h"
|
||||
|
||||
|
@ -1537,7 +1537,7 @@ void StickersListWidget::paintStickers(Painter &p, QRect clip) {
|
|||
auto selected = selectedButton ? (selectedButton->section == info.section) : false;
|
||||
auto &textBg = selected ? st::stickersTrendingAdd.textBgOver : st::stickersTrendingAdd.textBg;
|
||||
|
||||
App::roundRect(p, myrtlrect(add), textBg, ImageRoundRadius::Small);
|
||||
Ui::FillRoundRect(p, myrtlrect(add), textBg, ImageRoundRadius::Small);
|
||||
if (set.ripple) {
|
||||
set.ripple->paint(p, add.x(), add.y(), width());
|
||||
if (set.ripple->empty()) {
|
||||
|
@ -1767,7 +1767,7 @@ void StickersListWidget::paintMegagroupEmptySet(Painter &p, int y, bool buttonSe
|
|||
: st::stickerGroupCategoryAdd.textBg;
|
||||
|
||||
auto button = _megagroupSetButtonRect.translated(0, y);
|
||||
App::roundRect(p, myrtlrect(button), textBg, ImageRoundRadius::Small);
|
||||
Ui::FillRoundRect(p, myrtlrect(button), textBg, ImageRoundRadius::Small);
|
||||
if (_megagroupSetButtonRipple) {
|
||||
_megagroupSetButtonRipple->paint(p, button.x(), button.y(), width());
|
||||
if (_megagroupSetButtonRipple->empty()) {
|
||||
|
@ -1847,7 +1847,7 @@ void StickersListWidget::paintSticker(Painter &p, Set &set, int y, int section,
|
|||
if (selected) {
|
||||
auto tl = pos;
|
||||
if (rtl()) tl.setX(width() - tl.x() - _singleSize.width());
|
||||
App::roundRect(p, QRect(tl, _singleSize), st::emojiPanHover, StickerHoverCorners);
|
||||
Ui::FillRoundRect(p, QRect(tl, _singleSize), st::emojiPanHover, Ui::StickerHoverCorners);
|
||||
}
|
||||
|
||||
media->checkStickerSmall();
|
||||
|
|
|
@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/widgets/popup_menu.h"
|
||||
#include "ui/widgets/scroll_area.h"
|
||||
#include "ui/image/image_prepare.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "main/main_session.h"
|
||||
#include "main/main_session_settings.h"
|
||||
|
@ -521,10 +522,10 @@ void TabbedSelector::paintSlideFrame(Painter &p) {
|
|||
if (_roundRadius > 0) {
|
||||
if (full()) {
|
||||
auto topPart = QRect(0, 0, width(), _tabsSlider->height() + _roundRadius);
|
||||
App::roundRect(p, topPart, st::emojiPanBg, ImageRoundRadius::Small, RectPart::FullTop | RectPart::NoTopBottom);
|
||||
Ui::FillRoundRect(p, topPart, st::emojiPanBg, ImageRoundRadius::Small, RectPart::FullTop | RectPart::NoTopBottom);
|
||||
} else {
|
||||
auto topPart = QRect(0, 0, width(), 3 * _roundRadius);
|
||||
App::roundRect(p, topPart, st::emojiPanBg, ImageRoundRadius::Small, RectPart::FullTop);
|
||||
Ui::FillRoundRect(p, topPart, st::emojiPanBg, ImageRoundRadius::Small, RectPart::FullTop);
|
||||
}
|
||||
} else if (full()) {
|
||||
p.fillRect(0, 0, width(), _tabsSlider->height(), st::emojiPanBg);
|
||||
|
@ -538,15 +539,15 @@ void TabbedSelector::paintContent(Painter &p) {
|
|||
if (_roundRadius > 0) {
|
||||
if (full()) {
|
||||
auto topPart = QRect(0, 0, width(), _tabsSlider->height() + _roundRadius);
|
||||
App::roundRect(p, topPart, st::emojiPanBg, ImageRoundRadius::Small, RectPart::FullTop | RectPart::NoTopBottom);
|
||||
Ui::FillRoundRect(p, topPart, st::emojiPanBg, ImageRoundRadius::Small, RectPart::FullTop | RectPart::NoTopBottom);
|
||||
} else {
|
||||
auto topPart = QRect(0, 0, width(), 3 * _roundRadius);
|
||||
App::roundRect(p, topPart, st::emojiPanBg, ImageRoundRadius::Small, RectPart::FullTop);
|
||||
Ui::FillRoundRect(p, topPart, st::emojiPanBg, ImageRoundRadius::Small, RectPart::FullTop);
|
||||
}
|
||||
|
||||
auto bottomPart = QRect(0, _footerTop - _roundRadius, width(), st::emojiFooterHeight + _roundRadius);
|
||||
auto bottomParts = RectPart::NoTopBottom | RectPart::FullBottom;
|
||||
App::roundRect(p, bottomPart, bottomBg, ImageRoundRadius::Small, bottomParts);
|
||||
Ui::FillRoundRect(p, bottomPart, bottomBg, ImageRoundRadius::Small, bottomParts);
|
||||
} else {
|
||||
if (full()) {
|
||||
p.fillRect(0, 0, width(), _tabsSlider->height(), st::emojiPanBg);
|
||||
|
|
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
#include "boxes/send_files_box.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "ui/chat/attach/attach_common.h"
|
||||
#include "storage/serialize_common.h"
|
||||
#include "window/themes/window_theme.h"
|
||||
#include "window/section_widget.h"
|
||||
|
@ -18,7 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
namespace Core {
|
||||
|
||||
Settings::Settings()
|
||||
: _sendFilesWay(SendFilesWay::Album)
|
||||
: _sendFilesWay(Ui::SendFilesWay::Album)
|
||||
, _sendSubmitWay(Ui::InputSubmitSettings::Enter)
|
||||
, _floatPlayerColumn(Window::Column::Second)
|
||||
, _floatPlayerCorner(RectPart::TopRight)
|
||||
|
@ -309,11 +310,11 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
|
|||
_callAudioDuckingEnabled = (callAudioDuckingEnabled == 1);
|
||||
_lastSeenWarningSeen = (lastSeenWarningSeen == 1);
|
||||
_soundOverrides = std::move(soundOverrides);
|
||||
auto uncheckedSendFilesWay = static_cast<SendFilesWay>(sendFilesWay);
|
||||
auto uncheckedSendFilesWay = static_cast<Ui::SendFilesWay>(sendFilesWay);
|
||||
switch (uncheckedSendFilesWay) {
|
||||
case SendFilesWay::Album:
|
||||
case SendFilesWay::Photos:
|
||||
case SendFilesWay::Files: _sendFilesWay = uncheckedSendFilesWay; break;
|
||||
case Ui::SendFilesWay::Album:
|
||||
case Ui::SendFilesWay::Photos:
|
||||
case Ui::SendFilesWay::Files: _sendFilesWay = uncheckedSendFilesWay; break;
|
||||
}
|
||||
auto uncheckedSendSubmitWay = static_cast<Ui::InputSubmitSettings>(sendSubmitWay);
|
||||
switch (uncheckedSendSubmitWay) {
|
||||
|
@ -469,7 +470,7 @@ void Settings::resetOnLastLogout() {
|
|||
//_themesAccentColors = Window::Theme::AccentColors();
|
||||
|
||||
_lastSeenWarningSeen = false;
|
||||
_sendFilesWay = SendFilesWay::Album;
|
||||
_sendFilesWay = Ui::SendFilesWay::Album;
|
||||
//_sendSubmitWay = Ui::InputSubmitSettings::Enter;
|
||||
_soundOverrides = {};
|
||||
|
||||
|
|
|
@ -10,11 +10,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "window/themes/window_themes_embedded.h"
|
||||
#include "window/window_controls_layout.h"
|
||||
|
||||
enum class SendFilesWay;
|
||||
enum class RectPart;
|
||||
|
||||
namespace Ui {
|
||||
enum class InputSubmitSettings;
|
||||
enum class SendFilesWay;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Window {
|
||||
|
@ -229,10 +229,10 @@ public:
|
|||
[[nodiscard]] bool lastSeenWarningSeen() const {
|
||||
return _lastSeenWarningSeen;
|
||||
}
|
||||
void setSendFilesWay(SendFilesWay way) {
|
||||
void setSendFilesWay(Ui::SendFilesWay way) {
|
||||
_sendFilesWay = way;
|
||||
}
|
||||
[[nodiscard]] SendFilesWay sendFilesWay() const {
|
||||
[[nodiscard]] Ui::SendFilesWay sendFilesWay() const {
|
||||
return _sendFilesWay;
|
||||
}
|
||||
void setSendSubmitWay(Ui::InputSubmitSettings value) {
|
||||
|
@ -515,7 +515,7 @@ private:
|
|||
bool _callAudioDuckingEnabled = true;
|
||||
Window::Theme::AccentColors _themesAccentColors;
|
||||
bool _lastSeenWarningSeen = false;
|
||||
SendFilesWay _sendFilesWay;
|
||||
Ui::SendFilesWay _sendFilesWay;
|
||||
Ui::InputSubmitSettings _sendSubmitWay;
|
||||
base::flat_map<QString, QString> _soundOverrides;
|
||||
bool _exeLaunchWarning = true;
|
||||
|
|
|
@ -118,4 +118,23 @@ bool IsMimeAcceptedForAlbum(const QString &mime) {
|
|||
|| (mime == u"video/quicktime"_q);
|
||||
}
|
||||
|
||||
bool FileIsImage(const QString &name, const QString &mime) {
|
||||
QString lowermime = mime.toLower(), namelower = name.toLower();
|
||||
if (lowermime.startsWith(qstr("image/"))) {
|
||||
return true;
|
||||
} else if (namelower.endsWith(qstr(".bmp"))
|
||||
|| namelower.endsWith(qstr(".jpg"))
|
||||
|| namelower.endsWith(qstr(".jpeg"))
|
||||
|| namelower.endsWith(qstr(".gif"))
|
||||
|| namelower.endsWith(qstr(".webp"))
|
||||
|| namelower.endsWith(qstr(".tga"))
|
||||
|| namelower.endsWith(qstr(".tiff"))
|
||||
|| namelower.endsWith(qstr(".tif"))
|
||||
|| namelower.endsWith(qstr(".psd"))
|
||||
|| namelower.endsWith(qstr(".png"))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace Core
|
||||
|
|
|
@ -36,12 +36,14 @@ private:
|
|||
|
||||
};
|
||||
|
||||
MimeType MimeTypeForName(const QString &mime);
|
||||
MimeType MimeTypeForFile(const QFileInfo &file);
|
||||
MimeType MimeTypeForData(const QByteArray &data);
|
||||
[[nodiscard]] MimeType MimeTypeForName(const QString &mime);
|
||||
[[nodiscard]] MimeType MimeTypeForFile(const QFileInfo &file);
|
||||
[[nodiscard]] MimeType MimeTypeForData(const QByteArray &data);
|
||||
|
||||
bool IsMimeStickerAnimated(const QString &mime);
|
||||
bool IsMimeSticker(const QString &mime);
|
||||
bool IsMimeAcceptedForAlbum(const QString &mime);
|
||||
[[nodiscard]] bool IsMimeStickerAnimated(const QString &mime);
|
||||
[[nodiscard]] bool IsMimeSticker(const QString &mime);
|
||||
[[nodiscard]] bool IsMimeAcceptedForAlbum(const QString &mime);
|
||||
|
||||
[[nodiscard]] bool FileIsImage(const QString &name, const QString &mime);
|
||||
|
||||
} // namespace Core
|
||||
|
|
|
@ -39,6 +39,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "boxes/confirm_box.h"
|
||||
#include "ui/image/image.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/text/format_values.h"
|
||||
#include "base/base_file_utilities.h"
|
||||
#include "mainwindow.h"
|
||||
#include "core/application.h"
|
||||
|
@ -125,25 +126,6 @@ void LaunchWithWarning(
|
|||
|
||||
} // namespace
|
||||
|
||||
bool fileIsImage(const QString &name, const QString &mime) {
|
||||
QString lowermime = mime.toLower(), namelower = name.toLower();
|
||||
if (lowermime.startsWith(qstr("image/"))) {
|
||||
return true;
|
||||
} else if (namelower.endsWith(qstr(".bmp"))
|
||||
|| namelower.endsWith(qstr(".jpg"))
|
||||
|| namelower.endsWith(qstr(".jpeg"))
|
||||
|| namelower.endsWith(qstr(".gif"))
|
||||
|| namelower.endsWith(qstr(".webp"))
|
||||
|| namelower.endsWith(qstr(".tga"))
|
||||
|| namelower.endsWith(qstr(".tiff"))
|
||||
|| namelower.endsWith(qstr(".tif"))
|
||||
|| namelower.endsWith(qstr(".psd"))
|
||||
|| namelower.endsWith(qstr(".png"))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QString FileNameUnsafe(
|
||||
not_null<Main::Session*> session,
|
||||
const QString &title,
|
||||
|
@ -1456,12 +1438,12 @@ uint8 DocumentData::cacheTag() const {
|
|||
|
||||
QString DocumentData::composeNameString() const {
|
||||
if (auto songData = song()) {
|
||||
return ComposeNameString(
|
||||
return Ui::ComposeNameString(
|
||||
_filename,
|
||||
songData->title,
|
||||
songData->performer);
|
||||
}
|
||||
return ComposeNameString(_filename, QString(), QString());
|
||||
return Ui::ComposeNameString(_filename, QString(), QString());
|
||||
}
|
||||
|
||||
LocationType DocumentData::locationType() const {
|
||||
|
@ -1577,7 +1559,7 @@ void DocumentData::setMaybeSupportsStreaming(bool supports) {
|
|||
void DocumentData::recountIsImage() {
|
||||
const auto isImage = !isAnimation()
|
||||
&& !isVideoFile()
|
||||
&& fileIsImage(filename(), mimeString());
|
||||
&& Core::FileIsImage(filename(), mimeString());
|
||||
if (isImage) {
|
||||
_flags |= Flag::ImageType;
|
||||
} else {
|
||||
|
@ -1635,22 +1617,6 @@ void DocumentData::collectLocalData(not_null<DocumentData*> local) {
|
|||
}
|
||||
}
|
||||
|
||||
QString DocumentData::ComposeNameString(
|
||||
const QString &filename,
|
||||
const QString &songTitle,
|
||||
const QString &songPerformer) {
|
||||
if (songTitle.isEmpty() && songPerformer.isEmpty()) {
|
||||
return filename.isEmpty() ? qsl("Unknown File") : filename;
|
||||
}
|
||||
|
||||
if (songPerformer.isEmpty()) {
|
||||
return songTitle;
|
||||
}
|
||||
|
||||
auto trackTitle = (songTitle.isEmpty() ? qsl("Unknown Track") : songTitle);
|
||||
return songPerformer + QString::fromUtf8(" \xe2\x80\x93 ") + trackTitle;
|
||||
}
|
||||
|
||||
namespace Data {
|
||||
|
||||
QString FileExtension(const QString &filepath) {
|
||||
|
|
|
@ -78,8 +78,6 @@ struct VoiceData : public DocumentAdditionalData {
|
|||
char wavemax = 0;
|
||||
};
|
||||
|
||||
bool fileIsImage(const QString &name, const QString &mime);
|
||||
|
||||
namespace Serialize {
|
||||
class Document;
|
||||
} // namespace Serialize;
|
||||
|
@ -228,10 +226,6 @@ public:
|
|||
[[nodiscard]] Storage::Cache::Key cacheKey() const;
|
||||
[[nodiscard]] uint8 cacheTag() const;
|
||||
|
||||
[[nodiscard]] static QString ComposeNameString(
|
||||
const QString &filename,
|
||||
const QString &songTitle,
|
||||
const QString &songPerformer);
|
||||
[[nodiscard]] QString composeNameString() const;
|
||||
|
||||
[[nodiscard]] bool canBeStreamed() const;
|
||||
|
|
|
@ -18,10 +18,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "lang/lang_keys.h"
|
||||
#include "ui/widgets/shadow.h"
|
||||
#include "ui/ui_utility.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "mainwindow.h"
|
||||
#include "apiwrap.h"
|
||||
#include "mainwidget.h"
|
||||
#include "app.h"
|
||||
#include "storage/storage_media_prepare.h"
|
||||
#include "styles/style_chat_helpers.h"
|
||||
#include "styles/style_layers.h"
|
||||
|
@ -315,7 +315,7 @@ void DragArea::paintEvent(QPaintEvent *e) {
|
|||
}
|
||||
|
||||
Ui::Shadow::paint(p, inner, width(), st::boxRoundShadow);
|
||||
App::roundRect(p, inner, st::boxBg, BoxCorners);
|
||||
Ui::FillRoundRect(p, inner, st::boxBg, Ui::BoxCorners);
|
||||
|
||||
p.setPen(anim::pen(
|
||||
st::dragColor,
|
||||
|
|
|
@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/toast/toast.h"
|
||||
#include "ui/text/text_options.h"
|
||||
#include "ui/ui_utility.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "ui/inactive_press.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "window/window_peer_menu.h"
|
||||
|
@ -591,7 +592,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
|
|||
if (!_firstLoading && _botAbout && !_botAbout->info->text.isEmpty() && _botAbout->height > 0) {
|
||||
if (clip.y() < _botAbout->rect.y() + _botAbout->rect.height() && clip.y() + clip.height() > _botAbout->rect.y()) {
|
||||
p.setTextPalette(st::inTextPalette);
|
||||
App::roundRect(p, _botAbout->rect, st::msgInBg, MessageInCorners, &st::msgInShadow);
|
||||
Ui::FillRoundRect(p, _botAbout->rect, st::msgInBg, Ui::MessageInCorners, &st::msgInShadow);
|
||||
|
||||
auto top = _botAbout->rect.top() + st::msgPadding.top();
|
||||
if (!_history->peer->isRepliesChat()) {
|
||||
|
|
|
@ -31,6 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/text/text_utilities.h" // Ui::Text::ToUpper
|
||||
#include "ui/text/format_values.h"
|
||||
#include "ui/chat/message_bar.h"
|
||||
#include "ui/chat/attach/attach_common.h"
|
||||
#include "ui/image/image.h"
|
||||
#include "ui/special_buttons.h"
|
||||
#include "ui/controls/emoji_button.h"
|
||||
|
@ -4193,17 +4194,17 @@ bool HistoryWidget::confirmSendingFiles(
|
|||
_field->setTextWithTags({});
|
||||
box->setConfirmedCallback(crl::guard(this, [=](
|
||||
Ui::PreparedList &&list,
|
||||
SendFilesWay way,
|
||||
Ui::SendFilesWay way,
|
||||
TextWithTags &&caption,
|
||||
Api::SendOptions options,
|
||||
bool ctrlShiftEnter) {
|
||||
if (showSendingFilesError(list)) {
|
||||
return;
|
||||
}
|
||||
const auto type = (way == SendFilesWay::Files)
|
||||
const auto type = (way == Ui::SendFilesWay::Files)
|
||||
? SendMediaType::File
|
||||
: SendMediaType::Photo;
|
||||
const auto album = (way == SendFilesWay::Album)
|
||||
const auto album = (way == Ui::SendFilesWay::Album)
|
||||
? std::make_shared<SendingAlbum>()
|
||||
: nullptr;
|
||||
uploadFilesAfterConfirmation(
|
||||
|
|
|
@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/toast/toast.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/text/text_entity.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_channel.h"
|
||||
|
@ -30,7 +31,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "apiwrap.h"
|
||||
#include "layout.h"
|
||||
#include "facades.h"
|
||||
#include "app.h"
|
||||
#include "styles/style_widgets.h"
|
||||
#include "styles/style_chat.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
|
@ -81,11 +81,11 @@ void KeyboardStyle::paintButtonBg(
|
|||
Painter &p,
|
||||
const QRect &rect,
|
||||
float64 howMuchOver) const {
|
||||
App::roundRect(p, rect, st::msgServiceBg, StickerCorners);
|
||||
Ui::FillRoundRect(p, rect, st::msgServiceBg, Ui::StickerCorners);
|
||||
if (howMuchOver > 0) {
|
||||
auto o = p.opacity();
|
||||
p.setOpacity(o * howMuchOver);
|
||||
App::roundRect(p, rect, st::msgBotKbOverBgAdd, BotKbOverCorners);
|
||||
Ui::FillRoundRect(p, rect, st::msgBotKbOverBgAdd, Ui::BotKbOverCorners);
|
||||
p.setOpacity(o);
|
||||
}
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ QString FastReplyText() {
|
|||
void PaintBubble(Painter &p, QRect rect, int outerWidth, bool selected, bool outbg, RectPart tailSide, RectParts skip) {
|
||||
auto &bg = selected ? (outbg ? st::msgOutBgSelected : st::msgInBgSelected) : (outbg ? st::msgOutBg : st::msgInBg);
|
||||
auto sh = &(selected ? (outbg ? st::msgOutShadowSelected : st::msgInShadowSelected) : (outbg ? st::msgOutShadow : st::msgInShadow));
|
||||
auto cors = selected ? (outbg ? MessageOutSelectedCorners : MessageInSelectedCorners) : (outbg ? MessageOutCorners : MessageInCorners);
|
||||
auto cors = selected ? (outbg ? Ui::MessageOutSelectedCorners : Ui::MessageInSelectedCorners) : (outbg ? Ui::MessageOutCorners : Ui::MessageInCorners);
|
||||
auto parts = RectPart::None | RectPart::NoTopBottom;
|
||||
if (skip & RectPart::Top) {
|
||||
if (skip & RectPart::Bottom) {
|
||||
|
@ -174,7 +174,7 @@ void PaintBubble(Painter &p, QRect rect, int outerWidth, bool selected, bool out
|
|||
} else if (!(skip & RectPart::Bottom)) {
|
||||
parts |= RectPart::FullBottom;
|
||||
}
|
||||
App::roundRect(p, rect, bg, cors, sh, parts);
|
||||
Ui::FillRoundRect(p, rect, bg, cors, sh, parts);
|
||||
}
|
||||
|
||||
void PaintBubble(Painter &p, QRect rect, int outerWidth, bool selected, const std::vector<BubbleSelectionInterval> &selection, bool outbg, RectPart tailSide) {
|
||||
|
@ -1799,10 +1799,10 @@ void Message::drawInfo(
|
|||
auto dateY = infoBottom - st::msgDateFont->height;
|
||||
if (type == InfoDisplayType::Image) {
|
||||
auto dateW = infoW + 2 * st::msgDateImgPadding.x(), dateH = st::msgDateFont->height + 2 * st::msgDateImgPadding.y();
|
||||
App::roundRect(p, dateX - st::msgDateImgPadding.x(), dateY - st::msgDateImgPadding.y(), dateW, dateH, selected ? st::msgDateImgBgSelected : st::msgDateImgBg, selected ? DateSelectedCorners : DateCorners);
|
||||
Ui::FillRoundRect(p, dateX - st::msgDateImgPadding.x(), dateY - st::msgDateImgPadding.y(), dateW, dateH, selected ? st::msgDateImgBgSelected : st::msgDateImgBg, selected ? Ui::DateSelectedCorners : Ui::DateCorners);
|
||||
} else if (type == InfoDisplayType::Background) {
|
||||
auto dateW = infoW + 2 * st::msgDateImgPadding.x(), dateH = st::msgDateFont->height + 2 * st::msgDateImgPadding.y();
|
||||
App::roundRect(p, dateX - st::msgDateImgPadding.x(), dateY - st::msgDateImgPadding.y(), dateW, dateH, selected ? st::msgServiceBgSelected : st::msgServiceBg, selected ? StickerSelectedCorners : StickerCorners);
|
||||
Ui::FillRoundRect(p, dateX - st::msgDateImgPadding.x(), dateY - st::msgDateImgPadding.y(), dateW, dateH, selected ? st::msgServiceBgSelected : st::msgServiceBg, selected ? Ui::StickerSelectedCorners : Ui::StickerCorners);
|
||||
}
|
||||
dateX += timeLeft();
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/text/format_values.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/chat/attach/attach_prepare.h"
|
||||
#include "ui/chat/attach/attach_common.h"
|
||||
#include "ui/special_buttons.h"
|
||||
#include "ui/ui_utility.h"
|
||||
#include "ui/toasts/common_toasts.h"
|
||||
|
@ -635,17 +636,17 @@ bool RepliesWidget::confirmSendingFiles(
|
|||
const auto replyTo = replyToId();
|
||||
box->setConfirmedCallback(crl::guard(this, [=](
|
||||
Ui::PreparedList &&list,
|
||||
SendFilesWay way,
|
||||
Ui::SendFilesWay way,
|
||||
TextWithTags &&caption,
|
||||
Api::SendOptions options,
|
||||
bool ctrlShiftEnter) {
|
||||
if (showSendingFilesError(list)) {
|
||||
return;
|
||||
}
|
||||
const auto type = (way == SendFilesWay::Files)
|
||||
const auto type = (way == Ui::SendFilesWay::Files)
|
||||
? SendMediaType::File
|
||||
: SendMediaType::Photo;
|
||||
const auto album = (way == SendFilesWay::Album)
|
||||
const auto album = (way == Ui::SendFilesWay::Album)
|
||||
? std::make_shared<SendingAlbum>()
|
||||
: nullptr;
|
||||
uploadFilesAfterConfirmation(
|
||||
|
|
|
@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/item_text_options.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "ui/chat/attach/attach_prepare.h"
|
||||
#include "ui/chat/attach/attach_common.h"
|
||||
#include "ui/special_buttons.h"
|
||||
#include "ui/ui_utility.h"
|
||||
#include "ui/toasts/common_toasts.h"
|
||||
|
@ -376,17 +377,17 @@ bool ScheduledWidget::confirmSendingFiles(
|
|||
|
||||
box->setConfirmedCallback(crl::guard(this, [=](
|
||||
Ui::PreparedList &&list,
|
||||
SendFilesWay way,
|
||||
Ui::SendFilesWay way,
|
||||
TextWithTags &&caption,
|
||||
Api::SendOptions options,
|
||||
bool ctrlShiftEnter) {
|
||||
if (showSendingFilesError(list)) {
|
||||
return;
|
||||
}
|
||||
const auto type = (way == SendFilesWay::Files)
|
||||
const auto type = (way == Ui::SendFilesWay::Files)
|
||||
? SendMediaType::File
|
||||
: SendMediaType::Photo;
|
||||
const auto album = (way == SendFilesWay::Album)
|
||||
const auto album = (way == Ui::SendFilesWay::Album)
|
||||
? std::make_shared<SendingAlbum>()
|
||||
: nullptr;
|
||||
uploadFilesAfterConfirmation(
|
||||
|
|
|
@ -18,13 +18,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/view/media/history_view_media_common.h"
|
||||
#include "ui/image/image.h"
|
||||
#include "ui/text/format_values.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "layout.h" // FullSelection
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_document.h"
|
||||
#include "data/data_document_media.h"
|
||||
#include "data/data_media_types.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "app.h"
|
||||
#include "styles/style_chat.h"
|
||||
|
||||
namespace HistoryView {
|
||||
|
@ -306,8 +306,8 @@ void Document::draw(
|
|||
}
|
||||
p.drawPixmap(rthumb.topLeft(), thumb);
|
||||
if (selected) {
|
||||
auto overlayCorners = inWebPage ? SelectedOverlaySmallCorners : SelectedOverlayLargeCorners;
|
||||
App::roundRect(p, rthumb, p.textPalette().selectOverlay, overlayCorners);
|
||||
auto overlayCorners = inWebPage ? Ui::SelectedOverlaySmallCorners : Ui::SelectedOverlayLargeCorners;
|
||||
Ui::FillRoundRect(p, rthumb, p.textPalette().selectOverlay, overlayCorners);
|
||||
}
|
||||
|
||||
if (radial || (!loaded && !_data->loading())) {
|
||||
|
|
|
@ -15,11 +15,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/view/history_view_cursor_state.h"
|
||||
#include "history/view/media/history_view_media_common.h"
|
||||
#include "ui/item_text_options.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "core/ui_integration.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_game.h"
|
||||
#include "data/data_media_types.h"
|
||||
#include "app.h"
|
||||
#include "styles/style_chat.h"
|
||||
|
||||
namespace HistoryView {
|
||||
|
@ -261,7 +261,7 @@ void Game::draw(Painter &p, const QRect &r, TextSelection selection, crl::time m
|
|||
auto gameX = pixwidth - st::msgDateImgDelta - gameW;
|
||||
auto gameY = pixheight - st::msgDateImgDelta - gameH;
|
||||
|
||||
App::roundRect(p, style::rtlrect(gameX, gameY, gameW, gameH, pixwidth), selected ? st::msgDateImgBgSelected : st::msgDateImgBg, selected ? DateSelectedCorners : DateCorners);
|
||||
Ui::FillRoundRect(p, style::rtlrect(gameX, gameY, gameW, gameH, pixwidth), selected ? st::msgDateImgBgSelected : st::msgDateImgBg, selected ? Ui::DateSelectedCorners : Ui::DateCorners);
|
||||
|
||||
p.setFont(st::msgDateFont);
|
||||
p.setPen(st::msgDateImgFg);
|
||||
|
|
|
@ -29,12 +29,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/image/image.h"
|
||||
#include "ui/text/format_values.h"
|
||||
#include "ui/grouped_layout.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_streaming.h"
|
||||
#include "data/data_document.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "data/data_document_media.h"
|
||||
#include "app.h"
|
||||
#include "layout.h" // FullSelection
|
||||
#include "styles/style_chat.h"
|
||||
|
||||
|
@ -343,7 +343,7 @@ void Gif::draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms
|
|||
}
|
||||
}
|
||||
} else if (!isRound) {
|
||||
App::roundShadow(p, 0, 0, paintw, height(), selected ? st::msgInShadowSelected : st::msgInShadow, selected ? InSelectedShadowCorners : InShadowCorners);
|
||||
Ui::FillRoundShadow(p, 0, 0, paintw, height(), selected ? st::msgInShadowSelected : st::msgInShadow, selected ? Ui::InSelectedShadowCorners : Ui::InShadowCorners);
|
||||
}
|
||||
|
||||
auto usex = 0, usew = paintw;
|
||||
|
@ -451,14 +451,14 @@ void Gif::draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms
|
|||
| RectPart::NoTopBottom
|
||||
| (roundTop ? RectPart::Top : RectPart::None)
|
||||
| (roundBottom ? RectPart::Bottom : RectPart::None);
|
||||
App::roundRect(p, rthumb.marginsAdded({ 0, roundTop ? 0 : margin, 0, roundBottom ? 0 : margin }), st::imageBg, roundRadius, parts);
|
||||
Ui::FillRoundRect(p, rthumb.marginsAdded({ 0, roundTop ? 0 : margin, 0, roundBottom ? 0 : margin }), st::imageBg, roundRadius, parts);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selected) {
|
||||
App::complexOverlayRect(p, rthumb, roundRadius, roundCorners);
|
||||
Ui::FillComplexOverlayRect(p, rthumb, roundRadius, roundCorners);
|
||||
}
|
||||
|
||||
if (radial
|
||||
|
@ -553,7 +553,7 @@ void Gif::draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms
|
|||
if (mediaUnread) {
|
||||
statusW += st::mediaUnreadSkip + st::mediaUnreadSize;
|
||||
}
|
||||
App::roundRect(p, style::rtlrect(statusX - st::msgDateImgPadding.x(), statusY - st::msgDateImgPadding.y(), statusW, statusH, width()), selected ? st::msgServiceBgSelected : st::msgServiceBg, selected ? StickerSelectedCorners : StickerCorners);
|
||||
Ui::FillRoundRect(p, style::rtlrect(statusX - st::msgDateImgPadding.x(), statusY - st::msgDateImgPadding.y(), statusW, statusH, width()), selected ? st::msgServiceBgSelected : st::msgServiceBg, selected ? Ui::StickerSelectedCorners : Ui::StickerCorners);
|
||||
p.setFont(st::normalFont);
|
||||
p.setPen(st::msgServiceFg);
|
||||
p.drawTextLeft(statusX, statusY, width(), _statusText, statusW - 2 * st::msgDateImgPadding.x());
|
||||
|
@ -584,7 +584,7 @@ void Gif::draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms
|
|||
int recty = painty;
|
||||
if (rtl()) rectx = width() - rectx - rectw;
|
||||
|
||||
App::roundRect(p, rectx, recty, rectw, recth, selected ? st::msgServiceBgSelected : st::msgServiceBg, selected ? StickerSelectedCorners : StickerCorners);
|
||||
Ui::FillRoundRect(p, rectx, recty, rectw, recth, selected ? st::msgServiceBgSelected : st::msgServiceBg, selected ? Ui::StickerSelectedCorners : Ui::StickerCorners);
|
||||
p.setPen(st::msgServiceFg);
|
||||
rectx += st::msgReplyPadding.left();
|
||||
rectw = innerw;
|
||||
|
@ -677,7 +677,7 @@ void Gif::drawCornerStatus(Painter &p, bool selected, QPoint position) const {
|
|||
const auto statusY = position.y() + st::msgDateImgDelta + padding.y();
|
||||
const auto around = style::rtlrect(statusX - padding.x(), statusY - padding.y(), statusW, statusH, width());
|
||||
const auto statusTextTop = statusY + (cornerDownload ? (((statusH - 2 * st::normalFont->height) / 3) - padding.y()) : 0);
|
||||
App::roundRect(p, around, selected ? st::msgDateImgBgSelected : st::msgDateImgBg, selected ? DateSelectedCorners : DateCorners);
|
||||
Ui::FillRoundRect(p, around, selected ? st::msgDateImgBgSelected : st::msgDateImgBg, selected ? Ui::DateSelectedCorners : Ui::DateCorners);
|
||||
p.setFont(st::normalFont);
|
||||
p.setPen(st::msgDateImgFg);
|
||||
p.drawTextLeft(statusX + addLeft, statusTextTop, width(), text, statusW - 2 * padding.x());
|
||||
|
@ -985,7 +985,7 @@ void Gif::drawGrouped(
|
|||
}
|
||||
|
||||
if (selected) {
|
||||
App::complexOverlayRect(p, geometry, roundRadius, corners);
|
||||
Ui::FillComplexOverlayRect(p, geometry, roundRadius, corners);
|
||||
}
|
||||
|
||||
if (radial
|
||||
|
|
|
@ -15,8 +15,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/view/media/history_view_media_common.h"
|
||||
#include "ui/item_text_options.h"
|
||||
#include "ui/text/format_values.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "data/data_media_types.h"
|
||||
#include "app.h"
|
||||
#include "styles/style_chat.h"
|
||||
|
||||
namespace HistoryView {
|
||||
|
@ -260,7 +260,7 @@ void Invoice::draw(Painter &p, const QRect &r, TextSelection selection, crl::tim
|
|||
auto statusX = st::msgDateImgDelta;
|
||||
auto statusY = st::msgDateImgDelta;
|
||||
|
||||
App::roundRect(p, style::rtlrect(statusX, statusY, statusW, statusH, pixwidth), selected ? st::msgDateImgBgSelected : st::msgDateImgBg, selected ? DateSelectedCorners : DateCorners);
|
||||
Ui::FillRoundRect(p, style::rtlrect(statusX, statusY, statusW, statusH, pixwidth), selected ? st::msgDateImgBgSelected : st::msgDateImgBg, selected ? Ui::DateSelectedCorners : Ui::DateCorners);
|
||||
|
||||
p.setFont(st::msgDateFont);
|
||||
p.setPen(st::msgDateImgFg);
|
||||
|
|
|
@ -16,10 +16,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/view/history_view_cursor_state.h"
|
||||
#include "ui/image/image.h"
|
||||
#include "ui/text/text_options.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "data/data_cloud_file.h"
|
||||
#include "app.h"
|
||||
#include "styles/style_chat.h"
|
||||
|
||||
namespace HistoryView {
|
||||
|
@ -179,7 +179,7 @@ void Location::draw(Painter &p, const QRect &r, TextSelection selection, crl::ti
|
|||
}
|
||||
painth -= painty;
|
||||
} else {
|
||||
App::roundShadow(p, 0, 0, paintw, painth, selected ? st::msgInShadowSelected : st::msgInShadow, selected ? InSelectedShadowCorners : InShadowCorners);
|
||||
Ui::FillRoundShadow(p, 0, 0, paintw, painth, selected ? st::msgInShadowSelected : st::msgInShadow, selected ? Ui::InSelectedShadowCorners : Ui::InShadowCorners);
|
||||
}
|
||||
|
||||
auto roundRadius = ImageRoundRadius::Large;
|
||||
|
@ -191,7 +191,7 @@ void Location::draw(Painter &p, const QRect &r, TextSelection selection, crl::ti
|
|||
const auto &pix = thumbnail->pixSingle(paintw, painth, paintw, painth, roundRadius, roundCorners);
|
||||
p.drawPixmap(rthumb.topLeft(), pix);
|
||||
} else {
|
||||
App::complexLocationRect(p, rthumb, roundRadius, roundCorners);
|
||||
Ui::FillComplexLocationRect(p, rthumb, roundRadius, roundCorners);
|
||||
}
|
||||
const auto paintMarker = [&](const style::icon &icon) {
|
||||
icon.paint(
|
||||
|
@ -203,7 +203,7 @@ void Location::draw(Painter &p, const QRect &r, TextSelection selection, crl::ti
|
|||
paintMarker(st::historyMapPoint);
|
||||
paintMarker(st::historyMapPointInner);
|
||||
if (selected) {
|
||||
App::complexOverlayRect(p, rthumb, roundRadius, roundCorners);
|
||||
Ui::FillComplexOverlayRect(p, rthumb, roundRadius, roundCorners);
|
||||
}
|
||||
|
||||
if (_parent->media() == this) {
|
||||
|
|
|
@ -15,8 +15,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "lottie/lottie_single_player.h"
|
||||
#include "core/application.h"
|
||||
#include "core/core_settings.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "layout.h"
|
||||
#include "app.h"
|
||||
#include "styles/style_chat.h"
|
||||
|
||||
namespace HistoryView {
|
||||
|
@ -206,7 +206,7 @@ void UnwrappedMedia::drawSurrounding(
|
|||
int recty = 0;
|
||||
if (rtl()) rectx = width() - rectx - rectw;
|
||||
|
||||
App::roundRect(p, rectx, recty, rectw, recth, selected ? st::msgServiceBgSelected : st::msgServiceBg, selected ? StickerSelectedCorners : StickerCorners);
|
||||
Ui::FillRoundRect(p, rectx, recty, rectw, recth, selected ? st::msgServiceBgSelected : st::msgServiceBg, selected ? Ui::StickerSelectedCorners : Ui::StickerCorners);
|
||||
p.setPen(st::msgServiceFg);
|
||||
rectx += st::msgReplyPadding.left();
|
||||
rectw -= st::msgReplyPadding.left() + st::msgReplyPadding.right();
|
||||
|
|
|
@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "main/main_session_settings.h"
|
||||
#include "ui/image/image.h"
|
||||
#include "ui/grouped_layout.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_streaming.h"
|
||||
#include "data/data_photo.h"
|
||||
|
@ -28,7 +29,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_file_origin.h"
|
||||
#include "data/data_auto_download.h"
|
||||
#include "core/application.h"
|
||||
#include "app.h"
|
||||
#include "styles/style_chat.h"
|
||||
|
||||
namespace HistoryView {
|
||||
|
@ -249,7 +249,7 @@ void Photo::draw(Painter &p, const QRect &r, TextSelection selection, crl::time
|
|||
rthumb = style::rtlrect(paintx, painty, paintw, painth, width());
|
||||
}
|
||||
} else {
|
||||
App::roundShadow(p, 0, 0, paintw, painth, selected ? st::msgInShadowSelected : st::msgInShadow, selected ? InSelectedShadowCorners : InShadowCorners);
|
||||
Ui::FillRoundShadow(p, 0, 0, paintw, painth, selected ? st::msgInShadowSelected : st::msgInShadow, selected ? Ui::InSelectedShadowCorners : Ui::InShadowCorners);
|
||||
}
|
||||
auto inWebPage = (_parent->media() != this);
|
||||
auto roundRadius = inWebPage ? ImageRoundRadius::Small : ImageRoundRadius::Large;
|
||||
|
@ -272,7 +272,7 @@ void Photo::draw(Painter &p, const QRect &r, TextSelection selection, crl::time
|
|||
}();
|
||||
p.drawPixmap(rthumb.topLeft(), pix);
|
||||
if (selected) {
|
||||
App::complexOverlayRect(p, rthumb, roundRadius, roundCorners);
|
||||
Ui::FillComplexOverlayRect(p, rthumb, roundRadius, roundCorners);
|
||||
}
|
||||
}
|
||||
if (radial || (!loaded && !_data->loading())) {
|
||||
|
@ -505,7 +505,7 @@ void Photo::drawGrouped(
|
|||
p.drawPixmap(geometry.topLeft(), *cache);
|
||||
if (selected) {
|
||||
const auto roundRadius = ImageRoundRadius::Large;
|
||||
App::complexOverlayRect(p, geometry, roundRadius, corners);
|
||||
Ui::FillComplexOverlayRect(p, geometry, roundRadius, corners);
|
||||
}
|
||||
|
||||
const auto displayState = radial
|
||||
|
|
|
@ -17,9 +17,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_file_origin.h"
|
||||
#include "base/qthelp_url.h"
|
||||
#include "ui/text/format_values.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "window/themes/window_theme.h"
|
||||
#include "layout.h" // FullSelection
|
||||
#include "app.h"
|
||||
#include "app.h" // App::pixmapFromImageInPlace.
|
||||
#include "styles/style_chat.h"
|
||||
|
||||
namespace HistoryView {
|
||||
|
@ -139,14 +140,14 @@ void ThemeDocument::draw(Painter &p, const QRect &r, TextSelection selection, cr
|
|||
validateThumbnail();
|
||||
p.drawPixmap(rthumb.topLeft(), _thumbnail);
|
||||
if (selected) {
|
||||
App::complexOverlayRect(p, rthumb, roundRadius, roundCorners);
|
||||
Ui::FillComplexOverlayRect(p, rthumb, roundRadius, roundCorners);
|
||||
}
|
||||
|
||||
auto statusX = paintx + st::msgDateImgDelta + st::msgDateImgPadding.x();
|
||||
auto statusY = painty + st::msgDateImgDelta + st::msgDateImgPadding.y();
|
||||
auto statusW = st::normalFont->width(_statusText) + 2 * st::msgDateImgPadding.x();
|
||||
auto statusH = st::normalFont->height + 2 * st::msgDateImgPadding.y();
|
||||
App::roundRect(p, style::rtlrect(statusX - st::msgDateImgPadding.x(), statusY - st::msgDateImgPadding.y(), statusW, statusH, width()), selected ? st::msgDateImgBgSelected : st::msgDateImgBg, selected ? DateSelectedCorners : DateCorners);
|
||||
Ui::FillRoundRect(p, style::rtlrect(statusX - st::msgDateImgPadding.x(), statusY - st::msgDateImgPadding.y(), statusW, statusH, width()), selected ? st::msgDateImgBgSelected : st::msgDateImgBg, selected ? Ui::DateSelectedCorners : Ui::DateCorners);
|
||||
p.setFont(st::normalFont);
|
||||
p.setPen(st::msgDateImgFg);
|
||||
p.drawTextLeft(statusX, statusY, width(), _statusText, statusW - 2 * st::msgDateImgPadding.x());
|
||||
|
|
|
@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/image/image.h"
|
||||
#include "ui/text/text_options.h"
|
||||
#include "ui/text/format_values.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "layout.h" // FullSelection
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_media_types.h"
|
||||
|
@ -26,7 +27,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_photo.h"
|
||||
#include "data/data_photo_media.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "app.h"
|
||||
#include "styles/style_chat.h"
|
||||
|
||||
namespace HistoryView {
|
||||
|
@ -501,7 +501,7 @@ void WebPage::draw(Painter &p, const QRect &r, TextSelection selection, crl::tim
|
|||
}
|
||||
p.drawPixmapLeft(padding.left() + paintw - pw, tshift, width(), pix);
|
||||
if (selected) {
|
||||
App::roundRect(p, style::rtlrect(padding.left() + paintw - pw, tshift, pw, _pixh, width()), p.textPalette().selectOverlay, SelectedOverlaySmallCorners);
|
||||
Ui::FillRoundRect(p, style::rtlrect(padding.left() + paintw - pw, tshift, pw, _pixh, width()), p.textPalette().selectOverlay, Ui::SelectedOverlaySmallCorners);
|
||||
}
|
||||
paintw -= pw + st::webPagePhotoDelta;
|
||||
}
|
||||
|
@ -569,7 +569,7 @@ void WebPage::draw(Painter &p, const QRect &r, TextSelection selection, crl::tim
|
|||
auto dateW = pixwidth - dateX - st::msgDateImgDelta;
|
||||
auto dateH = pixheight - dateY - st::msgDateImgDelta;
|
||||
|
||||
App::roundRect(p, dateX, dateY, dateW, dateH, selected ? st::msgDateImgBgSelected : st::msgDateImgBg, selected ? DateSelectedCorners : DateCorners);
|
||||
Ui::FillRoundRect(p, dateX, dateY, dateW, dateH, selected ? st::msgDateImgBgSelected : st::msgDateImgBg, selected ? Ui::DateSelectedCorners : Ui::DateCorners);
|
||||
|
||||
p.setFont(st::msgDateFont);
|
||||
p.setPen(st::msgDateImgFg);
|
||||
|
|
|
@ -13,13 +13,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/rp_widget.h"
|
||||
#include "ui/focus_persister.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "window/section_widget.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "window/main_window.h"
|
||||
#include "main/main_session.h"
|
||||
#include "boxes/abstract_box.h"
|
||||
#include "core/application.h"
|
||||
#include "app.h"
|
||||
#include "app.h" // App::quitting.
|
||||
#include "styles/style_info.h"
|
||||
#include "styles/style_window.h"
|
||||
#include "styles/style_layers.h"
|
||||
|
@ -269,11 +270,11 @@ void LayerWidget::paintEvent(QPaintEvent *e) {
|
|||
}
|
||||
}
|
||||
if (parts) {
|
||||
App::roundRect(
|
||||
Ui::FillRoundRect(
|
||||
p,
|
||||
rect(),
|
||||
st::boxBg,
|
||||
BoxCorners,
|
||||
Ui::BoxCorners,
|
||||
nullptr,
|
||||
parts);
|
||||
}
|
||||
|
|
|
@ -25,9 +25,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/view/history_view_cursor_state.h"
|
||||
#include "ui/image/image.h"
|
||||
#include "ui/text/format_values.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "main/main_session.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "app.h"
|
||||
#include "styles/style_overview.h"
|
||||
#include "styles/style_chat.h"
|
||||
#include "styles/style_chat_helpers.h"
|
||||
|
@ -460,7 +460,7 @@ void Sticker::paint(Painter &p, const QRect &clip, const PaintContext *context)
|
|||
auto over = _a_over.value(_active ? 1. : 0.);
|
||||
if (over > 0) {
|
||||
p.setOpacity(over);
|
||||
App::roundRect(p, QRect(QPoint(0, 0), st::stickerPanSize), st::emojiPanHover, StickerHoverCorners);
|
||||
Ui::FillRoundRect(p, QRect(QPoint(0, 0), st::stickerPanSize), st::emojiPanHover, Ui::StickerHoverCorners);
|
||||
p.setOpacity(1);
|
||||
}
|
||||
|
||||
|
@ -734,7 +734,7 @@ void Video::paint(Painter &p, const QRect &clip, const PaintContext *context) co
|
|||
int durationTop = st::inlineRowMargin + st::inlineThumbSize - st::normalFont->height - st::inlineDurationMargin;
|
||||
int durationW = _durationWidth + 2 * st::msgDateImgPadding.x(), durationH = st::normalFont->height + 2 * st::msgDateImgPadding.y();
|
||||
int durationX = (st::inlineThumbSize - durationW) / 2, durationY = st::inlineRowMargin + st::inlineThumbSize - durationH;
|
||||
App::roundRect(p, durationX, durationY - st::msgDateImgPadding.y(), durationW, durationH, st::msgDateImgBg, DateCorners);
|
||||
Ui::FillRoundRect(p, durationX, durationY - st::msgDateImgPadding.y(), durationW, durationH, st::msgDateImgBg, Ui::DateCorners);
|
||||
p.setPen(st::msgDateImgFg);
|
||||
p.setFont(st::normalFont);
|
||||
p.drawText(durationX + st::msgDateImgPadding.x(), durationTop + st::normalFont->ascent, _duration);
|
||||
|
|
|
@ -33,9 +33,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "window/window_session_controller.h"
|
||||
#include "ui/widgets/scroll_area.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "history/view/history_view_cursor_state.h"
|
||||
#include "facades.h"
|
||||
#include "app.h"
|
||||
#include "styles/style_chat_helpers.h"
|
||||
|
||||
#include <QtWidgets/QApplication>
|
||||
|
@ -905,7 +905,7 @@ void Widget::paintEvent(QPaintEvent *e) {
|
|||
|
||||
void Widget::paintContent(Painter &p) {
|
||||
auto inner = innerRect();
|
||||
App::roundRect(p, inner, st::emojiPanBg, ImageRoundRadius::Small, RectPart::FullTop | RectPart::FullBottom);
|
||||
Ui::FillRoundRect(p, inner, st::emojiPanBg, ImageRoundRadius::Small, RectPart::FullTop | RectPart::FullBottom);
|
||||
|
||||
auto horizontal = horizontalRect();
|
||||
auto sidesTop = horizontal.y();
|
||||
|
|
|
@ -18,7 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "media/audio/media_audio.h"
|
||||
#include "storage/localstorage.h"
|
||||
#include "history/view/history_view_cursor_state.h"
|
||||
#include "app.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
|
||||
int32 documentColorIndex(DocumentData *document, QString &ext) {
|
||||
auto colorIndex = 0;
|
||||
|
@ -118,8 +118,8 @@ style::color documentSelectedColor(int32 colorIndex) {
|
|||
return colors[colorIndex & 3];
|
||||
}
|
||||
|
||||
RoundCorners documentCorners(int32 colorIndex) {
|
||||
return RoundCorners(Doc1Corners + (colorIndex & 3));
|
||||
Ui::CachedRoundCorners documentCorners(int32 colorIndex) {
|
||||
return Ui::CachedRoundCorners(Ui::Doc1Corners + (colorIndex & 3));
|
||||
}
|
||||
|
||||
[[nodiscard]] HistoryView::TextState LayoutItemBase::getState(
|
||||
|
|
|
@ -14,7 +14,9 @@ struct TextState;
|
|||
struct StateRequest;
|
||||
} // namespace HistoryView
|
||||
|
||||
enum RoundCorners : int;
|
||||
namespace Ui {
|
||||
enum CachedRoundCorners : int;
|
||||
} // namespace Ui
|
||||
|
||||
constexpr auto FullSelection = TextSelection { 0xFFFF, 0xFFFF };
|
||||
|
||||
|
@ -57,7 +59,7 @@ style::color documentColor(int colorIndex);
|
|||
style::color documentDarkColor(int colorIndex);
|
||||
style::color documentOverColor(int colorIndex);
|
||||
style::color documentSelectedColor(int colorIndex);
|
||||
RoundCorners documentCorners(int colorIndex);
|
||||
Ui::CachedRoundCorners documentCorners(int colorIndex);
|
||||
|
||||
class PaintContextBase {
|
||||
public:
|
||||
|
|
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
#include "chat_helpers/tabbed_selector.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "ui/chat/attach/attach_common.h"
|
||||
#include "window/section_widget.h"
|
||||
#include "support/support_common.h"
|
||||
#include "storage/serialize_common.h"
|
||||
|
@ -367,11 +368,11 @@ void SessionSettings::addFromSerialized(const QByteArray &serialized) {
|
|||
for (const auto &[key, value] : appSoundOverrides) {
|
||||
app.setSoundOverride(key, value);
|
||||
}
|
||||
auto uncheckedSendFilesWay = static_cast<SendFilesWay>(appSendFilesWay);
|
||||
auto uncheckedSendFilesWay = static_cast<Ui::SendFilesWay>(appSendFilesWay);
|
||||
switch (uncheckedSendFilesWay) {
|
||||
case SendFilesWay::Album:
|
||||
case SendFilesWay::Photos:
|
||||
case SendFilesWay::Files: app.setSendFilesWay(uncheckedSendFilesWay); break;
|
||||
case Ui::SendFilesWay::Album:
|
||||
case Ui::SendFilesWay::Photos:
|
||||
case Ui::SendFilesWay::Files: app.setSendFilesWay(uncheckedSendFilesWay); break;
|
||||
}
|
||||
auto uncheckedSendSubmitWay = static_cast<Ui::InputSubmitSettings>(
|
||||
appSendSubmitWay);
|
||||
|
|
|
@ -19,9 +19,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/widgets/shadow.h"
|
||||
#include "ui/widgets/scroll_area.h"
|
||||
#include "ui/ui_utility.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "mainwindow.h"
|
||||
#include "main/main_session.h"
|
||||
#include "app.h"
|
||||
#include "styles/style_overview.h"
|
||||
#include "styles/style_widgets.h"
|
||||
#include "styles/style_media_player.h"
|
||||
|
@ -159,7 +159,7 @@ void Panel::paintEvent(QPaintEvent *e) {
|
|||
| RectPart::Top;
|
||||
Ui::Shadow::paint(p, shadowedRect, width(), st::defaultRoundShadow, shadowedSides);
|
||||
auto parts = RectPart::Full;
|
||||
App::roundRect(p, shadowedRect, st::menuBg, MenuCorners, nullptr, parts);
|
||||
Ui::FillRoundRect(p, shadowedRect, st::menuBg, Ui::MenuCorners, nullptr, parts);
|
||||
}
|
||||
|
||||
void Panel::enterEventHook(QEvent *e) {
|
||||
|
|
|
@ -12,13 +12,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/widgets/shadow.h"
|
||||
#include "ui/widgets/continuous_sliders.h"
|
||||
#include "ui/ui_utility.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "base/object_ptr.h"
|
||||
#include "mainwindow.h"
|
||||
#include "main/main_session.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "core/application.h"
|
||||
#include "core/core_settings.h"
|
||||
#include "app.h"
|
||||
#include "styles/style_media_player.h"
|
||||
#include "styles/style_widgets.h"
|
||||
|
||||
|
@ -146,7 +146,7 @@ void VolumeWidget::paintEvent(QPaintEvent *e) {
|
|||
auto shadowedSides = RectPart::Left | RectPart::Right | RectPart::Bottom;
|
||||
Ui::Shadow::paint(p, shadowedRect, width(), st::defaultRoundShadow, shadowedSides);
|
||||
auto parts = RectPart::NoTopBottom | RectPart::FullBottom;
|
||||
App::roundRect(p, QRect(shadowedRect.x(), -st::buttonRadius, shadowedRect.width(), shadowedRect.y() + shadowedRect.height() + st::buttonRadius), st::menuBg, MenuCorners, nullptr, parts);
|
||||
Ui::FillRoundRect(p, QRect(shadowedRect.x(), -st::buttonRadius, shadowedRect.width(), shadowedRect.y() + shadowedRect.height() + st::buttonRadius), st::menuBg, Ui::MenuCorners, nullptr, parts);
|
||||
}
|
||||
|
||||
void VolumeWidget::enterEventHook(QEvent *e) {
|
||||
|
|
|
@ -25,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/text/format_values.h"
|
||||
#include "ui/item_text_options.h"
|
||||
#include "ui/ui_utility.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "media/audio/media_audio.h"
|
||||
#include "media/view/media_view_playback_controls.h"
|
||||
|
@ -3014,7 +3015,7 @@ void OverlayWidget::paintEvent(QPaintEvent *e) {
|
|||
_saveMsgOpacity.update(qMin(progress, 1.), anim::linear);
|
||||
if (_saveMsgOpacity.current() > 0) {
|
||||
p.setOpacity(_saveMsgOpacity.current());
|
||||
App::roundRect(p, _saveMsg, st::mediaviewSaveMsgBg, MediaviewSaveCorners);
|
||||
Ui::FillRoundRect(p, _saveMsg, st::mediaviewSaveMsgBg, Ui::MediaviewSaveCorners);
|
||||
st::mediaviewSaveMsgCheck.paint(p, _saveMsg.topLeft() + st::mediaviewSaveMsgCheckPos, width());
|
||||
|
||||
p.setPen(st::mediaviewSaveMsgFg);
|
||||
|
|
|
@ -15,8 +15,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/popup_menu.h"
|
||||
#include "ui/text/format_values.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "app.h"
|
||||
#include "styles/style_media_view.h"
|
||||
|
||||
namespace Media {
|
||||
|
@ -429,7 +429,7 @@ void PlaybackControls::paintEvent(QPaintEvent *e) {
|
|||
_volumeController->setFadeOpacity(1.);
|
||||
_childrenHidden = false;
|
||||
}
|
||||
App::roundRect(p, rect(), st::mediaviewSaveMsgBg, MediaviewSaveCorners);
|
||||
Ui::FillRoundRect(p, rect(), st::mediaviewSaveMsgBg, Ui::MediaviewSaveCorners);
|
||||
}
|
||||
|
||||
void PlaybackControls::mousePressEvent(QMouseEvent *e) {
|
||||
|
|
|
@ -38,6 +38,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/image/image.h"
|
||||
#include "ui/text/format_values.h"
|
||||
#include "ui/text/text_options.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "app.h"
|
||||
|
||||
namespace Overview {
|
||||
|
@ -501,7 +502,7 @@ void Video::paint(Painter &p, const QRect &clip, TextSelection selection, const
|
|||
const auto statusW = icon.width() + padding.x() + st::normalFont->width(text) + 2 * padding.x();
|
||||
const auto statusH = st::normalFont->height + 2 * padding.y();
|
||||
p.setOpacity(1. - radialOpacity);
|
||||
App::roundRect(p, statusX - padding.x(), statusY - padding.y(), statusW, statusH, selected ? st::msgDateImgBgSelected : st::msgDateImgBg, selected ? OverviewVideoSelectedCorners : OverviewVideoCorners);
|
||||
Ui::FillRoundRect(p, statusX - padding.x(), statusY - padding.y(), statusW, statusH, selected ? st::msgDateImgBgSelected : st::msgDateImgBg, selected ? Ui::OverviewVideoSelectedCorners : Ui::OverviewVideoCorners);
|
||||
p.setFont(st::normalFont);
|
||||
p.setPen(st::msgDateImgFg);
|
||||
icon.paint(p, statusX, statusY + (st::normalFont->height - icon.height()) / 2, _width);
|
||||
|
@ -1658,19 +1659,19 @@ void Link::validateThumbnail() {
|
|||
const auto index = _letter.isEmpty()
|
||||
? 0
|
||||
: (_letter[0].unicode() % 4);
|
||||
const auto fill = [&](style::color color, RoundCorners corners) {
|
||||
const auto fill = [&](style::color color, Ui::CachedRoundCorners corners) {
|
||||
auto pixRect = QRect(
|
||||
0,
|
||||
0,
|
||||
st::linksPhotoSize,
|
||||
st::linksPhotoSize);
|
||||
App::roundRect(p, pixRect, color, corners);
|
||||
Ui::FillRoundRect(p, pixRect, color, corners);
|
||||
};
|
||||
switch (index) {
|
||||
case 0: fill(st::msgFile1Bg, Doc1Corners); break;
|
||||
case 1: fill(st::msgFile2Bg, Doc2Corners); break;
|
||||
case 2: fill(st::msgFile3Bg, Doc3Corners); break;
|
||||
case 3: fill(st::msgFile4Bg, Doc4Corners); break;
|
||||
case 0: fill(st::msgFile1Bg, Ui::Doc1Corners); break;
|
||||
case 1: fill(st::msgFile2Bg, Ui::Doc2Corners); break;
|
||||
case 2: fill(st::msgFile3Bg, Ui::Doc3Corners); break;
|
||||
case 3: fill(st::msgFile4Bg, Ui::Doc4Corners); break;
|
||||
}
|
||||
|
||||
if (!_letter.isEmpty()) {
|
||||
|
|
|
@ -18,10 +18,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/widgets/labels.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/scroll_area.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "boxes/abstract_box.h"
|
||||
#include "window/window_controller.h"
|
||||
#include "app.h"
|
||||
#include "styles/style_settings.h"
|
||||
#include "styles/style_layers.h"
|
||||
#include "styles/style_info.h"
|
||||
|
@ -524,11 +524,11 @@ void LayerWidget::paintEvent(QPaintEvent *e) {
|
|||
parts |= RectPart::FullBottom;
|
||||
}
|
||||
if (parts) {
|
||||
App::roundRect(
|
||||
Ui::FillRoundRect(
|
||||
p,
|
||||
rect(),
|
||||
st::boxBg,
|
||||
BoxCorners,
|
||||
Ui::BoxCorners,
|
||||
nullptr,
|
||||
parts);
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/wrap/vertical_layout.h"
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "ui/image/image_prepare.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "window/section_widget.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "boxes/peer_list_controllers.h"
|
||||
|
@ -859,7 +860,7 @@ void ForwardsPrivacyController::PaintForwardedTooltip(
|
|||
const auto arrowLeft = arrowLeft2;
|
||||
const auto geometry = rect.translated(left, top);
|
||||
|
||||
App::roundRect(p, geometry, st::toastBg, ImageRoundRadius::Small);
|
||||
Ui::FillRoundRect(p, geometry, st::toastBg, ImageRoundRadius::Small);
|
||||
|
||||
p.setFont(font);
|
||||
p.setPen(st::toastFg);
|
||||
|
|
|
@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "mtproto/mtproto_config.h"
|
||||
#include "ui/effects/animation_value.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "ui/chat/attach/attach_common.h"
|
||||
#include "window/themes/window_theme.h"
|
||||
#include "core/update_checker.h"
|
||||
#include "platform/platform_specific.h"
|
||||
|
@ -918,8 +919,8 @@ bool ReadSetting(
|
|||
if (!CheckStreamStatus(stream)) return false;
|
||||
|
||||
Core::App().settings().setSendFilesWay((v == 1)
|
||||
? SendFilesWay::Album
|
||||
: SendFilesWay::Files);
|
||||
? Ui::SendFilesWay::Album
|
||||
: Ui::SendFilesWay::Files);
|
||||
context.legacyRead = true;
|
||||
} break;
|
||||
|
||||
|
|
255
Telegram/SourceFiles/ui/cached_round_corners.cpp
Normal file
255
Telegram/SourceFiles/ui/cached_round_corners.cpp
Normal file
|
@ -0,0 +1,255 @@
|
|||
/*
|
||||
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 "ui/cached_round_corners.h"
|
||||
|
||||
#include "ui/ui_utility.h"
|
||||
#include "ui/image/image_prepare.h"
|
||||
#include "styles/style_chat.h"
|
||||
#include "styles/style_layers.h"
|
||||
#include "styles/style_overview.h"
|
||||
#include "styles/style_media_view.h"
|
||||
#include "styles/style_chat_helpers.h"
|
||||
|
||||
namespace Ui {
|
||||
namespace {
|
||||
|
||||
struct CornersPixmaps {
|
||||
QPixmap p[4];
|
||||
};
|
||||
std::vector<CornersPixmaps> Corners;
|
||||
base::flat_map<uint32, CornersPixmaps> CornersMap;
|
||||
QImage CornersMaskLarge[4], CornersMaskSmall[4];
|
||||
rpl::lifetime PaletteChangedLifetime;
|
||||
|
||||
void PrepareCorners(CachedRoundCorners index, int32 radius, const QBrush &brush, const style::color *shadow = nullptr, QImage *cors = nullptr) {
|
||||
Expects(Corners.size() > index);
|
||||
|
||||
int32 r = radius * style::DevicePixelRatio(), s = st::msgShadow * style::DevicePixelRatio();
|
||||
QImage rect(r * 3, r * 3 + (shadow ? s : 0), QImage::Format_ARGB32_Premultiplied), localCors[4];
|
||||
{
|
||||
Painter p(&rect);
|
||||
PainterHighQualityEnabler hq(p);
|
||||
|
||||
p.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
p.fillRect(QRect(0, 0, rect.width(), rect.height()), Qt::transparent);
|
||||
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||
p.setPen(Qt::NoPen);
|
||||
if (shadow) {
|
||||
p.setBrush((*shadow)->b);
|
||||
p.drawRoundedRect(0, s, r * 3, r * 3, r, r);
|
||||
}
|
||||
p.setBrush(brush);
|
||||
p.drawRoundedRect(0, 0, r * 3, r * 3, r, r);
|
||||
}
|
||||
if (!cors) cors = localCors;
|
||||
cors[0] = rect.copy(0, 0, r, r);
|
||||
cors[1] = rect.copy(r * 2, 0, r, r);
|
||||
cors[2] = rect.copy(0, r * 2, r, r + (shadow ? s : 0));
|
||||
cors[3] = rect.copy(r * 2, r * 2, r, r + (shadow ? s : 0));
|
||||
if (index != SmallMaskCorners && index != LargeMaskCorners) {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
Corners[index].p[i] = PixmapFromImage(std::move(cors[i]));
|
||||
Corners[index].p[i].setDevicePixelRatio(style::DevicePixelRatio());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CreateMaskCorners() {
|
||||
QImage mask[4];
|
||||
PrepareCorners(SmallMaskCorners, st::buttonRadius, QColor(255, 255, 255), nullptr, mask);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
CornersMaskSmall[i] = mask[i].convertToFormat(QImage::Format_ARGB32_Premultiplied);
|
||||
CornersMaskSmall[i].setDevicePixelRatio(style::DevicePixelRatio());
|
||||
}
|
||||
PrepareCorners(LargeMaskCorners, st::historyMessageRadius, QColor(255, 255, 255), nullptr, mask);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
CornersMaskLarge[i] = mask[i].convertToFormat(QImage::Format_ARGB32_Premultiplied);
|
||||
CornersMaskLarge[i].setDevicePixelRatio(style::DevicePixelRatio());
|
||||
}
|
||||
}
|
||||
|
||||
void CreatePaletteCorners() {
|
||||
PrepareCorners(MenuCorners, st::buttonRadius, st::menuBg);
|
||||
PrepareCorners(BoxCorners, st::boxRadius, st::boxBg);
|
||||
PrepareCorners(BotKbOverCorners, st::dateRadius, st::msgBotKbOverBgAdd);
|
||||
PrepareCorners(StickerCorners, st::dateRadius, st::msgServiceBg);
|
||||
PrepareCorners(StickerSelectedCorners, st::dateRadius, st::msgServiceBgSelected);
|
||||
PrepareCorners(SelectedOverlaySmallCorners, st::buttonRadius, st::msgSelectOverlay);
|
||||
PrepareCorners(SelectedOverlayLargeCorners, st::historyMessageRadius, st::msgSelectOverlay);
|
||||
PrepareCorners(DateCorners, st::dateRadius, st::msgDateImgBg);
|
||||
PrepareCorners(DateSelectedCorners, st::dateRadius, st::msgDateImgBgSelected);
|
||||
PrepareCorners(OverviewVideoCorners, st::overviewVideoStatusRadius, st::msgDateImgBg);
|
||||
PrepareCorners(OverviewVideoSelectedCorners, st::overviewVideoStatusRadius, st::msgDateImgBgSelected);
|
||||
PrepareCorners(InShadowCorners, st::historyMessageRadius, st::msgInShadow);
|
||||
PrepareCorners(InSelectedShadowCorners, st::historyMessageRadius, st::msgInShadowSelected);
|
||||
PrepareCorners(ForwardCorners, st::historyMessageRadius, st::historyForwardChooseBg);
|
||||
PrepareCorners(MediaviewSaveCorners, st::mediaviewControllerRadius, st::mediaviewSaveMsgBg);
|
||||
PrepareCorners(EmojiHoverCorners, st::buttonRadius, st::emojiPanHover);
|
||||
PrepareCorners(StickerHoverCorners, st::buttonRadius, st::emojiPanHover);
|
||||
PrepareCorners(BotKeyboardCorners, st::buttonRadius, st::botKbBg);
|
||||
PrepareCorners(PhotoSelectOverlayCorners, st::buttonRadius, st::overviewPhotoSelectOverlay);
|
||||
|
||||
PrepareCorners(Doc1Corners, st::buttonRadius, st::msgFile1Bg);
|
||||
PrepareCorners(Doc2Corners, st::buttonRadius, st::msgFile2Bg);
|
||||
PrepareCorners(Doc3Corners, st::buttonRadius, st::msgFile3Bg);
|
||||
PrepareCorners(Doc4Corners, st::buttonRadius, st::msgFile4Bg);
|
||||
|
||||
PrepareCorners(MessageInCorners, st::historyMessageRadius, st::msgInBg, &st::msgInShadow);
|
||||
PrepareCorners(MessageInSelectedCorners, st::historyMessageRadius, st::msgInBgSelected, &st::msgInShadowSelected);
|
||||
PrepareCorners(MessageOutCorners, st::historyMessageRadius, st::msgOutBg, &st::msgOutShadow);
|
||||
PrepareCorners(MessageOutSelectedCorners, st::historyMessageRadius, st::msgOutBgSelected, &st::msgOutShadowSelected);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void StartCachedCorners() {
|
||||
Corners.resize(RoundCornersCount);
|
||||
CreateMaskCorners();
|
||||
CreatePaletteCorners();
|
||||
|
||||
style::PaletteChanged(
|
||||
) | rpl::start_with_next([=] {
|
||||
CreatePaletteCorners();
|
||||
}, PaletteChangedLifetime);
|
||||
}
|
||||
|
||||
void FinishCachedCorners() {
|
||||
Corners.clear();
|
||||
CornersMap.clear();
|
||||
PaletteChangedLifetime.destroy();
|
||||
}
|
||||
|
||||
void RectWithCorners(Painter &p, QRect rect, const style::color &bg, CachedRoundCorners index, RectParts corners) {
|
||||
auto parts = RectPart::Top
|
||||
| RectPart::NoTopBottom
|
||||
| RectPart::Bottom
|
||||
| corners;
|
||||
FillRoundRect(p, rect, bg, index, nullptr, parts);
|
||||
if ((corners & RectPart::AllCorners) != RectPart::AllCorners) {
|
||||
const auto size = Corners[index].p[0].width() / style::DevicePixelRatio();
|
||||
if (!(corners & RectPart::TopLeft)) {
|
||||
p.fillRect(rect.x(), rect.y(), size, size, bg);
|
||||
}
|
||||
if (!(corners & RectPart::TopRight)) {
|
||||
p.fillRect(rect.x() + rect.width() - size, rect.y(), size, size, bg);
|
||||
}
|
||||
if (!(corners & RectPart::BottomLeft)) {
|
||||
p.fillRect(rect.x(), rect.y() + rect.height() - size, size, size, bg);
|
||||
}
|
||||
if (!(corners & RectPart::BottomRight)) {
|
||||
p.fillRect(rect.x() + rect.width() - size, rect.y() + rect.height() - size, size, size, bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FillComplexOverlayRect(Painter &p, QRect rect, ImageRoundRadius radius, RectParts corners) {
|
||||
if (radius == ImageRoundRadius::Ellipse) {
|
||||
PainterHighQualityEnabler hq(p);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(p.textPalette().selectOverlay);
|
||||
p.drawEllipse(rect);
|
||||
} else {
|
||||
auto overlayCorners = (radius == ImageRoundRadius::Small)
|
||||
? SelectedOverlaySmallCorners
|
||||
: SelectedOverlayLargeCorners;
|
||||
const auto bg = p.textPalette().selectOverlay;
|
||||
RectWithCorners(p, rect, bg, overlayCorners, corners);
|
||||
}
|
||||
}
|
||||
|
||||
void FillComplexLocationRect(Painter &p, QRect rect, ImageRoundRadius radius, RectParts corners) {
|
||||
RectWithCorners(p, rect, st::msgInBg, MessageInCorners, corners);
|
||||
}
|
||||
|
||||
void FillRoundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, const CornersPixmaps &corner, const style::color *shadow, RectParts parts) {
|
||||
auto cornerWidth = corner.p[0].width() / style::DevicePixelRatio();
|
||||
auto cornerHeight = corner.p[0].height() / style::DevicePixelRatio();
|
||||
if (w < 2 * cornerWidth || h < 2 * cornerHeight) return;
|
||||
if (w > 2 * cornerWidth) {
|
||||
if (parts & RectPart::Top) {
|
||||
p.fillRect(x + cornerWidth, y, w - 2 * cornerWidth, cornerHeight, bg);
|
||||
}
|
||||
if (parts & RectPart::Bottom) {
|
||||
p.fillRect(x + cornerWidth, y + h - cornerHeight, w - 2 * cornerWidth, cornerHeight, bg);
|
||||
if (shadow) {
|
||||
p.fillRect(x + cornerWidth, y + h, w - 2 * cornerWidth, st::msgShadow, *shadow);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (h > 2 * cornerHeight) {
|
||||
if ((parts & RectPart::NoTopBottom) == RectPart::NoTopBottom) {
|
||||
p.fillRect(x, y + cornerHeight, w, h - 2 * cornerHeight, bg);
|
||||
} else {
|
||||
if (parts & RectPart::Left) {
|
||||
p.fillRect(x, y + cornerHeight, cornerWidth, h - 2 * cornerHeight, bg);
|
||||
}
|
||||
if ((parts & RectPart::Center) && w > 2 * cornerWidth) {
|
||||
p.fillRect(x + cornerWidth, y + cornerHeight, w - 2 * cornerWidth, h - 2 * cornerHeight, bg);
|
||||
}
|
||||
if (parts & RectPart::Right) {
|
||||
p.fillRect(x + w - cornerWidth, y + cornerHeight, cornerWidth, h - 2 * cornerHeight, bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (parts & RectPart::TopLeft) {
|
||||
p.drawPixmap(x, y, corner.p[0]);
|
||||
}
|
||||
if (parts & RectPart::TopRight) {
|
||||
p.drawPixmap(x + w - cornerWidth, y, corner.p[1]);
|
||||
}
|
||||
if (parts & RectPart::BottomLeft) {
|
||||
p.drawPixmap(x, y + h - cornerHeight, corner.p[2]);
|
||||
}
|
||||
if (parts & RectPart::BottomRight) {
|
||||
p.drawPixmap(x + w - cornerWidth, y + h - cornerHeight, corner.p[3]);
|
||||
}
|
||||
}
|
||||
|
||||
void FillRoundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, CachedRoundCorners index, const style::color *shadow, RectParts parts) {
|
||||
FillRoundRect(p, x, y, w, h, bg, Corners[index], shadow, parts);
|
||||
}
|
||||
|
||||
void FillRoundShadow(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color shadow, CachedRoundCorners index, RectParts parts) {
|
||||
auto &corner = Corners[index];
|
||||
auto cornerWidth = corner.p[0].width() / style::DevicePixelRatio();
|
||||
auto cornerHeight = corner.p[0].height() / style::DevicePixelRatio();
|
||||
if (parts & RectPart::Bottom) {
|
||||
p.fillRect(x + cornerWidth, y + h, w - 2 * cornerWidth, st::msgShadow, shadow);
|
||||
}
|
||||
if (parts & RectPart::BottomLeft) {
|
||||
p.fillRect(x, y + h - cornerHeight, cornerWidth, st::msgShadow, shadow);
|
||||
p.drawPixmap(x, y + h - cornerHeight + st::msgShadow, corner.p[2]);
|
||||
}
|
||||
if (parts & RectPart::BottomRight) {
|
||||
p.fillRect(x + w - cornerWidth, y + h - cornerHeight, cornerWidth, st::msgShadow, shadow);
|
||||
p.drawPixmap(x + w - cornerWidth, y + h - cornerHeight + st::msgShadow, corner.p[3]);
|
||||
}
|
||||
}
|
||||
|
||||
void FillRoundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, ImageRoundRadius radius, RectParts parts) {
|
||||
auto colorKey = ((uint32(bg->c.alpha()) & 0xFF) << 24) | ((uint32(bg->c.red()) & 0xFF) << 16) | ((uint32(bg->c.green()) & 0xFF) << 8) | ((uint32(bg->c.blue()) & 0xFF) << 24);
|
||||
auto i = CornersMap.find(colorKey);
|
||||
if (i == CornersMap.cend()) {
|
||||
QImage images[4];
|
||||
switch (radius) {
|
||||
case ImageRoundRadius::Small: PrepareCorners(SmallMaskCorners, st::buttonRadius, bg, nullptr, images); break;
|
||||
case ImageRoundRadius::Large: PrepareCorners(LargeMaskCorners, st::historyMessageRadius, bg, nullptr, images); break;
|
||||
default: p.fillRect(x, y, w, h, bg); return;
|
||||
}
|
||||
|
||||
CornersPixmaps pixmaps;
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
pixmaps.p[j] = PixmapFromImage(std::move(images[j]));
|
||||
pixmaps.p[j].setDevicePixelRatio(style::DevicePixelRatio());
|
||||
}
|
||||
i = CornersMap.emplace(colorKey, pixmaps).first;
|
||||
}
|
||||
FillRoundRect(p, x, y, w, h, bg, i->second, nullptr, parts);
|
||||
}
|
||||
|
||||
} // namespace Ui
|
75
Telegram/SourceFiles/ui/cached_round_corners.h
Normal file
75
Telegram/SourceFiles/ui/cached_round_corners.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
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/rect_part.h"
|
||||
|
||||
class Painter;
|
||||
|
||||
enum class ImageRoundRadius;
|
||||
|
||||
namespace Ui {
|
||||
|
||||
enum CachedRoundCorners : int {
|
||||
SmallMaskCorners = 0x00, // for images
|
||||
LargeMaskCorners,
|
||||
|
||||
BoxCorners,
|
||||
MenuCorners,
|
||||
BotKbOverCorners,
|
||||
StickerCorners,
|
||||
StickerSelectedCorners,
|
||||
SelectedOverlaySmallCorners,
|
||||
SelectedOverlayLargeCorners,
|
||||
DateCorners,
|
||||
DateSelectedCorners,
|
||||
OverviewVideoCorners,
|
||||
OverviewVideoSelectedCorners,
|
||||
ForwardCorners,
|
||||
MediaviewSaveCorners,
|
||||
EmojiHoverCorners,
|
||||
StickerHoverCorners,
|
||||
BotKeyboardCorners,
|
||||
PhotoSelectOverlayCorners,
|
||||
|
||||
Doc1Corners,
|
||||
Doc2Corners,
|
||||
Doc3Corners,
|
||||
Doc4Corners,
|
||||
|
||||
InShadowCorners, // for photos without bg
|
||||
InSelectedShadowCorners,
|
||||
|
||||
MessageInCorners, // with shadow
|
||||
MessageInSelectedCorners,
|
||||
MessageOutCorners,
|
||||
MessageOutSelectedCorners,
|
||||
|
||||
RoundCornersCount
|
||||
};
|
||||
|
||||
void FillComplexOverlayRect(Painter &p, QRect rect, ImageRoundRadius radius, RectParts corners);
|
||||
void FillComplexLocationRect(Painter &p, QRect rect, ImageRoundRadius radius, RectParts corners);
|
||||
|
||||
void FillRoundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, CachedRoundCorners index, const style::color *shadow = nullptr, RectParts parts = RectPart::Full);
|
||||
inline void FillRoundRect(Painter &p, const QRect &rect, style::color bg, CachedRoundCorners index, const style::color *shadow = nullptr, RectParts parts = RectPart::Full) {
|
||||
return FillRoundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, index, shadow, parts);
|
||||
}
|
||||
void FillRoundShadow(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color shadow, CachedRoundCorners index, RectParts parts = RectPart::Full);
|
||||
inline void FillRoundShadow(Painter &p, const QRect &rect, style::color shadow, CachedRoundCorners index, RectParts parts = RectPart::Full) {
|
||||
return FillRoundShadow(p, rect.x(), rect.y(), rect.width(), rect.height(), shadow, index, parts);
|
||||
}
|
||||
void FillRoundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, ImageRoundRadius radius, RectParts parts = RectPart::Full);
|
||||
inline void FillRoundRect(Painter &p, const QRect &rect, style::color bg, ImageRoundRadius radius, RectParts parts = RectPart::Full) {
|
||||
return FillRoundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, radius, parts);
|
||||
}
|
||||
|
||||
void StartCachedCorners();
|
||||
void FinishCachedCorners();
|
||||
|
||||
} // namespace Ui
|
484
Telegram/SourceFiles/ui/chat/attach/attach_album_preview.cpp
Normal file
484
Telegram/SourceFiles/ui/chat/attach/attach_album_preview.cpp
Normal file
|
@ -0,0 +1,484 @@
|
|||
/*
|
||||
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 "ui/chat/attach/attach_album_preview.h"
|
||||
|
||||
#include "ui/chat/attach/attach_album_thumbnail.h"
|
||||
#include "ui/chat/attach/attach_prepare.h"
|
||||
#include "styles/style_chat.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "styles/style_layers.h"
|
||||
|
||||
namespace Ui {
|
||||
namespace {
|
||||
|
||||
constexpr auto kDragDuration = crl::time(200);
|
||||
|
||||
} // namespace
|
||||
|
||||
AlbumPreview::AlbumPreview(
|
||||
QWidget *parent,
|
||||
const PreparedList &list,
|
||||
SendFilesWay way)
|
||||
: RpWidget(parent)
|
||||
, _list(list)
|
||||
, _sendWay(way) {
|
||||
setMouseTracking(true);
|
||||
prepareThumbs();
|
||||
updateSize();
|
||||
updateFileRows();
|
||||
}
|
||||
|
||||
AlbumPreview::~AlbumPreview() = default;
|
||||
|
||||
void AlbumPreview::setSendWay(SendFilesWay way) {
|
||||
if (_sendWay != way) {
|
||||
cancelDrag();
|
||||
_sendWay = way;
|
||||
}
|
||||
updateSize();
|
||||
updateFileRows();
|
||||
update();
|
||||
}
|
||||
|
||||
void AlbumPreview::updateFileRows() {
|
||||
Expects(_order.size() == _thumbs.size());
|
||||
const auto isFile = (_sendWay == SendFilesWay::Files);
|
||||
for (auto i = 0; i < _order.size(); i++) {
|
||||
_thumbs[i]->updateFileRow(isFile ? _order[i] : -1);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int> AlbumPreview::takeOrder() {
|
||||
auto reordered = std::vector<std::unique_ptr<AlbumThumbnail>>();
|
||||
reordered.reserve(_thumbs.size());
|
||||
for (auto index : _order) {
|
||||
reordered.push_back(std::move(_thumbs[index]));
|
||||
}
|
||||
_thumbs = std::move(reordered);
|
||||
return std::exchange(_order, defaultOrder());
|
||||
}
|
||||
|
||||
auto AlbumPreview::generateOrderedLayout() const
|
||||
-> std::vector<GroupMediaLayout> {
|
||||
auto sizes = ranges::view::all(
|
||||
_order
|
||||
) | ranges::view::transform([&](int index) {
|
||||
return _list.files[index].shownDimensions;
|
||||
}) | ranges::to_vector;
|
||||
|
||||
auto layout = LayoutMediaGroup(
|
||||
sizes,
|
||||
st::sendMediaPreviewSize,
|
||||
st::historyGroupWidthMin / 2,
|
||||
st::historyGroupSkip / 2);
|
||||
Assert(layout.size() == _order.size());
|
||||
return layout;
|
||||
}
|
||||
|
||||
std::vector<int> AlbumPreview::defaultOrder() const {
|
||||
const auto count = int(_list.files.size());
|
||||
return ranges::view::ints(0, count) | ranges::to_vector;
|
||||
}
|
||||
|
||||
void AlbumPreview::prepareThumbs() {
|
||||
_order = defaultOrder();
|
||||
|
||||
const auto count = int(_list.files.size());
|
||||
const auto layout = generateOrderedLayout();
|
||||
_thumbs.reserve(count);
|
||||
for (auto i = 0; i != count; ++i) {
|
||||
_thumbs.push_back(std::make_unique<AlbumThumbnail>(
|
||||
_list.files[i],
|
||||
layout[i],
|
||||
this,
|
||||
[=] { changeThumbByIndex(thumbIndex(thumbUnderCursor())); },
|
||||
[=] { deleteThumbByIndex(thumbIndex(thumbUnderCursor())); }));
|
||||
}
|
||||
_thumbsHeight = countLayoutHeight(layout);
|
||||
_photosHeight = ranges::accumulate(ranges::view::all(
|
||||
_thumbs
|
||||
) | ranges::view::transform([](const auto &thumb) {
|
||||
return thumb->photoHeight();
|
||||
}), 0) + (count - 1) * st::sendMediaPreviewPhotoSkip;
|
||||
|
||||
_filesHeight = count * st::sendMediaFileThumbSize
|
||||
+ (count - 1) * st::sendMediaFileThumbSkip;
|
||||
}
|
||||
|
||||
int AlbumPreview::contentLeft() const {
|
||||
return (st::boxWideWidth - st::sendMediaPreviewSize) / 2;
|
||||
}
|
||||
|
||||
int AlbumPreview::contentTop() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
AlbumThumbnail *AlbumPreview::findThumb(QPoint position) const {
|
||||
position -= QPoint(contentLeft(), contentTop());
|
||||
|
||||
auto top = 0;
|
||||
const auto isPhotosWay = (_sendWay == SendFilesWay::Photos);
|
||||
const auto skip = isPhotosWay
|
||||
? st::sendMediaPreviewPhotoSkip
|
||||
: st::sendMediaFileThumbSkip;
|
||||
auto find = [&](const auto &thumb) {
|
||||
if (_sendWay == SendFilesWay::Album) {
|
||||
return thumb->containsPoint(position);
|
||||
} else if (isPhotosWay || _sendWay == SendFilesWay::Files) {
|
||||
const auto bottom = top + (isPhotosWay
|
||||
? thumb->photoHeight()
|
||||
: st::sendMediaFileThumbSize);
|
||||
const auto isUnderTop = (position.y() > top);
|
||||
top = bottom + skip;
|
||||
return isUnderTop && (position.y() < bottom);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const auto i = ranges::find_if(_thumbs, std::move(find));
|
||||
return (i == _thumbs.end()) ? nullptr : i->get();
|
||||
}
|
||||
|
||||
not_null<AlbumThumbnail*> AlbumPreview::findClosestThumb(
|
||||
QPoint position) const {
|
||||
Expects(_draggedThumb != nullptr);
|
||||
|
||||
if (const auto exact = findThumb(position)) {
|
||||
return exact;
|
||||
}
|
||||
auto result = _draggedThumb;
|
||||
auto distance = _draggedThumb->distanceTo(position);
|
||||
for (const auto &thumb : _thumbs) {
|
||||
const auto check = thumb->distanceTo(position);
|
||||
if (check < distance) {
|
||||
distance = check;
|
||||
result = thumb.get();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int AlbumPreview::orderIndex(
|
||||
not_null<AlbumThumbnail*> thumb) const {
|
||||
const auto i = ranges::find_if(_order, [&](int index) {
|
||||
return (_thumbs[index].get() == thumb);
|
||||
});
|
||||
Assert(i != _order.end());
|
||||
return int(i - _order.begin());
|
||||
}
|
||||
|
||||
void AlbumPreview::cancelDrag() {
|
||||
_thumbsHeightAnimation.stop();
|
||||
_finishDragAnimation.stop();
|
||||
_shrinkAnimation.stop();
|
||||
if (_draggedThumb) {
|
||||
_draggedThumb->moveInAlbum({ 0, 0 });
|
||||
_draggedThumb = nullptr;
|
||||
}
|
||||
if (_suggestedThumb) {
|
||||
const auto suggestedIndex = orderIndex(_suggestedThumb);
|
||||
if (suggestedIndex > 0) {
|
||||
_thumbs[_order[suggestedIndex - 1]]->suggestMove(0., [] {});
|
||||
}
|
||||
if (suggestedIndex < int(_order.size() - 1)) {
|
||||
_thumbs[_order[suggestedIndex + 1]]->suggestMove(0., [] {});
|
||||
}
|
||||
_suggestedThumb->suggestMove(0., [] {});
|
||||
_suggestedThumb->finishAnimations();
|
||||
_suggestedThumb = nullptr;
|
||||
}
|
||||
_paintedAbove = nullptr;
|
||||
update();
|
||||
}
|
||||
|
||||
void AlbumPreview::finishDrag() {
|
||||
Expects(_draggedThumb != nullptr);
|
||||
Expects(_suggestedThumb != nullptr);
|
||||
|
||||
if (_suggestedThumb != _draggedThumb) {
|
||||
const auto currentIndex = orderIndex(_draggedThumb);
|
||||
const auto newIndex = orderIndex(_suggestedThumb);
|
||||
const auto delta = (currentIndex < newIndex) ? 1 : -1;
|
||||
const auto realIndex = _order[currentIndex];
|
||||
for (auto i = currentIndex; i != newIndex; i += delta) {
|
||||
_order[i] = _order[i + delta];
|
||||
}
|
||||
_order[newIndex] = realIndex;
|
||||
const auto layout = generateOrderedLayout();
|
||||
for (auto i = 0, count = int(_order.size()); i != count; ++i) {
|
||||
_thumbs[_order[i]]->moveToLayout(layout[i]);
|
||||
}
|
||||
_finishDragAnimation.start([=] { update(); }, 0., 1., kDragDuration);
|
||||
|
||||
updateSizeAnimated(layout);
|
||||
} else {
|
||||
for (const auto &thumb : _thumbs) {
|
||||
thumb->resetLayoutAnimation();
|
||||
}
|
||||
_draggedThumb->animateLayoutToInitial();
|
||||
_finishDragAnimation.start([=] { update(); }, 0., 1., kDragDuration);
|
||||
}
|
||||
}
|
||||
|
||||
int AlbumPreview::countLayoutHeight(
|
||||
const std::vector<GroupMediaLayout> &layout) const {
|
||||
const auto accumulator = [](int current, const auto &item) {
|
||||
return std::max(current, item.geometry.y() + item.geometry.height());
|
||||
};
|
||||
return ranges::accumulate(layout, 0, accumulator);
|
||||
}
|
||||
|
||||
void AlbumPreview::updateSizeAnimated(
|
||||
const std::vector<GroupMediaLayout> &layout) {
|
||||
const auto newHeight = countLayoutHeight(layout);
|
||||
if (newHeight != _thumbsHeight) {
|
||||
_thumbsHeightAnimation.start(
|
||||
[=] { updateSize(); },
|
||||
_thumbsHeight,
|
||||
newHeight,
|
||||
kDragDuration);
|
||||
_thumbsHeight = newHeight;
|
||||
}
|
||||
}
|
||||
|
||||
void AlbumPreview::updateSize() {
|
||||
const auto newHeight = [&] {
|
||||
switch (_sendWay) {
|
||||
case SendFilesWay::Album:
|
||||
return int(std::round(_thumbsHeightAnimation.value(
|
||||
_thumbsHeight)));
|
||||
case SendFilesWay::Photos: return _photosHeight;
|
||||
case SendFilesWay::Files: return _filesHeight;
|
||||
}
|
||||
Unexpected("Send way in AlbumPreview::updateSize");
|
||||
}();
|
||||
if (height() != newHeight) {
|
||||
resize(st::boxWideWidth, newHeight);
|
||||
}
|
||||
}
|
||||
|
||||
void AlbumPreview::paintEvent(QPaintEvent *e) {
|
||||
Painter p(this);
|
||||
|
||||
switch (_sendWay) {
|
||||
case SendFilesWay::Album: paintAlbum(p); break;
|
||||
case SendFilesWay::Photos: paintPhotos(p, e->rect()); break;
|
||||
case SendFilesWay::Files: paintFiles(p, e->rect()); break;
|
||||
}
|
||||
}
|
||||
|
||||
void AlbumPreview::paintAlbum(Painter &p) const {
|
||||
const auto shrink = _shrinkAnimation.value(_draggedThumb ? 1. : 0.);
|
||||
const auto moveProgress = _finishDragAnimation.value(1.);
|
||||
const auto left = contentLeft();
|
||||
const auto top = contentTop();
|
||||
for (const auto &thumb : _thumbs) {
|
||||
if (thumb.get() != _paintedAbove) {
|
||||
thumb->paintInAlbum(p, left, top, shrink, moveProgress);
|
||||
}
|
||||
}
|
||||
if (_paintedAbove) {
|
||||
_paintedAbove->paintInAlbum(p, left, top, shrink, moveProgress);
|
||||
}
|
||||
}
|
||||
|
||||
void AlbumPreview::paintPhotos(Painter &p, QRect clip) const {
|
||||
const auto left = (st::boxWideWidth - st::sendMediaPreviewSize) / 2;
|
||||
auto top = 0;
|
||||
const auto outerWidth = width();
|
||||
for (const auto &thumb : _thumbs) {
|
||||
const auto bottom = top + thumb->photoHeight();
|
||||
const auto guard = gsl::finally([&] {
|
||||
top = bottom + st::sendMediaPreviewPhotoSkip;
|
||||
});
|
||||
if (top >= clip.y() + clip.height()) {
|
||||
break;
|
||||
} else if (bottom <= clip.y()) {
|
||||
continue;
|
||||
}
|
||||
thumb->paintPhoto(p, left, top, outerWidth);
|
||||
}
|
||||
}
|
||||
|
||||
void AlbumPreview::paintFiles(Painter &p, QRect clip) const {
|
||||
const auto fileHeight = st::sendMediaFileThumbSize
|
||||
+ st::sendMediaFileThumbSkip;
|
||||
const auto bottom = clip.y() + clip.height();
|
||||
const auto from = std::clamp(clip.y() / fileHeight, 0, int(_thumbs.size()));
|
||||
const auto till = std::clamp((bottom + fileHeight - 1) / fileHeight, 0, int(_thumbs.size()));
|
||||
const auto left = (st::boxWideWidth - st::sendMediaPreviewSize) / 2;
|
||||
const auto outerWidth = width();
|
||||
|
||||
auto top = from * fileHeight;
|
||||
for (auto i = from; i != till; ++i) {
|
||||
_thumbs[i]->paintFile(p, left, top, outerWidth);
|
||||
top += fileHeight;
|
||||
}
|
||||
}
|
||||
|
||||
int AlbumPreview::thumbIndex(AlbumThumbnail *thumb) {
|
||||
if (!thumb) {
|
||||
return -1;
|
||||
}
|
||||
const auto thumbIt = ranges::find_if(_thumbs, [&](auto &t) {
|
||||
return t.get() == thumb;
|
||||
});
|
||||
Expects(thumbIt != _thumbs.end());
|
||||
return std::distance(_thumbs.begin(), thumbIt);
|
||||
}
|
||||
|
||||
AlbumThumbnail *AlbumPreview::thumbUnderCursor() {
|
||||
return findThumb(mapFromGlobal(QCursor::pos()));
|
||||
}
|
||||
|
||||
void AlbumPreview::deleteThumbByIndex(int index) {
|
||||
if (index < 0) {
|
||||
return;
|
||||
}
|
||||
const auto orderIt = ranges::find(_order, index);
|
||||
Expects(orderIt != _order.end());
|
||||
|
||||
_order.erase(orderIt);
|
||||
ranges::for_each(_order, [=](auto &i) {
|
||||
if (i > index) {
|
||||
i--;
|
||||
}
|
||||
});
|
||||
_thumbDeleted.fire(std::move(index));
|
||||
}
|
||||
|
||||
void AlbumPreview::changeThumbByIndex(int index) {
|
||||
if (index < 0) {
|
||||
return;
|
||||
}
|
||||
_thumbChanged.fire(std::move(index));
|
||||
}
|
||||
|
||||
void AlbumPreview::thumbButtonsCallback(
|
||||
not_null<AlbumThumbnail*> thumb,
|
||||
AttachButtonType type) {
|
||||
const auto index = thumbIndex(thumb);
|
||||
|
||||
switch (type) {
|
||||
case AttachButtonType::None: return;
|
||||
case AttachButtonType::Edit: changeThumbByIndex(index); break;
|
||||
case AttachButtonType::Delete: deleteThumbByIndex(index); break;
|
||||
}
|
||||
}
|
||||
|
||||
void AlbumPreview::mousePressEvent(QMouseEvent *e) {
|
||||
if (_finishDragAnimation.animating()) {
|
||||
return;
|
||||
}
|
||||
const auto position = e->pos();
|
||||
cancelDrag();
|
||||
if (const auto thumb = findThumb(position)) {
|
||||
if (thumb->buttonsContainPoint(e->pos())) {
|
||||
thumbButtonsCallback(thumb, thumb->buttonTypeFromPoint(e->pos()));
|
||||
return;
|
||||
}
|
||||
_paintedAbove = _suggestedThumb = _draggedThumb = thumb;
|
||||
_draggedStartPosition = position;
|
||||
_shrinkAnimation.start(
|
||||
[=] { update(); },
|
||||
0.,
|
||||
1.,
|
||||
AlbumThumbnail::kShrinkDuration);
|
||||
}
|
||||
}
|
||||
|
||||
void AlbumPreview::mouseMoveEvent(QMouseEvent *e) {
|
||||
if (_sendWay == SendFilesWay::Files) {
|
||||
applyCursor(style::cur_default);
|
||||
return;
|
||||
}
|
||||
const auto isAlbum = (_sendWay == SendFilesWay::Album);
|
||||
if (isAlbum && _draggedThumb) {
|
||||
const auto position = e->pos();
|
||||
_draggedThumb->moveInAlbum(position - _draggedStartPosition);
|
||||
updateSuggestedDrag(_draggedThumb->center());
|
||||
update();
|
||||
} else {
|
||||
const auto thumb = findThumb(e->pos());
|
||||
const auto regularCursor = isAlbum
|
||||
? style::cur_sizeall
|
||||
: style::cur_default;
|
||||
const auto cursor = thumb
|
||||
? (thumb->buttonsContainPoint(e->pos())
|
||||
? style::cur_pointer
|
||||
: regularCursor)
|
||||
: style::cur_default;
|
||||
applyCursor(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
void AlbumPreview::applyCursor(style::cursor cursor) {
|
||||
if (_cursor != cursor) {
|
||||
_cursor = cursor;
|
||||
setCursor(_cursor);
|
||||
}
|
||||
}
|
||||
|
||||
void AlbumPreview::updateSuggestedDrag(QPoint position) {
|
||||
auto closest = findClosestThumb(position);
|
||||
auto closestIndex = orderIndex(closest);
|
||||
|
||||
const auto draggedIndex = orderIndex(_draggedThumb);
|
||||
const auto closestIsBeforePoint = closest->isPointAfter(position);
|
||||
if (closestIndex < draggedIndex && closestIsBeforePoint) {
|
||||
closest = _thumbs[_order[++closestIndex]].get();
|
||||
} else if (closestIndex > draggedIndex && !closestIsBeforePoint) {
|
||||
closest = _thumbs[_order[--closestIndex]].get();
|
||||
}
|
||||
|
||||
if (_suggestedThumb == closest) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto last = int(_order.size()) - 1;
|
||||
if (_suggestedThumb) {
|
||||
const auto suggestedIndex = orderIndex(_suggestedThumb);
|
||||
if (suggestedIndex < draggedIndex && suggestedIndex > 0) {
|
||||
const auto previous = _thumbs[_order[suggestedIndex - 1]].get();
|
||||
previous->suggestMove(0., [=] { update(); });
|
||||
} else if (suggestedIndex > draggedIndex && suggestedIndex < last) {
|
||||
const auto next = _thumbs[_order[suggestedIndex + 1]].get();
|
||||
next->suggestMove(0., [=] { update(); });
|
||||
}
|
||||
_suggestedThumb->suggestMove(0., [=] { update(); });
|
||||
}
|
||||
_suggestedThumb = closest;
|
||||
const auto suggestedIndex = closestIndex;
|
||||
if (_suggestedThumb != _draggedThumb) {
|
||||
const auto delta = (suggestedIndex < draggedIndex) ? 1. : -1.;
|
||||
if (delta > 0. && suggestedIndex > 0) {
|
||||
const auto previous = _thumbs[_order[suggestedIndex - 1]].get();
|
||||
previous->suggestMove(-delta, [=] { update(); });
|
||||
} else if (delta < 0. && suggestedIndex < last) {
|
||||
const auto next = _thumbs[_order[suggestedIndex + 1]].get();
|
||||
next->suggestMove(-delta, [=] { update(); });
|
||||
}
|
||||
_suggestedThumb->suggestMove(delta, [=] { update(); });
|
||||
}
|
||||
}
|
||||
|
||||
void AlbumPreview::mouseReleaseEvent(QMouseEvent *e) {
|
||||
if (_draggedThumb) {
|
||||
finishDrag();
|
||||
_shrinkAnimation.start(
|
||||
[=] { update(); },
|
||||
1.,
|
||||
0.,
|
||||
AlbumThumbnail::kShrinkDuration);
|
||||
_draggedThumb = nullptr;
|
||||
_suggestedThumb = nullptr;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Ui
|
99
Telegram/SourceFiles/ui/chat/attach/attach_album_preview.h
Normal file
99
Telegram/SourceFiles/ui/chat/attach/attach_album_preview.h
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
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/rp_widget.h"
|
||||
#include "ui/chat/attach/attach_common.h"
|
||||
|
||||
namespace Ui {
|
||||
|
||||
struct PreparedList;
|
||||
struct GroupMediaLayout;
|
||||
class AlbumThumbnail;
|
||||
|
||||
class AlbumPreview final : public RpWidget {
|
||||
public:
|
||||
AlbumPreview(
|
||||
QWidget *parent,
|
||||
const PreparedList &list,
|
||||
SendFilesWay way);
|
||||
~AlbumPreview();
|
||||
|
||||
void setSendWay(SendFilesWay way);
|
||||
std::vector<int> takeOrder();
|
||||
|
||||
auto thumbDeleted() {
|
||||
return _thumbDeleted.events();
|
||||
}
|
||||
|
||||
auto thumbChanged() {
|
||||
return _thumbChanged.events();
|
||||
}
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
void mousePressEvent(QMouseEvent *e) override;
|
||||
void mouseMoveEvent(QMouseEvent *e) override;
|
||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||
|
||||
private:
|
||||
int countLayoutHeight(
|
||||
const std::vector<GroupMediaLayout> &layout) const;
|
||||
std::vector<GroupMediaLayout> generateOrderedLayout() const;
|
||||
std::vector<int> defaultOrder() const;
|
||||
void prepareThumbs();
|
||||
void updateSizeAnimated(const std::vector<GroupMediaLayout> &layout);
|
||||
void updateSize();
|
||||
void updateFileRows();
|
||||
|
||||
int thumbIndex(AlbumThumbnail *thumb);
|
||||
AlbumThumbnail *thumbUnderCursor();
|
||||
void deleteThumbByIndex(int index);
|
||||
void changeThumbByIndex(int index);
|
||||
void thumbButtonsCallback(
|
||||
not_null<AlbumThumbnail*> thumb,
|
||||
AttachButtonType type);
|
||||
|
||||
void paintAlbum(Painter &p) const;
|
||||
void paintPhotos(Painter &p, QRect clip) const;
|
||||
void paintFiles(Painter &p, QRect clip) const;
|
||||
|
||||
void applyCursor(style::cursor cursor);
|
||||
int contentLeft() const;
|
||||
int contentTop() const;
|
||||
AlbumThumbnail *findThumb(QPoint position) const;
|
||||
not_null<AlbumThumbnail*> findClosestThumb(QPoint position) const;
|
||||
void updateSuggestedDrag(QPoint position);
|
||||
int orderIndex(not_null<AlbumThumbnail*> thumb) const;
|
||||
void cancelDrag();
|
||||
void finishDrag();
|
||||
|
||||
const PreparedList &_list;
|
||||
SendFilesWay _sendWay = SendFilesWay::Files;
|
||||
style::cursor _cursor = style::cur_default;
|
||||
std::vector<int> _order;
|
||||
std::vector<std::unique_ptr<AlbumThumbnail>> _thumbs;
|
||||
int _thumbsHeight = 0;
|
||||
int _photosHeight = 0;
|
||||
int _filesHeight = 0;
|
||||
|
||||
AlbumThumbnail *_draggedThumb = nullptr;
|
||||
AlbumThumbnail *_suggestedThumb = nullptr;
|
||||
AlbumThumbnail *_paintedAbove = nullptr;
|
||||
QPoint _draggedStartPosition;
|
||||
|
||||
rpl::event_stream<int> _thumbDeleted;
|
||||
rpl::event_stream<int> _thumbChanged;
|
||||
|
||||
mutable Animations::Simple _thumbsHeightAnimation;
|
||||
mutable Animations::Simple _shrinkAnimation;
|
||||
mutable Animations::Simple _finishDragAnimation;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Ui
|
543
Telegram/SourceFiles/ui/chat/attach/attach_album_thumbnail.cpp
Normal file
543
Telegram/SourceFiles/ui/chat/attach/attach_album_thumbnail.cpp
Normal file
|
@ -0,0 +1,543 @@
|
|||
/*
|
||||
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 "ui/chat/attach/attach_album_thumbnail.h"
|
||||
|
||||
#include "ui/chat/attach/attach_prepare.h"
|
||||
#include "ui/image/image_prepare.h"
|
||||
#include "ui/text/format_values.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/ui_utility.h"
|
||||
#include "base/call_delayed.h"
|
||||
#include "styles/style_chat.h"
|
||||
#include "styles/style_boxes.h"
|
||||
|
||||
#include <QtCore/QFileInfo>
|
||||
|
||||
namespace Ui {
|
||||
|
||||
AlbumThumbnail::AlbumThumbnail(
|
||||
const PreparedFile &file,
|
||||
const GroupMediaLayout &layout,
|
||||
QWidget *parent,
|
||||
Fn<void()> editCallback,
|
||||
Fn<void()> deleteCallback)
|
||||
: _layout(layout)
|
||||
, _fullPreview(file.preview)
|
||||
, _shrinkSize(int(std::ceil(st::historyMessageRadius / 1.4)))
|
||||
, _isVideo(file.type == PreparedFile::AlbumType::Video)
|
||||
, _buttonsRect(st::sendBoxAlbumGroupRadius, st::callFingerprintBg) {
|
||||
Expects(!_fullPreview.isNull());
|
||||
|
||||
moveToLayout(layout);
|
||||
|
||||
using Option = Images::Option;
|
||||
const auto previewWidth = _fullPreview.width();
|
||||
const auto previewHeight = _fullPreview.height();
|
||||
const auto imageWidth = std::max(
|
||||
previewWidth / style::DevicePixelRatio(),
|
||||
st::minPhotoSize);
|
||||
const auto imageHeight = std::max(
|
||||
previewHeight / style::DevicePixelRatio(),
|
||||
st::minPhotoSize);
|
||||
_photo = PixmapFromImage(Images::prepare(
|
||||
_fullPreview,
|
||||
previewWidth,
|
||||
previewHeight,
|
||||
Option::RoundedLarge | Option::RoundedAll,
|
||||
imageWidth,
|
||||
imageHeight));
|
||||
|
||||
const auto idealSize = st::sendMediaFileThumbSize * style::DevicePixelRatio();
|
||||
const auto fileThumbSize = (previewWidth > previewHeight)
|
||||
? QSize(previewWidth * idealSize / previewHeight, idealSize)
|
||||
: QSize(idealSize, previewHeight * idealSize / previewWidth);
|
||||
_fileThumb = PixmapFromImage(Images::prepare(
|
||||
_fullPreview,
|
||||
fileThumbSize.width(),
|
||||
fileThumbSize.height(),
|
||||
Option::RoundedSmall | Option::RoundedAll,
|
||||
st::sendMediaFileThumbSize,
|
||||
st::sendMediaFileThumbSize
|
||||
));
|
||||
|
||||
const auto availableFileWidth = st::sendMediaPreviewSize
|
||||
- st::sendMediaFileThumbSkip
|
||||
- st::sendMediaFileThumbSize
|
||||
// Right buttons.
|
||||
- st::sendBoxAlbumGroupButtonFile.width * 2
|
||||
- st::sendBoxAlbumGroupEditInternalSkip * 2
|
||||
- st::sendBoxAlbumGroupSkipRight;
|
||||
const auto filepath = file.path;
|
||||
if (filepath.isEmpty()) {
|
||||
//_name = filedialogDefaultName( // #TODO files
|
||||
// u"image"_q,
|
||||
// u".png"_q,
|
||||
// QString(),
|
||||
// true);
|
||||
_name = "image.png";
|
||||
_status = u"%1x%2"_q.arg(
|
||||
_fullPreview.width()
|
||||
).arg(
|
||||
_fullPreview.height()
|
||||
);
|
||||
} else {
|
||||
auto fileinfo = QFileInfo(filepath);
|
||||
_name = fileinfo.fileName();
|
||||
_status = FormatSizeText(fileinfo.size());
|
||||
}
|
||||
_nameWidth = st::semiboldFont->width(_name);
|
||||
if (_nameWidth > availableFileWidth) {
|
||||
_name = st::semiboldFont->elided(
|
||||
_name,
|
||||
availableFileWidth,
|
||||
Qt::ElideMiddle);
|
||||
_nameWidth = st::semiboldFont->width(_name);
|
||||
}
|
||||
_statusWidth = st::normalFont->width(_status);
|
||||
|
||||
_editMedia.create(parent, st::sendBoxAlbumGroupButtonFile);
|
||||
_deleteMedia.create(parent, st::sendBoxAlbumGroupButtonFile);
|
||||
|
||||
const auto duration = st::historyAttach.ripple.hideDuration;
|
||||
_editMedia->setClickedCallback([=] {
|
||||
base::call_delayed(duration, parent, editCallback);
|
||||
});
|
||||
_deleteMedia->setClickedCallback([=] {
|
||||
base::call_delayed(duration, parent, deleteCallback);
|
||||
});
|
||||
|
||||
_editMedia->setIconOverride(&st::editMediaButtonIconFile);
|
||||
_deleteMedia->setIconOverride(&st::sendBoxAlbumGroupDeleteButtonIconFile);
|
||||
|
||||
updateFileRow(-1);
|
||||
}
|
||||
|
||||
void AlbumThumbnail::updateFileRow(int row) {
|
||||
if (row < 0) {
|
||||
_editMedia->hide();
|
||||
_deleteMedia->hide();
|
||||
return;
|
||||
}
|
||||
_editMedia->show();
|
||||
_deleteMedia->show();
|
||||
|
||||
const auto fileHeight = st::sendMediaFileThumbSize
|
||||
+ st::sendMediaFileThumbSkip;
|
||||
|
||||
const auto top = row * fileHeight + st::sendBoxAlbumGroupSkipTop;
|
||||
const auto size = st::editMediaButtonSize;
|
||||
|
||||
auto right = st::sendBoxAlbumGroupSkipRight + size;
|
||||
_deleteMedia->moveToRight(right, top);
|
||||
right += st::sendBoxAlbumGroupEditInternalSkip + size;
|
||||
_editMedia->moveToRight(right, top);
|
||||
}
|
||||
|
||||
void AlbumThumbnail::resetLayoutAnimation() {
|
||||
_animateFromGeometry = std::nullopt;
|
||||
}
|
||||
|
||||
void AlbumThumbnail::animateLayoutToInitial() {
|
||||
_animateFromGeometry = countRealGeometry();
|
||||
_suggestedMove = 0.;
|
||||
_albumPosition = QPoint(0, 0);
|
||||
}
|
||||
|
||||
void AlbumThumbnail::moveToLayout(const GroupMediaLayout &layout) {
|
||||
animateLayoutToInitial();
|
||||
_layout = layout;
|
||||
|
||||
const auto width = _layout.geometry.width();
|
||||
const auto height = _layout.geometry.height();
|
||||
_albumCorners = GetCornersFromSides(_layout.sides);
|
||||
using Option = Images::Option;
|
||||
const auto options = Option::Smooth
|
||||
| Option::RoundedLarge
|
||||
| ((_albumCorners & RectPart::TopLeft)
|
||||
? Option::RoundedTopLeft
|
||||
: Option::None)
|
||||
| ((_albumCorners & RectPart::TopRight)
|
||||
? Option::RoundedTopRight
|
||||
: Option::None)
|
||||
| ((_albumCorners & RectPart::BottomLeft)
|
||||
? Option::RoundedBottomLeft
|
||||
: Option::None)
|
||||
| ((_albumCorners & RectPart::BottomRight)
|
||||
? Option::RoundedBottomRight
|
||||
: Option::None);
|
||||
const auto pixSize = GetImageScaleSizeForGeometry(
|
||||
{ _fullPreview.width(), _fullPreview.height() },
|
||||
{ width, height });
|
||||
const auto pixWidth = pixSize.width() * style::DevicePixelRatio();
|
||||
const auto pixHeight = pixSize.height() * style::DevicePixelRatio();
|
||||
|
||||
_albumImage = PixmapFromImage(Images::prepare(
|
||||
_fullPreview,
|
||||
pixWidth,
|
||||
pixHeight,
|
||||
options,
|
||||
width,
|
||||
height));
|
||||
}
|
||||
|
||||
int AlbumThumbnail::photoHeight() const {
|
||||
return _photo.height() / style::DevicePixelRatio();
|
||||
}
|
||||
|
||||
void AlbumThumbnail::paintInAlbum(
|
||||
Painter &p,
|
||||
int left,
|
||||
int top,
|
||||
float64 shrinkProgress,
|
||||
float64 moveProgress) {
|
||||
const auto shrink = anim::interpolate(0, _shrinkSize, shrinkProgress);
|
||||
_lastShrinkValue = shrink;
|
||||
const auto geometry = countCurrentGeometry(moveProgress);
|
||||
const auto x = left + geometry.x();
|
||||
const auto y = top + geometry.y();
|
||||
if (shrink > 0 || moveProgress < 1.) {
|
||||
const auto size = geometry.size();
|
||||
if (shrinkProgress < 1 && _albumCorners != RectPart::None) {
|
||||
prepareCache(size, shrink);
|
||||
p.drawImage(x, y, _albumCache);
|
||||
} else {
|
||||
const auto to = QRect({ x, y }, size).marginsRemoved(
|
||||
{ shrink, shrink, shrink, shrink }
|
||||
);
|
||||
drawSimpleFrame(p, to, size);
|
||||
}
|
||||
} else {
|
||||
p.drawPixmap(x, y, _albumImage);
|
||||
}
|
||||
if (_isVideo) {
|
||||
const auto inner = QRect(
|
||||
x + (geometry.width() - st::msgFileSize) / 2,
|
||||
y + (geometry.height() - st::msgFileSize) / 2,
|
||||
st::msgFileSize,
|
||||
st::msgFileSize);
|
||||
{
|
||||
PainterHighQualityEnabler hq(p);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(st::msgDateImgBg);
|
||||
p.drawEllipse(inner);
|
||||
}
|
||||
st::historyFileThumbPlay.paintInCenter(p, inner);
|
||||
}
|
||||
|
||||
_lastRectOfButtons = paintButtons(
|
||||
p,
|
||||
{ x, y },
|
||||
geometry.width(),
|
||||
shrinkProgress);
|
||||
}
|
||||
|
||||
void AlbumThumbnail::prepareCache(QSize size, int shrink) {
|
||||
const auto width = std::max(
|
||||
_layout.geometry.width(),
|
||||
_animateFromGeometry ? _animateFromGeometry->width() : 0);
|
||||
const auto height = std::max(
|
||||
_layout.geometry.height(),
|
||||
_animateFromGeometry ? _animateFromGeometry->height() : 0);
|
||||
const auto cacheSize = QSize(width, height) * style::DevicePixelRatio();
|
||||
|
||||
if (_albumCache.width() < cacheSize.width()
|
||||
|| _albumCache.height() < cacheSize.height()) {
|
||||
_albumCache = QImage(cacheSize, QImage::Format_ARGB32_Premultiplied);
|
||||
}
|
||||
_albumCache.fill(Qt::transparent);
|
||||
{
|
||||
Painter p(&_albumCache);
|
||||
const auto to = QRect(QPoint(), size).marginsRemoved(
|
||||
{ shrink, shrink, shrink, shrink }
|
||||
);
|
||||
drawSimpleFrame(p, to, size);
|
||||
}
|
||||
Images::prepareRound(
|
||||
_albumCache,
|
||||
ImageRoundRadius::Large,
|
||||
_albumCorners,
|
||||
QRect(QPoint(), size * style::DevicePixelRatio()));
|
||||
_albumCache.setDevicePixelRatio(style::DevicePixelRatio());
|
||||
}
|
||||
|
||||
void AlbumThumbnail::drawSimpleFrame(Painter &p, QRect to, QSize size) const {
|
||||
const auto fullWidth = _fullPreview.width();
|
||||
const auto fullHeight = _fullPreview.height();
|
||||
const auto previewSize = GetImageScaleSizeForGeometry(
|
||||
{ fullWidth, fullHeight },
|
||||
{ size.width(), size.height() });
|
||||
const auto previewWidth = previewSize.width() * style::DevicePixelRatio();
|
||||
const auto previewHeight = previewSize.height() * style::DevicePixelRatio();
|
||||
const auto width = size.width() * style::DevicePixelRatio();
|
||||
const auto height = size.height() * style::DevicePixelRatio();
|
||||
const auto scaleWidth = to.width() / float64(width);
|
||||
const auto scaleHeight = to.height() / float64(height);
|
||||
const auto Round = [](float64 value) {
|
||||
return int(std::round(value));
|
||||
};
|
||||
const auto [from, fillBlack] = [&] {
|
||||
if (previewWidth < width && previewHeight < height) {
|
||||
const auto toWidth = Round(previewWidth * scaleWidth);
|
||||
const auto toHeight = Round(previewHeight * scaleHeight);
|
||||
return std::make_pair(
|
||||
QRect(0, 0, fullWidth, fullHeight),
|
||||
QMargins(
|
||||
(to.width() - toWidth) / 2,
|
||||
(to.height() - toHeight) / 2,
|
||||
to.width() - toWidth - (to.width() - toWidth) / 2,
|
||||
to.height() - toHeight - (to.height() - toHeight) / 2));
|
||||
} else if (previewWidth * height > previewHeight * width) {
|
||||
if (previewHeight >= height) {
|
||||
const auto takeWidth = previewWidth * height / previewHeight;
|
||||
const auto useWidth = fullWidth * width / takeWidth;
|
||||
return std::make_pair(
|
||||
QRect(
|
||||
(fullWidth - useWidth) / 2,
|
||||
0,
|
||||
useWidth,
|
||||
fullHeight),
|
||||
QMargins(0, 0, 0, 0));
|
||||
} else {
|
||||
const auto takeWidth = previewWidth;
|
||||
const auto useWidth = fullWidth * width / takeWidth;
|
||||
const auto toHeight = Round(previewHeight * scaleHeight);
|
||||
const auto toSkip = (to.height() - toHeight) / 2;
|
||||
return std::make_pair(
|
||||
QRect(
|
||||
(fullWidth - useWidth) / 2,
|
||||
0,
|
||||
useWidth,
|
||||
fullHeight),
|
||||
QMargins(
|
||||
0,
|
||||
toSkip,
|
||||
0,
|
||||
to.height() - toHeight - toSkip));
|
||||
}
|
||||
} else {
|
||||
if (previewWidth >= width) {
|
||||
const auto takeHeight = previewHeight * width / previewWidth;
|
||||
const auto useHeight = fullHeight * height / takeHeight;
|
||||
return std::make_pair(
|
||||
QRect(
|
||||
0,
|
||||
(fullHeight - useHeight) / 2,
|
||||
fullWidth,
|
||||
useHeight),
|
||||
QMargins(0, 0, 0, 0));
|
||||
} else {
|
||||
const auto takeHeight = previewHeight;
|
||||
const auto useHeight = fullHeight * height / takeHeight;
|
||||
const auto toWidth = Round(previewWidth * scaleWidth);
|
||||
const auto toSkip = (to.width() - toWidth) / 2;
|
||||
return std::make_pair(
|
||||
QRect(
|
||||
0,
|
||||
(fullHeight - useHeight) / 2,
|
||||
fullWidth,
|
||||
useHeight),
|
||||
QMargins(
|
||||
toSkip,
|
||||
0,
|
||||
to.width() - toWidth - toSkip,
|
||||
0));
|
||||
}
|
||||
}
|
||||
}();
|
||||
|
||||
p.drawImage(to.marginsRemoved(fillBlack), _fullPreview, from);
|
||||
if (fillBlack.top() > 0) {
|
||||
p.fillRect(to.x(), to.y(), to.width(), fillBlack.top(), st::imageBg);
|
||||
}
|
||||
if (fillBlack.bottom() > 0) {
|
||||
p.fillRect(
|
||||
to.x(),
|
||||
to.y() + to.height() - fillBlack.bottom(),
|
||||
to.width(),
|
||||
fillBlack.bottom(),
|
||||
st::imageBg);
|
||||
}
|
||||
if (fillBlack.left() > 0) {
|
||||
p.fillRect(
|
||||
to.x(),
|
||||
to.y() + fillBlack.top(),
|
||||
fillBlack.left(),
|
||||
to.height() - fillBlack.top() - fillBlack.bottom(),
|
||||
st::imageBg);
|
||||
}
|
||||
if (fillBlack.right() > 0) {
|
||||
p.fillRect(
|
||||
to.x() + to.width() - fillBlack.right(),
|
||||
to.y() + fillBlack.top(),
|
||||
fillBlack.right(),
|
||||
to.height() - fillBlack.top() - fillBlack.bottom(),
|
||||
st::imageBg);
|
||||
}
|
||||
}
|
||||
|
||||
void AlbumThumbnail::paintPhoto(Painter &p, int left, int top, int outerWidth) {
|
||||
const auto width = _photo.width() / style::DevicePixelRatio();
|
||||
p.drawPixmapLeft(
|
||||
left + (st::sendMediaPreviewSize - width) / 2,
|
||||
top,
|
||||
outerWidth,
|
||||
_photo);
|
||||
|
||||
_lastRectOfButtons = paintButtons(
|
||||
p,
|
||||
{ left, top },
|
||||
st::sendMediaPreviewSize,
|
||||
0);
|
||||
}
|
||||
|
||||
void AlbumThumbnail::paintFile(Painter &p, int left, int top, int outerWidth) {
|
||||
const auto textLeft = left
|
||||
+ st::sendMediaFileThumbSize
|
||||
+ st::sendMediaFileThumbSkip;
|
||||
|
||||
p.drawPixmap(left, top, _fileThumb);
|
||||
p.setFont(st::semiboldFont);
|
||||
p.setPen(st::historyFileNameInFg);
|
||||
p.drawTextLeft(
|
||||
textLeft,
|
||||
top + st::sendMediaFileNameTop,
|
||||
outerWidth,
|
||||
_name,
|
||||
_nameWidth);
|
||||
p.setFont(st::normalFont);
|
||||
p.setPen(st::mediaInFg);
|
||||
p.drawTextLeft(
|
||||
textLeft,
|
||||
top + st::sendMediaFileStatusTop,
|
||||
outerWidth,
|
||||
_status,
|
||||
_statusWidth);
|
||||
}
|
||||
|
||||
bool AlbumThumbnail::containsPoint(QPoint position) const {
|
||||
return _layout.geometry.contains(position);
|
||||
}
|
||||
|
||||
bool AlbumThumbnail::buttonsContainPoint(QPoint position) const {
|
||||
return _lastRectOfButtons.contains(position);
|
||||
}
|
||||
|
||||
AttachButtonType AlbumThumbnail::buttonTypeFromPoint(QPoint position) const {
|
||||
if (!buttonsContainPoint(position)) {
|
||||
return AttachButtonType::None;
|
||||
}
|
||||
return (position.x() < _lastRectOfButtons.center().x())
|
||||
? AttachButtonType::Edit
|
||||
: AttachButtonType::Delete;
|
||||
}
|
||||
|
||||
int AlbumThumbnail::distanceTo(QPoint position) const {
|
||||
const auto delta = (_layout.geometry.center() - position);
|
||||
return QPoint::dotProduct(delta, delta);
|
||||
}
|
||||
|
||||
bool AlbumThumbnail::isPointAfter(QPoint position) const {
|
||||
return position.x() > _layout.geometry.center().x();
|
||||
}
|
||||
|
||||
void AlbumThumbnail::moveInAlbum(QPoint to) {
|
||||
_albumPosition = to;
|
||||
}
|
||||
|
||||
QPoint AlbumThumbnail::center() const {
|
||||
auto realGeometry = _layout.geometry;
|
||||
realGeometry.moveTopLeft(realGeometry.topLeft() + _albumPosition);
|
||||
return realGeometry.center();
|
||||
}
|
||||
|
||||
void AlbumThumbnail::suggestMove(float64 delta, Fn<void()> callback) {
|
||||
if (_suggestedMove != delta) {
|
||||
_suggestedMoveAnimation.start(
|
||||
std::move(callback),
|
||||
_suggestedMove,
|
||||
delta,
|
||||
kShrinkDuration);
|
||||
_suggestedMove = delta;
|
||||
}
|
||||
}
|
||||
|
||||
QRect AlbumThumbnail::countRealGeometry() const {
|
||||
const auto addLeft = int(std::round(
|
||||
_suggestedMoveAnimation.value(_suggestedMove) * _lastShrinkValue));
|
||||
const auto current = _layout.geometry;
|
||||
const auto realTopLeft = current.topLeft()
|
||||
+ _albumPosition
|
||||
+ QPoint(addLeft, 0);
|
||||
return { realTopLeft, current.size() };
|
||||
}
|
||||
|
||||
QRect AlbumThumbnail::countCurrentGeometry(float64 progress) const {
|
||||
const auto now = countRealGeometry();
|
||||
if (_animateFromGeometry && progress < 1.) {
|
||||
return {
|
||||
anim::interpolate(_animateFromGeometry->x(), now.x(), progress),
|
||||
anim::interpolate(_animateFromGeometry->y(), now.y(), progress),
|
||||
anim::interpolate(_animateFromGeometry->width(), now.width(), progress),
|
||||
anim::interpolate(_animateFromGeometry->height(), now.height(), progress)
|
||||
};
|
||||
}
|
||||
return now;
|
||||
}
|
||||
|
||||
void AlbumThumbnail::finishAnimations() {
|
||||
_suggestedMoveAnimation.stop();
|
||||
}
|
||||
|
||||
QRect AlbumThumbnail::paintButtons(
|
||||
Painter &p,
|
||||
QPoint point,
|
||||
int outerWidth,
|
||||
float64 shrinkProgress) {
|
||||
const auto skipInternal = st::sendBoxAlbumGroupEditInternalSkip;
|
||||
const auto size = st::sendBoxAlbumGroupHeight;
|
||||
const auto skipRight = st::sendBoxAlbumGroupSkipRight;
|
||||
const auto skipTop = st::sendBoxAlbumGroupSkipTop;
|
||||
const auto groupWidth = size * 2 + skipInternal;
|
||||
|
||||
// If the width is tiny, it would be better to not display the buttons.
|
||||
if (groupWidth > outerWidth) {
|
||||
return QRect();
|
||||
}
|
||||
|
||||
// If the width is too small,
|
||||
// it would be better to display the buttons in the center.
|
||||
const auto groupX = point.x() + ((groupWidth + skipRight * 2 > outerWidth)
|
||||
? (outerWidth - groupWidth) / 2
|
||||
: outerWidth - skipRight - groupWidth);
|
||||
const auto groupY = point.y() + skipTop;
|
||||
const auto deleteLeft = skipInternal + size;
|
||||
|
||||
p.setOpacity(1.0 - shrinkProgress);
|
||||
|
||||
QRect groupRect(groupX, groupY, groupWidth, size);
|
||||
_buttonsRect.paint(p, groupRect);
|
||||
|
||||
const auto editP = st::sendBoxAlbumGroupEditButtonIconPosition;
|
||||
const auto deleteP = st::sendBoxAlbumGroupDeleteButtonIconPosition;
|
||||
|
||||
st::sendBoxAlbumGroupEditButtonIcon.paintInCenter(
|
||||
p,
|
||||
QRect(groupX + editP.x(), groupY + editP.y(), size, size));
|
||||
st::sendBoxAlbumGroupDeleteButtonIcon.paintInCenter(
|
||||
p,
|
||||
QRect(
|
||||
groupX + deleteLeft + deleteP.x(),
|
||||
groupY + deleteP.y(),
|
||||
size,
|
||||
size));
|
||||
p.setOpacity(1);
|
||||
|
||||
return groupRect;
|
||||
}
|
||||
|
||||
} // namespace Ui
|
97
Telegram/SourceFiles/ui/chat/attach/attach_album_thumbnail.h
Normal file
97
Telegram/SourceFiles/ui/chat/attach/attach_album_thumbnail.h
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
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/chat/attach/attach_common.h"
|
||||
#include "ui/effects/animations.h"
|
||||
#include "ui/grouped_layout.h"
|
||||
#include "ui/round_rect.h"
|
||||
#include "base/object_ptr.h"
|
||||
|
||||
namespace Ui {
|
||||
|
||||
struct PreparedFile;
|
||||
class IconButton;
|
||||
|
||||
class AlbumThumbnail final {
|
||||
public:
|
||||
AlbumThumbnail(
|
||||
const PreparedFile &file,
|
||||
const GroupMediaLayout &layout,
|
||||
QWidget *parent,
|
||||
Fn<void()> editCallback,
|
||||
Fn<void()> deleteCallback);
|
||||
|
||||
void moveToLayout(const GroupMediaLayout &layout);
|
||||
void animateLayoutToInitial();
|
||||
void resetLayoutAnimation();
|
||||
|
||||
int photoHeight() const;
|
||||
|
||||
void paintInAlbum(
|
||||
Painter &p,
|
||||
int left,
|
||||
int top,
|
||||
float64 shrinkProgress,
|
||||
float64 moveProgress);
|
||||
void paintPhoto(Painter &p, int left, int top, int outerWidth);
|
||||
void paintFile(Painter &p, int left, int top, int outerWidth);
|
||||
|
||||
bool containsPoint(QPoint position) const;
|
||||
bool buttonsContainPoint(QPoint position) const;
|
||||
AttachButtonType buttonTypeFromPoint(QPoint position) const;
|
||||
int distanceTo(QPoint position) const;
|
||||
bool isPointAfter(QPoint position) const;
|
||||
void moveInAlbum(QPoint to);
|
||||
QPoint center() const;
|
||||
void suggestMove(float64 delta, Fn<void()> callback);
|
||||
void finishAnimations();
|
||||
|
||||
void updateFileRow(int row);
|
||||
|
||||
static constexpr auto kShrinkDuration = crl::time(150);
|
||||
|
||||
private:
|
||||
QRect countRealGeometry() const;
|
||||
QRect countCurrentGeometry(float64 progress) const;
|
||||
void prepareCache(QSize size, int shrink);
|
||||
void drawSimpleFrame(Painter &p, QRect to, QSize size) const;
|
||||
QRect paintButtons(
|
||||
Painter &p,
|
||||
QPoint point,
|
||||
int outerWidth,
|
||||
float64 shrinkProgress);
|
||||
|
||||
GroupMediaLayout _layout;
|
||||
std::optional<QRect> _animateFromGeometry;
|
||||
const QImage _fullPreview;
|
||||
const int _shrinkSize = 0;
|
||||
QPixmap _albumImage;
|
||||
QImage _albumCache;
|
||||
QPoint _albumPosition;
|
||||
RectParts _albumCorners = RectPart::None;
|
||||
QPixmap _photo;
|
||||
QPixmap _fileThumb;
|
||||
QString _name;
|
||||
QString _status;
|
||||
int _nameWidth = 0;
|
||||
int _statusWidth = 0;
|
||||
bool _isVideo = false;
|
||||
float64 _suggestedMove = 0.;
|
||||
Animations::Simple _suggestedMoveAnimation;
|
||||
int _lastShrinkValue = 0;
|
||||
RoundRect _buttonsRect;
|
||||
|
||||
QRect _lastRectOfButtons;
|
||||
|
||||
object_ptr<IconButton> _editMedia = nullptr;
|
||||
object_ptr<IconButton> _deleteMedia = nullptr;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Ui
|
24
Telegram/SourceFiles/ui/chat/attach/attach_common.h
Normal file
24
Telegram/SourceFiles/ui/chat/attach/attach_common.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
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
|
||||
|
||||
namespace Ui {
|
||||
|
||||
enum class AttachButtonType {
|
||||
Edit,
|
||||
Delete,
|
||||
None,
|
||||
};
|
||||
|
||||
enum class SendFilesWay {
|
||||
Album,
|
||||
Photos,
|
||||
Files,
|
||||
};
|
||||
|
||||
} // namespace Ui
|
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
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 "ui/chat/attach/attach_single_file_preview.h"
|
||||
|
||||
#include "ui/chat/attach/attach_prepare.h"
|
||||
#include "ui/text/format_values.h"
|
||||
#include "ui/text/text_options.h"
|
||||
#include "ui/image/image_prepare.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "core/mime_type.h"
|
||||
#include "styles/style_chat.h"
|
||||
#include "styles/style_boxes.h"
|
||||
|
||||
#include <QtCore/QFileInfo>
|
||||
|
||||
namespace Ui {
|
||||
|
||||
SingleFilePreview::SingleFilePreview(
|
||||
QWidget *parent,
|
||||
const PreparedFile &file)
|
||||
: RpWidget(parent) {
|
||||
preparePreview(file);
|
||||
}
|
||||
|
||||
void SingleFilePreview::prepareThumb(const QImage &preview) {
|
||||
if (preview.isNull()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto originalWidth = preview.width();
|
||||
auto originalHeight = preview.height();
|
||||
auto thumbWidth = st::msgFileThumbSize;
|
||||
if (originalWidth > originalHeight) {
|
||||
thumbWidth = (originalWidth * st::msgFileThumbSize)
|
||||
/ originalHeight;
|
||||
}
|
||||
auto options = Images::Option::Smooth
|
||||
| Images::Option::RoundedSmall
|
||||
| Images::Option::RoundedTopLeft
|
||||
| Images::Option::RoundedTopRight
|
||||
| Images::Option::RoundedBottomLeft
|
||||
| Images::Option::RoundedBottomRight;
|
||||
_fileThumb = PixmapFromImage(Images::prepare(
|
||||
preview,
|
||||
thumbWidth * style::DevicePixelRatio(),
|
||||
0,
|
||||
options,
|
||||
st::msgFileThumbSize,
|
||||
st::msgFileThumbSize));
|
||||
}
|
||||
|
||||
void SingleFilePreview::preparePreview(const PreparedFile &file) {
|
||||
auto preview = QImage();
|
||||
if (const auto image = std::get_if<PreparedFileInformation::Image>(
|
||||
&file.information->media)) {
|
||||
preview = image->data;
|
||||
} else if (const auto video = std::get_if<PreparedFileInformation::Video>(
|
||||
&file.information->media)) {
|
||||
preview = video->thumbnail;
|
||||
}
|
||||
prepareThumb(preview);
|
||||
const auto filepath = file.path;
|
||||
if (filepath.isEmpty()) {
|
||||
//auto filename = filedialogDefaultName(
|
||||
// qsl("image"),
|
||||
// qsl(".png"),
|
||||
// QString(),
|
||||
// true); // #TODO files
|
||||
auto filename = "image.png";
|
||||
_nameText.setText(
|
||||
st::semiboldTextStyle,
|
||||
filename,
|
||||
NameTextOptions());
|
||||
_statusText = u"%1x%2"_q.arg(preview.width()).arg(preview.height());
|
||||
_statusWidth = qMax(_nameText.maxWidth(), st::normalFont->width(_statusText));
|
||||
_fileIsImage = true;
|
||||
} else {
|
||||
auto fileinfo = QFileInfo(filepath);
|
||||
auto filename = fileinfo.fileName();
|
||||
_fileIsImage = Core::FileIsImage(filename, Core::MimeTypeForFile(fileinfo).name());
|
||||
|
||||
auto songTitle = QString();
|
||||
auto songPerformer = QString();
|
||||
if (file.information) {
|
||||
if (const auto song = std::get_if<PreparedFileInformation::Song>(
|
||||
&file.information->media)) {
|
||||
songTitle = song->title;
|
||||
songPerformer = song->performer;
|
||||
_fileIsAudio = true;
|
||||
}
|
||||
}
|
||||
|
||||
const auto nameString = ComposeNameString(
|
||||
filename,
|
||||
songTitle,
|
||||
songPerformer);
|
||||
_nameText.setText(
|
||||
st::semiboldTextStyle,
|
||||
nameString,
|
||||
NameTextOptions());
|
||||
_statusText = FormatSizeText(fileinfo.size());
|
||||
_statusWidth = qMax(
|
||||
_nameText.maxWidth(),
|
||||
st::normalFont->width(_statusText));
|
||||
}
|
||||
}
|
||||
|
||||
void SingleFilePreview::paintEvent(QPaintEvent *e) {
|
||||
Painter p(this);
|
||||
|
||||
auto w = width() - st::boxPhotoPadding.left() - st::boxPhotoPadding.right();
|
||||
auto h = _fileThumb.isNull() ? (st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom()) : (st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom());
|
||||
auto nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0;
|
||||
if (_fileThumb.isNull()) {
|
||||
nameleft = st::msgFilePadding.left() + st::msgFileSize + st::msgFilePadding.right();
|
||||
nametop = st::msgFileNameTop;
|
||||
nameright = st::msgFilePadding.left();
|
||||
statustop = st::msgFileStatusTop;
|
||||
} else {
|
||||
nameleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right();
|
||||
nametop = st::msgFileThumbNameTop;
|
||||
nameright = st::msgFileThumbPadding.left();
|
||||
statustop = st::msgFileThumbStatusTop;
|
||||
linktop = st::msgFileThumbLinkTop;
|
||||
}
|
||||
auto namewidth = w - nameleft - (_fileThumb.isNull() ? st::msgFilePadding.left() : st::msgFileThumbPadding.left());
|
||||
int32 x = (width() - w) / 2, y = st::boxPhotoPadding.top();
|
||||
|
||||
FillRoundRect(p, x, y, w, h, st::msgOutBg, MessageOutCorners, &st::msgOutShadow);
|
||||
|
||||
if (_fileThumb.isNull()) {
|
||||
QRect inner(style::rtlrect(x + st::msgFilePadding.left(), y + st::msgFilePadding.top(), st::msgFileSize, st::msgFileSize, width()));
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(st::msgFileOutBg);
|
||||
|
||||
{
|
||||
PainterHighQualityEnabler hq(p);
|
||||
p.drawEllipse(inner);
|
||||
}
|
||||
|
||||
auto &icon = _fileIsAudio
|
||||
? st::historyFileOutPlay
|
||||
: _fileIsImage
|
||||
? st::historyFileOutImage
|
||||
: st::historyFileOutDocument;
|
||||
icon.paintInCenter(p, inner);
|
||||
} else {
|
||||
QRect rthumb(style::rtlrect(x + st::msgFileThumbPadding.left(), y + st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, width()));
|
||||
p.drawPixmap(rthumb.topLeft(), _fileThumb);
|
||||
}
|
||||
p.setFont(st::semiboldFont);
|
||||
p.setPen(st::historyFileNameOutFg);
|
||||
_nameText.drawLeftElided(p, x + nameleft, y + nametop, namewidth, width());
|
||||
|
||||
auto &status = st::mediaOutFg;
|
||||
p.setFont(st::normalFont);
|
||||
p.setPen(status);
|
||||
p.drawTextLeft(x + nameleft, y + statustop, width(), _statusText);
|
||||
}
|
||||
|
||||
rpl::producer<int> SingleFilePreview::desiredHeightValue() const {
|
||||
auto h = _fileThumb.isNull()
|
||||
? (st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom())
|
||||
: (st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom());
|
||||
return rpl::single(st::boxPhotoPadding.top() + h + st::msgShadow);
|
||||
}
|
||||
|
||||
} // namespace Ui
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
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/rp_widget.h"
|
||||
|
||||
namespace Ui {
|
||||
|
||||
struct PreparedFile;
|
||||
|
||||
class SingleFilePreview final : public RpWidget {
|
||||
public:
|
||||
SingleFilePreview(
|
||||
QWidget *parent,
|
||||
const PreparedFile &file);
|
||||
|
||||
rpl::producer<int> desiredHeightValue() const override;
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
|
||||
private:
|
||||
void preparePreview(const PreparedFile &file);
|
||||
void prepareThumb(const QImage &preview);
|
||||
|
||||
QPixmap _fileThumb;
|
||||
Text::String _nameText;
|
||||
bool _fileIsAudio = false;
|
||||
bool _fileIsImage = false;
|
||||
QString _statusText;
|
||||
int _statusWidth = 0;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Ui
|
|
@ -12,9 +12,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/effects/panel_animation.h"
|
||||
#include "ui/ui_utility.h"
|
||||
#include "ui/filter_icons.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "core/application.h"
|
||||
#include "app.h"
|
||||
#include "styles/style_chat_helpers.h"
|
||||
#include "styles/style_window.h"
|
||||
|
||||
|
@ -102,7 +102,7 @@ void FilterIconPanel::setupInner() {
|
|||
_inner->paintRequest(
|
||||
) | rpl::start_with_next([=](QRect clip) {
|
||||
auto p = Painter(_inner);
|
||||
App::roundRect(
|
||||
Ui::FillRoundRect(
|
||||
p,
|
||||
_inner->rect(),
|
||||
st::emojiPanBg,
|
||||
|
@ -122,11 +122,11 @@ void FilterIconPanel::setupInner() {
|
|||
continue;
|
||||
}
|
||||
if (i == selected) {
|
||||
App::roundRect(
|
||||
Ui::FillRoundRect(
|
||||
p,
|
||||
rect,
|
||||
st::emojiPanHover,
|
||||
StickerHoverCorners);
|
||||
Ui::StickerHoverCorners);
|
||||
}
|
||||
const auto icon = LookupFilterIcon(kIcons[i]).normal;
|
||||
icon->paintInCenter(p, rect, st::emojiIconFg->c);
|
||||
|
|
|
@ -444,8 +444,8 @@ std::vector<float64> ComplexLayouter::CropRatios(
|
|||
constexpr auto kMaxRatio = 2.75;
|
||||
constexpr auto kMinRatio = 0.6667;
|
||||
return (averageRatio > 1.1)
|
||||
? snap(ratio, 1., kMaxRatio)
|
||||
: snap(ratio, kMinRatio, 1.);
|
||||
? std::clamp(ratio, 1., kMaxRatio)
|
||||
: std::clamp(ratio, kMinRatio, 1.);
|
||||
}) | ranges::to_vector;
|
||||
}
|
||||
|
||||
|
|
|
@ -128,4 +128,20 @@ QString FillAmountAndCurrency(uint64 amount, const QString ¤cy) {
|
|||
//return currencyText + amountText;
|
||||
}
|
||||
|
||||
QString ComposeNameString(
|
||||
const QString &filename,
|
||||
const QString &songTitle,
|
||||
const QString &songPerformer) {
|
||||
if (songTitle.isEmpty() && songPerformer.isEmpty()) {
|
||||
return filename.isEmpty() ? u"Unknown File"_q : filename;
|
||||
}
|
||||
|
||||
if (songPerformer.isEmpty()) {
|
||||
return songTitle;
|
||||
}
|
||||
|
||||
auto trackTitle = (songTitle.isEmpty() ? u"Unknown Track"_q : songTitle);
|
||||
return songPerformer + QString::fromUtf8(" \xe2\x80\x93 ") + trackTitle;
|
||||
}
|
||||
|
||||
} // namespace Ui
|
||||
|
|
|
@ -25,4 +25,9 @@ inline constexpr auto FileStatusSizeFailed = 0x7FFFFFF2;
|
|||
uint64 amount,
|
||||
const QString ¤cy);
|
||||
|
||||
[[nodiscard]] QString ComposeNameString(
|
||||
const QString &filename,
|
||||
const QString &songTitle,
|
||||
const QString &songPerformer);
|
||||
|
||||
} // namespace Ui
|
||||
|
|
|
@ -118,7 +118,8 @@ struct BackgroundUpdate {
|
|||
[[nodiscard]] bool paletteChanged() const {
|
||||
return (type == Type::TestingTheme)
|
||||
|| (type == Type::RevertingTheme)
|
||||
|| (type == Type::ApplyingEdit);
|
||||
|| (type == Type::ApplyingEdit)
|
||||
|| (type == Type::New);
|
||||
}
|
||||
Type type;
|
||||
bool tiled;
|
||||
|
|
|
@ -10,9 +10,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/shadow.h"
|
||||
#include "ui/ui_utility.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "window/themes/window_theme.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "app.h"
|
||||
#include "styles/style_layers.h"
|
||||
#include "styles/style_boxes.h"
|
||||
|
||||
|
@ -62,7 +62,7 @@ void WarningWidget::paintEvent(QPaintEvent *e) {
|
|||
}
|
||||
|
||||
Ui::Shadow::paint(p, _inner, width(), st::boxRoundShadow);
|
||||
App::roundRect(p, _inner, st::boxBg, BoxCorners);
|
||||
Ui::FillRoundRect(p, _inner, st::boxBg, Ui::BoxCorners);
|
||||
|
||||
p.setFont(st::boxTitleFont);
|
||||
p.setPen(st::boxTitleFg);
|
||||
|
|
|
@ -10,9 +10,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "lang/lang_keys.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/shadow.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "mainwidget.h"
|
||||
#include "facades.h"
|
||||
#include "app.h"
|
||||
#include "styles/style_layers.h"
|
||||
#include "styles/style_chat.h"
|
||||
|
||||
|
@ -57,7 +57,7 @@ void HistoryHider::paintEvent(QPaintEvent *e) {
|
|||
p.setFont(st::historyForwardChooseFont);
|
||||
auto w = st::historyForwardChooseMargins.left() + _chooseWidth + st::historyForwardChooseMargins.right();
|
||||
auto h = st::historyForwardChooseMargins.top() + st::historyForwardChooseFont->height + st::historyForwardChooseMargins.bottom();
|
||||
App::roundRect(p, (width() - w) / 2, (height() - h) / 2, w, h, st::historyForwardChooseBg, ForwardCorners);
|
||||
Ui::FillRoundRect(p, (width() - w) / 2, (height() - h) / 2, w, h, st::historyForwardChooseBg, Ui::ForwardCorners);
|
||||
|
||||
p.setPen(st::historyForwardChooseFg);
|
||||
p.drawText(_box, _text, QTextOption(style::al_center));
|
||||
|
|
|
@ -9,11 +9,25 @@ init_target(td_ui)
|
|||
add_library(tdesktop::td_ui ALIAS td_ui)
|
||||
|
||||
include(lib_ui/cmake/generate_styles.cmake)
|
||||
include(cmake/generate_numbers.cmake)
|
||||
|
||||
set(style_files
|
||||
ui/td_common.style
|
||||
ui/filter_icons.style
|
||||
ui/chat/chat.style
|
||||
boxes/boxes.style
|
||||
dialogs/dialogs.style
|
||||
chat_helpers/chat_helpers.style
|
||||
calls/calls.style
|
||||
export/view/export.style
|
||||
info/info.style
|
||||
intro/intro.style
|
||||
media/player/media_player.style
|
||||
passport/passport.style
|
||||
profile/profile.style
|
||||
settings/settings.style
|
||||
media/view/media_view.style
|
||||
overview/overview.style
|
||||
window/window.style
|
||||
)
|
||||
|
||||
|
@ -25,14 +39,27 @@ set(dependent_style_files
|
|||
)
|
||||
|
||||
generate_styles(td_ui ${src_loc} "${style_files}" "${dependent_style_files}")
|
||||
generate_numbers(td_ui ${res_loc}/numbers.txt)
|
||||
|
||||
target_precompile_headers(td_ui PRIVATE ${src_loc}/ui/ui_pch.h)
|
||||
nice_target_sources(td_ui ${src_loc}
|
||||
PRIVATE
|
||||
${style_files}
|
||||
|
||||
core/mime_type.cpp
|
||||
core/mime_type.h
|
||||
|
||||
ui/chat/attach/attach_album_thumbnail.cpp
|
||||
ui/chat/attach/attach_album_thumbnail.h
|
||||
ui/chat/attach/attach_album_preview.cpp
|
||||
ui/chat/attach/attach_album_preview.h
|
||||
ui/chat/attach/attach_common.h
|
||||
ui/chat/attach/attach_extensions.cpp
|
||||
ui/chat/attach/attach_extensions.h
|
||||
ui/chat/attach/attach_prepare.cpp
|
||||
ui/chat/attach/attach_prepare.h
|
||||
ui/chat/attach/attach_single_file_preview.cpp
|
||||
ui/chat/attach/attach_single_file_preview.h
|
||||
ui/chat/message_bar.cpp
|
||||
ui/chat/message_bar.h
|
||||
ui/chat/pinned_bar.cpp
|
||||
|
@ -47,7 +74,11 @@ PRIVATE
|
|||
ui/text/text_options.h
|
||||
ui/toasts/common_toasts.cpp
|
||||
ui/toasts/common_toasts.h
|
||||
|
||||
ui/cached_round_corners.cpp
|
||||
ui/cached_round_corners.h
|
||||
ui/grouped_layout.cpp
|
||||
ui/grouped_layout.h
|
||||
|
||||
ui/ui_pch.h
|
||||
)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue