| 95 | } // namespace |
| 96 | |
| 97 | FilterEditorPanel::FilterEditorPanel( |
| 98 | SessionManager* session, CatalogModel* catalog, std::vector<CurveDescriptor> sources, |
| 99 | QHash<QString, QColor> source_colors, QWidget* parent) |
| 100 | : QWidget(parent), |
| 101 | ui_(std::make_unique<Ui::FilterEditorPanel>()), |
| 102 | session_(session), |
| 103 | catalog_(catalog), |
| 104 | sources_(std::move(sources)), |
| 105 | source_colors_(std::move(source_colors)) { |
| 106 | ui_->setupUi(this); |
| 107 | |
| 108 | populateSources(); |
| 109 | populateTransforms(); |
| 110 | |
| 111 | connect(ui_->transform_list, &QListWidget::currentRowChanged, this, [this](int) { onTransformChanged(); }); |
| 112 | |
| 113 | // Primary action: Apply (materialize + replace in place). "Generate time |
| 114 | // series" (an additive new series) is deferred under the replace-in-place |
| 115 | // model, so its button is hidden for now. |
| 116 | ui_->save_btn->setText(tr("Apply")); |
| 117 | connect(ui_->save_btn, &QPushButton::clicked, this, [this]() { applyToSelected(); }); |
| 118 | ui_->generate_btn->setVisible(false); |
| 119 | |
| 120 | ui_->cancel_btn->setText(tr("Close")); |
| 121 | connect(ui_->cancel_btn, &QPushButton::clicked, this, [this]() { emit closed(); }); |
| 122 | |
| 123 | // The generated parameter editor replaces the 7 hardcoded panel_* widgets. Its |
| 124 | // schema comes from the bundled Luau filter classes (read once from the app |
| 125 | // resource); M5 routes this through the FilterCatalogue instead. |
| 126 | filter_engine_ = scripting::makeLuauEngine(); |
| 127 | if (QFile f(QStringLiteral(":/filters/builtin_filters.luau")); f.open(QIODevice::ReadOnly)) { |
| 128 | if (auto classes = filter_engine_->inspectModule(f.readAll().toStdString(), "bundled"); classes.has_value()) { |
| 129 | filter_classes_ = std::move(classes.value()); |
| 130 | } |
| 131 | } |
| 132 | if (filter_classes_.empty()) { // the resource is embedded, so this is defensive |
| 133 | ui_->status_label->setText(tr("Warning: built-in filter definitions failed to load")); |
| 134 | } |
| 135 | param_form_ = new ParameterForm(this); |
| 136 | ui_->paramsLayout->insertWidget(0, param_form_); |
| 137 | connect(param_form_, &ParameterForm::changed, this, [this]() { scheduleRefresh(); }); |
| 138 | |
| 139 | // Copy / paste / apply-to-all of the visible filter parameters — icon buttons |
| 140 | // in the parameters-column header (the params are what is copied), matching the |
| 141 | // scene3d settings toolbar's SVGs and 20px sizing. |
| 142 | const auto make_icon_button = [this](const QString& svg, const QString& tip) { |
| 143 | auto* button = new QToolButton(this); |
| 144 | button->setAutoRaise(true); |
| 145 | button->setFocusPolicy(Qt::NoFocus); |
| 146 | button->setIconSize(QSize(Style::kInputHeight, Style::kInputHeight)); |
| 147 | button->setFixedSize(Style::kInputHeight, Style::kInputHeight); // 20x20, like every icon button |
| 148 | button->setIcon(QIcon(loadSvg(svg, currentTheme()))); |
| 149 | button->setToolTip(tip); |
| 150 | return button; |
| 151 | }; |
| 152 | copy_button_ = make_icon_button(QStringLiteral(":/resources/svg/copy.svg"), tr("Copy parameters")); |
| 153 | paste_button_ = make_icon_button(QStringLiteral(":/resources/svg/paste.svg"), tr("Paste parameters")); |
| 154 | apply_all_button_ = |
nothing calls this directly
no test coverage detected