Merge pull request #2882 from aws-lumberyard-dev/Prism/RemoveTabFocus

Change Focus From Tabs in o3de.exe, Refactor Project Page Create, Sort Projects Alphabetically
monroegm-disable-blank-issue-2
AMZN-Phil 4 years ago committed by GitHub
commit 5a3c289fac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -20,8 +20,7 @@ QPushButton:focus {
QTabBar {
background-color: transparent;
}
QTabWidget::tab-bar
{
QTabWidget::tab-bar {
left: 78px; /* make room for the logo */
}
QTabBar::tab {
@ -32,27 +31,35 @@ QTabBar::tab {
margin-right:40px;
border-bottom: 3px solid transparent;
}
QTabBar::tab:text
{
QTabBar::tab:text {
text-align:left;
}
QTabWidget::pane {
background-color: #333333;
border:0 none;
}
QTabBar::tab:selected
{
QTabBar::tab:selected {
background-color: transparent;
border-bottom: 3px solid #1e70eb;
color: #1e70eb;
font-weight: 500;
}
QTabBar::tab:hover
{
QTabBar::tab:hover {
color: #1e70eb;
font-weight: 500;
}
QTabBar::tab:pressed
{
QTabBar::tab:pressed {
color: #0e60eb;
}
QTabBar::focus {
outline: 0px;
outline: none;
outline-style: none;
}
QTabBar::tab:focus {
background-color: #525252;
color: #4082eb;
}
/************** General (Forms) **************/

@ -52,6 +52,7 @@ namespace O3DE::ProjectManager
if (projectButton)
{
projectButton->SetProjectBuilding();
projectButton->SetProjectButtonAction(tr("Cancel Build"), [this] { HandleCancel(); });
if (m_lastProgress != 0)
@ -111,6 +112,10 @@ namespace O3DE::ProjectManager
emit Done(false);
return;
}
else
{
m_projectInfo.m_buildFailed = false;
}
emit Done(true);
}

@ -162,22 +162,9 @@ namespace O3DE::ProjectManager
QDesktopServices::openUrl(m_logUrl);
}
ProjectButton::ProjectButton(const ProjectInfo& projectInfo, QWidget* parent, bool processing)
ProjectButton::ProjectButton(const ProjectInfo& projectInfo, QWidget* parent)
: QFrame(parent)
, m_projectInfo(projectInfo)
{
BaseSetup();
if (processing)
{
ProcessingSetup();
}
else
{
ReadySetup();
}
}
void ProjectButton::BaseSetup()
{
setObjectName("projectButton");
@ -199,50 +186,63 @@ namespace O3DE::ProjectManager
}
m_projectImageLabel->setPixmap(QPixmap(projectPreviewPath).scaled(m_projectImageLabel->size(), Qt::KeepAspectRatioByExpanding));
m_projectFooter = new QFrame(this);
QFrame* projectFooter = new QFrame(this);
QHBoxLayout* hLayout = new QHBoxLayout();
hLayout->setContentsMargins(0, 0, 0, 0);
m_projectFooter->setLayout(hLayout);
projectFooter->setLayout(hLayout);
{
QLabel* projectNameLabel = new QLabel(m_projectInfo.GetProjectDisplayName(), this);
hLayout->addWidget(projectNameLabel);
QMenu* menu = new QMenu(this);
menu->addAction(tr("Edit Project Settings..."), this, [this]() { emit EditProject(m_projectInfo.m_path); });
menu->addAction(tr("Build"), this, [this]() { emit BuildProject(m_projectInfo); });
menu->addSeparator();
menu->addAction(tr("Open Project folder..."), this, [this]()
{
AzQtComponents::ShowFileOnDesktop(m_projectInfo.m_path);
});
menu->addSeparator();
menu->addAction(tr("Duplicate"), this, [this]() { emit CopyProject(m_projectInfo); });
menu->addSeparator();
menu->addAction(tr("Remove from O3DE"), this, [this]() { emit RemoveProject(m_projectInfo.m_path); });
menu->addAction(tr("Delete this Project"), this, [this]() { emit DeleteProject(m_projectInfo.m_path); });
m_projectMenuButton = new QPushButton(this);
m_projectMenuButton->setObjectName("projectMenuButton");
m_projectMenuButton->setMenu(menu);
hLayout->addWidget(m_projectMenuButton);
}
vLayout->addWidget(m_projectFooter);
vLayout->addWidget(projectFooter);
connect(m_projectImageLabel->GetOpenEditorButton(), &QPushButton::clicked, [this](){ emit OpenProject(m_projectInfo.m_path); });
}
void ProjectButton::ProcessingSetup()
const ProjectInfo& ProjectButton::GetProjectInfo() const
{
m_projectImageLabel->SetEnabled(false);
m_projectImageLabel->SetOverlayText(tr("Processing...\n\n"));
return m_projectInfo;
}
void ProjectButton::RestoreDefaultState()
{
m_projectImageLabel->SetEnabled(true);
m_projectImageLabel->SetOverlayText("");
m_projectMenuButton->setVisible(true);
QProgressBar* progressBar = m_projectImageLabel->GetProgressBar();
progressBar->setVisible(true);
progressBar->setVisible(false);
progressBar->setValue(0);
}
void ProjectButton::ReadySetup()
{
connect(m_projectImageLabel->GetOpenEditorButton(), &QPushButton::clicked, [this](){ emit OpenProject(m_projectInfo.m_path); });
QPushButton* projectActionButton = m_projectImageLabel->GetActionButton();
projectActionButton->setVisible(false);
if (m_actionButtonConnection)
{
disconnect(m_actionButtonConnection);
}
QMenu* menu = new QMenu(this);
menu->addAction(tr("Edit Project Settings..."), this, [this]() { emit EditProject(m_projectInfo.m_path); });
menu->addAction(tr("Build"), this, [this]() { emit BuildProject(m_projectInfo); });
menu->addSeparator();
menu->addAction(tr("Open Project folder..."), this, [this]()
{
AzQtComponents::ShowFileOnDesktop(m_projectInfo.m_path);
});
menu->addSeparator();
menu->addAction(tr("Duplicate"), this, [this]() { emit CopyProject(m_projectInfo); });
menu->addSeparator();
menu->addAction(tr("Remove from O3DE"), this, [this]() { emit RemoveProject(m_projectInfo.m_path); });
menu->addAction(tr("Delete this Project"), this, [this]() { emit DeleteProject(m_projectInfo.m_path); });
QPushButton* projectMenuButton = new QPushButton(this);
projectMenuButton->setObjectName("projectMenuButton");
projectMenuButton->setMenu(menu);
m_projectFooter->layout()->addWidget(projectMenuButton);
m_projectImageLabel->GetWarningIcon()->setVisible(false);
m_projectImageLabel->GetWarningLabel()->setVisible(false);
}
void ProjectButton::SetProjectButtonAction(const QString& text, AZStd::function<void()> lambda)
@ -292,9 +292,15 @@ namespace O3DE::ProjectManager
SetProjectButtonAction(tr("Build Project"), [this]() { emit BuildProject(m_projectInfo); });
}
void ProjectButton::BuildThisProject()
void ProjectButton::SetProjectBuilding()
{
emit BuildProject(m_projectInfo);
m_projectImageLabel->SetEnabled(false);
m_projectImageLabel->SetOverlayText(tr("Building...\n\n"));
m_projectMenuButton->setVisible(false);
QProgressBar* progressBar = m_projectImageLabel->GetProgressBar();
progressBar->setVisible(true);
progressBar->setValue(0);
}
void ProjectButton::SetLaunchButtonEnabled(bool enabled)

@ -56,13 +56,14 @@ namespace O3DE::ProjectManager
void OnLinkActivated(const QString& link);
private:
QVBoxLayout* m_buildOverlayLayout;
QLabel* m_overlayLabel;
QProgressBar* m_progressBar;
QPushButton* m_openEditorButton;
QPushButton* m_actionButton;
QLabel* m_warningText;
QLabel* m_warningIcon;
QVBoxLayout* m_buildOverlayLayout = nullptr;
QLabel* m_overlayLabel = nullptr;
QProgressBar* m_progressBar = nullptr;
QPushButton* m_openEditorButton = nullptr;
QPushButton* m_actionButton = nullptr;
QLabel* m_warningText = nullptr;
QLabel* m_warningIcon = nullptr;
QUrl m_logUrl;
bool m_enabled = true;
};
@ -73,13 +74,18 @@ namespace O3DE::ProjectManager
Q_OBJECT // AUTOMOC
public:
explicit ProjectButton(const ProjectInfo& m_projectInfo, QWidget* parent = nullptr, bool processing = false);
explicit ProjectButton(const ProjectInfo& m_projectInfo, QWidget* parent = nullptr);
~ProjectButton() = default;
const ProjectInfo& GetProjectInfo() const;
void RestoreDefaultState();
void SetProjectButtonAction(const QString& text, AZStd::function<void()> lambda);
void SetProjectBuildButtonAction();
void SetBuildLogsLink(const QUrl& logUrl);
void ShowBuildFailed(bool show, const QUrl& logUrl);
void SetProjectBuilding();
void SetLaunchButtonEnabled(bool enabled);
void SetButtonOverlayText(const QString& text);
@ -95,17 +101,14 @@ namespace O3DE::ProjectManager
void BuildProject(const ProjectInfo& projectInfo);
private:
void BaseSetup();
void ProcessingSetup();
void ReadySetup();
void enterEvent(QEvent* event) override;
void leaveEvent(QEvent* event) override;
void BuildThisProject();
ProjectInfo m_projectInfo;
LabelButton* m_projectImageLabel;
QFrame* m_projectFooter;
QLayout* m_requiresBuildLayout;
LabelButton* m_projectImageLabel = nullptr;
QPushButton* m_projectMenuButton = nullptr;
QLayout* m_requiresBuildLayout = nullptr;
QMetaObject::Connection m_actionButtonConnection;
};

@ -68,9 +68,7 @@ namespace O3DE::ProjectManager
}
ProjectsScreen::~ProjectsScreen()
{
delete m_currentBuilder;
}
QFrame* ProjectsScreen::CreateFirstTimeContent()
@ -114,10 +112,8 @@ namespace O3DE::ProjectManager
return frame;
}
QFrame* ProjectsScreen::CreateProjectsContent(QString buildProjectPath, ProjectButton** projectButton)
QFrame* ProjectsScreen::CreateProjectsContent()
{
RemoveInvalidProjects();
QFrame* frame = new QFrame(this);
frame->setObjectName("projectsContent");
{
@ -126,7 +122,7 @@ namespace O3DE::ProjectManager
layout->setContentsMargins(0, 0, 0, 0);
frame->setLayout(layout);
QFrame* header = new QFrame(this);
QFrame* header = new QFrame(frame);
QHBoxLayout* headerLayout = new QHBoxLayout();
{
QLabel* titleLabel = new QLabel(tr("My Projects"), this);
@ -150,87 +146,34 @@ namespace O3DE::ProjectManager
layout->addWidget(header);
// Get all projects and create a horizontal scrolling list of them
auto projectsResult = PythonBindingsInterface::Get()->GetProjects();
if (projectsResult.IsSuccess() && !projectsResult.GetValue().isEmpty())
{
QScrollArea* projectsScrollArea = new QScrollArea(this);
QWidget* scrollWidget = new QWidget();
FlowLayout* flowLayout = new FlowLayout(0, s_spacerSize, s_spacerSize);
scrollWidget->setLayout(flowLayout);
projectsScrollArea->setWidget(scrollWidget);
projectsScrollArea->setWidgetResizable(true);
QVector<ProjectInfo> nonProcessingProjects;
buildProjectPath = QDir::fromNativeSeparators(buildProjectPath);
for (auto& project : projectsResult.GetValue())
{
if (projectButton && !*projectButton)
{
if (QDir::fromNativeSeparators(project.m_path) == buildProjectPath)
{
*projectButton = CreateProjectButton(project, flowLayout, true);
continue;
}
}
QScrollArea* projectsScrollArea = new QScrollArea(this);
QWidget* scrollWidget = new QWidget();
nonProcessingProjects.append(project);
}
m_projectsFlowLayout = new FlowLayout(0, s_spacerSize, s_spacerSize);
scrollWidget->setLayout(m_projectsFlowLayout);
for (auto& project : nonProcessingProjects)
{
ProjectButton* projectButtonWidget = CreateProjectButton(project, flowLayout);
projectsScrollArea->setWidget(scrollWidget);
projectsScrollArea->setWidgetResizable(true);
if (BuildQueueContainsProject(project.m_path))
{
projectButtonWidget->SetProjectButtonAction(tr("Cancel Queued Build"),
[this, project]
{
UnqueueBuildProject(project);
SuggestBuildProjectMsg(project, false);
});
}
else if (RequiresBuildProjectIterator(project.m_path) != m_requiresBuild.end())
{
auto buildProjectIterator = RequiresBuildProjectIterator(project.m_path);
if (buildProjectIterator != m_requiresBuild.end())
{
if (buildProjectIterator->m_buildFailed)
{
projectButtonWidget->ShowBuildFailed(true, buildProjectIterator->m_logUrl);
}
else
{
projectButtonWidget->SetProjectBuildButtonAction();
}
}
}
}
ResetProjectsContent();
layout->addWidget(projectsScrollArea);
}
layout->addWidget(projectsScrollArea);
}
return frame;
}
ProjectButton* ProjectsScreen::CreateProjectButton(ProjectInfo& project, QLayout* flowLayout, bool processing)
ProjectButton* ProjectsScreen::CreateProjectButton(const ProjectInfo& project)
{
ProjectButton* projectButton = new ProjectButton(project, this, processing);
flowLayout->addWidget(projectButton);
if (!processing)
{
connect(projectButton, &ProjectButton::OpenProject, this, &ProjectsScreen::HandleOpenProject);
connect(projectButton, &ProjectButton::EditProject, this, &ProjectsScreen::HandleEditProject);
connect(projectButton, &ProjectButton::CopyProject, this, &ProjectsScreen::HandleCopyProject);
connect(projectButton, &ProjectButton::RemoveProject, this, &ProjectsScreen::HandleRemoveProject);
connect(projectButton, &ProjectButton::DeleteProject, this, &ProjectsScreen::HandleDeleteProject);
}
ProjectButton* projectButton = new ProjectButton(project, this);
m_projectButtons.insert(project.m_path, projectButton);
m_projectsFlowLayout->addWidget(projectButton);
connect(projectButton, &ProjectButton::OpenProject, this, &ProjectsScreen::HandleOpenProject);
connect(projectButton, &ProjectButton::EditProject, this, &ProjectsScreen::HandleEditProject);
connect(projectButton, &ProjectButton::CopyProject, this, &ProjectsScreen::HandleCopyProject);
connect(projectButton, &ProjectButton::RemoveProject, this, &ProjectsScreen::HandleRemoveProject);
connect(projectButton, &ProjectButton::DeleteProject, this, &ProjectsScreen::HandleDeleteProject);
connect(projectButton, &ProjectButton::BuildProject, this, &ProjectsScreen::QueueBuildProject);
return projectButton;
@ -238,29 +181,128 @@ namespace O3DE::ProjectManager
void ProjectsScreen::ResetProjectsContent()
{
// refresh the projects content by re-creating it for now
if (m_projectsContent)
RemoveInvalidProjects();
// Get all projects and create a vertical scrolling list of them
// Sort building and queued projects first
auto projectsResult = PythonBindingsInterface::Get()->GetProjects();
if (projectsResult.IsSuccess() && !projectsResult.GetValue().isEmpty())
{
m_stack->removeWidget(m_projectsContent);
m_projectsContent->deleteLater();
}
QVector<ProjectInfo> projectsVector = projectsResult.GetValue();
// If a project path is in this set then the button for it will be kept
QSet<QString> keepProject;
for (const ProjectInfo& project : projectsVector)
{
keepProject.insert(project.m_path);
}
m_background.load(":/Backgrounds/DefaultBackground.jpg");
// Clear flow and delete buttons for removed projects
auto projectButtonsIter = m_projectButtons.begin();
while (projectButtonsIter != m_projectButtons.end())
{
m_projectsFlowLayout->removeWidget(projectButtonsIter.value());
// Make sure to update builder with latest Project Button
if (m_currentBuilder)
{
ProjectButton* projectButtonPtr = nullptr;
if (!keepProject.contains(projectButtonsIter.key()))
{
projectButtonsIter = m_projectButtons.erase(projectButtonsIter);
}
else
{
++projectButtonsIter;
}
}
m_projectsContent = CreateProjectsContent(m_currentBuilder->GetProjectInfo().m_path, &projectButtonPtr);
m_currentBuilder->SetProjectButton(projectButtonPtr);
}
else
{
m_projectsContent = CreateProjectsContent();
QString buildProjectPath = "";
if (m_currentBuilder)
{
buildProjectPath = m_currentBuilder->GetProjectInfo().m_path;
}
// Put currently building project in front, then queued projects, then sorts alphabetically
std::sort(projectsVector.begin(), projectsVector.end(), [buildProjectPath, this](const ProjectInfo& arg1, const ProjectInfo& arg2)
{
if (arg1.m_path == buildProjectPath)
{
return true;
}
else if (arg2.m_path == buildProjectPath)
{
return false;
}
bool arg1InBuildQueue = BuildQueueContainsProject(arg1.m_path);
bool arg2InBuildQueue = BuildQueueContainsProject(arg2.m_path);
if (arg1InBuildQueue && !arg2InBuildQueue)
{
return true;
}
else if (!arg1InBuildQueue && arg2InBuildQueue)
{
return false;
}
else
{
return arg1.m_displayName.toLower() < arg2.m_displayName.toLower();
}
});
// Add any missing project buttons and restore buttons to default state
for (const ProjectInfo& project : projectsVector)
{
if (!m_projectButtons.contains(project.m_path))
{
m_projectButtons.insert(project.m_path, CreateProjectButton(project));
}
else
{
auto projectButtonIter = m_projectButtons.find(project.m_path);
if (projectButtonIter != m_projectButtons.end())
{
projectButtonIter.value()->RestoreDefaultState();
m_projectsFlowLayout->addWidget(projectButtonIter.value());
}
}
}
// Setup building button again
auto buildProjectIter = m_projectButtons.find(buildProjectPath);
if (buildProjectIter != m_projectButtons.end())
{
m_currentBuilder->SetProjectButton(buildProjectIter.value());
}
for (const ProjectInfo& project : m_buildQueue)
{
auto projectIter = m_projectButtons.find(project.m_path);
if (projectIter != m_projectButtons.end())
{
projectIter.value()->SetProjectButtonAction(
tr("Cancel Queued Build"),
[this, project]
{
UnqueueBuildProject(project);
SuggestBuildProjectMsg(project, false);
});
}
}
for (const ProjectInfo& project : m_requiresBuild)
{
auto projectIter = m_projectButtons.find(project.m_path);
if (projectIter != m_projectButtons.end())
{
if (project.m_buildFailed)
{
projectIter.value()->ShowBuildFailed(true, project.m_logUrl);
}
else
{
projectIter.value()->SetProjectBuildButtonAction();
}
}
}
}
m_stack->addWidget(m_projectsContent);
m_stack->setCurrentWidget(m_projectsContent);
}
@ -466,7 +508,7 @@ namespace O3DE::ProjectManager
if (m_buildQueue.empty() && !m_currentBuilder)
{
StartProjectBuild(projectInfo);
// Projects Content is already reset in fuction
// Projects Content is already reset in function
}
else
{
@ -491,6 +533,7 @@ namespace O3DE::ProjectManager
}
else
{
m_background.load(":/Backgrounds/DefaultBackground.jpg");
ResetProjectsContent();
}
}

@ -18,6 +18,7 @@ QT_FORWARD_DECLARE_CLASS(QPaintEvent)
QT_FORWARD_DECLARE_CLASS(QFrame)
QT_FORWARD_DECLARE_CLASS(QStackedWidget)
QT_FORWARD_DECLARE_CLASS(QLayout)
QT_FORWARD_DECLARE_CLASS(FlowLayout)
namespace O3DE::ProjectManager
{
@ -59,8 +60,8 @@ namespace O3DE::ProjectManager
private:
QFrame* CreateFirstTimeContent();
QFrame* CreateProjectsContent(QString buildProjectPath = "", ProjectButton** projectButton = nullptr);
ProjectButton* CreateProjectButton(ProjectInfo& project, QLayout* flowLayout, bool processing = false);
QFrame* CreateProjectsContent();
ProjectButton* CreateProjectButton(const ProjectInfo& project);
void ResetProjectsContent();
bool ShouldDisplayFirstTimeContent();
bool RemoveInvalidProjects();
@ -75,7 +76,9 @@ namespace O3DE::ProjectManager
QPixmap m_background;
QFrame* m_firstTimeContent = nullptr;
QFrame* m_projectsContent = nullptr;
FlowLayout* m_projectsFlowLayout = nullptr;
QStackedWidget* m_stack = nullptr;
QHash<QString, ProjectButton*> m_projectButtons;
QList<ProjectInfo> m_requiresBuild;
QQueue<ProjectInfo> m_buildQueue;
ProjectBuilderController* m_currentBuilder = nullptr;

@ -30,6 +30,7 @@ namespace O3DE::ProjectManager
// add a tab widget at the bottom of the stack
m_tabWidget = new QTabWidget();
m_tabWidget->tabBar()->setFocusPolicy(Qt::TabFocus);
m_screenStack->addWidget(m_tabWidget);
connect(m_tabWidget, &QTabWidget::currentChanged, this, &ScreensCtrl::TabChanged);
}

@ -54,6 +54,7 @@ namespace O3DE::ProjectManager
QTabWidget* tabWidget = new QTabWidget();
tabWidget->setObjectName("projectSettingsTab");
tabWidget->tabBar()->setObjectName("projectSettingsTabBar");
tabWidget->tabBar()->setFocusPolicy(Qt::TabFocus);
tabWidget->addTab(m_updateSettingsScreen, tr("General"));
QPushButton* gemsButton = new QPushButton(tr("Configure Gems"), this);

Loading…
Cancel
Save