Extract a reusable Ui::ResizeArea class.
This commit is contained in:
parent
3a25313e61
commit
bca9b3ca3f
|
@ -38,6 +38,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "data/data_drafts.h"
|
#include "data/data_drafts.h"
|
||||||
#include "ui/widgets/dropdown_menu.h"
|
#include "ui/widgets/dropdown_menu.h"
|
||||||
#include "ui/focus_persister.h"
|
#include "ui/focus_persister.h"
|
||||||
|
#include "ui/resize_area.h"
|
||||||
#include "chat_helpers/message_field.h"
|
#include "chat_helpers/message_field.h"
|
||||||
#include "chat_helpers/stickers.h"
|
#include "chat_helpers/stickers.h"
|
||||||
#include "observer_peer.h"
|
#include "observer_peer.h"
|
||||||
|
@ -226,7 +227,6 @@ MainWidget::MainWidget(
|
||||||
, _controller(controller)
|
, _controller(controller)
|
||||||
, _dialogsWidth(st::dialogsWidthMin)
|
, _dialogsWidth(st::dialogsWidthMin)
|
||||||
, _sideShadow(this)
|
, _sideShadow(this)
|
||||||
, _sideResizeArea(this)
|
|
||||||
, _dialogs(this, _controller)
|
, _dialogs(this, _controller)
|
||||||
, _history(this, _controller)
|
, _history(this, _controller)
|
||||||
, _playerPlaylist(this, Media::Player::Panel::Layout::OnlyPlaylist)
|
, _playerPlaylist(this, Media::Player::Panel::Layout::OnlyPlaylist)
|
||||||
|
@ -292,8 +292,6 @@ MainWidget::MainWidget(
|
||||||
_webPageOrGameUpdater.setSingleShot(true);
|
_webPageOrGameUpdater.setSingleShot(true);
|
||||||
connect(&_webPageOrGameUpdater, SIGNAL(timeout()), this, SLOT(webPagesOrGamesUpdate()));
|
connect(&_webPageOrGameUpdater, SIGNAL(timeout()), this, SLOT(webPagesOrGamesUpdate()));
|
||||||
|
|
||||||
_sideResizeArea->setCursor(style::cur_sizehor);
|
|
||||||
|
|
||||||
using Update = Window::Theme::BackgroundUpdate;
|
using Update = Window::Theme::BackgroundUpdate;
|
||||||
subscribe(Window::Theme::Background(), [this](const Update &update) {
|
subscribe(Window::Theme::Background(), [this](const Update &update) {
|
||||||
if (update.type == Update::Type::New || update.type == Update::Type::Changed) {
|
if (update.type == Update::Type::New || update.type == Update::Type::Changed) {
|
||||||
|
@ -354,8 +352,6 @@ MainWidget::MainWidget(
|
||||||
|
|
||||||
orderWidgets();
|
orderWidgets();
|
||||||
|
|
||||||
_sideResizeArea->installEventFilter(this);
|
|
||||||
|
|
||||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||||
Sandbox::startUpdateCheck();
|
Sandbox::startUpdateCheck();
|
||||||
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
|
#endif // !TDESKTOP_DISABLE_AUTOUPDATE
|
||||||
|
@ -3078,7 +3074,12 @@ void MainWidget::orderWidgets() {
|
||||||
if (_thirdShadow) {
|
if (_thirdShadow) {
|
||||||
_thirdShadow->raise();
|
_thirdShadow->raise();
|
||||||
}
|
}
|
||||||
_sideResizeArea->raise();
|
if (_firstColumnResizeArea) {
|
||||||
|
_firstColumnResizeArea->raise();
|
||||||
|
}
|
||||||
|
if (_thirdColumnResizeArea) {
|
||||||
|
_thirdColumnResizeArea->raise();
|
||||||
|
}
|
||||||
_playerPlaylist->raise();
|
_playerPlaylist->raise();
|
||||||
_playerPanel->raise();
|
_playerPanel->raise();
|
||||||
for (auto &instance : _playerFloats) {
|
for (auto &instance : _playerFloats) {
|
||||||
|
@ -3458,22 +3459,12 @@ void MainWidget::updateControlsGeometry() {
|
||||||
_hider->setGeometryToLeft(dialogsWidth, 0, mainSectionWidth, height());
|
_hider->setGeometryToLeft(dialogsWidth, 0, mainSectionWidth, height());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_sideResizeArea->setGeometryToLeft(_history->x(), 0, st::historyResizeWidth, height());
|
|
||||||
auto isSideResizeAreaVisible = [this] {
|
|
||||||
if (width() < st::columnMinimalWidthLeft + st::columnMinimalWidthMain) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (Adaptive::OneColumn() && !isMainSectionShown()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
_sideResizeArea->setVisible(isSideResizeAreaVisible());
|
|
||||||
if (_mainSection) {
|
if (_mainSection) {
|
||||||
auto mainSectionGeometry = QRect(_history->x(), mainSectionTop, _history->width(), height() - mainSectionTop);
|
auto mainSectionGeometry = QRect(_history->x(), mainSectionTop, _history->width(), height() - mainSectionTop);
|
||||||
_mainSection->setGeometryWithTopMoved(mainSectionGeometry, _contentScrollAddToY);
|
_mainSection->setGeometryWithTopMoved(mainSectionGeometry, _contentScrollAddToY);
|
||||||
}
|
}
|
||||||
if (_overview) _overview->setGeometry(_history->geometry());
|
if (_overview) _overview->setGeometry(_history->geometry());
|
||||||
|
refreshResizeAreas();
|
||||||
updateMediaPlayerPosition();
|
updateMediaPlayerPosition();
|
||||||
updateMediaPlaylistPosition(_playerPlaylist->x());
|
updateMediaPlaylistPosition(_playerPlaylist->x());
|
||||||
_contentScrollAddToY = 0;
|
_contentScrollAddToY = 0;
|
||||||
|
@ -3482,6 +3473,84 @@ void MainWidget::updateControlsGeometry() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWidget::refreshResizeAreas() {
|
||||||
|
if (!Adaptive::OneColumn()) {
|
||||||
|
ensureFirstColumnResizeAreaCreated();
|
||||||
|
_firstColumnResizeArea->setGeometryToLeft(
|
||||||
|
_history->x(),
|
||||||
|
0,
|
||||||
|
st::historyResizeWidth,
|
||||||
|
height());
|
||||||
|
} else if (_firstColumnResizeArea) {
|
||||||
|
_firstColumnResizeArea.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Adaptive::ThreeColumn() && _thirdSection) {
|
||||||
|
ensureThirdColumnResizeAreaCreated();
|
||||||
|
_thirdColumnResizeArea->setGeometryToLeft(
|
||||||
|
_thirdSection->x(),
|
||||||
|
0,
|
||||||
|
st::historyResizeWidth,
|
||||||
|
height());
|
||||||
|
} else if (_thirdColumnResizeArea) {
|
||||||
|
_thirdColumnResizeArea.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename MoveCallback, typename FinishCallback>
|
||||||
|
void MainWidget::createResizeArea(
|
||||||
|
object_ptr<Ui::ResizeArea> &area,
|
||||||
|
MoveCallback &&moveCallback,
|
||||||
|
FinishCallback &&finishCallback) {
|
||||||
|
area.create(this);
|
||||||
|
area->show();
|
||||||
|
area->addMoveLeftCallback(
|
||||||
|
std::forward<MoveCallback>(moveCallback));
|
||||||
|
area->addMoveFinishedCallback(
|
||||||
|
std::forward<FinishCallback>(finishCallback));
|
||||||
|
orderWidgets();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWidget::ensureFirstColumnResizeAreaCreated() {
|
||||||
|
if (_firstColumnResizeArea) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto moveLeftCallback = [=](int globalLeft) {
|
||||||
|
auto newWidth = globalLeft - mapToGlobal(QPoint(0, 0)).x();
|
||||||
|
auto newRatio = (newWidth < st::dialogsWidthMin / 2)
|
||||||
|
? 0.
|
||||||
|
: float64(newWidth) / width();
|
||||||
|
Auth().data().setDialogsWidthRatio(newRatio);
|
||||||
|
};
|
||||||
|
auto moveFinishedCallback = [=] {
|
||||||
|
if (!Adaptive::OneColumn()
|
||||||
|
&& Auth().data().dialogsWidthRatio() > 0) {
|
||||||
|
Auth().data().setDialogsWidthRatio(
|
||||||
|
float64(_dialogsWidth) / width());
|
||||||
|
}
|
||||||
|
Local::writeUserSettings();
|
||||||
|
};
|
||||||
|
createResizeArea(
|
||||||
|
_firstColumnResizeArea,
|
||||||
|
std::move(moveLeftCallback),
|
||||||
|
std::move(moveFinishedCallback));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWidget::ensureThirdColumnResizeAreaCreated() {
|
||||||
|
if (_thirdColumnResizeArea) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto moveLeftCallback = [=](int globalLeft) {
|
||||||
|
};
|
||||||
|
auto moveFinishedCallback = [=] {
|
||||||
|
|
||||||
|
};
|
||||||
|
createResizeArea(
|
||||||
|
_thirdColumnResizeArea,
|
||||||
|
std::move(moveLeftCallback),
|
||||||
|
std::move(moveFinishedCallback));
|
||||||
|
}
|
||||||
|
|
||||||
void MainWidget::updateDialogsWidthAnimated() {
|
void MainWidget::updateDialogsWidthAnimated() {
|
||||||
if (Auth().data().dialogsWidthRatio() > 0) {
|
if (Auth().data().dialogsWidthRatio() > 0) {
|
||||||
return;
|
return;
|
||||||
|
@ -3581,27 +3650,7 @@ void MainWidget::keyPressEvent(QKeyEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MainWidget::eventFilter(QObject *o, QEvent *e) {
|
bool MainWidget::eventFilter(QObject *o, QEvent *e) {
|
||||||
if (o == _sideResizeArea) {
|
if (e->type() == QEvent::FocusIn) {
|
||||||
auto mouseLeft = [this, e] {
|
|
||||||
return mapFromGlobal(static_cast<QMouseEvent*>(e)->globalPos()).x();
|
|
||||||
};
|
|
||||||
if (e->type() == QEvent::MouseButtonPress && static_cast<QMouseEvent*>(e)->button() == Qt::LeftButton) {
|
|
||||||
_resizingSide = true;
|
|
||||||
_resizingSideShift = mouseLeft() - (Adaptive::OneColumn() ? 0 : _dialogsWidth);
|
|
||||||
} else if (e->type() == QEvent::MouseButtonRelease) {
|
|
||||||
_resizingSide = false;
|
|
||||||
if (!Adaptive::OneColumn()
|
|
||||||
&& Auth().data().dialogsWidthRatio() > 0) {
|
|
||||||
Auth().data().setDialogsWidthRatio(
|
|
||||||
float64(_dialogsWidth) / width());
|
|
||||||
}
|
|
||||||
Local::writeUserSettings();
|
|
||||||
} else if (e->type() == QEvent::MouseMove && _resizingSide) {
|
|
||||||
auto newWidth = mouseLeft() - _resizingSideShift;
|
|
||||||
auto newRatio = (newWidth < st::dialogsWidthMin / 2) ? 0. : float64(newWidth) / width();
|
|
||||||
Auth().data().setDialogsWidthRatio(newRatio);
|
|
||||||
}
|
|
||||||
} else if (e->type() == QEvent::FocusIn) {
|
|
||||||
if (auto widget = qobject_cast<QWidget*>(o)) {
|
if (auto widget = qobject_cast<QWidget*>(o)) {
|
||||||
if (_history == widget || _history->isAncestorOf(widget)
|
if (_history == widget || _history->isAncestorOf(widget)
|
||||||
|| (_overview && (_overview == widget || _overview->isAncestorOf(widget)))
|
|| (_overview && (_overview == widget || _overview->isAncestorOf(widget)))
|
||||||
|
|
|
@ -44,6 +44,7 @@ class Float;
|
||||||
} // namespace Media
|
} // namespace Media
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
class ResizeArea;
|
||||||
class PlainShadow;
|
class PlainShadow;
|
||||||
class DropdownMenu;
|
class DropdownMenu;
|
||||||
template <typename Widget>
|
template <typename Widget>
|
||||||
|
@ -558,6 +559,15 @@ private:
|
||||||
void viewsIncrementDone(QVector<MTPint> ids, const MTPVector<MTPint> &result, mtpRequestId req);
|
void viewsIncrementDone(QVector<MTPint> ids, const MTPVector<MTPint> &result, mtpRequestId req);
|
||||||
bool viewsIncrementFail(const RPCError &error, mtpRequestId req);
|
bool viewsIncrementFail(const RPCError &error, mtpRequestId req);
|
||||||
|
|
||||||
|
void refreshResizeAreas();
|
||||||
|
template <typename MoveCallback, typename FinishCallback>
|
||||||
|
void createResizeArea(
|
||||||
|
object_ptr<Ui::ResizeArea> &area,
|
||||||
|
MoveCallback &&moveCallback,
|
||||||
|
FinishCallback &&finishCallback);
|
||||||
|
void ensureFirstColumnResizeAreaCreated();
|
||||||
|
void ensureThirdColumnResizeAreaCreated();
|
||||||
|
|
||||||
not_null<Window::Controller*> _controller;
|
not_null<Window::Controller*> _controller;
|
||||||
bool _started = false;
|
bool _started = false;
|
||||||
|
|
||||||
|
@ -578,7 +588,8 @@ private:
|
||||||
|
|
||||||
object_ptr<Ui::PlainShadow> _sideShadow;
|
object_ptr<Ui::PlainShadow> _sideShadow;
|
||||||
object_ptr<Ui::PlainShadow> _thirdShadow = { nullptr };
|
object_ptr<Ui::PlainShadow> _thirdShadow = { nullptr };
|
||||||
object_ptr<TWidget> _sideResizeArea;
|
object_ptr<Ui::ResizeArea> _firstColumnResizeArea = { nullptr };
|
||||||
|
object_ptr<Ui::ResizeArea> _thirdColumnResizeArea = { nullptr };
|
||||||
object_ptr<DialogsWidget> _dialogs;
|
object_ptr<DialogsWidget> _dialogs;
|
||||||
object_ptr<HistoryWidget> _history;
|
object_ptr<HistoryWidget> _history;
|
||||||
object_ptr<Window::SectionWidget> _mainSection = { nullptr };
|
object_ptr<Window::SectionWidget> _mainSection = { nullptr };
|
||||||
|
@ -670,7 +681,7 @@ private:
|
||||||
|
|
||||||
std::unique_ptr<App::WallPaper> _background;
|
std::unique_ptr<App::WallPaper> _background;
|
||||||
|
|
||||||
bool _resizingSide = false;
|
bool _firstColumnResizing = false;
|
||||||
int _resizingSideShift = 0;
|
int _firstColumnResizingShift = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ui/rp_widget.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
|
||||||
|
class ResizeArea : public RpWidget {
|
||||||
|
public:
|
||||||
|
ResizeArea(QWidget *parent) : RpWidget(parent) {
|
||||||
|
setCursor(style::cur_sizehor);
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<int> moveLeft() const {
|
||||||
|
return _moveLeft.events();
|
||||||
|
}
|
||||||
|
template <typename Callback>
|
||||||
|
void addMoveLeftCallback(Callback &&callback) {
|
||||||
|
moveLeft()
|
||||||
|
| rpl::start_with_next(
|
||||||
|
std::forward<Callback>(callback),
|
||||||
|
lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<> moveFinished() const {
|
||||||
|
return _moveFinished.events();
|
||||||
|
}
|
||||||
|
template <typename Callback>
|
||||||
|
void addMoveFinishedCallback(Callback &&callback) {
|
||||||
|
moveFinished()
|
||||||
|
| rpl::start_with_next(
|
||||||
|
std::forward<Callback>(callback),
|
||||||
|
lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
|
~ResizeArea() {
|
||||||
|
moveFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void mousePressEvent(QMouseEvent *e) override {
|
||||||
|
if (e->button() == Qt::LeftButton) {
|
||||||
|
_moving = true;
|
||||||
|
_moveStartLeft = e->pos().x();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void mouseReleaseEvent(QMouseEvent *e) override {
|
||||||
|
if (e->button() == Qt::LeftButton) {
|
||||||
|
moveFinish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void mouseMoveEvent(QMouseEvent *e) override {
|
||||||
|
if (_moving) {
|
||||||
|
_moveLeft.fire(e->globalPos().x() - _moveStartLeft);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void moveFinish() {
|
||||||
|
if (base::take(_moving)) {
|
||||||
|
_moveFinished.fire({});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::event_stream<int> _moveLeft;
|
||||||
|
rpl::event_stream<> _moveFinished;
|
||||||
|
int _moveStartLeft = 0;
|
||||||
|
bool _moving = false;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Ui
|
|
@ -32,7 +32,7 @@ windowShadowShift: 1px;
|
||||||
|
|
||||||
columnMinimalWidthLeft: 260px;
|
columnMinimalWidthLeft: 260px;
|
||||||
columnMinimalWidthMain: 380px;
|
columnMinimalWidthMain: 380px;
|
||||||
columnMinimalWidthThird: 345px;//292px;//345px;
|
columnMinimalWidthThird: 292px;//345px;
|
||||||
|
|
||||||
adaptiveChatWideWidth: 880px;
|
adaptiveChatWideWidth: 880px;
|
||||||
|
|
||||||
|
|
|
@ -609,6 +609,7 @@
|
||||||
<(src_loc)/ui/focus_persister.h
|
<(src_loc)/ui/focus_persister.h
|
||||||
<(src_loc)/ui/images.cpp
|
<(src_loc)/ui/images.cpp
|
||||||
<(src_loc)/ui/images.h
|
<(src_loc)/ui/images.h
|
||||||
|
<(src_loc)/ui/resize_area.h
|
||||||
<(src_loc)/ui/rp_widget.h
|
<(src_loc)/ui/rp_widget.h
|
||||||
<(src_loc)/ui/search_field_controller.cpp
|
<(src_loc)/ui/search_field_controller.cpp
|
||||||
<(src_loc)/ui/search_field_controller.h
|
<(src_loc)/ui/search_field_controller.h
|
||||||
|
|
Loading…
Reference in New Issue