feat(blame): restore rich code view and minimap
This commit is contained in:
@@ -442,8 +442,8 @@ void drawMinimap(const std::vector<MinimapEntry>& entries, float scale,
|
||||
|
||||
void drawCodeLine(const std::string& text, SyntaxLanguage language, SyntaxState& syntax,
|
||||
float scale, ImU32 background = IM_COL32(0, 0, 0, 0), float left_gutter = 0.0f,
|
||||
float minimum_width = 0.0f) {
|
||||
const float row_height = scaled(21.0f, scale);
|
||||
float minimum_width = 0.0f, float custom_row_height = 0.0f) {
|
||||
const float row_height = custom_row_height > 0.0f ? custom_row_height : scaled(21.0f, scale);
|
||||
const ImVec2 start = ImGui::GetCursorScreenPos();
|
||||
const float width = std::max(minimum_width, ImGui::CalcTextSize(text.c_str()).x + left_gutter + scaled(12.0f, scale));
|
||||
ImGui::InvisibleButton("##code_line", {width, row_height});
|
||||
@@ -659,7 +659,6 @@ void DiffViewer::loadSupplement(RepositoryView& repository, GitManager& manager,
|
||||
|
||||
void DiffViewer::draw(RepositoryView& repository, GitManager& manager, AvatarCache* avatars,
|
||||
float scale, ImFont* code_font, std::string& notice) {
|
||||
(void)avatars;
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, {scaled(8, scale), scaled(5, scale)});
|
||||
ImGui::BeginChild("diff_viewer", {-1, -1}, ImGuiChildFlags_None,
|
||||
ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
|
||||
@@ -713,7 +712,7 @@ void DiffViewer::draw(RepositoryView& repository, GitManager& manager, AvatarCac
|
||||
ImGui::Separator();
|
||||
}
|
||||
|
||||
const bool show_minimap = mode_ == Mode::diff || mode_ == Mode::file;
|
||||
const bool show_minimap = mode_ == Mode::diff || mode_ == Mode::file || mode_ == Mode::blame;
|
||||
const float minimap_width = scaled(56.0f, scale);
|
||||
float main_scroll_y = 0.0f;
|
||||
float main_window_height = 0.0f;
|
||||
@@ -736,10 +735,14 @@ void DiffViewer::draw(RepositoryView& repository, GitManager& manager, AvatarCac
|
||||
}
|
||||
minimap_entries.push_back({0, IM_COL32(0, 0, 0, 0)});
|
||||
}
|
||||
} else {
|
||||
} else if (mode_ == Mode::file) {
|
||||
minimap_entries.reserve(file_lines_.size());
|
||||
for (const std::string& line : file_lines_)
|
||||
minimap_entries.push_back({line.size(), IM_COL32(112, 118, 128, 255)});
|
||||
} else {
|
||||
minimap_entries.reserve(blame_lines_.size());
|
||||
for (const BlameLine& line : blame_lines_)
|
||||
minimap_entries.push_back({line.text.size(), blameColor(line.hash, line.show_attribution ? 200 : 125)});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -820,22 +823,55 @@ void DiffViewer::draw(RepositoryView& repository, GitManager& manager, AvatarCac
|
||||
reload(repository, manager, notice);
|
||||
}
|
||||
} else if (mode_ == Mode::blame) {
|
||||
std::ostringstream blame_text;
|
||||
for (size_t index = 0; index < blame_lines_.size(); ++index) {
|
||||
const BlameLine& line = blame_lines_[index];
|
||||
if (index) blame_text << '\n';
|
||||
blame_text << line.line_number << " ";
|
||||
if (line.show_attribution) {
|
||||
blame_text << line.summary;
|
||||
if (!line.date.empty()) blame_text << " " << line.date;
|
||||
blame_text << " ";
|
||||
} else {
|
||||
blame_text << "| ";
|
||||
if (blame_lines_.empty()) {
|
||||
ImGui::TextDisabled("No blame data is available for this file.");
|
||||
} else {
|
||||
SyntaxState syntax;
|
||||
const float info_width = scaled(270.0f, scale);
|
||||
const float line_number_width = scaled(48.0f, scale);
|
||||
const float code_gutter = info_width + line_number_width + scaled(14.0f, scale);
|
||||
for (size_t index = 0; index < blame_lines_.size(); ++index) {
|
||||
ImGui::PushID(static_cast<int>(index));
|
||||
const BlameLine& line = blame_lines_[index];
|
||||
const ImVec2 line_minimum = ImGui::GetCursorScreenPos();
|
||||
const ImU32 accent = blameColor(line.hash, line.show_attribution ? 255 : 190);
|
||||
const ImU32 background = line.show_attribution ? IM_COL32(39, 42, 50, 150) : IM_COL32(31, 34, 40, 105);
|
||||
const float blame_row_height = line.show_attribution ? scaled(28.0f, scale) : scaled(21.0f, scale);
|
||||
drawCodeLine(line.text, language, syntax, scale, background, code_gutter, content_width,
|
||||
blame_row_height);
|
||||
ImDrawList* draw = ImGui::GetWindowDrawList();
|
||||
const ImVec2 line_maximum = ImGui::GetItemRectMax();
|
||||
draw->AddRectFilled({line_minimum.x, line_minimum.y},
|
||||
{line_minimum.x + scaled(3.0f, scale), line_maximum.y}, accent);
|
||||
drawCodeLineNumber(line.line_number, line_minimum.x + info_width + scaled(6.0f, scale),
|
||||
line_minimum.y + scaled(2.0f, scale), IM_COL32(126, 132, 142, 255));
|
||||
if (line.show_attribution) {
|
||||
const float avatar_size = scaled(16.0f, scale);
|
||||
const ImVec2 avatar_min{line_minimum.x + scaled(8.0f, scale), line_minimum.y + scaled(2.0f, scale)};
|
||||
const unsigned int avatar_texture = avatars ? avatars->textureFor(line.email) : 0;
|
||||
if (avatar_texture) {
|
||||
draw->AddImageRounded(ImTextureRef(static_cast<ImTextureID>(avatar_texture)),
|
||||
avatar_min, {avatar_min.x + avatar_size, avatar_min.y + avatar_size},
|
||||
{0, 0}, {1, 1}, IM_COL32_WHITE, scaled(3.0f, scale));
|
||||
} else {
|
||||
draw->AddRectFilled(avatar_min, {avatar_min.x + avatar_size, avatar_min.y + avatar_size},
|
||||
accent, scaled(3.0f, scale));
|
||||
}
|
||||
const float info_x = avatar_min.x + avatar_size + scaled(8.0f, scale);
|
||||
const std::string author = line.author.empty() ? "Unknown author" : line.author;
|
||||
std::string summary = line.summary.empty() ? "(no summary)" : line.summary;
|
||||
if (!line.date.empty()) summary += " " + line.date;
|
||||
draw->AddText({info_x, line_minimum.y + scaled(1.0f, scale)},
|
||||
IM_COL32(216, 220, 226, 255), author.c_str());
|
||||
draw->AddText({info_x, line_minimum.y + scaled(10.0f, scale)},
|
||||
IM_COL32(134, 140, 151, 255), summary.c_str());
|
||||
} else {
|
||||
draw->AddText({line_minimum.x + scaled(16.0f, scale), line_minimum.y + scaled(2.0f, scale)},
|
||||
IM_COL32(92, 99, 110, 255), "...");
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
blame_text << line.text;
|
||||
}
|
||||
drawSelectableTextBlock("##blame_text", blame_text.str(), {-1, -1});
|
||||
if (blame_lines_.empty()) ImGui::TextDisabled("No blame data is available for this file.");
|
||||
} else {
|
||||
const std::vector<std::string>* lines = mode_ == Mode::file ? &file_lines_ : &history_lines_;
|
||||
if (mode_ == Mode::file) {
|
||||
|
||||
Reference in New Issue
Block a user