Compare commits

...

2 Commits

Author SHA1 Message Date
cristian64
30dd1e79df DolphinQt: Use vertical tabs in Hotkey Settings dialog.
At this time, only the **Hotkey Settings** dialog will use vertical
tabs. This dialog happens to feature many tabs that, when horizontal
tabs are used, require horizontal scroll. Also, with these many tabs,
it can make good use of the vertical space that the vertical tabs
require.

| Before | After |
| ------ | ----- |
| <img width="918" height="679" alt="[Dolphin Emulator] Hotkey Settings dialog" title="[Dolphin Emulator] Hotkey Settings dialog" src="https://github.com/user-attachments/assets/7c9d9964-f36b-4872-ab52-6ebbe974a8ca" /> | <img width="1041" height="653" alt="[Dolphin Emulator] Hotkey Settings dialog with vertical tabs" title="[Dolphin Emulator] Hotkey Settings dialog with vertical tabs" src="https://github.com/user-attachments/assets/c6d875f9-f52d-4564-9d68-0555521a77fa" /> |
2025-08-30 21:50:25 +01:00
cristian64
9a359fd47c DolphinQt: Add tab widget with vertical tabs. 2025-08-30 21:50:20 +01:00
5 changed files with 110 additions and 2 deletions

View File

@ -334,6 +334,8 @@ add_executable(dolphin-emu
QtUtils/SignalBlocking.h
QtUtils/UTF8CodePointCountValidator.cpp
QtUtils/UTF8CodePointCountValidator.h
QtUtils/VerticalTabsTabWidget.cpp
QtUtils/VerticalTabsTabWidget.h
QtUtils/WindowActivationEventFilter.cpp
QtUtils/WindowActivationEventFilter.h
QtUtils/WrapInScrollArea.cpp

View File

@ -51,6 +51,7 @@
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/QtUtils/QtUtils.h"
#include "DolphinQt/QtUtils/VerticalTabsTabWidget.h"
#include "DolphinQt/QtUtils/WindowActivationEventFilter.h"
#include "DolphinQt/QtUtils/WrapInScrollArea.h"
#include "DolphinQt/Settings.h"
@ -61,7 +62,7 @@
#include "InputCommon/InputConfig.h"
MappingWindow::MappingWindow(QWidget* parent, Type type, int port_num)
: QDialog(parent), m_port(port_num)
: QDialog(parent), m_mapping_type(type), m_port(port_num)
{
setWindowTitle(tr("Port %1").arg(port_num + 1));
@ -179,7 +180,14 @@ void MappingWindow::CreateMainLayout()
{
m_main_layout = new QVBoxLayout();
m_config_layout = new QHBoxLayout();
m_tab_widget = new QTabWidget();
if (m_mapping_type == MappingWindow::Type::MAPPING_HOTKEYS)
{
m_tab_widget = new QtUtils::VerticalTabsTabWidget;
}
else
{
m_tab_widget = new QTabWidget;
}
m_button_box = new QDialogButtonBox(QDialogButtonBox::Close);
m_tab_widget->setTabBarAutoHide(true);

View File

@ -204,6 +204,7 @@
<ClCompile Include="QtUtils\QtUtils.cpp" />
<ClCompile Include="QtUtils\SetWindowDecorations.cpp" />
<ClCompile Include="QtUtils\UTF8CodePointCountValidator.cpp" />
<ClCompile Include="QtUtils\VerticalTabsTabWidget.cpp" />
<ClCompile Include="QtUtils\WindowActivationEventFilter.cpp" />
<ClCompile Include="QtUtils\WrapInScrollArea.cpp" />
<ClCompile Include="RenderWidget.cpp" />
@ -265,6 +266,7 @@
<ClInclude Include="QtUtils\QueueOnObject.h" />
<ClInclude Include="QtUtils\RunOnObject.h" />
<ClInclude Include="QtUtils\SignalBlocking.h" />
<ClInclude Include="QtUtils\VerticalTabsTabWidget.h" />
<ClInclude Include="QtUtils\WrapInScrollArea.h" />
<ClInclude Include="ResourcePackManager.h" />
<ClInclude Include="Resources.h" />

View File

@ -0,0 +1,77 @@
// Copyright 2025 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "DolphinQt/QtUtils/VerticalTabsTabWidget.h"
#include <QStyleOptionTab>
#include <QStylePainter>
namespace
{
class HorizontalTabBar : public QTabBar
{
public:
explicit HorizontalTabBar(QWidget* const parent = nullptr) : QTabBar(parent)
{
setUsesScrollButtons(false);
}
protected:
QSize tabSizeHint(const int index) const override
{
return QTabBar::tabSizeHint(index).transposed();
}
void paintEvent(QPaintEvent* const event) override
{
QStylePainter painter(this);
const int current_tab_index{currentIndex()};
const int tab_count{count()};
for (int i{0}; i < tab_count; ++i)
{
if (i != current_tab_index)
paintTab(painter, i);
}
// Current tab is painted last as, depending on the [system] style, it is possible that the
// decoration is required to occlude the adjacent tab underneath.
paintTab(painter, current_tab_index);
}
private:
void paintTab(QStylePainter& painter, const int tab_index)
{
painter.save();
QStyleOptionTab option;
initStyleOption(&option, tab_index);
painter.drawControl(QStyle::CE_TabBarTabShape, option);
const QSize size{option.rect.size().transposed()};
QRect rect(QPoint(), size);
rect.moveCenter(option.rect.center());
option.rect = rect;
const QPoint center{tabRect(tab_index).center()};
painter.translate(center);
painter.rotate(90.0);
painter.translate(-center);
painter.drawControl(QStyle::CE_TabBarTabLabel, option);
painter.restore();
}
};
} // namespace
namespace QtUtils
{
VerticalTabsTabWidget::VerticalTabsTabWidget(QWidget* const parent) : QTabWidget(parent)
{
setTabBar(new HorizontalTabBar);
setTabPosition(QTabWidget::TabPosition::West);
}
} // namespace QtUtils

View File

@ -0,0 +1,19 @@
// Copyright 2025 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <QTabWidget>
#include <QWidget>
namespace QtUtils
{
// A tab widget where tabs are drawn to the left of the pages with horizontal text.
class VerticalTabsTabWidget : public QTabWidget
{
public:
explicit VerticalTabsTabWidget(QWidget* parent = nullptr);
};
} // namespace QtUtils