/
pi_coder
/
ByteMachine
Обзор
Документация
Войти
/
pi_coder
/
ByteMachine
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/forms/main_window.cpp
819 строк
29 KB
pimenov-and
Восстановление функционала старой версии
28 июл 2026, 20:04
28 июл 2026, 20:04
98412d0
Код
Авторство
О чём код?
//////////////////////////////////////////////////////////////// // ByteMachine // Главное окно //////////////////////////////////////////////////////////////// #include "main_window.h" #include "global_settings.h" #include "project.h" #include "nodes/node_helper.h" #include "nodes/forms/form_node_panel_item.h" #include "icons.h" #include <QFileDialog> #include <QFile> #include <QTextStream> //============================================================== // Конструктор с параметром //============================================================== MainWindow::MainWindow(QWidget *parent) : QMainWindow{parent} { ui_.setupUi(this); setConnections(); initNodesPanel(); // Задание оформления const QPalette palette = style()->standardPalette(); qApp->setPalette(palette); qApp->setStyleSheet(lightColorSchemeStyleSheet()); } //============================================================== // Деструктор //============================================================== MainWindow::~MainWindow() { } //============================================================== // Открыть проект //============================================================== void MainWindow::slotOpenProject() { qDebug("MainWindow::slotOpenProject"); } //============================================================== // Сохранить проект как //============================================================== void MainWindow::slotSaveProjectAs() { qDebug("MainWindow::slotSaveProjectAs"); } //============================================================== // Функция вызывается при изменении видимости панели узлов //============================================================== void MainWindow::slotNodesPanelVisibleChanged(bool visible) { Q_UNUSED(visible) } //============================================================== // Функция вызывается при изменении видимости панели свойств //============================================================== void MainWindow::slotSettingsPanelVisibleChanged(bool visible) { Q_UNUSED(visible) } //============================================================== // Функция вызывается при изменении видимости сетки дизайнера //============================================================== void MainWindow::slotDesignerGridVisible(bool visible) { Q_UNUSED(visible) } //============================================================== // Функция вызывается при изменении видимости панели Output //============================================================== void MainWindow::slotOutputPanelVisible(bool visible) { Q_UNUSED(visible) } //============================================================== // Функция вызывается при изменении видимости комментариев узлов //============================================================== void MainWindow::slotNodesCommentsVisibleChanged(bool visible) { Q_UNUSED(visible) } //============================================================== // Функция выбора английского языка интерфейса //============================================================== void MainWindow::slotSetEnglishLanguage() { qDebug("MainWindow::slotSetEnglishLanguage"); } //============================================================== // Функция выбора русского языка интерфейса //============================================================== void MainWindow::slotSetRussianLanguage() { qDebug("MainWindow::slotSetRussianLanguage"); } //============================================================== // Функция выбора светлой цветовой схемы //============================================================== void MainWindow::slotSetLightColorTheme() { qDebug("MainWindow::slotSetLightColorTheme"); } //============================================================== // Функция выбора тёмной цветовой схемы //============================================================== void MainWindow::slotSetDarkColorTheme() { qDebug("MainWindow::slotSetDarkColorTheme"); } //============================================================== // Функция вызывается при добавлении узла через панель //============================================================== void MainWindow::slotAddNodeByType(NodeTypes nodeType) { QUndoStack *undoStack = project()->undoStack(); const auto node = createNode(nodeType, undoStack); const auto selNode = project()->selectedNode(); if (selNode != nullptr) { // selNode->setSelected(false); const QPoint selTopLeft = selNode->topLeft(); node->setUndo(true); node->setTopLeft(selTopLeft + QPoint{20, 20}); node->setUndo(false); } project()->addNode(node); } //============================================================== // Функция вызывается при возникновении события //============================================================== void MainWindow::changeEvent(QEvent *event) { Q_UNUSED(event) } //============================================================== // Функция вызывается при закрытия окна //============================================================== void MainWindow::closeEvent(QCloseEvent*) { qDebug("MainWindow::closeEvent"); } //============================================================== // Задание соединений //============================================================== void MainWindow::setConnections() { // Меню "File" connect(ui_.actOpen_, &QAction::triggered, this, &MainWindow::slotOpenProject); connect(ui_.actSaveAs_, &QAction::triggered, this, &MainWindow::slotSaveProjectAs); } //============================================================== // Перевод интерфейса //============================================================== void MainWindow::retranslate() { } //============================================================== // Получение строки со стилем виджетов для светлой цветовой схемы //============================================================== [[nodiscard]] QString MainWindow::lightColorSchemeStyleSheet() const { const QString sheet = "QMenuBar::item:selected" "{" " background: rgb(133, 194, 245);" "}" "" "" "QMenu" "{" " background: rgb(240, 240, 240);" " border: 1px solid rgb(140, 140, 140);" "}" "" "" "QMenu::separator" "{" " height: 1px;" " background: rgb(180, 180, 180);" " margin-left: 5px;" " margin-right: 5px;" "}" "" "QMenu::item:selected" "{" " background-color: rgb(114, 186, 245);" "}" "" "QMenu::separator" "{" " height: 1px;" " background: rgb(200, 200, 200);" " margin-left: 5px;" " margin-right: 5px;" "}" "" "QMenu::item:disabled" "{ " " color: rgb(110, 110, 110);" "}" "" "" "QToolBox::tab" "{" " background: rgb(239, 239, 239);" " border: 1px solid rgb(180, 180, 180);" " border-radius: 3px;" "}" "" "" "QToolTip" "{" " background: white;" " border: 1px solid rgb(40, 40, 40);" "}" "" "" "QGroupBox" "{" " border: 1px solid rgb(180, 180, 180);" " margin-top: 7px;" "}" "" "QGroupBox::title" "{" " subcontrol-origin: margin;" " subcontrol-position: top left;" " left: 7px;" " margin: 0 3px;" "}"; return sheet; } //============================================================== // Получение строки со стилем виджетов для темной цветовой схемы //============================================================== [[nodiscard]] QString MainWindow::darkColorSchemeStyleSheet() const { const QString sheet = "QMenuBar::item:selected" "{" " background: rgb(80, 80, 80);" "}" "" "" "QMenu" "{" " background: rgb(53, 53, 53);" " border: 1px solid rgb(190, 190, 190);" "}" "" "QMenu::item:selected" "{" " background-color: rgb(80, 80, 80);" "}" "" "QMenu::icon:checked" "{" " background: black;" " border: 1px inset gray;" " position: absolute;" " top: 1px;" " right: 1px;" " bottom: 1px;" " left: 1px;" "}" "" "QMenu::separator" "{" " height: 1px;" "}" "" "QMenu::separator" "{" " height: 1px;" " background: rgb(100, 100, 100);" " margin-left: 5px;" " margin-right: 5px;" "}" "" "QMenu::item:disabled" "{ " " color: rgb(130, 130, 130);" "}" "" "" "QToolBox::tab" "{" " background: rgb(53, 53, 53);" " border: 1px solid rgb(110, 110, 110);" " border-radius: 3px;" "}" "" "" "QToolTip" "{" " background: rgb(55, 55, 55);" " color: rgb(210, 210, 210);" " border: 1px solid rgb(180, 180, 180);" "}" "" "" "QGroupBox" "{" " border: 1px solid rgb(110, 110, 110);" " margin-top: 7px;" "}" "" "QGroupBox::title" "{" " subcontrol-origin: margin;" " subcontrol-position: top left;" " left: 7px;" " margin: 0 3px;" "}" "" "" "QPlainTextEdit" "{" " border: 1px solid rgb(110, 110, 110);" "}" "" "" "QScrollArea#scrollAreaDesigner_" "{" " border: 1px solid rgb(110, 110, 110);" "}" "" "" "QScrollArea#scrollAreaOpenGlDesigner_" "{" " border: 1px solid rgb(110, 110, 110);" "}"; return sheet; } //============================================================== // Создание виджета с настройками узла //============================================================== QWidget* MainWindow::createNodeSettingsWidget(BaseNode *node) { Q_ASSERT(node != nullptr); return nullptr; } //============================================================== // Создание кнопки для тул-бара для вызова списка отмен //============================================================== QPushButton* MainWindow::createUndoViewBtn() const { return nullptr; } //============================================================== // Инициализация панели с узлами //============================================================== void MainWindow::initNodesPanel() { QToolBox *const toolBoxNodes = ui_.toolBoxNodes_; #ifdef Q_OS_WASM QFont font{"Segoe UI", 10}; toolBoxNodes->setFont(font); #endif // Q_OS_WASM while (toolBoxNodes->count() > 0) { toolBoxNodes->removeItem(0); } const ColorThemes theme = globalSettings()->colorTheme(); const int standardItemIndex = toolBoxNodes->addItem(createStandardPage(), Icons::collapseArrow(theme), tr("Standard")); toolBoxNodes->setItemToolTip(standardItemIndex, tr("Set for standard nodes")); const int visualizationItemIndex = toolBoxNodes->addItem(createVisualizationPage(), Icons::collapseArrow(theme), tr("Visualization")); toolBoxNodes->setItemToolTip(visualizationItemIndex, tr("Set for visualization nodes")); const int communicationItemIndex = toolBoxNodes->addItem(createCommunicationPage(), Icons::collapseArrow(theme), tr("Communication")); toolBoxNodes->setItemToolTip(communicationItemIndex, tr("Set for communication nodes")); const int scriptItemIndex = toolBoxNodes->addItem(createScriptPage(), Icons::collapseArrow(theme), tr("Script")); toolBoxNodes->setItemToolTip(scriptItemIndex, tr("Set for scripting nodes")); const int otherItemIndex = toolBoxNodes->addItem(createOtherPage(), Icons::collapseArrow(theme), tr("Other")); toolBoxNodes->setItemToolTip(otherItemIndex, tr("Set for other nodes")); } //============================================================== // Создание вкладки Standard для панели Nodes //============================================================== QWidget* MainWindow::createStandardPage() { auto page = new QWidget{}; auto pageLayout = new QVBoxLayout{page}; pageLayout->setContentsMargins(QMargins{}); pageLayout->setSpacing(0); const auto generateItem = new FormNodePanelItem{NodeTypes::Generate}; connect(generateItem, &FormNodePanelItem::sigClicked, this, &MainWindow::slotAddNodeByType); #ifdef Q_OS_WASM connect(generateItem, &FormNodePanelItem::sigDragNode, this, &MainWindow::slotDragNode); connect(generateItem, &FormNodePanelItem::sigDropNode, this, &MainWindow::slotDropNode); #endif // Q_OS_WASM generateItem->setToolTip(tr("A node that generates stream")); pageLayout->addWidget(generateItem); const auto inFileItem = new FormNodePanelItem{NodeTypes::InFile}; connect(inFileItem, &FormNodePanelItem::sigClicked, this, &MainWindow::slotAddNodeByType); #ifdef Q_OS_WASM connect(inFileItem, &FormNodePanelItem::sigDragNode, this, &MainWindow::slotDragNode); connect(inFileItem, &FormNodePanelItem::sigDropNode, this, &MainWindow::slotDropNode); #endif // Q_OS_WASM inFileItem->setToolTip(tr("A node that loads data from a file")); pageLayout->addWidget(inFileItem); const auto takeItem = new FormNodePanelItem{NodeTypes::Take}; connect(takeItem, &FormNodePanelItem::sigClicked, this, &MainWindow::slotAddNodeByType); #ifdef Q_OS_WASM connect(takeItem, &FormNodePanelItem::sigDragNode, this, &MainWindow::slotDragNode); connect(takeItem, &FormNodePanelItem::sigDropNode, this, &MainWindow::slotDropNode); #endif // Q_OS_WASM takeItem->setToolTip(tr("A node that takes the first count bytes from the stream")); pageLayout->addWidget(takeItem); const auto skipItem = new FormNodePanelItem{NodeTypes::Skip}; connect(skipItem, &FormNodePanelItem::sigClicked, this, &MainWindow::slotAddNodeByType); #ifdef Q_OS_WASM connect(skipItem, &FormNodePanelItem::sigDragNode, this, &MainWindow::slotDragNode); connect(skipItem, &FormNodePanelItem::sigDropNode, this, &MainWindow::slotDropNode); #endif // Q_OS_WASM skipItem->setToolTip(tr("A node that skips the first count bytes in the stream")); pageLayout->addWidget(skipItem); const auto reverseItem = new FormNodePanelItem{NodeTypes::Reverse}; connect(reverseItem, &FormNodePanelItem::sigClicked, this, &MainWindow::slotAddNodeByType); #ifdef Q_OS_WASM connect(reverseItem, &FormNodePanelItem::sigDragNode, this, &MainWindow::slotDragNode); connect(reverseItem, &FormNodePanelItem::sigDropNode, this, &MainWindow::slotDropNode); #endif // Q_OS_WASM reverseItem->setToolTip(tr("A node that reverses the byte order in the stream")); pageLayout->addWidget(reverseItem); const auto mergeItem = new FormNodePanelItem{NodeTypes::Merge}; connect(mergeItem, &FormNodePanelItem::sigClicked, this, &MainWindow::slotAddNodeByType); #ifdef Q_OS_WASM connect(mergeItem, &FormNodePanelItem::sigDragNode, this, &MainWindow::slotDragNode); connect(mergeItem, &FormNodePanelItem::sigDropNode, this, &MainWindow::slotDropNode); #endif // Q_OS_WASM mergeItem->setToolTip(tr("A node that merges two streams into one")); pageLayout->addWidget(mergeItem); const auto outFileItem = new FormNodePanelItem{NodeTypes::OutFile}; connect(outFileItem, &FormNodePanelItem::sigClicked, this, &MainWindow::slotAddNodeByType); #ifdef Q_OS_WASM connect(outFileItem, &FormNodePanelItem::sigDragNode, this, &MainWindow::slotDragNode); connect(outFileItem, &FormNodePanelItem::sigDropNode, this, &MainWindow::slotDropNode); #endif // Q_OS_WASM outFileItem->setToolTip(tr("A node that saves incoming stream to a file")); pageLayout->addWidget(outFileItem); const auto paintOpItem = new FormNodePanelItem{NodeTypes::PaintOp}; connect(paintOpItem, &FormNodePanelItem::sigClicked, this, &MainWindow::slotAddNodeByType); #ifdef Q_OS_WASM connect(paintOpItem, &FormNodePanelItem::sigDragNode, this, &MainWindow::slotDragNode); connect(paintOpItem, &FormNodePanelItem::sigDropNode, this, &MainWindow::slotDropNode); #endif // Q_OS_WASM paintOpItem->setToolTip(tr("A node that generates a single graphics operation")); paintOpItem->setEnabled(false); pageLayout->addWidget(paintOpItem); auto spacer = new QSpacerItem{20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding}; pageLayout->addItem(spacer); return page; } //============================================================== // Создание вкладки Visualization для панели Nodes //============================================================== QWidget* MainWindow::createVisualizationPage() { auto page = new QWidget{}; auto pageLayout = new QVBoxLayout{page}; pageLayout->setContentsMargins(QMargins{}); pageLayout->setSpacing(0); const auto sizeItem = new FormNodePanelItem{NodeTypes::Size}; connect(sizeItem, &FormNodePanelItem::sigClicked, this, &MainWindow::slotAddNodeByType); #ifdef Q_OS_WASM connect(sizeItem, &FormNodePanelItem::sigDragNode, this, &MainWindow::slotDragNode); connect(sizeItem, &FormNodePanelItem::sigDropNode, this, &MainWindow::slotDropNode); #endif // Q_OS_WASM sizeItem->setToolTip(tr("A node that displays the size of the data passing through it")); pageLayout->addWidget(sizeItem); const auto dumpItem = new FormNodePanelItem{NodeTypes::Dump}; connect(dumpItem, &FormNodePanelItem::sigClicked, this, &MainWindow::slotAddNodeByType); #ifdef Q_OS_WASM connect(dumpItem, &FormNodePanelItem::sigDragNode, this, &MainWindow::slotDragNode); connect(dumpItem, &FormNodePanelItem::sigDropNode, this, &MainWindow::slotDropNode); #endif // Q_OS_WASM dumpItem->setToolTip(tr("A node that displays a hexadecimal dump of the data passing through it")); pageLayout->addWidget(dumpItem); const auto structItem = new FormNodePanelItem{NodeTypes::Struct}; connect(structItem, &FormNodePanelItem::sigClicked, this, &MainWindow::slotAddNodeByType); #ifdef Q_OS_WASM connect(structItem, &FormNodePanelItem::sigDragNode, this, &MainWindow::slotDragNode); connect(structItem, &FormNodePanelItem::sigDropNode, this, &MainWindow::slotDropNode); #endif // Q_OS_WASM structItem->setToolTip(tr("A node that overlays a structure with basic types onto raw data")); pageLayout->addWidget(structItem); const auto graphItem = new FormNodePanelItem{NodeTypes::Graph}; connect(graphItem, &FormNodePanelItem::sigClicked, this, &MainWindow::slotAddNodeByType); #ifdef Q_OS_WASM connect(graphItem, &FormNodePanelItem::sigDragNode, this, &MainWindow::slotDragNode); connect(graphItem, &FormNodePanelItem::sigDropNode, this, &MainWindow::slotDropNode); #endif // Q_OS_WASM graphItem->setToolTip(tr("A node that plots a graph from the data passing through it")); pageLayout->addWidget(graphItem); const auto paintItem = new FormNodePanelItem{NodeTypes::Paint}; connect(paintItem, &FormNodePanelItem::sigClicked, this, &MainWindow::slotAddNodeByType); #ifdef Q_OS_WASM connect(paintItem, &FormNodePanelItem::sigDragNode, this, &MainWindow::slotDragNode); connect(paintItem, &FormNodePanelItem::sigDropNode, this, &MainWindow::slotDropNode); #endif // Q_OS_WASM paintItem->setToolTip(tr("A node that renders graphical operations from the input stream")); pageLayout->addWidget(paintItem); auto spacer = new QSpacerItem{20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding}; pageLayout->addItem(spacer); return page; } //============================================================== // Создание вкладки Communication для панели Nodes //============================================================== QWidget* MainWindow::createCommunicationPage() { auto page = new QWidget{}; auto pageLayout = new QVBoxLayout{page}; pageLayout->setContentsMargins(QMargins{}); pageLayout->setSpacing(0); const auto tcpServerItem = new FormNodePanelItem{NodeTypes::TcpServer}; connect(tcpServerItem, &FormNodePanelItem::sigClicked, this, &MainWindow::slotAddNodeByType); tcpServerItem->setEnabled(false); pageLayout->addWidget(tcpServerItem); const auto tcpClientItem = new FormNodePanelItem{NodeTypes::TcpClient}; connect(tcpClientItem, &FormNodePanelItem::sigClicked, this, &MainWindow::slotAddNodeByType); tcpClientItem->setEnabled(false); pageLayout->addWidget(tcpClientItem); const auto udpServerItem = new FormNodePanelItem{NodeTypes::UdpServer}; connect(udpServerItem, &FormNodePanelItem::sigClicked, this, &MainWindow::slotAddNodeByType); udpServerItem->setEnabled(false); pageLayout->addWidget(udpServerItem); const auto udpClientItem = new FormNodePanelItem{NodeTypes::UdpClient}; connect(udpClientItem, &FormNodePanelItem::sigClicked, this, &MainWindow::slotAddNodeByType); udpClientItem->setEnabled(false); pageLayout->addWidget(udpClientItem); const auto comReaderItem = new FormNodePanelItem{NodeTypes::ComReader}; #ifndef Q_OS_WASM connect(comReaderItem, &FormNodePanelItem::sigClicked, this, &MainWindow::slotAddNodeByType); comReaderItem->setToolTip(tr("The node for reading data from a serial port")); #else comReaderItem->setEnabled(false); #endif // Q_OS_WASM pageLayout->addWidget(comReaderItem); const auto comWriterItem = new FormNodePanelItem{NodeTypes::ComWriter}; #ifndef Q_OS_WASM connect(comWriterItem, &FormNodePanelItem::sigClicked, this, &MainWindow::slotAddNodeByType); comWriterItem->setToolTip(tr("The node for writing data to a serial port")); #else comWriterItem->setEnabled(false); #endif // Q_OS_WASM pageLayout->addWidget(comWriterItem); auto spacer = new QSpacerItem{20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding}; pageLayout->addItem(spacer); return page; } //============================================================== // Создание вкладки Script для панели Nodes //============================================================== QWidget* MainWindow::createScriptPage() { auto page = new QWidget{}; auto pageLayout = new QVBoxLayout{page}; pageLayout->setContentsMargins(QMargins{}); pageLayout->setSpacing(0); const auto sinItem = new FormNodePanelItem{NodeTypes::SIn}; connect(sinItem, &FormNodePanelItem::sigClicked, this, &MainWindow::slotAddNodeByType); #ifdef Q_OS_WASM connect(sinItem, &FormNodePanelItem::sigDragNode, this, &MainWindow::slotDragNode); connect(sinItem, &FormNodePanelItem::sigDropNode, this, &MainWindow::slotDropNode); #endif // Q_OS_WASM sinItem->setToolTip(tr("A node that generates data using " "an embedded xMonkey script")); sinItem->setEnabled(false); pageLayout->addWidget(sinItem); const auto schangeItem = new FormNodePanelItem{NodeTypes::SChange}; connect(schangeItem, &FormNodePanelItem::sigClicked, this, &MainWindow::slotAddNodeByType); #ifdef Q_OS_WASM connect(schangeItem, &FormNodePanelItem::sigDragNode, this, &MainWindow::slotDragNode); connect(schangeItem, &FormNodePanelItem::sigDropNode, this, &MainWindow::slotDropNode); #endif // Q_OS_WASM schangeItem->setToolTip(tr("A node that processes the input stream " "using an embedded xMonkey script")); schangeItem->setEnabled(false); pageLayout->addWidget(schangeItem); const auto smergeItem = new FormNodePanelItem{NodeTypes::SMerge}; connect(smergeItem, &FormNodePanelItem::sigClicked, this, &MainWindow::slotAddNodeByType); #ifdef Q_OS_WASM connect(smergeItem, &FormNodePanelItem::sigDragNode, this, &MainWindow::slotDragNode); connect(smergeItem, &FormNodePanelItem::sigDropNode, this, &MainWindow::slotDropNode); #endif // Q_OS_WASM smergeItem->setToolTip(tr("A node that merges two input streams " "and processes them with an xMonkey script")); smergeItem->setEnabled(false); pageLayout->addWidget(smergeItem); const auto soutItem = new FormNodePanelItem{NodeTypes::SOut}; connect(soutItem, &FormNodePanelItem::sigClicked, this, &MainWindow::slotAddNodeByType); #ifdef Q_OS_WASM connect(soutItem, &FormNodePanelItem::sigDragNode, this, &MainWindow::slotDragNode); connect(soutItem, &FormNodePanelItem::sigDropNode, this, &MainWindow::slotDropNode); #endif // Q_OS_WASM soutItem->setToolTip(tr("A node that processes the input stream " "using an embedded xMonkey script (final node)")); soutItem->setEnabled(false); pageLayout->addWidget(soutItem); auto spacer = new QSpacerItem{20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding}; pageLayout->addItem(spacer); return page; } //============================================================== // Создание вкладки Other для панели Nodes //============================================================== QWidget* MainWindow::createOtherPage() { auto page = new QWidget{}; auto pageLayout = new QVBoxLayout{page}; pageLayout->setContentsMargins(QMargins{}); pageLayout->setSpacing(0); const auto blockItem = new FormNodePanelItem{NodeTypes::Block}; connect(blockItem, &FormNodePanelItem::sigClicked, this, &MainWindow::slotAddNodeByType); #ifdef Q_OS_WASM connect(blockItem, &FormNodePanelItem::sigDragNode, this, &MainWindow::slotDragNode); connect(blockItem, &FormNodePanelItem::sigDropNode, this, &MainWindow::slotDropNode); #endif // Q_OS_WASM blockItem->setToolTip(tr("A node that groups other nodes into " "a collapsible block for better organization")); blockItem->setEnabled(false); pageLayout->addWidget(blockItem); const auto cacheItem = new FormNodePanelItem{NodeTypes::Cache}; connect(cacheItem, &FormNodePanelItem::sigClicked, this, &MainWindow::slotAddNodeByType); #ifdef Q_OS_WASM connect(cacheItem, &FormNodePanelItem::sigDragNode, this, &MainWindow::slotDragNode); connect(cacheItem, &FormNodePanelItem::sigDropNode, this, &MainWindow::slotDropNode); #endif // Q_OS_WASM cacheItem->setEnabled(false); pageLayout->addWidget(cacheItem); const auto nonItem = new FormNodePanelItem{NodeTypes::Non}; connect(nonItem, &FormNodePanelItem::sigClicked, this, &MainWindow::slotAddNodeByType); #ifdef Q_OS_WASM connect(nonItem, &FormNodePanelItem::sigDragNode, this, &MainWindow::slotDragNode); connect(nonItem, &FormNodePanelItem::sigDropNode, this, &MainWindow::slotDropNode); #endif // Q_OS_WASM nonItem->setToolTip(tr("A decorative node that bends " "the connection line for visual clarity")); nonItem->setEnabled(false); pageLayout->addWidget(nonItem); const auto areaArea = new FormNodePanelItem{NodeTypes::Area}; connect(areaArea, &FormNodePanelItem::sigClicked, this, &MainWindow::slotAddNodeByType); #ifdef Q_OS_WASM connect(areaArea, &FormNodePanelItem::sigDragNode, this, &MainWindow::slotDragNode); connect(areaArea, &FormNodePanelItem::sigDropNode, this, &MainWindow::slotDropNode); #endif // Q_OS_WASM areaArea->setToolTip(tr("A decorative container for visually grouping nodes")); pageLayout->addWidget(areaArea); auto spacer = new QSpacerItem{20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding}; pageLayout->addItem(spacer); return page; }