DolphinQt: Make WrapInScrollArea and GetWrappedWidget less hacky.

This commit is contained in:
Jordan Woyak
2025-05-12 22:17:49 -05:00
parent e796e82e8c
commit 543b85a451
18 changed files with 93 additions and 82 deletions

View File

@ -56,20 +56,21 @@ void AchievementsWindow::CreateMainLayout()
m_settings_widget = new AchievementSettingsWidget(m_tab_widget);
m_progress_widget = new AchievementProgressWidget(m_tab_widget);
m_leaderboard_widget = new AchievementLeaderboardWidget(m_tab_widget);
m_tab_widget->addTab(GetWrappedWidget(m_settings_widget, this, 125, 100), tr("Settings"));
m_tab_widget->addTab(GetWrappedWidget(m_progress_widget, this, 125, 100), tr("Progress"));
m_tab_widget->setTabVisible(1, is_game_loaded);
m_tab_widget->addTab(GetWrappedWidget(m_leaderboard_widget, this, 125, 100), tr("Leaderboards"));
m_tab_widget->setTabVisible(2, is_game_loaded);
m_tab_widget->addTab(GetWrappedWidget(m_settings_widget), tr("Settings"));
m_tab_widget->addTab(GetWrappedWidget(m_progress_widget), tr("Progress"));
m_tab_widget->addTab(GetWrappedWidget(m_leaderboard_widget), tr("Leaderboards"));
m_button_box = new QDialogButtonBox(QDialogButtonBox::Close);
auto* layout = new QVBoxLayout();
auto* const layout = new QVBoxLayout{this};
layout->addWidget(m_header_widget);
layout->addWidget(m_tab_widget);
layout->addWidget(m_button_box);
WrapInScrollArea(this, layout);
adjustSize();
m_tab_widget->setTabVisible(1, is_game_loaded);
m_tab_widget->setTabVisible(2, is_game_loaded);
}
void AchievementsWindow::ConnectWidgets()

View File

@ -18,14 +18,12 @@
#include "Common/StringUtil.h"
#include "Core/CheatSearch.h"
#include "Core/Config/MainSettings.h"
#include "Core/Core.h"
#include "Core/HW/Memmap.h"
#include "Core/PowerPC/MMU.h"
#include "Core/System.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/QtUtils/WrapInScrollArea.h"
CheatSearchFactoryWidget::CheatSearchFactoryWidget()
{
@ -40,7 +38,7 @@ Q_DECLARE_METATYPE(Cheats::DataType);
void CheatSearchFactoryWidget::CreateWidgets()
{
auto* layout = new QVBoxLayout();
auto* const layout = new QVBoxLayout{this};
auto* address_space_group = new QGroupBox(tr("Address Space"));
auto* address_space_layout = new QVBoxLayout();
@ -124,8 +122,6 @@ void CheatSearchFactoryWidget::CreateWidgets()
layout->addWidget(m_new_search);
layout->addStretch();
WrapInScrollArea(this, layout);
}
void CheatSearchFactoryWidget::ConnectWidgets()

View File

@ -3,8 +3,6 @@
#pragma once
#include <vector>
#include <QWidget>
#include "Core/CheatSearch.h"

View File

@ -249,7 +249,7 @@ void CheatSearchWidget::CreateWidgets()
checkboxes_layout->addWidget(m_autoupdate_current_values);
checkboxes_layout->setStretchFactor(m_autoupdate_current_values, 2);
QVBoxLayout* layout = new QVBoxLayout();
auto* const layout = new QVBoxLayout{this};
layout->addWidget(session_info_label);
layout->addWidget(instructions_label);
layout->addLayout(value_layout);
@ -258,8 +258,6 @@ void CheatSearchWidget::CreateWidgets()
layout->addWidget(m_info_label_1);
layout->addWidget(m_info_label_2);
layout->addWidget(m_address_table);
WrapInScrollArea(this, layout);
}
void CheatSearchWidget::ConnectWidgets()

View File

@ -5,19 +5,13 @@
#include <QWidget>
#include <functional>
#include <optional>
#include <string>
#include <unordered_map>
#include <vector>
#include "Common/CommonTypes.h"
#include "Core/ActionReplay.h"
#include "Core/CheatSearch.h"
namespace ActionReplay
{
struct ARCode;
}
namespace Core
{
class System;
@ -57,7 +51,7 @@ public:
signals:
void ActionReplayCodeGenerated(const ActionReplay::ARCode& ar_code);
void RequestWatch(QString name, u32 address);
void ShowMemory(const u32 address);
void ShowMemory(u32 address);
private:
void CreateWidgets();

View File

@ -3,17 +3,15 @@
#include "DolphinQt/CheatsManager.h"
#include <functional>
#include <QDialogButtonBox>
#include <QVBoxLayout>
#include "Core/ActionReplay.h"
#include "Core/CheatSearch.h"
#include "Core/ConfigManager.h"
#include "Core/Core.h"
#include "UICommon/GameFile.h"
#include "DolphinQt/QtUtils/QtUtils.h"
#include "DolphinQt/QtUtils/WrapInScrollArea.h"
#include "DolphinQt/CheatSearchFactoryWidget.h"
#include "DolphinQt/CheatSearchWidget.h"
@ -36,6 +34,8 @@ CheatsManager::CheatsManager(Core::System& system, QWidget* parent)
CreateWidgets();
ConnectWidgets();
QtUtils::AdjustSizeWithinScreen(this);
auto& settings = Settings::GetQSettings();
restoreGeometry(settings.value(QStringLiteral("cheatsmanager/geometry")).toByteArray());
}
@ -124,18 +124,19 @@ void CheatsManager::CreateWidgets()
m_tab_widget = new PartiallyClosableTabWidget;
m_button_box = new QDialogButtonBox(QDialogButtonBox::Close);
int tab_index;
int tab_index = 0;
m_ar_code = new ARCodeWidget(m_game_id, m_revision, false);
tab_index = m_tab_widget->addTab(m_ar_code, tr("AR Code"));
tab_index = m_tab_widget->addTab(GetWrappedWidget(m_ar_code), tr("AR Code"));
m_tab_widget->setTabUnclosable(tab_index);
m_gecko_code = new GeckoCodeWidget(m_game_id, m_game_tdb_id, m_revision, false);
tab_index = m_tab_widget->addTab(m_gecko_code, tr("Gecko Codes"));
tab_index = m_tab_widget->addTab(GetWrappedWidget(m_gecko_code), tr("Gecko Codes"));
m_tab_widget->setTabUnclosable(tab_index);
m_cheat_search_new = new CheatSearchFactoryWidget();
tab_index = m_tab_widget->addTab(m_cheat_search_new, tr("Start New Cheat Search"));
tab_index =
m_tab_widget->addTab(GetWrappedWidget(m_cheat_search_new), tr("Start New Cheat Search"));
m_tab_widget->setTabUnclosable(tab_index);
auto* layout = new QVBoxLayout;

View File

@ -24,9 +24,6 @@
#include "DolphinQt/Config/HardcoreWarningWidget.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/QtUtils/WrapInScrollArea.h"
#include "UICommon/GameFile.h"
ARCodeWidget::ARCodeWidget(std::string game_id, u16 game_revision, bool restart_required)
: m_game_id(std::move(game_id)), m_game_revision(game_revision),
@ -77,7 +74,7 @@ void ARCodeWidget::CreateWidgets()
button_layout->addWidget(m_code_edit);
button_layout->addWidget(m_code_remove);
QVBoxLayout* layout = new QVBoxLayout;
auto* const layout = new QVBoxLayout{this};
layout->addWidget(m_warning);
#ifdef USE_RETRO_ACHIEVEMENTS
@ -85,8 +82,6 @@ void ARCodeWidget::CreateWidgets()
#endif // USE_RETRO_ACHIEVEMENTS
layout->addWidget(m_code_list);
layout->addLayout(button_layout);
WrapInScrollArea(this, layout);
}
void ARCodeWidget::ConnectWidgets()

View File

@ -9,6 +9,7 @@
#include "DolphinQt/Config/CommonControllersWidget.h"
#include "DolphinQt/Config/GamecubeControllersWidget.h"
#include "DolphinQt/Config/WiimoteControllersWidget.h"
#include "DolphinQt/QtUtils/QtUtils.h"
#include "DolphinQt/QtUtils/WrapInScrollArea.h"
ControllersWindow::ControllersWindow(QWidget* parent) : QDialog(parent)
@ -41,6 +42,7 @@ void ControllersWindow::CreateMainLayout()
layout->addWidget(m_button_box);
WrapInScrollArea(this, layout);
QtUtils::AdjustSizeWithinScreen(this);
}
void ControllersWindow::ConnectWidgets()

View File

@ -205,14 +205,11 @@ void GameConfigWidget::CreateWidgets()
auto* gfx_tabs = new QTabWidget;
gfx_tabs->addTab(GetWrappedWidget(new GeneralWidget(this, m_layer.get()), this, 125, 100),
tr("General"));
gfx_tabs->addTab(GetWrappedWidget(new EnhancementsWidget(this, m_layer.get()), this, 125, 100),
gfx_tabs->addTab(GetWrappedWidget(new GeneralWidget(this, m_layer.get())), tr("General"));
gfx_tabs->addTab(GetWrappedWidget(new EnhancementsWidget(this, m_layer.get())),
tr("Enhancements"));
gfx_tabs->addTab(GetWrappedWidget(new HacksWidget(this, m_layer.get()), this, 125, 100),
tr("Hacks"));
gfx_tabs->addTab(GetWrappedWidget(new AdvancedWidget(this, m_layer.get()), this, 125, 100),
tr("Advanced"));
gfx_tabs->addTab(GetWrappedWidget(new HacksWidget(this, m_layer.get())), tr("Hacks"));
gfx_tabs->addTab(GetWrappedWidget(new AdvancedWidget(this, m_layer.get())), tr("Advanced"));
const int editor_index = tab_widget->addTab(advanced_widget, tr("Editor"));
gfx_layout->addWidget(gfx_tabs);

View File

@ -32,8 +32,6 @@
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/QtUtils/WrapInScrollArea.h"
#include "UICommon/GameFile.h"
GeckoCodeWidget::GeckoCodeWidget(std::string game_id, std::string gametdb_id, u16 game_revision,
bool restart_required)
: m_game_id(std::move(game_id)), m_gametdb_id(std::move(gametdb_id)),
@ -105,7 +103,7 @@ void GeckoCodeWidget::CreateWidgets()
m_download_codes->setToolTip(tr("Download Codes from the WiiRD Database"));
auto* layout = new QVBoxLayout;
auto* const layout = new QVBoxLayout{this};
layout->addWidget(m_warning);
#ifdef USE_RETRO_ACHIEVEMENTS
@ -139,8 +137,6 @@ void GeckoCodeWidget::CreateWidgets()
btn_layout->addWidget(m_download_codes);
layout->addLayout(btn_layout);
WrapInScrollArea(this, layout);
}
void GeckoCodeWidget::ConnectWidgets()

View File

@ -156,8 +156,8 @@ void ColorCorrectionConfigWindow::Create()
layout->addStretch();
layout->addWidget(m_button_box);
setLayout(layout);
WrapInScrollArea(this, layout);
adjustSize();
}
void ColorCorrectionConfigWindow::ConnectWidgets()

View File

@ -12,17 +12,16 @@
#include "Common/Config/Config.h"
#include "Core/Config/MainSettings.h"
#include "Core/ConfigManager.h"
#include "DolphinQt/Config/Graphics/AdvancedWidget.h"
#include "DolphinQt/Config/Graphics/EnhancementsWidget.h"
#include "DolphinQt/Config/Graphics/GeneralWidget.h"
#include "DolphinQt/Config/Graphics/HacksWidget.h"
#include "DolphinQt/MainWindow.h"
#include "DolphinQt/QtUtils/QtUtils.h"
#include "DolphinQt/QtUtils/WrapInScrollArea.h"
#include "VideoCommon/VideoBackendBase.h"
#include "VideoCommon/VideoConfig.h"
GraphicsWindow::GraphicsWindow(MainWindow* parent) : QDialog(parent), m_main_window(parent)
{
@ -32,6 +31,8 @@ GraphicsWindow::GraphicsWindow(MainWindow* parent) : QDialog(parent), m_main_win
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
OnBackendChanged(QString::fromStdString(Config::Get(Config::MAIN_GFX_BACKEND)));
QtUtils::AdjustSizeWithinScreen(this);
}
void GraphicsWindow::CreateMainLayout()
@ -52,10 +53,10 @@ void GraphicsWindow::CreateMainLayout()
connect(general_widget, &GeneralWidget::BackendChanged, this, &GraphicsWindow::OnBackendChanged);
QWidget* const wrapped_general = GetWrappedWidget(general_widget, this, 50, 100);
QWidget* const wrapped_enhancements = GetWrappedWidget(enhancements_widget, this, 50, 100);
QWidget* const wrapped_hacks = GetWrappedWidget(hacks_widget, this, 50, 100);
QWidget* const wrapped_advanced = GetWrappedWidget(advanced_widget, this, 50, 100);
QWidget* const wrapped_general = GetWrappedWidget(general_widget);
QWidget* const wrapped_enhancements = GetWrappedWidget(enhancements_widget);
QWidget* const wrapped_hacks = GetWrappedWidget(hacks_widget);
QWidget* const wrapped_advanced = GetWrappedWidget(advanced_widget);
tab_widget->addTab(wrapped_general, tr("General"));
tab_widget->addTab(wrapped_enhancements, tr("Enhancements"));

View File

@ -50,6 +50,7 @@
#include "DolphinQt/Config/Mapping/WiimoteEmuMotionControlIMU.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h"
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
#include "DolphinQt/QtUtils/QtUtils.h"
#include "DolphinQt/QtUtils/SetWindowDecorations.h"
#include "DolphinQt/QtUtils/WindowActivationEventFilter.h"
#include "DolphinQt/QtUtils/WrapInScrollArea.h"
@ -96,6 +97,8 @@ MappingWindow::MappingWindow(QWidget* parent, Type type, int port_num)
[] { HotkeyManagerEmu::Enable(false); });
MappingCommon::CreateMappingProcessor(this);
QtUtils::AdjustSizeWithinScreen(this);
}
void MappingWindow::CreateDevicesLayout()
@ -543,7 +546,7 @@ void MappingWindow::PopulateProfileSelection()
QWidget* MappingWindow::AddWidget(const QString& name, QWidget* widget)
{
QWidget* wrapper = GetWrappedWidget(widget, this, 150, 210);
auto* const wrapper = GetWrappedWidget(widget);
m_tab_widget->addTab(wrapper, name);
return wrapper;
}

View File

@ -110,7 +110,7 @@ void StackedSettingsWindow::OnDoneCreatingPanes()
// Make sure the first item is actually selected by default.
ActivatePane(0);
// Take on the preferred size.
adjustSize();
QtUtils::AdjustSizeWithinScreen(this);
}
void StackedSettingsWindow::AddPane(QWidget* widget, const QString& name)

View File

@ -6,6 +6,7 @@
#include <QDateTimeEdit>
#include <QHBoxLayout>
#include <QLabel>
#include <QScreen>
namespace QtUtils
{
@ -35,4 +36,13 @@ QWidget* CreateIconWarning(QWidget* parent, QStyle::StandardPixmap standard_pixm
return widget;
}
void AdjustSizeWithinScreen(QWidget* widget)
{
const auto screen_size = widget->screen()->availableSize();
const auto adj_screen_size = screen_size * 9 / 10;
widget->resize(widget->sizeHint().boundedTo(adj_screen_size));
}
} // namespace QtUtils

View File

@ -16,4 +16,7 @@ void ShowFourDigitYear(QDateTimeEdit* widget);
QWidget* CreateIconWarning(QWidget* parent, QStyle::StandardPixmap standard_pixmap, QLabel* label);
// Similar to QWidget::adjustSize except maximum size is 9/10 of screen rather than 2/3.
void AdjustSizeWithinScreen(QWidget* widget);
} // namespace QtUtils

View File

@ -7,43 +7,59 @@
#include <QLayout>
#include <QPalette>
#include <QScrollArea>
#include <QScrollBar>
#include <QVBoxLayout>
#include <QWidget>
QWidget* GetWrappedWidget(QWidget* wrapped_widget, QWidget* to_resize, int margin_width,
int margin_height)
namespace
{
auto* scroll = new QScrollArea;
scroll->setWidget(wrapped_widget);
scroll->setWidgetResizable(true);
scroll->setFrameStyle(QFrame::NoFrame);
if (to_resize != nullptr)
// This scroll area prefers the size of its underlying widget.
class HintingScrollArea final : public QScrollArea
{
public:
HintingScrollArea()
{
// For some reason width() is bigger than it needs to be.
auto min_size = wrapped_widget->minimumSizeHint();
int recommended_width = min_size.width() + margin_width;
int recommended_height = min_size.height() + margin_height;
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
setWidgetResizable(true);
to_resize->resize(std::max(recommended_width, to_resize->width()),
std::max(recommended_height, to_resize->height()));
// Make things not look horrendous on Windows.
setFrameStyle(QFrame::NoFrame);
}
QSize sizeHint() const override
{
// Including the scrollbars in our hint can prevent
// a window undersized in one direction gaining unnecessary scrolling in both directions.
const auto scrollbar_padding =
QSize{verticalScrollBar()->sizeHint().width(), horizontalScrollBar()->sizeHint().height()};
const auto size_hint = widget()->sizeHint();
return size_hint + scrollbar_padding;
}
};
} // namespace
QWidget* GetWrappedWidget(QWidget* wrapped_widget)
{
auto* const scroll = new HintingScrollArea;
scroll->setWidget(wrapped_widget);
// Workaround for transparency issues on macOS. Not sure if this is still needed.
scroll->viewport()->setAutoFillBackground(false);
wrapped_widget->setAutoFillBackground(false);
return scroll;
}
void WrapInScrollArea(QWidget* parent, QLayout* wrapped_layout, QWidget* to_resize)
void WrapInScrollArea(QWidget* parent, QLayout* wrapped_layout)
{
if (to_resize == nullptr)
to_resize = parent;
auto* widget = new QWidget;
widget->setLayout(wrapped_layout);
auto* scroll_area = GetWrappedWidget(widget, to_resize, 0, 0);
auto* scroll_area = GetWrappedWidget(widget);
auto* scroll_layout = new QVBoxLayout;
scroll_layout->addWidget(scroll_area);

View File

@ -6,8 +6,8 @@
class QLayout;
class QWidget;
QWidget* GetWrappedWidget(QWidget* wrapped_widget, QWidget* to_resize = nullptr,
int margin_width = 50, int margin_height = 50);
// Puts the given widget in a QScrollArea and returns that.
QWidget* GetWrappedWidget(QWidget* wrapped_widget);
// Wrap wrapped_layout in a QScrollArea and fill the parent widget with it
void WrapInScrollArea(QWidget* parent, QLayout* wrapped_layout, QWidget* to_resize = nullptr);
// Wrap wrapped_layout in a QScrollArea and fill the parent widget with it.
void WrapInScrollArea(QWidget* parent, QLayout* wrapped_layout);