Skip to content
This repository has been archived by the owner on Oct 7, 2024. It is now read-only.

Commit

Permalink
added modals to ui
Browse files Browse the repository at this point in the history
  • Loading branch information
Prevter committed Apr 18, 2024
1 parent b3a2317 commit 9ce72fd
Show file tree
Hide file tree
Showing 6 changed files with 298 additions and 86 deletions.
1 change: 1 addition & 0 deletions src/shared/gui/gui.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "themes/themes.hpp"
#include "window.hpp"
#include "modal.hpp"

namespace openhack::gui {
/// @brief Struct containing variants of one font.
Expand Down
92 changes: 92 additions & 0 deletions src/shared/gui/modal.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#include "modal.hpp"

#include <utility>
#include "gui.hpp"

namespace openhack::gui {
void Modal::create(const std::string &title, std::function<void(Modal *)> onDraw, bool canEscapeClose) {
// Check if popup with the same title already exists
auto &popups = getPopups();
for (auto popup: popups) {
if (popup->getTitle() == title) {
return;
}
}

// Create new popup
auto *popup = new Modal(title, std::move(onDraw), canEscapeClose);
popups.push_back(popup);
}

void Modal::create(const std::string &title, const std::string &message) {
create(title, [message](Modal *popup) {
gui::text("%s", message.c_str());
if (gui::button("OK")) {
popup->close();
}
});
}

void Modal::draw() {
bool isOpen = false;
ImGui::OpenPopup(m_title.c_str(), ImGuiPopupFlags_NoOpenOverExistingPopup | ImGuiPopupFlags_NoOpenOverItems);

auto scale = config::getGlobal<float>("UIScale");
ImGui::SetNextWindowSizeConstraints({MIN_SIZE.x * scale, MIN_SIZE.y * scale},
{MAX_SIZE.x * scale, MAX_SIZE.y * scale});

auto font = gui::getFont();
ImGui::PushFont(font.title);

if (ImGui::BeginPopupModal(m_title.c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
isOpen = true;
if (m_canEscapeClose && utils::isKeyPressed("Esc")) {
close();
return ImGui::EndPopup();
}
ImGui::PushFont(font.normal);
m_onDraw(this);
ImGui::PopFont();
ImGui::EndPopup();
}

ImGui::PopFont();

// check if the popup was closed
if (!isOpen) {
auto &popups = getPopups();
popups.erase(std::remove(popups.begin(), popups.end(), this), popups.end());
}
}

const std::string &Modal::getTitle() const {
return m_title;
}

void Modal::setTitle(const std::string &title) {
m_title = title;
}

void Modal::close() {
ImGui::CloseCurrentPopup();
auto &popups = getPopups();
popups.erase(std::remove(popups.begin(), popups.end(), this), popups.end());
}

std::vector<Modal *> &getPopups() {
static std::vector<Modal *> popups;
return popups;
}

void drawPopups() {
for (auto popup: getPopups()) {
popup->draw();
}
}

void closePopups() {
for (auto popup: getPopups()) {
popup->close();
}
}
}
55 changes: 55 additions & 0 deletions src/shared/gui/modal.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#pragma once

#include <imgui.h>
#include <string>
#include <functional>
#include <vector>

namespace openhack::gui {
class Modal {
public:
inline static const ImVec2 MIN_SIZE{400, 1}; // Minimum popup size
inline static const ImVec2 MAX_SIZE{600, 800}; // Maximum popup size

/// @brief Create a new popup with a custom draw function
/// @param title The title of the popup
/// @param onDraw The function that draws the popup
/// @param canEscapeClose Whether the popup can be closed by pressing the Escape key
static void create(const std::string &title, std::function<void(Modal *)> onDraw, bool canEscapeClose = true);

/// @brief Create a new popup with a message and an OK button
/// @param title The title of the popup
/// @param message The message to display
static void create(const std::string &title, const std::string &message);

public:
Modal(std::string title, std::function<void(Modal *)> onDraw, bool canEscapeClose)
: m_title(std::move(title)), m_onDraw(std::move(onDraw)), m_canEscapeClose(canEscapeClose) {}

/// @brief Draws the popup
void draw();

/// @brief Get the title of the popup
[[nodiscard]] const std::string &getTitle() const;

/// @brief Set the title of the popup
void setTitle(const std::string &title);

/// @brief Close the popup
void close();

private:
std::string m_title;
std::function<void(Modal *)> m_onDraw;
bool m_canEscapeClose = true; // Whether the popup can be closed by pressing the Escape key
};

/// @brief Get all popups
[[nodiscard]] std::vector<Modal *> &getPopups();

/// @brief Draw all popups
void drawPopups();

/// @brief Close all popups
void closePopups();
}
59 changes: 48 additions & 11 deletions src/shared/hacks/shortcuts/shortcuts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,35 @@ namespace openhack::hacks {
#ifdef PLATFORM_WINDOWS

void Shortcuts::patchGame() {
bool success = win32::four_gb::patch();
L_INFO("Patched the game to use 4GB of memory: {}", success);
MessageBox(nullptr, success ? "Patched the game to use 4GB of memory. Please restart the game."
: "Failed to patch the game. Could not write to the file.",
"4GB Patch", (success ? MB_ICONINFORMATION : MB_ICONERROR) | MB_OK);

if (success) {
// Close the game
std::exit(0);
}
gui::Modal::create("4GB Patch", [](gui::Modal *popup) {
ImGui::TextWrapped("This patch allows the game to use 4GB, instead of only 2GB.");
ImGui::TextWrapped("It is highly recommended to install this patch, as "
"it resolves some \"Out of memory\"/\"Bad Allocation\" crashes.");

if (gui::button("Apply Patch", {0.5, 0.f})) {
bool success = win32::four_gb::patch();
L_INFO("Patched the game to use 4GB of memory: {}", success);
if (success) {
popup->close();
gui::Modal::create("4GB Patch", [](gui::Modal *popup) {
ImGui::TextWrapped("Patched the game to use 4GB of memory. Please restart the game.");
if (gui::button("Restart")) {
ON_STANDALONE( std::exit(0); ) // TODO: Implement proper restart for standalone
ON_GEODE( geode::utils::game::restart(); )
}
});
} else {
popup->close();
gui::Modal::create("4GB Patch", "Failed to patch the game. Could not write to the file.");
}
}

ImGui::SameLine(0, 2);

if (gui::button("Cancel")) {
popup->close();
}
});
}

#else
Expand All @@ -32,7 +51,7 @@ namespace openhack::hacks {

#endif

void Shortcuts::uncompleteLevel() {
void uncompleteLevelConfirmed() {
if (gd::PlayLayer *playLayer = gd::PlayLayer::get()) {
auto *level = playLayer->m_level();
auto *statsManager = gd::GameStatsManager::sharedState();
Expand Down Expand Up @@ -65,6 +84,24 @@ namespace openhack::hacks {
}
}

void Shortcuts::uncompleteLevel() {
gui::Modal::create("Uncomplete level", [](gui::Modal *popup) {
ImGui::TextWrapped("This will clear all progress from the current level (except for orbs).");
ImGui::TextWrapped("Are you sure you want to uncomplete the level?");

if (gui::button("Yes", {0.5f, 0.f})) {
uncompleteLevelConfirmed();
popup->close();
}

ImGui::SameLine(0, 2);

if (gui::button("Cancel")) {
popup->close();
}
});
}

void Shortcuts::openOptions() {
auto *options = gd::OptionsLayer::create();
auto *scene = gd::cocos2d::CCDirector::sharedDirector()->getRunningScene();
Expand Down
Loading

0 comments on commit 9ce72fd

Please sign in to comment.