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 1223 of file kis_popup_palette.cpp.

1224{
1225 if (numColors < 1) {
1226 return -1;
1227 }
1228 // relative to palette center
1229 QPointF relPosition = position - QPointF(0.5 * m_popupPaletteSize, 0.5 * m_popupPaletteSize);
1230
1231 qreal angle = M_PI - qAtan2(relPosition.x(), relPosition.y()) + M_PI / numColors;
1232 angle = normalizeAngle(angle);
1233
1234 int index = floor(angle * numColors / (2 * M_PI));
1235 return qBound(0, index, numColors - 1);
1236}
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 1256 of file kis_popup_palette.cpp.

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

1574 {
1575 int i = 0;
1576 for (QRect &rect: m_snapRects) {
1577 QPointF point(drawPointOnAngle(i * 15, m_popupPaletteSize / 2 - BORDER_WIDTH - m_snapRadius/2));
1578 point += QPointF(m_popupPaletteSize / 2 - m_snapRadius, m_popupPaletteSize / 2 - m_snapRadius);
1579 rect = QRect(point.x(), point.y(), m_snapRadius*2, m_snapRadius*2);
1580 i++;
1581 }
1582 i = 0;
1583 for (QLineF &line: m_snapLines) {
1584 qreal penWidth = BORDER_WIDTH / 2;
1585 QPointF point1 = drawPointOnAngle(i * 15, m_popupPaletteSize / 2 - m_rotationTrackSize + penWidth);
1586 point1 += QPointF(m_popupPaletteSize / 2, m_popupPaletteSize / 2);
1587 QPointF point2 = drawPointOnAngle(i * 15, m_popupPaletteSize / 2 - BORDER_WIDTH - penWidth);
1588 point2 += QPointF(m_popupPaletteSize / 2, m_popupPaletteSize / 2);
1589 line = QLineF(point1, point2);
1590 i++;
1591 }
1592}
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 1517 of file kis_popup_palette.cpp.

1518{
1519 // how many degrees each slice will get
1520 // if the slot count is 1, we must divide by 2 to get 180 for the algorithm to work
1521 qreal angleSlice = 360.0 / qMax(m_presetSlotCount, 2);
1522 // the starting angle of the slice we need to draw. the negative sign makes us go clockwise.
1523 // adding 90 degrees makes us start at the top. otherwise we would start at the right
1524 qreal startingAngle = -(index * angleSlice) + 90;
1526 qreal radius = m_cachedPresetLayout.firstRowRadius;
1528 case 1: break;
1529 case 2: {
1530 angleSlice = 180.0/((m_presetSlotCount+1) / 2);
1531 startingAngle = -(index * angleSlice) + 90;
1532
1533 if (index % 2) {
1536 }
1537 break;
1538 }
1539 case 3: {
1540 int triplet = index / 3;
1541 angleSlice = 180.0 / ((m_presetSlotCount + 2) / 3);
1542 switch (index % 3) {
1543 case 0:
1544 startingAngle = -(triplet * 2 * angleSlice) + 90;
1547 break;
1548 case 1:
1549 startingAngle = -(triplet * 2 * angleSlice) + 90;
1552 break;
1553 case 2:
1554 startingAngle = -((triplet * 2 + 1) * angleSlice) + 90;
1557 break;
1558 default:
1559 KIS_ASSERT(false);
1560 }
1561 break;
1562 }
1563 default:
1565 }
1566 QPainterPath path;
1567 qreal pathX = length * qCos(qDegreesToRadians(startingAngle)) - radius;
1568 qreal pathY = -(length) * qSin(qDegreesToRadians(startingAngle)) - radius;
1569 qreal pathDiameter = 2 * radius; // distance is used to calculate the X/Y in addition to the preset circle size
1570 path.addEllipse(pathX, pathY, pathDiameter, pathDiameter);
1571 return path;
1572}
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 1246 of file kis_popup_palette.cpp.

1247{
1248 QPointF p(
1249 // -90 so it starts at the top since this is mainly used by calculatePresetLayout
1250 radius * qCos(qDegreesToRadians(angle - 90)),
1251 radius * qSin(qDegreesToRadians(angle - 90))
1252 );
1253 return p;
1254}
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 1594 of file kis_popup_palette.cpp.

1595{
1596 QPointF adjustedPoint = position - QPointF(m_popupPaletteSize/2, m_popupPaletteSize/2);
1597 for (int i = 0; i < m_presetSlotCount; i++) {
1598 if (createPathFromPresetIndex(i).contains(adjustedPoint)) {
1599 return i;
1600 }
1601 }
1602 return -1;
1603}
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 1238 of file kis_popup_palette.cpp.

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

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 1172 of file kis_popup_palette.cpp.

1173{
1174 QPointF point = event->localPos();
1175 event->accept();
1176
1180#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1181 const QPointF localPos = event->localPos();
1182#else
1183 const QPointF localPos = event->position();
1184#endif
1185
1186 if (this->windowHandle() && !QRectF(rect()).contains(localPos)) {
1187 Q_EMIT finished();
1188 return;
1189 }
1190
1192 update();
1193 }
1194
1196
1197 if (event->button() == Qt::LeftButton) {
1198 if (m_isOverFgBgColors) {
1200 }
1201
1202 //in favorite brushes area
1203 if (hoveredPreset() > -1) {
1204 //setSelectedBrush(hoveredBrush());
1206 }
1207
1208 if (m_showColorHistory) {
1210 if (pathColor.contains(point)) {
1212
1213 if (pos >= 0 && pos < m_resourceManager->recentColorsTotal()) {
1214 Q_EMIT sigUpdateRecentColor(pos);
1215 }
1216 }
1217 }
1218 } else if (event->button() == Qt::RightButton) {
1219 Q_EMIT finished();
1220 }
1221}

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{
1137 // Ensure that the palette is always on top of all other canvas children
1138 raise();
1139
1141
1142 // don't set the zoom slider if we are outside of the zoom slider bounds. It will change the zoom level to within
1143 // the bounds and cause the canvas to jump between the slider's min and max
1147 zoomCanvasSlider->setValue(m_coordinatesConverter->zoomInPercent()); // sync the zoom slider
1148 }
1149
1150 QWidget::showEvent(event);
1151}

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 1153 of file kis_popup_palette.cpp.

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

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: