#include "gpointsattributesmanager.h" #include "ui_gpointsattributesmanager.h" #include "dm_guimanager.h" #include "gdocumentviewforgraphics.h" #include "gminmaxattributesscalarconfiguration.h" #include "tools/attributes/dm_attributesbuildingcollectiont.h" #include "tools/attributes/worker/dm_attributescolort.h" #include "tools/attributes/worker/dm_attributesnormalt.h" #include "tools/attributes/worker/dm_attributesscalart.h" #include #include GPointsAttributesManager::GPointsAttributesManager(QWidget *parent) : QDialog(parent), ui(new Ui::GPointsAttributesManager) { ui->setupUi(this); m_manager = NULL; m_doc = NULL; m_itemPointRootColor = NULL; m_itemPointRootScalar = NULL; m_itemPointRootNormal = NULL; m_itemFaceRootColor = NULL; m_itemFaceRootScalar = NULL; m_itemFaceRootNormal = NULL; m_itemEdgeRootColor = NULL; m_itemEdgeRootScalar = NULL; m_itemEdgeRootNormal = NULL; m_internalSetColor = false; ui->pushButtonGradientColorPicker->setStandardColors(); ui->pushButtonAddColor->setEnabled(false); ui->pushButtonNormalsColorPicker->setStandardColors(); ui->pushButtonNormalsColorPicker->setCurrentColor(Qt::white); ui->pushButtonApplyEditNormals->setEnabled(false); ui->treeView->setModel(&m_model); ui->treeView->setSelectionMode(QAbstractItemView::SingleSelection); connect(ui->treeView->selectionModel(), SIGNAL(currentRowChanged(QModelIndex,QModelIndex)), this, SLOT(treeView_currentRowChanged(QModelIndex,QModelIndex))); connect(&m_model, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(itemChanged(QStandardItem*))); connect(ui->gradientManagerView, SIGNAL(newGradientSelected(QLinearGradient)), ui->colorGradientView, SLOT(fromLinearGradient(QLinearGradient))); connect(ui->colorGradientView, SIGNAL(arrowMove(qreal,GradientArrow)), this, SLOT(updateArrowValue(qreal,GradientArrow))); } GPointsAttributesManager::~GPointsAttributesManager() { delete ui; } void GPointsAttributesManager::setManager(const DM_AttributesManager *man) { m_manager = (DM_AttributesManager*)man; if(m_manager != NULL) m_manager->clearInvalid(); initTreeView(); } void GPointsAttributesManager::setDocument(const GDocumentViewForGraphics *doc) { m_doc = (GDocumentViewForGraphics*)doc; if(m_doc != NULL) ui->checkBoxShowNormals->setChecked(m_doc->useNormalCloud()); } void GPointsAttributesManager::closeEvent(QCloseEvent *e) { checkAndSave(dynamic_cast(attributesSelected())); QDialog::closeEvent(e); } void GPointsAttributesManager::initTreeView() { typedef DM_AttributesScalarT PointAttributesScalar; typedef DM_AttributesColorT PointAttributesColor; typedef DM_AttributesNormalT PointAttributesNormal; typedef DM_AttributesScalarT FaceAttributesScalar; typedef DM_AttributesColorT FaceAttributesColor; typedef DM_AttributesNormalT FaceAttributesNormal; typedef DM_AttributesScalarT EdgeAttributesScalar; typedef DM_AttributesColorT EdgeAttributesColor; typedef DM_AttributesNormalT EdgeAttributesNormal; m_model.clear(); constructHeader(); m_itemPointRoot = new QStandardItem(tr("Point")); m_itemPointRoot->setEditable(false); m_model.appendRow(m_itemPointRoot); m_itemFaceRoot = new QStandardItem(tr("Face")); m_itemFaceRoot->setEditable(false); m_model.appendRow(m_itemFaceRoot); m_itemEdgeRoot = new QStandardItem(tr("Edge")); m_itemEdgeRoot->setEditable(false); m_model.appendRow(m_itemEdgeRoot); QList steps = GUI_MANAGER->getStepManager()->getStepRootList(); while(!steps.isEmpty()) { CT_VirtualAbstractStep *st = steps.takeFirst(); buildTreeViewTForStep< CT_AbstractPointsAttributes, PointAttributesScalar, PointAttributesColor, PointAttributesNormal >(st); buildTreeViewTForStep< CT_AbstractFaceAttributes, FaceAttributesScalar, FaceAttributesColor, FaceAttributesNormal >(st); buildTreeViewTForStep< CT_AbstractEdgeAttributes, EdgeAttributesScalar, EdgeAttributesColor, EdgeAttributesNormal >(st); } } template void GPointsAttributesManager::buildTreeViewTForStep(CT_VirtualAbstractStep *step) { DM_AttributesBuildingCollectionT builderPoints; builderPoints.buildFrom(step); QListIterator it(builderPoints.attributesCollection()); while(it.hasNext()) { IAttributesType *pa = it.next(); CT_AbstractAttributesScalar *pas = dynamic_cast(pa); if(pas != NULL) { AttributesScalarType *dpas = (AttributesScalarType*)m_manager->getAttributesFromInterface(pa); if(dpas == NULL) { dpas = new AttributesScalarType(); dpas->setTypeAttributes(pa, pas); m_manager->addAttributes(dpas); } addToScalarRoot(createAttributesScalarForModel(dpas)); } else { CT_AttributesColor *pac = dynamic_cast(pa); if(pac != NULL) { AttributesColorType *dpac = dynamic_cast(m_manager->getAttributesFromInterface(pa)); if(dpac == NULL) { dpac = new AttributesColorType(); dpac->setTypeAttributes(pa, pac); m_manager->addAttributes(dpac); } addToColorRoot(createAttributesColorForModel(dpac)); } else { CT_AttributesNormal *pan = dynamic_cast(pa); if(pan != NULL) { AttributesNormalType *dpan = dynamic_cast(m_manager->getAttributesFromInterface(pa)); if(dpan == NULL) { dpan = new AttributesNormalType(); dpan->setTypeAttributes(pa, pan); m_manager->addAttributes(dpan); } addToNormalRoot(createAttributesNormalForModel(dpan)); } } } } } void GPointsAttributesManager::constructHeader() { QStringList header; header << tr("Nom"); header << tr("Appliquer"); //header << tr("Utiliser seul ?"); header << tr("Utiliser gradient partagé ?"); header << tr("Configurer"); m_model.setHorizontalHeaderLabels(header); #if QT_VERSION < QT_VERSION_CHECK(5,0,0) for(int i=0; itreeView->header()->setResizeMode(i, QHeaderView::ResizeToContents); #else for(int i=0; itreeView->header()->setSectionResizeMode(i, QHeaderView::ResizeToContents); #endif } void GPointsAttributesManager::checkAndSave(DM_AbstractAttributesScalar *pas) { if((pas != NULL) && (ui->pushButtonSave->isEnabled())) { int ret = QMessageBox::question(this, tr("Enregistrer"), tr("Vous n'avez pas enregistré le gradient. Voulez vous le faire maintenant ?"), QMessageBox::Yes | QMessageBox::No); if(ret == QMessageBox::Yes) saveCurrentGradientTo(pas); } } QList GPointsAttributesManager::createAttributesScalarForModel(DM_AbstractAttributesScalar *pa) { QList items; // NOM QStandardItem *item = new QStandardItem(pa->displayableName()); item->setEditable(false); item->setData(qVariantFromValue((void*)pa)); items << item; // BOUTON APPLIQUER item = new QStandardItem(tr("Appliquer")); item->setEditable(false); item->setData(qVariantFromValue((void*)pa)); items << item; // CHECKBOX "UTILISER SEUL ?" // attention si vous decommentez cette ligne il faut vérifier // les comparaison avec les "column()" des items /*item = new QStandardItem(); item->setEditable(false); item->setCheckable(true); item->setCheckState(pa->isDisplayedAlone() ? Qt::Checked : Qt::Unchecked); item->setData(qVariantFromValue((void*)pa)); items << item;*/ // CHECKBOX "UTILISER GRADIENT PARTAGE ?" item = new QStandardItem(); item->setEditable(false); item->setCheckable(true); item->setCheckState(pa->isUsedSharedGradient() ? Qt::Checked : Qt::Unchecked); item->setData(qVariantFromValue((void*)pa)); items << item; // BOUTON CONFIGURER item = new QStandardItem(tr("Configurer")); item->setEditable(false); item->setData(qVariantFromValue((void*)pa)); items << item; return items; } QList GPointsAttributesManager::createAttributesColorForModel(DM_AbstractAttributesColor *pa) { QList items; // NOM QStandardItem *item = new QStandardItem(pa->displayableName()); item->setEditable(false); item->setData(qVariantFromValue((void*)pa)); items << item; // BOUTON APPLIQUER item = new QStandardItem(tr("Appliquer")); item->setEditable(false); item->setData(qVariantFromValue((void*)pa)); items << item; // CHECKBOX "UTILISER SEUL ?" // attention si vous decommentez cette ligne il faut vérifier // les comparaison avec les "column()" des items /*item = new QStandardItem(); item->setEditable(false); item->setCheckable(true); item->setCheckState(pa->isDisplayedAlone() ? Qt::Checked : Qt::Unchecked); item->setData(qVariantFromValue((void*)pa)); items << item;*/ return items; } QList GPointsAttributesManager::createAttributesNormalForModel(DM_AbstractAttributesNormal *pa) { QList items; // NOM QStandardItem *item = new QStandardItem(pa->displayableName()); item->setEditable(false); item->setData(qVariantFromValue((void*)pa)); items << item; // BOUTON APPLIQUER item = new QStandardItem(tr("Appliquer")); item->setEditable(false); item->setData(qVariantFromValue((void*)pa)); items << item; // CHECKBOX "UTILISER SEUL ?" // attention si vous decommentez cette ligne il faut vérifier // les comparaison avec les "column()" des items /*item = new QStandardItem(); item->setEditable(false); item->setCheckable(true); item->setCheckState(pa->isDisplayedAlone() ? Qt::Checked : Qt::Unchecked); item->setData(qVariantFromValue((void*)pa)); items << item;*/ return items; } template<> void GPointsAttributesManager::addToScalarRoot(const QList &items) { addToScalarRoot(items, m_itemPointRootScalar, m_itemPointRoot); } template<> void GPointsAttributesManager::addToScalarRoot(const QList &items) { addToScalarRoot(items, m_itemFaceRootScalar, m_itemFaceRoot); } template<> void GPointsAttributesManager::addToScalarRoot(const QList &items) { addToScalarRoot(items, m_itemEdgeRootScalar, m_itemEdgeRoot); } void GPointsAttributesManager::addToScalarRoot(const QList &items, QStandardItem *&root, QStandardItem *model) { if(root == NULL) { root = new QStandardItem(tr("Gradients")); root->setEditable(false); model->appendRow(root); } root->appendRow(items); ui->treeView->expand(m_model.indexFromItem(model)); ui->treeView->expand(m_model.indexFromItem(root)); createWidgetForItems(items); } template<> void GPointsAttributesManager::addToColorRoot(const QList &items) { addToColorRoot(items, m_itemPointRootColor, m_itemPointRoot); } template<> void GPointsAttributesManager::addToColorRoot(const QList &items) { addToColorRoot(items, m_itemFaceRootColor, m_itemFaceRoot); } template<> void GPointsAttributesManager::addToColorRoot(const QList &items) { addToColorRoot(items, m_itemEdgeRootColor, m_itemEdgeRoot); } void GPointsAttributesManager::addToColorRoot(const QList &items, QStandardItem *&root, QStandardItem *model) { if(root == NULL) { root = new QStandardItem(tr("Couleurs")); root->setEditable(false); model->appendRow(root); } root->appendRow(items); ui->treeView->expand(m_model.indexFromItem(model)); ui->treeView->expand(m_model.indexFromItem(root)); createWidgetForItems(items); } template<> void GPointsAttributesManager::addToNormalRoot(const QList &items) { addToNormalRoot(items, m_itemPointRootNormal, m_itemPointRoot); } template<> void GPointsAttributesManager::addToNormalRoot(const QList &items) { addToNormalRoot(items, m_itemFaceRootNormal, m_itemFaceRoot); } template<> void GPointsAttributesManager::addToNormalRoot(const QList &items) { addToNormalRoot(items, m_itemEdgeRootNormal, m_itemEdgeRoot); } void GPointsAttributesManager::addToNormalRoot(const QList &items, QStandardItem *&root, QStandardItem *model) { if(root == NULL) { root = new QStandardItem(tr("Normales")); root->setEditable(false); model->appendRow(root); } root->appendRow(items); ui->treeView->expand(m_model.indexFromItem(model)); ui->treeView->expand(m_model.indexFromItem(root)); createWidgetForItems(items); } void GPointsAttributesManager::createWidgetForItems(const QList &items) { QStandardItem *item = items.at(1); QPushButton *pushButton = new QPushButton(item->text(), ui->treeView); pushButton->setProperty("userdata", item->data()); ui->treeView->setIndexWidget(m_model.indexFromItem(item), pushButton); connect(pushButton, SIGNAL(clicked()), this, SLOT(pushButtonApplyClicked())); if(items.size() > 3) { item = items.at(3); QPushButton *pushButtonC = new QPushButton(item->text(), ui->treeView); pushButtonC->setProperty("userdata", item->data()); ui->treeView->setIndexWidget(m_model.indexFromItem(item), pushButtonC); connect(pushButtonC, SIGNAL(clicked()), this, SLOT(pushButtonConfigureClicked())); } } void GPointsAttributesManager::editAttributesScalar(DM_AbstractAttributesScalar *pas) { QGradientStops stops = pas->gradient().stops(); QVectorIterator it(stops); int i = 0; while(it.hasNext()) { QGradientStop stop = it.next(); GradientArrow arrow; arrow.setHasFocus(i==0); arrow.setColor(stop.second); arrow.setPosition(stop.first); arrow.setIndex(i); ui->colorGradientView->changeArrow(arrow); ++i; } ui->pushButtonAddColor->setEnabled(true); ui->pushButtonDeleteColor->setEnabled(ui->colorGradientView->nArrows() > 2); ui->widgetEditGradient->setVisible(true); ui->doubleSpinBoxGradientArrowValue->setMinimum(pas->min()); ui->doubleSpinBoxGradientArrowValue->setMaximum(pas->max()); } void GPointsAttributesManager::clearEditGradient() { ui->colorGradientView->clearArrows(); ui->pushButtonSave->setEnabled(false); ui->pushButtonDeleteColor->setEnabled(false); ui->pushButtonAddColor->setEnabled(false); } void GPointsAttributesManager::saveCurrentGradientTo(DM_AbstractAttributesScalar *pas) { QLinearGradient gradient = ui->colorGradientView->toLinearGradient(); if(gradient.stops().size() > 1) { pas->setGradient(gradient); // si il utilise un gradient partagé if(pas->isUsedSharedGradient()) { // on applique le gradient à tous ceux qui utilise un gradient partagé QListIterator it(m_manager->attributes()); while(it.hasNext()) { DM_AbstractAttributesScalar *pass = dynamic_cast(it.next()); if((pass != NULL) && (pass != pas) && (pass->isUsedSharedGradient())) { pass->setGradient(gradient); } } } } ui->pushButtonSave->setEnabled(false); } void GPointsAttributesManager::editAttributesNormal(DM_AbstractAttributesNormal *pan) { Q_UNUSED(pan) GDocumentViewForGraphics::NormalsConfiguration c = m_doc->getNormalsConfiguration(); ui->pushButtonNormalsColorPicker->setCurrentColor(c.normalColor); ui->doubleSpinBoxNormalsLength->setValue(c.normalLength); ui->widgetEditNormals->setVisible(true); } void GPointsAttributesManager::clearEditNormal() { ui->pushButtonApplyEditNormals->setEnabled(false); } void GPointsAttributesManager::applyAndSaveNormal() { GDocumentViewForGraphics::NormalsConfiguration c; c.normalColor = ui->pushButtonNormalsColorPicker->currentColor(); c.normalLength = ui->doubleSpinBoxNormalsLength->value(); m_doc->applyNormalsConfiguration(c); } DM_AbstractAttributes *GPointsAttributesManager::attributesSelected() const { QModelIndexList list = ui->treeView->selectionModel()->selectedIndexes(); if(list.isEmpty()) return NULL; return (DM_AbstractAttributes*)m_model.itemFromIndex(list.first())->data().value(); } void GPointsAttributesManager::on_pushButtonAddColor_clicked() { GradientArrow newArrow; newArrow.setIndex(ui->colorGradientView->indexUnused()); newArrow.setHasFocus(true); newArrow.setPosition(ui->colorGradientView->positionUnused()); newArrow.setColor(Qt::white); ui->colorGradientView->changeArrow(newArrow); ui->pushButtonDeleteColor->setEnabled(ui->colorGradientView->nArrows() > 2); ui->pushButtonSave->setEnabled(true); } void GPointsAttributesManager::on_pushButtonDeleteColor_clicked() { ui->colorGradientView->removeArrow(ui->colorGradientView->currentArrow().index()); ui->pushButtonDeleteColor->setEnabled(ui->colorGradientView->nArrows() > 2); ui->pushButtonSave->setEnabled(true); } void GPointsAttributesManager::on_pushButtonSave_clicked() { saveCurrentGradientTo(dynamic_cast(attributesSelected())); } void GPointsAttributesManager::pushButtonApplyClicked() { QPushButton *pushButton = (QPushButton*)sender(); DM_AbstractAttributes *dpa = (DM_AbstractAttributes*)pushButton->property("userdata").value(); DM_AbstractAttributesScalar *as = dynamic_cast(attributesSelected()); if(dpa == as) saveCurrentGradientTo((DM_AbstractAttributesScalar*)dpa); m_doc->applyAttributes(dpa); } void GPointsAttributesManager::pushButtonConfigureClicked() { QPushButton *pushButton = (QPushButton*)sender(); DM_AbstractAttributes *dpa = (DM_AbstractAttributes*)pushButton->property("userdata").value(); DM_AbstractAttributesScalar *pas = dynamic_cast(dpa); if(pas != NULL) { GMinMaxAttributesScalarConfiguration dialog(this); dialog.setAttributes(pas); dialog.exec(); } } void GPointsAttributesManager::itemChanged(QStandardItem *item) { DM_AbstractAttributes *pa = (DM_AbstractAttributes*)item->data().value(); if(pa != NULL) { // use shared gradient if(item->column() == 2) { DM_AbstractAttributesScalar *pas = dynamic_cast(pa); if(pas != NULL) { pas->setUseSharedGradient(item->checkState() == Qt::Checked); if(pas->isUsedSharedGradient()) { // recherche d'un autre qui utilise le gradient partagé QListIterator it(m_manager->attributes()); while(it.hasNext()) { DM_AbstractAttributesScalar *pass = dynamic_cast(it.next()); if((pass != NULL) && (pass != pas) && (pass->isUsedSharedGradient())) { // on applique le gradient partagé a l'attribut de points courant pas->setGradient(pass->gradient()); if(attributesSelected() == pa) editAttributesScalar(pas); return; } } } } } } } void GPointsAttributesManager::on_pushButtonGradientColorPicker_colorChanged(const QColor &color) { if(!m_internalSetColor) { GradientArrow arrow = ui->colorGradientView->currentArrow(); arrow.setColor(color); ui->colorGradientView->changeArrow(arrow); ui->pushButtonSave->setEnabled(true); } m_internalSetColor = false; } void GPointsAttributesManager::on_colorGradientView_newFocusColor(const QColor &color, int arrowIndex) { Q_UNUSED(arrowIndex) if(ui->pushButtonGradientColorPicker->currentColor() != color) { m_internalSetColor = true; ui->pushButtonGradientColorPicker->setCurrentColor(color); } GradientArrow arr = ui->colorGradientView->arrowByIndex(arrowIndex); updateArrowValue(arr.position(), arr); } void GPointsAttributesManager::on_colorGradientView_arrowMove(qreal lastPos, const GradientArrow &arrow) { Q_UNUSED(lastPos) Q_UNUSED(arrow) ui->pushButtonSave->setEnabled(true); } void GPointsAttributesManager::on_checkBoxShowNormals_stateChanged(int state) { m_doc->setUseNormalCloud(state == Qt::Checked); } void GPointsAttributesManager::on_doubleSpinBoxNormalsLength_valueChanged(double v) { if(m_doc != NULL) { GDocumentViewForGraphics::NormalsConfiguration c = m_doc->getNormalsConfiguration(); if(v != c.normalLength) ui->pushButtonApplyEditNormals->setEnabled(true); } } void GPointsAttributesManager::on_pushButtonNormalsColorPicker_colorChanged(QColor c) { if(m_doc != NULL) { GDocumentViewForGraphics::NormalsConfiguration co = m_doc->getNormalsConfiguration(); if(c != co.normalColor) ui->pushButtonApplyEditNormals->setEnabled(true); } } void GPointsAttributesManager::on_pushButtonApplyEditNormals_clicked() { ui->pushButtonApplyEditNormals->setEnabled(false); applyAndSaveNormal(); } void GPointsAttributesManager::on_doubleSpinBoxGradientArrowValue_editingFinished() { GradientArrow arr = ui->colorGradientView->currentArrow(); DM_AbstractAttributesScalar *pas = dynamic_cast(attributesSelected()); if((pas != NULL) && (arr.index() != -1)) { double range = pas->max() - pas->min(); if(range != 0) { double pos = (ui->doubleSpinBoxGradientArrowValue->value()-pas->min())/range; if(pos < 0) pos = 0; if(pos > 1) pos = 1; arr.setPosition(pos); ui->colorGradientView->changeArrow(arr); } } } void GPointsAttributesManager::treeView_currentRowChanged(const QModelIndex ¤t, const QModelIndex &previous) { QStandardItem *pItem = m_model.itemFromIndex(previous); if((pItem != NULL) && !pItem->data().isNull()) { DM_AbstractAttributesScalar *pas = dynamic_cast((DM_AbstractAttributes*)pItem->data().value()); checkAndSave(pas); } clearEditGradient(); ui->widgetEditGradient->setVisible(false); ui->widgetEditNormals->setVisible(false); QStandardItem *cItem = m_model.itemFromIndex(current); if((cItem != NULL) && !cItem->data().isNull()) { DM_AbstractAttributesScalar *pas = dynamic_cast((DM_AbstractAttributes*)cItem->data().value()); if(pas != NULL) { editAttributesScalar(pas); return; } DM_AbstractAttributesNormal *pan = dynamic_cast((DM_AbstractAttributes*)cItem->data().value()); if(pan != NULL) { editAttributesNormal(pan); return; } } } void GPointsAttributesManager::updateArrowValue(qreal val, GradientArrow arr) { Q_UNUSED(val) bool ok = false; DM_AbstractAttributesScalar *pas = dynamic_cast(attributesSelected()); if((pas != NULL) && (arr.index() != -1)) { double range = pas->max() - pas->min(); ok = range != 0; if(ok) ui->doubleSpinBoxGradientArrowValue->setValue((arr.position()*range)+pas->min()); } if(!ok) ui->doubleSpinBoxGradientArrowValue->setValue(0); }