2020-12-26 14:12:05 -08:00
|
|
|
// 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.
|
2018-09-28 04:18:18 -04:00
|
|
|
|
|
|
|
|
#include "frc/shuffleboard/ShuffleboardContainer.h"
|
|
|
|
|
|
2021-06-13 16:38:05 -07:00
|
|
|
#include <wpi/sendable/SendableRegistry.h>
|
|
|
|
|
|
2021-04-18 20:35:29 -07:00
|
|
|
#include "frc/Errors.h"
|
2018-09-28 04:18:18 -04:00
|
|
|
#include "frc/shuffleboard/ComplexWidget.h"
|
|
|
|
|
#include "frc/shuffleboard/ShuffleboardComponent.h"
|
|
|
|
|
#include "frc/shuffleboard/ShuffleboardLayout.h"
|
|
|
|
|
#include "frc/shuffleboard/SimpleWidget.h"
|
|
|
|
|
|
|
|
|
|
using namespace frc;
|
|
|
|
|
|
2019-02-14 23:44:30 -05:00
|
|
|
static constexpr const char* layoutStrings[] = {"List Layout", "Grid Layout"};
|
|
|
|
|
|
|
|
|
|
static constexpr const char* GetStringFromBuiltInLayout(BuiltInLayouts layout) {
|
|
|
|
|
return layoutStrings[static_cast<int>(layout)];
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
ShuffleboardContainer::ShuffleboardContainer(std::string_view title)
|
2018-09-28 04:18:18 -04:00
|
|
|
: ShuffleboardValue(title) {}
|
|
|
|
|
|
|
|
|
|
const std::vector<std::unique_ptr<ShuffleboardComponentBase>>&
|
|
|
|
|
ShuffleboardContainer::GetComponents() const {
|
|
|
|
|
return m_components;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
ShuffleboardLayout& ShuffleboardContainer::GetLayout(std::string_view title,
|
2019-02-14 23:44:30 -05:00
|
|
|
BuiltInLayouts type) {
|
|
|
|
|
return GetLayout(title, GetStringFromBuiltInLayout(type));
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
ShuffleboardLayout& ShuffleboardContainer::GetLayout(std::string_view title,
|
2018-12-29 20:22:47 -05:00
|
|
|
const LayoutType& type) {
|
|
|
|
|
return GetLayout(title, type.GetLayoutName());
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
ShuffleboardLayout& ShuffleboardContainer::GetLayout(std::string_view title,
|
|
|
|
|
std::string_view type) {
|
|
|
|
|
if (m_layouts.count(title) == 0) {
|
|
|
|
|
auto layout = std::make_unique<ShuffleboardLayout>(*this, title, type);
|
2018-09-28 04:18:18 -04:00
|
|
|
auto ptr = layout.get();
|
|
|
|
|
m_components.emplace_back(std::move(layout));
|
2021-05-26 17:44:18 -07:00
|
|
|
m_layouts.insert(std::make_pair(title, ptr));
|
2018-09-28 04:18:18 -04:00
|
|
|
}
|
2021-05-26 17:44:18 -07:00
|
|
|
return *m_layouts[title];
|
2018-09-28 04:18:18 -04:00
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
ShuffleboardLayout& ShuffleboardContainer::GetLayout(std::string_view title) {
|
|
|
|
|
if (m_layouts.count(title) == 0) {
|
2021-04-18 20:35:29 -07:00
|
|
|
throw FRC_MakeError(err::InvalidParameter,
|
2021-05-26 17:44:18 -07:00
|
|
|
"No layout with title {} has been defined", title);
|
2018-12-29 20:22:47 -05:00
|
|
|
}
|
2021-05-26 17:44:18 -07:00
|
|
|
return *m_layouts[title];
|
2018-12-29 20:22:47 -05:00
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
ComplexWidget& ShuffleboardContainer::Add(std::string_view title,
|
2021-06-13 16:38:05 -07:00
|
|
|
wpi::Sendable& sendable) {
|
2018-09-28 04:18:18 -04:00
|
|
|
CheckTitle(title);
|
|
|
|
|
auto widget = std::make_unique<ComplexWidget>(*this, title, sendable);
|
|
|
|
|
auto ptr = widget.get();
|
|
|
|
|
m_components.emplace_back(std::move(widget));
|
|
|
|
|
return *ptr;
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-13 16:38:05 -07:00
|
|
|
ComplexWidget& ShuffleboardContainer::Add(wpi::Sendable& sendable) {
|
2021-06-15 23:06:03 -07:00
|
|
|
auto name = wpi::SendableRegistry::GetName(&sendable);
|
2019-09-14 15:22:54 -05:00
|
|
|
if (name.empty()) {
|
2021-06-06 16:13:58 -07:00
|
|
|
FRC_ReportError(err::Error, "{}", "Sendable must have a name");
|
2018-09-28 04:18:18 -04:00
|
|
|
}
|
2019-09-14 15:22:54 -05:00
|
|
|
return Add(name, sendable);
|
2018-09-28 04:18:18 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SimpleWidget& ShuffleboardContainer::Add(
|
2021-05-26 17:44:18 -07:00
|
|
|
std::string_view title, std::shared_ptr<nt::Value> defaultValue) {
|
2018-09-28 04:18:18 -04:00
|
|
|
CheckTitle(title);
|
|
|
|
|
|
|
|
|
|
auto widget = std::make_unique<SimpleWidget>(*this, title);
|
|
|
|
|
auto ptr = widget.get();
|
|
|
|
|
m_components.emplace_back(std::move(widget));
|
2018-10-02 20:55:03 -07:00
|
|
|
ptr->GetEntry().SetDefaultValue(defaultValue);
|
2018-09-28 04:18:18 -04:00
|
|
|
return *ptr;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
SimpleWidget& ShuffleboardContainer::Add(std::string_view title,
|
2018-09-28 04:18:18 -04:00
|
|
|
bool defaultValue) {
|
|
|
|
|
return Add(title, nt::Value::MakeBoolean(defaultValue));
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
SimpleWidget& ShuffleboardContainer::Add(std::string_view title,
|
2018-09-28 04:18:18 -04:00
|
|
|
double defaultValue) {
|
|
|
|
|
return Add(title, nt::Value::MakeDouble(defaultValue));
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
SimpleWidget& ShuffleboardContainer::Add(std::string_view title,
|
2018-09-28 04:18:18 -04:00
|
|
|
int defaultValue) {
|
|
|
|
|
return Add(title, nt::Value::MakeDouble(defaultValue));
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
SimpleWidget& ShuffleboardContainer::Add(std::string_view title,
|
|
|
|
|
std::string_view defaultValue) {
|
2018-09-28 04:18:18 -04:00
|
|
|
return Add(title, nt::Value::MakeString(defaultValue));
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
SimpleWidget& ShuffleboardContainer::Add(std::string_view title,
|
2018-10-02 20:55:03 -07:00
|
|
|
const char* defaultValue) {
|
|
|
|
|
return Add(title, nt::Value::MakeString(defaultValue));
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
SimpleWidget& ShuffleboardContainer::Add(std::string_view title,
|
2021-06-06 19:51:14 -07:00
|
|
|
wpi::span<const bool> defaultValue) {
|
2018-09-28 04:18:18 -04:00
|
|
|
return Add(title, nt::Value::MakeBooleanArray(defaultValue));
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
SimpleWidget& ShuffleboardContainer::Add(std::string_view title,
|
2021-06-06 19:51:14 -07:00
|
|
|
wpi::span<const double> defaultValue) {
|
2018-09-28 04:18:18 -04:00
|
|
|
return Add(title, nt::Value::MakeDoubleArray(defaultValue));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SimpleWidget& ShuffleboardContainer::Add(
|
2021-06-06 19:51:14 -07:00
|
|
|
std::string_view title, wpi::span<const std::string> defaultValue) {
|
2018-09-28 04:18:18 -04:00
|
|
|
return Add(title, nt::Value::MakeStringArray(defaultValue));
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-30 12:45:23 -04:00
|
|
|
SuppliedValueWidget<std::string>& ShuffleboardContainer::AddString(
|
2021-05-26 17:44:18 -07:00
|
|
|
std::string_view title, std::function<std::string()> supplier) {
|
2019-05-30 12:45:23 -04:00
|
|
|
static auto setter = [](nt::NetworkTableEntry entry, std::string value) {
|
|
|
|
|
entry.SetString(value);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
CheckTitle(title);
|
|
|
|
|
auto widget = std::make_unique<SuppliedValueWidget<std::string>>(
|
|
|
|
|
*this, title, supplier, setter);
|
|
|
|
|
auto ptr = widget.get();
|
|
|
|
|
m_components.emplace_back(std::move(widget));
|
|
|
|
|
return *ptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SuppliedValueWidget<double>& ShuffleboardContainer::AddNumber(
|
2021-05-26 17:44:18 -07:00
|
|
|
std::string_view title, std::function<double()> supplier) {
|
2019-05-30 12:45:23 -04:00
|
|
|
static auto setter = [](nt::NetworkTableEntry entry, double value) {
|
|
|
|
|
entry.SetDouble(value);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
CheckTitle(title);
|
|
|
|
|
auto widget = std::make_unique<SuppliedValueWidget<double>>(*this, title,
|
|
|
|
|
supplier, setter);
|
|
|
|
|
auto ptr = widget.get();
|
|
|
|
|
m_components.emplace_back(std::move(widget));
|
|
|
|
|
return *ptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SuppliedValueWidget<bool>& ShuffleboardContainer::AddBoolean(
|
2021-05-26 17:44:18 -07:00
|
|
|
std::string_view title, std::function<bool()> supplier) {
|
2019-05-30 12:45:23 -04:00
|
|
|
static auto setter = [](nt::NetworkTableEntry entry, bool value) {
|
|
|
|
|
entry.SetBoolean(value);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
CheckTitle(title);
|
|
|
|
|
auto widget = std::make_unique<SuppliedValueWidget<bool>>(*this, title,
|
|
|
|
|
supplier, setter);
|
|
|
|
|
auto ptr = widget.get();
|
|
|
|
|
m_components.emplace_back(std::move(widget));
|
|
|
|
|
return *ptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SuppliedValueWidget<std::vector<std::string>>&
|
|
|
|
|
ShuffleboardContainer::AddStringArray(
|
2021-05-26 17:44:18 -07:00
|
|
|
std::string_view title,
|
2019-05-30 12:45:23 -04:00
|
|
|
std::function<std::vector<std::string>()> supplier) {
|
|
|
|
|
static auto setter = [](nt::NetworkTableEntry entry,
|
|
|
|
|
std::vector<std::string> value) {
|
|
|
|
|
entry.SetStringArray(value);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
CheckTitle(title);
|
|
|
|
|
auto widget = std::make_unique<SuppliedValueWidget<std::vector<std::string>>>(
|
|
|
|
|
*this, title, supplier, setter);
|
|
|
|
|
auto ptr = widget.get();
|
|
|
|
|
m_components.emplace_back(std::move(widget));
|
|
|
|
|
return *ptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SuppliedValueWidget<std::vector<double>>& ShuffleboardContainer::AddNumberArray(
|
2021-05-26 17:44:18 -07:00
|
|
|
std::string_view title, std::function<std::vector<double>()> supplier) {
|
2019-05-30 12:45:23 -04:00
|
|
|
static auto setter = [](nt::NetworkTableEntry entry,
|
|
|
|
|
std::vector<double> value) {
|
|
|
|
|
entry.SetDoubleArray(value);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
CheckTitle(title);
|
|
|
|
|
auto widget = std::make_unique<SuppliedValueWidget<std::vector<double>>>(
|
|
|
|
|
*this, title, supplier, setter);
|
|
|
|
|
auto ptr = widget.get();
|
|
|
|
|
m_components.emplace_back(std::move(widget));
|
|
|
|
|
return *ptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SuppliedValueWidget<std::vector<int>>& ShuffleboardContainer::AddBooleanArray(
|
2021-05-26 17:44:18 -07:00
|
|
|
std::string_view title, std::function<std::vector<int>()> supplier) {
|
2019-05-30 12:45:23 -04:00
|
|
|
static auto setter = [](nt::NetworkTableEntry entry, std::vector<int> value) {
|
|
|
|
|
entry.SetBooleanArray(value);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
CheckTitle(title);
|
|
|
|
|
auto widget = std::make_unique<SuppliedValueWidget<std::vector<int>>>(
|
|
|
|
|
*this, title, supplier, setter);
|
|
|
|
|
auto ptr = widget.get();
|
|
|
|
|
m_components.emplace_back(std::move(widget));
|
|
|
|
|
return *ptr;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
SuppliedValueWidget<std::string_view>& ShuffleboardContainer::AddRaw(
|
|
|
|
|
std::string_view title, std::function<std::string_view()> supplier) {
|
|
|
|
|
static auto setter = [](nt::NetworkTableEntry entry, std::string_view value) {
|
2019-05-30 12:45:23 -04:00
|
|
|
entry.SetRaw(value);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
CheckTitle(title);
|
2021-05-26 17:44:18 -07:00
|
|
|
auto widget = std::make_unique<SuppliedValueWidget<std::string_view>>(
|
2019-05-30 12:45:23 -04:00
|
|
|
*this, title, supplier, setter);
|
|
|
|
|
auto ptr = widget.get();
|
|
|
|
|
m_components.emplace_back(std::move(widget));
|
|
|
|
|
return *ptr;
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-28 04:18:18 -04:00
|
|
|
SimpleWidget& ShuffleboardContainer::AddPersistent(
|
2021-05-26 17:44:18 -07:00
|
|
|
std::string_view title, std::shared_ptr<nt::Value> defaultValue) {
|
2018-09-28 04:18:18 -04:00
|
|
|
auto& widget = Add(title, defaultValue);
|
|
|
|
|
widget.GetEntry().SetPersistent();
|
|
|
|
|
return widget;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
SimpleWidget& ShuffleboardContainer::AddPersistent(std::string_view title,
|
2018-09-28 04:18:18 -04:00
|
|
|
bool defaultValue) {
|
|
|
|
|
return AddPersistent(title, nt::Value::MakeBoolean(defaultValue));
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
SimpleWidget& ShuffleboardContainer::AddPersistent(std::string_view title,
|
2018-09-28 04:18:18 -04:00
|
|
|
double defaultValue) {
|
|
|
|
|
return AddPersistent(title, nt::Value::MakeDouble(defaultValue));
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
SimpleWidget& ShuffleboardContainer::AddPersistent(std::string_view title,
|
2018-09-28 04:18:18 -04:00
|
|
|
int defaultValue) {
|
|
|
|
|
return AddPersistent(title, nt::Value::MakeDouble(defaultValue));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SimpleWidget& ShuffleboardContainer::AddPersistent(
|
2021-05-26 17:44:18 -07:00
|
|
|
std::string_view title, std::string_view defaultValue) {
|
2018-09-28 04:18:18 -04:00
|
|
|
return AddPersistent(title, nt::Value::MakeString(defaultValue));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SimpleWidget& ShuffleboardContainer::AddPersistent(
|
2021-06-06 19:51:14 -07:00
|
|
|
std::string_view title, wpi::span<const bool> defaultValue) {
|
2018-09-28 04:18:18 -04:00
|
|
|
return AddPersistent(title, nt::Value::MakeBooleanArray(defaultValue));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SimpleWidget& ShuffleboardContainer::AddPersistent(
|
2021-06-06 19:51:14 -07:00
|
|
|
std::string_view title, wpi::span<const double> defaultValue) {
|
2018-09-28 04:18:18 -04:00
|
|
|
return AddPersistent(title, nt::Value::MakeDoubleArray(defaultValue));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SimpleWidget& ShuffleboardContainer::AddPersistent(
|
2021-06-06 19:51:14 -07:00
|
|
|
std::string_view title, wpi::span<const std::string> defaultValue) {
|
2018-09-28 04:18:18 -04:00
|
|
|
return AddPersistent(title, nt::Value::MakeStringArray(defaultValue));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ShuffleboardContainer::EnableIfActuator() {
|
|
|
|
|
for (auto& component : GetComponents()) {
|
|
|
|
|
component->EnableIfActuator();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ShuffleboardContainer::DisableIfActuator() {
|
|
|
|
|
for (auto& component : GetComponents()) {
|
|
|
|
|
component->DisableIfActuator();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-26 17:44:18 -07:00
|
|
|
void ShuffleboardContainer::CheckTitle(std::string_view title) {
|
|
|
|
|
std::string titleStr{title};
|
|
|
|
|
if (m_usedTitles.count(titleStr) > 0) {
|
2021-06-06 16:13:58 -07:00
|
|
|
FRC_ReportError(err::Error, "Title is already in use: {}", title);
|
2018-09-28 04:18:18 -04:00
|
|
|
return;
|
|
|
|
|
}
|
2021-05-26 17:44:18 -07:00
|
|
|
m_usedTitles.insert(titleStr);
|
2018-09-28 04:18:18 -04:00
|
|
|
}
|