/******************************************************************************* ** Qt Advanced Docking System ** Copyright (C) 2017 Uwe Kindler ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Lesser General Public ** License as published by the Free Software Foundation; either ** version 2.1 of the License, or (at your option) any later version. ** ** This library 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 ** Lesser General Public License for more details. ** ** You should have received a copy of the GNU Lesser General Public ** License along with this library; If not, see . ******************************************************************************/ //============================================================================ /// \file AutoHideTab.cpp /// \author Syarif Fakhri /// \date 05.09.2022 /// \brief Implementation of CAutoHideTab class //============================================================================ //============================================================================ // INCLUDES //============================================================================ #include "AutoHideTab.h" #include #include #include #include "AutoHideDockContainer.h" #include "AutoHideSideBar.h" #include "DockAreaWidget.h" #include "DockManager.h" #include "DockWidget.h" namespace ads { /** * Private data class of CDockWidgetTab class (pimpl) */ struct AutoHideTabPrivate { CAutoHideTab* _this; CDockWidget* DockWidget = nullptr; CAutoHideSideBar* SideBar = nullptr; Qt::Orientation Orientation{Qt::Vertical}; QElapsedTimer TimeSinceHoverMousePress; /** * Private data constructor */ AutoHideTabPrivate(CAutoHideTab* _public); /** * Update the orientation, visibility and spacing based on the area of * the side bar */ void updateOrientation(); /** * Convenience function to ease dock container access */ CDockContainerWidget* dockContainer() const { return DockWidget ? DockWidget->dockContainer() : nullptr; } /** * Forward this event to the dock container */ void forwardEventToDockContainer(QEvent* event) { auto DockContainer = dockContainer(); if (DockContainer) { DockContainer->handleAutoHideWidgetEvent(event, _this); } } }; // struct DockWidgetTabPrivate //============================================================================ AutoHideTabPrivate::AutoHideTabPrivate(CAutoHideTab* _public) : _this(_public) { } //============================================================================ void AutoHideTabPrivate::updateOrientation() { bool IconOnly = CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideSideBarsIconOnly); if (IconOnly && !_this->icon().isNull()) { _this->setText(""); _this->setOrientation(Qt::Horizontal); } else { auto area = SideBar->sideBarLocation(); _this->setOrientation((area == SideBarBottom || area == SideBarTop) ? Qt::Horizontal : Qt::Vertical); } } //============================================================================ void CAutoHideTab::setSideBar(CAutoHideSideBar* SideTabBar) { d->SideBar = SideTabBar; if (d->SideBar) { d->updateOrientation(); } } //============================================================================ void CAutoHideTab::removeFromSideBar() { if (d->SideBar == nullptr) { return; } d->SideBar->removeTab(this); setSideBar(nullptr); } //============================================================================ CAutoHideTab::CAutoHideTab(QWidget* parent) : CPushButton(parent), d(new AutoHideTabPrivate(this)) { setAttribute(Qt::WA_NoMousePropagation); setFocusPolicy(Qt::NoFocus); } //============================================================================ CAutoHideTab::~CAutoHideTab() { ADS_PRINT("~CDockWidgetSideTab()"); delete d; } //============================================================================ void CAutoHideTab::updateStyle() { internal::repolishStyle(this, internal::RepolishDirectChildren); update(); } //============================================================================ SideBarLocation CAutoHideTab::sideBarLocation() const { if (d->SideBar) { return d->SideBar->sideBarLocation(); } return SideBarLeft; } //============================================================================ void CAutoHideTab::setOrientation(Qt::Orientation Orientation) { d->Orientation = Orientation; if (orientation() == Qt::Horizontal) { setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); } else { setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); } CPushButton::setButtonOrientation((Qt::Horizontal == Orientation) ? CPushButton::Horizontal : CPushButton::VerticalTopToBottom); updateStyle(); } //============================================================================ Qt::Orientation CAutoHideTab::orientation() const { return d->Orientation; } //============================================================================ bool CAutoHideTab::isActiveTab() const { if (d->DockWidget && d->DockWidget->autoHideDockContainer()) { return d->DockWidget->autoHideDockContainer()->isVisible(); } return false; } //============================================================================ CDockWidget* CAutoHideTab::dockWidget() const { return d->DockWidget; } //============================================================================ void CAutoHideTab::setDockWidget(CDockWidget* DockWidget) { if (!DockWidget) { return; } d->DockWidget = DockWidget; setText(DockWidget->windowTitle()); setIcon(d->DockWidget->icon()); setToolTip(DockWidget->windowTitle()); } //============================================================================ bool CAutoHideTab::event(QEvent* event) { if (!CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideShowOnMouseOver)) { return Super::event(event); } switch (event->type()) { case QEvent::Enter: case QEvent::Leave: d->forwardEventToDockContainer(event); break; case QEvent::MouseButtonPress: // If AutoHideShowOnMouseOver is active, then the showing is triggered // by a MousePressEvent sent to this tab. To prevent accidental hiding // of the tab by a mouse click, we wait at least 500 ms before we accept // the mouse click if (!event->spontaneous()) { d->TimeSinceHoverMousePress.restart(); d->forwardEventToDockContainer(event); } else if (d->TimeSinceHoverMousePress.hasExpired(500)) { d->forwardEventToDockContainer(event); } break; default: break; } return Super::event(event); } //============================================================================ bool CAutoHideTab::iconOnly() const { return CDockManager::testAutoHideConfigFlag(CDockManager::AutoHideSideBarsIconOnly) && !icon().isNull(); } }