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

[glass] Add NetworkTables view entry order setting #7715

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 21 additions & 0 deletions glass/src/lib/native/cpp/support/EnumSetting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,27 @@ bool EnumSetting::Combo(const char* label, int numOptions,
return false;
}

bool EnumSetting::Menu(const char* label) {
if (m_value == -1) {
UpdateValue();
}

int i = 0;
bool change = false;
if (ImGui::BeginMenu(label)) {
for (auto choice : m_choices) {
if (ImGui::MenuItem(choice, nullptr, i == m_value)) {
SetValue(i);
change = true;
}
++i;
}
ImGui::EndMenu();
}

return change;
}

void EnumSetting::UpdateValue() const {
// override default value if str is one of the choices
int i = 0;
Expand Down
2 changes: 2 additions & 0 deletions glass/src/lib/native/include/glass/support/EnumSetting.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ class EnumSetting {
bool Combo(const char* label, int numOptions = -1,
int popup_max_height_in_items = -1);

bool Menu(const char* label);

private:
void UpdateValue() const;

Expand Down
190 changes: 140 additions & 50 deletions glass/src/libnt/native/cpp/NetworkTables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1667,38 +1667,78 @@ static void EmitValueName(DataSource* source, const char* name,

static void EmitValueTree(
const std::vector<NetworkTablesModel::EntryValueTreeNode>& children,
NetworkTablesFlags flags);

static void EmitValueTreeChild(
const NetworkTablesModel::EntryValueTreeNode& child,
NetworkTablesFlags flags) {
for (auto&& child : children) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
EmitValueName(child.source.get(), child.name.c_str(), child.path.c_str());
ImGui::TableNextRow();
ImGui::TableNextColumn();
EmitValueName(child.source.get(), child.name.c_str(), child.path.c_str());

ImGui::TableNextColumn();
if (!child.valueChildren.empty()) {
auto pos = ImGui::GetCursorPos();
char label[128];
std::string_view ts = child.typeStr;
bool havePopup = GetHeadingTypeString(&ts);
wpi::format_to_n_c_str(label, sizeof(label), "{}##v_{}", ts.data(),
child.name.c_str());
bool valueChildrenOpen =
TreeNodeEx(label, ImGuiTreeNodeFlags_SpanFullWidth);
if (havePopup) {
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
ImGui::TextUnformatted(child.typeStr.c_str());
ImGui::EndTooltip();
}
ImGui::TableNextColumn();
if (!child.valueChildren.empty()) {
auto pos = ImGui::GetCursorPos();
char label[128];
std::string_view ts = child.typeStr;
bool havePopup = GetHeadingTypeString(&ts);
wpi::format_to_n_c_str(label, sizeof(label), "{}##v_{}", ts.data(),
child.name.c_str());
bool valueChildrenOpen =
TreeNodeEx(label, ImGuiTreeNodeFlags_SpanFullWidth);
if (havePopup) {
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
ImGui::TextUnformatted(child.typeStr.c_str());
ImGui::EndTooltip();
}
// make it look like a normal label w/type
ImGui::SetCursorPos(pos);
ImGui::LabelText(child.valueChildrenMap ? "{...}" : "[...]", "%s", "");
if (valueChildrenOpen) {
EmitValueTree(child.valueChildren, flags);
TreePop();
}
// make it look like a normal label w/type
ImGui::SetCursorPos(pos);
ImGui::LabelText(child.valueChildrenMap ? "{...}" : "[...]", "%s", "");
if (valueChildrenOpen) {
EmitValueTree(child.valueChildren, flags);
TreePop();
}
} else {
EmitEntryValueReadonly(child, nullptr, flags);
}
}

static void EmitValueTree(
const std::vector<NetworkTablesModel::EntryValueTreeNode>& children,
NetworkTablesFlags flags) {
NetworkTablesOrdering order = (flags & NetworkTablesFlags_Ordering) >>
kNetworkTablesFlags_OrderingBitShift;

if (order == NetworkTablesOrdering_Combined) {
// All in order
for (auto&& child : children) {
EmitValueTreeChild(child, flags);
}
} else if (order == NetworkTablesOrdering_EntriesFirst) {
// All entries, then all subtables
for (auto&& child : children) {
if (child.valueChildren.empty()) {
EmitValueTreeChild(child, flags);
}
}
for (auto&& child : children) {
if (!child.valueChildren.empty()) {
EmitValueTreeChild(child, flags);
}
}
} else if (order == NetworkTablesOrdering_SubtablesFirst) {
// All subtables, then all entries
for (auto&& child : children) {
if (!child.valueChildren.empty()) {
EmitValueTreeChild(child, flags);
}
}
for (auto&& child : children) {
if (child.valueChildren.empty()) {
EmitValueTreeChild(child, flags);
}
} else {
EmitEntryValueReadonly(child, nullptr, flags);
}
}
}
Expand Down Expand Up @@ -1829,28 +1869,69 @@ static void EmitEntry(NetworkTablesModel* model,
}
}

static void EmitTree(NetworkTablesModel* model,
const std::vector<NetworkTablesModel::TreeNode>& tree,
NetworkTablesFlags flags, ShowCategory category,
bool root);

static void EmitTreeNode(NetworkTablesModel* model,
const NetworkTablesModel::TreeNode& node,
NetworkTablesFlags flags, ShowCategory category,
bool root) {
if (root && (flags & NetworkTablesFlags_ShowSpecial) == 0 &&
wpi::starts_with(node.name, '$')) {
return;
}
if (node.entry) {
EmitEntry(model, *node.entry, node.name.c_str(), flags, category);
}

if (!node.children.empty()) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
bool open = TreeNodeEx(node.name.c_str(), ImGuiTreeNodeFlags_SpanFullWidth);
EmitParentContextMenu(model, node.path, flags);
if (open) {
EmitTree(model, node.children, flags, category, false);
TreePop();
}
}
}

static void EmitTree(NetworkTablesModel* model,
const std::vector<NetworkTablesModel::TreeNode>& tree,
NetworkTablesFlags flags, ShowCategory category,
bool root) {
for (auto&& node : tree) {
if (root && (flags & NetworkTablesFlags_ShowSpecial) == 0 &&
wpi::starts_with(node.name, '$')) {
continue;
NetworkTablesOrdering order = (flags & NetworkTablesFlags_Ordering) >>
kNetworkTablesFlags_OrderingBitShift;

if (order == NetworkTablesOrdering_Combined) {
// All in order
for (auto&& node : tree) {
EmitTreeNode(model, node, flags, category, root);
}
} else if (order == NetworkTablesOrdering_EntriesFirst) {
// All entries, then all subtables
for (auto&& node : tree) {
if (node.entry) {
EmitTreeNode(model, node, flags, category, root);
}
}
if (node.entry) {
EmitEntry(model, *node.entry, node.name.c_str(), flags, category);
for (auto&& node : tree) {
if (!node.entry) {
EmitTreeNode(model, node, flags, category, root);
}
}

if (!node.children.empty()) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
bool open =
TreeNodeEx(node.name.c_str(), ImGuiTreeNodeFlags_SpanFullWidth);
EmitParentContextMenu(model, node.path, flags);
if (open) {
EmitTree(model, node.children, flags, category, false);
TreePop();
} else if (order == NetworkTablesOrdering_SubtablesFirst) {
// All subtables, then all entries
for (auto&& node : tree) {
if (!node.entry) {
EmitTreeNode(model, node, flags, category, root);
}
}
for (auto&& node : tree) {
if (node.entry) {
EmitTreeNode(model, node, flags, category, root);
}
}
}
Expand Down Expand Up @@ -2073,17 +2154,24 @@ void NetworkTablesFlagsSettings::Update() {
m_pCreateNoncanonicalKeys = &storage.GetBool(
"createNonCanonical",
m_defaultFlags & NetworkTablesFlags_CreateNoncanonicalKeys);
m_pOrdering = std::make_unique<EnumSetting>(
storage.GetString("ordering"),
(m_defaultFlags & NetworkTablesFlags_Ordering) >>
kNetworkTablesFlags_OrderingBitShift,
std::initializer_list<const char*>(
{"Combined", "Entries First", "Subtables First"}));
m_pPrecision = &storage.GetInt(
"precision", (m_defaultFlags & NetworkTablesFlags_Precision) >>
kNetworkTablesFlags_PrecisionBitShift);
}

m_flags &= ~(
NetworkTablesFlags_TreeView | NetworkTablesFlags_CombinedView |
NetworkTablesFlags_ShowSpecial | NetworkTablesFlags_ShowProperties |
NetworkTablesFlags_ShowTimestamp |
NetworkTablesFlags_ShowServerTimestamp |
NetworkTablesFlags_CreateNoncanonicalKeys | NetworkTablesFlags_Precision);
m_flags &=
~(NetworkTablesFlags_TreeView | NetworkTablesFlags_CombinedView |
NetworkTablesFlags_ShowSpecial | NetworkTablesFlags_ShowProperties |
NetworkTablesFlags_ShowTimestamp |
NetworkTablesFlags_ShowServerTimestamp |
NetworkTablesFlags_CreateNoncanonicalKeys |
NetworkTablesFlags_Ordering | NetworkTablesFlags_Precision);
m_flags |=
(*m_pTreeView ? NetworkTablesFlags_TreeView : 0) |
(*m_pCombinedView ? NetworkTablesFlags_CombinedView : 0) |
Expand All @@ -2093,6 +2181,7 @@ void NetworkTablesFlagsSettings::Update() {
(*m_pShowServerTimestamp ? NetworkTablesFlags_ShowServerTimestamp : 0) |
(*m_pCreateNoncanonicalKeys ? NetworkTablesFlags_CreateNoncanonicalKeys
: 0) |
(m_pOrdering->GetValue() << kNetworkTablesFlags_OrderingBitShift) |
(*m_pPrecision << kNetworkTablesFlags_PrecisionBitShift);
}

Expand All @@ -2106,6 +2195,7 @@ void NetworkTablesFlagsSettings::DisplayMenu() {
ImGui::MenuItem("Show Properties", "", m_pShowProperties);
ImGui::MenuItem("Show Timestamp", "", m_pShowTimestamp);
ImGui::MenuItem("Show Server Timestamp", "", m_pShowServerTimestamp);
m_pOrdering->Menu("Entry Ordering");
if (ImGui::BeginMenu("Decimal Precision")) {
static const char* precisionOptions[] = {"1", "2", "3", "4", "5",
"6", "7", "8", "9", "10"};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include "glass/Model.h"
#include "glass/View.h"
#include "glass/support/EnumSetting.h"

namespace glass {

Expand Down Expand Up @@ -201,9 +202,18 @@ class NetworkTablesModel : public Model {
#endif
};

using NetworkTablesOrdering = int;

enum NetworkTablesOrdering_ {
NetworkTablesOrdering_Combined = 0,
NetworkTablesOrdering_EntriesFirst,
NetworkTablesOrdering_SubtablesFirst,
};

using NetworkTablesFlags = int;

static constexpr const int kNetworkTablesFlags_PrecisionBitShift = 9;
static constexpr const int kNetworkTablesFlags_OrderingBitShift = 9;
static constexpr const int kNetworkTablesFlags_PrecisionBitShift = 11;

enum NetworkTablesFlags_ {
NetworkTablesFlags_TreeView = 1 << 0,
Expand All @@ -214,6 +224,7 @@ enum NetworkTablesFlags_ {
NetworkTablesFlags_ShowTimestamp = 1 << 5,
NetworkTablesFlags_ShowServerTimestamp = 1 << 6,
NetworkTablesFlags_CreateNoncanonicalKeys = 1 << 7,
NetworkTablesFlags_Ordering = 0b11 << kNetworkTablesFlags_OrderingBitShift,
rmheuer marked this conversation as resolved.
Show resolved Hide resolved
NetworkTablesFlags_Precision = 0xff << kNetworkTablesFlags_PrecisionBitShift,
NetworkTablesFlags_Default = NetworkTablesFlags_TreeView |
(6 << kNetworkTablesFlags_PrecisionBitShift),
Expand Down Expand Up @@ -248,6 +259,7 @@ class NetworkTablesFlagsSettings {
bool* m_pShowTimestamp = nullptr;
bool* m_pShowServerTimestamp = nullptr;
bool* m_pCreateNoncanonicalKeys = nullptr;
std::unique_ptr<EnumSetting> m_pOrdering; // NetworkTablesOrdering
int* m_pPrecision = nullptr;
NetworkTablesFlags m_defaultFlags; // NOLINT
NetworkTablesFlags m_flags; // NOLINT
Expand Down
Loading