impr: More Welcome Screen UI improvements
This commit is contained in:
parent
f00daf171b
commit
21057d51e1
@ -404,6 +404,12 @@ namespace hex {
|
|||||||
*/
|
*/
|
||||||
static void clearTemporary();
|
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:
|
private:
|
||||||
static void achievementAdded();
|
static void achievementAdded();
|
||||||
};
|
};
|
||||||
|
@ -113,6 +113,7 @@ namespace ImGui {
|
|||||||
bool Hyperlink(const char *label, const ImVec2 &size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0);
|
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 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 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);
|
void HelpHover(const char *text);
|
||||||
|
|
||||||
|
@ -157,6 +157,22 @@ namespace hex {
|
|||||||
getAchievementNodes(false).clear();
|
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() {
|
void AchievementManager::achievementAdded() {
|
||||||
getAchievementStartNodes(false).clear();
|
getAchievementStartNodes(false).clear();
|
||||||
getAchievementNodes(false).clear();
|
getAchievementNodes(false).clear();
|
||||||
|
@ -265,6 +265,61 @@ namespace ImGui {
|
|||||||
return pressed;
|
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) {
|
void HelpHover(const char *text) {
|
||||||
const auto iconColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonActive);
|
const auto iconColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonActive);
|
||||||
|
|
||||||
|
@ -115,6 +115,7 @@
|
|||||||
"hex.builtin.common.range.entire_data": "Entire Data",
|
"hex.builtin.common.range.entire_data": "Entire Data",
|
||||||
"hex.builtin.common.range.selection": "Selection",
|
"hex.builtin.common.range.selection": "Selection",
|
||||||
"hex.builtin.common.region": "Region",
|
"hex.builtin.common.region": "Region",
|
||||||
|
"hex.builtin.common.remove": "Remove",
|
||||||
"hex.builtin.common.reset": "Reset",
|
"hex.builtin.common.reset": "Reset",
|
||||||
"hex.builtin.common.set": "Set",
|
"hex.builtin.common.set": "Set",
|
||||||
"hex.builtin.common.settings": "Settings",
|
"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.gethelp.link": "https://github.com/WerWolv/ImHex/discussions/categories/get-help",
|
||||||
"hex.builtin.welcome.help.repo": "GitHub Repository",
|
"hex.builtin.welcome.help.repo": "GitHub Repository",
|
||||||
"hex.builtin.welcome.help.repo.link": "https://imhex.werwolv.net/git",
|
"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.desc": "Read ImHex's current changelog",
|
||||||
"hex.builtin.welcome.learn.latest.link": "https://github.com/WerWolv/ImHex/releases/latest",
|
"hex.builtin.welcome.learn.latest.link": "https://github.com/WerWolv/ImHex/releases/latest",
|
||||||
"hex.builtin.welcome.learn.latest.title": "Latest Release",
|
"hex.builtin.welcome.learn.latest.title": "Latest Release",
|
||||||
|
@ -178,19 +178,23 @@ namespace hex::plugin::builtin::recent {
|
|||||||
const auto &recentEntry = *it;
|
const auto &recentEntry = *it;
|
||||||
bool shouldRemove = false;
|
bool shouldRemove = false;
|
||||||
|
|
||||||
|
const bool isProject = recentEntry.type == "project";
|
||||||
|
|
||||||
ImGui::PushID(&recentEntry);
|
ImGui::PushID(&recentEntry);
|
||||||
ON_SCOPE_EXIT { ImGui::PopID(); };
|
ON_SCOPE_EXIT { ImGui::PopID(); };
|
||||||
|
|
||||||
const char* icon;
|
const char* icon;
|
||||||
if (recentEntry.type == "project") {
|
if (isProject) {
|
||||||
icon = ICON_VS_PROJECT;
|
icon = ICON_VS_PROJECT;
|
||||||
} else {
|
} else {
|
||||||
icon = ICON_VS_FILE_BINARY;
|
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);
|
loadRecentEntry(recentEntry);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (!isProject)
|
||||||
|
ImGui::SetItemTooltip("%s", LangEntry(recentEntry.type).get().c_str());
|
||||||
|
|
||||||
// Detect right click on recent provider
|
// Detect right click on recent provider
|
||||||
std::string popupID = hex::format("RecentEntryMenu.{}", recentEntry.getHash());
|
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::BeginPopup(popupID.c_str())) {
|
||||||
if (ImGui::MenuItem("Remove")) {
|
if (ImGui::MenuItem("hex.builtin.common.remove"_lang)) {
|
||||||
shouldRemove = true;
|
shouldRemove = true;
|
||||||
}
|
}
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
|
@ -164,38 +164,46 @@ namespace hex::plugin::builtin {
|
|||||||
ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetTextLineHeightWithSpacing() * 6);
|
ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetTextLineHeightWithSpacing() * 6);
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
|
|
||||||
|
static bool otherProvidersVisible = false;
|
||||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5_scaled);
|
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 startPos = ImGui::GetCursorPos();
|
||||||
auto newProvider = hex::ImHexApi::Provider::createProvider("hex.builtin.provider.mem_file", true);
|
ImGui::BeginSubWindow("hex.builtin.welcome.header.start"_lang, ImVec2(), ImGuiChildFlags_AutoResizeX);
|
||||||
if (newProvider != nullptr && !newProvider->open())
|
{
|
||||||
hex::ImHexApi::Provider::remove(newProvider);
|
if (ImGui::IconHyperlink(ICON_VS_NEW_FILE, "hex.builtin.welcome.start.create_file"_lang)) {
|
||||||
else
|
auto newProvider = hex::ImHexApi::Provider::createProvider("hex.builtin.provider.mem_file", true);
|
||||||
EventManager::post<EventProviderOpened>(newProvider);
|
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))
|
ImGui::EndSubWindow();
|
||||||
EventManager::post<RequestOpenWindow>("Open File");
|
auto endPos = ImGui::GetCursorPos();
|
||||||
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::SetNextWindowPos(ImGui::GetWindowPos() + ImGui::GetCursorPos());
|
if (otherProvidersVisible) {
|
||||||
if (ImGui::BeginPopup("hex.builtin.welcome.start.popup.open_other"_lang)) {
|
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()) {
|
for (const auto &unlocalizedProviderName : ContentRegistry::Provider::impl::getEntries()) {
|
||||||
if (ImGui::Hyperlink(LangEntry(unlocalizedProviderName))) {
|
if (ImGui::Hyperlink(LangEntry(unlocalizedProviderName))) {
|
||||||
ImHexApi::Provider::createProvider(unlocalizedProviderName);
|
ImHexApi::Provider::createProvider(unlocalizedProviderName);
|
||||||
ImGui::CloseCurrentPopup();
|
otherProvidersVisible = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ImGui::EndSubWindow();
|
||||||
ImGui::EndPopup();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::EndSubWindow();
|
|
||||||
|
|
||||||
|
|
||||||
// Draw recent entries
|
// Draw recent entries
|
||||||
ImGui::Dummy({});
|
ImGui::Dummy({});
|
||||||
@ -286,16 +294,23 @@ namespace hex::plugin::builtin {
|
|||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::BeginSubWindow("hex.builtin.welcome.header.learn"_lang, ImVec2(ImGui::GetContentRegionAvail().x - windowPadding, 0), ImGuiChildFlags_AutoResizeX);
|
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);
|
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");
|
AchievementManager::unlockAchievement("hex.builtin.achievement.starting_out", "hex.builtin.achievement.starting_out.docs.name");
|
||||||
hex::openWebpage("hex.builtin.welcome.learn.imhex.link"_lang);
|
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);
|
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);
|
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();
|
ImGui::EndSubWindow();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user