mirror of https://github.com/procxx/kepka.git
Alpha 1.0.4: Click and drag to reorder pinned chats.
This commit is contained in:
parent
b21f72fef0
commit
d1b9b8e3a3
|
@ -34,8 +34,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,0,3,0
|
FILEVERSION 1,0,4,0
|
||||||
PRODUCTVERSION 1,0,3,0
|
PRODUCTVERSION 1,0,4,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -51,10 +51,10 @@ BEGIN
|
||||||
BLOCK "040904b0"
|
BLOCK "040904b0"
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Telegram Messenger LLP"
|
VALUE "CompanyName", "Telegram Messenger LLP"
|
||||||
VALUE "FileVersion", "1.0.3.0"
|
VALUE "FileVersion", "1.0.4.0"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2014-2017"
|
VALUE "LegalCopyright", "Copyright (C) 2014-2017"
|
||||||
VALUE "ProductName", "Telegram Desktop"
|
VALUE "ProductName", "Telegram Desktop"
|
||||||
VALUE "ProductVersion", "1.0.3.0"
|
VALUE "ProductVersion", "1.0.4.0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,0,3,0
|
FILEVERSION 1,0,4,0
|
||||||
PRODUCTVERSION 1,0,3,0
|
PRODUCTVERSION 1,0,4,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -43,10 +43,10 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Telegram Messenger LLP"
|
VALUE "CompanyName", "Telegram Messenger LLP"
|
||||||
VALUE "FileDescription", "Telegram Updater"
|
VALUE "FileDescription", "Telegram Updater"
|
||||||
VALUE "FileVersion", "1.0.3.0"
|
VALUE "FileVersion", "1.0.4.0"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2014-2017"
|
VALUE "LegalCopyright", "Copyright (C) 2014-2017"
|
||||||
VALUE "ProductName", "Telegram Desktop"
|
VALUE "ProductName", "Telegram Desktop"
|
||||||
VALUE "ProductVersion", "1.0.3.0"
|
VALUE "ProductVersion", "1.0.4.0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -1069,8 +1069,8 @@ void AppClass::checkMapVersion() {
|
||||||
if (Local::oldMapVersion() < AppVersion) {
|
if (Local::oldMapVersion() < AppVersion) {
|
||||||
if (Local::oldMapVersion()) {
|
if (Local::oldMapVersion()) {
|
||||||
QString versionFeatures;
|
QString versionFeatures;
|
||||||
if ((cAlphaVersion() || cBetaVersion()) && Local::oldMapVersion() < 1000003) {
|
if ((cAlphaVersion() || cBetaVersion()) && Local::oldMapVersion() < 1000004) {
|
||||||
versionFeatures = QString::fromUtf8("\xe2\x80\x94 Audio device is opened only when some sound is played.\n\xe2\x80\x94 On Windows Vista and later audio device should switch after the system default changes.");
|
versionFeatures = QString::fromUtf8("\xe2\x80\x94 Click and drag to reorder pinned chats.");
|
||||||
} else if (!(cAlphaVersion() || cBetaVersion()) && Local::oldMapVersion() < 1000002) {
|
} else if (!(cAlphaVersion() || cBetaVersion()) && Local::oldMapVersion() < 1000002) {
|
||||||
versionFeatures = langNewVersionText();
|
versionFeatures = langNewVersionText();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -330,7 +330,7 @@ void SessionsBox::Inner::onTerminateAll() {
|
||||||
_terminateBox->closeBox();
|
_terminateBox->closeBox();
|
||||||
_terminateBox = nullptr;
|
_terminateBox = nullptr;
|
||||||
}
|
}
|
||||||
// MTP::send(MTPauth_ResetAuthorizations(), rpcDone(&Inner::terminateAllDone), rpcFail(&Inner::terminateAllFail));
|
MTP::send(MTPauth_ResetAuthorizations(), rpcDone(&Inner::terminateAllDone), rpcFail(&Inner::terminateAllFail));
|
||||||
emit terminateAll();
|
emit terminateAll();
|
||||||
})), KeepOtherLayers);
|
})), KeepOtherLayers);
|
||||||
}
|
}
|
||||||
|
|
|
@ -860,7 +860,7 @@ void StickersBox::Inner::onUpdateSelected() {
|
||||||
}
|
}
|
||||||
_rows[_dragging]->yadd = anim::value(local.y() - _dragStart.y(), local.y() - _dragStart.y());
|
_rows[_dragging]->yadd = anim::value(local.y() - _dragStart.y(), local.y() - _dragStart.y());
|
||||||
_animStartTimes[_dragging] = 0;
|
_animStartTimes[_dragging] = 0;
|
||||||
_a_shifting.step(getms(), true);
|
_a_shifting.step(ms, true);
|
||||||
|
|
||||||
auto countDraggingScrollDelta = [this, local] {
|
auto countDraggingScrollDelta = [this, local] {
|
||||||
if (local.y() < _visibleTop) {
|
if (local.y() < _visibleTop) {
|
||||||
|
|
|
@ -24,7 +24,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#define BETA_VERSION_MACRO (0ULL)
|
#define BETA_VERSION_MACRO (0ULL)
|
||||||
|
|
||||||
constexpr int AppVersion = 1000003;
|
constexpr int AppVersion = 1000004;
|
||||||
constexpr str_const AppVersionStr = "1.0.3";
|
constexpr str_const AppVersionStr = "1.0.4";
|
||||||
constexpr bool AppAlphaVersion = true;
|
constexpr bool AppAlphaVersion = true;
|
||||||
constexpr uint64 AppBetaVersion = BETA_VERSION_MACRO;
|
constexpr uint64 AppBetaVersion = BETA_VERSION_MACRO;
|
||||||
|
|
|
@ -81,6 +81,25 @@ void IndexedList::moveToTop(PeerData *peer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IndexedList::movePinned(Row *row, int deltaSign) {
|
||||||
|
auto swapPinnedIndexWith = find(row);
|
||||||
|
t_assert(swapPinnedIndexWith != cend());
|
||||||
|
if (deltaSign > 0) {
|
||||||
|
++swapPinnedIndexWith;
|
||||||
|
} else {
|
||||||
|
t_assert(swapPinnedIndexWith != cbegin());
|
||||||
|
--swapPinnedIndexWith;
|
||||||
|
}
|
||||||
|
auto history1 = row->history();
|
||||||
|
auto history2 = (*swapPinnedIndexWith)->history();
|
||||||
|
t_assert(history1->isPinnedDialog());
|
||||||
|
t_assert(history2->isPinnedDialog());
|
||||||
|
auto index1 = history1->getPinnedIndex();
|
||||||
|
auto index2 = history2->getPinnedIndex();
|
||||||
|
history1->setPinnedIndex(index2);
|
||||||
|
history2->setPinnedIndex(index1);
|
||||||
|
}
|
||||||
|
|
||||||
void IndexedList::peerNameChanged(PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars) {
|
void IndexedList::peerNameChanged(PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars) {
|
||||||
t_assert(_sortMode != SortMode::Date);
|
t_assert(_sortMode != SortMode::Date);
|
||||||
if (_sortMode == SortMode::Name) {
|
if (_sortMode == SortMode::Name) {
|
||||||
|
|
|
@ -36,6 +36,9 @@ public:
|
||||||
void adjustByPos(const RowsByLetter &links);
|
void adjustByPos(const RowsByLetter &links);
|
||||||
void moveToTop(PeerData *peer);
|
void moveToTop(PeerData *peer);
|
||||||
|
|
||||||
|
// row must belong to this indexed list all().
|
||||||
|
void movePinned(Row *row, int deltaSign);
|
||||||
|
|
||||||
// For sortMode != SortMode::Date
|
// For sortMode != SortMode::Date
|
||||||
void peerNameChanged(PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars);
|
void peerNameChanged(PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars);
|
||||||
|
|
||||||
|
|
|
@ -47,20 +47,6 @@ void List::adjustCurrent(int32 y, int32 h) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void List::paint(Painter &p, int32 w, int32 hFrom, int32 hTo, PeerData *act, PeerData *sel, bool onlyBackground, TimeMs ms) const {
|
|
||||||
adjustCurrent(hFrom, st::dialogsRowHeight);
|
|
||||||
|
|
||||||
Row *row = _current;
|
|
||||||
p.translate(0, row->_pos * st::dialogsRowHeight);
|
|
||||||
while (row != _end && row->_pos * st::dialogsRowHeight < hTo) {
|
|
||||||
bool active = (row->history()->peer == act) || (row->history()->peer->migrateTo() && row->history()->peer->migrateTo() == act);
|
|
||||||
bool selected = (row->history()->peer == sel);
|
|
||||||
Layout::RowPainter::paint(p, row, w, active, selected, onlyBackground, ms);
|
|
||||||
row = row->_next;
|
|
||||||
p.translate(0, st::dialogsRowHeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row *List::addToEnd(History *history) {
|
Row *List::addToEnd(History *history) {
|
||||||
Row *result = new Row(history, _end->_prev, _end, _end->_pos);
|
Row *result = new Row(history, _end->_prev, _end, _end->_pos);
|
||||||
_end->_pos++;
|
_end->_pos++;
|
||||||
|
|
|
@ -51,7 +51,6 @@ public:
|
||||||
return *i;
|
return *i;
|
||||||
}
|
}
|
||||||
|
|
||||||
void paint(Painter &p, int32 w, int32 hFrom, int32 hTo, PeerData *act, PeerData *sel, bool onlyBackground, TimeMs ms) const;
|
|
||||||
Row *addToEnd(History *history);
|
Row *addToEnd(History *history);
|
||||||
Row *adjustByName(const PeerData *peer);
|
Row *adjustByName(const PeerData *peer);
|
||||||
Row *addByName(History *history);
|
Row *addByName(History *history);
|
||||||
|
|
|
@ -44,10 +44,12 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "ui/widgets/input_fields.h"
|
#include "ui/widgets/input_fields.h"
|
||||||
#include "window/window_theme.h"
|
#include "window/window_theme.h"
|
||||||
#include "autoupdater.h"
|
#include "autoupdater.h"
|
||||||
|
#include "observer_peer.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr auto kHashtagResultsLimit = 5;
|
constexpr auto kHashtagResultsLimit = 5;
|
||||||
|
constexpr auto kStartReorderThreshold = 30;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
@ -73,6 +75,7 @@ DialogsInner::DialogsInner(QWidget *parent, QWidget *main) : SplittedWidget(pare
|
||||||
, _dialogs(std_::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Date))
|
, _dialogs(std_::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Date))
|
||||||
, _contactsNoDialogs(std_::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Name))
|
, _contactsNoDialogs(std_::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Name))
|
||||||
, _contacts(std_::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Name))
|
, _contacts(std_::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Name))
|
||||||
|
, _a_pinnedShifting(animation(this, &DialogsInner::step_pinnedShifting))
|
||||||
, _addContactLnk(this, lang(lng_add_contact_button))
|
, _addContactLnk(this, lang(lng_add_contact_button))
|
||||||
, _cancelSearchInPeer(this, st::dialogsCancelSearchInPeer) {
|
, _cancelSearchInPeer(this, st::dialogsCancelSearchInPeer) {
|
||||||
if (Global::DialogsModeEnabled()) {
|
if (Global::DialogsModeEnabled()) {
|
||||||
|
@ -101,6 +104,10 @@ DialogsInner::DialogsInner(QWidget *parent, QWidget *main) : SplittedWidget(pare
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::PinnedChanged, [this](const Notify::PeerUpdate &update) {
|
||||||
|
stopReorderPinned();
|
||||||
|
}));
|
||||||
|
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,18 +142,60 @@ void DialogsInner::paintRegion(Painter &p, const QRegion ®ion, bool paintingO
|
||||||
auto fullWidth = getFullWidth();
|
auto fullWidth = getFullWidth();
|
||||||
auto ms = getms();
|
auto ms = getms();
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
QRect dialogsClip = r;
|
auto rows = shownDialogs();
|
||||||
|
auto dialogsClip = r;
|
||||||
if (_dialogsImportant) {
|
if (_dialogsImportant) {
|
||||||
auto selected = isPressed() ? _importantSwitchPressed : _importantSwitchSelected;
|
auto selected = isPressed() ? _importantSwitchPressed : _importantSwitchSelected;
|
||||||
Dialogs::Layout::paintImportantSwitch(p, Global::DialogsMode(), fullWidth, selected, paintingOther);
|
Dialogs::Layout::paintImportantSwitch(p, Global::DialogsMode(), fullWidth, selected, paintingOther);
|
||||||
dialogsClip.translate(0, -st::dialogsImportantBarHeight);
|
dialogsClip.translate(0, -st::dialogsImportantBarHeight);
|
||||||
p.translate(0, st::dialogsImportantBarHeight);
|
p.translate(0, st::dialogsImportantBarHeight);
|
||||||
}
|
}
|
||||||
auto otherStart = shownDialogs()->size() * st::dialogsRowHeight;
|
auto otherStart = rows->size() * st::dialogsRowHeight;
|
||||||
auto active = App::main()->activePeer();
|
auto active = App::main()->activePeer();
|
||||||
auto selected = _menuPeer ? _menuPeer : (isPressed() ? (_pressed ? _pressed->history()->peer : nullptr) : (_selected ? _selected->history()->peer : nullptr));
|
auto selected = _menuPeer ? _menuPeer : (isPressed() ? (_pressed ? _pressed->history()->peer : nullptr) : (_selected ? _selected->history()->peer : nullptr));
|
||||||
if (otherStart) {
|
if (otherStart) {
|
||||||
shownDialogs()->all().paint(p, fullWidth, dialogsClip.top(), dialogsClip.top() + dialogsClip.height(), active, selected, paintingOther, ms);
|
auto reorderingPinned = (_aboveIndex >= 0 && !_pinnedRows.isEmpty());
|
||||||
|
auto &list = rows->all();
|
||||||
|
if (reorderingPinned) {
|
||||||
|
dialogsClip = dialogsClip.marginsAdded(QMargins(0, st::dialogsRowHeight, 0, st::dialogsRowHeight));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto i = list.cfind(dialogsClip.top(), st::dialogsRowHeight);
|
||||||
|
if (i != list.cend()) {
|
||||||
|
auto lastPaintedPos = (*i)->pos();
|
||||||
|
|
||||||
|
// If we're reordering pinned chats we need to fill this area background first.
|
||||||
|
if (reorderingPinned) {
|
||||||
|
p.fillRect(0, 0, fullWidth, st::dialogsRowHeight * _pinnedRows.size(), st::dialogsBg);
|
||||||
|
}
|
||||||
|
|
||||||
|
p.translate(0, lastPaintedPos * st::dialogsRowHeight);
|
||||||
|
for (auto e = list.cend(); i != e; ++i) {
|
||||||
|
auto row = (*i);
|
||||||
|
lastPaintedPos = row->pos();
|
||||||
|
if (lastPaintedPos * st::dialogsRowHeight >= dialogsClip.top() + dialogsClip.height()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip currently dragged chat to paint it above others after.
|
||||||
|
if (lastPaintedPos != _aboveIndex) {
|
||||||
|
paintDialog(p, row, fullWidth, active, selected, paintingOther, ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
p.translate(0, st::dialogsRowHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Paint the dragged chat above all others.
|
||||||
|
if (_aboveIndex >= 0) {
|
||||||
|
auto i = list.cfind(_aboveIndex, 1);
|
||||||
|
auto pos = (i == list.cend()) ? -1 : (*i)->pos();
|
||||||
|
if (pos == _aboveIndex) {
|
||||||
|
p.translate(0, (pos - lastPaintedPos) * st::dialogsRowHeight);
|
||||||
|
paintDialog(p, *i, fullWidth, active, selected, paintingOther, ms);
|
||||||
|
p.translate(0, (lastPaintedPos - pos) * st::dialogsRowHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!otherStart) {
|
if (!otherStart) {
|
||||||
p.fillRect(dialogsClip, st::dialogsBg);
|
p.fillRect(dialogsClip, st::dialogsBg);
|
||||||
|
@ -294,6 +343,19 @@ void DialogsInner::paintRegion(Painter &p, const QRegion ®ion, bool paintingO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DialogsInner::paintDialog(Painter &p, Dialogs::Row *row, int fullWidth, PeerData *active, PeerData *selected, bool onlyBackground, TimeMs ms) {
|
||||||
|
auto pos = row->pos();
|
||||||
|
auto xadd = 0, yadd = 0;
|
||||||
|
if (pos < _pinnedRows.size()) {
|
||||||
|
yadd = qRound(_pinnedRows[pos].yadd.current());
|
||||||
|
}
|
||||||
|
if (xadd || yadd) p.translate(xadd, yadd);
|
||||||
|
auto isActive = (row->history()->peer == active) || (row->history()->peer->migrateTo() && row->history()->peer->migrateTo() == active);
|
||||||
|
auto isSelected = (row->history()->peer == selected);
|
||||||
|
Dialogs::Layout::RowPainter::paint(p, row, fullWidth, isActive, isSelected, onlyBackground, ms);
|
||||||
|
if (xadd || yadd) p.translate(-xadd, -yadd);
|
||||||
|
}
|
||||||
|
|
||||||
void DialogsInner::paintPeerSearchResult(Painter &p, const PeerSearchResult *result, int fullWidth, bool active, bool selected, bool onlyBackground, TimeMs ms) const {
|
void DialogsInner::paintPeerSearchResult(Painter &p, const PeerSearchResult *result, int fullWidth, bool active, bool selected, bool onlyBackground, TimeMs ms) const {
|
||||||
QRect fullRect(0, 0, fullWidth, st::dialogsRowHeight);
|
QRect fullRect(0, 0, fullWidth, st::dialogsRowHeight);
|
||||||
p.fillRect(fullRect, active ? st::dialogsBgActive : (selected ? st::dialogsBgOver : st::dialogsBg));
|
p.fillRect(fullRect, active ? st::dialogsBgActive : (selected ? st::dialogsBgOver : st::dialogsBg));
|
||||||
|
@ -399,7 +461,12 @@ void DialogsInner::clearIrrelevantState() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsInner::updateSelected(QPoint localPos) {
|
void DialogsInner::updateSelected(QPoint localPos) {
|
||||||
if (!_mouseSelection) return;
|
if (updateReorderPinned(localPos)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!_mouseSelection) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int w = width(), mouseY = localPos.y();
|
int w = width(), mouseY = localPos.y();
|
||||||
clearIrrelevantState();
|
clearIrrelevantState();
|
||||||
|
@ -495,6 +562,7 @@ void DialogsInner::mousePressEvent(QMouseEvent *e) {
|
||||||
row->addRipple(e->pos() - QPoint(0, dialogsOffset() + _pressed->pos() * st::dialogsRowHeight), QSize(getFullWidth(), st::dialogsRowHeight), [row] {
|
row->addRipple(e->pos() - QPoint(0, dialogsOffset() + _pressed->pos() * st::dialogsRowHeight), QSize(getFullWidth(), st::dialogsRowHeight), [row] {
|
||||||
row->history()->updateChatListEntry();
|
row->history()->updateChatListEntry();
|
||||||
});
|
});
|
||||||
|
_dragStart = e->pos();
|
||||||
} else if (_hashtagPressed >= 0 && _hashtagPressed < _hashtagResults.size() && !_hashtagDeletePressed) {
|
} else if (_hashtagPressed >= 0 && _hashtagPressed < _hashtagResults.size() && !_hashtagDeletePressed) {
|
||||||
auto row = &_hashtagResults[_hashtagPressed]->row;
|
auto row = &_hashtagResults[_hashtagPressed]->row;
|
||||||
row->addRipple(e->pos(), QSize(getFullWidth(), st::mentionHeight), [this, index = _hashtagPressed] {
|
row->addRipple(e->pos(), QSize(getFullWidth(), st::mentionHeight), [this, index = _hashtagPressed] {
|
||||||
|
@ -523,11 +591,233 @@ void DialogsInner::mousePressEvent(QMouseEvent *e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DialogsInner::checkReorderPinnedStart(QPoint localPosition) {
|
||||||
|
if (_pressed != nullptr && !_dragging && _state == DefaultState) {
|
||||||
|
if (qAbs(localPosition.y() - _dragStart.y()) >= convertScale(kStartReorderThreshold)) {
|
||||||
|
_dragging = _pressed;
|
||||||
|
if (updateReorderIndexGetCount() < 2) {
|
||||||
|
_dragging = nullptr;
|
||||||
|
} else {
|
||||||
|
_pinnedOrder = App::histories().getPinnedOrder();
|
||||||
|
_pinnedRows[_draggingIndex].yadd = anim::value(0, localPosition.y() - _dragStart.y());
|
||||||
|
_pinnedRows[_draggingIndex].animStartTime = getms();
|
||||||
|
_a_pinnedShifting.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int DialogsInner::shownPinnedCount() const {
|
||||||
|
auto result = 0;
|
||||||
|
for_const (auto row, *shownDialogs()) {
|
||||||
|
if (!row->history()->isPinnedDialog()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DialogsInner::countPinnedIndex(Dialogs::Row *ofRow) {
|
||||||
|
if (!ofRow || !ofRow->history()->isPinnedDialog()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
auto result = 0;
|
||||||
|
for_const (auto row, *shownDialogs()) {
|
||||||
|
if (!row->history()->isPinnedDialog()) {
|
||||||
|
break;
|
||||||
|
} else if (row == ofRow) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
++result;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogsInner::savePinnedOrder() {
|
||||||
|
auto newOrder = App::histories().getPinnedOrder();
|
||||||
|
if (newOrder.size() != _pinnedOrder.size()) {
|
||||||
|
return; // Something has changed in the set of pinned chats.
|
||||||
|
}
|
||||||
|
|
||||||
|
auto peers = QVector<MTPInputPeer>();
|
||||||
|
peers.reserve(newOrder.size());
|
||||||
|
for_const (auto history, newOrder) {
|
||||||
|
if (_pinnedOrder.indexOf(history) < 0) {
|
||||||
|
return; // Something has changed in the set of pinned chats.
|
||||||
|
}
|
||||||
|
peers.push_back(history->peer->input);
|
||||||
|
}
|
||||||
|
auto flags = MTPmessages_ReorderPinnedDialogs::Flag::f_force;
|
||||||
|
MTP::send(MTPmessages_ReorderPinnedDialogs(MTP_flags(qFlags(flags)), MTP_vector(peers)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogsInner::finishReorderPinned() {
|
||||||
|
auto wasDragging = (_dragging != nullptr);
|
||||||
|
if (wasDragging) {
|
||||||
|
savePinnedOrder();
|
||||||
|
_dragging = nullptr;
|
||||||
|
}
|
||||||
|
_draggingIndex = -1;
|
||||||
|
if (!_a_pinnedShifting.animating()) {
|
||||||
|
_pinnedRows.clear();
|
||||||
|
_aboveIndex = -1;
|
||||||
|
}
|
||||||
|
if (wasDragging) {
|
||||||
|
emit draggingScrollDelta(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogsInner::stopReorderPinned() {
|
||||||
|
_a_pinnedShifting.stop();
|
||||||
|
finishReorderPinned();
|
||||||
|
}
|
||||||
|
|
||||||
|
int DialogsInner::updateReorderIndexGetCount() {
|
||||||
|
auto index = countPinnedIndex(_dragging);
|
||||||
|
if (index < 0) {
|
||||||
|
finishReorderPinned();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto count = shownPinnedCount();
|
||||||
|
t_assert(index < count);
|
||||||
|
if (count < 2) {
|
||||||
|
stopReorderPinned();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_draggingIndex = index;
|
||||||
|
_aboveIndex = _draggingIndex;
|
||||||
|
while (count > _pinnedRows.size()) {
|
||||||
|
_pinnedRows.push_back(PinnedRow());
|
||||||
|
}
|
||||||
|
while (count < _pinnedRows.size()) {
|
||||||
|
_pinnedRows.pop_back();
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DialogsInner::updateReorderPinned(QPoint localPosition) {
|
||||||
|
checkReorderPinnedStart(localPosition);
|
||||||
|
auto pinnedCount = updateReorderIndexGetCount();
|
||||||
|
if (pinnedCount < 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto yaddWas = _pinnedRows[_draggingIndex].yadd.current();
|
||||||
|
auto shift = 0;
|
||||||
|
auto ms = getms();
|
||||||
|
auto rowHeight = st::dialogsRowHeight;
|
||||||
|
if (_dragStart.y() > localPosition.y() && _draggingIndex > 0) {
|
||||||
|
shift = -floorclamp(_dragStart.y() - localPosition.y() + (rowHeight / 2), rowHeight, 0, _draggingIndex);
|
||||||
|
for (auto from = _draggingIndex, to = _draggingIndex + shift; from > to; --from) {
|
||||||
|
shownDialogs()->movePinned(_dragging, -1);
|
||||||
|
std_::swap_moveable(_pinnedRows[from], _pinnedRows[from - 1]);
|
||||||
|
_pinnedRows[from].yadd = anim::value(_pinnedRows[from].yadd.current() - rowHeight, 0);
|
||||||
|
_pinnedRows[from].animStartTime = ms;
|
||||||
|
}
|
||||||
|
} else if (_dragStart.y() < localPosition.y() && _draggingIndex + 1 < pinnedCount) {
|
||||||
|
shift = floorclamp(localPosition.y() - _dragStart.y() + (rowHeight / 2), rowHeight, 0, pinnedCount - _draggingIndex - 1);
|
||||||
|
for (auto from = _draggingIndex, to = _draggingIndex + shift; from < to; ++from) {
|
||||||
|
shownDialogs()->movePinned(_dragging, 1);
|
||||||
|
std_::swap_moveable(_pinnedRows[from], _pinnedRows[from + 1]);
|
||||||
|
_pinnedRows[from].yadd = anim::value(_pinnedRows[from].yadd.current() + rowHeight, 0);
|
||||||
|
_pinnedRows[from].animStartTime = ms;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (shift) {
|
||||||
|
_draggingIndex += shift;
|
||||||
|
_aboveIndex = _draggingIndex;
|
||||||
|
_dragStart.setY(_dragStart.y() + shift * rowHeight);
|
||||||
|
if (!_a_pinnedShifting.animating()) {
|
||||||
|
_a_pinnedShifting.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_aboveTopShift = qCeil(_pinnedRows[_aboveIndex].yadd.current());
|
||||||
|
_pinnedRows[_draggingIndex].yadd = anim::value(yaddWas - shift * rowHeight, localPosition.y() - _dragStart.y());
|
||||||
|
if (!_pinnedRows[_draggingIndex].animStartTime) {
|
||||||
|
_pinnedRows[_draggingIndex].yadd.finish();
|
||||||
|
}
|
||||||
|
_a_pinnedShifting.step(ms, true);
|
||||||
|
|
||||||
|
auto countDraggingScrollDelta = [this, localPosition] {
|
||||||
|
if (localPosition.y() < _visibleTop) {
|
||||||
|
return localPosition.y() - _visibleTop;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
emit draggingScrollDelta(countDraggingScrollDelta());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogsInner::step_pinnedShifting(TimeMs ms, bool timer) {
|
||||||
|
auto animating = false;
|
||||||
|
auto updateMin = -1;
|
||||||
|
auto updateMax = 0;
|
||||||
|
for (auto i = 0, l = _pinnedRows.size(); i != l; ++i) {
|
||||||
|
auto start = _pinnedRows[i].animStartTime;
|
||||||
|
if (start) {
|
||||||
|
if (updateMin < 0) updateMin = i;
|
||||||
|
updateMax = i;
|
||||||
|
if (start + st::stickersRowDuration > ms && ms >= start) {
|
||||||
|
_pinnedRows[i].yadd.update(float64(ms - start) / st::stickersRowDuration, anim::sineInOut);
|
||||||
|
animating = true;
|
||||||
|
} else {
|
||||||
|
_pinnedRows[i].yadd.finish();
|
||||||
|
_pinnedRows[i].animStartTime = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (timer) {
|
||||||
|
updateReorderIndexGetCount();
|
||||||
|
if (_draggingIndex >= 0) {
|
||||||
|
if (updateMin < 0 || updateMin > _draggingIndex) {
|
||||||
|
updateMin = _draggingIndex;
|
||||||
|
}
|
||||||
|
if (updateMax < _draggingIndex) updateMax = _draggingIndex;
|
||||||
|
}
|
||||||
|
if (updateMin >= 0) {
|
||||||
|
auto top = _dialogsImportant ? st::dialogsImportantBarHeight : 0;
|
||||||
|
auto updateFrom = top + st::dialogsRowHeight * (updateMin - 1);
|
||||||
|
auto updateHeight = st::dialogsRowHeight * (updateMax - updateMin + 3);
|
||||||
|
if (_aboveIndex >= 0 && _aboveIndex < _pinnedRows.size()) {
|
||||||
|
// Always include currently dragged chat in its current and old positions.
|
||||||
|
auto aboveRowBottom = top + (_aboveIndex + 1) * st::dialogsRowHeight;
|
||||||
|
auto aboveTopShift = qCeil(_pinnedRows[_aboveIndex].yadd.current());
|
||||||
|
accumulate_max(updateHeight, (aboveRowBottom - updateFrom) + _aboveTopShift);
|
||||||
|
accumulate_max(updateHeight, (aboveRowBottom - updateFrom) + aboveTopShift);
|
||||||
|
_aboveTopShift = aboveTopShift;
|
||||||
|
}
|
||||||
|
update(0, updateFrom, getFullWidth(), updateHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!animating) {
|
||||||
|
_aboveIndex = _draggingIndex;
|
||||||
|
_a_pinnedShifting.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DialogsInner::mouseReleaseEvent(QMouseEvent *e) {
|
void DialogsInner::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
mousePressReleased(e->button());
|
mousePressReleased(e->button());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsInner::mousePressReleased(Qt::MouseButton button) {
|
void DialogsInner::mousePressReleased(Qt::MouseButton button) {
|
||||||
|
auto wasDragging = (_dragging != nullptr);
|
||||||
|
if (wasDragging) {
|
||||||
|
updateReorderIndexGetCount();
|
||||||
|
if (_draggingIndex >= 0) {
|
||||||
|
auto localPosition = mapFromGlobal(QCursor::pos());
|
||||||
|
_pinnedRows[_draggingIndex].yadd.start(0.);
|
||||||
|
_pinnedRows[_draggingIndex].animStartTime = getms();
|
||||||
|
if (!_a_pinnedShifting.animating()) {
|
||||||
|
_a_pinnedShifting.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finishReorderPinned();
|
||||||
|
}
|
||||||
|
|
||||||
auto importantSwitchPressed = _importantSwitchPressed;
|
auto importantSwitchPressed = _importantSwitchPressed;
|
||||||
setImportantSwitchPressed(false);
|
setImportantSwitchPressed(false);
|
||||||
auto pressed = _pressed;
|
auto pressed = _pressed;
|
||||||
|
@ -542,8 +832,11 @@ void DialogsInner::mousePressReleased(Qt::MouseButton button) {
|
||||||
setPeerSearchPressed(-1);
|
setPeerSearchPressed(-1);
|
||||||
auto searchedPressed = _searchedPressed;
|
auto searchedPressed = _searchedPressed;
|
||||||
setSearchedPressed(-1);
|
setSearchedPressed(-1);
|
||||||
|
if (wasDragging) {
|
||||||
|
updateSelected();
|
||||||
|
}
|
||||||
updateSelectedRow();
|
updateSelectedRow();
|
||||||
if (button == Qt::LeftButton) {
|
if (!wasDragging && button == Qt::LeftButton) {
|
||||||
if (importantSwitchPressed && importantSwitchPressed == _importantSwitchSelected) {
|
if (importantSwitchPressed && importantSwitchPressed == _importantSwitchSelected) {
|
||||||
choosePeer();
|
choosePeer();
|
||||||
} else if (pressed && pressed == _selected) {
|
} else if (pressed && pressed == _selected) {
|
||||||
|
@ -633,6 +926,13 @@ void DialogsInner::onDialogRowReplaced(Dialogs::Row *oldRow, Dialogs::Row *newRo
|
||||||
if (_pressed == oldRow) {
|
if (_pressed == oldRow) {
|
||||||
setPressed(newRow);
|
setPressed(newRow);
|
||||||
}
|
}
|
||||||
|
if (_dragging == oldRow) {
|
||||||
|
if (newRow) {
|
||||||
|
_dragging = newRow;
|
||||||
|
} else {
|
||||||
|
stopReorderPinned();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsInner::createDialog(History *history) {
|
void DialogsInner::createDialog(History *history) {
|
||||||
|
@ -711,7 +1011,12 @@ void DialogsInner::removeDialog(History *history) {
|
||||||
void DialogsInner::dlgUpdated(Dialogs::Mode list, Dialogs::Row *row) {
|
void DialogsInner::dlgUpdated(Dialogs::Mode list, Dialogs::Row *row) {
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
if (Global::DialogsMode() == list) {
|
if (Global::DialogsMode() == list) {
|
||||||
update(0, dialogsOffset() + row->pos() * st::dialogsRowHeight, getFullWidth(), st::dialogsRowHeight);
|
auto position = row->pos();
|
||||||
|
auto top = dialogsOffset();
|
||||||
|
if (position >= 0 && position < _pinnedRows.size()) {
|
||||||
|
top += qRound(_pinnedRows[position].yadd.current());
|
||||||
|
}
|
||||||
|
update(0, top + position * st::dialogsRowHeight, getFullWidth(), st::dialogsRowHeight);
|
||||||
}
|
}
|
||||||
} else if (_state == FilteredState || _state == SearchedState) {
|
} else if (_state == FilteredState || _state == SearchedState) {
|
||||||
if (list == Dialogs::Mode::All) {
|
if (list == Dialogs::Mode::All) {
|
||||||
|
@ -736,7 +1041,12 @@ void DialogsInner::updateDialogRow(PeerData *peer, MsgId msgId, QRect updateRect
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
if (sections & UpdateRowSection::Default) {
|
if (sections & UpdateRowSection::Default) {
|
||||||
if (auto row = shownDialogs()->getRow(peer->id)) {
|
if (auto row = shownDialogs()->getRow(peer->id)) {
|
||||||
updateRow(dialogsOffset() + row->pos() * st::dialogsRowHeight);
|
auto position = row->pos();
|
||||||
|
auto top = dialogsOffset();
|
||||||
|
if (position >= 0 && position < _pinnedRows.size()) {
|
||||||
|
top += qRound(_pinnedRows[position].yadd.current());
|
||||||
|
}
|
||||||
|
updateRow(top + position * st::dialogsRowHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (_state == FilteredState || _state == SearchedState) {
|
} else if (_state == FilteredState || _state == SearchedState) {
|
||||||
|
@ -782,9 +1092,14 @@ void DialogsInner::enterEvent(QEvent *e) {
|
||||||
void DialogsInner::updateSelectedRow(PeerData *peer) {
|
void DialogsInner::updateSelectedRow(PeerData *peer) {
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
if (peer) {
|
if (peer) {
|
||||||
if (History *h = App::historyLoaded(peer->id)) {
|
if (auto h = App::historyLoaded(peer->id)) {
|
||||||
if (h->inChatList(Global::DialogsMode())) {
|
if (h->inChatList(Global::DialogsMode())) {
|
||||||
update(0, dialogsOffset() + h->posInChatList(Global::DialogsMode()) * st::dialogsRowHeight, getFullWidth(), st::dialogsRowHeight);
|
auto position = h->posInChatList(Global::DialogsMode());
|
||||||
|
auto top = dialogsOffset();
|
||||||
|
if (position >= 0 && position < _pinnedRows.size()) {
|
||||||
|
top += qRound(_pinnedRows[position].yadd.current());
|
||||||
|
}
|
||||||
|
update(0, top + position * st::dialogsRowHeight, getFullWidth(), st::dialogsRowHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (_selected) {
|
} else if (_selected) {
|
||||||
|
@ -810,7 +1125,6 @@ void DialogsInner::updateSelectedRow(PeerData *peer) {
|
||||||
update(0, searchedOffset() + _searchedSelected * st::dialogsRowHeight, getFullWidth(), st::dialogsRowHeight);
|
update(0, searchedOffset() + _searchedSelected * st::dialogsRowHeight, getFullWidth(), st::dialogsRowHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsInner::leaveEvent(QEvent *e) {
|
void DialogsInner::leaveEvent(QEvent *e) {
|
||||||
|
@ -1081,9 +1395,10 @@ PeerData *DialogsInner::updateFromParentDrag(QPoint globalPos) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsInner::setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
void DialogsInner::setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
||||||
_visibleAreaHeight = visibleBottom - visibleTop;
|
_visibleTop = visibleTop;
|
||||||
loadPeerPhotos(visibleTop);
|
_visibleBottom = visibleBottom;
|
||||||
if (visibleTop + PreloadHeightsCount * (visibleBottom - visibleTop) >= height()) {
|
loadPeerPhotos();
|
||||||
|
if (_visibleTop + PreloadHeightsCount * (_visibleBottom - _visibleTop) >= height()) {
|
||||||
if (_loadMoreCallback) {
|
if (_loadMoreCallback) {
|
||||||
_loadMoreCallback();
|
_loadMoreCallback();
|
||||||
}
|
}
|
||||||
|
@ -1347,8 +1662,9 @@ void DialogsInner::refresh(bool toTop) {
|
||||||
}
|
}
|
||||||
setHeight(h);
|
setHeight(h);
|
||||||
if (toTop) {
|
if (toTop) {
|
||||||
|
stopReorderPinned();
|
||||||
emit mustScrollTo(0, 0);
|
emit mustScrollTo(0, 0);
|
||||||
loadPeerPhotos(0);
|
loadPeerPhotos();
|
||||||
}
|
}
|
||||||
Global::RefDialogsListDisplayForced().set(_searchInPeer || !_filter.isEmpty(), true);
|
Global::RefDialogsListDisplayForced().set(_searchInPeer || !_filter.isEmpty(), true);
|
||||||
update();
|
update();
|
||||||
|
@ -1563,11 +1879,11 @@ void DialogsInner::selectSkipPage(int32 pixels, int32 direction) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsInner::loadPeerPhotos(int visibleTop) {
|
void DialogsInner::loadPeerPhotos() {
|
||||||
if (!parentWidget()) return;
|
if (!parentWidget()) return;
|
||||||
|
|
||||||
auto yFrom = visibleTop;
|
auto yFrom = _visibleTop;
|
||||||
auto yTo = visibleTop + _visibleAreaHeight * (PreloadHeightsCount + 1);
|
auto yTo = _visibleTop + (_visibleBottom - _visibleTop) * (PreloadHeightsCount + 1);
|
||||||
MTP::clearLoaderPriorities();
|
MTP::clearLoaderPriorities();
|
||||||
if (_state == DefaultState) {
|
if (_state == DefaultState) {
|
||||||
auto otherStart = shownDialogs()->size() * st::dialogsRowHeight;
|
auto otherStart = shownDialogs()->size() * st::dialogsRowHeight;
|
||||||
|
@ -1945,6 +2261,7 @@ DialogsWidget::DialogsWidget(QWidget *parent) : TWidget(parent)
|
||||||
, _lockUnlock(this, st::dialogsLock)
|
, _lockUnlock(this, st::dialogsLock)
|
||||||
, _scroll(this, st::dialogsScroll) {
|
, _scroll(this, st::dialogsScroll) {
|
||||||
_inner = _scroll->setOwnedWidget(object_ptr<DialogsInner>(this, parent));
|
_inner = _scroll->setOwnedWidget(object_ptr<DialogsInner>(this, parent));
|
||||||
|
connect(_inner, SIGNAL(draggingScrollDelta(int)), this, SLOT(onDraggingScrollDelta(int)));
|
||||||
connect(_inner, SIGNAL(mustScrollTo(int,int)), _scroll, SLOT(scrollToY(int,int)));
|
connect(_inner, SIGNAL(mustScrollTo(int,int)), _scroll, SLOT(scrollToY(int,int)));
|
||||||
connect(_inner, SIGNAL(dialogMoved(int,int)), this, SLOT(onDialogMoved(int,int)));
|
connect(_inner, SIGNAL(dialogMoved(int,int)), this, SLOT(onDialogMoved(int,int)));
|
||||||
connect(_inner, SIGNAL(searchMessages()), this, SLOT(onNeedSearchMessages()));
|
connect(_inner, SIGNAL(searchMessages()), this, SLOT(onNeedSearchMessages()));
|
||||||
|
@ -2262,6 +2579,25 @@ bool DialogsWidget::dialogsFailed(const RPCError &error, mtpRequestId requestId)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DialogsWidget::onDraggingScrollDelta(int delta) {
|
||||||
|
_draggingScrollDelta = _scroll ? delta : 0;
|
||||||
|
if (_draggingScrollDelta) {
|
||||||
|
if (!_draggingScrollTimer) {
|
||||||
|
_draggingScrollTimer.create(this);
|
||||||
|
_draggingScrollTimer->setSingleShot(false);
|
||||||
|
connect(_draggingScrollTimer, SIGNAL(timeout()), this, SLOT(onDraggingScrollTimer()));
|
||||||
|
}
|
||||||
|
_draggingScrollTimer->start(15);
|
||||||
|
} else {
|
||||||
|
_draggingScrollTimer.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogsWidget::onDraggingScrollTimer() {
|
||||||
|
auto delta = (_draggingScrollDelta > 0) ? qMin(_draggingScrollDelta * 3 / 20 + 1, int32(MaxScrollSpeed)) : qMax(_draggingScrollDelta * 3 / 20 - 1, -int32(MaxScrollSpeed));
|
||||||
|
_scroll->scrollToY(_scroll->scrollTop() + delta);
|
||||||
|
}
|
||||||
|
|
||||||
bool DialogsWidget::onSearchMessages(bool searchCache) {
|
bool DialogsWidget::onSearchMessages(bool searchCache) {
|
||||||
QString q = _filter->getLastText().trimmed();
|
QString q = _filter->getLastText().trimmed();
|
||||||
if (q.isEmpty()) {
|
if (q.isEmpty()) {
|
||||||
|
|
|
@ -131,6 +131,7 @@ public slots:
|
||||||
void onMenuDestroyed(QObject*);
|
void onMenuDestroyed(QObject*);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
void draggingScrollDelta(int delta);
|
||||||
void mustScrollTo(int scrollToTop, int scrollToBottom);
|
void mustScrollTo(int scrollToTop, int scrollToBottom);
|
||||||
void dialogMoved(int movedFrom, int movedTo);
|
void dialogMoved(int movedFrom, int movedTo);
|
||||||
void searchMessages();
|
void searchMessages();
|
||||||
|
@ -165,7 +166,7 @@ private:
|
||||||
updateSelected(mapFromGlobal(QCursor::pos()));
|
updateSelected(mapFromGlobal(QCursor::pos()));
|
||||||
}
|
}
|
||||||
void updateSelected(QPoint localPos);
|
void updateSelected(QPoint localPos);
|
||||||
void loadPeerPhotos(int visibleTop);
|
void loadPeerPhotos();
|
||||||
void setImportantSwitchPressed(bool pressed);
|
void setImportantSwitchPressed(bool pressed);
|
||||||
void setPressed(Dialogs::Row *pressed);
|
void setPressed(Dialogs::Row *pressed);
|
||||||
void setHashtagPressed(int pressed);
|
void setHashtagPressed(int pressed);
|
||||||
|
@ -196,9 +197,9 @@ private:
|
||||||
int peerSearchOffset() const;
|
int peerSearchOffset() const;
|
||||||
int searchedOffset() const;
|
int searchedOffset() const;
|
||||||
|
|
||||||
void paintDialog(QPainter &p, Dialogs::Row *dialog);
|
void paintDialog(Painter &p, Dialogs::Row *row, int fullWidth, PeerData *active, PeerData *selected, bool onlyBackground, TimeMs ms);
|
||||||
void paintPeerSearchResult(Painter &p, const PeerSearchResult *result, int32 w, bool active, bool selected, bool onlyBackground, TimeMs ms) const;
|
void paintPeerSearchResult(Painter &p, const PeerSearchResult *result, int fullWidth, bool active, bool selected, bool onlyBackground, TimeMs ms) const;
|
||||||
void paintSearchInPeer(Painter &p, int32 w, bool onlyBackground) const;
|
void paintSearchInPeer(Painter &p, int fullWidth, bool onlyBackground) const;
|
||||||
|
|
||||||
void clearSelection();
|
void clearSelection();
|
||||||
void clearSearchResults(bool clearPeerSearchResults = true);
|
void clearSearchResults(bool clearPeerSearchResults = true);
|
||||||
|
@ -208,6 +209,16 @@ private:
|
||||||
return (Global::DialogsMode() == Dialogs::Mode::Important) ? _dialogsImportant.get() : _dialogs.get();
|
return (Global::DialogsMode() == Dialogs::Mode::Important) ? _dialogsImportant.get() : _dialogs.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void checkReorderPinnedStart(QPoint localPosition);
|
||||||
|
int shownPinnedCount() const;
|
||||||
|
int updateReorderIndexGetCount();
|
||||||
|
bool updateReorderPinned(QPoint localPosition);
|
||||||
|
void finishReorderPinned();
|
||||||
|
void stopReorderPinned();
|
||||||
|
int countPinnedIndex(Dialogs::Row *ofRow);
|
||||||
|
void savePinnedOrder();
|
||||||
|
void step_pinnedShifting(TimeMs ms, bool timer);
|
||||||
|
|
||||||
DialogsList _dialogs;
|
DialogsList _dialogs;
|
||||||
DialogsList _dialogsImportant;
|
DialogsList _dialogsImportant;
|
||||||
|
|
||||||
|
@ -223,7 +234,23 @@ private:
|
||||||
Dialogs::Row *_selected = nullptr;
|
Dialogs::Row *_selected = nullptr;
|
||||||
Dialogs::Row *_pressed = nullptr;
|
Dialogs::Row *_pressed = nullptr;
|
||||||
|
|
||||||
int _visibleAreaHeight = 0;
|
Dialogs::Row *_dragging = nullptr;
|
||||||
|
int _draggingIndex = -1;
|
||||||
|
int _aboveIndex = -1;
|
||||||
|
QPoint _dragStart;
|
||||||
|
struct PinnedRow {
|
||||||
|
anim::value yadd;
|
||||||
|
TimeMs animStartTime = 0;
|
||||||
|
};
|
||||||
|
std_::vector_of_moveable<PinnedRow> _pinnedRows;
|
||||||
|
BasicAnimation _a_pinnedShifting;
|
||||||
|
QList<History*> _pinnedOrder;
|
||||||
|
|
||||||
|
// Remember the last currently dragged row top shift for updating area.
|
||||||
|
int _aboveTopShift = -1;
|
||||||
|
|
||||||
|
int _visibleTop = 0;
|
||||||
|
int _visibleBottom = 0;
|
||||||
QString _filter, _hashtagFilter;
|
QString _filter, _hashtagFilter;
|
||||||
|
|
||||||
HashtagResults _hashtagResults;
|
HashtagResults _hashtagResults;
|
||||||
|
@ -322,6 +349,8 @@ signals:
|
||||||
void cancelled();
|
void cancelled();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
void onDraggingScrollDelta(int delta);
|
||||||
|
|
||||||
void onCancel();
|
void onCancel();
|
||||||
void onListScroll();
|
void onListScroll();
|
||||||
void activate();
|
void activate();
|
||||||
|
@ -338,8 +367,10 @@ public slots:
|
||||||
|
|
||||||
void onChooseByDrag();
|
void onChooseByDrag();
|
||||||
|
|
||||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void onDraggingScrollTimer();
|
||||||
|
|
||||||
|
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||||
void onCheckUpdateStatus();
|
void onCheckUpdateStatus();
|
||||||
#endif // TDESKTOP_DISABLE_AUTOUPDATE
|
#endif // TDESKTOP_DISABLE_AUTOUPDATE
|
||||||
|
|
||||||
|
@ -427,4 +458,7 @@ private:
|
||||||
|
|
||||||
QPixmap _widthAnimationCache;
|
QPixmap _widthAnimationCache;
|
||||||
|
|
||||||
|
object_ptr<QTimer> _draggingScrollTimer = { nullptr };
|
||||||
|
int _draggingScrollDelta = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -754,6 +754,19 @@ int Histories::pinnedCount() const {
|
||||||
return _pinnedDialogs.size();
|
return _pinnedDialogs.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<History*> Histories::getPinnedOrder() const {
|
||||||
|
QMap<int, History*> sorter;
|
||||||
|
for_const (auto pinned, _pinnedDialogs) {
|
||||||
|
sorter.insert(pinned->getPinnedIndex(), pinned);
|
||||||
|
}
|
||||||
|
QList<History*> result;
|
||||||
|
for (auto i = sorter.cend(), e = sorter.cbegin(); i != e;) {
|
||||||
|
--i;
|
||||||
|
result.push_back(i.value());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction, bool detachExistingItem) {
|
HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction, bool detachExistingItem) {
|
||||||
auto msgId = MsgId(0);
|
auto msgId = MsgId(0);
|
||||||
switch (msg.type()) {
|
switch (msg.type()) {
|
||||||
|
@ -2129,7 +2142,10 @@ void History::updateChatListEntry() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void History::setPinnedDialog(bool isPinned) {
|
void History::setPinnedDialog(bool isPinned) {
|
||||||
auto pinnedIndex = isPinned ? (++GlobalPinnedIndex) : 0;
|
setPinnedIndex(isPinned ? (++GlobalPinnedIndex) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void History::setPinnedIndex(int pinnedIndex) {
|
||||||
if (_pinnedIndex != pinnedIndex) {
|
if (_pinnedIndex != pinnedIndex) {
|
||||||
auto wasPinned = isPinnedDialog();
|
auto wasPinned = isPinnedDialog();
|
||||||
_pinnedIndex = pinnedIndex;
|
_pinnedIndex = pinnedIndex;
|
||||||
|
|
|
@ -82,6 +82,7 @@ public:
|
||||||
void setIsPinned(History *history, bool isPinned);
|
void setIsPinned(History *history, bool isPinned);
|
||||||
void clearPinned();
|
void clearPinned();
|
||||||
int pinnedCount() const;
|
int pinnedCount() const;
|
||||||
|
QList<History*> getPinnedOrder() const;
|
||||||
|
|
||||||
struct SendActionAnimationUpdate {
|
struct SendActionAnimationUpdate {
|
||||||
History *history;
|
History *history;
|
||||||
|
@ -288,6 +289,7 @@ public:
|
||||||
return (_pinnedIndex > 0);
|
return (_pinnedIndex > 0);
|
||||||
}
|
}
|
||||||
void setPinnedDialog(bool isPinned);
|
void setPinnedDialog(bool isPinned);
|
||||||
|
void setPinnedIndex(int newPinnedIndex);
|
||||||
int getPinnedIndex() const {
|
int getPinnedIndex() const {
|
||||||
return _pinnedIndex;
|
return _pinnedIndex;
|
||||||
}
|
}
|
||||||
|
|
|
@ -656,12 +656,12 @@ void MainWidget::hiderLayer(object_ptr<HistoryHider> h) {
|
||||||
}
|
}
|
||||||
if (_dialogs->isHidden()) {
|
if (_dialogs->isHidden()) {
|
||||||
_dialogs->show();
|
_dialogs->show();
|
||||||
resizeEvent(0);
|
updateControlsGeometry();
|
||||||
_dialogs->showAnimated(Window::SlideDirection::FromLeft, animationParams);
|
_dialogs->showAnimated(Window::SlideDirection::FromLeft, animationParams);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_hider->show();
|
_hider->show();
|
||||||
resizeEvent(0);
|
updateControlsGeometry();
|
||||||
_dialogs->activate();
|
_dialogs->activate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2293,7 +2293,7 @@ void MainWidget::ui_showPeerHistory(quint64 peerId, qint32 showAtMsgId, Ui::Show
|
||||||
} else {
|
} else {
|
||||||
if (noPeer) {
|
if (noPeer) {
|
||||||
_topBar->hide();
|
_topBar->hide();
|
||||||
resizeEvent(0);
|
updateControlsGeometry();
|
||||||
} else if (wasActivePeer != activePeer()) {
|
} else if (wasActivePeer != activePeer()) {
|
||||||
if (activePeer()->isChannel()) {
|
if (activePeer()->isChannel()) {
|
||||||
activePeer()->asChannel()->ptsWaitingForShortPoll(WaitForChannelGetDifference);
|
activePeer()->asChannel()->ptsWaitingForShortPoll(WaitForChannelGetDifference);
|
||||||
|
@ -2421,6 +2421,8 @@ void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool
|
||||||
if (!back) {
|
if (!back) {
|
||||||
saveSectionInStack();
|
saveSectionInStack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setFocus(); // otherwise dialogs widget could be focused.
|
||||||
if (_overview) {
|
if (_overview) {
|
||||||
_overview->hide();
|
_overview->hide();
|
||||||
_overview->clear();
|
_overview->clear();
|
||||||
|
@ -2435,7 +2437,7 @@ void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool
|
||||||
_overview.create(this, peer, type);
|
_overview.create(this, peer, type);
|
||||||
_mediaTypeMask = 0;
|
_mediaTypeMask = 0;
|
||||||
_topBar->show();
|
_topBar->show();
|
||||||
resizeEvent(nullptr);
|
updateControlsGeometry();
|
||||||
|
|
||||||
// Send a fake update.
|
// Send a fake update.
|
||||||
Notify::PeerUpdate update(peer);
|
Notify::PeerUpdate update(peer);
|
||||||
|
@ -2574,6 +2576,8 @@ void MainWidget::showNewWideSection(const Window::SectionMemento *memento, bool
|
||||||
if (saveInStack) {
|
if (saveInStack) {
|
||||||
saveSectionInStack();
|
saveSectionInStack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setFocus(); // otherwise dialogs widget could be focused.
|
||||||
if (_overview) {
|
if (_overview) {
|
||||||
_overview->hide();
|
_overview->hide();
|
||||||
_overview->clear();
|
_overview->clear();
|
||||||
|
@ -2588,7 +2592,7 @@ void MainWidget::showNewWideSection(const Window::SectionMemento *memento, bool
|
||||||
}
|
}
|
||||||
_wideSection = std_::move(newWideSection);
|
_wideSection = std_::move(newWideSection);
|
||||||
_topBar->hide();
|
_topBar->hide();
|
||||||
resizeEvent(0);
|
updateControlsGeometry();
|
||||||
_history->finishAnimation();
|
_history->finishAnimation();
|
||||||
_history->showHistory(0, 0);
|
_history->showHistory(0, 0);
|
||||||
_history->hide();
|
_history->hide();
|
||||||
|
@ -2924,7 +2928,7 @@ void MainWidget::showAll() {
|
||||||
_player->show();
|
_player->show();
|
||||||
_playerHeight = _player->contentHeight();
|
_playerHeight = _player->contentHeight();
|
||||||
}
|
}
|
||||||
resizeEvent(0);
|
updateControlsGeometry();
|
||||||
|
|
||||||
App::wnd()->checkHistoryActivation();
|
App::wnd()->checkHistoryActivation();
|
||||||
}
|
}
|
||||||
|
@ -3206,7 +3210,7 @@ void MainWidget::onHistoryShown(History *history, MsgId atMsgId) {
|
||||||
} else {
|
} else {
|
||||||
_topBar->hide();
|
_topBar->hide();
|
||||||
}
|
}
|
||||||
resizeEvent(0);
|
updateControlsGeometry();
|
||||||
if (_a_show.animating()) {
|
if (_a_show.animating()) {
|
||||||
_topBar->hide();
|
_topBar->hide();
|
||||||
}
|
}
|
||||||
|
|
|
@ -298,7 +298,7 @@ void InitAudio() {
|
||||||
PrepareNotifySound();
|
PrepareNotifySound();
|
||||||
|
|
||||||
auto loglevel = getenv("ALSOFT_LOGLEVEL");
|
auto loglevel = getenv("ALSOFT_LOGLEVEL");
|
||||||
LOG(("OpenAL Logging Level: ").arg(loglevel ? loglevel : "(not set)"));
|
LOG(("OpenAL Logging Level: %1").arg(loglevel ? loglevel : "(not set)"));
|
||||||
|
|
||||||
EnumeratePlaybackDevices();
|
EnumeratePlaybackDevices();
|
||||||
EnumerateCaptureDevices();
|
EnumerateCaptureDevices();
|
||||||
|
|
|
@ -76,7 +76,7 @@ FontData::FontData(int size, uint32 flags, int family, Font *other) : f(fontFami
|
||||||
ascent = m.ascent();
|
ascent = m.ascent();
|
||||||
descent = m.descent();
|
descent = m.descent();
|
||||||
spacew = width(QLatin1Char(' '));
|
spacew = width(QLatin1Char(' '));
|
||||||
elidew = width(QLatin1Char('.')) * 3;
|
elidew = width(qsl("..."));
|
||||||
}
|
}
|
||||||
|
|
||||||
Font FontData::bold(bool set) const {
|
Font FontData::bold(bool set) const {
|
||||||
|
|
|
@ -1555,7 +1555,7 @@ public:
|
||||||
line.length = lineLength;
|
line.length = lineLength;
|
||||||
eShapeLine(line);
|
eShapeLine(line);
|
||||||
|
|
||||||
int32 elideWidth = _f->width(_Elide);
|
auto elideWidth = _f->elidew;
|
||||||
_wLeft = _w - elideWidth - _elideRemoveFromEnd;
|
_wLeft = _w - elideWidth - _elideRemoveFromEnd;
|
||||||
|
|
||||||
int firstItem = engine.findItem(line.from), lastItem = engine.findItem(line.from + line.length - 1);
|
int firstItem = engine.findItem(line.from), lastItem = engine.findItem(line.from + line.length - 1);
|
||||||
|
@ -1654,15 +1654,21 @@ public:
|
||||||
|
|
||||||
// COPIED FROM qtextengine.cpp AND MODIFIED
|
// COPIED FROM qtextengine.cpp AND MODIFIED
|
||||||
void eShapeLine(const QScriptLine &line) {
|
void eShapeLine(const QScriptLine &line) {
|
||||||
int item = _e->findItem(line.from), end = _e->findItem(line.from + line.length - 1);
|
int item = _e->findItem(line.from);
|
||||||
if (item == -1)
|
if (item == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#ifdef OS_MAC_OLD
|
||||||
|
auto end = _e->findItem(line.from + line.length - 1);
|
||||||
|
#else // OS_MAC_OLD
|
||||||
|
auto end = _e->findItem(line.from + line.length - 1, item);
|
||||||
|
#endif // OS_MAC_OLD
|
||||||
|
|
||||||
int blockIndex = _lineStartBlock;
|
int blockIndex = _lineStartBlock;
|
||||||
ITextBlock *currentBlock = _t->_blocks[blockIndex];
|
ITextBlock *currentBlock = _t->_blocks[blockIndex];
|
||||||
ITextBlock *nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex] : 0;
|
ITextBlock *nextBlock = (++blockIndex < _blocksSize) ? _t->_blocks[blockIndex] : 0;
|
||||||
eSetFont(currentBlock);
|
eSetFont(currentBlock);
|
||||||
for (item = _e->findItem(line.from); item <= end; ++item) {
|
for (; item <= end; ++item) {
|
||||||
QScriptItem &si = _e->layoutData->items[item];
|
QScriptItem &si = _e->layoutData->items[item];
|
||||||
while (nextBlock && nextBlock->from() <= _localFrom + si.position) {
|
while (nextBlock && nextBlock->from() <= _localFrom + si.position) {
|
||||||
currentBlock = nextBlock;
|
currentBlock = nextBlock;
|
||||||
|
|
|
@ -335,8 +335,6 @@ TextBlock::TextBlock(const style::font &font, const QString &str, QFixed minResi
|
||||||
SignalHandlers::setCrashAnnotationRef("CrashString", &part);
|
SignalHandlers::setCrashAnnotationRef("CrashString", &part);
|
||||||
|
|
||||||
QStackTextEngine engine(part, blockFont->f);
|
QStackTextEngine engine(part, blockFont->f);
|
||||||
engine.itemize();
|
|
||||||
|
|
||||||
QTextLayout layout(&engine);
|
QTextLayout layout(&engine);
|
||||||
layout.beginLayout();
|
layout.beginLayout();
|
||||||
layout.createLine();
|
layout.createLine();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
AppVersion 1000003
|
AppVersion 1000004
|
||||||
AppVersionStrMajor 1.0
|
AppVersionStrMajor 1.0
|
||||||
AppVersionStrSmall 1.0.3
|
AppVersionStrSmall 1.0.4
|
||||||
AppVersionStr 1.0.3
|
AppVersionStr 1.0.4
|
||||||
AlphaChannel 1
|
AlphaChannel 1
|
||||||
BetaVersion 0
|
BetaVersion 0
|
||||||
|
|
Loading…
Reference in New Issue