File indexing completed on 2024-12-15 04:03:31
0001 0002 /* 0003 Copyright (c) 2003-2007 Clarence Dang <dang@kde.org> 0004 All rights reserved. 0005 0006 Redistribution and use in source and binary forms, with or without 0007 modification, are permitted provided that the following conditions 0008 are met: 0009 0010 1. Redistributions of source code must retain the above copyright 0011 notice, this list of conditions and the following disclaimer. 0012 2. Redistributions in binary form must reproduce the above copyright 0013 notice, this list of conditions and the following disclaimer in the 0014 documentation and/or other materials provided with the distribution. 0015 0016 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 0017 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 0018 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 0019 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 0020 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 0021 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 0022 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 0023 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0024 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 0025 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0026 */ 0027 0028 0029 #define DEBUG_KP_TOOL_WIDGET_BRUSH 0 0030 0031 0032 #include "widgets/toolbars/options/kpToolWidgetBrush.h" 0033 0034 #include <QPainter> 0035 0036 #include <KLocalizedString> 0037 0038 #include "kpLogCategories.h" 0039 #include "kpDefs.h" 0040 0041 //--------------------------------------------------------------------- 0042 0043 // LOREFACTOR: more OO, no arrays (use safer structs). 0044 /* sync: <brushes> */ 0045 static int BrushSizes [][3] = 0046 { 0047 {8, 4, 1/*like Pen*/}, 0048 {9, 5, 2}, 0049 {9, 5, 2}, 0050 {9, 5, 2} 0051 }; 0052 0053 #define BRUSH_SIZE_NUM_COLS (int (sizeof (::BrushSizes [0]) / sizeof (::BrushSizes [0][0]))) 0054 #define BRUSH_SIZE_NUM_ROWS (int (sizeof (::BrushSizes) / sizeof (::BrushSizes [0]))) 0055 0056 0057 //--------------------------------------------------------------------- 0058 0059 static void Draw (kpImage *destImage, const QPoint &topLeft, void *userData) 0060 { 0061 auto *pack = static_cast <kpToolWidgetBrush::DrawPackage *> (userData); 0062 0063 #if DEBUG_KP_TOOL_WIDGET_BRUSH 0064 qCDebug(kpLogWidgets) << "kptoolwidgetbrush.cpp:Draw(destImage,topLeft=" 0065 << topLeft << " pack: row=" << pack->row << " col=" << pack->col 0066 << " color=" << (int *) pack->color.toQRgb (); 0067 #endif 0068 const int size = ::BrushSizes [pack->row][pack->col]; 0069 #if DEBUG_KP_TOOL_WIDGET_BRUSH 0070 qCDebug(kpLogWidgets) << "\tsize=" << size; 0071 #endif 0072 0073 QPainter painter(destImage); 0074 0075 if ( size == 1 ) 0076 { 0077 painter.setPen(pack->color.toQColor()); 0078 painter.drawPoint(topLeft); 0079 return; 0080 } 0081 0082 // sync: <brushes> 0083 switch (pack->row/*shape*/) 0084 { 0085 case 0: 0086 { 0087 // work around ugly circle when using QPainter on QImage 0088 if ( size == 4 ) 0089 { 0090 // do not draw a pixel twice, as with an alpha color it will become darker 0091 painter.setPen(Qt::NoPen); 0092 painter.setBrush(pack->color.toQColor()); 0093 painter.drawRect(topLeft.x() + 1, topLeft.y(), 2, size); 0094 painter.setPen(pack->color.toQColor()); 0095 painter.drawLine(topLeft.x(), topLeft.y() + 1, topLeft.x(), topLeft.y() + 2); 0096 painter.drawLine(topLeft.x() + 3, topLeft.y() + 1, topLeft.x() + 3, topLeft.y() + 2); 0097 } 0098 else if ( size == 8 ) // size defined in BrushSizes above 0099 { 0100 // do not draw a pixel twice, as with an alpha color it will become darker 0101 painter.setPen(Qt::NoPen); 0102 painter.setBrush(pack->color.toQColor()); 0103 painter.drawRect(topLeft.x() + 2, topLeft.y(), 4, size); 0104 painter.drawRect(topLeft.x(), topLeft.y() + 2, 2, 4); 0105 painter.drawRect(topLeft.x() + 6, topLeft.y() + 2, 2, 4); 0106 painter.setPen(pack->color.toQColor()); 0107 painter.drawPoint(topLeft.x() + 1, topLeft.y() + 1); 0108 painter.drawPoint(topLeft.x() + 6, topLeft.y() + 1); 0109 painter.drawPoint(topLeft.x() + 1, topLeft.y() + 6); 0110 painter.drawPoint(topLeft.x() + 6, topLeft.y() + 6); 0111 } 0112 else 0113 { 0114 Q_ASSERT(!"illegal size"); 0115 } 0116 break; 0117 } 0118 0119 case 1: 0120 { 0121 // only paint filling so that a color with an alpha channel does not 0122 // create a darker border due to drawing some pixels twice with composition 0123 painter.setPen(Qt::NoPen); 0124 painter.setBrush(pack->color.toQColor()); 0125 painter.drawRect(topLeft.x(), topLeft.y(), size, size); 0126 break; 0127 } 0128 0129 case 2: 0130 { 0131 painter.setPen(pack->color.toQColor()); 0132 painter.drawLine(topLeft.x() + size - 1, topLeft.y(), 0133 topLeft.x(), topLeft.y() + size - 1); 0134 break; 0135 } 0136 0137 case 3: 0138 { 0139 painter.setPen(pack->color.toQColor()); 0140 painter.drawLine(topLeft.x(), topLeft.y(), 0141 topLeft.x() + size - 1, topLeft.y() + size - 1); 0142 break; 0143 } 0144 0145 default: 0146 Q_ASSERT (!"Unknown row"); 0147 break; 0148 } 0149 } 0150 0151 //--------------------------------------------------------------------- 0152 0153 kpToolWidgetBrush::kpToolWidgetBrush (QWidget *parent, const QString &name) 0154 : kpToolWidgetBase (parent, name) 0155 { 0156 for (int shape = 0; shape < BRUSH_SIZE_NUM_ROWS; shape++) 0157 { 0158 for (int i = 0; i < BRUSH_SIZE_NUM_COLS; i++) 0159 { 0160 const int s = ::BrushSizes [shape][i]; 0161 0162 0163 const int w = (width () - 2/*margin*/ - 2/*spacing*/) 0164 / BRUSH_SIZE_NUM_COLS; 0165 const int h = (height () - 2/*margin*/ - 3/*spacing*/) 0166 / BRUSH_SIZE_NUM_ROWS; 0167 Q_ASSERT (w >= s && h >= s); 0168 QImage previewPixmap (w, h, QImage::Format_ARGB32_Premultiplied); 0169 previewPixmap.fill(0); 0170 0171 DrawPackage pack = drawFunctionDataForRowCol (kpColor::Black, shape, i); 0172 ::Draw (&previewPixmap, 0173 QPoint ((previewPixmap.width () - s) / 2, 0174 (previewPixmap.height () - s) / 2), 0175 &pack); 0176 0177 addOption(QPixmap::fromImage(std::move(previewPixmap)), 0178 brushName(shape, i) /*tooltip*/); 0179 } 0180 0181 startNewOptionRow (); 0182 } 0183 0184 finishConstruction (0, 0); 0185 } 0186 0187 //--------------------------------------------------------------------- 0188 0189 kpToolWidgetBrush::~kpToolWidgetBrush () = default; 0190 0191 //--------------------------------------------------------------------- 0192 0193 // private 0194 QString kpToolWidgetBrush::brushName (int shape, int whichSize) const 0195 { 0196 int s = ::BrushSizes [shape][whichSize]; 0197 0198 if (s == 1) { 0199 return i18n ("1x1"); 0200 } 0201 0202 QString shapeName; 0203 0204 // sync: <brushes> 0205 switch (shape) 0206 { 0207 case 0: 0208 shapeName = i18n ("Circle"); 0209 break; 0210 case 1: 0211 shapeName = i18n ("Square"); 0212 break; 0213 case 2: 0214 // TODO: is this really the name of a shape? :) 0215 shapeName = i18n ("Slash"); 0216 break; 0217 case 3: 0218 // TODO: is this really the name of a shape? :) 0219 shapeName = i18n ("Backslash"); 0220 break; 0221 } 0222 0223 if (shapeName.isEmpty ()) { 0224 return {}; 0225 } 0226 0227 return i18n ("%1x%2 %3", s, s, shapeName); 0228 } 0229 0230 //--------------------------------------------------------------------- 0231 0232 // public 0233 int kpToolWidgetBrush::brushSize () const 0234 { 0235 return ::BrushSizes [selectedRow ()][selectedCol ()]; 0236 } 0237 0238 //--------------------------------------------------------------------- 0239 0240 // public 0241 bool kpToolWidgetBrush::brushIsDiagonalLine () const 0242 { 0243 // sync: <brushes> 0244 return (selectedRow () >= 2); 0245 } 0246 0247 //--------------------------------------------------------------------- 0248 0249 0250 // public 0251 kpTempImage::UserFunctionType kpToolWidgetBrush::drawFunction () const 0252 { 0253 return &::Draw; 0254 } 0255 0256 //--------------------------------------------------------------------- 0257 0258 0259 // public static 0260 kpToolWidgetBrush::DrawPackage kpToolWidgetBrush::drawFunctionDataForRowCol ( 0261 const kpColor &color, int row, int col) 0262 { 0263 Q_ASSERT (row >= 0 && col >= 0); 0264 0265 DrawPackage pack; 0266 0267 pack.row = row; 0268 pack.col = col; 0269 pack.color = color; 0270 0271 return pack; 0272 } 0273 0274 //--------------------------------------------------------------------- 0275 0276 // public 0277 kpToolWidgetBrush::DrawPackage kpToolWidgetBrush::drawFunctionData ( 0278 const kpColor &color) const 0279 { 0280 return drawFunctionDataForRowCol (color, selectedRow (), selectedCol ()); 0281 } 0282 0283 //--------------------------------------------------------------------- 0284 0285 // protected slot virtual [base kpToolWidgetBase] 0286 bool kpToolWidgetBrush::setSelected (int row, int col, bool saveAsDefault) 0287 { 0288 const bool ret = kpToolWidgetBase::setSelected (row, col, saveAsDefault); 0289 if (ret) { 0290 Q_EMIT brushChanged (); 0291 } 0292 return ret; 0293 } 0294 0295 //--------------------------------------------------------------------- 0296 0297 #include "moc_kpToolWidgetBrush.cpp"