Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/src/duckstation-qt/colorpickerbutton.cpp
4802 views
1
// SPDX-FileCopyrightText: 2019-2025 Connor McLaughlin <[email protected]>
2
// SPDX-License-Identifier: CC-BY-NC-ND-4.0
3
4
#include "colorpickerbutton.h"
5
#include "qtutils.h"
6
7
#include <QtGui/QPainter>
8
#include <QtWidgets/QColorDialog>
9
#include <QtWidgets/QStyle>
10
#include <QtWidgets/QStyleOptionButton>
11
12
#include "moc_colorpickerbutton.cpp"
13
14
ColorPickerButton::ColorPickerButton(QWidget* parent) : QPushButton(parent)
15
{
16
connect(this, &QPushButton::clicked, this, &ColorPickerButton::onClicked);
17
}
18
19
u32 ColorPickerButton::color()
20
{
21
return m_color;
22
}
23
24
void ColorPickerButton::setColor(u32 rgb)
25
{
26
if (m_color == rgb)
27
return;
28
29
m_color = rgb;
30
update();
31
}
32
33
void ColorPickerButton::paintEvent(QPaintEvent* event)
34
{
35
Q_UNUSED(event);
36
37
QPainter painter(this);
38
QStyleOptionButton option;
39
option.initFrom(this);
40
41
if (isDown())
42
option.state |= QStyle::State_Sunken;
43
if (isDefault())
44
option.features |= QStyleOptionButton::DefaultButton;
45
46
// Get the content rect (area inside the border)
47
const QRect contentRect = style()->subElementRect(QStyle::SE_PushButtonContents, &option, this);
48
49
// Draw the button frame first (this includes the border but should not fill the interior)
50
style()->drawPrimitive(QStyle::PE_PanelButtonBevel, &option, &painter, this);
51
52
// Fill the content area with our custom color
53
painter.fillRect(contentRect, QColor::fromRgb(m_color));
54
55
// Draw the focus rectangle if needed
56
if (option.state & QStyle::State_HasFocus)
57
{
58
QStyleOptionFocusRect focusOption;
59
focusOption.initFrom(this);
60
focusOption.rect = style()->subElementRect(QStyle::SE_PushButtonFocusRect, &option, this);
61
style()->drawPrimitive(QStyle::PE_FrameFocusRect, &focusOption, &painter, this);
62
}
63
64
// Draw the button label (text/icon) on top
65
style()->drawControl(QStyle::CE_PushButtonLabel, &option, &painter, this);
66
}
67
68
void ColorPickerButton::onClicked()
69
{
70
const u32 red = (m_color >> 16) & 0xff;
71
const u32 green = (m_color >> 8) & 0xff;
72
const u32 blue = m_color & 0xff;
73
74
const QColor initial(QColor::fromRgb(red, green, blue));
75
const QColor selected(QColorDialog::getColor(initial, QtUtils::GetRootWidget(this), tr("Select LED Color")));
76
77
// QColorDialog returns Invalid on cancel, and apparently initial == Invalid is true...
78
if (!selected.isValid() || initial == selected)
79
return;
80
81
const u32 new_rgb = (static_cast<u32>(selected.red()) << 16) | (static_cast<u32>(selected.green()) << 8) |
82
static_cast<u32>(selected.blue());
83
m_color = new_rgb;
84
update();
85
emit colorChanged(new_rgb);
86
}
87
88