diff --git a/libs/ui/widgets/kis_layer_filter_widget.cpp b/libs/ui/widgets/kis_layer_filter_widget.cpp index 93067b137c..95c73b0789 100644 --- a/libs/ui/widgets/kis_layer_filter_widget.cpp +++ b/libs/ui/widgets/kis_layer_filter_widget.cpp @@ -1,225 +1,227 @@ #include "kis_layer_filter_widget.h" #include #include #include #include #include #include #include #include "kis_debug.h" #include "kis_node.h" #include "kis_color_label_button.h" #include "kis_color_label_selector_widget.h" #include "kis_node_view_color_scheme.h" KisLayerFilterWidget::KisLayerFilterWidget(QWidget *parent) : QWidget(parent) { QVBoxLayout *layout = new QVBoxLayout(this); setLayout(layout); textFilter = new QLineEdit(this); textFilter->setPlaceholderText("Filter by name..."); textFilter->setMinimumWidth(256); textFilter->setMinimumHeight(32); textFilter->setClearButtonEnabled(true); connect(textFilter, SIGNAL(textChanged(QString)), this, SIGNAL(filteringOptionsChanged())); KisNodeViewColorScheme colorScheme; QWidget *buttonContainer = new QWidget(this); buttonContainer->setToolTip("Filter by color label..."); buttonEventFilter = new EventFilter(buttonContainer); { QHBoxLayout *subLayout = new QHBoxLayout(buttonContainer); buttonContainer->setLayout(subLayout); subLayout->setContentsMargins(0,0,0,0); buttonGroup = new KisColorLabelButtonGroup(buttonContainer); buttonGroup->setExclusive(false); foreach (const QColor &color, colorScheme.allColorLabels()) { KisColorLabelButton* btn = new KisColorLabelButton(color, buttonContainer); buttonGroup->addButton(btn); btn->setVisible(false); btn->installEventFilter(buttonEventFilter); subLayout->addWidget(btn); colorLabelButtons.append(btn); } connect(buttonGroup, SIGNAL(buttonToggled(int,bool)), this, SIGNAL(filteringOptionsChanged())); } QPushButton *resetButton = new QPushButton("Reset Filters", this); connect(resetButton, &QPushButton::clicked, [this](){ textFilter->clear(); buttonGroup->reset(); }); layout->addWidget(textFilter); layout->addWidget(buttonContainer); layout->addWidget(resetButton); } void KisLayerFilterWidget::scanUsedColorLabels(KisNodeSP node, QSet &colorLabels) { if (node->parent()) { colorLabels.insert(node->colorLabelIndex()); } KisNodeSP child = node->firstChild(); while(child) { scanUsedColorLabels(child, colorLabels); child = child->nextSibling(); } } void KisLayerFilterWidget::updateColorLabels(KisNodeSP root) { QSet colorLabels; scanUsedColorLabels(root, colorLabels); if (colorLabels.size() > 1) { colorLabelButtons[0]->parentWidget()->setVisible(true); for (size_t index = 0; index < colorLabelButtons.size(); index++) { if (colorLabels.contains(index)) { colorLabelButtons[index]->setVisible(true); } else { colorLabelButtons[index]->setVisible(false); colorLabelButtons[index]->setChecked(true); } } } else { colorLabelButtons[0]->parentWidget()->setVisible(false); } } bool KisLayerFilterWidget::isCurrentlyFiltering() { const bool isFilteringText = !textFilter->text().isEmpty(); bool isFilteringColors = false; for (int index = 0; index < colorLabelButtons.size(); index++) { if (colorLabelButtons[index]->isVisible() && !colorLabelButtons[index]->isChecked()) { isFilteringColors = true; } } return isFilteringText || isFilteringColors; } QList KisLayerFilterWidget::getActiveColors() { QList activeColors; for (int index = 0; index < colorLabelButtons.size(); index++) { if (!colorLabelButtons[index]->isVisible() || colorLabelButtons[index]->isChecked()) { activeColors.append(index); } } return activeColors; } QString KisLayerFilterWidget::getTextFilter() { return textFilter->text(); } void KisLayerFilterWidget::reset() { textFilter->clear(); for (int index = 0; index < colorLabelButtons.size(); index++) { colorLabelButtons[index]->setChecked(true); } filteringOptionsChanged(); } KisLayerFilterWidget::EventFilter::EventFilter(QWidget *buttonContainer, QObject* parent) : QObject(parent) { m_buttonContainer = buttonContainer; lastKnownMousePosition = QPoint(0,0); currentState = Idle; } bool KisLayerFilterWidget::EventFilter::eventFilter(QObject *obj, QEvent *event) { if (event->type() == QEvent::MouseButtonPress) { QMouseEvent* mouseEvent = static_cast(event); currentState = WaitingForDragLeave; lastKnownMousePosition = mouseEvent->globalPos(); return true; } else if (event->type() == QEvent::MouseButtonRelease) { QMouseEvent* mouseEvent = static_cast(event); //If we never left, toggle the original button. if( currentState == WaitingForDragLeave ) { QAbstractButton* btn = static_cast(obj); btn->click(); } currentState = Idle; lastKnownMousePosition = mouseEvent->globalPos(); return true; } else if (event->type() == QEvent::MouseMove ) { if (currentState == WaitingForDragLeave) { QMouseEvent* mouseEvent = static_cast(event); QWidget* firstClicked = static_cast(obj); const QPointF localPosition = mouseEvent->localPos(); if (!firstClicked->rect().contains(localPosition.x(), localPosition.y())) { QAbstractButton* btn = static_cast(obj); btn->click(); checkSlideOverNeighborButtons(mouseEvent, btn); currentState = WaitingForDragEnter; } lastKnownMousePosition = mouseEvent->globalPos(); return true; } else if (currentState == WaitingForDragEnter) { QMouseEvent* mouseEvent = static_cast(event); QAbstractButton* startingButton = static_cast(obj); const QPoint currentPosition = mouseEvent->globalPos(); checkSlideOverNeighborButtons(mouseEvent, startingButton); lastKnownMousePosition = currentPosition; return true; } } return false; } void KisLayerFilterWidget::EventFilter::checkSlideOverNeighborButtons(QMouseEvent* mouseEvent, QAbstractButton* startingButton) { const QPoint currentPosition = mouseEvent->globalPos(); if (startingButton->group()) { QList allButtons = startingButton->group()->buttons(); Q_FOREACH(QAbstractButton* button, allButtons) { const QRect bounds = QRect(button->mapToGlobal(QPoint(0,0)), button->size()); - const QRect mouseMovement = QRect(lastKnownMousePosition, currentPosition); + const QPoint upperLeft = QPoint(qMin(lastKnownMousePosition.x(), currentPosition.x()), qMin(lastKnownMousePosition.y(), currentPosition.y())); + const QPoint lowerRight = QPoint(qMax(lastKnownMousePosition.x(), currentPosition.x()), qMax(lastKnownMousePosition.y(), currentPosition.y())); + const QRect mouseMovement = QRect(upperLeft, lowerRight); if( bounds.intersects(mouseMovement) && !bounds.contains(lastKnownMousePosition)) { button->click(); } } } }