diff --git a/CMakeLists.txt b/CMakeLists.txt index 86098ed4..59156491 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -106,6 +106,7 @@ set(VIEW_FILES src/view/src/rocprofvis_minimap.cpp src/view/src/widgets/rocprofvis_widget.cpp src/view/src/widgets/rocprofvis_split_containers.cpp + src/view/src/widgets/rocprofvis_flex_container.cpp src/view/src/widgets/rocprofvis_tab_container.cpp src/view/src/widgets/rocprofvis_editable_textfield.cpp src/view/src/widgets/rocprofvis_debug_window.cpp diff --git a/src/view/src/widgets/rocprofvis_flex_container.cpp b/src/view/src/widgets/rocprofvis_flex_container.cpp new file mode 100644 index 00000000..31a38197 --- /dev/null +++ b/src/view/src/widgets/rocprofvis_flex_container.cpp @@ -0,0 +1,105 @@ +// Copyright Advanced Micro Devices, Inc. +// SPDX-License-Identifier: MIT + +#include "rocprofvis_flex_container.h" +#include "rocprofvis_settings_manager.h" + +#include +#include +#include + +namespace RocProfVis +{ +namespace View +{ + +struct FlexRow +{ + size_t start = 0; + size_t count = 0; + float min_w = 0.0f; + float grow = 0.0f; +}; + +FlexItem& +FlexContainer::GetItem(const std::string& id) +{ + for(auto& item : items) + if(item.id == id) return item; + throw std::runtime_error("FlexContainer: item not found: " + id); +} + +void +FlexContainer::Render() +{ + if(items.empty()) return; + + float avail_width = ImGui::GetContentRegionAvail().x; + float avail_height = ImGui::GetContentRegionAvail().y; + + // bin items into rows + + std::vector rows; + rows.push_back({}); + + for(size_t i = 0; i < items.size(); i++) + { + FlexRow& cur = rows.back(); + float gap_w = (cur.count > 0) ? gap : 0.0f; + float needed = cur.min_w + gap_w + items[i].min_width; + + if(cur.count > 0 && needed > avail_width) + rows.push_back({i, 0, 0.0f, 0.0f}); + + FlexRow& target = rows.back(); + if(target.count > 0) target.min_w += gap; + target.min_w += items[i].min_width; + target.grow += items[i].flex_grow; + target.count++; + } + + // figure out default row height + + size_t num_rows = rows.size(); + float row_gap_total = gap * static_cast(num_rows > 1 ? num_rows - 1 : 0); + float row_height = std::max(avail_height, min_row_height); + row_height = (row_height - row_gap_total) / static_cast(num_rows); + + // render + + for(size_t row_index = 0; row_index < num_rows; row_index++) + { + FlexRow& row = rows[row_index]; + float row_gaps = gap * static_cast(row.count > 1 ? row.count - 1 : 0); + float min_sum = row.min_w - row_gaps; + float free = std::max(0.0f, avail_width - min_sum - row_gaps); + + for(size_t column_index = 0; column_index < row.count; column_index++) + { + FlexItem& item = items[row.start + column_index]; + + float w = item.min_width; + if(row.grow > 0.0f) + w += free * (item.flex_grow / row.grow); + + float h = (item.height > 0.0f) ? item.height : row_height; + + ImGui::PushStyleColor(ImGuiCol_ChildBg, + SettingsManager::GetInstance().GetColor(Colors::kFillerColor)); + + ImGui::BeginChild(ImGui::GetID(&item), ImVec2(w, h), + ImGuiChildFlags_Borders); + if(item.widget) item.widget->Render(); + ImGui::EndChild(); + + ImGui::PopStyleColor(); + + if(column_index + 1 < row.count) ImGui::SameLine(0.0f, gap); + } + + if(row_index + 1 < num_rows) ImGui::Dummy(ImVec2(0.0f, gap)); + } +} + +} // namespace View +} // namespace RocProfVis diff --git a/src/view/src/widgets/rocprofvis_flex_container.h b/src/view/src/widgets/rocprofvis_flex_container.h new file mode 100644 index 00000000..394efa84 --- /dev/null +++ b/src/view/src/widgets/rocprofvis_flex_container.h @@ -0,0 +1,34 @@ +// Copyright Advanced Micro Devices, Inc. +// SPDX-License-Identifier: MIT + +#pragma once + +#include "rocprofvis_widget.h" + +namespace RocProfVis +{ +namespace View +{ + +struct FlexItem +{ + std::string id; + std::shared_ptr widget; + float min_width = 500.0f; + float height = 0.0f; + float flex_grow = 1.0f; +}; + +class FlexContainer : public RocWidget +{ +public: + void Render() override; + FlexItem& GetItem(const std::string& id); + + std::vector items; + float gap = 8.0f; + float min_row_height = 0.0f; +}; + +} // namespace View +} // namespace RocProfVis