/*************************************************************************** * Copyright (C) 2016 The Qt Company Ltd. * * Copyright (C) 2016-2021 by Ilya Kotov * * forkotov02@ya.ru * * * * This program 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 2 of the License, or * * (at your option) any later version. * * * * This program 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. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ //Based on QTabWidget class copyrighted by Qt Company Ltd. #include #include #include #include #include #include "qsuitabwidget.h" QSUiTabWidget::QSUiTabWidget(QWidget *parent) : QWidget(parent) { m_tabBar = new QSUiTabBar(this); m_tabBar->setMovable(true); m_tabBar->setExpanding(false); m_listWidget = new ListWidget(PlayListManager::instance()->selectedPlayList(), this); m_listWidget->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred, QSizePolicy::TabWidget)); setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, QSizePolicy::TabWidget)); setFocusPolicy(Qt::TabFocus); setFocusProxy(m_tabBar); m_menu = new QMenu(this); m_group = new QActionGroup(this); m_group->setExclusive(true); connect(m_tabBar, SIGNAL(tabMoved(int,int)), SIGNAL(tabMoved(int,int))); connect(m_tabBar, SIGNAL(tabMoved(int,int)), SLOT(updateActions())); connect(m_tabBar, SIGNAL(tabCloseRequested(int)), SIGNAL(tabCloseRequested(int))); connect(m_tabBar, SIGNAL(currentChanged(int)), SLOT(onCurrentChanged(int))); connect(m_menu, SIGNAL(triggered(QAction*)), SLOT(onActionTriggered(QAction*))); readSettings(); } QSUiTabBar *QSUiTabWidget::tabBar() const { return m_tabBar; } ListWidget *QSUiTabWidget::listWidget() const { return m_listWidget; } void QSUiTabWidget::setCornerWidget(QWidget *widget, Qt::Corner corner) { if (widget && widget->parentWidget() != this) widget->setParent(this); if (corner & Qt::TopRightCorner) { if (m_rightCornerWidget) m_rightCornerWidget->hide(); m_rightCornerWidget = widget; } else { if (m_leftCornerWidget) m_leftCornerWidget->hide(); m_leftCornerWidget = widget; } setUpLayout(); } void QSUiTabWidget::readSettings() { QSettings settings(Qmmp::configFile(), QSettings::IniFormat); settings.beginGroup("Simple"); m_tabBar->setTabsClosable(settings.value("pl_tabs_closable", false).toBool()); QFont tab_font = qApp->font(m_tabBar); if(!settings.value("use_system_fonts", true).toBool()) { tab_font.fromString(settings.value("pl_tabs_font", tab_font.toString()).toString()); } m_tabBar->setFont(tab_font); m_tabBar->setShape(static_cast(settings.value("pl_tab_position", QTabBar::RoundedNorth).toInt())); settings.endGroup(); m_tabBar->updateGeometry(); setUpLayout(); } QMenu *QSUiTabWidget::menu() const { return m_menu; } void QSUiTabWidget::setTabText(int index, const QString &text) { QString tabText = text; tabText.replace("&","&&"); m_tabBar->setTabText(index, tabText); m_menu->actions().at(index)->setText(tabText); } int QSUiTabWidget::addTab(const QString &label) { return insertTab(-1, label); } int QSUiTabWidget::addTab(const QIcon &icon, const QString &label) { return insertTab(-1, icon, label); } int QSUiTabWidget::insertTab(int index, const QString &label) { return insertTab(index, QIcon(), label); } int QSUiTabWidget::insertTab(int index, const QIcon &icon, const QString &label) { QString tabText = label; index = m_tabBar->insertTab(index, icon, tabText.replace("&", "&&")); setUpLayout(); tabInserted(index); return index; } void QSUiTabWidget::removeTab(int index) { m_tabBar->removeTab(index); setUpLayout(); tabRemoved(index); } void QSUiTabWidget::setTabsVisible(bool visible) { m_tabBar->setVisible(visible); } void QSUiTabWidget::setCurrentIndex(int index) { m_tabBar->setCurrentIndex(index); } void QSUiTabWidget::onCurrentChanged(int index) { emit currentChanged(index); if(index >= m_menu->actions().count()) return; m_menu->actions().at(index)->setChecked(true); } void QSUiTabWidget::onActionTriggered(QAction *action) { m_tabBar->setCurrentIndex(m_menu->actions().indexOf(action)); } void QSUiTabWidget::updateActions() { for(int i = 0; i < m_menu->actions().size(); ++i) { m_menu->actions().at(i)->setText(m_tabBar->tabText(i)); } m_menu->actions().at(m_tabBar->currentIndex())->setChecked(true); } void QSUiTabWidget::initStyleOption(QStyleOptionTabWidgetFrame *option) const { if (!option) return; option->initFrom(this); option->shape = m_tabBar->shape(); option->lineWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, nullptr, this); int exth = style()->pixelMetric(QStyle::PM_TabBarBaseHeight, nullptr, this); QSize t(0, 0); if (m_tabBar->isVisibleTo(const_cast(this))) t = m_tabBar->sizeHint(); if (m_rightCornerWidget) { const QSize rightCornerSizeHint = m_rightCornerWidget->sizeHint(); const QSize bounds(rightCornerSizeHint.width(), t.height() - exth); option->rightCornerWidgetSize = rightCornerSizeHint.boundedTo(bounds); } else { option->rightCornerWidgetSize = QSize(0, 0); } if (m_leftCornerWidget) { const QSize leftCornerSizeHint = m_leftCornerWidget->sizeHint(); const QSize bounds(leftCornerSizeHint.width(), t.height() - exth); option->leftCornerWidgetSize = leftCornerSizeHint.boundedTo(bounds); } else { option->leftCornerWidgetSize = QSize(0, 0); } option->tabBarSize = t; QRect tbRect = m_tabBar->geometry(); QRect selectedTabRect = tabBar()->tabRect(tabBar()->currentIndex()); option->tabBarRect = tbRect; selectedTabRect.moveTopLeft(selectedTabRect.topLeft() + tbRect.topLeft()); option->selectedTabRect = selectedTabRect; } void QSUiTabWidget::setUpLayout() { QStyleOptionTabWidgetFrame option; initStyleOption(&option); QRect tabRect = style()->subElementRect(QStyle::SE_TabWidgetTabBar, &option, this); m_panelRect = style()->subElementRect(QStyle::SE_TabWidgetTabPane, &option, this); QRect contentsRect = style()->subElementRect(QStyle::SE_TabWidgetTabContents, &option, this); QRect leftCornerRect = style()->subElementRect(QStyle::SE_TabWidgetLeftCorner, &option, this); QRect rightCornerRect = style()->subElementRect(QStyle::SE_TabWidgetRightCorner, &option, this); m_tabBar->setGeometry(tabRect); m_listWidget->setGeometry(contentsRect); if (m_leftCornerWidget) m_leftCornerWidget->setGeometry(leftCornerRect); if (m_rightCornerWidget) m_rightCornerWidget->setGeometry(rightCornerRect); updateGeometry(); } void QSUiTabWidget::showEvent(QShowEvent *) { setUpLayout(); } void QSUiTabWidget::resizeEvent(QResizeEvent *e) { QWidget::resizeEvent(e); setUpLayout(); } void QSUiTabWidget::paintEvent(QPaintEvent *) { if(!m_tabBar->isVisibleTo(this)) return; QStylePainter p(this); QStyleOptionTabWidgetFrame opt; initStyleOption(&opt); opt.rect = m_panelRect; p.drawPrimitive(QStyle::PE_FrameTabWidget, opt); } void QSUiTabWidget::changeEvent(QEvent *ev) { if (ev->type() == QEvent::StyleChange #ifdef Q_OS_MAC || ev->type() == QEvent::MacSizeChange #endif ) setUpLayout(); QWidget::changeEvent(ev); } bool QSUiTabWidget::event(QEvent *ev) { if (ev->type() == QEvent::LayoutRequest) setUpLayout(); return QWidget::event(ev); } void QSUiTabWidget::tabInserted(int index) { QAction *action = new QAction(m_menu); action->setCheckable(true); action->setActionGroup(m_group); action->setText(m_tabBar->tabText(index)); if(m_menu->actions().isEmpty() || index == m_menu->actions().count()) { m_menu->addAction(action); } else { QAction *before = m_menu->actions().at(index); m_menu->insertAction(before, action); } if(m_tabBar->currentIndex() == index) action->setChecked(true); } void QSUiTabWidget::tabRemoved(int index) { QAction *a = m_menu->actions().at(index); m_menu->removeAction(a); delete a; } void QSUiTabWidget::mousePressEvent(QMouseEvent *e) { if((e->button() == Qt::MidButton) && (childAt(e->pos()) == nullptr)) { e->accept(); emit createPlayListRequested(); } QWidget::mousePressEvent(e); } void QSUiTabWidget::mouseDoubleClickEvent(QMouseEvent *e) { if((e->button() == Qt::LeftButton) && (childAt(e->pos()) == nullptr)) { e->accept(); emit createPlayListRequested(); } QWidget::mouseDoubleClickEvent(e); }