File indexing completed on 2024-05-19 04:29:30
0001 /* 0002 * SPDX-FileCopyrightText: 2016 Wolthera van Hovell tot Westerflier <griffinvalley@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 #include "KisVisualTriangleSelectorShape.h" 0007 0008 #include <QColor> 0009 #include <QPainter> 0010 #include <QRect> 0011 #include <QtMath> 0012 0013 #include "kis_debug.h" 0014 #include "kis_global.h" 0015 0016 KisVisualTriangleSelectorShape::KisVisualTriangleSelectorShape(KisVisualColorSelector *parent, 0017 Dimensions dimension, 0018 int channel1, int channel2, 0019 int margin) 0020 : KisVisualColorSelectorShape(parent, dimension, channel1, channel2), 0021 m_margin(margin) 0022 { 0023 //qDebug() << "creating KisVisualTriangleSelectorShape" << this; 0024 } 0025 0026 KisVisualTriangleSelectorShape::~KisVisualTriangleSelectorShape() 0027 { 0028 //qDebug() << "deleting KisVisualTriangleSelectorShape" << this; 0029 } 0030 0031 void KisVisualTriangleSelectorShape::setBorderWidth(int /*width*/) 0032 { 0033 // triangle doesn't have a 1-dimensional mode 0034 } 0035 0036 QRect KisVisualTriangleSelectorShape::getSpaceForSquare(QRect geom) 0037 { 0038 return geom; 0039 } 0040 0041 QRect KisVisualTriangleSelectorShape::getSpaceForCircle(QRect geom) 0042 { 0043 return geom; 0044 } 0045 0046 QRect KisVisualTriangleSelectorShape::getSpaceForTriangle(QRect geom) 0047 { 0048 return geom; 0049 } 0050 0051 QPointF KisVisualTriangleSelectorShape::convertShapeCoordinateToWidgetCoordinate(QPointF coordinate) const 0052 { 0053 // margin serves to render the cursor, and triangle is rendered 1px larger than its active area 0054 qreal offset = m_margin + 1.0; 0055 0056 qreal y = (coordinate.y() * (height() - 1 - 2 * offset)) + offset; 0057 0058 qreal triWidth = width() - 1 - 2 * offset; 0059 qreal horizontalLineLength = coordinate.y() * triWidth; 0060 qreal horizontalLineStart = offset + 0.5 * (triWidth - horizontalLineLength); 0061 0062 qreal x = coordinate.x() * horizontalLineLength + horizontalLineStart; 0063 0064 return QPointF(x, y); 0065 } 0066 0067 QPointF KisVisualTriangleSelectorShape::convertWidgetCoordinateToShapeCoordinate(QPointF coordinate) const 0068 { 0069 // margin serves to render the cursor, and triangle is rendered 1px larger than its active area 0070 qreal offset = m_margin + 1.0; 0071 0072 qreal x = 0.5; 0073 qreal y = qBound(0.0, (coordinate.y() - offset)/(height() - 1 - 2 * offset), 1.0); 0074 0075 if (y > 0) { 0076 qreal triWidth = width() - 1 - 2 * offset; 0077 qreal horizontalLineLength = y * triWidth; 0078 qreal horizontalLineStart = offset + 0.5 * (triWidth - horizontalLineLength); 0079 0080 x = qBound(0.0, (coordinate.x() - horizontalLineStart) / horizontalLineLength, 1.0); 0081 } 0082 0083 return QPointF(x, y); 0084 } 0085 0086 QRegion KisVisualTriangleSelectorShape::getMaskMap() 0087 { 0088 const int cursorWidth = qMax(2 * m_margin, 2); 0089 QPolygon maskPoly; 0090 maskPoly << QPoint(qFloor(0.5 * (width() - cursorWidth)), 0) 0091 << QPoint(qCeil(0.5 * (width() + cursorWidth)), 0) 0092 << QPoint(width(), height() - cursorWidth) 0093 << QPoint(width(), height()) 0094 << QPoint(0, height()) 0095 << QPoint(0, height() - cursorWidth); 0096 0097 return QRegion(maskPoly); 0098 } 0099 0100 QImage KisVisualTriangleSelectorShape::renderAlphaMask() const 0101 { 0102 // Hi-DPI aware rendering requires that we determine the device pixel dimension; 0103 // actual widget size in device pixels is not accessible unfortunately, it might be 1px smaller... 0104 const int deviceWidth = qCeil(width() * devicePixelRatioF()); 0105 const int deviceHeight = qCeil(height() * devicePixelRatioF()); 0106 0107 QImage alphaMask(deviceWidth, deviceHeight, QImage::Format_Alpha8); 0108 alphaMask.fill(0); 0109 alphaMask.setDevicePixelRatio(devicePixelRatioF()); 0110 QPainter painter(&alphaMask); 0111 painter.setRenderHint(QPainter::Antialiasing); 0112 painter.setBrush(Qt::white); 0113 painter.setPen(Qt::NoPen); 0114 QPointF triangle[3] = { 0115 QPointF(0.5 * width(), m_margin), 0116 QPointF(m_margin, height() - m_margin), 0117 QPointF(width() - m_margin, height() - m_margin), 0118 }; 0119 painter.drawConvexPolygon(triangle, 3); 0120 0121 return alphaMask; 0122 } 0123 0124 void KisVisualTriangleSelectorShape::drawCursor(QPainter &painter) 0125 { 0126 //qDebug() << this << "KisVisualTriangleSelectorShape::drawCursor: image needs update" << imagesNeedUpdate(); 0127 QPointF cursorPoint = convertShapeCoordinateToWidgetCoordinate(getCursorPosition()); 0128 QColor col = getColorFromConverter(getCurrentColor()); 0129 QBrush fill(Qt::SolidPattern); 0130 0131 int cursorwidth = 5; 0132 0133 painter.setPen(Qt::white); 0134 fill.setColor(Qt::white); 0135 painter.setBrush(fill); 0136 painter.drawEllipse(cursorPoint, cursorwidth, cursorwidth); 0137 fill.setColor(col); 0138 painter.setPen(Qt::black); 0139 painter.setBrush(fill); 0140 painter.drawEllipse(cursorPoint, cursorwidth-1.0, cursorwidth-1.0); 0141 }