mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-03-28 07:47:03 -05:00
feat: Added full-screen views for use with subcommands in the future
This commit is contained in:
2
lib/external/libwolv
vendored
2
lib/external/libwolv
vendored
Submodule lib/external/libwolv updated: 68e548eaa9...95efb87f5d
@@ -580,7 +580,10 @@ EXPORT_MODULE namespace hex {
|
||||
namespace impl {
|
||||
|
||||
void add(std::unique_ptr<View> &&view);
|
||||
void setFullScreenView(std::unique_ptr<View> &&view);
|
||||
|
||||
const std::map<UnlocalizedString, std::unique_ptr<View>>& getEntries();
|
||||
const std::unique_ptr<View>& getFullScreenView();
|
||||
|
||||
}
|
||||
|
||||
@@ -595,6 +598,17 @@ EXPORT_MODULE namespace hex {
|
||||
return impl::add(std::make_unique<T>(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a view as a full-screen view. This will cause the view to take up the entire ImHex window
|
||||
* @tparam T The custom view class that extends View
|
||||
* @tparam Args Arguments types
|
||||
* @param args Arguments passed to the constructor of the view
|
||||
*/
|
||||
template<std::derived_from<View> T, typename... Args>
|
||||
void setFullScreenView(Args &&...args) {
|
||||
return impl::setFullScreenView(std::make_unique<T>(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets a view by its unlocalized name
|
||||
* @param unlocalizedName The unlocalized name of the view
|
||||
|
||||
@@ -119,6 +119,7 @@ namespace hex {
|
||||
class Special;
|
||||
class Floating;
|
||||
class Modal;
|
||||
class FullScreen;
|
||||
|
||||
private:
|
||||
UnlocalizedString m_unlocalizedViewName;
|
||||
@@ -142,7 +143,8 @@ namespace hex {
|
||||
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())) {
|
||||
const auto title = hex::format("{} {}", this->getIcon(), View::toWindowName(this->getUnlocalizedName()));
|
||||
if (ImGui::Begin(title.c_str(), &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse | this->getWindowFlags())) {
|
||||
this->drawContent();
|
||||
}
|
||||
ImGui::End();
|
||||
@@ -206,4 +208,14 @@ namespace hex {
|
||||
[[nodiscard]] bool shouldStoreWindowState() const override { return false; }
|
||||
};
|
||||
|
||||
class View::FullScreen : public View {
|
||||
public:
|
||||
explicit FullScreen() : View("FullScreen", "") {}
|
||||
|
||||
void draw() final {
|
||||
this->drawContent();
|
||||
this->drawAlwaysVisibleContent();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -720,10 +720,19 @@ namespace hex {
|
||||
}
|
||||
|
||||
void add(std::unique_ptr<View> &&view) {
|
||||
log::debug("Registered new view: {}", view->getUnlocalizedName().get());
|
||||
log::debug("Registered new view: {}", view->getUnlocalizedName().get());
|
||||
|
||||
s_views->emplace(view->getUnlocalizedName(), std::move(view));
|
||||
}
|
||||
s_views->emplace(view->getUnlocalizedName(), std::move(view));
|
||||
}
|
||||
|
||||
static AutoReset<std::unique_ptr<View>> s_fullscreenView;
|
||||
const std::unique_ptr<View>& getFullScreenView() {
|
||||
return *s_fullscreenView;
|
||||
}
|
||||
|
||||
void setFullScreenView(std::unique_ptr<View> &&view) {
|
||||
s_fullscreenView = std::move(view);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -740,66 +740,70 @@ namespace hex {
|
||||
|
||||
ShortcutManager::resetLastActivatedMenu();
|
||||
|
||||
// Loop through all views and draw them
|
||||
for (auto &[name, view] : ContentRegistry::Views::impl::getEntries()) {
|
||||
ImGui::GetCurrentContext()->NextWindowData.ClearFlags();
|
||||
if (const auto &fullScreenView = ContentRegistry::Views::impl::getFullScreenView(); fullScreenView == nullptr) {
|
||||
|
||||
// Draw always visible views
|
||||
view->drawAlwaysVisibleContent();
|
||||
// Loop through all views and draw them
|
||||
for (auto &[name, view] : ContentRegistry::Views::impl::getEntries()) {
|
||||
ImGui::GetCurrentContext()->NextWindowData.ClearFlags();
|
||||
|
||||
// Skip views that shouldn't be processed currently
|
||||
if (!view->shouldProcess())
|
||||
continue;
|
||||
// Draw always visible views
|
||||
view->drawAlwaysVisibleContent();
|
||||
|
||||
const auto openViewCount = std::ranges::count_if(ContentRegistry::Views::impl::getEntries(), [](const auto &entry) {
|
||||
const auto &[unlocalizedName, openView] = entry;
|
||||
// Skip views that shouldn't be processed currently
|
||||
if (!view->shouldProcess())
|
||||
continue;
|
||||
|
||||
return openView->hasViewMenuItemEntry() && openView->shouldProcess();
|
||||
});
|
||||
const auto openViewCount = std::ranges::count_if(ContentRegistry::Views::impl::getEntries(), [](const auto &entry) {
|
||||
const auto &[unlocalizedName, openView] = entry;
|
||||
|
||||
ImGuiWindowClass windowClass = {};
|
||||
return openView->hasViewMenuItemEntry() && openView->shouldProcess();
|
||||
});
|
||||
|
||||
windowClass.DockNodeFlagsOverrideSet |= ImGuiDockNodeFlags_NoCloseButton;
|
||||
ImGuiWindowClass windowClass = {};
|
||||
|
||||
if (openViewCount <= 1 || LayoutManager::isLayoutLocked())
|
||||
windowClass.DockNodeFlagsOverrideSet |= ImGuiDockNodeFlags_NoTabBar;
|
||||
windowClass.DockNodeFlagsOverrideSet |= ImGuiDockNodeFlags_NoCloseButton;
|
||||
|
||||
ImGui::SetNextWindowClass(&windowClass);
|
||||
if (openViewCount <= 1 || LayoutManager::isLayoutLocked())
|
||||
windowClass.DockNodeFlagsOverrideSet |= ImGuiDockNodeFlags_NoTabBar;
|
||||
|
||||
auto window = ImGui::FindWindowByName(view->getName().c_str());
|
||||
if (window != nullptr && window->DockNode == nullptr)
|
||||
ImGui::SetNextWindowBgAlpha(1.0F);
|
||||
ImGui::SetNextWindowClass(&windowClass);
|
||||
|
||||
// Draw view
|
||||
view->draw();
|
||||
view->trackViewOpenState();
|
||||
auto window = ImGui::FindWindowByName(view->getName().c_str());
|
||||
if (window != nullptr && window->DockNode == nullptr)
|
||||
ImGui::SetNextWindowBgAlpha(1.0F);
|
||||
|
||||
if (view->getWindowOpenState()) {
|
||||
// Get the currently focused view
|
||||
if (window != nullptr && (window->Flags & ImGuiWindowFlags_Popup) != ImGuiWindowFlags_Popup) {
|
||||
auto windowName = View::toWindowName(name);
|
||||
ImGui::Begin(windowName.c_str());
|
||||
// Draw view
|
||||
view->draw();
|
||||
view->trackViewOpenState();
|
||||
|
||||
// Detect if the window is focused
|
||||
const bool focused = ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows | ImGuiFocusedFlags_NoPopupHierarchy);
|
||||
view->setFocused(focused);
|
||||
if (view->getWindowOpenState()) {
|
||||
// Get the currently focused view
|
||||
if (window != nullptr && (window->Flags & ImGuiWindowFlags_Popup) != ImGuiWindowFlags_Popup) {
|
||||
auto windowName = View::toWindowName(name);
|
||||
ImGui::Begin(windowName.c_str());
|
||||
|
||||
// Dock the window if it's not already docked
|
||||
if (view->didWindowJustOpen() && !ImGui::IsWindowDocked()) {
|
||||
ImGui::DockBuilderDockWindow(windowName.c_str(), ImHexApi::System::getMainDockSpaceId());
|
||||
EventViewOpened::post(view.get());
|
||||
// Detect if the window is focused
|
||||
const bool focused = ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows | ImGuiFocusedFlags_NoPopupHierarchy);
|
||||
view->setFocused(focused);
|
||||
|
||||
// Dock the window if it's not already docked
|
||||
if (view->didWindowJustOpen() && !ImGui::IsWindowDocked()) {
|
||||
ImGui::DockBuilderDockWindow(windowName.c_str(), ImHexApi::System::getMainDockSpaceId());
|
||||
EventViewOpened::post(view.get());
|
||||
}
|
||||
|
||||
// Pass on currently pressed keys to the shortcut handler
|
||||
for (const auto &key : m_pressedKeys) {
|
||||
ShortcutManager::process(view.get(), io.ConfigMacOSXBehaviors ? io.KeySuper : io.KeyCtrl, io.KeyAlt, io.KeyShift, io.ConfigMacOSXBehaviors ? io.KeyCtrl : io.KeySuper, focused, key);
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
// Pass on currently pressed keys to the shortcut handler
|
||||
for (const auto &key : m_pressedKeys) {
|
||||
ShortcutManager::process(view.get(), io.ConfigMacOSXBehaviors ? io.KeySuper : io.KeyCtrl, io.KeyAlt, io.KeyShift, io.ConfigMacOSXBehaviors ? io.KeyCtrl : io.KeySuper, focused, key);
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Handle global shortcuts
|
||||
for (const auto &key : m_pressedKeys) {
|
||||
ShortcutManager::processGlobals(io.ConfigMacOSXBehaviors ? io.KeySuper : io.KeyCtrl, io.KeyAlt, io.KeyShift, io.ConfigMacOSXBehaviors ? io.KeyCtrl : io.KeySuper, key);
|
||||
|
||||
@@ -502,33 +502,38 @@ namespace hex::plugin::builtin {
|
||||
if (ImGui::Begin("Welcome Screen", nullptr, ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove)) {
|
||||
ImGui::BringWindowToDisplayBack(ImGui::GetCurrentWindowRead());
|
||||
|
||||
drawWelcomeScreenBackground();
|
||||
if (const auto &fullScreenView = ContentRegistry::Views::impl::getFullScreenView(); fullScreenView != nullptr) {
|
||||
fullScreenView->draw();
|
||||
} else {
|
||||
drawWelcomeScreenBackground();
|
||||
|
||||
if (s_simplifiedWelcomeScreen)
|
||||
drawWelcomeScreenContentSimplified();
|
||||
else
|
||||
drawWelcomeScreenContentFull();
|
||||
if (s_simplifiedWelcomeScreen)
|
||||
drawWelcomeScreenContentSimplified();
|
||||
else
|
||||
drawWelcomeScreenContentFull();
|
||||
|
||||
static bool hovered = false;
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, hovered ? 1.0F : 0.3F);
|
||||
{
|
||||
const ImVec2 windowSize = { 150_scaled, ImGui::GetTextLineHeightWithSpacing() * 3.5F };
|
||||
ImGui::SetCursorScreenPos(ImGui::GetWindowPos() + ImGui::GetWindowSize() - windowSize - ImGui::GetStyle().WindowPadding);
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::GetStyleColorVec4(ImGuiCol_WindowBg));
|
||||
if (ImGuiExt::BeginSubWindow("hex.builtin.welcome.header.quick_settings"_lang, nullptr, windowSize, ImGuiChildFlags_AutoResizeY)) {
|
||||
if (ImGuiExt::ToggleSwitch("hex.builtin.welcome.quick_settings.simplified"_lang, &s_simplifiedWelcomeScreen)) {
|
||||
ContentRegistry::Settings::write<bool>("hex.builtin.setting.interface", "hex.builtin.setting.interface.simplified_welcome_screen", s_simplifiedWelcomeScreen);
|
||||
WorkspaceManager::switchWorkspace(s_simplifiedWelcomeScreen ? "Minimal" : "Default");
|
||||
}
|
||||
|
||||
static bool hovered = false;
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, hovered ? 1.0F : 0.3F);
|
||||
{
|
||||
const ImVec2 windowSize = { 150_scaled, ImGui::GetTextLineHeightWithSpacing() * 3.5F };
|
||||
ImGui::SetCursorScreenPos(ImGui::GetWindowPos() + ImGui::GetWindowSize() - windowSize - ImGui::GetStyle().WindowPadding);
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::GetStyleColorVec4(ImGuiCol_WindowBg));
|
||||
if (ImGuiExt::BeginSubWindow("hex.builtin.welcome.header.quick_settings"_lang, nullptr, windowSize, ImGuiChildFlags_AutoResizeY)) {
|
||||
if (ImGuiExt::ToggleSwitch("hex.builtin.welcome.quick_settings.simplified"_lang, &s_simplifiedWelcomeScreen)) {
|
||||
ContentRegistry::Settings::write<bool>("hex.builtin.setting.interface", "hex.builtin.setting.interface.simplified_welcome_screen", s_simplifiedWelcomeScreen);
|
||||
WorkspaceManager::switchWorkspace(s_simplifiedWelcomeScreen ? "Minimal" : "Default");
|
||||
}
|
||||
ImGuiExt::EndSubWindow();
|
||||
|
||||
ImGui::PopStyleColor();
|
||||
hovered = ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenOverlappedByItem | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem);
|
||||
|
||||
}
|
||||
ImGuiExt::EndSubWindow();
|
||||
|
||||
ImGui::PopStyleColor();
|
||||
hovered = ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenOverlappedByItem | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem);
|
||||
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
}
|
||||
ImGui::End();
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
@@ -495,7 +495,12 @@ namespace hex::plugin::builtin {
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
drawMenu();
|
||||
|
||||
{
|
||||
ImGui::BeginDisabled(ContentRegistry::Views::impl::getFullScreenView() != nullptr);
|
||||
drawMenu();
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
menu::endMainMenuBar();
|
||||
}
|
||||
menu::enableNativeMenuBar(false);
|
||||
@@ -541,18 +546,23 @@ namespace hex::plugin::builtin {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0F);
|
||||
if (ImGui::BeginMenuBar()) {
|
||||
drawTitleBarBackDrop();
|
||||
for (const auto &callback : ContentRegistry::Interface::impl::getToolbarItems()) {
|
||||
callback();
|
||||
ImGui::SameLine();
|
||||
}
|
||||
|
||||
if (auto provider = ImHexApi::Provider::get(); provider != nullptr) {
|
||||
ImGui::BeginDisabled(TaskManager::getRunningTaskCount() > 0);
|
||||
if (ImGui::CloseButton(ImGui::GetID("ProviderCloseButton"), ImGui::GetCursorScreenPos() + ImVec2(ImGui::GetContentRegionAvail().x - 17_scaled, 3_scaled))) {
|
||||
ImHexApi::Provider::remove(provider);
|
||||
ImGui::BeginDisabled(ContentRegistry::Views::impl::getFullScreenView() != nullptr);
|
||||
{
|
||||
for (const auto &callback : ContentRegistry::Interface::impl::getToolbarItems()) {
|
||||
callback();
|
||||
ImGui::SameLine();
|
||||
}
|
||||
|
||||
if (auto provider = ImHexApi::Provider::get(); provider != nullptr) {
|
||||
ImGui::BeginDisabled(TaskManager::getRunningTaskCount() > 0);
|
||||
if (ImGui::CloseButton(ImGui::GetID("ProviderCloseButton"), ImGui::GetCursorScreenPos() + ImVec2(ImGui::GetContentRegionAvail().x - 17_scaled, 3_scaled))) {
|
||||
ImHexApi::Provider::remove(provider);
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user