mirror of
https://github.com/Stone-Red-Code/dvc.git
synced 2026-11-10 07:18:27 +01:00
show: use asciimatics to provide scrollable graph
Fixes #1177 Signed-off-by: Ruslan Kuprieiev <[email protected]>
This commit is contained in:
+80
-2
@@ -1,4 +1,9 @@
|
||||
import sys
|
||||
import math
|
||||
import select
|
||||
|
||||
from asciimatics.screen import Screen
|
||||
from asciimatics.event import KeyboardEvent
|
||||
|
||||
from grandalf.graphs import Vertex, Edge, Graph
|
||||
from grandalf.layouts import SugiyamaLayout
|
||||
@@ -12,11 +17,84 @@ class AsciiCanvas(object):
|
||||
|
||||
self.cols = cols
|
||||
self.lines = lines
|
||||
|
||||
self.canvas = [[' '] * cols for l in range(lines)]
|
||||
|
||||
def draw(self):
|
||||
for line in self.canvas:
|
||||
print(''.join(line))
|
||||
if sys.stdout.isatty():
|
||||
Screen.wrapper(self._do_draw)
|
||||
else:
|
||||
for line in self.canvas:
|
||||
print(''.join(line))
|
||||
|
||||
def _do_draw(self, screen):
|
||||
offset_x = 0
|
||||
offset_y = 0
|
||||
smaxrow, smaxcol = screen.dimensions
|
||||
assert smaxrow > 1
|
||||
assert smaxcol > 1
|
||||
smaxrow -= 1
|
||||
smaxcol -= 1
|
||||
|
||||
if self.lines + 1 > smaxrow:
|
||||
max_y = self.lines + 1 - smaxrow
|
||||
else:
|
||||
max_y = 0
|
||||
|
||||
if self.cols + 1 > smaxcol:
|
||||
max_x = self.cols + 1 - smaxcol
|
||||
else:
|
||||
max_x = 0
|
||||
|
||||
while True:
|
||||
for y in range(smaxrow + 1):
|
||||
y_index = offset_y + y
|
||||
line = []
|
||||
for x in range(smaxcol + 1):
|
||||
x_index = offset_x + x
|
||||
if len(self.canvas) > y_index \
|
||||
and len(self.canvas[y_index]) > x_index:
|
||||
line.append(self.canvas[y_index][x_index])
|
||||
else:
|
||||
line.append(' ')
|
||||
assert len(line) == (smaxcol + 1)
|
||||
screen.print_at(''.join(line), 0, y)
|
||||
|
||||
screen.refresh()
|
||||
|
||||
# NOTE: get_event() doesn't block by itself,
|
||||
# so we have to do the blocking ourselves.
|
||||
select.select([sys.stdin], [], [], None)
|
||||
|
||||
event = screen.get_event()
|
||||
if not isinstance(event, KeyboardEvent):
|
||||
continue
|
||||
|
||||
k = event.key_code
|
||||
if k == screen.KEY_DOWN:
|
||||
offset_y += 1
|
||||
elif k == screen.KEY_PAGE_DOWN:
|
||||
offset_y += smaxrow
|
||||
elif k == screen.KEY_UP:
|
||||
offset_y -= 1
|
||||
elif k == screen.KEY_PAGE_UP:
|
||||
offset_y -= smaxrow
|
||||
elif k == screen.KEY_RIGHT:
|
||||
offset_x += 1
|
||||
elif k == screen.KEY_LEFT:
|
||||
offset_x -= 1
|
||||
elif k == ord('q'):
|
||||
break
|
||||
|
||||
if offset_y > max_y:
|
||||
offset_y = max_y
|
||||
elif offset_y < 0:
|
||||
offset_y = 0
|
||||
|
||||
if offset_x > max_x:
|
||||
offset_x = max_x
|
||||
elif offset_x < 0:
|
||||
offset_x = 0
|
||||
|
||||
def point(self, x, y, char):
|
||||
assert x >= 0
|
||||
|
||||
@@ -23,3 +23,4 @@ wheel>=0.31.1
|
||||
futures>=3.2.0; python_version == "2.7"
|
||||
grandalf==0.6
|
||||
pydot>=1.2.4
|
||||
asciimatics>=1.10.0
|
||||
|
||||
Reference in New Issue
Block a user