Skip to content

Commit

Permalink
feat, fix: added project settings, input will now forget keys that we…
Browse files Browse the repository at this point in the history
…re released
  • Loading branch information
Jaskowicz1 committed May 14, 2024
1 parent 2792ec6 commit efdfaf9
Show file tree
Hide file tree
Showing 8 changed files with 470 additions and 92 deletions.
27 changes: 27 additions & 0 deletions include/engine/project_settings.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#pragma once

#include <string>
#include "utilities/json_utilities.h"

class project_settings {

public:
project_settings() = default;

void render_window();

bool show_window;

std::string start_id{};

std::string normal_button_path{};
std::string hovered_button_path{};
std::string selected_button_path{};

std::string button_sound_path{};

project_settings& fill_from_json(const json* j);

json to_json() const;

};
14 changes: 11 additions & 3 deletions include/engine/utilities/file_management.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#pragma once

#include "video_manager.h"
#include "project_settings.h"

#include <glad/gl.h>

#ifdef _WIN32
#include <windows.h>
Expand Down Expand Up @@ -42,23 +45,28 @@ class linux_file {
};
#endif

// Simple helper function to load an image into a OpenGL texture with common settings
bool LoadTextureFromFile(const std::string& filename, GLuint* out_texture, int* out_width = nullptr, int* out_height = nullptr);

/**
* @brief Save the current project
*
* @param manager The video manager with the videos.
* @param settings The project settings to save.
*
* @return bool true if project was able to save
*/
bool save_project(video_manager& manager);
bool save_project(video_manager& manager, project_settings& settings);

/**
* @brief Load a project.
*
* @brief The video manager to load the videos to.
* @param manager The video manager to load the videos to.
* @param settings The project settings to load the settings to.
*
* @return bool true if project was loaded successfully.
*/
bool load_project(video_manager& manager);
bool load_project(video_manager& manager, project_settings& settings);

/**
* @brief Opens a file prompt to retrieve a file path.
Expand Down
19 changes: 19 additions & 0 deletions include/engine/window.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
#include "utilities/input_manager.h"
#include <glad/gl.h>

#include "miniaudio/miniaudio.h"
#include "project_settings.h"

class window {

public:
Expand All @@ -19,8 +22,12 @@ class window {

video_manager manager{};

project_settings settings{};

std::unique_ptr<input::input_manager> input_man{nullptr};

void reload_button_textures();

private:

struct GLFWwindow* glfw_window{nullptr};
Expand All @@ -34,4 +41,16 @@ class window {

void render_window_bar();

ma_result result;
ma_engine engine;

// This is a temp solution to forcing a video to play next frame.
std::string force_video_to_play{};

int button_texture_width = 0;
int button_texture_height = 0;
GLuint button_texture{};
GLuint hovered_button_texture{};
GLuint pressed_button_texture{};

};
126 changes: 126 additions & 0 deletions src/engine/project_settings.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#include <fstream>
#include "project_settings.h"
#include "imgui.h"
#include "utilities/file_management.h"
#include "ImGuiNotify.hpp"

void project_settings::render_window() {
if(!show_window) {
return;
}

if(ImGui::Begin("Project Settings")) {

static char start_vid_id[1024];
if(!start_id.empty())
std::memcpy(start_vid_id, start_id.c_str(), start_id.length());
if(ImGui::InputText("Starting Video ID", start_vid_id, IM_ARRAYSIZE(start_vid_id))) {
start_id = start_vid_id;
}


static char button_texture_path[1024];
if(!normal_button_path.empty())
std::memcpy(button_texture_path, normal_button_path.c_str(), normal_button_path.length());
if(ImGui::InputText("Normal Button Texture Path", button_texture_path, IM_ARRAYSIZE(button_texture_path))) {
normal_button_path = button_texture_path;
}

ImGui::SameLine();

if (ImGui::Button(std::string("Select Image##001").c_str())) {
std::string image_path{utilities::get_file_from_prompt(false, "Select Image", "Image File | *.png *.jpg", "PNG\0*.png\0JPEG\0*.jpg\0All\0*.*\0")};

std::ifstream image_file(image_path);

if (image_file.good()) {
normal_button_path = image_path;
} else {
ImGui::InsertNotification({ ImGuiToastType::Error, 3000, "Failed to open Image file, please make sure it's a valid image file!" });
}
}

static char hovered_button_texture_path[1024];
if(!hovered_button_path.empty())
std::memcpy(hovered_button_texture_path, hovered_button_path.c_str(), hovered_button_path.length());
if(ImGui::InputText("Hovered Button Texture Path", hovered_button_texture_path, IM_ARRAYSIZE(hovered_button_texture_path))) {
hovered_button_path = hovered_button_texture_path;
}

ImGui::SameLine();
if (ImGui::Button(std::string("Select Image##002").c_str())) {
std::string image_path{utilities::get_file_from_prompt(false, "Select Image", "Image File | *.png *.jpg", "PNG\0*.png\0JPEG\0*.jpg\0All\0*.*\0")};

std::ifstream image_file(image_path);

if (image_file.good()) {
hovered_button_path = image_path;
} else {
ImGui::InsertNotification({ ImGuiToastType::Error, 3000, "Failed to open Image file, please make sure it's a valid image file!" });
}
}

static char selected_button_texture_path[1024];
if(!selected_button_path.empty())
std::memcpy(selected_button_texture_path, selected_button_path.c_str(), selected_button_path.length());
if(ImGui::InputText("Selected Button Texture Path", selected_button_texture_path, IM_ARRAYSIZE(selected_button_texture_path))) {
selected_button_path = selected_button_texture_path;
}

ImGui::SameLine();
if (ImGui::Button(std::string("Select Image##003").c_str())) {
std::string image_path{utilities::get_file_from_prompt(false, "Select Image", "Image File | *.png *.jpg", "PNG\0*.png\0JPEG\0*.jpg\0All\0*.*\0")};

std::ifstream image_file(image_path);

if (image_file.good()) {
selected_button_path = image_path;
} else {
ImGui::InsertNotification({ ImGuiToastType::Error, 3000, "Failed to open Image file, please make sure it's a valid image file!" });
}
}

static char button_pressed_sound[1024];
if(!button_sound_path.empty())
std::memcpy(button_pressed_sound, button_sound_path.c_str(), button_sound_path.length());
if(ImGui::InputText("Button Pressed Sound Path", button_pressed_sound, IM_ARRAYSIZE(button_pressed_sound))) {
button_sound_path = button_pressed_sound;
}

ImGui::SameLine();
if (ImGui::Button(std::string("Select Sound").c_str())) {
std::string sound_path{utilities::get_file_from_prompt(false, "Select Sound", "Sound File | *.mp3 *.wav", "MP3\0*.mp3\0WAV\0*.wav\0All\0*.*\0")};

std::ifstream sound_file(sound_path);

if (sound_file.good()) {
button_sound_path = sound_path;
} else {
ImGui::InsertNotification({ ImGuiToastType::Error, 3000, "Failed to open Sound file, please make sure it's a valid sound file!" });
}
}
}
ImGui::End();
}

project_settings &project_settings::fill_from_json(const json *j) {
utilities::set_string_not_null(j, "start_id", start_id);
utilities::set_string_not_null(j, "normal_button_path", normal_button_path);
utilities::set_string_not_null(j, "hovered_button_path", hovered_button_path);
utilities::set_string_not_null(j, "selected_button_path", selected_button_path);
utilities::set_string_not_null(j, "button_sound_path", button_sound_path);

return *this;
}

json project_settings::to_json() const {
json j;

j["start_id"] = start_id;
j["normal_button_path"] = normal_button_path;
j["hovered_button_path"] = hovered_button_path;
j["selected_button_path"] = selected_button_path;
j["button_sound_path"] = button_sound_path;

return j;
}
59 changes: 52 additions & 7 deletions src/engine/utilities/file_management.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,19 @@
#include <set>
#include "utilities/file_management.h"

bool utilities::save_project(video_manager& manager) {
#include "stb_image.h"
#include "project_settings.h"

bool utilities::save_project(video_manager& manager, project_settings& settings) {

std::string filename{get_file_from_prompt(true, "Save Project", "Hexwave Project | *.hexw", "Hexwave Project\0*.hexw\0")};

if(filename.empty()) {
if (filename.empty()) {
return false;
}

// Does filename NOT end in ".hexw"?
if(filename.compare(filename.size() - hexwave_project_ext.size(), hexwave_project_ext.size(), hexwave_project_ext) != 0) {
if (filename.compare(filename.size() - hexwave_project_ext.size(), hexwave_project_ext.size(), hexwave_project_ext) != 0) {
// because file doesn't end in ".hexw", we need to add ".hexw" to it to ensure all files end in that.
filename.append(hexwave_project_ext);
}
Expand All @@ -26,6 +29,7 @@ bool utilities::save_project(video_manager& manager) {
}

j["videos"] = video_array;
j["project_settings"] = utilities::to_json(settings);

// will auto close on deconstructor
std::ofstream project_file(filename);
Expand All @@ -34,11 +38,11 @@ bool utilities::save_project(video_manager& manager) {
return true;
}

bool utilities::load_project(video_manager& manager) {
bool utilities::load_project(video_manager& manager, project_settings& settings) {

std::string filename{get_file_from_prompt(false, "Open Project", "Hexwave Project | *.hexw", "Hexwave Project\0*.hexw\0")};

if(filename.empty()) {
if (filename.empty()) {
return false;
}

Expand Down Expand Up @@ -67,6 +71,9 @@ bool utilities::load_project(video_manager& manager) {
opt["name"].get<std::string>(), opt["video_id"].get<std::string>());
}
}

settings.fill_from_json(&j["project_settings"]);

}
catch (const json::parse_error& exception) {
std::cout << exception.what() << "\n";
Expand All @@ -88,7 +95,7 @@ std::string utilities::get_file_from_prompt(const bool is_save, const std::strin

// Might be possible to just not use fgets, should look into this.
// Will be true if fgets is nullptr (invalid).
if(fgets(filename, 1024, f) == nullptr) {
if (fgets(filename, 1024, f) == nullptr) {
return "";
}

Expand Down Expand Up @@ -117,7 +124,7 @@ std::string utilities::get_file_from_prompt(const bool is_save, const std::strin

#endif

if(std::strlen(filename) == 0) {
if (std::strlen(filename) == 0) {
return "";
}

Expand All @@ -128,3 +135,41 @@ std::string utilities::get_file_from_prompt(const bool is_save, const std::strin

return filename;
}


bool utilities::LoadTextureFromFile(const std::string& filename, GLuint* out_texture, int* out_width, int* out_height) {
// Load from file
int image_width = 0;
int image_height = 0;
unsigned char* image_data = stbi_load(filename.c_str(), &image_width, &image_height, nullptr, 4);
if (image_data == nullptr)
return false;

// Create a OpenGL texture identifier
GLuint image_texture;
glGenTextures(1, &image_texture);
glBindTexture(GL_TEXTURE_2D, image_texture);

// Setup filtering parameters for display
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // This is required on WebGL for non power-of-two textures
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Same

// Upload pixels into texture
#if defined(GL_UNPACK_ROW_LENGTH) && !defined(__EMSCRIPTEN__)
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
#endif
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image_width, image_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
stbi_image_free(image_data);

*out_texture = image_texture;

if(out_width)
*out_width = image_width;

if(out_height)
*out_height = image_height;

return true;
}
Loading

0 comments on commit efdfaf9

Please sign in to comment.