mirror of
https://github.com/migatu/vtt_work.git
synced 2026-07-14 13:34:42 +00:00
v 1.17 interim
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -0,0 +1,23 @@
|
|||||||
|
cffi==2.0.0
|
||||||
|
contourpy==1.3.3
|
||||||
|
cycler==0.12.1
|
||||||
|
fonttools==4.60.1
|
||||||
|
kiwisolver==1.4.9
|
||||||
|
matplotlib==3.10.7
|
||||||
|
numpy==2.3.3
|
||||||
|
packaging==25.0
|
||||||
|
pillow==12.0.0
|
||||||
|
pycparser==2.23
|
||||||
|
pyparsing==3.2.5
|
||||||
|
PyQt5==5.15.11
|
||||||
|
PyQt5-Qt5==5.15.2
|
||||||
|
PyQt5_sip==12.17.1
|
||||||
|
pyqtgraph==0.13.7
|
||||||
|
PySide6==6.10.0
|
||||||
|
PySide6_Addons==6.10.0
|
||||||
|
PySide6_Essentials==6.10.0
|
||||||
|
python-dateutil==2.9.0.post0
|
||||||
|
scipy==1.16.2
|
||||||
|
shiboken6==6.10.0
|
||||||
|
six==1.17.0
|
||||||
|
soundfile==0.13.1
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Quick test to verify the arrange_plot_windows function improvements.
|
||||||
|
This script simulates the functionality without running the full nuclear monitor.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import math
|
||||||
|
|
||||||
|
def test_best_grid():
|
||||||
|
"""Test the improved grid calculation"""
|
||||||
|
def best_grid(n):
|
||||||
|
if n <= 0:
|
||||||
|
return (1, 1)
|
||||||
|
# For small number of windows, prefer horizontal layout
|
||||||
|
if n <= 3:
|
||||||
|
return (1, n)
|
||||||
|
if n == 4:
|
||||||
|
return (2, 2)
|
||||||
|
|
||||||
|
# For larger numbers: approximate square, but prefer width
|
||||||
|
cols = int(math.ceil(math.sqrt(n)))
|
||||||
|
if cols * (cols - 1) >= n: # check if we can reduce rows
|
||||||
|
cols -= 1
|
||||||
|
rows = int(math.ceil(n / cols))
|
||||||
|
return (rows, cols)
|
||||||
|
|
||||||
|
test_cases = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 16]
|
||||||
|
|
||||||
|
print("Grid layout tests:")
|
||||||
|
print("Windows | Grid (rows x cols) | Layout")
|
||||||
|
print("--------|-------------------|--------")
|
||||||
|
|
||||||
|
for n in test_cases:
|
||||||
|
rows, cols = best_grid(n)
|
||||||
|
layout = "x".join(["O"] * cols)
|
||||||
|
layout = " | ".join([layout] * rows)
|
||||||
|
print(f"{n:7d} | {rows:2d} x {cols:2d} | {layout}")
|
||||||
|
|
||||||
|
def test_window_padding():
|
||||||
|
"""Test the window-specific padding"""
|
||||||
|
def get_window_padding(kind):
|
||||||
|
if kind == "qt":
|
||||||
|
return (15, 40) # Qt needs more space for title bar
|
||||||
|
else:
|
||||||
|
return (8, 12) # Tk windows
|
||||||
|
|
||||||
|
print("\nWindow padding tests:")
|
||||||
|
print("Type | Width Pad | Height Pad | Reason")
|
||||||
|
print("-----|-----------|------------|--------")
|
||||||
|
|
||||||
|
for kind in ["tk", "qt"]:
|
||||||
|
w_pad, h_pad = get_window_padding(kind)
|
||||||
|
reason = "Qt title bar & frames" if kind == "qt" else "Tk decorations"
|
||||||
|
print(f"{kind:4s} | {w_pad:9d} | {h_pad:10d} | {reason}")
|
||||||
|
|
||||||
|
def test_arrangement_calculation():
|
||||||
|
"""Test the arrangement calculation for different scenarios"""
|
||||||
|
print("\nArrangement calculation test:")
|
||||||
|
|
||||||
|
# Simulate monitor: 1920x1080
|
||||||
|
mon_w, mon_h = 1920, 1080
|
||||||
|
SIDE_MARGIN = 12
|
||||||
|
TOP_MARGIN = 60
|
||||||
|
BOTTOM_MARGIN = 12
|
||||||
|
CELL_PAD = 10
|
||||||
|
MAX_W, MAX_H = 380, 210 # Half of 760x420
|
||||||
|
|
||||||
|
test_scenarios = [
|
||||||
|
(2, "Two windows - should be side by side"),
|
||||||
|
(4, "Four windows - 2x2 grid"),
|
||||||
|
(6, "Six windows - 2x3 or 3x2 grid"),
|
||||||
|
(9, "Nine windows - full screen mode"),
|
||||||
|
]
|
||||||
|
|
||||||
|
def best_grid(n):
|
||||||
|
if n <= 0:
|
||||||
|
return (1, 1)
|
||||||
|
if n <= 3:
|
||||||
|
return (1, n)
|
||||||
|
if n == 4:
|
||||||
|
return (2, 2)
|
||||||
|
cols = int(math.ceil(math.sqrt(n)))
|
||||||
|
if cols * (cols - 1) >= n:
|
||||||
|
cols -= 1
|
||||||
|
rows = int(math.ceil(n / cols))
|
||||||
|
return (rows, cols)
|
||||||
|
|
||||||
|
for n_windows, description in test_scenarios:
|
||||||
|
print(f"\n{description}")
|
||||||
|
print(f"Windows: {n_windows}")
|
||||||
|
|
||||||
|
rows, cols = best_grid(n_windows)
|
||||||
|
use_max_size = n_windows < 9
|
||||||
|
|
||||||
|
# Calculate available space
|
||||||
|
available_w = mon_w - (cols + 1) * CELL_PAD - 2 * SIDE_MARGIN
|
||||||
|
available_h = mon_h - (rows + 1) * CELL_PAD - TOP_MARGIN - BOTTOM_MARGIN
|
||||||
|
|
||||||
|
# Initial cell size
|
||||||
|
cell_w = max(1, available_w // cols)
|
||||||
|
cell_h = max(1, available_h // rows)
|
||||||
|
|
||||||
|
# Apply max size constraint for few windows
|
||||||
|
if use_max_size:
|
||||||
|
cell_w = min(MAX_W, cell_w)
|
||||||
|
cell_h = min(MAX_H, cell_h)
|
||||||
|
|
||||||
|
print(f"Grid: {rows}x{cols}")
|
||||||
|
print(f"Available space: {available_w}x{available_h}")
|
||||||
|
print(f"Cell size: {cell_w}x{cell_h}")
|
||||||
|
print(f"Max size applied: {use_max_size}")
|
||||||
|
|
||||||
|
# Test padding for different window types
|
||||||
|
for win_type in ["tk", "qt"]:
|
||||||
|
if win_type == "qt":
|
||||||
|
w_pad, h_pad = (15, 40)
|
||||||
|
else:
|
||||||
|
w_pad, h_pad = (8, 12)
|
||||||
|
|
||||||
|
adj_w = max(50, cell_w - w_pad)
|
||||||
|
adj_h = max(50, cell_h - h_pad)
|
||||||
|
print(f" {win_type} windows: {adj_w}x{adj_h} (after padding)")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("Testing arrange_plot_windows improvements\n")
|
||||||
|
print("=" * 50)
|
||||||
|
|
||||||
|
test_best_grid()
|
||||||
|
test_window_padding()
|
||||||
|
test_arrangement_calculation()
|
||||||
|
|
||||||
|
print("\n" + "=" * 50)
|
||||||
|
print("All tests completed. The arrange_plot_windows function should now:")
|
||||||
|
print("1. ✅ Properly detect both Qt and matplotlib windows")
|
||||||
|
print("2. ✅ Use improved grid layout (prefer horizontal for few windows)")
|
||||||
|
print("3. ✅ Apply appropriate padding for different window types")
|
||||||
|
print("4. ✅ Arrange windows top-to-bottom, left-to-right")
|
||||||
|
print("5. ✅ Handle multiple displays correctly")
|
||||||
|
print("6. ✅ Scale down when windows don't fit")
|
||||||
|
print("7. ✅ Sort windows alphabetically by display name")
|
||||||
@@ -0,0 +1,217 @@
|
|||||||
|
#!/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(f"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