Project Manager Toolbar Update
- use flow control for projects page for automatic updates when resizing - made the first time screen only display the first timemain
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a18fae4040a22d2bb359a8ca642b97bb8f6468eeb52e2826b3b029bd8f1350b6
|
||||
size 5466
|
||||
oid sha256:40949893ed7009eeaa90b7ce6057cb6be9dfaf7b162e3c26ba9dadf985939d7d
|
||||
size 2038
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
<svg width="24" height="64" viewBox="0 0 24 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g transform="translate(0,40)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13 3H11V11H3V13H11V21H13V13H21V11H13V3Z" fill="white"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 246 B |
@ -0,0 +1,5 @@
|
||||
<svg width="24" height="64" viewBox="0 0 24 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g transform="translate(0,40)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13 3H11V11H3V13H11V21H13V13H21V11H13V3Z" fill="#1e70eb"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 248 B |
@ -0,0 +1,3 @@
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.02554 10L9 15.0362V18L0 9L9 0V2.98885L4 8H18V10H4.02554Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 228 B |
@ -0,0 +1,5 @@
|
||||
<svg width="24" height="64" viewBox="0 0 24 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g transform="translate(0,40)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.98407 4H2V6V7V19.8145H2.07539L6.02059 7.99123H19V6H11.328L9.98407 4ZM19 19.7473L22.0766 10H7.05436L3.68763 19.8329H18.973L18.9788 19.8145H19V19.7473Z" fill="white"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 358 B |
@ -0,0 +1,5 @@
|
||||
<svg width="24" height="64" viewBox="0 0 24 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g transform="translate(0,40)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.98407 4H2V6V7V19.8145H2.07539L6.02059 7.99123H19V6H11.328L9.98407 4ZM19 19.7473L22.0766 10H7.05436L3.68763 19.8329H18.973L18.9788 19.8145H19V19.7473Z" fill="#1e70eb"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 360 B |
@ -0,0 +1,11 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="3" y="16" width="5" height="5" fill="white"/>
|
||||
<rect x="9.5" y="16" width="5" height="5" fill="white"/>
|
||||
<rect x="16" y="16" width="5" height="5" fill="white"/>
|
||||
<rect x="3" y="9.5" width="5" height="5" fill="white"/>
|
||||
<rect x="9.5" y="9.5" width="5" height="5" fill="white"/>
|
||||
<rect x="19.415" y="8.58496" width="5" height="5" transform="rotate(60 19.415 8.58496)" fill="white"/>
|
||||
<rect x="3" y="3" width="5" height="5" fill="white"/>
|
||||
<rect x="8.58496" y="6.41504" width="5" height="5" transform="rotate(-60 8.58496 6.41504)" fill="white"/>
|
||||
<rect x="19.5" y="0.964844" width="5" height="5" transform="rotate(45 19.5 0.964844)" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 749 B |
@ -0,0 +1,5 @@
|
||||
<svg width="24" height="16" viewBox="0 0 24 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="1.3335" y="2.66675" width="13.3333" height="1.33333" fill="white"/>
|
||||
<rect x="1.3335" y="7.33325" width="13.3333" height="1.33333" fill="white"/>
|
||||
<rect x="1.3335" y="12" width="13.3333" height="1.33333" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 329 B |
@ -0,0 +1,5 @@
|
||||
<svg width="24" height="16" viewBox="0 0 24 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="1.3335" y="2.66675" width="13.3333" height="1.33333" fill="#1e70eb"/>
|
||||
<rect x="1.3335" y="7.33325" width="13.3333" height="1.33333" fill="#1e70eb"/>
|
||||
<rect x="1.3335" y="12" width="13.3333" height="1.33333" fill="#1e70eb"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 335 B |
@ -0,0 +1,3 @@
|
||||
<svg width="38" height="32" viewBox="0 0 38 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M33.0335 27.6364C30.2006 30.4503 26.4498 32 22.4729 32H22.4719L22.4007 31.9999C18.3948 31.9813 14.6226 30.396 11.7792 27.5358C7.98134 23.7148 6.67845 18.3374 7.86239 13.445H13.291C12.8522 14.5772 12.6238 15.7937 12.6313 17.0465C12.6466 19.6692 13.682 22.1248 15.5465 23.9605C17.4134 25.7987 19.8692 26.811 22.462 26.811L22.4897 26.8108C25.0998 26.8025 27.555 25.7736 29.4067 23.9136C31.2794 22.0326 32.3023 19.5505 32.2872 16.9246C32.2718 14.2963 31.2187 11.8234 29.3215 9.96131C27.4791 8.153 25.0581 7.16098 22.4942 7.16098C22.4558 7.16098 22.4177 7.16127 22.379 7.16171C20.9514 7.17701 19.5695 7.49947 18.3061 8.09355V2.5551C19.6438 2.16896 21.0401 1.96569 22.4658 1.96569L22.5394 1.96598C26.5556 1.98507 30.3331 3.58486 33.1758 6.47058C35.976 9.31332 37.5035 13.0777 37.4771 17.0703C37.4508 21.0641 35.8727 24.8164 33.0335 27.6364ZM1.73437 2.98423H4.71974V0H1.73437V2.98423ZM0 11.9513H4.68388V7.26925H0V11.9513ZM7.65831 10.0451H14.8796V2.82656H7.65831V10.0451Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@ -1,95 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <FirstTimeUseScreen.h>
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QIcon>
|
||||
#include <QSpacerItem>
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
FirstTimeUseScreen::FirstTimeUseScreen(QWidget* parent)
|
||||
: ScreenWidget(parent)
|
||||
{
|
||||
QVBoxLayout* vLayout = new QVBoxLayout();
|
||||
setLayout(vLayout);
|
||||
vLayout->setContentsMargins(s_contentMargins, s_contentMargins, s_contentMargins, s_contentMargins);
|
||||
|
||||
QLabel* titleLabel = new QLabel(this);
|
||||
titleLabel->setText(tr("Ready. Set. Create!"));
|
||||
titleLabel->setStyleSheet("font-size: 60px");
|
||||
vLayout->addWidget(titleLabel);
|
||||
|
||||
QLabel* introLabel = new QLabel(this);
|
||||
introLabel->setTextFormat(Qt::AutoText);
|
||||
introLabel->setText(tr("<html><head/><body><p>Welcome to O3DE! Start something new by creating a project. Not sure what to create? </p><p>Explore what\342\200\231s available by downloading our sample project.</p></body></html>"));
|
||||
introLabel->setStyleSheet("font-size: 14px");
|
||||
vLayout->addWidget(introLabel);
|
||||
|
||||
QHBoxLayout* buttonLayout = new QHBoxLayout();
|
||||
buttonLayout->setSpacing(s_buttonSpacing);
|
||||
|
||||
m_createProjectButton = CreateLargeBoxButton(QIcon(":/Add.svg"), tr("Create Project"), this);
|
||||
m_createProjectButton->setIconSize(QSize(s_iconSize, s_iconSize));
|
||||
buttonLayout->addWidget(m_createProjectButton);
|
||||
|
||||
m_addProjectButton = CreateLargeBoxButton(QIcon(":/Select_Folder.svg"), tr("Add a Project"), this);
|
||||
m_addProjectButton->setIconSize(QSize(s_iconSize, s_iconSize));
|
||||
buttonLayout->addWidget(m_addProjectButton);
|
||||
|
||||
QSpacerItem* buttonSpacer = new QSpacerItem(s_spacerSize, s_spacerSize, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
buttonLayout->addItem(buttonSpacer);
|
||||
|
||||
vLayout->addItem(buttonLayout);
|
||||
|
||||
QSpacerItem* verticalSpacer = new QSpacerItem(s_spacerSize, s_spacerSize, QSizePolicy::Minimum, QSizePolicy::Expanding);
|
||||
vLayout->addItem(verticalSpacer);
|
||||
|
||||
// Using border-image allows for scaling options background-image does not support
|
||||
setStyleSheet("O3DE--ProjectManager--ScreenWidget { border-image: url(:/Backgrounds/FirstTimeBackgroundImage.jpg) repeat repeat; }");
|
||||
|
||||
connect(m_createProjectButton, &QPushButton::pressed, this, &FirstTimeUseScreen::HandleNewProjectButton);
|
||||
connect(m_addProjectButton, &QPushButton::pressed, this, &FirstTimeUseScreen::HandleAddProjectButton);
|
||||
}
|
||||
|
||||
ProjectManagerScreen FirstTimeUseScreen::GetScreenEnum()
|
||||
{
|
||||
return ProjectManagerScreen::FirstTimeUse;
|
||||
}
|
||||
|
||||
void FirstTimeUseScreen::HandleNewProjectButton()
|
||||
{
|
||||
emit ResetScreenRequest(ProjectManagerScreen::CreateProject);
|
||||
emit ChangeScreenRequest(ProjectManagerScreen::CreateProject);
|
||||
}
|
||||
void FirstTimeUseScreen::HandleAddProjectButton()
|
||||
{
|
||||
emit ChangeScreenRequest(ProjectManagerScreen::ProjectsHome);
|
||||
}
|
||||
|
||||
QPushButton* FirstTimeUseScreen::CreateLargeBoxButton(const QIcon& icon, const QString& text, QWidget* parent)
|
||||
{
|
||||
QPushButton* largeBoxButton = new QPushButton(icon, text, parent);
|
||||
|
||||
largeBoxButton->setFixedSize(s_boxButtonWidth, s_boxButtonHeight);
|
||||
largeBoxButton->setFlat(true);
|
||||
largeBoxButton->setFocusPolicy(Qt::FocusPolicy::NoFocus);
|
||||
largeBoxButton->setStyleSheet("QPushButton { font-size: 14px; background-color: rgba(0, 0, 0, 191); }");
|
||||
|
||||
return largeBoxButton;
|
||||
}
|
||||
|
||||
} // namespace O3DE::ProjectManager
|
||||
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <ScreenWidget.h>
|
||||
#endif
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QIcon)
|
||||
QT_FORWARD_DECLARE_CLASS(QPushButton)
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
class FirstTimeUseScreen
|
||||
: public ScreenWidget
|
||||
{
|
||||
public:
|
||||
explicit FirstTimeUseScreen(QWidget* parent = nullptr);
|
||||
~FirstTimeUseScreen() = default;
|
||||
ProjectManagerScreen GetScreenEnum() override;
|
||||
|
||||
protected slots:
|
||||
void HandleNewProjectButton();
|
||||
void HandleAddProjectButton();
|
||||
|
||||
private:
|
||||
QPushButton* CreateLargeBoxButton(const QIcon& icon, const QString& text, QWidget* parent = nullptr);
|
||||
|
||||
QPushButton* m_createProjectButton;
|
||||
QPushButton* m_addProjectButton;
|
||||
|
||||
inline constexpr static int s_contentMargins = 80;
|
||||
inline constexpr static int s_buttonSpacing = 30;
|
||||
inline constexpr static int s_iconSize = 24;
|
||||
inline constexpr static int s_spacerSize = 20;
|
||||
inline constexpr static int s_boxButtonWidth = 210;
|
||||
inline constexpr static int s_boxButtonHeight = 280;
|
||||
};
|
||||
|
||||
} // namespace O3DE::ProjectManager
|
||||
@ -1,67 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ProjectManagerWindowClass</class>
|
||||
<widget class="QMainWindow" name="ProjectManagerWindowClass">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1200</width>
|
||||
<height>800</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>O3DE Project Manager</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralWidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout"/>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menuBar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1200</width>
|
||||
<height>36</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>16</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<widget class="QMenu" name="iconMenu">
|
||||
<property name="title">
|
||||
<string>Icon</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../Resources/ProjectManager.qrc">
|
||||
<normaloff>:/o3de_editor.ico</normaloff>:/o3de_editor.ico</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QMenu" name="projectsMenu">
|
||||
<property name="title">
|
||||
<string>Projects</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QMenu" name="engineMenu">
|
||||
<property name="title">
|
||||
<string>Engine</string>
|
||||
</property>
|
||||
</widget>
|
||||
<addaction name="iconMenu"/>
|
||||
<addaction name="projectsMenu"/>
|
||||
<addaction name="engineMenu"/>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../Resources/ProjectManager.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
@ -1,206 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ProjectsHomeScreen.h>
|
||||
|
||||
#include <ProjectButtonWidget.h>
|
||||
#include <PythonBindingsInterface.h>
|
||||
#include <AzCore/Platform.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
#include <AzFramework/AzFramework_Traits_Platform.h>
|
||||
#include <AzFramework/Process/ProcessCommon.h>
|
||||
#include <AzFramework/Process/ProcessWatcher.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QMenu>
|
||||
#include <QListView>
|
||||
#include <QSpacerItem>
|
||||
#include <QListWidget>
|
||||
#include <QListWidgetItem>
|
||||
#include <QFileInfo>
|
||||
#include <QScrollArea>
|
||||
#include <QMessageBox>
|
||||
#include <QTimer>
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
ProjectsHomeScreen::ProjectsHomeScreen(QWidget* parent)
|
||||
: ScreenWidget(parent)
|
||||
{
|
||||
QVBoxLayout* vLayout = new QVBoxLayout();
|
||||
setLayout(vLayout);
|
||||
vLayout->setContentsMargins(s_contentMargins, s_contentMargins, s_contentMargins, s_contentMargins);
|
||||
|
||||
QHBoxLayout* topLayout = new QHBoxLayout();
|
||||
|
||||
QLabel* titleLabel = new QLabel(this);
|
||||
titleLabel->setText("My Projects");
|
||||
titleLabel->setStyleSheet("font-size: 24px");
|
||||
topLayout->addWidget(titleLabel);
|
||||
|
||||
QSpacerItem* topSpacer = new QSpacerItem(s_spacerSize, s_spacerSize, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
topLayout->addItem(topSpacer);
|
||||
|
||||
QMenu* newProjectMenu = new QMenu(this);
|
||||
m_createNewProjectAction = newProjectMenu->addAction("Create New Project");
|
||||
m_addExistingProjectAction = newProjectMenu->addAction("Add Existing Project");
|
||||
|
||||
QPushButton* newProjectMenuButton = new QPushButton(this);
|
||||
newProjectMenuButton->setText("New Project...");
|
||||
newProjectMenuButton->setMenu(newProjectMenu);
|
||||
newProjectMenuButton->setFixedWidth(s_newProjectButtonWidth);
|
||||
newProjectMenuButton->setStyleSheet("font-size: 14px;");
|
||||
topLayout->addWidget(newProjectMenuButton);
|
||||
|
||||
vLayout->addLayout(topLayout);
|
||||
|
||||
// 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();
|
||||
QGridLayout* projectGridLayout = new QGridLayout();
|
||||
scrollWidget->setLayout(projectGridLayout);
|
||||
projectsScrollArea->setWidget(scrollWidget);
|
||||
projectsScrollArea->setWidgetResizable(true);
|
||||
|
||||
int gridIndex = 0;
|
||||
for (auto project : projectsResult.GetValue())
|
||||
{
|
||||
ProjectButton* projectButton;
|
||||
QString projectPreviewPath = project.m_path + m_projectPreviewImagePath;
|
||||
QFileInfo doesPreviewExist(projectPreviewPath);
|
||||
if (doesPreviewExist.exists() && doesPreviewExist.isFile())
|
||||
{
|
||||
projectButton = new ProjectButton(project.m_projectName, projectPreviewPath, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
projectButton = new ProjectButton(project.m_projectName, this);
|
||||
}
|
||||
|
||||
// Create rows of projects buttons s_projectButtonRowCount buttons wide
|
||||
projectGridLayout->addWidget(projectButton, gridIndex / s_projectButtonRowCount, gridIndex % s_projectButtonRowCount);
|
||||
|
||||
connect(projectButton, &ProjectButton::OpenProject, this, &ProjectsHomeScreen::HandleOpenProject);
|
||||
connect(projectButton, &ProjectButton::EditProject, this, &ProjectsHomeScreen::HandleEditProject);
|
||||
|
||||
#ifdef SHOW_ALL_PROJECT_ACTIONS
|
||||
connect(projectButton, &ProjectButton::EditProjectGems, this, &ProjectsHomeScreen::HandleEditProjectGems);
|
||||
connect(projectButton, &ProjectButton::CopyProject, this, &ProjectsHomeScreen::HandleCopyProject);
|
||||
connect(projectButton, &ProjectButton::RemoveProject, this, &ProjectsHomeScreen::HandleRemoveProject);
|
||||
connect(projectButton, &ProjectButton::DeleteProject, this, &ProjectsHomeScreen::HandleDeleteProject);
|
||||
#endif
|
||||
++gridIndex;
|
||||
}
|
||||
|
||||
vLayout->addWidget(projectsScrollArea);
|
||||
}
|
||||
|
||||
// Using border-image allows for scaling options background-image does not support
|
||||
setStyleSheet("O3DE--ProjectManager--ScreenWidget { border-image: url(:/Backgrounds/FirstTimeBackgroundImage.jpg) repeat repeat; }");
|
||||
|
||||
connect(m_createNewProjectAction, &QAction::triggered, this, &ProjectsHomeScreen::HandleNewProjectButton);
|
||||
connect(m_addExistingProjectAction, &QAction::triggered, this, &ProjectsHomeScreen::HandleAddProjectButton);
|
||||
}
|
||||
|
||||
ProjectManagerScreen ProjectsHomeScreen::GetScreenEnum()
|
||||
{
|
||||
return ProjectManagerScreen::ProjectsHome;
|
||||
}
|
||||
|
||||
void ProjectsHomeScreen::HandleNewProjectButton()
|
||||
{
|
||||
emit ResetScreenRequest(ProjectManagerScreen::CreateProject);
|
||||
emit ChangeScreenRequest(ProjectManagerScreen::CreateProject);
|
||||
}
|
||||
void ProjectsHomeScreen::HandleAddProjectButton()
|
||||
{
|
||||
// Do nothing for now
|
||||
}
|
||||
void ProjectsHomeScreen::HandleOpenProject(const QString& projectPath)
|
||||
{
|
||||
if (!projectPath.isEmpty())
|
||||
{
|
||||
AZ::IO::FixedMaxPath executableDirectory = AZ::Utils::GetExecutableDirectory();
|
||||
AZStd::string executableFilename = "Editor";
|
||||
AZ::IO::FixedMaxPath editorExecutablePath = executableDirectory / (executableFilename + AZ_TRAIT_OS_EXECUTABLE_EXTENSION);
|
||||
auto cmdPath = AZ::IO::FixedMaxPathString::format("%s -regset=\"/Amazon/AzCore/Bootstrap/project_path=%s\"", editorExecutablePath.c_str(), projectPath.toStdString().c_str());
|
||||
|
||||
AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo;
|
||||
processLaunchInfo.m_commandlineParameters = cmdPath;
|
||||
bool launchSucceeded = AzFramework::ProcessLauncher::LaunchUnwatchedProcess(processLaunchInfo);
|
||||
if (!launchSucceeded)
|
||||
{
|
||||
AZ_Error("ProjectManager", false, "Failed to launch editor");
|
||||
QMessageBox::critical( this, tr("Error"), tr("Failed to launch the Editor, please verify the project settings are valid."));
|
||||
}
|
||||
else
|
||||
{
|
||||
// prevent the user from accidentally pressing the button while the editor is launching
|
||||
// and let them know what's happening
|
||||
ProjectButton* button = qobject_cast<ProjectButton*>(sender());
|
||||
if (button)
|
||||
{
|
||||
button->SetButtonEnabled(false);
|
||||
button->SetButtonOverlayText(tr("Opening Editor..."));
|
||||
}
|
||||
|
||||
// enable the button after 3 seconds
|
||||
constexpr int waitTimeInMs = 3000;
|
||||
QTimer::singleShot(waitTimeInMs, this, [this, button] {
|
||||
if (button)
|
||||
{
|
||||
button->SetButtonEnabled(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("ProjectManager", false, "Cannot open editor because an empty project path was provided");
|
||||
QMessageBox::critical( this, tr("Error"), tr("Failed to launch the Editor because the project path is invalid."));
|
||||
}
|
||||
|
||||
}
|
||||
void ProjectsHomeScreen::HandleEditProject(const QString& projectPath)
|
||||
{
|
||||
emit NotifyCurrentProject(projectPath);
|
||||
emit ResetScreenRequest(ProjectManagerScreen::UpdateProject);
|
||||
emit ChangeScreenRequest(ProjectManagerScreen::UpdateProject);
|
||||
}
|
||||
void ProjectsHomeScreen::HandleEditProjectGems(const QString& projectPath)
|
||||
{
|
||||
emit NotifyCurrentProject(projectPath);
|
||||
emit ChangeScreenRequest(ProjectManagerScreen::GemCatalog);
|
||||
}
|
||||
void ProjectsHomeScreen::HandleCopyProject([[maybe_unused]] const QString& projectPath)
|
||||
{
|
||||
// Open file dialog and choose location for copied project then register copy with O3DE
|
||||
}
|
||||
void ProjectsHomeScreen::HandleRemoveProject([[maybe_unused]] const QString& projectPath)
|
||||
{
|
||||
// Unregister Project from O3DE
|
||||
}
|
||||
void ProjectsHomeScreen::HandleDeleteProject([[maybe_unused]] const QString& projectPath)
|
||||
{
|
||||
// Remove project from 03DE and delete from disk
|
||||
ProjectsHomeScreen::HandleRemoveProject(projectPath);
|
||||
}
|
||||
|
||||
} // namespace O3DE::ProjectManager
|
||||
@ -0,0 +1,347 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ProjectsScreen.h>
|
||||
|
||||
#include <ProjectButtonWidget.h>
|
||||
#include <PythonBindingsInterface.h>
|
||||
|
||||
#include <AzQtComponents/Components/FlowLayout.h>
|
||||
#include <AzCore/Platform.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
#include <AzFramework/AzFramework_Traits_Platform.h>
|
||||
#include <AzFramework/Process/ProcessCommon.h>
|
||||
#include <AzFramework/Process/ProcessWatcher.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QMenu>
|
||||
#include <QListView>
|
||||
#include <QSpacerItem>
|
||||
#include <QListWidget>
|
||||
#include <QListWidgetItem>
|
||||
#include <QFileInfo>
|
||||
#include <QScrollArea>
|
||||
#include <QStackedWidget>
|
||||
#include <QFrame>
|
||||
#include <QIcon>
|
||||
#include <QPixmap>
|
||||
#include <QSettings>
|
||||
#include <QMessageBox>
|
||||
#include <QTimer>
|
||||
|
||||
//#define DISPLAY_PROJECT_DEV_DATA true
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
ProjectsScreen::ProjectsScreen(QWidget* parent)
|
||||
: ScreenWidget(parent)
|
||||
{
|
||||
QVBoxLayout* vLayout = new QVBoxLayout();
|
||||
vLayout->setAlignment(Qt::AlignTop);
|
||||
vLayout->setContentsMargins(s_contentMargins, 0, s_contentMargins, 0);
|
||||
setLayout(vLayout);
|
||||
|
||||
m_background.load(":/Backgrounds/FirstTimeBackgroundImage.jpg");
|
||||
|
||||
m_stack = new QStackedWidget(this);
|
||||
|
||||
m_firstTimeContent = CreateFirstTimeContent();
|
||||
m_stack->addWidget(m_firstTimeContent);
|
||||
|
||||
m_projectsContent = CreateProjectsContent();
|
||||
m_stack->addWidget(m_projectsContent);
|
||||
|
||||
vLayout->addWidget(m_stack);
|
||||
|
||||
connect(m_createNewProjectAction, &QAction::triggered, this, &ProjectsScreen::HandleNewProjectButton);
|
||||
connect(m_addExistingProjectAction, &QAction::triggered, this, &ProjectsScreen::HandleAddProjectButton);
|
||||
}
|
||||
|
||||
QFrame* ProjectsScreen::CreateFirstTimeContent()
|
||||
{
|
||||
QFrame* frame = new QFrame(this);
|
||||
frame->setObjectName("firstTimeContent");
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->setAlignment(Qt::AlignTop);
|
||||
frame->setLayout(layout);
|
||||
|
||||
QLabel* titleLabel = new QLabel(tr("Ready. Set. Create."), this);
|
||||
titleLabel->setObjectName("titleLabel");
|
||||
layout->addWidget(titleLabel);
|
||||
|
||||
QLabel* introLabel = new QLabel(this);
|
||||
introLabel->setObjectName("introLabel");
|
||||
introLabel->setText(tr("Welcome to O3DE! Start something new by creating a project. Not sure what to create? \nExplore what's "
|
||||
"available by downloading our sample project."));
|
||||
layout->addWidget(introLabel);
|
||||
|
||||
QHBoxLayout* buttonLayout = new QHBoxLayout(this);
|
||||
buttonLayout->setAlignment(Qt::AlignLeft);
|
||||
buttonLayout->setSpacing(s_spacerSize);
|
||||
|
||||
// use a newline to force the text up
|
||||
QPushButton* createProjectButton = new QPushButton(tr("Create a Project\n"), this);
|
||||
createProjectButton->setObjectName("createProjectButton");
|
||||
buttonLayout->addWidget(createProjectButton);
|
||||
|
||||
QPushButton* addProjectButton = new QPushButton(tr("Add a Project\n"), this);
|
||||
addProjectButton->setObjectName("addProjectButton");
|
||||
buttonLayout->addWidget(addProjectButton);
|
||||
|
||||
connect(createProjectButton, &QPushButton::clicked, this, &ProjectsScreen::HandleNewProjectButton);
|
||||
connect(addProjectButton, &QPushButton::clicked, this, &ProjectsScreen::HandleAddProjectButton);
|
||||
|
||||
layout->addLayout(buttonLayout);
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
QFrame* ProjectsScreen::CreateProjectsContent()
|
||||
{
|
||||
QFrame* frame = new QFrame(this);
|
||||
frame->setObjectName("projectsContent");
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout();
|
||||
layout->setAlignment(Qt::AlignTop);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
frame->setLayout(layout);
|
||||
|
||||
QFrame* header = new QFrame(this);
|
||||
QHBoxLayout* headerLayout = new QHBoxLayout();
|
||||
{
|
||||
QLabel* titleLabel = new QLabel(tr("My Projects"), this);
|
||||
titleLabel->setObjectName("titleLabel");
|
||||
headerLayout->addWidget(titleLabel);
|
||||
|
||||
QMenu* newProjectMenu = new QMenu(this);
|
||||
m_createNewProjectAction = newProjectMenu->addAction("Create New Project");
|
||||
m_addExistingProjectAction = newProjectMenu->addAction("Add Existing Project");
|
||||
|
||||
connect(m_createNewProjectAction, &QAction::triggered, this, &ProjectsScreen::HandleNewProjectButton);
|
||||
connect(m_addExistingProjectAction, &QAction::triggered, this, &ProjectsScreen::HandleAddProjectButton);
|
||||
|
||||
QPushButton* newProjectMenuButton = new QPushButton(tr("New Project..."), this);
|
||||
newProjectMenuButton->setObjectName("newProjectButton");
|
||||
newProjectMenuButton->setMenu(newProjectMenu);
|
||||
newProjectMenuButton->setDefault(true);
|
||||
headerLayout->addWidget(newProjectMenuButton);
|
||||
}
|
||||
header->setLayout(headerLayout);
|
||||
|
||||
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);
|
||||
|
||||
#ifndef DISPLAY_PROJECT_DEV_DATA
|
||||
for (auto project : projectsResult.GetValue())
|
||||
#else
|
||||
ProjectInfo project = projectsResult.GetValue().at(0);
|
||||
for (int i = 0; i < 15; i++)
|
||||
#endif
|
||||
{
|
||||
ProjectButton* projectButton;
|
||||
QString projectPreviewPath = project.m_path + m_projectPreviewImagePath;
|
||||
QFileInfo doesPreviewExist(projectPreviewPath);
|
||||
if (doesPreviewExist.exists() && doesPreviewExist.isFile())
|
||||
{
|
||||
projectButton = new ProjectButton(project.m_projectName, projectPreviewPath, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
projectButton = new ProjectButton(project.m_projectName, this);
|
||||
}
|
||||
|
||||
flowLayout->addWidget(projectButton);
|
||||
|
||||
connect(projectButton, &ProjectButton::OpenProject, this, &ProjectsScreen::HandleOpenProject);
|
||||
connect(projectButton, &ProjectButton::EditProject, this, &ProjectsScreen::HandleEditProject);
|
||||
|
||||
#ifdef DISPLAY_PROJECT_DEV_DATA
|
||||
connect(projectButton, &ProjectButton::EditProjectGems, this, &ProjectsScreen::HandleEditProjectGems);
|
||||
connect(projectButton, &ProjectButton::CopyProject, this, &ProjectsScreen::HandleCopyProject);
|
||||
connect(projectButton, &ProjectButton::RemoveProject, this, &ProjectsScreen::HandleRemoveProject);
|
||||
connect(projectButton, &ProjectButton::DeleteProject, this, &ProjectsScreen::HandleDeleteProject);
|
||||
#endif
|
||||
}
|
||||
|
||||
layout->addWidget(projectsScrollArea);
|
||||
}
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
ProjectManagerScreen ProjectsScreen::GetScreenEnum()
|
||||
{
|
||||
return ProjectManagerScreen::Projects;
|
||||
}
|
||||
|
||||
bool ProjectsScreen::IsTab()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
QString ProjectsScreen::GetTabText()
|
||||
{
|
||||
return tr("Projects");
|
||||
}
|
||||
|
||||
void ProjectsScreen::paintEvent([[maybe_unused]] QPaintEvent* event)
|
||||
{
|
||||
// we paint the background here because qss does not support background cover scaling
|
||||
QPainter painter(this);
|
||||
|
||||
auto winSize = size();
|
||||
auto pixmapRatio = (float)m_background.width() / m_background.height();
|
||||
auto windowRatio = (float)winSize.width() / winSize.height();
|
||||
|
||||
if (pixmapRatio > windowRatio)
|
||||
{
|
||||
auto newWidth = (int)(winSize.height() * pixmapRatio);
|
||||
auto offset = (newWidth - winSize.width()) / -2;
|
||||
painter.drawPixmap(offset, 0, newWidth, winSize.height(), m_background);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto newHeight = (int)(winSize.width() / pixmapRatio);
|
||||
painter.drawPixmap(0, 0, winSize.width(), newHeight, m_background);
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectsScreen::HandleNewProjectButton()
|
||||
{
|
||||
emit ResetScreenRequest(ProjectManagerScreen::CreateProject);
|
||||
emit ChangeScreenRequest(ProjectManagerScreen::CreateProject);
|
||||
}
|
||||
void ProjectsScreen::HandleAddProjectButton()
|
||||
{
|
||||
// Do nothing for now
|
||||
}
|
||||
void ProjectsScreen::HandleOpenProject(const QString& projectPath)
|
||||
{
|
||||
if (!projectPath.isEmpty())
|
||||
{
|
||||
AZ::IO::FixedMaxPath executableDirectory = AZ::Utils::GetExecutableDirectory();
|
||||
AZStd::string executableFilename = "Editor";
|
||||
AZ::IO::FixedMaxPath editorExecutablePath = executableDirectory / (executableFilename + AZ_TRAIT_OS_EXECUTABLE_EXTENSION);
|
||||
auto cmdPath = AZ::IO::FixedMaxPathString::format("%s -regset=\"/Amazon/AzCore/Bootstrap/project_path=%s\"", editorExecutablePath.c_str(), projectPath.toStdString().c_str());
|
||||
|
||||
AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo;
|
||||
processLaunchInfo.m_commandlineParameters = cmdPath;
|
||||
bool launchSucceeded = AzFramework::ProcessLauncher::LaunchUnwatchedProcess(processLaunchInfo);
|
||||
if (!launchSucceeded)
|
||||
{
|
||||
AZ_Error("ProjectManager", false, "Failed to launch editor");
|
||||
QMessageBox::critical( this, tr("Error"), tr("Failed to launch the Editor, please verify the project settings are valid."));
|
||||
}
|
||||
else
|
||||
{
|
||||
// prevent the user from accidentally pressing the button while the editor is launching
|
||||
// and let them know what's happening
|
||||
ProjectButton* button = qobject_cast<ProjectButton*>(sender());
|
||||
if (button)
|
||||
{
|
||||
button->SetButtonEnabled(false);
|
||||
button->SetButtonOverlayText(tr("Opening Editor..."));
|
||||
}
|
||||
|
||||
// enable the button after 3 seconds
|
||||
constexpr int waitTimeInMs = 3000;
|
||||
QTimer::singleShot(waitTimeInMs, this, [this, button] {
|
||||
if (button)
|
||||
{
|
||||
button->SetButtonEnabled(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("ProjectManager", false, "Cannot open editor because an empty project path was provided");
|
||||
QMessageBox::critical( this, tr("Error"), tr("Failed to launch the Editor because the project path is invalid."));
|
||||
}
|
||||
|
||||
}
|
||||
void ProjectsScreen::HandleEditProject(const QString& projectPath)
|
||||
{
|
||||
emit NotifyCurrentProject(projectPath);
|
||||
emit ResetScreenRequest(ProjectManagerScreen::UpdateProject);
|
||||
emit ChangeScreenRequest(ProjectManagerScreen::UpdateProject);
|
||||
}
|
||||
void ProjectsScreen::HandleEditProjectGems(const QString& projectPath)
|
||||
{
|
||||
emit NotifyCurrentProject(projectPath);
|
||||
emit ChangeScreenRequest(ProjectManagerScreen::GemCatalog);
|
||||
}
|
||||
void ProjectsScreen::HandleCopyProject([[maybe_unused]] const QString& projectPath)
|
||||
{
|
||||
// Open file dialog and choose location for copied project then register copy with O3DE
|
||||
}
|
||||
void ProjectsScreen::HandleRemoveProject([[maybe_unused]] const QString& projectPath)
|
||||
{
|
||||
// Unregister Project from O3DE
|
||||
}
|
||||
void ProjectsScreen::HandleDeleteProject([[maybe_unused]] const QString& projectPath)
|
||||
{
|
||||
// Remove project from 03DE and delete from disk
|
||||
ProjectsScreen::HandleRemoveProject(projectPath);
|
||||
}
|
||||
|
||||
void ProjectsScreen::NotifyCurrentScreen()
|
||||
{
|
||||
if (ShouldDisplayFirstTimeContent())
|
||||
{
|
||||
m_stack->setCurrentWidget(m_firstTimeContent);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_stack->setCurrentWidget(m_projectsContent);
|
||||
}
|
||||
}
|
||||
|
||||
bool ProjectsScreen::ShouldDisplayFirstTimeContent()
|
||||
{
|
||||
auto projectsResult = PythonBindingsInterface::Get()->GetProjects();
|
||||
if (!projectsResult.IsSuccess() || projectsResult.GetValue().isEmpty())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
QSettings settings;
|
||||
bool displayFirstTimeContent = settings.value("displayFirstTimeContent", true).toBool();
|
||||
if (displayFirstTimeContent)
|
||||
{
|
||||
settings.setValue("displayFirstTimeContent", false);
|
||||
}
|
||||
|
||||
return displayFirstTimeContent;
|
||||
}
|
||||
|
||||
} // namespace O3DE::ProjectManager
|
||||
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ScreenHeaderWidget.h>
|
||||
#include <QHBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include <QLabel>
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
ScreenHeader::ScreenHeader(QWidget* parent)
|
||||
: QFrame(parent)
|
||||
{
|
||||
setObjectName("header");
|
||||
|
||||
QHBoxLayout* layout = new QHBoxLayout();
|
||||
layout->setAlignment(Qt::AlignLeft);
|
||||
layout->setContentsMargins(0,0,0,0);
|
||||
|
||||
m_backButton = new QPushButton();
|
||||
m_backButton->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
|
||||
layout->addWidget(m_backButton);
|
||||
|
||||
QVBoxLayout* titleLayout = new QVBoxLayout();
|
||||
m_title = new QLabel();
|
||||
m_title->setObjectName("headerTitle");
|
||||
titleLayout->addWidget(m_title);
|
||||
|
||||
m_subTitle = new QLabel();
|
||||
m_subTitle->setObjectName("headerSubTitle");
|
||||
titleLayout->addWidget(m_subTitle);
|
||||
|
||||
layout->addLayout(titleLayout);
|
||||
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
void ScreenHeader::setTitle(const QString& text)
|
||||
{
|
||||
m_title->setText(text);
|
||||
}
|
||||
|
||||
void ScreenHeader::setSubTitle(const QString& text)
|
||||
{
|
||||
m_subTitle->setText(text);
|
||||
}
|
||||
|
||||
QPushButton* ScreenHeader::backButton()
|
||||
{
|
||||
return m_backButton;
|
||||
}
|
||||
|
||||
} // namespace O3DE::ProjectManager
|
||||
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <QFrame>
|
||||
#endif
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QLabel)
|
||||
QT_FORWARD_DECLARE_CLASS(QPushButton)
|
||||
|
||||
namespace O3DE::ProjectManager
|
||||
{
|
||||
class ScreenHeader
|
||||
: public QFrame
|
||||
{
|
||||
Q_OBJECT // AUTOMOC
|
||||
|
||||
public:
|
||||
ScreenHeader(QWidget* parent = nullptr);
|
||||
|
||||
void setTitle(const QString& text);
|
||||
void setSubTitle(const QString& text);
|
||||
|
||||
QPushButton* backButton();
|
||||
|
||||
private:
|
||||
QLabel* m_title;
|
||||
QLabel* m_subTitle;
|
||||
QPushButton* m_backButton;
|
||||
};
|
||||
} // namespace O3DE::ProjectManager
|
||||
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a18fae4040a22d2bb359a8ca642b97bb8f6468eeb52e2826b3b029bd8f1350b6
|
||||
size 5466
|
||||
oid sha256:40949893ed7009eeaa90b7ce6057cb6be9dfaf7b162e3c26ba9dadf985939d7d
|
||||
size 2038
|
||||
|
||||