diff --git a/glass/src/libnt/native/cpp/NetworkTables.cpp b/glass/src/libnt/native/cpp/NetworkTables.cpp index a0525b8cf98..57469a20bdc 100644 --- a/glass/src/libnt/native/cpp/NetworkTables.cpp +++ b/glass/src/libnt/native/cpp/NetworkTables.cpp @@ -1071,7 +1071,7 @@ void NetworkTablesModel::UpdateClients(std::span data) { m_clients = std::move(newClients); } -static bool SimplifyTypeString(std::string_view* ts) { +static bool GetHeadingTypeString(std::string_view* ts) { if (wpi::starts_with(*ts, "proto:")) { *ts = wpi::drop_front(*ts, 6); auto lastdot = ts->rfind('.'); @@ -1089,7 +1089,20 @@ static bool SimplifyTypeString(std::string_view* ts) { return false; } -static std::string_view GetTypeString(NT_Type type) { +static const char* GetShortTypeString(std::string_view ts) { + if (wpi::starts_with(ts, "proto:")) { + return "protobuf"; + } else if (wpi::starts_with(ts, "struct:")) { + return "struct"; + } else { + return ts.data(); + } +} + +static const char* GetTypeString(NT_Type type, const char* overrideTypeStr) { + if (overrideTypeStr) { + return GetShortTypeString(overrideTypeStr); + } switch (type) { case NT_BOOLEAN: return "boolean"; @@ -1128,21 +1141,19 @@ static void EmitEntryValueReadonly(const NetworkTablesModel::ValueSource& entry, return; } - std::string_view typeStr = - overrideTypeStr ? overrideTypeStr : GetTypeString(val.type()); - ImGui::SetNextItemWidth(-1 * (ImGui::CalcTextSize(typeStr.data()).x + - ImGui::GetStyle().FramePadding.x)); + const char* typeStr = GetTypeString(val.type(), overrideTypeStr); + ImGui::SetNextItemWidth( + -1 * (ImGui::CalcTextSize(typeStr).x + ImGui::GetStyle().FramePadding.x)); switch (val.type()) { case NT_BOOLEAN: - ImGui::LabelText(typeStr.data(), "%s", - val.GetBoolean() ? "true" : "false"); + ImGui::LabelText(typeStr, "%s", val.GetBoolean() ? "true" : "false"); break; case NT_INTEGER: - ImGui::LabelText(typeStr.data(), "%" PRId64, val.GetInteger()); + ImGui::LabelText(typeStr, "%" PRId64, val.GetInteger()); break; case NT_FLOAT: - ImGui::LabelText(typeStr.data(), "%.6f", val.GetFloat()); + ImGui::LabelText(typeStr, "%.6f", val.GetFloat()); break; case NT_DOUBLE: { unsigned char precision = (flags & NetworkTablesFlags_Precision) >> @@ -1151,7 +1162,7 @@ static void EmitEntryValueReadonly(const NetworkTablesModel::ValueSource& entry, #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat-nonliteral" #endif - ImGui::LabelText(typeStr.data(), fmt::format("%.{}f", precision).c_str(), + ImGui::LabelText(typeStr, fmt::format("%.{}f", precision).c_str(), val.GetDouble()); #ifdef __GNUC__ #pragma GCC diagnostic pop @@ -1159,32 +1170,22 @@ static void EmitEntryValueReadonly(const NetworkTablesModel::ValueSource& entry, break; } case NT_STRING: { - ImGui::LabelText(typeStr.data(), "%s", entry.valueStr.c_str()); + ImGui::LabelText(typeStr, "%s", entry.valueStr.c_str()); break; } case NT_BOOLEAN_ARRAY: - ImGui::LabelText(typeStr.data(), "[]"); - break; case NT_INTEGER_ARRAY: - ImGui::LabelText(typeStr.data(), "[]"); - break; case NT_FLOAT_ARRAY: - ImGui::LabelText(typeStr.data(), "[]"); - break; case NT_DOUBLE_ARRAY: - ImGui::LabelText(typeStr.data(), "[]"); - break; case NT_STRING_ARRAY: - ImGui::LabelText(typeStr.data(), "[]"); + ImGui::LabelText(typeStr, "[]"); break; case NT_RAW: { - std::string_view ts = typeStr; - bool partial = SimplifyTypeString(&ts); - ImGui::LabelText(val.GetRaw().empty() ? "[]" : "[...]", "%s", ts.data()); + ImGui::LabelText(typeStr, val.GetRaw().empty() ? "[]" : "[...]"); if (ImGui::IsItemHovered()) { ImGui::BeginTooltip(); - if (partial) { - ImGui::TextUnformatted(typeStr.data()); + if (overrideTypeStr) { + ImGui::TextUnformatted(overrideTypeStr); } ImGui::Text("%u bytes", static_cast(val.GetRaw().size())); ImGui::EndTooltip(); @@ -1192,7 +1193,7 @@ static void EmitEntryValueReadonly(const NetworkTablesModel::ValueSource& entry, break; } default: - ImGui::LabelText(typeStr.data(), "?"); + ImGui::LabelText(typeStr, "?"); break; } } @@ -1354,18 +1355,18 @@ static void EmitEntryValueEditable(NetworkTablesModel* model, return; } - std::string_view typeStr = entry.info.type_str.empty() - ? entry.info.type_str - : GetTypeString(val.type()); - ImGui::SetNextItemWidth(-1 * (ImGui::CalcTextSize(typeStr.data()).x + - ImGui::GetStyle().FramePadding.x)); + const char* typeStr = GetTypeString( + val.type(), + entry.info.type_str.empty() ? nullptr : entry.info.type_str.c_str()); + ImGui::SetNextItemWidth( + -1 * (ImGui::CalcTextSize(typeStr).x + ImGui::GetStyle().FramePadding.x)); ImGui::PushID(entry.info.name.c_str()); switch (val.type()) { case NT_BOOLEAN: { static const char* boolOptions[] = {"false", "true"}; int v = val.GetBoolean() ? 1 : 0; - if (ImGui::Combo(typeStr.data(), &v, boolOptions, 2)) { + if (ImGui::Combo(typeStr, &v, boolOptions, 2)) { if (entry.publisher == 0) { entry.publisher = nt::Publish(entry.info.topic, NT_BOOLEAN, "boolean"); @@ -1376,9 +1377,8 @@ static void EmitEntryValueEditable(NetworkTablesModel* model, } case NT_INTEGER: { int64_t v = val.GetInteger(); - if (ImGui::InputScalar(typeStr.data(), ImGuiDataType_S64, &v, nullptr, - nullptr, nullptr, - ImGuiInputTextFlags_EnterReturnsTrue)) { + if (ImGui::InputScalar(typeStr, ImGuiDataType_S64, &v, nullptr, nullptr, + nullptr, ImGuiInputTextFlags_EnterReturnsTrue)) { if (entry.publisher == 0) { entry.publisher = nt::Publish(entry.info.topic, NT_INTEGER, "int"); } @@ -1388,7 +1388,7 @@ static void EmitEntryValueEditable(NetworkTablesModel* model, } case NT_FLOAT: { float v = val.GetFloat(); - if (ImGui::InputFloat(typeStr.data(), &v, 0, 0, "%.6f", + if (ImGui::InputFloat(typeStr, &v, 0, 0, "%.6f", ImGuiInputTextFlags_EnterReturnsTrue)) { if (entry.publisher == 0) { entry.publisher = nt::Publish(entry.info.topic, NT_FLOAT, "float"); @@ -1405,7 +1405,7 @@ static void EmitEntryValueEditable(NetworkTablesModel* model, #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat-nonliteral" #endif - if (ImGui::InputDouble(typeStr.data(), &v, 0, 0, + if (ImGui::InputDouble(typeStr, &v, 0, 0, fmt::format("%.{}f", precision).c_str(), ImGuiInputTextFlags_EnterReturnsTrue)) { if (entry.publisher == 0) { @@ -1420,7 +1420,7 @@ static void EmitEntryValueEditable(NetworkTablesModel* model, } case NT_STRING: { char* v = GetTextBuffer(entry.valueStr); - if (ImGui::InputText(typeStr.data(), v, kTextBufferSize, + if (ImGui::InputText(typeStr, v, kTextBufferSize, ImGuiInputTextFlags_EnterReturnsTrue)) { if (v[0] == '"') { if (entry.publisher == 0) { @@ -1435,7 +1435,7 @@ static void EmitEntryValueEditable(NetworkTablesModel* model, break; } case NT_BOOLEAN_ARRAY: - ImGui::LabelText(typeStr.data(), "[]"); + ImGui::LabelText(typeStr, "[]"); if (ImGui::BeginPopupContextItem("boolean[]")) { if (ImGui::Selectable("Edit Array")) { gArrayEditor = @@ -1448,7 +1448,7 @@ static void EmitEntryValueEditable(NetworkTablesModel* model, } break; case NT_INTEGER_ARRAY: - ImGui::LabelText(typeStr.data(), "[]"); + ImGui::LabelText(typeStr, "[]"); if (ImGui::BeginPopupContextItem("int[]")) { if (ImGui::Selectable("Edit Array")) { gArrayEditor = @@ -1461,7 +1461,7 @@ static void EmitEntryValueEditable(NetworkTablesModel* model, } break; case NT_FLOAT_ARRAY: - ImGui::LabelText(typeStr.data(), "[]"); + ImGui::LabelText(typeStr, "[]"); if (ImGui::BeginPopupContextItem("float[]")) { if (ImGui::Selectable("Edit Array")) { gArrayEditor = @@ -1473,7 +1473,7 @@ static void EmitEntryValueEditable(NetworkTablesModel* model, } break; case NT_DOUBLE_ARRAY: - ImGui::LabelText(typeStr.data(), "[]"); + ImGui::LabelText(typeStr, "[]"); if (ImGui::BeginPopupContextItem("double[]")) { if (ImGui::Selectable("Edit Array")) { gArrayEditor = @@ -1485,7 +1485,7 @@ static void EmitEntryValueEditable(NetworkTablesModel* model, } break; case NT_STRING_ARRAY: - ImGui::LabelText(typeStr.data(), "[]"); + ImGui::LabelText(typeStr, "[]"); if (ImGui::BeginPopupContextItem("string[]")) { if (ImGui::Selectable("Edit Array")) { gArrayEditor = @@ -1498,13 +1498,11 @@ static void EmitEntryValueEditable(NetworkTablesModel* model, } break; case NT_RAW: { - std::string_view ts = typeStr; - bool partial = SimplifyTypeString(&ts); - ImGui::LabelText(val.GetRaw().empty() ? "[]" : "[...]", "%s", ts.data()); + ImGui::LabelText(typeStr, val.GetRaw().empty() ? "[]" : "[...]"); if (ImGui::IsItemHovered()) { ImGui::BeginTooltip(); - if (partial) { - ImGui::TextUnformatted(typeStr.data()); + if (!entry.info.type_str.empty()) { + ImGui::TextUnformatted(entry.info.type_str.c_str()); } ImGui::Text("%u bytes", static_cast(val.GetRaw().size())); ImGui::EndTooltip(); @@ -1512,10 +1510,10 @@ static void EmitEntryValueEditable(NetworkTablesModel* model, break; } case NT_RPC: - ImGui::LabelText(typeStr.data(), "[...]"); + ImGui::LabelText(typeStr, "[...]"); break; default: - ImGui::LabelText(typeStr.data(), "?"); + ImGui::LabelText(typeStr, "?"); break; } ImGui::PopID(); @@ -1652,7 +1650,7 @@ static void EmitValueTree( auto pos = ImGui::GetCursorPos(); char label[128]; std::string_view ts = child.typeStr; - bool havePopup = SimplifyTypeString(&ts); + bool havePopup = GetHeadingTypeString(&ts); wpi::format_to_n_c_str(label, sizeof(label), "{}##v_{}", ts.data(), child.name.c_str()); bool valueChildrenOpen = @@ -1694,7 +1692,7 @@ static void EmitEntry(NetworkTablesModel* model, auto pos = ImGui::GetCursorPos(); char label[128]; std::string_view ts = entry.info.type_str; - bool havePopup = SimplifyTypeString(&ts); + bool havePopup = GetHeadingTypeString(&ts); wpi::format_to_n_c_str(label, sizeof(label), "{}##v_{}", ts.data(), entry.info.name.c_str()); valueChildrenOpen = @@ -1708,11 +1706,13 @@ static void EmitEntry(NetworkTablesModel* model, } } // make it look like a normal label w/type + const char* typeStr = GetTypeString( + NT_RAW, + entry.info.type_str.empty() ? nullptr : entry.info.type_str.c_str()); ImGui::SetCursorPos(pos); - ImGui::SetNextItemWidth( - -1 * (ImGui::CalcTextSize(entry.info.type_str.c_str()).x + - ImGui::GetStyle().FramePadding.x)); - ImGui::LabelText(entry.info.type_str.c_str(), "%s", ""); + ImGui::SetNextItemWidth(-1 * (ImGui::CalcTextSize(typeStr).x + + ImGui::GetStyle().FramePadding.x)); + ImGui::LabelText(typeStr, "%s", ""); if ((entry.value.IsBooleanArray() || entry.value.IsFloatArray() || entry.value.IsDoubleArray() || entry.value.IsIntegerArray() || entry.value.IsStringArray()) &&