// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #include #include #include #include "JFJochViewerSidePanel.h" #include "widgets/TitleLabel.h" #include "widgets/JFJochViewerImageStatistics.h" #include "widgets/PowderCalibrationWidget.h" JFJochViewerSidePanel::JFJochViewerSidePanel(QWidget *parent) : QWidget(parent) { auto layout = new QVBoxLayout(this); layout->addWidget(new TitleLabel("Image statistics", this)); auto stats = new JFJochViewerImageStatistics(this); layout->addWidget(stats); connect(this, &JFJochViewerSidePanel::imageLoaded, stats, &JFJochViewerImageStatistics::loadImage); layout->addWidget(new TitleLabel("Image features", this)); auto spotToggleCheckBox = new QCheckBox("Show spots", this); spotToggleCheckBox->setCheckState(Qt::CheckState::Unchecked); connect(spotToggleCheckBox, &QCheckBox::toggled, this, &JFJochViewerSidePanel::spotsToggled); auto highlightIceRingToggleCheckBox = new QCheckBox("Highlight spots on ice rings", this); highlightIceRingToggleCheckBox->setCheckState(Qt::CheckState::Checked); connect(highlightIceRingToggleCheckBox, &QCheckBox::toggled, this,&JFJochViewerSidePanel::highlightIceRingsToggled); auto predictionsToggleCheckBox = new QCheckBox("Show predictions", this); predictionsToggleCheckBox->setCheckState(Qt::CheckState::Unchecked); connect(predictionsToggleCheckBox, &QCheckBox::toggled, this, &JFJochViewerSidePanel::predictionsToggled); auto highestPixelsComboBox = new QComboBox(this); highestPixelsComboBox->addItem("Show 0 highest pixels", 0); highestPixelsComboBox->addItem("Show 1 highest pixel", 1); highestPixelsComboBox->addItem("Show 2 highest pixels", 2); highestPixelsComboBox->addItem("Show 3 highest pixels", 3); highestPixelsComboBox->addItem("Show 5 highest pixels", 5); highestPixelsComboBox->addItem("Show 10 highest pixels", 10); highestPixelsComboBox->setCurrentIndex(0); connect(highestPixelsComboBox, &QComboBox::currentIndexChanged, this, [this, highestPixelsComboBox](int index) { int value = highestPixelsComboBox->itemData(index).toInt(); emit showHighestPixels(value); }); auto saturatedPixelsCheckBox = new QCheckBox("Show saturated pixels", this); connect(saturatedPixelsCheckBox, &QCheckBox::toggled, this, &JFJochViewerSidePanel::saturatedPixelsToggled); auto colorSelectButton = new QPushButton("Select feature color", this); connect(colorSelectButton, &QPushButton::clicked, this, [this]() { QColor color = QColorDialog::getColor(Qt::magenta, this, "Select Feature Color"); if (color.isValid()) { emit setFeatureColor(color); } }); auto spotColorSelectButton = new QPushButton("Select spot color", this); connect(spotColorSelectButton, &QPushButton::clicked, this, [this]() { QColor color = QColorDialog::getColor(Qt::green, this, "Select Spot Color"); if (color.isValid()) { emit setSpotColor(color); } }); auto image_feature_grid = new QGridLayout(); image_feature_grid->addWidget(spotToggleCheckBox, 0, 0); image_feature_grid->addWidget(highlightIceRingToggleCheckBox, 0, 1); image_feature_grid->addWidget(predictionsToggleCheckBox, 1, 0); image_feature_grid->addWidget(saturatedPixelsCheckBox, 2, 0); image_feature_grid->addWidget(highestPixelsComboBox, 2, 1); image_feature_grid->addWidget(colorSelectButton, 3, 0); image_feature_grid->addWidget(spotColorSelectButton, 3, 1); layout->addLayout(image_feature_grid); layout->addWidget(new TitleLabel("Resolution rings", this)); res_rings = new ResolutionRingWidget(this); connect(res_rings, &ResolutionRingWidget::resRingsSet, [this] (const QVector &v) { emit resRingsSet(v); }); connect(res_rings, &ResolutionRingWidget::ringModeSet, [this] (JFJochDiffractionImage::RingMode mode) { emit ringModeSet(mode); }); layout->addWidget(res_rings); // The per-image statistics plot now lives in the dataset-info dock (its "Per-image" toggle), // so it is no longer duplicated here. layout->addWidget(new TitleLabel("ROI", this)); auto roiLabelsCheckBox = new QCheckBox("Show labels", this); roiLabelsCheckBox->setCheckState(Qt::CheckState::Unchecked); connect(roiLabelsCheckBox, &QCheckBox::toggled, this, &JFJochViewerSidePanel::showROILabels); auto roiFillCheckBox = new QCheckBox("Translucent fill", this); roiFillCheckBox->setCheckState(Qt::CheckState::Unchecked); connect(roiFillCheckBox, &QCheckBox::toggled, this, &JFJochViewerSidePanel::showROIFill); auto roiToggleRow = new QHBoxLayout(); roiToggleRow->addWidget(roiLabelsCheckBox); roiToggleRow->addWidget(roiFillCheckBox); layout->addLayout(roiToggleRow); roi_list = new JFJochViewerROIList(this); layout->addWidget(roi_list); connect(this, &JFJochViewerSidePanel::imageLoaded, roi_list, &JFJochViewerROIList::loadImage); connect(roi_list, &JFJochViewerROIList::roisChanged, this, &JFJochViewerSidePanel::roisChanged); connect(roi_list, &JFJochViewerROIList::selectedROIChanged, this, &JFJochViewerSidePanel::selectedROIChanged); connect(roi_list, &JFJochViewerROIList::downloadROIs, this, &JFJochViewerSidePanel::downloadROIs); connect(roi_list, &JFJochViewerROIList::uploadROIs, this, &JFJochViewerSidePanel::uploadROIs); connect(roi_list, &JFJochViewerROIList::maskFromROI, this, &JFJochViewerSidePanel::maskFromROI); layout->addWidget(new TitleLabel("Data analysis", this)); auto analyzeButton = new QPushButton("Full analysis", this); connect(analyzeButton, &QPushButton::clicked,[this] {emit analyze();}); layout->addWidget(analyzeButton); // Calibrant selection combo box layout->addWidget(new TitleLabel("Powder geometry calibration", this)); auto power_calibration = new PowderCalibrationWidget(this); layout->addWidget(power_calibration); connect(this, &JFJochViewerSidePanel::imageLoaded, power_calibration, &PowderCalibrationWidget::loadImage); connect(power_calibration, &PowderCalibrationWidget::ringsFromCalibration, res_rings, &ResolutionRingWidget::setRings); connect(power_calibration, &PowderCalibrationWidget::findBeamCenter, [this] (const UnitCell& input, bool guess) { emit findBeamCenter(input, guess); }); layout->addStretch(); setLayout(layout); // Set the layout to the widget } void JFJochViewerSidePanel::spotsToggled(bool input) { emit showSpots(input); } void JFJochViewerSidePanel::predictionsToggled(bool input) { emit showPredictions(input); } void JFJochViewerSidePanel::loadImage(std::shared_ptr image) { emit imageLoaded(image); } void JFJochViewerSidePanel::saturatedPixelsToggled(bool input) { emit showSaturatedPixels(input); } void JFJochViewerSidePanel::highlightIceRingsToggled(bool input) { emit highlightIceRings(input); } void JFJochViewerSidePanel::selectROIInList(QString name) { roi_list->setSelected(name); } void JFJochViewerSidePanel::SetRings(QVector v) { res_rings->setRings(v); }