mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-10 16:19:28 +01:00
Qt/CodeViewWidget: Indent branch arrows based on free space rather than reserving a full column for each.
This commit is contained in:
parent
18127e2554
commit
9c98b659f1
@ -36,6 +36,7 @@ struct CodeViewBranch
|
|||||||
{
|
{
|
||||||
u32 src_addr;
|
u32 src_addr;
|
||||||
u32 dst_addr;
|
u32 dst_addr;
|
||||||
|
u32 indentation = 0;
|
||||||
bool is_link;
|
bool is_link;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -60,11 +61,10 @@ private:
|
|||||||
|
|
||||||
constexpr u32 x_offset_in_branch_for_vertical_line = 10;
|
constexpr u32 x_offset_in_branch_for_vertical_line = 10;
|
||||||
const u32 addr = m_parent->AddressForRow(index.row());
|
const u32 addr = m_parent->AddressForRow(index.row());
|
||||||
u32 current_branch_index = 0;
|
|
||||||
for (const CodeViewBranch& branch : m_parent->m_branches)
|
for (const CodeViewBranch& branch : m_parent->m_branches)
|
||||||
{
|
{
|
||||||
const int y_center = option.rect.top() + option.rect.height() / 2;
|
const int y_center = option.rect.top() + option.rect.height() / 2;
|
||||||
const int x_left = option.rect.left() + WIDTH_PER_BRANCH_ARROW * current_branch_index;
|
const int x_left = option.rect.left() + WIDTH_PER_BRANCH_ARROW * branch.indentation;
|
||||||
const int x_right = x_left + x_offset_in_branch_for_vertical_line;
|
const int x_right = x_left + x_offset_in_branch_for_vertical_line;
|
||||||
|
|
||||||
if (branch.is_link)
|
if (branch.is_link)
|
||||||
@ -108,8 +108,6 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
++current_branch_index;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
painter->restore();
|
painter->restore();
|
||||||
@ -322,15 +320,88 @@ void CodeViewWidget::Update()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CalculateBranchIndentation();
|
||||||
|
|
||||||
|
u32 max_indent = 0;
|
||||||
|
for (const CodeViewBranch& branch : m_branches)
|
||||||
|
max_indent = std::max(max_indent, branch.indentation);
|
||||||
|
|
||||||
resizeColumnsToContents();
|
resizeColumnsToContents();
|
||||||
setColumnWidth(CODE_VIEW_COLUMN_BRANCH_ARROWS,
|
setColumnWidth(CODE_VIEW_COLUMN_BRANCH_ARROWS,
|
||||||
static_cast<int>(WIDTH_PER_BRANCH_ARROW * m_branches.size()));
|
static_cast<int>(WIDTH_PER_BRANCH_ARROW * (max_indent + 1)));
|
||||||
g_symbolDB.FillInCallers();
|
g_symbolDB.FillInCallers();
|
||||||
|
|
||||||
repaint();
|
repaint();
|
||||||
m_updating = false;
|
m_updating = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CodeViewWidget::CalculateBranchIndentation()
|
||||||
|
{
|
||||||
|
const size_t rows = rowCount();
|
||||||
|
const size_t columns = m_branches.size();
|
||||||
|
if (rows < 1 || columns < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// process in order of how much vertical space the drawn arrow would take up
|
||||||
|
// so shorter arrows go further to the left
|
||||||
|
const auto priority = [](const CodeViewBranch& b) {
|
||||||
|
return b.is_link ? 0 : (std::max(b.src_addr, b.dst_addr) - std::min(b.src_addr, b.dst_addr));
|
||||||
|
};
|
||||||
|
std::stable_sort(m_branches.begin(), m_branches.end(),
|
||||||
|
[&priority](const CodeViewBranch& lhs, const CodeViewBranch& rhs) {
|
||||||
|
return priority(lhs) < priority(rhs);
|
||||||
|
});
|
||||||
|
|
||||||
|
// build a 2D lookup table representing the columns and rows the arrow could be drawn in
|
||||||
|
// and try to place all branch arrows in it as far left as possible
|
||||||
|
std::vector<bool> arrow_space_used(columns * rows, false);
|
||||||
|
const auto index = [&](u32 column, u32 row) { return column * rows + row; };
|
||||||
|
const u32 first_visible_addr = AddressForRow(0);
|
||||||
|
const u32 last_visible_addr = AddressForRow(static_cast<int>(rows - 1));
|
||||||
|
for (CodeViewBranch& branch : m_branches)
|
||||||
|
{
|
||||||
|
const u32 arrow_src_addr = branch.src_addr;
|
||||||
|
const u32 arrow_dst_addr = branch.is_link ? branch.src_addr : branch.dst_addr;
|
||||||
|
const u32 arrow_addr_lower = std::min(arrow_src_addr, arrow_dst_addr);
|
||||||
|
const u32 arrow_addr_higher = std::max(arrow_src_addr, arrow_dst_addr);
|
||||||
|
const bool is_visible =
|
||||||
|
last_visible_addr >= arrow_addr_lower || first_visible_addr <= arrow_addr_higher;
|
||||||
|
if (!is_visible)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const u32 arrow_first_visible_addr =
|
||||||
|
std::clamp(arrow_addr_lower, first_visible_addr, last_visible_addr);
|
||||||
|
const u32 arrow_last_visible_addr =
|
||||||
|
std::clamp(arrow_addr_higher, first_visible_addr, last_visible_addr);
|
||||||
|
const u32 arrow_first_visible_row = (arrow_first_visible_addr - first_visible_addr) / 4;
|
||||||
|
const u32 arrow_last_visible_row = (arrow_last_visible_addr - first_visible_addr) / 4;
|
||||||
|
|
||||||
|
const auto free_column = [&]() -> std::optional<u32> {
|
||||||
|
for (u32 column = 0; column < columns; ++column)
|
||||||
|
{
|
||||||
|
const bool column_is_free = [&] {
|
||||||
|
for (u32 row = arrow_first_visible_row; row <= arrow_last_visible_row; ++row)
|
||||||
|
{
|
||||||
|
if (arrow_space_used[index(column, row)])
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}();
|
||||||
|
if (column_is_free)
|
||||||
|
return column;
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}();
|
||||||
|
|
||||||
|
if (!free_column)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
branch.indentation = *free_column;
|
||||||
|
for (u32 row = arrow_first_visible_row; row <= arrow_last_visible_row; ++row)
|
||||||
|
arrow_space_used[index(*free_column, row)] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
u32 CodeViewWidget::GetAddress() const
|
u32 CodeViewWidget::GetAddress() const
|
||||||
{
|
{
|
||||||
return m_address;
|
return m_address;
|
||||||
|
@ -85,6 +85,8 @@ private:
|
|||||||
void OnReplaceInstruction();
|
void OnReplaceInstruction();
|
||||||
void OnRestoreInstruction();
|
void OnRestoreInstruction();
|
||||||
|
|
||||||
|
void CalculateBranchIndentation();
|
||||||
|
|
||||||
bool m_updating = false;
|
bool m_updating = false;
|
||||||
|
|
||||||
u32 m_address = 0;
|
u32 m_address = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user