diff --git a/src/Mod/Start/Gui/FirstStartWidget.cpp b/src/Mod/Start/Gui/FirstStartWidget.cpp index b506b382e7..9a00acfbcc 100644 --- a/src/Mod/Start/Gui/FirstStartWidget.cpp +++ b/src/Mod/Start/Gui/FirstStartWidget.cpp @@ -58,6 +58,7 @@ FirstStartWidget::FirstStartWidget(QWidget* parent) void FirstStartWidget::setupUi() { auto outerLayout = gsl::owner(new QVBoxLayout(this)); + outerLayout->addStretch(); QString application = QString::fromUtf8(App::Application::Config()["ExeName"].c_str()); _welcomeLabel = gsl::owner(new QLabel); outerLayout->addWidget(_welcomeLabel); @@ -71,23 +72,16 @@ void FirstStartWidget::setupUi() outerLayout->addWidget(_themeSelectorWidget); _doneButton = gsl::owner(new QPushButton); + connect(_doneButton, &QPushButton::clicked, this, &FirstStartWidget::dismissed); auto buttonBar = gsl::owner(new QHBoxLayout); buttonBar->addStretch(); buttonBar->addWidget(_doneButton); outerLayout->addLayout(buttonBar); + outerLayout->addStretch(); - connect(_doneButton, &QPushButton::clicked, this, &FirstStartWidget::doneClicked); retranslateUi(); } -void FirstStartWidget::doneClicked() -{ - auto hGrp = App::GetApplication().GetParameterGroupByPath( - "User parameter:BaseApp/Preferences/Mod/Start"); - hGrp->SetBool("FirstStart2024", false); - this->hide(); -} - bool FirstStartWidget::eventFilter(QObject* object, QEvent* event) { if (object == this && event->type() == QEvent::LanguageChange) { diff --git a/src/Mod/Start/Gui/FirstStartWidget.h b/src/Mod/Start/Gui/FirstStartWidget.h index 0965d80424..7a5b4505c6 100644 --- a/src/Mod/Start/Gui/FirstStartWidget.h +++ b/src/Mod/Start/Gui/FirstStartWidget.h @@ -42,11 +42,11 @@ class FirstStartWidget: public QGroupBox public: explicit FirstStartWidget(QWidget* parent = nullptr); bool eventFilter(QObject* object, QEvent* event) override; + Q_SIGNAL void dismissed(); private: void retranslateUi(); void setupUi(); - void doneClicked(); ThemeSelectorWidget* _themeSelectorWidget; GeneralSettingsWidget* _generalSettingsWidget; diff --git a/src/Mod/Start/Gui/StartView.cpp b/src/Mod/Start/Gui/StartView.cpp index fc245fc65a..481e142398 100644 --- a/src/Mod/Start/Gui/StartView.cpp +++ b/src/Mod/Start/Gui/StartView.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #endif #include "StartView.h" @@ -68,7 +69,7 @@ gsl::owner createNewButton(const NewButton& newButton) { auto hGrp = App::GetApplication().GetParameterGroupByPath( "User parameter:BaseApp/Preferences/Mod/Start"); - const auto cardSpacing = static_cast(hGrp->GetInt("FileCardSpacing", 20)); // NOLINT + const auto cardSpacing = static_cast(hGrp->GetInt("FileCardSpacing", 25)); // NOLINT const auto newFileIconSize = static_cast(hGrp->GetInt("NewFileIconSize", 48)); // NOLINT const auto cardLabelWith = static_cast(hGrp->GetInt("FileCardLabelWith", 180)); // NOLINT @@ -82,7 +83,8 @@ gsl::owner createNewButton(const NewButton& newButton) auto textLayout = gsl::owner(new QVBoxLayout); auto textLabelLine1 = gsl::owner(new QLabel(button)); - textLabelLine1->setText(QLatin1String("") + newButton.heading + QLatin1String("")); + textLabelLine1->setText(newButton.heading); + textLabelLine1->setStyleSheet(QLatin1String("font-weight: bold;")); auto textLabelLine2 = gsl::owner(new QLabel(button)); textLabelLine2->setText(newButton.description); textLabelLine2->setWordWrap(true); @@ -102,7 +104,7 @@ gsl::owner createNewButton(const NewButton& newButton) StartView::StartView(QWidget* parent) : Gui::MDIView(nullptr, parent) - , _contents(new QScrollArea(parent)) + , _contents(new QStackedWidget(parent)) , _newFileLabel {nullptr} , _examplesLabel {nullptr} , _recentFilesLabel {nullptr} @@ -111,73 +113,90 @@ StartView::StartView(QWidget* parent) setObjectName(QLatin1String("StartView")); auto hGrp = App::GetApplication().GetParameterGroupByPath( "User parameter:BaseApp/Preferences/Mod/Start"); - auto cardSpacing = hGrp->GetInt("FileCardSpacing", 30); // NOLINT + auto cardSpacing = hGrp->GetInt("FileCardSpacing", 15); // NOLINT - auto scrolledWidget = gsl::owner(new QWidget(this)); - _contents->setWidget(scrolledWidget); - _contents->setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded); - _contents->setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded); - _contents->setWidgetResizable(true); - auto layout = gsl::owner(new QVBoxLayout(scrolledWidget)); - layout->setSizeConstraint(QLayout::SizeConstraint::SetMinAndMaxSize); + // First start page + auto firstStartScrollArea = gsl::owner(new QScrollArea()); + auto firstStartRegion = gsl::owner(new QHBoxLayout(firstStartScrollArea)); + firstStartRegion->addStretch(); + auto firstStartWidget = gsl::owner(new FirstStartWidget(this)); + connect(firstStartWidget, + &FirstStartWidget::dismissed, + this, + &StartView::firstStartWidgetDismissed); + firstStartRegion->addWidget(firstStartWidget); + firstStartRegion->addStretch(); + _contents->addWidget(firstStartScrollArea); - auto firstStart = hGrp->GetBool("FirstStart2024", true); // NOLINT - if (firstStart) { - auto firstStartRegion = gsl::owner(new QHBoxLayout); - firstStartRegion->addStretch(); - auto firstStartWidget = gsl::owner(new FirstStartWidget(this)); - firstStartRegion->addWidget(firstStartWidget); - firstStartRegion->addStretch(); - layout->addLayout(firstStartRegion); + // Documents page + auto documentsWidget = gsl::owner(new QWidget()); + _contents->addWidget(documentsWidget); + auto documentsMainLayout = gsl::owner(new QVBoxLayout()); + documentsWidget->setLayout(documentsMainLayout); + auto documentsScrollArea = gsl::owner(new QScrollArea()); + documentsScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded); + documentsMainLayout->addWidget(documentsScrollArea); + auto documentsScrollWidget = gsl::owner(new QWidget(documentsScrollArea)); + documentsScrollArea->setWidget(documentsScrollWidget); + documentsScrollArea->setWidgetResizable(true); + auto documentsContentLayout = gsl::owner(new QVBoxLayout(documentsScrollWidget)); + documentsContentLayout->setSizeConstraint(QLayout::SizeConstraint::SetMinAndMaxSize); - // Try to further differentiate the checkbox below, when the First Start box is shown - auto line = new QFrame(); - line->setFrameShape(QFrame::HLine); - line->setFrameShadow(QFrame::Sunken); - layout->addWidget(line); - } + _newFileLabel = gsl::owner(new QLabel()); + documentsContentLayout->addWidget(_newFileLabel); + + auto createNewRow = gsl::owner(new QWidget); + auto flowLayout = gsl::owner(new FlowLayout); + + // Reset margins of layout to provide consistent spacing + flowLayout->setContentsMargins({}); + + // This allows new file widgets to be targeted via QSS + createNewRow->setObjectName(QStringLiteral("CreateNewRow")); + createNewRow->setLayout(flowLayout); + + documentsContentLayout->addWidget(createNewRow); + configureNewFileButtons(flowLayout); + + _recentFilesLabel = gsl::owner(new QLabel()); + documentsContentLayout->addWidget(_recentFilesLabel); + auto recentFilesListWidget = gsl::owner(new FileCardView(_contents)); + connect(recentFilesListWidget, &QListView::clicked, this, &StartView::fileCardSelected); + documentsContentLayout->addWidget(recentFilesListWidget); + + _examplesLabel = gsl::owner(new QLabel()); + documentsContentLayout->addWidget(_examplesLabel); + auto examplesListWidget = gsl::owner(new FileCardView(_contents)); + connect(examplesListWidget, &QListView::clicked, this, &StartView::fileCardSelected); + documentsContentLayout->addWidget(examplesListWidget); + + documentsContentLayout->setSpacing(static_cast(cardSpacing)); + documentsContentLayout->addStretch(); + + // Documents page footer + auto footerLayout = gsl::owner(new QHBoxLayout()); + documentsMainLayout->addLayout(footerLayout); + + _openFirstStart = gsl::owner(new QPushButton()); + _openFirstStart->setIcon(QIcon(QLatin1String(":/icons/preferences-general.svg"))); + connect(_openFirstStart, &QPushButton::clicked, this, &StartView::openFirstStartClicked); - // Launch start automatically? _showOnStartupCheckBox = gsl::owner(new QCheckBox()); bool showOnStartup = hGrp->GetBool("ShowOnStartup", true); _showOnStartupCheckBox->setCheckState(showOnStartup ? Qt::CheckState::Unchecked : Qt::CheckState::Checked); connect(_showOnStartupCheckBox, &QCheckBox::toggled, this, &StartView::showOnStartupChanged); - layout->addWidget(_showOnStartupCheckBox); - _newFileLabel = gsl::owner(new QLabel()); - layout->addWidget(_newFileLabel); - - auto createNewRow = gsl::owner(new QWidget); - auto flowLayout = gsl::owner(new FlowLayout); - - // reset margins of layout to provide consistent spacing - flowLayout->setContentsMargins({}); - - // this allows new file widgets to be targeted via QSS - createNewRow->setObjectName(QStringLiteral("CreateNewRow")); - createNewRow->setLayout(flowLayout); - - layout->addWidget(createNewRow); - configureNewFileButtons(flowLayout); - - _recentFilesLabel = gsl::owner(new QLabel()); - layout->addWidget(_recentFilesLabel); - auto recentFilesListWidget = gsl::owner(new FileCardView(_contents)); - connect(recentFilesListWidget, &QListView::clicked, this, &StartView::fileCardSelected); - layout->addWidget(recentFilesListWidget); - - _examplesLabel = gsl::owner(new QLabel()); - layout->addWidget(_examplesLabel); - auto examplesListWidget = gsl::owner(new FileCardView(_contents)); - connect(examplesListWidget, &QListView::clicked, this, &StartView::fileCardSelected); - layout->addWidget(examplesListWidget); - - layout->setSpacing(static_cast(cardSpacing)); - layout->addStretch(); + footerLayout->addWidget(_openFirstStart); + footerLayout->addStretch(); + footerLayout->addWidget(_showOnStartupCheckBox); setCentralWidget(_contents); + // Set startup widget according to the first start parameter + auto firstStart = hGrp->GetBool("FirstStart2024", true); // NOLINT + _contents->setCurrentWidget(firstStart ? firstStartScrollArea : documentsWidget); + configureExamplesListWidget(examplesListWidget); configureRecentFilesListWidget(recentFilesListWidget, _recentFilesLabel); @@ -428,6 +447,19 @@ void StartView::showOnStartupChanged(bool checked) // original sense, so is stored inverted. } +void StartView::openFirstStartClicked() +{ + _contents->setCurrentIndex(0); +} + +void StartView::firstStartWidgetDismissed() +{ + auto hGrp = App::GetApplication().GetParameterGroupByPath( + "User parameter:BaseApp/Preferences/Mod/Start"); + hGrp->SetBool("FirstStart2024", false); + _contents->setCurrentIndex(1); +} + void StartView::changeEvent(QEvent* event) { if (event->type() == QEvent::LanguageChange) { @@ -449,6 +481,7 @@ void StartView::retranslateUi() _recentFilesLabel->setText(h1Start + tr("Recent Files") + h1End); QString application = QString::fromUtf8(App::Application::Config()["ExeName"].c_str()); + _openFirstStart->setText(tr("Open first start setup")); _showOnStartupCheckBox->setText( tr("Don't show this Start page again (start with blank screen)")); } diff --git a/src/Mod/Start/Gui/StartView.h b/src/Mod/Start/Gui/StartView.h index fe2d33167c..1c4f589551 100644 --- a/src/Mod/Start/Gui/StartView.h +++ b/src/Mod/Start/Gui/StartView.h @@ -38,6 +38,8 @@ class QGridLayout; class QLabel; class QListView; class QScrollArea; +class QStackedWidget; +class QPushButton; namespace Gui { @@ -86,20 +88,23 @@ protected: void postStart(PostStartBehavior behavior) const; void fileCardSelected(const QModelIndex& index); - void showOnStartupChanged(bool checked); + void openFirstStartClicked(); + void firstStartWidgetDismissed(); + QString fileCardStyle() const; private: void retranslateUi(); - QScrollArea* _contents = nullptr; + QStackedWidget* _contents = nullptr; Start::RecentFilesModel _recentFilesModel; Start::ExamplesModel _examplesModel; QLabel* _newFileLabel; QLabel* _examplesLabel; QLabel* _recentFilesLabel; + QPushButton* _openFirstStart; QCheckBox* _showOnStartupCheckBox;