File indexing completed on 2024-05-05 05:57:02

0001 /*
0002   SPDX-FileCopyrightText: 2008-2014 Eike Hein <hein@kde.org>
0003   SPDX-FileCopyrightText: 2020 Ryan McCoskrie <work@ryanmccoskrie.me>
0004 
0005   SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0006 */
0007 
0008 #include "titlebar.h"
0009 #include "mainwindow.h"
0010 #include "skin.h"
0011 
0012 #include <KLocalizedString>
0013 #include <QFontDatabase>
0014 #include <QPushButton>
0015 
0016 #include <QBitmap>
0017 #include <QPainter>
0018 
0019 TitleBar::TitleBar(MainWindow *mainWindow)
0020     : QWidget(mainWindow)
0021 {
0022     setWhatsThis(xi18nc("@info:whatsthis",
0023                         "<title>Title Bar</title>"
0024                         "<para>The title bar displays the session title if available.</para>"));
0025 
0026     setAttribute(Qt::WA_OpaquePaintEvent);
0027 
0028     m_mainWindow = mainWindow;
0029     m_skin = mainWindow->skin();
0030 
0031     setCursor(Qt::SizeVerCursor);
0032 
0033     m_focusButton = new QPushButton(this);
0034     m_focusButton->setFocusPolicy(Qt::NoFocus);
0035     m_focusButton->setCheckable(true);
0036     m_focusButton->setToolTip(xi18nc("@info:tooltip", "Keep window open when it loses focus"));
0037     m_focusButton->setWhatsThis(xi18nc("@info:whatsthis", "If this is checked, the window will stay open when it loses focus."));
0038     m_focusButton->setCursor(Qt::ArrowCursor);
0039     connect(m_focusButton, SIGNAL(toggled(bool)), mainWindow, SLOT(setKeepOpen(bool)));
0040 
0041     m_menuButton = new QPushButton(this);
0042     m_menuButton->setFocusPolicy(Qt::NoFocus);
0043     m_menuButton->setMenu(mainWindow->menu());
0044     m_menuButton->setToolTip(xi18nc("@info:tooltip", "Open Menu"));
0045     m_menuButton->setWhatsThis(xi18nc("@info:whatsthis", "Opens the main menu."));
0046     m_menuButton->setCursor(Qt::ArrowCursor);
0047 
0048     m_quitButton = new QPushButton(this);
0049     m_quitButton->setFocusPolicy(Qt::NoFocus);
0050     m_quitButton->setToolTip(xi18nc("@info:tooltip Quits the application", "Quit"));
0051     m_quitButton->setWhatsThis(xi18nc("@info:whatsthis", "Quits the application."));
0052     m_quitButton->setCursor(Qt::ArrowCursor);
0053     connect(m_quitButton, SIGNAL(clicked()), mainWindow, SLOT(close()));
0054 }
0055 
0056 TitleBar::~TitleBar()
0057 {
0058 }
0059 
0060 void TitleBar::setVisible(bool visible)
0061 {
0062     m_visible = visible;
0063     if (m_visible) {
0064         resize(width(), m_skin->titleBarBackgroundImage().height());
0065     } else {
0066         resize(width(), 0);
0067     }
0068 
0069     QWidget::setVisible(m_visible);
0070 }
0071 
0072 void TitleBar::applySkin()
0073 {
0074     resize(width(), m_visible ? m_skin->titleBarBackgroundImage().height() : 0);
0075 
0076     m_focusButton->setStyleSheet(m_skin->titleBarFocusButtonStyleSheet());
0077     m_menuButton->setStyleSheet(m_skin->titleBarMenuButtonStyleSheet());
0078     m_quitButton->setStyleSheet(m_skin->titleBarQuitButtonStyleSheet());
0079 
0080     moveButtons();
0081 
0082     repaint();
0083 
0084     updateMask();
0085 }
0086 
0087 void TitleBar::moveButtons()
0088 {
0089     if (m_skin->titleBarFocusButtonAnchor() == Qt::AnchorLeft)
0090         m_focusButton->move(m_skin->titleBarFocusButtonPosition().x(), m_skin->titleBarFocusButtonPosition().y());
0091     else if (m_skin->titleBarFocusButtonAnchor() == Qt::AnchorRight)
0092         m_focusButton->move(width() - m_skin->titleBarFocusButtonPosition().x(), m_skin->titleBarFocusButtonPosition().y());
0093 
0094     if (m_skin->titleBarMenuButtonAnchor() == Qt::AnchorLeft)
0095         m_menuButton->move(m_skin->titleBarMenuButtonPosition().x(), m_skin->titleBarMenuButtonPosition().y());
0096     else if (m_skin->titleBarMenuButtonAnchor() == Qt::AnchorRight)
0097         m_menuButton->move(width() - m_skin->titleBarMenuButtonPosition().x(), m_skin->titleBarMenuButtonPosition().y());
0098 
0099     if (m_skin->titleBarQuitButtonAnchor() == Qt::AnchorLeft)
0100         m_quitButton->move(m_skin->titleBarQuitButtonPosition().x(), m_skin->titleBarQuitButtonPosition().y());
0101     else if (m_skin->titleBarQuitButtonAnchor() == Qt::AnchorRight)
0102         m_quitButton->move(width() - m_skin->titleBarQuitButtonPosition().x(), m_skin->titleBarQuitButtonPosition().y());
0103 }
0104 
0105 void TitleBar::resizeEvent(QResizeEvent *event)
0106 {
0107     moveButtons();
0108 
0109     updateMask();
0110 
0111     QWidget::resizeEvent(event);
0112 }
0113 
0114 void TitleBar::paintEvent(QPaintEvent *)
0115 {
0116     QPainter painter(this);
0117     painter.setPen(m_skin->titleBarTextColor());
0118 
0119     const QPixmap &backgroundImage = m_skin->titleBarBackgroundImage();
0120     const QPixmap &leftCornerImage = m_skin->titleBarLeftCornerImage();
0121     const QPixmap &rightCornerImage = m_skin->titleBarRightCornerImage();
0122 
0123     painter.drawTiledPixmap(leftCornerImage.width(), 0, width() - leftCornerImage.width() - rightCornerImage.width(), height(), backgroundImage);
0124 
0125     painter.drawPixmap(0, 0, leftCornerImage);
0126     painter.drawPixmap(width() - rightCornerImage.width(), 0, rightCornerImage);
0127 
0128     QFont font = QFontDatabase::systemFont(QFontDatabase::TitleFont);
0129     font.setBold(m_skin->titleBarTextBold());
0130     painter.setFont(font);
0131 
0132     const QString titleAsString = this->title();
0133     if (m_skin->titleBarTextCentered()
0134         && width() > m_skin->titleBarTextPosition().x() + painter.fontMetrics().horizontalAdvance(titleAsString) + m_focusButton->width()
0135                 + m_quitButton->width() + m_menuButton->width())
0136         painter.drawText(0, 0, width(), height(), Qt::AlignCenter, titleAsString);
0137     else
0138         painter.drawText(m_skin->titleBarTextPosition(), titleAsString);
0139 
0140     painter.end();
0141 }
0142 
0143 void TitleBar::mouseMoveEvent(QMouseEvent *event)
0144 {
0145     if (event->buttons() == Qt::LeftButton) {
0146         // Dynamic cast needed to use getDesktopGeometry()
0147         MainWindow *window = dynamic_cast<MainWindow *>(parent());
0148 
0149         int maxHeight = window->getDesktopGeometry().height();
0150         int newHeight = event->globalY() / (maxHeight / 100);
0151 
0152         // Correct newHeight if mouse is dragged too far
0153         if (newHeight > 100) {
0154             newHeight = 100;
0155         } else if (newHeight < 10) {
0156             newHeight = 10;
0157         }
0158 
0159         window->setWindowHeight(newHeight);
0160     } else {
0161         QWidget::mouseMoveEvent(event);
0162     }
0163 }
0164 
0165 void TitleBar::updateMask()
0166 {
0167     const QPixmap &leftCornerImage = m_skin->titleBarLeftCornerImage();
0168     const QPixmap &rightCornerImage = m_skin->titleBarRightCornerImage();
0169 
0170     QRegion leftCornerRegion = leftCornerImage.hasAlpha() ? QRegion(leftCornerImage.mask()) : QRegion(leftCornerImage.rect());
0171     QRegion rightCornerRegion = rightCornerImage.hasAlpha() ? QRegion(rightCornerImage.mask()) : QRegion(rightCornerImage.rect());
0172 
0173     QRegion mask = leftCornerRegion;
0174 
0175     mask += QRegion(QRect(0, 0, width() - leftCornerImage.width() - rightCornerImage.width(), height())).translated(leftCornerImage.width(), 0);
0176 
0177     mask += rightCornerRegion.translated(width() - rightCornerImage.width(), 0);
0178 
0179     setMask(mask);
0180 }
0181 
0182 void TitleBar::updateMenu()
0183 {
0184     m_menuButton->setMenu(m_mainWindow->menu());
0185 }
0186 
0187 void TitleBar::setFocusButtonState(bool checked)
0188 {
0189     m_focusButton->setChecked(checked);
0190 }
0191 
0192 QString TitleBar::title()
0193 {
0194     if (!m_skin->titleBarText().isEmpty() && !m_title.isEmpty())
0195         return m_title + QStringLiteral(" - ") + m_skin->titleBarText();
0196     else if (!m_skin->titleBarText().isEmpty() && m_title.isEmpty())
0197         return m_skin->titleBarText();
0198     else
0199         return m_title;
0200 }
0201 
0202 void TitleBar::setTitle(const QString &title)
0203 {
0204     m_title = title;
0205 
0206     repaint();
0207 }
0208 
0209 #include "moc_titlebar.cpp"