mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +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(lib_webrtc)
|
||||||
add_subdirectory(codegen)
|
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(src_loc SourceFiles REALPATH)
|
||||||
get_filename_component(res_loc Resources 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_scheme.cmake)
|
||||||
include(cmake/td_ui.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)
|
set_target_properties(Telegram PROPERTIES AUTOMOC ON AUTORCC ON)
|
||||||
|
|
||||||
target_link_libraries(Telegram
|
target_link_libraries(Telegram
|
||||||
|
@ -359,8 +329,6 @@ PRIVATE
|
||||||
core/launcher.h
|
core/launcher.h
|
||||||
core/local_url_handlers.cpp
|
core/local_url_handlers.cpp
|
||||||
core/local_url_handlers.h
|
core/local_url_handlers.h
|
||||||
core/mime_type.cpp
|
|
||||||
core/mime_type.h
|
|
||||||
core/sandbox.cpp
|
core/sandbox.cpp
|
||||||
core/sandbox.h
|
core/sandbox.h
|
||||||
core/shortcuts.cpp
|
core/shortcuts.cpp
|
||||||
|
@ -1023,8 +991,6 @@ PRIVATE
|
||||||
ui/filter_icons.h
|
ui/filter_icons.h
|
||||||
ui/filter_icon_panel.cpp
|
ui/filter_icon_panel.cpp
|
||||||
ui/filter_icon_panel.h
|
ui/filter_icon_panel.h
|
||||||
ui/grouped_layout.cpp
|
|
||||||
ui/grouped_layout.h
|
|
||||||
ui/item_text_options.cpp
|
ui/item_text_options.cpp
|
||||||
ui/item_text_options.h
|
ui/item_text_options.h
|
||||||
ui/resize_area.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 "history/view/history_view_service_message.h"
|
||||||
#include "media/audio/media_audio.h"
|
#include "media/audio/media_audio.h"
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "inline_bots/inline_bot_layout_item.h"
|
#include "inline_bots/inline_bot_layout_item.h"
|
||||||
#include "core/crash_reports.h"
|
#include "core/crash_reports.h"
|
||||||
#include "core/update_checker.h"
|
#include "core/update_checker.h"
|
||||||
|
@ -66,14 +67,6 @@ HistoryView::Element *hoveredItem = nullptr,
|
||||||
*pressedLinkItem = nullptr,
|
*pressedLinkItem = nullptr,
|
||||||
*mousedItem = 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
|
||||||
|
|
||||||
namespace App {
|
namespace App {
|
||||||
|
@ -104,114 +97,12 @@ namespace App {
|
||||||
return result;
|
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() {
|
void initMedia() {
|
||||||
createCorners();
|
Ui::StartCachedCorners();
|
||||||
|
|
||||||
using Update = Window::Theme::BackgroundUpdate;
|
using Update = Window::Theme::BackgroundUpdate;
|
||||||
static auto subscription = Window::Theme::Background()->add_subscription([](const Update &update) {
|
static auto subscription = Window::Theme::Background()->add_subscription([](const Update &update) {
|
||||||
if (update.paletteChanged()) {
|
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
|
if (const auto m = App::main()) { // multi good
|
||||||
m->updateScrollColors();
|
m->updateScrollColors();
|
||||||
}
|
}
|
||||||
|
@ -221,8 +112,7 @@ namespace App {
|
||||||
}
|
}
|
||||||
|
|
||||||
void deinitMedia() {
|
void deinitMedia() {
|
||||||
clearCorners();
|
Ui::FinishCachedCorners();
|
||||||
|
|
||||||
Data::clearGlobalStructures();
|
Data::clearGlobalStructures();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,132 +286,4 @@ namespace App {
|
||||||
return QPixmap::fromImage(std::move(image), Qt::ColorOnly);
|
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
|
#pragma once
|
||||||
|
|
||||||
#include "data/data_types.h"
|
#include "data/data_types.h"
|
||||||
#include "ui/rect_part.h"
|
|
||||||
|
|
||||||
enum class ImageRoundRadius;
|
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
class Element;
|
class Element;
|
||||||
} // namespace HistoryView
|
} // 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 {
|
namespace App {
|
||||||
QString formatPhone(QString phone);
|
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);
|
QImage readImage(const QString &file, QByteArray *format = nullptr, bool opaque = true, bool *animated = nullptr, QByteArray *content = 0);
|
||||||
QPixmap pixmapFromImageInPlace(QImage &&image);
|
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/text/text_options.h"
|
||||||
#include "ui/chat/attach/attach_prepare.h"
|
#include "ui/chat/attach/attach_prepare.h"
|
||||||
#include "ui/controls/emoji_button.h"
|
#include "ui/controls/emoji_button.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "confirm_box.h"
|
#include "confirm_box.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
|
#include "app.h" // App::pixmapFromImageInPlace.
|
||||||
#include "facades.h" // App::LambdaDelayed.
|
#include "facades.h" // App::LambdaDelayed.
|
||||||
#include "app.h"
|
|
||||||
#include "styles/style_layers.h"
|
#include "styles/style_layers.h"
|
||||||
#include "styles/style_boxes.h"
|
#include "styles/style_boxes.h"
|
||||||
#include "styles/style_chat_helpers.h"
|
#include "styles/style_chat_helpers.h"
|
||||||
|
@ -484,7 +485,7 @@ void EditCaptionBox::updateEditPreview() {
|
||||||
const auto fileinfo = QFileInfo(file->path);
|
const auto fileinfo = QFileInfo(file->path);
|
||||||
const auto filename = fileinfo.fileName();
|
const auto filename = fileinfo.fileName();
|
||||||
|
|
||||||
_isImage = fileIsImage(filename, file->mime);
|
_isImage = Core::FileIsImage(filename, file->mime);
|
||||||
_isAudio = false;
|
_isAudio = false;
|
||||||
_animated = false;
|
_animated = false;
|
||||||
_photo = false;
|
_photo = false;
|
||||||
|
@ -516,7 +517,7 @@ void EditCaptionBox::updateEditPreview() {
|
||||||
if (shouldAsDoc) {
|
if (shouldAsDoc) {
|
||||||
auto nameString = filename;
|
auto nameString = filename;
|
||||||
if (const auto song = std::get_if<Info::Song>(fileMedia)) {
|
if (const auto song = std::get_if<Info::Song>(fileMedia)) {
|
||||||
nameString = DocumentData::ComposeNameString(
|
nameString = Ui::ComposeNameString(
|
||||||
filename,
|
filename,
|
||||||
song->title,
|
song->title,
|
||||||
song->performer);
|
song->performer);
|
||||||
|
@ -623,9 +624,10 @@ void EditCaptionBox::createEditMediaButton() {
|
||||||
_editMedia.create(this, st::editMediaButton);
|
_editMedia.create(this, st::editMediaButton);
|
||||||
updateEditMediaButton();
|
updateEditMediaButton();
|
||||||
_editMedia->setClickedCallback(
|
_editMedia->setClickedCallback(
|
||||||
App::LambdaDelayed(st::historyAttach.ripple.hideDuration, this, [=] {
|
App::LambdaDelayed(
|
||||||
buttonCallback();
|
st::historyAttach.ripple.hideDuration,
|
||||||
}));
|
this,
|
||||||
|
buttonCallback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditCaptionBox::prepare() {
|
void EditCaptionBox::prepare() {
|
||||||
|
@ -894,7 +896,7 @@ void EditCaptionBox::paintEvent(QPaintEvent *e) {
|
||||||
const auto namewidth = w - nameleft - editButton;
|
const auto namewidth = w - nameleft - editButton;
|
||||||
const auto x = (width() - w) / 2, y = st::boxPhotoPadding.top();
|
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) {
|
if (_thumbw) {
|
||||||
QRect rthumb(style::rtlrect(x + 0, y + 0, st::msgFileThumbSize, st::msgFileThumbSize, width()));
|
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;
|
class InputField;
|
||||||
struct GroupMediaLayout;
|
struct GroupMediaLayout;
|
||||||
class EmojiButton;
|
class EmojiButton;
|
||||||
|
class AlbumPreview;
|
||||||
|
enum class SendFilesWay;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
|
@ -45,12 +47,6 @@ namespace SendMenu {
|
||||||
enum class Type;
|
enum class Type;
|
||||||
} // namespace SendMenu
|
} // namespace SendMenu
|
||||||
|
|
||||||
enum class SendFilesWay {
|
|
||||||
Album,
|
|
||||||
Photos,
|
|
||||||
Files,
|
|
||||||
};
|
|
||||||
|
|
||||||
class SendFilesBox : public Ui::BoxContent {
|
class SendFilesBox : public Ui::BoxContent {
|
||||||
public:
|
public:
|
||||||
enum class SendLimit {
|
enum class SendLimit {
|
||||||
|
@ -70,7 +66,7 @@ public:
|
||||||
void setConfirmedCallback(
|
void setConfirmedCallback(
|
||||||
Fn<void(
|
Fn<void(
|
||||||
Ui::PreparedList &&list,
|
Ui::PreparedList &&list,
|
||||||
SendFilesWay way,
|
Ui::SendFilesWay way,
|
||||||
TextWithTags &&caption,
|
TextWithTags &&caption,
|
||||||
Api::SendOptions options,
|
Api::SendOptions options,
|
||||||
bool ctrlShiftEnter)> callback) {
|
bool ctrlShiftEnter)> callback) {
|
||||||
|
@ -91,8 +87,6 @@ protected:
|
||||||
void resizeEvent(QResizeEvent *e) override;
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class AlbumPreview;
|
|
||||||
|
|
||||||
void initSendWay();
|
void initSendWay();
|
||||||
void initPreview(rpl::producer<int> desiredPreviewHeight);
|
void initPreview(rpl::producer<int> desiredPreviewHeight);
|
||||||
|
|
||||||
|
@ -101,7 +95,7 @@ private:
|
||||||
void setupCaption();
|
void setupCaption();
|
||||||
void setupShadows(
|
void setupShadows(
|
||||||
not_null<Ui::ScrollArea*> wrap,
|
not_null<Ui::ScrollArea*> wrap,
|
||||||
not_null<AlbumPreview*> content);
|
not_null<Ui::AlbumPreview*> content);
|
||||||
|
|
||||||
void setupEmojiPanel();
|
void setupEmojiPanel();
|
||||||
void updateEmojiPanelGeometry();
|
void updateEmojiPanelGeometry();
|
||||||
|
@ -149,7 +143,7 @@ private:
|
||||||
|
|
||||||
Fn<void(
|
Fn<void(
|
||||||
Ui::PreparedList &&list,
|
Ui::PreparedList &&list,
|
||||||
SendFilesWay way,
|
Ui::SendFilesWay way,
|
||||||
TextWithTags &&caption,
|
TextWithTags &&caption,
|
||||||
Api::SendOptions options,
|
Api::SendOptions options,
|
||||||
bool ctrlShiftEnter)> _confirmedCallback;
|
bool ctrlShiftEnter)> _confirmedCallback;
|
||||||
|
@ -161,16 +155,16 @@ private:
|
||||||
base::unique_qptr<ChatHelpers::TabbedPanel> _emojiPanel;
|
base::unique_qptr<ChatHelpers::TabbedPanel> _emojiPanel;
|
||||||
base::unique_qptr<QObject> _emojiFilter;
|
base::unique_qptr<QObject> _emojiFilter;
|
||||||
|
|
||||||
object_ptr<Ui::Radioenum<SendFilesWay>> _sendAlbum = { nullptr };
|
object_ptr<Ui::Radioenum<Ui::SendFilesWay>> _sendAlbum = { nullptr };
|
||||||
object_ptr<Ui::Radioenum<SendFilesWay>> _sendPhotos = { nullptr };
|
object_ptr<Ui::Radioenum<Ui::SendFilesWay>> _sendPhotos = { nullptr };
|
||||||
object_ptr<Ui::Radioenum<SendFilesWay>> _sendFiles = { nullptr };
|
object_ptr<Ui::Radioenum<Ui::SendFilesWay>> _sendFiles = { nullptr };
|
||||||
std::shared_ptr<Ui::RadioenumGroup<SendFilesWay>> _sendWay;
|
std::shared_ptr<Ui::RadioenumGroup<Ui::SendFilesWay>> _sendWay;
|
||||||
|
|
||||||
rpl::variable<int> _footerHeight = 0;
|
rpl::variable<int> _footerHeight = 0;
|
||||||
rpl::event_stream<> _albumChanged;
|
rpl::event_stream<> _albumChanged;
|
||||||
|
|
||||||
QWidget *_preview = nullptr;
|
QWidget *_preview = nullptr;
|
||||||
AlbumPreview *_albumPreview = nullptr;
|
Ui::AlbumPreview *_albumPreview = nullptr;
|
||||||
int _albumVideosCount = 0;
|
int _albumVideosCount = 0;
|
||||||
int _albumPhotosCount = 0;
|
int _albumPhotosCount = 0;
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/emoji_config.h"
|
#include "ui/emoji_config.h"
|
||||||
#include "ui/toast/toast.h"
|
#include "ui/toast/toast.h"
|
||||||
#include "ui/widgets/popup_menu.h"
|
#include "ui/widgets/popup_menu.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "lottie/lottie_multi_player.h"
|
#include "lottie/lottie_multi_player.h"
|
||||||
#include "lottie/lottie_animation.h"
|
#include "lottie/lottie_animation.h"
|
||||||
#include "chat_helpers/stickers_lottie.h"
|
#include "chat_helpers/stickers_lottie.h"
|
||||||
|
@ -35,7 +36,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "app.h"
|
|
||||||
#include "styles/style_layers.h"
|
#include "styles/style_layers.h"
|
||||||
#include "styles/style_chat_helpers.h"
|
#include "styles/style_chat_helpers.h"
|
||||||
#include "styles/style_info.h"
|
#include "styles/style_info.h"
|
||||||
|
@ -661,7 +661,7 @@ void StickerSetBox::Inner::paintSticker(
|
||||||
p.setOpacity(over);
|
p.setOpacity(over);
|
||||||
auto tl = position;
|
auto tl = position;
|
||||||
if (rtl()) tl.setX(width() - tl.x() - st::stickersSize.width());
|
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);
|
p.setOpacity(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,9 +33,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/widgets/discrete_sliders.h"
|
#include "ui/widgets/discrete_sliders.h"
|
||||||
#include "ui/widgets/input_fields.h"
|
#include "ui/widgets/input_fields.h"
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "app.h"
|
|
||||||
#include "styles/style_layers.h"
|
#include "styles/style_layers.h"
|
||||||
#include "styles/style_boxes.h"
|
#include "styles/style_boxes.h"
|
||||||
#include "styles/style_chat_helpers.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);
|
Ui::Shadow::paint(p, rect, width(), st::boxRoundShadow);
|
||||||
p.setOpacity(1);
|
p.setOpacity(1);
|
||||||
|
|
||||||
App::roundRect(p, rect, st::boxBg, BoxCorners);
|
Ui::FillRoundRect(p, rect, st::boxBg, Ui::BoxCorners);
|
||||||
|
|
||||||
p.setOpacity(1. - current);
|
p.setOpacity(1. - current);
|
||||||
paintFakeButton(p, row, index);
|
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 textWidth = (_section == Section::Installed) ? _undoWidth : _addWidth;
|
||||||
auto &text = (_section == Section::Installed) ? _undoText : _addText;
|
auto &text = (_section == Section::Installed) ? _undoText : _addText;
|
||||||
auto &textBg = selected ? st.textBgOver : st.textBg;
|
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) {
|
if (row->ripple) {
|
||||||
row->ripple->paint(p, rect.x(), rect.y(), width());
|
row->ripple->paint(p, rect.x(), rect.y(), width());
|
||||||
if (row->ripple->empty()) {
|
if (row->ripple->empty()) {
|
||||||
|
|
|
@ -12,8 +12,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "facades.h"
|
#include "facades.h"
|
||||||
#include "app.h"
|
|
||||||
#include "styles/style_widgets.h"
|
#include "styles/style_widgets.h"
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ void Style::paintButtonBg(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
const QRect &rect,
|
const QRect &rect,
|
||||||
float64 howMuchOver) const {
|
float64 howMuchOver) const {
|
||||||
App::roundRect(p, rect, st::botKbBg, BotKeyboardCorners);
|
Ui::FillRoundRect(p, rect, st::botKbBg, Ui::BotKeyboardCorners);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Style::paintButtonIcon(
|
void Style::paintButtonIcon(
|
||||||
|
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/widgets/shadow.h"
|
#include "ui/widgets/shadow.h"
|
||||||
#include "ui/emoji_config.h"
|
#include "ui/emoji_config.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "emoji_suggestions_data.h"
|
#include "emoji_suggestions_data.h"
|
||||||
#include "emoji_suggestions_helper.h"
|
#include "emoji_suggestions_helper.h"
|
||||||
|
@ -20,7 +21,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "facades.h"
|
#include "facades.h"
|
||||||
#include "app.h"
|
|
||||||
#include "styles/style_chat_helpers.h"
|
#include "styles/style_chat_helpers.h"
|
||||||
|
|
||||||
namespace ChatHelpers {
|
namespace ChatHelpers {
|
||||||
|
@ -211,7 +211,7 @@ void EmojiColorPicker::paintEvent(QPaintEvent *e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Ui::Shadow::paint(p, inner, width(), st::defaultRoundShadow);
|
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();
|
auto x = st::emojiPanMargins.left() + 2 * st::emojiColorsPadding + _singleSize.width();
|
||||||
if (rtl()) x = width() - x - st::emojiColorsSep;
|
if (rtl()) x = width() - x - st::emojiColorsSep;
|
||||||
|
@ -372,7 +372,7 @@ void EmojiColorPicker::drawVariant(Painter &p, int variant) {
|
||||||
if (variant == _selected) {
|
if (variant == _selected) {
|
||||||
QPoint tl(w);
|
QPoint tl(w);
|
||||||
if (rtl()) tl.setX(width() - tl.x() - _singleSize.width());
|
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();
|
const auto esize = Ui::Emoji::GetSizeLarge();
|
||||||
Ui::Emoji::Draw(
|
Ui::Emoji::Draw(
|
||||||
|
@ -558,7 +558,7 @@ void EmojiListWidget::paintEvent(QPaintEvent *e) {
|
||||||
if (selected) {
|
if (selected) {
|
||||||
auto tl = w;
|
auto tl = w;
|
||||||
if (rtl()) tl.setX(width() - tl.x() - _singleSize.width());
|
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(
|
Ui::Emoji::Draw(
|
||||||
p,
|
p,
|
||||||
|
|
|
@ -17,11 +17,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/widgets/input_fields.h"
|
#include "ui/widgets/input_fields.h"
|
||||||
#include "ui/emoji_config.h"
|
#include "ui/emoji_config.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "platform/platform_specific.h"
|
#include "platform/platform_specific.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "base/event_filter.h"
|
#include "base/event_filter.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "app.h"
|
|
||||||
#include "styles/style_chat_helpers.h"
|
#include "styles/style_chat_helpers.h"
|
||||||
|
|
||||||
#include <QtWidgets/QApplication>
|
#include <QtWidgets/QApplication>
|
||||||
|
@ -218,11 +218,11 @@ void SuggestionsWidget::paintEvent(QPaintEvent *e) {
|
||||||
? _pressed
|
? _pressed
|
||||||
: _selectedAnimation.value(_selected);
|
: _selectedAnimation.value(_selected);
|
||||||
if (selected > -1.) {
|
if (selected > -1.) {
|
||||||
App::roundRect(
|
Ui::FillRoundRect(
|
||||||
p,
|
p,
|
||||||
QRect(selected * _oneWidth, 0, _oneWidth, _oneWidth),
|
QRect(selected * _oneWidth, 0, _oneWidth, _oneWidth),
|
||||||
st::emojiPanHover,
|
st::emojiPanHover,
|
||||||
StickerHoverCorners);
|
Ui::StickerHoverCorners);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto i = from; i != till; ++i) {
|
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/widgets/scroll_area.h"
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "base/unixtime.h"
|
#include "base/unixtime.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "facades.h"
|
#include "facades.h"
|
||||||
#include "app.h"
|
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
#include "styles/style_widgets.h"
|
#include "styles/style_widgets.h"
|
||||||
#include "styles/style_chat_helpers.h"
|
#include "styles/style_chat_helpers.h"
|
||||||
|
@ -686,7 +686,7 @@ void FieldAutocompleteInner::paintEvent(QPaintEvent *e) {
|
||||||
if (_sel == index) {
|
if (_sel == index) {
|
||||||
QPoint tl(pos);
|
QPoint tl(pos);
|
||||||
if (rtl()) tl.setX(width() - tl.x() - st::stickerPanSize.width());
|
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();
|
media->checkStickerSmall();
|
||||||
|
|
|
@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/effects/animations.h"
|
#include "ui/effects/animations.h"
|
||||||
#include "ui/effects/ripple_animation.h"
|
#include "ui/effects/ripple_animation.h"
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "lottie/lottie_multi_player.h"
|
#include "lottie/lottie_multi_player.h"
|
||||||
#include "lottie/lottie_single_player.h"
|
#include "lottie/lottie_single_player.h"
|
||||||
#include "lottie/lottie_animation.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 "main/main_session_settings.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "api/api_toggling_media.h" // Api::ToggleFavedSticker
|
#include "api/api_toggling_media.h" // Api::ToggleFavedSticker
|
||||||
#include "app.h"
|
|
||||||
#include "styles/style_chat_helpers.h"
|
#include "styles/style_chat_helpers.h"
|
||||||
#include "styles/style_window.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 selected = selectedButton ? (selectedButton->section == info.section) : false;
|
||||||
auto &textBg = selected ? st::stickersTrendingAdd.textBgOver : st::stickersTrendingAdd.textBg;
|
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) {
|
if (set.ripple) {
|
||||||
set.ripple->paint(p, add.x(), add.y(), width());
|
set.ripple->paint(p, add.x(), add.y(), width());
|
||||||
if (set.ripple->empty()) {
|
if (set.ripple->empty()) {
|
||||||
|
@ -1767,7 +1767,7 @@ void StickersListWidget::paintMegagroupEmptySet(Painter &p, int y, bool buttonSe
|
||||||
: st::stickerGroupCategoryAdd.textBg;
|
: st::stickerGroupCategoryAdd.textBg;
|
||||||
|
|
||||||
auto button = _megagroupSetButtonRect.translated(0, y);
|
auto button = _megagroupSetButtonRect.translated(0, y);
|
||||||
App::roundRect(p, myrtlrect(button), textBg, ImageRoundRadius::Small);
|
Ui::FillRoundRect(p, myrtlrect(button), textBg, ImageRoundRadius::Small);
|
||||||
if (_megagroupSetButtonRipple) {
|
if (_megagroupSetButtonRipple) {
|
||||||
_megagroupSetButtonRipple->paint(p, button.x(), button.y(), width());
|
_megagroupSetButtonRipple->paint(p, button.x(), button.y(), width());
|
||||||
if (_megagroupSetButtonRipple->empty()) {
|
if (_megagroupSetButtonRipple->empty()) {
|
||||||
|
@ -1847,7 +1847,7 @@ void StickersListWidget::paintSticker(Painter &p, Set &set, int y, int section,
|
||||||
if (selected) {
|
if (selected) {
|
||||||
auto tl = pos;
|
auto tl = pos;
|
||||||
if (rtl()) tl.setX(width() - tl.x() - _singleSize.width());
|
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();
|
media->checkStickerSmall();
|
||||||
|
|
|
@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/widgets/popup_menu.h"
|
#include "ui/widgets/popup_menu.h"
|
||||||
#include "ui/widgets/scroll_area.h"
|
#include "ui/widgets/scroll_area.h"
|
||||||
#include "ui/image/image_prepare.h"
|
#include "ui/image/image_prepare.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "main/main_session_settings.h"
|
#include "main/main_session_settings.h"
|
||||||
|
@ -521,10 +522,10 @@ void TabbedSelector::paintSlideFrame(Painter &p) {
|
||||||
if (_roundRadius > 0) {
|
if (_roundRadius > 0) {
|
||||||
if (full()) {
|
if (full()) {
|
||||||
auto topPart = QRect(0, 0, width(), _tabsSlider->height() + _roundRadius);
|
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 {
|
} else {
|
||||||
auto topPart = QRect(0, 0, width(), 3 * _roundRadius);
|
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()) {
|
} else if (full()) {
|
||||||
p.fillRect(0, 0, width(), _tabsSlider->height(), st::emojiPanBg);
|
p.fillRect(0, 0, width(), _tabsSlider->height(), st::emojiPanBg);
|
||||||
|
@ -538,15 +539,15 @@ void TabbedSelector::paintContent(Painter &p) {
|
||||||
if (_roundRadius > 0) {
|
if (_roundRadius > 0) {
|
||||||
if (full()) {
|
if (full()) {
|
||||||
auto topPart = QRect(0, 0, width(), _tabsSlider->height() + _roundRadius);
|
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 {
|
} else {
|
||||||
auto topPart = QRect(0, 0, width(), 3 * _roundRadius);
|
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 bottomPart = QRect(0, _footerTop - _roundRadius, width(), st::emojiFooterHeight + _roundRadius);
|
||||||
auto bottomParts = RectPart::NoTopBottom | RectPart::FullBottom;
|
auto bottomParts = RectPart::NoTopBottom | RectPart::FullBottom;
|
||||||
App::roundRect(p, bottomPart, bottomBg, ImageRoundRadius::Small, bottomParts);
|
Ui::FillRoundRect(p, bottomPart, bottomBg, ImageRoundRadius::Small, bottomParts);
|
||||||
} else {
|
} else {
|
||||||
if (full()) {
|
if (full()) {
|
||||||
p.fillRect(0, 0, width(), _tabsSlider->height(), st::emojiPanBg);
|
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 "boxes/send_files_box.h"
|
||||||
#include "ui/widgets/input_fields.h"
|
#include "ui/widgets/input_fields.h"
|
||||||
|
#include "ui/chat/attach/attach_common.h"
|
||||||
#include "storage/serialize_common.h"
|
#include "storage/serialize_common.h"
|
||||||
#include "window/themes/window_theme.h"
|
#include "window/themes/window_theme.h"
|
||||||
#include "window/section_widget.h"
|
#include "window/section_widget.h"
|
||||||
|
@ -18,7 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
Settings::Settings()
|
Settings::Settings()
|
||||||
: _sendFilesWay(SendFilesWay::Album)
|
: _sendFilesWay(Ui::SendFilesWay::Album)
|
||||||
, _sendSubmitWay(Ui::InputSubmitSettings::Enter)
|
, _sendSubmitWay(Ui::InputSubmitSettings::Enter)
|
||||||
, _floatPlayerColumn(Window::Column::Second)
|
, _floatPlayerColumn(Window::Column::Second)
|
||||||
, _floatPlayerCorner(RectPart::TopRight)
|
, _floatPlayerCorner(RectPart::TopRight)
|
||||||
|
@ -309,11 +310,11 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
|
||||||
_callAudioDuckingEnabled = (callAudioDuckingEnabled == 1);
|
_callAudioDuckingEnabled = (callAudioDuckingEnabled == 1);
|
||||||
_lastSeenWarningSeen = (lastSeenWarningSeen == 1);
|
_lastSeenWarningSeen = (lastSeenWarningSeen == 1);
|
||||||
_soundOverrides = std::move(soundOverrides);
|
_soundOverrides = std::move(soundOverrides);
|
||||||
auto uncheckedSendFilesWay = static_cast<SendFilesWay>(sendFilesWay);
|
auto uncheckedSendFilesWay = static_cast<Ui::SendFilesWay>(sendFilesWay);
|
||||||
switch (uncheckedSendFilesWay) {
|
switch (uncheckedSendFilesWay) {
|
||||||
case SendFilesWay::Album:
|
case Ui::SendFilesWay::Album:
|
||||||
case SendFilesWay::Photos:
|
case Ui::SendFilesWay::Photos:
|
||||||
case SendFilesWay::Files: _sendFilesWay = uncheckedSendFilesWay; break;
|
case Ui::SendFilesWay::Files: _sendFilesWay = uncheckedSendFilesWay; break;
|
||||||
}
|
}
|
||||||
auto uncheckedSendSubmitWay = static_cast<Ui::InputSubmitSettings>(sendSubmitWay);
|
auto uncheckedSendSubmitWay = static_cast<Ui::InputSubmitSettings>(sendSubmitWay);
|
||||||
switch (uncheckedSendSubmitWay) {
|
switch (uncheckedSendSubmitWay) {
|
||||||
|
@ -469,7 +470,7 @@ void Settings::resetOnLastLogout() {
|
||||||
//_themesAccentColors = Window::Theme::AccentColors();
|
//_themesAccentColors = Window::Theme::AccentColors();
|
||||||
|
|
||||||
_lastSeenWarningSeen = false;
|
_lastSeenWarningSeen = false;
|
||||||
_sendFilesWay = SendFilesWay::Album;
|
_sendFilesWay = Ui::SendFilesWay::Album;
|
||||||
//_sendSubmitWay = Ui::InputSubmitSettings::Enter;
|
//_sendSubmitWay = Ui::InputSubmitSettings::Enter;
|
||||||
_soundOverrides = {};
|
_soundOverrides = {};
|
||||||
|
|
||||||
|
|
|
@ -10,11 +10,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "window/themes/window_themes_embedded.h"
|
#include "window/themes/window_themes_embedded.h"
|
||||||
#include "window/window_controls_layout.h"
|
#include "window/window_controls_layout.h"
|
||||||
|
|
||||||
enum class SendFilesWay;
|
|
||||||
enum class RectPart;
|
enum class RectPart;
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
enum class InputSubmitSettings;
|
enum class InputSubmitSettings;
|
||||||
|
enum class SendFilesWay;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
|
@ -229,10 +229,10 @@ public:
|
||||||
[[nodiscard]] bool lastSeenWarningSeen() const {
|
[[nodiscard]] bool lastSeenWarningSeen() const {
|
||||||
return _lastSeenWarningSeen;
|
return _lastSeenWarningSeen;
|
||||||
}
|
}
|
||||||
void setSendFilesWay(SendFilesWay way) {
|
void setSendFilesWay(Ui::SendFilesWay way) {
|
||||||
_sendFilesWay = way;
|
_sendFilesWay = way;
|
||||||
}
|
}
|
||||||
[[nodiscard]] SendFilesWay sendFilesWay() const {
|
[[nodiscard]] Ui::SendFilesWay sendFilesWay() const {
|
||||||
return _sendFilesWay;
|
return _sendFilesWay;
|
||||||
}
|
}
|
||||||
void setSendSubmitWay(Ui::InputSubmitSettings value) {
|
void setSendSubmitWay(Ui::InputSubmitSettings value) {
|
||||||
|
@ -515,7 +515,7 @@ private:
|
||||||
bool _callAudioDuckingEnabled = true;
|
bool _callAudioDuckingEnabled = true;
|
||||||
Window::Theme::AccentColors _themesAccentColors;
|
Window::Theme::AccentColors _themesAccentColors;
|
||||||
bool _lastSeenWarningSeen = false;
|
bool _lastSeenWarningSeen = false;
|
||||||
SendFilesWay _sendFilesWay;
|
Ui::SendFilesWay _sendFilesWay;
|
||||||
Ui::InputSubmitSettings _sendSubmitWay;
|
Ui::InputSubmitSettings _sendSubmitWay;
|
||||||
base::flat_map<QString, QString> _soundOverrides;
|
base::flat_map<QString, QString> _soundOverrides;
|
||||||
bool _exeLaunchWarning = true;
|
bool _exeLaunchWarning = true;
|
||||||
|
|
|
@ -118,4 +118,23 @@ bool IsMimeAcceptedForAlbum(const QString &mime) {
|
||||||
|| (mime == u"video/quicktime"_q);
|
|| (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
|
} // namespace Core
|
||||||
|
|
|
@ -36,12 +36,14 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
MimeType MimeTypeForName(const QString &mime);
|
[[nodiscard]] MimeType MimeTypeForName(const QString &mime);
|
||||||
MimeType MimeTypeForFile(const QFileInfo &file);
|
[[nodiscard]] MimeType MimeTypeForFile(const QFileInfo &file);
|
||||||
MimeType MimeTypeForData(const QByteArray &data);
|
[[nodiscard]] MimeType MimeTypeForData(const QByteArray &data);
|
||||||
|
|
||||||
bool IsMimeStickerAnimated(const QString &mime);
|
[[nodiscard]] bool IsMimeStickerAnimated(const QString &mime);
|
||||||
bool IsMimeSticker(const QString &mime);
|
[[nodiscard]] bool IsMimeSticker(const QString &mime);
|
||||||
bool IsMimeAcceptedForAlbum(const QString &mime);
|
[[nodiscard]] bool IsMimeAcceptedForAlbum(const QString &mime);
|
||||||
|
|
||||||
|
[[nodiscard]] bool FileIsImage(const QString &name, const QString &mime);
|
||||||
|
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
|
|
@ -39,6 +39,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "boxes/confirm_box.h"
|
#include "boxes/confirm_box.h"
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
#include "ui/text/text_utilities.h"
|
#include "ui/text/text_utilities.h"
|
||||||
|
#include "ui/text/format_values.h"
|
||||||
#include "base/base_file_utilities.h"
|
#include "base/base_file_utilities.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
|
@ -125,25 +126,6 @@ void LaunchWithWarning(
|
||||||
|
|
||||||
} // namespace
|
} // 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(
|
QString FileNameUnsafe(
|
||||||
not_null<Main::Session*> session,
|
not_null<Main::Session*> session,
|
||||||
const QString &title,
|
const QString &title,
|
||||||
|
@ -1456,12 +1438,12 @@ uint8 DocumentData::cacheTag() const {
|
||||||
|
|
||||||
QString DocumentData::composeNameString() const {
|
QString DocumentData::composeNameString() const {
|
||||||
if (auto songData = song()) {
|
if (auto songData = song()) {
|
||||||
return ComposeNameString(
|
return Ui::ComposeNameString(
|
||||||
_filename,
|
_filename,
|
||||||
songData->title,
|
songData->title,
|
||||||
songData->performer);
|
songData->performer);
|
||||||
}
|
}
|
||||||
return ComposeNameString(_filename, QString(), QString());
|
return Ui::ComposeNameString(_filename, QString(), QString());
|
||||||
}
|
}
|
||||||
|
|
||||||
LocationType DocumentData::locationType() const {
|
LocationType DocumentData::locationType() const {
|
||||||
|
@ -1577,7 +1559,7 @@ void DocumentData::setMaybeSupportsStreaming(bool supports) {
|
||||||
void DocumentData::recountIsImage() {
|
void DocumentData::recountIsImage() {
|
||||||
const auto isImage = !isAnimation()
|
const auto isImage = !isAnimation()
|
||||||
&& !isVideoFile()
|
&& !isVideoFile()
|
||||||
&& fileIsImage(filename(), mimeString());
|
&& Core::FileIsImage(filename(), mimeString());
|
||||||
if (isImage) {
|
if (isImage) {
|
||||||
_flags |= Flag::ImageType;
|
_flags |= Flag::ImageType;
|
||||||
} else {
|
} 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 {
|
namespace Data {
|
||||||
|
|
||||||
QString FileExtension(const QString &filepath) {
|
QString FileExtension(const QString &filepath) {
|
||||||
|
|
|
@ -78,8 +78,6 @@ struct VoiceData : public DocumentAdditionalData {
|
||||||
char wavemax = 0;
|
char wavemax = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool fileIsImage(const QString &name, const QString &mime);
|
|
||||||
|
|
||||||
namespace Serialize {
|
namespace Serialize {
|
||||||
class Document;
|
class Document;
|
||||||
} // namespace Serialize;
|
} // namespace Serialize;
|
||||||
|
@ -228,10 +226,6 @@ public:
|
||||||
[[nodiscard]] Storage::Cache::Key cacheKey() const;
|
[[nodiscard]] Storage::Cache::Key cacheKey() const;
|
||||||
[[nodiscard]] uint8 cacheTag() const;
|
[[nodiscard]] uint8 cacheTag() const;
|
||||||
|
|
||||||
[[nodiscard]] static QString ComposeNameString(
|
|
||||||
const QString &filename,
|
|
||||||
const QString &songTitle,
|
|
||||||
const QString &songPerformer);
|
|
||||||
[[nodiscard]] QString composeNameString() const;
|
[[nodiscard]] QString composeNameString() const;
|
||||||
|
|
||||||
[[nodiscard]] bool canBeStreamed() const;
|
[[nodiscard]] bool canBeStreamed() const;
|
||||||
|
|
|
@ -18,10 +18,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "ui/widgets/shadow.h"
|
#include "ui/widgets/shadow.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "app.h"
|
|
||||||
#include "storage/storage_media_prepare.h"
|
#include "storage/storage_media_prepare.h"
|
||||||
#include "styles/style_chat_helpers.h"
|
#include "styles/style_chat_helpers.h"
|
||||||
#include "styles/style_layers.h"
|
#include "styles/style_layers.h"
|
||||||
|
@ -315,7 +315,7 @@ void DragArea::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Ui::Shadow::paint(p, inner, width(), st::boxRoundShadow);
|
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(
|
p.setPen(anim::pen(
|
||||||
st::dragColor,
|
st::dragColor,
|
||||||
|
|
|
@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/toast/toast.h"
|
#include "ui/toast/toast.h"
|
||||||
#include "ui/text/text_options.h"
|
#include "ui/text/text_options.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "ui/inactive_press.h"
|
#include "ui/inactive_press.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "window/window_peer_menu.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 (!_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()) {
|
if (clip.y() < _botAbout->rect.y() + _botAbout->rect.height() && clip.y() + clip.height() > _botAbout->rect.y()) {
|
||||||
p.setTextPalette(st::inTextPalette);
|
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();
|
auto top = _botAbout->rect.top() + st::msgPadding.top();
|
||||||
if (!_history->peer->isRepliesChat()) {
|
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/text_utilities.h" // Ui::Text::ToUpper
|
||||||
#include "ui/text/format_values.h"
|
#include "ui/text/format_values.h"
|
||||||
#include "ui/chat/message_bar.h"
|
#include "ui/chat/message_bar.h"
|
||||||
|
#include "ui/chat/attach/attach_common.h"
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
#include "ui/special_buttons.h"
|
#include "ui/special_buttons.h"
|
||||||
#include "ui/controls/emoji_button.h"
|
#include "ui/controls/emoji_button.h"
|
||||||
|
@ -4193,17 +4194,17 @@ bool HistoryWidget::confirmSendingFiles(
|
||||||
_field->setTextWithTags({});
|
_field->setTextWithTags({});
|
||||||
box->setConfirmedCallback(crl::guard(this, [=](
|
box->setConfirmedCallback(crl::guard(this, [=](
|
||||||
Ui::PreparedList &&list,
|
Ui::PreparedList &&list,
|
||||||
SendFilesWay way,
|
Ui::SendFilesWay way,
|
||||||
TextWithTags &&caption,
|
TextWithTags &&caption,
|
||||||
Api::SendOptions options,
|
Api::SendOptions options,
|
||||||
bool ctrlShiftEnter) {
|
bool ctrlShiftEnter) {
|
||||||
if (showSendingFilesError(list)) {
|
if (showSendingFilesError(list)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto type = (way == SendFilesWay::Files)
|
const auto type = (way == Ui::SendFilesWay::Files)
|
||||||
? SendMediaType::File
|
? SendMediaType::File
|
||||||
: SendMediaType::Photo;
|
: SendMediaType::Photo;
|
||||||
const auto album = (way == SendFilesWay::Album)
|
const auto album = (way == Ui::SendFilesWay::Album)
|
||||||
? std::make_shared<SendingAlbum>()
|
? std::make_shared<SendingAlbum>()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
uploadFilesAfterConfirmation(
|
uploadFilesAfterConfirmation(
|
||||||
|
|
|
@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/toast/toast.h"
|
#include "ui/toast/toast.h"
|
||||||
#include "ui/text/text_utilities.h"
|
#include "ui/text/text_utilities.h"
|
||||||
#include "ui/text/text_entity.h"
|
#include "ui/text/text_entity.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
|
@ -30,7 +31,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
#include "facades.h"
|
#include "facades.h"
|
||||||
#include "app.h"
|
|
||||||
#include "styles/style_widgets.h"
|
#include "styles/style_widgets.h"
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
#include "styles/style_dialogs.h"
|
#include "styles/style_dialogs.h"
|
||||||
|
@ -81,11 +81,11 @@ void KeyboardStyle::paintButtonBg(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
const QRect &rect,
|
const QRect &rect,
|
||||||
float64 howMuchOver) const {
|
float64 howMuchOver) const {
|
||||||
App::roundRect(p, rect, st::msgServiceBg, StickerCorners);
|
Ui::FillRoundRect(p, rect, st::msgServiceBg, Ui::StickerCorners);
|
||||||
if (howMuchOver > 0) {
|
if (howMuchOver > 0) {
|
||||||
auto o = p.opacity();
|
auto o = p.opacity();
|
||||||
p.setOpacity(o * howMuchOver);
|
p.setOpacity(o * howMuchOver);
|
||||||
App::roundRect(p, rect, st::msgBotKbOverBgAdd, BotKbOverCorners);
|
Ui::FillRoundRect(p, rect, st::msgBotKbOverBgAdd, Ui::BotKbOverCorners);
|
||||||
p.setOpacity(o);
|
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) {
|
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 &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 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;
|
auto parts = RectPart::None | RectPart::NoTopBottom;
|
||||||
if (skip & RectPart::Top) {
|
if (skip & RectPart::Top) {
|
||||||
if (skip & RectPart::Bottom) {
|
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)) {
|
} else if (!(skip & RectPart::Bottom)) {
|
||||||
parts |= RectPart::FullBottom;
|
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) {
|
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;
|
auto dateY = infoBottom - st::msgDateFont->height;
|
||||||
if (type == InfoDisplayType::Image) {
|
if (type == InfoDisplayType::Image) {
|
||||||
auto dateW = infoW + 2 * st::msgDateImgPadding.x(), dateH = st::msgDateFont->height + 2 * st::msgDateImgPadding.y();
|
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) {
|
} else if (type == InfoDisplayType::Background) {
|
||||||
auto dateW = infoW + 2 * st::msgDateImgPadding.x(), dateH = st::msgDateFont->height + 2 * st::msgDateImgPadding.y();
|
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();
|
dateX += timeLeft();
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/text/format_values.h"
|
#include "ui/text/format_values.h"
|
||||||
#include "ui/text/text_utilities.h"
|
#include "ui/text/text_utilities.h"
|
||||||
#include "ui/chat/attach/attach_prepare.h"
|
#include "ui/chat/attach/attach_prepare.h"
|
||||||
|
#include "ui/chat/attach/attach_common.h"
|
||||||
#include "ui/special_buttons.h"
|
#include "ui/special_buttons.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
#include "ui/toasts/common_toasts.h"
|
#include "ui/toasts/common_toasts.h"
|
||||||
|
@ -635,17 +636,17 @@ bool RepliesWidget::confirmSendingFiles(
|
||||||
const auto replyTo = replyToId();
|
const auto replyTo = replyToId();
|
||||||
box->setConfirmedCallback(crl::guard(this, [=](
|
box->setConfirmedCallback(crl::guard(this, [=](
|
||||||
Ui::PreparedList &&list,
|
Ui::PreparedList &&list,
|
||||||
SendFilesWay way,
|
Ui::SendFilesWay way,
|
||||||
TextWithTags &&caption,
|
TextWithTags &&caption,
|
||||||
Api::SendOptions options,
|
Api::SendOptions options,
|
||||||
bool ctrlShiftEnter) {
|
bool ctrlShiftEnter) {
|
||||||
if (showSendingFilesError(list)) {
|
if (showSendingFilesError(list)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto type = (way == SendFilesWay::Files)
|
const auto type = (way == Ui::SendFilesWay::Files)
|
||||||
? SendMediaType::File
|
? SendMediaType::File
|
||||||
: SendMediaType::Photo;
|
: SendMediaType::Photo;
|
||||||
const auto album = (way == SendFilesWay::Album)
|
const auto album = (way == Ui::SendFilesWay::Album)
|
||||||
? std::make_shared<SendingAlbum>()
|
? std::make_shared<SendingAlbum>()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
uploadFilesAfterConfirmation(
|
uploadFilesAfterConfirmation(
|
||||||
|
|
|
@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/item_text_options.h"
|
#include "ui/item_text_options.h"
|
||||||
#include "ui/toast/toast.h"
|
#include "ui/toast/toast.h"
|
||||||
#include "ui/chat/attach/attach_prepare.h"
|
#include "ui/chat/attach/attach_prepare.h"
|
||||||
|
#include "ui/chat/attach/attach_common.h"
|
||||||
#include "ui/special_buttons.h"
|
#include "ui/special_buttons.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
#include "ui/toasts/common_toasts.h"
|
#include "ui/toasts/common_toasts.h"
|
||||||
|
@ -376,17 +377,17 @@ bool ScheduledWidget::confirmSendingFiles(
|
||||||
|
|
||||||
box->setConfirmedCallback(crl::guard(this, [=](
|
box->setConfirmedCallback(crl::guard(this, [=](
|
||||||
Ui::PreparedList &&list,
|
Ui::PreparedList &&list,
|
||||||
SendFilesWay way,
|
Ui::SendFilesWay way,
|
||||||
TextWithTags &&caption,
|
TextWithTags &&caption,
|
||||||
Api::SendOptions options,
|
Api::SendOptions options,
|
||||||
bool ctrlShiftEnter) {
|
bool ctrlShiftEnter) {
|
||||||
if (showSendingFilesError(list)) {
|
if (showSendingFilesError(list)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto type = (way == SendFilesWay::Files)
|
const auto type = (way == Ui::SendFilesWay::Files)
|
||||||
? SendMediaType::File
|
? SendMediaType::File
|
||||||
: SendMediaType::Photo;
|
: SendMediaType::Photo;
|
||||||
const auto album = (way == SendFilesWay::Album)
|
const auto album = (way == Ui::SendFilesWay::Album)
|
||||||
? std::make_shared<SendingAlbum>()
|
? std::make_shared<SendingAlbum>()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
uploadFilesAfterConfirmation(
|
uploadFilesAfterConfirmation(
|
||||||
|
|
|
@ -18,13 +18,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/view/media/history_view_media_common.h"
|
#include "history/view/media/history_view_media_common.h"
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
#include "ui/text/format_values.h"
|
#include "ui/text/format_values.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "layout.h" // FullSelection
|
#include "layout.h" // FullSelection
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
#include "data/data_document_media.h"
|
#include "data/data_document_media.h"
|
||||||
#include "data/data_media_types.h"
|
#include "data/data_media_types.h"
|
||||||
#include "data/data_file_origin.h"
|
#include "data/data_file_origin.h"
|
||||||
#include "app.h"
|
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
|
@ -306,8 +306,8 @@ void Document::draw(
|
||||||
}
|
}
|
||||||
p.drawPixmap(rthumb.topLeft(), thumb);
|
p.drawPixmap(rthumb.topLeft(), thumb);
|
||||||
if (selected) {
|
if (selected) {
|
||||||
auto overlayCorners = inWebPage ? SelectedOverlaySmallCorners : SelectedOverlayLargeCorners;
|
auto overlayCorners = inWebPage ? Ui::SelectedOverlaySmallCorners : Ui::SelectedOverlayLargeCorners;
|
||||||
App::roundRect(p, rthumb, p.textPalette().selectOverlay, overlayCorners);
|
Ui::FillRoundRect(p, rthumb, p.textPalette().selectOverlay, overlayCorners);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (radial || (!loaded && !_data->loading())) {
|
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/history_view_cursor_state.h"
|
||||||
#include "history/view/media/history_view_media_common.h"
|
#include "history/view/media/history_view_media_common.h"
|
||||||
#include "ui/item_text_options.h"
|
#include "ui/item_text_options.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "core/ui_integration.h"
|
#include "core/ui_integration.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_game.h"
|
#include "data/data_game.h"
|
||||||
#include "data/data_media_types.h"
|
#include "data/data_media_types.h"
|
||||||
#include "app.h"
|
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
|
|
||||||
namespace HistoryView {
|
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 gameX = pixwidth - st::msgDateImgDelta - gameW;
|
||||||
auto gameY = pixheight - st::msgDateImgDelta - gameH;
|
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.setFont(st::msgDateFont);
|
||||||
p.setPen(st::msgDateImgFg);
|
p.setPen(st::msgDateImgFg);
|
||||||
|
|
|
@ -29,12 +29,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
#include "ui/text/format_values.h"
|
#include "ui/text/format_values.h"
|
||||||
#include "ui/grouped_layout.h"
|
#include "ui/grouped_layout.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_streaming.h"
|
#include "data/data_streaming.h"
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
#include "data/data_file_origin.h"
|
#include "data/data_file_origin.h"
|
||||||
#include "data/data_document_media.h"
|
#include "data/data_document_media.h"
|
||||||
#include "app.h"
|
|
||||||
#include "layout.h" // FullSelection
|
#include "layout.h" // FullSelection
|
||||||
#include "styles/style_chat.h"
|
#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) {
|
} 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;
|
auto usex = 0, usew = paintw;
|
||||||
|
@ -451,14 +451,14 @@ void Gif::draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms
|
||||||
| RectPart::NoTopBottom
|
| RectPart::NoTopBottom
|
||||||
| (roundTop ? RectPart::Top : RectPart::None)
|
| (roundTop ? RectPart::Top : RectPart::None)
|
||||||
| (roundBottom ? RectPart::Bottom : 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) {
|
if (selected) {
|
||||||
App::complexOverlayRect(p, rthumb, roundRadius, roundCorners);
|
Ui::FillComplexOverlayRect(p, rthumb, roundRadius, roundCorners);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (radial
|
if (radial
|
||||||
|
@ -553,7 +553,7 @@ void Gif::draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms
|
||||||
if (mediaUnread) {
|
if (mediaUnread) {
|
||||||
statusW += st::mediaUnreadSkip + st::mediaUnreadSize;
|
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.setFont(st::normalFont);
|
||||||
p.setPen(st::msgServiceFg);
|
p.setPen(st::msgServiceFg);
|
||||||
p.drawTextLeft(statusX, statusY, width(), _statusText, statusW - 2 * st::msgDateImgPadding.x());
|
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;
|
int recty = painty;
|
||||||
if (rtl()) rectx = width() - rectx - rectw;
|
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);
|
p.setPen(st::msgServiceFg);
|
||||||
rectx += st::msgReplyPadding.left();
|
rectx += st::msgReplyPadding.left();
|
||||||
rectw = innerw;
|
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 statusY = position.y() + st::msgDateImgDelta + padding.y();
|
||||||
const auto around = style::rtlrect(statusX - padding.x(), statusY - padding.y(), statusW, statusH, width());
|
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);
|
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.setFont(st::normalFont);
|
||||||
p.setPen(st::msgDateImgFg);
|
p.setPen(st::msgDateImgFg);
|
||||||
p.drawTextLeft(statusX + addLeft, statusTextTop, width(), text, statusW - 2 * padding.x());
|
p.drawTextLeft(statusX + addLeft, statusTextTop, width(), text, statusW - 2 * padding.x());
|
||||||
|
@ -985,7 +985,7 @@ void Gif::drawGrouped(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selected) {
|
if (selected) {
|
||||||
App::complexOverlayRect(p, geometry, roundRadius, corners);
|
Ui::FillComplexOverlayRect(p, geometry, roundRadius, corners);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (radial
|
if (radial
|
||||||
|
|
|
@ -15,8 +15,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/view/media/history_view_media_common.h"
|
#include "history/view/media/history_view_media_common.h"
|
||||||
#include "ui/item_text_options.h"
|
#include "ui/item_text_options.h"
|
||||||
#include "ui/text/format_values.h"
|
#include "ui/text/format_values.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "data/data_media_types.h"
|
#include "data/data_media_types.h"
|
||||||
#include "app.h"
|
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
|
@ -260,7 +260,7 @@ void Invoice::draw(Painter &p, const QRect &r, TextSelection selection, crl::tim
|
||||||
auto statusX = st::msgDateImgDelta;
|
auto statusX = st::msgDateImgDelta;
|
||||||
auto statusY = 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.setFont(st::msgDateFont);
|
||||||
p.setPen(st::msgDateImgFg);
|
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 "history/view/history_view_cursor_state.h"
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
#include "ui/text/text_options.h"
|
#include "ui/text/text_options.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_file_origin.h"
|
#include "data/data_file_origin.h"
|
||||||
#include "data/data_cloud_file.h"
|
#include "data/data_cloud_file.h"
|
||||||
#include "app.h"
|
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
|
@ -179,7 +179,7 @@ void Location::draw(Painter &p, const QRect &r, TextSelection selection, crl::ti
|
||||||
}
|
}
|
||||||
painth -= painty;
|
painth -= painty;
|
||||||
} else {
|
} 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;
|
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);
|
const auto &pix = thumbnail->pixSingle(paintw, painth, paintw, painth, roundRadius, roundCorners);
|
||||||
p.drawPixmap(rthumb.topLeft(), pix);
|
p.drawPixmap(rthumb.topLeft(), pix);
|
||||||
} else {
|
} else {
|
||||||
App::complexLocationRect(p, rthumb, roundRadius, roundCorners);
|
Ui::FillComplexLocationRect(p, rthumb, roundRadius, roundCorners);
|
||||||
}
|
}
|
||||||
const auto paintMarker = [&](const style::icon &icon) {
|
const auto paintMarker = [&](const style::icon &icon) {
|
||||||
icon.paint(
|
icon.paint(
|
||||||
|
@ -203,7 +203,7 @@ void Location::draw(Painter &p, const QRect &r, TextSelection selection, crl::ti
|
||||||
paintMarker(st::historyMapPoint);
|
paintMarker(st::historyMapPoint);
|
||||||
paintMarker(st::historyMapPointInner);
|
paintMarker(st::historyMapPointInner);
|
||||||
if (selected) {
|
if (selected) {
|
||||||
App::complexOverlayRect(p, rthumb, roundRadius, roundCorners);
|
Ui::FillComplexOverlayRect(p, rthumb, roundRadius, roundCorners);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_parent->media() == this) {
|
if (_parent->media() == this) {
|
||||||
|
|
|
@ -15,8 +15,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "lottie/lottie_single_player.h"
|
#include "lottie/lottie_single_player.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "core/core_settings.h"
|
#include "core/core_settings.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
#include "app.h"
|
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
|
@ -206,7 +206,7 @@ void UnwrappedMedia::drawSurrounding(
|
||||||
int recty = 0;
|
int recty = 0;
|
||||||
if (rtl()) rectx = width() - rectx - rectw;
|
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);
|
p.setPen(st::msgServiceFg);
|
||||||
rectx += st::msgReplyPadding.left();
|
rectx += st::msgReplyPadding.left();
|
||||||
rectw -= st::msgReplyPadding.left() + st::msgReplyPadding.right();
|
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 "main/main_session_settings.h"
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
#include "ui/grouped_layout.h"
|
#include "ui/grouped_layout.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_streaming.h"
|
#include "data/data_streaming.h"
|
||||||
#include "data/data_photo.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_file_origin.h"
|
||||||
#include "data/data_auto_download.h"
|
#include "data/data_auto_download.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "app.h"
|
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
|
|
||||||
namespace HistoryView {
|
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());
|
rthumb = style::rtlrect(paintx, painty, paintw, painth, width());
|
||||||
}
|
}
|
||||||
} else {
|
} 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 inWebPage = (_parent->media() != this);
|
||||||
auto roundRadius = inWebPage ? ImageRoundRadius::Small : ImageRoundRadius::Large;
|
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);
|
p.drawPixmap(rthumb.topLeft(), pix);
|
||||||
if (selected) {
|
if (selected) {
|
||||||
App::complexOverlayRect(p, rthumb, roundRadius, roundCorners);
|
Ui::FillComplexOverlayRect(p, rthumb, roundRadius, roundCorners);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (radial || (!loaded && !_data->loading())) {
|
if (radial || (!loaded && !_data->loading())) {
|
||||||
|
@ -505,7 +505,7 @@ void Photo::drawGrouped(
|
||||||
p.drawPixmap(geometry.topLeft(), *cache);
|
p.drawPixmap(geometry.topLeft(), *cache);
|
||||||
if (selected) {
|
if (selected) {
|
||||||
const auto roundRadius = ImageRoundRadius::Large;
|
const auto roundRadius = ImageRoundRadius::Large;
|
||||||
App::complexOverlayRect(p, geometry, roundRadius, corners);
|
Ui::FillComplexOverlayRect(p, geometry, roundRadius, corners);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto displayState = radial
|
const auto displayState = radial
|
||||||
|
|
|
@ -17,9 +17,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_file_origin.h"
|
#include "data/data_file_origin.h"
|
||||||
#include "base/qthelp_url.h"
|
#include "base/qthelp_url.h"
|
||||||
#include "ui/text/format_values.h"
|
#include "ui/text/format_values.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "window/themes/window_theme.h"
|
#include "window/themes/window_theme.h"
|
||||||
#include "layout.h" // FullSelection
|
#include "layout.h" // FullSelection
|
||||||
#include "app.h"
|
#include "app.h" // App::pixmapFromImageInPlace.
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
|
@ -139,14 +140,14 @@ void ThemeDocument::draw(Painter &p, const QRect &r, TextSelection selection, cr
|
||||||
validateThumbnail();
|
validateThumbnail();
|
||||||
p.drawPixmap(rthumb.topLeft(), _thumbnail);
|
p.drawPixmap(rthumb.topLeft(), _thumbnail);
|
||||||
if (selected) {
|
if (selected) {
|
||||||
App::complexOverlayRect(p, rthumb, roundRadius, roundCorners);
|
Ui::FillComplexOverlayRect(p, rthumb, roundRadius, roundCorners);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto statusX = paintx + st::msgDateImgDelta + st::msgDateImgPadding.x();
|
auto statusX = paintx + st::msgDateImgDelta + st::msgDateImgPadding.x();
|
||||||
auto statusY = painty + st::msgDateImgDelta + st::msgDateImgPadding.y();
|
auto statusY = painty + st::msgDateImgDelta + st::msgDateImgPadding.y();
|
||||||
auto statusW = st::normalFont->width(_statusText) + 2 * st::msgDateImgPadding.x();
|
auto statusW = st::normalFont->width(_statusText) + 2 * st::msgDateImgPadding.x();
|
||||||
auto statusH = st::normalFont->height + 2 * st::msgDateImgPadding.y();
|
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.setFont(st::normalFont);
|
||||||
p.setPen(st::msgDateImgFg);
|
p.setPen(st::msgDateImgFg);
|
||||||
p.drawTextLeft(statusX, statusY, width(), _statusText, statusW - 2 * st::msgDateImgPadding.x());
|
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/image/image.h"
|
||||||
#include "ui/text/text_options.h"
|
#include "ui/text/text_options.h"
|
||||||
#include "ui/text/format_values.h"
|
#include "ui/text/format_values.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "layout.h" // FullSelection
|
#include "layout.h" // FullSelection
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_media_types.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.h"
|
||||||
#include "data/data_photo_media.h"
|
#include "data/data_photo_media.h"
|
||||||
#include "data/data_file_origin.h"
|
#include "data/data_file_origin.h"
|
||||||
#include "app.h"
|
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
|
|
||||||
namespace HistoryView {
|
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);
|
p.drawPixmapLeft(padding.left() + paintw - pw, tshift, width(), pix);
|
||||||
if (selected) {
|
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;
|
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 dateW = pixwidth - dateX - st::msgDateImgDelta;
|
||||||
auto dateH = pixheight - dateY - 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.setFont(st::msgDateFont);
|
||||||
p.setPen(st::msgDateImgFg);
|
p.setPen(st::msgDateImgFg);
|
||||||
|
|
|
@ -13,13 +13,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/rp_widget.h"
|
#include "ui/rp_widget.h"
|
||||||
#include "ui/focus_persister.h"
|
#include "ui/focus_persister.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "window/section_widget.h"
|
#include "window/section_widget.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "window/main_window.h"
|
#include "window/main_window.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "boxes/abstract_box.h"
|
#include "boxes/abstract_box.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "app.h"
|
#include "app.h" // App::quitting.
|
||||||
#include "styles/style_info.h"
|
#include "styles/style_info.h"
|
||||||
#include "styles/style_window.h"
|
#include "styles/style_window.h"
|
||||||
#include "styles/style_layers.h"
|
#include "styles/style_layers.h"
|
||||||
|
@ -269,11 +270,11 @@ void LayerWidget::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (parts) {
|
if (parts) {
|
||||||
App::roundRect(
|
Ui::FillRoundRect(
|
||||||
p,
|
p,
|
||||||
rect(),
|
rect(),
|
||||||
st::boxBg,
|
st::boxBg,
|
||||||
BoxCorners,
|
Ui::BoxCorners,
|
||||||
nullptr,
|
nullptr,
|
||||||
parts);
|
parts);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,9 +25,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/view/history_view_cursor_state.h"
|
#include "history/view/history_view_cursor_state.h"
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
#include "ui/text/format_values.h"
|
#include "ui/text/format_values.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "app.h"
|
|
||||||
#include "styles/style_overview.h"
|
#include "styles/style_overview.h"
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
#include "styles/style_chat_helpers.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.);
|
auto over = _a_over.value(_active ? 1. : 0.);
|
||||||
if (over > 0) {
|
if (over > 0) {
|
||||||
p.setOpacity(over);
|
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);
|
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 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 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;
|
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.setPen(st::msgDateImgFg);
|
||||||
p.setFont(st::normalFont);
|
p.setFont(st::normalFont);
|
||||||
p.drawText(durationX + st::msgDateImgPadding.x(), durationTop + st::normalFont->ascent, _duration);
|
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 "window/window_session_controller.h"
|
||||||
#include "ui/widgets/scroll_area.h"
|
#include "ui/widgets/scroll_area.h"
|
||||||
#include "ui/widgets/labels.h"
|
#include "ui/widgets/labels.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "history/view/history_view_cursor_state.h"
|
#include "history/view/history_view_cursor_state.h"
|
||||||
#include "facades.h"
|
#include "facades.h"
|
||||||
#include "app.h"
|
|
||||||
#include "styles/style_chat_helpers.h"
|
#include "styles/style_chat_helpers.h"
|
||||||
|
|
||||||
#include <QtWidgets/QApplication>
|
#include <QtWidgets/QApplication>
|
||||||
|
@ -905,7 +905,7 @@ void Widget::paintEvent(QPaintEvent *e) {
|
||||||
|
|
||||||
void Widget::paintContent(Painter &p) {
|
void Widget::paintContent(Painter &p) {
|
||||||
auto inner = innerRect();
|
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 horizontal = horizontalRect();
|
||||||
auto sidesTop = horizontal.y();
|
auto sidesTop = horizontal.y();
|
||||||
|
|
|
@ -18,7 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "media/audio/media_audio.h"
|
#include "media/audio/media_audio.h"
|
||||||
#include "storage/localstorage.h"
|
#include "storage/localstorage.h"
|
||||||
#include "history/view/history_view_cursor_state.h"
|
#include "history/view/history_view_cursor_state.h"
|
||||||
#include "app.h"
|
#include "ui/cached_round_corners.h"
|
||||||
|
|
||||||
int32 documentColorIndex(DocumentData *document, QString &ext) {
|
int32 documentColorIndex(DocumentData *document, QString &ext) {
|
||||||
auto colorIndex = 0;
|
auto colorIndex = 0;
|
||||||
|
@ -118,8 +118,8 @@ style::color documentSelectedColor(int32 colorIndex) {
|
||||||
return colors[colorIndex & 3];
|
return colors[colorIndex & 3];
|
||||||
}
|
}
|
||||||
|
|
||||||
RoundCorners documentCorners(int32 colorIndex) {
|
Ui::CachedRoundCorners documentCorners(int32 colorIndex) {
|
||||||
return RoundCorners(Doc1Corners + (colorIndex & 3));
|
return Ui::CachedRoundCorners(Ui::Doc1Corners + (colorIndex & 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] HistoryView::TextState LayoutItemBase::getState(
|
[[nodiscard]] HistoryView::TextState LayoutItemBase::getState(
|
||||||
|
|
|
@ -14,7 +14,9 @@ struct TextState;
|
||||||
struct StateRequest;
|
struct StateRequest;
|
||||||
} // namespace HistoryView
|
} // namespace HistoryView
|
||||||
|
|
||||||
enum RoundCorners : int;
|
namespace Ui {
|
||||||
|
enum CachedRoundCorners : int;
|
||||||
|
} // namespace Ui
|
||||||
|
|
||||||
constexpr auto FullSelection = TextSelection { 0xFFFF, 0xFFFF };
|
constexpr auto FullSelection = TextSelection { 0xFFFF, 0xFFFF };
|
||||||
|
|
||||||
|
@ -57,7 +59,7 @@ style::color documentColor(int colorIndex);
|
||||||
style::color documentDarkColor(int colorIndex);
|
style::color documentDarkColor(int colorIndex);
|
||||||
style::color documentOverColor(int colorIndex);
|
style::color documentOverColor(int colorIndex);
|
||||||
style::color documentSelectedColor(int colorIndex);
|
style::color documentSelectedColor(int colorIndex);
|
||||||
RoundCorners documentCorners(int colorIndex);
|
Ui::CachedRoundCorners documentCorners(int colorIndex);
|
||||||
|
|
||||||
class PaintContextBase {
|
class PaintContextBase {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "chat_helpers/tabbed_selector.h"
|
#include "chat_helpers/tabbed_selector.h"
|
||||||
#include "ui/widgets/input_fields.h"
|
#include "ui/widgets/input_fields.h"
|
||||||
|
#include "ui/chat/attach/attach_common.h"
|
||||||
#include "window/section_widget.h"
|
#include "window/section_widget.h"
|
||||||
#include "support/support_common.h"
|
#include "support/support_common.h"
|
||||||
#include "storage/serialize_common.h"
|
#include "storage/serialize_common.h"
|
||||||
|
@ -367,11 +368,11 @@ void SessionSettings::addFromSerialized(const QByteArray &serialized) {
|
||||||
for (const auto &[key, value] : appSoundOverrides) {
|
for (const auto &[key, value] : appSoundOverrides) {
|
||||||
app.setSoundOverride(key, value);
|
app.setSoundOverride(key, value);
|
||||||
}
|
}
|
||||||
auto uncheckedSendFilesWay = static_cast<SendFilesWay>(appSendFilesWay);
|
auto uncheckedSendFilesWay = static_cast<Ui::SendFilesWay>(appSendFilesWay);
|
||||||
switch (uncheckedSendFilesWay) {
|
switch (uncheckedSendFilesWay) {
|
||||||
case SendFilesWay::Album:
|
case Ui::SendFilesWay::Album:
|
||||||
case SendFilesWay::Photos:
|
case Ui::SendFilesWay::Photos:
|
||||||
case SendFilesWay::Files: app.setSendFilesWay(uncheckedSendFilesWay); break;
|
case Ui::SendFilesWay::Files: app.setSendFilesWay(uncheckedSendFilesWay); break;
|
||||||
}
|
}
|
||||||
auto uncheckedSendSubmitWay = static_cast<Ui::InputSubmitSettings>(
|
auto uncheckedSendSubmitWay = static_cast<Ui::InputSubmitSettings>(
|
||||||
appSendSubmitWay);
|
appSendSubmitWay);
|
||||||
|
|
|
@ -19,9 +19,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/widgets/shadow.h"
|
#include "ui/widgets/shadow.h"
|
||||||
#include "ui/widgets/scroll_area.h"
|
#include "ui/widgets/scroll_area.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "app.h"
|
|
||||||
#include "styles/style_overview.h"
|
#include "styles/style_overview.h"
|
||||||
#include "styles/style_widgets.h"
|
#include "styles/style_widgets.h"
|
||||||
#include "styles/style_media_player.h"
|
#include "styles/style_media_player.h"
|
||||||
|
@ -159,7 +159,7 @@ void Panel::paintEvent(QPaintEvent *e) {
|
||||||
| RectPart::Top;
|
| RectPart::Top;
|
||||||
Ui::Shadow::paint(p, shadowedRect, width(), st::defaultRoundShadow, shadowedSides);
|
Ui::Shadow::paint(p, shadowedRect, width(), st::defaultRoundShadow, shadowedSides);
|
||||||
auto parts = RectPart::Full;
|
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) {
|
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/shadow.h"
|
||||||
#include "ui/widgets/continuous_sliders.h"
|
#include "ui/widgets/continuous_sliders.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "base/object_ptr.h"
|
#include "base/object_ptr.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "core/core_settings.h"
|
#include "core/core_settings.h"
|
||||||
#include "app.h"
|
|
||||||
#include "styles/style_media_player.h"
|
#include "styles/style_media_player.h"
|
||||||
#include "styles/style_widgets.h"
|
#include "styles/style_widgets.h"
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ void VolumeWidget::paintEvent(QPaintEvent *e) {
|
||||||
auto shadowedSides = RectPart::Left | RectPart::Right | RectPart::Bottom;
|
auto shadowedSides = RectPart::Left | RectPart::Right | RectPart::Bottom;
|
||||||
Ui::Shadow::paint(p, shadowedRect, width(), st::defaultRoundShadow, shadowedSides);
|
Ui::Shadow::paint(p, shadowedRect, width(), st::defaultRoundShadow, shadowedSides);
|
||||||
auto parts = RectPart::NoTopBottom | RectPart::FullBottom;
|
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) {
|
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/text/format_values.h"
|
||||||
#include "ui/item_text_options.h"
|
#include "ui/item_text_options.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "boxes/confirm_box.h"
|
#include "boxes/confirm_box.h"
|
||||||
#include "media/audio/media_audio.h"
|
#include "media/audio/media_audio.h"
|
||||||
#include "media/view/media_view_playback_controls.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);
|
_saveMsgOpacity.update(qMin(progress, 1.), anim::linear);
|
||||||
if (_saveMsgOpacity.current() > 0) {
|
if (_saveMsgOpacity.current() > 0) {
|
||||||
p.setOpacity(_saveMsgOpacity.current());
|
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());
|
st::mediaviewSaveMsgCheck.paint(p, _saveMsg.topLeft() + st::mediaviewSaveMsgCheckPos, width());
|
||||||
|
|
||||||
p.setPen(st::mediaviewSaveMsgFg);
|
p.setPen(st::mediaviewSaveMsgFg);
|
||||||
|
|
|
@ -15,8 +15,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/popup_menu.h"
|
#include "ui/widgets/popup_menu.h"
|
||||||
#include "ui/text/format_values.h"
|
#include "ui/text/format_values.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "app.h"
|
|
||||||
#include "styles/style_media_view.h"
|
#include "styles/style_media_view.h"
|
||||||
|
|
||||||
namespace Media {
|
namespace Media {
|
||||||
|
@ -429,7 +429,7 @@ void PlaybackControls::paintEvent(QPaintEvent *e) {
|
||||||
_volumeController->setFadeOpacity(1.);
|
_volumeController->setFadeOpacity(1.);
|
||||||
_childrenHidden = false;
|
_childrenHidden = false;
|
||||||
}
|
}
|
||||||
App::roundRect(p, rect(), st::mediaviewSaveMsgBg, MediaviewSaveCorners);
|
Ui::FillRoundRect(p, rect(), st::mediaviewSaveMsgBg, Ui::MediaviewSaveCorners);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlaybackControls::mousePressEvent(QMouseEvent *e) {
|
void PlaybackControls::mousePressEvent(QMouseEvent *e) {
|
||||||
|
|
|
@ -38,6 +38,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
#include "ui/text/format_values.h"
|
#include "ui/text/format_values.h"
|
||||||
#include "ui/text/text_options.h"
|
#include "ui/text/text_options.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "app.h"
|
#include "app.h"
|
||||||
|
|
||||||
namespace Overview {
|
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 statusW = icon.width() + padding.x() + st::normalFont->width(text) + 2 * padding.x();
|
||||||
const auto statusH = st::normalFont->height + 2 * padding.y();
|
const auto statusH = st::normalFont->height + 2 * padding.y();
|
||||||
p.setOpacity(1. - radialOpacity);
|
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.setFont(st::normalFont);
|
||||||
p.setPen(st::msgDateImgFg);
|
p.setPen(st::msgDateImgFg);
|
||||||
icon.paint(p, statusX, statusY + (st::normalFont->height - icon.height()) / 2, _width);
|
icon.paint(p, statusX, statusY + (st::normalFont->height - icon.height()) / 2, _width);
|
||||||
|
@ -1658,19 +1659,19 @@ void Link::validateThumbnail() {
|
||||||
const auto index = _letter.isEmpty()
|
const auto index = _letter.isEmpty()
|
||||||
? 0
|
? 0
|
||||||
: (_letter[0].unicode() % 4);
|
: (_letter[0].unicode() % 4);
|
||||||
const auto fill = [&](style::color color, RoundCorners corners) {
|
const auto fill = [&](style::color color, Ui::CachedRoundCorners corners) {
|
||||||
auto pixRect = QRect(
|
auto pixRect = QRect(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
st::linksPhotoSize,
|
st::linksPhotoSize,
|
||||||
st::linksPhotoSize);
|
st::linksPhotoSize);
|
||||||
App::roundRect(p, pixRect, color, corners);
|
Ui::FillRoundRect(p, pixRect, color, corners);
|
||||||
};
|
};
|
||||||
switch (index) {
|
switch (index) {
|
||||||
case 0: fill(st::msgFile1Bg, Doc1Corners); break;
|
case 0: fill(st::msgFile1Bg, Ui::Doc1Corners); break;
|
||||||
case 1: fill(st::msgFile2Bg, Doc2Corners); break;
|
case 1: fill(st::msgFile2Bg, Ui::Doc2Corners); break;
|
||||||
case 2: fill(st::msgFile3Bg, Doc3Corners); break;
|
case 2: fill(st::msgFile3Bg, Ui::Doc3Corners); break;
|
||||||
case 3: fill(st::msgFile4Bg, Doc4Corners); break;
|
case 3: fill(st::msgFile4Bg, Ui::Doc4Corners); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_letter.isEmpty()) {
|
if (!_letter.isEmpty()) {
|
||||||
|
|
|
@ -18,10 +18,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/widgets/labels.h"
|
#include "ui/widgets/labels.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/scroll_area.h"
|
#include "ui/widgets/scroll_area.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "boxes/abstract_box.h"
|
#include "boxes/abstract_box.h"
|
||||||
#include "window/window_controller.h"
|
#include "window/window_controller.h"
|
||||||
#include "app.h"
|
|
||||||
#include "styles/style_settings.h"
|
#include "styles/style_settings.h"
|
||||||
#include "styles/style_layers.h"
|
#include "styles/style_layers.h"
|
||||||
#include "styles/style_info.h"
|
#include "styles/style_info.h"
|
||||||
|
@ -524,11 +524,11 @@ void LayerWidget::paintEvent(QPaintEvent *e) {
|
||||||
parts |= RectPart::FullBottom;
|
parts |= RectPart::FullBottom;
|
||||||
}
|
}
|
||||||
if (parts) {
|
if (parts) {
|
||||||
App::roundRect(
|
Ui::FillRoundRect(
|
||||||
p,
|
p,
|
||||||
rect(),
|
rect(),
|
||||||
st::boxBg,
|
st::boxBg,
|
||||||
BoxCorners,
|
Ui::BoxCorners,
|
||||||
nullptr,
|
nullptr,
|
||||||
parts);
|
parts);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/wrap/vertical_layout.h"
|
#include "ui/wrap/vertical_layout.h"
|
||||||
#include "ui/wrap/slide_wrap.h"
|
#include "ui/wrap/slide_wrap.h"
|
||||||
#include "ui/image/image_prepare.h"
|
#include "ui/image/image_prepare.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "window/section_widget.h"
|
#include "window/section_widget.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "boxes/peer_list_controllers.h"
|
#include "boxes/peer_list_controllers.h"
|
||||||
|
@ -859,7 +860,7 @@ void ForwardsPrivacyController::PaintForwardedTooltip(
|
||||||
const auto arrowLeft = arrowLeft2;
|
const auto arrowLeft = arrowLeft2;
|
||||||
const auto geometry = rect.translated(left, top);
|
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.setFont(font);
|
||||||
p.setPen(st::toastFg);
|
p.setPen(st::toastFg);
|
||||||
|
|
|
@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "mtproto/mtproto_config.h"
|
#include "mtproto/mtproto_config.h"
|
||||||
#include "ui/effects/animation_value.h"
|
#include "ui/effects/animation_value.h"
|
||||||
#include "ui/widgets/input_fields.h"
|
#include "ui/widgets/input_fields.h"
|
||||||
|
#include "ui/chat/attach/attach_common.h"
|
||||||
#include "window/themes/window_theme.h"
|
#include "window/themes/window_theme.h"
|
||||||
#include "core/update_checker.h"
|
#include "core/update_checker.h"
|
||||||
#include "platform/platform_specific.h"
|
#include "platform/platform_specific.h"
|
||||||
|
@ -918,8 +919,8 @@ bool ReadSetting(
|
||||||
if (!CheckStreamStatus(stream)) return false;
|
if (!CheckStreamStatus(stream)) return false;
|
||||||
|
|
||||||
Core::App().settings().setSendFilesWay((v == 1)
|
Core::App().settings().setSendFilesWay((v == 1)
|
||||||
? SendFilesWay::Album
|
? Ui::SendFilesWay::Album
|
||||||
: SendFilesWay::Files);
|
: Ui::SendFilesWay::Files);
|
||||||
context.legacyRead = true;
|
context.legacyRead = true;
|
||||||
} break;
|
} 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/effects/panel_animation.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
#include "ui/filter_icons.h"
|
#include "ui/filter_icons.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "app.h"
|
|
||||||
#include "styles/style_chat_helpers.h"
|
#include "styles/style_chat_helpers.h"
|
||||||
#include "styles/style_window.h"
|
#include "styles/style_window.h"
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ void FilterIconPanel::setupInner() {
|
||||||
_inner->paintRequest(
|
_inner->paintRequest(
|
||||||
) | rpl::start_with_next([=](QRect clip) {
|
) | rpl::start_with_next([=](QRect clip) {
|
||||||
auto p = Painter(_inner);
|
auto p = Painter(_inner);
|
||||||
App::roundRect(
|
Ui::FillRoundRect(
|
||||||
p,
|
p,
|
||||||
_inner->rect(),
|
_inner->rect(),
|
||||||
st::emojiPanBg,
|
st::emojiPanBg,
|
||||||
|
@ -122,11 +122,11 @@ void FilterIconPanel::setupInner() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (i == selected) {
|
if (i == selected) {
|
||||||
App::roundRect(
|
Ui::FillRoundRect(
|
||||||
p,
|
p,
|
||||||
rect,
|
rect,
|
||||||
st::emojiPanHover,
|
st::emojiPanHover,
|
||||||
StickerHoverCorners);
|
Ui::StickerHoverCorners);
|
||||||
}
|
}
|
||||||
const auto icon = LookupFilterIcon(kIcons[i]).normal;
|
const auto icon = LookupFilterIcon(kIcons[i]).normal;
|
||||||
icon->paintInCenter(p, rect, st::emojiIconFg->c);
|
icon->paintInCenter(p, rect, st::emojiIconFg->c);
|
||||||
|
|
|
@ -444,8 +444,8 @@ std::vector<float64> ComplexLayouter::CropRatios(
|
||||||
constexpr auto kMaxRatio = 2.75;
|
constexpr auto kMaxRatio = 2.75;
|
||||||
constexpr auto kMinRatio = 0.6667;
|
constexpr auto kMinRatio = 0.6667;
|
||||||
return (averageRatio > 1.1)
|
return (averageRatio > 1.1)
|
||||||
? snap(ratio, 1., kMaxRatio)
|
? std::clamp(ratio, 1., kMaxRatio)
|
||||||
: snap(ratio, kMinRatio, 1.);
|
: std::clamp(ratio, kMinRatio, 1.);
|
||||||
}) | ranges::to_vector;
|
}) | ranges::to_vector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,4 +128,20 @@ QString FillAmountAndCurrency(uint64 amount, const QString ¤cy) {
|
||||||
//return currencyText + amountText;
|
//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
|
} // namespace Ui
|
||||||
|
|
|
@ -25,4 +25,9 @@ inline constexpr auto FileStatusSizeFailed = 0x7FFFFFF2;
|
||||||
uint64 amount,
|
uint64 amount,
|
||||||
const QString ¤cy);
|
const QString ¤cy);
|
||||||
|
|
||||||
|
[[nodiscard]] QString ComposeNameString(
|
||||||
|
const QString &filename,
|
||||||
|
const QString &songTitle,
|
||||||
|
const QString &songPerformer);
|
||||||
|
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
|
@ -118,7 +118,8 @@ struct BackgroundUpdate {
|
||||||
[[nodiscard]] bool paletteChanged() const {
|
[[nodiscard]] bool paletteChanged() const {
|
||||||
return (type == Type::TestingTheme)
|
return (type == Type::TestingTheme)
|
||||||
|| (type == Type::RevertingTheme)
|
|| (type == Type::RevertingTheme)
|
||||||
|| (type == Type::ApplyingEdit);
|
|| (type == Type::ApplyingEdit)
|
||||||
|
|| (type == Type::New);
|
||||||
}
|
}
|
||||||
Type type;
|
Type type;
|
||||||
bool tiled;
|
bool tiled;
|
||||||
|
|
|
@ -10,9 +10,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/shadow.h"
|
#include "ui/widgets/shadow.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "window/themes/window_theme.h"
|
#include "window/themes/window_theme.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "app.h"
|
|
||||||
#include "styles/style_layers.h"
|
#include "styles/style_layers.h"
|
||||||
#include "styles/style_boxes.h"
|
#include "styles/style_boxes.h"
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ void WarningWidget::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Ui::Shadow::paint(p, _inner, width(), st::boxRoundShadow);
|
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.setFont(st::boxTitleFont);
|
||||||
p.setPen(st::boxTitleFg);
|
p.setPen(st::boxTitleFg);
|
||||||
|
|
|
@ -10,9 +10,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/shadow.h"
|
#include "ui/widgets/shadow.h"
|
||||||
|
#include "ui/cached_round_corners.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "facades.h"
|
#include "facades.h"
|
||||||
#include "app.h"
|
|
||||||
#include "styles/style_layers.h"
|
#include "styles/style_layers.h"
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ void HistoryHider::paintEvent(QPaintEvent *e) {
|
||||||
p.setFont(st::historyForwardChooseFont);
|
p.setFont(st::historyForwardChooseFont);
|
||||||
auto w = st::historyForwardChooseMargins.left() + _chooseWidth + st::historyForwardChooseMargins.right();
|
auto w = st::historyForwardChooseMargins.left() + _chooseWidth + st::historyForwardChooseMargins.right();
|
||||||
auto h = st::historyForwardChooseMargins.top() + st::historyForwardChooseFont->height + st::historyForwardChooseMargins.bottom();
|
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.setPen(st::historyForwardChooseFg);
|
||||||
p.drawText(_box, _text, QTextOption(style::al_center));
|
p.drawText(_box, _text, QTextOption(style::al_center));
|
||||||
|
|
|
@ -9,11 +9,25 @@ init_target(td_ui)
|
||||||
add_library(tdesktop::td_ui ALIAS td_ui)
|
add_library(tdesktop::td_ui ALIAS td_ui)
|
||||||
|
|
||||||
include(lib_ui/cmake/generate_styles.cmake)
|
include(lib_ui/cmake/generate_styles.cmake)
|
||||||
|
include(cmake/generate_numbers.cmake)
|
||||||
|
|
||||||
set(style_files
|
set(style_files
|
||||||
ui/td_common.style
|
ui/td_common.style
|
||||||
|
ui/filter_icons.style
|
||||||
ui/chat/chat.style
|
ui/chat/chat.style
|
||||||
|
boxes/boxes.style
|
||||||
dialogs/dialogs.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
|
window/window.style
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -25,14 +39,27 @@ set(dependent_style_files
|
||||||
)
|
)
|
||||||
|
|
||||||
generate_styles(td_ui ${src_loc} "${style_files}" "${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)
|
target_precompile_headers(td_ui PRIVATE ${src_loc}/ui/ui_pch.h)
|
||||||
nice_target_sources(td_ui ${src_loc}
|
nice_target_sources(td_ui ${src_loc}
|
||||||
PRIVATE
|
PRIVATE
|
||||||
${style_files}
|
${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.cpp
|
||||||
ui/chat/attach/attach_extensions.h
|
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.cpp
|
||||||
ui/chat/message_bar.h
|
ui/chat/message_bar.h
|
||||||
ui/chat/pinned_bar.cpp
|
ui/chat/pinned_bar.cpp
|
||||||
|
@ -47,7 +74,11 @@ PRIVATE
|
||||||
ui/text/text_options.h
|
ui/text/text_options.h
|
||||||
ui/toasts/common_toasts.cpp
|
ui/toasts/common_toasts.cpp
|
||||||
ui/toasts/common_toasts.h
|
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
|
ui/ui_pch.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue