add war sar metadata view
This commit is contained in:
parent
93833289fd
commit
c0b40803cf
640
ControlPanel.py
640
ControlPanel.py
File diff suppressed because it is too large
Load Diff
210
ui.py
210
ui.py
@ -10,7 +10,8 @@ Defines the user interface components for the Control Panel application,
|
|||||||
including the main control panel area, status bar, map parameters, info display
|
including the main control panel area, status bar, map parameters, info display
|
||||||
with Google Maps/Earth links, and helper functions for window creation.
|
with Google Maps/Earth links, and helper functions for window creation.
|
||||||
The main ControlPanel frame is designed to be placed within a container managed
|
The main ControlPanel frame is designed to be placed within a container managed
|
||||||
by the main application.
|
by the main application. The metadata display components are now created and
|
||||||
|
managed directly by the main application (ControlPanelApp).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Standard library imports
|
# Standard library imports
|
||||||
@ -20,7 +21,8 @@ from typing import TYPE_CHECKING, Dict, Tuple, Optional
|
|||||||
# Third-party imports
|
# Third-party imports
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from tkinter import ttk
|
from tkinter import ttk
|
||||||
# Import ScrolledText only if needed within this module (currently not)
|
|
||||||
|
# Removed ScrolledText import as it's no longer created here
|
||||||
# from tkinter.scrolledtext import ScrolledText
|
# from tkinter.scrolledtext import ScrolledText
|
||||||
|
|
||||||
# Local application imports
|
# Local application imports
|
||||||
@ -32,12 +34,13 @@ if TYPE_CHECKING:
|
|||||||
from ControlPanel import ControlPanelApp
|
from ControlPanel import ControlPanelApp
|
||||||
|
|
||||||
|
|
||||||
class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
||||||
"""
|
"""
|
||||||
Main control panel frame containing SAR, MFD, Map parameter widgets,
|
Main control panel frame containing SAR, MFD, Map parameter widgets,
|
||||||
information displays, statistics labels, and interaction buttons.
|
information displays, statistics labels, and interaction buttons.
|
||||||
This frame is typically placed in the main application window's container.
|
This frame is typically placed in the main application window's container.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, parent: tk.Widget, app: "ControlPanelApp", *args, **kwargs):
|
def __init__(self, parent: tk.Widget, app: "ControlPanelApp", *args, **kwargs):
|
||||||
"""Initializes the ControlPanel frame."""
|
"""Initializes the ControlPanel frame."""
|
||||||
log_prefix = "[UI Setup]"
|
log_prefix = "[UI Setup]"
|
||||||
@ -57,19 +60,17 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
self.sar_lon_shift_var = tk.StringVar(
|
self.sar_lon_shift_var = tk.StringVar(
|
||||||
value=f"{self.app.state.sar_lon_shift_deg:.6f}"
|
value=f"{self.app.state.sar_lon_shift_deg:.6f}"
|
||||||
)
|
)
|
||||||
self.dropped_stats_var = tk.StringVar(
|
self.dropped_stats_var = tk.StringVar(value="Drop (Q): S=0, M=0, Tk=0, Mo=0")
|
||||||
value="Drop (Q): S=0, M=0, Tk=0, Mo=0"
|
self.incomplete_stats_var = tk.StringVar(value="Incmpl (RX): S=0, M=0")
|
||||||
)
|
# Checkbox variable for metadata toggle (still needed here)
|
||||||
self.incomplete_stats_var = tk.StringVar(
|
self.show_meta_var = tk.BooleanVar(value=self.app.state.display_sar_metadata)
|
||||||
value="Incmpl (RX): S=0, M=0"
|
|
||||||
)
|
|
||||||
|
|
||||||
# --- References to UI widgets ---
|
# --- References to UI widgets ---
|
||||||
self.mfd_color_labels: Dict[str, tk.Label] = {}
|
self.mfd_color_labels: Dict[str, tk.Label] = {}
|
||||||
# References to metadata widgets are REMOVED from here
|
# References to metadata widgets are REMOVED from this class
|
||||||
|
|
||||||
# --- Initialize UI structure ---
|
# --- Initialize UI structure ---
|
||||||
self.init_ui() # Call the UI building method
|
self.init_ui() # Call the UI building method
|
||||||
|
|
||||||
logging.debug(f"{log_prefix} ControlPanel frame initialization complete.")
|
logging.debug(f"{log_prefix} ControlPanel frame initialization complete.")
|
||||||
|
|
||||||
@ -85,7 +86,7 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
self.sar_params_frame = ttk.Labelframe(self, text="SAR Parameters", padding=5)
|
self.sar_params_frame = ttk.Labelframe(self, text="SAR Parameters", padding=5)
|
||||||
self.sar_params_frame.pack(side=tk.TOP, fill=tk.X, padx=5, pady=(5, 2))
|
self.sar_params_frame.pack(side=tk.TOP, fill=tk.X, padx=5, pady=(5, 2))
|
||||||
|
|
||||||
sar_row = 0 # Row counter for SAR grid
|
sar_row = 0 # Row counter for SAR grid
|
||||||
|
|
||||||
# Test Image Checkbox
|
# Test Image Checkbox
|
||||||
self.test_image_var = tk.IntVar(value=1 if config.ENABLE_TEST_MODE else 0)
|
self.test_image_var = tk.IntVar(value=1 if config.ENABLE_TEST_MODE else 0)
|
||||||
@ -100,9 +101,7 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Record SAR Checkbox
|
# Record SAR Checkbox
|
||||||
self.record_sar_var = tk.BooleanVar(
|
self.record_sar_var = tk.BooleanVar(value=config.DEFAULT_SAR_RECORDING_ENABLED)
|
||||||
value=config.DEFAULT_SAR_RECORDING_ENABLED
|
|
||||||
)
|
|
||||||
self.record_sar_check = ttk.Checkbutton(
|
self.record_sar_check = ttk.Checkbutton(
|
||||||
self.sar_params_frame,
|
self.sar_params_frame,
|
||||||
text="Record SAR",
|
text="Record SAR",
|
||||||
@ -126,7 +125,7 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
state="readonly",
|
state="readonly",
|
||||||
width=6,
|
width=6,
|
||||||
)
|
)
|
||||||
try: # Set initial value based on current state
|
try: # Set initial value based on current state
|
||||||
factor = 1
|
factor = 1
|
||||||
if self.app.state.sar_display_width > 0:
|
if self.app.state.sar_display_width > 0:
|
||||||
factor = max(1, config.SAR_WIDTH // self.app.state.sar_display_width)
|
factor = max(1, config.SAR_WIDTH // self.app.state.sar_display_width)
|
||||||
@ -135,7 +134,7 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
self.sar_size_combo.set(sz_str)
|
self.sar_size_combo.set(sz_str)
|
||||||
else:
|
else:
|
||||||
self.sar_size_combo.set(config.DEFAULT_SAR_SIZE)
|
self.sar_size_combo.set(config.DEFAULT_SAR_SIZE)
|
||||||
except Exception: # Fallback to default if error
|
except Exception: # Fallback to default if error
|
||||||
self.sar_size_combo.set(config.DEFAULT_SAR_SIZE)
|
self.sar_size_combo.set(config.DEFAULT_SAR_SIZE)
|
||||||
self.sar_size_combo.grid(
|
self.sar_size_combo.grid(
|
||||||
row=sar_row, column=1, sticky=tk.EW, padx=(0, 10), pady=1
|
row=sar_row, column=1, sticky=tk.EW, padx=(0, 10), pady=1
|
||||||
@ -144,16 +143,14 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
|
|
||||||
# SAR Palette Combobox
|
# SAR Palette Combobox
|
||||||
self.palette_label = ttk.Label(self.sar_params_frame, text="Palette:")
|
self.palette_label = ttk.Label(self.sar_params_frame, text="Palette:")
|
||||||
self.palette_label.grid(
|
self.palette_label.grid(row=sar_row, column=2, sticky=tk.W, padx=(0, 2), pady=1)
|
||||||
row=sar_row, column=2, sticky=tk.W, padx=(0, 2), pady=1
|
|
||||||
)
|
|
||||||
self.palette_combo = ttk.Combobox(
|
self.palette_combo = ttk.Combobox(
|
||||||
self.sar_params_frame,
|
self.sar_params_frame,
|
||||||
values=config.COLOR_PALETTES,
|
values=config.COLOR_PALETTES,
|
||||||
state="readonly",
|
state="readonly",
|
||||||
width=8,
|
width=8,
|
||||||
)
|
)
|
||||||
self.palette_combo.set(self.app.state.sar_palette) # Set from state
|
self.palette_combo.set(self.app.state.sar_palette) # Set from state
|
||||||
self.palette_combo.grid(
|
self.palette_combo.grid(
|
||||||
row=sar_row, column=3, sticky=tk.EW, padx=(0, 5), pady=1
|
row=sar_row, column=3, sticky=tk.EW, padx=(0, 5), pady=1
|
||||||
)
|
)
|
||||||
@ -171,7 +168,7 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
orient=tk.HORIZONTAL,
|
orient=tk.HORIZONTAL,
|
||||||
from_=0.1,
|
from_=0.1,
|
||||||
to=3.0,
|
to=3.0,
|
||||||
value=self.app.state.sar_contrast, # Set from state
|
value=self.app.state.sar_contrast, # Set from state
|
||||||
command=self.app.update_contrast,
|
command=self.app.update_contrast,
|
||||||
)
|
)
|
||||||
self.contrast_scale.grid(
|
self.contrast_scale.grid(
|
||||||
@ -188,42 +185,48 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
orient=tk.HORIZONTAL,
|
orient=tk.HORIZONTAL,
|
||||||
from_=-100,
|
from_=-100,
|
||||||
to=100,
|
to=100,
|
||||||
value=self.app.state.sar_brightness, # Set from state
|
value=self.app.state.sar_brightness, # Set from state
|
||||||
command=self.app.update_brightness,
|
command=self.app.update_brightness,
|
||||||
)
|
)
|
||||||
self.brightness_scale.grid(
|
self.brightness_scale.grid(
|
||||||
row=sar_row, column=3, sticky=tk.EW, padx=(0, 5), pady=1
|
row=sar_row, column=3, sticky=tk.EW, padx=(0, 5), pady=1
|
||||||
)
|
)
|
||||||
|
|
||||||
# SAR Metadata Checkbox
|
# SAR Metadata Checkbox (Still created here as it belongs logically with SAR params)
|
||||||
sar_row += 1
|
sar_row += 1
|
||||||
self.show_meta_var = tk.BooleanVar(value=self.app.state.display_sar_metadata)
|
# self.show_meta_var is already created in __init__
|
||||||
self.show_meta_check = ttk.Checkbutton(
|
self.show_meta_check = ttk.Checkbutton(
|
||||||
self.sar_params_frame,
|
self.sar_params_frame,
|
||||||
text="Show SAR Metadata",
|
text="Show SAR Metadata",
|
||||||
variable=self.show_meta_var,
|
variable=self.show_meta_var,
|
||||||
command=self.app.toggle_sar_metadata_display # Link to app callback
|
command=self.app.toggle_sar_metadata_display, # Link to app callback
|
||||||
)
|
)
|
||||||
self.show_meta_check.grid(
|
self.show_meta_check.grid(
|
||||||
row=sar_row, column=0, columnspan=4, sticky=tk.W, padx=5, pady=(5, 2)
|
row=sar_row, column=0, columnspan=4, sticky=tk.W, padx=5, pady=(5, 2)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Configure SAR frame column weights
|
# Configure SAR frame column weights
|
||||||
self.sar_params_frame.columnconfigure(1, weight=1) # Allow sliders to expand
|
self.sar_params_frame.columnconfigure(1, weight=1) # Allow sliders to expand
|
||||||
self.sar_params_frame.columnconfigure(3, weight=1)
|
self.sar_params_frame.columnconfigure(3, weight=1)
|
||||||
|
|
||||||
# --- 2. MFD Parameters Frame ---
|
# --- 2. MFD Parameters Frame ---
|
||||||
self.mfd_params_frame = ttk.Labelframe(self, text="MFD Parameters", padding=5)
|
self.mfd_params_frame = ttk.Labelframe(self, text="MFD Parameters", padding=5)
|
||||||
self.mfd_params_frame.pack(side=tk.TOP, fill=tk.X, padx=5, pady=2)
|
self.mfd_params_frame.pack(side=tk.TOP, fill=tk.X, padx=5, pady=2)
|
||||||
|
|
||||||
mfd_categories_ordered = [ # Order for display
|
mfd_categories_ordered = [
|
||||||
"Occlusion", "Cat A", "Cat B", "Cat C", "Cat C1", "Cat C2", "Cat C3",
|
"Occlusion",
|
||||||
|
"Cat A",
|
||||||
|
"Cat B",
|
||||||
|
"Cat C",
|
||||||
|
"Cat C1",
|
||||||
|
"Cat C2",
|
||||||
|
"Cat C3",
|
||||||
]
|
]
|
||||||
num_categories = len(mfd_categories_ordered)
|
num_categories = len(mfd_categories_ordered)
|
||||||
|
|
||||||
for index, name in enumerate(mfd_categories_ordered):
|
for index, name in enumerate(mfd_categories_ordered):
|
||||||
row = index // 2 # Two categories per row
|
row = index // 2
|
||||||
col_offset = 0 if (index % 2 == 0) else 4 # Offset for second column
|
col_offset = 0 if (index % 2 == 0) else 4
|
||||||
|
|
||||||
# Category Label
|
# Category Label
|
||||||
cat_label = ttk.Label(self.mfd_params_frame, text=f"{name}:")
|
cat_label = ttk.Label(self.mfd_params_frame, text=f"{name}:")
|
||||||
@ -233,12 +236,12 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
|
|
||||||
# Intensity Slider Variable and Widget
|
# Intensity Slider Variable and Widget
|
||||||
intensity_var = tk.IntVar(value=config.DEFAULT_MFD_INTENSITY)
|
intensity_var = tk.IntVar(value=config.DEFAULT_MFD_INTENSITY)
|
||||||
try: # Set initial value from state
|
try:
|
||||||
intensity_var.set(
|
intensity_var.set(
|
||||||
self.app.state.mfd_params["categories"][name]["intensity"]
|
self.app.state.mfd_params["categories"][name]["intensity"]
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass # Ignore if state not ready or key missing
|
pass
|
||||||
intensity_scale = ttk.Scale(
|
intensity_scale = ttk.Scale(
|
||||||
self.mfd_params_frame,
|
self.mfd_params_frame,
|
||||||
orient=tk.HORIZONTAL,
|
orient=tk.HORIZONTAL,
|
||||||
@ -246,7 +249,6 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
from_=0,
|
from_=0,
|
||||||
to=255,
|
to=255,
|
||||||
variable=intensity_var,
|
variable=intensity_var,
|
||||||
# Use lambda to pass name and var correctly to callback
|
|
||||||
command=lambda v, n=name, var=intensity_var: (
|
command=lambda v, n=name, var=intensity_var: (
|
||||||
self.app.update_mfd_category_intensity(n, var.get())
|
self.app.update_mfd_category_intensity(n, var.get())
|
||||||
),
|
),
|
||||||
@ -268,41 +270,39 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
|
|
||||||
# Color Preview Label
|
# Color Preview Label
|
||||||
color_label = tk.Label(
|
color_label = tk.Label(
|
||||||
self.mfd_params_frame,
|
self.mfd_params_frame, text="", width=3, relief=tk.SUNKEN, borderwidth=1
|
||||||
text="",
|
|
||||||
width=3,
|
|
||||||
relief=tk.SUNKEN,
|
|
||||||
borderwidth=1
|
|
||||||
)
|
)
|
||||||
try: # Set initial color from state
|
try:
|
||||||
bgr = self.app.state.mfd_params["categories"][name]["color"]
|
bgr = self.app.state.mfd_params["categories"][name]["color"]
|
||||||
hex_color = f"#{bgr[2]:02x}{bgr[1]:02x}{bgr[0]:02x}"
|
hex_color = f"#{bgr[2]:02x}{bgr[1]:02x}{bgr[0]:02x}"
|
||||||
color_label.config(background=hex_color)
|
color_label.config(background=hex_color)
|
||||||
except Exception:
|
except Exception:
|
||||||
color_label.config(background="grey") # Fallback
|
color_label.config(background="grey")
|
||||||
color_label.grid(
|
color_label.grid(
|
||||||
row=row, column=3 + col_offset, sticky=tk.W, padx=(1, 5), pady=1
|
row=row, column=3 + col_offset, sticky=tk.W, padx=(1, 5), pady=1
|
||||||
)
|
)
|
||||||
self.mfd_color_labels[name] = color_label # Store label reference
|
self.mfd_color_labels[name] = color_label
|
||||||
|
|
||||||
# Raw Map Intensity Slider
|
# Raw Map Intensity Slider
|
||||||
last_cat_row = (num_categories - 1) // 2
|
last_cat_row = (num_categories - 1) // 2
|
||||||
# Determine position based on number of categories
|
|
||||||
raw_map_col_offset = 4 if (num_categories % 2 != 0) else 0
|
raw_map_col_offset = 4 if (num_categories % 2 != 0) else 0
|
||||||
raw_map_row = last_cat_row if (num_categories % 2 != 0) else last_cat_row + 1
|
raw_map_row = last_cat_row if (num_categories % 2 != 0) else last_cat_row + 1
|
||||||
|
|
||||||
raw_map_label = ttk.Label(self.mfd_params_frame, text="Raw Map:")
|
raw_map_label = ttk.Label(self.mfd_params_frame, text="Raw Map:")
|
||||||
raw_map_label.grid(
|
raw_map_label.grid(
|
||||||
row=raw_map_row, column=0 + raw_map_col_offset, sticky=tk.W, padx=(5, 1), pady=1
|
row=raw_map_row,
|
||||||
|
column=0 + raw_map_col_offset,
|
||||||
|
sticky=tk.W,
|
||||||
|
padx=(5, 1),
|
||||||
|
pady=1,
|
||||||
)
|
)
|
||||||
|
|
||||||
raw_map_intensity_var = tk.IntVar(value=config.DEFAULT_MFD_RAW_MAP_INTENSITY)
|
raw_map_intensity_var = tk.IntVar(value=config.DEFAULT_MFD_RAW_MAP_INTENSITY)
|
||||||
try: # Set initial value from state
|
try:
|
||||||
raw_map_intensity_var.set(self.app.state.mfd_params["raw_map_intensity"])
|
raw_map_intensity_var.set(self.app.state.mfd_params["raw_map_intensity"])
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
# Store var reference if needed elsewhere
|
self.mfd_raw_map_intensity_var = raw_map_intensity_var # Keep reference
|
||||||
self.mfd_raw_map_intensity_var = raw_map_intensity_var
|
|
||||||
|
|
||||||
raw_map_scale = ttk.Scale(
|
raw_map_scale = ttk.Scale(
|
||||||
self.mfd_params_frame,
|
self.mfd_params_frame,
|
||||||
@ -318,20 +318,20 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
raw_map_scale.grid(
|
raw_map_scale.grid(
|
||||||
row=raw_map_row,
|
row=raw_map_row,
|
||||||
column=1 + raw_map_col_offset,
|
column=1 + raw_map_col_offset,
|
||||||
columnspan=3, # Span 3 cols after label
|
columnspan=3,
|
||||||
sticky=tk.EW,
|
sticky=tk.EW,
|
||||||
padx=(1, 5),
|
padx=(1, 5),
|
||||||
pady=1,
|
pady=1,
|
||||||
)
|
)
|
||||||
# Configure MFD frame column weights
|
# Configure MFD frame column weights
|
||||||
self.mfd_params_frame.columnconfigure(1, weight=1) # Allow sliders to expand
|
self.mfd_params_frame.columnconfigure(1, weight=1)
|
||||||
self.mfd_params_frame.columnconfigure(5, weight=1) # Allow sliders on right
|
self.mfd_params_frame.columnconfigure(5, weight=1)
|
||||||
|
|
||||||
# --- 3. Map Parameters Frame ---
|
# --- 3. Map Parameters Frame ---
|
||||||
self.map_params_frame = ttk.Labelframe(self, text="Map Parameters", padding=5)
|
self.map_params_frame = ttk.Labelframe(self, text="Map Parameters", padding=5)
|
||||||
self.map_params_frame.pack(side=tk.TOP, fill=tk.X, padx=5, pady=2)
|
self.map_params_frame.pack(side=tk.TOP, fill=tk.X, padx=5, pady=2)
|
||||||
|
|
||||||
map_row = 0 # Row counter for Map grid
|
map_row = 0 # Row counter for Map grid
|
||||||
|
|
||||||
# Map Size Combobox
|
# Map Size Combobox
|
||||||
self.map_size_label = ttk.Label(self.map_params_frame, text="Map Display Size:")
|
self.map_size_label = ttk.Label(self.map_params_frame, text="Map Display Size:")
|
||||||
@ -342,9 +342,9 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
self.map_params_frame,
|
self.map_params_frame,
|
||||||
values=config.MAP_SIZE_FACTORS,
|
values=config.MAP_SIZE_FACTORS,
|
||||||
state="readonly",
|
state="readonly",
|
||||||
width=6
|
width=6,
|
||||||
)
|
)
|
||||||
self.map_size_combo.set(config.DEFAULT_MAP_SIZE) # Set default initially
|
self.map_size_combo.set(config.DEFAULT_MAP_SIZE)
|
||||||
self.map_size_combo.grid(
|
self.map_size_combo.grid(
|
||||||
row=map_row, column=1, sticky=tk.EW, padx=(2, 10), pady=1
|
row=map_row, column=1, sticky=tk.EW, padx=(2, 10), pady=1
|
||||||
)
|
)
|
||||||
@ -354,7 +354,7 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
self.save_map_button = ttk.Button(
|
self.save_map_button = ttk.Button(
|
||||||
self.map_params_frame,
|
self.map_params_frame,
|
||||||
text="Save Map View",
|
text="Save Map View",
|
||||||
command=self.app.save_current_map_view
|
command=self.app.save_current_map_view,
|
||||||
)
|
)
|
||||||
self.save_map_button.grid(
|
self.save_map_button.grid(
|
||||||
row=map_row, column=2, columnspan=4, sticky=tk.E, padx=5, pady=1
|
row=map_row, column=2, columnspan=4, sticky=tk.E, padx=5, pady=1
|
||||||
@ -380,9 +380,7 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
|
|
||||||
# SAR Overlay Alpha Slider
|
# SAR Overlay Alpha Slider
|
||||||
self.alpha_label = ttk.Label(self.map_params_frame, text="SAR Overlay Alpha:")
|
self.alpha_label = ttk.Label(self.map_params_frame, text="SAR Overlay Alpha:")
|
||||||
self.alpha_label.grid(
|
self.alpha_label.grid(row=map_row, column=0, sticky=tk.W, padx=(5, 2), pady=1)
|
||||||
row=map_row, column=0, sticky=tk.W, padx=(5, 2), pady=1
|
|
||||||
)
|
|
||||||
self.sar_overlay_alpha_var = tk.DoubleVar(
|
self.sar_overlay_alpha_var = tk.DoubleVar(
|
||||||
value=self.app.state.map_sar_overlay_alpha
|
value=self.app.state.map_sar_overlay_alpha
|
||||||
)
|
)
|
||||||
@ -393,7 +391,6 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
to=1.0,
|
to=1.0,
|
||||||
variable=self.sar_overlay_alpha_var,
|
variable=self.sar_overlay_alpha_var,
|
||||||
)
|
)
|
||||||
# Trigger update only on release for performance
|
|
||||||
self.alpha_scale.bind("<ButtonRelease-1>", self.app.on_alpha_slider_release)
|
self.alpha_scale.bind("<ButtonRelease-1>", self.app.on_alpha_slider_release)
|
||||||
self.alpha_scale.grid(
|
self.alpha_scale.grid(
|
||||||
row=map_row, column=1, columnspan=5, sticky=tk.EW, padx=(0, 5), pady=1
|
row=map_row, column=1, columnspan=5, sticky=tk.EW, padx=(0, 5), pady=1
|
||||||
@ -403,51 +400,42 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
|
|
||||||
# SAR Shift Inputs and Apply Button
|
# SAR Shift Inputs and Apply Button
|
||||||
shift_label = ttk.Label(self.map_params_frame, text="SAR Shift (deg):")
|
shift_label = ttk.Label(self.map_params_frame, text="SAR Shift (deg):")
|
||||||
shift_label.grid(
|
shift_label.grid(row=map_row, column=0, sticky=tk.W, padx=(5, 2), pady=1)
|
||||||
row=map_row, column=0, sticky=tk.W, padx=(5, 2), pady=1
|
|
||||||
)
|
|
||||||
|
|
||||||
lat_label = ttk.Label(self.map_params_frame, text="Lat:")
|
lat_label = ttk.Label(self.map_params_frame, text="Lat:")
|
||||||
lat_label.grid(row=map_row, column=1, sticky=tk.W, padx=(0, 0), pady=1)
|
lat_label.grid(row=map_row, column=1, sticky=tk.W, padx=(0, 0), pady=1)
|
||||||
self.lat_shift_entry = ttk.Entry(
|
self.lat_shift_entry = ttk.Entry(
|
||||||
self.map_params_frame,
|
self.map_params_frame, textvariable=self.sar_lat_shift_var, width=10
|
||||||
textvariable=self.sar_lat_shift_var,
|
|
||||||
width=10
|
|
||||||
)
|
)
|
||||||
self.lat_shift_entry.grid(
|
self.lat_shift_entry.grid(
|
||||||
row=map_row, column=2, sticky=tk.W, padx=(0, 5), pady=1
|
row=map_row, column=2, sticky=tk.W, padx=(0, 5), pady=1
|
||||||
)
|
)
|
||||||
|
|
||||||
lon_label = ttk.Label(self.map_params_frame, text="Lon:")
|
lon_label = ttk.Label(self.map_params_frame, text="Lon:")
|
||||||
lon_label.grid(row=map_row, column=3, sticky=tk.W, padx=(5, 0), pady=1)
|
lon_label.grid(row=map_row, column=3, sticky=tk.W, padx=(5, 0), pady=1)
|
||||||
self.lon_shift_entry = ttk.Entry(
|
self.lon_shift_entry = ttk.Entry(
|
||||||
self.map_params_frame,
|
self.map_params_frame, textvariable=self.sar_lon_shift_var, width=10
|
||||||
textvariable=self.sar_lon_shift_var,
|
|
||||||
width=10
|
|
||||||
)
|
)
|
||||||
self.lon_shift_entry.grid(
|
self.lon_shift_entry.grid(
|
||||||
row=map_row, column=4, sticky=tk.W, padx=(0, 5), pady=1
|
row=map_row, column=4, sticky=tk.W, padx=(0, 5), pady=1
|
||||||
)
|
)
|
||||||
|
|
||||||
self.apply_shift_button = ttk.Button(
|
self.apply_shift_button = ttk.Button(
|
||||||
self.map_params_frame,
|
self.map_params_frame,
|
||||||
text="Apply Shift",
|
text="Apply Shift",
|
||||||
command=self.app.apply_sar_overlay_shift
|
command=self.app.apply_sar_overlay_shift,
|
||||||
)
|
)
|
||||||
self.apply_shift_button.grid(
|
self.apply_shift_button.grid(
|
||||||
row=map_row, column=5, sticky=tk.E, padx=(5, 5), pady=1
|
row=map_row, column=5, sticky=tk.E, padx=(5, 5), pady=1
|
||||||
)
|
)
|
||||||
|
|
||||||
# Configure Map frame column weights
|
# Configure Map frame column weights
|
||||||
self.map_params_frame.columnconfigure(2, weight=1) # Allow Lat entry expand
|
self.map_params_frame.columnconfigure(2, weight=1)
|
||||||
self.map_params_frame.columnconfigure(4, weight=1) # Allow Lon entry expand
|
self.map_params_frame.columnconfigure(4, weight=1)
|
||||||
|
|
||||||
# --- 4. Info Display Frame ---
|
# --- 4. Info Display Frame ---
|
||||||
self.info_display_frame = ttk.Labelframe(self, text="Info Display", padding=5)
|
self.info_display_frame = ttk.Labelframe(self, text="Info Display", padding=5)
|
||||||
self.info_display_frame.pack(side=tk.TOP, fill=tk.X, padx=5, pady=2)
|
self.info_display_frame.pack(side=tk.TOP, fill=tk.X, padx=5, pady=2)
|
||||||
|
|
||||||
info_row = 0 # Row counter for Info grid
|
info_row = 0 # Row counter for Info grid
|
||||||
button_width = 3 # Standard width for Go/GE buttons
|
button_width = 3 # Standard width for Go/GE buttons
|
||||||
|
|
||||||
# --- Row 0: SAR Center Coords ---
|
# --- Row 0: SAR Center Coords ---
|
||||||
ref_label = ttk.Label(self.info_display_frame, text="SAR Center:")
|
ref_label = ttk.Label(self.info_display_frame, text="SAR Center:")
|
||||||
@ -456,7 +444,7 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
self.info_display_frame,
|
self.info_display_frame,
|
||||||
textvariable=self.sar_center_coords_var,
|
textvariable=self.sar_center_coords_var,
|
||||||
state="readonly",
|
state="readonly",
|
||||||
width=35
|
width=35,
|
||||||
)
|
)
|
||||||
self.sar_center_entry.grid(
|
self.sar_center_entry.grid(
|
||||||
row=info_row, column=1, columnspan=3, sticky=tk.EW, padx=(0, 2), pady=1
|
row=info_row, column=1, columnspan=3, sticky=tk.EW, padx=(0, 2), pady=1
|
||||||
@ -465,7 +453,7 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
self.info_display_frame,
|
self.info_display_frame,
|
||||||
text="Go",
|
text="Go",
|
||||||
width=button_width,
|
width=button_width,
|
||||||
command=lambda: self.app.go_to_google_maps("sar_center")
|
command=lambda: self.app.go_to_google_maps("sar_center"),
|
||||||
)
|
)
|
||||||
self.ref_gmaps_button.grid(
|
self.ref_gmaps_button.grid(
|
||||||
row=info_row, column=4, sticky=tk.E, padx=(0, 1), pady=1
|
row=info_row, column=4, sticky=tk.E, padx=(0, 1), pady=1
|
||||||
@ -474,7 +462,7 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
self.info_display_frame,
|
self.info_display_frame,
|
||||||
text="GE",
|
text="GE",
|
||||||
width=button_width,
|
width=button_width,
|
||||||
command=lambda: self.app.go_to_google_earth("sar_center")
|
command=lambda: self.app.go_to_google_earth("sar_center"),
|
||||||
)
|
)
|
||||||
self.ref_gearth_button.grid(
|
self.ref_gearth_button.grid(
|
||||||
row=info_row, column=5, sticky=tk.E, padx=(0, 5), pady=1
|
row=info_row, column=5, sticky=tk.E, padx=(0, 5), pady=1
|
||||||
@ -488,20 +476,18 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
self.info_display_frame,
|
self.info_display_frame,
|
||||||
textvariable=self.sar_orientation_var,
|
textvariable=self.sar_orientation_var,
|
||||||
state="readonly",
|
state="readonly",
|
||||||
width=15
|
width=15,
|
||||||
)
|
)
|
||||||
self.sar_orientation_entry.grid(
|
self.sar_orientation_entry.grid(
|
||||||
row=info_row, column=1, sticky=tk.EW, padx=(0, 5), pady=1
|
row=info_row, column=1, sticky=tk.EW, padx=(0, 5), pady=1
|
||||||
)
|
)
|
||||||
size_label = ttk.Label(self.info_display_frame, text="Image Size:")
|
size_label = ttk.Label(self.info_display_frame, text="Image Size:")
|
||||||
size_label.grid(
|
size_label.grid(row=info_row, column=2, sticky=tk.W, padx=(10, 2), pady=1)
|
||||||
row=info_row, column=2, sticky=tk.W, padx=(10, 2), pady=1
|
|
||||||
)
|
|
||||||
self.sar_size_entry = ttk.Entry(
|
self.sar_size_entry = ttk.Entry(
|
||||||
self.info_display_frame,
|
self.info_display_frame,
|
||||||
textvariable=self.sar_size_km_var,
|
textvariable=self.sar_size_km_var,
|
||||||
state="readonly",
|
state="readonly",
|
||||||
width=25
|
width=25,
|
||||||
)
|
)
|
||||||
self.sar_size_entry.grid(
|
self.sar_size_entry.grid(
|
||||||
row=info_row, column=3, columnspan=3, sticky=tk.EW, padx=(0, 5), pady=1
|
row=info_row, column=3, columnspan=3, sticky=tk.EW, padx=(0, 5), pady=1
|
||||||
@ -515,7 +501,7 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
self.info_display_frame,
|
self.info_display_frame,
|
||||||
textvariable=self.mouse_coords_var,
|
textvariable=self.mouse_coords_var,
|
||||||
state="readonly",
|
state="readonly",
|
||||||
width=35
|
width=35,
|
||||||
)
|
)
|
||||||
self.mouse_latlon_entry.grid(
|
self.mouse_latlon_entry.grid(
|
||||||
row=info_row, column=1, columnspan=3, sticky=tk.EW, padx=(0, 2), pady=1
|
row=info_row, column=1, columnspan=3, sticky=tk.EW, padx=(0, 2), pady=1
|
||||||
@ -524,7 +510,7 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
self.info_display_frame,
|
self.info_display_frame,
|
||||||
text="Go",
|
text="Go",
|
||||||
width=button_width,
|
width=button_width,
|
||||||
command=lambda: self.app.go_to_google_maps("sar_mouse")
|
command=lambda: self.app.go_to_google_maps("sar_mouse"),
|
||||||
)
|
)
|
||||||
self.sar_mouse_gmaps_button.grid(
|
self.sar_mouse_gmaps_button.grid(
|
||||||
row=info_row, column=4, sticky=tk.E, padx=(0, 1), pady=1
|
row=info_row, column=4, sticky=tk.E, padx=(0, 1), pady=1
|
||||||
@ -533,7 +519,7 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
self.info_display_frame,
|
self.info_display_frame,
|
||||||
text="GE",
|
text="GE",
|
||||||
width=button_width,
|
width=button_width,
|
||||||
command=lambda: self.app.go_to_google_earth("sar_mouse")
|
command=lambda: self.app.go_to_google_earth("sar_mouse"),
|
||||||
)
|
)
|
||||||
self.sar_mouse_gearth_button.grid(
|
self.sar_mouse_gearth_button.grid(
|
||||||
row=info_row, column=5, sticky=tk.E, padx=(0, 5), pady=1
|
row=info_row, column=5, sticky=tk.E, padx=(0, 5), pady=1
|
||||||
@ -547,7 +533,7 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
self.info_display_frame,
|
self.info_display_frame,
|
||||||
textvariable=self.map_mouse_coords_var,
|
textvariable=self.map_mouse_coords_var,
|
||||||
state="readonly",
|
state="readonly",
|
||||||
width=35
|
width=35,
|
||||||
)
|
)
|
||||||
self.map_mouse_latlon_entry.grid(
|
self.map_mouse_latlon_entry.grid(
|
||||||
row=info_row, column=1, columnspan=3, sticky=tk.EW, padx=(0, 2), pady=1
|
row=info_row, column=1, columnspan=3, sticky=tk.EW, padx=(0, 2), pady=1
|
||||||
@ -556,7 +542,7 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
self.info_display_frame,
|
self.info_display_frame,
|
||||||
text="Go",
|
text="Go",
|
||||||
width=button_width,
|
width=button_width,
|
||||||
command=lambda: self.app.go_to_google_maps("map_mouse")
|
command=lambda: self.app.go_to_google_maps("map_mouse"),
|
||||||
)
|
)
|
||||||
self.map_mouse_gmaps_button.grid(
|
self.map_mouse_gmaps_button.grid(
|
||||||
row=info_row, column=4, sticky=tk.E, padx=(0, 1), pady=1
|
row=info_row, column=4, sticky=tk.E, padx=(0, 1), pady=1
|
||||||
@ -565,7 +551,7 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
self.info_display_frame,
|
self.info_display_frame,
|
||||||
text="GE",
|
text="GE",
|
||||||
width=button_width,
|
width=button_width,
|
||||||
command=lambda: self.app.go_to_google_earth("map_mouse")
|
command=lambda: self.app.go_to_google_earth("map_mouse"),
|
||||||
)
|
)
|
||||||
self.map_mouse_gearth_button.grid(
|
self.map_mouse_gearth_button.grid(
|
||||||
row=info_row, column=5, sticky=tk.E, padx=(0, 5), pady=1
|
row=info_row, column=5, sticky=tk.E, padx=(0, 5), pady=1
|
||||||
@ -574,14 +560,12 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
|
|
||||||
# --- Row 4: Drop & Incomplete Stats ---
|
# --- Row 4: Drop & Incomplete Stats ---
|
||||||
dropped_label_text = ttk.Label(self.info_display_frame, text="Stats Drop:")
|
dropped_label_text = ttk.Label(self.info_display_frame, text="Stats Drop:")
|
||||||
dropped_label_text.grid(
|
dropped_label_text.grid(row=info_row, column=0, sticky=tk.W, padx=5, pady=1)
|
||||||
row=info_row, column=0, sticky=tk.W, padx=5, pady=1
|
|
||||||
)
|
|
||||||
self.dropped_entry = ttk.Entry(
|
self.dropped_entry = ttk.Entry(
|
||||||
self.info_display_frame,
|
self.info_display_frame,
|
||||||
textvariable=self.dropped_stats_var,
|
textvariable=self.dropped_stats_var,
|
||||||
state="readonly",
|
state="readonly",
|
||||||
width=30
|
width=30,
|
||||||
)
|
)
|
||||||
self.dropped_entry.grid(
|
self.dropped_entry.grid(
|
||||||
row=info_row, column=1, sticky=tk.EW, padx=(0, 5), pady=1
|
row=info_row, column=1, sticky=tk.EW, padx=(0, 5), pady=1
|
||||||
@ -594,7 +578,7 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
self.info_display_frame,
|
self.info_display_frame,
|
||||||
textvariable=self.incomplete_stats_var,
|
textvariable=self.incomplete_stats_var,
|
||||||
state="readonly",
|
state="readonly",
|
||||||
width=15
|
width=15,
|
||||||
)
|
)
|
||||||
self.incomplete_entry.grid(
|
self.incomplete_entry.grid(
|
||||||
row=info_row, column=3, columnspan=3, sticky=tk.EW, padx=(0, 5), pady=1
|
row=info_row, column=3, columnspan=3, sticky=tk.EW, padx=(0, 5), pady=1
|
||||||
@ -603,33 +587,25 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
|
|
||||||
# --- Row 5: "GE All" Button ---
|
# --- Row 5: "GE All" Button ---
|
||||||
self.ge_all_button = ttk.Button(
|
self.ge_all_button = ttk.Button(
|
||||||
self.info_display_frame,
|
self.info_display_frame, text="GE All", command=self.app.go_to_all_gearth
|
||||||
text="GE All",
|
|
||||||
command=self.app.go_to_all_gearth # Link to app callback
|
|
||||||
)
|
)
|
||||||
self.ge_all_button.grid(
|
self.ge_all_button.grid(
|
||||||
row=info_row,
|
row=info_row, column=0, columnspan=6, sticky=tk.EW, padx=5, pady=(5, 5)
|
||||||
column=0, # Start column 0
|
|
||||||
columnspan=6, # Span all 6 columns
|
|
||||||
sticky=tk.EW, # Expand horizontally
|
|
||||||
padx=5,
|
|
||||||
pady=(5, 5) # Padding top and bottom
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Configure column weights for Info Display frame
|
# Configure column weights for Info Display frame
|
||||||
self.info_display_frame.columnconfigure(1, weight=1) # Entry column
|
self.info_display_frame.columnconfigure(1, weight=1) # Entry column
|
||||||
self.info_display_frame.columnconfigure(3, weight=1) # Entry column
|
self.info_display_frame.columnconfigure(3, weight=1) # Entry column
|
||||||
self.info_display_frame.columnconfigure(4, weight=0) # Button Go
|
self.info_display_frame.columnconfigure(4, weight=0) # Button Go
|
||||||
self.info_display_frame.columnconfigure(5, weight=0) # Button GE
|
self.info_display_frame.columnconfigure(5, weight=0) # Button GE
|
||||||
logging.debug(f"{log_prefix} Info Display frame created.")
|
logging.debug(f"{log_prefix} Info Display frame created.")
|
||||||
|
|
||||||
# --- 5. Metadata Display Frame (Creation REMOVED from here) ---
|
# --- 5. Metadata Display Frame (Creation REMOVED from here) ---
|
||||||
# The structure is now created in ControlPanelApp.__init__
|
# This is now created and managed in ControlPanelApp
|
||||||
|
|
||||||
# --- End of init_ui ---
|
# --- End of init_ui ---
|
||||||
logging.debug(f"{log_prefix} init_ui widget creation complete.")
|
logging.debug(f"{log_prefix} init_ui widget creation complete.")
|
||||||
|
|
||||||
|
|
||||||
# --- UI Update Methods ---
|
# --- UI Update Methods ---
|
||||||
def set_sar_center_coords(self, latitude_str: str, longitude_str: str):
|
def set_sar_center_coords(self, latitude_str: str, longitude_str: str):
|
||||||
"""Updates the SAR Center coordinates display."""
|
"""Updates the SAR Center coordinates display."""
|
||||||
@ -698,6 +674,7 @@ class ControlPanel(ttk.Frame): # This is the main panel holding user controls
|
|||||||
f"[UI Update] Error updating MFD color for {category_name}: {e}"
|
f"[UI Update] Error updating MFD color for {category_name}: {e}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# --- StatusBar Class ---
|
# --- StatusBar Class ---
|
||||||
class StatusBar(ttk.Label):
|
class StatusBar(ttk.Label):
|
||||||
"""Represents the status bar at the bottom of the main window."""
|
"""Represents the status bar at the bottom of the main window."""
|
||||||
@ -709,10 +686,10 @@ class StatusBar(ttk.Label):
|
|||||||
parent,
|
parent,
|
||||||
text=config.INITIAL_STATUS_MESSAGE,
|
text=config.INITIAL_STATUS_MESSAGE,
|
||||||
relief=tk.SUNKEN,
|
relief=tk.SUNKEN,
|
||||||
anchor=tk.W, # Anchor text to the West (left)
|
anchor=tk.W, # Anchor text to the West (left)
|
||||||
padding=(5, 2), # Add some internal padding
|
padding=(5, 2), # Add some internal padding
|
||||||
*args,
|
*args,
|
||||||
**kwargs
|
**kwargs,
|
||||||
)
|
)
|
||||||
# Packed by the main application layout manager
|
# Packed by the main application layout manager
|
||||||
|
|
||||||
@ -726,6 +703,7 @@ class StatusBar(ttk.Label):
|
|||||||
# Ignore errors during status update, especially during shutdown
|
# Ignore errors during status update, especially during shutdown
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
# --- Window Creation Helper ---
|
# --- Window Creation Helper ---
|
||||||
def create_main_window(
|
def create_main_window(
|
||||||
title: str, min_width: int, min_height: int, x_pos: int, y_pos: int
|
title: str, min_width: int, min_height: int, x_pos: int, y_pos: int
|
||||||
@ -740,9 +718,10 @@ def create_main_window(
|
|||||||
# Set minimum size constraint
|
# Set minimum size constraint
|
||||||
root.minsize(min_width, min_height)
|
root.minsize(min_width, min_height)
|
||||||
# Set initial position (may be overridden by OS window manager)
|
# Set initial position (may be overridden by OS window manager)
|
||||||
|
# This is less critical now as the app constructor sets the final position
|
||||||
root.geometry(f"+{x_pos}+{y_pos}")
|
root.geometry(f"+{x_pos}+{y_pos}")
|
||||||
logging.debug(
|
logging.debug(
|
||||||
f"{log_prefix} Main Tkinter root window created (requested pos: {x_pos},{y_pos})."
|
f"{log_prefix} Main Tkinter root window created (initial requested pos: {x_pos},{y_pos})."
|
||||||
)
|
)
|
||||||
return root
|
return root
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -752,4 +731,5 @@ def create_main_window(
|
|||||||
# Re-raise the exception to halt execution if window creation fails
|
# Re-raise the exception to halt execution if window creation fails
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
# --- END OF FILE ui.py ---
|
# --- END OF FILE ui.py ---
|
||||||
Loading…
Reference in New Issue
Block a user