mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Move ChatTheme to td_ui.
This commit is contained in:
parent
3cd0f9d189
commit
0a1e84ddb2
37 changed files with 353 additions and 244 deletions
|
@ -1100,8 +1100,6 @@ PRIVATE
|
||||||
window/window_slide_animation.cpp
|
window/window_slide_animation.cpp
|
||||||
window/window_slide_animation.h
|
window/window_slide_animation.h
|
||||||
window/window_top_bar_wrap.h
|
window/window_top_bar_wrap.h
|
||||||
window/themes/window_chat_theme.cpp
|
|
||||||
window/themes/window_chat_theme.h
|
|
||||||
window/themes/window_theme.cpp
|
window/themes/window_theme.cpp
|
||||||
window/themes/window_theme.h
|
window/themes/window_theme.h
|
||||||
window/themes/window_theme_editor.cpp
|
window/themes/window_theme_editor.cpp
|
||||||
|
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "window/themes/window_theme.h"
|
#include "window/themes/window_theme.h"
|
||||||
|
#include "ui/chat/chat_theme.h"
|
||||||
#include "ui/toast/toast.h"
|
#include "ui/toast/toast.h"
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
#include "ui/widgets/checkbox.h"
|
#include "ui/widgets/checkbox.h"
|
||||||
|
|
|
@ -30,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#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"
|
||||||
|
#include "ui/chat/chat_theme.h"
|
||||||
#include "ui/widgets/popup_menu.h"
|
#include "ui/widgets/popup_menu.h"
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
#include "ui/text/text_utilities.h"
|
#include "ui/text/text_utilities.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 "history/view/history_view_cursor_state.h"
|
#include "history/view/history_view_cursor_state.h"
|
||||||
#include "history/view/history_view_context_menu.h"
|
#include "history/view/history_view_context_menu.h"
|
||||||
|
#include "ui/chat/chat_theme.h"
|
||||||
#include "ui/widgets/popup_menu.h"
|
#include "ui/widgets/popup_menu.h"
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
#include "ui/toast/toast.h"
|
#include "ui/toast/toast.h"
|
||||||
|
|
|
@ -105,6 +105,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/boxes/report_box.h"
|
#include "ui/boxes/report_box.h"
|
||||||
#include "ui/chat/pinned_bar.h"
|
#include "ui/chat/pinned_bar.h"
|
||||||
#include "ui/chat/group_call_bar.h"
|
#include "ui/chat/group_call_bar.h"
|
||||||
|
#include "ui/chat/chat_theme.h"
|
||||||
#include "ui/widgets/popup_menu.h"
|
#include "ui/widgets/popup_menu.h"
|
||||||
#include "ui/item_text_options.h"
|
#include "ui/item_text_options.h"
|
||||||
#include "ui/unread_badge.h"
|
#include "ui/unread_badge.h"
|
||||||
|
@ -116,7 +117,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "window/window_slide_animation.h"
|
#include "window/window_slide_animation.h"
|
||||||
#include "window/window_peer_menu.h"
|
#include "window/window_peer_menu.h"
|
||||||
#include "window/themes/window_chat_theme.h"
|
|
||||||
#include "inline_bots/inline_results_widget.h"
|
#include "inline_bots/inline_results_widget.h"
|
||||||
#include "info/profile/info_profile_values.h" // SharedMediaCountValue.
|
#include "info/profile/info_profile_values.h" // SharedMediaCountValue.
|
||||||
#include "chat_helpers/emoji_suggestions_widget.h"
|
#include "chat_helpers/emoji_suggestions_widget.h"
|
||||||
|
|
|
@ -25,6 +25,7 @@ class SessionController;
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class PathShiftGradient;
|
class PathShiftGradient;
|
||||||
struct BubblePattern;
|
struct BubblePattern;
|
||||||
|
struct ChatPaintContext;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
|
@ -192,30 +193,7 @@ struct DateBadge : public RuntimeComponent<DateBadge, Element> {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PaintContext {
|
using PaintContext = Ui::ChatPaintContext;
|
||||||
not_null<const style::palette*> st;
|
|
||||||
const Ui::BubblePattern *bubblesPattern = nullptr;
|
|
||||||
QRect viewport;
|
|
||||||
QRect clip;
|
|
||||||
TextSelection selection;
|
|
||||||
crl::time now = 0;
|
|
||||||
|
|
||||||
void translate(int x, int y) {
|
|
||||||
viewport.translate(x, y);
|
|
||||||
clip.translate(x, y);
|
|
||||||
}
|
|
||||||
void translate(QPoint point) {
|
|
||||||
translate(point.x(), point.y());
|
|
||||||
}
|
|
||||||
[[nodiscard]] PaintContext translated(int x, int y) const {
|
|
||||||
auto result = *this;
|
|
||||||
result.translate(x, y);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
[[nodiscard]] PaintContext translated(QPoint point) const {
|
|
||||||
return translated(point.x(), point.y());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class Element
|
class Element
|
||||||
: public Object
|
: public Object
|
||||||
|
|
|
@ -27,13 +27,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "window/window_adaptive.h"
|
#include "window/window_adaptive.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"
|
||||||
#include "window/themes/window_chat_theme.h"
|
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "boxes/confirm_box.h"
|
#include "boxes/confirm_box.h"
|
||||||
#include "ui/widgets/popup_menu.h"
|
#include "ui/widgets/popup_menu.h"
|
||||||
#include "ui/toast/toast.h"
|
#include "ui/toast/toast.h"
|
||||||
#include "ui/inactive_press.h"
|
#include "ui/inactive_press.h"
|
||||||
#include "ui/effects/path_shift_gradient.h"
|
#include "ui/effects/path_shift_gradient.h"
|
||||||
|
#include "ui/chat/chat_theme.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "boxes/peers/edit_participant_box.h"
|
#include "boxes/peers/edit_participant_box.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
|
|
|
@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/view/media/history_view_web_page.h"
|
#include "history/view/media/history_view_web_page.h"
|
||||||
#include "history/view/history_view_group_call_tracker.h" // UserpicInRow.
|
#include "history/view/history_view_group_call_tracker.h" // UserpicInRow.
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
|
#include "ui/chat/chat_theme.h"
|
||||||
#include "ui/effects/ripple_animation.h"
|
#include "ui/effects/ripple_animation.h"
|
||||||
#include "base/unixtime.h"
|
#include "base/unixtime.h"
|
||||||
#include "ui/chat/message_bubble.h"
|
#include "ui/chat/message_bubble.h"
|
||||||
|
|
|
@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_abstract_structure.h"
|
#include "data/data_abstract_structure.h"
|
||||||
#include "data/data_chat.h"
|
#include "data/data_chat.h"
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
|
#include "ui/chat/chat_theme.h"
|
||||||
#include "ui/text/text_options.h"
|
#include "ui/text/text_options.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/view/media/history_view_call.h"
|
#include "history/view/media/history_view_call.h"
|
||||||
|
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
|
#include "ui/chat/chat_theme.h"
|
||||||
#include "ui/text/format_values.h"
|
#include "ui/text/format_values.h"
|
||||||
#include "layout/layout_selection.h" // FullSelection
|
#include "layout/layout_selection.h" // FullSelection
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
|
|
|
@ -19,6 +19,7 @@ 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 "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "ui/empty_userpic.h"
|
#include "ui/empty_userpic.h"
|
||||||
|
#include "ui/chat/chat_theme.h"
|
||||||
#include "ui/text/format_values.h" // Ui::FormatPhone
|
#include "ui/text/format_values.h" // Ui::FormatPhone
|
||||||
#include "ui/text/text_options.h"
|
#include "ui/text/text_options.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
|
|
|
@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/text/format_values.h"
|
#include "ui/text/format_values.h"
|
||||||
#include "ui/text/format_song_document_name.h"
|
#include "ui/text/format_song_document_name.h"
|
||||||
#include "ui/chat/message_bubble.h"
|
#include "ui/chat/message_bubble.h"
|
||||||
|
#include "ui/chat/chat_theme.h"
|
||||||
#include "ui/cached_round_corners.h"
|
#include "ui/cached_round_corners.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
#include "layout/layout_selection.h" // FullSelection
|
#include "layout/layout_selection.h" // FullSelection
|
||||||
|
|
|
@ -16,6 +16,7 @@ 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/cached_round_corners.h"
|
#include "ui/cached_round_corners.h"
|
||||||
|
#include "ui/chat/chat_theme.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"
|
||||||
|
|
|
@ -26,6 +26,7 @@ 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 "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "core/application.h" // Application::showDocument.
|
#include "core/application.h" // Application::showDocument.
|
||||||
|
#include "ui/chat/chat_theme.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/grouped_layout.h"
|
#include "ui/grouped_layout.h"
|
||||||
|
|
|
@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/view/media/history_view_photo.h"
|
#include "history/view/media/history_view_photo.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/chat/chat_theme.h"
|
||||||
#include "ui/text/format_values.h"
|
#include "ui/text/format_values.h"
|
||||||
#include "ui/cached_round_corners.h"
|
#include "ui/cached_round_corners.h"
|
||||||
#include "data/data_media_types.h"
|
#include "data/data_media_types.h"
|
||||||
|
|
|
@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/history_location_manager.h"
|
#include "history/history_location_manager.h"
|
||||||
#include "history/view/history_view_element.h"
|
#include "history/view/history_view_element.h"
|
||||||
#include "history/view/history_view_cursor_state.h"
|
#include "history/view/history_view_cursor_state.h"
|
||||||
|
#include "ui/chat/chat_theme.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 "ui/cached_round_corners.h"
|
||||||
|
|
|
@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "layout/layout_selection.h"
|
#include "layout/layout_selection.h"
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
#include "ui/item_text_options.h"
|
#include "ui/item_text_options.h"
|
||||||
|
#include "ui/chat/chat_theme.h"
|
||||||
#include "ui/chat/message_bubble.h"
|
#include "ui/chat/message_bubble.h"
|
||||||
#include "core/ui_integration.h"
|
#include "core/ui_integration.h"
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
|
|
|
@ -31,6 +31,7 @@ struct ColorReplacements;
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
struct BubbleSelectionInterval;
|
struct BubbleSelectionInterval;
|
||||||
|
struct ChatPaintContext;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
|
@ -40,9 +41,10 @@ enum class CursorState : char;
|
||||||
enum class InfoDisplayType : char;
|
enum class InfoDisplayType : char;
|
||||||
struct TextState;
|
struct TextState;
|
||||||
struct StateRequest;
|
struct StateRequest;
|
||||||
struct PaintContext;
|
|
||||||
class Element;
|
class Element;
|
||||||
|
|
||||||
|
using PaintContext = Ui::ChatPaintContext;
|
||||||
|
|
||||||
enum class MediaInBubbleState {
|
enum class MediaInBubbleState {
|
||||||
None,
|
None,
|
||||||
Top,
|
Top,
|
||||||
|
|
|
@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "storage/storage_shared_media.h"
|
#include "storage/storage_shared_media.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "ui/grouped_layout.h"
|
#include "ui/grouped_layout.h"
|
||||||
|
#include "ui/chat/chat_theme.h"
|
||||||
#include "ui/chat/message_bubble.h"
|
#include "ui/chat/message_bubble.h"
|
||||||
#include "ui/text/text_options.h"
|
#include "ui/text/text_options.h"
|
||||||
#include "layout/layout_selection.h"
|
#include "layout/layout_selection.h"
|
||||||
|
|
|
@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/history_item_components.h"
|
#include "history/history_item_components.h"
|
||||||
#include "lottie/lottie_single_player.h"
|
#include "lottie/lottie_single_player.h"
|
||||||
#include "ui/cached_round_corners.h"
|
#include "ui/cached_round_corners.h"
|
||||||
|
#include "ui/chat/chat_theme.h"
|
||||||
#include "layout/layout_selection.h"
|
#include "layout/layout_selection.h"
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "main/main_session_settings.h"
|
#include "main/main_session_settings.h"
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
|
#include "ui/chat/chat_theme.h"
|
||||||
#include "ui/grouped_layout.h"
|
#include "ui/grouped_layout.h"
|
||||||
#include "ui/cached_round_corners.h"
|
#include "ui/cached_round_corners.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
|
|
|
@ -14,6 +14,7 @@ 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 "calls/calls_instance.h"
|
#include "calls/calls_instance.h"
|
||||||
#include "ui/chat/message_bubble.h"
|
#include "ui/chat/message_bubble.h"
|
||||||
|
#include "ui/chat/chat_theme.h"
|
||||||
#include "ui/text/text_options.h"
|
#include "ui/text/text_options.h"
|
||||||
#include "ui/text/text_utilities.h"
|
#include "ui/text/text_utilities.h"
|
||||||
#include "ui/text/format_values.h"
|
#include "ui/text/format_values.h"
|
||||||
|
|
|
@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "base/qthelp_url.h"
|
#include "base/qthelp_url.h"
|
||||||
#include "core/local_url_handlers.h"
|
#include "core/local_url_handlers.h"
|
||||||
#include "ui/text/format_values.h"
|
#include "ui/text/format_values.h"
|
||||||
|
#include "ui/chat/chat_theme.h"
|
||||||
#include "ui/cached_round_corners.h"
|
#include "ui/cached_round_corners.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
#include "layout/layout_selection.h" // FullSelection
|
#include "layout/layout_selection.h" // FullSelection
|
||||||
|
|
|
@ -20,6 +20,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/chat/chat_theme.h"
|
||||||
#include "ui/cached_round_corners.h"
|
#include "ui/cached_round_corners.h"
|
||||||
#include "layout/layout_selection.h" // FullSelection
|
#include "layout/layout_selection.h" // FullSelection
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
|
|
|
@ -25,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "calls/calls_instance.h"
|
#include "calls/calls_instance.h"
|
||||||
#include "base/unixtime.h"
|
#include "base/unixtime.h"
|
||||||
|
#include "ui/chat/chat_theme.h"
|
||||||
#include "ui/widgets/checkbox.h"
|
#include "ui/widgets/checkbox.h"
|
||||||
#include "ui/wrap/padding_wrap.h"
|
#include "ui/wrap/padding_wrap.h"
|
||||||
#include "ui/wrap/vertical_layout.h"
|
#include "ui/wrap/vertical_layout.h"
|
||||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "support/support_autocomplete.h"
|
#include "support/support_autocomplete.h"
|
||||||
|
|
||||||
|
#include "ui/chat/chat_theme.h"
|
||||||
#include "ui/widgets/scroll_area.h"
|
#include "ui/widgets/scroll_area.h"
|
||||||
#include "ui/widgets/input_fields.h"
|
#include "ui/widgets/input_fields.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
|
|
|
@ -5,17 +5,16 @@ the official desktop application for the Telegram messaging service.
|
||||||
For license and copyright information please follow this link:
|
For license and copyright information please follow this link:
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "window/themes/window_chat_theme.h"
|
#include "ui/chat/chat_theme.h"
|
||||||
|
|
||||||
#include "window/themes/window_theme.h"
|
|
||||||
#include "ui/image/image_prepare.h"
|
#include "ui/image/image_prepare.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
#include "ui/chat/message_bubble.h"
|
#include "ui/chat/message_bubble.h"
|
||||||
#include "history/view/history_view_element.h"
|
|
||||||
|
|
||||||
|
#include <crl/crl_async.h>
|
||||||
#include <QtGui/QGuiApplication>
|
#include <QtGui/QGuiApplication>
|
||||||
|
|
||||||
namespace Window::Theme {
|
namespace Ui {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr auto kMaxChatEntryHistorySize = 50;
|
constexpr auto kMaxChatEntryHistorySize = 50;
|
||||||
|
@ -25,49 +24,52 @@ constexpr auto kBackgroundFadeDuration = crl::time(200);
|
||||||
|
|
||||||
[[nodiscard]] CacheBackgroundResult CacheBackground(
|
[[nodiscard]] CacheBackgroundResult CacheBackground(
|
||||||
const CacheBackgroundRequest &request) {
|
const CacheBackgroundRequest &request) {
|
||||||
const auto gradient = request.gradient.isNull()
|
const auto gradient = request.background.gradientForFill.isNull()
|
||||||
? QImage()
|
? QImage()
|
||||||
: request.recreateGradient
|
: (request.gradientRotationAdd != 0)
|
||||||
? Images::GenerateGradient(
|
? Images::GenerateGradient(
|
||||||
request.gradient.size(),
|
request.background.gradientForFill.size(),
|
||||||
request.gradientColors,
|
request.background.colors,
|
||||||
request.gradientRotation)
|
(request.background.gradientRotation
|
||||||
: request.gradient;
|
+ request.gradientRotationAdd) % 360)
|
||||||
if (request.isPattern || request.tile || request.prepared.isNull()) {
|
: request.background.gradientForFill;
|
||||||
|
if (request.background.isPattern
|
||||||
|
|| request.background.tile
|
||||||
|
|| request.background.prepared.isNull()) {
|
||||||
auto result = gradient.isNull()
|
auto result = gradient.isNull()
|
||||||
? QImage(
|
? QImage(
|
||||||
request.area * cIntRetinaFactor(),
|
request.area * style::DevicePixelRatio(),
|
||||||
QImage::Format_ARGB32_Premultiplied)
|
QImage::Format_ARGB32_Premultiplied)
|
||||||
: gradient.scaled(
|
: gradient.scaled(
|
||||||
request.area * cIntRetinaFactor(),
|
request.area * style::DevicePixelRatio(),
|
||||||
Qt::IgnoreAspectRatio,
|
Qt::IgnoreAspectRatio,
|
||||||
Qt::SmoothTransformation);
|
Qt::SmoothTransformation);
|
||||||
result.setDevicePixelRatio(cRetinaFactor());
|
result.setDevicePixelRatio(style::DevicePixelRatio());
|
||||||
if (!request.prepared.isNull()) {
|
if (!request.background.prepared.isNull()) {
|
||||||
QPainter p(&result);
|
QPainter p(&result);
|
||||||
if (!gradient.isNull()) {
|
if (!gradient.isNull()) {
|
||||||
if (request.patternOpacity >= 0.) {
|
if (request.background.patternOpacity >= 0.) {
|
||||||
p.setCompositionMode(QPainter::CompositionMode_SoftLight);
|
p.setCompositionMode(QPainter::CompositionMode_SoftLight);
|
||||||
p.setOpacity(request.patternOpacity);
|
p.setOpacity(request.background.patternOpacity);
|
||||||
} else {
|
} else {
|
||||||
p.setCompositionMode(
|
p.setCompositionMode(
|
||||||
QPainter::CompositionMode_DestinationIn);
|
QPainter::CompositionMode_DestinationIn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const auto tiled = request.isPattern
|
const auto tiled = request.background.isPattern
|
||||||
? request.prepared.scaled(
|
? request.background.prepared.scaled(
|
||||||
request.area.height() * cIntRetinaFactor(),
|
request.area.height() * style::DevicePixelRatio(),
|
||||||
request.area.height() * cIntRetinaFactor(),
|
request.area.height() * style::DevicePixelRatio(),
|
||||||
Qt::KeepAspectRatio,
|
Qt::KeepAspectRatio,
|
||||||
Qt::SmoothTransformation)
|
Qt::SmoothTransformation)
|
||||||
: request.preparedForTiled;
|
: request.background.preparedForTiled;
|
||||||
const auto w = tiled.width() / cRetinaFactor();
|
const auto w = tiled.width() / style::DevicePixelRatio();
|
||||||
const auto h = tiled.height() / cRetinaFactor();
|
const auto h = tiled.height() / style::DevicePixelRatio();
|
||||||
const auto cx = qCeil(request.area.width() / w);
|
const auto cx = int(std::ceil(request.area.width() / w));
|
||||||
const auto cy = qCeil(request.area.height() / h);
|
const auto cy = int(std::ceil(request.area.height() / h));
|
||||||
const auto rows = cy;
|
const auto rows = cy;
|
||||||
const auto cols = request.isPattern ? (((cx / 2) * 2) + 1) : cx;
|
const auto cols = request.background.isPattern ? (((cx / 2) * 2) + 1) : cx;
|
||||||
const auto xshift = request.isPattern
|
const auto xshift = request.background.isPattern
|
||||||
? (request.area.width() - cols * w) / 2
|
? (request.area.width() - cols * w) / 2
|
||||||
: 0;
|
: 0;
|
||||||
for (auto y = 0; y != rows; ++y) {
|
for (auto y = 0; y != rows; ++y) {
|
||||||
|
@ -76,10 +78,10 @@ constexpr auto kBackgroundFadeDuration = crl::time(200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!gradient.isNull()
|
if (!gradient.isNull()
|
||||||
&& request.patternOpacity < 0.
|
&& request.background.patternOpacity < 0.
|
||||||
&& request.patternOpacity > -1.) {
|
&& request.background.patternOpacity > -1.) {
|
||||||
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||||
p.setOpacity(1. + request.patternOpacity);
|
p.setOpacity(1. + request.background.patternOpacity);
|
||||||
p.fillRect(QRect(QPoint(), request.area), Qt::black);
|
p.fillRect(QRect(QPoint(), request.area), Qt::black);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,15 +92,15 @@ constexpr auto kBackgroundFadeDuration = crl::time(200);
|
||||||
.area = request.area,
|
.area = request.area,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
const auto rects = ComputeBackgroundRects(
|
const auto rects = ComputeChatBackgroundRects(
|
||||||
request.area,
|
request.area,
|
||||||
request.prepared.size());
|
request.background.prepared.size());
|
||||||
auto result = request.prepared.copy(rects.from).scaled(
|
auto result = request.background.prepared.copy(rects.from).scaled(
|
||||||
rects.to.width() * cIntRetinaFactor(),
|
rects.to.width() * style::DevicePixelRatio(),
|
||||||
rects.to.height() * cIntRetinaFactor(),
|
rects.to.height() * style::DevicePixelRatio(),
|
||||||
Qt::IgnoreAspectRatio,
|
Qt::IgnoreAspectRatio,
|
||||||
Qt::SmoothTransformation);
|
Qt::SmoothTransformation);
|
||||||
result.setDevicePixelRatio(cRetinaFactor());
|
result.setDevicePixelRatio(style::DevicePixelRatio());
|
||||||
return {
|
return {
|
||||||
.image = std::move(result).convertToFormat(
|
.image = std::move(result).convertToFormat(
|
||||||
QImage::Format_ARGB32_Premultiplied),
|
QImage::Format_ARGB32_Premultiplied),
|
||||||
|
@ -112,17 +114,24 @@ constexpr auto kBackgroundFadeDuration = crl::time(200);
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
bool operator==(const ChatThemeBackground &a, const ChatThemeBackground &b) {
|
||||||
|
return (a.prepared.cacheKey() == b.prepared.cacheKey())
|
||||||
|
&& (a.gradientForFill.cacheKey() == b.gradientForFill.cacheKey())
|
||||||
|
&& (a.tile == b.tile)
|
||||||
|
&& (a.patternOpacity == b.patternOpacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const ChatThemeBackground &a, const ChatThemeBackground &b) {
|
||||||
|
return !(a == b);
|
||||||
|
}
|
||||||
|
|
||||||
bool operator==(
|
bool operator==(
|
||||||
const CacheBackgroundRequest &a,
|
const CacheBackgroundRequest &a,
|
||||||
const CacheBackgroundRequest &b) {
|
const CacheBackgroundRequest &b) {
|
||||||
return (a.prepared.cacheKey() == b.prepared.cacheKey())
|
return (a.background == b.background)
|
||||||
&& (a.area == b.area)
|
&& (a.area == b.area)
|
||||||
&& (a.gradientRotation == b.gradientRotation)
|
&& (a.gradientRotationAdd == b.gradientRotationAdd)
|
||||||
&& (a.tile == b.tile)
|
&& (a.gradientProgress == b.gradientProgress);
|
||||||
&& (a.recreateGradient == b.recreateGradient)
|
|
||||||
&& (a.gradient.cacheKey() == b.gradient.cacheKey())
|
|
||||||
&& (a.gradientProgress == b.gradientProgress)
|
|
||||||
&& (a.patternOpacity == b.patternOpacity);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(
|
bool operator!=(
|
||||||
|
@ -139,19 +148,25 @@ CachedBackground::CachedBackground(CacheBackgroundResult &&result)
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatTheme::ChatTheme() {
|
ChatTheme::ChatTheme() {
|
||||||
Background()->updates(
|
|
||||||
) | rpl::start_with_next([=](const BackgroundUpdate &update) {
|
|
||||||
if (update.type == BackgroundUpdate::Type::New
|
|
||||||
|| update.type == BackgroundUpdate::Type::Changed) {
|
|
||||||
clearCachedBackground();
|
|
||||||
}
|
|
||||||
}, _lifetime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Runs from background thread.
|
// Runs from background thread.
|
||||||
ChatTheme::ChatTheme(const Data::CloudTheme &theme)
|
ChatTheme::ChatTheme(ChatThemeDescriptor &&descriptor)
|
||||||
: _id(theme.id)
|
: _id(descriptor.id)
|
||||||
, _palette(std::make_unique<style::palette>()) {
|
, _palette(std::make_unique<style::palette>()) {
|
||||||
|
descriptor.preparePalette(*_palette);
|
||||||
|
setBackground(descriptor.prepareBackground());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatTheme::setBackground(ChatThemeBackground &&background) {
|
||||||
|
_mutableBackground = std::move(background);
|
||||||
|
_backgroundState = {};
|
||||||
|
_backgroundNext = {};
|
||||||
|
_backgroundFade.stop();
|
||||||
|
if (_cacheBackgroundTimer) {
|
||||||
|
_cacheBackgroundTimer->cancel();
|
||||||
|
}
|
||||||
|
_repaintBackgroundRequests.fire({});
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 ChatTheme::key() const {
|
uint64 ChatTheme::key() const {
|
||||||
|
@ -162,7 +177,9 @@ void ChatTheme::setBubblesBackground(QImage image) {
|
||||||
_bubblesBackgroundPrepared = std::move(image);
|
_bubblesBackgroundPrepared = std::move(image);
|
||||||
if (!_bubblesBackground.area.isEmpty()) {
|
if (!_bubblesBackground.area.isEmpty()) {
|
||||||
_bubblesBackground = CacheBackground({
|
_bubblesBackground = CacheBackground({
|
||||||
.prepared = _bubblesBackgroundPrepared,
|
.background = {
|
||||||
|
.prepared = _bubblesBackgroundPrepared,
|
||||||
|
},
|
||||||
.area = _bubblesBackground.area,
|
.area = _bubblesBackground.area,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -173,7 +190,7 @@ void ChatTheme::setBubblesBackground(QImage image) {
|
||||||
_repaintBackgroundRequests.fire({});
|
_repaintBackgroundRequests.fire({});
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryView::PaintContext ChatTheme::preparePaintContext(
|
ChatPaintContext ChatTheme::preparePaintContext(
|
||||||
QRect viewport,
|
QRect viewport,
|
||||||
QRect clip) {
|
QRect clip) {
|
||||||
_bubblesBackground.area = viewport.size();
|
_bubblesBackground.area = viewport.size();
|
||||||
|
@ -202,7 +219,7 @@ const BackgroundState &ChatTheme::backgroundState(QSize area) {
|
||||||
}
|
}
|
||||||
_backgroundState.shown = _backgroundFade.value(1.);
|
_backgroundState.shown = _backgroundFade.value(1.);
|
||||||
if (_backgroundState.now.pixmap.isNull()
|
if (_backgroundState.now.pixmap.isNull()
|
||||||
&& !Background()->gradientForFill().isNull()) {
|
&& !background().gradientForFill.isNull()) {
|
||||||
// We don't support direct painting of patterned gradients.
|
// We don't support direct painting of patterned gradients.
|
||||||
// So we need to sync-generate cache image here.
|
// So we need to sync-generate cache image here.
|
||||||
setCachedBackground(CacheBackground(currentCacheRequest(area)));
|
setCachedBackground(CacheBackground(currentCacheRequest(area)));
|
||||||
|
@ -235,8 +252,7 @@ void ChatTheme::generateNextBackgroundRotation() {
|
||||||
|| !readyForBackgroundRotation()) {
|
|| !readyForBackgroundRotation()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto background = Background();
|
if (background().colors.size() < 3) {
|
||||||
if (background->paper().backgroundColors().size() < 3) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
constexpr auto kAddRotation = 315;
|
constexpr auto kAddRotation = 315;
|
||||||
|
@ -255,8 +271,8 @@ void ChatTheme::generateNextBackgroundRotation() {
|
||||||
_backgroundState.now.area,
|
_backgroundState.now.area,
|
||||||
kAddRotation);
|
kAddRotation);
|
||||||
if (forRequest == request) {
|
if (forRequest == request) {
|
||||||
_backgroundAddRotation
|
_mutableBackground.gradientRotation
|
||||||
= (_backgroundAddRotation + kAddRotation) % 360;
|
= (_mutableBackground.gradientRotation + kAddRotation) % 360;
|
||||||
_backgroundNext = std::move(result);
|
_backgroundNext = std::move(result);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -264,28 +280,14 @@ void ChatTheme::generateNextBackgroundRotation() {
|
||||||
|
|
||||||
auto ChatTheme::currentCacheRequest(QSize area, int addRotation) const
|
auto ChatTheme::currentCacheRequest(QSize area, int addRotation) const
|
||||||
-> CacheBackgroundRequest {
|
-> CacheBackgroundRequest {
|
||||||
const auto background = Background();
|
if (background().colorForFill) {
|
||||||
if (background->colorForFill()) {
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
const auto rotation = background->paper().gradientRotation();
|
|
||||||
const auto gradient = background->gradientForFill();
|
|
||||||
return {
|
return {
|
||||||
.prepared = background->prepared(),
|
.background = background(),
|
||||||
.preparedForTiled = background->preparedForTiled(),
|
|
||||||
.area = area,
|
.area = area,
|
||||||
.gradientRotation = (rotation
|
.gradientRotationAdd = addRotation,
|
||||||
+ _backgroundAddRotation
|
// .recreateGradient = (addRotation != 0),
|
||||||
+ addRotation) % 360,
|
|
||||||
.tile = background->tile(),
|
|
||||||
.isPattern = background->paper().isPattern(),
|
|
||||||
.recreateGradient = (addRotation != 0),
|
|
||||||
.gradient = gradient,
|
|
||||||
.gradientColors = (gradient.isNull()
|
|
||||||
? std::vector<QColor>()
|
|
||||||
: background->paper().backgroundColors()),
|
|
||||||
.gradientProgress = 1.,
|
|
||||||
.patternOpacity = background->paper().patternOpacity(),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,8 +339,7 @@ void ChatTheme::cacheBackgroundAsync(
|
||||||
void ChatTheme::setCachedBackground(CacheBackgroundResult &&cached) {
|
void ChatTheme::setCachedBackground(CacheBackgroundResult &&cached) {
|
||||||
_backgroundNext = {};
|
_backgroundNext = {};
|
||||||
|
|
||||||
const auto background = Background();
|
if (background().gradientForFill.isNull()
|
||||||
if (background->gradientForFill().isNull()
|
|
||||||
|| _backgroundState.now.pixmap.isNull()
|
|| _backgroundState.now.pixmap.isNull()
|
||||||
|| anim::Disabled()) {
|
|| anim::Disabled()) {
|
||||||
_backgroundFade.stop();
|
_backgroundFade.stop();
|
||||||
|
@ -364,27 +365,66 @@ void ChatTheme::setCachedBackground(CacheBackgroundResult &&cached) {
|
||||||
kBackgroundFadeDuration);
|
kBackgroundFadeDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatTheme::clearCachedBackground() {
|
|
||||||
_backgroundState = {};
|
|
||||||
_backgroundAddRotation = 0;
|
|
||||||
_backgroundNext = {};
|
|
||||||
_backgroundFade.stop();
|
|
||||||
if (_cacheBackgroundTimer) {
|
|
||||||
_cacheBackgroundTimer->cancel();
|
|
||||||
}
|
|
||||||
_repaintBackgroundRequests.fire({});
|
|
||||||
}
|
|
||||||
|
|
||||||
rpl::producer<> ChatTheme::repaintBackgroundRequests() const {
|
rpl::producer<> ChatTheme::repaintBackgroundRequests() const {
|
||||||
return _repaintBackgroundRequests.events();
|
return _repaintBackgroundRequests.events();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatTheme::rotateComplexGradientBackground() {
|
void ChatTheme::rotateComplexGradientBackground() {
|
||||||
if (!_backgroundFade.animating() && !_backgroundNext.image.isNull()) {
|
if (!_backgroundFade.animating() && !_backgroundNext.image.isNull()) {
|
||||||
Background()->recacheGradientForFill(
|
if (_mutableBackground.gradientForFill.size()
|
||||||
std::move(_backgroundNext.gradient));
|
== _backgroundNext.gradient.size()) {
|
||||||
|
_mutableBackground.gradientForFill
|
||||||
|
= std::move(_backgroundNext.gradient);
|
||||||
|
}
|
||||||
setCachedBackground(base::take(_backgroundNext));
|
setCachedBackground(base::take(_backgroundNext));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ChatBackgroundRects ComputeChatBackgroundRects(
|
||||||
|
QSize fillSize,
|
||||||
|
QSize imageSize) {
|
||||||
|
if (uint64(imageSize.width()) * fillSize.height()
|
||||||
|
> uint64(imageSize.height()) * fillSize.width()) {
|
||||||
|
const auto pxsize = fillSize.height() / float64(imageSize.height());
|
||||||
|
auto takewidth = int(std::ceil(fillSize.width() / pxsize));
|
||||||
|
if (takewidth > imageSize.width()) {
|
||||||
|
takewidth = imageSize.width();
|
||||||
|
} else if ((imageSize.width() % 2) != (takewidth % 2)) {
|
||||||
|
++takewidth;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
.from = QRect(
|
||||||
|
(imageSize.width() - takewidth) / 2,
|
||||||
|
0,
|
||||||
|
takewidth,
|
||||||
|
imageSize.height()),
|
||||||
|
.to = QRect(
|
||||||
|
int((fillSize.width() - takewidth * pxsize) / 2.),
|
||||||
|
0,
|
||||||
|
int(std::ceil(takewidth * pxsize)),
|
||||||
|
fillSize.height()),
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
const auto pxsize = fillSize.width() / float64(imageSize.width());
|
||||||
|
auto takeheight = int(std::ceil(fillSize.height() / pxsize));
|
||||||
|
if (takeheight > imageSize.height()) {
|
||||||
|
takeheight = imageSize.height();
|
||||||
|
} else if ((imageSize.height() % 2) != (takeheight % 2)) {
|
||||||
|
++takeheight;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
.from = QRect(
|
||||||
|
0,
|
||||||
|
(imageSize.height() - takeheight) / 2,
|
||||||
|
imageSize.width(),
|
||||||
|
takeheight),
|
||||||
|
.to = QRect(
|
||||||
|
0,
|
||||||
|
int((fillSize.height() - takeheight * pxsize) / 2.),
|
||||||
|
fillSize.width(),
|
||||||
|
int(std::ceil(takeheight * pxsize))),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Window::Theme
|
} // namespace Window::Theme
|
|
@ -11,35 +11,59 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "base/timer.h"
|
#include "base/timer.h"
|
||||||
#include "base/weak_ptr.h"
|
#include "base/weak_ptr.h"
|
||||||
|
|
||||||
namespace Data {
|
|
||||||
struct CloudTheme;
|
|
||||||
} // namespace Data
|
|
||||||
|
|
||||||
namespace HistoryView {
|
|
||||||
struct PaintContext;
|
|
||||||
} // namespace HistoryView
|
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
||||||
struct BubblePattern;
|
struct BubblePattern;
|
||||||
} // namespace Ui
|
|
||||||
|
|
||||||
namespace Window::Theme {
|
struct ChatPaintContext {
|
||||||
|
not_null<const style::palette*> st;
|
||||||
|
const BubblePattern *bubblesPattern = nullptr;
|
||||||
|
QRect viewport;
|
||||||
|
QRect clip;
|
||||||
|
TextSelection selection;
|
||||||
|
crl::time now = 0;
|
||||||
|
|
||||||
struct CacheBackgroundRequest {
|
void translate(int x, int y) {
|
||||||
|
viewport.translate(x, y);
|
||||||
|
clip.translate(x, y);
|
||||||
|
}
|
||||||
|
void translate(QPoint point) {
|
||||||
|
translate(point.x(), point.y());
|
||||||
|
}
|
||||||
|
[[nodiscard]] ChatPaintContext translated(int x, int y) const {
|
||||||
|
auto result = *this;
|
||||||
|
result.translate(x, y);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
[[nodiscard]] ChatPaintContext translated(QPoint point) const {
|
||||||
|
return translated(point.x(), point.y());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ChatThemeBackground {
|
||||||
QImage prepared;
|
QImage prepared;
|
||||||
QImage preparedForTiled;
|
QImage preparedForTiled;
|
||||||
QSize area;
|
QImage gradientForFill;
|
||||||
int gradientRotation = 0;
|
std::optional<QColor> colorForFill;
|
||||||
bool tile = false;
|
std::vector<QColor> colors;
|
||||||
bool isPattern = false;
|
|
||||||
bool recreateGradient = false;
|
|
||||||
QImage gradient;
|
|
||||||
std::vector<QColor> gradientColors;
|
|
||||||
float64 gradientProgress = 1.;
|
|
||||||
float64 patternOpacity = 1.;
|
float64 patternOpacity = 1.;
|
||||||
|
int gradientRotation = 0;
|
||||||
|
bool isPattern = false;
|
||||||
|
bool tile = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator==(const ChatThemeBackground &a, const ChatThemeBackground &b);
|
||||||
|
bool operator!=(const ChatThemeBackground &a, const ChatThemeBackground &b);
|
||||||
|
|
||||||
|
struct CacheBackgroundRequest {
|
||||||
|
ChatThemeBackground background;
|
||||||
|
QSize area;
|
||||||
|
int gradientRotationAdd = 0;
|
||||||
|
float64 gradientProgress = 1.;
|
||||||
|
|
||||||
explicit operator bool() const {
|
explicit operator bool() const {
|
||||||
return !prepared.isNull() || !gradient.isNull();
|
return !background.prepared.isNull()
|
||||||
|
|| !background.gradientForFill.isNull();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -74,38 +98,35 @@ struct BackgroundState {
|
||||||
float64 shown = 1.;
|
float64 shown = 1.;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ChatThemeBackground {
|
|
||||||
QImage prepared;
|
|
||||||
QImage gradientForFill;
|
|
||||||
std::optional<QColor> colorForFill;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ChatThemeDescriptor {
|
struct ChatThemeDescriptor {
|
||||||
|
uint64 id = 0;
|
||||||
Fn<void(style::palette&)> preparePalette;
|
Fn<void(style::palette&)> preparePalette;
|
||||||
Fn<ChatThemeBackground()> prepareBackground;
|
Fn<ChatThemeBackground()> prepareBackground;
|
||||||
std::vector<QColor> backgroundColors;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ChatTheme final : public base::has_weak_ptr {
|
class ChatTheme final : public base::has_weak_ptr {
|
||||||
public:
|
public:
|
||||||
ChatTheme();
|
ChatTheme();
|
||||||
|
|
||||||
// Runs from background thread.
|
// Expected to be invoked on a background thread. Invokes callbacks there.
|
||||||
ChatTheme(const Data::CloudTheme &theme);
|
ChatTheme(ChatThemeDescriptor &&descriptor);
|
||||||
|
|
||||||
[[nodiscard]] uint64 key() const;
|
[[nodiscard]] uint64 key() const;
|
||||||
[[nodiscard]] not_null<const style::palette*> palette() const {
|
[[nodiscard]] not_null<const style::palette*> palette() const {
|
||||||
return _palette.get();
|
return _palette.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setBackground(ChatThemeBackground);
|
void setBackground(ChatThemeBackground &&background);
|
||||||
|
const ChatThemeBackground &background() const {
|
||||||
|
return _mutableBackground;
|
||||||
|
}
|
||||||
|
|
||||||
void setBubblesBackground(QImage image);
|
void setBubblesBackground(QImage image);
|
||||||
const Ui::BubblePattern *bubblesBackgroundPattern() const {
|
const BubblePattern *bubblesBackgroundPattern() const {
|
||||||
return _bubblesBackgroundPattern.get();
|
return _bubblesBackgroundPattern.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] HistoryView::PaintContext preparePaintContext(
|
[[nodiscard]] ChatPaintContext preparePaintContext(
|
||||||
QRect viewport,
|
QRect viewport,
|
||||||
QRect clip);
|
QRect clip);
|
||||||
[[nodiscard]] const BackgroundState &backgroundState(QSize area);
|
[[nodiscard]] const BackgroundState &backgroundState(QSize area);
|
||||||
|
@ -118,7 +139,6 @@ private:
|
||||||
void cacheBackgroundAsync(
|
void cacheBackgroundAsync(
|
||||||
const CacheBackgroundRequest &request,
|
const CacheBackgroundRequest &request,
|
||||||
Fn<void(CacheBackgroundResult&&)> done = nullptr);
|
Fn<void(CacheBackgroundResult&&)> done = nullptr);
|
||||||
void clearCachedBackground();
|
|
||||||
void setCachedBackground(CacheBackgroundResult &&cached);
|
void setCachedBackground(CacheBackgroundResult &&cached);
|
||||||
[[nodiscard]] CacheBackgroundRequest currentCacheRequest(
|
[[nodiscard]] CacheBackgroundRequest currentCacheRequest(
|
||||||
QSize area,
|
QSize area,
|
||||||
|
@ -128,8 +148,9 @@ private:
|
||||||
|
|
||||||
uint64 _id = 0;
|
uint64 _id = 0;
|
||||||
std::unique_ptr<style::palette> _palette;
|
std::unique_ptr<style::palette> _palette;
|
||||||
|
ChatThemeBackground _mutableBackground;
|
||||||
BackgroundState _backgroundState;
|
BackgroundState _backgroundState;
|
||||||
Ui::Animations::Simple _backgroundFade;
|
Animations::Simple _backgroundFade;
|
||||||
CacheBackgroundRequest _backgroundCachingRequest;
|
CacheBackgroundRequest _backgroundCachingRequest;
|
||||||
CacheBackgroundResult _backgroundNext;
|
CacheBackgroundResult _backgroundNext;
|
||||||
int _backgroundAddRotation = 0;
|
int _backgroundAddRotation = 0;
|
||||||
|
@ -138,7 +159,7 @@ private:
|
||||||
std::optional<base::Timer> _cacheBackgroundTimer;
|
std::optional<base::Timer> _cacheBackgroundTimer;
|
||||||
CachedBackground _bubblesBackground;
|
CachedBackground _bubblesBackground;
|
||||||
QImage _bubblesBackgroundPrepared;
|
QImage _bubblesBackgroundPrepared;
|
||||||
std::unique_ptr<Ui::BubblePattern> _bubblesBackgroundPattern;
|
std::unique_ptr<BubblePattern> _bubblesBackgroundPattern;
|
||||||
|
|
||||||
rpl::event_stream<> _repaintBackgroundRequests;
|
rpl::event_stream<> _repaintBackgroundRequests;
|
||||||
|
|
||||||
|
@ -146,4 +167,12 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Window::Theme
|
struct ChatBackgroundRects {
|
||||||
|
QRect from;
|
||||||
|
QRect to;
|
||||||
|
};
|
||||||
|
[[nodiscard]] ChatBackgroundRects ComputeChatBackgroundRects(
|
||||||
|
QSize fillSize,
|
||||||
|
QSize imageSize);
|
||||||
|
|
||||||
|
} // namespace Ui
|
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
|
#include "ui/chat/chat_theme.h"
|
||||||
#include "data/data_peer.h"
|
#include "data/data_peer.h"
|
||||||
#include "data/data_changes.h"
|
#include "data/data_changes.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
|
@ -18,7 +19,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "window/window_slide_animation.h"
|
#include "window/window_slide_animation.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "window/themes/window_theme.h"
|
#include "window/themes/window_theme.h"
|
||||||
#include "window/themes/window_chat_theme.h"
|
|
||||||
|
|
||||||
#include <rpl/range.h>
|
#include <rpl/range.h>
|
||||||
|
|
||||||
|
@ -64,11 +64,11 @@ namespace {
|
||||||
[[nodiscard]] auto ChatThemeValueFromPeer(
|
[[nodiscard]] auto ChatThemeValueFromPeer(
|
||||||
not_null<SessionController*> controller,
|
not_null<SessionController*> controller,
|
||||||
not_null<PeerData*> peer)
|
not_null<PeerData*> peer)
|
||||||
-> rpl::producer<std::shared_ptr<Theme::ChatTheme>> {
|
-> rpl::producer<std::shared_ptr<Ui::ChatTheme>> {
|
||||||
return MaybeCloudThemeValueFromPeer(
|
return MaybeCloudThemeValueFromPeer(
|
||||||
peer
|
peer
|
||||||
) | rpl::map([=](std::optional<Data::CloudTheme> theme)
|
) | rpl::map([=](std::optional<Data::CloudTheme> theme)
|
||||||
-> rpl::producer<std::shared_ptr<Theme::ChatTheme>> {
|
-> rpl::producer<std::shared_ptr<Ui::ChatTheme>> {
|
||||||
if (!theme) {
|
if (!theme) {
|
||||||
return rpl::single(controller->defaultChatTheme());
|
return rpl::single(controller->defaultChatTheme());
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ AbstractSectionWidget::AbstractSectionWidget(
|
||||||
return ChatThemeValueFromPeer(
|
return ChatThemeValueFromPeer(
|
||||||
controller,
|
controller,
|
||||||
peer
|
peer
|
||||||
) | rpl::map([](const std::shared_ptr<Theme::ChatTheme> &theme) {
|
) | rpl::map([](const std::shared_ptr<Ui::ChatTheme> &theme) {
|
||||||
return rpl::single(
|
return rpl::single(
|
||||||
rpl::empty_value()
|
rpl::empty_value()
|
||||||
) | rpl::then(
|
) | rpl::then(
|
||||||
|
@ -185,21 +185,21 @@ QPixmap SectionWidget::grabForShowAnimation(
|
||||||
|
|
||||||
void SectionWidget::PaintBackground(
|
void SectionWidget::PaintBackground(
|
||||||
not_null<Window::SessionController*> controller,
|
not_null<Window::SessionController*> controller,
|
||||||
not_null<Window::Theme::ChatTheme*> theme,
|
not_null<Ui::ChatTheme*> theme,
|
||||||
not_null<QWidget*> widget,
|
not_null<QWidget*> widget,
|
||||||
QRect clip) {
|
QRect clip) {
|
||||||
Painter p(widget);
|
Painter p(widget);
|
||||||
|
|
||||||
const auto background = Window::Theme::Background();
|
const auto &background = theme->background();
|
||||||
if (const auto color = background->colorForFill()) {
|
if (background.colorForFill) {
|
||||||
p.fillRect(clip, *color);
|
p.fillRect(clip, *background.colorForFill);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto gradient = background->gradientForFill();
|
const auto &gradient = background.gradientForFill;
|
||||||
const auto fill = QSize(widget->width(), controller->content()->height());
|
const auto fill = QSize(widget->width(), controller->content()->height());
|
||||||
auto fromy = controller->content()->backgroundFromY();
|
auto fromy = controller->content()->backgroundFromY();
|
||||||
auto state = theme->backgroundState(fill);
|
auto state = theme->backgroundState(fill);
|
||||||
const auto paintCache = [&](const Theme::CachedBackground &cache) {
|
const auto paintCache = [&](const Ui::CachedBackground &cache) {
|
||||||
const auto to = QRect(
|
const auto to = QRect(
|
||||||
QPoint(cache.x, fromy + cache.y),
|
QPoint(cache.x, fromy + cache.y),
|
||||||
cache.pixmap.size() / cIntRetinaFactor());
|
cache.pixmap.size() / cIntRetinaFactor());
|
||||||
|
@ -233,10 +233,10 @@ void SectionWidget::PaintBackground(
|
||||||
paintCache(state.now);
|
paintCache(state.now);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto &prepared = background->prepared();
|
const auto &prepared = background.prepared;
|
||||||
if (prepared.isNull()) {
|
if (prepared.isNull()) {
|
||||||
return;
|
return;
|
||||||
} else if (background->paper().isPattern()) {
|
} else if (background.isPattern) {
|
||||||
const auto w = prepared.width() * fill.height() / prepared.height();
|
const auto w = prepared.width() * fill.height() / prepared.height();
|
||||||
const auto cx = qCeil(fill.width() / float64(w));
|
const auto cx = qCeil(fill.width() / float64(w));
|
||||||
const auto cols = (cx / 2) * 2 + 1;
|
const auto cols = (cx / 2) * 2 + 1;
|
||||||
|
@ -247,8 +247,8 @@ void SectionWidget::PaintBackground(
|
||||||
prepared,
|
prepared,
|
||||||
QRect(QPoint(), prepared.size()));
|
QRect(QPoint(), prepared.size()));
|
||||||
}
|
}
|
||||||
} else if (background->tile()) {
|
} else if (background.tile) {
|
||||||
const auto &tiled = background->preparedForTiled();
|
const auto &tiled = background.preparedForTiled;
|
||||||
const auto left = clip.left();
|
const auto left = clip.left();
|
||||||
const auto top = clip.top();
|
const auto top = clip.top();
|
||||||
const auto right = clip.left() + clip.width();
|
const auto right = clip.left() + clip.width();
|
||||||
|
@ -266,7 +266,7 @@ void SectionWidget::PaintBackground(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const auto hq = PainterHighQualityEnabler(p);
|
const auto hq = PainterHighQualityEnabler(p);
|
||||||
const auto rects = Window::Theme::ComputeBackgroundRects(
|
const auto rects = Ui::ComputeChatBackgroundRects(
|
||||||
fill,
|
fill,
|
||||||
prepared.size());
|
prepared.size());
|
||||||
auto to = rects.to;
|
auto to = rects.to;
|
||||||
|
|
|
@ -22,11 +22,8 @@ class Session;
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class LayerWidget;
|
class LayerWidget;
|
||||||
} // namespace Ui
|
|
||||||
|
|
||||||
namespace Window::Theme {
|
|
||||||
class ChatTheme;
|
class ChatTheme;
|
||||||
} // namespace Window::Theme
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
|
|
||||||
|
@ -164,7 +161,7 @@ public:
|
||||||
|
|
||||||
static void PaintBackground(
|
static void PaintBackground(
|
||||||
not_null<SessionController*> controller,
|
not_null<SessionController*> controller,
|
||||||
not_null<Window::Theme::ChatTheme*> theme,
|
not_null<Ui::ChatTheme*> theme,
|
||||||
not_null<QWidget*> widget,
|
not_null<QWidget*> widget,
|
||||||
QRect clip);
|
QRect clip);
|
||||||
|
|
||||||
|
|
|
@ -1448,10 +1448,22 @@ bool LoadFromFile(
|
||||||
const QString &path,
|
const QString &path,
|
||||||
not_null<Instance*> out,
|
not_null<Instance*> out,
|
||||||
Cached *outCache,
|
Cached *outCache,
|
||||||
not_null<QByteArray*> outContent) {
|
QByteArray *outContent) {
|
||||||
*outContent = readThemeContent(path);
|
|
||||||
const auto colorizer = ColorizerForTheme(path);
|
const auto colorizer = ColorizerForTheme(path);
|
||||||
return LoadTheme(*outContent, colorizer, std::nullopt, outCache, out);
|
return LoadFromFile(path, out, outCache, outContent, colorizer);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LoadFromFile(
|
||||||
|
const QString &path,
|
||||||
|
not_null<Instance*> out,
|
||||||
|
Cached *outCache,
|
||||||
|
QByteArray *outContent,
|
||||||
|
const Colorizer &colorizer) {
|
||||||
|
const auto content = readThemeContent(path);
|
||||||
|
if (outContent) {
|
||||||
|
*outContent = content;
|
||||||
|
}
|
||||||
|
return LoadTheme(content, colorizer, std::nullopt, outCache, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LoadFromContent(
|
bool LoadFromContent(
|
||||||
|
@ -1523,34 +1535,6 @@ QImage PreprocessBackgroundImage(QImage image) {
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
BackgroundRects ComputeBackgroundRects(QSize fillSize, QSize imageSize) {
|
|
||||||
if (uint64(imageSize.width()) * fillSize.height() > uint64(imageSize.height()) * fillSize.width()) {
|
|
||||||
float64 pxsize = fillSize.height() / float64(imageSize.height());
|
|
||||||
int takewidth = qCeil(fillSize.width() / pxsize);
|
|
||||||
if (takewidth > imageSize.width()) {
|
|
||||||
takewidth = imageSize.width();
|
|
||||||
} else if ((imageSize.width() % 2) != (takewidth % 2)) {
|
|
||||||
++takewidth;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
.from = QRect((imageSize.width() - takewidth) / 2, 0, takewidth, imageSize.height()),
|
|
||||||
.to = QRect(int((fillSize.width() - takewidth * pxsize) / 2.), 0, qCeil(takewidth * pxsize), fillSize.height()),
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
float64 pxsize = fillSize.width() / float64(imageSize.width());
|
|
||||||
int takeheight = qCeil(fillSize.height() / pxsize);
|
|
||||||
if (takeheight > imageSize.height()) {
|
|
||||||
takeheight = imageSize.height();
|
|
||||||
} else if ((imageSize.height() % 2) != (takeheight % 2)) {
|
|
||||||
++takeheight;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
.from = QRect(0, (imageSize.height() - takeheight) / 2, imageSize.width(), takeheight),
|
|
||||||
.to = QRect(0, int((fillSize.height() - takeheight * pxsize) / 2.), fillSize.width(), qCeil(takeheight * pxsize)),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ReadPaletteValues(const QByteArray &content, Fn<bool(QLatin1String name, QLatin1String value)> callback) {
|
bool ReadPaletteValues(const QByteArray &content, Fn<bool(QLatin1String name, QLatin1String value)> callback) {
|
||||||
if (content.size() > kThemeSchemeSizeLimit) {
|
if (content.size() > kThemeSchemeSizeLimit) {
|
||||||
LOG(("Theme Error: color scheme file too large (should be less than 1 MB, got %2)").arg(content.size()));
|
LOG(("Theme Error: color scheme file too large (should be less than 1 MB, got %2)").arg(content.size()));
|
||||||
|
|
|
@ -25,6 +25,7 @@ inline constexpr auto kThemeSchemeSizeLimit = 1024 * 1024;
|
||||||
inline constexpr auto kThemeBackgroundSizeLimit = 4 * 1024 * 1024;
|
inline constexpr auto kThemeBackgroundSizeLimit = 4 * 1024 * 1024;
|
||||||
|
|
||||||
struct ParsedTheme;
|
struct ParsedTheme;
|
||||||
|
struct Colorizer;
|
||||||
|
|
||||||
[[nodiscard]] bool IsEmbeddedTheme(const QString &path);
|
[[nodiscard]] bool IsEmbeddedTheme(const QString &path);
|
||||||
|
|
||||||
|
@ -90,11 +91,18 @@ void Revert();
|
||||||
|
|
||||||
[[nodiscard]] QString EditingPalettePath();
|
[[nodiscard]] QString EditingPalettePath();
|
||||||
|
|
||||||
|
// NB! This method looks to Core::App().settings() to get colorizer by 'file'.
|
||||||
bool LoadFromFile(
|
bool LoadFromFile(
|
||||||
const QString &file,
|
const QString &path,
|
||||||
not_null<Instance*> out,
|
not_null<Instance*> out,
|
||||||
Cached *outCache,
|
Cached *outCache,
|
||||||
not_null<QByteArray*> outContent);
|
QByteArray *outContent);
|
||||||
|
bool LoadFromFile(
|
||||||
|
const QString &path,
|
||||||
|
not_null<Instance*> out,
|
||||||
|
Cached *outCache,
|
||||||
|
QByteArray *outContent,
|
||||||
|
const Colorizer &colorizer);
|
||||||
bool LoadFromContent(
|
bool LoadFromContent(
|
||||||
const QByteArray &content,
|
const QByteArray &content,
|
||||||
not_null<Instance*> out,
|
not_null<Instance*> out,
|
||||||
|
@ -272,14 +280,6 @@ private:
|
||||||
|
|
||||||
[[nodiscard]] ChatBackground *Background();
|
[[nodiscard]] ChatBackground *Background();
|
||||||
|
|
||||||
struct BackgroundRects {
|
|
||||||
QRect from;
|
|
||||||
QRect to;
|
|
||||||
};
|
|
||||||
[[nodiscard]] BackgroundRects ComputeBackgroundRects(
|
|
||||||
QSize fillSize,
|
|
||||||
QSize imageSize);
|
|
||||||
|
|
||||||
bool ReadPaletteValues(const QByteArray &content, Fn<bool(QLatin1String name, QLatin1String value)> callback);
|
bool ReadPaletteValues(const QByteArray &content, Fn<bool(QLatin1String name, QLatin1String value)> callback);
|
||||||
|
|
||||||
} // namespace Theme
|
} // namespace Theme
|
||||||
|
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/text/text_options.h"
|
#include "ui/text/text_options.h"
|
||||||
#include "ui/image/image_prepare.h"
|
#include "ui/image/image_prepare.h"
|
||||||
#include "ui/emoji_config.h"
|
#include "ui/emoji_config.h"
|
||||||
|
#include "ui/chat/chat_theme.h"
|
||||||
#include "styles/style_widgets.h"
|
#include "styles/style_widgets.h"
|
||||||
#include "styles/style_window.h"
|
#include "styles/style_window.h"
|
||||||
#include "styles/style_media_view.h"
|
#include "styles/style_media_view.h"
|
||||||
|
@ -456,7 +457,9 @@ void Generator::paintHistoryBackground() {
|
||||||
PainterHighQualityEnabler hq(*_p);
|
PainterHighQualityEnabler hq(*_p);
|
||||||
|
|
||||||
auto fill = QSize(_topBar.width(), _body.height());
|
auto fill = QSize(_topBar.width(), _body.height());
|
||||||
const auto rects = ComputeBackgroundRects(fill, background.size());
|
const auto rects = Ui::ComputeChatBackgroundRects(
|
||||||
|
fill,
|
||||||
|
background.size());
|
||||||
auto to = rects.to;
|
auto to = rects.to;
|
||||||
to.moveTop(to.top() + fromy);
|
to.moveTop(to.top() + fromy);
|
||||||
to.moveTopLeft(to.topLeft() + _history.topLeft());
|
to.moveTopLeft(to.topLeft() + _history.topLeft());
|
||||||
|
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "window/themes/window_theme.h"
|
#include "window/themes/window_theme.h"
|
||||||
#include "window/window_peer_menu.h"
|
#include "window/window_peer_menu.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
|
#include "ui/chat/chat_theme.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/labels.h"
|
#include "ui/widgets/labels.h"
|
||||||
#include "ui/widgets/menu/menu.h"
|
#include "ui/widgets/menu/menu.h"
|
||||||
|
@ -990,7 +991,7 @@ void MainMenu::refreshBackground() {
|
||||||
const auto &paper = background->paper();
|
const auto &paper = background->paper();
|
||||||
const auto &prepared = background->prepared();
|
const auto &prepared = background->prepared();
|
||||||
|
|
||||||
const auto rects = Window::Theme::ComputeBackgroundRects(
|
const auto rects = Ui::ComputeChatBackgroundRects(
|
||||||
fill,
|
fill,
|
||||||
prepared.size());
|
prepared.size());
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "window/window_controller.h"
|
#include "window/window_controller.h"
|
||||||
#include "window/main_window.h"
|
#include "window/main_window.h"
|
||||||
#include "window/window_filters_menu.h"
|
#include "window/window_filters_menu.h"
|
||||||
#include "window/themes/window_chat_theme.h"
|
|
||||||
#include "info/info_memento.h"
|
#include "info/info_memento.h"
|
||||||
#include "info/info_controller.h"
|
#include "info/info_controller.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
|
@ -43,6 +42,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/text/text_utilities.h"
|
#include "ui/text/text_utilities.h"
|
||||||
#include "ui/delayed_activation.h"
|
#include "ui/delayed_activation.h"
|
||||||
#include "ui/chat/message_bubble.h"
|
#include "ui/chat/message_bubble.h"
|
||||||
|
#include "ui/chat/chat_theme.h"
|
||||||
#include "ui/toast/toast.h"
|
#include "ui/toast/toast.h"
|
||||||
#include "ui/toasts/common_toasts.h"
|
#include "ui/toasts/common_toasts.h"
|
||||||
#include "calls/calls_instance.h" // Core::App().calls().inCall().
|
#include "calls/calls_instance.h" // Core::App().calls().inCall().
|
||||||
|
@ -468,9 +468,18 @@ SessionController::SessionController(
|
||||||
_window->widget(),
|
_window->widget(),
|
||||||
this))
|
this))
|
||||||
, _invitePeekTimer([=] { checkInvitePeek(); })
|
, _invitePeekTimer([=] { checkInvitePeek(); })
|
||||||
, _defaultChatTheme(std::make_shared<Theme::ChatTheme>()) {
|
, _defaultChatTheme(std::make_shared<Ui::ChatTheme>()) {
|
||||||
init();
|
init();
|
||||||
|
|
||||||
|
pushDefaultChatBackground();
|
||||||
|
Theme::Background()->updates(
|
||||||
|
) | rpl::start_with_next([=](const Theme::BackgroundUpdate &update) {
|
||||||
|
if (update.type == Theme::BackgroundUpdate::Type::New
|
||||||
|
|| update.type == Theme::BackgroundUpdate::Type::Changed) {
|
||||||
|
pushDefaultChatBackground();
|
||||||
|
}
|
||||||
|
}, _lifetime);
|
||||||
|
|
||||||
if (Media::Player::instance()->pauseGifByRoundVideo()) {
|
if (Media::Player::instance()->pauseGifByRoundVideo()) {
|
||||||
enableGifPauseReason(GifPauseReason::RoundPlaying);
|
enableGifPauseReason(GifPauseReason::RoundPlaying);
|
||||||
}
|
}
|
||||||
|
@ -1310,7 +1319,7 @@ void SessionController::openDocument(
|
||||||
|
|
||||||
auto SessionController::cachedChatThemeValue(
|
auto SessionController::cachedChatThemeValue(
|
||||||
const Data::CloudTheme &data)
|
const Data::CloudTheme &data)
|
||||||
-> rpl::producer<std::shared_ptr<Theme::ChatTheme>> {
|
-> rpl::producer<std::shared_ptr<Ui::ChatTheme>> {
|
||||||
const auto key = data.id;
|
const auto key = data.id;
|
||||||
if (!key || !data.paper || data.paper->backgroundColors().empty()) {
|
if (!key || !data.paper || data.paper->backgroundColors().empty()) {
|
||||||
return rpl::single(_defaultChatTheme);
|
return rpl::single(_defaultChatTheme);
|
||||||
|
@ -1326,23 +1335,75 @@ auto SessionController::cachedChatThemeValue(
|
||||||
return rpl::single(
|
return rpl::single(
|
||||||
_defaultChatTheme
|
_defaultChatTheme
|
||||||
) | rpl::then(_cachedThemesStream.events(
|
) | rpl::then(_cachedThemesStream.events(
|
||||||
) | rpl::filter([=](const std::shared_ptr<Theme::ChatTheme> &theme) {
|
) | rpl::filter([=](const std::shared_ptr<Ui::ChatTheme> &theme) {
|
||||||
return (theme->key() == key);
|
return (theme->key() == key);
|
||||||
}) | rpl::take(1));
|
}) | rpl::take(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SessionController::pushDefaultChatBackground() {
|
||||||
|
const auto background = Theme::Background();
|
||||||
|
const auto &paper = background->paper();
|
||||||
|
_defaultChatTheme->setBackground({
|
||||||
|
.prepared = background->prepared(),
|
||||||
|
.preparedForTiled = background->preparedForTiled(),
|
||||||
|
.gradientForFill = background->gradientForFill(),
|
||||||
|
.colorForFill = background->colorForFill(),
|
||||||
|
.colors = paper.backgroundColors(),
|
||||||
|
.patternOpacity = paper.patternOpacity(),
|
||||||
|
.gradientRotation = paper.gradientRotation(),
|
||||||
|
.isPattern = paper.isPattern(),
|
||||||
|
.tile = background->tile(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void SessionController::cacheChatTheme(const Data::CloudTheme &data) {
|
void SessionController::cacheChatTheme(const Data::CloudTheme &data) {
|
||||||
Expects(data.id != 0);
|
Expects(data.id != 0);
|
||||||
|
|
||||||
|
using namespace Theme;
|
||||||
|
|
||||||
const auto key = data.id;
|
const auto key = data.id;
|
||||||
|
const auto dark = data.basedOnDark;
|
||||||
|
const auto accent = data.accentColor;
|
||||||
if (data.paper) {
|
if (data.paper) {
|
||||||
const auto document = data.paper->document();
|
const auto document = data.paper->document();
|
||||||
|
|
||||||
}
|
}
|
||||||
crl::async([this, data, weak = base::make_weak(this)] {
|
const auto preparePalette = [=](style::palette &palette) {
|
||||||
|
if (dark) {
|
||||||
|
const auto &embedded = Theme::EmbeddedThemes();
|
||||||
|
const auto i = ranges::find(
|
||||||
|
embedded,
|
||||||
|
EmbeddedType::Night,
|
||||||
|
&EmbeddedScheme::type);
|
||||||
|
Assert(i != end(embedded));
|
||||||
|
|
||||||
|
auto instance = Instance();
|
||||||
|
const auto loaded = LoadFromFile(
|
||||||
|
i->path,
|
||||||
|
&instance,
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
accent ? ColorizerFrom(*i, *accent) : Colorizer());
|
||||||
|
Assert(loaded);
|
||||||
|
palette = instance.palette;
|
||||||
|
} else {
|
||||||
|
// #TODO themes apply accent color to classic theme
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const auto prepareBackground = [] {
|
||||||
|
return Ui::ChatThemeBackground{
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
||||||
|
auto descriptor = Ui::ChatThemeDescriptor{
|
||||||
|
.id = key,
|
||||||
|
.preparePalette = preparePalette,
|
||||||
|
.prepareBackground = prepareBackground,
|
||||||
|
};
|
||||||
|
crl::async([this, descriptor = std::move(descriptor), weak = base::make_weak(this)] {
|
||||||
crl::on_main(weak, [
|
crl::on_main(weak, [
|
||||||
this,
|
this,
|
||||||
result = std::make_shared<Theme::ChatTheme>(data)
|
result = std::make_shared<Ui::ChatTheme>(std::move(descriptor))
|
||||||
]() mutable {
|
]() mutable {
|
||||||
_customChatThemes.emplace(result->key(), result);
|
_customChatThemes.emplace(result->key(), result);
|
||||||
_cachedThemesStream.fire(std::move(result));
|
_cachedThemesStream.fire(std::move(result));
|
||||||
|
|
|
@ -25,10 +25,6 @@ namespace Adaptive {
|
||||||
enum class WindowLayout;
|
enum class WindowLayout;
|
||||||
} // namespace Adaptive
|
} // namespace Adaptive
|
||||||
|
|
||||||
namespace HistoryView {
|
|
||||||
struct PaintContext;
|
|
||||||
} // namespace HistoryView
|
|
||||||
|
|
||||||
namespace ChatHelpers {
|
namespace ChatHelpers {
|
||||||
class TabbedSelector;
|
class TabbedSelector;
|
||||||
} // namespace ChatHelpers
|
} // namespace ChatHelpers
|
||||||
|
@ -49,11 +45,9 @@ class FormController;
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class LayerWidget;
|
class LayerWidget;
|
||||||
enum class ReportReason;
|
enum class ReportReason;
|
||||||
} // namespace Ui
|
|
||||||
|
|
||||||
namespace Window::Theme {
|
|
||||||
class ChatTheme;
|
class ChatTheme;
|
||||||
} // namespace Window::Theme
|
struct ChatPaintContext;
|
||||||
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
struct CloudTheme;
|
struct CloudTheme;
|
||||||
|
@ -403,21 +397,21 @@ public:
|
||||||
[[nodiscard]] rpl::producer<> filtersMenuChanged() const;
|
[[nodiscard]] rpl::producer<> filtersMenuChanged() const;
|
||||||
|
|
||||||
[[nodiscard]] auto defaultChatTheme() const
|
[[nodiscard]] auto defaultChatTheme() const
|
||||||
-> const std::shared_ptr<Theme::ChatTheme> & {
|
-> const std::shared_ptr<Ui::ChatTheme> & {
|
||||||
return _defaultChatTheme;
|
return _defaultChatTheme;
|
||||||
}
|
}
|
||||||
[[nodiscard]] auto cachedChatThemeValue(
|
[[nodiscard]] auto cachedChatThemeValue(
|
||||||
const Data::CloudTheme &data)
|
const Data::CloudTheme &data)
|
||||||
-> rpl::producer<std::shared_ptr<Theme::ChatTheme>>;
|
-> rpl::producer<std::shared_ptr<Ui::ChatTheme>>;
|
||||||
|
|
||||||
struct PaintContextArgs {
|
struct PaintContextArgs {
|
||||||
not_null<Theme::ChatTheme*> theme;
|
not_null<Ui::ChatTheme*> theme;
|
||||||
int visibleAreaTop = 0;
|
int visibleAreaTop = 0;
|
||||||
int visibleAreaTopGlobal = 0;
|
int visibleAreaTopGlobal = 0;
|
||||||
int visibleAreaWidth = 0;
|
int visibleAreaWidth = 0;
|
||||||
QRect clip;
|
QRect clip;
|
||||||
};
|
};
|
||||||
[[nodiscard]] HistoryView::PaintContext preparePaintContext(
|
[[nodiscard]] Ui::ChatPaintContext preparePaintContext(
|
||||||
PaintContextArgs &&args);
|
PaintContextArgs &&args);
|
||||||
|
|
||||||
rpl::lifetime &lifetime() {
|
rpl::lifetime &lifetime() {
|
||||||
|
@ -449,6 +443,7 @@ private:
|
||||||
|
|
||||||
void checkInvitePeek();
|
void checkInvitePeek();
|
||||||
|
|
||||||
|
void pushDefaultChatBackground();
|
||||||
void cacheChatTheme(const Data::CloudTheme &data);
|
void cacheChatTheme(const Data::CloudTheme &data);
|
||||||
|
|
||||||
const not_null<Controller*> _window;
|
const not_null<Controller*> _window;
|
||||||
|
@ -478,11 +473,9 @@ private:
|
||||||
|
|
||||||
rpl::event_stream<> _filtersMenuChanged;
|
rpl::event_stream<> _filtersMenuChanged;
|
||||||
|
|
||||||
std::shared_ptr<Theme::ChatTheme> _defaultChatTheme;
|
std::shared_ptr<Ui::ChatTheme> _defaultChatTheme;
|
||||||
base::flat_map<
|
base::flat_map<uint64, std::shared_ptr<Ui::ChatTheme>> _customChatThemes;
|
||||||
uint64,
|
rpl::event_stream<std::shared_ptr<Ui::ChatTheme>> _cachedThemesStream;
|
||||||
std::shared_ptr<Theme::ChatTheme>> _customChatThemes;
|
|
||||||
rpl::event_stream<std::shared_ptr<Theme::ChatTheme>> _cachedThemesStream;
|
|
||||||
|
|
||||||
rpl::lifetime _lifetime;
|
rpl::lifetime _lifetime;
|
||||||
|
|
||||||
|
|
|
@ -135,6 +135,8 @@ PRIVATE
|
||||||
ui/chat/attach/attach_single_file_preview.h
|
ui/chat/attach/attach_single_file_preview.h
|
||||||
ui/chat/attach/attach_single_media_preview.cpp
|
ui/chat/attach/attach_single_media_preview.cpp
|
||||||
ui/chat/attach/attach_single_media_preview.h
|
ui/chat/attach/attach_single_media_preview.h
|
||||||
|
ui/chat/chat_theme.cpp
|
||||||
|
ui/chat/chat_theme.h
|
||||||
ui/chat/group_call_bar.cpp
|
ui/chat/group_call_bar.cpp
|
||||||
ui/chat/group_call_bar.h
|
ui/chat/group_call_bar.h
|
||||||
ui/chat/group_call_userpics.cpp
|
ui/chat/group_call_userpics.cpp
|
||||||
|
|
Loading…
Add table
Reference in a new issue