1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
|
Location
========
If you just want to move the location of the cursor before writing text, and aren't worried about
returning, do something like this:
>>> print(term.home + term.clear, end='')
>>> print(term.move_down(2) + term.move_right(20) + term.bright_red('fire!'), end='')
>>> print(term.move_xy(20, 7) + term.bold('Direct hit!'), end='')
>>> print(term.move_y(term.height - 3), end='')
Note our use of ``end=''`` to the built-in :func:`print` function, this is
because the default ``end='\n'`` value causes the cursor to move to the first
column of the next row.
There are four direct movement capabilities:
``move_xy(x, y)``
Position cursor at given **x**, **y**.
``move_x(x)``
Position cursor at column **x**.
``move_y(y)``
Position cursor at row **y**.
``home``
Position cursor at (0, 0).
And four relative capabilities:
``move_up`` or ``move_up(y)``
Position cursor 1 or **y** row cells above the current position.
``move_down(y)``
Position cursor 1 or **y** row cells below the current position.
.. note:: ``move_down`` or is often valued as *\\n*, which additionally returns the carriage to
column 0, and, depending on your terminal emulator, may also destroy any characters to end of
line.
``move_down(1)`` is always a safe non-destructive one-notch movement in the downward direction.
``move_left`` or ``move_left(x)``
Position cursor 1 or **x** column cells left of the current position.
``move_right`` or ``move_right(x)``
Position cursor 1 or **x** column cells right of the current position.
Example
-------
The source code of :ref:`bounce.py` combines a small bit of :doc:`keyboard` input with many of the
Terminal location capabilities, ``home``, ``width``, ``height``, and ``move_xy`` are used to create
a classic game of tennis:
.. literalinclude:: ../bin/bounce.py
:language: python
:lines: 3-
:emphasize-lines: 17,22,25,27,34
.. figure:: https://dxtz6bzwq9sxx.cloudfront.net/demo_basic_bounce.gif
:alt: Animated screenshot of :ref:`bounce.py`
Context Manager
---------------
A :func:`contextlib.contextmanager`, :meth:`~.Terminal.location` is provided to move the cursor to
an *(x, y)* screen position and *restore the previous position* on exit:
.. code-block:: python
with term.location(0, term.height - 1):
print('Here is the bottom.')
print('This is back where I came from.')
All parameters to :meth:`~.Terminal.location` are **optional**, we can use
it without any arguments at all to restore the cursor location:
.. code-block:: python
with term.location():
print(term.move_xy(1, 1) + 'Hi Mom!' + term.clear_eol)
.. note:: calls to :meth:`~.Terminal.location` may not be nested.
Finding The Cursor
------------------
We can determine the cursor's current position at anytime using :meth:`~.get_location`.
This uses a kind of "answer back" sequence that your terminal emulator responds to. Because the
terminal may not respond, or may take some time to respond, the :paramref:`~.get_location.timeout`
keyword argument can be specified to return coordinates (-1, -1) after a blocking timeout:
>>> term.get_location(timeout=5)
(32, 0)
The return value of :meth:`~.Terminal.get_location` mirrors the arguments of
:meth:`~Terminal.location`:
.. code-block:: python
with term.location(12, 12):
val = term.get_location()
print(val)
Produces output, ``(12, 12)``
Although this wouldn't be suggested in most applications because of its latency, it certainly
simplifies many applications, and, can also be timed, to make a determination of the round-trip
time, perhaps even the bandwidth constraints, of a remote terminal!
|