Merge pull request #13495 from wwmayer/material_colors

Support to customize all material colors
This commit is contained in:
Chris Hennes
2024-04-22 11:09:05 -05:00
committed by GitHub
10 changed files with 549 additions and 70 deletions

View File

@@ -82,20 +82,38 @@ Color& Color::setPackedValue(uint32_t rgba)
uint32_t Color::getPackedValue() const
{
// clang-format off
return (static_cast<uint32_t>(r * 255.0F + 0.5F) << 24 |
static_cast<uint32_t>(g * 255.0F + 0.5F) << 16 |
static_cast<uint32_t>(b * 255.0F + 0.5F) << 8 |
static_cast<uint32_t>(a * 255.0F + 0.5F));
return (static_cast<uint32_t>(std::lround(r * 255.0F)) << 24 |
static_cast<uint32_t>(std::lround(g * 255.0F)) << 16 |
static_cast<uint32_t>(std::lround(b * 255.0F)) << 8 |
static_cast<uint32_t>(std::lround(a * 255.0F)));
// clang-format on
}
void Color::setPackedRGB(uint32_t rgb)
{
// clang-format off
this->set(static_cast<float>((rgb >> 24) & 0xff) / 255.0F,
static_cast<float>((rgb >> 16) & 0xff) / 255.0F,
static_cast<float>((rgb >> 8) & 0xff) / 255.0F);
// clang-format on
}
uint32_t Color::getPackedRGB() const
{
// clang-format off
return (static_cast<uint32_t>(std::lround(r * 255.0F)) << 24 |
static_cast<uint32_t>(std::lround(g * 255.0F)) << 16 |
static_cast<uint32_t>(std::lround(b * 255.0F)) << 8);
// clang-format on
}
uint32_t Color::getPackedARGB() const
{
// clang-format off
return (static_cast<uint32_t>(a * 255.0F + 0.5F) << 24 |
static_cast<uint32_t>(r * 255.0F + 0.5F) << 16 |
static_cast<uint32_t>(g * 255.0F + 0.5F) << 8 |
static_cast<uint32_t>(b * 255.0F + 0.5F));
return (static_cast<uint32_t>(std::lround(a * 255.0F)) << 24 |
static_cast<uint32_t>(std::lround(r * 255.0F)) << 16 |
static_cast<uint32_t>(std::lround(g * 255.0F)) << 8 |
static_cast<uint32_t>(std::lround(b * 255.0F)));
// clang-format on
}
@@ -113,9 +131,9 @@ std::string Color::asHexString() const
{
std::stringstream ss;
ss << "#" << std::hex << std::uppercase << std::setfill('0')
<< std::setw(2) << int(r * 255.0F)
<< std::setw(2) << int(g * 255.0F)
<< std::setw(2) << int(b * 255.0F);
<< std::setw(2) << int(std::lround(r * 255.0F))
<< std::setw(2) << int(std::lround(g * 255.0F))
<< std::setw(2) << int(std::lround(b * 255.0F));
return ss.str();
}

View File

@@ -27,6 +27,7 @@
#ifdef __GNUC__
# include <cstdint>
#endif
#include <cmath>
#include <string>
#include <FCGlobal.h>
@@ -79,6 +80,14 @@ public:
* \sa setPackedValue().
*/
uint32_t getPackedValue() const;
/**
* Returns color as a 32 bit packed unsigned int in the form 0xRRGGBB.
*/
uint32_t getPackedRGB() const;
/**
* Sets color as a 32 bit packed unsigned int in the form 0xRRGGBB.
*/
void setPackedRGB(uint32_t);
/**
* Returns color as a 32 bit packed unsigned int in the form 0xAARRGGBB.
*/
@@ -119,8 +128,13 @@ public:
*
*/
template <typename T>
inline T asValue() const {
return(T(int(r*255.0f),int(g*255.0f),int(b*255.0f)));
inline T asValue() const
{
// clang-format off
return(T(int(std::lround(r * 255.0F)),
int(std::lround(g * 255.0F)),
int(std::lround(b * 255.0F))));
// clang-format on
}
/**
* returns color as hex color "#RRGGBB"

View File

@@ -23,6 +23,7 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <random>
#include <Inventor/SoPickedPoint.h>
#include <Inventor/actions/SoRayPickAction.h>
#include <Inventor/actions/SoSearchAction.h>
@@ -70,10 +71,8 @@ const App::PropertyIntegerConstraint::Constraints intPercent = {0, 100, 5};
ViewProviderGeometryObject::ViewProviderGeometryObject()
{
ParameterGrp::handle hGrp =
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
int initialTransparency = hGrp->GetInt("DefaultShapeTransparency", 0);
App::Material mat = getDefaultMaterial();
long initialTransparency = toPercent(mat.transparency);
static const char* dogroup = "Display Options";
static const char* sgroup = "Selection";
@@ -86,28 +85,6 @@ ViewProviderGeometryObject::ViewProviderGeometryObject()
"Set object transparency");
Transparency.setConstraints(&intPercent);
App::Material mat(App::Material::DEFAULT);
// This is handled in the material code when using the object appearance
bool randomColor = hGrp->GetBool("RandomColor", false);
float red {};
float green {};
float blue {};
if (randomColor) {
auto fMax = (float)RAND_MAX;
red = (float)rand() / fMax;
green = (float)rand() / fMax;
blue = (float)rand() / fMax;
}
else {
// Color = (204, 204, 230)
unsigned long shcol = hGrp->GetUnsigned("DefaultShapeColor", 3435980543UL);
red = ((shcol >> 24) & 0xff) / 255.0F;
green = ((shcol >> 16) & 0xff) / 255.0F;
blue = ((shcol >> 8) & 0xff) / 255.0F;
}
mat.diffuseColor = App::Color(red, green, blue);
ADD_PROPERTY_TYPE(ShapeAppearance, (mat), osgroup, App::Prop_None, "Shape appearrance");
ADD_PROPERTY_TYPE(BoundingBox, (false), dogroup, App::Prop_None, "Display object bounding box");
ADD_PROPERTY_TYPE(Selectable,
@@ -116,8 +93,7 @@ ViewProviderGeometryObject::ViewProviderGeometryObject()
App::Prop_None,
"Set if the object is selectable in the 3d view");
bool enableSel = hGrp->GetBool("EnableSelection", true);
Selectable.setValue(enableSel);
Selectable.setValue(isSelectionEnabled());
pcShapeMaterial = new SoMaterial;
setSoMaterial(mat);
@@ -139,6 +115,56 @@ ViewProviderGeometryObject::~ViewProviderGeometryObject()
pcBoundColor->unref();
}
App::Material ViewProviderGeometryObject::getDefaultMaterial() const
{
ParameterGrp::handle hGrp =
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
auto getColor = [hGrp](const char* parameter, App::Color& color) {
uint32_t packed = color.getPackedRGB();
packed = hGrp->GetUnsigned(parameter, packed);
color.setPackedRGB(packed);
};
auto intRandom = [] (int min, int max) -> int {
static std::mt19937 generator;
std::uniform_int_distribution<int> distribution(min, max);
return distribution(generator);
};
App::Material mat(App::Material::DEFAULT);
mat.transparency = fromPercent(hGrp->GetInt("DefaultShapeTransparency", 0));
long shininess = toPercent(mat.shininess);
mat.shininess = fromPercent(hGrp->GetInt("DefaultShapeShininess", shininess));
// This is handled in the material code when using the object appearance
bool randomColor = hGrp->GetBool("RandomColor", false);
// diffuse color
if (randomColor) {
float red = static_cast<float>(intRandom(0, 255)) / 255.0F;
float green = static_cast<float>(intRandom(0, 255)) / 255.0F;
float blue = static_cast<float>(intRandom(0, 255)) / 255.0F;
mat.diffuseColor = App::Color(red, green, blue);
}
else {
// Color = (204, 204, 230) = 3435980543UL
getColor("DefaultShapeColor", mat.diffuseColor);
}
getColor("DefaultAmbientColor", mat.ambientColor);
getColor("DefaultEmissiveColor", mat.emissiveColor);
getColor("DefaultSpecularColor", mat.specularColor);
return mat;
}
bool ViewProviderGeometryObject::isSelectionEnabled() const
{
ParameterGrp::handle hGrp =
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
return hGrp->GetBool("EnableSelection", true);
}
void ViewProviderGeometryObject::onChanged(const App::Property* prop)
{
// Actually, the properties 'ShapeColor' and 'Transparency' are part of the property
@@ -257,8 +283,8 @@ unsigned long ViewProviderGeometryObject::getBoundColor() const
{
ParameterGrp::handle hGrp =
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
unsigned long bbcol =
hGrp->GetUnsigned("BoundingBoxColor", 4294967295UL); // white (255,255,255)
// white (255,255,255)
unsigned long bbcol = hGrp->GetUnsigned("BoundingBoxColor", 4294967295UL);
return bbcol;
}

View File

@@ -104,11 +104,15 @@ protected:
virtual unsigned long getBoundColor() const;
void setSoMaterial(const App::Material& source);
void handleChangedPropertyName(Base::XMLReader& reader,
const char* TypeName,
const char* PropName) override;
private:
void setSoMaterial(const App::Material& source);
App::Material getDefaultMaterial() const;
bool isSelectionEnabled() const;
protected:
SoMaterial* pcShapeMaterial {nullptr};
SoFCBoundingBox* pcBoundingBox {nullptr};

View File

@@ -21,6 +21,7 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <random>
#endif
#include <QDirIterator>
@@ -116,30 +117,52 @@ std::shared_ptr<Material> MaterialManager::defaultMaterial()
ParameterGrp::handle hGrp =
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
auto getColor = [hGrp](const char* parameter, App::Color& color) {
uint32_t packed = color.getPackedRGB();
packed = hGrp->GetUnsigned(parameter, packed);
color.setPackedRGB(packed);
};
auto intRandom = [] (int min, int max) -> int {
static std::mt19937 generator;
std::uniform_int_distribution<int> distribution(min, max);
return distribution(generator);
};
App::Material mat(App::Material::DEFAULT);
bool randomColor = hGrp->GetBool("RandomColor", false);
float r, g, b;
if (randomColor) {
auto fMax = (float)RAND_MAX;
r = (float)rand() / fMax;
g = (float)rand() / fMax;
b = (float)rand() / fMax;
float red = static_cast<float>(intRandom(0, 255)) / 255.0F;
float green = static_cast<float>(intRandom(0, 255)) / 255.0F;
float blue = static_cast<float>(intRandom(0, 255)) / 255.0F;
mat.diffuseColor = App::Color(red, green, blue);
}
else {
unsigned long shcol = hGrp->GetUnsigned("DefaultShapeColor", 3435980543UL);
r = ((shcol >> 24) & 0xff) / 255.0;
g = ((shcol >> 16) & 0xff) / 255.0;
b = ((shcol >> 8) & 0xff) / 255.0;
getColor("DefaultShapeColor", mat.diffuseColor);
}
int initialTransparency = hGrp->GetInt("DefaultShapeTransparency", 0);
getColor("DefaultAmbientColor", mat.ambientColor);
getColor("DefaultEmissiveColor", mat.emissiveColor);
getColor("DefaultSpecularColor", mat.specularColor);
long initialTransparency = hGrp->GetInt("DefaultShapeTransparency", 0);
long initialShininess = hGrp->GetInt("DefaultShapeShininess", 90);
auto material = manager.getMaterial(defaultMaterialUUID());
if (material->hasAppearanceModel(ModelUUIDs::ModelUUID_Rendering_Basic)) {
material->getAppearanceProperty(QString::fromLatin1("DiffuseColor"))
->setColor(App::Color(r, g, b));
->setColor(mat.diffuseColor);
material->getAppearanceProperty(QString::fromLatin1("AmbientColor"))
->setColor(mat.ambientColor);
material->getAppearanceProperty(QString::fromLatin1("EmissiveColor"))
->setColor(mat.emissiveColor);
material->getAppearanceProperty(QString::fromLatin1("SpecularColor"))
->setColor(mat.specularColor);
material->getAppearanceProperty(QString::fromLatin1("Transparency"))
->setFloat((float)initialTransparency / 100.0f);
->setFloat((float)initialTransparency / 100.0F);
material->getAppearanceProperty(QString::fromLatin1("Shininess"))
->setFloat((float)initialShininess / 100.0F);
}
return material;

View File

@@ -50,6 +50,7 @@
#include <fstream>
#include <map>
#include <memory>
#include <random>
#include <sstream>
#include <string>
#include <vector>

View File

@@ -51,8 +51,12 @@ void DlgSettingsObjectColor::saveSettings()
{
// Part
ui->DefaultShapeColor->onSave();
ui->DefaultAmbientColor->onSave();
ui->DefaultEmissiveColor->onSave();
ui->DefaultSpecularColor->onSave();
ui->checkRandomColor->onSave();
ui->DefaultShapeTransparency->onSave();
ui->DefaultShapeShininess->onSave();
ui->DefaultShapeLineColor->onSave();
ui->DefaultShapeLineWidth->onSave();
ui->DefaultShapeVertexColor->onSave();
@@ -68,8 +72,12 @@ void DlgSettingsObjectColor::loadSettings()
{
// Part
ui->DefaultShapeColor->onRestore();
ui->DefaultAmbientColor->onRestore();
ui->DefaultEmissiveColor->onRestore();
ui->DefaultSpecularColor->onRestore();
ui->checkRandomColor->onRestore();
ui->DefaultShapeTransparency->onRestore();
ui->DefaultShapeShininess->onRestore();
ui->DefaultShapeLineColor->onRestore();
ui->DefaultShapeLineWidth->onRestore();
ui->DefaultShapeVertexColor->onRestore();

View File

@@ -72,6 +72,105 @@
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_ambient">
<property name="minimumSize">
<size>
<width>182</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Ambient shape color</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="Gui::PrefColorButton" name="DefaultAmbientColor">
<property name="toolTip">
<string>The default ambient color for new shapes</string>
</property>
<property name="color">
<color>
<red>85</red>
<green>85</green>
<blue>85</blue>
</color>
</property>
<property name="prefEntry" stdset="0">
<cstring>DefaultAmbientColor</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_emissive">
<property name="minimumSize">
<size>
<width>182</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Emissive shape color</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="Gui::PrefColorButton" name="DefaultEmissiveColor">
<property name="toolTip">
<string>The default emissive color for new shapes</string>
</property>
<property name="color">
<color>
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</property>
<property name="prefEntry" stdset="0">
<cstring>DefaultEmissiveColor</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_specular">
<property name="minimumSize">
<size>
<width>182</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Specular shape color</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="Gui::PrefColorButton" name="DefaultSpecularColor">
<property name="toolTip">
<string>The default specular color for new shapes</string>
</property>
<property name="color">
<color>
<red>136</red>
<green>136</green>
<blue>136</blue>
</color>
</property>
<property name="prefEntry" stdset="0">
<cstring>DefaultSpecularColor</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_transparency">
<property name="minimumSize">
<size>
@@ -84,7 +183,7 @@
</property>
</widget>
</item>
<item row="1" column="1">
<item row="4" column="1">
<widget class="Gui::PrefSpinBox" name="DefaultShapeTransparency">
<property name="toolTip">
<string>The default transparency for new shapes</string>
@@ -106,7 +205,45 @@
</property>
</widget>
</item>
<item row="2" column="0">
<item row="5" column="0">
<widget class="QLabel" name="label_shininess">
<property name="minimumSize">
<size>
<width>182</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Shape shininess</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="Gui::PrefSpinBox" name="DefaultShapeShininess">
<property name="toolTip">
<string>The default shininess for new shapes</string>
</property>
<property name="suffix">
<string notr="true">%</string>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>90</number>
</property>
<property name="singleStep">
<number>5</number>
</property>
<property name="prefEntry" stdset="0">
<cstring>DefaultShapeShininess</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_7">
<property name="minimumSize">
<size>
@@ -119,7 +256,7 @@
</property>
</widget>
</item>
<item row="2" column="1">
<item row="6" column="1">
<widget class="Gui::PrefColorButton" name="DefaultShapeLineColor">
<property name="toolTip">
<string>The default line color for new shapes</string>
@@ -139,7 +276,7 @@
</property>
</widget>
</item>
<item row="3" column="0">
<item row="7" column="0">
<widget class="QLabel" name="label_9">
<property name="minimumSize">
<size>
@@ -152,7 +289,7 @@
</property>
</widget>
</item>
<item row="3" column="1">
<item row="7" column="1">
<widget class="Gui::PrefSpinBox" name="DefaultShapeLineWidth">
<property name="toolTip">
<string>The default line thickness for new shapes</string>
@@ -174,7 +311,7 @@
</property>
</widget>
</item>
<item row="4" column="0">
<item row="8" column="0">
<widget class="QLabel" name="label_10">
<property name="minimumSize">
<size>
@@ -187,7 +324,7 @@
</property>
</widget>
</item>
<item row="4" column="1">
<item row="8" column="1">
<widget class="Gui::PrefColorButton" name="DefaultShapeVertexColor">
<property name="toolTip">
<string>The default color for new vertices</string>
@@ -207,7 +344,7 @@
</property>
</widget>
</item>
<item row="5" column="0">
<item row="9" column="0">
<widget class="QLabel" name="label_11">
<property name="minimumSize">
<size>
@@ -220,7 +357,7 @@
</property>
</widget>
</item>
<item row="5" column="1">
<item row="9" column="1">
<widget class="Gui::PrefSpinBox" name="DefaultShapeVertexSize">
<property name="toolTip">
<string>The default size for new vertices</string>
@@ -242,7 +379,7 @@
</property>
</widget>
</item>
<item row="6" column="0">
<item row="10" column="0">
<widget class="QLabel" name="label_8">
<property name="minimumSize">
<size>
@@ -255,7 +392,7 @@
</property>
</widget>
</item>
<item row="6" column="1">
<item row="10" column="1">
<widget class="Gui::PrefColorButton" name="BoundingBoxColor">
<property name="toolTip">
<string>The color of bounding boxes in the 3D view</string>
@@ -275,7 +412,7 @@
</property>
</widget>
</item>
<item row="7" column="0">
<item row="11" column="0">
<widget class="QLabel" name="label_fontsize">
<property name="minimumSize">
<size>
@@ -288,7 +425,7 @@
</property>
</widget>
</item>
<item row="7" column="1">
<item row="11" column="1">
<widget class="Gui::PrefDoubleSpinBox" name="BoundingBoxFontSize">
<property name="toolTip">
<string>The font size of bounding boxes in the 3D view</string>
@@ -316,7 +453,7 @@
</property>
</widget>
</item>
<item row="8" column="0">
<item row="12" column="0">
<widget class="Gui::PrefCheckBox" name="twosideRendering">
<property name="minimumSize">
<size>

View File

@@ -5,6 +5,7 @@ target_sources(
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/Application.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Branding.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Color.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ComplexGeoData.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Document.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Expression.cpp

247
tests/src/App/Color.cpp Normal file
View File

@@ -0,0 +1,247 @@
#include "gtest/gtest.h"
#include <cmath>
#include "App/Color.h"
// NOLINTBEGIN
TEST(TestColor, equal)
{
int red = 85;
int green = 170;
int blue = 255;
App::Color color(red / 255.0F, green / 255.0F, blue / 255.0F);
uint32_t packed = color.getPackedValue();
App::Color color2 {packed};
EXPECT_EQ(color, color2);
}
TEST(TestColor, round)
{
for (int index = 0; index < 256; index++) {
float value = static_cast<float>(index) / 255.0F;
EXPECT_EQ(std::lround(value * 255.0F), index);
}
}
TEST(TestColor, packedValue)
{
int red = 85;
int green = 170;
int blue = 255;
App::Color color(red / 255.0F, green / 255.0F, blue / 255.0F);
uint32_t packed = color.getPackedValue();
App::Color color2 {packed};
EXPECT_EQ(std::lround(color2.r * 255.0F), 85);
EXPECT_EQ(std::lround(color2.g * 255.0F), 170);
EXPECT_EQ(std::lround(color2.b * 255.0F), 255);
}
TEST(TestColor, packedRGB)
{
int red = 85;
int green = 170;
int blue = 255;
App::Color color(red / 255.0F, green / 255.0F, blue / 255.0F);
uint32_t packed = color.getPackedRGB();
App::Color color2;
color2.setPackedRGB(packed);
EXPECT_EQ(std::lround(color2.r * 255.0F), 85);
EXPECT_EQ(std::lround(color2.g * 255.0F), 170);
EXPECT_EQ(std::lround(color2.b * 255.0F), 255);
}
TEST(TestColor, packedARGB)
{
int red = 85;
int green = 170;
int blue = 255;
int alpha = 127;
App::Color color(red / 255.0F, green / 255.0F, blue / 255.0F, alpha / 255.0F);
uint32_t packed = color.getPackedARGB();
App::Color color2;
color2.setPackedARGB(packed);
EXPECT_EQ(std::lround(color2.r * 255.0F), 85);
EXPECT_EQ(std::lround(color2.g * 255.0F), 170);
EXPECT_EQ(std::lround(color2.b * 255.0F), 255);
EXPECT_EQ(std::lround(color2.a * 255.0F), 127);
}
struct IntColor
{
IntColor(int red, int green, int blue, int alpha = 0)
: red_ {red}
, green_ {green}
, blue_ {blue}
, alpha_ {alpha}
{}
float redF() const
{
return static_cast<float>(red_) / 255.0F;
}
float greenF() const
{
return static_cast<float>(green_) / 255.0F;
}
float blueF() const
{
return static_cast<float>(blue_) / 255.0F;
}
float alphaF() const
{
return static_cast<float>(alpha_) / 255.0F;
}
int red() const
{
return red_;
}
int green() const
{
return green_;
}
int blue() const
{
return blue_;
}
int alpha() const
{
return alpha_;
}
private:
int red_ {};
int green_ {};
int blue_ {};
int alpha_ {};
};
TEST(TestColor, asPackedRGB)
{
int red = 85;
int green = 170;
int blue = 255;
IntColor intColor {red, green, blue};
uint32_t packed = App::Color::asPackedRGB<IntColor>(intColor);
EXPECT_EQ(packed, 1437269760);
}
TEST(TestColor, fromPackedRGB)
{
int red = 85;
int green = 170;
int blue = 255;
App::Color color(red / 255.0F, green / 255.0F, blue / 255.0F);
IntColor intColor = App::Color::fromPackedRGB<IntColor>(color.getPackedRGB());
EXPECT_EQ(intColor.red(), red);
EXPECT_EQ(intColor.green(), green);
EXPECT_EQ(intColor.blue(), blue);
}
TEST(TestColor, asPackedRGBA)
{
int red = 85;
int green = 170;
int blue = 255;
int alpha = 127;
IntColor intColor {red, green, blue, alpha};
uint32_t packed = App::Color::asPackedRGBA<IntColor>(intColor);
EXPECT_EQ(packed, 1437269887);
}
TEST(TestColor, fromPackedRGBA)
{
int red = 85;
int green = 170;
int blue = 255;
int alpha = 127;
App::Color color(red / 255.0F, green / 255.0F, blue / 255.0F, alpha / 255.0F);
IntColor intColor = App::Color::fromPackedRGBA<IntColor>(color.getPackedValue());
EXPECT_EQ(intColor.red(), red);
EXPECT_EQ(intColor.green(), green);
EXPECT_EQ(intColor.blue(), blue);
EXPECT_EQ(intColor.alpha(), alpha);
}
TEST(TestColor, setValue)
{
int red = 85;
int green = 170;
int blue = 255;
IntColor intColor {red, green, blue};
App::Color color {};
color.setValue<IntColor>(intColor);
EXPECT_FLOAT_EQ(color.r, 85.0F / 255.0F);
EXPECT_FLOAT_EQ(color.g, 170.0F / 255.0F);
EXPECT_FLOAT_EQ(color.b, 255.0F / 255.0F);
}
TEST(TestColor, asValue)
{
int red = 85;
int green = 170;
int blue = 255;
App::Color color(red / 255.0F, green / 255.0F, blue / 255.0F);
IntColor intColor = color.asValue<IntColor>();
EXPECT_EQ(intColor.red(), 85);
EXPECT_EQ(intColor.green(), 170);
EXPECT_EQ(intColor.blue(), 255);
}
TEST(TestColor, asHexString)
{
int red = 85;
int green = 170;
int blue = 255;
App::Color color(red / 255.0F, green / 255.0F, blue / 255.0F);
EXPECT_EQ(color.asHexString(), "#55AAFF");
}
TEST(TestColor, fromHexString)
{
App::Color color;
EXPECT_FALSE(color.fromHexString(std::string("")));
EXPECT_FALSE(color.fromHexString(std::string("abcdef")));
EXPECT_TRUE(color.fromHexString(std::string("#abcdef")));
EXPECT_TRUE(color.fromHexString(std::string("#ABCDEF")));
EXPECT_FALSE(color.fromHexString(std::string("#abcde")));
EXPECT_FALSE(color.fromHexString(std::string("#abcdeff")));
EXPECT_FALSE(color.fromHexString(std::string("#abcdeffff")));
EXPECT_TRUE(color.fromHexString(std::string("#55AAFF")));
EXPECT_FLOAT_EQ(color.r, 85.0F / 255.0F);
EXPECT_FLOAT_EQ(color.g, 170.0F / 255.0F);
EXPECT_FLOAT_EQ(color.b, 255.0F / 255.0F);
}
// NOLINTEND