155 lines
4.4 KiB
C++
155 lines
4.4 KiB
C++
#pragma once
|
|
#include "Core/Base/global_include.h"
|
|
|
|
#include <QComboBox>
|
|
#include <QHBoxLayout>
|
|
#include <QLabel>
|
|
#include <QLineEdit>
|
|
#include <iostream>
|
|
|
|
#include "magic_enum/magic_enum.hpp"
|
|
|
|
namespace Psc {
|
|
|
|
// 用于选择一个值
|
|
template <typename Value_Type>
|
|
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<Value_Type>) {
|
|
bool ok = false;
|
|
if constexpr (std::is_signed_v<Value_Type>) {
|
|
auto v = str.toLongLong(&ok);
|
|
if (!ok)
|
|
throw std::runtime_error("Invalid integer");
|
|
return static_cast<Value_Type>(v);
|
|
} else {
|
|
auto v = str.toULongLong(&ok);
|
|
if (!ok)
|
|
throw std::runtime_error("Invalid unsigned integer");
|
|
return static_cast<Value_Type>(v);
|
|
}
|
|
} else if constexpr (std::is_floating_point_v<Value_Type>) {
|
|
bool ok = false;
|
|
auto v = str.toDouble(&ok);
|
|
if (!ok)
|
|
throw std::runtime_error("Invalid float");
|
|
return static_cast<Value_Type>(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 <typename Value_Type, typename Enum_Type>
|
|
class Value_Select : public QWidget {
|
|
public:
|
|
Value_Select_Simple<Value_Type>* 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<Value_Type>;
|
|
for (auto ev : magic_enum::enum_values<Enum_Type>()) {
|
|
unit->addItem(enum_name(ev), static_cast<int>(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<int>(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<Enum_Type>(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<Enum_Type>(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_Type>()));
|
|
}
|
|
};
|
|
|
|
enum class Memory_Size_Uint : size_t { Byte, KB, MB, GB };
|
|
class Byte_Select : public Value_Select<size_t, Memory_Size_Uint> {
|
|
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<size_t>(e)];
|
|
}
|
|
};
|
|
|
|
enum class Frequent_Uint : size_t {
|
|
HZ,
|
|
KHZ,
|
|
MHZ,
|
|
};
|
|
class Frequent_Select : public Value_Select<size_t, Frequent_Uint> {
|
|
public:
|
|
size_t uint_value(Frequent_Uint e) override {
|
|
static constexpr size_t table[] = {1ull, 1000ull, 1000ull * 1000ull};
|
|
return table[static_cast<size_t>(e)];
|
|
}
|
|
};
|
|
|
|
} // namespace Psc
|