-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathParentContainerUpdater.java
More file actions
181 lines (163 loc) · 7.2 KB
/
ParentContainerUpdater.java
File metadata and controls
181 lines (163 loc) · 7.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
package com.demcha.compose.engine.pagination;
import com.demcha.compose.engine.components.core.Entity;
import com.demcha.compose.engine.components.geometry.ContentSize;
import com.demcha.compose.engine.components.layout.ParentComponent;
import com.demcha.compose.engine.components.layout.coordinator.ComputedPosition;
import com.demcha.compose.engine.core.EntityManager;
import lombok.NonNull;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
/**
* Pagination helper that propagates child-driven size and position changes to
* parent containers.
*
* <p>
* The page breaker uses these routines after a child moves or grows so parent
* boxes can reflect the same change before later layout/render stages inspect
* the tree.
* </p>
*/
@Slf4j
@UtilityClass
public class ParentContainerUpdater {
/**
* Propagates a resolved offset from a child entity to its parent container.
*
* @param entity child entity whose parent should be updated
* @param manager entity manager used to resolve parent entities
* @param offset resolved offset object
* @return {@code true} when a parent update was applied
*/
public static boolean updateParentContainer(Entity entity, EntityManager manager, Offset offset) {
if (offset == null) {
log.error("Offset cannot be null");
return false;
}
return updateParentContainer(entity, manager, offset.y());
}
/**
* Propagates a vertical delta from a child entity to its parent container
* chain.
*
* @param entity child entity whose parent should be updated
* @param manager entity manager used to resolve parent entities
* @param offsetY vertical delta to propagate
* @return {@code true} when a parent update was applied
*/
public static boolean updateParentContainer(Entity entity, EntityManager manager, double offsetY) {
if (offsetY == 0) {
if (log.isDebugEnabled()) {
log.debug("Skipping parent container position update because offset is zero for {}", entity.getUuid());
}
return false;
}
ParentComponent parentComponent = entity.getComponent(ParentComponent.class).orElse(null);
if (parentComponent == null) {
if (log.isDebugEnabled()) {
log.debug("Parent component missing for entity [{}]; parent position update skipped.", entity.getUuid());
}
return false;
}
Entity parent = manager.getEntity(parentComponent.uuid()).orElse(null);
if (parent == null) {
log.error("Parent entity not found in manager for UUID {}", parentComponent.uuid());
return false;
}
return updateEntitySizeAndPosition(manager, offsetY, parent);
}
/**
* Propagates a size-only delta from a child entity to its parent container
* chain.
*
* @param entity child entity whose parent size should be updated
* @param manager entity manager used to resolve parent entities
* @param offsetY height delta to propagate
* @return {@code true} when a parent size update was applied
*/
public static boolean updateParentContainerSize(Entity entity, EntityManager manager, double offsetY) {
if (offsetY == 0) {
if (log.isDebugEnabled()) {
log.debug("Skipping parent container size update because offset is zero for {}", entity.getUuid());
}
return false;
}
ParentComponent parentComponent = entity.getComponent(ParentComponent.class).orElse(null);
if (parentComponent == null) {
if (log.isDebugEnabled()) {
log.debug("Parent component missing for entity [{}]; parent size update skipped.", entity.getUuid());
}
return false;
}
Entity parent = manager.getEntity(parentComponent.uuid()).orElse(null);
if (parent == null) {
log.error("Parent entity not found in manager for UUID {}", parentComponent.uuid());
return false;
}
return updateEntitySize(manager, offsetY, parent);
}
/**
* Resizes the target entity and, for negative offsets, also shifts its Y
* position before propagating the change upward.
*
* @param manager entity manager used to resolve parent entities
* @param offsetY height delta or upward shift delta
* @param entity entity to mutate
* @return {@code true} when propagation reached a parent container
*/
public static boolean updateEntitySizeAndPosition(EntityManager manager, double offsetY, @NonNull Entity entity) {
ComputedPosition computedPosition = entity.require(ComputedPosition.class);
ContentSize size = entity.require(ContentSize.class);
if (offsetY < 0) {
double newY = computedPosition.y() + offsetY;
double newHeight = size.height() + Math.abs(offsetY);
entity.addComponent(new ComputedPosition(computedPosition.x(), newY));
entity.addComponent(new ContentSize(size.width(), newHeight));
} else {
double newHeight = size.height() + offsetY;
entity.addComponent(new ContentSize(size.width(), newHeight));
}
return updateParentContainer(entity, manager, offsetY);
}
/**
* Resizes the target entity without changing its own Y coordinate and then
* propagates the size change upward.
*
* @param manager entity manager used to resolve parent entities
* @param offsetY height delta to apply
* @param entity entity to resize
* @return {@code true} when propagation reached a parent container
*/
public static boolean updateEntitySize(EntityManager manager, double offsetY, @NonNull Entity entity) {
entity.require(ComputedPosition.class);
ContentSize size = entity.require(ContentSize.class);
if (offsetY < 0) {
double newHeight = size.height() + Math.abs(offsetY);
entity.addComponent(new ContentSize(size.width(), newHeight));
} else {
double newHeight = size.height() + offsetY;
entity.addComponent(new ContentSize(size.width(), newHeight));
}
return updateParentContainerSize(entity, manager, offsetY);
}
/**
* Resizes the current entity and propagates the size-only change to the parent
* container chain.
*
* @param entity current entity to resize
* @param manager entity manager used to resolve parent entities
* @param offsetY height delta to apply
* @return {@code true} when propagation reached a parent container
*/
public static boolean updateCurrentEntitySize(Entity entity, EntityManager manager, double offsetY) {
entity.require(ComputedPosition.class);
ContentSize size = entity.require(ContentSize.class);
if (offsetY < 0) {
double newHeight = size.height() + Math.abs(offsetY);
entity.addComponent(new ContentSize(size.width(), newHeight));
} else {
double newHeight = size.height() + offsetY;
entity.addComponent(new ContentSize(size.width(), newHeight));
}
return updateParentContainerSize(entity, manager, offsetY);
}
}