2022-03-04 19:06:29 +01:00
# include "content/views/view_about.hpp"
2022-02-01 18:09:40 +01:00
2023-11-05 19:57:29 +01:00
# include <hex/api_urls.hpp>
2022-02-01 18:09:40 +01:00
# include <hex/api/content_registry.hpp>
2023-08-06 21:33:15 +02:00
# include <hex/api/achievement_manager.hpp>
2020-11-14 21:16:03 +01:00
2021-09-06 20:35:38 +02:00
# include <hex/helpers/fmt.hpp>
2022-03-04 11:36:37 +01:00
# include <hex/helpers/fs.hpp>
2022-02-01 18:09:40 +01:00
# include <hex/helpers/utils.hpp>
2023-11-05 19:57:29 +01:00
# include <hex/helpers/http_requests.hpp>
2021-09-06 20:35:38 +02:00
2023-05-12 08:38:32 +02:00
# include <content/popups/popup_docs_question.hpp>
2022-01-22 23:11:28 +01:00
# include <romfs/romfs.hpp>
2023-11-05 19:57:29 +01:00
# include <wolv/utils/string.hpp>
2022-01-22 23:11:28 +01:00
2021-12-07 22:47:41 +01:00
namespace hex : : plugin : : builtin {
2020-11-14 21:16:03 +01:00
2022-03-04 19:06:29 +01:00
ViewAbout : : ViewAbout ( ) : View ( " hex.builtin.view.help.about.name " ) {
2022-01-23 02:28:38 +01:00
2023-08-26 12:54:52 +02:00
// Add "About" menu item to the help menu
2023-03-20 13:11:43 +01:00
ContentRegistry : : Interface : : addMenuItem ( { " hex.builtin.menu.help " , " hex.builtin.view.help.about.name " } , 1000 , Shortcut : : None , [ this ] {
TaskManager : : doLater ( [ ] { ImGui : : OpenPopup ( View : : toWindowName ( " hex.builtin.view.help.about.name " ) . c_str ( ) ) ; } ) ;
this - > m_aboutWindowOpen = true ;
this - > getWindowOpenState ( ) = true ;
} ) ;
2023-05-12 08:38:32 +02:00
ContentRegistry : : Interface : : addMenuItemSeparator ( { " hex.builtin.menu.help " } , 2000 ) ;
2023-08-26 12:54:52 +02:00
// Add documentation links to the help menu
2023-05-12 08:38:32 +02:00
ContentRegistry : : Interface : : addMenuItem ( { " hex.builtin.menu.help " , " hex.builtin.view.help.documentation " } , 3000 , Shortcut : : None , [ ] {
2023-08-06 21:33:15 +02:00
hex : : openWebpage ( " https://docs.werwolv.net/imhex " ) ;
AchievementManager : : unlockAchievement ( " hex.builtin.achievement.starting_out " , " hex.builtin.achievement.starting_out.docs.name " ) ;
2022-01-23 02:28:38 +01:00
} ) ;
2023-05-12 08:38:32 +02:00
ContentRegistry : : Interface : : addMenuItem ( { " hex.builtin.menu.help " , " hex.builtin.menu.help.ask_for_help " } , 4000 , CTRLCMD + SHIFT + Keys : : D , [ ] {
PopupDocsQuestion : : open ( ) ;
} ) ;
2020-11-14 21:16:03 +01:00
}
2022-03-04 19:06:29 +01:00
static void link ( const std : : string & name , const std : : string & author , const std : : string & url ) {
2023-08-26 12:54:52 +02:00
// Draw the hyperlink and open the URL if clicked
2023-11-16 22:24:06 +01:00
if ( ImGuiExt : : BulletHyperlink ( name . c_str ( ) ) )
2022-01-23 20:46:19 +01:00
hex : : openWebpage ( url ) ;
2022-03-04 19:06:29 +01:00
2023-08-26 12:54:52 +02:00
// Show the URL as a tooltip
2022-03-04 19:06:29 +01:00
if ( ImGui : : IsItemHovered ( ) ) {
ImGui : : BeginTooltip ( ) ;
2023-11-16 22:24:06 +01:00
ImGuiExt : : TextFormatted ( " {} " , url ) ;
2022-03-04 19:06:29 +01:00
ImGui : : EndTooltip ( ) ;
}
2023-08-26 12:54:52 +02:00
// Show the author if there is one
2022-03-04 19:06:29 +01:00
if ( ! author . empty ( ) ) {
ImGui : : SameLine ( 0 , 0 ) ;
2023-11-16 22:24:06 +01:00
ImGuiExt : : TextFormatted ( " by {} " , author ) ;
2022-03-04 19:06:29 +01:00
}
2020-11-30 21:44:40 +01:00
}
2022-03-04 19:06:29 +01:00
void ViewAbout : : drawAboutMainPage ( ) {
2023-08-26 12:54:52 +02:00
// Draw main about table
2022-01-23 20:46:19 +01:00
if ( ImGui : : BeginTable ( " about_table " , 2 , ImGuiTableFlags_SizingFixedFit ) ) {
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
2023-08-26 12:54:52 +02:00
// Draw the ImHex icon
2023-08-26 23:43:35 +02:00
if ( ! this - > m_logoTexture . isValid ( ) )
2023-11-16 22:24:06 +01:00
this - > m_logoTexture = ImGuiExt : : Texture ( romfs : : get ( " assets/common/logo.png " ) . span ( ) ) ;
2023-08-26 23:43:35 +02:00
2022-09-18 20:38:45 +02:00
ImGui : : Image ( this - > m_logoTexture , scaled ( { 64 , 64 } ) ) ;
2023-11-05 19:57:29 +01:00
if ( ImGui : : IsItemHovered ( ) & & ImGui : : IsItemClicked ( ) ) {
this - > m_clickCount + = 1 ;
}
2022-01-23 20:46:19 +01:00
ImGui : : TableNextColumn ( ) ;
2021-08-25 19:54:59 +02:00
2023-08-26 12:54:52 +02:00
// Draw basic information about ImHex and its version
2023-11-16 22:24:06 +01:00
ImGuiExt : : TextFormatted ( " ImHex Hex Editor v{} by WerWolv " ICON_FA_CODE_BRANCH , ImHexApi : : System : : getImHexVersion ( ) ) ;
2021-12-12 13:35:07 +01:00
2023-06-26 14:01:45 +02:00
ImGui : : SameLine ( ) ;
2023-08-26 12:54:52 +02:00
2023-09-03 10:27:03 +02:00
// Draw a clickable link to the current commit
2023-11-16 22:24:06 +01:00
if ( ImGuiExt : : Hyperlink ( hex : : format ( " {0}@{1} " , ImHexApi : : System : : getCommitBranch ( ) , ImHexApi : : System : : getCommitHash ( ) ) . c_str ( ) ) )
2023-06-26 14:01:45 +02:00
hex : : openWebpage ( " https://github.com/WerWolv/ImHex/commit/ " + ImHexApi : : System : : getCommitHash ( true ) ) ;
2022-01-23 20:46:19 +01:00
2023-10-30 23:24:00 +01:00
// Draw the build date and time
2023-11-16 22:24:06 +01:00
ImGuiExt : : TextFormatted ( " {}, {} " , __DATE__ , __TIME__ ) ;
2023-10-30 23:24:00 +01:00
2023-08-26 12:54:52 +02:00
// Draw the author of the current translation
2022-01-23 20:46:19 +01:00
ImGui : : TextUnformatted ( " hex.builtin.view.help.about.translator " _lang ) ;
2023-08-26 12:54:52 +02:00
// Draw information about the open-source nature of ImHex
2022-01-24 20:53:17 +01:00
ImGui : : TextUnformatted ( " hex.builtin.view.help.about.source " _lang ) ;
2023-08-26 12:54:52 +02:00
2022-01-24 20:53:17 +01:00
ImGui : : SameLine ( ) ;
2023-08-26 12:54:52 +02:00
2023-09-03 10:27:03 +02:00
// Draw a clickable link to the GitHub repository
2023-11-16 22:24:06 +01:00
if ( ImGuiExt : : Hyperlink ( " WerWolv/ImHex " ) )
2022-01-23 20:46:19 +01:00
hex : : openWebpage ( " https://github.com/WerWolv/ImHex " ) ;
ImGui : : EndTable ( ) ;
}
2020-11-30 21:44:40 +01:00
ImGui : : NewLine ( ) ;
2023-08-26 12:54:52 +02:00
// Draw donation links
2021-12-12 13:35:07 +01:00
ImGui : : TextUnformatted ( " hex.builtin.view.help.about.donations " _lang ) ;
ImGui : : Separator ( ) ;
2020-11-14 21:16:03 +01:00
2023-09-03 10:27:03 +02:00
constexpr std : : array Links = { " https://werwolv.net/donate " , " https://www.patreon.com/werwolv " , " https://github.com/sponsors/WerWolv " } ;
2021-12-12 13:35:07 +01:00
2023-11-16 22:24:06 +01:00
ImGuiExt : : TextFormattedWrapped ( " {} " , static_cast < const char * > ( " hex.builtin.view.help.about.thanks " _lang ) ) ;
2021-12-12 13:35:07 +01:00
ImGui : : NewLine ( ) ;
2021-01-23 00:46:50 +01:00
2021-12-12 13:35:07 +01:00
for ( auto & link : Links ) {
2023-11-16 22:24:06 +01:00
if ( ImGuiExt : : Hyperlink ( link ) )
2021-12-12 13:35:07 +01:00
hex : : openWebpage ( link ) ;
}
}
2021-01-23 00:46:50 +01:00
2022-03-04 19:06:29 +01:00
void ViewAbout : : drawContributorPage ( ) {
2023-11-16 22:24:06 +01:00
ImGuiExt : : TextFormattedWrapped ( " These amazing people have contributed to ImHex in the past. If you'd like to become part of them, please submit a PR to the GitHub Repository! " ) ;
2022-03-04 19:06:29 +01:00
ImGui : : NewLine ( ) ;
2023-08-26 12:54:52 +02:00
// Draw main ImHex contributors
link ( " iTrooz for a huge amount of help maintaining ImHex and the CI " , " " , " https://github.com/iTrooz " ) ;
link ( " jumanji144 for a ton of help with the Pattern Language, API and usage stats " , " " , " https://github.com/Nowilltolife " ) ;
ImGui : : NewLine ( ) ;
// Draw additional contributors
2023-11-01 10:43:59 +01:00
link ( " Mary for porting ImHex to MacOS " , " " , " https://github.com/marysaka " ) ;
2022-03-04 19:06:29 +01:00
link ( " Roblabla for adding the MSI Windows installer " , " " , " https://github.com/roblabla " ) ;
link ( " jam1garner for adding support for Rust plugins " , " " , " https://github.com/jam1garner " ) ;
ImGui : : NewLine ( ) ;
link ( " All other amazing contributors " , " " , " https://github.com/WerWolv/ImHex/graphs/contributors/ " ) ;
2021-12-12 13:35:07 +01:00
}
2021-01-23 00:46:50 +01:00
2022-03-04 19:06:29 +01:00
void ViewAbout : : drawLibraryCreditsPage ( ) {
2021-12-12 13:35:07 +01:00
ImGui : : PushStyleColor ( ImGuiCol_ChildBg , ImVec4 ( 0.2F , 0.2F , 0.2F , 0.3F ) ) ;
2021-01-23 00:46:50 +01:00
2023-08-26 12:54:52 +02:00
// Draw ImGui dependencies
2022-03-04 19:06:29 +01:00
link ( " ImGui " , " ocornut " , " https://github.com/ocornut/imgui/ " ) ;
link ( " imgui_club " , " ocornut " , " https://github.com/ocornut/imgui_club/ " ) ;
link ( " imnodes " , " Nelarius " , " https://github.com/Nelarius/imnodes/ " ) ;
link ( " ImGuiColorTextEdit " , " BalazsJako " , " https://github.com/BalazsJako/ImGuiColorTextEdit/ " ) ;
link ( " ImPlot " , " epezent " , " https://github.com/epezent/implot/ " ) ;
ImGui : : NewLine ( ) ;
2023-08-26 12:54:52 +02:00
// Draw dependencies maintained by individual people
2022-03-04 19:06:29 +01:00
link ( " capstone " , " aquynh " , " https://github.com/aquynh/capstone/ " ) ;
link ( " JSON for Modern C++ " , " nlohmann " , " https://github.com/nlohmann/json/ " ) ;
link ( " YARA " , " VirusTotal " , " https://github.com/VirusTotal/yara/ " ) ;
link ( " Native File Dialog Extended " , " btzy and mlabbe " , " https://github.com/btzy/nativefiledialog-extended/ " ) ;
link ( " libromfs " , " WerWolv " , " https://github.com/WerWolv/libromfs/ " ) ;
link ( " microtar " , " rxi " , " https://github.com/rxi/microtar/ " ) ;
link ( " xdgpp " , " danyspin97 " , " https://sr.ht/~danyspin97/xdgpp/ " ) ;
link ( " FreeType " , " David Turner " , " https://gitlab.freedesktop.org/freetype/freetype/ " ) ;
2023-08-26 12:54:52 +02:00
link ( " mbedTLS " , " ARM " , " https://github.com/ARMmbed/mbedtls/ " ) ;
2022-03-04 19:06:29 +01:00
link ( " libcurl " , " Daniel Stenberg " , " https://curl.se/ " ) ;
link ( " libfmt " , " vitaut " , " https://fmt.dev/ " ) ;
2021-12-12 13:35:07 +01:00
ImGui : : NewLine ( ) ;
2022-03-04 19:06:29 +01:00
2023-08-26 12:54:52 +02:00
// Draw dependencies maintained by groups
2022-03-04 19:06:29 +01:00
link ( " GNU libmagic " , " " , " https://www.darwinsys.com/file/ " ) ;
link ( " GLFW3 " , " " , " https://github.com/glfw/glfw/ " ) ;
link ( " LLVM " , " " , " https://github.com/llvm/llvm-project/ " ) ;
2021-01-23 00:46:50 +01:00
2021-12-12 13:35:07 +01:00
ImGui : : PopStyleColor ( ) ;
2022-03-04 19:06:29 +01:00
ImGui : : NewLine ( ) ;
2021-12-12 13:35:07 +01:00
}
2021-01-23 00:46:50 +01:00
2022-03-04 19:06:29 +01:00
void ViewAbout : : drawPathsPage ( ) {
2021-12-12 13:35:07 +01:00
if ( ImGui : : BeginTable ( " ##imhex_paths " , 2 , ImGuiTableFlags_ScrollY | ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit ) ) {
ImGui : : TableSetupScrollFreeze ( 0 , 1 ) ;
ImGui : : TableSetupColumn ( " Type " ) ;
ImGui : : TableSetupColumn ( " Paths " ) ;
2023-08-26 12:54:52 +02:00
// Specify the types of paths to display
constexpr static std : : array < std : : pair < const char * , fs : : ImHexPath > , size_t ( fs : : ImHexPath : : END ) - 1U > PathTypes = {
2022-12-29 23:32:57 +01:00
{
{ " Patterns " , fs : : ImHexPath : : Patterns } ,
{ " Patterns Includes " , fs : : ImHexPath : : PatternsInclude } ,
{ " Magic " , fs : : ImHexPath : : Magic } ,
{ " Plugins " , fs : : ImHexPath : : Plugins } ,
2023-01-07 10:32:01 +01:00
{ " Libraries " , fs : : ImHexPath : : Libraries } ,
2022-12-29 23:32:57 +01:00
{ " Yara Patterns " , fs : : ImHexPath : : Yara } ,
{ " Config " , fs : : ImHexPath : : Config } ,
{ " Resources " , fs : : ImHexPath : : Resources } ,
{ " Constants lists " , fs : : ImHexPath : : Constants } ,
{ " Custom encodings " , fs : : ImHexPath : : Encodings } ,
{ " Logs " , fs : : ImHexPath : : Logs } ,
{ " Recent files " , fs : : ImHexPath : : Recent } ,
{ " Scripts " , fs : : ImHexPath : : Scripts } ,
{ " Themes " , fs : : ImHexPath : : Themes } ,
{ " Data inspector scripts " , fs : : ImHexPath : : Inspectors } ,
2023-02-09 23:07:04 +01:00
{ " Custom data processor nodes " , fs : : ImHexPath : : Nodes } ,
2022-12-29 23:32:57 +01:00
}
2022-01-24 20:53:17 +01:00
} ;
2021-12-12 13:35:07 +01:00
2023-08-26 12:54:52 +02:00
// Draw the table
2021-12-12 13:35:07 +01:00
ImGui : : TableHeadersRow ( ) ;
for ( const auto & [ name , type ] : PathTypes ) {
ImGui : : TableNextRow ( ) ;
ImGui : : TableNextColumn ( ) ;
ImGui : : TextUnformatted ( name ) ;
ImGui : : TableNextColumn ( ) ;
2022-10-13 08:07:46 +02:00
for ( auto & path : fs : : getDefaultPaths ( type , true ) ) {
2023-08-26 12:54:52 +02:00
// Draw hyperlink to paths that exist or red text if they don't
2023-06-05 13:50:55 +02:00
if ( wolv : : io : : fs : : isDirectory ( path ) ) {
2023-11-16 22:24:06 +01:00
if ( ImGuiExt : : Hyperlink ( wolv : : util : : toUTF8String ( path ) . c_str ( ) ) ) {
2023-06-05 13:50:55 +02:00
fs : : openFolderExternal ( path ) ;
}
} else {
2023-11-16 22:24:06 +01:00
ImGuiExt : : TextFormattedColored ( ImGuiExt : : GetCustomColorVec4 ( ImGuiCustomCol_ToolbarRed ) , wolv : : util : : toUTF8String ( path ) ) ;
2022-10-13 08:07:46 +02:00
}
}
2021-01-23 00:46:50 +01:00
}
2021-12-12 13:35:07 +01:00
ImGui : : EndTable ( ) ;
}
}
2023-11-05 19:57:29 +01:00
void ViewAbout : : drawReleaseNotesPage ( ) {
static std : : string releaseTitle ;
static std : : vector < std : : string > releaseNotes ;
2022-01-22 23:11:28 +01:00
2023-11-05 19:57:29 +01:00
// Set up the request to get the release notes the first time the page is opened
AT_FIRST_TIME {
static HttpRequest request ( " GET " , GitHubApiURL + std : : string ( " /releases/tags/v " ) + ImHexApi : : System : : getImHexVersion ( false ) ) ;
2021-01-14 17:01:44 +01:00
2023-11-05 19:57:29 +01:00
this - > m_releaseNoteRequest = request . execute ( ) ;
} ;
2021-01-14 17:01:44 +01:00
2023-11-05 19:57:29 +01:00
// Wait for the request to finish and parse the response
if ( this - > m_releaseNoteRequest . valid ( ) ) {
if ( this - > m_releaseNoteRequest . wait_for ( std : : chrono : : seconds ( 0 ) ) = = std : : future_status : : ready ) {
auto response = this - > m_releaseNoteRequest . get ( ) ;
nlohmann : : json json ;
if ( response . isSuccess ( ) ) {
// A valid response was received, parse it
try {
json = nlohmann : : json : : parse ( response . getData ( ) ) ;
// Get the release title
releaseTitle = json [ " name " ] . get < std : : string > ( ) ;
2021-12-12 13:35:07 +01:00
2023-11-05 19:57:29 +01:00
// Get the release notes and split it into lines
auto body = json [ " body " ] . get < std : : string > ( ) ;
releaseNotes = wolv : : util : : splitString ( body , " \r \n " ) ;
} catch ( std : : exception & e ) {
releaseNotes . push_back ( " ## Error: " + std : : string ( e . what ( ) ) ) ;
2022-01-24 00:45:46 +01:00
}
2023-11-05 19:57:29 +01:00
} else {
// An error occurred, display it
releaseNotes . push_back ( " ## HTTP Error: " + std : : to_string ( response . getStatusCode ( ) ) ) ;
2021-05-23 23:35:04 +02:00
}
2023-11-05 19:57:29 +01:00
} else {
// Draw a spinner while the release notes are loading
2023-11-16 22:24:06 +01:00
ImGuiExt : : TextSpinner ( " hex.builtin.common.loading " _lang ) ;
2023-11-05 19:57:29 +01:00
}
}
2021-05-23 23:35:04 +02:00
2023-11-05 19:57:29 +01:00
// Function to handle drawing of a regular text line
static const auto drawRegularLine = [ ] ( const std : : string & line ) {
ImGui : : Bullet ( ) ;
ImGui : : SameLine ( ) ;
// Check if the line contains bold text
auto boldStart = line . find ( " ** " ) ;
if ( boldStart ! = std : : string : : npos ) {
// Find the end of the bold text
auto boldEnd = line . find ( " ** " , boldStart + 2 ) ;
// Draw the line with the bold text highlighted
ImGui : : TextUnformatted ( line . substr ( 0 , boldStart ) . c_str ( ) ) ;
ImGui : : SameLine ( 0 , 0 ) ;
2023-11-16 22:24:06 +01:00
ImGuiExt : : TextFormattedColored ( ImGuiExt : : GetCustomColorVec4 ( ImGuiCustomCol_Highlight ) , " {} " , line . substr ( boldStart + 2 , boldEnd - boldStart - 2 ) . c_str ( ) ) ;
2023-11-05 19:57:29 +01:00
ImGui : : SameLine ( 0 , 0 ) ;
ImGui : : TextUnformatted ( line . substr ( boldEnd + 2 ) . c_str ( ) ) ;
} else {
// Draw the line normally
ImGui : : TextUnformatted ( line . c_str ( ) ) ;
}
} ;
// Draw the release title
if ( ! releaseTitle . empty ( ) ) {
auto title = hex : : format ( " v{}: {} " , ImHexApi : : System : : getImHexVersion ( false ) , releaseTitle ) ;
2023-11-16 22:24:06 +01:00
ImGuiExt : : Header ( title . c_str ( ) , true ) ;
2023-11-05 19:57:29 +01:00
ImGui : : Separator ( ) ;
}
// Draw the release notes and format them using parts of the GitHub Markdown syntax
// This is not a full implementation of the syntax, but it's enough to make the release notes look good.
for ( const auto & line : releaseNotes ) {
if ( line . starts_with ( " ## " ) ) {
// Draw H2 Header
2023-11-16 22:24:06 +01:00
ImGuiExt : : Header ( line . substr ( 3 ) . c_str ( ) ) ;
2023-11-05 19:57:29 +01:00
} else if ( line . starts_with ( " ### " ) ) {
// Draw H3 Header
2023-11-16 22:24:06 +01:00
ImGuiExt : : Header ( line . substr ( 4 ) . c_str ( ) ) ;
2023-11-05 19:57:29 +01:00
} else if ( line . starts_with ( " - " ) ) {
// Draw bullet point
drawRegularLine ( line . substr ( 2 ) ) ;
} else if ( line . starts_with ( " - " ) ) {
// Draw further indented bullet point
ImGui : : Indent ( ) ;
ImGui : : Indent ( ) ;
drawRegularLine ( line . substr ( 6 ) ) ;
ImGui : : Unindent ( ) ;
ImGui : : Unindent ( ) ;
}
}
}
void ViewAbout : : drawCommitHistoryPage ( ) {
struct Commit {
std : : string hash ;
std : : string message ;
std : : string description ;
std : : string author ;
std : : string date ;
std : : string url ;
} ;
static std : : vector < Commit > commits ;
// Set up the request to get the commit history the first time the page is opened
AT_FIRST_TIME {
static HttpRequest request ( " GET " , GitHubApiURL + std : : string ( " /commits?per_page=100 " ) ) ;
this - > m_commitHistoryRequest = request . execute ( ) ;
} ;
// Wait for the request to finish and parse the response
if ( this - > m_commitHistoryRequest . valid ( ) ) {
if ( this - > m_commitHistoryRequest . wait_for ( std : : chrono : : seconds ( 0 ) ) = = std : : future_status : : ready ) {
auto response = this - > m_commitHistoryRequest . get ( ) ;
nlohmann : : json json ;
if ( response . isSuccess ( ) ) {
// A valid response was received, parse it
try {
json = nlohmann : : json : : parse ( response . getData ( ) ) ;
for ( auto & commit : json ) {
const auto message = commit [ " commit " ] [ " message " ] . get < std : : string > ( ) ;
// Split commit title and description. They're separated by two newlines.
const auto messageEnd = message . find ( " \n \n " ) ;
auto commitTitle = messageEnd = = std : : string : : npos ? message : message . substr ( 0 , messageEnd ) ;
auto commitDescription = messageEnd = = std : : string : : npos ? " " : message . substr ( commitTitle . size ( ) + 2 ) ;
auto url = commit [ " html_url " ] . get < std : : string > ( ) ;
auto sha = commit [ " sha " ] . get < std : : string > ( ) ;
auto date = commit [ " commit " ] [ " author " ] [ " date " ] . get < std : : string > ( ) ;
auto author = hex : : format ( " {} <{}> " ,
commit [ " commit " ] [ " author " ] [ " name " ] . get < std : : string > ( ) ,
commit [ " commit " ] [ " author " ] [ " email " ] . get < std : : string > ( )
) ;
// Move the commit data into the list of commits
commits . emplace_back (
std : : move ( sha ) ,
std : : move ( commitTitle ) ,
std : : move ( commitDescription ) ,
std : : move ( author ) ,
std : : move ( date ) ,
std : : move ( url )
) ;
}
} catch ( std : : exception & e ) {
commits . emplace_back (
" hex.builtin.common.error " _lang ,
e . what ( ) ,
" " ,
" " ,
" "
) ;
2022-01-24 00:45:46 +01:00
}
2023-11-05 19:57:29 +01:00
} else {
// An error occurred, display it
commits . emplace_back (
" hex.builtin.common.error " _lang ,
" HTTP " + std : : to_string ( response . getStatusCode ( ) ) ,
" " ,
" " ,
" "
) ;
2021-12-12 13:35:07 +01:00
}
2023-11-05 19:57:29 +01:00
} else {
// Draw a spinner while the commits are loading
2023-11-16 22:24:06 +01:00
ImGuiExt : : TextSpinner ( " hex.builtin.common.loading " _lang ) ;
2023-11-05 19:57:29 +01:00
}
}
2021-05-23 23:35:04 +02:00
2023-11-05 19:57:29 +01:00
// Draw commits table
if ( ! commits . empty ( ) ) {
if ( ImGui : : BeginTable ( " ##commits " , 2 , ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_ScrollY ) ) {
// Draw commits
for ( const auto & commit : commits ) {
ImGui : : PushID ( commit . hash . c_str ( ) ) ;
ImGui : : TableNextRow ( ) ;
// Draw hover tooltip
ImGui : : TableNextColumn ( ) ;
if ( ImGui : : Selectable ( " ##commit " , false , ImGuiSelectableFlags_SpanAllColumns ) ) {
hex : : openWebpage ( commit . url ) ;
2022-01-24 00:45:46 +01:00
}
2020-11-14 21:16:03 +01:00
2023-11-05 19:57:29 +01:00
if ( ImGui : : IsItemHovered ( ) ) {
if ( ImGui : : BeginTooltip ( ) ) {
// Draw author and commit date
2023-11-16 22:24:06 +01:00
ImGuiExt : : TextFormattedColored ( ImGuiExt : : GetCustomColorVec4 ( ImGuiCustomCol_Highlight ) , " {} " , commit . author ) ;
2023-11-05 19:57:29 +01:00
ImGui : : SameLine ( ) ;
2023-11-16 22:24:06 +01:00
ImGuiExt : : TextFormatted ( " @ {} " , commit . date . c_str ( ) ) ;
2023-11-05 19:57:29 +01:00
// Draw description if there is one
if ( ! commit . description . empty ( ) ) {
ImGui : : Separator ( ) ;
2023-11-16 22:24:06 +01:00
ImGuiExt : : TextFormatted ( " {} " , commit . description ) ;
2023-11-05 19:57:29 +01:00
}
ImGui : : EndTooltip ( ) ;
}
2022-01-24 00:45:46 +01:00
}
2023-11-05 19:57:29 +01:00
// Draw commit hash
ImGui : : SameLine ( 0 , 0 ) ;
2023-11-16 22:24:06 +01:00
ImGuiExt : : TextFormattedColored ( ImGuiExt : : GetCustomColorVec4 ( ImGuiCustomCol_Highlight ) , " {} " , commit . hash . substr ( 0 , 7 ) ) ;
2023-11-05 19:57:29 +01:00
// Draw the commit message
ImGui : : TableNextColumn ( ) ;
const ImColor color = [ & ] {
if ( commit . hash = = ImHexApi : : System : : getCommitHash ( true ) )
return ImGui : : GetStyleColorVec4 ( ImGuiCol_HeaderActive ) ;
else
return ImGui : : GetStyleColorVec4 ( ImGuiCol_Text ) ;
} ( ) ;
2023-11-16 22:24:06 +01:00
ImGuiExt : : TextFormattedColored ( color , commit . message ) ;
2023-11-05 19:57:29 +01:00
ImGui : : PopID ( ) ;
2021-12-12 13:35:07 +01:00
}
2020-11-30 21:44:40 +01:00
2023-11-05 19:57:29 +01:00
ImGui : : EndTable ( ) ;
}
}
}
void ViewAbout : : drawLicensePage ( ) {
2023-11-16 22:24:06 +01:00
ImGuiExt : : TextFormattedWrapped ( " {} " , romfs : : get ( " licenses/LICENSE " ) . string ( ) ) ;
2023-11-05 19:57:29 +01:00
}
void ViewAbout : : drawAboutPopup ( ) {
struct Tab {
using Function = void ( ViewAbout : : * ) ( ) ;
const char * unlocalizedName ;
Function function ;
} ;
constexpr std : : array Tabs = {
Tab { " ImHex " , & ViewAbout : : drawAboutMainPage } ,
Tab { " hex.builtin.view.help.about.contributor " , & ViewAbout : : drawContributorPage } ,
Tab { " hex.builtin.view.help.about.libs " , & ViewAbout : : drawLibraryCreditsPage } ,
Tab { " hex.builtin.view.help.about.paths " , & ViewAbout : : drawPathsPage } ,
Tab { " hex.builtin.view.help.about.release_notes " , & ViewAbout : : drawReleaseNotesPage } ,
Tab { " hex.builtin.view.help.about.commits " , & ViewAbout : : drawCommitHistoryPage } ,
Tab { " hex.builtin.view.help.about.license " , & ViewAbout : : drawLicensePage } ,
} ;
if ( ImGui : : BeginPopupModal ( View : : toWindowName ( " hex.builtin.view.help.about.name " ) . c_str ( ) , & this - > m_aboutWindowOpen ) ) {
// Allow the window to be closed by pressing ESC
if ( ImGui : : IsKeyDown ( ImGui : : GetKeyIndex ( ImGuiKey_Escape ) ) )
ImGui : : CloseCurrentPopup ( ) ;
if ( ImGui : : BeginTabBar ( " about_tab_bar " ) ) {
// Draw all tabs
for ( const auto & [ unlocalizedName , function ] : Tabs ) {
if ( ImGui : : BeginTabItem ( LangEntry ( unlocalizedName ) ) ) {
ImGui : : NewLine ( ) ;
if ( ImGui : : BeginChild ( 1 ) ) {
( this - > * function ) ( ) ;
}
ImGui : : EndChild ( ) ;
ImGui : : EndTabItem ( ) ;
2022-01-24 00:45:46 +01:00
}
2022-01-22 23:11:28 +01:00
}
2021-12-12 13:35:07 +01:00
ImGui : : EndTabBar ( ) ;
}
2020-11-30 21:44:40 +01:00
2021-12-12 13:35:07 +01:00
ImGui : : EndPopup ( ) ;
2020-11-14 21:16:03 +01:00
}
}
2022-03-04 19:06:29 +01:00
void ViewAbout : : drawContent ( ) {
2021-12-12 13:35:07 +01:00
if ( ! this - > m_aboutWindowOpen )
2021-01-27 14:26:24 +01:00
this - > getWindowOpenState ( ) = false ;
2020-11-17 13:59:16 +01:00
this - > drawAboutPopup ( ) ;
2020-11-14 21:16:03 +01:00
}
2021-08-25 19:54:59 +02:00
}