#include "MainWindow.h" #include "ViewportWidget.h" #include "Document.h" #include "SketchFeature.h" #include "Feature.h" #include "ApplicationController.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include MainWindow::MainWindow(ApplicationController* appController, QWidget *parent) : QMainWindow(parent) , m_appController(appController) { qApp->installEventFilter(this); setWindowTitle("OpenCAD"); resize(1920, 1080); QMenu *fileMenu = menuBar()->addMenu("&File"); QAction *newAction = fileMenu->addAction("&New"); connect(newAction, &QAction::triggered, this, &MainWindow::newFile); QAction *openAction = fileMenu->addAction("&Open..."); connect(openAction, &QAction::triggered, this, &MainWindow::open); QAction *saveAction = fileMenu->addAction("&Save"); connect(saveAction, &QAction::triggered, this, &MainWindow::save); QAction *saveAsAction = fileMenu->addAction("Save &As..."); connect(saveAsAction, &QAction::triggered, this, &MainWindow::saveAs); QToolBar* mainToolBar = addToolBar("Main Toolbar"); mainToolBar->setMovable(false); mainToolBar->setFloatable(false); mainToolBar->setStyleSheet("QToolBar { border: 0px }"); m_tabWidget = new QTabWidget(); mainToolBar->addWidget(m_tabWidget); // --- SOLID Tab --- m_solidTab = new QWidget(); QHBoxLayout *solidLayout = new QHBoxLayout(m_solidTab); solidLayout->setContentsMargins(5, 5, 5, 5); solidLayout->setSpacing(5); solidLayout->setAlignment(Qt::AlignLeft); QToolButton *createSketchButton = new QToolButton(); createSketchButton->setText("Create Sketch"); createSketchButton->setIcon(QIcon(":/icons/create-sketch.svg")); createSketchButton->setIconSize(QSize(48, 48)); createSketchButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); connect(createSketchButton, &QToolButton::clicked, this, &MainWindow::createSketch); solidLayout->addWidget(createSketchButton); QToolButton *extrudeButton = new QToolButton(); extrudeButton->setText("Extrude"); extrudeButton->setIcon(QIcon(":/icons/extrude.svg")); extrudeButton->setIconSize(QSize(48, 48)); extrudeButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); solidLayout->addWidget(extrudeButton); m_tabWidget->addTab(m_solidTab, "SOLID"); // --- SURFACE Tab --- m_surfaceTab = new QWidget(); m_tabWidget->addTab(m_surfaceTab, "SURFACE"); // --- TOOLS Tab --- m_toolsTab = new QWidget(); m_tabWidget->addTab(m_toolsTab, "TOOLS"); // --- SKETCH Tab --- m_sketchTab = new QWidget(); QHBoxLayout *sketchLayout = new QHBoxLayout(m_sketchTab); sketchLayout->setContentsMargins(5, 5, 5, 5); sketchLayout->setSpacing(5); sketchLayout->setAlignment(Qt::AlignLeft); QToolButton *lineButton = new QToolButton(); lineButton->setText("Line"); lineButton->setIcon(QIcon(":/icons/line.svg")); lineButton->setIconSize(QSize(48, 48)); lineButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); connect(lineButton, &QToolButton::clicked, this, [this]() { m_appController->setActiveTool(ApplicationController::ToolType::Line); }); sketchLayout->addWidget(lineButton); QToolButton *rectangleButton = new QToolButton(); rectangleButton->setText("Rectangle"); rectangleButton->setIcon(QIcon(":/icons/rectangle.svg")); rectangleButton->setIconSize(QSize(48, 48)); rectangleButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); connect(rectangleButton, &QToolButton::clicked, this, [this]() { m_appController->setActiveTool(ApplicationController::ToolType::Rectangle); }); sketchLayout->addWidget(rectangleButton); QToolButton *circleButton = new QToolButton(); circleButton->setText("Circle"); circleButton->setIcon(QIcon(":/icons/circle.svg")); circleButton->setIconSize(QSize(48, 48)); circleButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); connect(circleButton, &QToolButton::clicked, this, [this]() { m_appController->setActiveTool(ApplicationController::ToolType::Circle); }); sketchLayout->addWidget(circleButton); QToolButton *saveSketchButton = new QToolButton(); saveSketchButton->setText("Save Sketch"); saveSketchButton->setIcon(QIcon(":/icons/save-sketch.svg")); saveSketchButton->setIconSize(QSize(48, 48)); saveSketchButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); connect(saveSketchButton, &QToolButton::clicked, this, &MainWindow::saveSketch); sketchLayout->addWidget(saveSketchButton); m_viewport = new ViewportWidget; setCentralWidget(m_viewport); m_appController->setMainWindow(this); Document* document = m_appController->document(); m_viewport->setDocument(document); connect(document, &Document::featureAdded, m_viewport, QOverload<>::of(&QWidget::update)); connect(document, &Document::cleared, m_viewport, QOverload<>::of(&QWidget::update)); connect(m_appController, &ApplicationController::sketchModeStarted, this, &MainWindow::enterSketchMode); connect(m_appController, &ApplicationController::sketchModeEnded, this, &MainWindow::exitSketchMode); connect(m_appController, &ApplicationController::sketchModeStarted, m_viewport, &ViewportWidget::onSketchModeStarted); connect(m_appController, &ApplicationController::sketchModeEnded, m_viewport, &ViewportWidget::onSketchModeEnded); connect(m_appController, &ApplicationController::currentFileChanged, this, &MainWindow::updateWindowTitle); connect(m_appController, &ApplicationController::activeToolChanged, m_viewport, &ViewportWidget::onActiveToolChanged); connect(m_appController, &ApplicationController::planeSelectionModeStarted, m_viewport, &ViewportWidget::onPlaneSelectionModeStarted); connect(m_viewport, &ViewportWidget::lineAdded, m_appController, &ApplicationController::addLine); connect(m_viewport, &ViewportWidget::rectangleAdded, m_appController, &ApplicationController::addRectangle); connect(m_viewport, &ViewportWidget::circleAdded, m_appController, &ApplicationController::addCircle); connect(m_viewport, &ViewportWidget::planeSelected, m_appController, &ApplicationController::onPlaneSelected); connect(m_viewport, &ViewportWidget::toolDeactivated, m_appController, [this]() { m_appController->setActiveTool(ApplicationController::ToolType::None); }); updateWindowTitle(QString()); } void MainWindow::createSketch() { m_appController->beginSketchCreation(); } void MainWindow::saveSketch() { m_appController->endSketch(); } void MainWindow::newFile() { m_appController->newDocument(); } void MainWindow::open() { m_appController->openDocument(); } bool MainWindow::save() { return m_appController->saveDocument(); } bool MainWindow::saveAs() { return m_appController->saveDocumentAs(); } void MainWindow::enterSketchMode() { m_tabWidget->removeTab(m_tabWidget->indexOf(m_toolsTab)); m_tabWidget->removeTab(m_tabWidget->indexOf(m_surfaceTab)); m_tabWidget->removeTab(m_tabWidget->indexOf(m_solidTab)); m_tabWidget->addTab(m_sketchTab, "SKETCH"); } void MainWindow::exitSketchMode() { m_tabWidget->removeTab(m_tabWidget->indexOf(m_sketchTab)); m_tabWidget->addTab(m_solidTab, "SOLID"); m_tabWidget->addTab(m_surfaceTab, "SURFACE"); m_tabWidget->addTab(m_toolsTab, "TOOLS"); } void MainWindow::updateWindowTitle(const QString& filePath) { setWindowFilePath(filePath); QString shownName = filePath; if (filePath.isEmpty()) shownName = "Untitled"; setWindowTitle(tr("%1[*] - %2").arg(QFileInfo(shownName).fileName(), tr("OpenCAD"))); } bool MainWindow::eventFilter(QObject *watched, QEvent *event) { if (m_appController->activeTool() != ApplicationController::ToolType::None && event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast(event); if (keyEvent->key() == Qt::Key_Tab || keyEvent->key() == Qt::Key_Backtab) { if (watched == m_viewport) { return false; // Let the viewport handle its own event } // Forward event to viewport and consume it QApplication::sendEvent(m_viewport, keyEvent); return true; } } return QMainWindow::eventFilter(watched, event); }