From cbe63ca0cc0e7ec964626a7c3cc7d7bbc4600c1e Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Thu, 19 Dec 2024 15:40:37 +0000 Subject: [PATCH] allow reverse order --- src/textual/screen.py | 4 +++- src/textual/selection.py | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/textual/screen.py b/src/textual/screen.py index 31bf351c6e..2b86243e4f 100644 --- a/src/textual/screen.py +++ b/src/textual/screen.py @@ -1469,7 +1469,9 @@ def watch__select_end(self, select_end: tuple[Widget, Offset] | None) -> None: start_widget, start_offset = self._select_start end_widget, end_offset = select_end - self.selections = {start_widget: Selection(start_offset, end_offset)} + self.selections = { + start_widget: Selection.from_offsets(start_offset, end_offset) + } def dismiss(self, result: ScreenResultType | None = None) -> AwaitComplete: """Dismiss the screen, optionally with a result. diff --git a/src/textual/selection.py b/src/textual/selection.py index a993fce375..159e2e4628 100644 --- a/src/textual/selection.py +++ b/src/textual/selection.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import NamedTuple from textual.geometry import Offset @@ -11,6 +13,20 @@ class Selection(NamedTuple): end: Offset | None """Offset or None for `end`.""" + @classmethod + def from_offsets(cls, offset1: Offset, offset2: Offset) -> Selection: + """Create selection from 2 offsets. + + Args: + offset1: First offset. + offset2: Second offset. + + Returns: + New Selection. + """ + offsets = sorted([offset1, offset2], key=(lambda offset: (offset.y, offset.x))) + return cls(*offsets) + def get_span(self, y: int) -> tuple[int, int] | None: """Get the selected span in a given line.