Krita Source Code Documentation
Loading...
Searching...
No Matches
KisPopupPalette Class Reference

#include <kis_popup_palette.h>

+ Inheritance diagram for KisPopupPalette:

Public Slots

void slotUpdateIcons ()
 

Signals

void finished () override
 
void sigChangeActivePaintop (int)
 
void sigChangefGColor (const KoColor &)
 
void sigUpdateCanvas ()
 
void sigUpdateRecentColor (int)
 
void zoomLevelChanged (int)
 
- Signals inherited from KisPopupWidgetInterface
virtual void finished ()=0
 Emitted when a popup widget believes that its job is finished.
 

Public Member Functions

void dismiss () override
 Called when you want to dismiss a popup widget.
 
void ensureWithinParent (const QPoint &globalPos, bool useUpperLeft)
 
 KisPopupPalette (KisViewManager *, KisCoordinatesConverter *, KisFavoriteResourceManager *, const KoColorDisplayRendererInterface *displayRenderer, QWidget *parent=0)
 
bool onScreen () override
 Returns whether the widget is active (on screen) or not.
 
void popup (const QPoint &position) override
 Called when and where you want a widget to popup.
 
int selectedColor () const
 
void setParent (QWidget *parent)
 
void setSelectedColor (int x)
 
QSize sizeHint () const override
 
 ~KisPopupPalette () override
 
- Public Member Functions inherited from KisPopupWidgetInterface
virtual ~KisPopupWidgetInterface ()
 

Protected Member Functions

int calculateColorIndex (QPointF position, int numColors) const
 Calculate index of recent color in array.
 
bool eventFilter (QObject *, QEvent *) override
 
int findPresetSlot (QPointF position) const
 / find the index of the brush preset slot containing @position.
 
int hoveredColor () const
 
int hoveredPreset () const
 
void mouseMoveEvent (QMouseEvent *) override
 
void mousePressEvent (QMouseEvent *) override
 
void mouseReleaseEvent (QMouseEvent *) override
 
void paintEvent (QPaintEvent *) override
 
void resizeEvent (QResizeEvent *) override
 
void setHoveredColor (int x)
 
void setHoveredPreset (int x)
 
void showEvent (QShowEvent *event) override
 
void tabletEvent (QTabletEvent *event) override
 

Properties

int hoveredColor
 
int hoveredPreset
 
int selectedColor
 

Private Slots

void showBottomBarWidget (bool visible)
 
void showHudWidget (bool visible)
 
void slotConfigurationChanged ()
 
void slotDisplayConfigurationChanged ()
 
void slotEmitColorChanged ()
 
void slotExternalFgColorChanged (const KoColor &color)
 
void slotFitToViewClicked ()
 
void slotRemoveMirrorPos ()
 
void slotSetMirrorPos ()
 
void slotSetSelectedColor (int x)
 
void slotShowTagsPopup ()
 
void slotUpdate ()
 
void slotZoomSliderChanged (int zoom)
 
void slotZoomSliderPressed ()
 
void slotZoomSliderReleased ()
 
void slotZoomToOneHundredPercentClicked ()
 

Private Member Functions

void calculatePresetLayout ()
 Determine the number of rings to distribute the presets and calculate the radius of the brush preset slots and saves the "layout" to m_cachedPresetLayout.
 
void calculateRotationSnapAreas ()
 
QPainterPath createPathFromPresetIndex (int index) const
 
QPainterPath drawDonutPathAngle (int, int, int)
 
QPainterPath drawDonutPathFull (int, int, int, int)
 
QPainterPath drawFgBgColorIndicator (int type) const
 
QPointF drawPointOnAngle (qreal angle, qreal radius) const
 
bool isPointInPixmap (QPointF &, int pos)
 
void reconfigure ()
 
QRectF rotationIndicatorRect (qreal rotationAngle) const
 

Private Attributes

KisHighlightedToolButtoncanvasOnlyButton {0}
 
QPushButton * fitToViewButton {0}
 
KisKActionCollectionm_actionCollection
 
KisActionManagerm_actionManager
 
KisAcyclicSignalConnectorm_acyclicConnector = 0
 
KisRoundHudButtonm_bottomBarButton {0}
 
QWidget * m_bottomBarWidget {0}
 
CachedPresetLayout m_cachedPresetLayout
 
QRectF m_canvasRotationIndicatorRect
 
KisRoundHudButtonm_clearColorHistoryButton {0}
 
KisMouseClickEaterm_clicksEater
 
QScopedPointer< KisSignalCompressorm_colorChangeCompressor
 
qreal m_colorHistoryInnerRadius {72.0}
 
qreal m_colorHistoryOuterRadius {92.0}
 
KisColorSelectorInterfacem_colorSelector {0}
 
KisCoordinatesConverterm_coordinatesConverter
 
const KoColorDisplayRendererInterfacem_displayRenderer
 
KisDockerHudm_dockerHud {0}
 
KisRoundHudButtonm_dockerHudButton {0}
 
int m_hoveredColor {0}
 
int m_hoveredPreset {0}
 
bool m_isOverCanvasRotationIndicator {false}
 
bool m_isOverFgBgColors {false}
 
bool m_isOverResetCanvasRotationIndicator {false}
 
bool m_isRotatingCanvasIndicator {false}
 
bool m_isZoomingCanvas {false}
 
QSpacerItem * m_mainArea {0}
 
int m_maxPresetSlotCount {10}
 
QPoint m_mirrorPos {}
 
qreal m_popupPaletteSize {385.0}
 
qreal m_presetRingMargin {3.0}
 
int m_presetSlotCount {10}
 
QRectF m_resetCanvasRotationIndicatorRect
 
KisFavoriteResourceManagerm_resourceManager
 
qreal m_rotationSnapAngle {0}
 
qreal m_rotationTrackSize {18.0}
 
int m_selectedColor {0}
 
bool m_showColorHistory {true}
 
bool m_showRotationTrack {true}
 
std::array< QLineF, 24 > m_snapLines {}
 
qreal m_snapRadius {15}
 
std::array< QRect, 24 > m_snapRects {}
 
bool m_snapRotation {false}
 
KisRoundHudButtonm_tagsButton {0}
 
bool m_touchBeginReceived {false}
 
bool m_useDynamicSlotCount {true}
 
KisViewManagerm_viewManager
 
KisHighlightedToolButtonmirrorMode {0}
 
QGraphicsOpacityEffect * opacityChange {0}
 
QSlider * zoomCanvasSlider {0}
 
int zoomSliderMaxValue {200}
 
int zoomSliderMinValue {10}
 
QPushButton * zoomToOneHundredPercentButton {0}
 

Detailed Description

Definition at line 45 of file kis_popup_palette.h.

Constructor & Destructor Documentation

◆ KisPopupPalette()

KisPopupPalette::KisPopupPalette ( KisViewManager * viewManager,
KisCoordinatesConverter * coordinatesConverter,
KisFavoriteResourceManager * manager,
const KoColorDisplayRendererInterface * displayRenderer,
QWidget * parent = 0 )

Tablet support code generates a spurious right-click right after opening the window, so we should ignore it. Next right-click will be used for closing the popup palette

Definition at line 92 of file kis_popup_palette.cpp.

94 : QWidget(parent,
95
111 KisPlatformPluginInterfaceFactory::instance()->surfaceColorManagedByOS() ?
112 Qt::Popup :
113 Qt::FramelessWindowHint)
114 , m_coordinatesConverter(coordinatesConverter)
115 , m_viewManager(viewManager)
116 , m_actionManager(viewManager->actionManager())
117 , m_resourceManager(manager)
118 , m_displayRenderer(displayRenderer)
120 , m_actionCollection(viewManager->actionCollection())
122 , m_clicksEater(new KisMouseClickEater(Qt::RightButton, 1, this))
123{
124 setAttribute(Qt::WA_TranslucentBackground);
125
126 connect(m_colorChangeCompressor.data(), SIGNAL(timeout()),
127 SLOT(slotEmitColorChanged()));
128
129 connect(KisConfigNotifier::instance(), SIGNAL(configChanged()), this, SLOT(slotConfigurationChanged()));
130 connect(m_displayRenderer, SIGNAL(displayConfigurationChanged()), this, SLOT(slotDisplayConfigurationChanged()));
131
132 m_acyclicConnector->connectForwardKoColor(m_resourceManager, SIGNAL(sigChangeFGColorSelector(KoColor)),
134
136 m_resourceManager, SIGNAL(sigSetFGColor(KoColor)));
137 // just update() to repaint color labels on external background color change
138 connect(viewManager->canvasResourceProvider(), SIGNAL(sigBGColorChanged(KoColor)), SLOT(update()));
139
140 connect(this, SIGNAL(sigChangeActivePaintop(int)), m_resourceManager, SLOT(slotChangeActivePaintop(int)));
141 connect(this, SIGNAL(sigUpdateRecentColor(int)), m_resourceManager, SLOT(slotUpdateRecentColor(int)));
142
143 connect(m_resourceManager, SIGNAL(setSelectedColor(int)), this, SLOT(slotSetSelectedColor(int)));
144 connect(m_resourceManager, SIGNAL(updatePalettes()), this, SLOT(slotUpdate()));
145 connect(m_resourceManager, SIGNAL(hidePalettes()), this, SIGNAL(finished()));
146
147 // Instances of `this` rely on finished() to be detached and its lifetime is associated with `parent`
148 connect(parent, SIGNAL(destroyed(QObject *)), this, SIGNAL(finished()), Qt::DirectConnection);
149
150 setCursor(Qt::ArrowCursor);
151 setMouseTracking(true);
153 setHoveredColor(-1);
155
156 m_dockerHud = new KisDockerHud(i18n("Popup Palette"), "popuppalette");
157
159
160 connect(m_tagsButton, SIGNAL(clicked()), SLOT(slotShowTagsPopup()));
161
163 m_dockerHudButton->setCheckable(true);
164
165 connect(m_dockerHudButton, SIGNAL(toggled(bool)), SLOT(showHudWidget(bool)));
166
167 m_bottomBarWidget = new QWidget(this);
168
170 m_bottomBarButton->setCheckable(true);
171
172 connect( m_bottomBarButton, SIGNAL(toggled(bool)), SLOT(showBottomBarWidget(bool)));
173
175 m_clearColorHistoryButton->setToolTip(i18n("Clear color history"));
176
177 connect(m_clearColorHistoryButton, SIGNAL(clicked(bool)), m_resourceManager, SLOT(slotClearHistory()));
178 //Otherwise the colors won't disappear until the cursor moves away from the button:
179 connect(m_clearColorHistoryButton, SIGNAL(released()), this, SLOT(slotUpdate()));
180
181 // add some stuff below the pop-up palette that will make it easier to use for tablet people
182 QGridLayout* gLayout = new QGridLayout(this);
183 gLayout->setSizeConstraint(QLayout::SetFixedSize);
184 gLayout->setSpacing(0);
185 gLayout->setContentsMargins(QMargins());
187 gLayout->addItem(m_mainArea, 0, 0); // this should push the box to the bottom
188 gLayout->setColumnMinimumWidth(1, WIDGET_MARGIN);
189 gLayout->addWidget(m_dockerHud, 0, 2);
190 gLayout->setRowMinimumHeight(1, WIDGET_MARGIN);
191 gLayout->addWidget(m_bottomBarWidget, 2, 0);
192
193 QHBoxLayout* hLayout = new QHBoxLayout(m_bottomBarWidget);
194
196 mirrorMode->setFixedSize(35, 35);
197
198 mirrorMode->setToolTip(i18n("Mirror Canvas"));
199 mirrorMode->setDefaultAction(m_actionCollection->action("mirror_canvas_around_cursor"));
200 connect(mirrorMode, SIGNAL(clicked(bool)), this, SLOT(slotUpdate()));
201 connect(mirrorMode, SIGNAL(pressed()), this, SLOT(slotSetMirrorPos()));
202 connect(mirrorMode, SIGNAL(clicked()), this, SLOT(slotRemoveMirrorPos()));
203
205 canvasOnlyButton->setFixedSize(35, 35);
206
207 canvasOnlyButton->setToolTip(i18n("Canvas Only"));
208 canvasOnlyButton->setDefaultAction(m_actionCollection->action("view_show_canvas_only"));
209
210 zoomToOneHundredPercentButton = new QPushButton(this);
211 zoomToOneHundredPercentButton->setText(i18n("100%"));
212 zoomToOneHundredPercentButton->setFixedHeight(35);
213
214 zoomToOneHundredPercentButton->setToolTip(i18n("Zoom to 100%"));
215 connect(zoomToOneHundredPercentButton, SIGNAL(clicked(bool)), this, SLOT(slotZoomToOneHundredPercentClicked()));
216
217 fitToViewButton = new QPushButton(this);
218 fitToViewButton->setFixedHeight(35);
219
220 fitToViewButton->setToolTip(i18n("Fit Canvas to View"));
221 connect(fitToViewButton, SIGNAL(clicked(bool)), this, SLOT(slotFitToViewClicked()));
222
223 zoomCanvasSlider = new QSlider(Qt::Horizontal, this);
224 zoomSliderMinValue = 10; // set in %
225 zoomSliderMaxValue = 200; // set in %
226
228 zoomCanvasSlider->setFixedHeight(35);
230
231 zoomCanvasSlider->setSingleStep(1);
232 zoomCanvasSlider->setPageStep(1);
233
234 connect(zoomCanvasSlider, SIGNAL(valueChanged(int)), this, SLOT(slotZoomSliderChanged(int)));
235 connect(zoomCanvasSlider, SIGNAL(sliderPressed()), this, SLOT(slotZoomSliderPressed()));
236 connect(zoomCanvasSlider, SIGNAL(sliderReleased()), this, SLOT(slotZoomSliderReleased()));
237
239
240 hLayout->setSpacing(2);
241 hLayout->setContentsMargins(0, 6, 0, 0);
242 hLayout->addWidget(mirrorMode);
243 hLayout->addWidget(canvasOnlyButton);
244 hLayout->addWidget(zoomCanvasSlider);
246 hLayout->addWidget(fitToViewButton);
247
248 setVisible(false);
249 reconfigure();
250
251 opacityChange = new QGraphicsOpacityEffect(this);
252 opacityChange->setOpacity(1);
253 setGraphicsEffect(opacityChange);
254
260 installEventFilter(m_clicksEater);
261
262 // Prevent tablet events from being captured by the canvas
263 setAttribute(Qt::WA_NoMousePropagation, true);
264
265 // Because we can create a popup in canvas widget, synthetic events sometimes arrive here (see mousePressEvent()).
266 setAttribute(Qt::WA_AcceptTouchEvents, true);
267 installEventFilter(this);
268 const QList<QWidget *> childrenWidgets = findChildren<QWidget *>();
269 for (const auto &child: childrenWidgets) {
270 child->setAttribute(Qt::WA_AcceptTouchEvents, true);
271 child->installEventFilter(this);
272 }
273
274 // No context menu here. Setting this avoids long-presses from delaying
275 // inputs or dismissing the palette, see KisLongPressEventFilter.cpp.
276 setContextMenuPolicy(Qt::PreventContextMenu);
277
278 // Load configuration..
279 KisConfig cfg(true);
280 m_dockerHudButton->setChecked(cfg.showBrushHud());
281 m_bottomBarButton->setChecked(cfg.showPaletteBottomBar());
282
283 m_dockerHud->setVisible(m_dockerHudButton->isChecked());
284 m_bottomBarWidget->setVisible(m_bottomBarButton->isChecked());
285}
void connectBackwardKoColor(QObject *sender, const char *signal, QObject *receiver, const char *method)
void connectForwardKoColor(QObject *sender, const char *signal, QObject *receiver, const char *method)
static KisConfigNotifier * instance()
QAction * action(int index) const
static KisPlatformPluginInterfaceFactory * instance()
KisHighlightedToolButton * canvasOnlyButton
KisActionManager * m_actionManager
KisRoundHudButton * m_dockerHudButton
KisViewManager * m_viewManager
void finished() override
KisKActionCollection * m_actionCollection
KisRoundHudButton * m_tagsButton
QPushButton * zoomToOneHundredPercentButton
void slotExternalFgColorChanged(const KoColor &color)
void slotSetSelectedColor(int x)
KisRoundHudButton * m_bottomBarButton
void slotZoomSliderChanged(int zoom)
void sigChangefGColor(const KoColor &)
KisHighlightedToolButton * mirrorMode
KisCoordinatesConverter * m_coordinatesConverter
void slotDisplayConfigurationChanged()
void sigChangeActivePaintop(int)
void showBottomBarWidget(bool visible)
QSpacerItem * m_mainArea
KisMouseClickEater * m_clicksEater
void showHudWidget(bool visible)
QWidget * m_bottomBarWidget
QScopedPointer< KisSignalCompressor > m_colorChangeCompressor
KisFavoriteResourceManager * m_resourceManager
KisRoundHudButton * m_clearColorHistoryButton
KisDockerHud * m_dockerHud
void setHoveredPreset(int x)
KisAcyclicSignalConnector * m_acyclicConnector
QGraphicsOpacityEffect * opacityChange
void setSelectedColor(int x)
void slotZoomToOneHundredPercentClicked()
const KoColorDisplayRendererInterface * m_displayRenderer
void setHoveredColor(int x)
void sigUpdateRecentColor(int)
QPushButton * fitToViewButton
KisCanvasResourceProvider * canvasResourceProvider()
int zoomInPercent() const
static const int WIDGET_MARGIN
bool update(QSpinBox *spinBox)

References KisKActionCollection::action(), canvasOnlyButton, KisViewManager::canvasResourceProvider(), KisAcyclicSignalConnector::connectBackwardKoColor(), KisAcyclicSignalConnector::connectForwardKoColor(), finished(), fitToViewButton, KisConfigNotifier::instance(), m_actionCollection, m_acyclicConnector, m_bottomBarButton, m_bottomBarWidget, m_clearColorHistoryButton, m_clicksEater, m_colorChangeCompressor, m_coordinatesConverter, m_displayRenderer, m_dockerHud, m_dockerHudButton, m_mainArea, m_popupPaletteSize, m_resourceManager, m_tagsButton, mirrorMode, opacityChange, reconfigure(), setHoveredColor(), setHoveredPreset(), setSelectedColor(), showBottomBarWidget(), KisConfig::showBrushHud(), showHudWidget(), KisConfig::showPaletteBottomBar(), sigChangeActivePaintop(), sigChangefGColor(), sigUpdateRecentColor(), slotConfigurationChanged(), slotDisplayConfigurationChanged(), slotEmitColorChanged(), slotExternalFgColorChanged(), slotFitToViewClicked(), slotRemoveMirrorPos(), slotSetMirrorPos(), slotSetSelectedColor(), slotShowTagsPopup(), slotUpdate(), slotUpdateIcons(), slotZoomSliderChanged(), slotZoomSliderPressed(), slotZoomSliderReleased(), slotZoomToOneHundredPercentClicked(), WIDGET_MARGIN, zoomCanvasSlider, KoZoomHandler::zoomInPercent(), zoomSliderMaxValue, zoomSliderMinValue, and zoomToOneHundredPercentButton.

◆ ~KisPopupPalette()

KisPopupPalette::~KisPopupPalette ( )
override

Definition at line 287 of file kis_popup_palette.cpp.

288{
289}

Member Function Documentation

◆ calculateColorIndex()

int KisPopupPalette::calculateColorIndex ( QPointF position,
int numColors ) const
protected

Calculate index of recent color in array.

Parameters
numColorsthe total number of recent colors
Returns
-1 if numColors < 1

Definition at line 1220 of file kis_popup_palette.cpp.

1221{
1222 if (numColors < 1) {
1223 return -1;
1224 }
1225 // relative to palette center
1226 QPointF relPosition = position - QPointF(0.5 * m_popupPaletteSize, 0.5 * m_popupPaletteSize);
1227
1228 qreal angle = M_PI - qAtan2(relPosition.x(), relPosition.y()) + M_PI / numColors;
1229 angle = normalizeAngle(angle);
1230
1231 int index = floor(angle * numColors / (2 * M_PI));
1232 return qBound(0, index, numColors - 1);
1233}
std::enable_if< std::is_floating_point< T >::value, T >::type normalizeAngle(T a)
Definition kis_global.h:121
#define M_PI
Definition kis_global.h:111

References M_PI, m_popupPaletteSize, and normalizeAngle().

◆ calculatePresetLayout()

void KisPopupPalette::calculatePresetLayout ( )
private

Determine the number of rings to distribute the presets and calculate the radius of the brush preset slots and saves the "layout" to m_cachedPresetLayout.

Definition at line 1253 of file kis_popup_palette.cpp.

1254{
1255 if (m_presetSlotCount == 0) {
1257 return;
1258 }
1259 // how many degrees each slice will get
1260 // if the slot count is 1, we must divide by 2 to get 180 for the algorithm to work
1261 qreal angleSlice = 360.0 / qMax(m_presetSlotCount, 2);
1262 qreal outerRadius = m_popupPaletteSize/2 - m_presetRingMargin - (m_showRotationTrack ? m_rotationTrackSize + 1 /* half of stroke */ : BORDER_WIDTH);
1263 qreal innerRadius = m_colorHistoryOuterRadius +
1265 ? 1 /* half of stroke */ + m_presetRingMargin
1266 : 0 /* preset margin is already included in either color history radius when it's not showing */
1267 );
1268
1269 qreal ringWidth = outerRadius - innerRadius;
1270 qreal halfRingWidth = 0.5 * ringWidth;
1271 qreal ringMidRadius = innerRadius + halfRingWidth;
1272
1273 // reset the cached layout
1276
1277 // note: adding the margin the way it's done
1278 // (calculating the radiuses without taking it into account then subtracting it after)
1279 // is not particularly accurate, but it looks fine since it's so small
1280 int margin = 2;
1281
1282 // assume one row and get the max radius until the circles would touch
1283 qreal oneRowAngleSlice = angleSlice / 2;
1284 qreal oneRowMaxRadius = ringMidRadius * qSin(qDegreesToRadians(oneRowAngleSlice));
1285
1286 // if the circles are bigger than the ring we're limited by the
1287 // ring's width instead and only one row would fit
1288
1289 // oneRowMaxRadius * 0.2 is to make sure that we still do one row if
1290 // there isn't that much of a difference and two would just look weirder
1291 if (oneRowMaxRadius - margin > halfRingWidth - oneRowMaxRadius * 0.2) {
1292 c.ringCount = 1;
1293 c.firstRowRadius = qMin(halfRingWidth, oneRowMaxRadius - margin);
1294 c.firstRowPos = ringMidRadius;
1295 return;
1296 }
1297
1298 // otherwise 2 or 3 rows always fit
1299 qreal tempRadius = halfRingWidth;
1300 {
1301 // for two rows, the first row is tangent to the inner radius
1302 // and the second row to the outer one
1303 qreal twoRowInnerCount = ceil(qMax(m_presetSlotCount, 2) / 2.0);
1304 qreal twoRowAngleSlice = 360.0 / twoRowInnerCount;
1305
1306 // we can start at half the ring width and shrink the radius until nothing is overlapping
1307 while (tempRadius >= 0) {
1308 tempRadius -= 0.2;
1309 QPointF r1p1(drawPointOnAngle(twoRowAngleSlice / 2, innerRadius + tempRadius));
1310 QPointF r1p2(drawPointOnAngle(twoRowAngleSlice / 2 * 3, innerRadius + tempRadius));
1311 QPointF r2p(drawPointOnAngle(twoRowAngleSlice, outerRadius - tempRadius));
1312 qreal row1SiblingDistance = kisDistance(r1p1, r1p2);
1313 qreal row1To2Distance = kisDistance(r1p1, r2p);
1314 if (row1To2Distance >= (tempRadius + margin) * 2) {
1315 // the previous radius is the one that's guaranteed not to be overlapping
1316 if (row1SiblingDistance < (tempRadius + margin) * 2) {
1317 // the inner row still overlaps, attempt 3 rows instead
1318 break;
1319 }
1320 c.ringCount = 2;
1321 c.secondRowRadius = tempRadius;
1322 c.secondRowPos = outerRadius - tempRadius;
1323 c.firstRowRadius = tempRadius;
1324 c.firstRowPos = innerRadius + tempRadius;
1325 return;
1326 }
1327 }
1328 }
1329
1330 // for three rows, we initially arrange them like so:
1331 // the first row tangent to the inner radius
1332 // the second row in the middle
1333 // the third row tangent to the outer radius
1334
1335 qreal threeRowInnerCount = ceil(qMax(m_presetSlotCount, 2) / 3.0);
1336 qreal threeRowAngleSlice = 360.0 / threeRowInnerCount;
1337
1338 // then we decrease the radius until no row is overlapping each other or itself
1339 while (tempRadius >= 0) {
1340 QPointF r1p1(drawPointOnAngle(threeRowAngleSlice / 2, innerRadius + tempRadius));
1341 QPointF r1p2(drawPointOnAngle(threeRowAngleSlice / 2 * 3, innerRadius + tempRadius));
1342 QPointF r2p1(drawPointOnAngle(threeRowAngleSlice, ringMidRadius));
1343 QPointF r2p2(drawPointOnAngle(threeRowAngleSlice * 2, ringMidRadius));
1344 QPointF r3p(drawPointOnAngle(threeRowAngleSlice / 2, outerRadius - tempRadius));
1345
1346 qreal row1SiblingDistance = kisDistance(r1p1, r1p2);
1347 qreal row1to2Distance = kisDistance(r1p1, r2p1);
1348 qreal row2to3Distance = kisDistance(r2p1, r3p);
1349 qreal row1to3Distance = kisDistance(r1p1, r3p);
1350
1351 if (
1352 row1to2Distance >= tempRadius * 2 &&
1353 row2to3Distance >= tempRadius * 2 &&
1354 row1to3Distance >= tempRadius * 2 &&
1355 row1SiblingDistance >= tempRadius * 2
1356 ) {
1357
1358 qreal row2SiblingDistance = kisDistance(r2p1, r2p2);
1359
1360 qreal firstRowRadius = tempRadius;
1361 qreal thirdRowRadius = tempRadius;
1362 qreal secondRowRadius = tempRadius;
1363
1364 bool firstRowTouching = row1SiblingDistance - firstRowRadius * 2 < 1;
1365 if (firstRowTouching) {
1366 // attempt to expand the second row
1367 // and expand + move the third row inwards
1368 QPointF tempR3p = r3p;
1369 qreal tempSecondThirdRowRadius = secondRowRadius;
1370 qreal tempRow2to3Distance = row2to3Distance;
1371 qreal tempRow1to3Distance = row1to3Distance;
1372 while (
1373 tempSecondThirdRowRadius * 2 < tempRow2to3Distance &&
1374 tempSecondThirdRowRadius * 2 < row2SiblingDistance &&
1375 tempSecondThirdRowRadius * 2 < tempRow1to3Distance &&
1376 tempSecondThirdRowRadius + firstRowRadius < row1to2Distance
1377 ) {
1378 // the previous temp variables are within limits
1379 r3p = tempR3p;
1380 row2to3Distance = tempRow2to3Distance;
1381 row1to3Distance = tempRow1to3Distance;
1382 secondRowRadius = tempSecondThirdRowRadius;
1383
1384 tempSecondThirdRowRadius += 1;
1385
1386 tempR3p = drawPointOnAngle(threeRowAngleSlice / 2, outerRadius - tempSecondThirdRowRadius);
1387
1388 tempRow2to3Distance = kisDistance(r2p1, tempR3p);
1389 tempRow1to3Distance = kisDistance(r1p1, tempR3p);
1390 }
1391 thirdRowRadius = secondRowRadius;
1392 }
1393
1394 {
1395 // the third row can sometimes be expanded + moved a bit more
1396 qreal tempThirdRowRadius = thirdRowRadius;
1397 QPointF tempR3p = r3p;
1398 qreal tempRow2to3Distance = row2to3Distance;
1399 qreal tempRow1to3Distance = row1to3Distance;
1400 while (
1401 tempThirdRowRadius < halfRingWidth &&
1402 secondRowRadius + tempThirdRowRadius < tempRow2to3Distance &&
1403 firstRowRadius + tempThirdRowRadius < tempRow1to3Distance
1404 ) {
1405 r3p = tempR3p;
1406 row2to3Distance = tempRow2to3Distance;
1407 row1to3Distance = tempRow1to3Distance;
1408 thirdRowRadius = tempThirdRowRadius;
1409
1410 tempThirdRowRadius += 1;
1411
1412 tempR3p = drawPointOnAngle(threeRowAngleSlice / 2, outerRadius - tempThirdRowRadius);
1413 tempRow2to3Distance = kisDistance(r2p1, tempR3p);
1414 tempRow1to3Distance = kisDistance(r1p1, tempR3p);
1415 }
1416 }
1417 // the third row is no longer moved
1418 qreal thirdRowPos = outerRadius - thirdRowRadius;
1419
1420 // many times, e.g. when the second row is touching
1421 // the first row can be moved outwards and expanded
1422 // sometimes it will even detach from the inner radius if the ringwidth is large enough
1423 // and there's a lot of presets
1424 qreal firstRowPos = innerRadius + tempRadius;
1425 {
1426 qreal tempFirstRowPos = firstRowPos;
1427 qreal tempFirstRowRadius = firstRowRadius;
1428 qreal tempRow1SiblingDistance = row1SiblingDistance;
1429 qreal tempRow1to3Distance = row1to3Distance;
1430 qreal tempRow1to2Distance = row1to2Distance;
1431 QPointF tempR1p1 = r1p1;
1432 QPointF tempR1p2 = r1p2;
1433
1434 while (
1435 tempFirstRowPos < ringMidRadius &&
1436 tempFirstRowRadius + secondRowRadius < tempRow1to2Distance &&
1437 tempFirstRowRadius + thirdRowRadius < tempRow1to3Distance
1438 ) {
1439 firstRowPos = tempFirstRowPos;
1440 firstRowRadius = tempFirstRowRadius;
1441 row1to2Distance = tempRow1to2Distance;
1442 r1p1 = tempR1p1;
1443 // these are unused after so it's not necessary to update them
1444 // row1to3Distance = tempRow1to3Distance;
1445 // row1SiblingDistance = tempRow1SiblingDistance;
1446 // r1p2 = tempR1p2;
1447
1448 tempFirstRowPos += 1;
1449
1450 tempR1p1 = drawPointOnAngle(threeRowAngleSlice / 2, tempFirstRowPos);
1451 tempR1p2 = drawPointOnAngle(threeRowAngleSlice / 2 * 3, tempFirstRowPos);
1452 tempRow1SiblingDistance = kisDistance(tempR1p1, tempR1p2);
1453 // expand it to the max size
1454 tempFirstRowRadius = tempRow1SiblingDistance / 2;
1455 tempRow1to2Distance = kisDistance(tempR1p2, r2p1);
1456 tempRow1to3Distance = kisDistance(tempR1p1, r3p);
1457 }
1458 }
1459
1460 // finally it's rare, but sometimes possible to also move + expand the second row
1461 qreal secondRowPos = ringMidRadius;
1462 bool row2touching1 = row1to2Distance - (firstRowRadius + secondRowRadius) < 1;
1463 bool row2touching3 = row2to3Distance - (thirdRowRadius + secondRowRadius) < 1;
1464 if (!row2touching1 && !row2touching3) {
1465 // move the second row in until it's touching the first row
1466 qreal knownAngleRatio = qSin(qDegreesToRadians(threeRowAngleSlice / 2)) /
1467 (firstRowRadius + secondRowRadius);
1468 qreal angleRow1Row2Center = qAsin(knownAngleRatio * firstRowPos);
1469 qreal angleCenterRow2Row1 = 180 - threeRowAngleSlice / 2 - qRadiansToDegrees(angleRow1Row2Center);
1470 secondRowPos = qSin(qDegreesToRadians(angleCenterRow2Row1)) / knownAngleRatio;
1471 }
1472 if (!row2touching3) {
1473 QPointF tempR2p1 = r2p1;
1474 qreal tempRadius = secondRowRadius;
1475 qreal tempRow1to2Distance = row1to2Distance;
1476 qreal tempRow2to3Distance = row2to3Distance;
1477 qreal tempSecondRowPos = secondRowPos;
1478 while (
1479 tempSecondRowPos < thirdRowPos &&
1480 tempRadius + thirdRowRadius < tempRow2to3Distance &&
1481 // this is an artificial limit, it could get bigger but looks weird
1482 tempRadius < thirdRowRadius
1483 ) {
1484 secondRowRadius = tempRadius;
1485 secondRowPos = tempSecondRowPos;
1486 // these are unused after so it's not necessary to update them
1487 // r2p1 = tempR2p1;
1488 // row1to2Distance = tempRow1to2Distance;
1489 // row2to3Distance = tempRow2to3Distance;
1490
1491 tempSecondRowPos += 1;
1492
1493 tempR2p1 = drawPointOnAngle(threeRowAngleSlice, secondRowPos + 1);
1494 tempRow1to2Distance = kisDistance(tempR2p1, r1p1);
1495 tempRow2to3Distance = kisDistance(tempR2p1, r3p);
1496 tempRadius = tempRow1to2Distance - firstRowRadius;
1497 }
1498 }
1499 c = {
1500 3, //ringCount
1501 firstRowRadius - margin,
1502 secondRowRadius - margin,
1503 thirdRowRadius - margin,
1504 firstRowPos,
1505 secondRowPos,
1506 thirdRowPos
1507 };
1508 return;
1509 }
1510 tempRadius -= 0.2;
1511 }
1512}
QPointF drawPointOnAngle(qreal angle, qreal radius) const
CachedPresetLayout m_cachedPresetLayout
qreal kisDistance(const QPointF &pt1, const QPointF &pt2)
Definition kis_global.h:190
static const qreal BORDER_WIDTH

References BORDER_WIDTH, drawPointOnAngle(), CachedPresetLayout::firstRowPos, CachedPresetLayout::firstRowRadius, kisDistance(), m_cachedPresetLayout, m_colorHistoryOuterRadius, m_popupPaletteSize, m_presetRingMargin, m_presetSlotCount, m_rotationTrackSize, m_showColorHistory, m_showRotationTrack, CachedPresetLayout::ringCount, CachedPresetLayout::secondRowPos, and CachedPresetLayout::secondRowRadius.

◆ calculateRotationSnapAreas()

void KisPopupPalette::calculateRotationSnapAreas ( )
private

Definition at line 1571 of file kis_popup_palette.cpp.

1571 {
1572 int i = 0;
1573 for (QRect &rect: m_snapRects) {
1574 QPointF point(drawPointOnAngle(i * 15, m_popupPaletteSize / 2 - BORDER_WIDTH - m_snapRadius/2));
1575 point += QPointF(m_popupPaletteSize / 2 - m_snapRadius, m_popupPaletteSize / 2 - m_snapRadius);
1576 rect = QRect(point.x(), point.y(), m_snapRadius*2, m_snapRadius*2);
1577 i++;
1578 }
1579 i = 0;
1580 for (QLineF &line: m_snapLines) {
1581 qreal penWidth = BORDER_WIDTH / 2;
1582 QPointF point1 = drawPointOnAngle(i * 15, m_popupPaletteSize / 2 - m_rotationTrackSize + penWidth);
1583 point1 += QPointF(m_popupPaletteSize / 2, m_popupPaletteSize / 2);
1584 QPointF point2 = drawPointOnAngle(i * 15, m_popupPaletteSize / 2 - BORDER_WIDTH - penWidth);
1585 point2 += QPointF(m_popupPaletteSize / 2, m_popupPaletteSize / 2);
1586 line = QLineF(point1, point2);
1587 i++;
1588 }
1589}
std::array< QRect, 24 > m_snapRects
std::array< QLineF, 24 > m_snapLines

References BORDER_WIDTH, drawPointOnAngle(), m_popupPaletteSize, m_rotationTrackSize, m_snapLines, m_snapRadius, and m_snapRects.

◆ createPathFromPresetIndex()

QPainterPath KisPopupPalette::createPathFromPresetIndex ( int index) const
private

Definition at line 1514 of file kis_popup_palette.cpp.

1515{
1516 // how many degrees each slice will get
1517 // if the slot count is 1, we must divide by 2 to get 180 for the algorithm to work
1518 qreal angleSlice = 360.0 / qMax(m_presetSlotCount, 2);
1519 // the starting angle of the slice we need to draw. the negative sign makes us go clockwise.
1520 // adding 90 degrees makes us start at the top. otherwise we would start at the right
1521 qreal startingAngle = -(index * angleSlice) + 90;
1523 qreal radius = m_cachedPresetLayout.firstRowRadius;
1525 case 1: break;
1526 case 2: {
1527 angleSlice = 180.0/((m_presetSlotCount+1) / 2);
1528 startingAngle = -(index * angleSlice) + 90;
1529
1530 if (index % 2) {
1533 }
1534 break;
1535 }
1536 case 3: {
1537 int triplet = index / 3;
1538 angleSlice = 180.0 / ((m_presetSlotCount + 2) / 3);
1539 switch (index % 3) {
1540 case 0:
1541 startingAngle = -(triplet * 2 * angleSlice) + 90;
1544 break;
1545 case 1:
1546 startingAngle = -(triplet * 2 * angleSlice) + 90;
1549 break;
1550 case 2:
1551 startingAngle = -((triplet * 2 + 1) * angleSlice) + 90;
1554 break;
1555 default:
1556 KIS_ASSERT(false);
1557 }
1558 break;
1559 }
1560 default:
1562 }
1563 QPainterPath path;
1564 qreal pathX = length * qCos(qDegreesToRadians(startingAngle)) - radius;
1565 qreal pathY = -(length) * qSin(qDegreesToRadians(startingAngle)) - radius;
1566 qreal pathDiameter = 2 * radius; // distance is used to calculate the X/Y in addition to the preset circle size
1567 path.addEllipse(pathX, pathY, pathDiameter, pathDiameter);
1568 return path;
1569}
qreal length(const QPointF &vec)
Definition Ellipse.cc:82
#define KIS_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:97
#define KIS_ASSERT(cond)
Definition kis_assert.h:33

References CachedPresetLayout::firstRowPos, CachedPresetLayout::firstRowRadius, KIS_ASSERT, KIS_ASSERT_RECOVER_NOOP, length(), m_cachedPresetLayout, m_presetSlotCount, CachedPresetLayout::ringCount, CachedPresetLayout::secondRowPos, CachedPresetLayout::secondRowRadius, CachedPresetLayout::thirdRowPos, and CachedPresetLayout::thirdRowRadius.

◆ dismiss()

void KisPopupPalette::dismiss ( )
overridevirtual

Called when you want to dismiss a popup widget.

Implements KisPopupWidgetInterface.

Definition at line 1097 of file kis_popup_palette.cpp.

1098{
1099 setVisible(false);
1100}

◆ drawDonutPathAngle()

QPainterPath KisPopupPalette::drawDonutPathAngle ( int inner_radius,
int outer_radius,
int limit )
private

Definition at line 798 of file kis_popup_palette.cpp.

799{
800 QPainterPath path;
801 path.moveTo(-0.999 * outer_radius * sin(M_PI / limit), 0.999 * outer_radius * cos(M_PI / limit));
802 path.arcTo(-1 * outer_radius, -1 * outer_radius, 2 * outer_radius, 2 * outer_radius, -90.0 - 180.0 / limit,
803 360.0 / limit);
804 path.arcTo(-1 * inner_radius, -1 * inner_radius, 2 * inner_radius, 2 * inner_radius, -90.0 + 180.0 / limit,
805 - 360.0 / limit);
806 path.closeSubpath();
807
808 return path;
809}

References M_PI.

◆ drawDonutPathFull()

QPainterPath KisPopupPalette::drawDonutPathFull ( int x,
int y,
int inner_radius,
int outer_radius )
private

Definition at line 788 of file kis_popup_palette.cpp.

789{
790 QPainterPath path;
791 path.addEllipse(QPointF(x, y), outer_radius, outer_radius);
792 path.addEllipse(QPointF(x, y), inner_radius, inner_radius);
793 path.setFillRule(Qt::OddEvenFill);
794
795 return path;
796}

◆ drawFgBgColorIndicator()

QPainterPath KisPopupPalette::drawFgBgColorIndicator ( int type) const
private

Definition at line 811 of file kis_popup_palette.cpp.

812{
813 QPointF edgePoint = QPointF(0.14645, 0.14645) * (m_popupPaletteSize);
814
815 // the points are really (-5, 15) and (5, 15) shifted right 1px
816 // this is so that where the circles meet the circle of the palette, the space occupied is exactly half to either side of the -45deg line
817 QPainterPath indicator;
818 switch (type) {
819 case 0: { // background
820 indicator.addEllipse(edgePoint + QPointF(-4, 15), 30, 30);
821 break;
822 }
823 case 1: { //foreground
824 indicator.addEllipse(edgePoint + QPointF(6, -15), 30, 30);
825 break;
826 }
827 }
828 return indicator;
829}

References m_popupPaletteSize.

◆ drawPointOnAngle()

QPointF KisPopupPalette::drawPointOnAngle ( qreal angle,
qreal radius ) const
private

Definition at line 1243 of file kis_popup_palette.cpp.

1244{
1245 QPointF p(
1246 // -90 so it starts at the top since this is mainly used by calculatePresetLayout
1247 radius * qCos(qDegreesToRadians(angle - 90)),
1248 radius * qSin(qDegreesToRadians(angle - 90))
1249 );
1250 return p;
1251}
const Params2D p

References p.

◆ ensureWithinParent()

void KisPopupPalette::ensureWithinParent ( const QPoint & globalPos,
bool useUpperLeft )

Definition at line 1107 of file kis_popup_palette.cpp.

1107 {
1108 if (isVisible()) {
1109 const QSize paletteSize = geometry().size();
1110 const QPoint paletteCenterOffset(paletteSize.width() / 2, paletteSize.height() / 2);
1111
1112 QPoint paletteGlobalPos = globalPos;
1113 if (!useUpperLeft) {
1114 paletteGlobalPos -= paletteCenterOffset;
1115 }
1116
1117 if (parentWidget()) {
1118 const qreal widgetMargin = -20.0;
1119
1120 const QPoint paletteParentPos = parentWidget()->mapFromGlobal(paletteGlobalPos);
1121 QRect paletteParentRect(paletteParentPos, paletteSize);
1122
1123 const QRect fitRect = kisGrowRect(parentWidget()->rect(), widgetMargin);
1124 paletteParentRect = kisEnsureInRect(paletteParentRect, fitRect);
1125 paletteGlobalPos = parentWidget()->mapToGlobal(paletteParentRect.topLeft());
1126 }
1127
1128
1129 const QPoint moveToPoint = this->windowHandle() ? paletteGlobalPos : parentWidget()->mapFromGlobal(paletteGlobalPos);
1130
1131 move(moveToPoint);
1132 }
1133}
T kisGrowRect(const T &rect, U offset)
Definition kis_global.h:186
QRect kisEnsureInRect(QRect rc, const QRect &bounds)
Definition kis_global.h:291
unsigned paletteSize
Definition palette.c:34

References kisEnsureInRect(), kisGrowRect(), and paletteSize.

◆ eventFilter()

bool KisPopupPalette::eventFilter ( QObject * ,
QEvent * event )
overrideprotected

Definition at line 992 of file kis_popup_palette.cpp.

993{
994 switch (event->type()) {
995 case QEvent::TouchBegin:
997 break;
998 case QEvent::MouseButtonPress:
999 case QEvent::MouseMove:
1000 // HACK(sh_zam): Let's say the tap gesture is used by the canvas to launch the popup. Following that, a
1001 // synthesized mousePress is sent and this arrives in our event filter here. But, this event was meant for the
1002 // canvas (even though it blocks it), so we only act on the event if we got a TouchBegin on it first.
1003 if (static_cast<QMouseEvent *>(event)->source() == Qt::MouseEventSynthesizedBySystem && !m_touchBeginReceived) {
1004 event->accept();
1005 return true;
1006 }
1007 break;
1008 case QEvent::MouseButtonRelease:
1009 if (static_cast<QMouseEvent *>(event)->source() == Qt::MouseEventSynthesizedBySystem && !m_touchBeginReceived) {
1010 event->accept();
1011 return true;
1012 }
1013 // fallthrough
1014 case QEvent::Show:
1015 case QEvent::FocusOut:
1016 m_touchBeginReceived = false;
1017 break;
1018 default:
1019 break;
1020 }
1021 return false;
1022}
KisMagneticGraph::vertex_descriptor source(typename KisMagneticGraph::edge_descriptor e, KisMagneticGraph g)

References m_touchBeginReceived, and source().

◆ findPresetSlot()

int KisPopupPalette::findPresetSlot ( QPointF position) const
protected

/ find the index of the brush preset slot containing @position.

Returns
-1 if none is found

Definition at line 1591 of file kis_popup_palette.cpp.

1592{
1593 QPointF adjustedPoint = position - QPointF(m_popupPaletteSize/2, m_popupPaletteSize/2);
1594 for (int i = 0; i < m_presetSlotCount; i++) {
1595 if (createPathFromPresetIndex(i).contains(adjustedPoint)) {
1596 return i;
1597 }
1598 }
1599 return -1;
1600}
QPainterPath createPathFromPresetIndex(int index) const

References createPathFromPresetIndex(), m_popupPaletteSize, and m_presetSlotCount.

◆ finished

void KisPopupPalette::finished ( )
overridesignal

◆ hoveredColor()

int KisPopupPalette::hoveredColor ( ) const
protected

Definition at line 487 of file kis_popup_palette.cpp.

488{
489 return m_hoveredColor;
490}

References m_hoveredColor.

◆ hoveredPreset()

int KisPopupPalette::hoveredPreset ( ) const
protected

Definition at line 477 of file kis_popup_palette.cpp.

478{
479 return m_hoveredPreset;
480}

References m_hoveredPreset.

◆ isPointInPixmap()

bool KisPopupPalette::isPointInPixmap ( QPointF & point,
int pos )
private

Definition at line 1235 of file kis_popup_palette.cpp.

1236{
1237 if (createPathFromPresetIndex(pos).contains(point + QPointF(-m_popupPaletteSize / 2, -m_popupPaletteSize / 2))) {
1238 return true;
1239 }
1240 return false;
1241}

References createPathFromPresetIndex(), and m_popupPaletteSize.

◆ mouseMoveEvent()

void KisPopupPalette::mouseMoveEvent ( QMouseEvent * event)
overrideprotected

Definition at line 841 of file kis_popup_palette.cpp.

842{
843 QPointF point = event->localPos();
844 event->accept();
845
847 // check if mouse is over the canvas rotation knob
848 bool wasOverRotationIndicator = m_isOverCanvasRotationIndicator;
850 bool wasOverResetRotationIndicator = m_isOverResetCanvasRotationIndicator;
852
853 if (
854 wasOverRotationIndicator != m_isOverCanvasRotationIndicator ||
855 wasOverResetRotationIndicator != m_isOverResetCanvasRotationIndicator
856 ) {
857 update();
858 }
859
861 m_snapRotation = false;
862 int i = 0;
863 for (QRect &rect: m_snapRects) {
864 QPainterPath circle;
865 circle.addEllipse(rect);
866 if (circle.contains(point)) {
867 m_snapRotation = true;
868 m_rotationSnapAngle = i * 15;
869 break;
870 }
871 i++;
872 }
873 qreal finalAngle = 0.0;
874 if (m_snapRotation) {
875 finalAngle = m_rotationSnapAngle;
876 // to match the numbers displayed when rotating without snapping
877 if (finalAngle >= 270) {
878 finalAngle = finalAngle - 360;
879 }
880 } else {
881 // we are rotating the canvas, so calculate the rotation angle based off the center
882 // calculate the angle we are at first
883 QPoint widgetCenterPoint = QPoint(m_popupPaletteSize/2, m_popupPaletteSize/2);
884
885 qreal dX = point.x() - widgetCenterPoint.x();
886 qreal dY = point.y() - widgetCenterPoint.y();
887
888
889 finalAngle = qAtan2(dY,dX) * 180 / M_PI; // what we need if we have two points, but don't know the angle
890 finalAngle = finalAngle + 90; // add 90 degrees so 0 degree position points up
891 }
892 qreal angleDifference = finalAngle - m_coordinatesConverter->rotationAngle(); // the rotation function accepts diffs, so find it out
893
894 KisCanvasController *canvasController =
896 KIS_ASSERT_RECOVER_RETURN(canvasController);
897 canvasController->rotateCanvas(angleDifference);
899
900 update();
901 Q_EMIT sigUpdateCanvas();
902 }
903 }
904
905 if (m_isRotatingCanvasIndicator == false) {
906 QPainterPath bgColor(drawFgBgColorIndicator(0));
907 QPainterPath fgColor(drawFgBgColorIndicator(1));
908 QPainterPath backgroundContainer;
910 backgroundContainer.addEllipse(circleRect);
911
912 QPainterPath fgBgColors = (fgColor + bgColor) - backgroundContainer;
913
914 if (fgBgColors.contains(point)) {
915 if (!m_isOverFgBgColors) {
916 m_isOverFgBgColors = true;
917 setToolTip(i18n("Click to swap foreground and background colors.\nRight click to set to black and white."));
918 update();
919 }
920 } else {
921 if (m_isOverFgBgColors) {
922 m_isOverFgBgColors = false;
923 setToolTip(QString());
924 update();
925 }
926 }
927
929 if (colorHistoryPath.contains(point)) {
930 if (hoveredPreset() >= 0) {
931 setToolTip(QString());
933 }
934
936
937 if (pos != hoveredColor()) {
938 setHoveredColor(pos);
939 update();
940 }
941 }
942 else {
943 if (hoveredColor() >= 0) {
944 setHoveredColor(-1);
945 update();
946 }
947
948 int pos = findPresetSlot(point);
949
950 if (pos != hoveredPreset()) {
951
952 if (pos >= 0 && pos < m_resourceManager->numFavoritePresets()) {
953 setToolTip(m_resourceManager->favoritePresetNamesList().at(pos));
954 setHoveredPreset(pos);
955 }
956 else {
957 setToolTip(QString());
959 }
960
961 update();
962 }
963 }
964 }
965}
void rotateCanvas(qreal angle, const std::optional< KoViewTransformStillPoint > &stillPoint, bool isNativeGesture=false)
QPainterPath drawFgBgColorIndicator(int type) const
void sigUpdateCanvas()
int findPresetSlot(QPointF position) const
/ find the index of the brush preset slot containing @position.
QRectF m_resetCanvasRotationIndicatorRect
QPainterPath drawDonutPathFull(int, int, int, int)
int calculateColorIndex(QPointF position, int numColors) const
Calculate index of recent color in array.
QRectF rotationIndicatorRect(qreal rotationAngle) const
bool m_isOverResetCanvasRotationIndicator
QRectF m_canvasRotationIndicatorRect
KisCanvas2 * canvasBase() const
Return the canvas base class.
KoCanvasController * canvasController() const
#define KIS_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:75

References BORDER_WIDTH, calculateColorIndex(), KisViewManager::canvasBase(), KoCanvasBase::canvasController(), drawDonutPathFull(), drawFgBgColorIndicator(), KisFavoriteResourceManager::favoritePresetNamesList(), findPresetSlot(), hoveredColor, hoveredPreset, KIS_ASSERT_RECOVER_RETURN, m_canvasRotationIndicatorRect, m_colorHistoryInnerRadius, m_colorHistoryOuterRadius, m_coordinatesConverter, m_isOverCanvasRotationIndicator, m_isOverFgBgColors, m_isOverResetCanvasRotationIndicator, m_isRotatingCanvasIndicator, M_PI, m_popupPaletteSize, m_resetCanvasRotationIndicatorRect, m_resourceManager, m_rotationSnapAngle, m_showRotationTrack, m_snapRects, m_snapRotation, m_viewManager, KisFavoriteResourceManager::recentColorsTotal(), KisCanvasController::rotateCanvas(), KisCoordinatesConverter::rotationAngle(), rotationIndicatorRect(), setHoveredColor(), setHoveredPreset(), and sigUpdateCanvas().

◆ mousePressEvent()

void KisPopupPalette::mousePressEvent ( QMouseEvent * event)
overrideprotected

◆ mouseReleaseEvent()

void KisPopupPalette::mouseReleaseEvent ( QMouseEvent * event)
overrideprotected

We are in native and modal mode, so handle our closure ourselves

Definition at line 1169 of file kis_popup_palette.cpp.

1170{
1171 QPointF point = event->localPos();
1172 event->accept();
1173
1177#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1178 const QPointF localPos = event->localPos();
1179#else
1180 const QPointF localPos = event->position();
1181#endif
1182
1183 if (this->windowHandle() && !QRectF(rect()).contains(localPos)) {
1184 Q_EMIT finished();
1185 return;
1186 }
1187
1189 update();
1190 }
1191
1193
1194 if (event->button() == Qt::LeftButton) {
1195 if (m_isOverFgBgColors) {
1197 }
1198
1199 //in favorite brushes area
1200 if (hoveredPreset() > -1) {
1201 //setSelectedBrush(hoveredBrush());
1203 }
1204
1205 if (m_showColorHistory) {
1207 if (pathColor.contains(point)) {
1209
1210 if (pos >= 0 && pos < m_resourceManager->recentColorsTotal()) {
1211 Q_EMIT sigUpdateRecentColor(pos);
1212 }
1213 }
1214 }
1215 } else if (event->button() == Qt::RightButton) {
1216 Q_EMIT finished();
1217 }
1218}

References calculateColorIndex(), drawDonutPathFull(), finished(), hoveredPreset, m_colorHistoryInnerRadius, m_colorHistoryOuterRadius, m_isOverFgBgColors, m_isRotatingCanvasIndicator, m_popupPaletteSize, m_resourceManager, m_showColorHistory, m_viewManager, KisFavoriteResourceManager::recentColorsTotal(), sigChangeActivePaintop(), sigUpdateRecentColor(), and KisViewManager::slotToggleFgBg().

◆ onScreen()

bool KisPopupPalette::onScreen ( )
overridevirtual

Returns whether the widget is active (on screen) or not.

Implements KisPopupWidgetInterface.

Definition at line 1102 of file kis_popup_palette.cpp.

1103{
1104 return isVisible();
1105}

◆ paintEvent()

void KisPopupPalette::paintEvent ( QPaintEvent * e)
overrideprotected

Definition at line 572 of file kis_popup_palette.cpp.

573{
574 Q_UNUSED(e);
575
576 QPainter painter(this);
577
578 QPen pen(palette().color(QPalette::Text), BORDER_WIDTH);
579 painter.setPen(pen);
580
581 painter.setRenderHint(QPainter::Antialiasing);
582 painter.setRenderHint(QPainter::SmoothPixmapTransform);
583
584 if (m_isOverFgBgColors) {
585 painter.save();
586 painter.setPen(QPen(palette().color(QPalette::Highlight), BORDER_WIDTH));
587 }
588
589 // painting background color indicator
590 QPainterPath bgColor(drawFgBgColorIndicator(0));
591 painter.fillPath(bgColor, m_displayRenderer->toQColor(m_resourceManager->bgColor()));
592 painter.drawPath(bgColor);
593
594 // painting foreground color indicator
595 QPainterPath fgColor(drawFgBgColorIndicator(1));
596 painter.fillPath(fgColor, m_displayRenderer->toQColor(m_colorSelector->getCurrentColor()));
597 painter.drawPath(fgColor);
598
599 if (m_isOverFgBgColors) painter.restore();
600
601
602 // create a circle background that everything else will go into
603 QPainterPath backgroundContainer;
604
605 // draws the circle halfway into the border so that the border never goes past the bounds of the popup
607 backgroundContainer.addEllipse(circleRect);
608 painter.fillPath(backgroundContainer, palette().brush(QPalette::Window));
609 painter.drawPath(backgroundContainer);
610
612 painter.save();
613 QPen pen(palette().color(QPalette::Window).lighter(150), 2);
614 painter.setPen(pen);
615
616 // draw rotation snap lines
618 for (QLineF &line: m_snapLines) {
619 painter.drawLine(line);
620 }
621 }
622 // create a path slightly inside the container circle. this will create a 'track' to indicate that we can rotate the canvas
623 // with the indicator
624 QPainterPath rotationTrackPath;
625 QRectF circleRect2(m_rotationTrackSize, m_rotationTrackSize,
627
628 rotationTrackPath.addEllipse(circleRect2);
629 painter.drawPath(rotationTrackPath);
630
631 // create a reset canvas rotation indicator to bring the canvas back to 0 degrees
632 QRectF resetRotationIndicator = m_resetCanvasRotationIndicatorRect;
633
635 ? palette().color(QPalette::Highlight)
636 : palette().color(QPalette::Text));
637 // cover the first snap line
638 painter.setBrush(palette().brush(QPalette::Window));
639 painter.setPen(pen);
640 painter.drawEllipse(resetRotationIndicator);
641
642 // create the canvas rotation handle
643 // highlight if either just hovering or currently rotating
645 ? palette().color(QPalette::Highlight)
646 : palette().color(QPalette::Text));
647 painter.setPen(pen);
648
649 // fill with highlight if snapping
651 ? palette().brush(QPalette::Highlight)
652 : palette().brush(QPalette::Text));
653
654 // gotta update the rect, see bug 459801
655 // (note: it can't just update when it shows up because then rotating when popup palette is on the screen wouldn't make an effect)
657 painter.drawEllipse(m_canvasRotationIndicatorRect);
658
659 painter.restore();
660 }
661
662 // the following things needs to be based off the center, so let's translate the painter
663 painter.translate(m_popupPaletteSize / 2, m_popupPaletteSize / 2);
664
665 // painting favorite brushes
667
668 // painting favorite brushes pixmap/icon
669 QPainterPath presetPath;
670 int presetCount = images.size();
671 bool isTagEmpty = presetCount == 0;
672 for (int pos = 0; pos < m_presetSlotCount; pos++) {
673 painter.save();
674 presetPath = createPathFromPresetIndex(pos);
675
676 if (pos < presetCount) {
677 painter.setClipPath(presetPath);
678
679 QRect bounds = presetPath.boundingRect().toAlignedRect();
680 if (!images.at(pos).isNull()) {
681 QImage previewHighDPI = images.at(pos).scaled(bounds.size()*devicePixelRatioF() , Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
682 previewHighDPI.setDevicePixelRatio(devicePixelRatioF());
683 painter.drawImage(bounds.topLeft(), previewHighDPI);
684 }
685 } else {
686 painter.fillPath(presetPath, palette().brush(QPalette::Window)); // brush slot that has no brush in it
687 }
688 // needs to be called here so that the clipping is removed
689 painter.restore();
690 // if the slot is empty, stroke it slightly darker
691 QColor color = isTagEmpty || pos >= presetCount
692 ? palette().color(QPalette::Window).lighter(150)
693 : palette().color(QPalette::Text);
694 painter.setPen(QPen(color, 1));
695 painter.drawPath(presetPath);
696 }
697 if (hoveredPreset() > -1) {
699 painter.setPen(QPen(palette().color(QPalette::Highlight), BORDER_WIDTH));
700 painter.drawPath(presetPath);
701 }
702
703 if (m_showColorHistory) {
704 // paint recent colors area.
705 painter.setPen(Qt::NoPen);
706 const qreal rotationAngle = 360.0 / m_resourceManager->recentColorsTotal();
707 const qreal rotationOffset = 180.0;
708
709 painter.rotate(rotationOffset);
710
711 // there might be no recent colors at the start, so paint a placeholder
713 painter.setBrush(Qt::transparent);
714
715 QPainterPath emptyRecentColorsPath(drawDonutPathFull(0, 0, m_colorHistoryInnerRadius, m_colorHistoryOuterRadius));
716 painter.setPen(QPen(palette().color(QPalette::Window).lighter(150), 2, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
717 painter.drawPath(emptyRecentColorsPath);
718 } else {
719 for (int pos = 0; pos < m_resourceManager->recentColorsTotal(); pos++) {
721
722 //accessing recent color of index pos
723 painter.fillPath(recentColorsPath, m_displayRenderer->toQColor( m_resourceManager->recentColorAt(pos) ));
724 painter.drawPath(recentColorsPath);
725 painter.rotate(rotationAngle);
726 }
727 }
728
729 // painting hovered color
730 if (hoveredColor() > -1) {
731 painter.setPen(QPen(palette().color(QPalette::Highlight), 2, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
732
734 QPainterPath path_ColorDonut(drawDonutPathFull(0, 0, m_colorHistoryInnerRadius, m_colorHistoryOuterRadius));
735 painter.drawPath(path_ColorDonut);
736 } else {
737 painter.rotate((m_resourceManager->recentColorsTotal() + hoveredColor()) * rotationAngle);
739 painter.drawPath(path);
740 painter.rotate(hoveredColor() * -1 * rotationAngle);
741 }
742 }
743
744 // painting selected color
745 if (selectedColor() > -1) {
746 painter.setPen(QPen(palette().color(QPalette::Highlight).darker(130), 2, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
747
749 QPainterPath path_ColorDonut(drawDonutPathFull(0, 0, m_colorHistoryInnerRadius, m_colorHistoryOuterRadius));
750 painter.drawPath(path_ColorDonut);
751 } else {
752 painter.rotate((m_resourceManager->recentColorsTotal() + selectedColor()) * rotationAngle);
754 painter.drawPath(path);
755 painter.rotate(selectedColor() * -1 * rotationAngle);
756 }
757 }
758 }
759
760
761 // if we are actively rotating the canvas or zooming, make the panel slightly transparent to see the canvas better
763 opacityChange->setOpacity(0.4);
764 } else {
765 opacityChange->setOpacity(1.0);
766 }
767
768}
virtual KoColor getCurrentColor() const =0
QPainterPath drawDonutPathAngle(int, int, int)
KisColorSelectorInterface * m_colorSelector
virtual QColor toQColor(const KoColor &c, bool proofToPaintColors=false) const =0
#define bounds(x, a, b)
rgba palette[MAX_PALETTE]
Definition palette.c:35

References KisFavoriteResourceManager::bgColor(), BORDER_WIDTH, bounds, createPathFromPresetIndex(), drawDonutPathAngle(), drawDonutPathFull(), drawFgBgColorIndicator(), KisFavoriteResourceManager::favoritePresetImages(), KisColorSelectorInterface::getCurrentColor(), hoveredColor, hoveredPreset, m_canvasRotationIndicatorRect, m_colorHistoryInnerRadius, m_colorHistoryOuterRadius, m_colorSelector, m_coordinatesConverter, m_displayRenderer, m_isOverCanvasRotationIndicator, m_isOverFgBgColors, m_isOverResetCanvasRotationIndicator, m_isRotatingCanvasIndicator, m_isZoomingCanvas, m_popupPaletteSize, m_presetSlotCount, m_resetCanvasRotationIndicatorRect, m_resourceManager, m_rotationTrackSize, m_showColorHistory, m_showRotationTrack, m_snapLines, m_snapRotation, opacityChange, palette, KisFavoriteResourceManager::recentColorAt(), KisFavoriteResourceManager::recentColorsTotal(), KisCoordinatesConverter::rotationAngle(), rotationIndicatorRect(), selectedColor, and KoColorDisplayRendererInterface::toQColor().

◆ popup()

void KisPopupPalette::popup ( const QPoint & position)
overridevirtual

Called when and where you want a widget to popup.

Implements KisPopupWidgetInterface.

Definition at line 1089 of file kis_popup_palette.cpp.

1089 {
1090 setVisible(true);
1091 KIS_SAFE_ASSERT_RECOVER_RETURN(parentWidget());
1092 const QPoint globalPos = parentWidget()->mapToGlobal(position);
1093 ensureWithinParent(globalPos, false);
1094 m_mirrorPos = globalPos;
1095}
void ensureWithinParent(const QPoint &globalPos, bool useUpperLeft)
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128

References ensureWithinParent(), KIS_SAFE_ASSERT_RECOVER_RETURN, and m_mirrorPos.

◆ reconfigure()

void KisPopupPalette::reconfigure ( )
private

Definition at line 297 of file kis_popup_palette.cpp.

298{
299 KisConfig config(true);
300 m_useDynamicSlotCount = config.readEntry("popuppalette/useDynamicSlotCount", true);
301 m_maxPresetSlotCount = config.favoritePresets();
303 int presetCount = m_resourceManager->numFavoritePresets();
304 // if there are no presets because the tag is empty
305 // show the maximum number allowed (they will be painted as empty slots)
306 m_presetSlotCount = presetCount == 0
309 } else {
311 }
312 m_popupPaletteSize = config.readEntry("popuppalette/size", 385);
313 qreal selectorRadius = config.readEntry("popuppalette/selectorSize", 140) / 2.0;
314
315 m_showColorHistory = config.readEntry("popuppalette/showColorHistory", true);
316 m_showRotationTrack = config.readEntry("popuppalette/showRotationTrack", true);
317
320 if (m_showColorHistory) {
322 m_clearColorHistoryButton->setVisible(true);
323 } else {
324 m_clearColorHistoryButton->setVisible(false);
325 }
326
328
329 bool useVisualSelector = config.readEntry<bool>("popuppalette/usevisualcolorselector", false);
330 if (m_colorSelector) {
331 // if the selector type changed, delete it
332 bool haveVisualSelector = qobject_cast<KisVisualColorSelector*>(m_colorSelector) != 0;
333 if (useVisualSelector != haveVisualSelector) {
334 delete m_colorSelector;
335 m_colorSelector = 0;
336 }
337 }
338 if (!m_colorSelector) {
339 if (useVisualSelector) {
341 selector->setAcceptTabletEvents(true);
342 connect(KisConfigNotifier::instance(), SIGNAL(configChanged()),
343 selector, SLOT(slotConfigurationChanged()));
344 m_colorSelector = selector;
345 }
346 else {
348 connect(m_colorSelector, SIGNAL(requestCloseContainer()), this, SIGNAL(finished()));
349 connect(KisConfigNotifier::instance(), SIGNAL(configChanged()),
350 m_colorSelector, SLOT(configurationChanged()));
351 }
353 m_colorSelector->setConfig(true,false);
354 m_colorSelector->setVisible(true);
356 connect(m_colorSelector, SIGNAL(sigNewColor(KoColor)),
357 m_colorChangeCompressor.data(), SLOT(start()));
358
359 }
360
361 if (KoTriangleColorSelector *srgbColorSelector = dynamic_cast<KoTriangleColorSelector*>(m_colorSelector)) {
362 bool fixTriangleRotation = config.readEntry("popuppalette/fixTriangleRotation", false);
363 if (fixTriangleRotation) {
364 int triangleRotationAngle = config.readEntry("popuppalette/triangleRotationAngle", 0);
365 srgbColorSelector->setRotation(triangleRotationAngle);
366 }
367 else srgbColorSelector->setFollowHue(true);
368 }
369
370 const int auxButtonSize = 35;
371 m_colorSelector->move(m_popupPaletteSize/2 - selectorRadius, m_popupPaletteSize/2 - selectorRadius);
373
374 // ellipse - to make sure the widget doesn't eat events meant for recent colors or brushes
375 // - needs to be +2 pixels on every side for anti-aliasing to look nice on high dpi displays
376 // rectangle - to make sure the area doesn't extend outside of the widget
377 QRegion maskedEllipse(-2, -2, m_colorSelector->width() + 4, m_colorSelector->height() + 4, QRegion::Ellipse );
378 QRegion maskedRectangle(0, 0, m_colorSelector->width(), m_colorSelector->height(), QRegion::Rectangle);
379 QRegion maskedRegion = maskedEllipse.intersected(maskedRectangle);
380
381 m_colorSelector->setMask(maskedRegion);
382
383 m_dockerHud->setFixedHeight(int(m_popupPaletteSize));
384
385 // arranges the buttons around the popup palette
386 // buttons are spread out from the center of the set arc length
387
388 // the margin in degrees between buttons
389 qreal margin = 10.0;
390 // visual center
391 qreal center = m_popupPaletteSize/2 - auxButtonSize/2.0;
392 qreal length = m_popupPaletteSize/2 + auxButtonSize/2.0 + 5;
393 {
394 int buttonCount = 2;
395 int arcLength = 90;
396 // note the int buttonCount/2 is on purpose
397 qreal start = arcLength/2 - (buttonCount/2) * margin;
398 if (buttonCount % 2 == 0) start += margin / 2;
399 int place = 0;
400 m_dockerHudButton->setGeometry(
401 center + qCos(qDegreesToRadians(start + place*margin))*length,
402 center + qSin(qDegreesToRadians(start + place*margin))*length,
403 auxButtonSize, auxButtonSize
404 );
405 place++;
406 m_bottomBarButton->setGeometry (
407 center + qCos(qDegreesToRadians(start + place*margin))*length,
408 center + qSin(qDegreesToRadians(start + place*margin))*length,
409 auxButtonSize, auxButtonSize
410 );
411 }
412 {
413 int buttonCount = m_showColorHistory ? 2 : 1 ;
414 int arcLength = 90;
415 int shiftArc = 90;
416 // note the int buttonCount/2 is on purpose
417 qreal start = shiftArc + arcLength / 2 - (buttonCount/2) * margin;
418 if (buttonCount % 2 == 0) start += margin / 2;
419 int place = 0;
420 if (m_showColorHistory) {
421 m_clearColorHistoryButton->setGeometry(
422 center + qCos(qDegreesToRadians(start + place * margin)) * length,
423 center + qSin(qDegreesToRadians(start + place * margin)) * length,
424 auxButtonSize, auxButtonSize);
425 place++;
426 }
427 m_tagsButton->setGeometry(
428 center + qCos(qDegreesToRadians(start + place*margin))*length,
429 center + qSin(qDegreesToRadians(start + place*margin))*length,
430 auxButtonSize, auxButtonSize
431 );
432 }
434}
virtual void setDisplayRenderer(const KoColorDisplayRendererInterface *displayRenderer)
virtual void setConfig(bool forceCircular, bool forceSelfUpdate)
void calculatePresetLayout()
Determine the number of rings to distribute the presets and calculate the radius of the brush preset ...
The KisVisualColorSelector class.

References calculatePresetLayout(), KisConfig::favoritePresets(), finished(), KisConfigNotifier::instance(), length(), m_bottomBarButton, m_clearColorHistoryButton, m_colorChangeCompressor, m_colorHistoryInnerRadius, m_colorHistoryOuterRadius, m_colorSelector, m_displayRenderer, m_dockerHud, m_dockerHudButton, m_mainArea, m_maxPresetSlotCount, m_popupPaletteSize, m_presetRingMargin, m_presetSlotCount, m_resourceManager, m_showColorHistory, m_showRotationTrack, m_tagsButton, m_useDynamicSlotCount, KisFavoriteResourceManager::numFavoritePresets(), KisConfig::readEntry(), KisVisualColorSelector::setAcceptTabletEvents(), KisColorSelectorInterface::setConfig(), KisColorSelectorInterface::setDisplayRenderer(), slotConfigurationChanged(), and slotDisplayConfigurationChanged().

◆ resizeEvent()

void KisPopupPalette::resizeEvent ( QResizeEvent * resizeEvent)
overrideprotected

When popup is native, its geometry report the global position; then the popup is non-native, its geometry is in its parent's coordinate system.

Definition at line 770 of file kis_popup_palette.cpp.

770 {
771 Q_UNUSED(resizeEvent);
775 // Ensure that the resized geometry fits within the desired rect...
776
782 const QPoint globalTopLeft = windowHandle() ?
783 geometry().topLeft() :
784 parentWidget()->mapToGlobal(geometry().topLeft());
785 ensureWithinParent(globalTopLeft, true);
786}
void resizeEvent(QResizeEvent *) override

References calculateRotationSnapAreas(), ensureWithinParent(), m_canvasRotationIndicatorRect, m_coordinatesConverter, m_resetCanvasRotationIndicatorRect, resizeEvent(), KisCoordinatesConverter::rotationAngle(), and rotationIndicatorRect().

◆ rotationIndicatorRect()

QRectF KisPopupPalette::rotationIndicatorRect ( qreal rotationAngle) const
private

Definition at line 831 of file kis_popup_palette.cpp.

832{
833 qreal paletteRadius = 0.5 * m_popupPaletteSize;
834 QPointF rotationDialPosition(drawPointOnAngle(rotationAngle, paletteRadius - 10));
835 rotationDialPosition += QPointF(paletteRadius, paletteRadius);
836
837 QPointF indicatorDiagonal(7.5, 7.5);
838 return QRectF(rotationDialPosition - indicatorDiagonal, rotationDialPosition + indicatorDiagonal);
839}

References drawPointOnAngle(), and m_popupPaletteSize.

◆ selectedColor()

int KisPopupPalette::selectedColor ( ) const

Definition at line 497 of file kis_popup_palette.cpp.

498{
499 return m_selectedColor;
500}

References m_selectedColor.

◆ setHoveredColor()

void KisPopupPalette::setHoveredColor ( int x)
protected

Definition at line 492 of file kis_popup_palette.cpp.

References m_hoveredColor.

◆ setHoveredPreset()

void KisPopupPalette::setHoveredPreset ( int x)
protected

Definition at line 482 of file kis_popup_palette.cpp.

483{
485}

References m_hoveredPreset.

◆ setParent()

void KisPopupPalette::setParent ( QWidget * parent)

Definition at line 560 of file kis_popup_palette.cpp.

560 {
561 QWidget::setParent(parent);
562}

◆ setSelectedColor()

void KisPopupPalette::setSelectedColor ( int x)

Definition at line 502 of file kis_popup_palette.cpp.

503{
505}

References m_selectedColor.

◆ showBottomBarWidget

void KisPopupPalette::showBottomBarWidget ( bool visible)
privateslot

Definition at line 550 of file kis_popup_palette.cpp.

551{
552 const bool reallyVisible = visible && m_bottomBarButton->isChecked();
553
554 m_bottomBarWidget->setVisible(reallyVisible);
555
556 KisConfig cfg(false);
557 cfg.setShowPaletteBottomBar(visible);
558}

References m_bottomBarButton, m_bottomBarWidget, and KisConfig::setShowPaletteBottomBar().

◆ showEvent()

void KisPopupPalette::showEvent ( QShowEvent * event)
overrideprotected

Definition at line 1135 of file kis_popup_palette.cpp.

1136{
1138
1139 // don't set the zoom slider if we are outside of the zoom slider bounds. It will change the zoom level to within
1140 // the bounds and cause the canvas to jump between the slider's min and max
1144 zoomCanvasSlider->setValue(m_coordinatesConverter->zoomInPercent()); // sync the zoom slider
1145 }
1146
1147 QWidget::showEvent(event);
1148}

References m_clicksEater, m_coordinatesConverter, KisMouseClickEater::reset(), zoomCanvasSlider, KoZoomHandler::zoomInPercent(), zoomSliderMaxValue, and zoomSliderMinValue.

◆ showHudWidget

void KisPopupPalette::showHudWidget ( bool visible)
privateslot

Definition at line 540 of file kis_popup_palette.cpp.

541{
543 const bool reallyVisible = visible && m_dockerHudButton->isChecked();
544 m_dockerHud->setVisible(reallyVisible);
545
546 KisConfig cfg(false);
547 cfg.setShowBrushHud(visible);
548}
void setIsShown(bool isShown)

References m_dockerHud, m_dockerHudButton, KisDockerHud::setIsShown(), and KisConfig::setShowBrushHud().

◆ sigChangeActivePaintop

void KisPopupPalette::sigChangeActivePaintop ( int )
signal

◆ sigChangefGColor

void KisPopupPalette::sigChangefGColor ( const KoColor & )
signal

◆ sigUpdateCanvas

void KisPopupPalette::sigUpdateCanvas ( )
signal

◆ sigUpdateRecentColor

void KisPopupPalette::sigUpdateRecentColor ( int )
signal

◆ sizeHint()

QSize KisPopupPalette::sizeHint ( ) const
override

Definition at line 565 of file kis_popup_palette.cpp.

566{
567 // Note: the canvas popup widget system "abuses" the sizeHint to determine
568 // the position to show the widget; this does not reflect the true size.
570}

References m_popupPaletteSize.

◆ slotConfigurationChanged

void KisPopupPalette::slotConfigurationChanged ( )
privateslot

Definition at line 291 of file kis_popup_palette.cpp.

292{
293 reconfigure();
294 layout()->invalidate();
295}

References reconfigure().

◆ slotDisplayConfigurationChanged

void KisPopupPalette::slotDisplayConfigurationChanged ( )
privateslot

Definition at line 436 of file kis_popup_palette.cpp.

437{
438 // Visual Color Selector picks up color space from input
441 //hack to get around cmyk for now.
442 if (paintingCS->colorChannelCount()>3) {
443 paintingCS = KoColorSpaceRegistry::instance()->rgb8();
444 }
447}
virtual void slotSetColor(const KoColor &c)=0
virtual void slotSetColorSpace(const KoColorSpace *cs)
slotSetColorSpace Set the color space the selector should cover
virtual const KoColorSpace * getPaintingColorSpace() const =0
getColorSpace
virtual quint32 colorChannelCount() const =0
static KoColorSpaceRegistry * instance()
const KoColorSpace * rgb8(const QString &profileName=QString())

References KisViewManager::canvasResourceProvider(), KoColorSpace::colorChannelCount(), KisCanvasResourceProvider::fgColor(), KoColorDisplayRendererInterface::getPaintingColorSpace(), KoColorSpaceRegistry::instance(), m_colorSelector, m_displayRenderer, m_viewManager, KoColorSpaceRegistry::rgb8(), KisColorSelectorInterface::slotSetColor(), and KisColorSelectorInterface::slotSetColorSpace().

◆ slotEmitColorChanged

void KisPopupPalette::slotEmitColorChanged ( )
privateslot

Definition at line 456 of file kis_popup_palette.cpp.

457{
458 if (isVisible()) {
459 update();
461 }
462}

References KisColorSelectorInterface::getCurrentColor(), m_colorSelector, and sigChangefGColor().

◆ slotExternalFgColorChanged

void KisPopupPalette::slotExternalFgColorChanged ( const KoColor & color)
privateslot

◆ slotFitToViewClicked

void KisPopupPalette::slotFitToViewClicked ( )
privateslot

Definition at line 1071 of file kis_popup_palette.cpp.

1071 {
1072 QAction *action = m_actionCollection->action("zoom_to_fit");
1073
1074 if (action) {
1075 action->trigger();
1076 }
1077
1078 // sync zoom slider
1080}

References KisKActionCollection::action(), m_actionCollection, m_coordinatesConverter, zoomCanvasSlider, and KoZoomHandler::zoomInPercent().

◆ slotRemoveMirrorPos

void KisPopupPalette::slotRemoveMirrorPos ( )
privateslot

Definition at line 1085 of file kis_popup_palette.cpp.

1085 {
1086 m_actionCollection->action("mirror_canvas_around_cursor")->setProperty("customPosition", QVariant());
1087}

References KisKActionCollection::action(), and m_actionCollection.

◆ slotSetMirrorPos

void KisPopupPalette::slotSetMirrorPos ( )
privateslot

Definition at line 1082 of file kis_popup_palette.cpp.

1082 {
1083 m_actionCollection->action("mirror_canvas_around_cursor")->setProperty("customPosition", QVariant(m_mirrorPos));
1084}

References KisKActionCollection::action(), m_actionCollection, and m_mirrorPos.

◆ slotSetSelectedColor

void KisPopupPalette::slotSetSelectedColor ( int x)
inlineprivateslot

Definition at line 201 of file kis_popup_palette.h.

201{ setSelectedColor(x); update(); }

References setSelectedColor().

◆ slotShowTagsPopup

void KisPopupPalette::slotShowTagsPopup ( )
privateslot

Definition at line 1024 of file kis_popup_palette.cpp.

1025{
1027 QVector<QString> tags;
1028 for (int i = 0; i < model.rowCount(); ++i) {
1029 QModelIndex idx = model.index(i, 0);
1030 tags << model.data(idx, Qt::DisplayRole).toString();
1031 }
1032
1033 //std::sort(tags.begin(), tags.end());
1034
1035 if (!tags.isEmpty()) {
1036 QMenu menu;
1037 Q_FOREACH (const QString& tag, tags) {
1038 menu.addAction(tag)->setData(tag);
1039 }
1040
1041 QAction *action = menu.exec(QCursor::pos());
1042 if (action) {
1043
1044 for (int i = 0; i < model.rowCount(); ++i) {
1045 QModelIndex idx = model.index(i, 0);
1046 if (model.data(idx, Qt::DisplayRole).toString() == action->data()) {
1047 m_resourceManager->setCurrentTag(model.tagForIndex(idx));
1048 reconfigure();
1049 break;
1050 }
1051 }
1052 }
1053 } else {
1054 QWhatsThis::showText(QCursor::pos(),
1055 i18n("There are no tags available to show in this popup. To add presets, you need to tag them and then select the tag here."));
1056 }
1057
1058}
const QString PaintOpPresets

References m_resourceManager, ResourceType::PaintOpPresets, reconfigure(), KisFavoriteResourceManager::setCurrentTag(), and KisTagModel::tagForIndex().

◆ slotUpdate

◆ slotUpdateIcons

void KisPopupPalette::slotUpdateIcons ( )
slot

Definition at line 521 of file kis_popup_palette.cpp.

522{
523 this->setPalette(qApp->palette());
524
525 for(int i=0; i<this->children().size(); i++) {
526 QWidget *w = qobject_cast<QWidget*>(this->children().at(i));
527 if (w) {
528 w->setPalette(qApp->palette());
529 }
530 }
531 zoomToOneHundredPercentButton->setIcon(m_actionCollection->action("zoom_to_100pct")->icon());
532 fitToViewButton->setIcon(m_actionCollection->action("zoom_to_fit")->icon());
534 m_tagsButton->setIcon(KisIconUtils::loadIcon("tag"));
535 m_clearColorHistoryButton->setIcon(KisIconUtils::loadIcon("reload-preset-16"));
538}
void slotUpdateIcons()
void setOnOffIcons(const QIcon &on, const QIcon &off)
QIcon loadIcon(const QString &name)

References KisKActionCollection::action(), fitToViewButton, KisIconUtils::loadIcon(), m_actionCollection, m_bottomBarButton, m_clearColorHistoryButton, m_dockerHud, m_dockerHudButton, m_tagsButton, KisRoundHudButton::setOnOffIcons(), KisDockerHud::slotUpdateIcons(), and zoomToOneHundredPercentButton.

◆ slotZoomSliderChanged

void KisPopupPalette::slotZoomSliderChanged ( int zoom)
privateslot

Definition at line 507 of file kis_popup_palette.cpp.

507 {
508 Q_EMIT zoomLevelChanged(zoom);
509}
void zoomLevelChanged(int)

References zoomLevelChanged().

◆ slotZoomSliderPressed

void KisPopupPalette::slotZoomSliderPressed ( )
privateslot

Definition at line 511 of file kis_popup_palette.cpp.

512{
513 m_isZoomingCanvas = true;
514}

References m_isZoomingCanvas.

◆ slotZoomSliderReleased

void KisPopupPalette::slotZoomSliderReleased ( )
privateslot

Definition at line 516 of file kis_popup_palette.cpp.

517{
518 m_isZoomingCanvas = false;
519}

References m_isZoomingCanvas.

◆ slotZoomToOneHundredPercentClicked

void KisPopupPalette::slotZoomToOneHundredPercentClicked ( )
privateslot

Definition at line 1060 of file kis_popup_palette.cpp.

1060 {
1061 QAction *action = m_actionCollection->action("zoom_to_100pct");
1062
1063 if (action) {
1064 action->trigger();
1065 }
1066
1067 // also move the zoom slider to 100% position so they are in sync
1068 zoomCanvasSlider->setValue(100);
1069}

References KisKActionCollection::action(), m_actionCollection, and zoomCanvasSlider.

◆ tabletEvent()

void KisPopupPalette::tabletEvent ( QTabletEvent * event)
overrideprotected

Definition at line 1150 of file kis_popup_palette.cpp.

1151{
1152 event->ignore();
1153
1154 if (this->windowHandle()) {
1155#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1156 const QPointF localPos = event->posF();
1157#else
1158 const QPointF localPos = event->position();
1159#endif
1160
1161 if (event->type() == QEvent::TabletRelease && !QRectF(rect()).contains(localPos)) {
1162 event->accept();
1163 Q_EMIT finished();
1164 return;
1165 }
1166 }
1167}

References finished().

◆ zoomLevelChanged

void KisPopupPalette::zoomLevelChanged ( int )
signal

Member Data Documentation

◆ canvasOnlyButton

KisHighlightedToolButton* KisPopupPalette::canvasOnlyButton {0}
private

Definition at line 169 of file kis_popup_palette.h.

169{0};

◆ fitToViewButton

QPushButton* KisPopupPalette::fitToViewButton {0}
private

Definition at line 171 of file kis_popup_palette.h.

171{0};

◆ m_actionCollection

KisKActionCollection* KisPopupPalette::m_actionCollection
private

Definition at line 144 of file kis_popup_palette.h.

◆ m_actionManager

KisActionManager* KisPopupPalette::m_actionManager
private

Definition at line 139 of file kis_popup_palette.h.

◆ m_acyclicConnector

KisAcyclicSignalConnector* KisPopupPalette::m_acyclicConnector = 0
private

Definition at line 175 of file kis_popup_palette.h.

◆ m_bottomBarButton

KisRoundHudButton* KisPopupPalette::m_bottomBarButton {0}
private

Definition at line 159 of file kis_popup_palette.h.

159{0};

◆ m_bottomBarWidget

QWidget* KisPopupPalette::m_bottomBarWidget {0}
private

Definition at line 148 of file kis_popup_palette.h.

148{0};

◆ m_cachedPresetLayout

CachedPresetLayout KisPopupPalette::m_cachedPresetLayout
private

Definition at line 177 of file kis_popup_palette.h.

◆ m_canvasRotationIndicatorRect

QRectF KisPopupPalette::m_canvasRotationIndicatorRect
private

Definition at line 161 of file kis_popup_palette.h.

◆ m_clearColorHistoryButton

KisRoundHudButton* KisPopupPalette::m_clearColorHistoryButton {0}
private

Definition at line 157 of file kis_popup_palette.h.

157{0};

◆ m_clicksEater

KisMouseClickEater* KisPopupPalette::m_clicksEater
private

Definition at line 181 of file kis_popup_palette.h.

◆ m_colorChangeCompressor

QScopedPointer<KisSignalCompressor> KisPopupPalette::m_colorChangeCompressor
private

Definition at line 143 of file kis_popup_palette.h.

◆ m_colorHistoryInnerRadius

qreal KisPopupPalette::m_colorHistoryInnerRadius {72.0}
private

Definition at line 150 of file kis_popup_palette.h.

150{72.0};

◆ m_colorHistoryOuterRadius

qreal KisPopupPalette::m_colorHistoryOuterRadius {92.0}
private

Definition at line 151 of file kis_popup_palette.h.

151{92.0};

◆ m_colorSelector

KisColorSelectorInterface* KisPopupPalette::m_colorSelector {0}
private

Definition at line 141 of file kis_popup_palette.h.

141{0};

◆ m_coordinatesConverter

KisCoordinatesConverter* KisPopupPalette::m_coordinatesConverter
private

Definition at line 136 of file kis_popup_palette.h.

◆ m_displayRenderer

const KoColorDisplayRendererInterface* KisPopupPalette::m_displayRenderer
private

Definition at line 142 of file kis_popup_palette.h.

◆ m_dockerHud

KisDockerHud* KisPopupPalette::m_dockerHud {0}
private

Definition at line 147 of file kis_popup_palette.h.

147{0};

◆ m_dockerHudButton

KisRoundHudButton* KisPopupPalette::m_dockerHudButton {0}
private

Definition at line 160 of file kis_popup_palette.h.

160{0};

◆ m_hoveredColor

int KisPopupPalette::m_hoveredColor {0}
private

Definition at line 126 of file kis_popup_palette.h.

126{0};

◆ m_hoveredPreset

int KisPopupPalette::m_hoveredPreset {0}
private

Definition at line 124 of file kis_popup_palette.h.

124{0};

◆ m_isOverCanvasRotationIndicator

bool KisPopupPalette::m_isOverCanvasRotationIndicator {false}
private

Definition at line 163 of file kis_popup_palette.h.

163{false};

◆ m_isOverFgBgColors

bool KisPopupPalette::m_isOverFgBgColors {false}
private

Definition at line 129 of file kis_popup_palette.h.

129{false};

◆ m_isOverResetCanvasRotationIndicator

bool KisPopupPalette::m_isOverResetCanvasRotationIndicator {false}
private

Definition at line 164 of file kis_popup_palette.h.

164{false};

◆ m_isRotatingCanvasIndicator

bool KisPopupPalette::m_isRotatingCanvasIndicator {false}
private

Definition at line 165 of file kis_popup_palette.h.

165{false};

◆ m_isZoomingCanvas

bool KisPopupPalette::m_isZoomingCanvas {false}
private

Definition at line 166 of file kis_popup_palette.h.

166{false};

◆ m_mainArea

QSpacerItem* KisPopupPalette::m_mainArea {0}
private

Definition at line 146 of file kis_popup_palette.h.

146{0};

◆ m_maxPresetSlotCount

int KisPopupPalette::m_maxPresetSlotCount {10}
private

Definition at line 122 of file kis_popup_palette.h.

122{10};

◆ m_mirrorPos

QPoint KisPopupPalette::m_mirrorPos {}
private

Definition at line 121 of file kis_popup_palette.h.

121{};

◆ m_popupPaletteSize

qreal KisPopupPalette::m_popupPaletteSize {385.0}
private

Definition at line 149 of file kis_popup_palette.h.

149{385.0};

◆ m_presetRingMargin

qreal KisPopupPalette::m_presetRingMargin {3.0}
private

Definition at line 155 of file kis_popup_palette.h.

155{3.0};

◆ m_presetSlotCount

int KisPopupPalette::m_presetSlotCount {10}
private

Definition at line 123 of file kis_popup_palette.h.

123{10};

◆ m_resetCanvasRotationIndicatorRect

QRectF KisPopupPalette::m_resetCanvasRotationIndicatorRect
private

Definition at line 162 of file kis_popup_palette.h.

◆ m_resourceManager

KisFavoriteResourceManager* KisPopupPalette::m_resourceManager
private

Definition at line 140 of file kis_popup_palette.h.

◆ m_rotationSnapAngle

qreal KisPopupPalette::m_rotationSnapAngle {0}
private

Definition at line 131 of file kis_popup_palette.h.

131{0};

◆ m_rotationTrackSize

qreal KisPopupPalette::m_rotationTrackSize {18.0}
private

Definition at line 153 of file kis_popup_palette.h.

153{18.0};

◆ m_selectedColor

int KisPopupPalette::m_selectedColor {0}
private

Definition at line 127 of file kis_popup_palette.h.

127{0};

◆ m_showColorHistory

bool KisPopupPalette::m_showColorHistory {true}
private

Definition at line 152 of file kis_popup_palette.h.

152{true};

◆ m_showRotationTrack

bool KisPopupPalette::m_showRotationTrack {true}
private

Definition at line 154 of file kis_popup_palette.h.

154{true};

◆ m_snapLines

std::array<QLineF, 24> KisPopupPalette::m_snapLines {}
private

Definition at line 134 of file kis_popup_palette.h.

134{};

◆ m_snapRadius

qreal KisPopupPalette::m_snapRadius {15}
private

Definition at line 132 of file kis_popup_palette.h.

132{15};

◆ m_snapRects

std::array<QRect, 24> KisPopupPalette::m_snapRects {}
private

Definition at line 133 of file kis_popup_palette.h.

133{};

◆ m_snapRotation

bool KisPopupPalette::m_snapRotation {false}
private

Definition at line 130 of file kis_popup_palette.h.

130{false};

◆ m_tagsButton

KisRoundHudButton* KisPopupPalette::m_tagsButton {0}
private

Definition at line 158 of file kis_popup_palette.h.

158{0};

◆ m_touchBeginReceived

bool KisPopupPalette::m_touchBeginReceived {false}
private

Definition at line 128 of file kis_popup_palette.h.

128{false};

◆ m_useDynamicSlotCount

bool KisPopupPalette::m_useDynamicSlotCount {true}
private

Definition at line 125 of file kis_popup_palette.h.

125{true};

◆ m_viewManager

KisViewManager* KisPopupPalette::m_viewManager
private

Definition at line 138 of file kis_popup_palette.h.

◆ mirrorMode

KisHighlightedToolButton* KisPopupPalette::mirrorMode {0}
private

Definition at line 168 of file kis_popup_palette.h.

168{0};

◆ opacityChange

QGraphicsOpacityEffect* KisPopupPalette::opacityChange {0}
private

Definition at line 180 of file kis_popup_palette.h.

180{0};

◆ zoomCanvasSlider

QSlider* KisPopupPalette::zoomCanvasSlider {0}
private

Definition at line 172 of file kis_popup_palette.h.

172{0};

◆ zoomSliderMaxValue

int KisPopupPalette::zoomSliderMaxValue {200}
private

Definition at line 174 of file kis_popup_palette.h.

174{200};

◆ zoomSliderMinValue

int KisPopupPalette::zoomSliderMinValue {10}
private

Definition at line 173 of file kis_popup_palette.h.

173{10};

◆ zoomToOneHundredPercentButton

QPushButton* KisPopupPalette::zoomToOneHundredPercentButton {0}
private

Definition at line 170 of file kis_popup_palette.h.

170{0};

Property Documentation

◆ hoveredColor

int KisPopupPalette::hoveredColor
readwrite

Definition at line 51 of file kis_popup_palette.h.

◆ hoveredPreset

int KisPopupPalette::hoveredPreset
readwrite

Definition at line 50 of file kis_popup_palette.h.

◆ selectedColor

int KisPopupPalette::selectedColor
readwrite

Definition at line 52 of file kis_popup_palette.h.


The documentation for this class was generated from the following files: