File indexing completed on 2025-10-12 03:31:35
0001 /* 0002 File : SlidingPanel.cpp 0003 Project : LabPlot 0004 Description : Sliding panel shown in the presenter widget 0005 -------------------------------------------------------------------- 0006 SPDX-FileCopyrightText: 2016 Fabian Kristof <fkristofszabolcs@gmail.com> 0007 SPDX-FileCopyrightText: 2016-2023 Alexander Semke <alexander.semke@web.de> 0008 SPDX-License-Identifier: GPL-2.0-or-later 0009 */ 0010 #include "SlidingPanel.h" 0011 0012 #include "commonfrontend/worksheet/WorksheetView.h" 0013 0014 #include <QAction> 0015 #include <QApplication> 0016 #include <QHBoxLayout> 0017 #include <QLabel> 0018 #include <QPushButton> 0019 #include <QScreen> 0020 #include <QSize> 0021 #include <QTimeLine> 0022 #include <QToolBar> 0023 0024 #include <KLocalizedString> 0025 0026 SlidingPanel::SlidingPanel(const QRect& screenRect, Position position, QWidget* parent) 0027 : QFrame(parent) 0028 , m_screenRect(screenRect) 0029 , m_pos(position) 0030 , m_timeLine(new QTimeLine(400, this)) { 0031 setAttribute(Qt::WA_DeleteOnClose); 0032 connect(m_timeLine, &QTimeLine::valueChanged, this, &SlidingPanel::movePanel); 0033 } 0034 0035 SlidingPanel::~SlidingPanel() { 0036 } 0037 0038 void SlidingPanel::slideShow() { 0039 // timeline: 0 --> 1 0040 m_timeLine->setDirection(QTimeLine::Forward); 0041 startTimeline(); 0042 } 0043 0044 void SlidingPanel::slideHide() { 0045 // timeline: 1 --> 0 0046 m_timeLine->setDirection(QTimeLine::Backward); 0047 startTimeline(); 0048 } 0049 0050 void SlidingPanel::startTimeline() { 0051 if (m_timeLine->state() != QTimeLine::Running) 0052 m_timeLine->start(); 0053 } 0054 0055 void SlidingPanel::movePanel(qreal value) { 0056 switch (m_pos) { 0057 case Position::Top: 0058 move(pos().x(), -height() + static_cast<int>(value * height())); 0059 break; 0060 case Position::Bottom: 0061 move(pos().x(), m_screenRect.height() - static_cast<int>((1 - value) * height())); 0062 break; 0063 } 0064 raise(); 0065 } 0066 0067 bool SlidingPanel::insideRect(QPoint screenPos) { 0068 const auto leftTop = mapToGlobal(QPoint(rect().left(), rect().top())); 0069 const auto rightBottom = mapToGlobal(QPoint(rect().right(), rect().bottom())); 0070 const auto globalRect = QRect(leftTop.x(), leftTop.y(), rightBottom.x(), rightBottom.y()); 0071 return globalRect.contains(mapToGlobal(screenPos)); 0072 } 0073 0074 // #################################################################################################### 0075 0076 SlidingPanelTop::SlidingPanelTop(const QRect& screenRect, const QString& worksheetName, QWidget* parent) 0077 : SlidingPanel(screenRect, SlidingPanel::Position::Top, parent) { 0078 setAttribute(Qt::WA_DeleteOnClose); 0079 0080 m_worksheetName = new QLabel(worksheetName, this); 0081 QFont nameFont; 0082 nameFont.setPointSize(20); 0083 nameFont.setBold(true); 0084 m_worksheetName->setFont(nameFont); 0085 0086 m_quitPresentingMode = new QPushButton(i18n("Quit Presentation"), this); 0087 m_quitPresentingMode->setIcon(QIcon::fromTheme(QLatin1String("window-close"))); 0088 0089 auto* hlayout = new QHBoxLayout; 0090 hlayout->addWidget(m_worksheetName); 0091 auto* spacer = new QSpacerItem(10, 10, QSizePolicy::Expanding, QSizePolicy::Minimum); 0092 hlayout->addItem(spacer); 0093 hlayout->addWidget(m_quitPresentingMode); 0094 setLayout(hlayout); 0095 0096 QPalette pal(palette()); 0097 pal.setColor(QPalette::Window, Qt::lightGray); 0098 setAutoFillBackground(true); 0099 setPalette(pal); 0100 0101 move(0, 0); 0102 raise(); 0103 show(); 0104 } 0105 0106 QPushButton* SlidingPanelTop::quitButton() const { 0107 return m_quitPresentingMode; 0108 } 0109 0110 QSize SlidingPanelTop::sizeHint() const { 0111 QSize sh; 0112 sh.setWidth(m_screenRect.width()); 0113 sh.setHeight(m_worksheetName->sizeHint().height() + layout()->contentsMargins().top() + layout()->contentsMargins().bottom()); 0114 0115 return sh; 0116 } 0117 0118 // #################################################################################################### 0119 SlidingPanelBottom::SlidingPanelBottom(const QRect& screenRect, WorksheetView* view, bool fixed, QWidget* parent) 0120 : SlidingPanel(screenRect, SlidingPanel::Position::Bottom, parent) 0121 , m_toolBar(new QToolBar(this)) 0122 , m_fixed(fixed) { 0123 auto* layout = new QHBoxLayout(); 0124 layout->setContentsMargins(0, 0, 0, 0); 0125 setLayout(layout); 0126 0127 view->fillCartesianPlotNavigationToolBar(m_toolBar, false /* disable cursor action */); 0128 0129 // add an action to pin/unpin the panel (to make it fixed or floating) 0130 m_toolBar->addSeparator(); 0131 auto* pinAction = new QAction(QIcon::fromTheme(QStringLiteral("pin")), i18n("Pin the navigation panel")); 0132 pinAction->setCheckable(true); 0133 pinAction->setChecked(m_fixed); 0134 connect(pinAction, &QAction::toggled, this, [=](bool toggled) { 0135 m_fixed = toggled; 0136 }); 0137 m_toolBar->addAction(pinAction); 0138 0139 layout->addWidget(m_toolBar); 0140 0141 QPalette pal(palette()); 0142 pal.setColor(QPalette::Window, Qt::lightGray); 0143 setAutoFillBackground(true); 0144 setPalette(pal); 0145 0146 move(screenRect.width() / 2 - m_toolBar->sizeHint().width() / 2, screenRect.bottom() - m_toolBar->sizeHint().height()); 0147 raise(); 0148 show(); 0149 } 0150 0151 bool SlidingPanelBottom::isFixed() const { 0152 return m_fixed; 0153 } 0154 0155 // TODO: why is SlidingPanel::insideRect() not enough? 0156 bool SlidingPanelBottom::insideRect(QPoint screenPos) { 0157 QRect rect = this->rect(); 0158 rect.moveTo(screen()->geometry().width() / 2 - m_toolBar->sizeHint().width() / 2, screen()->geometry().bottom() - rect.height()); 0159 // Last part is a hack, because contains seems to be failing here 0160 const bool inside = rect.contains(screenPos) || screenPos.y() >= screen()->geometry().bottom(); 0161 return inside; 0162 } 0163 0164 QSize SlidingPanelBottom::sizeHint() const { 0165 return m_toolBar->sizeHint(); 0166 }