• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • krita API Reference
  • KDE Home
  • Contact Us
 

plugins/paintops/libpaintop

  • sources
  • kfour-appscomplete
  • krita
  • plugins
  • paintops
  • libpaintop
kis_custom_brush_widget.cpp
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2005 Bart Coppens <[email protected]>
3  * SPDX-FileCopyrightText: 2010 Lukáš Tvrdý <[email protected]>
4  *
5  * SPDX-License-Identifier: GPL-2.0-or-later
6  */
7 
8 #include "kis_custom_brush_widget.h"
9 
10 #include <kis_debug.h>
11 #include <QLabel>
12 #include <QImage>
13 #include <QPushButton>
14 #include <QComboBox>
15 #include <QCheckBox>
16 
17 #include <QDateTime>
18 
19 #include <QPixmap>
20 #include <QShowEvent>
21 
22 #include <KoResourcePaths.h>
23 
24 #include "kis_image.h"
25 #include "kis_layer.h"
26 #include "kis_paint_device.h"
27 #include "kis_gbr_brush.h"
28 #include "kis_imagepipe_brush.h"
29 #include <kis_fixed_paint_device.h>
30 
31 #include "KisBrushServerProvider.h"
32 #include "kis_paint_layer.h"
33 #include "kis_group_layer.h"
34 #include <kis_selection.h>
35 #include <KoProperties.h>
36 #include "kis_iterator_ng.h"
37 #include "kis_image_barrier_locker.h"
38 
39 KisCustomBrushWidget::KisCustomBrushWidget(QWidget *parent, const QString& caption, KisImageWSP image)
40  : KisWdgCustomBrush(parent)
41  , m_image(image)
42 {
43  setWindowTitle(caption);
44  preview->setScaledContents(false);
45  preview->setFixedSize(preview->size());
46  preview->setStyleSheet("border: 2px solid #222; border-radius: 4px; padding: 5px; font: normal 10px;");
47 
48  m_rServer = KisBrushServerProvider::instance()->brushServer();
49 
50  m_brush = 0;
51 
52  connect(this, SIGNAL(accepted()), SLOT(slotAddPredefined()));
53  connect(brushStyle, SIGNAL(activated(int)), this, SLOT(slotUpdateCurrentBrush(int)));
54  connect(colorAsMask, SIGNAL(toggled(bool)), this, SLOT(slotUpdateUseColorAsMask(bool)));
55  connect(preserveAlpha, SIGNAL(toggled(bool)), this, SLOT(slotUpdateCurrentBrush()));
56  connect(comboBox2, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateCurrentBrush(int)));
57 
58 
59  colorAsMask->setChecked(true); // use color as mask by default. This is by far the most common way to make tip.
60  spacingWidget->setSpacing(true, 1.0);
61  connect(spacingWidget, SIGNAL(sigSpacingChanged()), SLOT(slotSpacingChanged()));
62 }
63 
64 KisCustomBrushWidget::~KisCustomBrushWidget()
65 {
66 }
67 
68 
69 KisBrushSP KisCustomBrushWidget::brush()
70 {
71  return m_brush;
72 }
73 
74 void KisCustomBrushWidget::setImage(KisImageWSP image){
75  m_image = image;
76  createBrush();
77  updatePreviewImage();
78 }
79 
80 void KisCustomBrushWidget::showEvent(QShowEvent *)
81 {
82  slotUpdateCurrentBrush(0);
83 }
84 
85 void KisCustomBrushWidget::updatePreviewImage()
86 {
87  QImage brushImage = m_brush ? m_brush->brushTipImage() : QImage();
88 
89  if (!brushImage.isNull()) {
90  int w = preview->size().width() - 10; // 10 for the padding...
91  brushImage = brushImage.scaled(w, w, Qt::KeepAspectRatio);
92  }
93 
94  preview->setPixmap(QPixmap::fromImage(brushImage));
95 }
96 
97 void KisCustomBrushWidget::slotUpdateCurrentBrush(int)
98 {
99  if (brushStyle->currentIndex() == 0) {
100  comboBox2->setEnabled(false);
101  } else {
102  comboBox2->setEnabled(true);
103  }
104  if (m_image) {
105  createBrush();
106  updatePreviewImage();
107  }
108 }
109 
110 void KisCustomBrushWidget::slotSpacingChanged()
111 {
112  if (m_brush) {
113  m_brush->setSpacing(spacingWidget->spacing());
114  m_brush->setAutoSpacing(spacingWidget->autoSpacingActive(), spacingWidget->autoSpacingCoeff());
115  }
116 }
117 
118 void KisCustomBrushWidget::slotUpdateUseColorAsMask(bool useColorAsMask)
119 {
120  preserveAlpha->setEnabled(useColorAsMask);
121  slotUpdateCurrentBrush();
122 }
123 
124 void KisCustomBrushWidget::slotUpdateSaveButton()
125 {
126  QString suffix = ".gbr";
127  if (brushStyle->currentIndex() != 0) {
128  suffix = ".gih";
129  }
130  if (QFileInfo(m_rServer->saveLocation() + "/" + nameLineEdit->text().split(" ").join("_")
131  + suffix).exists()) {
132  buttonBox->button(QDialogButtonBox::Save)->setText(i18n("Overwrite"));
133  } else {
134  buttonBox->button(QDialogButtonBox::Save)->setText(i18n("Save"));
135  }
136 }
137 
138 
139 void KisCustomBrushWidget::slotAddPredefined()
140 {
141  QString dir = KoResourcePaths::saveLocation("data", ResourceType::Brushes);
142 
143  QString name = nameLineEdit->text();
144 
145  if (nameLineEdit->text().isEmpty()) {
146  name = (QDateTime::currentDateTime().toString("yyyy-MM-ddThh:mm"));
147  }
148 
149  // Add it to the brush server, so that it automatically gets to the mediators, and
150  // so to the other brush choosers can pick it up, if they want to
151  if (m_rServer && m_brush) {
152 
153 
154  if (m_brush->clone().dynamicCast<KisGbrBrush>()) {
155  KisGbrBrushSP resource = m_brush->clone().dynamicCast<KisGbrBrush>();
156  resource->setName(name);
157  resource->setFilename(resource->name().split(" ").join("_") + resource->defaultFileExtension());
158  m_rServer->addResource(resource.dynamicCast<KisBrush>());
159  emit sigNewPredefinedBrush(resource);
160  }
161  else {
162  KisImagePipeBrushSP resource = m_brush->clone().dynamicCast<KisImagePipeBrush>();
163  resource->setName(name);
164  resource->setFilename(resource->name().split(" ").join("_") + resource->defaultFileExtension());
165  m_rServer->addResource(resource.dynamicCast<KisBrush>());
166  emit sigNewPredefinedBrush(resource);
167  }
168  }
169 
170  close();
171 }
172 
173 void KisCustomBrushWidget::createBrush()
174 {
175  if (!m_image)
176  return;
177 
178  if (brushStyle->currentIndex() == 0) {
179  KisSelectionSP selection = m_image->globalSelection();
180 
181  // create copy of the data
182  m_image->barrierLock();
183  KisPaintDeviceSP dev = new KisPaintDevice(*m_image->projection());
184  m_image->unlock();
185 
186  if (!selection) {
187  m_brush = KisBrushSP(new KisGbrBrush(dev, 0, 0, m_image->width(), m_image->height()));
188  }
189  else {
190  // apply selection mask
191  QRect r = selection->selectedExactRect();
192 
193  KisHLineIteratorSP pixelIt = dev->createHLineIteratorNG(r.x(), r.top(), r.width());
194  KisHLineConstIteratorSP maskIt = selection->projection()->createHLineIteratorNG(r.x(), r.top(), r.width());
195 
196  for (qint32 y = r.top(); y <= r.bottom(); ++y) {
197 
198  do {
199  dev->colorSpace()->applyAlphaU8Mask(pixelIt->rawData(), maskIt->oldRawData(), 1);
200  } while (pixelIt->nextPixel() && maskIt->nextPixel());
201 
202  pixelIt->nextRow();
203  maskIt->nextRow();
204  }
205  m_brush = KisBrushSP(new KisGbrBrush(dev, r.x(), r.y(), r.width(), r.height()));
206  }
207 
208  }
209  else {
210  // For each layer in the current image, create a new image, and add it to the list
211  QVector< QVector<KisPaintDevice*> > devices;
212  devices.push_back(QVector<KisPaintDevice*>());
213  int w = m_image->width();
214  int h = m_image->height();
215 
216  KisImageBarrierLocker locker(m_image);
217 
218  // We only loop over the rootLayer. Since we actually should have a layer selection
219  // list, no need to elaborate on that here and now
220  KoProperties properties;
221  properties.setProperty("visible", true);
222  QList<KisNodeSP> layers = m_image->root()->childNodes(QStringList("KisLayer"), properties);
223  KisNodeSP node;
224  Q_FOREACH (KisNodeSP node, layers) {
225  devices[0].push_back(node->projection().data());
226  }
227 
228  QVector<KisParasite::SelectionMode> modes;
229 
230  switch (comboBox2->currentIndex()) {
231  case 0: modes.push_back(KisParasite::Constant); break;
232  case 1: modes.push_back(KisParasite::Random); break;
233  case 2: modes.push_back(KisParasite::Incremental); break;
234  case 3: modes.push_back(KisParasite::Pressure); break;
235  case 4: modes.push_back(KisParasite::Angular); break;
236  default: modes.push_back(KisParasite::Incremental);
237  }
238 
239  m_brush = KisBrushSP(new KisImagePipeBrush(m_image->objectName(), w, h, devices, modes));
240  }
241 
242  static_cast<KisGbrBrush*>(m_brush.data())->setBrushApplication(colorAsMask->isChecked() ? ALPHAMASK : IMAGESTAMP);
243  if (colorAsMask->isChecked()) {
244  static_cast<KisGbrBrush*>(m_brush.data())->makeMaskImage(preserveAlpha->isChecked());
245  }
246  m_brush->setSpacing(spacingWidget->spacing());
247  m_brush->setAutoSpacing(spacingWidget->autoSpacingActive(), spacingWidget->autoSpacingCoeff());
248  m_brush->setFilename(TEMPORARY_FILENAME);
249  m_brush->setName(TEMPORARY_BRUSH_NAME);
250  m_brush->setValid(true);
251 }
TEMPORARY_FILENAME
const QString TEMPORARY_FILENAME
Definition: kis_custom_brush_widget.h:18
QWidget::y
int y() const
QSharedPointer::data
T * data() const
QPixmap::fromImage
QPixmap fromImage(const QImage &image, QFlags< Qt::ImageConversionFlag > flags)
QRect
QDateTime::currentDateTime
QDateTime currentDateTime()
KisWdgCustomBrush
Definition: kis_custom_brush_widget.h:26
QVector::push_back
void push_back(const T &value)
QWidget
QRect::width
int width() const
QImage::scaled
QImage scaled(int width, int height, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformMode) const
QRect::x
int x() const
QRect::y
int y() const
QSharedPointer< KisBrush >
QWidget::close
bool close()
QList
KisCustomBrushWidget::KisCustomBrushWidget
KisCustomBrushWidget(QWidget *parent, const QString &caption, KisImageWSP image)
Definition: kis_custom_brush_widget.cpp:39
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
KisCustomBrushWidget::showEvent
virtual void showEvent(QShowEvent *)
Definition: kis_custom_brush_widget.cpp:80
KisCustomBrushWidget::brush
KisBrushSP brush()
Definition: kis_custom_brush_widget.cpp:69
QRect::bottom
int bottom() const
kis_custom_brush_widget.h
QRect::top
int top() const
QString
QWidget::setWindowTitle
void setWindowTitle(const QString &)
QImage::isNull
bool isNull() const
QWidget::caption
QString caption() const
KisCustomBrushWidget::sigNewPredefinedBrush
void sigNewPredefinedBrush(KoResourceSP)
QShowEvent
QRect::height
int height() const
KisCustomBrushWidget::setImage
void setImage(KisImageWSP image)
Definition: kis_custom_brush_widget.cpp:74
QFileInfo
QObject::name
const char * name() const
KisCustomBrushWidget::~KisCustomBrushWidget
virtual ~KisCustomBrushWidget()
Definition: kis_custom_brush_widget.cpp:64
QVector
QDateTime::toString
QString toString(Qt::DateFormat format) const
QImage
KisBrushSP
QSharedPointer< KisBrush > KisBrushSP
Definition: KisDabCacheUtils.h:21
TEMPORARY_BRUSH_NAME
const QString TEMPORARY_BRUSH_NAME
Definition: kis_custom_brush_widget.h:19
QSharedPointer::dynamicCast
QSharedPointer< X > dynamicCast() const
QStringList
QDialog::accepted
void accepted()
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sat Apr 17 2021 23:38:22 by doxygen 1.8.16 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

plugins/paintops/libpaintop

Skip menu "plugins/paintops/libpaintop"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

krita API Reference

Skip menu "krita API Reference"
  • libs
  •   KritaBasicFlakes
  •   brush
  •   KritaUndo2
  •   KritaFlake
  •   image
  •   KritaPlugin
  •   Krita
  •   KritaPigment
  •   KritaResources
  •   KritaStore
  •   ui
  •   KritaWidgets
  •   KritaWidgetUtils
  • plugins
  •   Assitants
  •   Extensions
  •   Filters
  •   Generators
  •   Formats
  •           src
  •   PaintOps
  •     libpaintop

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal