mirror of
https://github.com/logos-co/logos-basecamp.git
synced 2026-08-31 00:31:09 +00:00
214 lines
7.4 KiB
C++
214 lines
7.4 KiB
C++
#include "MainContainer.h"
|
|
#include "MainUIBackend.h"
|
|
#include "mdiview.h"
|
|
|
|
#include <QQuickWidget>
|
|
#include <QQmlEngine>
|
|
#include <QQmlContext>
|
|
#include <QQuickStyle>
|
|
#include <QVBoxLayout>
|
|
#include <QDebug>
|
|
#include <QDir>
|
|
#include <QFile>
|
|
#include <QQuickItem>
|
|
#include <QProcessEnvironment>
|
|
#include <QColor>
|
|
#include <QPalette>
|
|
|
|
MainContainer::MainContainer(LogosAPI* logosAPI, QWidget* parent)
|
|
: QWidget(parent)
|
|
, m_logosAPI(logosAPI)
|
|
, m_backend(nullptr)
|
|
, m_sidebarWidget(nullptr)
|
|
, m_contentStack(nullptr)
|
|
, m_mdiView(nullptr)
|
|
, m_contentWidget(nullptr)
|
|
{
|
|
// Set QML style
|
|
QQuickStyle::setStyle("Basic");
|
|
|
|
// Create backend
|
|
m_backend = new MainUIBackend(m_logosAPI, this);
|
|
|
|
setupUi();
|
|
|
|
// Connect section index changes
|
|
connect(m_backend, &MainUIBackend::currentActiveSectionIndexChanged,
|
|
this, &MainContainer::onViewIndexChanged);
|
|
connect(m_backend, &MainUIBackend::navigateToApps,
|
|
this, &MainContainer::onNavigateToApps);
|
|
|
|
// Connect plugin window signals to MdiView
|
|
connect(m_backend, &MainUIBackend::pluginWindowRequested,
|
|
this, &MainContainer::onPluginWindowRequested);
|
|
connect(m_backend, &MainUIBackend::pluginWindowRemoveRequested,
|
|
this, &MainContainer::onPluginWindowRemoveRequested);
|
|
connect(m_backend, &MainUIBackend::pluginWindowActivateRequested,
|
|
this, &MainContainer::onPluginWindowActivateRequested);
|
|
|
|
// When user closes a plugin window (tab/window X), notify backend to unload
|
|
connect(m_mdiView, &MdiView::pluginWindowClosed,
|
|
m_backend, &MainUIBackend::onPluginWindowClosed);
|
|
|
|
// Connect to QML signals from SidebarPanel
|
|
QObject* sidebarRoot = m_sidebarWidget->rootObject();
|
|
if (sidebarRoot) {
|
|
connect(sidebarRoot, SIGNAL(launchUIModule(QString)),
|
|
m_backend, SLOT(onAppLauncherClicked(QString)));
|
|
connect(sidebarRoot, SIGNAL(updateLauncherIndex(int)),
|
|
m_backend, SLOT(setCurrentActiveSectionIndex(int)));
|
|
}
|
|
|
|
qDebug() << "MainContainer created";
|
|
}
|
|
|
|
MainContainer::~MainContainer()
|
|
{
|
|
qDebug() << "MainContainer destroyed";
|
|
}
|
|
|
|
// Using this function to load qml files from local path instead of qrc
|
|
QUrl MainContainer::resolveQmlUrl(const QString& qmlFile)
|
|
{
|
|
QString qmlUiPath = QProcessEnvironment::systemEnvironment().value("QML_UI", "");
|
|
|
|
if (!qmlUiPath.isEmpty()) {
|
|
QDir qmlDir(qmlUiPath);
|
|
QString fullPath = qmlDir.absoluteFilePath(qmlFile);
|
|
|
|
if (QFile::exists(fullPath)) {
|
|
qDebug() << "Loading from filesystem " << fullPath;
|
|
return QUrl::fromLocalFile(fullPath);
|
|
}
|
|
}
|
|
|
|
qDebug() << "Loading from resources " << qmlFile;
|
|
QString resourcePath = "qrc:/" + qmlFile;
|
|
return QUrl(resourcePath);
|
|
}
|
|
|
|
void MainContainer::setupUi()
|
|
{
|
|
// We would likely move this to qml and use Logos.Theme instead
|
|
QColor bgColor("#171717");
|
|
// set background color
|
|
setAutoFillBackground(true);
|
|
QPalette p = palette();
|
|
p.setColor(QPalette::Window, bgColor);
|
|
setPalette(p);
|
|
|
|
// Create main horizontal layout
|
|
m_mainLayout = new QHBoxLayout(this);
|
|
m_mainLayout->setSpacing(0);
|
|
m_mainLayout->setContentsMargins(4, 0, 4, 2);
|
|
// When QML_UI is set, add it to each QML engine's import path so nested
|
|
// components (e.g. SidebarIconButton) load from disk — no rebuild for UI changes.
|
|
QString qmlUiPath = QProcessEnvironment::systemEnvironment().value("QML_UI", "");
|
|
|
|
// === SIDEBAR (QML) ===
|
|
m_sidebarWidget = new QQuickWidget(this);
|
|
m_sidebarWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
|
if (!qmlUiPath.isEmpty()) {
|
|
QString absPath = QDir(qmlUiPath).absolutePath();
|
|
m_sidebarWidget->engine()->addImportPath(absPath + "/qml");
|
|
m_sidebarWidget->engine()->addImportPath(absPath);
|
|
qDebug() << "DEV MODE: Added QML import paths:" << absPath + "/qml" << absPath;
|
|
} else {
|
|
m_sidebarWidget->engine()->addImportPath("qrc:/qml");
|
|
}
|
|
qDebug() << "Sidebar engine import paths:" << m_sidebarWidget->engine()->importPathList();
|
|
m_sidebarWidget->rootContext()->setContextProperty("backend", m_backend);
|
|
m_sidebarWidget->setSource(resolveQmlUrl("qml/panels/SidebarPanel.qml"));
|
|
m_sidebarWidget->setMinimumWidth(60);
|
|
m_sidebarWidget->setMaximumWidth(60);
|
|
// set clear color to sidebar so that rounded corners don't show white
|
|
m_sidebarWidget->setClearColor(bgColor);
|
|
|
|
// === CONTENT AREA (vertical layout with stack + app launcher) ===
|
|
QWidget* contentArea = new QWidget(this);
|
|
QVBoxLayout* contentLayout = new QVBoxLayout(contentArea);
|
|
contentLayout->setSpacing(0);
|
|
contentLayout->setContentsMargins(4, 9, 4, 4);
|
|
// Create content stack
|
|
m_contentStack = new QStackedWidget(contentArea);
|
|
m_contentStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
|
|
// Index 0: MdiView (C++ widget)
|
|
m_mdiView = new MdiView(m_contentStack);
|
|
m_contentStack->addWidget(m_mdiView);
|
|
|
|
// Index 1: QML content views (Dashboard, Modules, PackageManager, Settings)
|
|
m_contentWidget = new QQuickWidget(m_contentStack);
|
|
m_contentWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
|
if (!qmlUiPath.isEmpty()) {
|
|
QString absPath = QDir(qmlUiPath).absolutePath();
|
|
m_contentWidget->engine()->addImportPath(absPath + "/qml");
|
|
m_contentWidget->engine()->addImportPath(absPath);
|
|
} else {
|
|
m_contentWidget->engine()->addImportPath("qrc:/qml");
|
|
}
|
|
m_contentWidget->rootContext()->setContextProperty("backend", m_backend);
|
|
m_contentWidget->setSource(resolveQmlUrl("qml/views/ContentViews.qml"));
|
|
m_contentStack->addWidget(m_contentWidget);
|
|
|
|
// Add widgets to content layout
|
|
contentLayout->addWidget(m_contentStack, 1);
|
|
|
|
// Add widgets to main layout
|
|
m_mainLayout->addWidget(m_sidebarWidget);
|
|
m_mainLayout->addWidget(contentArea, 1);
|
|
|
|
// Set initial state
|
|
m_contentStack->setCurrentIndex(0); // Show MdiView by default
|
|
|
|
// Set reasonable minimum size
|
|
setMinimumSize(800, 600);
|
|
}
|
|
|
|
void MainContainer::onViewIndexChanged()
|
|
{
|
|
int sectionIndex = m_backend->currentActiveSectionIndex();
|
|
|
|
qDebug() << "MainContainer: Active section index changed to" << sectionIndex;
|
|
|
|
// Index 0 = Apps (show MdiView), Indices 1-3 = Dashboard/Modules/Settings (show QML)
|
|
if (sectionIndex == 0) {
|
|
// Apps workspace - show MdiView (C++ widget)
|
|
m_contentStack->setCurrentIndex(0);
|
|
} else {
|
|
// Dashboard, Modules, or Settings - show QML content
|
|
m_contentStack->setCurrentIndex(1);
|
|
}
|
|
}
|
|
|
|
void MainContainer::onNavigateToApps()
|
|
{
|
|
// This is called when an app is loaded and we need to switch to Apps view
|
|
m_backend->setCurrentActiveSectionIndex(0);
|
|
}
|
|
|
|
void MainContainer::onPluginWindowRequested(QWidget* widget, const QString& title)
|
|
{
|
|
if (m_mdiView && widget) {
|
|
m_mdiView->addPluginWindow(widget, title);
|
|
qDebug() << "MainContainer: Added plugin window to MdiView:" << title;
|
|
}
|
|
}
|
|
|
|
void MainContainer::onPluginWindowRemoveRequested(QWidget* widget)
|
|
{
|
|
if (m_mdiView && widget) {
|
|
m_mdiView->removePluginWindow(widget);
|
|
qDebug() << "MainContainer: Removed plugin window from MdiView";
|
|
}
|
|
}
|
|
|
|
void MainContainer::onPluginWindowActivateRequested(QWidget* widget)
|
|
{
|
|
if (m_mdiView && widget) {
|
|
m_mdiView->activatePluginWindow(widget);
|
|
qDebug() << "MainContainer: Activated plugin window in MdiView";
|
|
}
|
|
}
|
|
|