Drag links out of slots on the wiresheet; hide @palette=false types

Hovering a slot row highlights the half under the pointer and shows a
direction cursor. Pressing on a slot drags a rubber band; dropping on
another slot links them, dropping on a title bar opens the Link dialog
with the dragged slot preselected, and a no-entry cursor marks a slot
that would refuse the link. A right click that never moves still opens
the context menu.

The palette now leaves out types whose facets carry @palette=false, and
kits with nothing placeable left.

Also points the default device host at 192.168.1.251.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-03 23:15:47 +03:00
co-authored by Claude Opus 5.5
parent f22d4852c9
commit 85b6fa62f3
7 changed files with 538 additions and 11 deletions
+22 -7
View File
@@ -10,6 +10,7 @@ import threading
import app_state
import connect_dialog
import device_session
import link_drag
import link_view
import live_hooks
import manage_kits
@@ -1201,8 +1202,12 @@ def _slot_linkable(slot_flags, slot_type, readonly, is_target):
return True
def open_link_dialog(source_element, target_element):
"""Opens a dialog to select source and target slots, validates types, and creates a link."""
def open_link_dialog(source_element, target_element, source_slot=None, target_slot=None):
"""Opens a dialog to select source and target slots, validates types, and creates a link.
source_slot / target_slot pre-select a slot on that side, as when a link dragged out
of a slot is dropped on a component's title bar rather than on one of its slots.
"""
window = app_state.window
sides = [source_element, target_element]
@@ -1346,6 +1351,11 @@ def open_link_dialog(source_element, target_element):
ttk.Button(mid_frame, text="⇄", width=3, command=on_swap).pack(pady=5)
refresh_panels()
for var, slot, info, is_target in ((src_var, source_slot, src_slot_info, False),
(tgt_var, target_slot, tgt_slot_info, True)):
if slot in info and _slot_linkable(info[slot][1], info[slot][0], info[slot][2],
is_target):
var.set(slot)
status_label = tk.Label(main_frame, textvariable=status_var, anchor="w", fg="#333333")
status_label.grid(row=1, column=0, columnspan=3, sticky="w", pady=(8, 0))
@@ -2804,7 +2814,11 @@ def refresh_palette_kits():
if _schema_has_incomplete_checksums():
palette_kit_names = []
else:
palette_kit_names = sorted(app_state.active_schema_kits.keys())
# A kit with nothing placeable (all abstract or @palette=false) is left out.
palette_kit_names = [
kit_name for kit_name in sorted(app_state.active_schema_kits.keys())
if palette.list_component_types(kit_name)
]
labels = []
for kit_name in palette_kit_names:
@@ -2966,12 +2980,13 @@ canvas.pack(fill=tk.BOTH, expand=True)
canvas_vscroll.config(command=canvas.yview)
canvas_hscroll.config(command=canvas.xview)
canvas.bind("<ButtonPress-1>", on_canvas_click)
canvas.bind("<B1-Motion>", on_canvas_drag)
canvas.bind("<ButtonRelease-1>", on_canvas_release)
canvas.bind("<Configure>", lambda e: wiresheet.draw_grid())
canvas.bind("<ButtonPress-3>", on_canvas_right_click)
# Either button pressed on a slot row drags out a new link. Elsewhere the left button
# selects and moves boxes and a plain right click is the menu, as before.
link_drag.install(canvas, on_canvas_right_click,
on_canvas_click, on_canvas_drag, on_canvas_release,
link_dialog=open_link_dialog)
canvas.bind("<ButtonPress-2>", on_canvas_right_click)
canvas.bind("<Double-1>", on_canvas_double_click)