lay down basic imgui wrappers/helpers
This commit is contained in:
@@ -1,44 +1,44 @@
|
||||
#include <AudioSettings.hpp>
|
||||
|
||||
AudioSettings::AudioSettings(nlohmann::json &settings) : QWidget(nullptr), settings(settings) {
|
||||
lockChannels->setChecked(JSONGetField<bool>(settings, "audio", "lock"));
|
||||
volumeL->setValue(JSONGetField<float>(settings, "audio", "volumeL") * 100);
|
||||
volumeR->setValue(JSONGetField<float>(settings, "audio", "volumeR") * 100);
|
||||
volumeL->setRange(0, 100);
|
||||
volumeR->setRange(0, 100);
|
||||
|
||||
connect(lockChannels.get(), &QCheckBox::stateChanged, this, [&]() {
|
||||
JSONSetField(settings, "audio", "lock", lockChannels->isChecked());
|
||||
if (lockChannels->isChecked()) {
|
||||
volumeR->setValue(volumeL->value());
|
||||
}
|
||||
|
||||
emit modified();
|
||||
});
|
||||
|
||||
connect(volumeL.get(), &QSlider::valueChanged, this, [&]() {
|
||||
JSONSetField(settings, "audio", "volumeL", float(volumeL->value()) / 100.f);
|
||||
if (lockChannels->isChecked()) {
|
||||
volumeR->setValue(volumeL->value());
|
||||
JSONSetField(settings, "audio", "volumeR", float(volumeL->value()) / 100.f);
|
||||
}
|
||||
emit modified();
|
||||
});
|
||||
|
||||
connect(volumeR.get(), &QSlider::valueChanged, this, [&]() {
|
||||
if (!lockChannels->isChecked()) {
|
||||
JSONSetField(settings, "audio", "volumeR", float(volumeR->value()) / 100.f);
|
||||
}
|
||||
emit modified();
|
||||
});
|
||||
|
||||
mainLayout->addWidget(labelLock.get());
|
||||
mainLayout->addWidget(lockChannels.get());
|
||||
volLayout->addWidget(labelL.get());
|
||||
volLayout->addWidget(volumeL.get());
|
||||
volLayout->addWidget(labelR.get());
|
||||
volLayout->addWidget(volumeR.get());
|
||||
mainLayout->addLayout(volLayout.get());
|
||||
mainLayout->addStretch();
|
||||
setLayout(mainLayout.get());
|
||||
AudioSettings::AudioSettings(nlohmann::json &settings) : settings(settings) {
|
||||
lockChannels.setChecked(JSONGetField<bool>(settings, "audio", "lock"));
|
||||
volumeL.setValue(JSONGetField<float>(settings, "audio", "volumeL") * 100);
|
||||
volumeR.setValue(JSONGetField<float>(settings, "audio", "volumeR") * 100);
|
||||
}
|
||||
|
||||
bool AudioSettings::render() {
|
||||
if(lockChannels.render()) {
|
||||
auto isChecked = lockChannels.isChecked();
|
||||
JSONSetField(settings, "audio", "lock", isChecked);
|
||||
if (isChecked) {
|
||||
volumeR.setValue(volumeL.getValue());
|
||||
}
|
||||
|
||||
modified = true;
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if(volumeL.render()) {
|
||||
float valueL = volumeL.getValue();
|
||||
JSONSetField(settings, "audio", "volumeL", float(valueL) / 100.f);
|
||||
if (lockChannels.isChecked()) {
|
||||
volumeR.setValue(valueL);
|
||||
JSONSetField(settings, "audio", "volumeR", float(valueL) / 100.f);
|
||||
}
|
||||
|
||||
modified = true;
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if(volumeR.render()) {
|
||||
if (!lockChannels.isChecked()) {
|
||||
JSONSetField(settings, "audio", "volumeR", float(volumeR.getValue()) / 100.f);
|
||||
}
|
||||
|
||||
modified = true;
|
||||
}
|
||||
|
||||
return modified;
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
#pragma once
|
||||
#include <JSONUtils.hpp>
|
||||
#include <ImGuiImpl/Checkbox.hpp>
|
||||
#include <ImGuiImpl/Slider.hpp>
|
||||
|
||||
class AudioSettings final {
|
||||
//std::unique_ptr<QCheckBox> lockChannels = std::make_unique<QCheckBox>();
|
||||
//std::unique_ptr<QLabel> labelLock = std::make_unique<QLabel>("Lock channels:");
|
||||
//std::unique_ptr<QLabel> labelL = std::make_unique<QLabel>("Volume L");
|
||||
//std::unique_ptr<QLabel> labelR = std::make_unique<QLabel>("Volume R");
|
||||
//std::unique_ptr<QVBoxLayout> mainLayout = std::make_unique<QVBoxLayout>();
|
||||
//std::unique_ptr<QHBoxLayout> volLayout = std::make_unique<QHBoxLayout>();
|
||||
//Q_OBJECT
|
||||
gui::Checkbox lockChannels{"Lock channels:", false};
|
||||
bool modified = false;
|
||||
public:
|
||||
//std::unique_ptr<QSlider> volumeL = std::make_unique<QSlider>(Qt::Horizontal),
|
||||
// volumeR = std::make_unique<QSlider>(Qt::Horizontal);
|
||||
gui::SliderFloat volumeL{"Volume L", 0.f, 100.f, 0.f};
|
||||
gui::SliderFloat volumeR{"Volume R", 0.f, 100.f, 0.f};
|
||||
explicit AudioSettings(nlohmann::json &);
|
||||
bool render();
|
||||
void setModified(bool v) { modified = v; }
|
||||
bool getModified() { return modified; }
|
||||
nlohmann::json &settings;
|
||||
};
|
||||
|
||||
@@ -2,30 +2,22 @@
|
||||
#include <JSONUtils.hpp>
|
||||
#include <log.hpp>
|
||||
|
||||
CPUSettings::CPUSettings(nlohmann::json &settings) : QWidget(nullptr), settings(settings) {
|
||||
cpuTypes->addItems({
|
||||
"Interpreter" //, "Dynamic Recompiler"
|
||||
});
|
||||
CPUSettings::CPUSettings(nlohmann::json &settings) : settings(settings) {
|
||||
if (JSONGetField<std::string>(settings, "cpu", "type") == "jit") {
|
||||
cpuTypes->setCurrentIndex(1);
|
||||
cpuTypes.setCurrentIndex(1);
|
||||
} else {
|
||||
cpuTypes->setCurrentIndex(0);
|
||||
cpuTypes.setCurrentIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
bool CPUSettings::render() {
|
||||
if(cpuTypes.render()) {
|
||||
if(cpuTypes.getCurrentIndex() == 0) {
|
||||
JSONSetField(settings, "cpu", "type", "interpreter");
|
||||
} else {
|
||||
Util::panic("JIT is unfinished and currently not supported!");
|
||||
}
|
||||
|
||||
modified = true;
|
||||
}
|
||||
|
||||
connect(cpuTypes.get(), &QComboBox::currentIndexChanged, this, [&]() {
|
||||
if (cpuTypes->currentIndex() == 0) {
|
||||
JSONSetField(settings, "cpu", "type", "interpreter");
|
||||
//} else if (cpuTypes->currentIndex() == 1) {
|
||||
// JSONSetField(settings, "cpu", "type", "jit");
|
||||
} else {
|
||||
Util::panic("Impossible CPU type!");
|
||||
}
|
||||
|
||||
emit modified();
|
||||
});
|
||||
|
||||
mainLayout->addWidget(label.get());
|
||||
mainLayout->addWidget(cpuTypes.get());
|
||||
mainLayout->addStretch();
|
||||
setLayout(mainLayout.get());
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
#pragma once
|
||||
#include <JSONUtils.hpp>
|
||||
#include <ImGuiImpl/Combobox.hpp>
|
||||
|
||||
class CPUSettings final {
|
||||
//std::unique_ptr<QComboBox> cpuTypes = std::make_unique<QComboBox>();
|
||||
//std::unique_ptr<QLabel> label = std::make_unique<QLabel>("CPU type:");
|
||||
//std::unique_ptr<QVBoxLayout> mainLayout = std::make_unique<QVBoxLayout>();
|
||||
//Q_OBJECT
|
||||
gui::Combobox cpuTypes{"CPU type:", {"Interpreter" //, "Dynamic Recompiler"
|
||||
}};
|
||||
bool modified = false;
|
||||
public:
|
||||
bool render();
|
||||
explicit CPUSettings(nlohmann::json &);
|
||||
nlohmann::json &settings;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <Debugger.hpp>
|
||||
|
||||
Debugger::Debugger() : QWidget(nullptr) {
|
||||
Debugger::Debugger() {
|
||||
/*
|
||||
disassembly->setWindowTitle("Disassembly");
|
||||
disassembly->setFeatures(QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable);
|
||||
codeView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
@@ -18,4 +19,5 @@ Debugger::Debugger() : QWidget(nullptr) {
|
||||
setLayout(verLayout.get());
|
||||
|
||||
// connect(codeView.get(), &QTreeView::activated, this, );
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
#pragma once
|
||||
#include <imgui.h>
|
||||
#include <string>
|
||||
|
||||
namespace gui {
|
||||
struct Checkbox {
|
||||
Checkbox(const std::string& label, bool def = false) : val(def), label(label) {}
|
||||
|
||||
void setChecked(bool v) { val = v; }
|
||||
bool render() { return ImGui::Checkbox(label.c_str(), &val); }
|
||||
bool isChecked() { return val; }
|
||||
private:
|
||||
bool val = false;
|
||||
std::string label = "";
|
||||
};
|
||||
}
|
||||
46
src/frontend/ImGuiImpl/Combobox.hpp
Normal file
46
src/frontend/ImGuiImpl/Combobox.hpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
#include <imgui.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace gui {
|
||||
struct Combobox {
|
||||
Combobox(std::string label, const std::vector<std::string>& items, std::string preview = "") : label(label), items(items), preview(preview) {}
|
||||
|
||||
bool render() {
|
||||
const char* _preview = "";
|
||||
|
||||
if(preview != "") {
|
||||
_preview = preview.c_str();
|
||||
} else {
|
||||
_preview = items[current_index].c_str();
|
||||
}
|
||||
|
||||
bool changed = false;
|
||||
|
||||
if (ImGui::BeginCombo(label.c_str(), _preview)) {
|
||||
for (int n = 0; n < items.size(); n++) {
|
||||
const bool is_selected = ((current_index) == n);
|
||||
if (ImGui::Selectable(items[n].c_str(), is_selected))
|
||||
{
|
||||
current_index = n;
|
||||
changed = true;
|
||||
}
|
||||
// Set the initial focus when opening the combo (scrolling + keyboard navigation focus)
|
||||
if (is_selected)
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
void setCurrentIndex(int v) { current_index = v; }
|
||||
int getCurrentIndex() { return current_index; }
|
||||
private:
|
||||
const std::vector<std::string>& items;
|
||||
std::string label, preview;
|
||||
int current_index = 0;
|
||||
};
|
||||
}
|
||||
53
src/frontend/ImGuiImpl/Slider.hpp
Normal file
53
src/frontend/ImGuiImpl/Slider.hpp
Normal file
@@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
#include <imgui.h>
|
||||
#include <string>
|
||||
|
||||
namespace gui {
|
||||
template <typename T>
|
||||
struct Slider {
|
||||
Slider(const std::string& label, T min = 0, T max = 0, T default = 0)
|
||||
: val(default), label(label), min(min), max(max) { }
|
||||
|
||||
void setValue(T v) { val = v; }
|
||||
bool render() {
|
||||
return ImGui::SliderScalarN(label.c_str(), type_to_imgui(), (void*)&val, 1, (void*)&min, (void*)&max);
|
||||
}
|
||||
T getValue() { return val; }
|
||||
private:
|
||||
constexpr ImGuiDataType_ type_to_imgui() {
|
||||
if constexpr(std::is_same_v<T, char>) {
|
||||
return ImGuiDataType_S8;
|
||||
} else if constexpr(std::is_same_v<T, unsigned char>) {
|
||||
return ImGuiDataType_U8;
|
||||
} else if constexpr(std::is_same_v<T, short>) {
|
||||
return ImGuiDataType_S16;
|
||||
} else if constexpr(std::is_same_v<T, unsigned short>) {
|
||||
return ImGuiDataType_U16;
|
||||
} else if constexpr(std::is_same_v<T, int>) {
|
||||
return ImGuiDataType_S32;
|
||||
} else if constexpr(std::is_same_v<T, unsigned int>) {
|
||||
return ImGuiDataType_U32;
|
||||
} else if constexpr(std::is_same_v<T, long long>) {
|
||||
return ImGuiDataType_S64;
|
||||
} else if constexpr(std::is_same_v<T, unsigned long long>) {
|
||||
return ImGuiDataType_U64;
|
||||
} else if constexpr(std::is_same_v<T, float>) {
|
||||
return ImGuiDataType_Float;
|
||||
} else if constexpr(std::is_same_v<T, double>) {
|
||||
return ImGuiDataType_Double;
|
||||
} else if constexpr(std::is_same_v<T, bool>) {
|
||||
return ImGuiDataType_Bool;
|
||||
} else if constexpr(std::is_same_v<T, char*>) {
|
||||
return ImGuiDataType_String;
|
||||
} else {
|
||||
return ImGuiDataType_COUNT;
|
||||
}
|
||||
}
|
||||
|
||||
T val{}, min{}, max{};
|
||||
std::string label = "";
|
||||
};
|
||||
|
||||
using SliderFloat = Slider<float>;
|
||||
using SliderInt = Slider<int>;
|
||||
}
|
||||
Reference in New Issue
Block a user