1
0
mirror of synced 2024-11-28 09:30:51 +01:00

impr: More Welcome Screen UI improvements

This commit is contained in:
WerWolv 2023-11-16 13:23:28 +01:00
parent f00daf171b
commit 21057d51e1
7 changed files with 127 additions and 27 deletions

View File

@ -404,6 +404,12 @@ namespace hex {
*/
static void clearTemporary();
/**
* \brief Returns the current progress of all achievements
* \return A pair containing the number of unlocked achievements and the total number of achievements
*/
static std::pair<u32, u32> getProgress();
private:
static void achievementAdded();
};

View File

@ -113,6 +113,7 @@ namespace ImGui {
bool Hyperlink(const char *label, const ImVec2 &size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0);
bool BulletHyperlink(const char *label, const ImVec2 &size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0);
bool DescriptionButton(const char *label, const char *description, const ImVec2 &size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0);
bool DescriptionButtonProgress(const char *label, const char *description, float fraction, const ImVec2 &size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0);
void HelpHover(const char *text);

View File

@ -157,6 +157,22 @@ namespace hex {
getAchievementNodes(false).clear();
}
std::pair<u32, u32> AchievementManager::getProgress() {
u32 unlocked = 0;
u32 total = 0;
for (auto &[categoryName, achievements] : getAchievements()) {
for (auto &[achievementName, achievement] : achievements) {
total += 1;
if (achievement->isUnlocked()) {
unlocked += 1;
}
}
}
return { unlocked, total };
}
void AchievementManager::achievementAdded() {
getAchievementStartNodes(false).clear();
getAchievementNodes(false).clear();

View File

@ -265,6 +265,61 @@ namespace ImGui {
return pressed;
}
bool DescriptionButtonProgress(const char *label, const char *description, float fraction, const ImVec2 &size_arg, ImGuiButtonFlags flags) {
ImGuiWindow *window = GetCurrentWindow();
if (window->SkipItems)
return false;
ImGuiContext &g = *GImGui;
const ImGuiStyle &style = g.Style;
const ImGuiID id = window->GetID(label);
const ImVec2 text_size = CalcTextSize((std::string(label) + "\n " + std::string(description)).c_str(), nullptr, true);
const ImVec2 label_size = CalcTextSize(label, nullptr, true);
ImVec2 pos = window->DC.CursorPos;
if ((flags & ImGuiButtonFlags_AlignTextBaseLine) && style.FramePadding.y < window->DC.CurrLineTextBaseOffset) // Try to vertically align buttons that are smaller/have no padding so that text baseline matches (bit hacky, since it shouldn't be a flag)
pos.y += window->DC.CurrLineTextBaseOffset - style.FramePadding.y;
ImVec2 size = CalcItemSize(size_arg, text_size.x + style.FramePadding.x * 4.0f, text_size.y + style.FramePadding.y * 6.0f);
const ImRect bb(pos, pos + size);
ItemSize(size, style.FramePadding.y);
if (!ItemAdd(bb, id))
return false;
if (g.LastItemData.InFlags & ImGuiItemFlags_ButtonRepeat)
flags |= ImGuiButtonFlags_Repeat;
bool hovered, held;
bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags);
PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0, 0.5));
PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1);
// Render
const ImU32 col = GetCustomColorU32((held && hovered) ? ImGuiCustomCol_DescButtonActive : hovered ? ImGuiCustomCol_DescButtonHovered
: ImGuiCustomCol_DescButton);
RenderNavHighlight(bb, id);
RenderFrame(bb.Min, bb.Max, col, false, style.FrameRounding);
PushStyleColor(ImGuiCol_Text, GetColorU32(ImGuiCol_ButtonActive));
RenderTextWrapped(bb.Min + style.FramePadding * 2, label, nullptr, CalcWrapWidthForPos(window->DC.CursorPos, window->DC.TextWrapPos));
PopStyleColor();
PushStyleColor(ImGuiCol_Text, GetColorU32(ImGuiCol_Text));
RenderTextClipped(bb.Min + style.FramePadding * 2 + ImVec2(style.FramePadding.x * 2, label_size.y), bb.Max - style.FramePadding, description, nullptr, &text_size, style.ButtonTextAlign, &bb);
PopStyleColor();
RenderFrame(ImVec2(bb.Min.x, bb.Max.y - 5 * hex::ImHexApi::System::getGlobalScale()), bb.Max, GetColorU32(ImGuiCol_ScrollbarBg), false, style.FrameRounding);
RenderFrame(ImVec2(bb.Min.x, bb.Max.y - 5 * hex::ImHexApi::System::getGlobalScale()), ImVec2(bb.Min.x + fraction * bb.GetSize().x, bb.Max.y), GetColorU32(ImGuiCol_Button), false, style.FrameRounding);
RenderFrame(bb.Min, bb.Max, 0x00, true, style.FrameRounding);
PopStyleVar(2);
// Automatically close popups
// if (pressed && !(flags & ImGuiButtonFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup))
// CloseCurrentPopup();
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags);
return pressed;
}
void HelpHover(const char *text) {
const auto iconColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonActive);

View File

@ -115,6 +115,7 @@
"hex.builtin.common.range.entire_data": "Entire Data",
"hex.builtin.common.range.selection": "Selection",
"hex.builtin.common.region": "Region",
"hex.builtin.common.remove": "Remove",
"hex.builtin.common.reset": "Reset",
"hex.builtin.common.set": "Set",
"hex.builtin.common.settings": "Settings",
@ -1065,6 +1066,8 @@
"hex.builtin.welcome.help.gethelp.link": "https://github.com/WerWolv/ImHex/discussions/categories/get-help",
"hex.builtin.welcome.help.repo": "GitHub Repository",
"hex.builtin.welcome.help.repo.link": "https://imhex.werwolv.net/git",
"hex.builtin.welcome.learn.achievements.title": "Achievement Progress",
"hex.builtin.welcome.learn.achievements.desc": "Learn how to use ImHex by completing all achievements",
"hex.builtin.welcome.learn.latest.desc": "Read ImHex's current changelog",
"hex.builtin.welcome.learn.latest.link": "https://github.com/WerWolv/ImHex/releases/latest",
"hex.builtin.welcome.learn.latest.title": "Latest Release",

View File

@ -178,19 +178,23 @@ namespace hex::plugin::builtin::recent {
const auto &recentEntry = *it;
bool shouldRemove = false;
const bool isProject = recentEntry.type == "project";
ImGui::PushID(&recentEntry);
ON_SCOPE_EXIT { ImGui::PopID(); };
const char* icon;
if (recentEntry.type == "project") {
if (isProject) {
icon = ICON_VS_PROJECT;
} else {
icon = ICON_VS_FILE_BINARY;
}
if (ImGui::BulletHyperlink(hex::format("{} {}", icon, hex::limitStringLength(recentEntry.displayName, 32)).c_str())) {
if (ImGui::Hyperlink(hex::format("{} {}", icon, hex::limitStringLength(recentEntry.displayName, 32)).c_str())) {
loadRecentEntry(recentEntry);
break;
}
if (!isProject)
ImGui::SetItemTooltip("%s", LangEntry(recentEntry.type).get().c_str());
// Detect right click on recent provider
std::string popupID = hex::format("RecentEntryMenu.{}", recentEntry.getHash());
@ -199,7 +203,7 @@ namespace hex::plugin::builtin::recent {
}
if (ImGui::BeginPopup(popupID.c_str())) {
if (ImGui::MenuItem("Remove")) {
if (ImGui::MenuItem("hex.builtin.common.remove"_lang)) {
shouldRemove = true;
}
ImGui::EndPopup();

View File

@ -164,38 +164,46 @@ namespace hex::plugin::builtin {
ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetTextLineHeightWithSpacing() * 6);
ImGui::TableNextColumn();
static bool otherProvidersVisible = false;
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5_scaled);
ImGui::BeginSubWindow("hex.builtin.welcome.header.start"_lang, ImVec2(), ImGuiChildFlags_AutoResizeX);
{
if (ImGui::IconHyperlink(ICON_VS_NEW_FILE, "hex.builtin.welcome.start.create_file"_lang)) {
auto newProvider = hex::ImHexApi::Provider::createProvider("hex.builtin.provider.mem_file", true);
if (newProvider != nullptr && !newProvider->open())
hex::ImHexApi::Provider::remove(newProvider);
else
EventManager::post<EventProviderOpened>(newProvider);
auto startPos = ImGui::GetCursorPos();
ImGui::BeginSubWindow("hex.builtin.welcome.header.start"_lang, ImVec2(), ImGuiChildFlags_AutoResizeX);
{
if (ImGui::IconHyperlink(ICON_VS_NEW_FILE, "hex.builtin.welcome.start.create_file"_lang)) {
auto newProvider = hex::ImHexApi::Provider::createProvider("hex.builtin.provider.mem_file", true);
if (newProvider != nullptr && !newProvider->open())
hex::ImHexApi::Provider::remove(newProvider);
else
EventManager::post<EventProviderOpened>(newProvider);
}
if (ImGui::IconHyperlink(ICON_VS_GO_TO_FILE, "hex.builtin.welcome.start.open_file"_lang))
EventManager::post<RequestOpenWindow>("Open File");
if (ImGui::IconHyperlink(ICON_VS_NOTEBOOK, "hex.builtin.welcome.start.open_project"_lang))
EventManager::post<RequestOpenWindow>("Open Project");
if (ImGui::IconHyperlink(ICON_VS_TELESCOPE, "hex.builtin.welcome.start.open_other"_lang))
otherProvidersVisible = !otherProvidersVisible;
}
if (ImGui::IconHyperlink(ICON_VS_GO_TO_FILE, "hex.builtin.welcome.start.open_file"_lang))
EventManager::post<RequestOpenWindow>("Open File");
if (ImGui::IconHyperlink(ICON_VS_NOTEBOOK, "hex.builtin.welcome.start.open_project"_lang))
EventManager::post<RequestOpenWindow>("Open Project");
if (ImGui::IconHyperlink(ICON_VS_TELESCOPE, "hex.builtin.welcome.start.open_other"_lang))
ImGui::OpenPopup("hex.builtin.welcome.start.popup.open_other"_lang);
ImGui::EndSubWindow();
auto endPos = ImGui::GetCursorPos();
ImGui::SetNextWindowPos(ImGui::GetWindowPos() + ImGui::GetCursorPos());
if (ImGui::BeginPopup("hex.builtin.welcome.start.popup.open_other"_lang)) {
if (otherProvidersVisible) {
ImGui::SameLine(0, 2_scaled);
ImGui::SetCursorPos(ImGui::GetCursorPos() + ImVec2(0, (endPos - startPos).y / 2));
ImGui::TextUnformatted(ICON_VS_ARROW_RIGHT);
ImGui::SameLine(0, 2_scaled);
ImGui::BeginSubWindow("hex.builtin.welcome.start.open_other"_lang, ImVec2(0, ImGui::GetTextLineHeightWithSpacing() * 6), ImGuiChildFlags_AutoResizeX);
for (const auto &unlocalizedProviderName : ContentRegistry::Provider::impl::getEntries()) {
if (ImGui::Hyperlink(LangEntry(unlocalizedProviderName))) {
ImHexApi::Provider::createProvider(unlocalizedProviderName);
ImGui::CloseCurrentPopup();
otherProvidersVisible = false;
}
}
ImGui::EndPopup();
ImGui::EndSubWindow();
}
}
ImGui::EndSubWindow();
// Draw recent entries
ImGui::Dummy({});
@ -286,16 +294,23 @@ namespace hex::plugin::builtin {
ImGui::TableNextColumn();
ImGui::BeginSubWindow("hex.builtin.welcome.header.learn"_lang, ImVec2(ImGui::GetContentRegionAvail().x - windowPadding, 0), ImGuiChildFlags_AutoResizeX);
{
if (ImGui::DescriptionButton("hex.builtin.welcome.learn.latest.title"_lang, "hex.builtin.welcome.learn.latest.desc"_lang, ImVec2(ImGui::GetContentRegionAvail().x, 0)))
const auto size = ImVec2(ImGui::GetContentRegionAvail().x, 0);
if (ImGui::DescriptionButton("hex.builtin.welcome.learn.latest.title"_lang, "hex.builtin.welcome.learn.latest.desc"_lang, size))
hex::openWebpage("hex.builtin.welcome.learn.latest.link"_lang);
if (ImGui::DescriptionButton("hex.builtin.welcome.learn.imhex.title"_lang, "hex.builtin.welcome.learn.imhex.desc"_lang, ImVec2(ImGui::GetContentRegionAvail().x, 0))) {
if (ImGui::DescriptionButton("hex.builtin.welcome.learn.imhex.title"_lang, "hex.builtin.welcome.learn.imhex.desc"_lang, size)) {
AchievementManager::unlockAchievement("hex.builtin.achievement.starting_out", "hex.builtin.achievement.starting_out.docs.name");
hex::openWebpage("hex.builtin.welcome.learn.imhex.link"_lang);
}
if (ImGui::DescriptionButton("hex.builtin.welcome.learn.pattern.title"_lang, "hex.builtin.welcome.learn.pattern.desc"_lang, ImVec2(ImGui::GetContentRegionAvail().x, 0)))
if (ImGui::DescriptionButton("hex.builtin.welcome.learn.pattern.title"_lang, "hex.builtin.welcome.learn.pattern.desc"_lang, size))
hex::openWebpage("hex.builtin.welcome.learn.pattern.link"_lang);
if (ImGui::DescriptionButton("hex.builtin.welcome.learn.plugins.title"_lang, "hex.builtin.welcome.learn.plugins.desc"_lang, ImVec2(ImGui::GetContentRegionAvail().x, 0)))
if (ImGui::DescriptionButton("hex.builtin.welcome.learn.plugins.title"_lang, "hex.builtin.welcome.learn.plugins.desc"_lang, size))
hex::openWebpage("hex.builtin.welcome.learn.plugins.link"_lang);
if (auto [unlocked, total] = AchievementManager::getProgress(); unlocked != total) {
if (ImGui::DescriptionButtonProgress("hex.builtin.welcome.learn.achievements.title"_lang, "hex.builtin.welcome.learn.achievements.desc"_lang, float(unlocked) / float(total), size)) {
EventManager::post<RequestOpenWindow>("Achievements");
}
}
}
ImGui::EndSubWindow();