Commit e53fa516 authored by Yannick Kirschhoffer's avatar Yannick Kirschhoffer

Optimization of Links widget to match vertical alignment as much as possible.

parent b2066a2c
......@@ -100,7 +100,7 @@ class Renderer:
networks_box = VBox(network_widgets)
bridges_box = VBox(bridge_widgets)
links_box = Links(bridges_box, networks_box, links)
links_box = Links(bridges_box, networks_box, links, True)
# Port mapping
......
......@@ -13,11 +13,10 @@ class PortMapping:
class VolumeMapping:
def __init__(self, rw: bool, source: str, destination: str, type: str):
def __init__(self, rw: bool, source: str, destination: str):
self.rw = rw
self.source = source
self.destination = destination
self.type = type
def __repr__(self):
return '%s:%s' % (self.source, self.destination)
......@@ -25,14 +24,14 @@ class VolumeMapping:
class Container:
def __init__(self, name: str, status: str, networks: List[str], image: str,
ports: List[PortMapping] = [],
volumes: List[VolumeMapping] = []):
ports: List[PortMapping] = None,
volumes: List[VolumeMapping] = None):
self.name = name
self.status = status
self.networks = networks
self.image = image
self.ports = ports
self.volumes = volumes
self.ports = ports if ports is not None else []
self.volumes = volumes if volumes is not None else []
def is_running(self):
return self.status == 'running'
......@@ -68,7 +67,7 @@ class ConfigParser:
networks.sort()
ports = [PortMapping(p['PrivatePort'], p['PublicPort'])
for p in cinfo['Ports'] if 'PublicPort' in p.keys()]
volumes = [VolumeMapping(rw=v['RW'], type=v['Type'], source=v['Source'], destination=v['Destination'])
volumes = [VolumeMapping(rw=v['RW'], source=v['Source'], destination=v['Destination'])
for v in cinfo['Mounts']]
containers.append(Container(name, status, networks, image, ports, volumes))
......
......@@ -166,32 +166,55 @@ class Paragraph(Widget):
class Links(Widget):
def __init__(self, left: Widget, right: Widget, links: List[Tuple[Widget, Widget]]):
self._root = HBox([left, right])
def __init__(self, left: Widget, right: Widget,
links: List[Tuple[Widget, Widget]],
align: bool = False):
self._left = left
self._right = right
self._links = links
self._align = align
def preferred_size(self) -> Size:
return self._root.preferred_size()
return HBox([self._left, self._right]).preferred_size()
def render(self, hints: Hints = None):
raster = self._root.render(hints)
dy_values = []
dy_average = 0
root = HBox([self._left, self._right])
raster = root.render(hints)
for w_src, w_dst in self._links:
bounds_src = raster.origin_bounds(w_src)
bounds_dst = raster.origin_bounds(w_dst)
src_x = bounds_src.x + bounds_src.w
src_y = int(bounds_src.y + bounds_src.h / 2) - 1
dst_x = bounds_dst.x
if src_y in range(bounds_dst.y, bounds_dst.y + bounds_dst.h):
dst_y = src_y
dst_x, dst_y, src_x, src_y = self._compute_link_coords(raster, w_dst, w_src)
raster.draw_line(src_x, src_y, dst_x, dst_y)
dy_values.append(dst_y - src_y)
if self._align and len(dy_values) > 0:
dy_average = int(sum(dy_values) / len(dy_values))
if dy_average != 0:
if dy_average < 0:
root = HBox([self._left, Padding(self._right, Size(0, -dy_average))])
else:
dst_y = int(bounds_dst.y + bounds_dst.h / 2) - 1
root = HBox([Padding(self._left, Size(0, dy_average)), self._right])
raster.draw_line(src_x, src_y, dst_x, dst_y)
raster = root.render(hints)
for w_src, w_dst in self._links:
dst_x, dst_y, src_x, src_y = self._compute_link_coords(raster, w_dst, w_src)
raster.draw_line(src_x, src_y, dst_x, dst_y)
dy_values.append(dst_y - src_y)
return raster
def _compute_link_coords(self, raster, w_dst, w_src):
bounds_src = raster.origin_bounds(w_src)
bounds_dst = raster.origin_bounds(w_dst)
src_x = bounds_src.x + bounds_src.w
src_y = int(bounds_src.y + bounds_src.h / 2) - 1
dst_x = bounds_dst.x
dst_y = int(bounds_dst.y + bounds_dst.h / 2) - 1
return dst_x, dst_y, src_x, src_y
class Annotations(Widget):
def __init__(self, content: Widget, annotations: List[Tuple[Widget, str, str, List[str]]]):
......
import unittest
from docker_ascii_map.docker_config import *
from docker_ascii_map.ascii_render import Renderer
from docker_ascii_map.raster import RasterCell
from docker_ascii_map.docker_config import *
class RenderingTests(unittest.TestCase):
......@@ -81,10 +79,10 @@ class RenderingTests(unittest.TestCase):
self.assertEqual(
' +- net1 -+\n'
' | [✓] n1 |\n'
' [✓] n-front ------+-----| im |\n'
' httpd:2.4 | +--------+\n'
' | +- net2 -+\n'
' +-----| [✓] n1 |\n'
' | | im |\n'
' [✓] n-front ------+ +--------+\n'
' httpd:2.4 | +- net2 -+\n'
' +-----| [✓] n2 |\n'
' | im |\n'
' +--------+\n'
......@@ -105,10 +103,10 @@ class RenderingTests(unittest.TestCase):
self.assertEqual(
' +- net1 -+\n'
' | [✓] n1 |\n'
' [✓] n-front ------+-----| im |\n'
' httpd:2.4 | +--------+\n'
' | +- net3 -+\n'
' +-----| [✓] n1 |\n'
' | | im |\n'
' [✓] n-front ------+ +--------+\n'
' httpd:2.4 | +- net3 -+\n'
' +-----| [✓] n3 |\n'
' | im |\n'
' +--------+\n'
......
......@@ -155,6 +155,8 @@ class ModelTests(unittest.TestCase):
[(w1, w2)]
)
# print(str(model.render()))
self.assertEqual(
' \n'
' +-------Hello \n'
......@@ -177,10 +179,12 @@ class ModelTests(unittest.TestCase):
[(w1, w2)]
)
# print(model.render())
self.assertEqual(
' \n'
' Hello \n'
' Hello ----------------World ! \n'
' +-------Hello \n'
' Hello --------+ World ! \n'
' World ! \n'
' \n'
' \n'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment