feat: Enhance create_edit_window method with dynamic fields and improved layout
This commit is contained in:
+168
-21
@@ -602,52 +602,199 @@ class UIManager:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def create_edit_window(self, values, callbacks):
|
def create_edit_window(self, values, callbacks):
|
||||||
"""Minimal edit window allowing date and note changes.
|
"""Create the full edit window with dynamic fields.
|
||||||
|
|
||||||
This simplified version passes missing pathology/medicine values as zeros
|
Expected `values` format (as provided by main._create_edit_window):
|
||||||
and an empty dose mapping to the caller's save callback for compatibility.
|
(date,
|
||||||
|
[pathology values...],
|
||||||
|
[for each medicine: taken, doses_string],
|
||||||
|
note)
|
||||||
|
|
||||||
|
On save, call the provided callback with:
|
||||||
|
(window, date, pathology_values..., medicine_values..., note, dose_data_dict)
|
||||||
"""
|
"""
|
||||||
win = tk.Toplevel(master=self.root)
|
win = tk.Toplevel(master=self.root)
|
||||||
win.title("Edit Entry")
|
win.title("Edit Entry")
|
||||||
win.transient(self.root)
|
win.transient(self.root)
|
||||||
win.minsize(400, 240)
|
win.minsize(520, 420)
|
||||||
|
|
||||||
container = ttk.Frame(win, padding=12)
|
# Scrollable content area
|
||||||
container.pack(fill=tk.BOTH, expand=True)
|
outer = ttk.Frame(win, padding=12)
|
||||||
|
outer.pack(fill=tk.BOTH, expand=True)
|
||||||
|
|
||||||
ttk.Label(container, text="Date (mm/dd/yyyy):").grid(
|
canvas = tk.Canvas(outer, highlightthickness=0)
|
||||||
row=0, column=0, sticky="w"
|
vscroll = ttk.Scrollbar(outer, orient="vertical", command=canvas.yview)
|
||||||
)
|
content = ttk.Frame(canvas)
|
||||||
date_var = tk.StringVar(value=values[0] if values else "")
|
content.grid_columnconfigure(1, weight=1)
|
||||||
|
canvas_window_id = canvas.create_window((0, 0), window=content, anchor="nw")
|
||||||
|
canvas.configure(yscrollcommand=vscroll.set)
|
||||||
|
canvas.grid(row=0, column=0, sticky="nsew")
|
||||||
|
vscroll.grid(row=0, column=1, sticky="ns")
|
||||||
|
outer.grid_rowconfigure(0, weight=1)
|
||||||
|
outer.grid_columnconfigure(0, weight=1)
|
||||||
|
|
||||||
|
def _on_configure(_evt=None):
|
||||||
|
canvas.configure(scrollregion=canvas.bbox("all"))
|
||||||
|
|
||||||
|
def _on_canvas_width(_evt=None):
|
||||||
|
# Keep inner frame width in sync so widgets expand
|
||||||
|
bbox = canvas.bbox("all")
|
||||||
|
if bbox:
|
||||||
|
canvas.itemconfigure(canvas_window_id, width=canvas.winfo_width())
|
||||||
|
|
||||||
|
content.bind("<Configure>", _on_configure)
|
||||||
|
canvas.bind("<Configure>", _on_canvas_width)
|
||||||
|
|
||||||
|
# Unpack incoming values using managers' key orders
|
||||||
|
pathology_keys = list(self.pathology_manager.get_pathology_keys())
|
||||||
|
medicine_keys = list(self.medicine_manager.get_medicine_keys())
|
||||||
|
|
||||||
|
idx = 0
|
||||||
|
date_str = values[idx] if values else ""
|
||||||
|
idx += 1
|
||||||
|
|
||||||
|
# Pathology values
|
||||||
|
pathology_values: dict[str, int] = {}
|
||||||
|
for key in pathology_keys:
|
||||||
|
try:
|
||||||
|
pathology_values[key] = int(values[idx])
|
||||||
|
except Exception:
|
||||||
|
pathology_values[key] = 0
|
||||||
|
idx += 1
|
||||||
|
|
||||||
|
# Medicine taken and stored dose strings
|
||||||
|
medicine_taken: dict[str, int] = {}
|
||||||
|
medicine_doses_str: dict[str, str] = {}
|
||||||
|
for key in medicine_keys:
|
||||||
|
try:
|
||||||
|
medicine_taken[key] = int(values[idx])
|
||||||
|
except Exception:
|
||||||
|
medicine_taken[key] = 0
|
||||||
|
idx += 1
|
||||||
|
try:
|
||||||
|
medicine_doses_str[key] = str(values[idx])
|
||||||
|
except Exception:
|
||||||
|
medicine_doses_str[key] = ""
|
||||||
|
idx += 1
|
||||||
|
|
||||||
|
note_val = values[idx] if idx < len(values) else ""
|
||||||
|
|
||||||
|
# --- Build UI ---
|
||||||
|
# Date
|
||||||
|
ttk.Label(content, text="Date (mm/dd/yyyy):").grid(row=0, column=0, sticky="w")
|
||||||
|
date_var = tk.StringVar(value=str(date_str))
|
||||||
ttk.Entry(
|
ttk.Entry(
|
||||||
container, textvariable=date_var, justify="center", style="Modern.TEntry"
|
content,
|
||||||
|
textvariable=date_var,
|
||||||
|
justify="center",
|
||||||
|
style="Modern.TEntry",
|
||||||
).grid(row=0, column=1, sticky="ew", padx=8, pady=4)
|
).grid(row=0, column=1, sticky="ew", padx=8, pady=4)
|
||||||
|
|
||||||
ttk.Label(container, text="Note:").grid(row=1, column=0, sticky="w")
|
# Pathologies section
|
||||||
note_val = values[-1] if values else ""
|
row = 1
|
||||||
|
ttk.Label(content, text="Pathologies:").grid(row=row, column=0, sticky="w")
|
||||||
|
path_frame = ttk.Frame(content)
|
||||||
|
path_frame.grid(row=row, column=1, sticky="ew", padx=8, pady=4)
|
||||||
|
path_frame.grid_columnconfigure(1, weight=1)
|
||||||
|
row += 1
|
||||||
|
|
||||||
|
pathology_vars: dict[str, tk.IntVar] = {}
|
||||||
|
for i, key in enumerate(pathology_keys):
|
||||||
|
pathology_vars[key] = tk.IntVar(value=pathology_values.get(key, 0))
|
||||||
|
pathology = self.pathology_manager.get_pathology(key)
|
||||||
|
label = (
|
||||||
|
pathology.display_name
|
||||||
|
if getattr(pathology, "display_name", None)
|
||||||
|
else key.capitalize()
|
||||||
|
)
|
||||||
|
ttk.Label(path_frame, text=f"{label}:").grid(
|
||||||
|
row=i, column=0, sticky="w", padx=2
|
||||||
|
)
|
||||||
|
scale = ttk.Scale(path_frame, from_=0, to=10, orient=tk.HORIZONTAL)
|
||||||
|
scale.grid(row=i, column=1, sticky="ew", padx=4)
|
||||||
|
with suppress(Exception):
|
||||||
|
scale.set(pathology_vars[key].get())
|
||||||
|
|
||||||
|
# Keep IntVar in sync when dragging
|
||||||
|
def _mk_scale_cmd(k: str, s: ttk.Scale):
|
||||||
|
def _cmd(_evt=None):
|
||||||
|
with suppress(Exception):
|
||||||
|
pathology_vars[k].set(int(float(s.get())))
|
||||||
|
|
||||||
|
return _cmd
|
||||||
|
|
||||||
|
scale.bind("<ButtonRelease-1>", _mk_scale_cmd(key, scale))
|
||||||
|
|
||||||
|
# Medicines section
|
||||||
|
ttk.Label(content, text="Medicines:").grid(row=row, column=0, sticky="w")
|
||||||
|
meds_frame = ttk.Frame(content)
|
||||||
|
meds_frame.grid(row=row, column=1, sticky="ew", padx=8, pady=4)
|
||||||
|
meds_frame.grid_columnconfigure(0, weight=1)
|
||||||
|
row += 1
|
||||||
|
|
||||||
|
medicine_vars: dict[str, tk.IntVar] = {}
|
||||||
|
for i, key in enumerate(medicine_keys):
|
||||||
|
medicine_vars[key] = tk.IntVar(value=medicine_taken.get(key, 0))
|
||||||
|
med = self.medicine_manager.get_medicine(key)
|
||||||
|
text = (
|
||||||
|
med.display_name
|
||||||
|
if getattr(med, "display_name", None)
|
||||||
|
else key.capitalize()
|
||||||
|
)
|
||||||
|
chk = ttk.Checkbutton(
|
||||||
|
meds_frame,
|
||||||
|
text=text,
|
||||||
|
variable=medicine_vars[key],
|
||||||
|
style="Modern.TCheckbutton",
|
||||||
|
)
|
||||||
|
chk.grid(row=i, column=0, sticky="w", padx=2, pady=2)
|
||||||
|
|
||||||
|
# Note field
|
||||||
|
ttk.Label(content, text="Note:").grid(row=row, column=0, sticky="nw")
|
||||||
note_var = tk.StringVar(value=str(note_val))
|
note_var = tk.StringVar(value=str(note_val))
|
||||||
ttk.Entry(container, textvariable=note_var, style="Modern.TEntry").grid(
|
ttk.Entry(content, textvariable=note_var, style="Modern.TEntry").grid(
|
||||||
row=1, column=1, sticky="ew", padx=8, pady=4
|
row=row, column=1, sticky="ew", padx=8, pady=4
|
||||||
)
|
)
|
||||||
|
row += 1
|
||||||
|
|
||||||
container.grid_columnconfigure(1, weight=1)
|
# Buttons
|
||||||
|
buttons = ttk.Frame(content)
|
||||||
buttons = ttk.Frame(container)
|
buttons.grid(row=row, column=0, columnspan=2, pady=10)
|
||||||
buttons.grid(row=2, column=0, columnspan=2, pady=10)
|
|
||||||
|
|
||||||
def _on_save():
|
def _on_save():
|
||||||
# Only provide date and note; caller will default others.
|
# Build args matching main._save_edit expectation
|
||||||
|
args: list[object] = [date_var.get()]
|
||||||
|
# Pathology values in key order
|
||||||
|
for key in pathology_keys:
|
||||||
|
args.append(int(pathology_vars[key].get()))
|
||||||
|
# Medicine 'taken' values in key order
|
||||||
|
for key in medicine_keys:
|
||||||
|
args.append(int(medicine_vars[key].get()))
|
||||||
|
# Note
|
||||||
|
args.append(note_var.get())
|
||||||
|
# Preserve existing dose strings unless caller offers an editor elsewhere
|
||||||
|
dose_map = {k: medicine_doses_str.get(k, "") for k in medicine_keys}
|
||||||
|
args.append(dose_map)
|
||||||
with suppress(Exception):
|
with suppress(Exception):
|
||||||
callbacks.get("save")(win, date_var.get(), note_var.get(), {})
|
callbacks.get("save")(win, *args)
|
||||||
|
|
||||||
def _on_delete():
|
def _on_delete():
|
||||||
with suppress(Exception):
|
with suppress(Exception):
|
||||||
callbacks.get("delete")(win)
|
callbacks.get("delete")(win)
|
||||||
|
|
||||||
|
def _on_cancel():
|
||||||
|
with suppress(Exception):
|
||||||
|
win.destroy()
|
||||||
|
|
||||||
ttk.Button(buttons, text="Save", command=_on_save, style="Action.TButton").pack(
|
ttk.Button(buttons, text="Save", command=_on_save, style="Action.TButton").pack(
|
||||||
side="left", padx=5
|
side="left", padx=5
|
||||||
)
|
)
|
||||||
ttk.Button(buttons, text="Delete", command=_on_delete).pack(side="left", padx=5)
|
ttk.Button(buttons, text="Delete", command=_on_delete).pack(side="left", padx=5)
|
||||||
|
ttk.Button(buttons, text="Cancel", command=_on_cancel).pack(side="left", padx=5)
|
||||||
|
|
||||||
|
# Finalize scroll region
|
||||||
|
content.update_idletasks()
|
||||||
|
canvas.configure(scrollregion=canvas.bbox("all"))
|
||||||
|
|
||||||
return win
|
return win
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user