tdesktop/Telegram/SourceFiles/overviewwidget.h

355 lines
9.1 KiB
C
Raw Normal View History

2014-08-15 11:19:32 +00:00
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram messaging app, see https://telegram.org
2014-08-15 11:19:32 +00:00
Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
It is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014 John Preston, https://desktop.telegram.org
2014-08-15 11:19:32 +00:00
*/
#pragma once
class OverviewWidget;
2014-08-20 05:32:50 +00:00
class OverviewInner : public QWidget, public RPCSender {
2014-08-15 11:19:32 +00:00
Q_OBJECT
public:
OverviewInner(OverviewWidget *overview, ScrollArea *scroll, const PeerData *peer, MediaOverviewType type);
void activate();
2014-08-15 11:19:32 +00:00
void clear();
int32 itemTop(const FullMsgId &msgId) const;
2014-08-15 11:19:32 +00:00
bool preloadLocal();
void preloadMore();
2014-08-15 11:19:32 +00:00
bool event(QEvent *e);
2014-08-20 05:32:50 +00:00
void touchEvent(QTouchEvent *e);
2014-08-15 11:19:32 +00:00
void paintEvent(QPaintEvent *e);
void mouseMoveEvent(QMouseEvent *e);
void mousePressEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);
void keyPressEvent(QKeyEvent *e);
void enterEvent(QEvent *e);
void leaveEvent(QEvent *e);
void resizeEvent(QResizeEvent *e);
2014-08-20 05:32:50 +00:00
void showContextMenu(QContextMenuEvent *e, bool showFromTouch = false);
void dragActionStart(const QPoint &screenPos, Qt::MouseButton button = Qt::LeftButton);
void dragActionUpdate(const QPoint &screenPos);
void dragActionFinish(const QPoint &screenPos, Qt::MouseButton button = Qt::LeftButton);
void dragActionCancel();
void touchScrollUpdated(const QPoint &screenPos);
QPoint mapMouseToItem(QPoint p, MsgId itemId, int32 itemIndex);
2014-08-15 11:19:32 +00:00
int32 resizeToWidth(int32 nwidth, int32 scrollTop, int32 minHeight); // returns new scroll top
void dropResizeIndex();
PeerData *peer() const;
MediaOverviewType type() const;
void switchType(MediaOverviewType type);
void setSelectMode(bool enabled);
void mediaOverviewUpdated(bool fromResize = false);
void changingMsgId(HistoryItem *row, MsgId newId);
void msgUpdated(const HistoryItem *msg);
void itemRemoved(HistoryItem *item);
2015-04-04 20:01:34 +00:00
void itemResized(HistoryItem *item, bool scrollToIt);
2014-08-15 11:19:32 +00:00
2014-08-20 05:32:50 +00:00
void getSelectionState(int32 &selectedForForward, int32 &selectedForDelete) const;
void clearSelectedItems(bool onlyTextSelection = false);
void fillSelectedItems(SelectedItemSet &sel, bool forDelete = true);
2014-08-15 11:19:32 +00:00
~OverviewInner();
public slots:
2014-08-20 05:32:50 +00:00
void onUpdateSelected();
void showLinkTip();
2014-08-15 11:19:32 +00:00
void openContextUrl();
void copyContextUrl();
2014-08-15 11:19:32 +00:00
void cancelContextDownload();
void showContextInFolder();
void saveContextFile();
void openContextFile();
void goToMessage();
void deleteMessage();
void forwardMessage();
void selectMessage();
2014-08-15 11:19:32 +00:00
void onSearchUpdate();
void onCancel();
bool onCancelSearch();
2014-08-15 11:19:32 +00:00
void onMenuDestroy(QObject *obj);
2014-08-20 05:32:50 +00:00
void onTouchSelect();
void onTouchScrollTimer();
2014-08-15 11:19:32 +00:00
void onDragExec();
bool onSearchMessages(bool searchCache = false);
void onNeedSearchMessages();
2014-08-15 11:19:32 +00:00
private:
2014-08-20 05:32:50 +00:00
void fixItemIndex(int32 &current, MsgId msgId) const;
bool itemHasPoint(MsgId msgId, int32 index, int32 x, int32 y) const;
int32 itemHeight(MsgId msgId, int32 index) const;
void moveToNextItem(MsgId &msgId, int32 &index, MsgId upTo, int32 delta) const;
void updateDragSelection(MsgId dragSelFrom, int32 dragSelFromIndex, MsgId dragSelTo, int32 dragSelToIndex, bool dragSelecting);
void updateMsg(HistoryItem *item);
void updateMsg(MsgId itemId, int32 itemIndex);
void touchResetSpeed();
void touchUpdateSpeed();
void touchDeaccelerate(int32 elapsed);
void applyDragSelection();
2014-08-15 11:19:32 +00:00
QPixmap genPix(PhotoData *photo, int32 size);
void showAll(bool recountHeights = false);
2014-08-15 11:19:32 +00:00
OverviewWidget *_overview;
ScrollArea *_scroll;
int32 _resizeIndex, _resizeSkip;
PeerData *_peer;
MediaOverviewType _type;
History *_hist;
ChannelId _channel;
2014-08-20 05:32:50 +00:00
2014-08-15 11:19:32 +00:00
// photos
2014-08-20 05:32:50 +00:00
int32 _photosInRow, _photosToAdd, _vsize;
struct CachedSize {
2014-08-15 11:19:32 +00:00
int32 vsize;
bool medium;
QPixmap pix;
};
2014-08-15 11:19:32 +00:00
typedef QMap<PhotoData*, CachedSize> CachedSizes;
CachedSizes _cached;
bool _selMode;
2014-08-15 11:19:32 +00:00
2015-07-03 10:48:28 +00:00
// audio documents
int32 _audioLeft, _audioWidth, _audioHeight;
// shared links
int32 _linksLeft, _linksWidth;
struct Link {
Link() : width(0) {
}
2015-10-03 10:09:09 +00:00
Link(const QString &url, const QString &text) : url(url), text(text), width(st::msgFont->width(text)) {
}
QString url, text;
int32 width;
};
struct CachedLink {
CachedLink() : titleWidth(0), page(0), pixw(0), pixh(0), text(st::msgMinWidth) {
}
CachedLink(HistoryItem *item);
int32 countHeight(int32 w);
QString title, letter;
int32 titleWidth;
WebPageData *page;
int32 pixw, pixh;
Text text;
QVector<Link> urls;
};
typedef QMap<MsgId, CachedLink*> CachedLinks;
CachedLinks _links;
FlatInput _search;
IconedButton _cancelSearch;
QVector<MsgId> _results;
int32 _itemsToBeLoaded;
QTimer _searchTimer;
QString _searchQuery;
bool _inSearch, _searchFull;
mtpRequestId _searchRequest;
History::MediaOverview _searchResults;
MsgId _lastSearchId;
int32 _searchedCount;
void searchReceived(bool fromStart, const MTPmessages_Messages &result, mtpRequestId req);
bool searchFailed(const RPCError &error, mtpRequestId req);
typedef QMap<QString, MTPmessages_Messages> SearchCache;
SearchCache _searchCache;
typedef QMap<mtpRequestId, QString> SearchQueries;
SearchQueries _searchQueries;
CachedLink *cachedLink(HistoryItem *item);
2014-08-15 11:19:32 +00:00
// other
struct CachedItem {
CachedItem() : msgid(0), y(0) {
2014-08-15 11:19:32 +00:00
}
CachedItem(MsgId msgid, const QDate &date, int32 y) : msgid(msgid), date(date), y(y) {
2014-08-15 11:19:32 +00:00
}
MsgId msgid;
QDate date;
int32 y;
CachedLink *link;
};
2014-08-15 11:19:32 +00:00
typedef QVector<CachedItem> CachedItems;
CachedItems _items;
2015-07-03 08:47:16 +00:00
2014-08-20 05:32:50 +00:00
int32 _width, _height, _minHeight, _addToY;
QTimer _linkTipTimer;
2014-08-20 05:32:50 +00:00
// selection support, like in HistoryWidget
Qt::CursorShape _cursor;
HistoryCursorState _cursorState;
2014-08-20 05:32:50 +00:00
typedef QMap<MsgId, uint32> SelectedItems;
SelectedItems _selected;
enum DragAction {
NoDrag = 0x00,
PrepareDrag = 0x01,
Dragging = 0x02,
PrepareSelect = 0x03,
Selecting = 0x04,
};
DragAction _dragAction;
QPoint _dragStartPos, _dragPos;
2015-07-03 10:48:28 +00:00
MsgId _dragItem, _selectedMsgId;
2014-08-20 05:32:50 +00:00
int32 _dragItemIndex;
MsgId _mousedItem;
int32 _mousedItemIndex;
int32 _lnkOverIndex, _lnkDownIndex; // for OverviewLinks, 0 - none, -1 - photo or title, > 0 - lnk index
2014-08-20 05:32:50 +00:00
uint16 _dragSymbol;
bool _dragWasInactive;
2014-08-15 11:19:32 +00:00
QString urlByIndex(MsgId msgid, int32 index, int32 lnkIndex, bool *fullShown = 0) const;
bool urlIsEmail(const QString &url) const;
QString _contextMenuUrl;
2014-08-20 05:32:50 +00:00
TextLinkPtr _contextMenuLnk;
MsgId _dragSelFrom, _dragSelTo;
int32 _dragSelFromIndex, _dragSelToIndex;
bool _dragSelecting;
bool _touchScroll, _touchSelect, _touchInProgress;
QPoint _touchStart, _touchPrevPos, _touchPos;
QTimer _touchSelectTimer;
TouchScrollState _touchScrollState;
bool _touchPrevPosValid, _touchWaitingAcceleration;
QPoint _touchSpeed;
uint64 _touchSpeedTime, _touchAccelerationTime, _touchTime;
QTimer _touchScrollTimer;
ContextMenu *_menu;
2014-08-15 11:19:32 +00:00
};
class OverviewWidget : public QWidget, public RPCSender, public Animated {
Q_OBJECT
public:
OverviewWidget(QWidget *parent, const PeerData *peer, MediaOverviewType type);
void clear();
void resizeEvent(QResizeEvent *e);
void paintEvent(QPaintEvent *e);
2014-08-20 05:32:50 +00:00
void contextMenuEvent(QContextMenuEvent *e);
2014-08-15 11:19:32 +00:00
void scrollBy(int32 add);
void scrollReset();
2014-08-15 11:19:32 +00:00
void paintTopBar(QPainter &p, float64 over, int32 decreaseWidth);
2015-07-03 08:47:16 +00:00
void topBarShadowParams(int32 &x, float64 &o);
2014-08-15 11:19:32 +00:00
void topBarClick();
PeerData *peer() const;
MediaOverviewType type() const;
void switchType(MediaOverviewType type);
2014-08-20 05:32:50 +00:00
void updateTopBarSelection();
2014-08-15 11:19:32 +00:00
int32 lastWidth() const;
int32 lastScrollTop() const;
2015-07-03 10:48:28 +00:00
int32 countBestScroll() const;
2014-08-15 11:19:32 +00:00
2015-07-03 10:48:28 +00:00
void fastShow(bool back = false, int32 lastScrollTop = -1);
2014-08-15 11:19:32 +00:00
void animShow(const QPixmap &oldAnimCache, const QPixmap &bgAnimTopBarCache, bool back = false, int32 lastScrollTop = -1);
bool animStep(float64 ms);
2015-07-03 08:47:16 +00:00
void doneShow();
void mediaOverviewUpdated(PeerData *peer, MediaOverviewType type);
void changingMsgId(HistoryItem *row, MsgId newId);
void msgUpdated(PeerId peer, const HistoryItem *msg);
void itemRemoved(HistoryItem *item);
2015-04-04 20:01:34 +00:00
void itemResized(HistoryItem *row, bool scrollToIt);
2014-08-15 11:19:32 +00:00
2014-08-20 05:32:50 +00:00
QPoint clampMousePosition(QPoint point);
void checkSelectingScroll(QPoint point);
void noSelectingScroll();
bool touchScroll(const QPoint &delta);
void fillSelectedItems(SelectedItemSet &sel, bool forDelete);
2015-02-03 15:02:46 +00:00
void updateScrollColors();
void updateAfterDrag();
2014-08-15 11:19:32 +00:00
~OverviewWidget();
public slots:
void activate();
void onScroll();
2014-08-20 05:32:50 +00:00
void onScrollTimer();
void onPlayerSongChanged(const FullMsgId &msgId);
2014-08-20 05:32:50 +00:00
void onForwardSelected();
void onDeleteSelected();
void onDeleteSelectedSure();
void onDeleteContextSure();
void onClearSelected();
2014-08-15 11:19:32 +00:00
private:
ScrollArea _scroll;
OverviewInner _inner;
bool _noDropResizeIndex;
QString _header;
bool _showing;
QPixmap _animCache, _bgAnimCache, _animTopBarCache, _bgAnimTopBarCache;
anim::ivalue a_coord, a_bgCoord;
anim::fvalue a_alpha, a_bgAlpha;
int32 _scrollSetAfterShow;
2014-08-20 05:32:50 +00:00
QTimer _scrollTimer;
int32 _scrollDelta;
int32 _selCount;
2014-08-15 11:19:32 +00:00
};