fix(diff): restore syntax rendering and minimap sizing
This commit is contained in:
@@ -401,7 +401,7 @@ struct MinimapEntry {
|
||||
};
|
||||
|
||||
void drawMinimap(const std::vector<MinimapEntry>& entries, float scale,
|
||||
float visible_ratio, float scroll_ratio) {
|
||||
float rendered_content_height, float visible_start, float visible_height) {
|
||||
const ImVec2 minimum = ImGui::GetCursorScreenPos();
|
||||
const ImVec2 size = ImGui::GetContentRegionAvail();
|
||||
ImGui::InvisibleButton("##code_minimap", size);
|
||||
@@ -426,8 +426,12 @@ void drawMinimap(const std::vector<MinimapEntry>& entries, float scale,
|
||||
entries[index].color, scaled(1.0f, scale));
|
||||
}
|
||||
|
||||
const float viewport_height = std::clamp(size.y * visible_ratio, scaled(18.0f, scale), size.y);
|
||||
const float viewport_y = minimum.y + (size.y - viewport_height) * std::clamp(scroll_ratio, 0.0f, 1.0f);
|
||||
const float content_height = std::max(rendered_content_height, 1.0f);
|
||||
const float clamped_visible_height = std::clamp(visible_height, 0.0f, content_height);
|
||||
const float clamped_visible_start = std::clamp(visible_start, 0.0f, std::max(0.0f, content_height - clamped_visible_height));
|
||||
const float viewport_height = std::clamp(size.y * (clamped_visible_height / content_height),
|
||||
scaled(18.0f, scale), size.y);
|
||||
const float viewport_y = minimum.y + size.y * (clamped_visible_start / content_height);
|
||||
draw->AddRectFilled({minimum.x + scaled(1.0f, scale), viewport_y},
|
||||
{minimum.x + size.x - scaled(11.0f, scale), viewport_y + viewport_height},
|
||||
IM_COL32(120, 146, 198, 45), scaled(2.0f, scale));
|
||||
@@ -435,6 +439,27 @@ void drawMinimap(const std::vector<MinimapEntry>& entries, float scale,
|
||||
{minimum.x + size.x - scaled(11.0f, scale), viewport_y + viewport_height},
|
||||
IM_COL32(120, 146, 198, 160), scaled(2.0f, 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);
|
||||
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});
|
||||
const ImVec2 minimum = ImGui::GetItemRectMin();
|
||||
const ImVec2 maximum = ImGui::GetItemRectMax();
|
||||
ImDrawList* draw = ImGui::GetWindowDrawList();
|
||||
if ((background & IM_COL32_A_MASK) != 0)
|
||||
draw->AddRectFilled(minimum, maximum, background);
|
||||
drawSyntaxText(draw, {start.x + left_gutter, start.y + scaled(2.0f, scale)}, text, language, syntax);
|
||||
}
|
||||
|
||||
void drawCodeLineNumber(int value, float x, float y, ImU32 color) {
|
||||
if (value <= 0) return;
|
||||
const std::string text = std::to_string(value);
|
||||
ImGui::GetWindowDrawList()->AddText({x, y}, color, text.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void DiffViewer::open(RepositoryView& repository, GitManager& manager, const std::string& path,
|
||||
@@ -691,12 +716,17 @@ void DiffViewer::draw(RepositoryView& repository, GitManager& manager, AvatarCac
|
||||
const bool show_minimap = mode_ == Mode::diff || mode_ == Mode::file;
|
||||
const float minimap_width = scaled(56.0f, scale);
|
||||
float main_scroll_y = 0.0f;
|
||||
float main_scroll_max_y = 0.0f;
|
||||
float main_window_height = 0.0f;
|
||||
float rendered_content_height = 0.0f;
|
||||
std::vector<MinimapEntry> minimap_entries;
|
||||
if (show_minimap) {
|
||||
minimap_entries.push_back({0, IM_COL32(0, 0, 0, 0)});
|
||||
if (mode_ == Mode::diff) {
|
||||
for (size_t hunk_index = 0; hunk_index < hunks_.size(); ++hunk_index) {
|
||||
if (hunk_index > 0) {
|
||||
minimap_entries.push_back({0, IM_COL32(0, 0, 0, 0)});
|
||||
minimap_entries.push_back({0, IM_COL32(0, 0, 0, 0)});
|
||||
}
|
||||
minimap_entries.push_back({hunks_[hunk_index].header.size(), IM_COL32(128, 133, 141, 255)});
|
||||
for (const Line& line : hunks_[hunk_index].lines) {
|
||||
const ImU32 color = line.kind == LineKind::added ? IM_COL32(87, 190, 112, 255) :
|
||||
@@ -719,6 +749,8 @@ void DiffViewer::draw(RepositoryView& repository, GitManager& manager, AvatarCac
|
||||
const bool use_code_font = code_font && mode_ != Mode::history;
|
||||
if (use_code_font) ImGui::PushFont(code_font, 0.0f);
|
||||
const float row_height = scaled(21, scale);
|
||||
const float content_width = std::max(ImGui::GetContentRegionAvail().x, scaled(200.0f, scale));
|
||||
const SyntaxLanguage language = languageForPath(path_);
|
||||
|
||||
// Keep the first source row clear of the toolbar and aligned with a normal row inset.
|
||||
ImGui::Dummy({0.0f, row_height});
|
||||
@@ -762,15 +794,23 @@ void DiffViewer::draw(RepositoryView& repository, GitManager& manager, AvatarCac
|
||||
}
|
||||
ImGui::Separator();
|
||||
ImGui::Dummy({0.0f, scaled(4.0f, scale)});
|
||||
std::string hunk_text;
|
||||
for (size_t line_index = 0; line_index < hunks_[hunk_index].lines.size(); ++line_index) {
|
||||
if (line_index) hunk_text += '\n';
|
||||
hunk_text += hunks_[hunk_index].lines[line_index].raw;
|
||||
const float number_column = scaled(44.0f, scale);
|
||||
const float code_gutter = number_column * 2.0f + scaled(14.0f, scale);
|
||||
for (const Line& line : hunks_[hunk_index].lines) {
|
||||
ImGui::PushID(line_id++);
|
||||
const ImVec2 line_minimum = ImGui::GetCursorScreenPos();
|
||||
const ImU32 background = line.kind == LineKind::added ? IM_COL32(30, 68, 46, 170) :
|
||||
line.kind == LineKind::removed ? IM_COL32(86, 38, 42, 170) : IM_COL32(0, 0, 0, 0);
|
||||
drawCodeLine(line.text, language,
|
||||
line.kind == LineKind::removed ? old_syntax : new_syntax,
|
||||
scale, background, code_gutter, content_width);
|
||||
const float text_y = line_minimum.y + scaled(2.0f, scale);
|
||||
drawCodeLineNumber(line.old_number, line_minimum.x + scaled(6.0f, scale), text_y,
|
||||
IM_COL32(126, 132, 142, 255));
|
||||
drawCodeLineNumber(line.new_number, line_minimum.x + number_column + scaled(6.0f, scale), text_y,
|
||||
IM_COL32(126, 132, 142, 255));
|
||||
ImGui::PopID();
|
||||
}
|
||||
const float hunk_height = std::max(row_height * 3.0f,
|
||||
row_height * static_cast<float>(hunks_[hunk_index].lines.size()) + scaled(10.0f, scale));
|
||||
drawSelectableTextBlock(("##diff_hunk_text" + std::to_string(line_id++)).c_str(),
|
||||
hunk_text, {-1, hunk_height});
|
||||
ImGui::PopID();
|
||||
}
|
||||
if (pending_hunk >= 0 && pending_hunk < static_cast<int>(hunks_.size())) {
|
||||
@@ -798,23 +838,36 @@ void DiffViewer::draw(RepositoryView& repository, GitManager& manager, AvatarCac
|
||||
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_;
|
||||
drawSelectableTextBlock(mode_ == Mode::file ? "##file_text" : "##history_text",
|
||||
joinLines(*lines), {-1, -1});
|
||||
if (mode_ == Mode::file) {
|
||||
SyntaxState syntax;
|
||||
const float code_gutter = scaled(52.0f, scale);
|
||||
for (size_t index = 0; index < lines->size(); ++index) {
|
||||
ImGui::PushID(static_cast<int>(index));
|
||||
const ImVec2 line_minimum = ImGui::GetCursorScreenPos();
|
||||
drawCodeLine((*lines)[index], language, syntax, scale, IM_COL32(0, 0, 0, 0),
|
||||
code_gutter, content_width);
|
||||
drawCodeLineNumber(static_cast<int>(index + 1), line_minimum.x + scaled(6.0f, scale),
|
||||
line_minimum.y + scaled(2.0f, scale), IM_COL32(126, 132, 142, 255));
|
||||
ImGui::PopID();
|
||||
}
|
||||
} else {
|
||||
drawSelectableTextBlock("##history_text", joinLines(*lines), {-1, -1});
|
||||
}
|
||||
if (lines->empty()) ImGui::TextDisabled("No data is available for this view.");
|
||||
}
|
||||
main_scroll_y = ImGui::GetScrollY();
|
||||
main_scroll_max_y = ImGui::GetScrollMaxY();
|
||||
main_window_height = ImGui::GetWindowHeight();
|
||||
rendered_content_height = ImGui::GetCursorPosY();
|
||||
if (use_code_font) ImGui::PopFont();
|
||||
ImGui::EndChild();
|
||||
if (show_minimap) {
|
||||
ImGui::SameLine(0, scaled(6.0f, scale));
|
||||
ImGui::BeginChild("diff_content_minimap", {minimap_width, -1}, ImGuiChildFlags_None,
|
||||
const float minimap_line_height = scaled(2.0f, scale);
|
||||
const float minimap_height = std::min(main_window_height,
|
||||
std::max(scaled(36.0f, scale), static_cast<float>(minimap_entries.size()) * minimap_line_height + scaled(8.0f, scale)));
|
||||
ImGui::BeginChild("diff_content_minimap", {minimap_width, minimap_height}, ImGuiChildFlags_None,
|
||||
ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
|
||||
const float visible_ratio = main_scroll_max_y <= 0.0f
|
||||
? 1.0f : std::clamp(main_window_height / (main_window_height + main_scroll_max_y), 0.0f, 1.0f);
|
||||
const float scroll_ratio = main_scroll_max_y <= 0.0f ? 0.0f : main_scroll_y / main_scroll_max_y;
|
||||
drawMinimap(minimap_entries, scale, visible_ratio, scroll_ratio);
|
||||
drawMinimap(minimap_entries, scale, rendered_content_height, main_scroll_y, main_window_height);
|
||||
ImGui::EndChild();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
Reference in New Issue
Block a user