Enable borderless fullscreen window with custom controls
This commit is contained in:
parent
2077d574c3
commit
662f6b4df3
13
app/app.py
13
app/app.py
|
|
@ -21,11 +21,7 @@ class ICRSApp(
|
|||
def __init__(self, root: tk.Tk):
|
||||
self.root = root
|
||||
self.root.title("ICRS — Interactive Color Range Analyzer")
|
||||
try:
|
||||
self.root.state("zoomed")
|
||||
except Exception:
|
||||
pass
|
||||
self.root.configure(bg="#f2f2f7")
|
||||
self._setup_window()
|
||||
|
||||
# Theme and styling
|
||||
self.init_theme()
|
||||
|
|
@ -64,6 +60,13 @@ class ICRSApp(
|
|||
self._init_copy_menu()
|
||||
self.bring_to_front()
|
||||
|
||||
def _setup_window(self) -> None:
|
||||
self.root.overrideredirect(True)
|
||||
screen_width = self.root.winfo_screenwidth()
|
||||
screen_height = self.root.winfo_screenheight()
|
||||
self.root.geometry(f"{screen_width}x{screen_height}+0+0")
|
||||
self.root.configure(bg="#f2f2f7")
|
||||
|
||||
|
||||
def start_app() -> None:
|
||||
"""Entry point used by the CLI script."""
|
||||
|
|
|
|||
|
|
@ -11,8 +11,10 @@ class UIBuilderMixin:
|
|||
"""Constructs the Tkinter UI and common widgets."""
|
||||
|
||||
def setup_ui(self) -> None:
|
||||
self._create_titlebar()
|
||||
|
||||
toolbar = ttk.Frame(self.root)
|
||||
toolbar.pack(fill=tk.X, padx=12, pady=8)
|
||||
toolbar.pack(fill=tk.X, padx=12, pady=0)
|
||||
buttons = [
|
||||
("📂 Bild laden", self.load_image),
|
||||
("📁 Ordner laden", self.load_folder),
|
||||
|
|
@ -71,11 +73,13 @@ class UIBuilderMixin:
|
|||
|
||||
left_column = ttk.Frame(main)
|
||||
left_column.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 6))
|
||||
left_column.grid_columnconfigure(1, weight=1)
|
||||
left_column.grid_rowconfigure(0, weight=1)
|
||||
|
||||
self._create_navigation_button(left_column, "◀", self.show_previous_image)
|
||||
self._create_navigation_button(left_column, "◀", self.show_previous_image, column=0)
|
||||
|
||||
self.canvas_orig = tk.Canvas(left_column, bg="#1e1e1e", highlightthickness=0, relief="flat")
|
||||
self.canvas_orig.pack(fill=tk.BOTH, expand=True)
|
||||
self.canvas_orig.grid(row=0, column=1, sticky="nsew")
|
||||
self.canvas_orig.bind("<Button-1>", self.on_canvas_click)
|
||||
self.canvas_orig.bind("<ButtonPress-3>", self._exclude_start)
|
||||
self.canvas_orig.bind("<B3-Motion>", self._exclude_drag)
|
||||
|
|
@ -83,10 +87,13 @@ class UIBuilderMixin:
|
|||
|
||||
right_column = ttk.Frame(main)
|
||||
right_column.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=(6, 0))
|
||||
right_column.grid_columnconfigure(0, weight=1)
|
||||
right_column.grid_rowconfigure(0, weight=1)
|
||||
|
||||
self.canvas_overlay = tk.Canvas(right_column, bg="#1e1e1e", highlightthickness=0, relief="flat")
|
||||
self.canvas_overlay.pack(fill=tk.BOTH, expand=True)
|
||||
self._create_navigation_button(right_column, "▶", self.show_next_image)
|
||||
self.canvas_overlay.grid(row=0, column=0, sticky="nsew")
|
||||
self._create_navigation_button(right_column, "▶", self.show_next_image, column=1)
|
||||
|
||||
|
||||
info_frame = ttk.Frame(self.root)
|
||||
info_frame.pack(fill=tk.X, padx=12, pady=(0, 12))
|
||||
|
|
@ -113,6 +120,7 @@ class UIBuilderMixin:
|
|||
self._attach_copy_menu(self.ratio_label)
|
||||
|
||||
self.root.bind("<Escape>", self.disable_pick_mode)
|
||||
self.root.bind("<ButtonPress-1>", self._maybe_focus_window)
|
||||
|
||||
def add_slider_with_value(self, parent, text, var, minimum, maximum, column=0):
|
||||
cell = ttk.Frame(parent)
|
||||
|
|
@ -317,24 +325,83 @@ class UIBuilderMixin:
|
|||
]
|
||||
return canvas.create_polygon(points, smooth=True, splinesteps=24, **kwargs)
|
||||
|
||||
def _create_navigation_button(self, container, symbol: str, command) -> None:
|
||||
wrapper = ttk.Frame(container)
|
||||
wrapper.pack(fill=tk.Y)
|
||||
|
||||
def _create_navigation_button(self, container, symbol: str, command, *, column: int) -> None:
|
||||
bg = self.root.cget("bg") if hasattr(self.root, "cget") else "#f2f2f7"
|
||||
container.grid_rowconfigure(0, weight=1)
|
||||
btn = tk.Button(
|
||||
wrapper,
|
||||
container,
|
||||
text=symbol,
|
||||
command=command,
|
||||
font=("Segoe UI", 18, "bold"),
|
||||
font=("Segoe UI", 26, "bold"),
|
||||
relief="flat",
|
||||
borderwidth=0,
|
||||
background="#00000000",
|
||||
activebackground="#00000000",
|
||||
background=bg,
|
||||
activebackground=bg,
|
||||
highlightthickness=0,
|
||||
cursor="hand2",
|
||||
width=2,
|
||||
)
|
||||
btn.pack(side=tk.TOP, pady=12)
|
||||
wrapper.pack_propagate(False)
|
||||
btn.grid(row=0, column=column, sticky="ns", padx=6)
|
||||
|
||||
def _create_titlebar(self) -> None:
|
||||
bar_bg = "#1f1f1f"
|
||||
title_bar = tk.Frame(self.root, bg=bar_bg, relief="flat", height=34)
|
||||
title_bar.pack(fill=tk.X, side=tk.TOP)
|
||||
title_bar.pack_propagate(False)
|
||||
|
||||
title_label = tk.Label(
|
||||
title_bar,
|
||||
text="ICRS — Interactive Color Range Analyzer",
|
||||
bg=bar_bg,
|
||||
fg="#f5f5f5",
|
||||
font=("Segoe UI", 11, "bold"),
|
||||
anchor="w",
|
||||
)
|
||||
title_label.pack(side=tk.LEFT, padx=12)
|
||||
|
||||
close_btn = tk.Button(
|
||||
title_bar,
|
||||
text="✕",
|
||||
command=self._close_app,
|
||||
bg=bar_bg,
|
||||
fg="#f5f5f5",
|
||||
activebackground="#ff3b30",
|
||||
activeforeground="#ffffff",
|
||||
borderwidth=0,
|
||||
highlightthickness=0,
|
||||
relief="flat",
|
||||
font=("Segoe UI", 10, "bold"),
|
||||
cursor="hand2",
|
||||
width=3,
|
||||
)
|
||||
close_btn.pack(side=tk.RIGHT, padx=8, pady=4)
|
||||
|
||||
for widget in (title_bar, title_label):
|
||||
widget.bind("<ButtonPress-1>", self._start_window_drag)
|
||||
widget.bind("<B1-Motion>", self._perform_window_drag)
|
||||
|
||||
def _close_app(self) -> None:
|
||||
try:
|
||||
self.root.destroy()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def _start_window_drag(self, event) -> None:
|
||||
self._drag_offset = (event.x_root - self.root.winfo_rootx(), event.y_root - self.root.winfo_rooty())
|
||||
|
||||
def _perform_window_drag(self, event) -> None:
|
||||
offset = getattr(self, "_drag_offset", None)
|
||||
if offset is None:
|
||||
return
|
||||
x = event.x_root - offset[0]
|
||||
y = event.y_root - offset[1]
|
||||
self.root.geometry(f"+{x}+{y}")
|
||||
|
||||
def _maybe_focus_window(self, _event) -> None:
|
||||
try:
|
||||
self.root.focus_set()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def _toolbar_palette(self) -> dict[str, str]:
|
||||
is_dark = getattr(self, "theme", "light") == "dark"
|
||||
|
|
|
|||
Loading…
Reference in New Issue