Wiresheet: arrow keys nudge selected boxes one grid step
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -8,7 +8,7 @@ so later rebinding would only ever be seen by the module that did it.
|
|||||||
import configparser
|
import configparser
|
||||||
import os
|
import os
|
||||||
|
|
||||||
VERSION = "0.0.0.178"
|
VERSION = "0.0.0.179"
|
||||||
PROPERTIES_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "editor.properties")
|
PROPERTIES_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "editor.properties")
|
||||||
DEFAULT_GRID_SIZE = 10
|
DEFAULT_GRID_SIZE = 10
|
||||||
DEFAULT_ADD_TIMESTAMP = True
|
DEFAULT_ADD_TIMESTAMP = True
|
||||||
|
|||||||
@@ -2241,6 +2241,39 @@ def on_canvas_release(event):
|
|||||||
wiresheet.redraw_links()
|
wiresheet.redraw_links()
|
||||||
|
|
||||||
|
|
||||||
|
def nudge_selected_boxes(dx, dy):
|
||||||
|
"""Arrow keys: moves every selected box one meta step, as one undoable move."""
|
||||||
|
canvas = app_state.canvas
|
||||||
|
tags = [t for t in app_state.selected_canvas_tags if t in app_state.canvas_comp_map]
|
||||||
|
if not tags or app_state.drag_data.get("tag"):
|
||||||
|
return "break"
|
||||||
|
step = app_state.meta_scale * app_state.zoom
|
||||||
|
margin = wiresheet.layout_margin(app_state.meta_scale) * app_state.zoom
|
||||||
|
limit = wiresheet.META_COORD_MAX * step
|
||||||
|
origins = {t: wiresheet.get_box_origin(t) for t in tags}
|
||||||
|
if any(o is None for o in origins.values()):
|
||||||
|
return "break"
|
||||||
|
# The group stops as one at the margin strip and the sheet's far edge.
|
||||||
|
shift_x = min(limit - max(o[0] for o in origins.values()),
|
||||||
|
max(margin - min(o[0] for o in origins.values()), dx * step))
|
||||||
|
shift_y = min(limit - max(o[1] for o in origins.values()),
|
||||||
|
max(margin - min(o[1] for o in origins.values()), dy * step))
|
||||||
|
if not shift_x and not shift_y:
|
||||||
|
return "break"
|
||||||
|
|
||||||
|
# Moved on the canvas, then written back exactly as a finished mouse drag is.
|
||||||
|
group = []
|
||||||
|
for tag in tags:
|
||||||
|
comp = app_state.canvas_comp_map[tag]
|
||||||
|
meta_prop = comp.find("prop[@name='meta']")
|
||||||
|
group.append({"tag": tag, "origin": origins[tag],
|
||||||
|
"meta_before": meta_prop.get("val") if meta_prop is not None else None})
|
||||||
|
canvas.move(tag, shift_x, shift_y)
|
||||||
|
app_state.drag_data.update(tag=tags[0], group=group, moved=True, collapse_to=None)
|
||||||
|
on_canvas_release(None)
|
||||||
|
return "break"
|
||||||
|
|
||||||
|
|
||||||
def fit_tree_column(tree):
|
def fit_tree_column(tree):
|
||||||
"""Sizes a Treeview's tree column to its widest visible row.
|
"""Sizes a Treeview's tree column to its widest visible row.
|
||||||
|
|
||||||
@@ -3830,6 +3863,11 @@ link_drag.install(canvas, on_canvas_right_click,
|
|||||||
on_canvas_click, on_canvas_drag, on_canvas_release,
|
on_canvas_click, on_canvas_drag, on_canvas_release,
|
||||||
link_dialog=open_link_dialog, select_boxes=select_canvas_boxes)
|
link_dialog=open_link_dialog, select_boxes=select_canvas_boxes)
|
||||||
canvas.bind("<ButtonPress-2>", on_canvas_right_click)
|
canvas.bind("<ButtonPress-2>", on_canvas_right_click)
|
||||||
|
# A click gives the sheet the keyboard, so the arrows nudge its selected boxes rather
|
||||||
|
# than walking whatever tree or list last had focus.
|
||||||
|
canvas.bind("<ButtonPress-1>", lambda e: canvas.focus_set(), add="+")
|
||||||
|
for _key, _dx, _dy in (("Left", -1, 0), ("Right", 1, 0), ("Up", 0, -1), ("Down", 0, 1)):
|
||||||
|
canvas.bind(f"<{_key}>", lambda e, dx=_dx, dy=_dy: nudge_selected_boxes(dx, dy))
|
||||||
canvas.bind("<Double-1>", on_canvas_double_click)
|
canvas.bind("<Double-1>", on_canvas_double_click)
|
||||||
|
|
||||||
# Wheel zoom. Windows and macOS report a delta; X11 sends button 4 and 5 instead.
|
# Wheel zoom. Windows and macOS report a delta; X11 sends button 4 and 5 instead.
|
||||||
|
|||||||
Reference in New Issue
Block a user