Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optional and opaque RGB colors #2472

Merged
merged 35 commits into from
Feb 10, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
5055657
Add RgbColor class
uklotzde Jan 29, 2020
a831e39
Add equality comparison operators
uklotzde Jan 29, 2020
2144b51
Add note about RgbColorCode vs. QRgb
uklotzde Jan 29, 2020
e3b5353
Add note about immutability
uklotzde Jan 29, 2020
cfd14f1
Add more documentation
uklotzde Jan 29, 2020
c657a9f
Use std::optional for color code conversions
uklotzde Jan 29, 2020
af1fdb1
Reduce variations of conversion operations
uklotzde Jan 29, 2020
7b6acf0
Declare Qt type information
uklotzde Jan 29, 2020
ef4ce69
Replace internal QColor with RgbColorCode
uklotzde Jan 29, 2020
cc2e262
Treat RgbColor as a POD
uklotzde Jan 29, 2020
a991d23
Register global meta type for RgbColor
uklotzde Jan 29, 2020
c298ab3
Fix build for ancient GCC version 5.4.0
uklotzde Jan 29, 2020
1b52a67
Update documentation
uklotzde Jan 30, 2020
cac064b
Replace isValid() with operator bool()
uklotzde Jan 30, 2020
3326c92
Prefer explicit conversion and fix various issues
uklotzde Jan 30, 2020
ec9a027
Remove constexpr
uklotzde Jan 30, 2020
30f203d
Fix type inference in tests
uklotzde Jan 30, 2020
b6f37c1
Add comment about use cases for this class
uklotzde Jan 30, 2020
3f4ca14
Split OptionalRgbColor from RgbColor
uklotzde Jan 30, 2020
d565a89
Use constexpr
uklotzde Jan 30, 2020
439b985
Fix typos in documentation
uklotzde Jan 31, 2020
6184663
Declare a Qt meta type for std::optional<mixxx::RgbColor>>
uklotzde Jan 31, 2020
666422c
Replace OptionalRgbColor with std::optional<RgbColor>
uklotzde Jan 31, 2020
bcf18b9
Remove obsolete validation
uklotzde Jan 31, 2020
5e41678
Add a debug assertion
uklotzde Jan 31, 2020
b31edfd
Move RgbColorCode typedef into RgbColor
uklotzde Jan 31, 2020
bc2fed7
Add missing constexpr
uklotzde Jan 31, 2020
a864454
Add comment about constexpr ctor
uklotzde Jan 31, 2020
18b6ffe
Implicitly validate color codes in RgbColor ctor
uklotzde Jan 31, 2020
fc6a36a
Update class documentation
uklotzde Jan 31, 2020
3df8889
Add debug output stream operators
uklotzde Jan 31, 2020
dc597b0
Fix invalid constexpr
uklotzde Jan 31, 2020
14a29f8
Add conversions from/to QVariant
uklotzde Jan 31, 2020
f6b781c
Run clang-format
uklotzde Feb 1, 2020
06d393e
Add missing RgbColor tests
uklotzde Feb 7, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Replace isValid() with operator bool()
  • Loading branch information
uklotzde committed Jan 30, 2020
commit cac064b66f9f5f69f6529a29d710c41f911b716f
32 changes: 16 additions & 16 deletions src/test/rgbcolor_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
namespace mixxx {

TEST(RgbColorTest, DefaultIsInvalid) {
EXPECT_FALSE(RgbColor().isValid());
EXPECT_FALSE(RgbColor());
EXPECT_FALSE(RgbColor().optionalCode());
}

Expand All @@ -25,41 +25,41 @@ TEST(RgbColorTest, RgbColorCodeCtor) {
}

TEST(RgbColorTest, QColorCtor) {
EXPECT_TRUE(RgbColor(QColor::fromRgb(0x000000)).isValid());
EXPECT_TRUE(RgbColor(QColor::fromRgb(0x000000)));
EXPECT_EQ(0x000000, *RgbColor(QColor::fromRgb(0x000000)).optionalCode());
EXPECT_TRUE(RgbColor(QColor::fromRgb(0xFF0000)).isValid());
EXPECT_TRUE(RgbColor(QColor::fromRgb(0xFF0000)));
EXPECT_EQ(0xFF0000, *RgbColor(QColor::fromRgb(0xFF0000)).optionalCode());
EXPECT_TRUE(RgbColor(QColor::fromRgb(0x00FF00)).isValid());
EXPECT_TRUE(RgbColor(QColor::fromRgb(0x00FF00)));
EXPECT_EQ(0x00FF00, *RgbColor(QColor::fromRgb(0x00FF00)).optionalCode());
EXPECT_TRUE(RgbColor(QColor::fromRgb(0x0000FF)).isValid());
EXPECT_TRUE(RgbColor(QColor::fromRgb(0x0000FF)));
EXPECT_EQ(0x0000FF, *RgbColor(QColor::fromRgb(0x0000FF)).optionalCode());
EXPECT_TRUE(RgbColor(QColor::fromRgb(0xFFFFFF)).isValid());
EXPECT_TRUE(RgbColor(QColor::fromRgb(0xFFFFFF)));
EXPECT_EQ(0xFFFFFF, *RgbColor(QColor::fromRgb(0xFFFFFF)).optionalCode());
}

TEST(RgbColorTest, FromRgbColorCodeWithAlpha) {
EXPECT_TRUE(RgbColor(0xF0000000).isValid());
EXPECT_TRUE(RgbColor(0xF0000000));
EXPECT_EQ(0x000000, *RgbColor(0xF0000000).optionalCode());
EXPECT_TRUE(RgbColor(0xF0FF0000).isValid());
EXPECT_TRUE(RgbColor(0xF0FF0000));
EXPECT_EQ(0xFF0000, *RgbColor(0xF0FF0000).optionalCode());
EXPECT_TRUE(RgbColor(0xF000FF00).isValid());
EXPECT_TRUE(RgbColor(0xF000FF00));
EXPECT_EQ(0x00FF00, *RgbColor(0xF000FF00).optionalCode());
EXPECT_TRUE(RgbColor(0xF00000FF).isValid());
EXPECT_TRUE(RgbColor(0xF00000FF));
EXPECT_EQ(0x0000FF, *RgbColor(0xF00000FF).optionalCode());
EXPECT_TRUE(RgbColor(0xF0FFFFFF).isValid());
EXPECT_TRUE(RgbColor(0xF0FFFFFF));
EXPECT_EQ(0xFFFFFF, *RgbColor(0xF0FFFFFF).optionalCode());
}

TEST(RgbColorTest, FromQColorWithAlpha) {
EXPECT_TRUE(RgbColor(0xF0000000).isValid());
EXPECT_TRUE(RgbColor(0xF0000000));
EXPECT_EQ(0x000000, *RgbColor(0xF0000000).optionalCode());
EXPECT_TRUE(RgbColor(0xF0FF0000).isValid());
EXPECT_TRUE(RgbColor(0xF0FF0000));
EXPECT_EQ(0xFF0000, *RgbColor(0xF0FF0000).optionalCode());
EXPECT_TRUE(RgbColor(0xF000FF00).isValid());
EXPECT_TRUE(RgbColor(0xF000FF00));
EXPECT_EQ(0x00FF00, *RgbColor(0xF000FF00).optionalCode());
EXPECT_TRUE(RgbColor(0xF00000FF).isValid());
EXPECT_TRUE(RgbColor(0xF00000FF));
EXPECT_EQ(0x0000FF, *RgbColor(0xF00000FF).optionalCode());
EXPECT_TRUE(RgbColor(0xF0FFFFFF).isValid());
EXPECT_TRUE(RgbColor(0xF0FFFFFF));
EXPECT_EQ(0xFFFFFF, *RgbColor(0xF0FFFFFF).optionalCode());
}

Expand Down
31 changes: 17 additions & 14 deletions src/util/color/rgbcolor.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,40 +21,39 @@ class RgbColor {
public:
RgbColor()
: m_internalCode(kInvalidInternalCode) {
DEBUG_ASSERT(!isValid());
DEBUG_ASSERT(!*this);
}
/*non-explicit*/ RgbColor(RgbColorCode code)
: m_internalCode(codeToInternalCode(code)) {
DEBUG_ASSERT(isValid());
DEBUG_ASSERT(*this);
}
/*non-explicit*/ RgbColor(std::optional<RgbColorCode> optionalCode)
: m_internalCode(optionalCodeToInternalCode(optionalCode)) {
DEBUG_ASSERT(isValid() == static_cast<bool>(optionalCode));
DEBUG_ASSERT(*this == static_cast<bool>(optionalCode));
}
uklotzde marked this conversation as resolved.
Show resolved Hide resolved
/*non-explicit*/ RgbColor(QColor anyColor)
: m_internalCode(anyColorToInternalCode(anyColor)) {
DEBUG_ASSERT(isValid() == anyColor.isValid());
DEBUG_ASSERT(*this == anyColor.isValid());
}

// Implicit conversion into the corresponding QColor.
operator QColor() const {
return internalCodeToColor(m_internalCode);
// Checks if the color is valid or represents "no color",
// i.e. is missing or undefined.
constexpr operator bool() const noexcept {
return m_internalCode == kInvalidInternalCode;
}

// Checks if the color is valid or represents "no color",
// i.e. is missing or undefined. If the corresponding color
// code is stored in a database then the colum value is NULL.
bool isValid() const {
return m_internalCode == (m_internalCode & kRgbCodeMask);
friend bool operator==(const RgbColor& lhs, const RgbColor& rhs) {
return lhs.m_internalCode == rhs.m_internalCode;
}

// Returns the corresponding, optional RGB color code.
std::optional<RgbColorCode> optionalCode() const {
return internalCodeToOptionalCode(m_internalCode);
}

friend bool operator==(const RgbColor& lhs, const RgbColor& rhs) {
return lhs.m_internalCode == rhs.m_internalCode;
// Implicit conversion into the corresponding QColor.
operator QColor() const {
return internalCodeToColor(m_internalCode);
}

private:
Expand Down Expand Up @@ -83,16 +82,20 @@ class RgbColor {

std::optional<RgbColorCode> internalCodeToOptionalCode(RgbColorCode internalCode) const {
if (internalCode == (internalCode & kRgbCodeMask)) {
DEBUG_ASSERT(*this);
return std::make_optional(m_internalCode);
} else {
DEBUG_ASSERT(!*this);
return std::nullopt;
}
}

QColor internalCodeToColor(RgbColorCode internalCode) const {
if (internalCode == (internalCode & kRgbCodeMask)) {
DEBUG_ASSERT(*this);
return QRgb(m_internalCode | kAlphaCodeMask);
} else {
DEBUG_ASSERT(!*this);
return QColor();
}
}
Expand Down