Scaffold Qt6 Widgets app for Milestone 0
This commit is contained in:
27
CMakeLists.txt
Normal file
27
CMakeLists.txt
Normal file
@@ -0,0 +1,27 @@
|
||||
cmake_minimum_required(VERSION 3.21)
|
||||
|
||||
project(OrbitHub VERSION 0.1.0 LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
find_package(Qt6 6.2 REQUIRED COMPONENTS Widgets)
|
||||
|
||||
qt_standard_project_setup()
|
||||
|
||||
add_executable(orbithub
|
||||
src/main.cpp
|
||||
src/profiles_window.cpp
|
||||
src/profiles_window.h
|
||||
src/session_window.cpp
|
||||
src/session_window.h
|
||||
)
|
||||
|
||||
target_link_libraries(orbithub PRIVATE Qt6::Widgets)
|
||||
|
||||
install(TARGETS orbithub RUNTIME DESTINATION bin)
|
||||
13
src/main.cpp
Normal file
13
src/main.cpp
Normal file
@@ -0,0 +1,13 @@
|
||||
#include "profiles_window.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
ProfilesWindow window;
|
||||
window.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
135
src/profiles_window.cpp
Normal file
135
src/profiles_window.cpp
Normal file
@@ -0,0 +1,135 @@
|
||||
#include "profiles_window.h"
|
||||
|
||||
#include "session_window.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <QAbstractItemView>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QListWidget>
|
||||
#include <QListWidgetItem>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QStringList>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
|
||||
ProfilesWindow::ProfilesWindow(QWidget* parent)
|
||||
: QMainWindow(parent),
|
||||
m_searchBox(nullptr),
|
||||
m_profilesList(nullptr),
|
||||
m_newButton(nullptr),
|
||||
m_editButton(nullptr),
|
||||
m_deleteButton(nullptr)
|
||||
{
|
||||
setWindowTitle(QStringLiteral("OrbitHub Profiles"));
|
||||
resize(520, 620);
|
||||
|
||||
setupUi();
|
||||
populateSampleProfiles();
|
||||
}
|
||||
|
||||
void ProfilesWindow::setupUi()
|
||||
{
|
||||
auto* central = new QWidget(this);
|
||||
auto* rootLayout = new QVBoxLayout(central);
|
||||
|
||||
auto* searchLabel = new QLabel(QStringLiteral("Search"), central);
|
||||
m_searchBox = new QLineEdit(central);
|
||||
m_searchBox->setPlaceholderText(QStringLiteral("Filter profiles..."));
|
||||
|
||||
m_profilesList = new QListWidget(central);
|
||||
m_profilesList->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
|
||||
auto* buttonRow = new QHBoxLayout();
|
||||
m_newButton = new QPushButton(QStringLiteral("New"), central);
|
||||
m_editButton = new QPushButton(QStringLiteral("Edit"), central);
|
||||
m_deleteButton = new QPushButton(QStringLiteral("Delete"), central);
|
||||
|
||||
buttonRow->addWidget(m_newButton);
|
||||
buttonRow->addWidget(m_editButton);
|
||||
buttonRow->addWidget(m_deleteButton);
|
||||
buttonRow->addStretch();
|
||||
|
||||
rootLayout->addWidget(searchLabel);
|
||||
rootLayout->addWidget(m_searchBox);
|
||||
rootLayout->addWidget(m_profilesList, 1);
|
||||
rootLayout->addLayout(buttonRow);
|
||||
|
||||
setCentralWidget(central);
|
||||
|
||||
connect(m_searchBox,
|
||||
&QLineEdit::textChanged,
|
||||
this,
|
||||
[this](const QString& text) { filterProfiles(text); });
|
||||
|
||||
connect(m_profilesList,
|
||||
&QListWidget::itemDoubleClicked,
|
||||
this,
|
||||
[this](QListWidgetItem* item) { openSessionForItem(item); });
|
||||
|
||||
// Milestone 0 keeps profile management as placeholders.
|
||||
auto showTodo = [this](const QString& action) {
|
||||
QMessageBox::information(this,
|
||||
QStringLiteral("Milestone 0"),
|
||||
QStringLiteral("%1 is planned for Milestone 1.").arg(action));
|
||||
};
|
||||
|
||||
connect(m_newButton, &QPushButton::clicked, this, [showTodo]() { showTodo(QStringLiteral("New Profile")); });
|
||||
connect(m_editButton, &QPushButton::clicked, this, [showTodo]() { showTodo(QStringLiteral("Edit Profile")); });
|
||||
connect(m_deleteButton,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
[showTodo]() { showTodo(QStringLiteral("Delete Profile")); });
|
||||
}
|
||||
|
||||
void ProfilesWindow::populateSampleProfiles()
|
||||
{
|
||||
const QStringList sampleProfiles = {
|
||||
QStringLiteral("Production Bastion"),
|
||||
QStringLiteral("Staging API Host"),
|
||||
QStringLiteral("Local Lab VM"),
|
||||
QStringLiteral("CI Build Agent")};
|
||||
|
||||
m_profilesList->addItems(sampleProfiles);
|
||||
}
|
||||
|
||||
void ProfilesWindow::filterProfiles(const QString& query)
|
||||
{
|
||||
const QString trimmed = query.trimmed();
|
||||
|
||||
for (int i = 0; i < m_profilesList->count(); ++i) {
|
||||
QListWidgetItem* item = m_profilesList->item(i);
|
||||
const bool matches = trimmed.isEmpty()
|
||||
|| item->text().contains(trimmed, Qt::CaseInsensitive);
|
||||
item->setHidden(!matches);
|
||||
}
|
||||
}
|
||||
|
||||
void ProfilesWindow::openSessionForItem(QListWidgetItem* item)
|
||||
{
|
||||
if (item == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* session = new SessionWindow(item->text());
|
||||
session->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
m_sessionWindows.emplace_back(session);
|
||||
connect(session,
|
||||
&QObject::destroyed,
|
||||
this,
|
||||
[this](QObject* object) {
|
||||
m_sessionWindows.erase(
|
||||
std::remove_if(m_sessionWindows.begin(),
|
||||
m_sessionWindows.end(),
|
||||
[object](const QPointer<SessionWindow>& candidate) {
|
||||
return candidate.isNull() || candidate.data() == object;
|
||||
}),
|
||||
m_sessionWindows.end());
|
||||
});
|
||||
|
||||
session->show();
|
||||
}
|
||||
37
src/profiles_window.h
Normal file
37
src/profiles_window.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef ORBITHUB_PROFILES_WINDOW_H
|
||||
#define ORBITHUB_PROFILES_WINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QString>
|
||||
|
||||
#include <QPointer>
|
||||
#include <vector>
|
||||
|
||||
class QListWidget;
|
||||
class QListWidgetItem;
|
||||
class QLineEdit;
|
||||
class QPushButton;
|
||||
class SessionWindow;
|
||||
|
||||
class ProfilesWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ProfilesWindow(QWidget* parent = nullptr);
|
||||
|
||||
private:
|
||||
QLineEdit* m_searchBox;
|
||||
QListWidget* m_profilesList;
|
||||
QPushButton* m_newButton;
|
||||
QPushButton* m_editButton;
|
||||
QPushButton* m_deleteButton;
|
||||
std::vector<QPointer<SessionWindow>> m_sessionWindows;
|
||||
|
||||
void setupUi();
|
||||
void populateSampleProfiles();
|
||||
void filterProfiles(const QString& query);
|
||||
void openSessionForItem(QListWidgetItem* item);
|
||||
};
|
||||
|
||||
#endif
|
||||
45
src/session_window.cpp
Normal file
45
src/session_window.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#include "session_window.h"
|
||||
|
||||
#include <QFont>
|
||||
#include <QLabel>
|
||||
#include <QTabWidget>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
|
||||
SessionWindow::SessionWindow(const QString& profileName, QWidget* parent)
|
||||
: QMainWindow(parent), m_tabs(new QTabWidget(this))
|
||||
{
|
||||
setWindowTitle(QStringLiteral("OrbitHub Session - %1").arg(profileName));
|
||||
resize(900, 600);
|
||||
|
||||
setCentralWidget(m_tabs);
|
||||
addPlaceholderTab(profileName);
|
||||
}
|
||||
|
||||
void SessionWindow::addPlaceholderTab(const QString& profileName)
|
||||
{
|
||||
auto* container = new QWidget(this);
|
||||
auto* layout = new QVBoxLayout(container);
|
||||
|
||||
auto* titleLabel = new QLabel(QStringLiteral("Profile: %1").arg(profileName), container);
|
||||
auto* surfaceLabel = new QLabel(QStringLiteral("OrbitHub Native Surface"), container);
|
||||
|
||||
QFont titleFont = titleLabel->font();
|
||||
titleFont.setBold(true);
|
||||
titleLabel->setFont(titleFont);
|
||||
|
||||
QFont surfaceFont = surfaceLabel->font();
|
||||
surfaceFont.setPointSize(surfaceFont.pointSize() + 6);
|
||||
surfaceFont.setBold(true);
|
||||
surfaceLabel->setFont(surfaceFont);
|
||||
|
||||
surfaceLabel->setAlignment(Qt::AlignCenter);
|
||||
surfaceLabel->setMinimumHeight(200);
|
||||
surfaceLabel->setStyleSheet(
|
||||
QStringLiteral("border: 1px solid #8a8a8a; background-color: #f5f5f5;"));
|
||||
|
||||
layout->addWidget(titleLabel);
|
||||
layout->addWidget(surfaceLabel, 1);
|
||||
|
||||
m_tabs->addTab(container, profileName);
|
||||
}
|
||||
22
src/session_window.h
Normal file
22
src/session_window.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef ORBITHUB_SESSION_WINDOW_H
|
||||
#define ORBITHUB_SESSION_WINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QString>
|
||||
|
||||
class QTabWidget;
|
||||
|
||||
class SessionWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SessionWindow(const QString& profileName, QWidget* parent = nullptr);
|
||||
|
||||
private:
|
||||
QTabWidget* m_tabs;
|
||||
|
||||
void addPlaceholderTab(const QString& profileName);
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user