kis_brush_chooser.cpp 10.1 KB
Newer Older
1 2
/*
 *  Copyright (c) 2004 Adrian Page <adrian@pagenet.plus.com>
3
 *  Copyright (c) 2009 Sven Langkamp <sven.langkamp@gmail.com>
4
 *  Copyright (c) 2010 Cyrille Berger <cberger@cberger.net>
5
 *  Copyright (c) 2010 Lukáš Tvrdý <lukast.dev@gmail.com>
6
 *  Copyright (C) 2011 Srikanth Tiyyagura <srikanth.tulasiram@gmail.com>
7 8 9 10 11 12 13 14 15 16 17 18 19
 *
 *  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
20
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21
 */
Boudewijn Rempt's avatar
Boudewijn Rempt committed
22

23 24
#include "kis_brush_chooser.h"

25 26 27
#include <QLabel>
#include <QLayout>
#include <QCheckBox>
28
#include <QPushButton>
Adrian Page's avatar
Adrian Page committed
29
#include <QVBoxLayout>
30
#include <QHBoxLayout>
Adrian Page's avatar
Adrian Page committed
31
#include <QGridLayout>
32 33
#include <QPainter>
#include <QAbstractItemDelegate>
34 35
#include <klocale.h>

36
#include <KoResourceItemChooser.h>
Boudewijn Rempt's avatar
Boudewijn Rempt committed
37 38 39 40
#include <KoResourceServer.h>
#include <KoResourceServerAdapter.h>
#include <KoResourceServerProvider.h>

41
#include "kis_brush_registry.h"
42
#include "kis_brush_server.h"
43
#include "widgets/kis_slider_spin_box.h"
44
#include "widgets/kis_multipliers_double_slider_spinbox.h"
45 46 47
#include "kis_spacing_selection_widget.h"
#include "kis_signals_blocker.h"

Boudewijn Rempt's avatar
Boudewijn Rempt committed
48

49
#include "kis_global.h"
50
#include "kis_gbr_brush.h"
51
#include "kis_debug.h"
52

53 54 55 56
/// The resource item delegate for rendering the resource preview
class KisBrushDelegate : public QAbstractItemDelegate
{
public:
Boudewijn Rempt's avatar
Boudewijn Rempt committed
57
    KisBrushDelegate(QObject * parent = 0) : QAbstractItemDelegate(parent) {}
58 59
    virtual ~KisBrushDelegate() {}
    /// reimplemented
Boudewijn Rempt's avatar
Boudewijn Rempt committed
60
    virtual void paint(QPainter *, const QStyleOptionViewItem &, const QModelIndex &) const;
61
    /// reimplemented
Boudewijn Rempt's avatar
Boudewijn Rempt committed
62
    QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex &) const {
63 64 65 66
        return option.decorationSize;
    }
};

Boudewijn Rempt's avatar
Boudewijn Rempt committed
67
void KisBrushDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
68
{
Boudewijn Rempt's avatar
Boudewijn Rempt committed
69
    if (! index.isValid())
70 71
        return;

72
    KisBrush *brush = static_cast<KisBrush*>(index.internalPointer());
73 74

    QRect itemRect = option.rect;
Boudewijn Rempt's avatar
Boudewijn Rempt committed
75
    QImage thumbnail = brush->image();
76

Boudewijn Rempt's avatar
Boudewijn Rempt committed
77 78
    if (thumbnail.height() > itemRect.height() || thumbnail.width() > itemRect.width()) {
        thumbnail = thumbnail.scaled(itemRect.size() , Qt::KeepAspectRatio);
79 80 81 82 83
    }

    painter->save();
    int dx = (itemRect.width() - thumbnail.width()) / 2;
    int dy = (itemRect.height() - thumbnail.height()) / 2;
Boudewijn Rempt's avatar
Boudewijn Rempt committed
84
    painter->drawImage(itemRect.x() + dx, itemRect.y() + dy, thumbnail);
85 86

    if (option.state & QStyle::State_Selected) {
Boudewijn Rempt's avatar
Boudewijn Rempt committed
87 88
        painter->setPen(QPen(option.palette.highlight(), 2.0));
        painter->drawRect(option.rect);
89 90 91
        painter->setCompositionMode(QPainter::CompositionMode_HardLight);
        painter->setOpacity(0.65);
        painter->fillRect(option.rect, option.palette.highlight());
92 93 94 95 96 97
    }

    painter->restore();
}


98
KisBrushChooser::KisBrushChooser(QWidget *parent, const char *name)
99
    : QWidget(parent)
100
{
101 102
    setObjectName(name);

103
    m_lbSize = new QLabel(i18n("Size:"), this);
104
    m_slSize = new KisDoubleSliderSpinBox(this);
105 106 107 108 109 110
    m_slSize->setRange(0, 1000, 0);
    m_slSize->setValue(5);
    m_slSize->setExponentRatio(3.0);
    m_slSize->setSuffix(" px");


111
    m_slSize->setExponentRatio(3.0);
112 113
    QObject::connect(m_slSize, SIGNAL(valueChanged(qreal)), this, SLOT(slotSetItemSize(qreal)));

114

115
    m_lbRotation = new QLabel(i18n("Rotation:"), this);
116
    m_slRotation = new KisDoubleSliderSpinBox(this);
117 118 119
    m_slRotation->setRange(0, 360, 0);
    m_slRotation->setValue(0);
    m_slRotation->setSuffix(QChar(Qt::Key_degree));
120 121
    QObject::connect(m_slRotation, SIGNAL(valueChanged(qreal)), this, SLOT(slotSetItemRotation(qreal)));

122
    m_lbSpacing = new QLabel(i18n("Spacing:"), this);
123 124 125
    m_slSpacing = new KisSpacingSelectionWidget(this);
    m_slSpacing->setSpacing(true, 1.0);
    connect(m_slSpacing, SIGNAL(sigSpacingChanged()), SLOT(slotSpacingChanged()));
126

127 128
    m_chkColorMask = new QCheckBox(i18n("Use color as mask"), this);
    QObject::connect(m_chkColorMask, SIGNAL(toggled(bool)), this, SLOT(slotSetItemUseColorAsMask(bool)));
129

130
    m_lbName = new QLabel(this);
131

132 133
    KisBrushResourceServer* rServer = KisBrushServer::instance()->brushServer();
    QSharedPointer<KisBrushResourceServerAdapter> adapter(new KisBrushResourceServerAdapter(rServer));
Sven Langkamp's avatar
 
Sven Langkamp committed
134
    m_itemChooser = new KoResourceItemChooser(adapter, this);
135
    QString knsrcFile = "kritabrushes.knsrc";
136
    m_itemChooser->setKnsrcFile(knsrcFile);
137
    m_itemChooser->showGetHotNewStuff(true, true);
138
    m_itemChooser->showTaggingBar(true, true);
139 140 141
    m_itemChooser->setColumnCount(10);
    m_itemChooser->setRowHeight(30);
    m_itemChooser->setItemDelegate(new KisBrushDelegate(this));
142
    m_itemChooser->setCurrentItem(0, 0);
Sven Langkamp's avatar
 
Sven Langkamp committed
143

144
    connect(m_itemChooser, SIGNAL(resourceSelected(KoResource *)), this, SLOT(update(KoResource *)));
Boudewijn Rempt's avatar
Boudewijn Rempt committed
145

Adrian Page's avatar
Adrian Page committed
146 147
    QVBoxLayout *mainLayout = new QVBoxLayout(this);
    mainLayout->setObjectName("main layout");
148

149
    mainLayout->addWidget(m_lbName);
Boudewijn Rempt's avatar
Boudewijn Rempt committed
150
    mainLayout->addWidget(m_itemChooser, 10);
151

Adrian Page's avatar
Adrian Page committed
152
    QGridLayout *spacingLayout = new QGridLayout();
153

154
    mainLayout->addLayout(spacingLayout, 1);
155

156 157 158 159 160 161
    spacingLayout->addWidget(m_lbSize, 1, 0);
    spacingLayout->addWidget(m_slSize, 1, 1);
    spacingLayout->addWidget(m_lbRotation, 2, 0);
    spacingLayout->addWidget(m_slRotation, 2, 1);
    spacingLayout->addWidget(m_lbSpacing, 3, 0);
    spacingLayout->addWidget(m_slSpacing, 3, 1);
162
    spacingLayout->setColumnStretch(1, 3);
163

164
    QPushButton *resetBrushButton = new QPushButton(i18n("Reset Predefined Tip"), this);
165 166 167 168 169 170 171 172
    resetBrushButton->setToolTip(i18n("Reloads Spacing from file\nSets Scale to 1.0\nSets Rotation to 0.0"));
    connect(resetBrushButton, SIGNAL(clicked()), SLOT(slotResetBrush()));

    QHBoxLayout *resetHLayout = new QHBoxLayout();
    resetHLayout->addWidget(m_chkColorMask, 0);
    resetHLayout->addWidget(resetBrushButton, 0, Qt::AlignRight);

    spacingLayout->addLayout(resetHLayout, 4, 0, 1, 2);
173 174

    slotActivatedBrush(m_itemChooser->currentResource());
175
    update(m_itemChooser->currentResource());
176 177 178 179 180 181
}

KisBrushChooser::~KisBrushChooser()
{
}

Boudewijn Rempt's avatar
Boudewijn Rempt committed
182
void KisBrushChooser::setBrush(KisBrushSP _brush)
183
{
184 185
    m_itemChooser->setCurrentResource(_brush.data());
    update(_brush.data());
186 187
}

188
void KisBrushChooser::slotResetBrush()
189
{
190 191
    KisBrush *brush = dynamic_cast<KisBrush *>(m_itemChooser->currentResource());
    if (brush) {
192 193 194
        brush->load();
        brush->setScale(1.0);
        brush->setAngle(0.0);
195
        slotActivatedBrush(brush);
196 197 198 199
        update(brush);
        emit sigBrushChanged();
    }
}
200

201 202 203 204 205 206 207 208 209
void KisBrushChooser::slotSetItemSize(qreal sizeValue)
{
    KisBrush *brush = dynamic_cast<KisBrush *>(m_itemChooser->currentResource());

    if (brush) {
        int brushWidth = brush->width();

        brush->setScale(sizeValue / qreal(brushWidth));
        slotActivatedBrush(brush);
210 211 212
        emit sigBrushChanged();
    }
}
213

214 215
void KisBrushChooser::slotSetItemRotation(qreal rotationValue)
{
216 217
    KisBrush *brush = dynamic_cast<KisBrush *>(m_itemChooser->currentResource());
    if (brush) {
218
        brush->setAngle(rotationValue / 180.0 * M_PI);
219 220 221 222 223 224
        slotActivatedBrush(brush);

        emit sigBrushChanged();
    }
}

225
void KisBrushChooser::slotSpacingChanged()
226
{
227 228
    KisBrush *brush = dynamic_cast<KisBrush *>(m_itemChooser->currentResource());
    if (brush) {
229 230
        brush->setSpacing(m_slSpacing->spacing());
        brush->setAutoSpacing(m_slSpacing->autoSpacingActive(), m_slSpacing->autoSpacingCoeff());
231
        slotActivatedBrush(brush);
232

233 234
        emit sigBrushChanged();
    }
235 236 237 238
}

void KisBrushChooser::slotSetItemUseColorAsMask(bool useColorAsMask)
{
239 240 241 242
    KisGbrBrush *brush = dynamic_cast<KisGbrBrush *>(m_itemChooser->currentResource());
    if (brush) {
        brush->setUseColorAsMask(useColorAsMask);
        slotActivatedBrush(brush);
243

244
        emit sigBrushChanged();
245
    }
246 247
}

Sven Langkamp's avatar
 
Sven Langkamp committed
248
void KisBrushChooser::update(KoResource * resource)
249
{
250
    KisBrush* brush = dynamic_cast<KisBrush*>(resource);
251

252
    if (brush) {
253
        blockSignals(true);
254
        QString text = QString("%1 (%2 x %3)")
255 256 257
                       .arg(i18n(brush->name().toUtf8().data()))
                       .arg(brush->width())
                       .arg(brush->height());
258

259
        m_lbName->setText(text);
260 261 262 263 264 265 266

        {
            KisSignalsBlocker b(m_slSpacing);
            m_slSpacing->setSpacing(brush->autoSpacingActive(),
                                    brush->autoSpacingActive() ?
                                    brush->autoSpacingCoeff() : brush->spacing());
        }
267 268

        m_slRotation->blockSignals(true);
269
        m_slRotation->setValue(brush->angle() * 180 / M_PI);
270
        m_slRotation->blockSignals(false);
271

272 273 274
        m_slSize->blockSignals(true);
        m_slSize->setValue(brush->width() * brush->scale());
        m_slSize->blockSignals(false);
275

276 277 278 279 280 281
        // useColorAsMask support is only in gimp brush so far
        KisGbrBrush *gimpBrush = dynamic_cast<KisGbrBrush*>(resource);
        if (gimpBrush) {
            m_chkColorMask->setChecked(gimpBrush->useColorAsMask());
        }
        m_chkColorMask->setEnabled(brush->hasColor() && gimpBrush);
282
        blockSignals(false);
283

284
        slotActivatedBrush(brush);
285 286
        emit sigBrushChanged();
    }
287 288
}

289 290
void KisBrushChooser::slotActivatedBrush(KoResource * resource)
{
291 292 293
    if (m_brush) {
        m_brush->clearBrushPyramid();
    }
294
    KisBrush* brush = dynamic_cast<KisBrush*>(resource);
Boudewijn Rempt's avatar
Boudewijn Rempt committed
295
    if (brush) {
296
        m_brush = brush;
297
        m_brush->prepareBrushPyramid();
298 299 300
    }
}

301 302
void KisBrushChooser::setBrushSize(qreal xPixels, qreal yPixels)
{
303 304 305
    Q_UNUSED(yPixels);
    qreal oldWidth = m_brush->width() * m_brush->scale();
    qreal newWidth = oldWidth + xPixels;
306

Rex Dieter's avatar
Rex Dieter committed
307
    newWidth = qMax(newWidth, qreal(0.1));
308

309
    m_slSize->setValue(newWidth);
310 311 312
}


313
#include "kis_brush_chooser.moc"