Skip to content

Commit 71c19f2

Browse files
committed
fix file structure and added tests
1 parent 5f7ae67 commit 71c19f2

File tree

8 files changed

+322
-145
lines changed

8 files changed

+322
-145
lines changed
File renamed without changes.

python/rlc/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from .program import Program, compile, State, get_included_contents
1111
from .llm_runner import make_llm, run_game, Ollama, Gemini, GeminiStateless
1212
from .program_graph import parse_call_graph, Node, CallGraph, NodeKind
13-
from .ui_layout import Container, Text, Padding, Direction, FIT, FIXED, GROW
13+
from .layout import Layout, Padding, Direction, FIT, FIXED, GROW
14+
from .text import Text
1415
from rlc.layout_logger import LayoutLogConfig, LayoutLogger
15-
from rlc.display_layout import display
16+
from test.display_layout import display

python/rlc/ui_layout.py renamed to python/rlc/layout.py

Lines changed: 47 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
from enum import Enum
2-
import pygame
32
import copy
43
# //utility for dumping layout
54

@@ -34,7 +33,7 @@ def __init__(self, top=0, bottom=0, left=0, right=0):
3433
self.right = right
3534

3635

37-
class Container:
36+
class Layout:
3837
def __init__(self, backgroundColor="white", sizing=(FIT(), FIT()), padding=Padding(0, 0, 0, 0), direction=Direction.ROW, child_gap=0):
3938
self.sizing = sizing
4039
self.backgroundColor = backgroundColor
@@ -44,11 +43,11 @@ def __init__(self, backgroundColor="white", sizing=(FIT(), FIT()), padding=Paddi
4443
self.children = []
4544
self.x = 0
4645
self.y = 0
47-
self.width = 0
48-
self.height = 0
46+
self.width = sizing[0].value if sizing[0].mode == SizePolicies.FIXED else 0
47+
self.height = sizing[1].value if sizing[1].mode == SizePolicies.FIXED else 0
4948

5049
def add_child(self, child):
51-
self.children.append(copy.deepcopy(child))
50+
self.children.append(child)
5251

5352
def _inner_dims(self):
5453
iw = max(0, self.width - self.padding.left - self.padding.right)
@@ -59,59 +58,58 @@ def child_size(self,logger=None):
5958
# Always size children — even if self has fixed size
6059
inner_available_width = self.width - self.padding.left - self.padding.right
6160
inner_available_height = self.height - self.padding.top - self.padding.bottom
61+
6262
for child in self.children:
63-
if isinstance(child, Text):
64-
child_width_policy, child_height_policy = child.sizing
63+
child_width_policy, child_height_policy = child.sizing
64+
# Only pass constraints if needed
65+
child_width = (
66+
inner_available_width if child_width_policy.mode != SizePolicies.FIXED else child_width_policy.value
67+
)
68+
child_height = (
69+
inner_available_height if child_height_policy.mode != SizePolicies.FIXED else child_height_policy.value
70+
)
71+
child.compute_size(child_width, child_height,logger)
6572

66-
# Only pass constraints if needed
67-
child_width = (
68-
inner_available_width if child_width_policy.mode != SizePolicies.FIXED else child_width_policy.value
69-
)
70-
child_height = (
71-
inner_available_height if child_height_policy.mode != SizePolicies.FIXED else child_height_policy.value
72-
)
73-
child.compute_size(child_width, child_height,logger)
74-
else: child.compute_size(logger)
7573

7674
# Sizing
7775

78-
def compute_size(self, logger=None):
79-
if logger: logger.attach_id(self); logger.snapshot(self, "before_compute")
76+
def compute_size(self, available_width=None, available_height=None, logger=None):
77+
if logger: logger.snapshot(self, "before_compute")
8078
if self.direction == Direction.ROW:
81-
self.compute_width()
82-
self.compute_grow_width()
79+
self._compute_width()
80+
self._compute_grow_width()
8381
self.child_size(logger)
84-
if logger: logger.attach_id(self); logger.snapshot(self, "after_children_sizing")
85-
self.compute_height()
86-
self.compute_grow_height()
82+
if logger: logger.snapshot(self, "after_children_sizing")
83+
self._compute_height()
84+
self._compute_grow_height()
8785
if self.direction == Direction.COLUMN:
88-
self.compute_height()
89-
self.compute_grow_height()
86+
self._compute_height()
87+
self._compute_grow_height()
9088
self.child_size(logger)
91-
if logger: logger.attach_id(self); logger.snapshot(self, "after_children_sizing")
92-
self.compute_width()
93-
self.compute_grow_width()
94-
if logger: logger.attach_id(self); logger.snapshot(self, "after_compute")
89+
if logger: logger.snapshot(self, "after_children_sizing")
90+
self._compute_width()
91+
self._compute_grow_width()
92+
if logger: logger.snapshot(self, "after_compute")
9593

96-
def compute_width(self):
94+
def _compute_width(self):
9795
width_policy, _ = self.sizing
9896
if width_policy.mode == SizePolicies.FIXED:
9997
self.width = width_policy.value
10098
elif width_policy.mode == SizePolicies.FIT:
101-
self.width = self.compute_fit_width()
102-
elif width_policy.mode == SizePolicies.GROW:
103-
self.width = 0
99+
self.width = self._compute_fit_width()
100+
# elif width_policy.mode == SizePolicies.GROW:
101+
# self.width = 0
104102

105-
def compute_height(self):
103+
def _compute_height(self):
106104
_, height_policy = self.sizing
107105
if height_policy.mode == SizePolicies.FIXED:
108106
self.height = height_policy.value
109107
elif height_policy.mode == SizePolicies.FIT:
110-
self.height = self.compute_fit_height()
111-
elif height_policy.mode == SizePolicies.GROW:
112-
self.height = 0
108+
self.height = self._compute_fit_height()
109+
# elif height_policy.mode == SizePolicies.GROW:
110+
# self.height = 0
113111

114-
def compute_fit_width(self):
112+
def _compute_fit_width(self):
115113
self.child_size()
116114
if self.direction == Direction.ROW:
117115
content_width = sum(c.width for c in self.children)
@@ -122,7 +120,7 @@ def compute_fit_width(self):
122120

123121
return content_width + self.padding.left + self.padding.right
124122

125-
def compute_fit_height(self):
123+
def _compute_fit_height(self):
126124
self.child_size()
127125
if self.direction == Direction.COLUMN:
128126
content_height = sum(c.height for c in self.children)
@@ -133,13 +131,13 @@ def compute_fit_height(self):
133131

134132
return content_height + self.padding.top + self.padding.bottom
135133

136-
def compute_grow_width(self):
134+
def _compute_grow_width(self):
137135
if self.direction == Direction.ROW:
138136
# Horizontal GROW
139137
total_fixed_width = sum(child.width for child in self.children if child.sizing[0].mode != SizePolicies.GROW)
140138
total_gap = (len(self.children) - 1) * self.child_gap
141139
remaining_width = self.width - self.padding.left - self.padding.right - total_fixed_width - total_gap
142-
self.grow_children_evenly(self.children, remaining_width, axis=0)
140+
self._grow_children_evenly(self.children, remaining_width, axis=0)
143141

144142
if self.direction == Direction.COLUMN:
145143
# cross-axis GROW
@@ -148,7 +146,7 @@ def compute_grow_width(self):
148146
if child.sizing[0].mode == SizePolicies.GROW:
149147
child.width = remaining_width
150148

151-
def compute_grow_height(self):
149+
def _compute_grow_height(self):
152150
if self.direction == Direction.ROW:
153151
# cross-axis GROW
154152
remaining_height = self.height - self.padding.top - self.padding.bottom
@@ -161,12 +159,11 @@ def compute_grow_height(self):
161159
total_fixed_height = sum(child.height for child in self.children if child.sizing[1].mode != SizePolicies.GROW)
162160
total_gap = self.child_gap * (len(self.children) - 1)
163161
remaining_height = self.height - self.padding.top - self.padding.bottom - total_fixed_height - total_gap
164-
self.grow_children_evenly(self.children, remaining_height, axis=1)
162+
self._grow_children_evenly(self.children, remaining_height, axis=1)
165163

166-
def grow_children_evenly(self, children, remaining, axis):
164+
def _grow_children_evenly(self, children, remaining, axis):
167165
growable = [c for c in children if c.sizing[axis].mode == SizePolicies.GROW]
168166
while growable and remaining > 0:
169-
print("In GROW")
170167
growable.sort(key=lambda c: c.width if axis == 0 else c.height)
171168
smallest = growable[0]
172169
min_val = smallest.width if axis == 0 else smallest.height
@@ -195,10 +192,8 @@ def grow_children_evenly(self, children, remaining, axis):
195192
c.height += grow_amount
196193
remaining -= grow_amount
197194
growable = [c for c in growable if (c.width if axis == 0 else c.height) < second_smallest]
198-
199195
shrinkable = [c for c in children if c.sizing[axis].mode != SizePolicies.FIXED]
200196
while shrinkable and remaining < 0:
201-
print("In Shrink")
202197
shrinkable.sort(key=lambda c: c.width if axis == 0 else c.height, reverse=True)
203198
largest = shrinkable[0]
204199
to_remove = remaining
@@ -232,25 +227,25 @@ def grow_children_evenly(self, children, remaining, axis):
232227
shrinkable = [c for c in shrinkable if (c.width if axis == 0 else c.height) > second_largest_val]
233228

234229
# Position
235-
def layout(self, x, y, logger=None):
230+
def layout(self, x=0, y=0, logger=None):
236231
self.x = x
237232
self.y = y
238233
if logger: logger.snapshot(self, "before_layout")
239234
if self.direction == Direction.ROW:
240-
self.layout_row_children()
235+
self._layout_row_children()
241236
if self.direction == Direction.COLUMN:
242-
self.layout_column_children()
237+
self._layout_column_children()
243238
if logger: logger.snapshot(self, "after_layout")
244239

245-
def layout_row_children(self):
240+
def _layout_row_children(self):
246241
left_offset = self.padding.left
247242
for child in self.children:
248243
child_pos_x = self.x + left_offset
249244
child_pos_y = self.y + self.padding.top
250245
child.layout(child_pos_x, child_pos_y)
251246
left_offset += child.width + self.child_gap
252247

253-
def layout_column_children(self):
248+
def _layout_column_children(self):
254249
top_offset = self.padding.top
255250
for child in self.children:
256251
child_pos_x = self.x + self.padding.left
@@ -259,41 +254,7 @@ def layout_column_children(self):
259254
top_offset += child.height + self.child_gap
260255

261256

262-
class Text(Container):
263-
def __init__(self, text, font_name, font_size, color="black"):
264-
super().__init__()
265-
self.text = text
266-
self.color = pygame.Color(color)
267-
self.font_name = font_name
268-
self.font_size = font_size
269-
def compute_size(self, available_width=None, available_height=None, logger=None):
270-
font = pygame.font.SysFont(self.font_name, self.font_size)
271-
if available_width:
272-
lines = self.wrap_text(font, available_width)
273-
else:
274-
lines = [self.text]
275-
276-
self.text_surfaces = [font.render(line, True, self.color) for line in lines]
277-
self.width = max(s.get_width() for s in self.text_surfaces)
278-
self.height = sum(s.get_height() for s in self.text_surfaces)
279-
if logger: logger.attach_id(self);logger.snapshot(self, "text_compute")
280-
281-
def wrap_text(self, font, max_width):
282-
words = self.text.split(" ")
283-
lines = []
284-
current_line = ""
285257

286-
for word in words:
287-
line = current_line + (" " if current_line else "") + word
288-
if font.size(line)[0] <= max_width:
289-
current_line = line
290-
else:
291-
if current_line:
292-
lines.append(current_line)
293-
current_line = word
294-
if current_line:
295-
lines.append(current_line)
296-
return lines
297258

298259

299260

0 commit comments

Comments
 (0)