Allow to resize third column.

This commit is contained in:
John Preston 2017-11-12 20:50:58 +04:00
parent bca9b3ca3f
commit fe9630bb20
11 changed files with 152 additions and 34 deletions

View File

@ -73,7 +73,11 @@ QByteArray AuthSessionData::serialize() const {
}
stream << qint32(_variables.thirdSectionInfoEnabled ? 1 : 0);
stream << qint32(_variables.smallDialogsList ? 1 : 0);
stream << qint32(snap(qRound(_variables.dialogsWidthRatio.current() * 1000000), 0, 1000000));
stream << qint32(snap(
qRound(_variables.dialogsWidthRatio.current() * 1000000),
0,
1000000));
stream << qint32(_variables.thirdColumnWidth.current());
}
return result;
}
@ -96,6 +100,7 @@ void AuthSessionData::constructFromSerialized(const QByteArray &serialized) {
qint32 thirdSectionInfoEnabled = 0;
qint32 smallDialogsList = 0;
float64 dialogsWidthRatio = _variables.dialogsWidthRatio.current();
int thirdColumnWidth = _variables.thirdColumnWidth.current();
stream >> selectorTab;
stream >> lastSeenWarningSeen;
if (!stream.atEnd()) {
@ -137,6 +142,9 @@ void AuthSessionData::constructFromSerialized(const QByteArray &serialized) {
qint32 value = 0;
stream >> value;
dialogsWidthRatio = snap(value / 1000000., 0., 1.);
stream >> value;
thirdColumnWidth = value;
}
if (stream.status() != QDataStream::Ok) {
LOG(("App Error: Bad data for AuthSessionData::constructFromSerialized()"));
@ -170,6 +178,7 @@ void AuthSessionData::constructFromSerialized(const QByteArray &serialized) {
_variables.thirdSectionInfoEnabled = thirdSectionInfoEnabled;
_variables.smallDialogsList = smallDialogsList;
_variables.dialogsWidthRatio = dialogsWidthRatio;
_variables.thirdColumnWidth = thirdColumnWidth;
if (_variables.thirdSectionInfoEnabled) {
_variables.tabbedSelectorSectionEnabled = false;
}

View File

@ -224,6 +224,15 @@ public:
rpl::producer<float64> dialogsWidthRatioChanges() const {
return _variables.dialogsWidthRatio.changes();
}
void setThirdColumnWidth(int width) {
_variables.thirdColumnWidth = width;
}
int thirdColumnWidth() const {
return _variables.thirdColumnWidth.current();
}
rpl::producer<int> thirdColumnWidthChanges() const {
return _variables.thirdColumnWidth.changes();
}
void markStickersUpdated() {
_stickersUpdated.fire({});
@ -321,6 +330,7 @@ private:
Variables();
static constexpr auto kDefaultDialogsWidthRatio = 5. / 14;
static constexpr auto kDefaultThirdColumnWidth = 0;
bool lastSeenWarningSeen = false;
ChatHelpers::SelectorTab selectorTab; // per-window
@ -332,7 +342,10 @@ private:
base::flat_set<PeerId> groupStickersSectionHidden;
bool thirdSectionInfoEnabled = true; // per-window
bool smallDialogsList = false; // per-window
rpl::variable<float64> dialogsWidthRatio = kDefaultDialogsWidthRatio; // per-window
rpl::variable<float64> dialogsWidthRatio
= kDefaultDialogsWidthRatio; // per-window
rpl::variable<int> thirdColumnWidth
= kDefaultThirdColumnWidth; // per-window
};
bool stickersUpdateNeeded(TimeMs lastUpdate, TimeMs now) const {

View File

@ -51,8 +51,6 @@ dialogsImportantBarHeight: 37px;
dialogsSkip: 8px;
dialogsWidthMin: 260px;
dialogsWidthMax: 540px;
dialogsWidthDuration: 120;
dialogsTextWidthMin: 150px;
dialogsScroll: ScrollArea(defaultScrollArea) {

View File

@ -25,6 +25,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "dialogs/dialogs_search_from_controllers.h"
#include "styles/style_dialogs.h"
#include "styles/style_chat_helpers.h"
#include "styles/style_window.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/popup_menu.h"
#include "data/data_drafts.h"
@ -959,7 +960,7 @@ void DialogsInner::setSearchedPressed(int pressed) {
void DialogsInner::resizeEvent(QResizeEvent *e) {
_addContactLnk->move((width() - _addContactLnk->width()) / 2, (st::noContactsHeight + st::noContactsFont->height) / 2);
auto widthForCancelButton = qMax(width() + otherWidth(), st::dialogsWidthMin);
auto widthForCancelButton = qMax(width() + otherWidth(), st::columnMinimalWidthLeft);
_cancelSearchInPeer->moveToLeft(widthForCancelButton - st::dialogsSearchInSkip - _cancelSearchInPeer->width(), st::searchedBarHeight + (st::dialogsSearchInHeight - st::dialogsCancelSearchInPeer.height) / 2);
_cancelSearchFromUser->moveToLeft(widthForCancelButton - st::dialogsSearchInSkip - _cancelSearchFromUser->width(), st::searchedBarHeight + st::dialogsSearchInHeight + st::lineWidth + (st::dialogsSearchInHeight - st::dialogsCancelSearchInPeer.height) / 2);
}

View File

@ -23,6 +23,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "dialogs/dialogs_inner_widget.h"
#include "dialogs/dialogs_search_from_controllers.h"
#include "styles/style_dialogs.h"
#include "styles/style_window.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/input_fields.h"
#include "ui/wrap/fade_wrap.h"
@ -64,7 +65,7 @@ private:
DialogsWidget::UpdateButton::UpdateButton(QWidget *parent) : RippleButton(parent, st::dialogsUpdateButton.ripple)
, _text(lang(lng_update_telegram).toUpper())
, _st(st::dialogsUpdateButton) {
resize(st::dialogsWidthMin, _st.height);
resize(st::columnMinimalWidthLeft, _st.height);
}
void DialogsWidget::UpdateButton::onStateChanged(State was, StateChangeSource source) {
@ -84,7 +85,7 @@ void DialogsWidget::UpdateButton::paintEvent(QPaintEvent *e) {
p.setRenderHint(QPainter::TextAntialiasing);
p.setPen(isOver() ? _st.overColor : _st.color);
if (width() >= st::dialogsWidthMin) {
if (width() >= st::columnMinimalWidthLeft) {
r.setTop(_st.textTop);
p.drawText(r, _text, style::al_top);
} else {
@ -221,10 +222,16 @@ void DialogsWidget::startWidthAnimation() {
return;
}
auto scrollGeometry = _scroll->geometry();
auto grabGeometry = QRect(scrollGeometry.x(), scrollGeometry.y(), st::dialogsWidthMin, scrollGeometry.height());
auto grabGeometry = QRect(
scrollGeometry.x(),
scrollGeometry.y(),
st::columnMinimalWidthLeft,
scrollGeometry.height());
_scroll->setGeometry(grabGeometry);
myEnsureResized(_scroll);
auto image = QImage(grabGeometry.size() * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
auto image = QImage(
grabGeometry.size() * cIntRetinaFactor(),
QImage::Format_ARGB32_Premultiplied);
image.setDevicePixelRatio(cRetinaFactor());
image.fill(Qt::transparent);
_scroll->render(&image, QPoint(0, 0), QRect(QPoint(0, 0), grabGeometry.size()), QWidget::DrawChildren | QWidget::IgnoreMask);
@ -974,10 +981,10 @@ void DialogsWidget::updateControlsGeometry() {
filterAreaTop += st::dialogsForwardHeight;
}
auto smallLayoutWidth = (st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPadding.x());
auto smallLayoutRatio = (width() < st::dialogsWidthMin) ? (st::dialogsWidthMin - width()) / float64(st::dialogsWidthMin - smallLayoutWidth) : 0.;
auto smallLayoutRatio = (width() < st::columnMinimalWidthLeft) ? (st::columnMinimalWidthLeft - width()) / float64(st::columnMinimalWidthLeft - smallLayoutWidth) : 0.;
auto filterLeft = st::dialogsFilterPadding.x() + _mainMenuToggle->width() + st::dialogsFilterPadding.x();
auto filterRight = (Global::LocalPasscode() ? (st::dialogsFilterPadding.x() + _lockUnlock->width()) : st::dialogsFilterSkip) + st::dialogsFilterPadding.x();
auto filterWidth = qMax(width(), st::dialogsWidthMin) - filterLeft - filterRight;
auto filterWidth = qMax(width(), st::columnMinimalWidthLeft) - filterLeft - filterRight;
auto filterAreaHeight = st::dialogsFilterPadding.y() + _mainMenuToggle->height() + st::dialogsFilterPadding.y();
auto filterTop = filterAreaTop + (filterAreaHeight - _filter->height()) / 2;
filterLeft = anim::interpolate(filterLeft, smallLayoutWidth, smallLayoutRatio);

View File

@ -36,6 +36,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "styles/style_dialogs.h"
#include "styles/style_widgets.h"
#include "styles/style_history.h"
#include "styles/style_window.h"
#include "window/notifications_manager.h"
#include "observer_peer.h"
#include "storage/storage_shared_media.h"
@ -46,7 +47,7 @@ constexpr auto kPinnedMessageTextLimit = 16;
inline void initTextOptions() {
_historySrvOptions.dir = _textNameOptions.dir = _textDlgOptions.dir = cLangDir();
_textDlgOptions.maxw = st::dialogsWidthMax * 2;
_textDlgOptions.maxw = st::columnMaximalWidthLeft * 2;
}
style::color fromNameFg(int index) {

View File

@ -21,6 +21,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "mainwidget.h"
#include <rpl/combine.h>
#include <rpl/merge.h>
#include <rpl/flatten_latest.h>
#include "data/data_photo.h"
#include "data/data_document.h"
@ -225,7 +226,8 @@ MainWidget::MainWidget(
not_null<Window::Controller*> controller)
: RpWidget(parent)
, _controller(controller)
, _dialogsWidth(st::dialogsWidthMin)
, _dialogsWidth(st::columnMinimalWidthLeft)
, _thirdColumnWidth(st::columnMinimalWidthThird)
, _sideShadow(this)
, _dialogs(this, _controller)
, _history(this, _controller)
@ -262,7 +264,11 @@ MainWidget::MainWidget(
subscribe(_controller->dialogsListDisplayForced(), [this](bool) {
updateDialogsWidthAnimated();
});
Auth().data().dialogsWidthRatioChanges()
rpl::merge(
Auth().data().dialogsWidthRatioChanges()
| rpl::map([] { return rpl::empty_value(); }),
Auth().data().thirdColumnWidthChanges()
| rpl::map([] { return rpl::empty_value(); }))
| rpl::start_with_next(
[this] { updateControlsGeometry(); },
lifetime());
@ -2773,7 +2779,11 @@ Window::SectionSlideParams MainWidget::prepareShowAnimation(
auto sectionTop = getMainSectionTop();
if (selectingPeer() && Adaptive::OneColumn()) {
result.oldContentCache = myGrab(this, QRect(0, sectionTop, _dialogsWidth, height() - sectionTop));
result.oldContentCache = myGrab(this, QRect(
0,
sectionTop,
_dialogsWidth,
height() - sectionTop));
} else if (_mainSection) {
result.oldContentCache = _mainSection->grabForShowAnimation(result);
} else {
@ -2785,13 +2795,21 @@ Window::SectionSlideParams MainWidget::prepareShowAnimation(
_history->grabStart();
}
if (Adaptive::OneColumn()) {
result.oldContentCache = myGrab(this, QRect(0, sectionTop, _dialogsWidth, height() - sectionTop));
result.oldContentCache = myGrab(this, QRect(
0,
sectionTop,
_dialogsWidth,
height() - sectionTop));
} else {
_sideShadow->hide();
if (_thirdShadow) {
_thirdShadow->hide();
}
result.oldContentCache = myGrab(this, QRect(_dialogsWidth, sectionTop, width() - _dialogsWidth, height() - sectionTop));
result.oldContentCache = myGrab(this, QRect(
_dialogsWidth,
sectionTop,
width() - _dialogsWidth,
height() - sectionTop));
_sideShadow->show();
if (_thirdShadow) {
_thirdShadow->show();
@ -3118,13 +3136,21 @@ QPixmap MainWidget::grabForShowAnimation(const Window::SectionSlideParams &param
auto sectionTop = getMainSectionTop();
if (Adaptive::OneColumn()) {
result = myGrab(this, QRect(0, sectionTop, _dialogsWidth, height() - sectionTop));
result = myGrab(this, QRect(
0,
sectionTop,
_dialogsWidth,
height() - sectionTop));
} else {
_sideShadow->hide();
if (_thirdShadow) {
_thirdShadow->hide();
}
result = myGrab(this, QRect(_dialogsWidth, sectionTop, width() - _dialogsWidth, height() - sectionTop));
result = myGrab(this, QRect(
_dialogsWidth,
sectionTop,
width() - _dialogsWidth,
height() - sectionTop));
_sideShadow->show();
if (_thirdShadow) {
_thirdShadow->show();
@ -3423,11 +3449,9 @@ void MainWidget::updateControlsGeometry() {
_history->setGeometry(mainSectionGeometry);
if (_hider) _hider->setGeometry(0, 0, dialogsWidth, height());
} else {
auto thirdSectionWidth = _thirdSection ? _thirdSection->width() : 0;
auto thirdSectionWidth = _thirdSection ? _thirdColumnWidth : 0;
if (_thirdSection) {
auto thirdSectionTop = getThirdSectionTop();
accumulate_min(thirdSectionWidth, width() - st::columnMinimalWidthMain - st::columnMinimalWidthLeft);
accumulate_max(thirdSectionWidth, st::columnMinimalWidthThird);
_thirdSection->setGeometry(
width() - thirdSectionWidth,
thirdSectionTop,
@ -3517,14 +3541,16 @@ void MainWidget::ensureFirstColumnResizeAreaCreated() {
}
auto moveLeftCallback = [=](int globalLeft) {
auto newWidth = globalLeft - mapToGlobal(QPoint(0, 0)).x();
auto newRatio = (newWidth < st::dialogsWidthMin / 2)
auto newRatio = (newWidth < st::columnMinimalWidthLeft / 2)
? 0.
: float64(newWidth) / width();
Auth().data().setDialogsWidthRatio(newRatio);
};
auto moveFinishedCallback = [=] {
if (!Adaptive::OneColumn()
&& Auth().data().dialogsWidthRatio() > 0) {
if (Adaptive::OneColumn()) {
return;
}
if (Auth().data().dialogsWidthRatio() > 0) {
Auth().data().setDialogsWidthRatio(
float64(_dialogsWidth) / width());
}
@ -3541,9 +3567,18 @@ void MainWidget::ensureThirdColumnResizeAreaCreated() {
return;
}
auto moveLeftCallback = [=](int globalLeft) {
auto newWidth = mapToGlobal(QPoint(width(), 0)).x() - globalLeft;
Auth().data().setThirdColumnWidth(newWidth);
};
auto moveFinishedCallback = [=] {
if (!Adaptive::ThreeColumn() || !_thirdSection) {
return;
}
Auth().data().setThirdColumnWidth(snap(
Auth().data().thirdColumnWidth(),
st::columnMinimalWidthThird,
st::columnMaximalWidthThird));
Local::writeUserSettings();
};
createResizeArea(
_thirdColumnResizeArea,
@ -3739,6 +3774,7 @@ void MainWidget::updateWindowAdaptiveLayout() {
_dialogsWidth = useSmallColumnWidth
? _controller->dialogsSmallColumnWidth()
: layout.dialogsWidth;
_thirdColumnWidth = layout.thirdWidth;
if (layout.windowLayout != Global::AdaptiveWindowLayout()) {
Global::SetAdaptiveWindowLayout(layout.windowLayout);
Adaptive::Changed().notify(true);

View File

@ -583,7 +583,8 @@ private:
bool _showBack = false;
QPixmap _cacheUnder, _cacheOver;
int _dialogsWidth;
int _dialogsWidth = 0;
int _thirdColumnWidth = 0;
Animation _a_dialogsWidth;
object_ptr<Ui::PlainShadow> _sideShadow;

View File

@ -31,8 +31,10 @@ windowShadow: icon {{ "window_shadow", windowShadowFg }};
windowShadowShift: 1px;
columnMinimalWidthLeft: 260px;
columnMaximalWidthLeft: 540px;
columnMinimalWidthMain: 380px;
columnMinimalWidthThird: 292px;//345px;
columnMaximalWidthThird: 345px;
adaptiveChatWideWidth: 880px;

View File

@ -108,23 +108,63 @@ Controller::ColumnLayout Controller::computeColumnLayout() const {
dialogsWidth = chatWidth = bodyWidth;
} else if (useNormalLayout()) {
layout = Adaptive::WindowLayout::Normal;
dialogsWidth = qRound(bodyWidth * Auth().data().dialogsWidthRatio());
accumulate_max(dialogsWidth, st::columnMinimalWidthLeft);
dialogsWidth = countDialogsWidthFromRatio(bodyWidth);
accumulate_min(dialogsWidth, bodyWidth - st::columnMinimalWidthMain);
chatWidth = bodyWidth - dialogsWidth;
} else {
layout = Adaptive::WindowLayout::ThreeColumn;
dialogsWidth = qRound(bodyWidth * Auth().data().dialogsWidthRatio());
accumulate_max(dialogsWidth, st::columnMinimalWidthLeft);
thirdWidth = st::columnMinimalWidthThird;
accumulate_min(
dialogsWidth = countDialogsWidthFromRatio(bodyWidth);
thirdWidth = countThirdColumnWidthFromRatio(bodyWidth);
auto shrink = shrinkDialogsAndThirdColumns(
dialogsWidth,
bodyWidth - thirdWidth - st::columnMinimalWidthMain);
thirdWidth,
bodyWidth);
dialogsWidth = shrink.dialogsWidth;
thirdWidth = shrink.thirdWidth;
chatWidth = bodyWidth - dialogsWidth - thirdWidth;
}
return { bodyWidth, dialogsWidth, chatWidth, thirdWidth, layout };
}
int Controller::countDialogsWidthFromRatio(int bodyWidth) const {
auto result = qRound(bodyWidth * Auth().data().dialogsWidthRatio());
accumulate_max(result, st::columnMinimalWidthLeft);
accumulate_min(result, st::columnMaximalWidthLeft);
return result;
}
int Controller::countThirdColumnWidthFromRatio(int bodyWidth) const {
auto result = Auth().data().thirdColumnWidth();
accumulate_max(result, st::columnMinimalWidthThird);
accumulate_min(result, st::columnMaximalWidthThird);
return result;
}
Controller::ShrinkResult Controller::shrinkDialogsAndThirdColumns(
int dialogsWidth,
int thirdWidth,
int bodyWidth) const {
auto chatWidth = st::columnMinimalWidthMain;
if (dialogsWidth + thirdWidth + chatWidth <= bodyWidth) {
return { dialogsWidth, thirdWidth };
}
auto thirdWidthNew = ((bodyWidth - chatWidth) * thirdWidth)
/ (dialogsWidth + thirdWidth);
auto dialogsWidthNew = ((bodyWidth - chatWidth) * dialogsWidth)
/ (dialogsWidth + thirdWidth);
if (thirdWidthNew < st::columnMinimalWidthThird) {
thirdWidthNew = st::columnMinimalWidthThird;
dialogsWidthNew = bodyWidth - thirdWidthNew - chatWidth;
Assert(dialogsWidthNew >= st::columnMinimalWidthLeft);
} else if (dialogsWidthNew < st::columnMinimalWidthLeft) {
dialogsWidthNew = st::columnMinimalWidthLeft;
thirdWidthNew = bodyWidth - dialogsWidthNew - chatWidth;
Assert(thirdWidthNew >= st::columnMinimalWidthThird);
}
return { dialogsWidthNew, thirdWidthNew };
}
bool Controller::canShowThirdSection() const {
auto currentLayout = computeColumnLayout();
auto extendBy = minimalThreeColumnWidth()

View File

@ -189,6 +189,16 @@ public:
private:
int minimalThreeColumnWidth() const;
not_null<MainWidget*> chats() const;
int countDialogsWidthFromRatio(int bodyWidth) const;
int countThirdColumnWidthFromRatio(int bodyWidth) const;
struct ShrinkResult {
int dialogsWidth;
int thirdWidth;
};
ShrinkResult shrinkDialogsAndThirdColumns(
int dialogsWidth,
int thirdWidth,
int bodyWidth) const;
not_null<MainWindow*> _window;