2020-12-22 18:10:01 +01:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <hex.hpp>
|
|
|
|
|
2021-01-13 17:28:27 +01:00
|
|
|
#include <imgui.h>
|
2021-09-20 23:40:36 +02:00
|
|
|
#include <imgui_internal.h>
|
2021-12-31 01:10:06 +01:00
|
|
|
#include <hex/ui/imgui_imhex_extensions.h>
|
2021-02-25 21:50:57 +01:00
|
|
|
|
2022-07-26 14:59:08 +02:00
|
|
|
#include <fonts/fontawesome_font.h>
|
|
|
|
#include <fonts/codicons_font.h>
|
2020-12-22 18:10:01 +01:00
|
|
|
|
2021-08-21 13:55:21 +02:00
|
|
|
#include <hex/api/imhex_api.hpp>
|
2023-11-18 14:50:43 +01:00
|
|
|
#include <hex/api/shortcut_manager.hpp>
|
|
|
|
#include <hex/api/event_manager.hpp>
|
2021-01-27 14:26:24 +01:00
|
|
|
#include <hex/providers/provider.hpp>
|
2023-04-17 16:18:48 +02:00
|
|
|
#include <hex/providers/provider_data.hpp>
|
2022-02-27 23:25:39 +01:00
|
|
|
#include <hex/helpers/utils.hpp>
|
2020-12-22 18:10:01 +01:00
|
|
|
|
2023-11-21 14:38:01 +01:00
|
|
|
#include <hex/api/localization_manager.hpp>
|
2021-09-08 15:18:24 +02:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
#include <map>
|
2020-12-22 18:10:01 +01:00
|
|
|
#include <string>
|
|
|
|
|
|
|
|
namespace hex {
|
|
|
|
|
|
|
|
class View {
|
2023-11-10 20:47:08 +01:00
|
|
|
explicit View(std::string unlocalizedName);
|
2023-11-21 13:47:50 +01:00
|
|
|
public:
|
2020-12-22 18:10:01 +01:00
|
|
|
virtual ~View() = default;
|
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
/**
|
|
|
|
* @brief Draws the view
|
|
|
|
* @note Do not override this method. Override drawContent() instead
|
|
|
|
*/
|
|
|
|
virtual void draw() = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Draws the content of the view
|
|
|
|
*/
|
2020-12-22 18:10:01 +01:00
|
|
|
virtual void drawContent() = 0;
|
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
/**
|
|
|
|
* @brief Draws content that should always be visible, even if the view is not open
|
|
|
|
*/
|
|
|
|
virtual void drawAlwaysVisibleContent() { }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Whether or not the view window should be drawn
|
|
|
|
* @return True if the view window should be drawn, false otherwise
|
|
|
|
*/
|
|
|
|
[[nodiscard]] virtual bool shouldDraw() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Whether or not the entire view should be processed
|
|
|
|
* If this returns false, the view will not be drawn and no shortcuts will be handled. This includes things
|
|
|
|
* drawn in the drawAlwaysVisibleContent() function.
|
|
|
|
* @return True if the view should be processed, false otherwise
|
|
|
|
*/
|
2023-11-21 14:38:01 +01:00
|
|
|
[[nodiscard]] virtual bool shouldProcess() const;
|
2023-11-21 13:47:50 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Whether or not the view should have an entry in the view menu
|
|
|
|
* @return True if the view should have an entry in the view menu, false otherwise
|
|
|
|
*/
|
2022-02-01 18:09:40 +01:00
|
|
|
[[nodiscard]] virtual bool hasViewMenuItemEntry() const;
|
2023-11-21 13:47:50 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Gets the minimum size of the view window
|
|
|
|
* @return The minimum size of the view window
|
|
|
|
*/
|
2022-02-01 18:09:40 +01:00
|
|
|
[[nodiscard]] virtual ImVec2 getMinSize() const;
|
2023-11-21 13:47:50 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Gets the maximum size of the view window
|
|
|
|
* @return The maximum size of the view window
|
|
|
|
*/
|
2022-02-01 18:09:40 +01:00
|
|
|
[[nodiscard]] virtual ImVec2 getMaxSize() const;
|
2020-12-22 18:10:01 +01:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
/**
|
|
|
|
* @brief Gets additional window flags for the view window
|
|
|
|
* @return Additional window flags for the view window
|
|
|
|
*/
|
|
|
|
[[nodiscard]] virtual ImGuiWindowFlags getWindowFlags() const;
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-02-01 18:09:40 +01:00
|
|
|
[[nodiscard]] bool &getWindowOpenState();
|
|
|
|
[[nodiscard]] const bool &getWindowOpenState() const;
|
2020-12-22 18:10:01 +01:00
|
|
|
|
2022-01-24 20:53:17 +01:00
|
|
|
[[nodiscard]] const std::string &getUnlocalizedName() const;
|
2022-01-18 00:10:10 +01:00
|
|
|
[[nodiscard]] std::string getName() const;
|
2020-12-22 18:10:01 +01:00
|
|
|
|
2023-10-30 21:53:44 +01:00
|
|
|
[[nodiscard]] bool didWindowJustOpen();
|
|
|
|
void setWindowJustOpened(bool state);
|
|
|
|
|
2021-09-22 17:56:06 +02:00
|
|
|
static void discardNavigationRequests();
|
2021-01-04 00:19:56 +01:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
[[nodiscard]] static std::string toWindowName(const std::string &unlocalizedName);
|
2021-03-03 22:26:17 +01:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
public:
|
|
|
|
class Window;
|
|
|
|
class Special;
|
|
|
|
class Floating;
|
|
|
|
class Modal;
|
2022-02-01 18:09:40 +01:00
|
|
|
|
2020-12-22 18:10:01 +01:00
|
|
|
private:
|
2021-03-03 22:26:17 +01:00
|
|
|
std::string m_unlocalizedViewName;
|
2021-04-12 21:08:36 +02:00
|
|
|
bool m_windowOpen = false;
|
2023-11-17 14:46:21 +01:00
|
|
|
std::map<Shortcut, ShortcutManager::ShortcutEntry> m_shortcuts;
|
2023-10-30 21:53:44 +01:00
|
|
|
bool m_windowJustOpened = false;
|
2021-12-23 15:11:38 +01:00
|
|
|
|
|
|
|
friend class ShortcutManager;
|
2020-12-22 18:10:01 +01:00
|
|
|
};
|
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief A view that draws a regular window. This should be the default for most views
|
|
|
|
*/
|
|
|
|
class View::Window : public View {
|
|
|
|
public:
|
|
|
|
explicit Window(std::string unlocalizedName) : View(std::move(unlocalizedName)) {}
|
|
|
|
|
|
|
|
void draw() final {
|
|
|
|
if (this->shouldDraw()) {
|
|
|
|
ImGui::SetNextWindowSizeConstraints(this->getMinSize(), this->getMaxSize());
|
|
|
|
if (ImGui::Begin(View::toWindowName(this->getUnlocalizedName()).c_str(), &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse | this->getWindowFlags())) {
|
|
|
|
this->drawContent();
|
|
|
|
}
|
|
|
|
ImGui::End();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief A view that doesn't handle any window creation and just draws its content.
|
|
|
|
* This should be used if you intend to draw your own special window
|
|
|
|
*/
|
|
|
|
class View::Special : public View {
|
|
|
|
public:
|
|
|
|
explicit Special(std::string unlocalizedName) : View(std::move(unlocalizedName)) {}
|
|
|
|
|
|
|
|
void draw() final {
|
|
|
|
if (this->shouldDraw()) {
|
2023-11-25 12:43:48 +01:00
|
|
|
ImGui::SetNextWindowSizeConstraints(this->getMinSize(), this->getMaxSize());
|
2023-11-21 13:47:50 +01:00
|
|
|
this->drawContent();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief A view that draws a floating window. These are the same as regular windows but cannot be docked
|
|
|
|
*/
|
|
|
|
class View::Floating : public View::Window {
|
|
|
|
public:
|
|
|
|
explicit Floating(std::string unlocalizedName) : Window(std::move(unlocalizedName)) {}
|
|
|
|
|
|
|
|
[[nodiscard]] ImGuiWindowFlags getWindowFlags() const final { return ImGuiWindowFlags_NoDocking; }
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief A view that draws a modal window. The window will always be drawn on top and will block input to other windows
|
|
|
|
*/
|
|
|
|
class View::Modal : public View {
|
|
|
|
public:
|
|
|
|
explicit Modal(std::string unlocalizedName) : View(std::move(unlocalizedName)) {}
|
|
|
|
|
|
|
|
void draw() final {
|
|
|
|
if (this->shouldDraw()) {
|
|
|
|
ImGui::SetNextWindowSizeConstraints(this->getMinSize(), this->getMaxSize());
|
|
|
|
|
2023-11-23 13:08:45 +01:00
|
|
|
if (this->getWindowOpenState())
|
|
|
|
ImGui::OpenPopup(View::toWindowName(this->getUnlocalizedName()).c_str());
|
|
|
|
|
2023-11-27 15:34:05 +01:00
|
|
|
if (ImGui::BeginPopupModal(View::toWindowName(this->getUnlocalizedName()).c_str(), &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_AlwaysAutoResize | this->getWindowFlags())) {
|
2023-11-21 13:47:50 +01:00
|
|
|
this->drawContent();
|
2023-11-21 14:38:01 +01:00
|
|
|
|
|
|
|
ImGui::EndPopup();
|
2023-11-21 13:47:50 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2020-12-22 18:10:01 +01:00
|
|
|
}
|