File indexing completed on 2024-12-22 04:13:06

0001 /*
0002  *  SPDX-FileCopyrightText: 2021 Deif Lou <ginoba@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include <QPainterPath>
0008 
0009 #include <KoCheckerBoardPainter.h>
0010 
0011 #include "KisGradientWidgetsUtils.h"
0012 
0013 namespace KisGradientWidgetsUtils
0014 {
0015 
0016 void paintGradientBox(QPainter &painter, const KoAbstractGradientSP gradient, const QRectF &rect)
0017 {
0018     static KoCheckerBoardPainter checkerBoardPainter(4);
0019     
0020     // Background
0021     checkerBoardPainter.paint(painter, rect, rect.topLeft());
0022     // Gradient
0023     QImage image = gradient->generatePreview(rect.width(), rect.height());
0024     if (!image.isNull()) {
0025         painter.drawImage(rect.topLeft(), image);
0026     }
0027     // Border
0028     painter.setPen(QColor(0, 0, 0, 192));
0029     painter.drawRect(rect);
0030 }
0031 
0032 void paintStopHandle(QPainter &painter,
0033                      const QPointF &position,
0034                      const QSizeF &size,
0035                      bool isSelected, bool isHovered, bool hasFocus,
0036                      const QColor &highlightColor,
0037                      const StopHandleColor &color1,
0038                      const StopHandleColor &color2)
0039 {
0040     painter.save();
0041 
0042     QColor borderColor;
0043     int borderWidth;
0044     if (isSelected) {
0045         borderColor = highlightColor;
0046         borderColor.setAlpha(255);
0047         borderWidth = hasFocus ? 2 : 1;
0048     } else {
0049         if (isHovered) {
0050             borderColor = highlightColor;
0051             borderColor.setAlpha(192);
0052         } else {
0053             borderColor = QColor(0, 0, 0, 128);
0054         }
0055         borderWidth = 1;
0056     }
0057     const QPointF alignedPosition(qRound(position.x() + 0.5) - 0.5, position.y());
0058     const qreal halfWidth = size.width() * 0.5;
0059     QPainterPath path(alignedPosition);
0060     path.arcTo(
0061         alignedPosition.x() - halfWidth,
0062         alignedPosition.y() + size.height() - size.width(),
0063         size.width(),
0064         size.width(),
0065         150,
0066         240
0067     );
0068     path.closeSubpath();
0069     // paint the "drop" handle
0070     if (color1.type != None && color2.type != None && color1.color != color2.color) {
0071         painter.setClipRect(QRectF(QPointF(alignedPosition.x() - halfWidth, alignedPosition.y()), QSizeF(halfWidth, size.height())));
0072         painter.setPen(Qt::NoPen);
0073         painter.setBrush(color1.color);
0074         painter.drawPath(path);
0075         painter.setClipRect(QRectF(alignedPosition, QSizeF(halfWidth, size.height())));
0076         painter.setBrush(color2.color);
0077         painter.drawPath(path);
0078         painter.setClipping(false);
0079         painter.setPen(QPen(borderColor, borderWidth));
0080         painter.setBrush(Qt::NoBrush);
0081         painter.drawPath(path);
0082     } else {
0083         painter.setPen(QPen(borderColor, borderWidth));
0084         if (color1.type != None) {
0085             // Only color 1 was specified
0086             painter.setBrush(color1.color);
0087         } else {
0088             // Only color 2 was specified
0089             painter.setBrush(color2.color);
0090         }
0091         painter.drawPath(path);
0092     }
0093     // paint the type indicator
0094     constexpr QSizeF typeIndicatorSize(5.0, 5.0);
0095     if (color1.type == Foreground || color1.type == Background) {
0096         QPointF typeIndicatorPosition(
0097             alignedPosition.x() - halfWidth - 1.0,
0098             alignedPosition.y() + size.height() - typeIndicatorSize.height() + 1.0
0099         );
0100         if (color1.type == Foreground) {
0101             painter.setPen(QPen(Qt::white, 1));
0102             painter.setBrush(Qt::black);
0103         } else if (color1.type == Background) {
0104             painter.setPen(QPen(Qt::black, 1));
0105             painter.setBrush(Qt::white);
0106         }
0107         painter.drawEllipse(QRectF(typeIndicatorPosition, typeIndicatorSize));
0108     }
0109     if (color2.type == Foreground || color2.type == Background) {
0110         QPointF typeIndicatorPosition(
0111             alignedPosition.x() + halfWidth - typeIndicatorSize.width() + 1.0,
0112             alignedPosition.y() + size.height() - typeIndicatorSize.height() + 1.0
0113         );
0114         if (color2.type == Foreground) {
0115             painter.setPen(QPen(Qt::white, 1));
0116             painter.setBrush(Qt::black);
0117         } else if (color2.type == Background) {
0118             painter.setPen(QPen(Qt::black, 1));
0119             painter.setBrush(Qt::white);
0120         }
0121         painter.drawEllipse(QRectF(typeIndicatorPosition, typeIndicatorSize));
0122     }
0123 
0124     painter.restore();
0125 }
0126 
0127 void paintMidPointHandle(QPainter &painter,
0128                          const QPointF &position,
0129                          qreal size,
0130                          bool isSelected, bool isHovered, bool hasFocus,
0131                          const QColor &borderColor,
0132                          const QColor &fillColor,
0133                          const QColor &highlightColor)
0134 {
0135     painter.save();
0136 
0137     QColor brushColor;
0138     int penWidth;
0139     if (isSelected) {
0140         brushColor = highlightColor;
0141         penWidth = hasFocus ? 2 : 1;
0142     } else {
0143         if (isHovered) {
0144             brushColor = highlightColor;
0145             brushColor.setAlpha(192);
0146         } else {
0147             brushColor = fillColor;
0148         }
0149         penWidth = 1;
0150     }
0151     const QPointF alignedPosition(qRound(position.x() + 0.5) - 0.5, qRound(position.y() + 0.5) - 0.5);
0152     const qreal alignedSize = qRound(size);
0153     const qreal handleSizeOverTwo = alignedSize * 0.5;
0154     const QPointF points[4] =
0155         {
0156             QPointF(0.0, 0.0),
0157             QPointF(-handleSizeOverTwo, handleSizeOverTwo),
0158             QPointF(0.0, size),
0159             QPointF(handleSizeOverTwo, handleSizeOverTwo)
0160         };
0161     painter.translate(alignedPosition);
0162     painter.setPen(QPen(borderColor, penWidth));
0163     painter.setBrush(brushColor);
0164     painter.drawPolygon(points, 4);
0165 
0166     painter.restore();
0167 }
0168 
0169 
0170 KisGradientWidgetsUtils::ColorType segmentEndPointTypeToColorType(KoGradientSegmentEndpointType type)
0171 {
0172     if (type == FOREGROUND_ENDPOINT || type == FOREGROUND_TRANSPARENT_ENDPOINT) {
0173         return KisGradientWidgetsUtils::Foreground;
0174     } else if (type == BACKGROUND_ENDPOINT || type == BACKGROUND_TRANSPARENT_ENDPOINT) {
0175         return KisGradientWidgetsUtils::Background;
0176     }
0177     return KisGradientWidgetsUtils::Custom;
0178 }
0179 
0180 KoGradientSegmentEndpointType colorTypeToSegmentEndPointType(KisGradientWidgetsUtils::ColorType type, bool transparent)
0181 {
0182     if (type == Foreground) {
0183         return transparent ? FOREGROUND_TRANSPARENT_ENDPOINT : FOREGROUND_ENDPOINT;
0184     } else if (type == Background) {
0185         return transparent ? BACKGROUND_TRANSPARENT_ENDPOINT : BACKGROUND_ENDPOINT;
0186     }
0187     return COLOR_ENDPOINT;
0188 }
0189 
0190 }