Skip to content

Commit

Permalink
Info window (#21)
Browse files Browse the repository at this point in the history
* first version of info page

* include hash of latest commit in info window

* improved info window

* git safe.directory

---------

Co-authored-by: Jonas Otto <[email protected]>
  • Loading branch information
authaldo and ottojo authored Aug 20, 2023
1 parent b08b80f commit 894f9f8
Show file tree
Hide file tree
Showing 7 changed files with 245 additions and 31 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ jobs:
uses: actions/checkout@v3
with:
submodules: recursive
- name: Configure git checkout as safe directory to allow dubious permission-setup
run: git config --system --add safe.directory $GITHUB_WORKSPACE
- name: Install depdendencies
run: |
. /opt/ros/$ROS_DISTRO/setup.sh
Expand Down
8 changes: 6 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ set(CMAKE_CXX_STANDARD 20)
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)

# embedding of latest commit hash within the executable
include(cmake/CheckGit.cmake)
CheckGitSetup()

# Download imgui
include(FetchContent)
FetchContent_Declare(imgui
Expand Down Expand Up @@ -40,14 +44,14 @@ add_executable(${PROJECT_NAME} src/rig_reconfigure.cpp src/service_wrapper.cpp s
#target_link_options(${PROJECT_NAME} PRIVATE -fsanitize=thread)

target_include_directories(${PROJECT_NAME} PRIVATE include external/imspinner external/lodepng)
target_link_libraries(${PROJECT_NAME} imgui)
target_link_libraries(${PROJECT_NAME} imgui git_version)
ament_target_dependencies(${PROJECT_NAME} rclcpp)

install(TARGETS ${PROJECT_NAME}
DESTINATION lib/${PROJECT_NAME}
)

install(FILES resource/rig_reconfigure.png
install(FILES resource/rig_reconfigure.png resource/rig_reconfigure_text.png
DESTINATION share/${PROJECT_NAME}/resource
)

Expand Down
89 changes: 89 additions & 0 deletions cmake/CheckGit.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# adapted from https://gitlab.com/jhamberg/cmake-examples/-/blob/master/cmake/CheckGit.cmake

set(CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_DIR})
if (NOT DEFINED pre_configure_inc_dir)
set(pre_configure_inc_dir ${CMAKE_SOURCE_DIR}/include)
endif ()

if (NOT DEFINED pre_configure_dir)
set(pre_configure_dir ${CMAKE_SOURCE_DIR}/src)
endif ()

if (NOT DEFINED post_configure_dir)
set(post_configure_dir ${CMAKE_BINARY_DIR}/generated)
endif ()

set(pre_configure_file ${pre_configure_dir}/git_version.cpp.in)
set(post_configure_file ${post_configure_dir}/git_version.cpp)

function(CheckGitWrite git_hash)
file(WRITE ${CMAKE_BINARY_DIR}/git-state.txt ${git_hash})
endfunction()

function(CheckGitRead git_hash)
if (EXISTS ${CMAKE_BINARY_DIR}/git-state.txt)
file(STRINGS ${CMAKE_BINARY_DIR}/git-state.txt CONTENT)
LIST(GET CONTENT 0 var)

set(${git_hash} ${var} PARENT_SCOPE)
endif ()
endfunction()

function(CheckGitVersion)
# Get the latest abbreviated commit hash of the working branch
execute_process(
COMMAND git log -1 --format=%h
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
OUTPUT_VARIABLE GIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE
)

CheckGitRead(GIT_HASH_CACHE)
if (NOT EXISTS ${post_configure_dir})
file(MAKE_DIRECTORY ${post_configure_dir})
endif ()

if (NOT EXISTS ${post_configure_dir}/git_version.hpp)
file(COPY ${pre_configure_inc_dir}/git_version.hpp DESTINATION ${post_configure_dir})
endif()

if (NOT DEFINED GIT_HASH_CACHE)
set(GIT_HASH_CACHE "INVALID")
endif ()

# Only update the git_version.cpp if the hash has changed. This will
# prevent us from rebuilding the project more than we need to.
if (NOT ${GIT_HASH} STREQUAL ${GIT_HASH_CACHE} OR NOT EXISTS ${post_configure_file})
# Set che GIT_HASH_CACHE variable the next build won't have
# to regenerate the source file.
CheckGitWrite(${GIT_HASH})

configure_file(${pre_configure_file} ${post_configure_file} @ONLY)
endif ()

endfunction()

function(CheckGitSetup)

add_custom_target(AlwaysCheckGit COMMAND ${CMAKE_COMMAND}
-DRUN_CHECK_GIT_VERSION=1
-Dpre_configure_inc_dir=${pre_configure_inc_dir}
-Dpre_configure_dir=${pre_configure_dir}
-Dpost_configure_file=${post_configure_dir}
-DGIT_HASH_CACHE=${GIT_HASH_CACHE}
-P ${CURRENT_LIST_DIR}/CheckGit.cmake
BYPRODUCTS ${post_configure_file}
)

add_library(git_version ${CMAKE_BINARY_DIR}/generated/git_version.cpp)
target_include_directories(git_version PUBLIC ${CMAKE_BINARY_DIR}/generated)
add_dependencies(git_version AlwaysCheckGit)

CheckGitVersion()
endfunction()

# This is used to run this function from an external cmake process.
if (RUN_CHECK_GIT_VERSION)
CheckGitVersion()
endif ()

15 changes: 15 additions & 0 deletions include/git_version.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* @file git_version.hpp
* @author Dominik Authaler
* @date 12.08.2023
*
* Utility file for including the hash of the latest commit within the executable.
* Based on https://jonathanhamberg.com/post/cmake-embedding-git-hash/.
*/

#ifndef RIG_RECONFIGURE_GIT_VERSION_HPP
#define RIG_RECONFIGURE_GIT_VERSION_HPP

extern const char *gitHash;

#endif //RIG_RECONFIGURE_GIT_VERSION_HPP
Binary file added resource/rig_reconfigure_text.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions src/git_version.cpp.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* @file git_version.cpp.in
* @author Dominik Authaler
* @date 12.08.2023
*
* Utility file for including the hash of the latest commit within the executable.
* Based on https://jonathanhamberg.com/post/cmake-embedding-git-hash/.
*
* Note that this file is preprocessed by cmake before being forwarded to the compiler (this allows replacing
* the variable placeholder with the corresponding commit hash).
*/

#include "git_version.hpp"

const char *gitHash = "@GIT_HASH@";
147 changes: 118 additions & 29 deletions src/rig_reconfigure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#include "parameter_tree.hpp"
#include "service_wrapper.hpp"

#include "git_version.hpp"

using namespace std::chrono_literals;

/// Minimum width specified for text input fields.
Expand Down Expand Up @@ -56,6 +58,10 @@ static void highlightedText(const std::string &text, std::size_t start, std::siz
static bool highlightedSelectableText(const std::string &text, std::size_t start, std::size_t end,
const ImVec4 &highlightColor = FILTER_HIGHLIGHTING_COLOR);

static std::filesystem::path findResourcePath(const std::string &execPath);
static void loadWindowIcon(GLFWwindow *windowPtr, const std::filesystem::path &resourcePath);
static void renderInfoWindow(bool *showInfoWindow, const std::filesystem::path &resourcePath);

int main(int argc, char *argv[]) {
rclcpp::init(argc, argv);

Expand Down Expand Up @@ -87,36 +93,9 @@ int main(int argc, char *argv[]) {
glfwMakeContextCurrent(window);
glfwSwapInterval(1); // Enable vsync

// load window icon
auto logoPath = std::filesystem::path(argv[0]).parent_path().append("resource/rig_reconfigure.png");
const auto resourcePath = findResourcePath(argv[0]);

try {
// Try getting package share dir via ament, and use that if it succeeds.
logoPath = ament_index_cpp::get_package_share_directory("rig_reconfigure");
logoPath.append("resource/rig_reconfigure.png");
} catch (ament_index_cpp::PackageNotFoundError &e) {
std::cerr << "Warning: Error while looking for package share directory to find the app icon: " << e.what()
<< "\n";
}

std::vector<unsigned char> iconData;
unsigned int width;
unsigned int height;

unsigned error = lodepng::decode(iconData, width, height, logoPath.string());

if (!error) {
GLFWimage icon;

icon.width = static_cast<int>(width);
icon.height = static_cast<int>(height);
icon.pixels = iconData.data();

glfwSetWindowIcon(window, 1, &icon);
} else {
std::cerr << "Unable to load window icon (decoder error " << error << " - " << lodepng_error_text(error) << ")"
<< std::endl;
}
loadWindowIcon(window, resourcePath);

// Setup Dear ImGui context
IMGUI_CHECKVERSION();
Expand Down Expand Up @@ -152,6 +131,7 @@ int main(int argc, char *argv[]) {
serviceWrapper.pushRequest(std::make_shared<Request>(Request::Type::QUERY_NODE_NAMES));

bool shouldResetLayout = true;
bool showInfo = false;

// Main loop
while (!glfwWindowShouldClose(window)) {
Expand Down Expand Up @@ -304,9 +284,16 @@ int main(int argc, char *argv[]) {
ImGui::EndMenu();
}

if (ImGui::BeginMenu("Info")) {
ImGui::MenuItem("Show info", nullptr, &showInfo);
ImGui::EndMenu();
}

ImGui::EndMainMenuBar();
}

renderInfoWindow(&showInfo, resourcePath);

if (ImGui::DockBuilderGetNode(dockspace_id) == NULL || shouldResetLayout) {
shouldResetLayout = false;
ImGui::DockBuilderRemoveNode(dockspace_id); // Clear out existing layout
Expand Down Expand Up @@ -652,3 +639,105 @@ bool highlightedSelectableText(const std::string &text, std::size_t start, std::

return selected;
}

std::filesystem::path findResourcePath(const std::string &execPath) {
auto resourcePath = std::filesystem::path(execPath).parent_path().append("resource");

try {
// Try getting package share dir via ament, and use that if it succeeds.
resourcePath = ament_index_cpp::get_package_share_directory("rig_reconfigure");
resourcePath.append("resource");
} catch (ament_index_cpp::PackageNotFoundError &e) {
std::cerr << "Warning: Error while looking for package share directory: " << e.what()
<< "\n";
}

return resourcePath;
}

void loadWindowIcon(GLFWwindow *windowPtr, const std::filesystem::path &resourcePath) {
const auto logoPath = resourcePath / "rig_reconfigure.png";

std::vector<unsigned char> iconData;
unsigned int width;
unsigned int height;

unsigned int error = lodepng::decode(iconData, width, height, logoPath.string());

if (error == 0) {
GLFWimage icon;

icon.width = static_cast<int>(width);
icon.height = static_cast<int>(height);
icon.pixels = iconData.data();

glfwSetWindowIcon(windowPtr, 1, &icon);
} else {
std::cerr << "Unable to load window icon (decoder error " << error << " - " << lodepng_error_text(error) << ")"
<< std::endl;
}
}

void renderInfoWindow(bool *showInfoWindow, const std::filesystem::path &resourcePath) {
// load the logo with text only once
static GLuint imageTexture;
static unsigned int width = 0;
static unsigned int height = 0;
static bool imageLoaded = false;

if (!imageLoaded) {
auto logoPath = resourcePath / "rig_reconfigure_text.png";

std::vector<unsigned char> imageData;

unsigned int error = lodepng::decode(imageData, width, height, logoPath.string());

if (error == 0) {
glGenTextures(1, &imageTexture);
glBindTexture(GL_TEXTURE_2D, imageTexture);

// Setup filtering parameters for display
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

#if defined(GL_UNPACK_ROW_LENGTH) && !defined(__EMSCRIPTEN__)
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
#endif
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData.data());
}

imageLoaded = true;
}

if (*showInfoWindow) {
ImGui::Begin("Info", showInfoWindow, ImGuiWindowFlags_AlwaysAutoResize);

if (width != 0 && height != 0) {
ImGui::Image((void*)(intptr_t)imageTexture,
ImVec2(static_cast<float>(width), static_cast<float>(height)));
} else {
ImGui::Text("rig-reconfigure");
}

ImGui::Text(" ");
ImGui::Text("Version: %s", gitHash);
ImGui::Text(" ");

ImGui::Text("Created in winter 2022 by");
ImGui::Text(" ");
ImGui::Text("Dominik Authaler");
ImGui::Text("Jonas Otto");
ImGui::Text(" ");
ImGui::Text("Sources available at https://github.com/teamspatzenhirn/rig_reconfigure");
ImGui::Text("under MIT license. Pull requests extending the functionality / fixing");
ImGui::Text("bugs are always welcome!");
ImGui::Text(" ");
ImGui::Text("This tool has been created while the authors have been part of Team Spatzenhirn,");
ImGui::Text("a student team at Ulm University. If you like rig-reconfigure, please consider");
ImGui::Text("supporting the team (e.g. by joining if you're studying at Ulm University).");

ImGui::End();
}
}

0 comments on commit 894f9f8

Please sign in to comment.