Files
Renderive/Widget/Qt/Value_Select.h
T
2026-07-29 12:30:40 +08:00

153 lines
4.9 KiB
C++

#pragma once
#include <QComboBox>
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <iostream>
#include "Core/Base/global_include.h"
#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