diff --git a/src/propertyvisitors.cpp b/src/propertyvisitors.cpp index e57f3e5f1b9c833adf6480a04c63ff5dbc937d6e..701bc33cde97bd17579335120476f07db84eb782 100644 --- a/src/propertyvisitors.cpp +++ b/src/propertyvisitors.cpp @@ -1,192 +1,6 @@ #include "propertyvisitors.hpp" #include <QJsonArray> -#include <QGroupBox> -#include <QPushButton> -#include <QDebug> -#include <QScrollArea> - -UIBuilderVisitor::UIBuilderVisitor(QWidget *base_widget, bool destructive) -{ - assert(base_widget != nullptr); - - if (destructive) - { - // use a form layout on the parent widget - if (base_widget->layout()) - { - clear_layout(base_widget->layout()); - delete base_widget->layout(); - } - base_widget->setLayout(new QFormLayout); - } - else - assert(base_widget->layout() != nullptr); - - m_widget_hierarchy.push(base_widget); -} - -void UIBuilderVisitor::add_widget(const std::string &prop_name, QWidget *ptr) -{ - // handle whether the current widget is for JSON objects or JSON arrays - QFormLayout* form_layout = qobject_cast<QFormLayout*>(current_widget()->layout()); - QVBoxLayout* vbox_layout = qobject_cast<QVBoxLayout*>(current_widget()->layout()); - if (form_layout) - { - if (prop_name.empty()) - form_layout->addRow(ptr); - else - form_layout->addRow(QString::fromStdString(prop_name) + " : ", ptr); - } - else if (vbox_layout) - { - vbox_layout->addWidget(ptr); - } -} - -void UIBuilderVisitor::clear_layout(QLayout *layout) { - QLayoutItem *item; - while(layout->count() && (item = layout->takeAt(0))) { - if (item->layout()) { - clear_layout(item->layout()); - item->layout()->deleteLater(); - } - if (item->widget()) { - item->widget()->deleteLater(); - } - delete item; - } -} - -QWidget *UIBuilderVisitor::current_widget() -{ - assert(!m_widget_hierarchy.empty()); - return m_widget_hierarchy.top(); -} - -void UIBuilderVisitor::push_array_widget(const Property &prop) -{ - QScrollArea* scroll = new QScrollArea(current_widget()); - QGroupBox* box = new QGroupBox(QString::fromStdString(prop.display_name())); - scroll->setWidget(box); - scroll->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - scroll->setWidgetResizable(true); - box->setLayout(new QVBoxLayout); - add_widget("", scroll); - m_widget_hierarchy.push(box); -} - -QWidget* UIBuilderVisitor::pop_widget() -{ - assert(!m_widget_hierarchy.empty()); - QWidget* ptr = m_widget_hierarchy.top(); - m_widget_hierarchy.pop(); - return ptr; -} - -void UIBuilderVisitor::visit(StringProperty &str) -{ - QLineEdit* line = new QLineEdit(QString::fromStdString(str.str), current_widget()); - add_widget(str.display_name(), line); - - QObject::connect(line, &QLineEdit::textEdited, - [&str](const QString& qstr) { str.str = qstr.toStdString(); }); -} - -void UIBuilderVisitor::visit(IntegerProperty &prop) -{ - QSpinBox* spin = new QSpinBox(current_widget()); - add_widget(prop.display_name(), spin); - - spin->setValue(prop.val); - spin->setMinimum(prop.prop_min); - spin->setMaximum(prop.prop_max); - QObject::connect(spin, QOverload<int>::of(&QSpinBox::valueChanged), - [&prop](int i) { prop.val = i; }); -} - -void UIBuilderVisitor::visit(CoordinateProperty &prop) -{ - QWidget* frame = new QWidget(current_widget()); - frame->setLayout(new QHBoxLayout); - frame->layout()->setContentsMargins(0,0,0,0); - QSpinBox* spin_x = new QSpinBox(frame); - QSpinBox* spin_y = new QSpinBox(frame); - frame->layout()->addWidget(new QLabel("x :", frame)); - frame->layout()->addWidget(spin_x); - frame->layout()->addWidget(new QLabel("y :", frame)); - frame->layout()->addWidget(spin_y); - frame->layout()->addItem(new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum)); - add_widget(prop.display_name(), frame); - - spin_x->setMinimum(std::numeric_limits<int>::min()); spin_y->setMinimum(std::numeric_limits<int>::min()); - spin_x->setMaximum(std::numeric_limits<int>::max()); spin_y->setMaximum(std::numeric_limits<int>::max()); - spin_x->setValue(prop.c.x); spin_y->setValue(prop.c.y); - QObject::connect(spin_x, QOverload<int>::of(&QSpinBox::valueChanged), - [&prop](int i) { prop.c.x = i; }); - QObject::connect(spin_y, QOverload<int>::of(&QSpinBox::valueChanged), - [&prop](int i) { prop.c.y = i; }); -} - -void UIBuilderVisitor::visit(PropertyList &list) -{ - push_array_widget(list); - - for (const auto& ptr : list.contents) - { - ptr->accept(*this); - } - - QWidget* list_widget = pop_widget(); - - if (list.dynamic) - { - QWidget* frame = new QWidget(current_widget()); - frame->setLayout(new QHBoxLayout); - frame->layout()->setContentsMargins(0,0,0,0); - - QPushButton* add_button = new QPushButton("Ajouter...", current_widget()); - QPushButton* del_button = new QPushButton("Supprimer...", current_widget()); - QPushButton* widgetGridNeighborhoodButton = new QPushButton("Grille...", current_widget()); - - frame->layout()->addWidget(add_button); - frame->layout()->addWidget(del_button); - frame->layout()->addWidget(widgetGridNeighborhoodButton); - frame->layout()->addItem(new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum)); - - add_widget("", frame); - - QObject::connect(add_button, &QPushButton::pressed, - [&list, add_button, del_button, list_widget]() { - list.push_back(); - UIBuilderVisitor visit(list_widget, false); // keep the layout of the previous - list.back().accept(visit); - - if (list_widget->layout()->count() >= (int)list.max_size) - add_button->setEnabled(false); - if (list_widget->layout()->count() > (int)list.min_size) - del_button->setEnabled(true); - - }); - QObject::connect(del_button, &QPushButton::pressed, - [&list, add_button, list_widget, del_button]() { - if (!list.empty()) - { - list.pop_back(); - assert(list_widget->layout()->count() > 0); - QLayoutItem* child = list_widget->layout()->takeAt(list_widget->layout()->count()-1); - delete child->widget(); - delete child; - if (list_widget->layout()->count() <= (int)list.min_size) // no more items to delete, grey the button out - del_button->setEnabled(false); - if (list_widget->layout()->count() < (int)list.max_size) - add_button->setEnabled(true); - } - }); - // J'arrive pas à l'afficher - // QObject::connect(widgetGridNeighborhoodButton, &QPushButton::pressed); - } -} PropertySaverVisitor::PropertySaverVisitor() { diff --git a/src/src.pro b/src/src.pro index 567ef199cb3545040e85b1d418e710826bb5ab12..a5a72c61ac81b87413acefa49664b6ac46688c91 100644 --- a/src/src.pro +++ b/src/src.pro @@ -35,7 +35,8 @@ SOURCES += \ structurewriter.cpp \ structurelibraryview.cpp \ modelloadingdialog.cpp \ - transition_rules/totalistictransition.cpp + transition_rules/totalistictransition.cpp \ + uibuildervisitor.cpp HEADERS += \ diff --git a/src/uibuildervisitor.cpp b/src/uibuildervisitor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b4f160f2183cd4d81f87426868f5d87cffab78b1 --- /dev/null +++ b/src/uibuildervisitor.cpp @@ -0,0 +1,194 @@ +#include "propertyvisitors.hpp" + +#include "neighborhoodWidget.hpp" + +#include <QGroupBox> +#include <QPushButton> +#include <QDebug> +#include <QScrollArea> + +UIBuilderVisitor::UIBuilderVisitor(QWidget *base_widget, bool destructive) +{ + assert(base_widget != nullptr); + + if (destructive) + { + // use a form layout on the parent widget + if (base_widget->layout()) + { + clear_layout(base_widget->layout()); + delete base_widget->layout(); + } + base_widget->setLayout(new QFormLayout); + } + else + assert(base_widget->layout() != nullptr); + + m_widget_hierarchy.push(base_widget); +} + +void UIBuilderVisitor::add_widget(const std::string &prop_name, QWidget *ptr) +{ + // handle whether the current widget is for JSON objects or JSON arrays + QFormLayout* form_layout = qobject_cast<QFormLayout*>(current_widget()->layout()); + QVBoxLayout* vbox_layout = qobject_cast<QVBoxLayout*>(current_widget()->layout()); + if (form_layout) + { + if (prop_name.empty()) + form_layout->addRow(ptr); + else + form_layout->addRow(QString::fromStdString(prop_name) + " : ", ptr); + } + else if (vbox_layout) + { + vbox_layout->addWidget(ptr); + } +} + +void UIBuilderVisitor::clear_layout(QLayout *layout) { + QLayoutItem *item; + while(layout->count() && (item = layout->takeAt(0))) { + if (item->layout()) { + clear_layout(item->layout()); + item->layout()->deleteLater(); + } + if (item->widget()) { + item->widget()->deleteLater(); + } + delete item; + } +} + +QWidget *UIBuilderVisitor::current_widget() +{ + assert(!m_widget_hierarchy.empty()); + return m_widget_hierarchy.top(); +} + +void UIBuilderVisitor::push_array_widget(const Property &prop) +{ + QScrollArea* scroll = new QScrollArea(current_widget()); + QGroupBox* box = new QGroupBox(QString::fromStdString(prop.display_name())); + scroll->setWidget(box); + scroll->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + scroll->setWidgetResizable(true); + box->setLayout(new QVBoxLayout); + add_widget("", scroll); + m_widget_hierarchy.push(box); +} + +QWidget* UIBuilderVisitor::pop_widget() +{ + assert(!m_widget_hierarchy.empty()); + QWidget* ptr = m_widget_hierarchy.top(); + m_widget_hierarchy.pop(); + return ptr; +} + +void UIBuilderVisitor::visit(StringProperty &str) +{ + QLineEdit* line = new QLineEdit(QString::fromStdString(str.str), current_widget()); + add_widget(str.display_name(), line); + + QObject::connect(line, &QLineEdit::textEdited, + [&str](const QString& qstr) { str.str = qstr.toStdString(); }); +} + +void UIBuilderVisitor::visit(IntegerProperty &prop) +{ + QSpinBox* spin = new QSpinBox(current_widget()); + add_widget(prop.display_name(), spin); + + spin->setValue(prop.val); + spin->setMinimum(prop.prop_min); + spin->setMaximum(prop.prop_max); + QObject::connect(spin, QOverload<int>::of(&QSpinBox::valueChanged), + [&prop](int i) { prop.val = i; }); +} + +void UIBuilderVisitor::visit(CoordinateProperty &prop) +{ + QWidget* frame = new QWidget(current_widget()); + frame->setLayout(new QHBoxLayout); + frame->layout()->setContentsMargins(0,0,0,0); + QSpinBox* spin_x = new QSpinBox(frame); + QSpinBox* spin_y = new QSpinBox(frame); + frame->layout()->addWidget(new QLabel("x :", frame)); + frame->layout()->addWidget(spin_x); + frame->layout()->addWidget(new QLabel("y :", frame)); + frame->layout()->addWidget(spin_y); + frame->layout()->addItem(new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum)); + add_widget(prop.display_name(), frame); + + spin_x->setMinimum(std::numeric_limits<int>::min()); spin_y->setMinimum(std::numeric_limits<int>::min()); + spin_x->setMaximum(std::numeric_limits<int>::max()); spin_y->setMaximum(std::numeric_limits<int>::max()); + spin_x->setValue(prop.c.x); spin_y->setValue(prop.c.y); + QObject::connect(spin_x, QOverload<int>::of(&QSpinBox::valueChanged), + [&prop](int i) { prop.c.x = i; }); + QObject::connect(spin_y, QOverload<int>::of(&QSpinBox::valueChanged), + [&prop](int i) { prop.c.y = i; }); +} + +void UIBuilderVisitor::visit(PropertyList &list) +{ + push_array_widget(list); + + for (const auto& ptr : list.contents) + { + ptr->accept(*this); + } + + QWidget* list_widget = pop_widget(); + + if (list.dynamic) + { + QWidget* frame = new QWidget(current_widget()); + frame->setLayout(new QHBoxLayout); + frame->layout()->setContentsMargins(0,0,0,0); + + QPushButton* add_button = new QPushButton("Ajouter...", current_widget()); + QPushButton* del_button = new QPushButton("Supprimer...", current_widget()); + QPushButton* widgetGridNeighborhoodButton = new QPushButton("Grille...", current_widget()); + + frame->layout()->addWidget(add_button); + frame->layout()->addWidget(del_button); + frame->layout()->addWidget(widgetGridNeighborhoodButton); + frame->layout()->addItem(new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum)); + + add_widget("", frame); + + QObject::connect(add_button, &QPushButton::pressed, + [&list, add_button, del_button, list_widget]() { + list.push_back(); + UIBuilderVisitor visit(list_widget, false); // keep the layout of the previous + list.back().accept(visit); + + if (list_widget->layout()->count() >= (int)list.max_size) + add_button->setEnabled(false); + if (list_widget->layout()->count() > (int)list.min_size) + del_button->setEnabled(true); + + }); + QObject::connect(del_button, &QPushButton::pressed, + [&list, add_button, list_widget, del_button]() { + if (!list.empty()) + { + list.pop_back(); + assert(list_widget->layout()->count() > 0); + QLayoutItem* child = list_widget->layout()->takeAt(list_widget->layout()->count()-1); + delete child->widget(); + delete child; + if (list_widget->layout()->count() <= (int)list.min_size) // no more items to delete, grey the button out + del_button->setEnabled(false); + if (list_widget->layout()->count() < (int)list.max_size) + add_button->setEnabled(true); + } + }); + QObject::connect(widgetGridNeighborhoodButton, &QPushButton::pressed, [&list]() { + NeighborhoodWidget n; + n.show(); + }); + // J'arrive pas à l'afficher + // QObject::connect(widgetGridNeighborhoodButton, &QPushButton::pressed); + } +}