mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-29 02:21:44 +00:00
Add fluent builders for more flexibly adding data to Shuffleboard (#1022)
This commit is contained in:
committed by
Peter Johnson
parent
ac7dfa5042
commit
175c6c1f01
@@ -0,0 +1,46 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2018 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <networktables/NetworkTable.h>
|
||||
#include <wpi/Twine.h>
|
||||
|
||||
#include "frc/shuffleboard/ShuffleboardWidget.h"
|
||||
#include "frc/smartdashboard/SendableBuilder.h"
|
||||
#include "frc/smartdashboard/SendableBuilderImpl.h"
|
||||
|
||||
namespace frc {
|
||||
|
||||
class Sendable;
|
||||
class ShuffleboardContainer;
|
||||
|
||||
/**
|
||||
* A Shuffleboard widget that handles a {@link Sendable} object such as a speed
|
||||
* controller or sensor.
|
||||
*/
|
||||
class ComplexWidget final : public ShuffleboardWidget<ComplexWidget> {
|
||||
public:
|
||||
ComplexWidget(ShuffleboardContainer& parent, const wpi::Twine& title,
|
||||
Sendable& sendable);
|
||||
|
||||
void EnableIfActuator() override;
|
||||
|
||||
void DisableIfActuator() override;
|
||||
|
||||
void BuildInto(std::shared_ptr<nt::NetworkTable> parentTable,
|
||||
std::shared_ptr<nt::NetworkTable> metaTable) override;
|
||||
|
||||
private:
|
||||
Sendable& m_sendable;
|
||||
SendableBuilderImpl m_builder;
|
||||
bool m_builderInit = false;
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
111
wpilibc/src/main/native/include/frc/shuffleboard/Shuffleboard.h
Normal file
111
wpilibc/src/main/native/include/frc/shuffleboard/Shuffleboard.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2018 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wpi/StringRef.h>
|
||||
|
||||
#include "frc/shuffleboard/ShuffleboardInstance.h"
|
||||
|
||||
namespace frc {
|
||||
|
||||
class ShuffleboardTab;
|
||||
|
||||
/**
|
||||
* The Shuffleboard class provides a mechanism with which data can be added and
|
||||
* laid out in the Shuffleboard dashboard application from a robot program. Tabs
|
||||
* and layouts can be specified, as well as choosing which widgets to display
|
||||
* with and setting properties of these widgets; for example, programmers can
|
||||
* specify a specific {@code boolean} value to be displayed with a toggle button
|
||||
* instead of the default colored box, or set custom colors for that box.
|
||||
*
|
||||
* For example, displaying a boolean entry with a toggle button:
|
||||
* <pre>{@code
|
||||
* NetworkTableEntry myBoolean = Shuffleboard.getTab("Example Tab")
|
||||
* .add("My Boolean", false)
|
||||
* .withWidget("Toggle Button")
|
||||
* .getEntry();
|
||||
* }</pre>
|
||||
*
|
||||
* Changing the colors of the boolean box:
|
||||
* <pre>{@code
|
||||
* NetworkTableEntry myBoolean = Shuffleboard.getTab("Example Tab")
|
||||
* .add("My Boolean", false)
|
||||
* .withWidget("Boolean Box")
|
||||
* .withProperties(Map.of("colorWhenTrue", "green", "colorWhenFalse",
|
||||
* "maroon")) .getEntry();
|
||||
* }</pre>
|
||||
*
|
||||
* Specifying a parent layout. Note that the layout type must <i>always</i> be
|
||||
* specified, even if the layout has already been generated by a previously
|
||||
* defined entry.
|
||||
* <pre>{@code
|
||||
* NetworkTableEntry myBoolean = Shuffleboard.getTab("Example Tab")
|
||||
* .getLayout("List", "Example List")
|
||||
* .add("My Boolean", false)
|
||||
* .withWidget("Toggle Button")
|
||||
* .getEntry();
|
||||
* }</pre>
|
||||
* </p>
|
||||
*
|
||||
* Teams are encouraged to set up shuffleboard layouts at the start of the robot
|
||||
* program.
|
||||
*/
|
||||
class Shuffleboard final {
|
||||
public:
|
||||
/**
|
||||
* The name of the base NetworkTable into which all Shuffleboard data will be
|
||||
* added.
|
||||
*/
|
||||
static constexpr const char* kBaseTableName = "/Shuffleboard";
|
||||
|
||||
/**
|
||||
* Updates all the values in Shuffleboard. Iterative and timed robots are
|
||||
* pre-configured to call this method in the main robot loop; teams using
|
||||
* custom robot base classes, or subclass SampleRobot, should make sure to
|
||||
* call this repeatedly to keep data on the dashboard up to date.
|
||||
*/
|
||||
static void Update();
|
||||
|
||||
/**
|
||||
* Gets the Shuffleboard tab with the given title, creating it if it does not
|
||||
* already exist.
|
||||
*
|
||||
* @param title the title of the tab
|
||||
* @return the tab with the given title
|
||||
*/
|
||||
static ShuffleboardTab& GetTab(wpi::StringRef title);
|
||||
|
||||
/**
|
||||
* Enables user control of widgets containing actuators: speed controllers,
|
||||
* relays, etc. This should only be used when the robot is in test mode.
|
||||
* IterativeRobotBase and SampleRobot are both configured to call this method
|
||||
* when entering test mode; most users should not need to use this method
|
||||
* directly.
|
||||
*/
|
||||
static void EnableActuatorWidgets();
|
||||
|
||||
/**
|
||||
* Disables user control of widgets containing actuators. For safety reasons,
|
||||
* actuators should only be controlled while in test mode. IterativeRobotBase
|
||||
* and SampleRobot are both configured to call this method when exiting in
|
||||
* test mode; most users should not need to use this method directly.
|
||||
*/
|
||||
static void DisableActuatorWidgets();
|
||||
|
||||
private:
|
||||
static detail::ShuffleboardInstance& GetInstance();
|
||||
|
||||
// TODO usage reporting
|
||||
|
||||
Shuffleboard() = default;
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
|
||||
// Make use of references returned by member functions usable
|
||||
#include "frc/shuffleboard/ShuffleboardTab.h"
|
||||
@@ -0,0 +1,76 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2018 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <networktables/NetworkTable.h>
|
||||
#include <networktables/NetworkTableValue.h>
|
||||
#include <wpi/StringMap.h>
|
||||
#include <wpi/Twine.h>
|
||||
|
||||
#include "frc/shuffleboard/ShuffleboardComponentBase.h"
|
||||
|
||||
namespace frc {
|
||||
|
||||
class ShuffleboardContainer;
|
||||
|
||||
/**
|
||||
* A generic component in Shuffleboard.
|
||||
*
|
||||
* @tparam Derived the self type
|
||||
*/
|
||||
template <typename Derived>
|
||||
class ShuffleboardComponent : public ShuffleboardComponentBase {
|
||||
public:
|
||||
ShuffleboardComponent(ShuffleboardContainer& parent, const wpi::Twine& title,
|
||||
const wpi::Twine& type = "");
|
||||
|
||||
virtual ~ShuffleboardComponent() = default;
|
||||
|
||||
/**
|
||||
* Sets custom properties for this component. Property names are
|
||||
* case-sensitive and whitespace-insensitive (capitalization and spaces do not
|
||||
* matter).
|
||||
*
|
||||
* @param properties the properties for this component
|
||||
* @return this component
|
||||
*/
|
||||
Derived& WithProperties(
|
||||
const wpi::StringMap<std::shared_ptr<nt::Value>>& properties);
|
||||
|
||||
/**
|
||||
* Sets the position of this component in the tab. This has no effect if this
|
||||
* component is inside a layout.
|
||||
*
|
||||
* If the position of a single component is set, it is recommended to set the
|
||||
* positions of <i>all</i> components inside a tab to prevent Shuffleboard
|
||||
* from automatically placing another component there before the one with the
|
||||
* specific position is sent.
|
||||
*
|
||||
* @param columnIndex the column in the tab to place this component
|
||||
* @param rowIndex the row in the tab to place this component
|
||||
* @return this component
|
||||
*/
|
||||
Derived& WithPosition(int columnIndex, int rowIndex);
|
||||
|
||||
/**
|
||||
* Sets the size of this component in the tab. This has no effect if this
|
||||
* component is inside a layout.
|
||||
*
|
||||
* @param width how many columns wide the component should be
|
||||
* @param height how many rows high the component should be
|
||||
* @return this component
|
||||
*/
|
||||
Derived& WithSize(int width, int height);
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
|
||||
#include "frc/shuffleboard/ShuffleboardComponent.inc"
|
||||
@@ -0,0 +1,47 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2018 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace frc {
|
||||
|
||||
template <typename Derived>
|
||||
ShuffleboardComponent<Derived>::ShuffleboardComponent(
|
||||
ShuffleboardContainer& parent, const wpi::Twine& title,
|
||||
const wpi::Twine& type)
|
||||
: ShuffleboardValue(title),
|
||||
ShuffleboardComponentBase(parent, title, type) {}
|
||||
|
||||
template <typename Derived>
|
||||
Derived& ShuffleboardComponent<Derived>::WithProperties(
|
||||
const wpi::StringMap<std::shared_ptr<nt::Value>>& properties) {
|
||||
m_properties = properties;
|
||||
m_metadataDirty = true;
|
||||
return *static_cast<Derived*>(this);
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
Derived& ShuffleboardComponent<Derived>::WithPosition(int columnIndex,
|
||||
int rowIndex) {
|
||||
m_column = columnIndex;
|
||||
m_row = rowIndex;
|
||||
m_metadataDirty = true;
|
||||
return *static_cast<Derived*>(this);
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
Derived& ShuffleboardComponent<Derived>::WithSize(int width, int height) {
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_metadataDirty = true;
|
||||
return *static_cast<Derived*>(this);
|
||||
}
|
||||
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,61 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2018 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <networktables/NetworkTable.h>
|
||||
#include <networktables/NetworkTableValue.h>
|
||||
#include <wpi/StringMap.h>
|
||||
#include <wpi/Twine.h>
|
||||
|
||||
#include "frc/shuffleboard/ShuffleboardValue.h"
|
||||
|
||||
namespace frc {
|
||||
|
||||
class ShuffleboardContainer;
|
||||
|
||||
/**
|
||||
* A shim class to allow storing ShuffleboardComponents in arrays.
|
||||
*/
|
||||
class ShuffleboardComponentBase : public virtual ShuffleboardValue {
|
||||
public:
|
||||
ShuffleboardComponentBase(ShuffleboardContainer& parent,
|
||||
const wpi::Twine& title,
|
||||
const wpi::Twine& type = "");
|
||||
|
||||
virtual ~ShuffleboardComponentBase() = default;
|
||||
|
||||
void SetType(const wpi::Twine& type);
|
||||
|
||||
void BuildMetadata(std::shared_ptr<nt::NetworkTable> metaTable);
|
||||
|
||||
ShuffleboardContainer& GetParent();
|
||||
|
||||
const std::string& GetType() const;
|
||||
|
||||
protected:
|
||||
wpi::StringMap<std::shared_ptr<nt::Value>> m_properties;
|
||||
bool m_metadataDirty = false;
|
||||
int m_column = -1;
|
||||
int m_row = -1;
|
||||
int m_width = -1;
|
||||
int m_height = -1;
|
||||
|
||||
private:
|
||||
ShuffleboardContainer& m_parent;
|
||||
std::string m_type;
|
||||
|
||||
/**
|
||||
* Gets the custom properties for this component. May be null.
|
||||
*/
|
||||
const wpi::StringMap<std::shared_ptr<nt::Value>>& GetProperties() const;
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,324 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2018 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <networktables/NetworkTableEntry.h>
|
||||
#include <networktables/NetworkTableValue.h>
|
||||
#include <wpi/ArrayRef.h>
|
||||
#include <wpi/SmallSet.h>
|
||||
#include <wpi/StringMap.h>
|
||||
#include <wpi/Twine.h>
|
||||
|
||||
#include "frc/shuffleboard/ShuffleboardComponentBase.h"
|
||||
#include "frc/shuffleboard/ShuffleboardValue.h"
|
||||
|
||||
namespace frc {
|
||||
|
||||
class ComplexWidget;
|
||||
class Sendable;
|
||||
class ShuffleboardLayout;
|
||||
class SimpleWidget;
|
||||
|
||||
/**
|
||||
* Common interface for objects that can contain shuffleboard components.
|
||||
*/
|
||||
class ShuffleboardContainer : public virtual ShuffleboardValue {
|
||||
public:
|
||||
explicit ShuffleboardContainer(const wpi::Twine& title);
|
||||
|
||||
ShuffleboardContainer(ShuffleboardContainer&& rhs) = default;
|
||||
|
||||
virtual ~ShuffleboardContainer() = default;
|
||||
|
||||
/**
|
||||
* Gets the components that are direct children of this container.
|
||||
*/
|
||||
const std::vector<std::unique_ptr<ShuffleboardComponentBase>>& GetComponents()
|
||||
const;
|
||||
|
||||
/**
|
||||
* Gets the layout with the given type and title, creating it if it does not
|
||||
* already exist at the time this method is called.
|
||||
*
|
||||
* @param type the type of the layout, eg "List" or "Grid"
|
||||
* @param title the title of the layout
|
||||
* @return the layout
|
||||
*/
|
||||
ShuffleboardLayout& GetLayout(const wpi::Twine& type,
|
||||
const wpi::Twine& title);
|
||||
|
||||
/**
|
||||
* Adds a widget to this container to display the given sendable.
|
||||
*
|
||||
* @param title the title of the widget
|
||||
* @param sendable the sendable to display
|
||||
* @return a widget to display the sendable data
|
||||
* @throws IllegalArgumentException if a widget already exists in this
|
||||
* container with the given title
|
||||
*/
|
||||
ComplexWidget& Add(const wpi::Twine& title, Sendable& sendable);
|
||||
|
||||
/**
|
||||
* Adds a widget to this container to display the given sendable.
|
||||
*
|
||||
* @param sendable the sendable to display
|
||||
* @return a widget to display the sendable data
|
||||
* @throws IllegalArgumentException if a widget already exists in this
|
||||
* container with the given title, or if the sendable's name has not been
|
||||
* specified
|
||||
*/
|
||||
ComplexWidget& Add(Sendable& sendable);
|
||||
|
||||
/**
|
||||
* Adds a widget to this container to display the given data.
|
||||
*
|
||||
* @param title the title of the widget
|
||||
* @param defaultValue the default value of the widget
|
||||
* @return a widget to display the sendable data
|
||||
* @throws IllegalArgumentException if a widget already exists in this
|
||||
* container with the given title
|
||||
* @see #addPersistent(String, Object) add(String title, Object defaultValue)
|
||||
*/
|
||||
SimpleWidget& Add(const wpi::Twine& title,
|
||||
std::shared_ptr<nt::Value> defaultValue);
|
||||
|
||||
/**
|
||||
* Adds a widget to this container to display the given data.
|
||||
*
|
||||
* @param title the title of the widget
|
||||
* @param defaultValue the default value of the widget
|
||||
* @return a widget to display the sendable data
|
||||
* @throws IllegalArgumentException if a widget already exists in this
|
||||
* container with the given title
|
||||
* @see #addPersistent(String, Object) add(String title, Object defaultValue)
|
||||
*/
|
||||
SimpleWidget& Add(const wpi::Twine& title, bool defaultValue);
|
||||
|
||||
/**
|
||||
* Adds a widget to this container to display the given data.
|
||||
*
|
||||
* @param title the title of the widget
|
||||
* @param defaultValue the default value of the widget
|
||||
* @return a widget to display the sendable data
|
||||
* @throws IllegalArgumentException if a widget already exists in this
|
||||
* container with the given title
|
||||
* @see #addPersistent(String, Object) add(String title, Object defaultValue)
|
||||
*/
|
||||
SimpleWidget& Add(const wpi::Twine& title, double defaultValue);
|
||||
|
||||
/**
|
||||
* Adds a widget to this container to display the given data.
|
||||
*
|
||||
* @param title the title of the widget
|
||||
* @param defaultValue the default value of the widget
|
||||
* @return a widget to display the sendable data
|
||||
* @throws IllegalArgumentException if a widget already exists in this
|
||||
* container with the given title
|
||||
* @see #addPersistent(String, Object) add(String title, Object defaultValue)
|
||||
*/
|
||||
SimpleWidget& Add(const wpi::Twine& title, int defaultValue);
|
||||
|
||||
/**
|
||||
* Adds a widget to this container to display the given data.
|
||||
*
|
||||
* @param title the title of the widget
|
||||
* @param defaultValue the default value of the widget
|
||||
* @return a widget to display the sendable data
|
||||
* @throws IllegalArgumentException if a widget already exists in this
|
||||
* container with the given title
|
||||
* @see #addPersistent(String, Object) add(String title, Object defaultValue)
|
||||
*/
|
||||
SimpleWidget& Add(const wpi::Twine& title, const wpi::Twine& defaultValue);
|
||||
|
||||
/**
|
||||
* Adds a widget to this container to display the given data.
|
||||
*
|
||||
* @param title the title of the widget
|
||||
* @param defaultValue the default value of the widget
|
||||
* @return a widget to display the sendable data
|
||||
* @throws IllegalArgumentException if a widget already exists in this
|
||||
* container with the given title
|
||||
* @see #addPersistent(String, Object) add(String title, Object defaultValue)
|
||||
*/
|
||||
SimpleWidget& Add(const wpi::Twine& title, wpi::ArrayRef<bool> defaultValue);
|
||||
|
||||
/**
|
||||
* Adds a widget to this container to display the given data.
|
||||
*
|
||||
* @param title the title of the widget
|
||||
* @param defaultValue the default value of the widget
|
||||
* @return a widget to display the sendable data
|
||||
* @throws IllegalArgumentException if a widget already exists in this
|
||||
* container with the given title
|
||||
* @see #addPersistent(String, Object) add(String title, Object defaultValue)
|
||||
*/
|
||||
SimpleWidget& Add(const wpi::Twine& title,
|
||||
wpi::ArrayRef<double> defaultValue);
|
||||
|
||||
/**
|
||||
* Adds a widget to this container to display the given data.
|
||||
*
|
||||
* @param title the title of the widget
|
||||
* @param defaultValue the default value of the widget
|
||||
* @return a widget to display the sendable data
|
||||
* @throws IllegalArgumentException if a widget already exists in this
|
||||
* container with the given title
|
||||
* @see #addPersistent(String, Object) add(String title, Object defaultValue)
|
||||
*/
|
||||
SimpleWidget& Add(const wpi::Twine& title,
|
||||
wpi::ArrayRef<std::string> defaultValue);
|
||||
|
||||
/**
|
||||
* Adds a widget to this container to display a simple piece of data.
|
||||
*
|
||||
* Unlike {@link #add(String, Object)}, the value in the widget will be saved
|
||||
* on the robot and will be used when the robot program next starts rather
|
||||
* than {@code defaultValue}.
|
||||
*
|
||||
* @param title the title of the widget
|
||||
* @param defaultValue the default value of the widget
|
||||
* @return a widget to display the sendable data
|
||||
* @see #add(String, Object) add(String title, Object defaultValue)
|
||||
*/
|
||||
SimpleWidget& AddPersistent(const wpi::Twine& title,
|
||||
std::shared_ptr<nt::Value> defaultValue);
|
||||
|
||||
/**
|
||||
* Adds a widget to this container to display a simple piece of data.
|
||||
*
|
||||
* Unlike {@link #add(String, Object)}, the value in the widget will be saved
|
||||
* on the robot and will be used when the robot program next starts rather
|
||||
* than {@code defaultValue}.
|
||||
*
|
||||
* @param title the title of the widget
|
||||
* @param defaultValue the default value of the widget
|
||||
* @return a widget to display the sendable data
|
||||
* @see #add(String, Object) add(String title, Object defaultValue)
|
||||
*/
|
||||
SimpleWidget& AddPersistent(const wpi::Twine& title, bool defaultValue);
|
||||
|
||||
/**
|
||||
* Adds a widget to this container to display a simple piece of data.
|
||||
*
|
||||
* Unlike {@link #add(String, Object)}, the value in the widget will be saved
|
||||
* on the robot and will be used when the robot program next starts rather
|
||||
* than {@code defaultValue}.
|
||||
*
|
||||
* @param title the title of the widget
|
||||
* @param defaultValue the default value of the widget
|
||||
* @return a widget to display the sendable data
|
||||
* @see #add(String, Object) add(String title, Object defaultValue)
|
||||
*/
|
||||
SimpleWidget& AddPersistent(const wpi::Twine& title, double defaultValue);
|
||||
|
||||
/**
|
||||
* Adds a widget to this container to display a simple piece of data.
|
||||
*
|
||||
* Unlike {@link #add(String, Object)}, the value in the widget will be saved
|
||||
* on the robot and will be used when the robot program next starts rather
|
||||
* than {@code defaultValue}.
|
||||
*
|
||||
* @param title the title of the widget
|
||||
* @param defaultValue the default value of the widget
|
||||
* @return a widget to display the sendable data
|
||||
* @see #add(String, Object) add(String title, Object defaultValue)
|
||||
*/
|
||||
SimpleWidget& AddPersistent(const wpi::Twine& title, int defaultValue);
|
||||
|
||||
/**
|
||||
* Adds a widget to this container to display a simple piece of data.
|
||||
*
|
||||
* Unlike {@link #add(String, Object)}, the value in the widget will be saved
|
||||
* on the robot and will be used when the robot program next starts rather
|
||||
* than {@code defaultValue}.
|
||||
*
|
||||
* @param title the title of the widget
|
||||
* @param defaultValue the default value of the widget
|
||||
* @return a widget to display the sendable data
|
||||
* @see #add(String, Object) add(String title, Object defaultValue)
|
||||
*/
|
||||
SimpleWidget& AddPersistent(const wpi::Twine& title,
|
||||
const wpi::Twine& defaultValue);
|
||||
|
||||
/**
|
||||
* Adds a widget to this container to display a simple piece of data.
|
||||
*
|
||||
* Unlike {@link #add(String, Object)}, the value in the widget will be saved
|
||||
* on the robot and will be used when the robot program next starts rather
|
||||
* than {@code defaultValue}.
|
||||
*
|
||||
* @param title the title of the widget
|
||||
* @param defaultValue the default value of the widget
|
||||
* @return a widget to display the sendable data
|
||||
* @see #add(String, Object) add(String title, Object defaultValue)
|
||||
*/
|
||||
SimpleWidget& AddPersistent(const wpi::Twine& title,
|
||||
wpi::ArrayRef<bool> defaultValue);
|
||||
|
||||
/**
|
||||
* Adds a widget to this container to display a simple piece of data.
|
||||
*
|
||||
* Unlike {@link #add(String, Object)}, the value in the widget will be saved
|
||||
* on the robot and will be used when the robot program next starts rather
|
||||
* than {@code defaultValue}.
|
||||
*
|
||||
* @param title the title of the widget
|
||||
* @param defaultValue the default value of the widget
|
||||
* @return a widget to display the sendable data
|
||||
* @see #add(String, Object) add(String title, Object defaultValue)
|
||||
*/
|
||||
SimpleWidget& AddPersistent(const wpi::Twine& title,
|
||||
wpi::ArrayRef<double> defaultValue);
|
||||
|
||||
/**
|
||||
* Adds a widget to this container to display a simple piece of data.
|
||||
*
|
||||
* Unlike {@link #add(String, Object)}, the value in the widget will be saved
|
||||
* on the robot and will be used when the robot program next starts rather
|
||||
* than {@code defaultValue}.
|
||||
*
|
||||
* @param title the title of the widget
|
||||
* @param defaultValue the default value of the widget
|
||||
* @return a widget to display the sendable data
|
||||
* @see #add(String, Object) add(String title, Object defaultValue)
|
||||
*/
|
||||
SimpleWidget& AddPersistent(const wpi::Twine& title,
|
||||
wpi::ArrayRef<std::string> defaultValue);
|
||||
|
||||
void EnableIfActuator() override;
|
||||
|
||||
void DisableIfActuator() override;
|
||||
|
||||
protected:
|
||||
bool m_isLayout = false;
|
||||
|
||||
private:
|
||||
wpi::SmallSet<std::string, 32> m_usedTitles;
|
||||
std::vector<std::unique_ptr<ShuffleboardComponentBase>> m_components;
|
||||
wpi::StringMap<ShuffleboardLayout*> m_layouts;
|
||||
|
||||
/**
|
||||
* Adds title to internal set if it hasn't already.
|
||||
*
|
||||
* @return True if title isn't in use; false otherwise.
|
||||
*/
|
||||
void CheckTitle(const wpi::Twine& title);
|
||||
|
||||
friend class SimpleWidget;
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
|
||||
// Make use of references returned by member functions usable
|
||||
#include "frc/shuffleboard/ComplexWidget.h"
|
||||
#include "frc/shuffleboard/ShuffleboardLayout.h"
|
||||
#include "frc/shuffleboard/SimpleWidget.h"
|
||||
@@ -0,0 +1,37 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2018 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "frc/shuffleboard/ShuffleboardRoot.h"
|
||||
#include "frc/shuffleboard/ShuffleboardTab.h"
|
||||
|
||||
namespace frc {
|
||||
namespace detail {
|
||||
|
||||
class ShuffleboardInstance final : public ShuffleboardRoot {
|
||||
public:
|
||||
explicit ShuffleboardInstance(nt::NetworkTableInstance ntInstance);
|
||||
virtual ~ShuffleboardInstance();
|
||||
|
||||
frc::ShuffleboardTab& GetTab(wpi::StringRef title) override;
|
||||
|
||||
void Update() override;
|
||||
|
||||
void EnableActuatorWidgets() override;
|
||||
|
||||
void DisableActuatorWidgets() override;
|
||||
|
||||
private:
|
||||
struct Impl;
|
||||
std::unique_ptr<Impl> m_impl;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,35 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2018 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <networktables/NetworkTable.h>
|
||||
#include <wpi/Twine.h>
|
||||
|
||||
#include "frc/shuffleboard/ShuffleboardComponent.h"
|
||||
#include "frc/shuffleboard/ShuffleboardContainer.h"
|
||||
#include "frc/smartdashboard/Sendable.h"
|
||||
|
||||
namespace frc {
|
||||
|
||||
/**
|
||||
* A layout in a Shuffleboard tab. Layouts can contain widgets and other
|
||||
* layouts.
|
||||
*/
|
||||
class ShuffleboardLayout : public ShuffleboardComponent<ShuffleboardLayout>,
|
||||
public ShuffleboardContainer {
|
||||
public:
|
||||
ShuffleboardLayout(ShuffleboardContainer& parent, const wpi::Twine& name,
|
||||
const wpi::Twine& type);
|
||||
|
||||
void BuildInto(std::shared_ptr<nt::NetworkTable> parentTable,
|
||||
std::shared_ptr<nt::NetworkTable> metaTable) override;
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,50 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2018 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wpi/StringRef.h>
|
||||
|
||||
namespace frc {
|
||||
|
||||
class ShuffleboardTab;
|
||||
|
||||
/**
|
||||
* The root of the data placed in Shuffleboard. It contains the tabs, but no
|
||||
* data is placed directly in the root.
|
||||
*
|
||||
* This class is package-private to minimize API surface area.
|
||||
*/
|
||||
class ShuffleboardRoot {
|
||||
public:
|
||||
/**
|
||||
* Gets the tab with the given title, creating it if it does not already
|
||||
* exist.
|
||||
*
|
||||
* @param title the title of the tab
|
||||
* @return the tab with the given title
|
||||
*/
|
||||
virtual ShuffleboardTab& GetTab(wpi::StringRef title) = 0;
|
||||
|
||||
/**
|
||||
* Updates all tabs.
|
||||
*/
|
||||
virtual void Update() = 0;
|
||||
|
||||
/**
|
||||
* Enables all widgets in Shuffleboard that offer user control over actuators.
|
||||
*/
|
||||
virtual void EnableActuatorWidgets() = 0;
|
||||
|
||||
/**
|
||||
* Disables all widgets in Shuffleboard that offer user control over
|
||||
* actuators.
|
||||
*/
|
||||
virtual void DisableActuatorWidgets() = 0;
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,42 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2018 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <networktables/NetworkTable.h>
|
||||
#include <wpi/StringRef.h>
|
||||
|
||||
#include "frc/shuffleboard/ShuffleboardContainer.h"
|
||||
#include "frc/smartdashboard/Sendable.h"
|
||||
|
||||
namespace frc {
|
||||
|
||||
class ShuffleboardRoot;
|
||||
|
||||
/**
|
||||
* Represents a tab in the Shuffleboard dashboard. Widgets can be added to the
|
||||
* tab with {@link #add(Sendable)}, {@link #add(String, Object)}, and
|
||||
* {@link #add(String, Sendable)}. Widgets can also be added to layouts with
|
||||
* {@link #getLayout(String, String)}; layouts can be nested arbitrarily deep
|
||||
* (note that too many levels may make deeper components unusable).
|
||||
*/
|
||||
class ShuffleboardTab final : public ShuffleboardContainer {
|
||||
public:
|
||||
ShuffleboardTab(ShuffleboardRoot& root, wpi::StringRef title);
|
||||
|
||||
ShuffleboardRoot& GetRoot();
|
||||
|
||||
void BuildInto(std::shared_ptr<nt::NetworkTable> parentTable,
|
||||
std::shared_ptr<nt::NetworkTable> metaTable) override;
|
||||
|
||||
private:
|
||||
ShuffleboardRoot& m_root;
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,71 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2018 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <networktables/NetworkTable.h>
|
||||
#include <wpi/SmallVector.h>
|
||||
#include <wpi/StringRef.h>
|
||||
|
||||
namespace frc {
|
||||
|
||||
class ShuffleboardValue {
|
||||
public:
|
||||
explicit ShuffleboardValue(const wpi::Twine& title) {
|
||||
wpi::SmallVector<char, 16> storage;
|
||||
m_title = title.toStringRef(storage);
|
||||
}
|
||||
|
||||
virtual ~ShuffleboardValue() = default;
|
||||
|
||||
/**
|
||||
* Gets the title of this Shuffleboard value.
|
||||
*/
|
||||
wpi::StringRef GetTitle() const { return m_title; }
|
||||
|
||||
/**
|
||||
* Builds the entries for this value.
|
||||
*
|
||||
* @param parentTable The table containing all the data for the parent. Values
|
||||
* that require a complex entry or table structure should
|
||||
* call {@code parentTable.getSubtable(getTitle())} to get
|
||||
* the table to put data into. Values that only use a
|
||||
* single entry should call
|
||||
* {@code parentTable.getEntry(getTitle())} to get that
|
||||
* entry.
|
||||
* @param metaTable The table containing all the metadata for this value and
|
||||
* its sub-values
|
||||
*/
|
||||
virtual void BuildInto(std::shared_ptr<nt::NetworkTable> parentTable,
|
||||
std::shared_ptr<nt::NetworkTable> metaTable) = 0;
|
||||
|
||||
/**
|
||||
* Enables user control of this widget in the Shuffleboard application.
|
||||
*
|
||||
* This method is package-private to prevent users from enabling control
|
||||
* themselves. Has no effect if the sendable is not marked as an actuator with
|
||||
* {@link SendableBuilder#setActuator}.
|
||||
*/
|
||||
virtual void EnableIfActuator() {}
|
||||
|
||||
/**
|
||||
* Disables user control of this widget in the Shuffleboard application.
|
||||
*
|
||||
* This method is package-private to prevent users from enabling control
|
||||
* themselves. Has no effect if the sendable is not marked as an actuator with
|
||||
* {@link SendableBuilder#setActuator}.
|
||||
*/
|
||||
virtual void DisableIfActuator() {}
|
||||
|
||||
private:
|
||||
std::string m_title;
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,46 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2018 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wpi/Twine.h>
|
||||
|
||||
#include "frc/shuffleboard/ShuffleboardComponent.h"
|
||||
|
||||
namespace frc {
|
||||
|
||||
class ShuffleboardContainer;
|
||||
|
||||
/**
|
||||
* Abstract superclass for widgets.
|
||||
*
|
||||
* <p>This class is package-private to minimize API surface area.
|
||||
*
|
||||
* @tparam Derived the self type
|
||||
*/
|
||||
template <typename Derived>
|
||||
class ShuffleboardWidget
|
||||
: public ShuffleboardComponent<ShuffleboardWidget<Derived>> {
|
||||
public:
|
||||
ShuffleboardWidget(ShuffleboardContainer& parent, const wpi::Twine& title)
|
||||
: ShuffleboardValue(title),
|
||||
ShuffleboardComponent<ShuffleboardWidget<Derived>>(parent, title) {}
|
||||
|
||||
/**
|
||||
* Sets the type of widget used to display the data. If not set, the default
|
||||
* widget type will be used.
|
||||
*
|
||||
* @param widgetType the type of the widget used to display the data
|
||||
* @return this widget object
|
||||
*/
|
||||
Derived& WithWidget(const wpi::Twine& widgetType) {
|
||||
this->SetType(widgetType);
|
||||
return *static_cast<Derived*>(this);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
@@ -0,0 +1,45 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2018 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <networktables/NetworkTable.h>
|
||||
#include <networktables/NetworkTableEntry.h>
|
||||
#include <wpi/Twine.h>
|
||||
|
||||
#include "frc/shuffleboard/ShuffleboardWidget.h"
|
||||
|
||||
namespace frc {
|
||||
|
||||
class ShuffleboardContainer;
|
||||
|
||||
/**
|
||||
* A Shuffleboard widget that handles a single data point such as a number or
|
||||
* string.
|
||||
*/
|
||||
class SimpleWidget final : public ShuffleboardWidget<SimpleWidget> {
|
||||
public:
|
||||
SimpleWidget(ShuffleboardContainer& parent, const wpi::Twine& title);
|
||||
|
||||
/**
|
||||
* Gets the NetworkTable entry that contains the data for this widget.
|
||||
*/
|
||||
nt::NetworkTableEntry GetEntry();
|
||||
|
||||
void BuildInto(std::shared_ptr<nt::NetworkTable> parentTable,
|
||||
std::shared_ptr<nt::NetworkTable> metaTable) override;
|
||||
|
||||
private:
|
||||
nt::NetworkTableEntry m_entry;
|
||||
bool m_entryInitialized = false;
|
||||
|
||||
void ForceGenerate();
|
||||
};
|
||||
|
||||
} // namespace frc
|
||||
Reference in New Issue
Block a user