Add packed layout Python prototype

This commit is contained in:
ajp_anton
2026-05-13 03:06:09 +00:00
parent 5716224a8c
commit ba3b92d4d0
3 changed files with 1433 additions and 0 deletions
+159
View File
@@ -0,0 +1,159 @@
import tkinter as tk
from positions import *
TEXT_SIZE = 14
PADDING = 40
OVERLAP_OUTLINE_WIDTH = 4
SCREEN_WIDTH=1200
SCREEN_HEIGHT=160
VSCALE=2
def rgb_to_hex(rgb):
r, g, b = rgb
return f"#{r:02x}{g:02x}{b:02x}"
def rect_bounds(box):
return box.get_left(), box.get_top(), box.get_right(), box.get_bottom()
def intersection(a, b):
ax1, ay1, ax2, ay2 = rect_bounds(a)
bx1, by1, bx2, by2 = rect_bounds(b)
x1 = max(ax1, bx1)
y1 = max(ay1, by1)
x2 = min(ax2, bx2)
y2 = min(ay2, by2)
if x1 < x2 and y1 < y2:
return x1, y1, x2, y2
return None
def visualize_packing(items):
root = tk.Tk()
root.title("Rectangle Packing Visualizer")
canvas_width = SCREEN_WIDTH + PADDING * 2
canvas_height = SCREEN_HEIGHT*VSCALE + PADDING * 2
canvas = tk.Canvas(
root,
width=canvas_width,
height=canvas_height,
bg="black",
highlightthickness=0
)
canvas.pack()
ox = PADDING
oy = PADDING
# Outer perimeter
canvas.create_rectangle(
ox,
oy,
ox + SCREEN_WIDTH,
oy + SCREEN_HEIGHT*VSCALE,
fill="white",
outline="white"
)
boxes = [box for item in items for box in item.boxes]
# Draw boxes
for box in boxes:
x1 = ox + box.get_left()
y1 = oy + box.get_top() * VSCALE
x2 = ox + box.get_right()
y2 = oy + box.get_bottom() * VSCALE
canvas.create_rectangle(
x1,
y1,
x2,
y2,
fill=rgb_to_hex(box.item.color),
outline="black"
)
# Icon containers draw only vertical separators for simulated icon/dot slots.
if box.item.is_icon_item and box is box.item.boxes[0]:
cursor = box.get_left()
for kind, width in box.item.render_segments()[:-1]:
cursor += width
x = ox + cursor
canvas.create_line(
x,
y1,
x,
y2,
fill="black",
width=2,
)
# Draw overlap regions
for i in range(len(boxes)):
for j in range(i + 1, len(boxes)):
if boxes[i].item is boxes[j].item:
continue
overlap = intersection(boxes[i], boxes[j])
if overlap:
x1, y1, x2, y2 = overlap
y1 *= VSCALE
y2 *= VSCALE
x1 += ox
y1 += oy
x2 += ox
y2 += oy
# Red overlap area
canvas.create_rectangle(
x1,
y1,
x2,
y2,
fill="red",
outline="red"
)
# Thick red circle around overlap
cx = (x1 + x2) / 2
cy = (y1 + y2) / 2
radius = max(x2 - x1, y2 - y1) / 2 + 12
canvas.create_oval(
cx - radius,
cy - radius,
cx + radius,
cy + radius,
outline="red",
width=OVERLAP_OUTLINE_WIDTH
)
# Draw item texts
for item in items:
x1 = ox + item.get_left()
y1 = oy + item.get_top() * VSCALE
x2 = ox + item.get_right()
y2 = oy + item.get_bottom() * VSCALE
canvas.create_text(
(x1 + x2) / 2,
(y1 + y2) / 2,
text=item.rendername(),
font=("Arial", TEXT_SIZE),
fill="black"
)
root.mainloop()
if __name__ == "__main__":
containers = position_containers()
visualize_packing(containers)