impr: Better experience when first starting ImHex (#1510)
@ -252,6 +252,7 @@ namespace hex {
|
||||
EVENT_DEF(EventAchievementUnlocked, const Achievement&);
|
||||
EVENT_DEF(EventSearchBoxClicked, u32);
|
||||
EVENT_DEF(EventViewOpened, View*);
|
||||
EVENT_DEF(EventFirstLaunch);
|
||||
|
||||
EVENT_DEF(EventFileDragged, bool);
|
||||
EVENT_DEF(EventFileDropped, std::fs::path);
|
||||
|
@ -381,6 +381,8 @@ namespace hex {
|
||||
void addInitArgument(const std::string &key, const std::string &value = { });
|
||||
|
||||
void setLastFrameTime(double time);
|
||||
|
||||
bool isWindowResizable();
|
||||
}
|
||||
|
||||
struct ProgramArguments {
|
||||
@ -579,6 +581,8 @@ namespace hex {
|
||||
void addStartupTask(const std::string &name, bool async, const std::function<bool()> &function);
|
||||
|
||||
double getLastFrameTime();
|
||||
|
||||
void setWindowResizable(bool resizable);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include <imgui.h>
|
||||
#include <imgui_internal.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
@ -448,6 +449,11 @@ namespace hex {
|
||||
s_lastFrameTime = time;
|
||||
}
|
||||
|
||||
static bool s_windowResizable = true;
|
||||
bool isWindowResizable() {
|
||||
return s_windowResizable;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -708,6 +714,12 @@ namespace hex {
|
||||
return impl::s_lastFrameTime;
|
||||
}
|
||||
|
||||
void setWindowResizable(bool resizable) {
|
||||
glfwSetWindowAttrib(impl::s_mainWindowHandle, GLFW_RESIZABLE, resizable);
|
||||
impl::s_windowResizable = resizable;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -197,6 +197,12 @@ namespace hex {
|
||||
|
||||
std::string_view hoveredWindowName = GImGui->HoveredWindow == nullptr ? "" : GImGui->HoveredWindow->Name;
|
||||
|
||||
if (!ImHexApi::System::impl::isWindowResizable()) {
|
||||
if (result != RegionClient) {
|
||||
return HTCAPTION;
|
||||
}
|
||||
}
|
||||
|
||||
switch (result) {
|
||||
case RegionLeft:
|
||||
return HTLEFT;
|
||||
@ -481,6 +487,13 @@ namespace hex {
|
||||
// Remove WS_POPUP style from the window to make various window management tools work
|
||||
auto hwnd = glfwGetWin32Window(m_window);
|
||||
::SetWindowLong(hwnd, GWL_STYLE, (GetWindowLong(hwnd, GWL_STYLE) | WS_OVERLAPPEDWINDOW) & ~WS_POPUP);
|
||||
|
||||
if (!ImHexApi::System::impl::isWindowResizable()) {
|
||||
if (glfwGetWindowAttrib(m_window, GLFW_MAXIMIZED)) {
|
||||
glfwRestoreWindow(m_window);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Window::endNativeWindowFrame() {
|
||||
|
@ -159,6 +159,14 @@ namespace hex {
|
||||
|
||||
glfwPollEvents();
|
||||
|
||||
static ImVec2 lastWindowSize = ImHexApi::System::getMainWindowSize();
|
||||
if (ImHexApi::System::impl::isWindowResizable()) {
|
||||
glfwSetWindowSizeLimits(m_window, 480_scaled, 360_scaled, GLFW_DONT_CARE, GLFW_DONT_CARE);
|
||||
lastWindowSize = ImHexApi::System::getMainWindowSize();
|
||||
} else {
|
||||
glfwSetWindowSizeLimits(m_window, lastWindowSize.x, lastWindowSize.y, lastWindowSize.x, lastWindowSize.y);
|
||||
}
|
||||
|
||||
// Render frame
|
||||
this->frameBegin();
|
||||
this->frame();
|
||||
|
@ -44,6 +44,7 @@ add_imhex_plugin(
|
||||
source/content/fonts.cpp
|
||||
source/content/workspaces.cpp
|
||||
source/content/pl_visualizers.cpp
|
||||
source/content/out_of_box_experience.cpp
|
||||
|
||||
source/content/data_processor_nodes/basic_nodes.cpp
|
||||
source/content/data_processor_nodes/control_nodes.cpp
|
||||
|
@ -1,117 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex/ui/popup.hpp>
|
||||
|
||||
#include <hex/api/localization_manager.hpp>
|
||||
|
||||
#include <wolv/hash/uuid.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
class PopupTelemetryRequest : public Popup<PopupTelemetryRequest> {
|
||||
public:
|
||||
PopupTelemetryRequest()
|
||||
: hex::Popup<PopupTelemetryRequest>("hex.ui.common.question", false) {
|
||||
// Check if there is a telemetry uuid
|
||||
m_uuid = ContentRegistry::Settings::read("hex.builtin.setting.general", "hex.builtin.setting.general.uuid", "").get<std::string>();
|
||||
if(m_uuid.empty()) {
|
||||
// Generate a new uuid
|
||||
m_uuid = wolv::hash::generateUUID();
|
||||
// Save
|
||||
ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.uuid", m_uuid);
|
||||
}
|
||||
}
|
||||
|
||||
void drawContent() override {
|
||||
static std::string message = "hex.builtin.welcome.server_contact_text"_lang;
|
||||
ImGuiExt::TextFormattedWrapped("{}", message.c_str());
|
||||
ImGui::NewLine();
|
||||
|
||||
if(ImGui::CollapsingHeader("hex.builtin.welcome.server_contact.data_collected_title"_lang)) {
|
||||
if(ImGui::BeginTable("hex.builtin.welcome.server_contact.data_collected_table"_lang, 2,
|
||||
ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY | ImGuiTableFlags_NoHostExtendY,
|
||||
ImVec2(ImGui::GetContentRegionAvail().x, 100_scaled))) {
|
||||
ImGui::TableSetupColumn("hex.builtin.welcome.server_contact.data_collected_table.key"_lang);
|
||||
ImGui::TableSetupColumn("hex.builtin.welcome.server_contact.data_collected_table.value"_lang, ImGuiTableColumnFlags_WidthStretch);
|
||||
ImGui::TableSetupScrollFreeze(0, 1);
|
||||
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted("hex.builtin.welcome.server_contact.data_collected.uuid"_lang);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextWrapped("%s", m_uuid.c_str());
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted("hex.builtin.welcome.server_contact.data_collected.version"_lang);
|
||||
ImGui::TableNextColumn();
|
||||
ImGuiExt::TextFormattedWrapped("{}\n{}@{}\n{}",
|
||||
ImHexApi::System::getImHexVersion(),
|
||||
ImHexApi::System::getCommitHash(true),
|
||||
ImHexApi::System::getCommitBranch(),
|
||||
ImHexApi::System::isPortableVersion() ? "Portable" : "Installed"
|
||||
);
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted("hex.builtin.welcome.server_contact.data_collected.os"_lang);
|
||||
ImGui::TableNextColumn();
|
||||
ImGuiExt::TextFormattedWrapped("{}\n{}\n{}\n{}",
|
||||
ImHexApi::System::getOSName(),
|
||||
ImHexApi::System::getOSVersion(),
|
||||
ImHexApi::System::getArchitecture(),
|
||||
ImHexApi::System::getGPUVendor());
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::NewLine();
|
||||
|
||||
const auto width = ImGui::GetWindowWidth();
|
||||
const auto buttonSize = ImVec2(width / 3 - ImGui::GetStyle().FramePadding.x * 3, 0);
|
||||
const auto buttonPos = [&](u8 index) { return ImGui::GetStyle().FramePadding.x + (buttonSize.x + ImGui::GetStyle().FramePadding.x * 3) * index; };
|
||||
|
||||
ImGui::SetCursorPosX(buttonPos(0));
|
||||
if (ImGui::Button("hex.ui.common.allow"_lang, buttonSize)) {
|
||||
ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.server_contact", 1);
|
||||
ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.upload_crash_logs", 1);
|
||||
this->close();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosX(buttonPos(1));
|
||||
if (ImGui::Button("hex.builtin.welcome.server_contact.crash_logs_only"_lang, buttonSize)) {
|
||||
ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.server_contact", 0);
|
||||
ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.upload_crash_logs", 1);
|
||||
this->close();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosX(buttonPos(2));
|
||||
if (ImGui::Button("hex.ui.common.deny"_lang, buttonSize)) {
|
||||
this->close();
|
||||
}
|
||||
|
||||
ImGui::SetWindowPos((ImHexApi::System::getMainWindowSize() - ImGui::GetWindowSize()) / 2, ImGuiCond_Appearing);
|
||||
}
|
||||
|
||||
[[nodiscard]] ImGuiWindowFlags getFlags() const override {
|
||||
return ImGuiWindowFlags_AlwaysAutoResize;
|
||||
}
|
||||
|
||||
[[nodiscard]] ImVec2 getMinSize() const override {
|
||||
return scaled({ 500, 100 });
|
||||
}
|
||||
|
||||
[[nodiscard]] ImVec2 getMaxSize() const override {
|
||||
return scaled({ 500, 450 });
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_uuid;
|
||||
};
|
||||
|
||||
}
|
BIN
plugins/builtin/romfs/assets/common/compass.png
Normal file
After Width: | Height: | Size: 39 KiB |
42
plugins/builtin/romfs/assets/screenshot_descriptions.json
Normal file
@ -0,0 +1,42 @@
|
||||
{
|
||||
"3d_visualizer.png": {
|
||||
"title": "Advanced Data Visualizers",
|
||||
"description": "After analyzing data using the pattern language, it's often useful to visualize parts of that data. ImHex provides a variety of visualizers that can be used to visualize different types of data right in the editor.\n\nAvailable visualizers include a 3D model viewer, RGBA and Image decoder, a audio player, line and scatter plots and many more!"
|
||||
},
|
||||
"bookmarks.png": {
|
||||
"title": "Bookmarks",
|
||||
"description": "Bookmarks can be used to mark interesting locations in the file, give them a name, color and description."
|
||||
},
|
||||
"data_analysis.png": {
|
||||
"title": "Data Analysis",
|
||||
"description": "ImHex provides a variety of tools to analyze data and finding interesting information in it. This includes byte type and entropy graphs, byte frequency analysis, digram and layered distribution graphs and file magic based data type detection."
|
||||
},
|
||||
"data_processor.png": {
|
||||
"title": "Data Pre-processors",
|
||||
"description": "ImHex's data pre-processors can be used to transform the data before it's displayed in the editor. This can be used to decrypt encrypted data, extract parts of the file for further analysis or calculate custom checksums."
|
||||
},
|
||||
"diffing.png": {
|
||||
"title": "Binary Diffing",
|
||||
"description": "ImHex provides a powerful binary diffing tool that can compare two files and find the differences between them. It's able identify insertions, deletions and modifications of data."
|
||||
},
|
||||
"floating_windows.png": {
|
||||
"title": "Modern Interface",
|
||||
"description": "ImHex's interface is based on a range of dockable windows that can be moved around and detached from the main window at any time. This allows for a very flexible and customizable interface.\n\nThe interface is also fully themeable and comes with various built-in themes by default."
|
||||
},
|
||||
"patterns.png": {
|
||||
"title": "Pattern Language",
|
||||
"description": "ImHex's pattern language is a C-like language that can be used to describe data structures and patterns in the data. Writing format specifications in it allows ImHex to parse and decode the data and display it in a human readable way as well as highlight the different parts of the data in the Hex Editor.\n\nMany common data formats are already supported by the community and new ones can be created and shared easily."
|
||||
},
|
||||
"simplified_mode.png": {
|
||||
"title": "Simplified Mode",
|
||||
"description": "ImHex's simplified mode is a more beginner friendly mode that hides some of the more advanced features of the editor. It's a great way to get started with reverse engineering and binary analysis or to use ImHex without being overwhelmed by the amount of features."
|
||||
},
|
||||
"tools.png": {
|
||||
"title": "Helpful Tools",
|
||||
"description": "ImHex comes with a variety of tools that can be used to analyze and modify the data. This includes a symbol demangler, calculator, TCP client and server and many more!"
|
||||
},
|
||||
"welcome_screen.png": {
|
||||
"title": "Welcome Screen",
|
||||
"description": "ImHex's welcome screen provides a quick overview of the most important features and allows to quickly open files and projects.\n\nThere's many more options that go beyond just opening files, such as connecting to a GDB Server, attaching to a process or opening Intel Hex, Motorola S-Record and Base64 files."
|
||||
}
|
||||
}
|
BIN
plugins/builtin/romfs/assets/screenshots/3d_visualizer.png
Normal file
After Width: | Height: | Size: 71 KiB |
BIN
plugins/builtin/romfs/assets/screenshots/bookmarks.png
Normal file
After Width: | Height: | Size: 71 KiB |
BIN
plugins/builtin/romfs/assets/screenshots/data_analysis.png
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
plugins/builtin/romfs/assets/screenshots/data_processor.png
Normal file
After Width: | Height: | Size: 61 KiB |
BIN
plugins/builtin/romfs/assets/screenshots/diffing.png
Normal file
After Width: | Height: | Size: 57 KiB |
BIN
plugins/builtin/romfs/assets/screenshots/floating_windows.png
Normal file
After Width: | Height: | Size: 43 KiB |
BIN
plugins/builtin/romfs/assets/screenshots/patterns.png
Normal file
After Width: | Height: | Size: 88 KiB |
BIN
plugins/builtin/romfs/assets/screenshots/simplified_mode.png
Normal file
After Width: | Height: | Size: 6.5 KiB |
BIN
plugins/builtin/romfs/assets/screenshots/tools.png
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
plugins/builtin/romfs/assets/screenshots/welcome_screen.png
Normal file
After Width: | Height: | Size: 23 KiB |
@ -785,14 +785,14 @@
|
||||
"hex.builtin.visualizer.hexadecimal.8bit": "Hexadezimal (8 bits)",
|
||||
"hex.builtin.visualizer.hexii": "HexII",
|
||||
"hex.builtin.visualizer.rgba8": "RGBA8 Farbe",
|
||||
"hex.builtin.welcome.server_contact_text": "Möchtest du die Kommunikation mit ImHex Servern zulassen?\n\nDies erlaubt das automatische suchen nach Updates und das hochladen\nvon anonymen crash logs im falle eines absturzes.",
|
||||
"hex.builtin.welcome.server_contact.data_collected_table.key": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected_table.value": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected_title": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected.uuid": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected.version": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected.os": "",
|
||||
"hex.builtin.welcome.server_contact.crash_logs_only": "",
|
||||
"hex.builtin.oobe.server_contact_text": "Möchtest du die Kommunikation mit ImHex Servern zulassen?\n\nDies erlaubt das automatische suchen nach Updates und das hochladen\nvon anonymen crash logs im falle eines absturzes.",
|
||||
"hex.builtin.oobe.server_contact.data_collected_table.key": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected_table.value": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected_title": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected.uuid": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected.version": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected.os": "",
|
||||
"hex.builtin.oobe.server_contact.crash_logs_only": "",
|
||||
"hex.builtin.welcome.customize.settings.desc": "Ändere ImHex's Einstellungen",
|
||||
"hex.builtin.welcome.customize.settings.title": "Einstellungen",
|
||||
"hex.builtin.welcome.header.customize": "Anpassen",
|
||||
|
@ -934,14 +934,16 @@
|
||||
"hex.builtin.visualizer.hexadecimal.8bit": "Hexadecimal (8 bits)",
|
||||
"hex.builtin.visualizer.hexii": "HexII",
|
||||
"hex.builtin.visualizer.rgba8": "RGBA8 Color",
|
||||
"hex.builtin.welcome.server_contact_text": "Do you want to allow the communication with ImHex's Servers?\n\n\nThis allows performing automatic update checks and uploads of very limited usage statistics, all of which are listed below.\n\nAlternatively you can also choose to only submit crash logs which help immensely with identifying and fixing bugs you might experience.\n\nAll information is processed by our own Servers and is not given out to any third-parties.\n\n\nYou can change these choices at any time in the settings.",
|
||||
"hex.builtin.welcome.server_contact.data_collected_table.key": "Type",
|
||||
"hex.builtin.welcome.server_contact.data_collected_table.value": "Value",
|
||||
"hex.builtin.welcome.server_contact.data_collected_title": "Data that will be shared",
|
||||
"hex.builtin.welcome.server_contact.data_collected.uuid": "Random ID",
|
||||
"hex.builtin.welcome.server_contact.data_collected.version": "ImHex Version",
|
||||
"hex.builtin.welcome.server_contact.data_collected.os": "Operating System",
|
||||
"hex.builtin.welcome.server_contact.crash_logs_only": "Just crash logs",
|
||||
"hex.builtin.oobe.server_contact": "Server Contact",
|
||||
"hex.builtin.oobe.server_contact.text": "Do you want to allow the communication with ImHex's Servers?\n\n\nThis allows performing automatic update checks and uploads of very limited usage statistics, all of which are listed below.\n\nAlternatively you can also choose to only submit crash logs which help immensely with identifying and fixing bugs you might experience.\n\nAll information is processed by our own Servers and is not given out to any third-parties.\n\n\nYou can change these choices at any time in the settings.",
|
||||
"hex.builtin.oobe.server_contact.data_collected_table.key": "Type",
|
||||
"hex.builtin.oobe.server_contact.data_collected_table.value": "Value",
|
||||
"hex.builtin.oobe.server_contact.data_collected_title": "Data that will be shared",
|
||||
"hex.builtin.oobe.server_contact.data_collected.uuid": "Random ID",
|
||||
"hex.builtin.oobe.server_contact.data_collected.version": "ImHex Version",
|
||||
"hex.builtin.oobe.server_contact.data_collected.os": "Operating System",
|
||||
"hex.builtin.oobe.server_contact.crash_logs_only": "Just crash logs",
|
||||
"hex.builtin.oobe.tutorial_question": "Since this is the first time you are using ImHex, would you like to play through the introduction tutorial?\n\nYou can always access the tutorial from the Help menu.",
|
||||
"hex.builtin.welcome.customize.settings.desc": "Change preferences of ImHex",
|
||||
"hex.builtin.welcome.customize.settings.title": "Settings",
|
||||
"hex.builtin.welcome.drop_file": "Drop a file here to get started...",
|
||||
@ -983,7 +985,6 @@
|
||||
"hex.builtin.popup.safety_backup.report_error": "Send crash log to developers",
|
||||
"hex.builtin.popup.safety_backup.restore": "Yes, Restore",
|
||||
"hex.builtin.popup.safety_backup.title": "Restore lost data",
|
||||
"hex.builtin.popup.play_tutorial.desc": "As this is your first time launching ImHex, would you like to play through the interactive Tutorial?",
|
||||
"hex.builtin.welcome.start.create_file": "Create New File",
|
||||
"hex.builtin.welcome.start.open_file": "Open File",
|
||||
"hex.builtin.welcome.start.open_other": "Other Providers",
|
||||
|
@ -783,14 +783,14 @@
|
||||
"hex.builtin.visualizer.hexadecimal.8bit": "Hexadecimal (8 bits)",
|
||||
"hex.builtin.visualizer.hexii": "HexII",
|
||||
"hex.builtin.visualizer.rgba8": "Color RGBA8",
|
||||
"hex.builtin.welcome.server_contact_text": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected_table.key": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected_table.value": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected_title": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected.uuid": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected.version": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected.os": "",
|
||||
"hex.builtin.welcome.server_contact.crash_logs_only": "",
|
||||
"hex.builtin.oobe.server_contact_text": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected_table.key": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected_table.value": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected_title": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected.uuid": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected.version": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected.os": "",
|
||||
"hex.builtin.oobe.server_contact.crash_logs_only": "",
|
||||
"hex.builtin.welcome.customize.settings.desc": "Cambie preferencias de ImHex",
|
||||
"hex.builtin.welcome.customize.settings.title": "Ajustes",
|
||||
"hex.builtin.welcome.header.customize": "Personalizar",
|
||||
|
@ -783,14 +783,14 @@
|
||||
"hex.builtin.visualizer.hexadecimal.8bit": "",
|
||||
"hex.builtin.visualizer.hexii": "",
|
||||
"hex.builtin.visualizer.rgba8": "",
|
||||
"hex.builtin.welcome.server_contact_text": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected_table.key": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected_table.value": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected_title": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected.uuid": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected.version": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected.os": "",
|
||||
"hex.builtin.welcome.server_contact.crash_logs_only": "",
|
||||
"hex.builtin.oobe.server_contact_text": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected_table.key": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected_table.value": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected_title": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected.uuid": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected.version": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected.os": "",
|
||||
"hex.builtin.oobe.server_contact.crash_logs_only": "",
|
||||
"hex.builtin.welcome.customize.settings.desc": "Cambia le preferenze di ImHex",
|
||||
"hex.builtin.welcome.customize.settings.title": "Impostazioni",
|
||||
"hex.builtin.welcome.header.customize": "Personalizza",
|
||||
|
@ -783,14 +783,14 @@
|
||||
"hex.builtin.visualizer.hexadecimal.8bit": "16進数 ( 8 bits)",
|
||||
"hex.builtin.visualizer.hexii": "",
|
||||
"hex.builtin.visualizer.rgba8": "RGBA8",
|
||||
"hex.builtin.welcome.server_contact_text": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected_table.key": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected_table.value": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected_title": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected.uuid": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected.version": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected.os": "",
|
||||
"hex.builtin.welcome.server_contact.crash_logs_only": "",
|
||||
"hex.builtin.oobe.server_contact_text": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected_table.key": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected_table.value": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected_title": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected.uuid": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected.version": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected.os": "",
|
||||
"hex.builtin.oobe.server_contact.crash_logs_only": "",
|
||||
"hex.builtin.welcome.customize.settings.desc": "ImHexの設定を変更します",
|
||||
"hex.builtin.welcome.customize.settings.title": "設定",
|
||||
"hex.builtin.welcome.header.customize": "カスタマイズ",
|
||||
|
@ -804,14 +804,14 @@
|
||||
"hex.builtin.visualizer.hexadecimal.8bit": "16진수 (8비트)",
|
||||
"hex.builtin.visualizer.hexii": "HexII",
|
||||
"hex.builtin.visualizer.rgba8": "RGBA8 색상",
|
||||
"hex.builtin.welcome.server_contact_text": "ImHex 서버와의 통신을 허용하시겠습니까?\n\n\n이를 통해 자동으로 업데이트를 확인하고 매우 제한된 사용 통계를 업로드할 수 있으며 그 내용은 아래와 같습니다.\n\n또는 크래시 로그만 제출하도록 선택할 수도 있는데, 이는 발생할 수 있는 버그를 식별하고 수정하는 데 큰 도움이 됩니다.\n\n모든 정보는 당사 자체 서버에서 처리되며 제3자에게 제공되지 않습니다.\n\n\n이러한 선택 사항은 설정에서 언제든지 변경할 수 있습니다.",
|
||||
"hex.builtin.welcome.server_contact.data_collected_table.key": "유형",
|
||||
"hex.builtin.welcome.server_contact.data_collected_table.value": "값",
|
||||
"hex.builtin.welcome.server_contact.data_collected_title": "공유할 데이터",
|
||||
"hex.builtin.welcome.server_contact.data_collected.uuid": "무작위 ID",
|
||||
"hex.builtin.welcome.server_contact.data_collected.version": "ImHex 버전",
|
||||
"hex.builtin.welcome.server_contact.data_collected.os": "운영 체제",
|
||||
"hex.builtin.welcome.server_contact.crash_logs_only": "충돌 로그만 제출",
|
||||
"hex.builtin.oobe.server_contact_text": "ImHex 서버와의 통신을 허용하시겠습니까?\n\n\n이를 통해 자동으로 업데이트를 확인하고 매우 제한된 사용 통계를 업로드할 수 있으며 그 내용은 아래와 같습니다.\n\n또는 크래시 로그만 제출하도록 선택할 수도 있는데, 이는 발생할 수 있는 버그를 식별하고 수정하는 데 큰 도움이 됩니다.\n\n모든 정보는 당사 자체 서버에서 처리되며 제3자에게 제공되지 않습니다.\n\n\n이러한 선택 사항은 설정에서 언제든지 변경할 수 있습니다.",
|
||||
"hex.builtin.oobe.server_contact.data_collected_table.key": "유형",
|
||||
"hex.builtin.oobe.server_contact.data_collected_table.value": "값",
|
||||
"hex.builtin.oobe.server_contact.data_collected_title": "공유할 데이터",
|
||||
"hex.builtin.oobe.server_contact.data_collected.uuid": "무작위 ID",
|
||||
"hex.builtin.oobe.server_contact.data_collected.version": "ImHex 버전",
|
||||
"hex.builtin.oobe.server_contact.data_collected.os": "운영 체제",
|
||||
"hex.builtin.oobe.server_contact.crash_logs_only": "충돌 로그만 제출",
|
||||
"hex.builtin.welcome.customize.settings.desc": "ImHex의 설정을 변경합니다",
|
||||
"hex.builtin.welcome.customize.settings.title": "설정",
|
||||
"hex.builtin.welcome.header.customize": "사용자화",
|
||||
|
@ -783,14 +783,14 @@
|
||||
"hex.builtin.visualizer.hexadecimal.8bit": "Hexadecimal (8 bits)",
|
||||
"hex.builtin.visualizer.hexii": "HexII",
|
||||
"hex.builtin.visualizer.rgba8": "RGBA8 Color",
|
||||
"hex.builtin.welcome.server_contact_text": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected_table.key": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected_table.value": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected_title": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected.uuid": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected.version": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected.os": "",
|
||||
"hex.builtin.welcome.server_contact.crash_logs_only": "",
|
||||
"hex.builtin.oobe.server_contact_text": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected_table.key": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected_table.value": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected_title": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected.uuid": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected.version": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected.os": "",
|
||||
"hex.builtin.oobe.server_contact.crash_logs_only": "",
|
||||
"hex.builtin.welcome.customize.settings.desc": "Mudar preferencias do ImHex",
|
||||
"hex.builtin.welcome.customize.settings.title": "Configurações",
|
||||
"hex.builtin.welcome.header.customize": "Customizar",
|
||||
|
@ -797,14 +797,14 @@
|
||||
"hex.builtin.visualizer.hexadecimal.8bit": "十六进制(8 位)",
|
||||
"hex.builtin.visualizer.hexii": "HexII",
|
||||
"hex.builtin.visualizer.rgba8": "RGBA8 颜色",
|
||||
"hex.builtin.welcome.server_contact_text": "您想允许与 ImHex 的服务器通信吗?\n\n\n这允许执行自动更新检查并上传非常有限的使用统计信息,所有这些都在下面列出。\n\n或者,您也可以选择仅提交崩溃日志,这对确认与修复您可能遇到的错误有很大帮助。\n\n所有信息均由我们自己的服务器处理,不会泄露给任何第三方。\n\n\n您可以随时在设置中更改这些选择。",
|
||||
"hex.builtin.welcome.server_contact.data_collected_table.key": "类型",
|
||||
"hex.builtin.welcome.server_contact.data_collected_table.value": "值",
|
||||
"hex.builtin.welcome.server_contact.data_collected_title": "会被共享的数据",
|
||||
"hex.builtin.welcome.server_contact.data_collected.uuid": "随机 ID",
|
||||
"hex.builtin.welcome.server_contact.data_collected.version": "ImHex 版本",
|
||||
"hex.builtin.welcome.server_contact.data_collected.os": "操作系统",
|
||||
"hex.builtin.welcome.server_contact.crash_logs_only": "仅崩溃日志",
|
||||
"hex.builtin.oobe.server_contact_text": "您想允许与 ImHex 的服务器通信吗?\n\n\n这允许执行自动更新检查并上传非常有限的使用统计信息,所有这些都在下面列出。\n\n或者,您也可以选择仅提交崩溃日志,这对确认与修复您可能遇到的错误有很大帮助。\n\n所有信息均由我们自己的服务器处理,不会泄露给任何第三方。\n\n\n您可以随时在设置中更改这些选择。",
|
||||
"hex.builtin.oobe.server_contact.data_collected_table.key": "类型",
|
||||
"hex.builtin.oobe.server_contact.data_collected_table.value": "值",
|
||||
"hex.builtin.oobe.server_contact.data_collected_title": "会被共享的数据",
|
||||
"hex.builtin.oobe.server_contact.data_collected.uuid": "随机 ID",
|
||||
"hex.builtin.oobe.server_contact.data_collected.version": "ImHex 版本",
|
||||
"hex.builtin.oobe.server_contact.data_collected.os": "操作系统",
|
||||
"hex.builtin.oobe.server_contact.crash_logs_only": "仅崩溃日志",
|
||||
"hex.builtin.welcome.customize.settings.desc": "更改 ImHex 的设置",
|
||||
"hex.builtin.welcome.customize.settings.title": "设置",
|
||||
"hex.builtin.welcome.header.customize": "自定义",
|
||||
|
@ -797,14 +797,14 @@
|
||||
"hex.builtin.visualizer.hexadecimal.8bit": "十六進位 (8 位元)",
|
||||
"hex.builtin.visualizer.hexii": "HexII",
|
||||
"hex.builtin.visualizer.rgba8": "RGBA8 顏色",
|
||||
"hex.builtin.welcome.server_contact_text": "",
|
||||
"hex.builtin.welcome.server_contact.data_collected_table.key": "類型",
|
||||
"hex.builtin.welcome.server_contact.data_collected_table.value": "數值",
|
||||
"hex.builtin.welcome.server_contact.data_collected_title": "將分享的資料",
|
||||
"hex.builtin.welcome.server_contact.data_collected.uuid": "隨機 ID",
|
||||
"hex.builtin.welcome.server_contact.data_collected.version": "ImHex 版本",
|
||||
"hex.builtin.welcome.server_contact.data_collected.os": "作業系統",
|
||||
"hex.builtin.welcome.server_contact.crash_logs_only": "僅崩潰記錄檔",
|
||||
"hex.builtin.oobe.server_contact_text": "",
|
||||
"hex.builtin.oobe.server_contact.data_collected_table.key": "類型",
|
||||
"hex.builtin.oobe.server_contact.data_collected_table.value": "數值",
|
||||
"hex.builtin.oobe.server_contact.data_collected_title": "將分享的資料",
|
||||
"hex.builtin.oobe.server_contact.data_collected.uuid": "隨機 ID",
|
||||
"hex.builtin.oobe.server_contact.data_collected.version": "ImHex 版本",
|
||||
"hex.builtin.oobe.server_contact.data_collected.os": "作業系統",
|
||||
"hex.builtin.oobe.server_contact.crash_logs_only": "僅崩潰記錄檔",
|
||||
"hex.builtin.welcome.customize.settings.desc": "更改 ImHex 的設定",
|
||||
"hex.builtin.welcome.customize.settings.title": "設定",
|
||||
"hex.builtin.welcome.header.customize": "自訂",
|
||||
|
@ -194,6 +194,14 @@ namespace hex::plugin::builtin {
|
||||
RequestOpenFile::post(path);
|
||||
});
|
||||
|
||||
EventWindowInitialized::subscribe([] {
|
||||
if (ContentRegistry::Settings::read("hex.builtin.setting.general", "hex.builtin.setting.general.prev_launch_version", "") == "") {
|
||||
EventFirstLaunch::post();
|
||||
}
|
||||
|
||||
ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.prev_launch_version", ImHexApi::System::getImHexVersion());
|
||||
});
|
||||
|
||||
fs::setFileBrowserErrorCallback([](const std::string& errMsg){
|
||||
#if defined(NFD_PORTAL)
|
||||
ui::PopupError::open(hex::format("hex.builtin.popup.error.file_dialog.portal"_lang, errMsg));
|
||||
|
367
plugins/builtin/source/content/out_of_box_experience.cpp
Normal file
@ -0,0 +1,367 @@
|
||||
#include <imgui.h>
|
||||
#include <imgui_internal.h>
|
||||
#include <fonts/codicons_font.h>
|
||||
#include <hex/ui/imgui_imhex_extensions.h>
|
||||
|
||||
#include <hex/api/content_registry.hpp>
|
||||
#include <hex/api/event_manager.hpp>
|
||||
#include <hex/api/task_manager.hpp>
|
||||
#include <hex/api/theme_manager.hpp>
|
||||
#include <hex/api/tutorial_manager.hpp>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
|
||||
#include <romfs/romfs.hpp>
|
||||
#include <wolv/hash/uuid.hpp>
|
||||
#include <wolv/utils/guards.hpp>
|
||||
|
||||
#include <list>
|
||||
#include <ranges>
|
||||
#include <string>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
namespace {
|
||||
|
||||
ImGuiExt::Texture s_imhexBanner;
|
||||
ImGuiExt::Texture s_compassTexture;
|
||||
std::list<std::pair<std::fs::path, ImGuiExt::Texture>> s_screenshots;
|
||||
nlohmann::json s_screenshotDescriptions;
|
||||
|
||||
|
||||
std::string s_uuid;
|
||||
|
||||
class Blend {
|
||||
public:
|
||||
Blend(float start, float end) : m_time(0), m_start(start), m_end(end) {}
|
||||
|
||||
[[nodiscard]] operator float() {
|
||||
m_time += ImGui::GetIO().DeltaTime;
|
||||
|
||||
float t = m_time;
|
||||
t -= m_start;
|
||||
t /= (m_end - m_start);
|
||||
t = std::clamp(t, 0.0F, 1.0F);
|
||||
|
||||
float square = t * t;
|
||||
return square / (2.0F * (square - t) + 1.0F);
|
||||
}
|
||||
|
||||
private:
|
||||
float m_time;
|
||||
float m_start, m_end;
|
||||
};
|
||||
|
||||
EventManager::EventList::iterator s_drawEvent;
|
||||
void drawOutOfBoxExperience() {
|
||||
static float windowAlpha = 1.0F;
|
||||
static bool oobeDone = false;
|
||||
static bool tutorialEnabled = false;
|
||||
|
||||
ImGui::SetNextWindowPos(ImHexApi::System::getMainWindowPosition());
|
||||
ImGui::SetNextWindowSize(ImHexApi::System::getMainWindowSize());
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, windowAlpha);
|
||||
ON_SCOPE_EXIT { ImGui::PopStyleVar(); };
|
||||
|
||||
if (ImGui::Begin("##oobe", nullptr, ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize)) {
|
||||
ImGui::BringWindowToFocusFront(ImGui::GetCurrentWindowRead());
|
||||
|
||||
static Blend bannerSlideIn(-0.2F, 1.5F);
|
||||
static Blend bannerFadeIn(-0.2F, 1.5F);
|
||||
|
||||
// Draw banner
|
||||
ImGui::SetCursorPos(scaled({ 25 * bannerSlideIn, 25 }));
|
||||
const auto bannerSize = s_imhexBanner.getSize() / (1.5F * (1.0F / ImHexApi::System::getGlobalScale()));
|
||||
ImGui::Image(
|
||||
s_imhexBanner,
|
||||
bannerSize,
|
||||
{ 0, 0 }, { 1, 1 },
|
||||
{ 1, 1, 1, (bannerFadeIn - 0.5F) * 2.0F }
|
||||
);
|
||||
|
||||
static u32 page = 0;
|
||||
switch (page) {
|
||||
// Landing page
|
||||
case 0: {
|
||||
static Blend textFadeIn(2.0F, 2.5F);
|
||||
static Blend buttonFadeIn(2.5F, 3.0F);
|
||||
|
||||
// Draw welcome text
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, textFadeIn);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::BeginChild("Text", ImVec2(ImGui::GetContentRegionAvail().x, bannerSize.y))) {
|
||||
ImGuiExt::TextFormattedCentered("Welcome to ImHex!\n\nA powerful data analysis and visualization suite for Reverse Engineers, Hackers and Security Researchers.");
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
if (!s_screenshots.empty()) {
|
||||
const auto imageSize = s_screenshots.front().second.getSize() * ImHexApi::System::getGlobalScale();
|
||||
const auto padding = ImGui::GetStyle().CellPadding.x;
|
||||
const auto stride = imageSize.x + padding * 2;
|
||||
static bool imageHovered = false;
|
||||
static std::string clickedImage;
|
||||
|
||||
// Move last screenshot to the front of the list when the last screenshot is out of view
|
||||
static float position = 0;
|
||||
if (position >= stride) {
|
||||
position = 0;
|
||||
s_screenshots.splice(s_screenshots.begin(), s_screenshots, std::prev(s_screenshots.end()), s_screenshots.end());
|
||||
}
|
||||
|
||||
if (!imageHovered && clickedImage.empty())
|
||||
position += (ImGui::GetIO().DeltaTime) * 40;
|
||||
|
||||
imageHovered = false;
|
||||
|
||||
auto drawList = ImGui::GetWindowDrawList();
|
||||
const auto drawImage = [&](const std::fs::path &fileName, const ImGuiExt::Texture &screenshot) {
|
||||
auto pos = ImGui::GetCursorScreenPos();
|
||||
|
||||
// Draw image
|
||||
ImGui::Image(screenshot, imageSize);
|
||||
imageHovered = imageHovered || ImGui::IsItemHovered();
|
||||
auto currentHovered = ImGui::IsItemHovered();
|
||||
|
||||
if (ImGui::IsItemClicked()) {
|
||||
clickedImage = fileName.string();
|
||||
ImGui::OpenPopup("FeatureDescription");
|
||||
}
|
||||
|
||||
// Draw shadow
|
||||
auto &style = ImGui::GetStyle();
|
||||
float shadowSize = style.WindowShadowSize * (currentHovered ? 3.0F : 1.0F);
|
||||
ImU32 shadowCol = ImGui::GetColorU32(ImGuiCol_WindowShadow, currentHovered ? 2.0F : 1.0F);
|
||||
ImVec2 shadowOffset = ImVec2(ImCos(style.WindowShadowOffsetAngle), ImSin(style.WindowShadowOffsetAngle)) * style.WindowShadowOffsetDist;
|
||||
drawList->AddShadowRect(pos, pos + imageSize, shadowCol, shadowSize, shadowOffset, ImDrawFlags_ShadowCutOutShapeBackground);
|
||||
|
||||
ImGui::SameLine();
|
||||
};
|
||||
|
||||
ImGui::NewLine();
|
||||
|
||||
// Draw top screenshot row
|
||||
ImGui::SetCursorPosX(-position);
|
||||
for (const auto &[fileName, screenshot] : s_screenshots | std::views::take(s_screenshots.size() / 2) | std::views::reverse) {
|
||||
drawImage(fileName, screenshot);
|
||||
}
|
||||
|
||||
ImGui::NewLine();
|
||||
|
||||
// Draw bottom screenshot row
|
||||
ImGui::SetCursorPosX(-stride + position);
|
||||
for (const auto &[fileName, screenshot] : s_screenshots | std::views::drop(s_screenshots.size() / 2)) {
|
||||
drawImage(fileName, screenshot);
|
||||
}
|
||||
|
||||
ImGui::SetNextWindowPos(ImGui::GetWindowPos() + (ImGui::GetWindowSize() / 2), ImGuiCond_Always, ImVec2(0.5F, 0.5F));
|
||||
ImGui::SetNextWindowSize(ImVec2(400_scaled, 0), ImGuiCond_Always);
|
||||
if (ImGui::BeginPopup("FeatureDescription")) {
|
||||
const auto &description = s_screenshotDescriptions[clickedImage];
|
||||
ImGuiExt::Header(description["title"].get<std::string>().c_str(), true);
|
||||
ImGuiExt::TextFormattedWrapped("{}", description["description"].get<std::string>().c_str());
|
||||
ImGui::EndPopup();
|
||||
} else {
|
||||
clickedImage.clear();
|
||||
}
|
||||
|
||||
// Continue button
|
||||
const auto buttonSize = scaled({ 100, 50 });
|
||||
ImGui::SetCursorPos(ImHexApi::System::getMainWindowSize() - buttonSize - scaled({ 10, 10 }));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, buttonFadeIn);
|
||||
if (ImGuiExt::DimmedButton(hex::format("{} {}", "hex.ui.common.continue"_lang, ICON_VS_ARROW_RIGHT).c_str(), buttonSize))
|
||||
page += 1;
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
|
||||
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Server contact page
|
||||
case 1: {
|
||||
static ImVec2 subWindowSize = { 0, 0 };
|
||||
const auto windowSize = ImHexApi::System::getMainWindowSize();
|
||||
|
||||
// Draw telemetry subwindow
|
||||
ImGui::SetCursorPos((windowSize - subWindowSize) / 2);
|
||||
ImGuiExt::BeginSubWindow("hex.builtin.oobe.server_contact"_lang, subWindowSize, ImGuiChildFlags_AutoResizeY);
|
||||
{
|
||||
// Draw telemetry information
|
||||
auto yBegin = ImGui::GetCursorPosY();
|
||||
std::string message = "hex.builtin.oobe.server_contact.text"_lang;
|
||||
ImGuiExt::TextFormattedWrapped("{}", message.c_str());
|
||||
ImGui::NewLine();
|
||||
|
||||
// Draw table containing everything that's being reported
|
||||
if (ImGui::CollapsingHeader("hex.builtin.oobe.server_contact.data_collected_title"_lang)) {
|
||||
if (ImGui::BeginTable("hex.builtin.oobe.server_contact.data_collected_table"_lang, 2,
|
||||
ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY | ImGuiTableFlags_NoHostExtendY,
|
||||
ImVec2(ImGui::GetContentRegionAvail().x, 150_scaled))) {
|
||||
ImGui::TableSetupColumn("hex.builtin.oobe.server_contact.data_collected_table.key"_lang);
|
||||
ImGui::TableSetupColumn("hex.builtin.oobe.server_contact.data_collected_table.value"_lang, ImGuiTableColumnFlags_WidthStretch);
|
||||
ImGui::TableSetupScrollFreeze(0, 1);
|
||||
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted("hex.builtin.oobe.server_contact.data_collected.uuid"_lang);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextWrapped("%s", s_uuid.c_str());
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted("hex.builtin.oobe.server_contact.data_collected.version"_lang);
|
||||
ImGui::TableNextColumn();
|
||||
ImGuiExt::TextFormattedWrapped("{}\n{}@{}\n{}",
|
||||
ImHexApi::System::getImHexVersion(),
|
||||
ImHexApi::System::getCommitHash(true),
|
||||
ImHexApi::System::getCommitBranch(),
|
||||
ImHexApi::System::isPortableVersion() ? "Portable" : "Installed"
|
||||
);
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted("hex.builtin.oobe.server_contact.data_collected.os"_lang);
|
||||
ImGui::TableNextColumn();
|
||||
ImGuiExt::TextFormattedWrapped("{}\n{}\n{}\n{}",
|
||||
ImHexApi::System::getOSName(),
|
||||
ImHexApi::System::getOSVersion(),
|
||||
ImHexApi::System::getArchitecture(),
|
||||
ImHexApi::System::getGPUVendor());
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::NewLine();
|
||||
|
||||
const auto width = ImGui::GetWindowWidth();
|
||||
const auto buttonSize = ImVec2(width / 3 - ImGui::GetStyle().FramePadding.x * 3, 0);
|
||||
const auto buttonPos = [&](u8 index) { return ImGui::GetStyle().FramePadding.x + (buttonSize.x + ImGui::GetStyle().FramePadding.x * 3) * index; };
|
||||
|
||||
// Draw allow button
|
||||
ImGui::SetCursorPosX(buttonPos(0));
|
||||
if (ImGui::Button("hex.ui.common.allow"_lang, buttonSize)) {
|
||||
ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.server_contact", 1);
|
||||
ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.upload_crash_logs", 1);
|
||||
page += 1;
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
// Draw crash logs only button
|
||||
ImGui::SetCursorPosX(buttonPos(1));
|
||||
if (ImGui::Button("hex.builtin.oobe.server_contact.crash_logs_only"_lang, buttonSize)) {
|
||||
ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.server_contact", 0);
|
||||
ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.upload_crash_logs", 1);
|
||||
page += 1;
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
// Draw deny button
|
||||
ImGui::SetCursorPosX(buttonPos(2));
|
||||
if (ImGui::Button("hex.ui.common.deny"_lang, buttonSize)) {
|
||||
page += 1;
|
||||
}
|
||||
|
||||
auto yEnd = ImGui::GetCursorPosY();
|
||||
subWindowSize = ImGui::GetWindowSize();
|
||||
subWindowSize.y = (yEnd - yBegin) + 35_scaled;
|
||||
}
|
||||
ImGuiExt::EndSubWindow();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Tutorial page
|
||||
case 2: {
|
||||
ImGui::NewLine();
|
||||
|
||||
ImGui::NewLine();
|
||||
ImGui::NewLine();
|
||||
ImGui::NewLine();
|
||||
|
||||
// Draw compass image
|
||||
const auto imageSize = s_compassTexture.getSize() / (1.5F * (1.0F / ImHexApi::System::getGlobalScale()));
|
||||
ImGui::SetCursorPos((ImGui::GetWindowSize() / 2 - imageSize / 2) - ImVec2(0, 50_scaled));
|
||||
ImGui::Image(s_compassTexture, imageSize);
|
||||
|
||||
// Draw information text about playing the tutorial
|
||||
ImGui::SetCursorPosX(0);
|
||||
ImGuiExt::TextFormattedCentered("hex.builtin.oobe.tutorial_question"_lang);
|
||||
|
||||
// Draw no button
|
||||
const auto buttonSize = scaled({ 100, 50 });
|
||||
ImGui::SetCursorPos(ImHexApi::System::getMainWindowSize() - ImVec2(buttonSize.x * 2 + 20, buttonSize.y + 10));
|
||||
if (ImGuiExt::DimmedButton("hex.ui.common.no"_lang, buttonSize)) {
|
||||
oobeDone = true;
|
||||
}
|
||||
|
||||
// Draw yes button
|
||||
ImGui::SetCursorPos(ImHexApi::System::getMainWindowSize() - ImVec2(buttonSize.x + 10, buttonSize.y + 10));
|
||||
if (ImGuiExt::DimmedButton("hex.ui.common.yes"_lang, buttonSize)) {
|
||||
tutorialEnabled = true;
|
||||
oobeDone = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
page = 0;
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
|
||||
// Handle finishing the out of box experience
|
||||
if (oobeDone) {
|
||||
static Blend backgroundFadeOut(0.0F, 1.0F);
|
||||
windowAlpha = 1.0F - backgroundFadeOut;
|
||||
|
||||
if (backgroundFadeOut >= 1.0F) {
|
||||
if (tutorialEnabled) {
|
||||
TutorialManager::startTutorial("hex.builtin.tutorial.introduction");
|
||||
}
|
||||
|
||||
TaskManager::doLater([] {
|
||||
ImHexApi::System::setWindowResizable(true);
|
||||
EventFrameBegin::unsubscribe(s_drawEvent);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void setupOutOfBoxExperience() {
|
||||
// Check if there is a telemetry uuid
|
||||
s_uuid = ContentRegistry::Settings::read("hex.builtin.setting.general", "hex.builtin.setting.general.uuid", "").get<std::string>();
|
||||
|
||||
if (s_uuid.empty()) {
|
||||
// Generate a new UUID
|
||||
s_uuid = wolv::hash::generateUUID();
|
||||
|
||||
// Save UUID to settings
|
||||
ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.uuid", s_uuid);
|
||||
}
|
||||
|
||||
EventFirstLaunch::subscribe([] {
|
||||
ImHexApi::System::setWindowResizable(false);
|
||||
|
||||
const auto imageTheme = ThemeManager::getImageTheme();
|
||||
s_imhexBanner = ImGuiExt::Texture(romfs::get(hex::format("assets/{}/banner.png", imageTheme)).span<std::byte>());
|
||||
s_compassTexture = ImGuiExt::Texture(romfs::get("assets/common/compass.png").span<std::byte>());
|
||||
s_screenshotDescriptions = nlohmann::json::parse(romfs::get("assets/screenshot_descriptions.json").string());
|
||||
|
||||
for (const auto &path : romfs::list("assets/screenshots")) {
|
||||
s_screenshots.emplace_back(path.filename(), ImGuiExt::Texture(romfs::get(path).span<std::byte>(), ImGuiExt::Texture::Filter::Linear));
|
||||
}
|
||||
|
||||
s_drawEvent = EventFrameBegin::subscribe(drawOutOfBoxExperience);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -24,13 +24,11 @@
|
||||
|
||||
#include <fonts/codicons_font.h>
|
||||
|
||||
#include <content/popups/popup_telemetry_request.hpp>
|
||||
#include <content/recent.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <random>
|
||||
#include <popups/popup_question.hpp>
|
||||
#include <hex/api/tutorial_manager.hpp>
|
||||
#include <hex/api/workspace_manager.hpp>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
@ -497,29 +495,6 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
});
|
||||
|
||||
EventWindowInitialized::subscribe([] {
|
||||
if (ContentRegistry::Settings::read("hex.builtin.setting.general", "hex.builtin.setting.general.prev_launch_version", "") == "") {
|
||||
ui::PopupQuestion::open("hex.builtin.popup.play_tutorial.desc"_lang,
|
||||
[]{
|
||||
TutorialManager::startTutorial("hex.builtin.tutorial.introduction");
|
||||
},
|
||||
[]{ });
|
||||
}
|
||||
|
||||
ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.prev_launch_version", ImHexApi::System::getImHexVersion());
|
||||
|
||||
// Documentation of the value above the setting definition
|
||||
auto allowServerContact = ContentRegistry::Settings::read("hex.builtin.setting.general", "hex.builtin.setting.general.server_contact", 2);
|
||||
if (allowServerContact == 2) {
|
||||
ContentRegistry::Settings::write("hex.builtin.setting.general", "hex.builtin.setting.general.server_contact", 0);
|
||||
|
||||
// Open the telemetry popup but only on desktop versions
|
||||
#if !defined(OS_WEB)
|
||||
PopupTelemetryRequest::open();
|
||||
#endif
|
||||
}
|
||||
});
|
||||
|
||||
// Clear project context if we go back to the welcome screen
|
||||
EventProviderChanged::subscribe([](const hex::prv::Provider *oldProvider, const hex::prv::Provider *newProvider) {
|
||||
hex::unused(oldProvider);
|
||||
|
@ -48,6 +48,7 @@ namespace hex::plugin::builtin {
|
||||
void loadFonts();
|
||||
|
||||
void handleBorderlessWindowMode();
|
||||
void setupOutOfBoxExperience();
|
||||
|
||||
void extractBundledFiles();
|
||||
|
||||
@ -117,4 +118,5 @@ IMHEX_PLUGIN_SETUP("Built-in", "WerWolv", "Default ImHex functionality") {
|
||||
addGlobalUIItems();
|
||||
|
||||
handleBorderlessWindowMode();
|
||||
setupOutOfBoxExperience();
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
"hex.ui.common.choose_file": "Choose file",
|
||||
"hex.ui.common.close": "Close",
|
||||
"hex.ui.common.comment": "Comment",
|
||||
"hex.ui.common.continue": "Continue",
|
||||
"hex.ui.common.count": "Count",
|
||||
"hex.ui.common.decimal": "Decimal",
|
||||
"hex.ui.common.deny": "Deny",
|
||||
|