mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-02-23 08:46:55 +00:00
Added initial context menu to TabbedPanel.
Added ability to schedule and send silently stickers and GIFs.
This commit is contained in:
parent
a95a324401
commit
7db9843543
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "chat_helpers/gifs_list_widget.h"
|
||||
|
||||
#include "api/api_common.h"
|
||||
#include "base/const_string.h"
|
||||
#include "data/data_photo.h"
|
||||
#include "data/data_document.h"
|
||||
@ -16,8 +17,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/data_photo_media.h"
|
||||
#include "data/data_document_media.h"
|
||||
#include "data/stickers/data_stickers.h"
|
||||
#include "chat_helpers/message_field.h" // FillSendMenu
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "ui/widgets/popup_menu.h"
|
||||
#include "ui/effects/ripple_animation.h"
|
||||
#include "ui/image/image.h"
|
||||
#include "boxes/stickers_box.h"
|
||||
@ -28,6 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "main/main_session.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "history/view/history_view_cursor_state.h"
|
||||
#include "history/view/history_view_schedule_box.h"
|
||||
#include "app.h"
|
||||
#include "styles/style_chat_helpers.h"
|
||||
|
||||
@ -343,6 +347,32 @@ void GifsListWidget::mousePressEvent(QMouseEvent *e) {
|
||||
_previewTimer.callOnce(QApplication::startDragTime());
|
||||
}
|
||||
|
||||
void GifsListWidget::fillContextMenu(not_null<Ui::PopupMenu*> menu) {
|
||||
if (_selected < 0 || _pressed >= 0) {
|
||||
return;
|
||||
}
|
||||
const auto row = _selected / MatrixRowShift;
|
||||
const auto column = _selected % MatrixRowShift;
|
||||
|
||||
const auto send = [=](Api::SendOptions options) {
|
||||
selectInlineResult(row, column, options, true);
|
||||
};
|
||||
const auto silent = [=] { send({ .silent = true }); };
|
||||
const auto schedule = [=] {
|
||||
Ui::show(
|
||||
HistoryView::PrepareScheduleBox(
|
||||
this,
|
||||
SendMenuType::Scheduled,
|
||||
[=](Api::SendOptions options) { send(options); }),
|
||||
Ui::LayerOption::KeepOther);
|
||||
};
|
||||
FillSendMenu(
|
||||
menu,
|
||||
[] { return SendMenuType::Scheduled; },
|
||||
silent,
|
||||
schedule);
|
||||
}
|
||||
|
||||
void GifsListWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||
_previewTimer.cancel();
|
||||
|
||||
@ -370,17 +400,25 @@ void GifsListWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||
}
|
||||
|
||||
void GifsListWidget::selectInlineResult(int row, int column) {
|
||||
selectInlineResult(row, column, Api::SendOptions());
|
||||
}
|
||||
|
||||
void GifsListWidget::selectInlineResult(
|
||||
int row,
|
||||
int column,
|
||||
Api::SendOptions options,
|
||||
bool forceSend) {
|
||||
if (row >= _rows.size() || column >= _rows[row].items.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto ctrl = (QGuiApplication::keyboardModifiers()
|
||||
forceSend |= (QGuiApplication::keyboardModifiers()
|
||||
== Qt::ControlModifier);
|
||||
auto item = _rows[row].items[column];
|
||||
if (const auto photo = item->getPhoto()) {
|
||||
using Data::PhotoSize;
|
||||
const auto media = photo->activeMediaView();
|
||||
if (ctrl
|
||||
if (forceSend
|
||||
|| (media && media->image(PhotoSize::Thumbnail))
|
||||
|| (media && media->image(PhotoSize::Large))) {
|
||||
_photoChosen.fire_copy(photo);
|
||||
@ -390,8 +428,10 @@ void GifsListWidget::selectInlineResult(int row, int column) {
|
||||
} else if (const auto document = item->getDocument()) {
|
||||
const auto media = document->activeMediaView();
|
||||
const auto preview = Data::VideoPreviewState(media.get());
|
||||
if (ctrl || (media && preview.loaded())) {
|
||||
_fileChosen.fire_copy({ .document = document });
|
||||
if (forceSend || (media && preview.loaded())) {
|
||||
_fileChosen.fire_copy({
|
||||
.document = document,
|
||||
.options = options });
|
||||
} else if (!preview.usingThumbnail()) {
|
||||
if (preview.loading()) {
|
||||
document->cancel();
|
||||
|
@ -14,6 +14,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
#include <QtCore/QTimer>
|
||||
|
||||
namespace Api {
|
||||
struct SendOptions;
|
||||
} // namespace Api
|
||||
|
||||
namespace InlineBots {
|
||||
namespace Layout {
|
||||
class ItemBase;
|
||||
@ -22,6 +26,7 @@ class Result;
|
||||
} // namespace InlineBots
|
||||
|
||||
namespace Ui {
|
||||
class PopupMenu;
|
||||
class RoundButton;
|
||||
} // namespace Ui
|
||||
|
||||
@ -66,6 +71,8 @@ public:
|
||||
void cancelled();
|
||||
rpl::producer<> cancelRequests() const;
|
||||
|
||||
void fillContextMenu(not_null<Ui::PopupMenu*> menu) override;
|
||||
|
||||
~GifsListWidget();
|
||||
|
||||
protected:
|
||||
@ -158,6 +165,11 @@ private:
|
||||
|
||||
int validateExistingInlineRows(const InlineResults &results);
|
||||
void selectInlineResult(int row, int column);
|
||||
void selectInlineResult(
|
||||
int row,
|
||||
int column,
|
||||
Api::SendOptions options,
|
||||
bool forceSend = false);
|
||||
|
||||
Footer *_footer = nullptr;
|
||||
|
||||
|
@ -14,8 +14,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/data_file_origin.h"
|
||||
#include "data/data_cloud_file.h"
|
||||
#include "data/data_changes.h"
|
||||
#include "chat_helpers/message_field.h" // FillSendMenu
|
||||
#include "chat_helpers/stickers_lottie.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/popup_menu.h"
|
||||
#include "ui/effects/animations.h"
|
||||
#include "ui/effects/ripple_animation.h"
|
||||
#include "ui/image/image.h"
|
||||
@ -24,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "lottie/lottie_animation.h"
|
||||
#include "boxes/stickers_box.h"
|
||||
#include "inline_bots/inline_bot_result.h"
|
||||
#include "history/view/history_view_schedule_box.h"
|
||||
#include "storage/storage_account.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "mainwindow.h"
|
||||
@ -2043,6 +2046,40 @@ QPoint StickersListWidget::buttonRippleTopLeft(int section) const {
|
||||
return myrtlrect(removeButtonRect(section)).topLeft() + st::stickerPanRemoveSet.rippleAreaPosition;
|
||||
}
|
||||
|
||||
void StickersListWidget::fillContextMenu(not_null<Ui::PopupMenu*> menu) {
|
||||
auto selected = _selected;
|
||||
auto &sets = shownSets();
|
||||
if (!selected || _pressed) {
|
||||
return;
|
||||
}
|
||||
if (auto sticker = base::get_if<OverSticker>(&selected)) {
|
||||
Assert(sticker->section >= 0 && sticker->section < sets.size());
|
||||
auto &set = sets[sticker->section];
|
||||
Assert(sticker->index >= 0 && sticker->index < set.stickers.size());
|
||||
|
||||
const auto document = set.stickers[sticker->index].document;
|
||||
const auto send = [=](Api::SendOptions options) {
|
||||
_chosen.fire_copy({
|
||||
.document = document,
|
||||
.options = options });
|
||||
};
|
||||
const auto silent = [=] { send({ .silent = true }); };
|
||||
const auto schedule = [=] {
|
||||
checkHideWithBox(Ui::show(
|
||||
HistoryView::PrepareScheduleBox(
|
||||
this,
|
||||
SendMenuType::Scheduled,
|
||||
[=](Api::SendOptions options) { send(options); }),
|
||||
Ui::LayerOption::KeepOther).data());
|
||||
};
|
||||
FillSendMenu(
|
||||
menu,
|
||||
[] { return SendMenuType::Scheduled; },
|
||||
silent,
|
||||
schedule);
|
||||
}
|
||||
}
|
||||
|
||||
void StickersListWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||
_previewTimer.cancel();
|
||||
|
||||
|
@ -22,6 +22,7 @@ class SessionController;
|
||||
|
||||
namespace Ui {
|
||||
class LinkButton;
|
||||
class PopupMenu;
|
||||
class RippleAnimation;
|
||||
class BoxContent;
|
||||
} // namespace Ui
|
||||
@ -82,6 +83,8 @@ public:
|
||||
|
||||
std::shared_ptr<Lottie::FrameRenderer> getLottieRenderer();
|
||||
|
||||
void fillContextMenu(not_null<Ui::PopupMenu*> menu) override;
|
||||
|
||||
~StickersListWidget();
|
||||
|
||||
protected:
|
||||
|
@ -364,6 +364,10 @@ void TabbedPanel::hideAnimated() {
|
||||
} else {
|
||||
startOpacityAnimation(true);
|
||||
}
|
||||
|
||||
// There is no reason to worry about the message scheduling box
|
||||
// while it moves the user to the separate scheduled section.
|
||||
_shouldFinishHide = _selector->hasMenu();
|
||||
}
|
||||
|
||||
void TabbedPanel::toggleAnimated() {
|
||||
@ -380,6 +384,7 @@ void TabbedPanel::hideFinished() {
|
||||
_showAnimation.reset();
|
||||
_cache = QPixmap();
|
||||
_hiding = false;
|
||||
_shouldFinishHide = false;
|
||||
_selector->hideFinished();
|
||||
}
|
||||
|
||||
@ -390,6 +395,9 @@ void TabbedPanel::showAnimated() {
|
||||
}
|
||||
|
||||
void TabbedPanel::showStarted() {
|
||||
if (_shouldFinishHide) {
|
||||
return;
|
||||
}
|
||||
if (isHidden()) {
|
||||
_selector->showStarted();
|
||||
moveByBottom();
|
||||
|
@ -110,6 +110,8 @@ private:
|
||||
std::unique_ptr<Ui::PanelAnimation> _showAnimation;
|
||||
Ui::Animations::Simple _a_show;
|
||||
|
||||
bool _shouldFinishHide = false;
|
||||
|
||||
bool _hiding = false;
|
||||
bool _hideAfterSlide = false;
|
||||
QPixmap _cache;
|
||||
|
@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/widgets/shadow.h"
|
||||
#include "ui/widgets/discrete_sliders.h"
|
||||
#include "ui/widgets/popup_menu.h"
|
||||
#include "ui/widgets/scroll_area.h"
|
||||
#include "ui/image/image_prepare.h"
|
||||
#include "window/window_session_controller.h"
|
||||
@ -584,7 +585,13 @@ void TabbedSelector::refreshStickers() {
|
||||
}
|
||||
|
||||
bool TabbedSelector::preventAutoHide() const {
|
||||
return full() ? stickers()->preventAutoHide() : false;
|
||||
return full()
|
||||
? (stickers()->preventAutoHide() || hasMenu())
|
||||
: false;
|
||||
}
|
||||
|
||||
bool TabbedSelector::hasMenu() const {
|
||||
return (_menu && !_menu->actions().empty());
|
||||
}
|
||||
|
||||
QImage TabbedSelector::grabForAnimation() {
|
||||
@ -867,6 +874,15 @@ void TabbedSelector::scrollToY(int y) {
|
||||
}
|
||||
}
|
||||
|
||||
void TabbedSelector::contextMenuEvent(QContextMenuEvent *e) {
|
||||
_menu = base::make_unique_q<Ui::PopupMenu>(this);
|
||||
currentTab()->widget()->fillContextMenu(_menu);
|
||||
|
||||
if (!_menu->actions().empty()) {
|
||||
_menu->popup(QCursor::pos());
|
||||
}
|
||||
}
|
||||
|
||||
TabbedSelector::Inner::Inner(
|
||||
QWidget *parent,
|
||||
not_null<Window::SessionController*> controller)
|
||||
|
@ -24,6 +24,7 @@ class Session;
|
||||
|
||||
namespace Ui {
|
||||
class PlainShadow;
|
||||
class PopupMenu;
|
||||
class ScrollArea;
|
||||
class SettingsSlider;
|
||||
class FlatLabel;
|
||||
@ -94,6 +95,7 @@ public:
|
||||
bool isSliding() const {
|
||||
return _a_slide.animating();
|
||||
}
|
||||
bool hasMenu() const;
|
||||
|
||||
void setAfterShownCallback(Fn<void(SelectorTab)> callback) {
|
||||
_afterShownCallback = std::move(callback);
|
||||
@ -116,6 +118,7 @@ public:
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
void contextMenuEvent(QContextMenuEvent *e) override;
|
||||
|
||||
private:
|
||||
class Tab {
|
||||
@ -211,6 +214,8 @@ private:
|
||||
std::array<Tab, Tab::kCount> _tabs;
|
||||
SelectorTab _currentTabType = SelectorTab::Emoji;
|
||||
|
||||
base::unique_qptr<Ui::PopupMenu> _menu;
|
||||
|
||||
Fn<void(SelectorTab)> _afterShownCallback;
|
||||
Fn<void(SelectorTab)> _beforeHidingCallback;
|
||||
|
||||
@ -246,6 +251,8 @@ public:
|
||||
}
|
||||
virtual void beforeHiding() {
|
||||
}
|
||||
virtual void fillContextMenu(not_null<Ui::PopupMenu*> menu) {
|
||||
}
|
||||
|
||||
rpl::producer<int> scrollToRequests() const;
|
||||
rpl::producer<bool> disableScrollRequests() const;
|
||||
|
Loading…
Reference in New Issue
Block a user