KisPaletteComboBox.cpp 5.33 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 *  Copyright (c) 2018 Michael Zhou <simeirxh@gmail.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

Michael Zhou's avatar
Michael Zhou committed
19 20 21 22
// Qt
#include <QPainter>
#include <QPen>
#include <QVector>
23
#include <QCompleter>
Michael Zhou's avatar
Michael Zhou committed
24 25 26 27

// STL
#include <algorithm>

28
#include "kis_palette_view.h"
Michael Zhou's avatar
Michael Zhou committed
29 30 31
#include "KisPaletteComboBox.h"

KisPaletteComboBox::KisPaletteComboBox(QWidget *parent)
32
    : KisSqueezedComboBox(parent)
33
    , m_model(0)
Michael Zhou's avatar
Michael Zhou committed
34
{
35 36 37 38 39
    setEditable(true);
    setInsertPolicy(NoInsert);
    completer()->setCompletionMode(QCompleter::PopupCompletion);
    completer()->setCaseSensitivity(Qt::CaseInsensitive);
    completer()->setFilterMode(Qt::MatchContains);
40
    connect(this, SIGNAL(currentIndexChanged(int)), SLOT(slotIndexUpdated(int)));
Michael Zhou's avatar
Michael Zhou committed
41 42 43 44 45 46 47
}

KisPaletteComboBox::~KisPaletteComboBox()
{ }

void KisPaletteComboBox::setPaletteModel(const KisPaletteModel *paletteModel)
{
48 49 50
    if (!m_model.isNull()) {
        m_model->disconnect(this);
    }
Michael Zhou's avatar
Michael Zhou committed
51 52 53
    m_model = paletteModel;
    if (m_model.isNull()) { return; }
    slotPaletteChanged();
54
    connect(m_model, SIGNAL(sigPaletteChanged()),
55
            SLOT(slotPaletteChanged()));
56
    connect(m_model, SIGNAL(sigPaletteModified()),
Michael Zhou's avatar
Michael Zhou committed
57 58 59
            SLOT(slotPaletteChanged()));
}

60 61 62 63 64 65 66 67 68 69 70 71
void KisPaletteComboBox::setCompanionView(KisPaletteView *view)
{
    if (!m_view.isNull()) {
        m_view->disconnect(this);
        disconnect(m_view.data());
    }
    m_view = view;
    setPaletteModel(view->paletteModel());
    connect(view, SIGNAL(sigIndexSelected(QModelIndex)),
            SLOT(slotSwatchSelected(QModelIndex)));
}

Michael Zhou's avatar
Michael Zhou committed
72 73 74
void KisPaletteComboBox::slotPaletteChanged()
{
    clear();
75
    m_groupMapMap.clear();
76 77
    m_idxSwatchMap.clear();

78 79
    if (QPointer<KoColorSet>(m_model->colorSet()).isNull()) { return; }

Michael Zhou's avatar
Michael Zhou committed
80
    for (const QString &groupName : m_model->colorSet()->getGroupNames()) {
81 82
        QVector<SwatchInfoType> infoList;
        PosIdxMapType posIdxMap;
Michael Zhou's avatar
Michael Zhou committed
83 84
        const KisSwatchGroup *group = m_model->colorSet()->getGroup(groupName);
        for (const SwatchInfoType &info : group->infoList()) {
85
            infoList.append(info);
Michael Zhou's avatar
Michael Zhou committed
86
        }
87 88 89 90 91 92 93
        std::sort(infoList.begin(), infoList.end(), swatchInfoLess);
        for (const SwatchInfoType &info : infoList) {
            const KisSwatch &swatch = info.swatch;
            QString name = swatch.name();
            if (!swatch.id().isEmpty()){
                name = swatch.id() + " - " + swatch.name();
            }
94
            addSqueezedItem(QIcon(createColorSquare(swatch)), name);
95 96
            posIdxMap[SwatchPosType(info.column, info.row)] = count() - 1;
            m_idxSwatchMap.push_back(swatch);
Michael Zhou's avatar
Michael Zhou committed
97
        }
98
        m_groupMapMap[group->name()] = posIdxMap;
Michael Zhou's avatar
Michael Zhou committed
99
    }
Michael Zhou's avatar
Michael Zhou committed
100
    if (m_view.isNull()) {
101 102 103 104
        setCurrentIndex(0);
    }
    QModelIndex idx = m_view->currentIndex();
    if (!idx.isValid()) { return; }
Michael Zhou's avatar
Michael Zhou committed
105
    if (qvariant_cast<bool>(idx.data(KisPaletteModel::IsGroupNameRole))) { return; }
106 107 108
    if (!qvariant_cast<bool>(idx.data(KisPaletteModel::CheckSlotRole))) { return; }

    blockSignals(true); // this is a passive selection; this shouldn't make others change
Michael Zhou's avatar
Michael Zhou committed
109
    slotSwatchSelected(idx);
110
    blockSignals(false);
Michael Zhou's avatar
Michael Zhou committed
111 112
}

113
bool KisPaletteComboBox::swatchInfoLess(const SwatchInfoType &first, const SwatchInfoType &second)
Michael Zhou's avatar
Michael Zhou committed
114
{
115
    return first.swatch.name() < second.swatch.name();
Michael Zhou's avatar
Michael Zhou committed
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
}

QPixmap KisPaletteComboBox::createColorSquare(const KisSwatch &swatch) const
{
    QPixmap colorSquare(32, 32);
    if (swatch.spotColor()) {
        QImage img = QImage(32, 32, QImage::Format_ARGB32);
        QPainter circlePainter;
        img.fill(Qt::transparent);
        circlePainter.begin(&img);
        QBrush brush = QBrush(Qt::SolidPattern);
        brush.setColor(swatch.color().toQColor());
        circlePainter.setBrush(brush);
        QPen pen = circlePainter.pen();
        pen.setColor(Qt::transparent);
        pen.setWidth(0);
        circlePainter.setPen(pen);
        circlePainter.drawEllipse(0, 0, 32, 32);
        circlePainter.end();
        colorSquare = QPixmap::fromImage(img);
    } else {
        colorSquare.fill(swatch.color().toQColor());
    }
    return colorSquare;
}

142
void KisPaletteComboBox::slotSwatchSelected(const QModelIndex &index)
Michael Zhou's avatar
Michael Zhou committed
143
{
144 145 146
    if (!qvariant_cast<bool>(index.data(KisPaletteModel::CheckSlotRole))) {
        return;
    }
147 148 149
    if (qvariant_cast<bool>(index.data(KisPaletteModel::IsGroupNameRole))) {
        return;
    }
150 151 152
    QString gName = qvariant_cast<QString>(index.data(KisPaletteModel::GroupNameRole));
    int rowInGroup = qvariant_cast<int>(index.data(KisPaletteModel::RowInGroupRole));
    setCurrentIndex(m_groupMapMap[gName][SwatchPosType(index.column(), rowInGroup)]);
Michael Zhou's avatar
Michael Zhou committed
153
}
154

155
void KisPaletteComboBox::slotIndexUpdated(int idx)
156 157 158 159 160
{
    if (idx >= 0 && idx < m_idxSwatchMap.size()) {
        emit sigColorSelected(m_idxSwatchMap[idx].color());
    }
}