[wpiutil] Move Color and Color8Bit from wpilib to wpiutil (#8437)

Removes one of the org.wpilib.util package conflicts for modularization.

Only a few minor tweaks were required to remove the wpimath dependency.
This commit is contained in:
Peter Johnson
2025-11-30 11:11:48 -08:00
committed by GitHub
parent e902a98601
commit 42992953ed
32 changed files with 468 additions and 385 deletions

View File

@@ -79,7 +79,7 @@ class AddressableLED {
*
* @param color The color of the LED
*/
void SetLED(const Color& color) {
void SetLED(const wpi::util::Color& color) {
this->r = color.red * 255;
this->g = color.green * 255;
this->b = color.blue * 255;
@@ -90,7 +90,7 @@ class AddressableLED {
*
* @param color The color of the LED
*/
void SetLED(const Color8Bit& color) {
void SetLED(const wpi::util::Color8Bit& color) {
this->r = color.red;
this->g = color.green;
this->b = color.blue;

View File

@@ -41,12 +41,13 @@ class LEDPattern {
size_t m_size;
};
explicit LEDPattern(std::function<void(wpi::LEDPattern::LEDReader,
std::function<void(int, wpi::Color)>)>
impl);
explicit LEDPattern(
std::function<void(wpi::LEDPattern::LEDReader,
std::function<void(int, wpi::util::Color)>)>
impl);
void ApplyTo(LEDReader reader,
std::function<void(int, wpi::Color)> writer) const;
std::function<void(int, wpi::util::Color)> writer) const;
/**
* Writes the pattern to an LED buffer. Dynamic animations should be called
@@ -62,7 +63,7 @@ class LEDPattern {
* @param writer data writer for setting new LED colors on the LED strip
*/
void ApplyTo(std::span<wpi::AddressableLED::LEDData> data,
std::function<void(int, wpi::Color)> writer) const;
std::function<void(int, wpi::util::Color)> writer) const;
/**
* Writes the pattern to an LED buffer. Dynamic animations should be called
@@ -199,8 +200,8 @@ class LEDPattern {
/**
* Creates a pattern that plays this pattern overlaid on another. Anywhere
* this pattern sets an LED to off (or {@link wpi::Color::kBlack}), the base
* pattern will be displayed instead.
* this pattern sets an LED to off (or {@link wpi::util::Color::kBlack}), the
* base pattern will be displayed instead.
*
* @param base the base pattern to overlay on top of
* @return the combined overlay pattern
@@ -256,10 +257,10 @@ class LEDPattern {
*
* <pre>
* // Solid red, but at 50% brightness
* wpi::LEDPattern::Solid(wpi::Color::kRed).AtBrightness(0.5);
* wpi::LEDPattern::Solid(wpi::util::Color::kRed).AtBrightness(0.5);
*
* // Solid white, but at only 10% (i.e. ~0.5V)
* wpi::LEDPattern::Solid(frc:Color::kWhite).AtBrightness(0.1);
* wpi::LEDPattern::Solid(wpi::util::Color::kWhite).AtBrightness(0.1);
* </pre>
*
* @param relativeBrightness the multiplier to apply to all channels to modify
@@ -279,7 +280,7 @@ class LEDPattern {
* @param color the color to display
* @return the pattern
*/
static LEDPattern Solid(const Color color);
static LEDPattern Solid(const wpi::util::Color color);
/**
* Creates a pattern that works as a mask layer for {@link
@@ -296,8 +297,8 @@ class LEDPattern {
*
* <pre>
* wpi::LEDPattern basePattern =
* wpi::LEDPattern::Gradient(wpi::Color::kRed, wpi::Color::kBlue);
* wpi::LEDPattern progressPattern =
* wpi::LEDPattern::Gradient(wpi::util::Color::kRed,
* wpi::util::Color::kBlue); wpi::LEDPattern progressPattern =
* basePattern.Mask(wpi::LEDPattern::ProgressMaskLayer([&]() {
* return elevator.GetHeight() / elevator.MaxHeight();
* });
@@ -322,7 +323,8 @@ class LEDPattern {
* position along the LED strip
* @return a motionless step pattern
*/
static LEDPattern Steps(std::span<const std::pair<double, Color>> steps);
static LEDPattern Steps(
std::span<const std::pair<double, wpi::util::Color>> steps);
/**
* Display a set of colors in steps across the length of the LED strip. No
@@ -337,7 +339,7 @@ class LEDPattern {
* @return a motionless step pattern
*/
static LEDPattern Steps(
std::initializer_list<std::pair<double, Color>> steps);
std::initializer_list<std::pair<double, wpi::util::Color>> steps);
/** Types of gradients. */
enum GradientType {
@@ -368,7 +370,8 @@ class LEDPattern {
* @param colors the colors to display in the gradient
* @return a motionless gradient pattern
*/
static LEDPattern Gradient(GradientType type, std::span<const Color> colors);
static LEDPattern Gradient(GradientType type,
std::span<const wpi::util::Color> colors);
/**
* Creates a pattern that displays a non-animated gradient of colors across
@@ -384,7 +387,7 @@ class LEDPattern {
* @return a motionless gradient pattern
*/
static LEDPattern Gradient(GradientType type,
std::initializer_list<Color> colors);
std::initializer_list<wpi::util::Color> colors);
/**
* Creates an LED pattern that displays a rainbow across the color wheel. The
@@ -398,7 +401,7 @@ class LEDPattern {
private:
std::function<void(wpi::LEDPattern::LEDReader,
std::function<void(int, wpi::Color)>)>
std::function<void(int, wpi::util::Color)>)>
m_impl;
};
} // namespace wpi

View File

@@ -52,7 +52,7 @@ class Mechanism2d : public wpi::nt::NTSendable,
* @param backgroundColor the background color
*/
Mechanism2d(double width, double height,
const Color8Bit& backgroundColor = {0, 0, 32});
const wpi::util::Color8Bit& backgroundColor = {0, 0, 32});
/**
* Get or create a root in this Mechanism2d with the given name and
@@ -73,7 +73,7 @@ class Mechanism2d : public wpi::nt::NTSendable,
*
* @param color the new background color
*/
void SetBackgroundColor(const Color8Bit& color);
void SetBackgroundColor(const wpi::util::Color8Bit& color);
void InitSendable(wpi::nt::NTSendableBuilder& builder) override;

View File

@@ -27,21 +27,21 @@ class MechanismLigament2d : public MechanismObject2d {
public:
MechanismLigament2d(std::string_view name, double length,
wpi::units::degree_t angle, double lineWidth = 6,
const wpi::Color8Bit& color = {235, 137, 52});
const wpi::util::Color8Bit& color = {235, 137, 52});
/**
* Set the ligament color.
*
* @param color the color of the line
*/
void SetColor(const Color8Bit& color);
void SetColor(const wpi::util::Color8Bit& color);
/**
* Get the ligament color.
*
* @return the color of the line
*/
Color8Bit GetColor();
wpi::util::Color8Bit GetColor();
/**
* Set the ligament's length.

File diff suppressed because it is too large Load Diff

View File

@@ -1,134 +0,0 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include <algorithm>
#include <stdexcept>
#include <string>
#include <string_view>
#include <fmt/format.h>
#include "wpi/util/Color.hpp"
#include "wpi/util/StringExtras.hpp"
#include "wpi/util/ct_string.hpp"
namespace wpi {
/**
* Represents colors that can be used with Addressable LEDs.
*/
class Color8Bit {
public:
/**
* Constructs a default color (black).
*/
constexpr Color8Bit() = default;
/**
* Constructs a Color8Bit.
*
* @param r Red value (0-255)
* @param g Green value (0-255)
* @param b Blue value (0-255)
*/
constexpr Color8Bit(int r, int g, int b)
: red(std::clamp(r, 0, 255)),
green(std::clamp(g, 0, 255)),
blue(std::clamp(b, 0, 255)) {}
/**
* Constructs a Color8Bit from a Color.
*
* @param color The color
*/
constexpr Color8Bit(const Color& color) // NOLINT
: red(color.red * 255),
green(color.green * 255),
blue(color.blue * 255) {}
/**
* Constructs a Color8Bit from a hex string.
*
* @param hexString a string of the format <tt>\#RRGGBB</tt>
* @throws std::invalid_argument if the hex string is invalid.
*/
explicit constexpr Color8Bit(std::string_view hexString) {
if (hexString.length() != 7 || !hexString.starts_with("#") ||
!wpi::util::isHexDigit(hexString[1]) ||
!wpi::util::isHexDigit(hexString[2]) ||
!wpi::util::isHexDigit(hexString[3]) ||
!wpi::util::isHexDigit(hexString[4]) ||
!wpi::util::isHexDigit(hexString[5]) ||
!wpi::util::isHexDigit(hexString[6])) {
throw std::invalid_argument(
fmt::format("Invalid hex string for Color \"{}\"", hexString));
}
red = wpi::util::hexDigitValue(hexString[1]) * 16 +
wpi::util::hexDigitValue(hexString[2]);
green = wpi::util::hexDigitValue(hexString[3]) * 16 +
wpi::util::hexDigitValue(hexString[4]);
blue = wpi::util::hexDigitValue(hexString[5]) * 16 +
wpi::util::hexDigitValue(hexString[6]);
}
constexpr bool operator==(const Color8Bit&) const = default;
constexpr operator Color() const { // NOLINT
return Color(red / 255.0, green / 255.0, blue / 255.0);
}
/**
* Create a Color8Bit from a hex string.
*
* @param hexString a string of the format <tt>\#RRGGBB</tt>
* @return Color8Bit object from hex string.
* @throws std::invalid_argument if the hex string is invalid.
*/
static constexpr Color8Bit FromHexString(std::string_view hexString) {
if (hexString.length() != 7 || !hexString.starts_with("#") ||
!wpi::util::isHexDigit(hexString[1]) ||
!wpi::util::isHexDigit(hexString[2]) ||
!wpi::util::isHexDigit(hexString[3]) ||
!wpi::util::isHexDigit(hexString[4]) ||
!wpi::util::isHexDigit(hexString[5]) ||
!wpi::util::isHexDigit(hexString[6])) {
throw std::invalid_argument(
fmt::format("Invalid hex string for Color \"{}\"", hexString));
}
int r = wpi::util::hexDigitValue(hexString[0]) * 16 +
wpi::util::hexDigitValue(hexString[1]);
int g = wpi::util::hexDigitValue(hexString[2]) * 16 +
wpi::util::hexDigitValue(hexString[3]);
int b = wpi::util::hexDigitValue(hexString[4]) * 16 +
wpi::util::hexDigitValue(hexString[5]);
return Color8Bit{r, g, b};
}
/**
* Return this color represented as a hex string.
*
* @return a string of the format <tt>\#RRGGBB</tt>
*/
constexpr auto HexString() const {
return wpi::util::ct_string<char, std::char_traits<char>, 7>{
{'#', wpi::util::hexdigit(red / 16), wpi::util::hexdigit(red % 16),
wpi::util::hexdigit(green / 16), wpi::util::hexdigit(green % 16),
wpi::util::hexdigit(blue / 16), wpi::util::hexdigit(blue % 16)}};
}
/// Red component (0-255).
int red = 0;
/// Green component (0-255).
int green = 0;
/// Blue component (0-255).
int blue = 0;
};
} // namespace wpi