yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
split_boundary_drag.cc
Go to the documentation of this file.
2
3#include <algorithm>
4#include <cmath>
5#include <functional>
6
7namespace yaze {
8namespace editor {
9namespace layout_designer {
10namespace {
11
12bool IsHorizontalSplit(SplitDirection d) {
14}
15
16} // namespace
17
19 const DockTreeLayout& layout,
20 ImVec2 mouse, float tolerance) {
21 SplitBoundaryHit result;
22
23 std::function<bool(const DockNode*)> walk = [&](const DockNode* node) {
24 if (node == nullptr || node->type != DockNode::Type::kSplit)
25 return false;
26 const auto split_it = layout.node_rects.find(node);
27 if (split_it == layout.node_rects.end())
28 return false;
29
30 const DockNode* a = node->child_a.get();
31 const DockNode* b = node->child_b.get();
32 if (a == nullptr || b == nullptr)
33 return false;
34
35 const auto a_it = layout.node_rects.find(a);
36 const auto b_it = layout.node_rects.find(b);
37 if (a_it == layout.node_rects.end() || b_it == layout.node_rects.end()) {
38 // Collapsed split — no interactive gutter.
39 return false;
40 }
41
42 // Recurse first so deeper gutters win over an ancestor's when they
43 // overlap (rare but possible at the tolerance band).
44 if (walk(a) || walk(b))
45 return true;
46
47 const ImRect& split_rect = split_it->second;
48 const ImRect& a_rect = a_it->second;
49 const ImRect& b_rect = b_it->second;
50 const bool horizontal = IsHorizontalSplit(node->split_direction);
51 // Clamp the gutter hit band by a fraction of the smaller adjacent cell
52 // along the split axis, so a tiny neighbor doesn't lose its selectable
53 // area to the gutter zone. At kMinCellSize (20 px) the effective band
54 // is still 4 px; only shrinks when cells drop below 16 px (possible
55 // for hand-built layouts or future kMinCellSize changes).
56 const float a_axis = horizontal ? a_rect.GetWidth() : a_rect.GetHeight();
57 const float b_axis = horizontal ? b_rect.GetWidth() : b_rect.GetHeight();
58 const float effective_tol =
59 std::min(tolerance, std::min(a_axis, b_axis) * 0.25f);
60 if (horizontal) {
61 const float gutter_x = a_rect.Max.x;
62 if (std::abs(mouse.x - gutter_x) <= effective_tol &&
63 mouse.y >= split_rect.Min.y && mouse.y <= split_rect.Max.y) {
64 result.split_node = node;
65 result.horizontal = true;
66 return true;
67 }
68 } else {
69 const float gutter_y = a_rect.Max.y;
70 if (std::abs(mouse.y - gutter_y) <= effective_tol &&
71 mouse.x >= split_rect.Min.x && mouse.x <= split_rect.Max.x) {
72 result.split_node = node;
73 result.horizontal = false;
74 return true;
75 }
76 }
77 return false;
78 };
79
80 walk(tree.root.get());
81 return result;
82}
83
84float ComputeDraggedSplitRatio(float start_ratio, float axis_delta_px,
85 float axis_size_px) {
86 if (axis_size_px <= 0.0f) {
87 return std::clamp(start_ratio, kMinSplitRatio, kMaxSplitRatio);
88 }
89 const float new_ratio = start_ratio + axis_delta_px / axis_size_px;
90 return std::clamp(new_ratio, kMinSplitRatio, kMaxSplitRatio);
91}
92
93} // namespace layout_designer
94} // namespace editor
95} // namespace yaze
SplitBoundaryHit HitTestSplitBoundary(const DockTree &tree, const DockTreeLayout &layout, ImVec2 mouse, float tolerance)
float ComputeDraggedSplitRatio(float start_ratio, float axis_delta_px, float axis_size_px)
Represents a dock node in the layout tree.
Definition dock_tree.h:61
std::unique_ptr< DockNode > child_a
Definition dock_tree.h:78
std::unique_ptr< DockNode > child_b
Definition dock_tree.h:79
absl::flat_hash_map< const DockNode *, ImRect > node_rects
std::unique_ptr< DockNode > root
Definition dock_tree.h:115