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}
 
bool m_tabletRightClickPressed {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 1202 of file kis_popup_palette.cpp.

1203{
1204 if (numColors < 1) {
1205 return -1;
1206 }
1207 // relative to palette center
1208 QPointF relPosition = position - QPointF(0.5 * m_popupPaletteSize, 0.5 * m_popupPaletteSize);
1209
1210 qreal angle = M_PI - qAtan2(relPosition.x(), relPosition.y()) + M_PI / numColors;
1211 angle = normalizeAngle(angle);
1212
1213 int index = floor(angle * numColors / (2 * M_PI));
1214 return qBound(0, index, numColors - 1);
1215}
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 1235 of file kis_popup_palette.cpp.

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

1553 {
1554 int i = 0;
1555 for (QRect &rect: m_snapRects) {
1556 QPointF point(drawPointOnAngle(i * 15, m_popupPaletteSize / 2 - BORDER_WIDTH - m_snapRadius/2));
1557 point += QPointF(m_popupPaletteSize / 2 - m_snapRadius, m_popupPaletteSize / 2 - m_snapRadius);
1558 rect = QRect(point.x(), point.y(), m_snapRadius*2, m_snapRadius*2);
1559 i++;
1560 }
1561 i = 0;
1562 for (QLineF &line: m_snapLines) {
1563 qreal penWidth = BORDER_WIDTH / 2;
1564 QPointF point1 = drawPointOnAngle(i * 15, m_popupPaletteSize / 2 - m_rotationTrackSize + penWidth);
1565 point1 += QPointF(m_popupPaletteSize / 2, m_popupPaletteSize / 2);
1566 QPointF point2 = drawPointOnAngle(i * 15, m_popupPaletteSize / 2 - BORDER_WIDTH - penWidth);
1567 point2 += QPointF(m_popupPaletteSize / 2, m_popupPaletteSize / 2);
1568 line = QLineF(point1, point2);
1569 i++;
1570 }
1571}
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 1496 of file kis_popup_palette.cpp.

1497{
1498 // how many degrees each slice will get
1499 // if the slot count is 1, we must divide by 2 to get 180 for the algorithm to work
1500 qreal angleSlice = 360.0 / qMax(m_presetSlotCount, 2);
1501 // the starting angle of the slice we need to draw. the negative sign makes us go clockwise.
1502 // adding 90 degrees makes us start at the top. otherwise we would start at the right
1503 qreal startingAngle = -(index * angleSlice) + 90;
1505 qreal radius = m_cachedPresetLayout.firstRowRadius;
1507 case 1: break;
1508 case 2: {
1509 angleSlice = 180.0/((m_presetSlotCount+1) / 2);
1510 startingAngle = -(index * angleSlice) + 90;
1511
1512 if (index % 2) {
1515 }
1516 break;
1517 }
1518 case 3: {
1519 int triplet = index / 3;
1520 angleSlice = 180.0 / ((m_presetSlotCount + 2) / 3);
1521 switch (index % 3) {
1522 case 0:
1523 startingAngle = -(triplet * 2 * angleSlice) + 90;
1526 break;
1527 case 1:
1528 startingAngle = -(triplet * 2 * angleSlice) + 90;
1531 break;
1532 case 2:
1533 startingAngle = -((triplet * 2 + 1) * angleSlice) + 90;
1536 break;
1537 default:
1538 KIS_ASSERT(false);
1539 }
1540 break;
1541 }
1542 default:
1544 }
1545 QPainterPath path;
1546 qreal pathX = length * qCos(qDegreesToRadians(startingAngle)) - radius;
1547 qreal pathY = -(length) * qSin(qDegreesToRadians(startingAngle)) - radius;
1548 qreal pathDiameter = 2 * radius; // distance is used to calculate the X/Y in addition to the preset circle size
1549 path.addEllipse(pathX, pathY, pathDiameter, pathDiameter);
1550 return path;
1551}
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 1089 of file kis_popup_palette.cpp.

1090{
1091 setVisible(false);
1092}

◆ drawDonutPathAngle()

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

Definition at line 790 of file kis_popup_palette.cpp.

791{
792 QPainterPath path;
793 path.moveTo(-0.999 * outer_radius * sin(M_PI / limit), 0.999 * outer_radius * cos(M_PI / limit));
794 path.arcTo(-1 * outer_radius, -1 * outer_radius, 2 * outer_radius, 2 * outer_radius, -90.0 - 180.0 / limit,
795 360.0 / limit);
796 path.arcTo(-1 * inner_radius, -1 * inner_radius, 2 * inner_radius, 2 * inner_radius, -90.0 + 180.0 / limit,
797 - 360.0 / limit);
798 path.closeSubpath();
799
800 return path;
801}

References M_PI.

◆ drawDonutPathFull()

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

Definition at line 780 of file kis_popup_palette.cpp.

781{
782 QPainterPath path;
783 path.addEllipse(QPointF(x, y), outer_radius, outer_radius);
784 path.addEllipse(QPointF(x, y), inner_radius, inner_radius);
785 path.setFillRule(Qt::OddEvenFill);
786
787 return path;
788}

◆ drawFgBgColorIndicator()

QPainterPath KisPopupPalette::drawFgBgColorIndicator ( int type) const
private

Definition at line 803 of file kis_popup_palette.cpp.

804{
805 QPointF edgePoint = QPointF(0.14645, 0.14645) * (m_popupPaletteSize);
806
807 // the points are really (-5, 15) and (5, 15) shifted right 1px
808 // 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
809 QPainterPath indicator;
810 switch (type) {
811 case 0: { // background
812 indicator.addEllipse(edgePoint + QPointF(-4, 15), 30, 30);
813 break;
814 }
815 case 1: { //foreground
816 indicator.addEllipse(edgePoint + QPointF(6, -15), 30, 30);
817 break;
818 }
819 }
820 return indicator;
821}

References m_popupPaletteSize.

◆ drawPointOnAngle()

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

Definition at line 1225 of file kis_popup_palette.cpp.

1226{
1227 QPointF p(
1228 // -90 so it starts at the top since this is mainly used by calculatePresetLayout
1229 radius * qCos(qDegreesToRadians(angle - 90)),
1230 radius * qSin(qDegreesToRadians(angle - 90))
1231 );
1232 return p;
1233}
const Params2D p

References p.

◆ ensureWithinParent()

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

Definition at line 1099 of file kis_popup_palette.cpp.

1099 {
1100 if (isVisible()) {
1101 const QSize paletteSize = geometry().size();
1102 const QPoint paletteCenterOffset(paletteSize.width() / 2, paletteSize.height() / 2);
1103
1104 QPoint paletteGlobalPos = globalPos;
1105 if (!useUpperLeft) {
1106 paletteGlobalPos -= paletteCenterOffset;
1107 }
1108
1109 if (parentWidget()) {
1110 const qreal widgetMargin = -20.0;
1111
1112 const QPoint paletteParentPos = parentWidget()->mapFromGlobal(paletteGlobalPos);
1113 QRect paletteParentRect(paletteParentPos, paletteSize);
1114
1115 const QRect fitRect = kisGrowRect(parentWidget()->rect(), widgetMargin);
1116 paletteParentRect = kisEnsureInRect(paletteParentRect, fitRect);
1117 paletteGlobalPos = parentWidget()->mapToGlobal(paletteParentRect.topLeft());
1118 }
1119
1120
1121 const QPoint moveToPoint = this->windowHandle() ? paletteGlobalPos : parentWidget()->mapFromGlobal(paletteGlobalPos);
1122
1123 move(moveToPoint);
1124 }
1125}
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 984 of file kis_popup_palette.cpp.

985{
986 switch (event->type()) {
987 case QEvent::TouchBegin:
989 break;
990 case QEvent::MouseButtonPress:
991 case QEvent::MouseMove:
992 // HACK(sh_zam): Let's say the tap gesture is used by the canvas to launch the popup. Following that, a
993 // synthesized mousePress is sent and this arrives in our event filter here. But, this event was meant for the
994 // canvas (even though it blocks it), so we only act on the event if we got a TouchBegin on it first.
995 if (static_cast<QMouseEvent *>(event)->source() == Qt::MouseEventSynthesizedBySystem && !m_touchBeginReceived) {
996 event->accept();
997 return true;
998 }
999 break;
1000 case QEvent::MouseButtonRelease:
1001 if (static_cast<QMouseEvent *>(event)->source() == Qt::MouseEventSynthesizedBySystem && !m_touchBeginReceived) {
1002 event->accept();
1003 return true;
1004 }
1005 // fallthrough
1006 case QEvent::Show:
1007 case QEvent::FocusOut:
1008 m_touchBeginReceived = false;
1009 break;
1010 default:
1011 break;
1012 }
1013 return false;
1014}
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 1573 of file kis_popup_palette.cpp.

1574{
1575 QPointF adjustedPoint = position - QPointF(m_popupPaletteSize/2, m_popupPaletteSize/2);
1576 for (int i = 0; i < m_presetSlotCount; i++) {
1577 if (createPathFromPresetIndex(i).contains(adjustedPoint)) {
1578 return i;
1579 }
1580 }
1581 return -1;
1582}
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 479 of file kis_popup_palette.cpp.

480{
481 return m_hoveredColor;
482}

References m_hoveredColor.

◆ hoveredPreset()

int KisPopupPalette::hoveredPreset ( ) const
protected

Definition at line 469 of file kis_popup_palette.cpp.

470{
471 return m_hoveredPreset;
472}

References m_hoveredPreset.

◆ isPointInPixmap()

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

Definition at line 1217 of file kis_popup_palette.cpp.

1218{
1219 if (createPathFromPresetIndex(pos).contains(point + QPointF(-m_popupPaletteSize / 2, -m_popupPaletteSize / 2))) {
1220 return true;
1221 }
1222 return false;
1223}

References createPathFromPresetIndex(), and m_popupPaletteSize.

◆ mouseMoveEvent()

void KisPopupPalette::mouseMoveEvent ( QMouseEvent * event)
overrideprotected

Definition at line 833 of file kis_popup_palette.cpp.

834{
835 QPointF point = event->localPos();
836 event->accept();
837
839 // check if mouse is over the canvas rotation knob
840 bool wasOverRotationIndicator = m_isOverCanvasRotationIndicator;
842 bool wasOverResetRotationIndicator = m_isOverResetCanvasRotationIndicator;
844
845 if (
846 wasOverRotationIndicator != m_isOverCanvasRotationIndicator ||
847 wasOverResetRotationIndicator != m_isOverResetCanvasRotationIndicator
848 ) {
849 update();
850 }
851
853 m_snapRotation = false;
854 int i = 0;
855 for (QRect &rect: m_snapRects) {
856 QPainterPath circle;
857 circle.addEllipse(rect);
858 if (circle.contains(point)) {
859 m_snapRotation = true;
860 m_rotationSnapAngle = i * 15;
861 break;
862 }
863 i++;
864 }
865 qreal finalAngle = 0.0;
866 if (m_snapRotation) {
867 finalAngle = m_rotationSnapAngle;
868 // to match the numbers displayed when rotating without snapping
869 if (finalAngle >= 270) {
870 finalAngle = finalAngle - 360;
871 }
872 } else {
873 // we are rotating the canvas, so calculate the rotation angle based off the center
874 // calculate the angle we are at first
875 QPoint widgetCenterPoint = QPoint(m_popupPaletteSize/2, m_popupPaletteSize/2);
876
877 qreal dX = point.x() - widgetCenterPoint.x();
878 qreal dY = point.y() - widgetCenterPoint.y();
879
880
881 finalAngle = qAtan2(dY,dX) * 180 / M_PI; // what we need if we have two points, but don't know the angle
882 finalAngle = finalAngle + 90; // add 90 degrees so 0 degree position points up
883 }
884 qreal angleDifference = finalAngle - m_coordinatesConverter->rotationAngle(); // the rotation function accepts diffs, so find it out
885
886 KisCanvasController *canvasController =
888 KIS_ASSERT_RECOVER_RETURN(canvasController);
889 canvasController->rotateCanvas(angleDifference);
891
892 update();
893 Q_EMIT sigUpdateCanvas();
894 }
895 }
896
897 if (m_isRotatingCanvasIndicator == false) {
898 QPainterPath bgColor(drawFgBgColorIndicator(0));
899 QPainterPath fgColor(drawFgBgColorIndicator(1));
900 QPainterPath backgroundContainer;
902 backgroundContainer.addEllipse(circleRect);
903
904 QPainterPath fgBgColors = (fgColor + bgColor) - backgroundContainer;
905
906 if (fgBgColors.contains(point)) {
907 if (!m_isOverFgBgColors) {
908 m_isOverFgBgColors = true;
909 setToolTip(i18n("Click to swap foreground and background colors.\nRight click to set to black and white."));
910 update();
911 }
912 } else {
913 if (m_isOverFgBgColors) {
914 m_isOverFgBgColors = false;
915 setToolTip(QString());
916 update();
917 }
918 }
919
921 if (colorHistoryPath.contains(point)) {
922 if (hoveredPreset() >= 0) {
923 setToolTip(QString());
925 }
926
928
929 if (pos != hoveredColor()) {
930 setHoveredColor(pos);
931 update();
932 }
933 }
934 else {
935 if (hoveredColor() >= 0) {
936 setHoveredColor(-1);
937 update();
938 }
939
940 int pos = findPresetSlot(point);
941
942 if (pos != hoveredPreset()) {
943
944 if (pos >= 0 && pos < m_resourceManager->numFavoritePresets()) {
945 setToolTip(m_resourceManager->favoritePresetNamesList().at(pos));
946 setHoveredPreset(pos);
947 }
948 else {
949 setToolTip(QString());
951 }
952
953 update();
954 }
955 }
956 }
957}
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 1151 of file kis_popup_palette.cpp.

1152{
1153 QPointF point = event->localPos();
1154 event->accept();
1155
1159#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1160 const QPointF localPos = event->localPos();
1161#else
1162 const QPointF localPos = event->position();
1163#endif
1164
1165 if (this->windowHandle() && !QRectF(rect()).contains(localPos)) {
1166 Q_EMIT finished();
1167 return;
1168 }
1169
1171 update();
1172 }
1173
1175
1176 if (event->button() == Qt::LeftButton) {
1177 if (m_isOverFgBgColors) {
1179 }
1180
1181 //in favorite brushes area
1182 if (hoveredPreset() > -1) {
1183 //setSelectedBrush(hoveredBrush());
1185 }
1186
1187 if (m_showColorHistory) {
1189 if (pathColor.contains(point)) {
1191
1192 if (pos >= 0 && pos < m_resourceManager->recentColorsTotal()) {
1193 Q_EMIT sigUpdateRecentColor(pos);
1194 }
1195 }
1196 }
1197 } else if (event->button() == Qt::RightButton) {
1198 Q_EMIT finished();
1199 }
1200}

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

1095{
1096 return isVisible();
1097}

◆ paintEvent()

void KisPopupPalette::paintEvent ( QPaintEvent * e)
overrideprotected

Definition at line 564 of file kis_popup_palette.cpp.

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

1081 {
1082 setVisible(true);
1083 KIS_SAFE_ASSERT_RECOVER_RETURN(parentWidget());
1084 const QPoint globalPos = parentWidget()->mapToGlobal(position);
1085 ensureWithinParent(globalPos, false);
1086 m_mirrorPos = QCursor::pos();
1087}
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
362 const int auxButtonSize = 35;
363 m_colorSelector->move(m_popupPaletteSize/2 - selectorRadius, m_popupPaletteSize/2 - selectorRadius);
365
366 // ellipse - to make sure the widget doesn't eat events meant for recent colors or brushes
367 // - needs to be +2 pixels on every side for anti-aliasing to look nice on high dpi displays
368 // rectangle - to make sure the area doesn't extend outside of the widget
369 QRegion maskedEllipse(-2, -2, m_colorSelector->width() + 4, m_colorSelector->height() + 4, QRegion::Ellipse );
370 QRegion maskedRectangle(0, 0, m_colorSelector->width(), m_colorSelector->height(), QRegion::Rectangle);
371 QRegion maskedRegion = maskedEllipse.intersected(maskedRectangle);
372
373 m_colorSelector->setMask(maskedRegion);
374
375 m_dockerHud->setFixedHeight(int(m_popupPaletteSize));
376
377 // arranges the buttons around the popup palette
378 // buttons are spread out from the center of the set arc length
379
380 // the margin in degrees between buttons
381 qreal margin = 10.0;
382 // visual center
383 qreal center = m_popupPaletteSize/2 - auxButtonSize/2.0;
384 qreal length = m_popupPaletteSize/2 + auxButtonSize/2.0 + 5;
385 {
386 int buttonCount = 2;
387 int arcLength = 90;
388 // note the int buttonCount/2 is on purpose
389 qreal start = arcLength/2 - (buttonCount/2) * margin;
390 if (buttonCount % 2 == 0) start += margin / 2;
391 int place = 0;
392 m_dockerHudButton->setGeometry(
393 center + qCos(qDegreesToRadians(start + place*margin))*length,
394 center + qSin(qDegreesToRadians(start + place*margin))*length,
395 auxButtonSize, auxButtonSize
396 );
397 place++;
398 m_bottomBarButton->setGeometry (
399 center + qCos(qDegreesToRadians(start + place*margin))*length,
400 center + qSin(qDegreesToRadians(start + place*margin))*length,
401 auxButtonSize, auxButtonSize
402 );
403 }
404 {
405 int buttonCount = m_showColorHistory ? 2 : 1 ;
406 int arcLength = 90;
407 int shiftArc = 90;
408 // note the int buttonCount/2 is on purpose
409 qreal start = shiftArc + arcLength / 2 - (buttonCount/2) * margin;
410 if (buttonCount % 2 == 0) start += margin / 2;
411 int place = 0;
412 if (m_showColorHistory) {
413 m_clearColorHistoryButton->setGeometry(
414 center + qCos(qDegreesToRadians(start + place * margin)) * length,
415 center + qSin(qDegreesToRadians(start + place * margin)) * length,
416 auxButtonSize, auxButtonSize);
417 place++;
418 }
419 m_tagsButton->setGeometry(
420 center + qCos(qDegreesToRadians(start + place*margin))*length,
421 center + qSin(qDegreesToRadians(start + place*margin))*length,
422 auxButtonSize, auxButtonSize
423 );
424 }
426}
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 762 of file kis_popup_palette.cpp.

762 {
763 Q_UNUSED(resizeEvent);
767 // Ensure that the resized geometry fits within the desired rect...
768
774 const QPoint globalTopLeft = windowHandle() ?
775 geometry().topLeft() :
776 parentWidget()->mapToGlobal(geometry().topLeft());
777 ensureWithinParent(globalTopLeft, true);
778}
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 823 of file kis_popup_palette.cpp.

824{
825 qreal paletteRadius = 0.5 * m_popupPaletteSize;
826 QPointF rotationDialPosition(drawPointOnAngle(rotationAngle, paletteRadius - 10));
827 rotationDialPosition += QPointF(paletteRadius, paletteRadius);
828
829 QPointF indicatorDiagonal(7.5, 7.5);
830 return QRectF(rotationDialPosition - indicatorDiagonal, rotationDialPosition + indicatorDiagonal);
831}

References drawPointOnAngle(), and m_popupPaletteSize.

◆ selectedColor()

int KisPopupPalette::selectedColor ( ) const

Definition at line 489 of file kis_popup_palette.cpp.

490{
491 return m_selectedColor;
492}

References m_selectedColor.

◆ setHoveredColor()

void KisPopupPalette::setHoveredColor ( int x)
protected

Definition at line 484 of file kis_popup_palette.cpp.

References m_hoveredColor.

◆ setHoveredPreset()

void KisPopupPalette::setHoveredPreset ( int x)
protected

Definition at line 474 of file kis_popup_palette.cpp.

475{
477}

References m_hoveredPreset.

◆ setParent()

void KisPopupPalette::setParent ( QWidget * parent)

Definition at line 552 of file kis_popup_palette.cpp.

552 {
553 QWidget::setParent(parent);
554}

◆ setSelectedColor()

void KisPopupPalette::setSelectedColor ( int x)

Definition at line 494 of file kis_popup_palette.cpp.

495{
497}

References m_selectedColor.

◆ showBottomBarWidget

void KisPopupPalette::showBottomBarWidget ( bool visible)
privateslot

Definition at line 542 of file kis_popup_palette.cpp.

543{
544 const bool reallyVisible = visible && m_bottomBarButton->isChecked();
545
546 m_bottomBarWidget->setVisible(reallyVisible);
547
548 KisConfig cfg(false);
549 cfg.setShowPaletteBottomBar(visible);
550}

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

◆ showEvent()

void KisPopupPalette::showEvent ( QShowEvent * event)
overrideprotected

Definition at line 1127 of file kis_popup_palette.cpp.

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

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

◆ showHudWidget

void KisPopupPalette::showHudWidget ( bool visible)
privateslot

Definition at line 532 of file kis_popup_palette.cpp.

533{
535 const bool reallyVisible = visible && m_dockerHudButton->isChecked();
536 m_dockerHud->setVisible(reallyVisible);
537
538 KisConfig cfg(false);
539 cfg.setShowBrushHud(visible);
540}
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 557 of file kis_popup_palette.cpp.

558{
559 // Note: the canvas popup widget system "abuses" the sizeHint to determine
560 // the position to show the widget; this does not reflect the true size.
562}

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

429{
430 // Visual Color Selector picks up color space from input
433 //hack to get around cmyk for now.
434 if (paintingCS->colorChannelCount()>3) {
435 paintingCS = KoColorSpaceRegistry::instance()->rgb8();
436 }
439}
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 448 of file kis_popup_palette.cpp.

449{
450 if (isVisible()) {
451 update();
453 }
454}

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

◆ slotExternalFgColorChanged

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

◆ slotFitToViewClicked

void KisPopupPalette::slotFitToViewClicked ( )
privateslot

Definition at line 1063 of file kis_popup_palette.cpp.

1063 {
1064 QAction *action = m_actionCollection->action("zoom_to_fit");
1065
1066 if (action) {
1067 action->trigger();
1068 }
1069
1070 // sync zoom slider
1072}

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

◆ slotRemoveMirrorPos

void KisPopupPalette::slotRemoveMirrorPos ( )
privateslot

Definition at line 1077 of file kis_popup_palette.cpp.

1077 {
1078 m_actionCollection->action("mirror_canvas_around_cursor")->setProperty("customPosition", QVariant());
1079}

References KisKActionCollection::action(), and m_actionCollection.

◆ slotSetMirrorPos

void KisPopupPalette::slotSetMirrorPos ( )
privateslot

Definition at line 1074 of file kis_popup_palette.cpp.

1074 {
1075 m_actionCollection->action("mirror_canvas_around_cursor")->setProperty("customPosition", QVariant(m_mirrorPos));
1076}

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

◆ slotSetSelectedColor

void KisPopupPalette::slotSetSelectedColor ( int x)
inlineprivateslot

Definition at line 202 of file kis_popup_palette.h.

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

References setSelectedColor().

◆ slotShowTagsPopup

void KisPopupPalette::slotShowTagsPopup ( )
privateslot

Definition at line 1016 of file kis_popup_palette.cpp.

1017{
1019 QVector<QString> tags;
1020 for (int i = 0; i < model.rowCount(); ++i) {
1021 QModelIndex idx = model.index(i, 0);
1022 tags << model.data(idx, Qt::DisplayRole).toString();
1023 }
1024
1025 //std::sort(tags.begin(), tags.end());
1026
1027 if (!tags.isEmpty()) {
1028 QMenu menu;
1029 Q_FOREACH (const QString& tag, tags) {
1030 menu.addAction(tag)->setData(tag);
1031 }
1032
1033 QAction *action = menu.exec(QCursor::pos());
1034 if (action) {
1035
1036 for (int i = 0; i < model.rowCount(); ++i) {
1037 QModelIndex idx = model.index(i, 0);
1038 if (model.data(idx, Qt::DisplayRole).toString() == action->data()) {
1039 m_resourceManager->setCurrentTag(model.tagForIndex(idx));
1040 reconfigure();
1041 break;
1042 }
1043 }
1044 }
1045 } else {
1046 QWhatsThis::showText(QCursor::pos(),
1047 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."));
1048 }
1049
1050}
const QString PaintOpPresets

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

◆ slotUpdate

◆ slotUpdateIcons

void KisPopupPalette::slotUpdateIcons ( )
slot

Definition at line 513 of file kis_popup_palette.cpp.

514{
515 this->setPalette(qApp->palette());
516
517 for(int i=0; i<this->children().size(); i++) {
518 QWidget *w = qobject_cast<QWidget*>(this->children().at(i));
519 if (w) {
520 w->setPalette(qApp->palette());
521 }
522 }
523 zoomToOneHundredPercentButton->setIcon(m_actionCollection->action("zoom_to_100pct")->icon());
524 fitToViewButton->setIcon(m_actionCollection->action("zoom_to_fit")->icon());
526 m_tagsButton->setIcon(KisIconUtils::loadIcon("tag"));
527 m_clearColorHistoryButton->setIcon(KisIconUtils::loadIcon("reload-preset-16"));
530}
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 499 of file kis_popup_palette.cpp.

499 {
500 Q_EMIT zoomLevelChanged(zoom);
501}
void zoomLevelChanged(int)

References zoomLevelChanged().

◆ slotZoomSliderPressed

void KisPopupPalette::slotZoomSliderPressed ( )
privateslot

Definition at line 503 of file kis_popup_palette.cpp.

504{
505 m_isZoomingCanvas = true;
506}

References m_isZoomingCanvas.

◆ slotZoomSliderReleased

void KisPopupPalette::slotZoomSliderReleased ( )
privateslot

Definition at line 508 of file kis_popup_palette.cpp.

509{
510 m_isZoomingCanvas = false;
511}

References m_isZoomingCanvas.

◆ slotZoomToOneHundredPercentClicked

void KisPopupPalette::slotZoomToOneHundredPercentClicked ( )
privateslot

Definition at line 1052 of file kis_popup_palette.cpp.

1052 {
1053 QAction *action = m_actionCollection->action("zoom_to_100pct");
1054
1055 if (action) {
1056 action->trigger();
1057 }
1058
1059 // also move the zoom slider to 100% position so they are in sync
1060 zoomCanvasSlider->setValue(100);
1061}

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

◆ tabletEvent()

void KisPopupPalette::tabletEvent ( QTabletEvent * event)
overrideprotected

Definition at line 1142 of file kis_popup_palette.cpp.

1143{
1144 if (event->button() == Qt::RightButton && event->type() == QEvent::TabletPress) {
1146 }
1147
1148 event->ignore();
1149}

References m_tabletRightClickPressed.

◆ zoomLevelChanged

void KisPopupPalette::zoomLevelChanged ( int )
signal

Member Data Documentation

◆ canvasOnlyButton

KisHighlightedToolButton* KisPopupPalette::canvasOnlyButton {0}
private

Definition at line 170 of file kis_popup_palette.h.

170{0};

◆ fitToViewButton

QPushButton* KisPopupPalette::fitToViewButton {0}
private

Definition at line 172 of file kis_popup_palette.h.

172{0};

◆ m_actionCollection

KisKActionCollection* KisPopupPalette::m_actionCollection
private

Definition at line 145 of file kis_popup_palette.h.

◆ m_actionManager

KisActionManager* KisPopupPalette::m_actionManager
private

Definition at line 140 of file kis_popup_palette.h.

◆ m_acyclicConnector

KisAcyclicSignalConnector* KisPopupPalette::m_acyclicConnector = 0
private

Definition at line 176 of file kis_popup_palette.h.

◆ m_bottomBarButton

KisRoundHudButton* KisPopupPalette::m_bottomBarButton {0}
private

Definition at line 160 of file kis_popup_palette.h.

160{0};

◆ m_bottomBarWidget

QWidget* KisPopupPalette::m_bottomBarWidget {0}
private

Definition at line 149 of file kis_popup_palette.h.

149{0};

◆ m_cachedPresetLayout

CachedPresetLayout KisPopupPalette::m_cachedPresetLayout
private

Definition at line 178 of file kis_popup_palette.h.

◆ m_canvasRotationIndicatorRect

QRectF KisPopupPalette::m_canvasRotationIndicatorRect
private

Definition at line 162 of file kis_popup_palette.h.

◆ m_clearColorHistoryButton

KisRoundHudButton* KisPopupPalette::m_clearColorHistoryButton {0}
private

Definition at line 158 of file kis_popup_palette.h.

158{0};

◆ m_clicksEater

KisMouseClickEater* KisPopupPalette::m_clicksEater
private

Definition at line 182 of file kis_popup_palette.h.

◆ m_colorChangeCompressor

QScopedPointer<KisSignalCompressor> KisPopupPalette::m_colorChangeCompressor
private

Definition at line 144 of file kis_popup_palette.h.

◆ m_colorHistoryInnerRadius

qreal KisPopupPalette::m_colorHistoryInnerRadius {72.0}
private

Definition at line 151 of file kis_popup_palette.h.

151{72.0};

◆ m_colorHistoryOuterRadius

qreal KisPopupPalette::m_colorHistoryOuterRadius {92.0}
private

Definition at line 152 of file kis_popup_palette.h.

152{92.0};

◆ m_colorSelector

KisColorSelectorInterface* KisPopupPalette::m_colorSelector {0}
private

Definition at line 142 of file kis_popup_palette.h.

142{0};

◆ m_coordinatesConverter

KisCoordinatesConverter* KisPopupPalette::m_coordinatesConverter
private

Definition at line 137 of file kis_popup_palette.h.

◆ m_displayRenderer

const KoColorDisplayRendererInterface* KisPopupPalette::m_displayRenderer
private

Definition at line 143 of file kis_popup_palette.h.

◆ m_dockerHud

KisDockerHud* KisPopupPalette::m_dockerHud {0}
private

Definition at line 148 of file kis_popup_palette.h.

148{0};

◆ m_dockerHudButton

KisRoundHudButton* KisPopupPalette::m_dockerHudButton {0}
private

Definition at line 161 of file kis_popup_palette.h.

161{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 164 of file kis_popup_palette.h.

164{false};

◆ m_isOverFgBgColors

bool KisPopupPalette::m_isOverFgBgColors {false}
private

Definition at line 130 of file kis_popup_palette.h.

130{false};

◆ m_isOverResetCanvasRotationIndicator

bool KisPopupPalette::m_isOverResetCanvasRotationIndicator {false}
private

Definition at line 165 of file kis_popup_palette.h.

165{false};

◆ m_isRotatingCanvasIndicator

bool KisPopupPalette::m_isRotatingCanvasIndicator {false}
private

Definition at line 166 of file kis_popup_palette.h.

166{false};

◆ m_isZoomingCanvas

bool KisPopupPalette::m_isZoomingCanvas {false}
private

Definition at line 167 of file kis_popup_palette.h.

167{false};

◆ m_mainArea

QSpacerItem* KisPopupPalette::m_mainArea {0}
private

Definition at line 147 of file kis_popup_palette.h.

147{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 150 of file kis_popup_palette.h.

150{385.0};

◆ m_presetRingMargin

qreal KisPopupPalette::m_presetRingMargin {3.0}
private

Definition at line 156 of file kis_popup_palette.h.

156{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 163 of file kis_popup_palette.h.

◆ m_resourceManager

KisFavoriteResourceManager* KisPopupPalette::m_resourceManager
private

Definition at line 141 of file kis_popup_palette.h.

◆ m_rotationSnapAngle

qreal KisPopupPalette::m_rotationSnapAngle {0}
private

Definition at line 132 of file kis_popup_palette.h.

132{0};

◆ m_rotationTrackSize

qreal KisPopupPalette::m_rotationTrackSize {18.0}
private

Definition at line 154 of file kis_popup_palette.h.

154{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 153 of file kis_popup_palette.h.

153{true};

◆ m_showRotationTrack

bool KisPopupPalette::m_showRotationTrack {true}
private

Definition at line 155 of file kis_popup_palette.h.

155{true};

◆ m_snapLines

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

Definition at line 135 of file kis_popup_palette.h.

135{};

◆ m_snapRadius

qreal KisPopupPalette::m_snapRadius {15}
private

Definition at line 133 of file kis_popup_palette.h.

133{15};

◆ m_snapRects

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

Definition at line 134 of file kis_popup_palette.h.

134{};

◆ m_snapRotation

bool KisPopupPalette::m_snapRotation {false}
private

Definition at line 131 of file kis_popup_palette.h.

131{false};

◆ m_tabletRightClickPressed

bool KisPopupPalette::m_tabletRightClickPressed {false}
private

Definition at line 128 of file kis_popup_palette.h.

128{false};

◆ m_tagsButton

KisRoundHudButton* KisPopupPalette::m_tagsButton {0}
private

Definition at line 159 of file kis_popup_palette.h.

159{0};

◆ m_touchBeginReceived

bool KisPopupPalette::m_touchBeginReceived {false}
private

Definition at line 129 of file kis_popup_palette.h.

129{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 139 of file kis_popup_palette.h.

◆ mirrorMode

KisHighlightedToolButton* KisPopupPalette::mirrorMode {0}
private

Definition at line 169 of file kis_popup_palette.h.

169{0};

◆ opacityChange

QGraphicsOpacityEffect* KisPopupPalette::opacityChange {0}
private

Definition at line 181 of file kis_popup_palette.h.

181{0};

◆ zoomCanvasSlider

QSlider* KisPopupPalette::zoomCanvasSlider {0}
private

Definition at line 173 of file kis_popup_palette.h.

173{0};

◆ zoomSliderMaxValue

int KisPopupPalette::zoomSliderMaxValue {200}
private

Definition at line 175 of file kis_popup_palette.h.

175{200};

◆ zoomSliderMinValue

int KisPopupPalette::zoomSliderMinValue {10}
private

Definition at line 174 of file kis_popup_palette.h.

174{10};

◆ zoomToOneHundredPercentButton

QPushButton* KisPopupPalette::zoomToOneHundredPercentButton {0}
private

Definition at line 171 of file kis_popup_palette.h.

171{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: