Загрузка данных
---*--- Dozor/modules/utils/window_behavior.py ---*---
# import tkinter as tk
# class LevelOneBehavior:
# """
# Поведение Главного окна (Уровень 1).
# Применяется к объекту класса tk.Tk
# """
# def setup_level_one(self, target_window):
1. Окно неизменно в размерах
# target_window.resizable(False, False)
3. Возможность передвижения пользователем
# target_window.bind("<ButtonPress-1>", self.save_offset)
# target_window.bind("<B1-Motion>", self.drag_window)
Блокировка разворачивания двойным кликом
# target_window.bind("<Double-Button-1>", lambda e: None)
Хранилище для приклеенных окон 2 уровня
# if not hasattr(target_window, '_child_windows'):
# target_window._child_windows = []
# self._drag_start_x = 0
# self._drag_start_y = 0
# def save_offset(self, event):
# self._drag_start_x = event.x_root - self.winfo_x()
# self._drag_start_y = event.y_root - self.winfo_y()
# def drag_window(self, event):
# x = event.x_root - self._drag_start_x
# y = event.y_root - self._drag_start_y
# self.geometry(f"+{x}+{y}")
Двигаем приклеенные окна
# if hasattr(self, '_update_child_positions'):
# self._update_child_positions(x, y)
# def register_child_window(self, window, offset_x=0, offset_y=0):
# """Регистрирует дочернее окно 2 уровня."""
# self._child_windows.append((window, offset_x, offset_y))
# class LevelTwoBehavior:
# """
# Поведение окон второго уровня.
# Применяется к объекту класса tk.Toplevel
# """
# def setup_level_two(self, target_window):
1. Минимальный размер окна (спрашиваем у переданного окна)
# width, height = int(target_window.winfo_reqwidth()), int(target_window.winfo_reqheight())
# target_window.minsize(width, height)
2. Разрешаем изменение размера
# target_window.resizable(True, True)
3. Центрирование относительно родителя
# parent = target_window.master
# p_x = parent.winfo_rootx()
# p_y = parent.winfo_rooty()
# p_w = parent.winfo_width()
# p_h = parent.winfo_height()
# win_w = target_window.winfo_reqwidth()
# win_h = target_window.winfo_reqheight()
# x = p_x + (p_w - win_w) // 2
# y = p_y + (p_h - win_h) // 2
# target_window.geometry(f"+{x}+{y}")
4. Сохраняем смещение для синхронного движения
# offset_x = target_window.winfo_rootx() - p_x
# offset_y = target_window.winfo_rooty() - p_y
5. Регистрация у родителя
# if not hasattr(parent, '_child_windows'):
# parent._child_windows = []
# parent.register_child_window(target_window, offset_x, offset_y)
6. Блокировка сворачивания
# target_window.protocol("WM_MINIMIZE_WINDOW", self.do_nothing)
7. Протокол закрытия
# target_window.protocol("WM_DELETE_WINDOW", target_window.destroy)
8. Настройка перетаскивания (биндим события к самому ОКНУ)
# target_window.bind("<ButtonPress-1>", lambda e, tw=target_window: self.save_offset(e, tw))
# target_window.bind("<B1-Motion>", lambda e, tw=target_window: self.drag_with_parent(e, tw, parent))
# def do_nothing(self, event=None):
# pass
# def save_offset(self, event, window):
Запоминаем ГДЕ НА ЭКРАНЕ была нажата мышь
# self._start_screen_x = event.x_root
# self._start_screen_y = event.y_root
Запоминаем, где В ЭТОТ МОМЕНТ было окно (его угол)
# self._start_win_x = window.winfo_rootx()
# self._start_win_y = window.winfo_rooty()
Запоминаем, где был родитель
# parent = window.master
# self._start_parent_x = parent.winfo_rootx()
# self._start_parent_y = parent.winfo_rooty()
# def drag_with_parent(self, event, child_win, parent_win):
Считаем, как далеко уехала мышь от точки клика
# delta_x = event.x_root - self._start_screen_x
# delta_y = event.y_root - self._start_screen_y
Куда должно уехать главное окно?
# target_parent_x = self._start_parent_x + delta_x
# target_parent_y = self._start_parent_y + delta_y
Двигаем родителя
# parent_win.geometry(f"+{target_parent_x}+{target_parent_y}")
Куда должно уехать наше окно?
Оно должно сохранить ту же дистанцию от угла родителя, которая была при старте
# offset_x = self._start_win_x - self._start_parent_x
# offset_y = self._start_win_y - self._start_parent_y
# target_child_x = target_parent_x + offset_x
# target_child_y = target_parent_y + offset_y
# child_win.geometry(f"+{target_child_x}+{target_child_y}")
# class LevelThreeBehavior:
# """
# Поведение окон третьего уровня.
# Применяется к объекту класса tk.Toplevel
# """
# def setup_level_three(self):
1. Минимальный размер
# width, height = int(self.winfo_reqwidth()), int(self.winfo_reqheight())
# self.minsize(width, height)
# self.resizable(True, True)
2. Левый верхний угол независимо от других
# self.geometry("+0+0")
4. Блокировка сворачивания
# self.protocol("WM_MINIMIZE_WINDOW", self.do_nothing)
5. Закрытие
# self.protocol("WM_DELETE_WINDOW", self.destroy)
3. Свободное передвижение
# self.bind("<ButtonPress-1>", self.save_offset)
# self.bind("<B1-Motion>", self.drag_free)
# def do_nothing(self, event=None):
# pass
# def save_offset(self, event):
# self._win_click_x = event.x
# self._win_click_y = event.y
# def drag_free(self, event):
# dx = event.x_root - self._win_click_x
# dy = event.y_root - self._win_click_y
# self.geometry(f"+{dx}+{dy}")