File indexing completed on 2024-05-12 16:02:06
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(QWidget *parent, 0017 Dimensions dimension, 0018 const KoColorSpace *cs, 0019 int channel1, int channel2, 0020 const KoColorDisplayRendererInterface *displayRenderer, 0021 int margin) 0022 : KisVisualColorSelectorShape(parent, dimension, cs, channel1, channel2, displayRenderer), 0023 m_margin(margin) 0024 { 0025 //qDebug() << "creating KisVisualTriangleSelectorShape" << this; 0026 } 0027 0028 KisVisualTriangleSelectorShape::~KisVisualTriangleSelectorShape() 0029 { 0030 //qDebug() << "deleting KisVisualTriangleSelectorShape" << this; 0031 } 0032 0033 void KisVisualTriangleSelectorShape::setBorderWidth(int /*width*/) 0034 { 0035 // triangle doesn't have a 1-dimensional mode 0036 } 0037 0038 QRect KisVisualTriangleSelectorShape::getSpaceForSquare(QRect geom) 0039 { 0040 return geom; 0041 } 0042 0043 QRect KisVisualTriangleSelectorShape::getSpaceForCircle(QRect geom) 0044 { 0045 return geom; 0046 } 0047 0048 QRect KisVisualTriangleSelectorShape::getSpaceForTriangle(QRect geom) 0049 { 0050 return geom; 0051 } 0052 0053 QPointF KisVisualTriangleSelectorShape::convertShapeCoordinateToWidgetCoordinate(QPointF coordinate) const 0054 { 0055 // margin serves to render the cursor, and triangle is rendered 1px larger than its active area 0056 qreal offset = m_margin + 1.0; 0057 0058 qreal y = (coordinate.y() * (height() - 1 - 2 * offset)) + offset; 0059 0060 qreal triWidth = width() - 1 - 2 * offset; 0061 qreal horizontalLineLength = coordinate.y() * triWidth; 0062 qreal horizontalLineStart = offset + 0.5 * (triWidth - horizontalLineLength); 0063 0064 qreal x = coordinate.x() * horizontalLineLength + horizontalLineStart; 0065 0066 return QPointF(x, y); 0067 } 0068 0069 QPointF KisVisualTriangleSelectorShape::convertWidgetCoordinateToShapeCoordinate(QPointF coordinate) const 0070 { 0071 // margin serves to render the cursor, and triangle is rendered 1px larger than its active area 0072 qreal offset = m_margin + 1.0; 0073 0074 qreal x = 0.5; 0075 qreal y = qBound(0.0, (coordinate.y() - offset)/(height() - 1 - 2 * offset), 1.0); 0076 0077 if (y > 0) { 0078 qreal triWidth = width() - 1 - 2 * offset; 0079 qreal horizontalLineLength = y * triWidth; 0080 qreal horizontalLineStart = offset + 0.5 * (triWidth - horizontalLineLength); 0081 0082 x = qBound(0.0, (coordinate.x() - horizontalLineStart) / horizontalLineLength, 1.0); 0083 } 0084 0085 return QPointF(x, y); 0086 } 0087 0088 QRegion KisVisualTriangleSelectorShape::getMaskMap() 0089 { 0090 const int cursorWidth = qMax(2 * m_margin, 2); 0091 QPolygon maskPoly; 0092 maskPoly << QPoint(qFloor(0.5 * (width() - cursorWidth)), 0) 0093 << QPoint(qCeil(0.5 * (width() + cursorWidth)), 0) 0094 << QPoint(width(), height() - cursorWidth) 0095 << QPoint(width(), height()) 0096 << QPoint(0, height()) 0097 << QPoint(0, height() - cursorWidth); 0098 0099 return QRegion(maskPoly); 0100 } 0101 0102 QImage KisVisualTriangleSelectorShape::renderAlphaMask() const 0103 { 0104 // Hi-DPI aware rendering requires that we determine the device pixel dimension; 0105 // actual widget size in device pixels is not accessible unfortunately, it might be 1px smaller... 0106 const int deviceWidth = qCeil(width() * devicePixelRatioF()); 0107 const int deviceHeight = qCeil(height() * devicePixelRatioF()); 0108 0109 QImage alphaMask(deviceWidth, deviceHeight, QImage::Format_Alpha8); 0110 alphaMask.fill(0); 0111 alphaMask.setDevicePixelRatio(devicePixelRatioF()); 0112 QPainter painter(&alphaMask); 0113 painter.setRenderHint(QPainter::Antialiasing); 0114 painter.setBrush(Qt::white); 0115 painter.setPen(Qt::NoPen); 0116 QPointF triangle[3] = { 0117 QPointF(0.5 * width(), m_margin), 0118 QPointF(m_margin, height() - m_margin), 0119 QPointF(width() - m_margin, height() - m_margin), 0120 }; 0121 painter.drawConvexPolygon(triangle, 3); 0122 0123 return alphaMask; 0124 } 0125 0126 void KisVisualTriangleSelectorShape::drawCursor() 0127 { 0128 //qDebug() << this << "KisVisualTriangleSelectorShape::drawCursor: image needs update" << imagesNeedUpdate(); 0129 QPointF cursorPoint = convertShapeCoordinateToWidgetCoordinate(getCursorPosition()); 0130 QImage fullSelector = getImageMap(); 0131 QColor col = getColorFromConverter(getCurrentColor()); 0132 QPainter painter(&fullSelector); 0133 painter.setRenderHint(QPainter::Antialiasing); 0134 0135 QBrush fill(Qt::SolidPattern); 0136 0137 int cursorwidth = 5; 0138 0139 painter.setPen(Qt::white); 0140 fill.setColor(Qt::white); 0141 painter.setBrush(fill); 0142 painter.drawEllipse(cursorPoint, cursorwidth, cursorwidth); 0143 fill.setColor(col); 0144 painter.setPen(Qt::black); 0145 painter.setBrush(fill); 0146 painter.drawEllipse(cursorPoint, cursorwidth-1.0, cursorwidth-1.0); 0147 0148 painter.end(); 0149 setFullImage(fullSelector); 0150 }