diff --git a/include/ChatPage.h b/include/ChatPage.h index 234aabfd..faabd6db 100644 --- a/include/ChatPage.h +++ b/include/ChatPage.h @@ -69,6 +69,14 @@ public: QSharedPointer userSettings() { return userSettings_; } void deleteConfigs(); + //! Calculate the width of the message timeline. + int timelineWidth(); + bool isSideBarExpanded(); + //! Hide the room & group list (if it was visible). + void hideSideBars(); + //! Show the room/group list (if it was visible). + void showSideBars(); + public slots: void leaveRoom(const QString &room_id); diff --git a/include/Config.h b/include/Config.h index abf5dc05..3a3296d6 100644 --- a/include/Config.h +++ b/include/Config.h @@ -8,6 +8,7 @@ // Font sizes are in pixels. namespace conf { +constexpr int sideBarCollapsePoint = 450; // Global settings. constexpr int fontSize = 14; constexpr int textInputFontSize = 14; diff --git a/include/MainWindow.h b/include/MainWindow.h index 10750e00..3840bd9a 100644 --- a/include/MainWindow.h +++ b/include/MainWindow.h @@ -73,9 +73,13 @@ public: void openMemberListDialog(const QString &room_id = ""); protected: - void closeEvent(QCloseEvent *event); + void closeEvent(QCloseEvent *event) override; + void resizeEvent(QResizeEvent *event) override; + void showEvent(QShowEvent *event) override; private slots: + //! Show or hide the sidebars based on window's size. + void adjustSideBars(); //! Handle interaction with the tray icon. void iconActivated(QSystemTrayIcon::ActivationReason reason); diff --git a/include/Splitter.h b/include/Splitter.h index d4c34430..99e02eed 100644 --- a/include/Splitter.h +++ b/include/Splitter.h @@ -29,8 +29,8 @@ public: void restoreSizes(int fallback); public slots: - void showSidebar(); void hideSidebar(); + void showFullRoomList(); void showChatView(); signals: diff --git a/include/TopRoomBar.h b/include/TopRoomBar.h index 981e3e40..994486e0 100644 --- a/include/TopRoomBar.h +++ b/include/TopRoomBar.h @@ -55,11 +55,14 @@ public: void setBorderColor(QColor &color) { borderColor_ = color; } public slots: + //! Add a "back-arrow" button that can switch to roomlist only view. void enableBackButton(); + //! Replace the "back-arrow" button with the avatar of the room. + void disableBackButton(); signals: void inviteUsers(QStringList users); - void showSidebar(); + void showRoomList(); protected: void mousePressEvent(QMouseEvent *) override diff --git a/src/ChatPage.cc b/src/ChatPage.cc index fdd4e910..a14c7a93 100644 --- a/src/ChatPage.cc +++ b/src/ChatPage.cc @@ -65,7 +65,7 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) communitiesList_ = new CommunitiesList(this); topLayout_->addWidget(communitiesList_); - auto splitter = new Splitter(this); + splitter = new Splitter(this); splitter->setHandleWidth(0); topLayout_->addWidget(splitter); @@ -183,8 +183,7 @@ ChatPage::ChatPage(QSharedPointer userSettings, QWidget *parent) emit showOverlayProgressBar(); }); - connect(splitter, &Splitter::hiddenSidebar, top_bar_, &TopRoomBar::enableBackButton); - connect(top_bar_, &TopRoomBar::showSidebar, splitter, &Splitter::showSidebar); + connect(top_bar_, &TopRoomBar::showRoomList, splitter, &Splitter::showFullRoomList); connect(top_bar_, &TopRoomBar::inviteUsers, this, [this](QStringList users) { const auto room_id = current_room_.toStdString(); @@ -1314,3 +1313,35 @@ ChatPage::getProfileInfo() }); // TODO http::client()->getOwnCommunities(); } + +void +ChatPage::hideSideBars() +{ + communitiesList_->hide(); + sideBar_->hide(); + top_bar_->enableBackButton(); +} + +void +ChatPage::showSideBars() +{ + if (userSettings_->isGroupViewEnabled()) + communitiesList_->show(); + + sideBar_->show(); + top_bar_->disableBackButton(); +} + +int +ChatPage::timelineWidth() +{ + int sidebarWidth = sideBar_->size().width(); + sidebarWidth += communitiesList_->size().width(); + + return size().width() - sidebarWidth; +} +bool +ChatPage::isSideBarExpanded() +{ + return sideBar_->size().width() > ui::sidebar::NormalSize; +} diff --git a/src/MainWindow.cc b/src/MainWindow.cc index 7733a002..37739dc3 100644 --- a/src/MainWindow.cc +++ b/src/MainWindow.cc @@ -163,6 +163,34 @@ MainWindow::MainWindow(QWidget *parent) } } +void +MainWindow::showEvent(QShowEvent *event) +{ + adjustSideBars(); + QMainWindow::showEvent(event); +} + +void +MainWindow::resizeEvent(QResizeEvent *event) +{ + adjustSideBars(); + QMainWindow::resizeEvent(event); +} + +void +MainWindow::adjustSideBars() +{ + const int timelineWidth = chat_page_->timelineWidth(); + const int minAvailableWidth = + conf::sideBarCollapsePoint + ui::sidebar::CommunitiesSidebarSize; + + if (timelineWidth < minAvailableWidth && !chat_page_->isSideBarExpanded()) { + chat_page_->hideSideBars(); + } else { + chat_page_->showSideBars(); + } +} + void MainWindow::restoreWindowSize() { diff --git a/src/Splitter.cc b/src/Splitter.cc index acf0fd19..8a625227 100644 --- a/src/Splitter.cc +++ b/src/Splitter.cc @@ -21,37 +21,18 @@ #include #include +#include "Config.h" #include "Splitter.h" #include "Theme.h" +constexpr auto MaxWidth = (1 << 24) - 1; + Splitter::Splitter(QWidget *parent) : QSplitter(parent) { connect(this, &QSplitter::splitterMoved, this, &Splitter::onSplitterMoved); setChildrenCollapsible(false); setStyleSheet("QSplitter::handle { image: none; }"); - - auto showChatShortcut = new QShortcut(QKeySequence(tr("Ctrl+O", "Show chat")), parent); - auto showSidebarShortcut = - new QShortcut(QKeySequence(tr("Ctrl+L", "Show sidebar")), parent); - - connect(showChatShortcut, &QShortcut::activated, this, [this]() { - if (count() != 2) - return; - - hideSidebar(); - widget(1)->show(); - }); - connect(showSidebarShortcut, &QShortcut::activated, this, [this]() { - if (count() != 2) - return; - - widget(0)->setMinimumWidth(ui::sidebar::NormalSize); - widget(0)->setMaximumWidth(QApplication::desktop()->screenGeometry().height()); - - widget(0)->show(); - widget(1)->hide(); - }); } void @@ -61,7 +42,10 @@ Splitter::restoreSizes(int fallback) int savedWidth = settings.value("sidebar/width").toInt(); auto left = widget(0); - if (savedWidth == ui::sidebar::SmallSize) { + if (savedWidth == 0) { + hideSidebar(); + return; + } else if (savedWidth == ui::sidebar::SmallSize) { if (left) { left->setMinimumWidth(ui::sidebar::SmallSize); left->setMaximumWidth(ui::sidebar::SmallSize); @@ -69,21 +53,12 @@ Splitter::restoreSizes(int fallback) } } - if (savedWidth >= ui::sidebar::NormalSize && savedWidth <= 2 * ui::sidebar::NormalSize) { - if (left) { - left->setMinimumWidth(ui::sidebar::NormalSize); - left->setMaximumWidth(2 * ui::sidebar::NormalSize); - setSizes({savedWidth, fallback - savedWidth}); - return; - } - } - - if (savedWidth == 0) { - hideSidebar(); - return; - } - + left->setMinimumWidth(ui::sidebar::NormalSize); + left->setMaximumWidth(2 * ui::sidebar::NormalSize); setSizes({ui::sidebar::NormalSize, fallback - ui::sidebar::NormalSize}); + + setStretchFactor(0, 0); + setStretchFactor(1, 1); } Splitter::~Splitter() @@ -92,11 +67,7 @@ Splitter::~Splitter() if (left) { QSettings settings; - - if (!left->isVisible()) - settings.setValue("sidebar/width", 0); - else - settings.setValue("sidebar/width", left->width()); + settings.setValue("sidebar/width", left->width()); } } @@ -143,49 +114,55 @@ Splitter::onSplitterMoved(int pos, int index) // if we are coming from the left, the cursor should // end up on the second widget. - if (extended.contains(pos)) { + if (extended.contains(pos) && + right->size().width() >= + conf::sideBarCollapsePoint + ui::sidebar::NormalSize) { left->setMinimumWidth(ui::sidebar::NormalSize); left->setMaximumWidth(2 * ui::sidebar::NormalSize); leftMoveCount_ = 0; - } else if (left->rect().contains(left->mapFromGlobal(QCursor::pos()))) { - hideSidebar(); } } } } -void -Splitter::showChatView() -{ - if (count() != 2) - return; - - auto right = widget(1); - - // We are in Roomlist-only view so we'll switch into Chat-only view. - if (!right->isVisible()) { - right->show(); - hideSidebar(); - } -} - -void -Splitter::showSidebar() -{ - auto left = widget(0); - if (left) { - left->setMinimumWidth(ui::sidebar::SmallSize); - left->setMaximumWidth(ui::sidebar::SmallSize); - left->show(); - } -} void Splitter::hideSidebar() { auto left = widget(0); - if (left) { + if (left) left->hide(); - emit hiddenSidebar(); +} + +void +Splitter::showChatView() +{ + auto left = widget(0); + auto right = widget(1); + + if (right->isHidden()) { + left->hide(); + right->show(); + + // Restore previous size. + if (left->minimumWidth() == ui::sidebar::SmallSize) { + left->setMinimumWidth(ui::sidebar::SmallSize); + left->setMaximumWidth(ui::sidebar::SmallSize); + } else { + left->setMinimumWidth(ui::sidebar::NormalSize); + left->setMaximumWidth(2 * ui::sidebar::NormalSize); + } } } + +void +Splitter::showFullRoomList() +{ + auto left = widget(0); + auto right = widget(1); + + right->hide(); + + left->show(); + left->setMaximumWidth(MaxWidth); +} diff --git a/src/TopRoomBar.cc b/src/TopRoomBar.cc index 03241717..7b2814b9 100644 --- a/src/TopRoomBar.cc +++ b/src/TopRoomBar.cc @@ -83,11 +83,7 @@ TopRoomBar::TopRoomBar(QWidget *parent) backBtn_->setIconSize(QSize(buttonSize_ / 2, buttonSize_ / 2)); backBtn_->hide(); - connect(backBtn_, &QPushButton::clicked, this, [this]() { - backBtn_->hide(); - avatar_->show(); - emit showSidebar(); - }); + connect(backBtn_, &QPushButton::clicked, this, &TopRoomBar::showRoomList); topLayout_->addWidget(avatar_); topLayout_->addWidget(backBtn_); @@ -136,6 +132,13 @@ TopRoomBar::enableBackButton() backBtn_->show(); } +void +TopRoomBar::disableBackButton() +{ + avatar_->show(); + backBtn_->hide(); +} + void TopRoomBar::updateRoomAvatarFromName(const QString &name) {