From 15dd77512eb5827eef9d3d590ff3763ce65643a5 Mon Sep 17 00:00:00 2001 From: Paddle Date: Sat, 19 Nov 2022 18:51:58 +0100 Subject: [PATCH] Sketcher: Element widget: Improve filter widget. --- src/Mod/Sketcher/Gui/TaskSketcherElements.cpp | 173 +++++++++--------- src/Mod/Sketcher/Gui/TaskSketcherElements.h | 20 +- src/Mod/Sketcher/Gui/TaskSketcherElements.ui | 131 ++++--------- 3 files changed, 135 insertions(+), 189 deletions(-) diff --git a/src/Mod/Sketcher/Gui/TaskSketcherElements.cpp b/src/Mod/Sketcher/Gui/TaskSketcherElements.cpp index fa1af8d6e5..c2b7d8ef8a 100644 --- a/src/Mod/Sketcher/Gui/TaskSketcherElements.cpp +++ b/src/Mod/Sketcher/Gui/TaskSketcherElements.cpp @@ -57,6 +57,8 @@ #include +#include //to be put in _PreComp_ once grid PR merge. + using namespace SketcherGui; using namespace Gui::TaskView; @@ -371,7 +373,7 @@ ElementItem* ElementView::itemFromIndex(const QModelIndex& index) { return static_cast(QListWidget::itemFromIndex(index)); } -// ---------------------------------------------------------------------------- +/* ElementItem delegate ---------------------------------------------------- */ ElementItemDelegate::ElementItemDelegate(ElementView* parent) : QStyledItemDelegate(parent) { // This class relies on the parent being an ElementView, see getElementtItem @@ -486,7 +488,37 @@ ElementItem* ElementItemDelegate::getElementtItem(const QModelIndex& index) cons ElementView* elementView = static_cast(parent()); return elementView->itemFromIndex(index); } -// ---------------------------------------------------------------------------- + +/* Filter element list widget ------------------------------------------------------ */ +ElementFilterList::ElementFilterList(QWidget* parent) : QListWidget(parent) +{ + addItem(new QListWidgetItem(QApplication::translate("ElementFilterList", "Normal"), this)); + addItem(new QListWidgetItem(QApplication::translate("ElementFilterList", "Construction"), this)); + addItem(new QListWidgetItem(QApplication::translate("ElementFilterList", "Internal"), this)); + addItem(new QListWidgetItem(QApplication::translate("ElementFilterList", "External"), this)); + addItem(new QListWidgetItem(QApplication::translate("ElementFilterList", "All types"), this)); + addItem(new QListWidgetItem(QApplication::translate("ElementFilterList", " - Point"), this)); + addItem(new QListWidgetItem(QApplication::translate("ElementFilterList", " - Line"), this)); + addItem(new QListWidgetItem(QApplication::translate("ElementFilterList", " - Circle"), this)); + addItem(new QListWidgetItem(QApplication::translate("ElementFilterList", " - Ellipse"), this)); + addItem(new QListWidgetItem(QApplication::translate("ElementFilterList", " - Arc"), this)); + addItem(new QListWidgetItem(QApplication::translate("ElementFilterList", " - Arc of ellipse"), this)); + addItem(new QListWidgetItem(QApplication::translate("ElementFilterList", " - Arc of hyperbola"), this)); + addItem(new QListWidgetItem(QApplication::translate("ElementFilterList", " - Arc of parabola"), this)); + addItem(new QListWidgetItem(QApplication::translate("ElementFilterList", " - B-Spline"), this)); + + for (int i = 0; i < count(); i++) { + QListWidgetItem* it = item(i); + + it->setFlags(it->flags() | Qt::ItemIsUserCheckable); + it->setCheckState(Qt::Checked); + } +} + +ElementFilterList::~ElementFilterList() +{ +} + /* TRANSLATOR SketcherGui::TaskSketcherElements */ @@ -499,7 +531,6 @@ TaskSketcherElements::TaskSketcherElements(ViewProviderSketch *sketchView) , previouslyHoveredItemIndex(-1) , previouslyHoveredType(SubElementType::none) , isNamingBoxChecked(false) - , collapseFilter(true) { // we need a separate container widget to add all controls to proxy = new QWidget(this); @@ -518,6 +549,7 @@ TaskSketcherElements::TaskSketcherElements(ViewProviderSketch *sketchView) ui->listWidgetElements->setEditTriggers(QListWidget::NoEditTriggers); ui->listWidgetElements->setMouseTracking(true); + createFilterButtonActions(); createSettingsButtonActions(); connectSignals(); @@ -526,23 +558,6 @@ TaskSketcherElements::TaskSketcherElements(ViewProviderSketch *sketchView) slotElementsChanged(); - - // make filter items checkable - { - QSignalBlocker sigblk(ui->listMultiFilter); - for (int i = 0; i < ui->listMultiFilter->count(); i++) { - QListWidgetItem* item = ui->listMultiFilter->item(i); - - item->setFlags(item->flags() | Qt::ItemIsUserCheckable); - - item->setCheckState(Qt::Checked); - } - ui->listMultiFilter->setVisible(false); - } - - this->installEventFilter(this); - ui->filterBox->installEventFilter(this); - ui->listMultiFilter->installEventFilter(this); } TaskSketcherElements::~TaskSketcherElements() @@ -566,7 +581,7 @@ void TaskSketcherElements::connectSignals() this, &TaskSketcherElements::onListWidgetElementsMouseMoveOnItem ); QObject::connect( - ui->listMultiFilter, &QListWidget::itemChanged, + filterList, &QListWidget::itemChanged, this, &TaskSketcherElements::onListMultiFilterItemChanged ); QObject::connect( @@ -575,15 +590,15 @@ void TaskSketcherElements::connectSignals() ); QObject::connect( ui->settingsButton, &QToolButton::clicked, - this, &TaskSketcherElements::onSettingsButtonClicked + ui->settingsButton, &QToolButton::showMenu ); QObject::connect( qAsConst(ui->settingsButton)->actions()[0], &QAction::changed, this, &TaskSketcherElements::onSettingsExtendedInformationChanged ); QObject::connect( - qAsConst(ui->settingsButton)->actions()[1], &QAction::changed, - this, &TaskSketcherElements::onSettingsAutoCollapseFilterChanged + ui->filterButton, &QToolButton::clicked, + ui->filterButton, &QToolButton::showMenu ); connectionElementsChanged = sketchView->signalElementsChanged.connect( @@ -592,29 +607,19 @@ void TaskSketcherElements::connectSignals() /* filter functions --------------------------------------------------- */ -void TaskSketcherElements::onFilterBoxStateChanged(int val) +void TaskSketcherElements::createFilterButtonActions() { - Q_UNUSED(val) - - ui->listMultiFilter->setVisible(ui->filterBox->checkState() == Qt::Checked); - - slotElementsChanged(); + auto* action = new QWidgetAction(this); + filterList = new ElementFilterList(this); + action->setDefaultWidget(filterList); + qAsConst(ui->filterButton)->addAction(action); } -bool TaskSketcherElements::eventFilter(QObject* obj, QEvent* event) +void TaskSketcherElements::onFilterBoxStateChanged(int val) { - if (collapseFilter) { - if (obj == qobject_cast(ui->filterBox) && event->type() == QEvent::Enter && ui->filterBox->checkState() == Qt::Checked) { - ui->listMultiFilter->show(); - } - else if (obj == qobject_cast(ui->listMultiFilter) && event->type() == QEvent::Leave) { - ui->listMultiFilter->hide(); - } - else if (obj == this && event->type() == QEvent::Leave) { - ui->listMultiFilter->hide(); - } - } - return TaskBox::eventFilter(obj, event); + Q_UNUSED(val); + ui->filterButton->setEnabled(ui->filterBox->checkState() == Qt::Checked); + slotElementsChanged(); } enum class GeoFilterType { NormalGeos, @@ -636,13 +641,33 @@ enum class GeoFilterType { NormalGeos, void TaskSketcherElements::onListMultiFilterItemChanged(QListWidgetItem* item) { { - int start = 4; //From 4 to the end, it's the geometry types (line, circle, arc...) - QSignalBlocker sigblk(ui->listMultiFilter); - if (item == ui->listMultiFilter->item(static_cast(GeoFilterType::AllGeosTypes))) { - for (int i = start; i < ui->listMultiFilter->count(); i++) { - ui->listMultiFilter->item(i)->setCheckState(item->checkState()); + QSignalBlocker sigblk(filterList); + + int index = filterList->row(item); + int indexOfAllTypes = static_cast(GeoFilterType::AllGeosTypes); + + if (index == indexOfAllTypes) { + for (int i = indexOfAllTypes + 1; i < filterList->count(); i++) { + filterList->item(i)->setCheckState(item->checkState()); } } + else if (index > indexOfAllTypes) { + bool atLeastOneUnchecked = false; + bool atLeastOneChecked = false; + + for (int i = indexOfAllTypes + 1; i < filterList->count(); i++) { + if (filterList->item(i)->checkState() == Qt::Checked) + atLeastOneChecked = true; + if (filterList->item(i)->checkState() == Qt::Unchecked) + atLeastOneUnchecked = true; + } + if (atLeastOneChecked && atLeastOneUnchecked) + filterList->item(indexOfAllTypes)->setCheckState(Qt::PartiallyChecked); + else if(atLeastOneUnchecked) + filterList->item(indexOfAllTypes)->setCheckState(Qt::Unchecked); + else if(atLeastOneChecked) + filterList->item(indexOfAllTypes)->setCheckState(Qt::Checked); + } } updateVisibility(); @@ -656,19 +681,19 @@ void TaskSketcherElements::setItemVisibility(QListWidgetItem* it) using GeometryState = ElementItem::GeometryState; - if ((ui->listMultiFilter->item(static_cast(GeoFilterType::NormalGeos))->checkState() == Qt::Unchecked && item->State == GeometryState::Normal) || - (ui->listMultiFilter->item(static_cast(GeoFilterType::ConstructionGeos))->checkState() == Qt::Unchecked && item->State == GeometryState::Construction) || - (ui->listMultiFilter->item(static_cast(GeoFilterType::InternalGeos))->checkState() == Qt::Unchecked && item->State == GeometryState::InternalAlignment) || - (ui->listMultiFilter->item(static_cast(GeoFilterType::ExternalGeos))->checkState() == Qt::Unchecked && item->State == GeometryState::External) || - (ui->listMultiFilter->item(static_cast(GeoFilterType::PointGeos))->checkState() == Qt::Unchecked && item->GeometryType == Part::GeomPoint::getClassTypeId()) || - (ui->listMultiFilter->item(static_cast(GeoFilterType::LineGeos))->checkState() == Qt::Unchecked && item->GeometryType == Part::GeomLineSegment::getClassTypeId()) || - (ui->listMultiFilter->item(static_cast(GeoFilterType::CircleGeos))->checkState() == Qt::Unchecked && item->GeometryType == Part::GeomCircle::getClassTypeId()) || - (ui->listMultiFilter->item(static_cast(GeoFilterType::EllipseGeos))->checkState() == Qt::Unchecked && item->GeometryType == Part::GeomEllipse::getClassTypeId()) || - (ui->listMultiFilter->item(static_cast(GeoFilterType::ArcGeos))->checkState() == Qt::Unchecked && item->GeometryType == Part::GeomArcOfCircle::getClassTypeId()) || - (ui->listMultiFilter->item(static_cast(GeoFilterType::ArcOfEllipseGeos))->checkState() == Qt::Unchecked && item->GeometryType == Part::GeomArcOfEllipse::getClassTypeId()) || - (ui->listMultiFilter->item(static_cast(GeoFilterType::HyperbolaGeos))->checkState() == Qt::Unchecked && item->GeometryType == Part::GeomArcOfHyperbola::getClassTypeId()) || - (ui->listMultiFilter->item(static_cast(GeoFilterType::ParabolaGeos))->checkState() == Qt::Unchecked && item->GeometryType == Part::GeomArcOfParabola::getClassTypeId()) || - (ui->listMultiFilter->item(static_cast(GeoFilterType::BSplineGeos))->checkState() == Qt::Unchecked && item->GeometryType == Part::GeomBSplineCurve::getClassTypeId()) ) + if ((filterList->item(static_cast(GeoFilterType::NormalGeos))->checkState() == Qt::Unchecked && item->State == GeometryState::Normal) || + (filterList->item(static_cast(GeoFilterType::ConstructionGeos))->checkState() == Qt::Unchecked && item->State == GeometryState::Construction) || + (filterList->item(static_cast(GeoFilterType::InternalGeos))->checkState() == Qt::Unchecked && item->State == GeometryState::InternalAlignment) || + (filterList->item(static_cast(GeoFilterType::ExternalGeos))->checkState() == Qt::Unchecked && item->State == GeometryState::External) || + (filterList->item(static_cast(GeoFilterType::PointGeos))->checkState() == Qt::Unchecked && item->GeometryType == Part::GeomPoint::getClassTypeId()) || + (filterList->item(static_cast(GeoFilterType::LineGeos))->checkState() == Qt::Unchecked && item->GeometryType == Part::GeomLineSegment::getClassTypeId()) || + (filterList->item(static_cast(GeoFilterType::CircleGeos))->checkState() == Qt::Unchecked && item->GeometryType == Part::GeomCircle::getClassTypeId()) || + (filterList->item(static_cast(GeoFilterType::EllipseGeos))->checkState() == Qt::Unchecked && item->GeometryType == Part::GeomEllipse::getClassTypeId()) || + (filterList->item(static_cast(GeoFilterType::ArcGeos))->checkState() == Qt::Unchecked && item->GeometryType == Part::GeomArcOfCircle::getClassTypeId()) || + (filterList->item(static_cast(GeoFilterType::ArcOfEllipseGeos))->checkState() == Qt::Unchecked && item->GeometryType == Part::GeomArcOfEllipse::getClassTypeId()) || + (filterList->item(static_cast(GeoFilterType::HyperbolaGeos))->checkState() == Qt::Unchecked && item->GeometryType == Part::GeomArcOfHyperbola::getClassTypeId()) || + (filterList->item(static_cast(GeoFilterType::ParabolaGeos))->checkState() == Qt::Unchecked && item->GeometryType == Part::GeomArcOfParabola::getClassTypeId()) || + (filterList->item(static_cast(GeoFilterType::BSplineGeos))->checkState() == Qt::Unchecked && item->GeometryType == Part::GeomBSplineCurve::getClassTypeId()) ) { item->setHidden(true); return; @@ -1180,23 +1205,18 @@ void TaskSketcherElements::changeEvent(QEvent *e) void TaskSketcherElements::createSettingsButtonActions() { QAction* action = new QAction(tr("Extended information"), this); - QAction* action2 = new QAction(tr("Auto collapse filter"), this); action->setCheckable(true); - action2->setCheckable(true); ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/Elements"); { QSignalBlocker block(this); action->setChecked(hGrp->GetBool("ExtendedNaming", false)); - action2->setChecked(hGrp->GetBool("AutoCollapseFilter", false)); } ui->settingsButton->addAction(action); - ui->settingsButton->addAction(action2); isNamingBoxChecked = hGrp->GetBool("ExtendedNaming", false); - collapseFilter = hGrp->GetBool("AutoCollapseFilter", true); } void TaskSketcherElements::onSettingsExtendedInformationChanged() @@ -1210,25 +1230,4 @@ void TaskSketcherElements::onSettingsExtendedInformationChanged() slotElementsChanged(); } -void TaskSketcherElements::onSettingsAutoCollapseFilterChanged() -{ - QList acts = ui->settingsButton->actions(); - collapseFilter = acts[1]->isChecked(); - - ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/Elements"); - hGrp->SetBool("AutoCollapseFilter", collapseFilter); - - if (collapseFilter) { - ui->listMultiFilter->setVisible(false); - } - else { - ui->listMultiFilter->setVisible(ui->filterBox->checkState() == Qt::Checked); - } -} - -void TaskSketcherElements::onSettingsButtonClicked(bool) -{ - ui->settingsButton->showMenu(); -} - #include "moc_TaskSketcherElements.cpp" diff --git a/src/Mod/Sketcher/Gui/TaskSketcherElements.h b/src/Mod/Sketcher/Gui/TaskSketcherElements.h index 735b7f3714..43053ab416 100644 --- a/src/Mod/Sketcher/Gui/TaskSketcherElements.h +++ b/src/Mod/Sketcher/Gui/TaskSketcherElements.h @@ -69,7 +69,7 @@ class ElementItem : public QListWidgetItem , StartingVertex(startingVertex) , MidVertex(midVertex) , EndVertex(endVertex) - , GeometryType(geometryType) + , GeometryType(std::move(geometryType)) , State(state) , isLineSelected(false) , isStartingPointSelected(false) @@ -177,6 +177,16 @@ Q_SIGNALS: void onItemHovered(QListWidgetItem *); }; +class ElementFilterList : public QListWidget +{ + Q_OBJECT + +public: + explicit ElementFilterList(QWidget* parent = nullptr); + ~ElementFilterList() override; + +}; + class TaskSketcherElements : public Gui::TaskView::TaskBox, public Gui::SelectionObserver { Q_OBJECT @@ -188,13 +198,12 @@ public: /// Observer message from the Selection void onSelectionChanged(const Gui::SelectionChanges& msg) override; - bool eventFilter(QObject* obj, QEvent* event) override; - private: void slotElementsChanged(); void updateVisibility(); void setItemVisibility(QListWidgetItem* item); void clearWidget(); + void createFilterButtonActions(); void createSettingsButtonActions(); void connectSignals(); @@ -203,8 +212,6 @@ public Q_SLOTS: void onListWidgetElementsItemEntered(QListWidgetItem *item); void onListWidgetElementsMouseMoveOnItem(QListWidgetItem* item); void onSettingsExtendedInformationChanged(); - void onSettingsAutoCollapseFilterChanged(); - void onSettingsButtonClicked(bool); void onFilterBoxStateChanged(int val); void onListMultiFilterItemChanged(QListWidgetItem* item); @@ -224,8 +231,9 @@ private: int previouslyHoveredItemIndex; SubElementType previouslyHoveredType; + ElementFilterList* filterList; + bool isNamingBoxChecked; - bool collapseFilter; }; } //namespace SketcherGui diff --git a/src/Mod/Sketcher/Gui/TaskSketcherElements.ui b/src/Mod/Sketcher/Gui/TaskSketcherElements.ui index fb8d713478..a24ea81530 100644 --- a/src/Mod/Sketcher/Gui/TaskSketcherElements.ui +++ b/src/Mod/Sketcher/Gui/TaskSketcherElements.ui @@ -30,17 +30,48 @@ + + + 0 + 0 + + - Check to activate filters + Check to toggle filters - padding-bottom: 0px; margin-bottom: 0px + padding-right: 0px; margin-right: 0px + + + + + + false + + + + + + + + 0 + 0 + + + + Click to show filters + + + padding-left: 0px; margin-left: 0px + + + false Filters - - false + + QToolButton::MenuButtonPopup @@ -69,98 +100,6 @@ - - - - - 0 - 0 - - - - padding-top: 0px; margin-top: 0px - - - QAbstractScrollArea::AdjustToContents - - - QAbstractItemView::NoSelection - - - 0 - - - - Normal - - - - - Construction - - - - - Internal - - - - - External - - - - - All types - - - - - - Point - - - - - - Line - - - - - - Circle - - - - - - Ellipse - - - - - - Arc - - - - - - Arc of ellipse - - - - - - Arc of hyperbola - - - - - - Arc of parabola - - - - - - B-Spline - - - -