mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Empty preview widget on long userpic press.
This commit is contained in:
parent
ef2aa05197
commit
4427ae4306
6 changed files with 234 additions and 7 deletions
|
@ -781,6 +781,8 @@ PRIVATE
|
||||||
history/view/history_view_about_view.h
|
history/view/history_view_about_view.h
|
||||||
history/view/history_view_bottom_info.cpp
|
history/view/history_view_bottom_info.cpp
|
||||||
history/view/history_view_bottom_info.h
|
history/view/history_view_bottom_info.h
|
||||||
|
history/view/history_view_chat_preview.cpp
|
||||||
|
history/view/history_view_chat_preview.h
|
||||||
history/view/history_view_contact_status.cpp
|
history/view/history_view_contact_status.cpp
|
||||||
history/view/history_view_contact_status.h
|
history/view/history_view_contact_status.h
|
||||||
history/view/history_view_context_menu.cpp
|
history/view/history_view_context_menu.cpp
|
||||||
|
|
|
@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "dialogs/dialogs_widget.h"
|
#include "dialogs/dialogs_widget.h"
|
||||||
#include "dialogs/dialogs_search_from_controllers.h"
|
#include "dialogs/dialogs_search_from_controllers.h"
|
||||||
#include "dialogs/dialogs_search_tags.h"
|
#include "dialogs/dialogs_search_tags.h"
|
||||||
|
#include "history/view/history_view_chat_preview.h"
|
||||||
#include "history/view/history_view_context_menu.h"
|
#include "history/view/history_view_context_menu.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "history/history_item.h"
|
#include "history/history_item.h"
|
||||||
|
@ -80,6 +81,7 @@ namespace {
|
||||||
|
|
||||||
constexpr auto kHashtagResultsLimit = 5;
|
constexpr auto kHashtagResultsLimit = 5;
|
||||||
constexpr auto kStartReorderThreshold = 30;
|
constexpr auto kStartReorderThreshold = 30;
|
||||||
|
constexpr auto kChatPreviewDelay = crl::time(1000);
|
||||||
|
|
||||||
int FixedOnTopDialogsCount(not_null<Dialogs::IndexedList*> list) {
|
int FixedOnTopDialogsCount(not_null<Dialogs::IndexedList*> list) {
|
||||||
auto result = 0;
|
auto result = 0;
|
||||||
|
@ -157,6 +159,7 @@ InnerWidget::InnerWidget(
|
||||||
+ st::defaultDialogRow.padding.left())
|
+ st::defaultDialogRow.padding.left())
|
||||||
, _cancelSearchInChat(this, st::dialogsCancelSearchInPeer)
|
, _cancelSearchInChat(this, st::dialogsCancelSearchInPeer)
|
||||||
, _cancelSearchFromUser(this, st::dialogsCancelSearchInPeer)
|
, _cancelSearchFromUser(this, st::dialogsCancelSearchInPeer)
|
||||||
|
, _chatPreviewTimer([=] { showChatPreview(); })
|
||||||
, _childListShown(std::move(childListShown)) {
|
, _childListShown(std::move(childListShown)) {
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent, true);
|
setAttribute(Qt::WA_OpaquePaintEvent, true);
|
||||||
|
|
||||||
|
@ -651,6 +654,8 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
||||||
context.active = active;
|
context.active = active;
|
||||||
context.selected = _menuRow.key
|
context.selected = _menuRow.key
|
||||||
? (row->key() == _menuRow.key)
|
? (row->key() == _menuRow.key)
|
||||||
|
: _chatPreviewKey
|
||||||
|
? (row->key() == _chatPreviewKey)
|
||||||
: selected;
|
: selected;
|
||||||
context.topicJumpSelected = selected
|
context.topicJumpSelected = selected
|
||||||
&& _selectedTopicJump
|
&& _selectedTopicJump
|
||||||
|
@ -1268,6 +1273,14 @@ void InnerWidget::mouseMoveEvent(QMouseEvent *e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
selectByMouse(globalPosition);
|
selectByMouse(globalPosition);
|
||||||
|
if (!isUserpicPress()) {
|
||||||
|
cancelChatPreview();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InnerWidget::cancelChatPreview() {
|
||||||
|
_chatPreviewTimer.cancel();
|
||||||
|
_chatPreviewWillBeFor = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void InnerWidget::clearIrrelevantState() {
|
void InnerWidget::clearIrrelevantState() {
|
||||||
|
@ -1490,11 +1503,15 @@ void InnerWidget::mousePressEvent(QMouseEvent *e) {
|
||||||
row->repaint());
|
row->repaint());
|
||||||
}
|
}
|
||||||
ClickHandler::pressed();
|
ClickHandler::pressed();
|
||||||
if (anim::Disabled()
|
if (pressShowsPreview()) {
|
||||||
|
_chatPreviewWillBeFor = computeChosenRow().key;
|
||||||
|
_chatPreviewTimer.callOnce(kChatPreviewDelay);
|
||||||
|
} else if (anim::Disabled()
|
||||||
&& (!_pressed || !_pressed->entry()->isPinnedDialog(_filterId))) {
|
&& (!_pressed || !_pressed->entry()->isPinnedDialog(_filterId))) {
|
||||||
mousePressReleased(e->globalPos(), e->button(), e->modifiers());
|
mousePressReleased(e->globalPos(), e->button(), e->modifiers());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<Key> &InnerWidget::pinnedChatsOrder() const {
|
const std::vector<Key> &InnerWidget::pinnedChatsOrder() const {
|
||||||
const auto owner = &session().data();
|
const auto owner = &session().data();
|
||||||
return _savedSublists
|
return _savedSublists
|
||||||
|
@ -1513,6 +1530,7 @@ void InnerWidget::checkReorderPinnedStart(QPoint localPosition) {
|
||||||
< style::ConvertScale(kStartReorderThreshold)) {
|
< style::ConvertScale(kStartReorderThreshold)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
cancelChatPreview();
|
||||||
_dragging = _pressed;
|
_dragging = _pressed;
|
||||||
if (updateReorderIndexGetCount() < 2) {
|
if (updateReorderIndexGetCount() < 2) {
|
||||||
_dragging = nullptr;
|
_dragging = nullptr;
|
||||||
|
@ -2288,6 +2306,33 @@ void InnerWidget::fillArchiveSearchMenu(not_null<Ui::PopupMenu*> menu) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InnerWidget::showChatPreview() {
|
||||||
|
const auto key = base::take(_chatPreviewWillBeFor);
|
||||||
|
cancelChatPreview();
|
||||||
|
if (!pressShowsPreview() || key != computeChosenRow().key) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ClickHandler::unpressed();
|
||||||
|
mousePressReleased(QCursor::pos(), Qt::NoButton, Qt::NoModifier);
|
||||||
|
|
||||||
|
_chatPreviewKey = key;
|
||||||
|
_menu = HistoryView::MakeChatPreview(this, key.entry());
|
||||||
|
if (!_menu) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QObject::connect(_menu.get(), &QObject::destroyed, [=] {
|
||||||
|
if (_chatPreviewKey) {
|
||||||
|
updateDialogRow(RowDescriptor(base::take(_chatPreviewKey), {}));
|
||||||
|
}
|
||||||
|
const auto globalPosition = QCursor::pos();
|
||||||
|
if (rect().contains(mapFromGlobal(globalPosition))) {
|
||||||
|
setMouseTracking(true);
|
||||||
|
selectByMouse(globalPosition);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
_menu->popup(_lastMousePosition.value_or(QCursor::pos()));
|
||||||
|
}
|
||||||
|
|
||||||
void InnerWidget::contextMenuEvent(QContextMenuEvent *e) {
|
void InnerWidget::contextMenuEvent(QContextMenuEvent *e) {
|
||||||
_menu = nullptr;
|
_menu = nullptr;
|
||||||
|
|
||||||
|
@ -2316,7 +2361,9 @@ void InnerWidget::contextMenuEvent(QContextMenuEvent *e) {
|
||||||
}
|
}
|
||||||
return RowDescriptor();
|
return RowDescriptor();
|
||||||
}();
|
}();
|
||||||
if (!row.key) return;
|
if (!row.key) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_menuRow = row;
|
_menuRow = row;
|
||||||
if (_pressButton != Qt::LeftButton) {
|
if (_pressButton != Qt::LeftButton) {
|
||||||
|
@ -2555,6 +2602,12 @@ void InnerWidget::trackSearchResultsHistory(not_null<History*> history) {
|
||||||
refresh();
|
refresh();
|
||||||
clearMouseSelection(true);
|
clearMouseSelection(true);
|
||||||
}
|
}
|
||||||
|
if (_chatPreviewWillBeFor.topic() == topic) {
|
||||||
|
_chatPreviewWillBeFor = {};
|
||||||
|
}
|
||||||
|
if (_chatPreviewKey.topic() == topic) {
|
||||||
|
_chatPreviewKey = {};
|
||||||
|
}
|
||||||
}, _searchResultsLifetime);
|
}, _searchResultsLifetime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3499,6 +3552,23 @@ ChosenRow InnerWidget::computeChosenRow() const {
|
||||||
return ChosenRow();
|
return ChosenRow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InnerWidget::isUserpicPress() const {
|
||||||
|
return (_lastRowLocalMouseX >= 0)
|
||||||
|
&& (_lastRowLocalMouseX < _st->nameLeft)
|
||||||
|
&& (width() > _narrowWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InnerWidget::pressShowsPreview() const {
|
||||||
|
if (!isUserpicPress()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const auto key = computeChosenRow().key;
|
||||||
|
if (const auto history = key.history()) {
|
||||||
|
return !history->peer->isForum();
|
||||||
|
}
|
||||||
|
return key.topic() != nullptr;;
|
||||||
|
}
|
||||||
|
|
||||||
bool InnerWidget::chooseRow(
|
bool InnerWidget::chooseRow(
|
||||||
Qt::KeyboardModifiers modifiers,
|
Qt::KeyboardModifiers modifiers,
|
||||||
MsgId pressedTopicRootId) {
|
MsgId pressedTopicRootId) {
|
||||||
|
@ -3511,9 +3581,7 @@ bool InnerWidget::chooseRow(
|
||||||
ChosenRow row,
|
ChosenRow row,
|
||||||
Qt::KeyboardModifiers modifiers) {
|
Qt::KeyboardModifiers modifiers) {
|
||||||
row.newWindow = (modifiers & Qt::ControlModifier);
|
row.newWindow = (modifiers & Qt::ControlModifier);
|
||||||
row.userpicClick = (_lastRowLocalMouseX >= 0)
|
row.userpicClick = isUserpicPress();
|
||||||
&& (_lastRowLocalMouseX < _st->nameLeft)
|
|
||||||
&& (width() > _narrowWidth);
|
|
||||||
return row;
|
return row;
|
||||||
};
|
};
|
||||||
auto chosen = modifyChosenRow(computeChosenRow(), modifiers);
|
auto chosen = modifyChosenRow(computeChosenRow(), modifiers);
|
||||||
|
|
|
@ -7,14 +7,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "base/flags.h"
|
||||||
|
#include "base/object_ptr.h"
|
||||||
|
#include "base/timer.h"
|
||||||
#include "dialogs/dialogs_key.h"
|
#include "dialogs/dialogs_key.h"
|
||||||
#include "data/data_messages.h"
|
#include "data/data_messages.h"
|
||||||
#include "ui/dragging_scroll_manager.h"
|
#include "ui/dragging_scroll_manager.h"
|
||||||
#include "ui/effects/animations.h"
|
#include "ui/effects/animations.h"
|
||||||
#include "ui/rp_widget.h"
|
#include "ui/rp_widget.h"
|
||||||
#include "ui/userpic_view.h"
|
#include "ui/userpic_view.h"
|
||||||
#include "base/flags.h"
|
|
||||||
#include "base/object_ptr.h"
|
|
||||||
|
|
||||||
namespace style {
|
namespace style {
|
||||||
struct DialogRow;
|
struct DialogRow;
|
||||||
|
@ -121,6 +122,10 @@ public:
|
||||||
void refreshEmptyLabel();
|
void refreshEmptyLabel();
|
||||||
void resizeEmptyLabel();
|
void resizeEmptyLabel();
|
||||||
|
|
||||||
|
[[nodiscard]] bool isUserpicPress() const;
|
||||||
|
[[nodiscard]] bool pressShowsPreview() const;
|
||||||
|
void cancelChatPreview();
|
||||||
|
void showChatPreview();
|
||||||
bool chooseRow(
|
bool chooseRow(
|
||||||
Qt::KeyboardModifiers modifiers = {},
|
Qt::KeyboardModifiers modifiers = {},
|
||||||
MsgId pressedTopicRootId = {});
|
MsgId pressedTopicRootId = {});
|
||||||
|
@ -514,6 +519,10 @@ private:
|
||||||
rpl::event_stream<QString> _completeHashtagRequests;
|
rpl::event_stream<QString> _completeHashtagRequests;
|
||||||
rpl::event_stream<> _refreshHashtagsRequests;
|
rpl::event_stream<> _refreshHashtagsRequests;
|
||||||
|
|
||||||
|
base::Timer _chatPreviewTimer;
|
||||||
|
Key _chatPreviewWillBeFor;
|
||||||
|
Key _chatPreviewKey;
|
||||||
|
|
||||||
rpl::variable<ChildListShown> _childListShown;
|
rpl::variable<ChildListShown> _childListShown;
|
||||||
float64 _narrowRatio = 0.;
|
float64 _narrowRatio = 0.;
|
||||||
bool _geometryInited = false;
|
bool _geometryInited = false;
|
||||||
|
|
113
Telegram/SourceFiles/history/view/history_view_chat_preview.cpp
Normal file
113
Telegram/SourceFiles/history/view/history_view_chat_preview.cpp
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
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 "history/view/history_view_chat_preview.h"
|
||||||
|
|
||||||
|
#include "data/data_peer.h"
|
||||||
|
#include "history/history.h"
|
||||||
|
#include "ui/chat/chat_theme.h"
|
||||||
|
#include "ui/widgets/popup_menu.h"
|
||||||
|
#include "ui/widgets/menu/menu_item_base.h"
|
||||||
|
#include "window/themes/window_theme.h"
|
||||||
|
#include "window/section_widget.h"
|
||||||
|
#include "styles/style_chat.h"
|
||||||
|
|
||||||
|
namespace HistoryView {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class Item final : public Ui::Menu::ItemBase {
|
||||||
|
public:
|
||||||
|
Item(not_null<Ui::RpWidget*> parent, not_null<History*> history);
|
||||||
|
|
||||||
|
not_null<QAction*> action() const override;
|
||||||
|
bool isEnabled() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setupBackground();
|
||||||
|
|
||||||
|
int contentHeight() const override;
|
||||||
|
|
||||||
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
|
||||||
|
const not_null<QAction*> _dummyAction;
|
||||||
|
const std::shared_ptr<Ui::ChatTheme> _theme;
|
||||||
|
|
||||||
|
QImage _bg;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
Item::Item(not_null<Ui::RpWidget*> parent, not_null<History*> history)
|
||||||
|
: Ui::Menu::ItemBase(parent, st::previewMenu.menu)
|
||||||
|
, _dummyAction(new QAction(parent))
|
||||||
|
, _theme(Window::Theme::DefaultChatThemeOn(lifetime())) {
|
||||||
|
setPointerCursor(false);
|
||||||
|
setMinWidth(st::previewMenu.menu.widthMin);
|
||||||
|
resize(minWidth(), contentHeight());
|
||||||
|
setupBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
not_null<QAction*> Item::action() const {
|
||||||
|
return _dummyAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Item::isEnabled() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Item::contentHeight() const {
|
||||||
|
return st::previewMenu.maxHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Item::setupBackground() {
|
||||||
|
const auto ratio = style::DevicePixelRatio();
|
||||||
|
_bg = QImage(
|
||||||
|
size() * ratio,
|
||||||
|
QImage::Format_ARGB32_Premultiplied);
|
||||||
|
|
||||||
|
const auto paint = [=] {
|
||||||
|
auto p = QPainter(&_bg);
|
||||||
|
Window::SectionWidget::PaintBackground(
|
||||||
|
p,
|
||||||
|
_theme.get(),
|
||||||
|
QSize(width(), height() * 2),
|
||||||
|
QRect(QPoint(), size()));
|
||||||
|
};
|
||||||
|
paint();
|
||||||
|
_theme->repaintBackgroundRequests() | rpl::start_with_next([=] {
|
||||||
|
paint();
|
||||||
|
update();
|
||||||
|
}, lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Item::paintEvent(QPaintEvent *e) {
|
||||||
|
auto p = QPainter(this);
|
||||||
|
p.drawImage(0, 0, _bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
base::unique_qptr<Ui::PopupMenu> MakeChatPreview(
|
||||||
|
QWidget *parent,
|
||||||
|
not_null<Dialogs::Entry*> entry) {
|
||||||
|
if (const auto topic = entry->asTopic()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
const auto history = entry->asHistory();
|
||||||
|
if (!history || history->peer->isForum()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto result = base::make_unique_q<Ui::PopupMenu>(
|
||||||
|
parent,
|
||||||
|
st::previewMenu);
|
||||||
|
|
||||||
|
result->addAction(base::make_unique_q<Item>(result.get(), history));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace HistoryView
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
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 "base/unique_qptr.h"
|
||||||
|
|
||||||
|
namespace Dialogs {
|
||||||
|
class Entry;
|
||||||
|
} // namespace Dialogs
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class PopupMenu;
|
||||||
|
} // namespace Ui
|
||||||
|
|
||||||
|
namespace HistoryView {
|
||||||
|
|
||||||
|
[[nodiscard]] base::unique_qptr<Ui::PopupMenu> MakeChatPreview(
|
||||||
|
QWidget *parent,
|
||||||
|
not_null<Dialogs::Entry*> entry);
|
||||||
|
|
||||||
|
} // namespace HistoryView
|
|
@ -1076,3 +1076,12 @@ liveLocationLongInIconSelected: icon {{ "chat/live_location_long", msgInServiceF
|
||||||
liveLocationLongOutIcon: icon {{ "chat/live_location_long", msgOutServiceFg }};
|
liveLocationLongOutIcon: icon {{ "chat/live_location_long", msgOutServiceFg }};
|
||||||
liveLocationLongOutIconSelected: icon {{ "chat/live_location_long", msgOutServiceFgSelected }};
|
liveLocationLongOutIconSelected: icon {{ "chat/live_location_long", msgOutServiceFgSelected }};
|
||||||
liveLocationRemainingSize: 28px;
|
liveLocationRemainingSize: 28px;
|
||||||
|
|
||||||
|
previewMenu: PopupMenu(defaultPopupMenu) {
|
||||||
|
scrollPadding: margins(0px, 0px, 0px, 0px);
|
||||||
|
menu: Menu(defaultMenu) {
|
||||||
|
widthMin: 380px;
|
||||||
|
widthMax: 380px;
|
||||||
|
}
|
||||||
|
maxHeight: 420px;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue