BillySheet/src/gui/gui.cpp
Pcornat 75f8db9f5a
Feature: adding matériel to Billy.
No conformity is done when adding things (dagger or bow for example)
2024-09-02 12:46:04 +02:00

285 lines
9.4 KiB
C++

#include "gui/gui.hpp"
#include "imgui.h"
#include "imgui_stdlib.h"
#include "imgui_impl_glfw.h"
#include "imgui_impl_opengl3.h"
#include "gui/window.hpp"
#include "gui/gui_data.hpp"
#include "character_sheet.hpp"
#include "controller.hpp"
#include "billy_objects.hpp"
#include "characteristic/characteristic.hpp"
using character::characteristic::Characteristic;
gui::Gui::Gui(Window &window, GuiData &data, menu::MenuData &menuData) :
data(data), menu(menuData), font("font/DejaVuSans.ttf") {
SPDLOG_DEBUG("Creating GUI");
(void) ImGui::CreateContext();
ImGui::StyleColorsDark();
(void) ImGui::GetIO().Fonts->AddFontFromFileTTF(font.c_str(), 18.0f);
(void) ImGui_ImplGlfw_InitForOpenGL(window.get_window().get(), true);
initialized = ImGui_ImplOpenGL3_Init("#version 130");
SPDLOG_DEBUG("Initialized: {}", initialized);
}
gui::Gui::~Gui() noexcept {
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
}
void gui::Gui::render_gui(const Controller &controller) {
if (initialized) {
constexpr ImGuiWindowFlags flags = ImGuiWindowFlags_MenuBar |
ImGuiWindowFlags_NoMove |
ImGuiWindowFlags_NoResize |
ImGuiWindowFlags_NoCollapse |
ImGuiWindowFlags_NoTitleBar;
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
//TODO GUI
{
const ImGuiViewport &viewport = *ImGui::GetMainViewport();
ImGui::SetNextWindowPos(viewport.Pos);
ImGui::SetNextWindowSize(viewport.Size);
}
// Never collapsed.
(void) ImGui::Begin("Billy", nullptr, flags);
menu.gui();
if (ImGui::BeginCombo("Classe",
GuiData::classes[static_cast<std::uint32_t>(data.billy.get_current_class())].data(),
ImGuiComboFlags_PopupAlignLeft)) {
for (std::size_t i = 0; i < GuiData::classes.size(); ++i) {
const bool is_selected = (data.billy.get_current_class() == static_cast<character::classe>(i));
if (is_selected) {
ImGui::SetItemDefaultFocus();
}
}
ImGui::EndCombo();
}
{
ImGui::BeginChild("carac", ImVec2(0, ImGui::GetWindowHeight() * 0.2f), true);
ImGui::Text("Caractère");
// Remove label
ImGui::PushItemWidth(-1);
ImGui::InputTextMultiline("Caractère", &data.billy.caractere);
ImGui::PopItemWidth();
ImGui::EndChild();
}
ImGui::BeginGroup();
habilete_menu();
ImGui::SameLine();
adresse_menu();
endurance_menu();
ImGui::SameLine();
chance_menu();
ImGui::EndGroup();
ImGui::SameLine();
stat_second_menu();
materiel_menu();
ImGui::SameLine();
ImGui::BeginGroup();
gloire_menu();
richesse_menu();
ImGui::EndGroup();
ImGui::End();
controller.control_menu();
ImGui::Render();
}
}
void gui::Gui::render_gpu() const {
if (initialized) {
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
}
}
void gui::Gui::characteristic_gui(const Characteristic &characteristic) noexcept {
int base = static_cast<int>(characteristic.get_base());
(void) ImGui::InputInt("Base", &base, 1, 100, ImGuiInputTextFlags_ReadOnly);
int carac = static_cast<int>(characteristic.get_carac());
(void) ImGui::InputInt("Carac", &carac, 1, 100, ImGuiInputTextFlags_ReadOnly);
int materiel = static_cast<int>(characteristic.get_materiel());
(void) ImGui::InputInt("Matériel", &materiel, 1, 100, ImGuiInputTextFlags_ReadOnly);
int additional = static_cast<int>(characteristic.get_additional());
(void) ImGui::InputInt("Additionnel", &additional, 1, 100, ImGuiInputTextFlags_ReadOnly);
}
void gui::Gui::habilete_menu() noexcept {
ImGui::BeginChild("habilete",
ImVec2(ImGui::GetWindowWidth() / 3, ImGui::GetWindowHeight() * 0.2f),
ImGuiChildFlags_Border);
ImGui::Text("Habileté");
characteristic_gui(static_cast<const Characteristic &>(data.billy.get_habilete()));
ImGui::EndChild();
}
void gui::Gui::adresse_menu() noexcept {
ImGui::BeginChild("adresse",
ImVec2(ImGui::GetWindowWidth() / 3, ImGui::GetWindowHeight() * 0.2f),
ImGuiChildFlags_Border);
ImGui::Text("Adresse");
characteristic_gui(static_cast<const Characteristic &>(data.billy.get_adresse()));
ImGui::EndChild();
}
void gui::Gui::endurance_menu() noexcept {
ImGui::BeginChild("endurance",
ImVec2(ImGui::GetWindowWidth() / 3, ImGui::GetWindowHeight() * 0.2f),
ImGuiChildFlags_Border);
ImGui::Text("Endurance");
characteristic_gui(static_cast<const Characteristic &>(data.billy.get_endurance()));
ImGui::EndChild();
}
void gui::Gui::chance_menu() noexcept {
ImGui::BeginChild("chance",
ImVec2(ImGui::GetWindowWidth() / 3, ImGui::GetWindowHeight() * 0.2f),
ImGuiChildFlags_Border);
ImGui::Text("Chance");
characteristic_gui(static_cast<const Characteristic &>(data.billy.get_chance()));
ImGui::EndChild();
}
void gui::Gui::stat_second_menu() noexcept {
ImGui::BeginChild("stats secondaire",
ImVec2(ImGui::GetWindowWidth() / 3, ImGui::GetWindowHeight() * 0.4f),
ImGuiChildFlags_Border);
ImGui::Text("STAT. SECONDAIRES");
ImGui::EndChild();
}
template<typename MaterielEnum>
constexpr std::string_view combo_label() {
using character::weapons;
using character::equipments;
using character::tools;
if constexpr (std::is_same_v<MaterielEnum, weapons>) {
return "Weapons";
} else if constexpr (std::is_same_v<MaterielEnum, equipments>) {
return "Equipments";
} else {
return "Tools";
}
}
template<typename MaterielEnum>
constexpr std::string_view material_child_win_id() {
using character::weapons;
using character::equipments;
using character::tools;
if constexpr (std::is_same_v<MaterielEnum, weapons>) {
return "weapons";
} else if constexpr (std::is_same_v<MaterielEnum, equipments>) {
return "equipments";
} else {
return "tools";
}
}
template<typename MaterielEnum>
void generic_combo_menu(character::CharacterSheet &billy,
std::unordered_set<character::BillyObjects::billyObject> &availableObjects,
character::BillyObjects &dealObjects) noexcept {
using character::BillyObjects;
static auto selected = std::find_if(availableObjects.cbegin(), availableObjects.cend(), [](const auto &billyObj) {
return std::holds_alternative<MaterielEnum>(billyObj);
});
ImGui::BeginChild(material_child_win_id<MaterielEnum>().data(),
ImVec2(ImGui::GetWindowWidth(), 0),
ImGuiChildFlags_AutoResizeY);
if (ImGui::BeginCombo(combo_label<MaterielEnum>().data(),
BillyObjects::billy_object_to_string(*selected).data(),
ImGuiComboFlags_WidthFitPreview | ImGuiComboFlags_PopupAlignLeft)) {
for (auto iterator = availableObjects.cbegin();
iterator != availableObjects.cend(); ++iterator) {
if (!std::holds_alternative<MaterielEnum>(*iterator)) {
continue;
}
const bool is_selected = selected == iterator;
if (ImGui::Selectable(BillyObjects::billy_object_to_string(*iterator).data(), is_selected)) {
selected = iterator;
}
if (is_selected) {
ImGui::SetItemDefaultFocus();
}
}
ImGui::EndCombo();
}
ImGui::SameLine();
if (ImGui::Button("+")) {
if (dealObjects.push_object(*selected, billy)) {
selected = std::find_if(availableObjects.cbegin(),
availableObjects.cend(),
[](const auto &billyObj) { return std::holds_alternative<MaterielEnum>(billyObj); });
}
}
ImGui::EndChild();
}
void gui::Gui::materiel_menu() noexcept {
using character::BillyObjects;
ImGui::BeginChild("materiel",
ImVec2(ImGui::GetWindowWidth() / 3, 0),
ImGuiChildFlags_Border | ImGuiChildFlags_AutoResizeY);
ImGui::Text("Matériel");
generic_combo_menu<character::weapons>(data.billy, data.billy.available_objects, deal_objects);
generic_combo_menu<character::equipments>(data.billy, data.billy.available_objects, deal_objects);
generic_combo_menu<character::tools>(data.billy, data.billy.available_objects, deal_objects);
for (const auto &object: data.billy.get_objects()) {
ImGui::Text("%s", BillyObjects::billy_object_to_string(object).data());
}
if (ImGui::Button("Remove last object")) {
deal_objects.pop_object(data.billy);
}
ImGui::EndChild();
}
void gui::Gui::gloire_menu() noexcept {
ImGui::BeginChild("gloire",
ImVec2(ImGui::GetWindowWidth() / 3, ImGui::GetWindowHeight() * 0.1f),
ImGuiChildFlags_Border);
ImGui::Text("Gloire");
ImGui::EndChild();
}
void gui::Gui::richesse_menu() noexcept {
ImGui::BeginChild("richesse",
ImVec2(ImGui::GetWindowWidth() / 3, ImGui::GetWindowHeight() * 0.1f),
ImGuiChildFlags_Border);
ImGui::Text("Richesse");
ImGui::EndChild();
}