mirror of
https://github.com/migatu/vtt_work.git
synced 2026-07-14 21:38:39 +00:00
sync: help_scripts v0.4
This commit is contained in:
@@ -0,0 +1,240 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test script to verify the fixed arrange_plot_windows function.
|
||||
|
||||
This tests:
|
||||
1. Column-first arrangement (a-z in first column, then second column, etc.)
|
||||
2. Corrected padding (Qt gets less padding, matplotlib gets more padding)
|
||||
3. No double size calculation issues
|
||||
4. Proper window detection from unified storage
|
||||
"""
|
||||
|
||||
|
||||
# Mock window classes for testing
|
||||
class MockQtWindow:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.geometry_calls = []
|
||||
|
||||
def setGeometry(self, x, y, w, h):
|
||||
self.geometry_calls.append((x, y, w, h))
|
||||
print(f"Qt Window '{self.name}': setGeometry({x}, {y}, {w}, {h})")
|
||||
|
||||
|
||||
class MockTkWindow:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.geometry_calls = []
|
||||
|
||||
def geometry(self, geom_str):
|
||||
self.geometry_calls.append(geom_str)
|
||||
print(f"Tk Window '{self.name}': geometry('{geom_str}')")
|
||||
|
||||
|
||||
def test_arrangement_and_padding():
|
||||
"""Test the column-first arrangement and corrected padding values."""
|
||||
|
||||
print("=== Testing Column-First Arrangement and Corrected Padding ===\n")
|
||||
|
||||
# Test case: 6 windows arranged in a 3x2 grid (3 rows, 2 columns)
|
||||
windows = [
|
||||
("qt", MockQtWindow("PlotA"), "PlotA"),
|
||||
("tk", MockTkWindow("PlotB"), "PlotB"),
|
||||
("qt", MockQtWindow("PlotC"), "PlotC"),
|
||||
("tk", MockTkWindow("PlotD"), "PlotD"),
|
||||
("qt", MockQtWindow("PlotE"), "PlotE"),
|
||||
("tk", MockTkWindow("PlotF"), "PlotF"),
|
||||
]
|
||||
|
||||
# Grid parameters
|
||||
cols = 2
|
||||
rows = 3
|
||||
cell_w = 400
|
||||
cell_h = 300
|
||||
CELL_PAD = 10
|
||||
|
||||
# Mock monitor bounds
|
||||
L, T, R, B = 100, 100, 1500, 900
|
||||
SIDE_MARGIN = 20
|
||||
TOP_MARGIN = 50
|
||||
BOTTOM_MARGIN = 50
|
||||
|
||||
# Calculate grid layout (similar to real function)
|
||||
grid_w = cell_w * cols + (cols + 1) * CELL_PAD
|
||||
grid_h = cell_h * rows + (rows + 1) * CELL_PAD
|
||||
mon_w = R - L
|
||||
mon_h = B - T
|
||||
origin_x = L + SIDE_MARGIN + max(0, (mon_w - grid_w - 2 * SIDE_MARGIN) // 2)
|
||||
origin_y = (
|
||||
T + TOP_MARGIN + max(0, (mon_h - grid_h - TOP_MARGIN - BOTTOM_MARGIN) // 2)
|
||||
)
|
||||
|
||||
print(f"Grid: {cols}x{rows}, Cell: {cell_w}x{cell_h}")
|
||||
print(f"Monitor: ({L},{T}) to ({R},{B})")
|
||||
print(f"Grid origin: ({origin_x},{origin_y})")
|
||||
print("Expected arrangement (column-first):")
|
||||
print(" Column 1: PlotA(0,0), PlotB(0,1), PlotC(0,2)")
|
||||
print(" Column 2: PlotD(1,0), PlotE(1,1), PlotF(1,2)")
|
||||
print()
|
||||
|
||||
# Test the column-first arrangement with corrected padding
|
||||
arrangement_results = []
|
||||
i = 0
|
||||
for c in range(cols): # Column-first: iterate columns first
|
||||
for r in range(rows): # Then rows within each column
|
||||
if i >= len(windows):
|
||||
break
|
||||
kind, win, name = windows[i]
|
||||
|
||||
# Calculate position
|
||||
x = origin_x + CELL_PAD + c * (cell_w + CELL_PAD)
|
||||
y = origin_y + CELL_PAD + r * (cell_h + CELL_PAD)
|
||||
|
||||
# Apply corrected padding (Qt less, Tk/matplotlib more)
|
||||
if kind == "qt":
|
||||
w_pad, h_pad = (8, 15) # Qt: minimal frames, precise sizing
|
||||
else: # "tk" (matplotlib/canvas)
|
||||
w_pad, h_pad = (20, 50) # Tk/matplotlib: toolbar + larger decorations
|
||||
|
||||
adj_w = max(50, cell_w - w_pad)
|
||||
adj_h = max(50, cell_h - h_pad)
|
||||
|
||||
# Clamp to monitor bounds
|
||||
final_x = max(L + SIDE_MARGIN, min(x, R - SIDE_MARGIN - adj_w))
|
||||
final_y = max(T + TOP_MARGIN, min(y, B - BOTTOM_MARGIN - adj_h))
|
||||
|
||||
arrangement_results.append(
|
||||
{
|
||||
"name": name,
|
||||
"kind": kind,
|
||||
"column": c,
|
||||
"row": r,
|
||||
"padding": (w_pad, h_pad),
|
||||
"size": (adj_w, adj_h),
|
||||
"position": (final_x, final_y),
|
||||
}
|
||||
)
|
||||
|
||||
# Apply geometry
|
||||
if kind == "qt":
|
||||
win.setGeometry(final_x, final_y, adj_w, adj_h)
|
||||
else:
|
||||
win.geometry(f"{adj_w}x{adj_h}+{final_x}+{final_y}")
|
||||
|
||||
i += 1
|
||||
|
||||
print("\n=== Arrangement Results ===")
|
||||
for result in arrangement_results:
|
||||
name = result["name"]
|
||||
kind = result["kind"]
|
||||
col = result["column"]
|
||||
row = result["row"]
|
||||
w_pad, h_pad = result["padding"]
|
||||
adj_w, adj_h = result["size"]
|
||||
final_x, final_y = result["position"]
|
||||
|
||||
print(f"{name} ({kind}): Column {col}, Row {row}")
|
||||
print(
|
||||
f" Padding: {w_pad}x{h_pad} ({'minimal' if kind == 'qt' else 'toolbar+margins'})"
|
||||
)
|
||||
print(f" Final size: {adj_w}x{adj_h}")
|
||||
print(f" Position: ({final_x},{final_y})")
|
||||
print()
|
||||
|
||||
# Verify column-first arrangement
|
||||
print("=== Verification ===")
|
||||
expected_order = [
|
||||
("PlotA", 0, 0),
|
||||
("PlotB", 0, 1),
|
||||
("PlotC", 0, 2), # Column 1
|
||||
("PlotD", 1, 0),
|
||||
("PlotE", 1, 1),
|
||||
("PlotF", 1, 2), # Column 2
|
||||
]
|
||||
|
||||
success = True
|
||||
for i, (expected_name, expected_col, expected_row) in enumerate(expected_order):
|
||||
actual = arrangement_results[i]
|
||||
if (
|
||||
actual["name"] != expected_name
|
||||
or actual["column"] != expected_col
|
||||
or actual["row"] != expected_row
|
||||
):
|
||||
print(
|
||||
f"❌ Position {i}: Expected {expected_name} at ({expected_col},{expected_row}), "
|
||||
f"got {actual['name']} at ({actual['column']},{actual['row']})"
|
||||
)
|
||||
success = False
|
||||
|
||||
if success:
|
||||
print("✅ Column-first arrangement verified correctly!")
|
||||
|
||||
# Verify padding corrections
|
||||
qt_windows = [r for r in arrangement_results if r["kind"] == "qt"]
|
||||
tk_windows = [r for r in arrangement_results if r["kind"] == "tk"]
|
||||
|
||||
if qt_windows and tk_windows:
|
||||
qt_pad = qt_windows[0]["padding"]
|
||||
tk_pad = tk_windows[0]["padding"]
|
||||
|
||||
if qt_pad[0] < tk_pad[0] and qt_pad[1] < tk_pad[1]:
|
||||
print(
|
||||
"✅ Padding correction verified: Qt windows have less padding than Tk/matplotlib"
|
||||
)
|
||||
print(f" Qt padding: {qt_pad[0]}x{qt_pad[1]}")
|
||||
print(f" Tk padding: {tk_pad[0]}x{tk_pad[1]}")
|
||||
else:
|
||||
print(f"❌ Padding incorrect: Qt {qt_pad} should be less than Tk {tk_pad}")
|
||||
success = False
|
||||
|
||||
return success
|
||||
|
||||
|
||||
def test_grid_calculation():
|
||||
"""Test the grid calculation logic that prefers horizontal layouts."""
|
||||
|
||||
def best_grid(n):
|
||||
"""Find best grid dimensions preferring horizontal layouts for small n."""
|
||||
if n <= 0:
|
||||
return (0, 0)
|
||||
if n == 1:
|
||||
return (1, 1)
|
||||
if n <= 3:
|
||||
return (n, 1) # Horizontal preference for small counts
|
||||
|
||||
best_ratio = float("inf")
|
||||
best_cols, best_rows = 1, n
|
||||
|
||||
for cols in range(1, n + 1):
|
||||
rows = (n + cols - 1) // cols
|
||||
if cols * rows >= n:
|
||||
ratio = max(cols / rows, rows / cols)
|
||||
if ratio < best_ratio:
|
||||
best_ratio = ratio
|
||||
best_cols, best_rows = cols, rows
|
||||
|
||||
return (best_cols, best_rows)
|
||||
|
||||
print("\n=== Testing Grid Calculation ===")
|
||||
test_cases = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 15, 16]
|
||||
|
||||
for n in test_cases:
|
||||
cols, rows = best_grid(n)
|
||||
ratio = max(cols / rows, rows / cols) if rows > 0 else float("inf")
|
||||
print(f"Windows: {n:2d} → Grid: {cols}x{rows} (ratio: {ratio:.2f})")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Testing arrange_plot_windows fixes...\n")
|
||||
|
||||
result1 = test_arrangement_and_padding()
|
||||
result2 = test_grid_calculation()
|
||||
|
||||
if result1 and result2:
|
||||
print(
|
||||
"\n🎉 All tests passed! The arrangement and padding fixes are working correctly."
|
||||
)
|
||||
else:
|
||||
print("\n❌ Some tests failed. Check the implementation.")
|
||||
Reference in New Issue
Block a user