#pragma once #include #include #include #include #include #include "Core/Base/global_include.h" #include "magic_enum/magic_enum.hpp" namespace Psc { // 用于选择一个值 template class Value_Select_Simple : public QWidget { public: QLabel* label; QLineEdit* number_input; void set_title(const QString& title) const { label->setText(title); } [[nodiscard]] QString get_title() const { return label->text(); } void set_value(Value_Type value) { number_input->setText(QString::number(value)); } Value_Type get_value() { auto str = number_input->text(); if constexpr (std::is_integral_v) { bool ok = false; if constexpr (std::is_signed_v) { auto v = str.toLongLong(&ok); if (!ok) throw std::runtime_error("Invalid integer"); return static_cast(v); } else { auto v = str.toULongLong(&ok); if (!ok) throw std::runtime_error("Invalid unsigned integer"); return static_cast(v); } } else if constexpr (std::is_floating_point_v) { bool ok = false; auto v = str.toDouble(&ok); if (!ok) throw std::runtime_error("Invalid float"); return static_cast(v); } else { static_assert(sizeof(Value_Type) == 0, "Unsupported Value_Type"); } return Value_Type(); } explicit Value_Select_Simple(QWidget* parent = nullptr) : QWidget(parent) { label = new QLabel(this); number_input = new QLineEdit(this); auto layout = new QHBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); layout->addWidget(label); layout->addWidget(number_input); } }; // 选择带枚举单位的值 template class Value_Select : public QWidget { public: Value_Select_Simple* number; QComboBox* unit; void set_title(const QString& title) const { number->set_title(title); } [[nodiscard]] QString get_title() const { return number->get_title(); } explicit Value_Select(QWidget* parent = nullptr) : QWidget(parent) { unit = new QComboBox(this); number = new Value_Select_Simple; for (auto ev : magic_enum::enum_values()) { unit->addItem(enum_name(ev), static_cast(ev)); } auto layout = new QHBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); layout->addWidget(number); layout->addWidget(unit); } Value_Select& set_default_unit(Enum_Type value) { int idx = unit->findData(static_cast(value)); if (idx >= 0) unit->setCurrentIndex(idx); return *this; } void set_number_value(Value_Type value) { number->set_value(value); } Enum_Type unit_enum() { return from_value(unit->currentData().toInt()); } virtual Value_Type value() { return number->get_value() * uint_value(unit_enum()); } virtual Value_Type uint_value(Enum_Type enum_val) { return 1; } protected: Enum_Type from_name(const QString& name) { auto v = magic_enum::enum_cast(name.toStdString()); if (!v) throw std::runtime_error("Invalid enum name"); return *v; } Enum_Type from_value(int value) { auto v = magic_enum::enum_cast(value); if (!v) throw std::runtime_error("Invalid enum value"); return *v; } [[nodiscard]] QString enum_name(Enum_Type value) { return QString::fromStdString(std::string(magic_enum::enum_name(value))); } [[nodiscard]] QString enum_type_name() const { return QString::fromStdString( std::string(magic_enum::enum_type_name())); } }; enum class Memory_Size_Uint : size_t { Byte, KB, MB, GB }; class Byte_Select : public Value_Select { public: size_t uint_value(Memory_Size_Uint e) override { static constexpr size_t table[] = { 1ull, 1024ull, 1024ull * 1024ull, 1024ull * 1024ull * 1024ull}; return table[static_cast(e)]; } }; enum class Frequent_Uint : size_t { HZ, KHZ, MHZ, }; class Frequent_Select : public Value_Select { public: size_t uint_value(Frequent_Uint e) override { static constexpr size_t table[] = {1ull, 1000ull, 1000ull * 1000ull}; return table[static_cast(e)]; } }; } // namespace Psc