Add tests for window layout and responsiveness in GUI
- Verify that the window starts in a compact size with a minimum size floor. - Ensure that the overview and sidebar adapt correctly to narrow widths.
This commit is contained in:
parent
2bad7fbb7f
commit
04134c3096
3 changed files with 88885 additions and 5052 deletions
|
|
@ -2715,6 +2715,8 @@ class BfGui: # pragma: no cover - pencere gerektirir (statik testler dokunmaz)
|
||||||
self._browser_inner: dict[str, Any] = {}
|
self._browser_inner: dict[str, Any] = {}
|
||||||
self._detail_body: dict[str, Any] = {}
|
self._detail_body: dict[str, Any] = {}
|
||||||
self._activity: list[tuple[str, str, str, str, str]] = []
|
self._activity: list[tuple[str, str, str, str, str]] = []
|
||||||
|
self._overview_card_frames: list[Any] = []
|
||||||
|
self._overview_quick_buttons: list[Any] = []
|
||||||
self._elapsed = widgets.Elapsed()
|
self._elapsed = widgets.Elapsed()
|
||||||
self._exec_title_text = "Etkin işlem yok."
|
self._exec_title_text = "Etkin işlem yok."
|
||||||
self._current_page = CATEGORIES[0]
|
self._current_page = CATEGORIES[0]
|
||||||
|
|
@ -2723,13 +2725,19 @@ class BfGui: # pragma: no cover - pencere gerektirir (statik testler dokunmaz)
|
||||||
# gecerli olmali, sonradan boyamak gri bir pencere ve titreme uretir.
|
# gecerli olmali, sonradan boyamak gri bir pencere ve titreme uretir.
|
||||||
self.styles = theme.apply_theme(root)
|
self.styles = theme.apply_theme(root)
|
||||||
root.title(WINDOW_TITLE)
|
root.title(WINDOW_TITLE)
|
||||||
root.minsize(1040, 760)
|
# Tk, geometry verilmezse en buyuk istegi olan cikti/alt cubuk
|
||||||
|
# kombinasyonuna gore pencereyi ekranin tamamindan da buyuk acabiliyor.
|
||||||
|
# Saha laptoplarinda ilk bakis tek ekrana sigmali; kullanici yine
|
||||||
|
# pencereyi buyutebilir. 860x620, detayli moddaki iki kolonun
|
||||||
|
# kullanilabilir en dar guvenli tabanidir.
|
||||||
|
root.geometry("1180x720")
|
||||||
|
root.minsize(860, 620)
|
||||||
root.columnconfigure(0, weight=1)
|
root.columnconfigure(0, weight=1)
|
||||||
# Bantlar: baslik -> uyarilar -> hedef -> govde -> cikti -> eylem.
|
# Bantlar: baslik -> uyarilar -> hedef -> govde -> cikti -> eylem.
|
||||||
# minsize: minimum pencerede (1040x760) islem listesi de cikti kuyusu da
|
# minsize: minimum pencerede (860x620) islem listesi de cikti kuyusu da
|
||||||
# gorunur kalir; ikisi de agirlikla buyur, hicbiri digerini yutamaz.
|
# gorunur kalir; ikisi de agirlikla buyur, hicbiri digerini yutamaz.
|
||||||
root.rowconfigure(3, weight=3, minsize=200)
|
root.rowconfigure(3, weight=3, minsize=200)
|
||||||
root.rowconfigure(4, weight=2, minsize=170)
|
root.rowconfigure(4, weight=1, minsize=120)
|
||||||
|
|
||||||
self._build_header()
|
self._build_header()
|
||||||
self._build_notices()
|
self._build_notices()
|
||||||
|
|
@ -2747,11 +2755,12 @@ class BfGui: # pragma: no cover - pencere gerektirir (statik testler dokunmaz)
|
||||||
output_area.grid(row=4, column=0, sticky="nsew",
|
output_area.grid(row=4, column=0, sticky="nsew",
|
||||||
padx=theme.SP_4, pady=(theme.SP_3, 0))
|
padx=theme.SP_4, pady=(theme.SP_3, 0))
|
||||||
self._build_exec_header(output_area)
|
self._build_exec_header(output_area)
|
||||||
self.output = OutputPane(output_area, self.styles, height=7,
|
self.output = OutputPane(output_area, self.styles, height=5,
|
||||||
log_path=ctx.console_log)
|
log_path=ctx.console_log)
|
||||||
self.output.drain()
|
self.output.drain()
|
||||||
self._build_footer()
|
self._build_footer()
|
||||||
self._apply_privilege_controls()
|
self._apply_privilege_controls()
|
||||||
|
self.root.bind("<Configure>", self._on_window_resized)
|
||||||
|
|
||||||
self.show_mode(full=full_mode)
|
self.show_mode(full=full_mode)
|
||||||
self._load_inventory()
|
self._load_inventory()
|
||||||
|
|
@ -3167,6 +3176,7 @@ class BfGui: # pragma: no cover - pencere gerektirir (statik testler dokunmaz)
|
||||||
pady=(theme.SP_1, theme.SP_3))
|
pady=(theme.SP_1, theme.SP_3))
|
||||||
self._bind_wrap(card, sub, theme.SP_7)
|
self._bind_wrap(card, sub, theme.SP_7)
|
||||||
self._overview_values[key] = (value, sub)
|
self._overview_values[key] = (value, sub)
|
||||||
|
self._overview_card_frames.append(card)
|
||||||
self._refresh_overview()
|
self._refresh_overview()
|
||||||
|
|
||||||
box = ttk.Frame(page, style=self.styles["panel"])
|
box = ttk.Frame(page, style=self.styles["panel"])
|
||||||
|
|
@ -3187,7 +3197,9 @@ class BfGui: # pragma: no cover - pencere gerektirir (statik testler dokunmaz)
|
||||||
else self.styles["big_button"])
|
else self.styles["big_button"])
|
||||||
button = ttk.Button(inner, text=label, command=command,
|
button = ttk.Button(inner, text=label, command=command,
|
||||||
style=style_name, width=18)
|
style=style_name, width=18)
|
||||||
button.pack(fill="x", pady=theme.SP_2)
|
button.pack(side="left", fill="x", expand=True,
|
||||||
|
padx=(0, theme.SP_2), pady=theme.SP_2)
|
||||||
|
self._overview_quick_buttons.append(button)
|
||||||
if label == "Kur":
|
if label == "Kur":
|
||||||
self.install_button = button
|
self.install_button = button
|
||||||
ttk.Label(
|
ttk.Label(
|
||||||
|
|
@ -3399,14 +3411,28 @@ class BfGui: # pragma: no cover - pencere gerektirir (statik testler dokunmaz)
|
||||||
self._paint_nav()
|
self._paint_nav()
|
||||||
|
|
||||||
def _on_window_resized(self, event) -> None:
|
def _on_window_resized(self, event) -> None:
|
||||||
"""Dar pencerede kenar cubugu katlanir (icerik nefes alir)."""
|
"""Dar pencerede kabugu ve Genel Bakis kartlarini toplar."""
|
||||||
if event.widget is not self.root:
|
if event.widget is not self.root:
|
||||||
return
|
return
|
||||||
if event.width < 900:
|
if event.width < 900:
|
||||||
self._sidebar.grid_remove()
|
if hasattr(self, "_sidebar"):
|
||||||
else:
|
self._sidebar.grid_remove()
|
||||||
|
elif hasattr(self, "_sidebar"):
|
||||||
self._sidebar.grid()
|
self._sidebar.grid()
|
||||||
|
|
||||||
|
cards = getattr(self, "_overview_card_frames", ())
|
||||||
|
if cards:
|
||||||
|
columns = 2 if event.width < 1120 else 4
|
||||||
|
for index, card in enumerate(cards):
|
||||||
|
card.grid_configure(
|
||||||
|
row=index // columns,
|
||||||
|
column=index % columns,
|
||||||
|
padx=(0, theme.SP_3) if index % columns < columns - 1 else (0, 0),
|
||||||
|
pady=(0, theme.SP_2) if columns == 2 and index // columns == 0 else (0, 0),
|
||||||
|
)
|
||||||
|
for column in range(4):
|
||||||
|
self._overview_cards.columnconfigure(column, weight=1 if column < columns else 0)
|
||||||
|
|
||||||
def _build_category_page(self, parent, category: str):
|
def _build_category_page(self, parent, category: str):
|
||||||
"""Kategori sayfasi: solda islem tarayici, sagda ayrinti paneli."""
|
"""Kategori sayfasi: solda islem tarayici, sagda ayrinti paneli."""
|
||||||
page = ttk.Frame(parent, style=self.styles["frame"])
|
page = ttk.Frame(parent, style=self.styles["frame"])
|
||||||
|
|
|
||||||
93881
repomix-output.xml
93881
repomix-output.xml
File diff suppressed because one or more lines are too long
|
|
@ -1055,6 +1055,20 @@ class TestConsoleLayoutContract(StaticCase):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
re.findall(r"#[0-9a-fA-F]{3,8}\b", widgets_source), [])
|
re.findall(r"#[0-9a-fA-F]{3,8}\b", widgets_source), [])
|
||||||
|
|
||||||
|
def test_window_starts_compact_and_has_small_screen_floor(self) -> None:
|
||||||
|
self.assertIn('root.geometry("1180x720")', self.source)
|
||||||
|
self.assertIn('root.minsize(860, 620)', self.source)
|
||||||
|
self.assertIn('OutputPane(output_area, self.styles, height=5', self.source)
|
||||||
|
|
||||||
|
def test_overview_and_sidebar_adapt_to_narrow_widths(self) -> None:
|
||||||
|
for needle in (
|
||||||
|
'if event.width < 900:',
|
||||||
|
'columns = 2 if event.width < 1120 else 4',
|
||||||
|
'self._overview_card_frames',
|
||||||
|
):
|
||||||
|
with self.subTest(needle=needle):
|
||||||
|
self.assertIn(needle, self.source)
|
||||||
|
|
||||||
def test_there_is_exactly_one_exit_control(self) -> None:
|
def test_there_is_exactly_one_exit_control(self) -> None:
|
||||||
"""'Cik' tek kontrol: ya basit modda ya alt cubukta, ayni anda degil."""
|
"""'Cik' tek kontrol: ya basit modda ya alt cubukta, ayni anda degil."""
|
||||||
self.assertEqual(self.source.count('text="Çıkış"'), 1)
|
self.assertEqual(self.source.count('text="Çıkış"'), 1)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue